@qazuor/claude-code-config 0.3.0 → 0.3.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -1 +1 @@
1
- {"version":3,"sources":["../node_modules/.pnpm/tsup@8.5.1_postcss@8.5.6_typescript@5.9.3/node_modules/tsup/assets/cjs_shims.js","../src/lib/utils/fs.ts","../src/index.ts","../src/constants/bundles.ts","../src/constants/mcp-servers.ts","../src/constants/dependencies.ts","../src/constants/placeholders.ts","../src/constants/permissions.ts","../src/lib/bundles/resolver.ts","../src/lib/config/index.ts","../src/lib/config/reader.ts","../src/lib/utils/logger.ts","../src/lib/config/writer.ts","../src/lib/config/global-defaults.ts","../src/lib/modules/index.ts","../src/lib/modules/registry.ts","../src/lib/modules/resolver.ts","../src/lib/modules/installer.ts","../src/lib/utils/spinner.ts","../src/lib/placeholders/index.ts","../src/lib/placeholders/replacer.ts","../src/lib/scaffold/detector.ts","../src/lib/templates/index.ts","../src/lib/templates/parser.ts","../src/lib/templates/evaluator.ts","../src/lib/templates/processor.ts","../src/lib/templates/context.ts","../src/lib/templates/scanner.ts","../src/constants/template-placeholders.ts","../src/lib/templates/config-replacer.ts"],"sourcesContent":["// Shim globals in cjs bundle\n// There's a weird bug that esbuild will always inject importMetaUrl\n// if we export it as `const importMetaUrl = ... __filename ...`\n// But using a function will not cause this issue\n\nconst getImportMetaUrl = () => \n typeof document === \"undefined\" \n ? new URL(`file:${__filename}`).href \n : (document.currentScript && document.currentScript.tagName.toUpperCase() === 'SCRIPT') \n ? document.currentScript.src \n : new URL(\"main.js\", document.baseURI).href;\n\nexport const importMetaUrl = /* @__PURE__ */ getImportMetaUrl()\n","/**\n * Filesystem utility functions\n */\n\nimport path from 'node:path';\nimport fs from 'fs-extra';\nimport { glob } from 'glob';\n\n/**\n * Check if a path exists\n */\nexport async function pathExists(filePath: string): Promise<boolean> {\n return fs.pathExists(filePath);\n}\n\n/**\n * Check if a path is a directory\n */\nexport async function isDirectory(filePath: string): Promise<boolean> {\n try {\n const stat = await fs.stat(filePath);\n return stat.isDirectory();\n } catch {\n return false;\n }\n}\n\n/**\n * Check if a path is a file\n */\nexport async function isFile(filePath: string): Promise<boolean> {\n try {\n const stat = await fs.stat(filePath);\n return stat.isFile();\n } catch {\n return false;\n }\n}\n\n/**\n * Read a JSON file\n */\nexport async function readJson<T = unknown>(filePath: string): Promise<T> {\n return fs.readJson(filePath);\n}\n\n/**\n * Write a JSON file\n */\nexport async function writeJson(\n filePath: string,\n data: unknown,\n options?: { spaces?: number }\n): Promise<void> {\n await fs.ensureDir(path.dirname(filePath));\n await fs.writeJson(filePath, data, { spaces: options?.spaces ?? 2 });\n}\n\n/**\n * Read a text file\n */\nexport async function readFile(filePath: string): Promise<string> {\n return fs.readFile(filePath, 'utf-8');\n}\n\n/**\n * Write a text file\n */\nexport async function writeFile(filePath: string, content: string): Promise<void> {\n await fs.ensureDir(path.dirname(filePath));\n await fs.writeFile(filePath, content, 'utf-8');\n}\n\n/**\n * Copy a file or directory\n */\nexport async function copy(\n src: string,\n dest: string,\n options?: { overwrite?: boolean }\n): Promise<void> {\n await fs.ensureDir(path.dirname(dest));\n await fs.copy(src, dest, { overwrite: options?.overwrite ?? false });\n}\n\n/**\n * Copy a directory recursively\n */\nexport async function copyDir(\n src: string,\n dest: string,\n options?: { overwrite?: boolean; filter?: (src: string) => boolean }\n): Promise<void> {\n await fs.copy(src, dest, {\n overwrite: options?.overwrite ?? false,\n filter: options?.filter,\n });\n}\n\n/**\n * Create a directory (and parents if needed)\n */\nexport async function ensureDir(dirPath: string): Promise<void> {\n await fs.ensureDir(dirPath);\n}\n\n/**\n * Remove a file or directory\n */\nexport async function remove(filePath: string): Promise<void> {\n await fs.remove(filePath);\n}\n\n/**\n * List files matching a pattern\n */\nexport async function listFiles(\n pattern: string,\n options?: { cwd?: string; ignore?: string[] }\n): Promise<string[]> {\n return glob(pattern, {\n cwd: options?.cwd,\n ignore: options?.ignore,\n nodir: true,\n });\n}\n\n/**\n * List directories matching a pattern\n */\nexport async function listDirs(pattern: string, options?: { cwd?: string }): Promise<string[]> {\n const matches = await glob(pattern, {\n cwd: options?.cwd,\n });\n\n const dirs: string[] = [];\n for (const match of matches) {\n const fullPath = options?.cwd ? path.join(options.cwd, match) : match;\n if (await isDirectory(fullPath)) {\n dirs.push(match);\n }\n }\n\n return dirs;\n}\n\n/**\n * Get file info\n */\nexport async function getFileInfo(filePath: string): Promise<{\n exists: boolean;\n isFile: boolean;\n isDirectory: boolean;\n size: number;\n modified: Date;\n} | null> {\n try {\n const stat = await fs.stat(filePath);\n return {\n exists: true,\n isFile: stat.isFile(),\n isDirectory: stat.isDirectory(),\n size: stat.size,\n modified: stat.mtime,\n };\n } catch {\n return null;\n }\n}\n\n/**\n * Read all files in a directory recursively\n */\nexport async function readDirRecursive(\n dirPath: string,\n options?: { extensions?: string[] }\n): Promise<string[]> {\n const pattern = options?.extensions ? `**/*.{${options.extensions.join(',')}}` : '**/*';\n\n return glob(pattern, {\n cwd: dirPath,\n nodir: true,\n });\n}\n\n/**\n * Calculate hash of a file for comparison\n */\nexport async function getFileHash(filePath: string): Promise<string> {\n const crypto = await import('node:crypto');\n const content = await fs.readFile(filePath);\n return crypto.createHash('sha256').update(content).digest('hex');\n}\n\n/**\n * Compare two files\n */\nexport async function filesAreEqual(file1: string, file2: string): Promise<boolean> {\n try {\n const [hash1, hash2] = await Promise.all([getFileHash(file1), getFileHash(file2)]);\n return hash1 === hash2;\n } catch {\n return false;\n }\n}\n\n/**\n * Get relative path from base\n */\nexport function relativePath(from: string, to: string): string {\n return path.relative(from, to);\n}\n\n/**\n * Resolve path segments\n */\nexport function resolvePath(...segments: string[]): string {\n return path.resolve(...segments);\n}\n\n/**\n * Join path segments\n */\nexport function joinPath(...segments: string[]): string {\n return path.join(...segments);\n}\n\n/**\n * Get directory name\n */\nexport function dirname(filePath: string): string {\n return path.dirname(filePath);\n}\n\n/**\n * Get base name\n */\nexport function basename(filePath: string, ext?: string): string {\n return path.basename(filePath, ext);\n}\n\n/**\n * Get file extension\n */\nexport function extname(filePath: string): string {\n return path.extname(filePath);\n}\n\n/**\n * Backup a file or directory\n */\nexport async function backup(src: string, suffix = '.backup'): Promise<string> {\n const backupPath = `${src}${suffix}`;\n await copy(src, backupPath, { overwrite: true });\n return backupPath;\n}\n\n/**\n * Make a file executable (Unix only)\n */\nexport async function makeExecutable(filePath: string): Promise<void> {\n try {\n await fs.chmod(filePath, 0o755);\n } catch {\n // Ignore on Windows\n }\n}\n\n/**\n * Temporary directory utilities\n */\nexport async function createTempDir(prefix = 'claude-config-'): Promise<string> {\n const os = await import('node:os');\n const tempBase = os.tmpdir();\n const tempDir = path.join(tempBase, `${prefix}${Date.now()}`);\n await ensureDir(tempDir);\n return tempDir;\n}\n\nexport async function cleanTempDir(tempDir: string): Promise<void> {\n await remove(tempDir);\n}\n","/**\n * @qazuor/claude-code-config\n *\n * CLI tool to install and manage Claude Code configurations\n */\n\n// Export types\nexport type {\n ClaudeConfig,\n ModuleSelection,\n HookConfig,\n TemplateSource,\n Preferences,\n ScaffoldConfig,\n Customizations,\n} from './types/config.js';\n\nexport type {\n ModuleRegistry,\n ModuleDefinition,\n ModuleCategory,\n ResolvedModule,\n} from './types/modules.js';\n\nexport type {\n BundleCategory,\n BundleDefinition,\n BundleSelectionResult,\n ResolvedBundle,\n} from './types/bundles.js';\n\nexport type {\n McpServerDefinition,\n McpCategory,\n McpConfigField,\n McpInstallation,\n} from './types/mcp.js';\n\nexport type {\n ScaffoldType,\n ProjectType,\n ScaffoldOptions,\n ScaffoldResult,\n ProjectDetectionResult,\n} from './types/scaffold.js';\n\nexport type { PermissionPreset, PermissionsConfig } from './types/permissions.js';\n\n// Export constants\nexport { BUNDLES, getAllBundles, getBundleById } from './constants/bundles.js';\nexport { MCP_SERVERS } from './constants/mcp-servers.js';\nexport { DEPENDENCIES } from './constants/dependencies.js';\nexport { PLACEHOLDERS } from './constants/placeholders.js';\nexport { PERMISSION_PRESETS } from './constants/permissions.js';\n\n// Export bundle resolver\nexport { resolveBundles, resolveBundle, mergeBundleSelection } from './lib/bundles/resolver.js';\n\n// Export programmatic API\nexport { readConfig, writeConfig, hasConfig, createDefaultConfig } from './lib/config/index.js';\nexport { loadRegistry, resolveModules, installModules } from './lib/modules/index.js';\nexport { replacePlaceholders } from './lib/placeholders/index.js';\nexport { detectProject } from './lib/scaffold/detector.js';\nexport { processTemplates, buildTemplateContext } from './lib/templates/index.js';\n\n// Export template types\nexport type {\n TemplateContext,\n TemplateResult,\n TemplateProcessingReport,\n} from './types/templates.js';\n","/**\n * Predefined bundles for grouping related modules\n */\n\nimport type { BundleDefinition } from '../types/bundles.js';\n\n/**\n * All available bundles\n */\nexport const BUNDLES: BundleDefinition[] = [\n // ===================\n // STACK BUNDLES\n // ===================\n {\n id: 'react-tanstack-stack',\n name: 'React + TanStack Stack',\n description: 'React with TanStack Router/Start for admin dashboards and SPAs',\n category: 'stack',\n longDescription:\n 'Complete stack for building React applications with TanStack Router and Start. Includes React component development, TanStack-specific patterns, and related testing/quality tools.',\n techStack: ['React', 'TanStack Start', 'TanStack Router', 'TanStack Query', 'TypeScript'],\n tags: ['react', 'tanstack', 'admin', 'spa'],\n complexity: 'comprehensive',\n responsibilities: [\n 'React component architecture and best practices',\n 'TanStack Router file-based routing patterns',\n 'Server state management with TanStack Query',\n 'Form handling with React Hook Form + Zod',\n 'UI components with Shadcn/Radix primitives',\n ],\n scope: 'Full frontend stack for React SPAs and admin dashboards',\n useCases: [\n 'Admin dashboards and internal tools',\n 'Complex single-page applications',\n 'Data-heavy applications with tables/forms',\n 'Projects using TanStack ecosystem',\n ],\n moduleDetails: {\n agents: [\n {\n id: 'react-senior-dev',\n role: 'React Architecture',\n responsibilities: ['Component design', 'State management', 'Performance optimization'],\n },\n {\n id: 'tanstack-start-engineer',\n role: 'TanStack Specialist',\n responsibilities: ['Router setup', 'Query patterns', 'SSR configuration'],\n },\n {\n id: 'ux-ui-designer',\n role: 'UI/UX Design',\n responsibilities: ['Component styling', 'Accessibility', 'Design system'],\n },\n ],\n skills: [\n { id: 'web-app-testing', purpose: 'React Testing Library patterns' },\n { id: 'shadcn-specialist', purpose: 'Shadcn UI component usage' },\n { id: 'accessibility-audit', purpose: 'WCAG compliance' },\n { id: 'tanstack-query-patterns', purpose: 'Query/mutation patterns' },\n { id: 'react-hook-form-patterns', purpose: 'Form validation patterns' },\n { id: 'zustand-patterns', purpose: 'Client state management' },\n ],\n commands: [],\n docs: [{ id: 'design-standards', topic: 'UI/UX design standards' }],\n },\n modules: [\n { id: 'react-senior-dev', category: 'agents' },\n { id: 'tanstack-start-engineer', category: 'agents' },\n { id: 'ux-ui-designer', category: 'agents' },\n { id: 'web-app-testing', category: 'skills' },\n { id: 'shadcn-specialist', category: 'skills' },\n { id: 'accessibility-audit', category: 'skills' },\n { id: 'tanstack-query-patterns', category: 'skills' },\n { id: 'react-hook-form-patterns', category: 'skills' },\n { id: 'zustand-patterns', category: 'skills', optional: true },\n { id: 'design-standards', category: 'docs', requiredBy: ['ux-ui-designer'], optional: true },\n ],\n },\n {\n id: 'astro-react-stack',\n name: 'Astro + React Stack',\n description: 'Astro with React islands for content-focused websites',\n category: 'stack',\n longDescription:\n 'Stack for building fast, content-focused websites with Astro and React components. Perfect for marketing sites, blogs, and documentation sites.',\n techStack: ['Astro', 'React', 'Tailwind CSS', 'MDX', 'TypeScript'],\n tags: ['astro', 'react', 'ssg', 'content'],\n complexity: 'standard',\n responsibilities: [\n 'Static site generation with Astro',\n 'Interactive React islands for dynamic content',\n 'SEO optimization and meta tags',\n 'Performance-first architecture',\n 'Content management with MDX',\n ],\n scope: 'Content-focused websites with selective interactivity',\n useCases: [\n 'Marketing and landing pages',\n 'Documentation sites',\n 'Blogs and content platforms',\n 'Portfolio websites',\n ],\n moduleDetails: {\n agents: [\n {\n id: 'astro-engineer',\n role: 'Astro Specialist',\n responsibilities: ['Routing', 'Islands architecture', 'Build optimization'],\n },\n {\n id: 'react-senior-dev',\n role: 'React Components',\n responsibilities: ['Interactive components', 'Client hydration'],\n },\n {\n id: 'seo-ai-specialist',\n role: 'SEO Optimization',\n responsibilities: ['Meta tags', 'Structured data', 'Performance'],\n },\n ],\n skills: [\n { id: 'web-app-testing', purpose: 'Component testing' },\n { id: 'vercel-specialist', purpose: 'Deployment optimization' },\n { id: 'performance-audit', purpose: 'Core Web Vitals' },\n ],\n commands: [],\n docs: [],\n },\n modules: [\n { id: 'astro-engineer', category: 'agents' },\n { id: 'react-senior-dev', category: 'agents' },\n { id: 'seo-ai-specialist', category: 'agents' },\n { id: 'web-app-testing', category: 'skills' },\n { id: 'vercel-specialist', category: 'skills' },\n { id: 'performance-audit', category: 'skills' },\n ],\n },\n {\n id: 'nextjs-prisma-stack',\n name: 'Next.js + Prisma Stack',\n description: 'Full-stack Next.js with Prisma for modern web apps',\n category: 'stack',\n longDescription:\n 'Complete full-stack setup with Next.js App Router and Prisma ORM. Includes React components, Server Actions, and database patterns.',\n techStack: ['Next.js', 'React', 'Prisma', 'Tailwind CSS', 'TypeScript'],\n tags: ['nextjs', 'prisma', 'fullstack', 'react'],\n complexity: 'comprehensive',\n alternativeTo: ['react-tanstack-stack', 'astro-react-stack'],\n responsibilities: [\n 'Full-stack React with Next.js App Router',\n 'Database modeling with Prisma ORM',\n 'Server Actions and API routes',\n 'Authentication with NextAuth.js',\n 'Deployment on Vercel',\n ],\n scope: 'Complete full-stack web application development',\n useCases: [\n 'SaaS applications',\n 'E-commerce platforms',\n 'Full-stack web apps with auth',\n 'Projects needing SSR/SSG flexibility',\n ],\n moduleDetails: {\n agents: [\n {\n id: 'nextjs-engineer',\n role: 'Next.js Specialist',\n responsibilities: ['App Router', 'Server Actions', 'Caching strategies'],\n },\n {\n id: 'react-senior-dev',\n role: 'React Components',\n responsibilities: ['Client components', 'State management'],\n },\n {\n id: 'prisma-engineer',\n role: 'Database',\n responsibilities: ['Schema design', 'Migrations', 'Query optimization'],\n },\n {\n id: 'ux-ui-designer',\n role: 'UI/UX',\n responsibilities: ['Design system', 'Responsive design'],\n },\n ],\n skills: [\n { id: 'web-app-testing', purpose: 'Next.js testing patterns' },\n { id: 'shadcn-specialist', purpose: 'UI components' },\n { id: 'vercel-specialist', purpose: 'Deployment' },\n { id: 'tanstack-query-patterns', purpose: 'Client data fetching' },\n { id: 'react-hook-form-patterns', purpose: 'Form handling' },\n { id: 'nextauth-patterns', purpose: 'Authentication' },\n ],\n commands: [],\n docs: [],\n },\n modules: [\n { id: 'nextjs-engineer', category: 'agents' },\n { id: 'react-senior-dev', category: 'agents' },\n { id: 'prisma-engineer', category: 'agents' },\n { id: 'ux-ui-designer', category: 'agents' },\n { id: 'web-app-testing', category: 'skills' },\n { id: 'shadcn-specialist', category: 'skills' },\n { id: 'vercel-specialist', category: 'skills' },\n { id: 'tanstack-query-patterns', category: 'skills' },\n { id: 'react-hook-form-patterns', category: 'skills' },\n { id: 'nextauth-patterns', category: 'skills', optional: true },\n ],\n },\n {\n id: 'express-prisma-stack',\n name: 'Express + Prisma API Stack',\n description: 'Express backend with Prisma ORM',\n category: 'stack',\n longDescription:\n 'Backend stack using Express for APIs and Prisma for database access. Classic, well-documented stack for traditional REST APIs.',\n techStack: ['Express.js', 'Prisma', 'PostgreSQL', 'Zod', 'TypeScript'],\n tags: ['express', 'prisma', 'api', 'backend'],\n complexity: 'standard',\n alternativeTo: ['hono-drizzle-stack'],\n responsibilities: [\n 'RESTful API design with Express',\n 'Database access with Prisma ORM',\n 'Request validation with Zod',\n 'Error handling and logging',\n 'Authentication middleware',\n ],\n scope: 'Backend API development with traditional Express patterns',\n useCases: [\n 'REST APIs for mobile apps',\n 'Backend services for SPAs',\n 'Microservices',\n 'Projects needing Express ecosystem',\n ],\n moduleDetails: {\n agents: [\n {\n id: 'express-engineer',\n role: 'Express Specialist',\n responsibilities: ['Route design', 'Middleware', 'Error handling'],\n },\n {\n id: 'prisma-engineer',\n role: 'Database',\n responsibilities: ['Schema', 'Migrations', 'Queries'],\n },\n {\n id: 'node-typescript-engineer',\n role: 'Node.js/TypeScript',\n responsibilities: ['Type safety', 'Build config', 'Shared packages'],\n },\n ],\n skills: [\n { id: 'api-app-testing', purpose: 'API testing with supertest' },\n { id: 'error-handling-patterns', purpose: 'Error middleware' },\n { id: 'security-testing', purpose: 'Security best practices' },\n ],\n commands: [],\n docs: [{ id: 'architecture-patterns', topic: 'API architecture patterns' }],\n },\n modules: [\n { id: 'express-engineer', category: 'agents' },\n { id: 'prisma-engineer', category: 'agents' },\n { id: 'node-typescript-engineer', category: 'agents' },\n { id: 'api-app-testing', category: 'skills' },\n { id: 'error-handling-patterns', category: 'skills' },\n { id: 'security-testing', category: 'skills' },\n { id: 'architecture-patterns', category: 'docs', optional: true },\n ],\n },\n {\n id: 'hono-drizzle-stack',\n name: 'Hono + Drizzle API Stack',\n description: 'Hono API framework with Drizzle ORM for type-safe backends',\n category: 'stack',\n longDescription:\n 'Complete backend stack using Hono for APIs and Drizzle for database access. Includes shared TypeScript packages, API testing, and quality tools.',\n techStack: ['Hono', 'Drizzle ORM', 'PostgreSQL', 'Zod', 'TypeScript'],\n tags: ['hono', 'drizzle', 'api', 'backend'],\n complexity: 'standard',\n alternativeTo: ['express-prisma-stack'],\n responsibilities: [\n 'High-performance APIs with Hono',\n 'Type-safe database queries with Drizzle',\n 'Schema validation with Zod',\n 'Edge-ready deployment',\n 'Monorepo-friendly architecture',\n ],\n scope: 'Modern, type-safe backend API development',\n useCases: [\n 'Edge/serverless APIs',\n 'Type-safe monorepo backends',\n 'High-performance REST APIs',\n 'Projects prioritizing type safety',\n ],\n moduleDetails: {\n agents: [\n {\n id: 'hono-engineer',\n role: 'Hono Specialist',\n responsibilities: ['Route handlers', 'Middleware', 'OpenAPI integration'],\n },\n {\n id: 'db-drizzle-engineer',\n role: 'Drizzle Database',\n responsibilities: ['Schema design', 'Migrations', 'Type-safe queries'],\n },\n {\n id: 'node-typescript-engineer',\n role: 'TypeScript/Node',\n responsibilities: ['Type inference', 'Build setup', 'Shared types'],\n },\n ],\n skills: [\n { id: 'api-app-testing', purpose: 'Hono testing patterns' },\n { id: 'error-handling-patterns', purpose: 'Error middleware' },\n { id: 'security-testing', purpose: 'Security validation' },\n ],\n commands: [],\n docs: [{ id: 'architecture-patterns', topic: 'API architecture patterns' }],\n },\n modules: [\n { id: 'hono-engineer', category: 'agents' },\n { id: 'db-drizzle-engineer', category: 'agents' },\n { id: 'node-typescript-engineer', category: 'agents' },\n { id: 'api-app-testing', category: 'skills' },\n { id: 'error-handling-patterns', category: 'skills' },\n { id: 'security-testing', category: 'skills' },\n { id: 'architecture-patterns', category: 'docs', optional: true },\n ],\n },\n\n // ===================\n // TESTING BUNDLES\n // ===================\n {\n id: 'testing-complete',\n name: 'Complete Testing Suite',\n description: 'All testing skills and QA tools for comprehensive test coverage',\n category: 'testing',\n longDescription:\n 'Everything you need for a robust testing strategy including TDD methodology, web testing, API testing, performance testing, and QA validation.',\n techStack: ['Vitest', 'Playwright', 'Testing Library', 'MSW'],\n tags: ['testing', 'tdd', 'qa', 'e2e'],\n complexity: 'comprehensive',\n responsibilities: [\n 'TDD workflow enforcement (Red-Green-Refactor)',\n 'Unit, integration, and E2E testing patterns',\n 'API testing with mocking and fixtures',\n 'Performance testing and benchmarking',\n 'QA validation and acceptance criteria',\n ],\n scope: 'Complete testing strategy from unit tests to E2E',\n useCases: [\n 'Projects requiring 90%+ test coverage',\n 'TDD-first development workflow',\n 'API-heavy applications needing thorough testing',\n 'Projects with QA validation requirements',\n ],\n moduleDetails: {\n agents: [\n {\n id: 'qa-engineer',\n role: 'Quality Assurance',\n responsibilities: [\n 'Test planning and strategy',\n 'Acceptance criteria validation',\n 'Bug triage and reporting',\n ],\n },\n ],\n skills: [\n { id: 'tdd-methodology', purpose: 'TDD workflow and best practices' },\n { id: 'web-app-testing', purpose: 'Frontend testing patterns' },\n { id: 'api-app-testing', purpose: 'API and backend testing' },\n { id: 'performance-testing', purpose: 'Performance benchmarks' },\n { id: 'qa-criteria-validator', purpose: 'Acceptance validation' },\n ],\n commands: [{ id: 'run-tests', usage: '/run-tests --coverage' }],\n docs: [{ id: 'testing-standards', topic: 'Testing conventions and standards' }],\n },\n modules: [\n { id: 'qa-engineer', category: 'agents' },\n { id: 'tdd-methodology', category: 'skills' },\n { id: 'web-app-testing', category: 'skills' },\n { id: 'api-app-testing', category: 'skills' },\n { id: 'performance-testing', category: 'skills' },\n { id: 'qa-criteria-validator', category: 'skills' },\n { id: 'run-tests', category: 'commands' },\n // Doc required by QA agent and TDD skill\n { id: 'testing-standards', category: 'docs', requiredBy: ['qa-engineer', 'tdd-methodology'] },\n ],\n },\n {\n id: 'testing-minimal',\n name: 'Minimal Testing',\n description: 'Essential testing tools for TDD workflow',\n category: 'testing',\n longDescription: 'Core testing tools for TDD development without the full QA suite.',\n techStack: ['Vitest', 'Testing Library'],\n tags: ['testing', 'tdd', 'minimal'],\n complexity: 'minimal',\n responsibilities: [\n 'Basic TDD workflow support',\n 'Unit and integration testing',\n 'Test execution and reporting',\n ],\n scope: 'Essential testing for small to medium projects',\n useCases: [\n 'Small projects with basic testing needs',\n 'Quick prototypes needing some test coverage',\n 'Projects where full QA suite is overkill',\n ],\n moduleDetails: {\n agents: [],\n skills: [\n { id: 'tdd-methodology', purpose: 'TDD workflow basics' },\n { id: 'api-app-testing', purpose: 'API testing patterns' },\n ],\n commands: [{ id: 'run-tests', usage: '/run-tests' }],\n docs: [],\n },\n modules: [\n { id: 'tdd-methodology', category: 'skills' },\n { id: 'api-app-testing', category: 'skills' },\n { id: 'run-tests', category: 'commands' },\n ],\n },\n\n // ===================\n // QUALITY BUNDLES\n // ===================\n {\n id: 'quality-complete',\n name: 'Complete Quality Suite',\n description: 'Full quality assurance with security, performance, and accessibility audits',\n category: 'quality',\n longDescription:\n 'Comprehensive quality assurance bundle including all audit types, code review, and debugging tools.',\n tags: ['quality', 'audit', 'security', 'performance'],\n complexity: 'comprehensive',\n responsibilities: [\n 'Security vulnerability detection and prevention',\n 'Performance profiling and optimization guidance',\n 'Accessibility compliance (WCAG) validation',\n 'Code quality review and best practices',\n 'Bug investigation and debugging assistance',\n ],\n scope: 'Complete quality assurance across security, performance, and accessibility',\n useCases: [\n 'Enterprise applications with strict security requirements',\n 'Public-facing apps needing accessibility compliance',\n 'Performance-critical applications',\n 'Projects requiring comprehensive code reviews',\n ],\n moduleDetails: {\n agents: [\n {\n id: 'qa-engineer',\n role: 'Quality Assurance Lead',\n responsibilities: [\n 'Test strategy and coverage',\n 'Acceptance criteria validation',\n 'Quality metrics tracking',\n ],\n },\n {\n id: 'debugger',\n role: 'Debug Specialist',\n responsibilities: ['Root cause analysis', 'Bug reproduction', 'Fix verification'],\n },\n ],\n skills: [\n { id: 'security-audit', purpose: 'OWASP vulnerability scanning' },\n { id: 'security-testing', purpose: 'Security test patterns' },\n { id: 'performance-audit', purpose: 'Performance bottleneck detection' },\n { id: 'performance-testing', purpose: 'Load and stress testing' },\n { id: 'accessibility-audit', purpose: 'WCAG compliance checking' },\n { id: 'qa-criteria-validator', purpose: 'Acceptance criteria validation' },\n ],\n commands: [\n { id: 'quality-check', usage: '/quality-check' },\n { id: 'code-check', usage: '/code-check src/' },\n { id: 'review-code', usage: '/review-code --thorough' },\n { id: 'review-security', usage: '/review-security' },\n { id: 'review-performance', usage: '/review-performance' },\n ],\n docs: [\n { id: 'code-standards', topic: 'Code quality standards' },\n { id: 'atomic-commits', topic: 'Atomic commit practices' },\n ],\n },\n modules: [\n { id: 'qa-engineer', category: 'agents' },\n { id: 'debugger', category: 'agents' },\n { id: 'security-audit', category: 'skills' },\n { id: 'security-testing', category: 'skills' },\n { id: 'performance-audit', category: 'skills' },\n { id: 'performance-testing', category: 'skills' },\n { id: 'accessibility-audit', category: 'skills' },\n { id: 'qa-criteria-validator', category: 'skills' },\n { id: 'quality-check', category: 'commands' },\n { id: 'code-check', category: 'commands' },\n { id: 'review-code', category: 'commands' },\n { id: 'review-security', category: 'commands' },\n { id: 'review-performance', category: 'commands' },\n // Docs required by agents\n { id: 'code-standards', category: 'docs', requiredBy: ['qa-engineer'] },\n { id: 'atomic-commits', category: 'docs', optional: true },\n ],\n },\n {\n id: 'quality-minimal',\n name: 'Minimal Quality',\n description: 'Essential quality checks for everyday development',\n category: 'quality',\n longDescription: 'Core quality tools without the full audit suite.',\n tags: ['quality', 'minimal'],\n complexity: 'minimal',\n responsibilities: [\n 'Basic code quality checks',\n 'Quick code reviews',\n 'Lint and format validation',\n ],\n scope: 'Essential quality checks for day-to-day development',\n useCases: [\n 'Small projects with basic quality needs',\n 'Quick PRs needing fast review',\n 'Projects where full audits are overkill',\n ],\n moduleDetails: {\n agents: [],\n skills: [],\n commands: [\n { id: 'quality-check', usage: '/quality-check' },\n { id: 'code-check', usage: '/code-check' },\n { id: 'review-code', usage: '/review-code' },\n ],\n docs: [],\n },\n modules: [\n { id: 'quality-check', category: 'commands' },\n { id: 'code-check', category: 'commands' },\n { id: 'review-code', category: 'commands' },\n ],\n },\n\n // ===================\n // DATABASE BUNDLES\n // ===================\n {\n id: 'drizzle-database',\n name: 'Drizzle Database',\n description: 'Drizzle ORM with type-safe database patterns',\n category: 'database',\n longDescription:\n 'Database development with Drizzle ORM including schema design, migrations, and data validation.',\n techStack: ['Drizzle ORM', 'PostgreSQL', 'SQLite', 'Zod'],\n tags: ['database', 'drizzle', 'orm'],\n alternativeTo: ['prisma-database', 'mongoose-database'],\n modules: [\n { id: 'db-drizzle-engineer', category: 'agents' },\n { id: 'json-data-auditor', category: 'skills' },\n ],\n },\n {\n id: 'prisma-database',\n name: 'Prisma Database',\n description: 'Prisma ORM with type-safe database patterns',\n category: 'database',\n longDescription:\n 'Database development with Prisma ORM including schema design, migrations, and data validation.',\n techStack: ['Prisma', 'PostgreSQL', 'MySQL', 'SQLite', 'MongoDB'],\n tags: ['database', 'prisma', 'orm'],\n alternativeTo: ['drizzle-database', 'mongoose-database'],\n modules: [\n { id: 'prisma-engineer', category: 'agents' },\n { id: 'json-data-auditor', category: 'skills' },\n ],\n },\n {\n id: 'mongoose-database',\n name: 'MongoDB + Mongoose',\n description: 'MongoDB with Mongoose ODM',\n category: 'database',\n longDescription:\n 'MongoDB development with Mongoose ODM including document schemas and aggregation pipelines.',\n techStack: ['Mongoose', 'MongoDB', 'TypeScript'],\n tags: ['database', 'mongodb', 'mongoose', 'nosql'],\n alternativeTo: ['drizzle-database', 'prisma-database'],\n modules: [\n { id: 'mongoose-engineer', category: 'agents' },\n { id: 'json-data-auditor', category: 'skills' },\n ],\n },\n\n // ===================\n // API BUNDLES\n // ===================\n {\n id: 'hono-api',\n name: 'Hono API',\n description: 'Hono framework for high-performance APIs',\n category: 'api',\n longDescription:\n 'API development with Hono framework including middleware, validation, and error handling.',\n techStack: ['Hono', 'Zod', 'TypeScript'],\n tags: ['api', 'hono', 'backend'],\n alternativeTo: ['express-api', 'fastify-api', 'nestjs-api'],\n modules: [\n { id: 'hono-engineer', category: 'agents' },\n { id: 'api-app-testing', category: 'skills' },\n { id: 'error-handling-patterns', category: 'skills' },\n ],\n },\n {\n id: 'express-api',\n name: 'Express API',\n description: 'Express.js framework for REST APIs',\n category: 'api',\n longDescription:\n 'API development with Express.js including middleware chains, validation, and error handling.',\n techStack: ['Express.js', 'Zod', 'TypeScript', 'Passport.js'],\n tags: ['api', 'express', 'backend'],\n alternativeTo: ['hono-api', 'fastify-api', 'nestjs-api'],\n modules: [\n { id: 'express-engineer', category: 'agents' },\n { id: 'api-app-testing', category: 'skills' },\n { id: 'error-handling-patterns', category: 'skills' },\n ],\n },\n {\n id: 'fastify-api',\n name: 'Fastify API',\n description: 'Fastify framework for high-performance APIs',\n category: 'api',\n longDescription:\n 'High-performance API development with Fastify plugin architecture and schema validation.',\n techStack: ['Fastify', 'TypeBox', 'TypeScript', 'Pino'],\n tags: ['api', 'fastify', 'backend', 'performance'],\n alternativeTo: ['hono-api', 'express-api', 'nestjs-api'],\n modules: [\n { id: 'fastify-engineer', category: 'agents' },\n { id: 'api-app-testing', category: 'skills' },\n { id: 'error-handling-patterns', category: 'skills' },\n ],\n },\n {\n id: 'nestjs-api',\n name: 'NestJS API',\n description: 'NestJS framework for enterprise APIs',\n category: 'api',\n longDescription:\n 'Enterprise API development with NestJS dependency injection and modular architecture.',\n techStack: ['NestJS', 'TypeScript', 'class-validator', 'TypeORM'],\n tags: ['api', 'nestjs', 'backend', 'enterprise'],\n alternativeTo: ['hono-api', 'express-api', 'fastify-api'],\n modules: [\n { id: 'nestjs-engineer', category: 'agents' },\n { id: 'api-app-testing', category: 'skills' },\n { id: 'error-handling-patterns', category: 'skills' },\n ],\n },\n\n // ===================\n // FRONTEND BUNDLES\n // ===================\n {\n id: 'react-ui',\n name: 'React UI Development',\n description: 'React component development with Shadcn UI',\n category: 'frontend',\n longDescription:\n 'React component development bundle with Shadcn UI, accessibility, and design system tools.',\n techStack: ['React', 'Shadcn UI', 'Tailwind CSS', 'Radix UI'],\n tags: ['react', 'ui', 'components'],\n modules: [\n { id: 'react-senior-dev', category: 'agents' },\n { id: 'ux-ui-designer', category: 'agents' },\n { id: 'shadcn-specialist', category: 'skills' },\n { id: 'brand-guidelines', category: 'skills' },\n { id: 'accessibility-audit', category: 'skills' },\n ],\n },\n {\n id: 'react-forms',\n name: 'React Forms',\n description: 'React Hook Form with Zod validation',\n category: 'frontend',\n longDescription:\n 'Form handling patterns with React Hook Form and Zod validation. Includes Shadcn form integration.',\n techStack: ['React Hook Form', 'Zod', 'React', 'TypeScript'],\n tags: ['react', 'forms', 'validation'],\n modules: [\n { id: 'react-senior-dev', category: 'agents' },\n { id: 'react-hook-form-patterns', category: 'skills' },\n { id: 'shadcn-specialist', category: 'skills' },\n ],\n },\n {\n id: 'react-state-zustand',\n name: 'React State (Zustand)',\n description: 'Zustand for lightweight state management',\n category: 'frontend',\n longDescription:\n 'State management with Zustand including slices, persist middleware, and TanStack Query integration.',\n techStack: ['Zustand', 'TanStack Query', 'React', 'TypeScript'],\n tags: ['react', 'state', 'zustand'],\n alternativeTo: ['react-state-redux'],\n modules: [\n { id: 'react-senior-dev', category: 'agents' },\n { id: 'zustand-patterns', category: 'skills' },\n { id: 'tanstack-query-patterns', category: 'skills' },\n ],\n },\n {\n id: 'react-state-redux',\n name: 'React State (Redux)',\n description: 'Redux Toolkit for complex state management',\n category: 'frontend',\n longDescription:\n 'State management with Redux Toolkit including RTK Query, async thunks, and enterprise patterns.',\n techStack: ['Redux Toolkit', 'RTK Query', 'React', 'TypeScript'],\n tags: ['react', 'state', 'redux'],\n alternativeTo: ['react-state-zustand'],\n modules: [\n { id: 'react-senior-dev', category: 'agents' },\n { id: 'redux-toolkit-patterns', category: 'skills' },\n { id: 'tanstack-query-patterns', category: 'skills', optional: true },\n ],\n },\n {\n id: 'nextjs-auth',\n name: 'Next.js Authentication',\n description: 'NextAuth.js authentication for Next.js apps',\n category: 'frontend',\n longDescription:\n 'Authentication patterns with NextAuth.js including OAuth providers, credentials, sessions, and RBAC.',\n techStack: ['NextAuth.js', 'Auth.js', 'Next.js', 'Prisma'],\n tags: ['nextjs', 'auth', 'oauth'],\n modules: [\n { id: 'nextjs-engineer', category: 'agents' },\n { id: 'nextauth-patterns', category: 'skills' },\n { id: 'security-testing', category: 'skills' },\n ],\n },\n {\n id: 'nextjs-i18n',\n name: 'Next.js Internationalization',\n description: 'Multi-language support for Next.js apps',\n category: 'frontend',\n longDescription:\n 'Internationalization with next-intl including locale routing, translations, and formatting.',\n techStack: ['next-intl', 'Next.js', 'React', 'TypeScript'],\n tags: ['nextjs', 'i18n', 'internationalization'],\n modules: [\n { id: 'nextjs-engineer', category: 'agents' },\n { id: 'i18n-specialist', category: 'agents', optional: true },\n { id: 'i18n-patterns', category: 'skills' },\n ],\n },\n\n // ===================\n // WORKFLOW BUNDLES\n // ===================\n {\n id: 'planning-complete',\n name: 'Complete Planning Workflow',\n description: 'Full planning workflow with PDR, tech analysis, and task tracking',\n category: 'workflow',\n longDescription:\n 'Complete planning workflow bundle including product definition, technical analysis, task breakdown, and sync to issue trackers.',\n tags: ['planning', 'workflow', 'pdr'],\n complexity: 'comprehensive',\n responsibilities: [\n 'Feature planning from requirements to implementation tasks',\n 'Technical analysis and architecture decision documentation',\n 'Task breakdown with atomic task methodology',\n 'Integration with issue trackers (GitHub, Linear)',\n ],\n scope: 'End-to-end planning workflow for features, refactors, and epics',\n useCases: [\n 'Starting a new feature from scratch',\n 'Planning a major refactor or migration',\n 'Breaking down epics into manageable tasks',\n 'Documenting technical decisions (ADRs)',\n ],\n moduleDetails: {\n agents: [\n {\n id: 'product-functional',\n role: 'Product Requirements',\n responsibilities: [\n 'Create PDR documents',\n 'Define acceptance criteria',\n 'User story mapping',\n ],\n },\n {\n id: 'product-technical',\n role: 'Technical Analysis',\n responsibilities: ['Architecture decisions', 'Tech stack evaluation', 'Risk assessment'],\n },\n {\n id: 'tech-lead',\n role: 'Coordination & Task Breakdown',\n responsibilities: ['Task atomization', 'Workflow selection', 'Team coordination'],\n },\n ],\n skills: [],\n commands: [\n { id: 'start-feature-plan', usage: '/start-feature-plan \"User authentication\"' },\n { id: 'start-refactor-plan', usage: '/start-refactor-plan \"Database optimization\"' },\n { id: 'sync-planning', usage: '/sync-planning' },\n ],\n docs: [\n { id: 'decision-tree', topic: 'Workflow selection guide' },\n { id: 'phase-1-planning', topic: 'Planning phase methodology' },\n { id: 'phase-2-implementation', topic: 'Implementation phase guide' },\n { id: 'phase-3-validation', topic: 'Validation and QA phase' },\n { id: 'phase-4-finalization', topic: 'Closing and documentation' },\n { id: 'pdr-template', topic: 'Product Definition Record template' },\n { id: 'tech-analysis-template', topic: 'Technical analysis template' },\n { id: 'todos-template', topic: 'Task tracking template' },\n ],\n },\n modules: [\n { id: 'product-functional', category: 'agents' },\n { id: 'product-technical', category: 'agents' },\n { id: 'tech-lead', category: 'agents' },\n { id: 'start-feature-plan', category: 'commands' },\n { id: 'start-refactor-plan', category: 'commands' },\n { id: 'sync-planning', category: 'commands' },\n // Required docs - needed for agents to work properly\n { id: 'decision-tree', category: 'docs', requiredBy: ['tech-lead'] },\n {\n id: 'phase-1-planning',\n category: 'docs',\n requiredBy: ['product-functional', 'product-technical'],\n },\n { id: 'phase-2-implementation', category: 'docs', requiredBy: ['tech-lead'] },\n { id: 'phase-3-validation', category: 'docs' },\n { id: 'phase-4-finalization', category: 'docs' },\n { id: 'pdr-template', category: 'docs', requiredBy: ['product-functional'] },\n { id: 'tech-analysis-template', category: 'docs', requiredBy: ['product-technical'] },\n { id: 'todos-template', category: 'docs', requiredBy: ['tech-lead'] },\n ],\n },\n {\n id: 'documentation-complete',\n name: 'Complete Documentation',\n description: 'All documentation standards, templates, and writing tools',\n category: 'workflow',\n longDescription:\n 'Everything for comprehensive documentation including standards, templates, diagrams, and writing guidelines.',\n tags: ['documentation', 'writing', 'standards'],\n complexity: 'standard',\n responsibilities: [\n 'Technical documentation writing',\n 'API documentation generation',\n 'Architecture diagram creation',\n 'Markdown formatting and standards',\n 'Glossary and terminology management',\n ],\n scope: 'Complete documentation workflow for technical projects',\n useCases: [\n 'Creating and maintaining project documentation',\n 'Writing API and SDK documentation',\n 'Creating architecture diagrams',\n 'Standardizing documentation across team',\n ],\n moduleDetails: {\n agents: [\n {\n id: 'tech-writer',\n role: 'Technical Writer',\n responsibilities: ['Documentation structure', 'Content writing', 'Style consistency'],\n },\n ],\n skills: [\n { id: 'documentation-writer', purpose: 'Documentation best practices' },\n { id: 'mermaid-diagram-specialist', purpose: 'Diagram creation' },\n ],\n commands: [\n { id: 'update-docs', usage: '/update-docs' },\n { id: 'markdown-format', usage: '/markdown-format' },\n ],\n docs: [\n { id: 'documentation-standards', topic: 'Documentation conventions' },\n { id: 'workflow-diagrams', topic: 'Diagram templates' },\n { id: 'glossary', topic: 'Project terminology' },\n ],\n },\n modules: [\n { id: 'tech-writer', category: 'agents' },\n { id: 'documentation-writer', category: 'skills' },\n { id: 'mermaid-diagram-specialist', category: 'skills' },\n { id: 'update-docs', category: 'commands' },\n { id: 'markdown-format', category: 'commands' },\n { id: 'documentation-standards', category: 'docs', requiredBy: ['tech-writer'] },\n { id: 'workflow-diagrams', category: 'docs', optional: true },\n { id: 'glossary', category: 'docs', optional: true },\n ],\n },\n {\n id: 'git-workflow',\n name: 'Git Workflow',\n description: 'Git commit conventions and atomic commit practices',\n category: 'workflow',\n longDescription: 'Git workflow tools including conventional commits and atomic commit helpers.',\n tags: ['git', 'commits', 'workflow'],\n complexity: 'minimal',\n responsibilities: [\n 'Conventional commit message formatting',\n 'Atomic commit enforcement',\n 'Commit message generation',\n ],\n scope: 'Git commit workflow and conventions',\n useCases: [\n 'Enforcing commit message standards',\n 'Generating semantic commit messages',\n 'Following atomic commit practices',\n ],\n moduleDetails: {\n agents: [],\n skills: [{ id: 'git-commit-helper', purpose: 'Commit message patterns' }],\n commands: [{ id: 'commit', usage: '/commit' }],\n docs: [{ id: 'atomic-commits', topic: 'Atomic commit guidelines' }],\n },\n modules: [\n { id: 'git-commit-helper', category: 'skills' },\n { id: 'commit', category: 'commands' },\n { id: 'atomic-commits', category: 'docs', optional: true },\n ],\n },\n {\n id: 'cicd-github-actions',\n name: 'GitHub Actions CI/CD',\n description: 'GitHub Actions workflows for CI/CD automation',\n category: 'workflow',\n longDescription:\n 'Complete CI/CD setup with GitHub Actions including testing, quality checks, security scanning, and deployment workflows.',\n techStack: ['GitHub Actions', 'Node.js', 'PNPM'],\n tags: ['cicd', 'github', 'automation', 'devops'],\n complexity: 'standard',\n responsibilities: [\n 'Continuous Integration workflows',\n 'Automated testing on PRs',\n 'Code quality checks',\n 'Security scanning',\n 'Deployment automation',\n ],\n scope: 'CI/CD pipeline automation with GitHub Actions',\n useCases: [\n 'Automating test runs on PRs',\n 'Automated deployments to staging/production',\n 'Code quality gates',\n 'Security vulnerability scanning',\n ],\n moduleDetails: {\n agents: [],\n skills: [{ id: 'github-actions-specialist', purpose: 'GitHub Actions workflow patterns' }],\n commands: [],\n docs: [{ id: 'cicd-workflows', topic: 'CI/CD workflow documentation' }],\n },\n modules: [\n { id: 'github-actions-specialist', category: 'skills', optional: true },\n { id: 'cicd-workflows', category: 'docs', optional: true },\n ],\n },\n];\n\n/**\n * Get all bundles\n */\nexport function getAllBundles(): BundleDefinition[] {\n return BUNDLES;\n}\n\n/**\n * Get bundles by category\n */\nexport function getBundlesByCategory(category: string): BundleDefinition[] {\n return BUNDLES.filter((b) => b.category === category);\n}\n\n/**\n * Get bundle by ID\n */\nexport function getBundleById(id: string): BundleDefinition | undefined {\n return BUNDLES.find((b) => b.id === id);\n}\n\n/**\n * Get bundles grouped by category\n */\nexport function getBundlesGroupedByCategory(): Record<string, BundleDefinition[]> {\n const grouped: Record<string, BundleDefinition[]> = {};\n\n for (const bundle of BUNDLES) {\n if (!grouped[bundle.category]) {\n grouped[bundle.category] = [];\n }\n grouped[bundle.category].push(bundle);\n }\n\n return grouped;\n}\n\n/**\n * Category display names\n */\nexport const BUNDLE_CATEGORY_NAMES: Record<string, string> = {\n stack: 'Tech Stacks',\n testing: 'Testing',\n quality: 'Quality Assurance',\n database: 'Database',\n api: 'API Frameworks',\n frontend: 'Frontend',\n workflow: 'Workflows',\n cicd: 'CI/CD & DevOps',\n};\n","/**\n * MCP Server definitions\n * Only includes verified, real npm packages\n */\n\nimport type { McpServerDefinition } from '../types/mcp.js';\n\n/**\n * Available MCP servers - all packages verified to exist on npm\n */\nexport const MCP_SERVERS: McpServerDefinition[] = [\n // ============================================\n // DOCUMENTATION & AI TOOLS\n // ============================================\n {\n id: 'context7',\n name: 'Context7',\n description: 'Up-to-date documentation lookup for libraries and frameworks',\n package: '@upstash/context7-mcp',\n category: 'documentation',\n requiresConfig: false,\n installInstructions:\n 'API keys provide higher rate limits. Get one at https://context7.com/dashboard',\n },\n {\n id: 'perplexity',\n name: 'Perplexity',\n description: 'Web search without leaving the MCP ecosystem via Sonar API',\n package: '@chatmcp/server-perplexity-ask',\n category: 'search',\n requiresConfig: true,\n configFields: [\n {\n name: 'apiKey',\n type: 'string',\n required: true,\n description: 'Perplexity/Sonar API Key',\n envVar: 'PERPLEXITY_API_KEY',\n },\n ],\n installInstructions: 'Get API key at https://www.perplexity.ai/settings/api',\n },\n {\n id: 'sequential-thinking',\n name: 'Sequential Thinking',\n description: 'Dynamic problem-solving through structured thinking process',\n package: '@modelcontextprotocol/server-sequential-thinking',\n category: 'ai',\n requiresConfig: false,\n installInstructions: 'Helps break down complex problems into manageable steps.',\n },\n\n // ============================================\n // TESTING & BROWSER AUTOMATION\n // ============================================\n {\n id: 'puppeteer',\n name: 'Puppeteer',\n description: 'Headless Chrome automation for testing and scraping',\n package: '@modelcontextprotocol/server-puppeteer',\n category: 'testing',\n requiresConfig: false,\n },\n {\n id: 'playwright',\n name: 'Playwright',\n description: 'Browser automation via accessibility snapshots, not screenshots',\n package: '@playwright/mcp',\n category: 'testing',\n requiresConfig: false,\n installInstructions: 'Requires Node.js 18+. Supports Chrome, Firefox, WebKit.',\n },\n {\n id: 'chrome-devtools',\n name: 'Chrome DevTools',\n description: 'Control and inspect live Chrome browser with DevTools Protocol',\n package: 'chrome-devtools-mcp',\n category: 'testing',\n requiresConfig: false,\n installInstructions:\n 'Requires Chrome installed. For Claude Code: claude mcp add chrome-devtools npx chrome-devtools-mcp@latest',\n },\n\n // ============================================\n // VERSION CONTROL\n // ============================================\n {\n id: 'github',\n name: 'GitHub',\n description: 'GitHub API integration (issues, PRs, repos, file operations)',\n package: '@modelcontextprotocol/server-github',\n category: 'version-control',\n requiresConfig: true,\n configFields: [\n {\n name: 'token',\n type: 'string',\n required: false,\n description: 'GitHub Personal Access Token',\n envVar: 'GITHUB_TOKEN',\n },\n ],\n installInstructions:\n 'Create a Personal Access Token at https://github.com/settings/tokens with repo scope.',\n },\n {\n id: 'gitlab',\n name: 'GitLab',\n description: 'GitLab API for project management, issues, and merge requests',\n package: '@modelcontextprotocol/server-gitlab',\n category: 'version-control',\n requiresConfig: true,\n configFields: [\n {\n name: 'token',\n type: 'string',\n required: true,\n description: 'GitLab Personal Access Token',\n envVar: 'GITLAB_PERSONAL_ACCESS_TOKEN',\n },\n {\n name: 'apiUrl',\n type: 'string',\n required: false,\n description: 'GitLab API URL (default: https://gitlab.com/api/v4)',\n envVar: 'GITLAB_API_URL',\n default: 'https://gitlab.com/api/v4',\n },\n ],\n installInstructions:\n 'Create PAT at GitLab User Settings > Access Tokens with api, read_repository, write_repository scopes.',\n },\n\n // ============================================\n // DATABASES\n // ============================================\n {\n id: 'postgres',\n name: 'PostgreSQL',\n description: 'Read-only PostgreSQL database access with schema inspection',\n package: '@modelcontextprotocol/server-postgres',\n category: 'database',\n requiresConfig: true,\n configFields: [\n {\n name: 'connectionString',\n type: 'string',\n required: false,\n description: 'PostgreSQL connection string',\n envVar: 'DATABASE_URL',\n },\n ],\n installInstructions: 'Connection string format: postgresql://user:password@host:port/database',\n },\n {\n id: 'mysql',\n name: 'MySQL',\n description: 'Read-only MySQL/MariaDB database access',\n package: '@modelcontextprotocol/server-mysql',\n category: 'database',\n requiresConfig: true,\n configFields: [\n {\n name: 'connectionString',\n type: 'string',\n required: true,\n description: 'MySQL connection URL',\n envVar: 'MYSQL_URL',\n },\n ],\n installInstructions: 'Connection format: mysql://user:password@host:port/database',\n },\n {\n id: 'neon',\n name: 'Neon',\n description: 'Neon serverless PostgreSQL with branch management',\n package: '@neondatabase/mcp-server-neon',\n category: 'database',\n requiresConfig: true,\n configFields: [\n {\n name: 'apiKey',\n type: 'string',\n required: false,\n description: 'Neon API Key',\n envVar: 'NEON_API_KEY',\n },\n ],\n installInstructions: 'Get your API key from https://console.neon.tech/app/settings/api-keys',\n },\n {\n id: 'sqlite',\n name: 'SQLite',\n description: 'SQLite database interaction and business intelligence',\n package: '@modelcontextprotocol/server-sqlite',\n category: 'database',\n requiresConfig: true,\n configFields: [\n {\n name: 'dbPath',\n type: 'string',\n required: false,\n description: 'Path to SQLite database file',\n default: './data.db',\n },\n ],\n },\n {\n id: 'supabase',\n name: 'Supabase',\n description: 'Supabase projects, database, Edge Functions, and type generation',\n package: '@supabase/mcp-server-supabase',\n category: 'database',\n requiresConfig: true,\n configFields: [\n {\n name: 'accessToken',\n type: 'string',\n required: false,\n description: 'Supabase Personal Access Token',\n envVar: 'SUPABASE_ACCESS_TOKEN',\n },\n ],\n installInstructions: 'Get your access token from https://supabase.com/dashboard/account/tokens',\n },\n\n // ============================================\n // CACHE & KEY-VALUE STORES\n // ============================================\n {\n id: 'redis',\n name: 'Redis',\n description: 'Redis key-value store operations (set, get, delete, list)',\n package: '@modelcontextprotocol/server-redis',\n category: 'cache',\n requiresConfig: true,\n configFields: [\n {\n name: 'url',\n type: 'string',\n required: false,\n description: 'Redis connection URL',\n envVar: 'REDIS_URL',\n default: 'redis://localhost:6379',\n },\n ],\n installInstructions:\n 'Pass Redis URL as argument: npx @modelcontextprotocol/server-redis redis://localhost:6379',\n },\n {\n id: 'upstash',\n name: 'Upstash',\n description: 'Upstash Redis database management and commands',\n package: '@upstash/mcp-server',\n category: 'cache',\n requiresConfig: true,\n configFields: [\n {\n name: 'email',\n type: 'string',\n required: false,\n description: 'Upstash account email',\n envVar: 'UPSTASH_EMAIL',\n },\n {\n name: 'apiKey',\n type: 'string',\n required: false,\n description: 'Upstash API Key',\n envVar: 'UPSTASH_API_KEY',\n },\n ],\n installInstructions: 'Get credentials from https://console.upstash.com',\n },\n\n // ============================================\n // DEPLOYMENT & INFRASTRUCTURE\n // ============================================\n {\n id: 'cloudflare',\n name: 'Cloudflare',\n description: 'Cloudflare Workers, D1, KV, R2, and DNS management',\n package: '@cloudflare/mcp-server-cloudflare',\n category: 'deployment',\n requiresConfig: true,\n configFields: [\n {\n name: 'accountId',\n type: 'string',\n required: false,\n description: 'Cloudflare Account ID',\n envVar: 'CLOUDFLARE_ACCOUNT_ID',\n },\n ],\n installInstructions: 'Run: npx @cloudflare/mcp-server-cloudflare init',\n },\n {\n id: 'vercel',\n name: 'Vercel',\n description: 'Vercel deployments, DNS records, and project management',\n package: 'vercel-mcp',\n category: 'deployment',\n requiresConfig: true,\n configFields: [\n {\n name: 'apiKey',\n type: 'string',\n required: true,\n description: 'Vercel API Key',\n envVar: 'VERCEL_API_KEY',\n },\n ],\n installInstructions: 'Get API key at https://vercel.com/account/tokens',\n },\n {\n id: 'filesystem',\n name: 'Filesystem',\n description: 'Secure file operations with configurable access controls',\n package: '@modelcontextprotocol/server-filesystem',\n category: 'infrastructure',\n requiresConfig: false,\n },\n {\n id: 'memory',\n name: 'Memory',\n description: 'Knowledge graph-based persistent memory system',\n package: '@modelcontextprotocol/server-memory',\n category: 'infrastructure',\n requiresConfig: false,\n installInstructions: 'Memory is stored in memory.jsonl in the server directory by default.',\n },\n\n // ============================================\n // PROJECT MANAGEMENT & PRODUCTIVITY\n // ============================================\n {\n id: 'notion',\n name: 'Notion',\n description: 'Official Notion API for pages, databases, and workspace',\n package: '@notionhq/notion-mcp-server',\n category: 'project-mgmt',\n requiresConfig: true,\n configFields: [\n {\n name: 'token',\n type: 'string',\n required: true,\n description: 'Notion Integration Token',\n envVar: 'NOTION_TOKEN',\n },\n ],\n installInstructions:\n 'Create integration at https://www.notion.so/profile/integrations and share pages with it.',\n },\n {\n id: 'obsidian',\n name: 'Obsidian',\n description: 'Read and search Obsidian vaults and Markdown directories',\n package: 'mcp-obsidian',\n category: 'project-mgmt',\n requiresConfig: true,\n configFields: [\n {\n name: 'vaultPath',\n type: 'string',\n required: true,\n description: 'Path to Obsidian vault',\n },\n ],\n installInstructions: 'Works with any Markdown directory. Point to your vault path.',\n },\n {\n id: 'n8n',\n name: 'n8n',\n description: 'n8n workflow automation node documentation and management',\n package: 'n8n-mcp',\n category: 'project-mgmt',\n requiresConfig: false,\n installInstructions: 'Provides access to 543 n8n nodes documentation.',\n },\n\n // ============================================\n // MONITORING & OBSERVABILITY\n // ============================================\n {\n id: 'sentry',\n name: 'Sentry',\n description: 'Query Sentry errors, issues, and project information',\n package: '@sentry/mcp-server',\n category: 'monitoring',\n requiresConfig: true,\n configFields: [\n {\n name: 'authToken',\n type: 'string',\n required: false,\n description: 'Sentry Auth Token',\n envVar: 'SENTRY_AUTH_TOKEN',\n },\n ],\n installInstructions:\n 'For Claude Code: claude mcp add --transport http sentry https://mcp.sentry.dev/mcp',\n },\n\n // ============================================\n // COMMUNICATION\n // ============================================\n {\n id: 'slack',\n name: 'Slack',\n description: 'Slack messaging, channels, and workspace interaction',\n package: '@modelcontextprotocol/server-slack',\n category: 'communication',\n requiresConfig: true,\n configFields: [\n {\n name: 'token',\n type: 'string',\n required: false,\n description: 'Slack Bot Token (xoxb-...)',\n envVar: 'SLACK_BOT_TOKEN',\n },\n ],\n installInstructions:\n 'Create a Slack app at https://api.slack.com/apps and install to your workspace.',\n },\n\n // ============================================\n // DESIGN\n // ============================================\n {\n id: 'figma',\n name: 'Figma',\n description: 'Figma layout information for AI coding agents',\n package: 'figma-developer-mcp',\n category: 'design',\n requiresConfig: true,\n configFields: [\n {\n name: 'apiKey',\n type: 'string',\n required: true,\n description: 'Figma Personal Access Token',\n envVar: 'FIGMA_API_KEY',\n },\n ],\n installInstructions: 'Create token at https://www.figma.com/developers/api#access-tokens',\n },\n {\n id: 'shadcn',\n name: 'shadcn/ui',\n description: 'shadcn/ui component docs, installation, and code generation',\n package: '@heilgar/shadcn-ui-mcp-server',\n category: 'ui-library',\n requiresConfig: false,\n installInstructions: 'Supports npm, pnpm, yarn, and bun package managers.',\n },\n {\n id: 'magic-ui',\n name: '21st.dev Magic',\n description: 'AI-driven UI component generation through natural language',\n package: '@21st-dev/magic',\n category: 'ui-library',\n requiresConfig: true,\n configFields: [\n {\n name: 'apiKey',\n type: 'string',\n required: true,\n description: '21st.dev Magic API Key',\n envVar: 'TWENTYFIRST_API_KEY',\n },\n ],\n installInstructions: 'Get API key at https://21st.dev/magic/console',\n },\n\n // ============================================\n // PAYMENTS\n // ============================================\n {\n id: 'stripe',\n name: 'Stripe',\n description: 'Stripe payments API with MCP support via Agent Toolkit',\n package: '@stripe/agent-toolkit',\n category: 'payments',\n requiresConfig: true,\n configFields: [\n {\n name: 'secretKey',\n type: 'string',\n required: false,\n description: 'Stripe Secret Key',\n envVar: 'STRIPE_SECRET_KEY',\n },\n ],\n installInstructions:\n 'Get API keys at https://dashboard.stripe.com/apikeys. Run: npx -y @stripe/mcp --tools=all --api-key=YOUR_KEY',\n },\n {\n id: 'mercadopago',\n name: 'Mercado Pago',\n description: 'Mercado Pago payments, refunds, and customer management',\n package: 'mercado-pago-mcp',\n category: 'payments',\n requiresConfig: true,\n configFields: [\n {\n name: 'accessToken',\n type: 'string',\n required: true,\n description: 'Mercado Pago Access Token',\n envVar: 'MERCADOPAGO_ACCESS_TOKEN',\n },\n {\n name: 'environment',\n type: 'string',\n required: false,\n description: 'Environment (sandbox or production)',\n default: 'sandbox',\n },\n ],\n installInstructions: 'Get credentials at https://www.mercadopago.com/developers/panel/app',\n },\n\n // ============================================\n // SEARCH\n // ============================================\n {\n id: 'brave-search',\n name: 'Brave Search',\n description: 'Web and local search using Brave Search API',\n package: '@modelcontextprotocol/server-brave-search',\n category: 'search',\n requiresConfig: true,\n configFields: [\n {\n name: 'apiKey',\n type: 'string',\n required: false,\n description: 'Brave Search API Key',\n envVar: 'BRAVE_API_KEY',\n },\n ],\n installInstructions: 'Get an API key at https://brave.com/search/api/',\n },\n];\n\n/**\n * Get MCP server by ID\n */\nexport function getMcpServer(id: string): McpServerDefinition | undefined {\n return MCP_SERVERS.find((s) => s.id === id);\n}\n\n/**\n * Get MCP servers by category\n */\nexport function getMcpServersByCategory(\n category: McpServerDefinition['category']\n): McpServerDefinition[] {\n return MCP_SERVERS.filter((s) => s.category === category);\n}\n\n/**\n * Get all MCP server IDs\n */\nexport function getMcpServerIds(): string[] {\n return MCP_SERVERS.map((s) => s.id);\n}\n","/**\n * System dependency definitions\n */\n\nimport type { DependencyInfo } from '../types/dependencies.js';\n\n/**\n * System dependencies required for various features\n */\nexport const DEPENDENCIES: DependencyInfo[] = [\n {\n id: 'piper-tts',\n name: 'Piper TTS',\n description: 'Text-to-speech for audio notifications',\n requiredFor: ['hook:notification:audio'],\n checkCommand: 'command -v piper',\n platforms: {\n linux: {\n commands: [\n 'pip install piper-tts',\n 'mkdir -p ~/.local/share/piper/voices',\n 'wget -O ~/.local/share/piper/voices/en_US-hfc_male-medium.onnx https://huggingface.co/rhasspy/piper-voices/resolve/main/en/en_US/hfc_male/medium/en_US-hfc_male-medium.onnx',\n 'wget -O ~/.local/share/piper/voices/en_US-hfc_male-medium.onnx.json https://huggingface.co/rhasspy/piper-voices/resolve/main/en/en_US/hfc_male/medium/en_US-hfc_male-medium.onnx.json',\n ],\n notes: 'Requires Python 3.9+ and pip',\n links: ['https://github.com/rhasspy/piper'],\n },\n macos: {\n commands: [\n 'pip3 install piper-tts',\n 'mkdir -p ~/.local/share/piper/voices',\n '# Download voice files from https://github.com/rhasspy/piper/releases',\n ],\n notes: 'May need to install portaudio: brew install portaudio',\n links: ['https://github.com/rhasspy/piper'],\n },\n },\n },\n {\n id: 'notify-send',\n name: 'libnotify',\n description: 'Desktop notifications for Linux',\n requiredFor: ['hook:notification:desktop'],\n checkCommand: 'command -v notify-send',\n platforms: {\n linux: {\n commands: [\n '# Ubuntu/Debian:',\n 'sudo apt install libnotify-bin',\n '# Fedora:',\n 'sudo dnf install libnotify',\n '# Arch:',\n 'sudo pacman -S libnotify',\n ],\n },\n },\n },\n {\n id: 'terminal-notifier',\n name: 'terminal-notifier',\n description: 'Desktop notifications for macOS',\n requiredFor: ['hook:notification:desktop'],\n checkCommand: 'command -v terminal-notifier',\n platforms: {\n macos: {\n commands: ['brew install terminal-notifier'],\n links: ['https://github.com/julienXX/terminal-notifier'],\n },\n },\n },\n {\n id: 'jq',\n name: 'jq',\n description: 'JSON processor for hook scripts',\n requiredFor: ['hooks'],\n checkCommand: 'command -v jq',\n platforms: {\n linux: {\n commands: [\n '# Ubuntu/Debian:',\n 'sudo apt install jq',\n '# Fedora:',\n 'sudo dnf install jq',\n '# Arch:',\n 'sudo pacman -S jq',\n ],\n },\n macos: {\n commands: ['brew install jq'],\n },\n windows: {\n commands: ['choco install jq', '# Or: winget install jqlang.jq'],\n },\n },\n },\n {\n id: 'aplay',\n name: 'ALSA Utils',\n description: 'Audio playback for Linux',\n requiredFor: ['hook:notification:audio'],\n checkCommand: 'command -v aplay',\n platforms: {\n linux: {\n commands: [\n '# Ubuntu/Debian:',\n 'sudo apt install alsa-utils',\n '# Fedora:',\n 'sudo dnf install alsa-utils',\n '# Arch:',\n 'sudo pacman -S alsa-utils',\n ],\n },\n },\n },\n {\n id: 'afplay',\n name: 'afplay',\n description: 'Audio playback for macOS (built-in)',\n requiredFor: ['hook:notification:audio'],\n checkCommand: 'command -v afplay',\n platforms: {\n macos: {\n commands: ['# Built-in on macOS, no installation needed'],\n notes: 'afplay is included with macOS by default',\n },\n },\n },\n {\n id: 'git',\n name: 'Git',\n description: 'Version control system',\n requiredFor: ['version-control', 'remote-templates'],\n checkCommand: 'git --version',\n platforms: {\n linux: {\n commands: [\n '# Ubuntu/Debian:',\n 'sudo apt install git',\n '# Fedora:',\n 'sudo dnf install git',\n '# Arch:',\n 'sudo pacman -S git',\n ],\n },\n macos: {\n commands: ['brew install git', '# Or: xcode-select --install'],\n },\n windows: {\n commands: ['choco install git', '# Or: winget install Git.Git'],\n links: ['https://git-scm.com/download/win'],\n },\n },\n },\n {\n id: 'node',\n name: 'Node.js',\n description: 'JavaScript runtime',\n requiredFor: ['cli', 'mcp-servers'],\n checkCommand: 'node --version',\n platforms: {\n linux: {\n commands: [\n '# Using nvm (recommended):',\n 'curl -o- https://raw.githubusercontent.com/nvm-sh/nvm/v0.40.0/install.sh | bash',\n 'nvm install --lts',\n '# Or using package manager:',\n 'sudo apt install nodejs npm',\n ],\n links: ['https://nodejs.org/', 'https://github.com/nvm-sh/nvm'],\n },\n macos: {\n commands: [\n '# Using nvm (recommended):',\n 'curl -o- https://raw.githubusercontent.com/nvm-sh/nvm/v0.40.0/install.sh | bash',\n 'nvm install --lts',\n '# Or using Homebrew:',\n 'brew install node',\n ],\n links: ['https://nodejs.org/', 'https://github.com/nvm-sh/nvm'],\n },\n windows: {\n commands: ['choco install nodejs-lts', '# Or: winget install OpenJS.NodeJS.LTS'],\n links: ['https://nodejs.org/'],\n },\n },\n },\n];\n\n/**\n * Get dependency by ID\n */\nexport function getDependency(id: string): DependencyInfo | undefined {\n return DEPENDENCIES.find((d) => d.id === id);\n}\n\n/**\n * Get dependencies required for a feature\n */\nexport function getDependenciesForFeature(feature: string): DependencyInfo[] {\n return DEPENDENCIES.filter((d) => d.requiredFor.includes(feature));\n}\n\n/**\n * Get all dependency IDs\n */\nexport function getDependencyIds(): string[] {\n return DEPENDENCIES.map((d) => d.id);\n}\n","/**\n * Placeholder definitions for template processing\n */\n\nimport type { PlaceholderDefinition } from '../types/placeholders.js';\n\n/**\n * All placeholder patterns that can be replaced in templates\n */\nexport const PLACEHOLDERS: PlaceholderDefinition[] = [\n // Project info placeholders\n {\n pattern: /\\[Project Name\\]/g,\n configKey: 'name',\n transform: 'none',\n description: 'Project name',\n example: 'My Awesome Project',\n required: true,\n },\n {\n pattern: /\\[project-name\\]/g,\n configKey: 'name',\n transform: 'lowercase',\n description: 'Project name in lowercase with dashes',\n example: 'my-awesome-project',\n required: true,\n },\n {\n pattern: /\\[PROJECT_NAME\\]/g,\n configKey: 'name',\n transform: 'uppercase',\n description: 'Project name in uppercase with underscores',\n example: 'MY_AWESOME_PROJECT',\n required: true,\n },\n {\n pattern: /\\[Project Description\\]/g,\n configKey: 'description',\n transform: 'none',\n description: 'Project description',\n example: 'A powerful CLI tool for managing configurations',\n required: true,\n },\n {\n pattern: /your-org/g,\n configKey: 'org',\n transform: 'lowercase',\n description: 'GitHub organization or username',\n example: 'acme-corp',\n required: true,\n },\n {\n pattern: /your-repo/g,\n configKey: 'repo',\n transform: 'lowercase',\n description: 'Repository name',\n example: 'my-project',\n required: true,\n },\n {\n pattern: /example\\.com/g,\n configKey: 'domain',\n transform: 'lowercase',\n description: 'Project domain',\n example: 'myproject.com',\n required: false,\n },\n\n // Entity placeholders\n {\n pattern: /\\[Entity\\]/g,\n configKey: 'entityType',\n transform: 'capitalize',\n description: 'Primary entity type (capitalized)',\n example: 'Product',\n required: true,\n },\n {\n pattern: /\\[entity\\]/g,\n configKey: 'entityType',\n transform: 'lowercase',\n description: 'Primary entity type (lowercase)',\n example: 'product',\n required: true,\n },\n {\n pattern: /\\[Entities\\]/g,\n configKey: 'entityTypePlural',\n transform: 'capitalize',\n description: 'Primary entity type plural (capitalized)',\n example: 'Products',\n required: true,\n },\n {\n pattern: /\\[entities\\]/g,\n configKey: 'entityTypePlural',\n transform: 'lowercase',\n description: 'Primary entity type plural (lowercase)',\n example: 'products',\n required: true,\n },\n\n // Location placeholders\n {\n pattern: /\\[City Name\\]/g,\n configKey: 'location',\n transform: 'capitalize',\n description: 'City or location name',\n example: 'San Francisco',\n required: false,\n },\n {\n pattern: /\\[Your Region\\/Product\\]/g,\n configKey: 'location',\n transform: 'none',\n description: 'Region or product area',\n example: 'Bay Area',\n required: false,\n },\n {\n pattern: /\\[Your product\\/service tagline here\\]/g,\n configKey: 'description',\n transform: 'none',\n description: 'Product tagline',\n example: 'The best way to manage your projects',\n required: false,\n },\n];\n\n/**\n * Get placeholder by pattern string\n */\nexport function getPlaceholder(pattern: string): PlaceholderDefinition | undefined {\n return PLACEHOLDERS.find((p) => {\n if (p.pattern instanceof RegExp) {\n return p.pattern.source === pattern || p.pattern.source === new RegExp(pattern).source;\n }\n return p.pattern === pattern;\n });\n}\n\n/**\n * Get all required placeholders\n */\nexport function getRequiredPlaceholders(): PlaceholderDefinition[] {\n return PLACEHOLDERS.filter((p) => p.required);\n}\n\n/**\n * Get all optional placeholders\n */\nexport function getOptionalPlaceholders(): PlaceholderDefinition[] {\n return PLACEHOLDERS.filter((p) => !p.required);\n}\n\n/**\n * Apply transformation to a value\n */\nexport function applyTransform(\n value: string,\n transform: PlaceholderDefinition['transform']\n): string {\n switch (transform) {\n case 'lowercase':\n return value.toLowerCase().replace(/\\s+/g, '-');\n case 'uppercase':\n return value.toUpperCase().replace(/\\s+/g, '_');\n case 'capitalize':\n return value\n .split(' ')\n .map((word) => word.charAt(0).toUpperCase() + word.slice(1).toLowerCase())\n .join(' ');\n case 'pluralize':\n // Simple pluralization rules\n if (value.endsWith('y')) {\n return `${value.slice(0, -1)}ies`;\n }\n if (\n value.endsWith('s') ||\n value.endsWith('x') ||\n value.endsWith('ch') ||\n value.endsWith('sh')\n ) {\n return `${value}es`;\n }\n return `${value}s`;\n default:\n return value;\n }\n}\n","/**\n * Permission preset definitions\n */\n\nimport type {\n BashPermissions,\n FilePermissions,\n GitPermissions,\n PermissionPreset,\n PermissionsConfig,\n WebPermissions,\n} from '../types/permissions.js';\n\n/**\n * Default file permissions\n */\nconst DEFAULT_FILE_PERMISSIONS: FilePermissions = {\n readAll: true,\n writeCode: true,\n writeConfig: true,\n writeMarkdown: true,\n writeOther: false,\n editTool: true,\n};\n\n/**\n * Trust file permissions\n */\nconst TRUST_FILE_PERMISSIONS: FilePermissions = {\n readAll: true,\n writeCode: true,\n writeConfig: true,\n writeMarkdown: true,\n writeOther: true,\n editTool: true,\n};\n\n/**\n * Restrictive file permissions\n */\nconst RESTRICTIVE_FILE_PERMISSIONS: FilePermissions = {\n readAll: true,\n writeCode: false,\n writeConfig: false,\n writeMarkdown: true,\n writeOther: false,\n editTool: false,\n};\n\n/**\n * Default git permissions\n */\nconst DEFAULT_GIT_PERMISSIONS: GitPermissions = {\n readOnly: true,\n staging: false,\n commit: false,\n push: false,\n branching: false,\n};\n\n/**\n * Trust git permissions\n */\nconst TRUST_GIT_PERMISSIONS: GitPermissions = {\n readOnly: true,\n staging: true,\n commit: true,\n push: false,\n branching: true,\n};\n\n/**\n * Restrictive git permissions\n */\nconst RESTRICTIVE_GIT_PERMISSIONS: GitPermissions = {\n readOnly: true,\n staging: false,\n commit: false,\n push: false,\n branching: false,\n};\n\n/**\n * Default bash permissions\n */\nconst DEFAULT_BASH_PERMISSIONS: BashPermissions = {\n packageManager: true,\n testing: true,\n building: true,\n docker: false,\n arbitrary: false,\n};\n\n/**\n * Trust bash permissions\n */\nconst TRUST_BASH_PERMISSIONS: BashPermissions = {\n packageManager: true,\n testing: true,\n building: true,\n docker: true,\n arbitrary: true,\n};\n\n/**\n * Restrictive bash permissions\n */\nconst RESTRICTIVE_BASH_PERMISSIONS: BashPermissions = {\n packageManager: false,\n testing: false,\n building: false,\n docker: false,\n arbitrary: false,\n};\n\n/**\n * Default web permissions\n */\nconst DEFAULT_WEB_PERMISSIONS: WebPermissions = {\n fetch: true,\n search: true,\n};\n\n/**\n * All permission presets\n */\nexport const PERMISSION_PRESETS: Record<\n PermissionPreset,\n Omit<PermissionsConfig, 'preset' | 'custom'>\n> = {\n default: {\n files: DEFAULT_FILE_PERMISSIONS,\n git: DEFAULT_GIT_PERMISSIONS,\n bash: DEFAULT_BASH_PERMISSIONS,\n web: DEFAULT_WEB_PERMISSIONS,\n },\n trust: {\n files: TRUST_FILE_PERMISSIONS,\n git: TRUST_GIT_PERMISSIONS,\n bash: TRUST_BASH_PERMISSIONS,\n web: DEFAULT_WEB_PERMISSIONS,\n },\n restrictive: {\n files: RESTRICTIVE_FILE_PERMISSIONS,\n git: RESTRICTIVE_GIT_PERMISSIONS,\n bash: RESTRICTIVE_BASH_PERMISSIONS,\n web: DEFAULT_WEB_PERMISSIONS,\n },\n custom: {\n files: DEFAULT_FILE_PERMISSIONS,\n git: DEFAULT_GIT_PERMISSIONS,\n bash: DEFAULT_BASH_PERMISSIONS,\n web: DEFAULT_WEB_PERMISSIONS,\n },\n};\n\n/**\n * Default deny rules (always applied)\n */\nexport const DEFAULT_DENY_RULES: string[] = [\n // Directories\n 'Write(node_modules/**)',\n 'Write(.git/**)',\n 'Write(dist/**)',\n 'Write(build/**)',\n 'Write(.next/**)',\n 'Write(.nuxt/**)',\n 'Write(.output/**)',\n\n // System files\n 'Write(/etc/**)',\n 'Write(/usr/**)',\n 'Write(/bin/**)',\n 'Write(/sbin/**)',\n 'Write(/var/**)',\n 'Write(/tmp/**)',\n\n // Dangerous commands\n 'Bash(rm -rf /)',\n 'Bash(sudo *)',\n 'Bash(chmod 777 *)',\n 'Bash(curl * | bash)',\n 'Bash(wget * | bash)',\n\n // Sensitive files\n 'Write(.env)',\n 'Write(.env.*)',\n 'Write(**/secrets/**)',\n 'Write(**/credentials/**)',\n 'Read(.env)',\n 'Read(.env.*)',\n];\n\n/**\n * Get permissions for a preset\n */\nexport function getPresetPermissions(\n preset: PermissionPreset\n): Omit<PermissionsConfig, 'preset' | 'custom'> {\n return PERMISSION_PRESETS[preset];\n}\n\n/**\n * Generate allow rules from permissions config\n */\nexport function generateAllowRules(config: PermissionsConfig): string[] {\n const rules: string[] = [];\n\n // File permissions\n if (config.files.readAll) {\n rules.push(\n 'Read(**/*)',\n 'Glob(**/*)',\n 'Grep(**/*)',\n 'LS(**/*)',\n 'TodoRead',\n 'WebFetch',\n 'WebSearch'\n );\n }\n if (config.files.writeCode) {\n rules.push(\n 'Write(**/*.ts)',\n 'Write(**/*.tsx)',\n 'Write(**/*.js)',\n 'Write(**/*.jsx)',\n 'Write(**/*.mts)',\n 'Write(**/*.mjs)',\n 'Write(**/*.vue)',\n 'Write(**/*.svelte)'\n );\n }\n if (config.files.writeConfig) {\n rules.push(\n 'Write(**/*.json)',\n 'Write(**/*.yaml)',\n 'Write(**/*.yml)',\n 'Write(**/*.toml)',\n 'Write(**/*.xml)',\n 'Write(**/.env.example)',\n 'Write(**/.gitignore)',\n 'Write(**/.npmrc)',\n 'Write(**/.nvmrc)'\n );\n }\n if (config.files.writeMarkdown) {\n rules.push('Write(**/*.md)', 'Write(**/*.mdx)');\n }\n if (config.files.writeOther) {\n rules.push(\n 'Write(**/*.css)',\n 'Write(**/*.scss)',\n 'Write(**/*.less)',\n 'Write(**/*.html)',\n 'Write(**/*.sql)',\n 'Write(**/*.graphql)',\n 'Write(**/*.prisma)'\n );\n }\n if (config.files.editTool) {\n rules.push('Edit(**/*)', 'MultiEdit(**/*)', 'NotebookEdit(**/*)', 'TodoWrite');\n }\n\n // Git permissions\n if (config.git.readOnly) {\n rules.push(\n 'Bash(git status*)',\n 'Bash(git diff*)',\n 'Bash(git log*)',\n 'Bash(git show*)',\n 'Bash(git branch*)'\n );\n }\n if (config.git.staging) {\n rules.push('Bash(git add*)');\n }\n if (config.git.commit) {\n rules.push('Bash(git commit*)');\n }\n if (config.git.push) {\n rules.push('Bash(git push*)');\n }\n if (config.git.branching) {\n rules.push('Bash(git checkout*)', 'Bash(git branch*)', 'Bash(git merge*)', 'Bash(git rebase*)');\n }\n\n // Bash permissions\n if (config.bash.packageManager) {\n rules.push(\n 'Bash(pnpm *)',\n 'Bash(npm *)',\n 'Bash(yarn *)',\n 'Bash(bun *)',\n 'Bash(npx *)',\n 'Bash(bunx *)'\n );\n }\n if (config.bash.testing) {\n rules.push(\n 'Bash(vitest*)',\n 'Bash(jest*)',\n 'Bash(playwright*)',\n 'Bash(cypress*)',\n 'Bash(pnpm test*)',\n 'Bash(npm test*)',\n 'Bash(pnpm run test*)',\n 'Bash(npm run test*)'\n );\n }\n if (config.bash.building) {\n rules.push(\n 'Bash(pnpm build*)',\n 'Bash(npm run build*)',\n 'Bash(pnpm run build*)',\n 'Bash(tsc*)',\n 'Bash(tsup*)',\n 'Bash(vite build*)',\n 'Bash(next build*)',\n 'Bash(astro build*)'\n );\n }\n if (config.bash.docker) {\n rules.push('Bash(docker *)', 'Bash(docker-compose *)');\n }\n if (config.bash.arbitrary) {\n rules.push('Bash(*)');\n }\n\n // Web permissions\n if (config.web.fetch) {\n rules.push('WebFetch');\n }\n if (config.web.search) {\n rules.push('WebSearch');\n }\n\n // Add custom allow rules\n if (config.custom?.allow) {\n rules.push(...config.custom.allow);\n }\n\n return [...new Set(rules)]; // Remove duplicates\n}\n\n/**\n * Generate deny rules from permissions config\n */\nexport function generateDenyRules(config: PermissionsConfig): string[] {\n const rules = [...DEFAULT_DENY_RULES];\n\n // Add custom deny rules\n if (config.custom?.deny) {\n rules.push(...config.custom.deny);\n }\n\n return [...new Set(rules)]; // Remove duplicates\n}\n\n/**\n * Preset descriptions for UI\n */\nexport const PRESET_DESCRIPTIONS: Record<PermissionPreset, { name: string; description: string }> =\n {\n default: {\n name: 'Default',\n description:\n 'Balanced permissions - read all, write code/config/docs, basic git, package manager & testing',\n },\n trust: {\n name: 'Trust',\n description:\n 'Extended permissions - full file access, git staging/commit/branching, docker, arbitrary bash',\n },\n restrictive: {\n name: 'Restrictive',\n description:\n 'Minimal permissions - read only, markdown writing, no git operations, no bash commands',\n },\n custom: {\n name: 'Custom',\n description: 'Configure each permission individually',\n },\n };\n","/**\n * Bundle resolver - resolves bundles to individual modules\n */\n\nimport {\n BUNDLE_CATEGORY_NAMES,\n getAllBundles,\n getBundleById,\n getBundlesGroupedByCategory,\n} from '../../constants/bundles.js';\nimport type {\n BundleDefinition,\n BundleSelectionResult,\n ResolvedBundle,\n} from '../../types/bundles.js';\nimport type { ModuleSelectionResult } from '../../types/modules.js';\n\n/**\n * Resolve a bundle to its constituent modules\n */\nexport function resolveBundle(bundle: BundleDefinition): ResolvedBundle {\n const modules: ResolvedBundle['modules'] = {\n agents: [],\n skills: [],\n commands: [],\n docs: [],\n };\n\n for (const moduleRef of bundle.modules) {\n switch (moduleRef.category) {\n case 'agents':\n modules.agents.push(moduleRef.id);\n break;\n case 'skills':\n modules.skills.push(moduleRef.id);\n break;\n case 'commands':\n modules.commands.push(moduleRef.id);\n break;\n case 'docs':\n modules.docs.push(moduleRef.id);\n break;\n }\n }\n\n return {\n bundle,\n modules,\n };\n}\n\n/**\n * Resolve multiple bundles to a combined module selection\n */\nexport function resolveBundles(bundleIds: string[]): ModuleSelectionResult {\n const result: ModuleSelectionResult = {\n agents: [],\n skills: [],\n commands: [],\n docs: [],\n };\n\n const seenModules = {\n agents: new Set<string>(),\n skills: new Set<string>(),\n commands: new Set<string>(),\n docs: new Set<string>(),\n };\n\n for (const bundleId of bundleIds) {\n const bundle = getBundleById(bundleId);\n if (!bundle) continue;\n\n const resolved = resolveBundle(bundle);\n\n // Add modules without duplicates\n for (const id of resolved.modules.agents) {\n if (!seenModules.agents.has(id)) {\n seenModules.agents.add(id);\n result.agents.push(id);\n }\n }\n for (const id of resolved.modules.skills) {\n if (!seenModules.skills.has(id)) {\n seenModules.skills.add(id);\n result.skills.push(id);\n }\n }\n for (const id of resolved.modules.commands) {\n if (!seenModules.commands.has(id)) {\n seenModules.commands.add(id);\n result.commands.push(id);\n }\n }\n for (const id of resolved.modules.docs) {\n if (!seenModules.docs.has(id)) {\n seenModules.docs.add(id);\n result.docs.push(id);\n }\n }\n }\n\n return result;\n}\n\n/**\n * Merge bundle selection with additional individual modules\n */\nexport function mergeBundleSelection(bundleResult: BundleSelectionResult): ModuleSelectionResult {\n // Start with resolved bundles\n const result = resolveBundles(bundleResult.selectedBundles);\n\n // Track what we have\n const seenModules = {\n agents: new Set(result.agents),\n skills: new Set(result.skills),\n commands: new Set(result.commands),\n docs: new Set(result.docs),\n };\n\n // Add additional modules without duplicates\n for (const id of bundleResult.additionalModules.agents) {\n if (!seenModules.agents.has(id)) {\n result.agents.push(id);\n }\n }\n for (const id of bundleResult.additionalModules.skills) {\n if (!seenModules.skills.has(id)) {\n result.skills.push(id);\n }\n }\n for (const id of bundleResult.additionalModules.commands) {\n if (!seenModules.commands.has(id)) {\n result.commands.push(id);\n }\n }\n for (const id of bundleResult.additionalModules.docs) {\n if (!seenModules.docs.has(id)) {\n result.docs.push(id);\n }\n }\n\n return result;\n}\n\n/**\n * Find bundles that contain a specific module\n */\nexport function findBundlesContainingModule(\n moduleId: string,\n category: 'agents' | 'skills' | 'commands' | 'docs'\n): BundleDefinition[] {\n return getAllBundles().filter((bundle) =>\n bundle.modules.some((m) => m.id === moduleId && m.category === category)\n );\n}\n\n/**\n * Get suggested bundles based on selected modules\n */\nexport function getSuggestedBundles(selectedModules: ModuleSelectionResult): BundleDefinition[] {\n const allBundles = getAllBundles();\n const suggestions: BundleDefinition[] = [];\n\n for (const bundle of allBundles) {\n const resolved = resolveBundle(bundle);\n\n // Check overlap with selected modules\n let matchCount = 0;\n let totalInBundle = 0;\n\n for (const agentId of resolved.modules.agents) {\n totalInBundle++;\n if (selectedModules.agents.includes(agentId)) matchCount++;\n }\n for (const skillId of resolved.modules.skills) {\n totalInBundle++;\n if (selectedModules.skills.includes(skillId)) matchCount++;\n }\n for (const commandId of resolved.modules.commands) {\n totalInBundle++;\n if (selectedModules.commands.includes(commandId)) matchCount++;\n }\n for (const docId of resolved.modules.docs) {\n totalInBundle++;\n if (selectedModules.docs.includes(docId)) matchCount++;\n }\n\n // Suggest if at least 30% overlap but not 100%\n const overlapRatio = totalInBundle > 0 ? matchCount / totalInBundle : 0;\n if (overlapRatio >= 0.3 && overlapRatio < 1.0) {\n suggestions.push(bundle);\n }\n }\n\n return suggestions;\n}\n\n/**\n * Format bundle for display (short version for list names)\n */\nexport function formatBundleForDisplay(bundle: BundleDefinition): string {\n const resolved = resolveBundle(bundle);\n const parts: string[] = [];\n\n if (resolved.modules.agents.length > 0) {\n parts.push(`${resolved.modules.agents.length} agents`);\n }\n if (resolved.modules.skills.length > 0) {\n parts.push(`${resolved.modules.skills.length} skills`);\n }\n if (resolved.modules.commands.length > 0) {\n parts.push(`${resolved.modules.commands.length} commands`);\n }\n if (resolved.modules.docs.length > 0) {\n parts.push(`${resolved.modules.docs.length} docs`);\n }\n\n return `${bundle.name} (${parts.join(', ')})`;\n}\n\n/**\n * Format bundle description with full details for selection prompts\n * Shows detailed multiline info that appears when hovering over a choice\n */\nexport function formatBundleDetailedDescription(bundle: BundleDefinition): string {\n const resolved = resolveBundle(bundle);\n const lines: string[] = [];\n\n // Main description\n lines.push(bundle.description);\n lines.push('');\n\n // Responsibilities (if available)\n if (bundle.responsibilities && bundle.responsibilities.length > 0) {\n lines.push('📋 Responsibilities:');\n for (const resp of bundle.responsibilities.slice(0, 3)) {\n lines.push(` • ${resp}`);\n }\n if (bundle.responsibilities.length > 3) {\n lines.push(` • ...and ${bundle.responsibilities.length - 3} more`);\n }\n lines.push('');\n }\n\n // Use cases (if available and no responsibilities)\n if (bundle.useCases && bundle.useCases.length > 0 && !bundle.responsibilities?.length) {\n lines.push('🎯 Use cases:');\n for (const uc of bundle.useCases.slice(0, 2)) {\n lines.push(` • ${uc}`);\n }\n lines.push('');\n }\n\n // Modules breakdown\n lines.push('📦 Includes:');\n if (resolved.modules.agents.length > 0) {\n lines.push(\n ` 🤖 Agents (${resolved.modules.agents.length}): ${resolved.modules.agents.join(', ')}`\n );\n }\n if (resolved.modules.skills.length > 0) {\n lines.push(\n ` ⚡ Skills (${resolved.modules.skills.length}): ${resolved.modules.skills.join(', ')}`\n );\n }\n if (resolved.modules.commands.length > 0) {\n const cmds = resolved.modules.commands.map((c) => `/${c}`).join(', ');\n lines.push(` 💻 Commands (${resolved.modules.commands.length}): ${cmds}`);\n }\n if (resolved.modules.docs.length > 0) {\n const docsPreview = resolved.modules.docs.slice(0, 4);\n const more =\n resolved.modules.docs.length > 4 ? `, +${resolved.modules.docs.length - 4} more` : '';\n lines.push(` 📚 Docs (${resolved.modules.docs.length}): ${docsPreview.join(', ')}${more}`);\n }\n\n // Tech stack\n if (bundle.techStack && bundle.techStack.length > 0) {\n lines.push('');\n lines.push(`🔧 Tech: ${bundle.techStack.join(', ')}`);\n }\n\n // Complexity indicator\n if (bundle.complexity) {\n const complexityLabel =\n bundle.complexity === 'minimal'\n ? '⚡ Minimal - Quick setup'\n : bundle.complexity === 'comprehensive'\n ? '🔥 Comprehensive - Full featured'\n : '⭐ Standard';\n lines.push(`📊 ${complexityLabel}`);\n }\n\n return lines.join('\\n');\n}\n\n/**\n * Format bundle with rich multi-line description for display\n * Use this when you can show multiple lines\n */\nexport function formatBundleRichDescription(bundle: BundleDefinition): string[] {\n const resolved = resolveBundle(bundle);\n const lines: string[] = [];\n\n // Main description\n lines.push(bundle.description);\n\n // Responsibilities preview\n if (bundle.responsibilities && bundle.responsibilities.length > 0) {\n lines.push('');\n lines.push('Responsibilities:');\n for (const resp of bundle.responsibilities.slice(0, 3)) {\n lines.push(` • ${resp}`);\n }\n if (bundle.responsibilities.length > 3) {\n lines.push(` • ...and ${bundle.responsibilities.length - 3} more`);\n }\n }\n\n // Use cases preview\n if (bundle.useCases && bundle.useCases.length > 0) {\n lines.push('');\n lines.push('Use cases:');\n for (const uc of bundle.useCases.slice(0, 2)) {\n lines.push(` • ${uc}`);\n }\n }\n\n // Modules breakdown\n lines.push('');\n lines.push('Includes:');\n if (resolved.modules.agents.length > 0) {\n lines.push(` 🤖 Agents: ${resolved.modules.agents.join(', ')}`);\n }\n if (resolved.modules.skills.length > 0) {\n lines.push(` ⚡ Skills: ${resolved.modules.skills.join(', ')}`);\n }\n if (resolved.modules.commands.length > 0) {\n lines.push(` 💻 Commands: /${resolved.modules.commands.join(', /')}`);\n }\n if (resolved.modules.docs.length > 0) {\n const docsPreview = resolved.modules.docs.slice(0, 5);\n const more =\n resolved.modules.docs.length > 5 ? `, +${resolved.modules.docs.length - 5} more` : '';\n lines.push(` 📚 Docs: ${docsPreview.join(', ')}${more}`);\n }\n\n // Tech stack\n if (bundle.techStack && bundle.techStack.length > 0) {\n lines.push('');\n lines.push(`🔧 Tech: ${bundle.techStack.join(', ')}`);\n }\n\n return lines;\n}\n\n/**\n * Get bundle category display name\n */\nexport function getBundleCategoryName(category: string): string {\n return BUNDLE_CATEGORY_NAMES[category] ?? category;\n}\n\n/**\n * Export convenience access to constants\n */\nexport { getAllBundles, getBundleById, getBundlesGroupedByCategory, BUNDLE_CATEGORY_NAMES };\n","/**\n * Config exports\n */\n\n// Reader\nexport {\n readConfig,\n hasConfig,\n hasClaudeDir,\n getConfigPath,\n getClaudeDirPath,\n readPartialConfig,\n getInstalledModulesFromConfig,\n getConfigVersion,\n needsMigration,\n} from './reader.js';\n\n// Writer\nexport {\n writeConfig,\n updateConfig,\n mergeConfig,\n createDefaultConfig,\n addModulesToConfig,\n removeModulesFromConfig,\n updateMcpConfig,\n updateExtrasConfig,\n} from './writer.js';\n\n// Global Defaults\nexport {\n getGlobalDefaultsPath,\n readGlobalDefaults,\n writeGlobalDefaults,\n updateGlobalDefaults,\n mergeWithGlobalDefaults,\n hasGlobalDefaults,\n clearGlobalDefaults,\n getGlobalTemplateConfig,\n formatGlobalDefaults,\n} from './global-defaults.js';\n","/**\n * Configuration reader - reads Claude config files\n */\n\nimport type { ClaudeConfig, PartialClaudeConfig } from '../../types/config.js';\nimport { joinPath, pathExists, readJson } from '../utils/fs.js';\nimport { logger } from '../utils/logger.js';\n\nconst CONFIG_FILE = 'config.json';\nconst CLAUDE_DIR = '.claude';\n\n/**\n * Read Claude configuration from a project\n */\nexport async function readConfig(projectPath: string): Promise<ClaudeConfig | null> {\n const configPath = joinPath(projectPath, CLAUDE_DIR, CONFIG_FILE);\n\n if (!(await pathExists(configPath))) {\n return null;\n }\n\n try {\n return await readJson<ClaudeConfig>(configPath);\n } catch (error) {\n logger.debug(`Failed to read config: ${error}`);\n return null;\n }\n}\n\n/**\n * Check if a Claude configuration exists\n */\nexport async function hasConfig(projectPath: string): Promise<boolean> {\n const configPath = joinPath(projectPath, CLAUDE_DIR, CONFIG_FILE);\n return pathExists(configPath);\n}\n\n/**\n * Check if Claude directory exists\n */\nexport async function hasClaudeDir(projectPath: string): Promise<boolean> {\n const claudePath = joinPath(projectPath, CLAUDE_DIR);\n return pathExists(claudePath);\n}\n\n/**\n * Get config file path\n */\nexport function getConfigPath(projectPath: string): string {\n return joinPath(projectPath, CLAUDE_DIR, CONFIG_FILE);\n}\n\n/**\n * Get Claude directory path\n */\nexport function getClaudeDirPath(projectPath: string): string {\n return joinPath(projectPath, CLAUDE_DIR);\n}\n\n/**\n * Read partial config (for updates/merges)\n */\nexport async function readPartialConfig(projectPath: string): Promise<PartialClaudeConfig | null> {\n return readConfig(projectPath) as Promise<PartialClaudeConfig | null>;\n}\n\n/**\n * Get installed module IDs from config\n */\nexport function getInstalledModulesFromConfig(config: ClaudeConfig): Record<string, string[]> {\n return {\n agents: config.modules.agents.selected,\n skills: config.modules.skills.selected,\n commands: config.modules.commands.selected,\n docs: config.modules.docs.selected,\n };\n}\n\n/**\n * Get config version\n */\nexport function getConfigVersion(config: ClaudeConfig): string {\n return config.version;\n}\n\n/**\n * Check if config needs migration\n */\nexport function needsMigration(config: ClaudeConfig, currentVersion: string): boolean {\n const configVersion = config.version;\n\n // Simple semver comparison\n const [configMajor, configMinor] = configVersion.split('.').map(Number);\n const [currentMajor, currentMinor] = currentVersion.split('.').map(Number);\n\n return configMajor < currentMajor || (configMajor === currentMajor && configMinor < currentMinor);\n}\n","/**\n * Logger utility with colored output\n */\n\nimport chalk from 'chalk';\n\nexport type LogLevel = 'debug' | 'info' | 'success' | 'warn' | 'error';\n\ninterface LoggerOptions {\n verbose?: boolean;\n silent?: boolean;\n}\n\nconst SYMBOLS = {\n info: chalk.blue('ℹ'),\n success: chalk.green('✔'),\n warn: chalk.yellow('⚠'),\n error: chalk.red('✖'),\n debug: chalk.gray('●'),\n arrow: chalk.cyan('→'),\n bullet: chalk.dim('•'),\n};\n\nclass Logger {\n private verbose = false;\n private silent = false;\n\n configure(options: LoggerOptions): void {\n if (options.verbose !== undefined) this.verbose = options.verbose;\n if (options.silent !== undefined) this.silent = options.silent;\n }\n\n private log(level: LogLevel, message: string, ...args: unknown[]): void {\n if (this.silent && level !== 'error') return;\n if (level === 'debug' && !this.verbose) return;\n\n const prefix = SYMBOLS[level];\n const formattedMessage = args.length > 0 ? `${message} ${args.join(' ')}` : message;\n\n switch (level) {\n case 'error':\n console.error(`${prefix} ${chalk.red(formattedMessage)}`);\n break;\n case 'warn':\n console.warn(`${prefix} ${chalk.yellow(formattedMessage)}`);\n break;\n case 'success':\n console.log(`${prefix} ${chalk.green(formattedMessage)}`);\n break;\n case 'debug':\n console.log(`${prefix} ${chalk.gray(formattedMessage)}`);\n break;\n default:\n console.log(`${prefix} ${formattedMessage}`);\n }\n }\n\n debug(message: string, ...args: unknown[]): void {\n this.log('debug', message, ...args);\n }\n\n info(message: string, ...args: unknown[]): void {\n this.log('info', message, ...args);\n }\n\n success(message: string, ...args: unknown[]): void {\n this.log('success', message, ...args);\n }\n\n warn(message: string, ...args: unknown[]): void {\n this.log('warn', message, ...args);\n }\n\n error(message: string, ...args: unknown[]): void {\n this.log('error', message, ...args);\n }\n\n /**\n * Print a blank line\n */\n newline(): void {\n if (!this.silent) console.log();\n }\n\n /**\n * Print a title/header\n */\n title(text: string): void {\n if (this.silent) return;\n console.log();\n console.log(chalk.bold(chalk.cyan(text)));\n console.log(chalk.dim('─'.repeat(Math.min(text.length + 4, 60))));\n }\n\n /**\n * Print a subtitle\n */\n subtitle(text: string): void {\n if (this.silent) return;\n console.log();\n console.log(chalk.bold(text));\n }\n\n /**\n * Print a large section header for major transitions\n * Creates a visually prominent divider between configuration sections\n */\n section(text: string, icon?: string): void {\n if (this.silent) return;\n const displayIcon = icon || '◆';\n const width = 60;\n const border = '═'.repeat(width);\n const innerWidth = width - 4;\n const paddedText = text.length > innerWidth ? text.slice(0, innerWidth) : text;\n const leftPad = Math.floor((innerWidth - paddedText.length) / 2);\n const rightPad = innerWidth - paddedText.length - leftPad;\n\n console.log();\n console.log(chalk.cyan(`╔${border}╗`));\n console.log(chalk.cyan('║') + ' '.repeat(width) + chalk.cyan('║'));\n console.log(\n `${\n chalk.cyan('║') + ' '.repeat(leftPad + 1) + chalk.hex('#FED330')(displayIcon)\n } ${chalk.bold.white(paddedText)}${' '.repeat(rightPad + 1)}${chalk.cyan('║')}`\n );\n console.log(chalk.cyan('║') + ' '.repeat(width) + chalk.cyan('║'));\n console.log(chalk.cyan(`╚${border}╝`));\n console.log();\n }\n\n /**\n * Print a step in a process\n */\n step(stepNumber: number, totalSteps: number, message: string): void {\n if (this.silent) return;\n const progress = chalk.dim(`[${stepNumber}/${totalSteps}]`);\n console.log(`${progress} ${message}`);\n }\n\n /**\n * Print a list item\n */\n item(text: string, indent = 0): void {\n if (this.silent) return;\n const spaces = ' '.repeat(indent);\n console.log(`${spaces}${SYMBOLS.bullet} ${text}`);\n }\n\n /**\n * Print a key-value pair\n */\n keyValue(key: string, value: string, indent = 0): void {\n if (this.silent) return;\n const spaces = ' '.repeat(indent);\n console.log(`${spaces}${chalk.dim(`${key}:`)} ${value}`);\n }\n\n /**\n * Print an arrow item (for showing changes/actions)\n */\n arrow(text: string, indent = 0): void {\n if (this.silent) return;\n const spaces = ' '.repeat(indent);\n console.log(`${spaces}${SYMBOLS.arrow} ${text}`);\n }\n\n /**\n * Print a boxed message\n */\n box(title: string, content: string[]): void {\n if (this.silent) return;\n const maxLength = Math.max(title.length, ...content.map((line) => line.length));\n const width = Math.min(maxLength + 4, 70);\n const border = '─'.repeat(width - 2);\n\n console.log();\n console.log(chalk.cyan(`┌${border}┐`));\n console.log(chalk.cyan('│') + chalk.bold(` ${title.padEnd(width - 3)}`) + chalk.cyan('│'));\n console.log(chalk.cyan(`├${border}┤`));\n for (const line of content) {\n console.log(`${chalk.cyan('│')} ${line.padEnd(width - 3)}${chalk.cyan('│')}`);\n }\n console.log(chalk.cyan(`└${border}┘`));\n console.log();\n }\n\n /**\n * Print a table\n */\n table(headers: string[], rows: string[][]): void {\n if (this.silent) return;\n\n // Calculate column widths\n const colWidths = headers.map((h, i) => {\n const maxRowWidth = Math.max(...rows.map((r) => (r[i] || '').length));\n return Math.max(h.length, maxRowWidth);\n });\n\n // Print header\n const headerRow = headers.map((h, i) => chalk.bold(h.padEnd(colWidths[i]))).join(' ');\n console.log(headerRow);\n console.log(chalk.dim(colWidths.map((w) => '─'.repeat(w)).join(' ')));\n\n // Print rows\n for (const row of rows) {\n const rowStr = row.map((cell, i) => (cell || '').padEnd(colWidths[i])).join(' ');\n console.log(rowStr);\n }\n }\n\n /**\n * Print a colored status\n */\n status(label: string, status: 'success' | 'error' | 'warn' | 'pending' | 'skip'): void {\n if (this.silent) return;\n const statusColors = {\n success: chalk.green('✔ done'),\n error: chalk.red('✖ failed'),\n warn: chalk.yellow('⚠ warning'),\n pending: chalk.blue('◯ pending'),\n skip: chalk.dim('○ skipped'),\n };\n console.log(` ${label}: ${statusColors[status]}`);\n }\n\n /**\n * Print instructions\n */\n instructions(title: string, steps: string[]): void {\n if (this.silent) return;\n console.log();\n console.log(chalk.bold(chalk.cyan(title)));\n console.log();\n steps.forEach((step, index) => {\n console.log(` ${chalk.dim(`${index + 1}.`)} ${step}`);\n });\n console.log();\n }\n\n /**\n * Print a dimmed note\n */\n note(text: string): void {\n if (this.silent) return;\n console.log(chalk.dim(` ${text}`));\n }\n\n /**\n * Print raw text without formatting\n */\n raw(text: string): void {\n if (this.silent) return;\n console.log(text);\n }\n}\n\n// Export singleton instance\nexport const logger = new Logger();\n\n// Export color utilities for direct use\nexport const colors = {\n primary: chalk.cyan,\n secondary: chalk.blue,\n success: chalk.green,\n warning: chalk.yellow,\n error: chalk.red,\n muted: chalk.dim,\n bold: chalk.bold,\n underline: chalk.underline,\n};\n","/**\n * Configuration writer - writes Claude config files\n */\n\nimport type { ClaudeConfig, PartialClaudeConfig } from '../../types/config.js';\nimport { backup, ensureDir, joinPath, pathExists, writeJson } from '../utils/fs.js';\nimport { logger } from '../utils/logger.js';\nimport { readConfig } from './reader.js';\n\nconst CONFIG_FILE = 'config.json';\nconst CLAUDE_DIR = '.claude';\n\n/**\n * Write Claude configuration\n */\nexport async function writeConfig(\n projectPath: string,\n config: ClaudeConfig,\n options?: { backup?: boolean }\n): Promise<void> {\n const claudePath = joinPath(projectPath, CLAUDE_DIR);\n const configPath = joinPath(claudePath, CONFIG_FILE);\n\n // Create .claude directory if needed\n await ensureDir(claudePath);\n\n // Backup existing config if requested\n if (options?.backup && (await pathExists(configPath))) {\n const backupPath = await backup(configPath, `.backup.${Date.now()}`);\n logger.debug(`Config backed up to: ${backupPath}`);\n }\n\n // Write config\n await writeJson(configPath, config, { spaces: 2 });\n logger.debug(`Config written to: ${configPath}`);\n}\n\n/**\n * Update existing configuration (merge)\n */\nexport async function updateConfig(\n projectPath: string,\n updates: PartialClaudeConfig\n): Promise<ClaudeConfig | null> {\n const existing = await readConfig(projectPath);\n\n if (!existing) {\n logger.warn('No existing config to update');\n return null;\n }\n\n const updated = mergeConfig(existing, updates);\n updated.customizations.lastUpdated = new Date().toISOString();\n\n await writeConfig(projectPath, updated);\n return updated;\n}\n\n/**\n * Merge partial config into existing config\n */\nexport function mergeConfig(existing: ClaudeConfig, updates: PartialClaudeConfig): ClaudeConfig {\n return {\n version: updates.version || existing.version,\n templateSource: updates.templateSource || existing.templateSource,\n project: {\n ...existing.project,\n ...updates.project,\n },\n preferences: {\n ...existing.preferences,\n ...updates.preferences,\n },\n mcp: updates.mcp || existing.mcp,\n modules: {\n agents: updates.modules?.agents || existing.modules.agents,\n skills: updates.modules?.skills || existing.modules.skills,\n commands: updates.modules?.commands || existing.modules.commands,\n docs: updates.modules?.docs || existing.modules.docs,\n },\n extras: {\n ...existing.extras,\n ...updates.extras,\n hooks: updates.extras?.hooks || existing.extras.hooks,\n },\n scaffold: updates.scaffold || existing.scaffold,\n customizations: {\n ...existing.customizations,\n ...updates.customizations,\n lastUpdated: new Date().toISOString(),\n },\n };\n}\n\n/**\n * Create a default configuration\n */\nexport function createDefaultConfig(options: {\n version: string;\n projectInfo: ClaudeConfig['project'];\n preferences: ClaudeConfig['preferences'];\n}): ClaudeConfig {\n return {\n version: options.version,\n templateSource: {\n type: 'local',\n installedAt: new Date().toISOString(),\n },\n project: options.projectInfo,\n preferences: options.preferences,\n mcp: {\n level: 'project',\n servers: [],\n },\n modules: {\n agents: { selected: [], excluded: [] },\n skills: { selected: [], excluded: [] },\n commands: { selected: [], excluded: [] },\n docs: { selected: [], excluded: [] },\n },\n extras: {\n schemas: false,\n scripts: false,\n hooks: { enabled: false },\n sessions: false,\n },\n scaffold: {\n type: 'claude-only',\n createdStructure: [],\n },\n customizations: {\n placeholdersReplaced: false,\n lastUpdated: new Date().toISOString(),\n customFiles: [],\n },\n };\n}\n\n/**\n * Add selected modules to config\n */\nexport function addModulesToConfig(\n config: ClaudeConfig,\n category: keyof ClaudeConfig['modules'],\n moduleIds: string[]\n): ClaudeConfig {\n const existing = new Set(config.modules[category].selected);\n\n for (const id of moduleIds) {\n existing.add(id);\n }\n\n return {\n ...config,\n modules: {\n ...config.modules,\n [category]: {\n ...config.modules[category],\n selected: Array.from(existing),\n },\n },\n };\n}\n\n/**\n * Remove modules from config\n */\nexport function removeModulesFromConfig(\n config: ClaudeConfig,\n category: keyof ClaudeConfig['modules'],\n moduleIds: string[]\n): ClaudeConfig {\n const toRemove = new Set(moduleIds);\n const remaining = config.modules[category].selected.filter((id) => !toRemove.has(id));\n\n return {\n ...config,\n modules: {\n ...config.modules,\n [category]: {\n ...config.modules[category],\n selected: remaining,\n excluded: [...config.modules[category].excluded, ...moduleIds],\n },\n },\n };\n}\n\n/**\n * Update MCP configuration\n */\nexport function updateMcpConfig(config: ClaudeConfig, mcp: ClaudeConfig['mcp']): ClaudeConfig {\n return {\n ...config,\n mcp,\n };\n}\n\n/**\n * Update extras configuration\n */\nexport function updateExtrasConfig(\n config: ClaudeConfig,\n extras: Partial<ClaudeConfig['extras']>\n): ClaudeConfig {\n return {\n ...config,\n extras: {\n ...config.extras,\n ...extras,\n },\n };\n}\n","/**\n * Global defaults management\n *\n * Manages global defaults stored in ~/.claude/defaults.json\n * These defaults are used as fallbacks for new projects.\n */\n\nimport * as fs from 'node:fs/promises';\nimport { homedir } from 'node:os';\nimport * as path from 'node:path';\nimport type { GlobalDefaults, TemplateConfig } from '../../types/template-config.js';\n\n/**\n * Get the path to the global defaults file\n */\nexport function getGlobalDefaultsPath(): string {\n return path.join(homedir(), '.claude', 'defaults.json');\n}\n\n/**\n * Ensure the ~/.claude directory exists\n */\nasync function ensureClaudeDir(): Promise<void> {\n const claudeDir = path.join(homedir(), '.claude');\n try {\n await fs.mkdir(claudeDir, { recursive: true });\n } catch {\n // Directory exists or can't be created\n }\n}\n\n/**\n * Read global defaults from ~/.claude/defaults.json\n */\nexport async function readGlobalDefaults(): Promise<GlobalDefaults> {\n const defaultsPath = getGlobalDefaultsPath();\n\n try {\n const content = await fs.readFile(defaultsPath, 'utf-8');\n return JSON.parse(content) as GlobalDefaults;\n } catch {\n // File doesn't exist or is invalid\n return {};\n }\n}\n\n/**\n * Write global defaults to ~/.claude/defaults.json\n */\nexport async function writeGlobalDefaults(defaults: GlobalDefaults): Promise<void> {\n await ensureClaudeDir();\n const defaultsPath = getGlobalDefaultsPath();\n\n const dataToWrite: GlobalDefaults = {\n ...defaults,\n lastUpdated: new Date().toISOString(),\n };\n\n await fs.writeFile(defaultsPath, JSON.stringify(dataToWrite, null, 2), 'utf-8');\n}\n\n/**\n * Update global defaults with new template config\n */\nexport async function updateGlobalDefaults(templateConfig: Partial<TemplateConfig>): Promise<void> {\n const existing = await readGlobalDefaults();\n\n const updated: GlobalDefaults = {\n ...existing,\n templateConfig: mergeTemplateConfigs(existing.templateConfig || {}, templateConfig),\n lastUpdated: new Date().toISOString(),\n };\n\n await writeGlobalDefaults(updated);\n}\n\n/**\n * Merge two template configs, with source taking precedence\n */\nfunction mergeTemplateConfigs(\n target: Partial<TemplateConfig>,\n source: Partial<TemplateConfig>\n): Partial<TemplateConfig> {\n return {\n commands: { ...target.commands, ...source.commands },\n paths: { ...target.paths, ...source.paths },\n targets: { ...target.targets, ...source.targets },\n tracking: { ...target.tracking, ...source.tracking },\n techStack: { ...target.techStack, ...source.techStack },\n environment: { ...target.environment, ...source.environment },\n brand: { ...target.brand, ...source.brand },\n };\n}\n\n/**\n * Merge detected values with global defaults\n * Priority: detected > global > hardcoded defaults\n */\nexport function mergeWithGlobalDefaults(\n detected: Partial<TemplateConfig>,\n globalDefaults: Partial<TemplateConfig>\n): Partial<TemplateConfig> {\n return {\n commands: {\n ...globalDefaults.commands,\n ...filterUndefined(detected.commands || {}),\n },\n paths: {\n ...globalDefaults.paths,\n ...filterUndefined(detected.paths || {}),\n },\n targets: {\n ...globalDefaults.targets,\n ...filterUndefined(detected.targets || {}),\n },\n tracking: {\n ...globalDefaults.tracking,\n ...filterUndefined(detected.tracking || {}),\n },\n techStack: {\n ...globalDefaults.techStack,\n ...filterUndefined(detected.techStack || {}),\n },\n environment: {\n ...globalDefaults.environment,\n ...filterUndefined(detected.environment || {}),\n },\n brand: {\n ...globalDefaults.brand,\n ...filterUndefined(detected.brand || {}),\n },\n };\n}\n\n/**\n * Filter out undefined values from an object\n */\nfunction filterUndefined<T extends object>(obj: T): Partial<T> {\n const result: Partial<T> = {};\n for (const [key, value] of Object.entries(obj)) {\n if (value !== undefined) {\n (result as Record<string, unknown>)[key] = value;\n }\n }\n return result;\n}\n\n/**\n * Check if global defaults exist\n */\nexport async function hasGlobalDefaults(): Promise<boolean> {\n try {\n const defaults = await readGlobalDefaults();\n return defaults.templateConfig !== undefined && Object.keys(defaults.templateConfig).length > 0;\n } catch {\n return false;\n }\n}\n\n/**\n * Clear global defaults\n */\nexport async function clearGlobalDefaults(): Promise<void> {\n const defaultsPath = getGlobalDefaultsPath();\n try {\n await fs.unlink(defaultsPath);\n } catch {\n // File doesn't exist\n }\n}\n\n/**\n * Get template config from global defaults\n */\nexport async function getGlobalTemplateConfig(): Promise<Partial<TemplateConfig>> {\n const defaults = await readGlobalDefaults();\n return defaults.templateConfig || {};\n}\n\n/**\n * Format global defaults for display\n */\nexport function formatGlobalDefaults(defaults: GlobalDefaults): string {\n const lines: string[] = [];\n\n lines.push('Global Defaults');\n lines.push('─'.repeat(40));\n\n if (defaults.lastUpdated) {\n lines.push(`Last updated: ${new Date(defaults.lastUpdated).toLocaleString()}`);\n lines.push('');\n }\n\n if (!defaults.templateConfig || Object.keys(defaults.templateConfig).length === 0) {\n lines.push('No template configuration saved');\n return lines.join('\\n');\n }\n\n const config = defaults.templateConfig;\n\n if (config.commands && Object.keys(config.commands).length > 0) {\n lines.push('Commands:');\n for (const [key, value] of Object.entries(config.commands)) {\n if (value) lines.push(` ${key}: ${value}`);\n }\n lines.push('');\n }\n\n if (config.paths && Object.keys(config.paths).length > 0) {\n lines.push('Paths:');\n for (const [key, value] of Object.entries(config.paths)) {\n if (value) lines.push(` ${key}: ${value}`);\n }\n lines.push('');\n }\n\n if (config.targets && Object.keys(config.targets).length > 0) {\n lines.push('Targets:');\n for (const [key, value] of Object.entries(config.targets)) {\n if (value !== undefined) lines.push(` ${key}: ${value}`);\n }\n lines.push('');\n }\n\n if (config.tracking && Object.keys(config.tracking).length > 0) {\n lines.push('Tracking:');\n for (const [key, value] of Object.entries(config.tracking)) {\n if (value !== undefined) lines.push(` ${key}: ${value}`);\n }\n lines.push('');\n }\n\n if (config.techStack && Object.keys(config.techStack).length > 0) {\n lines.push('Tech Stack:');\n for (const [key, value] of Object.entries(config.techStack)) {\n if (value) lines.push(` ${key}: ${value}`);\n }\n lines.push('');\n }\n\n if (config.environment && Object.keys(config.environment).length > 0) {\n lines.push('Environment:');\n for (const [key, value] of Object.entries(config.environment)) {\n if (value) lines.push(` ${key}: ${value}`);\n }\n lines.push('');\n }\n\n if (config.brand && Object.keys(config.brand).length > 0) {\n lines.push('Brand:');\n for (const [key, value] of Object.entries(config.brand)) {\n if (value) lines.push(` ${key}: ${value}`);\n }\n lines.push('');\n }\n\n return lines.join('\\n');\n}\n","/**\n * Modules exports\n */\n\n// Registry\nexport {\n loadRegistry,\n getModule,\n getAllModules,\n getModulesByTag,\n filterModules,\n getModuleIds,\n validateModuleIds,\n} from './registry.js';\n\n// Resolver\nexport {\n resolveModules,\n resolveAllModules,\n getDependents,\n checkRemovalImpact,\n getSuggestedModules,\n sortByDependencies,\n type ResolvedModule,\n type ResolutionResult,\n} from './resolver.js';\n\n// Installer\nexport {\n installModules,\n installAllModules,\n uninstallModule,\n isModuleInstalled,\n getInstalledModules,\n installExtras,\n removeConfigRequiredFromFrontmatter,\n type InstallOptions,\n type InstallResult,\n} from './installer.js';\n","/**\n * Module registry - reads and manages module definitions from templates\n */\n\nimport type {\n ModuleCategory,\n ModuleDefinition,\n ModuleRegistry,\n RegistryFile,\n} from '../../types/modules.js';\nimport { joinPath, listDirs, pathExists, readJson } from '../utils/fs.js';\nimport { logger } from '../utils/logger.js';\n\nconst REGISTRY_FILE = '_registry.json';\n\n/**\n * Load module registry from a templates directory\n */\nexport async function loadRegistry(templatesPath: string): Promise<ModuleRegistry> {\n const registry: ModuleRegistry = {\n agents: [],\n skills: [],\n commands: [],\n docs: [],\n };\n\n const categories: ModuleCategory[] = ['agents', 'skills', 'commands', 'docs'];\n\n for (const category of categories) {\n const categoryPath = joinPath(templatesPath, category);\n\n if (!(await pathExists(categoryPath))) {\n logger.debug(`Category path not found: ${categoryPath}`);\n continue;\n }\n\n const modules = await loadCategoryModules(categoryPath, category);\n registry[category] = modules;\n }\n\n return registry;\n}\n\n/**\n * Load modules for a specific category\n */\nasync function loadCategoryModules(\n categoryPath: string,\n category: ModuleCategory\n): Promise<ModuleDefinition[]> {\n const registryPath = joinPath(categoryPath, REGISTRY_FILE);\n\n // Try to load from _registry.json first\n if (await pathExists(registryPath)) {\n try {\n const registryFile = await readJson<RegistryFile>(registryPath);\n return registryFile.modules.map((item) => ({\n id: item.id,\n name: item.name,\n description: item.description || '',\n category,\n file: item.file,\n dependencies: item.dependencies || [],\n tags: item.tags || [],\n }));\n } catch (error) {\n logger.debug(`Failed to load registry from ${registryPath}: ${error}`);\n }\n }\n\n // Fallback: scan directory for .md files\n return scanCategoryDirectory(categoryPath, category);\n}\n\n/**\n * Scan directory for module files when no registry exists\n */\nasync function scanCategoryDirectory(\n categoryPath: string,\n category: ModuleCategory\n): Promise<ModuleDefinition[]> {\n const modules: ModuleDefinition[] = [];\n\n // Get subdirectories (groups like 'engineering', 'quality', etc.)\n const subdirs = await listDirs('*', { cwd: categoryPath });\n\n for (const subdir of subdirs) {\n if (subdir.startsWith('_')) continue; // Skip special directories\n\n const subdirPath = joinPath(categoryPath, subdir);\n const files = await scanForModuleFiles(subdirPath);\n\n for (const file of files) {\n const id = file.replace('.md', '');\n modules.push({\n id,\n name: formatName(id),\n description: '',\n category,\n file: `${subdir}/${file}`,\n dependencies: [],\n tags: [subdir],\n });\n }\n }\n\n // Also scan root of category\n const rootFiles = await scanForModuleFiles(categoryPath);\n for (const file of rootFiles) {\n if (file === REGISTRY_FILE) continue;\n\n const id = file.replace('.md', '');\n modules.push({\n id,\n name: formatName(id),\n description: '',\n category,\n file,\n dependencies: [],\n tags: [],\n });\n }\n\n return modules;\n}\n\n/**\n * Scan a directory for module files (.md)\n */\nasync function scanForModuleFiles(dirPath: string): Promise<string[]> {\n const { glob } = await import('glob');\n const files = await glob('*.md', { cwd: dirPath });\n return files.filter((f) => !f.startsWith('_') && f !== 'README.md');\n}\n\n/**\n * Format ID to display name\n */\nfunction formatName(id: string): string {\n return id\n .split('-')\n .map((word) => word.charAt(0).toUpperCase() + word.slice(1))\n .join(' ');\n}\n\n/**\n * Get module by ID from registry\n */\nexport function getModule(\n registry: ModuleRegistry,\n category: ModuleCategory,\n id: string\n): ModuleDefinition | undefined {\n return registry[category].find((m) => m.id === id);\n}\n\n/**\n * Get all modules from registry\n */\nexport function getAllModules(registry: ModuleRegistry): ModuleDefinition[] {\n return [...registry.agents, ...registry.skills, ...registry.commands, ...registry.docs];\n}\n\n/**\n * Get modules by tag\n */\nexport function getModulesByTag(\n registry: ModuleRegistry,\n category: ModuleCategory,\n tag: string\n): ModuleDefinition[] {\n return registry[category].filter((m) => m.tags?.includes(tag));\n}\n\n/**\n * Filter modules by IDs or tags\n * Presets use tags (e.g., 'core', 'quality'), so we match both IDs and tags\n */\nexport function filterModules(\n registry: ModuleRegistry,\n category: ModuleCategory,\n idsOrTags: string[]\n): ModuleDefinition[] {\n const filterSet = new Set(idsOrTags);\n return registry[category].filter((m) => {\n // Match by ID\n if (filterSet.has(m.id)) return true;\n // Match by any tag\n if (m.tags?.some((tag) => filterSet.has(tag))) return true;\n return false;\n });\n}\n\n/**\n * Get module IDs for a category\n */\nexport function getModuleIds(registry: ModuleRegistry, category: ModuleCategory): string[] {\n return registry[category].map((m) => m.id);\n}\n\n/**\n * Validate that all requested modules exist\n */\nexport function validateModuleIds(\n registry: ModuleRegistry,\n category: ModuleCategory,\n ids: string[]\n): { valid: string[]; invalid: string[] } {\n const available = new Set(getModuleIds(registry, category));\n const valid: string[] = [];\n const invalid: string[] = [];\n\n for (const id of ids) {\n if (available.has(id)) {\n valid.push(id);\n } else {\n invalid.push(id);\n }\n }\n\n return { valid, invalid };\n}\n","/**\n * Module resolver - resolves module dependencies and order\n */\n\nimport type { ModuleCategory, ModuleDefinition, ModuleRegistry } from '../../types/modules.js';\nimport { getAllModules, getModule } from './registry.js';\n\nexport interface ResolvedModule extends ModuleDefinition {\n resolvedDependencies: string[];\n installOrder: number;\n}\n\nexport interface ResolutionResult {\n resolved: ResolvedModule[];\n unresolved: string[];\n circular: string[];\n}\n\n/**\n * Resolve dependencies for selected modules\n */\nexport function resolveModules(\n registry: ModuleRegistry,\n category: ModuleCategory,\n selectedIds: string[]\n): ResolutionResult {\n const resolved: Map<string, ResolvedModule> = new Map();\n const unresolved: string[] = [];\n const circular: string[] = [];\n const visiting = new Set<string>();\n let order = 0;\n\n function visit(id: string): boolean {\n if (resolved.has(id)) return true;\n\n if (visiting.has(id)) {\n circular.push(id);\n return false;\n }\n\n const module = getModule(registry, category, id);\n if (!module) {\n unresolved.push(id);\n return false;\n }\n\n visiting.add(id);\n\n // Resolve dependencies first\n const resolvedDeps: string[] = [];\n for (const depId of module.dependencies || []) {\n if (visit(depId)) {\n resolvedDeps.push(depId);\n }\n }\n\n visiting.delete(id);\n\n // Add this module\n resolved.set(id, {\n ...module,\n resolvedDependencies: resolvedDeps,\n installOrder: order++,\n });\n\n return true;\n }\n\n // Visit all selected modules\n for (const id of selectedIds) {\n visit(id);\n }\n\n return {\n resolved: Array.from(resolved.values()).sort((a, b) => a.installOrder - b.installOrder),\n unresolved,\n circular,\n };\n}\n\n/**\n * Resolve all dependencies for a set of modules across all categories\n */\nexport function resolveAllModules(\n registry: ModuleRegistry,\n selection: Record<ModuleCategory, string[]>\n): Record<ModuleCategory, ResolutionResult> {\n const categories: ModuleCategory[] = ['agents', 'skills', 'commands', 'docs'];\n const results: Record<ModuleCategory, ResolutionResult> = {} as Record<\n ModuleCategory,\n ResolutionResult\n >;\n\n for (const category of categories) {\n results[category] = resolveModules(registry, category, selection[category] || []);\n }\n\n return results;\n}\n\n/**\n * Get modules that depend on a given module\n */\nexport function getDependents(\n registry: ModuleRegistry,\n category: ModuleCategory,\n moduleId: string\n): ModuleDefinition[] {\n return registry[category].filter((m) => m.dependencies?.includes(moduleId));\n}\n\n/**\n * Check if removing a module would break dependencies\n */\nexport function checkRemovalImpact(\n registry: ModuleRegistry,\n category: ModuleCategory,\n moduleId: string,\n installedIds: string[]\n): { canRemove: boolean; blockedBy: string[] } {\n const dependents = getDependents(registry, category, moduleId);\n const blockedBy = dependents.filter((d) => installedIds.includes(d.id)).map((d) => d.id);\n\n return {\n canRemove: blockedBy.length === 0,\n blockedBy,\n };\n}\n\n/**\n * Get suggested modules based on installed ones\n */\nexport function getSuggestedModules(\n registry: ModuleRegistry,\n installedModules: Record<ModuleCategory, string[]>\n): ModuleDefinition[] {\n const suggestions: ModuleDefinition[] = [];\n const allInstalled = new Set<string>();\n\n // Collect all installed module IDs\n for (const ids of Object.values(installedModules)) {\n for (const id of ids) {\n allInstalled.add(id);\n }\n }\n\n // Find modules with tags that match installed modules\n const allModules = getAllModules(registry);\n const installedTags = new Set<string>();\n\n for (const module of allModules) {\n if (allInstalled.has(module.id)) {\n for (const tag of module.tags || []) {\n installedTags.add(tag);\n }\n }\n }\n\n // Suggest modules with matching tags that aren't installed\n for (const module of allModules) {\n if (allInstalled.has(module.id)) continue;\n\n const hasMatchingTag = (module.tags || []).some((tag) => installedTags.has(tag));\n if (hasMatchingTag) {\n suggestions.push(module);\n }\n }\n\n return suggestions;\n}\n\n/**\n * Sort modules by install order (dependencies first)\n */\nexport function sortByDependencies(modules: ModuleDefinition[]): ModuleDefinition[] {\n const sorted: ModuleDefinition[] = [];\n const visited = new Set<string>();\n const moduleMap = new Map(modules.map((m) => [m.id, m]));\n\n function visit(module: ModuleDefinition): void {\n if (visited.has(module.id)) return;\n visited.add(module.id);\n\n // Visit dependencies first\n for (const depId of module.dependencies || []) {\n const dep = moduleMap.get(depId);\n if (dep) {\n visit(dep);\n }\n }\n\n sorted.push(module);\n }\n\n for (const module of modules) {\n visit(module);\n }\n\n return sorted;\n}\n","/**\n * Module installer - copies and configures module files\n */\n\nimport type { ModuleCategory, ModuleDefinition } from '../../types/modules.js';\nimport {\n copy,\n dirname,\n ensureDir,\n joinPath,\n pathExists,\n readFile,\n writeFile,\n} from '../utils/fs.js';\nimport { logger } from '../utils/logger.js';\nimport { withSpinner } from '../utils/spinner.js';\n\n/**\n * Remove config_required section from YAML frontmatter in markdown files\n * This cleans up template files after installation\n */\nexport function removeConfigRequiredFromFrontmatter(content: string): string {\n // Match YAML frontmatter (starts with ---, ends with ---)\n const frontmatterRegex = /^---\\n([\\s\\S]*?)\\n---/;\n const match = content.match(frontmatterRegex);\n\n if (!match) {\n return content;\n }\n\n const frontmatter = match[1];\n\n // Remove config_required section from frontmatter\n // It can be multi-line with indented items like:\n // config_required:\n // - KEY: \"description\"\n // - KEY2: \"description2\"\n // The regex needs to match the key and all following indented lines\n const configRequiredRegex = /config_required:\\s*\\n(?:\\s+-\\s+[^\\n]+\\n?)*/g;\n const cleanedFrontmatter = frontmatter.replace(configRequiredRegex, '').trim();\n\n // Reconstruct the file\n const restOfFile = content.slice(match[0].length);\n\n // If frontmatter is now empty except for required fields, keep it minimal\n if (cleanedFrontmatter.trim() === '') {\n return restOfFile.trim();\n }\n\n return `---\\n${cleanedFrontmatter}\\n---${restOfFile}`;\n}\n\n/**\n * Process a module file after copying to clean up config_required\n */\nasync function processModuleFile(filePath: string): Promise<void> {\n // Only process markdown files\n if (!filePath.endsWith('.md')) {\n return;\n }\n\n try {\n const content = await readFile(filePath);\n const cleanedContent = removeConfigRequiredFromFrontmatter(content);\n\n // Only write if content changed\n if (cleanedContent !== content) {\n await writeFile(filePath, cleanedContent);\n logger.debug(`Cleaned config_required from: ${filePath}`);\n }\n } catch (error) {\n logger.debug(`Failed to process module file ${filePath}: ${error}`);\n }\n}\n\nexport interface InstallOptions {\n templatesPath: string;\n targetPath: string;\n overwrite?: boolean;\n dryRun?: boolean;\n}\n\nexport interface InstallResult {\n success: boolean;\n installed: string[];\n skipped: string[];\n failed: Array<{ id: string; error: string }>;\n}\n\n/**\n * Install modules for a category\n */\nexport async function installModules(\n category: ModuleCategory,\n modules: ModuleDefinition[],\n options: InstallOptions\n): Promise<InstallResult> {\n const result: InstallResult = {\n success: true,\n installed: [],\n skipped: [],\n failed: [],\n };\n\n const categorySourcePath = joinPath(options.templatesPath, category);\n const categoryTargetPath = joinPath(options.targetPath, '.claude', category);\n\n // Ensure target directory exists\n if (!options.dryRun) {\n await ensureDir(categoryTargetPath);\n }\n\n for (const module of modules) {\n try {\n const sourcePath = joinPath(categorySourcePath, module.file);\n const targetPath = joinPath(categoryTargetPath, module.file);\n\n // Check if source exists\n if (!(await pathExists(sourcePath))) {\n result.failed.push({ id: module.id, error: `Source file not found: ${sourcePath}` });\n result.success = false;\n continue;\n }\n\n // Check if target exists\n const targetExists = await pathExists(targetPath);\n if (targetExists && !options.overwrite) {\n result.skipped.push(module.id);\n continue;\n }\n\n if (options.dryRun) {\n logger.debug(`Would install: ${module.id} -> ${targetPath}`);\n result.installed.push(module.id);\n continue;\n }\n\n // Ensure target directory exists\n await ensureDir(dirname(targetPath));\n\n // Copy file\n await copy(sourcePath, targetPath, { overwrite: options.overwrite });\n\n // Process the file to clean up config_required\n await processModuleFile(targetPath);\n\n result.installed.push(module.id);\n\n logger.debug(`Installed: ${module.id}`);\n } catch (error) {\n const errorMessage = error instanceof Error ? error.message : 'Unknown error';\n result.failed.push({ id: module.id, error: errorMessage });\n result.success = false;\n }\n }\n\n return result;\n}\n\n/**\n * Install README file for a category\n */\nasync function installCategoryReadme(\n category: ModuleCategory,\n options: InstallOptions\n): Promise<void> {\n const sourceReadme = joinPath(options.templatesPath, category, 'README.md');\n const targetReadme = joinPath(options.targetPath, '.claude', category, 'README.md');\n\n // Check if source README exists\n if (!(await pathExists(sourceReadme))) {\n logger.debug(`No README found for category: ${category}`);\n return;\n }\n\n // Check if target exists\n const targetExists = await pathExists(targetReadme);\n if (targetExists && !options.overwrite) {\n logger.debug(`README already exists for ${category}, skipping`);\n return;\n }\n\n if (options.dryRun) {\n logger.debug(`Would install README for ${category}`);\n return;\n }\n\n try {\n await copy(sourceReadme, targetReadme, { overwrite: options.overwrite });\n logger.debug(`Installed README for ${category}`);\n } catch (error) {\n logger.debug(`Failed to install README for ${category}: ${error}`);\n }\n}\n\n/**\n * Install all modules with progress tracking\n */\nexport async function installAllModules(\n modulesByCategory: Record<ModuleCategory, ModuleDefinition[]>,\n options: InstallOptions\n): Promise<Record<ModuleCategory, InstallResult>> {\n const results: Record<ModuleCategory, InstallResult> = {} as Record<\n ModuleCategory,\n InstallResult\n >;\n const categories: ModuleCategory[] = ['agents', 'skills', 'commands', 'docs'];\n\n for (const category of categories) {\n const modules = modulesByCategory[category] || [];\n if (modules.length === 0) {\n results[category] = {\n success: true,\n installed: [],\n skipped: [],\n failed: [],\n };\n continue;\n }\n\n results[category] = await withSpinner(\n `Installing ${category} (${modules.length} modules)...`,\n () => installModules(category, modules, options),\n {\n successText: `Installed ${modules.length} ${category}`,\n silent: options.dryRun,\n }\n );\n\n // Install README for this category\n await installCategoryReadme(category, options);\n }\n\n return results;\n}\n\n/**\n * Uninstall a module\n */\nexport async function uninstallModule(\n category: ModuleCategory,\n moduleId: string,\n targetPath: string\n): Promise<{ success: boolean; error?: string }> {\n const { remove } = await import('../utils/fs.js');\n\n try {\n const modulePath = joinPath(targetPath, '.claude', category, `${moduleId}.md`);\n\n if (!(await pathExists(modulePath))) {\n return { success: false, error: 'Module file not found' };\n }\n\n await remove(modulePath);\n return { success: true };\n } catch (error) {\n return {\n success: false,\n error: error instanceof Error ? error.message : 'Unknown error',\n };\n }\n}\n\n/**\n * Check if a module is installed\n */\nexport async function isModuleInstalled(\n category: ModuleCategory,\n moduleId: string,\n targetPath: string\n): Promise<boolean> {\n // Try common file patterns\n const patterns = [\n joinPath(targetPath, '.claude', category, `${moduleId}.md`),\n joinPath(targetPath, '.claude', category, '**', `${moduleId}.md`),\n ];\n\n for (const pattern of patterns) {\n if (await pathExists(pattern)) {\n return true;\n }\n }\n\n return false;\n}\n\n/**\n * Get installed modules for a category\n */\nexport async function getInstalledModules(\n category: ModuleCategory,\n targetPath: string\n): Promise<string[]> {\n const { listFiles } = await import('../utils/fs.js');\n\n const categoryPath = joinPath(targetPath, '.claude', category);\n if (!(await pathExists(categoryPath))) {\n return [];\n }\n\n const files = await listFiles('**/*.md', { cwd: categoryPath });\n return files\n .filter((f) => !f.startsWith('_') && f !== 'README.md')\n .map((f) => {\n const parts = f.replace(/\\.md$/, '').split('/');\n return parts[parts.length - 1] ?? '';\n })\n .filter(Boolean);\n}\n\n/**\n * Copy extra files (schemas, scripts, hooks, sessions)\n */\nexport async function installExtras(\n extras: { schemas?: boolean; scripts?: boolean; hooks?: boolean; sessions?: boolean },\n options: InstallOptions\n): Promise<InstallResult> {\n const result: InstallResult = {\n success: true,\n installed: [],\n skipped: [],\n failed: [],\n };\n\n const extraDirs = [\n { name: 'schemas', enabled: extras.schemas },\n { name: 'scripts', enabled: extras.scripts },\n { name: 'hooks', enabled: extras.hooks },\n { name: 'sessions', enabled: extras.sessions },\n ];\n\n for (const { name, enabled } of extraDirs) {\n if (!enabled) continue;\n\n const sourcePath = joinPath(options.templatesPath, name);\n const targetPath = joinPath(options.targetPath, '.claude', name);\n\n if (!(await pathExists(sourcePath))) {\n logger.debug(`Extra directory not found: ${sourcePath}`);\n continue;\n }\n\n try {\n if (options.dryRun) {\n logger.debug(`Would copy: ${name} -> ${targetPath}`);\n result.installed.push(name);\n continue;\n }\n\n const targetExists = await pathExists(targetPath);\n if (targetExists && !options.overwrite) {\n result.skipped.push(name);\n continue;\n }\n\n await copy(sourcePath, targetPath, { overwrite: options.overwrite });\n result.installed.push(name);\n } catch (error) {\n const errorMessage = error instanceof Error ? error.message : 'Unknown error';\n result.failed.push({ id: name, error: errorMessage });\n result.success = false;\n }\n }\n\n return result;\n}\n","/**\n * Spinner utility for progress indication\n */\n\nimport ora, { type Ora } from 'ora';\nimport pc from 'picocolors';\n\ninterface SpinnerOptions {\n text?: string;\n color?: 'black' | 'red' | 'green' | 'yellow' | 'blue' | 'magenta' | 'cyan' | 'white' | 'gray';\n}\n\nclass SpinnerManager {\n private spinner: Ora | null = null;\n private silent = false;\n\n configure(options: { silent?: boolean }): void {\n if (options.silent !== undefined) this.silent = options.silent;\n }\n\n /**\n * Start a spinner with a message\n */\n start(text: string, options?: SpinnerOptions): Ora | null {\n if (this.silent) return null;\n\n // Stop any existing spinner\n this.stop();\n\n this.spinner = ora({\n text,\n color: options?.color || 'cyan',\n spinner: 'dots',\n }).start();\n\n return this.spinner;\n }\n\n /**\n * Update spinner text\n */\n text(text: string): void {\n if (this.spinner) {\n this.spinner.text = text;\n }\n }\n\n /**\n * Stop spinner with success message\n */\n succeed(text?: string): void {\n if (this.spinner) {\n this.spinner.succeed(text);\n this.spinner = null;\n }\n }\n\n /**\n * Stop spinner with failure message\n */\n fail(text?: string): void {\n if (this.spinner) {\n this.spinner.fail(text);\n this.spinner = null;\n }\n }\n\n /**\n * Stop spinner with warning message\n */\n warn(text?: string): void {\n if (this.spinner) {\n this.spinner.warn(text);\n this.spinner = null;\n }\n }\n\n /**\n * Stop spinner with info message\n */\n info(text?: string): void {\n if (this.spinner) {\n this.spinner.info(text);\n this.spinner = null;\n }\n }\n\n /**\n * Stop spinner without message\n */\n stop(): void {\n if (this.spinner) {\n this.spinner.stop();\n this.spinner = null;\n }\n }\n\n /**\n * Check if spinner is running\n */\n isRunning(): boolean {\n return this.spinner?.isSpinning ?? false;\n }\n}\n\n// Export singleton instance\nexport const spinner = new SpinnerManager();\n\n/**\n * Execute an async operation with a spinner\n */\nexport async function withSpinner<T>(\n text: string,\n operation: () => Promise<T>,\n options?: {\n successText?: string;\n failText?: string;\n silent?: boolean;\n }\n): Promise<T> {\n if (options?.silent) {\n return operation();\n }\n\n spinner.start(text);\n\n try {\n const result = await operation();\n spinner.succeed(options?.successText || text);\n return result;\n } catch (error) {\n const errorMessage = error instanceof Error ? error.message : 'Unknown error';\n spinner.fail(options?.failText || `${text} - ${pc.red(errorMessage)}`);\n throw error;\n }\n}\n\n/**\n * Create a progress indicator for multiple steps\n */\nexport function createProgressTracker(totalSteps: number, options?: { silent?: boolean }) {\n let currentStep = 0;\n\n return {\n next(stepText: string): void {\n currentStep++;\n if (!options?.silent) {\n spinner.start(`[${currentStep}/${totalSteps}] ${stepText}`);\n }\n },\n\n complete(text?: string): void {\n if (!options?.silent) {\n spinner.succeed(text || `[${currentStep}/${totalSteps}] Done`);\n }\n },\n\n fail(text?: string): void {\n if (!options?.silent) {\n spinner.fail(text);\n }\n },\n\n get current(): number {\n return currentStep;\n },\n\n get total(): number {\n return totalSteps;\n },\n };\n}\n","/**\n * Placeholders exports\n */\n\nexport {\n replaceInFile,\n replaceInDirectory,\n replacePlaceholders,\n showReplacementReport,\n} from './replacer.js';\n","/**\n * Placeholder replacer - finds and replaces placeholders in files\n */\n\nimport { PLACEHOLDERS, applyTransform } from '../../constants/placeholders.js';\nimport type { ProjectInfo } from '../../types/config.js';\nimport type {\n PlaceholderDefinition,\n PlaceholderReplacement,\n PlaceholderReport,\n} from '../../types/placeholders.js';\nimport { joinPath, listFiles, readFile, writeFile } from '../utils/fs.js';\nimport { logger } from '../utils/logger.js';\nimport { withSpinner } from '../utils/spinner.js';\n\n/**\n * Replace placeholders in a single file\n */\nexport async function replaceInFile(\n filePath: string,\n projectInfo: ProjectInfo,\n placeholders: PlaceholderDefinition[] = PLACEHOLDERS\n): Promise<PlaceholderReplacement[]> {\n const replacements: PlaceholderReplacement[] = [];\n let content = await readFile(filePath);\n let modified = false;\n\n for (const placeholder of placeholders) {\n const value = projectInfo[placeholder.configKey];\n\n if (value === undefined || value === null) {\n continue;\n }\n\n const transformedValue = applyTransform(String(value), placeholder.transform);\n const pattern = placeholder.pattern;\n\n if (pattern instanceof RegExp) {\n const matches = content.matchAll(new RegExp(pattern.source, 'g'));\n\n for (const match of matches) {\n const lineNumber = getLineNumber(content, match.index ?? 0);\n replacements.push({\n file: filePath,\n line: lineNumber,\n original: match[0],\n replacement: transformedValue,\n placeholder,\n });\n }\n\n if (pattern.test(content)) {\n content = content.replace(pattern, transformedValue);\n modified = true;\n }\n } else {\n // String pattern\n const regex = new RegExp(escapeRegex(pattern), 'g');\n const matches = content.matchAll(regex);\n\n for (const match of matches) {\n const lineNumber = getLineNumber(content, match.index ?? 0);\n replacements.push({\n file: filePath,\n line: lineNumber,\n original: match[0],\n replacement: transformedValue,\n placeholder,\n });\n }\n\n if (content.includes(pattern)) {\n content = content.replace(regex, transformedValue);\n modified = true;\n }\n }\n }\n\n if (modified) {\n await writeFile(filePath, content);\n }\n\n return replacements;\n}\n\n/**\n * Replace placeholders in all files in a directory\n */\nexport async function replaceInDirectory(\n dirPath: string,\n projectInfo: ProjectInfo,\n options?: {\n extensions?: string[];\n exclude?: string[];\n dryRun?: boolean;\n }\n): Promise<PlaceholderReport> {\n const extensions = options?.extensions || ['md', 'json', 'yaml', 'yml', 'ts', 'js', 'tsx', 'jsx'];\n const exclude = options?.exclude || ['node_modules', '.git', 'dist', 'build'];\n\n const pattern = `**/*.{${extensions.join(',')}}`;\n const files = await listFiles(pattern, {\n cwd: dirPath,\n ignore: exclude.map((e) => `**/${e}/**`),\n });\n\n const report: PlaceholderReport = {\n totalFiles: files.length,\n filesModified: 0,\n replacements: [],\n unreplacedPlaceholders: [],\n };\n\n for (const file of files) {\n const filePath = joinPath(dirPath, file);\n\n try {\n const replacements = options?.dryRun\n ? await scanFile(filePath, projectInfo)\n : await replaceInFile(filePath, projectInfo);\n\n if (replacements.length > 0) {\n report.filesModified++;\n report.replacements.push(...replacements);\n }\n } catch (error) {\n logger.debug(`Failed to process ${file}: ${error}`);\n }\n }\n\n // Find unreplaced placeholders\n report.unreplacedPlaceholders = findUnreplacedPlaceholders(projectInfo);\n\n return report;\n}\n\n/**\n * Scan file for placeholders without replacing\n */\nasync function scanFile(\n filePath: string,\n projectInfo: ProjectInfo\n): Promise<PlaceholderReplacement[]> {\n const replacements: PlaceholderReplacement[] = [];\n const content = await readFile(filePath);\n\n for (const placeholder of PLACEHOLDERS) {\n const value = projectInfo[placeholder.configKey];\n\n if (value === undefined || value === null) {\n continue;\n }\n\n const transformedValue = applyTransform(String(value), placeholder.transform);\n const pattern = placeholder.pattern;\n\n const regex =\n pattern instanceof RegExp\n ? new RegExp(pattern.source, 'g')\n : new RegExp(escapeRegex(pattern), 'g');\n\n const matches = content.matchAll(regex);\n\n for (const match of matches) {\n const lineNumber = getLineNumber(content, match.index ?? 0);\n replacements.push({\n file: filePath,\n line: lineNumber,\n original: match[0],\n replacement: transformedValue,\n placeholder,\n });\n }\n }\n\n return replacements;\n}\n\n/**\n * Replace placeholders with spinner\n */\nexport async function replacePlaceholders(\n dirPath: string,\n projectInfo: ProjectInfo,\n options?: {\n extensions?: string[];\n exclude?: string[];\n dryRun?: boolean;\n silent?: boolean;\n }\n): Promise<PlaceholderReport> {\n return withSpinner(\n 'Replacing placeholders...',\n () => replaceInDirectory(dirPath, projectInfo, options),\n {\n successText: 'Placeholders replaced',\n silent: options?.silent || options?.dryRun,\n }\n );\n}\n\n/**\n * Find placeholders that couldn't be replaced due to missing values\n */\nfunction findUnreplacedPlaceholders(projectInfo: ProjectInfo): string[] {\n const unreplaced: string[] = [];\n\n for (const placeholder of PLACEHOLDERS) {\n if (!placeholder.required) continue;\n\n const value = projectInfo[placeholder.configKey];\n if (value === undefined || value === null || value === '') {\n const patternStr =\n placeholder.pattern instanceof RegExp ? placeholder.pattern.source : placeholder.pattern;\n unreplaced.push(patternStr);\n }\n }\n\n return unreplaced;\n}\n\n/**\n * Get line number from string index\n */\nfunction getLineNumber(content: string, index: number): number {\n return content.slice(0, index).split('\\n').length;\n}\n\n/**\n * Escape regex special characters\n */\nfunction escapeRegex(str: string): string {\n return str.replace(/[.*+?^${}()|[\\]\\\\]/g, '\\\\$&');\n}\n\n/**\n * Show replacement report\n */\nexport function showReplacementReport(report: PlaceholderReport): void {\n logger.newline();\n logger.subtitle('Placeholder Replacement Report');\n logger.keyValue('Files scanned', String(report.totalFiles));\n logger.keyValue('Files modified', String(report.filesModified));\n logger.keyValue('Replacements', String(report.replacements.length));\n\n if (report.unreplacedPlaceholders.length > 0) {\n logger.newline();\n logger.warn('Unreplaced placeholders (missing values):');\n for (const p of report.unreplacedPlaceholders) {\n logger.item(p);\n }\n }\n}\n","/**\n * Project detector - detects existing project type and configuration\n */\n\nimport type {\n DetectionSignal,\n PackageManager,\n ProjectDetectionResult,\n ProjectType,\n} from '../../types/scaffold.js';\nimport { joinPath, pathExists, readJson } from '../utils/fs.js';\n\ninterface PackageJson {\n name?: string;\n description?: string;\n dependencies?: Record<string, string>;\n devDependencies?: Record<string, string>;\n scripts?: Record<string, string>;\n workspaces?: string[] | { packages: string[] };\n}\n\n/**\n * Detect project type and configuration\n */\nexport async function detectProject(projectPath: string): Promise<ProjectDetectionResult> {\n const signals: DetectionSignal[] = [];\n\n // Check for package.json\n const packageJsonPath = joinPath(projectPath, 'package.json');\n const hasPackageJson = await pathExists(packageJsonPath);\n\n if (!hasPackageJson) {\n return {\n detected: false,\n confidence: 'low',\n signals: [{ file: 'package.json', exists: false, indicates: 'not a Node.js project' }],\n };\n }\n\n signals.push({ file: 'package.json', exists: true, indicates: 'Node.js project' });\n\n // Read package.json\n const packageJson = await readJson<PackageJson>(packageJsonPath).catch(() => ({}) as PackageJson);\n\n // Detect package manager\n const packageManager = await detectPackageManager(projectPath);\n if (packageManager) {\n signals.push({\n file: `${packageManager}-lock`,\n exists: true,\n indicates: `${packageManager} package manager`,\n });\n }\n\n // Detect project type\n const typeResult = await detectProjectType(projectPath, packageJson);\n const projectType = typeResult.type;\n signals.push(...typeResult.signals);\n\n // Determine confidence\n const confidence: 'high' | 'medium' | 'low' =\n projectType && packageManager ? 'high' : projectType || packageManager ? 'medium' : 'low';\n\n // Suggest bundles based on project type\n const suggestedBundles = suggestBundles(projectType, packageJson);\n\n return {\n detected: true,\n projectType,\n packageManager,\n suggestedBundles,\n confidence,\n signals,\n };\n}\n\n/**\n * Detect package manager\n */\nasync function detectPackageManager(projectPath: string): Promise<PackageManager | undefined> {\n const lockFiles: Array<{ file: string; manager: PackageManager }> = [\n { file: 'pnpm-lock.yaml', manager: 'pnpm' },\n { file: 'yarn.lock', manager: 'yarn' },\n { file: 'package-lock.json', manager: 'npm' },\n { file: 'bun.lockb', manager: 'bun' },\n ];\n\n for (const { file, manager } of lockFiles) {\n if (await pathExists(joinPath(projectPath, file))) {\n return manager;\n }\n }\n\n return undefined;\n}\n\n/**\n * Detect project type from configuration files\n */\nasync function detectProjectType(\n projectPath: string,\n packageJson: PackageJson\n): Promise<{ type: ProjectType | undefined; signals: DetectionSignal[] }> {\n const signals: DetectionSignal[] = [];\n const deps = { ...packageJson.dependencies, ...packageJson.devDependencies };\n\n // Check for monorepo\n if (\n (await pathExists(joinPath(projectPath, 'turbo.json'))) ||\n (await pathExists(joinPath(projectPath, 'pnpm-workspace.yaml'))) ||\n packageJson.workspaces\n ) {\n signals.push({ file: 'turbo.json/pnpm-workspace.yaml', exists: true, indicates: 'monorepo' });\n return { type: 'monorepo', signals };\n }\n\n // Check for Astro\n if (\n (await pathExists(joinPath(projectPath, 'astro.config.mjs'))) ||\n (await pathExists(joinPath(projectPath, 'astro.config.ts'))) ||\n deps.astro\n ) {\n signals.push({ file: 'astro.config.*', exists: true, indicates: 'Astro project' });\n return { type: 'astro', signals };\n }\n\n // Check for Next.js\n if (\n (await pathExists(joinPath(projectPath, 'next.config.js'))) ||\n (await pathExists(joinPath(projectPath, 'next.config.mjs'))) ||\n (await pathExists(joinPath(projectPath, 'next.config.ts'))) ||\n deps.next\n ) {\n signals.push({ file: 'next.config.*', exists: true, indicates: 'Next.js project' });\n return { type: 'nextjs', signals };\n }\n\n // Check for Vite + React\n if (\n ((await pathExists(joinPath(projectPath, 'vite.config.ts'))) ||\n (await pathExists(joinPath(projectPath, 'vite.config.js')))) &&\n (deps.react || deps['react-dom'])\n ) {\n signals.push({ file: 'vite.config.*', exists: true, indicates: 'Vite project' });\n signals.push({ file: 'react dependency', exists: true, indicates: 'React project' });\n return { type: 'vite-react', signals };\n }\n\n // Check for Hono\n if (deps.hono) {\n signals.push({ file: 'hono dependency', exists: true, indicates: 'Hono API project' });\n return { type: 'hono', signals };\n }\n\n // Default to Node.js\n if (deps.typescript || (await pathExists(joinPath(projectPath, 'tsconfig.json')))) {\n signals.push({ file: 'tsconfig.json', exists: true, indicates: 'TypeScript project' });\n return { type: 'node', signals };\n }\n\n return { type: 'node', signals };\n}\n\n/**\n * Suggest bundles based on project type and dependencies\n */\nfunction suggestBundles(projectType: ProjectType | undefined, packageJson: PackageJson): string[] {\n const deps = { ...packageJson.dependencies, ...packageJson.devDependencies };\n const suggestedBundles: string[] = [];\n\n // Detect backend framework\n const hasHono = deps.hono || deps['@hono/node-server'];\n const hasExpress = deps.express;\n const hasFastify = deps.fastify;\n const hasNestjs = deps['@nestjs/core'];\n\n // Detect database ORM\n const hasDrizzle = deps.drizzle || deps['drizzle-orm'];\n const hasPrisma = deps.prisma || deps['@prisma/client'];\n const hasMongoose = deps.mongoose;\n\n // Detect frontend framework\n const hasReact = deps.react;\n const hasTanstack = deps['@tanstack/react-router'] || deps['@tanstack/start'];\n\n // Stack bundles based on detected technologies\n switch (projectType) {\n case 'astro':\n suggestedBundles.push('astro-react-stack');\n break;\n\n case 'nextjs':\n if (hasPrisma) {\n suggestedBundles.push('nextjs-prisma-stack');\n } else {\n // Just React + TanStack for Next.js without Prisma\n suggestedBundles.push('react-tanstack-stack');\n }\n break;\n\n case 'vite-react':\n suggestedBundles.push('react-tanstack-stack');\n break;\n\n case 'hono':\n if (hasDrizzle) {\n suggestedBundles.push('hono-drizzle-stack');\n } else if (hasPrisma) {\n suggestedBundles.push('hono-api');\n suggestedBundles.push('prisma-database');\n } else {\n suggestedBundles.push('hono-api');\n }\n break;\n\n case 'monorepo':\n // For monorepos, suggest based on detected technologies\n if (hasReact && hasTanstack) {\n suggestedBundles.push('react-tanstack-stack');\n }\n if (hasHono && hasDrizzle) {\n suggestedBundles.push('hono-drizzle-stack');\n } else if (hasHono) {\n suggestedBundles.push('hono-api');\n }\n break;\n\n case 'node':\n // Detect API framework\n if (hasHono) {\n if (hasDrizzle) {\n suggestedBundles.push('hono-drizzle-stack');\n } else {\n suggestedBundles.push('hono-api');\n }\n } else if (hasExpress) {\n if (hasPrisma) {\n suggestedBundles.push('express-prisma-stack');\n } else {\n suggestedBundles.push('express-api');\n }\n } else if (hasFastify) {\n suggestedBundles.push('fastify-api');\n } else if (hasNestjs) {\n suggestedBundles.push('nestjs-api');\n }\n break;\n }\n\n // Add database bundle if ORM detected but not in a stack\n if (hasDrizzle && !suggestedBundles.some((b) => b.includes('drizzle'))) {\n suggestedBundles.push('drizzle-database');\n }\n if (hasPrisma && !suggestedBundles.some((b) => b.includes('prisma'))) {\n suggestedBundles.push('prisma-database');\n }\n if (hasMongoose) {\n suggestedBundles.push('mongoose-database');\n }\n\n // Always suggest minimal testing and quality\n if (suggestedBundles.length > 0) {\n suggestedBundles.push('testing-minimal');\n suggestedBundles.push('quality-minimal');\n }\n\n // Add git workflow for all projects\n suggestedBundles.push('git-workflow');\n\n return suggestedBundles;\n}\n\n/**\n * Get project name from package.json or directory\n */\nexport async function getProjectName(projectPath: string): Promise<string | undefined> {\n try {\n const packageJson = await readJson<PackageJson>(joinPath(projectPath, 'package.json'));\n return packageJson.name;\n } catch {\n // Return directory name\n const parts = projectPath.split('/');\n return parts[parts.length - 1];\n }\n}\n\n/**\n * Get project description from package.json\n */\nexport async function getProjectDescription(projectPath: string): Promise<string | undefined> {\n try {\n const packageJson = await readJson<PackageJson>(joinPath(projectPath, 'package.json'));\n return packageJson.description;\n } catch {\n return undefined;\n }\n}\n\n/**\n * Check if project has existing Claude configuration\n */\nexport async function hasExistingClaudeConfig(projectPath: string): Promise<boolean> {\n return pathExists(joinPath(projectPath, '.claude'));\n}\n","/**\n * Template processing module\n *\n * Provides template directive parsing and processing for dynamic content generation.\n *\n * Supported directives:\n * - {{#if condition}}...{{/if}} - Conditional blocks\n * - {{#unless condition}}...{{/unless}} - Inverse conditionals\n * - {{#each items}}...{{/each}} - Loops over arrays\n * - {{#section name}}...{{/section}} - Named sections\n * - {{variable}} - Variable replacement\n * - {{variable | transform}} - Variable with transform\n *\n * Available transforms:\n * - lowercase, upper - Case transforms\n * - capitalize, title - Title case\n * - kebab, snake, camel, pascal - Naming conventions\n * - json - JSON stringify\n * - count - Array/string length\n * - first, last - First/last element\n * - join, joinlines - Join arrays\n * - bullet, numbered - List formatting\n */\n\n// Parser exports\nexport { parseDirectives, parseExpression, parseVariable, findVariables, hasDirectives, validateTemplate } from './parser.js';\n\n// Evaluator exports\nexport {\n getContextValue,\n evaluateCondition,\n isTruthy,\n getIterable,\n applyTemplateTransform,\n createLoopContext,\n} from './evaluator.js';\n\n// Processor exports\nexport {\n processTemplate,\n processTemplateFile,\n processTemplatesInDirectory,\n processTemplates,\n showTemplateReport,\n} from './processor.js';\n\n// Context exports\nexport {\n buildTemplateContext,\n extendContext,\n addCustomVariable,\n hasModule,\n hasAnyModule,\n hasAllModules,\n getAllModules,\n} from './context.js';\n\n// Scanner exports\nexport {\n extractPlaceholders,\n scanForPlaceholders,\n getUnconfiguredPlaceholders,\n getMissingRequiredPlaceholders,\n formatScanSummary,\n listAllConfigurablePlaceholders,\n} from './scanner.js';\n\n// Config replacer exports\nexport {\n flattenTemplateConfig,\n replaceTemplatePlaceholders,\n replaceTemplateConfigWithSpinner,\n formatReplacementReport,\n previewReplacements,\n} from './config-replacer.js';\n","/**\n * Template directive parser\n * Parses template directives like {{#if}}, {{#each}}, etc.\n */\n\nimport type { TemplateDirective, TemplateDirectiveType } from '../../types/templates.js';\n\n/**\n * Directive patterns\n *\n * Supported syntax:\n * - {{#if condition}}...{{/if}}\n * - {{#unless condition}}...{{/unless}}\n * - {{#each items}}...{{/each}}\n * - {{#section name}}...{{/section}}\n * - {{> partialName}}\n * - {{variable}}\n * - {{variable | transform}}\n */\n\nconst DIRECTIVE_PATTERNS = {\n // Block directives: {{#type expression}}...{{/type}}\n block: /\\{\\{#(if|unless|each|section)\\s+([^}]+)\\}\\}([\\s\\S]*?)\\{\\{\\/\\1\\}\\}/g,\n\n // Include directive: {{> partialName}}\n include: /\\{\\{>\\s*([^}]+)\\}\\}/g,\n\n // Variable with optional transform: {{variable}} or {{variable | transform}}\n variable: /\\{\\{([^#/>][^}|]*?)(?:\\s*\\|\\s*(\\w+))?\\}\\}/g,\n};\n\n/**\n * Parse template content for directives\n */\nexport function parseDirectives(content: string): TemplateDirective[] {\n const directives: TemplateDirective[] = [];\n\n // Parse block directives\n const blockMatches = content.matchAll(DIRECTIVE_PATTERNS.block);\n for (const match of blockMatches) {\n const [fullMatch, type, expression, innerContent] = match;\n const startIndex = match.index ?? 0;\n\n directives.push({\n type: type as TemplateDirectiveType,\n match: fullMatch,\n expression: expression.trim(),\n content: innerContent,\n startIndex,\n endIndex: startIndex + fullMatch.length,\n nested: parseDirectives(innerContent), // Recursive parse for nested directives\n });\n }\n\n // Parse include directives\n const includeMatches = content.matchAll(DIRECTIVE_PATTERNS.include);\n for (const match of includeMatches) {\n const [fullMatch, partialName] = match;\n const startIndex = match.index ?? 0;\n\n directives.push({\n type: 'include',\n match: fullMatch,\n expression: partialName.trim(),\n startIndex,\n endIndex: startIndex + fullMatch.length,\n });\n }\n\n return directives;\n}\n\n/**\n * Parse a single expression into its parts\n */\nexport function parseExpression(expression: string): {\n variable: string;\n path: string[];\n operator?: string;\n compareValue?: string;\n} {\n // Handle comparison operators: variable == value, variable != value\n const comparisonMatch = expression.match(/^(\\S+)\\s*(==|!=|>=|<=|>|<)\\s*(.+)$/);\n if (comparisonMatch) {\n const [, variable, operator, compareValue] = comparisonMatch;\n return {\n variable: variable.trim(),\n path: variable.trim().split('.'),\n operator,\n compareValue: compareValue.trim().replace(/^[\"']|[\"']$/g, ''),\n };\n }\n\n // Handle negation: !variable\n if (expression.startsWith('!')) {\n const variable = expression.slice(1).trim();\n return {\n variable,\n path: variable.split('.'),\n operator: '!',\n };\n }\n\n // Simple variable path\n const variable = expression.trim();\n return {\n variable,\n path: variable.split('.'),\n };\n}\n\n/**\n * Parse variable reference with optional transform\n */\nexport function parseVariable(match: string): {\n variable: string;\n transform?: string;\n} {\n // Remove {{ and }}\n const inner = match.slice(2, -2).trim();\n\n // Check for transform pipe\n const pipeIndex = inner.indexOf('|');\n if (pipeIndex !== -1) {\n return {\n variable: inner.slice(0, pipeIndex).trim(),\n transform: inner.slice(pipeIndex + 1).trim(),\n };\n }\n\n return { variable: inner };\n}\n\n/**\n * Find all variable references in content\n */\nexport function findVariables(content: string): Array<{\n match: string;\n variable: string;\n transform?: string;\n index: number;\n}> {\n const variables: Array<{\n match: string;\n variable: string;\n transform?: string;\n index: number;\n }> = [];\n\n const matches = content.matchAll(DIRECTIVE_PATTERNS.variable);\n for (const match of matches) {\n const [fullMatch, variable, transform] = match;\n\n // Skip if it looks like a block directive\n if (variable.startsWith('#') || variable.startsWith('/') || variable.startsWith('>')) {\n continue;\n }\n\n variables.push({\n match: fullMatch,\n variable: variable.trim(),\n transform: transform?.trim(),\n index: match.index ?? 0,\n });\n }\n\n return variables;\n}\n\n/**\n * Check if content has any template directives\n */\nexport function hasDirectives(content: string): boolean {\n return /\\{\\{[#/>]?\\s*\\w/.test(content);\n}\n\n/**\n * Validate template syntax\n */\nexport function validateTemplate(content: string): {\n valid: boolean;\n errors: string[];\n} {\n const errors: string[] = [];\n\n // Check for unmatched block directives\n const openBlocks: Array<{ type: string; index: number }> = [];\n\n // Find opening blocks\n const openMatches = content.matchAll(/\\{\\{#(if|unless|each|section)\\s+[^}]+\\}\\}/g);\n for (const match of openMatches) {\n openBlocks.push({\n type: match[1],\n index: match.index ?? 0,\n });\n }\n\n // Find closing blocks and match them\n const closeMatches = content.matchAll(/\\{\\{\\/(if|unless|each|section)\\}\\}/g);\n const closeBlocks: string[] = [];\n for (const match of closeMatches) {\n closeBlocks.push(match[1]);\n }\n\n // Check for mismatched blocks\n if (openBlocks.length !== closeBlocks.length) {\n errors.push(\n `Mismatched block directives: ${openBlocks.length} opening, ${closeBlocks.length} closing`\n );\n }\n\n // Check for unclosed variables\n const unclosedVars = content.match(/\\{\\{(?![^}]*\\}\\})/g);\n if (unclosedVars) {\n errors.push(`Found ${unclosedVars.length} unclosed variable reference(s)`);\n }\n\n return {\n valid: errors.length === 0,\n errors,\n };\n}\n","/**\n * Template expression evaluator\n * Evaluates conditions and expressions against a context\n */\n\nimport type { TemplateContext } from '../../types/templates.js';\nimport { parseExpression } from './parser.js';\n\n/**\n * Get a value from context using dot notation path\n */\nexport function getContextValue(\n context: TemplateContext,\n path: string\n): string | boolean | number | string[] | undefined {\n const parts = path.split('.');\n // biome-ignore lint/suspicious/noExplicitAny: dynamic access required\n let current: any = context;\n\n for (const part of parts) {\n if (current === undefined || current === null) {\n return undefined;\n }\n current = current[part];\n }\n\n return current;\n}\n\n/**\n * Evaluate a boolean expression\n */\nexport function evaluateCondition(expression: string, context: TemplateContext): boolean {\n const parsed = parseExpression(expression);\n\n // Handle AND/OR operators\n if (expression.includes('&&')) {\n const parts = expression.split('&&').map((p) => p.trim());\n return parts.every((part) => evaluateCondition(part, context));\n }\n\n if (expression.includes('||')) {\n const parts = expression.split('||').map((p) => p.trim());\n return parts.some((part) => evaluateCondition(part, context));\n }\n\n const value = getContextValue(context, parsed.variable);\n\n // Handle negation\n if (parsed.operator === '!') {\n return !isTruthy(value);\n }\n\n // Handle comparisons\n if (parsed.operator && parsed.compareValue !== undefined) {\n const compareValue = parsed.compareValue;\n\n switch (parsed.operator) {\n case '==':\n return String(value) === compareValue;\n case '!=':\n return String(value) !== compareValue;\n case '>':\n return Number(value) > Number(compareValue);\n case '>=':\n return Number(value) >= Number(compareValue);\n case '<':\n return Number(value) < Number(compareValue);\n case '<=':\n return Number(value) <= Number(compareValue);\n default:\n return false;\n }\n }\n\n // Handle array membership checks: modules.agents.includes(\"tech-lead\")\n if (expression.includes('.includes(')) {\n const match = expression.match(/^(.+?)\\.includes\\([\"'](.+?)[\"']\\)$/);\n if (match) {\n const [, arrayPath, searchValue] = match;\n const arrayValue = getContextValue(context, arrayPath);\n if (Array.isArray(arrayValue)) {\n return arrayValue.includes(searchValue);\n }\n }\n return false;\n }\n\n // Handle \"has\" helper: has modules.agents \"tech-lead\"\n if (expression.startsWith('has ')) {\n const match = expression.match(/^has\\s+(\\S+)\\s+[\"']?(.+?)[\"']?$/);\n if (match) {\n const [, arrayPath, searchValue] = match;\n const arrayValue = getContextValue(context, arrayPath);\n if (Array.isArray(arrayValue)) {\n return arrayValue.includes(searchValue);\n }\n }\n return false;\n }\n\n // Simple truthy check\n return isTruthy(value);\n}\n\n/**\n * Check if a value is truthy\n */\nexport function isTruthy(value: unknown): boolean {\n if (value === undefined || value === null) {\n return false;\n }\n\n if (typeof value === 'boolean') {\n return value;\n }\n\n if (typeof value === 'string') {\n return value.length > 0;\n }\n\n if (typeof value === 'number') {\n return value !== 0;\n }\n\n if (Array.isArray(value)) {\n return value.length > 0;\n }\n\n if (typeof value === 'object') {\n return Object.keys(value).length > 0;\n }\n\n return Boolean(value);\n}\n\n/**\n * Get iterable for each loops\n */\nexport function getIterable(\n expression: string,\n context: TemplateContext\n): Array<{ item: unknown; index: number; key?: string }> {\n const value = getContextValue(context, expression);\n\n if (Array.isArray(value)) {\n return value.map((item, index) => ({ item, index }));\n }\n\n if (typeof value === 'object' && value !== null) {\n return Object.entries(value).map(([key, item], index) => ({\n item,\n index,\n key,\n }));\n }\n\n return [];\n}\n\n/**\n * Apply a transform to a value\n */\nexport function applyTemplateTransform(\n value: string | boolean | number | string[] | undefined,\n transform: string\n): string {\n if (value === undefined || value === null) {\n return '';\n }\n\n const strValue = Array.isArray(value) ? value.join(', ') : String(value);\n\n switch (transform.toLowerCase()) {\n case 'lowercase':\n case 'lower':\n return strValue.toLowerCase();\n\n case 'uppercase':\n case 'upper':\n return strValue.toUpperCase();\n\n case 'capitalize':\n case 'title':\n return strValue\n .split(' ')\n .map((word) => word.charAt(0).toUpperCase() + word.slice(1).toLowerCase())\n .join(' ');\n\n case 'kebab':\n case 'kebabcase':\n return strValue.toLowerCase().replace(/\\s+/g, '-');\n\n case 'snake':\n case 'snakecase':\n return strValue.toLowerCase().replace(/\\s+/g, '_');\n\n case 'camel':\n case 'camelcase':\n return strValue\n .split(/[\\s-_]+/)\n .map((word, i) =>\n i === 0 ? word.toLowerCase() : word.charAt(0).toUpperCase() + word.slice(1).toLowerCase()\n )\n .join('');\n\n case 'pascal':\n case 'pascalcase':\n return strValue\n .split(/[\\s-_]+/)\n .map((word) => word.charAt(0).toUpperCase() + word.slice(1).toLowerCase())\n .join('');\n\n case 'json':\n return JSON.stringify(value);\n\n case 'count':\n return String(Array.isArray(value) ? value.length : strValue.length);\n\n case 'first':\n if (Array.isArray(value)) {\n return String(value[0] ?? '');\n }\n return strValue;\n\n case 'last':\n if (Array.isArray(value)) {\n return String(value[value.length - 1] ?? '');\n }\n return strValue;\n\n case 'join':\n if (Array.isArray(value)) {\n return value.join(', ');\n }\n return strValue;\n\n case 'joinlines':\n if (Array.isArray(value)) {\n return value.join('\\n');\n }\n return strValue;\n\n case 'bullet':\n case 'bullets':\n if (Array.isArray(value)) {\n return value.map((v) => `- ${v}`).join('\\n');\n }\n return `- ${strValue}`;\n\n case 'numbered':\n if (Array.isArray(value)) {\n return value.map((v, i) => `${i + 1}. ${v}`).join('\\n');\n }\n return `1. ${strValue}`;\n\n default:\n return strValue;\n }\n}\n\n/**\n * Create a scoped context for loop iterations\n */\nexport function createLoopContext(\n parentContext: TemplateContext,\n itemValue: unknown,\n index: number,\n key?: string\n): TemplateContext & { item: unknown; index: number; key?: string } {\n return {\n ...parentContext,\n item: itemValue,\n index,\n key,\n };\n}\n","/**\n * Template processor\n * Processes templates by evaluating directives and replacing variables\n */\n\nimport type {\n TemplateContext,\n TemplateDirective,\n TemplateResult,\n TemplateProcessingReport,\n} from '../../types/templates.js';\nimport { parseDirectives, findVariables, hasDirectives, validateTemplate } from './parser.js';\nimport {\n evaluateCondition,\n getIterable,\n getContextValue,\n applyTemplateTransform,\n createLoopContext,\n} from './evaluator.js';\nimport { joinPath, listFiles, readFile, writeFile } from '../utils/fs.js';\nimport { logger } from '../utils/logger.js';\nimport { withSpinner } from '../utils/spinner.js';\n\n/**\n * Process a single template string\n */\nexport function processTemplate(content: string, context: TemplateContext): TemplateResult {\n const result: TemplateResult = {\n content,\n modified: false,\n directivesProcessed: 0,\n warnings: [],\n errors: [],\n };\n\n // Validate first\n const validation = validateTemplate(content);\n if (!validation.valid) {\n result.errors.push(...validation.errors);\n return result;\n }\n\n // Check if there are any directives to process\n if (!hasDirectives(content)) {\n return result;\n }\n\n try {\n // Process block directives (if, unless, each, section)\n result.content = processBlockDirectives(result.content, context, result);\n\n // Process variable replacements\n result.content = processVariables(result.content, context, result);\n\n // Remove empty lines left by removed blocks (but preserve intentional blank lines)\n result.content = cleanupEmptyLines(result.content);\n\n result.modified = result.content !== content;\n } catch (error) {\n result.errors.push(`Template processing error: ${error}`);\n }\n\n return result;\n}\n\n/**\n * Process block directives\n */\nfunction processBlockDirectives(\n content: string,\n context: TemplateContext,\n result: TemplateResult\n): string {\n const directives = parseDirectives(content);\n\n // Process from last to first to maintain correct indexes\n const sortedDirectives = [...directives].sort((a, b) => b.startIndex - a.startIndex);\n\n for (const directive of sortedDirectives) {\n const replacement = processDirective(directive, context, result);\n content =\n content.slice(0, directive.startIndex) + replacement + content.slice(directive.endIndex);\n result.directivesProcessed++;\n }\n\n return content;\n}\n\n/**\n * Process a single directive\n */\nfunction processDirective(\n directive: TemplateDirective,\n context: TemplateContext,\n result: TemplateResult\n): string {\n switch (directive.type) {\n case 'if':\n return processIfDirective(directive, context, result);\n\n case 'unless':\n return processUnlessDirective(directive, context, result);\n\n case 'each':\n return processEachDirective(directive, context, result);\n\n case 'section':\n return processSectionDirective(directive, context, result);\n\n case 'include':\n result.warnings.push(`Include directive not yet supported: ${directive.expression}`);\n return directive.match;\n\n default:\n result.warnings.push(`Unknown directive type: ${directive.type}`);\n return directive.match;\n }\n}\n\n/**\n * Process if directive\n */\nfunction processIfDirective(\n directive: TemplateDirective,\n context: TemplateContext,\n result: TemplateResult\n): string {\n const condition = evaluateCondition(directive.expression, context);\n\n if (condition) {\n // Process nested content\n const innerContent = directive.content ?? '';\n const innerResult = processTemplate(innerContent, context);\n result.warnings.push(...innerResult.warnings);\n result.errors.push(...innerResult.errors);\n return innerResult.content;\n }\n\n return '';\n}\n\n/**\n * Process unless directive\n */\nfunction processUnlessDirective(\n directive: TemplateDirective,\n context: TemplateContext,\n result: TemplateResult\n): string {\n const condition = evaluateCondition(directive.expression, context);\n\n if (!condition) {\n const innerContent = directive.content ?? '';\n const innerResult = processTemplate(innerContent, context);\n result.warnings.push(...innerResult.warnings);\n result.errors.push(...innerResult.errors);\n return innerResult.content;\n }\n\n return '';\n}\n\n/**\n * Process each directive\n */\nfunction processEachDirective(\n directive: TemplateDirective,\n context: TemplateContext,\n result: TemplateResult\n): string {\n const items = getIterable(directive.expression, context);\n\n if (items.length === 0) {\n return '';\n }\n\n const outputs: string[] = [];\n\n for (const { item, index, key } of items) {\n const loopContext = createLoopContext(context, item, index, key);\n const innerContent = directive.content ?? '';\n const innerResult = processTemplate(innerContent, loopContext as unknown as TemplateContext);\n result.warnings.push(...innerResult.warnings);\n result.errors.push(...innerResult.errors);\n outputs.push(innerResult.content);\n }\n\n return outputs.join('');\n}\n\n/**\n * Process section directive (just returns content, used for marking sections)\n */\nfunction processSectionDirective(\n directive: TemplateDirective,\n context: TemplateContext,\n result: TemplateResult\n): string {\n const innerContent = directive.content ?? '';\n const innerResult = processTemplate(innerContent, context);\n result.warnings.push(...innerResult.warnings);\n result.errors.push(...innerResult.errors);\n return innerResult.content;\n}\n\n/**\n * Process variable replacements\n */\nfunction processVariables(\n content: string,\n context: TemplateContext,\n result: TemplateResult\n): string {\n const variables = findVariables(content);\n\n // Process from last to first to maintain correct indexes\n const sortedVariables = [...variables].sort((a, b) => b.index - a.index);\n\n for (const { match, variable, transform, index } of sortedVariables) {\n const value = getContextValue(context, variable);\n\n if (value !== undefined) {\n const replacement = transform ? applyTemplateTransform(value, transform) : String(value);\n\n content = content.slice(0, index) + replacement + content.slice(index + match.length);\n result.directivesProcessed++;\n } else {\n result.warnings.push(`Variable not found: ${variable}`);\n }\n }\n\n return content;\n}\n\n/**\n * Clean up empty lines left by removed blocks\n */\nfunction cleanupEmptyLines(content: string): string {\n // Remove lines that only contain whitespace after a removed block\n // But preserve intentional blank lines (max 2 consecutive)\n return content.replace(/\\n{3,}/g, '\\n\\n').trim();\n}\n\n/**\n * Process a template file\n */\nexport async function processTemplateFile(\n filePath: string,\n context: TemplateContext\n): Promise<TemplateResult> {\n const content = await readFile(filePath);\n const result = processTemplate(content, context);\n\n if (result.modified && result.errors.length === 0) {\n await writeFile(filePath, result.content);\n }\n\n return result;\n}\n\n/**\n * Process all template files in a directory\n */\nexport async function processTemplatesInDirectory(\n dirPath: string,\n context: TemplateContext,\n options?: {\n extensions?: string[];\n exclude?: string[];\n dryRun?: boolean;\n }\n): Promise<TemplateProcessingReport> {\n const extensions = options?.extensions ?? ['md', 'json', 'yaml', 'yml'];\n const exclude = options?.exclude ?? ['node_modules', '.git', 'dist', 'build'];\n\n const pattern = `**/*.{${extensions.join(',')}}`;\n const files = await listFiles(pattern, {\n cwd: dirPath,\n ignore: exclude.map((e) => `**/${e}/**`),\n });\n\n const report: TemplateProcessingReport = {\n totalFiles: files.length,\n filesModified: 0,\n totalDirectives: 0,\n filesWithErrors: [],\n warnings: [],\n };\n\n for (const file of files) {\n const filePath = joinPath(dirPath, file);\n\n try {\n const content = await readFile(filePath);\n\n // Skip files without directives\n if (!hasDirectives(content)) {\n continue;\n }\n\n const result = processTemplate(content, context);\n\n if (result.errors.length > 0) {\n report.filesWithErrors.push(file);\n report.warnings.push(`${file}: ${result.errors.join(', ')}`);\n continue;\n }\n\n if (result.modified) {\n if (!options?.dryRun) {\n await writeFile(filePath, result.content);\n }\n report.filesModified++;\n }\n\n report.totalDirectives += result.directivesProcessed;\n report.warnings.push(...result.warnings.map((w) => `${file}: ${w}`));\n } catch (error) {\n logger.debug(`Failed to process template ${file}: ${error}`);\n report.filesWithErrors.push(file);\n }\n }\n\n return report;\n}\n\n/**\n * Process templates with spinner\n */\nexport async function processTemplates(\n dirPath: string,\n context: TemplateContext,\n options?: {\n extensions?: string[];\n exclude?: string[];\n dryRun?: boolean;\n silent?: boolean;\n }\n): Promise<TemplateProcessingReport> {\n return withSpinner(\n 'Processing templates...',\n () => processTemplatesInDirectory(dirPath, context, options),\n {\n successText: 'Templates processed',\n silent: options?.silent ?? options?.dryRun,\n }\n );\n}\n\n/**\n * Show template processing report\n */\nexport function showTemplateReport(report: TemplateProcessingReport): void {\n logger.newline();\n logger.subtitle('Template Processing Report');\n logger.keyValue('Files scanned', String(report.totalFiles));\n logger.keyValue('Files modified', String(report.filesModified));\n logger.keyValue('Directives processed', String(report.totalDirectives));\n\n if (report.filesWithErrors.length > 0) {\n logger.newline();\n logger.warn('Files with errors:');\n for (const file of report.filesWithErrors) {\n logger.item(file);\n }\n }\n\n if (report.warnings.length > 0 && report.warnings.length <= 5) {\n logger.newline();\n logger.warn('Warnings:');\n for (const warning of report.warnings) {\n logger.item(warning);\n }\n } else if (report.warnings.length > 5) {\n logger.newline();\n logger.warn(`${report.warnings.length} warnings (showing first 5):`);\n for (const warning of report.warnings.slice(0, 5)) {\n logger.item(warning);\n }\n }\n}\n","/**\n * Template context builder\n * Creates a context object from config and module selections\n */\n\nimport type { ClaudeConfig } from '../../types/config.js';\nimport type { TemplateContext } from '../../types/templates.js';\n\n/**\n * Build a template context from config\n */\nexport function buildTemplateContext(config: Partial<ClaudeConfig>): TemplateContext {\n // Extract module IDs from ModuleSelection objects\n const getModuleIds = (selection?: { selected?: string[] }): string[] => {\n return selection?.selected ?? [];\n };\n\n // Extract MCP server IDs from installations\n const getMcpServerIds = (servers?: Array<{ serverId: string }>): string[] => {\n return servers?.map((s) => s.serverId) ?? [];\n };\n\n const context: TemplateContext = {\n project: {\n name: config.project?.name,\n description: config.project?.description,\n org: config.project?.org,\n repo: config.project?.repo,\n domain: config.project?.domain,\n entityType: config.project?.entityType,\n location: config.project?.location,\n },\n modules: {\n agents: getModuleIds(config.modules?.agents),\n skills: getModuleIds(config.modules?.skills),\n commands: getModuleIds(config.modules?.commands),\n docs: getModuleIds(config.modules?.docs),\n },\n codeStyle: {\n formatter: config.extras?.codeStyle?.biome\n ? 'biome'\n : config.extras?.codeStyle?.prettier\n ? 'prettier'\n : 'none',\n linter: config.extras?.codeStyle?.biome ? 'biome' : 'none',\n editorConfig: config.extras?.codeStyle?.editorconfig,\n commitlint: config.extras?.codeStyle?.commitlint,\n },\n techStack: {},\n bundles: [],\n mcpServers: getMcpServerIds(config.mcp?.servers),\n custom: {},\n };\n\n // Infer tech stack from selected modules\n context.techStack = inferTechStack(context.modules);\n\n return context;\n}\n\n/**\n * Infer tech stack from module selections\n */\nfunction inferTechStack(modules: TemplateContext['modules']): TemplateContext['techStack'] {\n const techStack: TemplateContext['techStack'] = {};\n\n const allModules = [\n ...modules.agents,\n ...modules.skills,\n ...modules.commands,\n ...modules.docs,\n ];\n\n // Framework detection\n if (allModules.some((m) => m.includes('nextjs'))) {\n techStack.framework = 'nextjs';\n } else if (allModules.some((m) => m.includes('astro'))) {\n techStack.framework = 'astro';\n } else if (allModules.some((m) => m.includes('tanstack-start'))) {\n techStack.framework = 'tanstack-start';\n } else if (allModules.some((m) => m.includes('react'))) {\n techStack.framework = 'react';\n }\n\n // Database/ORM detection\n if (allModules.some((m) => m.includes('prisma'))) {\n techStack.orm = 'prisma';\n } else if (allModules.some((m) => m.includes('drizzle'))) {\n techStack.orm = 'drizzle';\n } else if (allModules.some((m) => m.includes('mongoose'))) {\n techStack.orm = 'mongoose';\n }\n\n // API framework detection\n if (allModules.some((m) => m.includes('hono'))) {\n techStack.database = 'hono';\n } else if (allModules.some((m) => m.includes('express'))) {\n techStack.database = 'express';\n } else if (allModules.some((m) => m.includes('fastify'))) {\n techStack.database = 'fastify';\n } else if (allModules.some((m) => m.includes('nestjs'))) {\n techStack.database = 'nestjs';\n }\n\n // Testing detection\n if (allModules.some((m) => m.includes('testing') || m.includes('tdd'))) {\n techStack.testing = 'vitest';\n }\n\n // Deployment detection\n if (allModules.some((m) => m.includes('vercel'))) {\n techStack.deployment = 'vercel';\n }\n\n return techStack;\n}\n\n/**\n * Merge additional context values\n */\nexport function extendContext(\n context: TemplateContext,\n additions: Partial<TemplateContext>\n): TemplateContext {\n return {\n ...context,\n project: {\n ...context.project,\n ...additions.project,\n },\n modules: {\n ...context.modules,\n ...additions.modules,\n },\n codeStyle: {\n ...context.codeStyle,\n ...additions.codeStyle,\n },\n techStack: {\n ...context.techStack,\n ...additions.techStack,\n },\n bundles: [...context.bundles, ...(additions.bundles ?? [])],\n mcpServers: [...context.mcpServers, ...(additions.mcpServers ?? [])],\n custom: {\n ...context.custom,\n ...additions.custom,\n },\n };\n}\n\n/**\n * Add custom variables to context\n */\nexport function addCustomVariable(\n context: TemplateContext,\n key: string,\n value: string | boolean | number | string[]\n): TemplateContext {\n return {\n ...context,\n custom: {\n ...context.custom,\n [key]: value,\n },\n };\n}\n\n/**\n * Check if a module is in the context\n */\nexport function hasModule(context: TemplateContext, moduleId: string): boolean {\n return (\n context.modules.agents.includes(moduleId) ||\n context.modules.skills.includes(moduleId) ||\n context.modules.commands.includes(moduleId) ||\n context.modules.docs.includes(moduleId)\n );\n}\n\n/**\n * Check if any module in a list is in the context\n */\nexport function hasAnyModule(context: TemplateContext, moduleIds: string[]): boolean {\n return moduleIds.some((id) => hasModule(context, id));\n}\n\n/**\n * Check if all modules in a list are in the context\n */\nexport function hasAllModules(context: TemplateContext, moduleIds: string[]): boolean {\n return moduleIds.every((id) => hasModule(context, id));\n}\n\n/**\n * Get all selected modules as a flat list\n */\nexport function getAllModules(context: TemplateContext): string[] {\n return [\n ...context.modules.agents,\n ...context.modules.skills,\n ...context.modules.commands,\n ...context.modules.docs,\n ];\n}\n","/**\n * Template placeholder scanner\n *\n * Scans template files to discover {{PLACEHOLDER}} patterns\n * and returns information about which placeholders are used.\n */\n\nimport * as fs from 'node:fs/promises';\nimport * as path from 'node:path';\nimport type {\n PlaceholderScanResult,\n TemplateConfig,\n TemplatePlaceholderCategory,\n} from '../../types/template-config.js';\nimport {\n getAllPlaceholderPatterns,\n getPlaceholderByPattern,\n isConfigurablePlaceholder,\n TEMPLATE_PLACEHOLDERS,\n} from '../../constants/template-placeholders.js';\n\n/**\n * Regex to match {{PLACEHOLDER}} patterns\n */\nconst PLACEHOLDER_REGEX = /\\{\\{([A-Z][A-Z0-9_]*)\\}\\}/g;\n\n/**\n * File extensions to scan\n */\nconst SCANNABLE_EXTENSIONS = ['.md', '.json', '.yaml', '.yml', '.txt'];\n\n/**\n * Directories to skip during scanning\n */\nconst SKIP_DIRECTORIES = ['node_modules', '.git', 'dist', 'build', '.next', '.turbo'];\n\n/**\n * Check if a path should be scanned\n */\nfunction shouldScanPath(filePath: string): boolean {\n const ext = path.extname(filePath).toLowerCase();\n return SCANNABLE_EXTENSIONS.includes(ext);\n}\n\n/**\n * Check if a directory should be skipped\n */\nfunction shouldSkipDirectory(dirName: string): boolean {\n return SKIP_DIRECTORIES.includes(dirName) || dirName.startsWith('.');\n}\n\n/**\n * Extract all placeholder patterns from content\n */\nexport function extractPlaceholders(content: string): string[] {\n const matches = content.matchAll(PLACEHOLDER_REGEX);\n const placeholders = new Set<string>();\n\n for (const match of matches) {\n placeholders.add(`{{${match[1]}}}`);\n }\n\n return Array.from(placeholders);\n}\n\n/**\n * Recursively get all files in a directory\n */\nasync function getAllFiles(dir: string): Promise<string[]> {\n const files: string[] = [];\n\n try {\n const entries = await fs.readdir(dir, { withFileTypes: true });\n\n for (const entry of entries) {\n const fullPath = path.join(dir, entry.name);\n\n if (entry.isDirectory()) {\n if (!shouldSkipDirectory(entry.name)) {\n const subFiles = await getAllFiles(fullPath);\n files.push(...subFiles);\n }\n } else if (entry.isFile() && shouldScanPath(entry.name)) {\n files.push(fullPath);\n }\n }\n } catch {\n // Directory doesn't exist or can't be read\n }\n\n return files;\n}\n\n/**\n * Scan a directory for template placeholders\n */\nexport async function scanForPlaceholders(\n dir: string\n): Promise<PlaceholderScanResult> {\n const allPlaceholders = new Set<string>();\n const filesByPlaceholder: Record<string, string[]> = {};\n const counts: Record<string, number> = {};\n const byCategory: Record<TemplatePlaceholderCategory, string[]> = {\n commands: [],\n paths: [],\n targets: [],\n tracking: [],\n techStack: [],\n performance: [],\n brand: [],\n environment: [],\n };\n\n const files = await getAllFiles(dir);\n\n for (const file of files) {\n try {\n const content = await fs.readFile(file, 'utf-8');\n const placeholders = extractPlaceholders(content);\n\n for (const placeholder of placeholders) {\n // Only track configurable placeholders\n if (!isConfigurablePlaceholder(placeholder)) continue;\n\n allPlaceholders.add(placeholder);\n\n // Track files\n if (!filesByPlaceholder[placeholder]) {\n filesByPlaceholder[placeholder] = [];\n }\n filesByPlaceholder[placeholder].push(path.relative(dir, file));\n\n // Count occurrences\n const regex = new RegExp(\n placeholder.replace(/[{}]/g, '\\\\$&'),\n 'g'\n );\n const matchCount = (content.match(regex) || []).length;\n counts[placeholder] = (counts[placeholder] || 0) + matchCount;\n }\n } catch {\n // File can't be read, skip\n }\n }\n\n // Group by category\n for (const placeholder of allPlaceholders) {\n const def = getPlaceholderByPattern(placeholder);\n if (def) {\n byCategory[def.category].push(placeholder);\n }\n }\n\n return {\n placeholders: Array.from(allPlaceholders).sort(),\n byCategory,\n filesByPlaceholder,\n counts,\n };\n}\n\n/**\n * Get unconfigured placeholders (placeholders found but not in config)\n */\nexport async function getUnconfiguredPlaceholders(\n dir: string,\n config: Partial<TemplateConfig>\n): Promise<string[]> {\n const scanResult = await scanForPlaceholders(dir);\n const unconfigured: string[] = [];\n\n // Flatten config to get configured keys\n const configuredKeys = new Set<string>();\n\n if (config.commands) {\n for (const [key] of Object.entries(config.commands)) {\n configuredKeys.add(key.toUpperCase() + '_COMMAND');\n }\n }\n if (config.paths) {\n for (const [key] of Object.entries(config.paths)) {\n configuredKeys.add(key.toUpperCase());\n }\n }\n if (config.targets) {\n for (const [key] of Object.entries(config.targets)) {\n configuredKeys.add(key.toUpperCase());\n }\n }\n if (config.tracking) {\n for (const [key] of Object.entries(config.tracking)) {\n configuredKeys.add(key.toUpperCase());\n }\n }\n if (config.techStack) {\n for (const [key] of Object.entries(config.techStack)) {\n configuredKeys.add(key.toUpperCase());\n }\n }\n if (config.environment) {\n for (const [key] of Object.entries(config.environment)) {\n configuredKeys.add(key.toUpperCase());\n }\n }\n if (config.brand) {\n for (const [key] of Object.entries(config.brand)) {\n configuredKeys.add(key.toUpperCase());\n }\n }\n\n // Check each found placeholder\n for (const placeholder of scanResult.placeholders) {\n const def = getPlaceholderByPattern(placeholder);\n if (def && !configuredKeys.has(def.key)) {\n unconfigured.push(placeholder);\n }\n }\n\n return unconfigured;\n}\n\n/**\n * Get placeholders that are required but not configured\n */\nexport async function getMissingRequiredPlaceholders(\n dir: string,\n config: Partial<TemplateConfig>\n): Promise<string[]> {\n const scanResult = await scanForPlaceholders(dir);\n const missing: string[] = [];\n\n for (const placeholder of scanResult.placeholders) {\n const def = getPlaceholderByPattern(placeholder);\n if (def?.required) {\n // Check if configured\n const isConfigured = isPlaceholderConfigured(def.key, config);\n if (!isConfigured) {\n missing.push(placeholder);\n }\n }\n }\n\n return missing;\n}\n\n/**\n * Check if a specific placeholder key is configured\n */\nfunction isPlaceholderConfigured(\n key: string,\n config: Partial<TemplateConfig>\n): boolean {\n const def = TEMPLATE_PLACEHOLDERS.find((p) => p.key === key);\n if (!def) return false;\n\n switch (def.category) {\n case 'commands': {\n const cmdKey = keyToConfigKey(key, 'commands');\n return Boolean(\n config.commands?.[cmdKey as keyof typeof config.commands]\n );\n }\n case 'paths': {\n const pathKey = keyToConfigKey(key, 'paths');\n return Boolean(config.paths?.[pathKey as keyof typeof config.paths]);\n }\n case 'targets':\n case 'performance': {\n const targetKey = keyToConfigKey(key, 'targets');\n return config.targets?.[targetKey as keyof typeof config.targets] !== undefined;\n }\n case 'tracking': {\n const trackKey = keyToConfigKey(key, 'tracking');\n return Boolean(\n config.tracking?.[trackKey as keyof typeof config.tracking]\n );\n }\n case 'techStack': {\n const techKey = keyToConfigKey(key, 'techStack');\n return Boolean(\n config.techStack?.[techKey as keyof typeof config.techStack]\n );\n }\n case 'environment': {\n const envKey = keyToConfigKey(key, 'environment');\n return Boolean(\n config.environment?.[envKey as keyof typeof config.environment]\n );\n }\n case 'brand': {\n const brandKey = keyToConfigKey(key, 'brand');\n return Boolean(config.brand?.[brandKey as keyof typeof config.brand]);\n }\n default:\n return false;\n }\n}\n\n/**\n * Convert placeholder key to config object key\n * e.g., TYPECHECK_COMMAND -> typecheck\n * COVERAGE_TARGET -> coverageTarget\n */\nfunction keyToConfigKey(key: string, category: string): string {\n // Remove category suffix if present\n let cleanKey = key;\n\n if (category === 'commands' && key.endsWith('_COMMAND')) {\n cleanKey = key.slice(0, -8);\n } else if (category === 'environment' && key.endsWith('_ENV')) {\n cleanKey = key.slice(0, -4);\n }\n\n // Convert SNAKE_CASE to camelCase\n return cleanKey\n .toLowerCase()\n .replace(/_([a-z])/g, (_, char) => char.toUpperCase());\n}\n\n/**\n * Get scan summary as formatted string\n */\nexport function formatScanSummary(result: PlaceholderScanResult): string {\n const lines: string[] = [];\n\n lines.push(`Found ${result.placeholders.length} configurable placeholders:\\n`);\n\n const categories = Object.entries(result.byCategory).filter(\n ([, placeholders]) => placeholders.length > 0\n );\n\n for (const [category, placeholders] of categories) {\n lines.push(` ${category} (${placeholders.length}):`);\n for (const placeholder of placeholders) {\n const count = result.counts[placeholder] || 0;\n const files = result.filesByPlaceholder[placeholder]?.length || 0;\n lines.push(` ${placeholder} - ${count} uses in ${files} files`);\n }\n lines.push('');\n }\n\n return lines.join('\\n');\n}\n\n/**\n * List all known configurable placeholder patterns\n */\nexport function listAllConfigurablePlaceholders(): string[] {\n return getAllPlaceholderPatterns();\n}\n","/**\n * Template placeholder definitions for configurable values\n *\n * These placeholders use the {{PLACEHOLDER}} syntax and are configured\n * during installation or via the `configure` command.\n */\n\nimport type {\n TemplateConfigContext,\n TemplatePlaceholderDefinition,\n} from '../types/template-config.js';\n\n/**\n * Detect package manager command prefix\n */\nfunction getPackageManagerPrefix(context: TemplateConfigContext): string {\n switch (context.packageManager) {\n case 'yarn':\n return 'yarn';\n case 'bun':\n return 'bun run';\n case 'npm':\n return 'npm run';\n default:\n return 'pnpm';\n }\n}\n\n/**\n * Check if a script exists in package.json\n */\nfunction hasScript(context: TemplateConfigContext, name: string): boolean {\n return Boolean(context.scripts?.[name]);\n}\n\n/**\n * Get script command if it exists\n */\nfunction getScriptCommand(context: TemplateConfigContext, scriptName: string): string | undefined {\n if (!hasScript(context, scriptName)) return undefined;\n const prefix = getPackageManagerPrefix(context);\n return `${prefix} ${scriptName}`;\n}\n\n/**\n * Check if a dependency exists\n */\nfunction hasDependency(context: TemplateConfigContext, name: string): boolean {\n return Boolean(context.dependencies?.[name]);\n}\n\n/**\n * All configurable template placeholders\n */\nexport const TEMPLATE_PLACEHOLDERS: TemplatePlaceholderDefinition[] = [\n // ==========================================\n // COMMANDS CATEGORY\n // ==========================================\n {\n key: 'TYPECHECK_COMMAND',\n pattern: '{{TYPECHECK_COMMAND}}',\n category: 'commands',\n label: 'TypeScript Check Command',\n description: 'Command to run TypeScript type checking',\n inputType: 'text',\n default: (ctx) =>\n getScriptCommand(ctx, 'typecheck') ||\n getScriptCommand(ctx, 'type-check') ||\n getScriptCommand(ctx, 'tsc') ||\n `${getPackageManagerPrefix(ctx)} typecheck`,\n required: true,\n example: 'pnpm typecheck',\n },\n {\n key: 'LINT_COMMAND',\n pattern: '{{LINT_COMMAND}}',\n category: 'commands',\n label: 'Lint Command',\n description: 'Command to run linting (ESLint, Biome, etc.)',\n inputType: 'text',\n default: (ctx) => getScriptCommand(ctx, 'lint') || `${getPackageManagerPrefix(ctx)} lint`,\n required: true,\n example: 'pnpm lint',\n },\n {\n key: 'LINT_FIX_COMMAND',\n pattern: '{{LINT_FIX_COMMAND}}',\n category: 'commands',\n label: 'Lint Fix Command',\n description: 'Command to run linting with auto-fix',\n inputType: 'text',\n default: (ctx) =>\n getScriptCommand(ctx, 'lint:fix') || `${getPackageManagerPrefix(ctx)} lint --fix`,\n required: false,\n relatedTo: ['LINT_COMMAND'],\n example: 'pnpm lint --fix',\n },\n {\n key: 'TEST_COMMAND',\n pattern: '{{TEST_COMMAND}}',\n category: 'commands',\n label: 'Test Command',\n description: 'Command to run tests',\n inputType: 'text',\n default: (ctx) => getScriptCommand(ctx, 'test') || `${getPackageManagerPrefix(ctx)} test`,\n required: true,\n example: 'pnpm test',\n },\n {\n key: 'TEST_WATCH_COMMAND',\n pattern: '{{TEST_WATCH_COMMAND}}',\n category: 'commands',\n label: 'Test Watch Command',\n description: 'Command to run tests in watch mode',\n inputType: 'text',\n default: (ctx) =>\n getScriptCommand(ctx, 'test:watch') || `${getPackageManagerPrefix(ctx)} test --watch`,\n required: false,\n relatedTo: ['TEST_COMMAND'],\n example: 'pnpm test --watch',\n },\n {\n key: 'COVERAGE_COMMAND',\n pattern: '{{COVERAGE_COMMAND}}',\n category: 'commands',\n label: 'Coverage Command',\n description: 'Command to run tests with coverage',\n inputType: 'text',\n default: (ctx) =>\n getScriptCommand(ctx, 'test:coverage') ||\n getScriptCommand(ctx, 'coverage') ||\n `${getPackageManagerPrefix(ctx)} test --coverage`,\n required: true,\n relatedTo: ['TEST_COMMAND'],\n example: 'pnpm test:coverage',\n },\n {\n key: 'BUILD_COMMAND',\n pattern: '{{BUILD_COMMAND}}',\n category: 'commands',\n label: 'Build Command',\n description: 'Command to build the project',\n inputType: 'text',\n default: (ctx) => getScriptCommand(ctx, 'build') || `${getPackageManagerPrefix(ctx)} build`,\n required: false,\n example: 'pnpm build',\n },\n {\n key: 'FORMAT_COMMAND',\n pattern: '{{FORMAT_COMMAND}}',\n category: 'commands',\n label: 'Format Command',\n description: 'Command to format code (Prettier, Biome, etc.)',\n inputType: 'text',\n default: (ctx) => getScriptCommand(ctx, 'format') || `${getPackageManagerPrefix(ctx)} format`,\n required: false,\n example: 'pnpm format',\n },\n {\n key: 'SECURITY_SCAN_COMMAND',\n pattern: '{{SECURITY_SCAN_COMMAND}}',\n category: 'commands',\n label: 'Security Scan Command',\n description: 'Command to run security vulnerability scanning',\n inputType: 'text',\n default: (ctx) => getScriptCommand(ctx, 'audit') || `${getPackageManagerPrefix(ctx)} audit`,\n required: false,\n example: 'pnpm audit',\n },\n {\n key: 'LIGHTHOUSE_COMMAND',\n pattern: '{{LIGHTHOUSE_COMMAND}}',\n category: 'commands',\n label: 'Lighthouse Command',\n description: 'Command to run Lighthouse performance audit',\n inputType: 'text',\n default: 'npx lighthouse http://localhost:3000 --output=json',\n required: false,\n example: 'npx lighthouse http://localhost:3000 --output=json',\n },\n {\n key: 'BUNDLE_ANALYZE_COMMAND',\n pattern: '{{BUNDLE_ANALYZE_COMMAND}}',\n category: 'commands',\n label: 'Bundle Analyze Command',\n description: 'Command to analyze bundle size',\n inputType: 'text',\n default: (ctx) =>\n getScriptCommand(ctx, 'analyze') || `${getPackageManagerPrefix(ctx)} build --analyze`,\n required: false,\n example: 'pnpm build --analyze',\n },\n\n // ==========================================\n // PATHS CATEGORY\n // ==========================================\n {\n key: 'PLANNING_PATH',\n pattern: '{{PLANNING_PATH}}',\n category: 'paths',\n label: 'Planning Directory',\n description: 'Path for planning session documents',\n inputType: 'path',\n default: '.claude/sessions/planning',\n required: true,\n example: '.claude/sessions/planning',\n },\n {\n key: 'REFACTOR_PATH',\n pattern: '{{REFACTOR_PATH}}',\n category: 'paths',\n label: 'Refactor Directory',\n description: 'Path for refactoring session documents',\n inputType: 'path',\n default: '.claude/sessions/refactor',\n required: false,\n relatedTo: ['PLANNING_PATH'],\n example: '.claude/sessions/refactor',\n },\n {\n key: 'ARCHIVE_PATH',\n pattern: '{{ARCHIVE_PATH}}',\n category: 'paths',\n label: 'Archive Directory',\n description: 'Path for archived planning sessions',\n inputType: 'path',\n default: '.claude/sessions/archive',\n required: false,\n relatedTo: ['PLANNING_PATH'],\n example: '.claude/sessions/archive',\n },\n {\n key: 'SCHEMAS_PATH',\n pattern: '{{SCHEMAS_PATH}}',\n category: 'paths',\n label: 'Schemas Directory',\n description: 'Path for JSON schemas',\n inputType: 'path',\n default: '.claude/schemas',\n required: false,\n example: '.claude/schemas',\n },\n {\n key: 'PROJECT_ROOT',\n pattern: '{{PROJECT_ROOT}}',\n category: 'paths',\n label: 'Project Root',\n description: 'Root directory of the project',\n inputType: 'path',\n default: (ctx) => ctx.projectPath || '.',\n required: true,\n example: '.',\n },\n\n // ==========================================\n // TARGETS CATEGORY\n // ==========================================\n {\n key: 'COVERAGE_TARGET',\n pattern: '{{COVERAGE_TARGET}}',\n category: 'targets',\n label: 'Coverage Target (%)',\n description: 'Minimum test coverage percentage',\n inputType: 'number',\n default: '90',\n validate: (value) => {\n const num = Number.parseInt(value, 10);\n if (Number.isNaN(num) || num < 0 || num > 100) {\n return 'Coverage must be between 0 and 100';\n }\n return true;\n },\n required: true,\n example: '90',\n },\n {\n key: 'BUNDLE_SIZE_TARGET',\n pattern: '{{BUNDLE_SIZE_TARGET}}',\n category: 'targets',\n label: 'Bundle Size Target (KB)',\n description: 'Maximum bundle size in kilobytes',\n inputType: 'number',\n default: '500',\n validate: (value) => {\n const num = Number.parseInt(value, 10);\n if (Number.isNaN(num) || num < 0) {\n return 'Bundle size must be a positive number';\n }\n return true;\n },\n required: false,\n example: '500',\n },\n {\n key: 'LCP_TARGET',\n pattern: '{{LCP_TARGET}}',\n category: 'performance',\n label: 'LCP Target (ms)',\n description: 'Largest Contentful Paint target in milliseconds',\n inputType: 'number',\n default: '2500',\n required: false,\n example: '2500',\n },\n {\n key: 'FID_TARGET',\n pattern: '{{FID_TARGET}}',\n category: 'performance',\n label: 'FID Target (ms)',\n description: 'First Input Delay target in milliseconds',\n inputType: 'number',\n default: '100',\n required: false,\n example: '100',\n },\n {\n key: 'CLS_TARGET',\n pattern: '{{CLS_TARGET}}',\n category: 'performance',\n label: 'CLS Target',\n description: 'Cumulative Layout Shift target',\n inputType: 'number',\n default: '0.1',\n required: false,\n example: '0.1',\n },\n {\n key: 'API_RESPONSE_TARGET',\n pattern: '{{API_RESPONSE_TARGET}}',\n category: 'performance',\n label: 'API Response Target (ms)',\n description: 'Maximum API response time in milliseconds',\n inputType: 'number',\n default: '200',\n required: false,\n example: '200',\n },\n {\n key: 'DB_QUERY_TARGET',\n pattern: '{{DB_QUERY_TARGET}}',\n category: 'performance',\n label: 'DB Query Target (ms)',\n description: 'Maximum database query time in milliseconds',\n inputType: 'number',\n default: '50',\n required: false,\n example: '50',\n },\n {\n key: 'WCAG_LEVEL',\n pattern: '{{WCAG_LEVEL}}',\n category: 'targets',\n label: 'WCAG Compliance Level',\n description: 'Target WCAG accessibility compliance level',\n inputType: 'select',\n choices: [\n { name: 'Level A (Minimum)', value: 'A' },\n { name: 'Level AA (Recommended)', value: 'AA' },\n { name: 'Level AAA (Highest)', value: 'AAA' },\n ],\n default: 'AA',\n required: false,\n example: 'AA',\n },\n\n // ==========================================\n // TRACKING CATEGORY\n // ==========================================\n {\n key: 'ISSUE_TRACKER',\n pattern: '{{ISSUE_TRACKER}}',\n category: 'tracking',\n label: 'Issue Tracker',\n description: 'Issue tracking system to use',\n inputType: 'select',\n choices: [\n { name: 'GitHub Issues', value: 'github', description: 'Use GitHub Issues for tracking' },\n { name: 'Linear', value: 'linear', description: 'Use Linear for tracking' },\n { name: 'Jira', value: 'jira', description: 'Use Jira for tracking' },\n { name: 'None', value: 'none', description: 'No issue tracker integration' },\n ],\n default: (ctx) => (ctx.hasGitHubRemote ? 'github' : 'none'),\n required: true,\n example: 'github',\n },\n {\n key: 'TRACKING_FILE',\n pattern: '{{TRACKING_FILE}}',\n category: 'tracking',\n label: 'Tracking File',\n description: 'Path to the task tracking file',\n inputType: 'path',\n default: '.claude/tracking/tasks.json',\n required: false,\n example: '.claude/tracking/tasks.json',\n },\n {\n key: 'REGISTRY_FILE',\n pattern: '{{REGISTRY_FILE}}',\n category: 'tracking',\n label: 'Registry File',\n description: 'Path to the code registry file',\n inputType: 'path',\n default: '.claude/tracking/registry.json',\n required: false,\n example: '.claude/tracking/registry.json',\n },\n {\n key: 'TASK_CODE_PATTERN',\n pattern: '{{TASK_CODE_PATTERN}}',\n category: 'tracking',\n label: 'Task Code Pattern',\n description: 'Pattern for task codes (e.g., PROJ-XXX)',\n inputType: 'text',\n default: 'TASK-',\n required: false,\n example: 'TASK-',\n },\n {\n key: 'CLOSED_DAYS',\n pattern: '{{CLOSED_DAYS}}',\n category: 'tracking',\n label: 'Closed Days Threshold',\n description: 'Days after which closed issues can be cleaned up',\n inputType: 'number',\n default: '30',\n required: false,\n example: '30',\n },\n {\n key: 'STALE_DAYS',\n pattern: '{{STALE_DAYS}}',\n category: 'tracking',\n label: 'Stale Days Threshold',\n description: 'Days of inactivity before an issue is considered stale',\n inputType: 'number',\n default: '14',\n required: false,\n example: '14',\n },\n\n // ==========================================\n // TECH STACK CATEGORY\n // ==========================================\n {\n key: 'FRONTEND_FRAMEWORK',\n pattern: '{{FRONTEND_FRAMEWORK}}',\n category: 'techStack',\n label: 'Frontend Framework',\n description: 'Primary frontend framework',\n inputType: 'select',\n choices: [\n { name: 'React', value: 'React' },\n { name: 'Next.js', value: 'Next.js' },\n { name: 'TanStack Start', value: 'TanStack Start' },\n { name: 'Vue', value: 'Vue' },\n { name: 'Nuxt', value: 'Nuxt' },\n { name: 'Svelte', value: 'Svelte' },\n { name: 'SvelteKit', value: 'SvelteKit' },\n { name: 'Astro', value: 'Astro' },\n { name: 'SolidJS', value: 'SolidJS' },\n { name: 'Remix', value: 'Remix' },\n { name: 'Angular', value: 'Angular' },\n { name: 'None', value: 'None' },\n ],\n default: (ctx) => {\n if (hasDependency(ctx, '@tanstack/start')) return 'TanStack Start';\n if (hasDependency(ctx, 'next')) return 'Next.js';\n if (hasDependency(ctx, 'nuxt')) return 'Nuxt';\n if (hasDependency(ctx, 'vue')) return 'Vue';\n if (hasDependency(ctx, 'svelte')) return 'Svelte';\n if (hasDependency(ctx, '@sveltejs/kit')) return 'SvelteKit';\n if (hasDependency(ctx, 'astro')) return 'Astro';\n if (hasDependency(ctx, 'solid-js')) return 'SolidJS';\n if (hasDependency(ctx, '@remix-run/react')) return 'Remix';\n if (hasDependency(ctx, '@angular/core')) return 'Angular';\n if (hasDependency(ctx, 'react')) return 'React';\n return 'None';\n },\n required: false,\n example: 'React',\n },\n {\n key: 'DATABASE_ORM',\n pattern: '{{DATABASE_ORM}}',\n category: 'techStack',\n label: 'Database/ORM',\n description: 'Database ORM or query builder',\n inputType: 'select',\n choices: [\n { name: 'Drizzle', value: 'Drizzle' },\n { name: 'Prisma', value: 'Prisma' },\n { name: 'TypeORM', value: 'TypeORM' },\n { name: 'Sequelize', value: 'Sequelize' },\n { name: 'Knex', value: 'Knex' },\n { name: 'Kysely', value: 'Kysely' },\n { name: 'MongoDB/Mongoose', value: 'Mongoose' },\n { name: 'None', value: 'None' },\n ],\n default: (ctx) => {\n if (hasDependency(ctx, 'drizzle-orm')) return 'Drizzle';\n if (hasDependency(ctx, 'prisma') || hasDependency(ctx, '@prisma/client')) return 'Prisma';\n if (hasDependency(ctx, 'typeorm')) return 'TypeORM';\n if (hasDependency(ctx, 'sequelize')) return 'Sequelize';\n if (hasDependency(ctx, 'knex')) return 'Knex';\n if (hasDependency(ctx, 'kysely')) return 'Kysely';\n if (hasDependency(ctx, 'mongoose')) return 'Mongoose';\n return 'None';\n },\n required: false,\n example: 'Drizzle',\n },\n {\n key: 'VALIDATION_LIBRARY',\n pattern: '{{VALIDATION_LIBRARY}}',\n category: 'techStack',\n label: 'Validation Library',\n description: 'Schema validation library',\n inputType: 'select',\n choices: [\n { name: 'Zod', value: 'Zod' },\n { name: 'Yup', value: 'Yup' },\n { name: 'Joi', value: 'Joi' },\n { name: 'Valibot', value: 'Valibot' },\n { name: 'ArkType', value: 'ArkType' },\n { name: 'None', value: 'None' },\n ],\n default: (ctx) => {\n if (hasDependency(ctx, 'zod')) return 'Zod';\n if (hasDependency(ctx, 'yup')) return 'Yup';\n if (hasDependency(ctx, 'joi')) return 'Joi';\n if (hasDependency(ctx, 'valibot')) return 'Valibot';\n if (hasDependency(ctx, 'arktype')) return 'ArkType';\n return 'None';\n },\n required: false,\n example: 'Zod',\n },\n {\n key: 'AUTH_PATTERN',\n pattern: '{{AUTH_PATTERN}}',\n category: 'techStack',\n label: 'Authentication Pattern',\n description: 'Authentication approach',\n inputType: 'select',\n choices: [\n { name: 'Better Auth', value: 'Better Auth' },\n { name: 'Clerk', value: 'Clerk' },\n { name: 'Auth.js (NextAuth)', value: 'Auth.js' },\n { name: 'Lucia', value: 'Lucia' },\n { name: 'Firebase Auth', value: 'Firebase' },\n { name: 'Supabase Auth', value: 'Supabase' },\n { name: 'Kinde', value: 'Kinde' },\n { name: 'WorkOS', value: 'WorkOS' },\n { name: 'Custom JWT', value: 'JWT' },\n { name: 'Session-based', value: 'Session' },\n { name: 'None', value: 'None' },\n ],\n default: (ctx) => {\n if (hasDependency(ctx, 'better-auth')) return 'Better Auth';\n if (hasDependency(ctx, '@clerk/nextjs') || hasDependency(ctx, '@clerk/clerk-react'))\n return 'Clerk';\n if (hasDependency(ctx, 'next-auth') || hasDependency(ctx, '@auth/core')) return 'Auth.js';\n if (hasDependency(ctx, 'lucia')) return 'Lucia';\n if (hasDependency(ctx, 'firebase')) return 'Firebase';\n if (hasDependency(ctx, '@supabase/supabase-js')) return 'Supabase';\n if (hasDependency(ctx, '@kinde-oss/kinde-auth-nextjs')) return 'Kinde';\n if (hasDependency(ctx, '@workos-inc/authkit-nextjs')) return 'WorkOS';\n return 'None';\n },\n required: false,\n example: 'Better Auth',\n },\n {\n key: 'STATE_MANAGEMENT',\n pattern: '{{STATE_MANAGEMENT}}',\n category: 'techStack',\n label: 'State Management',\n description: 'Client-side state management',\n inputType: 'select',\n choices: [\n { name: 'TanStack Query', value: 'TanStack Query' },\n { name: 'Zustand', value: 'Zustand' },\n { name: 'Jotai', value: 'Jotai' },\n { name: 'Redux Toolkit', value: 'Redux' },\n { name: 'MobX', value: 'MobX' },\n { name: 'Recoil', value: 'Recoil' },\n { name: 'Pinia (Vue)', value: 'Pinia' },\n { name: 'None/Context', value: 'None' },\n ],\n default: (ctx) => {\n if (hasDependency(ctx, '@tanstack/react-query')) return 'TanStack Query';\n if (hasDependency(ctx, 'zustand')) return 'Zustand';\n if (hasDependency(ctx, 'jotai')) return 'Jotai';\n if (hasDependency(ctx, '@reduxjs/toolkit')) return 'Redux';\n if (hasDependency(ctx, 'mobx')) return 'MobX';\n if (hasDependency(ctx, 'recoil')) return 'Recoil';\n if (hasDependency(ctx, 'pinia')) return 'Pinia';\n return 'None';\n },\n required: false,\n example: 'TanStack Query',\n },\n {\n key: 'TEST_FRAMEWORK',\n pattern: '{{TEST_FRAMEWORK}}',\n category: 'techStack',\n label: 'Test Framework',\n description: 'Testing framework',\n inputType: 'select',\n choices: [\n { name: 'Vitest', value: 'Vitest' },\n { name: 'Jest', value: 'Jest' },\n { name: 'Mocha', value: 'Mocha' },\n { name: 'Ava', value: 'Ava' },\n { name: 'Node Test Runner', value: 'Node' },\n { name: 'None', value: 'None' },\n ],\n default: (ctx) => {\n if (hasDependency(ctx, 'vitest')) return 'Vitest';\n if (hasDependency(ctx, 'jest')) return 'Jest';\n if (hasDependency(ctx, 'mocha')) return 'Mocha';\n if (hasDependency(ctx, 'ava')) return 'Ava';\n return 'None';\n },\n required: false,\n example: 'Vitest',\n },\n {\n key: 'BUNDLER',\n pattern: '{{BUNDLER}}',\n category: 'techStack',\n label: 'Bundler',\n description: 'Build tool/bundler',\n inputType: 'select',\n choices: [\n { name: 'Vite', value: 'Vite' },\n { name: 'Webpack', value: 'Webpack' },\n { name: 'Rollup', value: 'Rollup' },\n { name: 'esbuild', value: 'esbuild' },\n { name: 'Parcel', value: 'Parcel' },\n { name: 'Turbopack', value: 'Turbopack' },\n { name: 'tsup', value: 'tsup' },\n { name: 'None', value: 'None' },\n ],\n default: (ctx) => {\n if (hasDependency(ctx, 'vite')) return 'Vite';\n if (hasDependency(ctx, 'webpack')) return 'Webpack';\n if (hasDependency(ctx, 'rollup')) return 'Rollup';\n if (hasDependency(ctx, 'esbuild')) return 'esbuild';\n if (hasDependency(ctx, 'parcel')) return 'Parcel';\n if (hasDependency(ctx, 'tsup')) return 'tsup';\n return 'None';\n },\n required: false,\n example: 'Vite',\n },\n {\n key: 'API_FRAMEWORK',\n pattern: '{{API_FRAMEWORK}}',\n category: 'techStack',\n label: 'API Framework',\n description: 'Backend API framework',\n inputType: 'select',\n choices: [\n { name: 'Hono', value: 'Hono' },\n { name: 'Express', value: 'Express' },\n { name: 'Fastify', value: 'Fastify' },\n { name: 'Koa', value: 'Koa' },\n { name: 'NestJS', value: 'NestJS' },\n { name: 'tRPC', value: 'tRPC' },\n { name: 'Next.js API Routes', value: 'Next.js API' },\n { name: 'None', value: 'None' },\n ],\n default: (ctx) => {\n if (hasDependency(ctx, 'hono')) return 'Hono';\n if (hasDependency(ctx, 'express')) return 'Express';\n if (hasDependency(ctx, 'fastify')) return 'Fastify';\n if (hasDependency(ctx, 'koa')) return 'Koa';\n if (hasDependency(ctx, '@nestjs/core')) return 'NestJS';\n if (hasDependency(ctx, '@trpc/server')) return 'tRPC';\n if (hasDependency(ctx, 'next')) return 'Next.js API';\n return 'None';\n },\n required: false,\n example: 'Hono',\n },\n\n // ==========================================\n // ENVIRONMENT CATEGORY\n // ==========================================\n {\n key: 'GITHUB_TOKEN_ENV',\n pattern: '{{GITHUB_TOKEN_ENV}}',\n category: 'environment',\n label: 'GitHub Token Env Var',\n description: 'Environment variable name for GitHub token',\n inputType: 'envVar',\n default: 'GITHUB_TOKEN',\n required: false,\n example: 'GITHUB_TOKEN',\n },\n {\n key: 'GITHUB_OWNER_ENV',\n pattern: '{{GITHUB_OWNER_ENV}}',\n category: 'environment',\n label: 'GitHub Owner Env Var',\n description: 'Environment variable name for GitHub owner/org',\n inputType: 'envVar',\n default: 'GITHUB_OWNER',\n required: false,\n example: 'GITHUB_OWNER',\n },\n {\n key: 'GITHUB_REPO_ENV',\n pattern: '{{GITHUB_REPO_ENV}}',\n category: 'environment',\n label: 'GitHub Repo Env Var',\n description: 'Environment variable name for GitHub repository',\n inputType: 'envVar',\n default: 'GITHUB_REPO',\n required: false,\n example: 'GITHUB_REPO',\n },\n {\n key: 'ISSUE_TRACKER_TOKEN_ENV',\n pattern: '{{ISSUE_TRACKER_TOKEN_ENV}}',\n category: 'environment',\n label: 'Issue Tracker Token Env Var',\n description: 'Environment variable for issue tracker API token',\n inputType: 'envVar',\n default: (ctx) => {\n // Set based on selected tracker\n const tracker = ctx.values.ISSUE_TRACKER;\n if (tracker === 'linear') return 'LINEAR_API_KEY';\n if (tracker === 'jira') return 'JIRA_API_TOKEN';\n return 'GITHUB_TOKEN';\n },\n dependsOn: ['ISSUE_TRACKER'],\n required: false,\n example: 'GITHUB_TOKEN',\n },\n\n // ==========================================\n // BRAND CATEGORY\n // ==========================================\n {\n key: 'BRAND_NAME',\n pattern: '{{BRAND_NAME}}',\n category: 'brand',\n label: 'Brand Name',\n description: 'Your brand or product name',\n inputType: 'text',\n default: '',\n required: false,\n example: 'MyProduct',\n },\n {\n key: 'PRIMARY_COLOR',\n pattern: '{{PRIMARY_COLOR}}',\n category: 'brand',\n label: 'Primary Color',\n description: 'Primary brand color (hex)',\n inputType: 'text',\n validate: (value) => {\n if (!value) return true;\n if (!/^#[0-9A-Fa-f]{6}$/.test(value)) {\n return 'Must be a valid hex color (e.g., #3B82F6)';\n }\n return true;\n },\n default: '#3B82F6',\n required: false,\n example: '#3B82F6',\n },\n {\n key: 'SECONDARY_COLOR',\n pattern: '{{SECONDARY_COLOR}}',\n category: 'brand',\n label: 'Secondary Color',\n description: 'Secondary brand color (hex)',\n inputType: 'text',\n validate: (value) => {\n if (!value) return true;\n if (!/^#[0-9A-Fa-f]{6}$/.test(value)) {\n return 'Must be a valid hex color (e.g., #10B981)';\n }\n return true;\n },\n default: '#10B981',\n required: false,\n example: '#10B981',\n },\n {\n key: 'FONT_FAMILY',\n pattern: '{{FONT_FAMILY}}',\n category: 'brand',\n label: 'Font Family',\n description: 'Primary font family',\n inputType: 'text',\n default: 'Inter, system-ui, sans-serif',\n required: false,\n example: 'Inter, system-ui, sans-serif',\n },\n {\n key: 'TONE_OF_VOICE',\n pattern: '{{TONE_OF_VOICE}}',\n category: 'brand',\n label: 'Tone of Voice',\n description: 'Brand communication tone',\n inputType: 'select',\n choices: [\n { name: 'Professional', value: 'professional' },\n { name: 'Friendly', value: 'friendly' },\n { name: 'Casual', value: 'casual' },\n { name: 'Technical', value: 'technical' },\n { name: 'Playful', value: 'playful' },\n ],\n default: 'professional',\n required: false,\n example: 'professional',\n },\n];\n\n/**\n * Get placeholder definition by key\n */\nexport function getPlaceholderByKey(key: string): TemplatePlaceholderDefinition | undefined {\n return TEMPLATE_PLACEHOLDERS.find((p) => p.key === key);\n}\n\n/**\n * Get placeholder definition by pattern\n */\nexport function getPlaceholderByPattern(\n pattern: string\n): TemplatePlaceholderDefinition | undefined {\n return TEMPLATE_PLACEHOLDERS.find((p) => p.pattern === pattern);\n}\n\n/**\n * Get all placeholders for a category\n */\nexport function getPlaceholdersByCategory(category: string): TemplatePlaceholderDefinition[] {\n return TEMPLATE_PLACEHOLDERS.filter((p) => p.category === category);\n}\n\n/**\n * Get all required placeholders\n */\nexport function getRequiredPlaceholders(): TemplatePlaceholderDefinition[] {\n return TEMPLATE_PLACEHOLDERS.filter((p) => p.required);\n}\n\n/**\n * Get all placeholder keys\n */\nexport function getAllPlaceholderKeys(): string[] {\n return TEMPLATE_PLACEHOLDERS.map((p) => p.key);\n}\n\n/**\n * Get all placeholder patterns\n */\nexport function getAllPlaceholderPatterns(): string[] {\n return TEMPLATE_PLACEHOLDERS.map((p) => p.pattern);\n}\n\n/**\n * Check if a pattern is a configurable placeholder\n */\nexport function isConfigurablePlaceholder(pattern: string): boolean {\n return TEMPLATE_PLACEHOLDERS.some((p) => p.pattern === pattern);\n}\n\n/**\n * Compute default value for a placeholder\n */\nexport function computeDefaultValue(\n placeholder: TemplatePlaceholderDefinition,\n context: TemplateConfigContext\n): string | undefined {\n if (typeof placeholder.default === 'function') {\n return placeholder.default(context);\n }\n return placeholder.default;\n}\n","/**\n * Template configuration replacer\n *\n * Replaces {{PLACEHOLDER}} patterns in template files\n * with configured values from TemplateConfig.\n */\n\nimport * as fs from 'node:fs/promises';\nimport * as path from 'node:path';\nimport ora from 'ora';\nimport type {\n TemplateConfig,\n TemplatePlaceholderReport,\n} from '../../types/template-config.js';\nimport { TEMPLATE_PLACEHOLDERS } from '../../constants/template-placeholders.js';\n\n/**\n * File extensions to process\n */\nconst PROCESSABLE_EXTENSIONS = ['.md', '.json', '.yaml', '.yml', '.txt'];\n\n/**\n * Directories to skip\n */\nconst SKIP_DIRECTORIES = ['node_modules', '.git', 'dist', 'build', '.next', '.turbo'];\n\n/**\n * Flatten TemplateConfig into a key-value map for replacement\n */\nexport function flattenTemplateConfig(\n config: Partial<TemplateConfig>\n): Record<string, string> {\n const flattened: Record<string, string> = {};\n\n // Commands\n if (config.commands) {\n if (config.commands.typecheck)\n flattened['{{TYPECHECK_COMMAND}}'] = config.commands.typecheck;\n if (config.commands.lint)\n flattened['{{LINT_COMMAND}}'] = config.commands.lint;\n if (config.commands.test)\n flattened['{{TEST_COMMAND}}'] = config.commands.test;\n if (config.commands.coverage)\n flattened['{{COVERAGE_COMMAND}}'] = config.commands.coverage;\n if (config.commands.build)\n flattened['{{BUILD_COMMAND}}'] = config.commands.build;\n if (config.commands.format)\n flattened['{{FORMAT_COMMAND}}'] = config.commands.format;\n if (config.commands.securityScan)\n flattened['{{SECURITY_SCAN_COMMAND}}'] = config.commands.securityScan;\n if (config.commands.lighthouse)\n flattened['{{LIGHTHOUSE_COMMAND}}'] = config.commands.lighthouse;\n if (config.commands.bundleAnalyze)\n flattened['{{BUNDLE_ANALYZE_COMMAND}}'] = config.commands.bundleAnalyze;\n }\n\n // Paths\n if (config.paths) {\n if (config.paths.planningPath)\n flattened['{{PLANNING_PATH}}'] = config.paths.planningPath;\n if (config.paths.refactorPath)\n flattened['{{REFACTOR_PATH}}'] = config.paths.refactorPath;\n if (config.paths.archivePath)\n flattened['{{ARCHIVE_PATH}}'] = config.paths.archivePath;\n if (config.paths.schemasPath)\n flattened['{{SCHEMAS_PATH}}'] = config.paths.schemasPath;\n if (config.paths.projectRoot)\n flattened['{{PROJECT_ROOT}}'] = config.paths.projectRoot;\n }\n\n // Targets\n if (config.targets) {\n if (config.targets.coverageTarget !== undefined)\n flattened['{{COVERAGE_TARGET}}'] = String(config.targets.coverageTarget);\n if (config.targets.bundleSizeTarget !== undefined)\n flattened['{{BUNDLE_SIZE_TARGET}}'] = String(config.targets.bundleSizeTarget);\n if (config.targets.lcpTarget !== undefined)\n flattened['{{LCP_TARGET}}'] = String(config.targets.lcpTarget);\n if (config.targets.fidTarget !== undefined)\n flattened['{{FID_TARGET}}'] = String(config.targets.fidTarget);\n if (config.targets.clsTarget !== undefined)\n flattened['{{CLS_TARGET}}'] = String(config.targets.clsTarget);\n if (config.targets.apiResponseTarget !== undefined)\n flattened['{{API_RESPONSE_TARGET}}'] = String(config.targets.apiResponseTarget);\n if (config.targets.dbQueryTarget !== undefined)\n flattened['{{DB_QUERY_TARGET}}'] = String(config.targets.dbQueryTarget);\n if (config.targets.wcagLevel)\n flattened['{{WCAG_LEVEL}}'] = config.targets.wcagLevel;\n }\n\n // Tracking\n if (config.tracking) {\n if (config.tracking.issueTracker)\n flattened['{{ISSUE_TRACKER}}'] = config.tracking.issueTracker;\n if (config.tracking.trackingFile)\n flattened['{{TRACKING_FILE}}'] = config.tracking.trackingFile;\n if (config.tracking.registryFile)\n flattened['{{REGISTRY_FILE}}'] = config.tracking.registryFile;\n if (config.tracking.taskCodePattern)\n flattened['{{TASK_CODE_PATTERN}}'] = config.tracking.taskCodePattern;\n if (config.tracking.closedDays !== undefined)\n flattened['{{CLOSED_DAYS}}'] = String(config.tracking.closedDays);\n if (config.tracking.staleDays !== undefined)\n flattened['{{STALE_DAYS}}'] = String(config.tracking.staleDays);\n }\n\n // Tech Stack\n if (config.techStack) {\n if (config.techStack.frontendFramework)\n flattened['{{FRONTEND_FRAMEWORK}}'] = config.techStack.frontendFramework;\n if (config.techStack.databaseOrm)\n flattened['{{DATABASE_ORM}}'] = config.techStack.databaseOrm;\n if (config.techStack.validationLibrary)\n flattened['{{VALIDATION_LIBRARY}}'] = config.techStack.validationLibrary;\n if (config.techStack.authPattern)\n flattened['{{AUTH_PATTERN}}'] = config.techStack.authPattern;\n if (config.techStack.stateManagement)\n flattened['{{STATE_MANAGEMENT}}'] = config.techStack.stateManagement;\n if (config.techStack.testFramework)\n flattened['{{TEST_FRAMEWORK}}'] = config.techStack.testFramework;\n if (config.techStack.bundler)\n flattened['{{BUNDLER}}'] = config.techStack.bundler;\n if (config.techStack.apiFramework)\n flattened['{{API_FRAMEWORK}}'] = config.techStack.apiFramework;\n }\n\n // Environment\n if (config.environment) {\n if (config.environment.githubTokenEnv)\n flattened['{{GITHUB_TOKEN_ENV}}'] = config.environment.githubTokenEnv;\n if (config.environment.githubOwnerEnv)\n flattened['{{GITHUB_OWNER_ENV}}'] = config.environment.githubOwnerEnv;\n if (config.environment.githubRepoEnv)\n flattened['{{GITHUB_REPO_ENV}}'] = config.environment.githubRepoEnv;\n if (config.environment.issueTrackerTokenEnv)\n flattened['{{ISSUE_TRACKER_TOKEN_ENV}}'] = config.environment.issueTrackerTokenEnv;\n }\n\n // Brand\n if (config.brand) {\n if (config.brand.brandName)\n flattened['{{BRAND_NAME}}'] = config.brand.brandName;\n if (config.brand.primaryColor)\n flattened['{{PRIMARY_COLOR}}'] = config.brand.primaryColor;\n if (config.brand.secondaryColor)\n flattened['{{SECONDARY_COLOR}}'] = config.brand.secondaryColor;\n if (config.brand.fontFamily)\n flattened['{{FONT_FAMILY}}'] = config.brand.fontFamily;\n if (config.brand.toneOfVoice)\n flattened['{{TONE_OF_VOICE}}'] = config.brand.toneOfVoice;\n }\n\n return flattened;\n}\n\n/**\n * Check if file should be processed\n */\nfunction shouldProcessFile(filePath: string): boolean {\n const ext = path.extname(filePath).toLowerCase();\n return PROCESSABLE_EXTENSIONS.includes(ext);\n}\n\n/**\n * Check if directory should be skipped\n */\nfunction shouldSkipDirectory(dirName: string): boolean {\n return SKIP_DIRECTORIES.includes(dirName) || dirName.startsWith('.');\n}\n\n/**\n * Get all files in directory recursively\n */\nasync function getAllFiles(dir: string): Promise<string[]> {\n const files: string[] = [];\n\n try {\n const entries = await fs.readdir(dir, { withFileTypes: true });\n\n for (const entry of entries) {\n const fullPath = path.join(dir, entry.name);\n\n if (entry.isDirectory()) {\n if (!shouldSkipDirectory(entry.name)) {\n const subFiles = await getAllFiles(fullPath);\n files.push(...subFiles);\n }\n } else if (entry.isFile() && shouldProcessFile(entry.name)) {\n files.push(fullPath);\n }\n }\n } catch {\n // Directory doesn't exist or can't be read\n }\n\n return files;\n}\n\n/**\n * Replace placeholders in a single file\n */\nasync function replaceInFile(\n filePath: string,\n replacements: Record<string, string>\n): Promise<Array<{ placeholder: string; value: string }>> {\n const changes: Array<{ placeholder: string; value: string }> = [];\n\n try {\n let content = await fs.readFile(filePath, 'utf-8');\n let modified = false;\n\n for (const [placeholder, value] of Object.entries(replacements)) {\n if (content.includes(placeholder)) {\n content = content.split(placeholder).join(value);\n changes.push({ placeholder, value });\n modified = true;\n }\n }\n\n if (modified) {\n await fs.writeFile(filePath, content, 'utf-8');\n }\n } catch {\n // File can't be read/written, skip\n }\n\n return changes;\n}\n\n/**\n * Replace template placeholders in directory\n */\nexport async function replaceTemplatePlaceholders(\n dir: string,\n config: Partial<TemplateConfig>\n): Promise<TemplatePlaceholderReport> {\n const replacements = flattenTemplateConfig(config);\n const files = await getAllFiles(dir);\n const report: TemplatePlaceholderReport = {\n totalFiles: files.length,\n filesModified: 0,\n replacements: [],\n unreplaced: [],\n };\n\n for (const file of files) {\n const changes = await replaceInFile(file, replacements);\n if (changes.length > 0) {\n report.filesModified++;\n for (const change of changes) {\n report.replacements.push({\n file: path.relative(dir, file),\n placeholder: change.placeholder,\n value: change.value,\n });\n }\n }\n }\n\n // Find unreplaced placeholders\n const allPatterns = TEMPLATE_PLACEHOLDERS.map((p) => p.pattern);\n const replacedPatterns = new Set(Object.keys(replacements));\n report.unreplaced = allPatterns.filter((p) => !replacedPatterns.has(p));\n\n return report;\n}\n\n/**\n * Replace template placeholders with spinner UI\n */\nexport async function replaceTemplateConfigWithSpinner(\n dir: string,\n config: Partial<TemplateConfig>\n): Promise<TemplatePlaceholderReport> {\n const spinner = ora('Applying template configuration...').start();\n\n try {\n const report = await replaceTemplatePlaceholders(dir, config);\n\n if (report.filesModified > 0) {\n spinner.succeed(\n `Applied ${report.replacements.length} replacements in ${report.filesModified} files`\n );\n } else {\n spinner.info('No template placeholders found to replace');\n }\n\n return report;\n } catch (error) {\n spinner.fail('Failed to apply template configuration');\n throw error;\n }\n}\n\n/**\n * Get a summary of the replacement report\n */\nexport function formatReplacementReport(\n report: TemplatePlaceholderReport\n): string {\n const lines: string[] = [];\n\n lines.push(`Template Configuration Applied`);\n lines.push(`${'─'.repeat(40)}`);\n lines.push(`Total files scanned: ${report.totalFiles}`);\n lines.push(`Files modified: ${report.filesModified}`);\n lines.push(`Total replacements: ${report.replacements.length}`);\n\n if (report.replacements.length > 0) {\n lines.push('');\n lines.push('Replacements:');\n\n // Group by file\n const byFile: Record<string, string[]> = {};\n for (const r of report.replacements) {\n if (!byFile[r.file]) {\n byFile[r.file] = [];\n }\n byFile[r.file].push(` ${r.placeholder} → ${r.value}`);\n }\n\n for (const [file, changes] of Object.entries(byFile)) {\n lines.push(` ${file}:`);\n for (const change of changes) {\n lines.push(change);\n }\n }\n }\n\n if (report.unreplaced.length > 0) {\n lines.push('');\n lines.push('Not configured (using defaults or runtime values):');\n for (const p of report.unreplaced.slice(0, 10)) {\n lines.push(` ${p}`);\n }\n if (report.unreplaced.length > 10) {\n lines.push(` ... and ${report.unreplaced.length - 10} more`);\n }\n }\n\n return lines.join('\\n');\n}\n\n/**\n * Preview replacements without making changes\n */\nexport async function previewReplacements(\n dir: string,\n config: Partial<TemplateConfig>\n): Promise<{ file: string; placeholder: string; value: string }[]> {\n const replacements = flattenTemplateConfig(config);\n const files = await getAllFiles(dir);\n const preview: Array<{ file: string; placeholder: string; value: string }> = [];\n\n for (const file of files) {\n try {\n const content = await fs.readFile(file, 'utf-8');\n\n for (const [placeholder, value] of Object.entries(replacements)) {\n if (content.includes(placeholder)) {\n preview.push({\n file: path.relative(dir, file),\n placeholder,\n value,\n });\n }\n }\n } catch {\n // Skip unreadable files\n }\n }\n\n return preview;\n}\n"],"mappings":"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","names":["fs","path","chalk","CONFIG_FILE","CLAUDE_DIR","fs","path","glob","module","ora","pc","module","variable","path","getModuleIds","fs","path","fs","path","import_ora"]}
1
+ {"version":3,"sources":["../node_modules/.pnpm/tsup@8.5.1_jiti@2.6.1_postcss@8.5.6_typescript@5.9.3/node_modules/tsup/assets/cjs_shims.js","../src/lib/utils/fs.ts","../src/index.ts","../src/constants/bundles.ts","../src/constants/mcp-servers.ts","../src/constants/dependencies.ts","../src/constants/placeholders.ts","../src/constants/permissions.ts","../src/lib/bundles/resolver.ts","../src/lib/config/index.ts","../src/lib/config/reader.ts","../src/lib/utils/logger.ts","../src/lib/config/writer.ts","../src/lib/config/global-defaults.ts","../src/lib/modules/index.ts","../src/lib/modules/registry.ts","../src/lib/modules/resolver.ts","../src/lib/modules/installer.ts","../src/lib/utils/spinner.ts","../src/lib/placeholders/index.ts","../src/lib/placeholders/replacer.ts","../src/lib/scaffold/detector.ts","../src/lib/templates/index.ts","../src/lib/templates/parser.ts","../src/lib/templates/evaluator.ts","../src/lib/templates/processor.ts","../src/lib/templates/context.ts","../src/lib/templates/scanner.ts","../src/constants/template-placeholders.ts","../src/lib/templates/config-replacer.ts"],"sourcesContent":["// Shim globals in cjs bundle\n// There's a weird bug that esbuild will always inject importMetaUrl\n// if we export it as `const importMetaUrl = ... __filename ...`\n// But using a function will not cause this issue\n\nconst getImportMetaUrl = () => \n typeof document === \"undefined\" \n ? new URL(`file:${__filename}`).href \n : (document.currentScript && document.currentScript.tagName.toUpperCase() === 'SCRIPT') \n ? document.currentScript.src \n : new URL(\"main.js\", document.baseURI).href;\n\nexport const importMetaUrl = /* @__PURE__ */ getImportMetaUrl()\n","/**\n * Filesystem utility functions\n */\n\nimport path from 'node:path';\nimport fs from 'fs-extra';\nimport { glob } from 'glob';\n\n/**\n * Check if a path exists\n */\nexport async function pathExists(filePath: string): Promise<boolean> {\n return fs.pathExists(filePath);\n}\n\n/**\n * Check if a path is a directory\n */\nexport async function isDirectory(filePath: string): Promise<boolean> {\n try {\n const stat = await fs.stat(filePath);\n return stat.isDirectory();\n } catch {\n return false;\n }\n}\n\n/**\n * Check if a path is a file\n */\nexport async function isFile(filePath: string): Promise<boolean> {\n try {\n const stat = await fs.stat(filePath);\n return stat.isFile();\n } catch {\n return false;\n }\n}\n\n/**\n * Read a JSON file\n */\nexport async function readJson<T = unknown>(filePath: string): Promise<T> {\n return fs.readJson(filePath);\n}\n\n/**\n * Write a JSON file\n */\nexport async function writeJson(\n filePath: string,\n data: unknown,\n options?: { spaces?: number }\n): Promise<void> {\n await fs.ensureDir(path.dirname(filePath));\n await fs.writeJson(filePath, data, { spaces: options?.spaces ?? 2 });\n}\n\n/**\n * Read a text file\n */\nexport async function readFile(filePath: string): Promise<string> {\n return fs.readFile(filePath, 'utf-8');\n}\n\n/**\n * Write a text file\n */\nexport async function writeFile(filePath: string, content: string): Promise<void> {\n await fs.ensureDir(path.dirname(filePath));\n await fs.writeFile(filePath, content, 'utf-8');\n}\n\n/**\n * Copy a file or directory\n */\nexport async function copy(\n src: string,\n dest: string,\n options?: { overwrite?: boolean }\n): Promise<void> {\n await fs.ensureDir(path.dirname(dest));\n await fs.copy(src, dest, { overwrite: options?.overwrite ?? false });\n}\n\n/**\n * Copy a directory recursively\n */\nexport async function copyDir(\n src: string,\n dest: string,\n options?: { overwrite?: boolean; filter?: (src: string) => boolean }\n): Promise<void> {\n await fs.copy(src, dest, {\n overwrite: options?.overwrite ?? false,\n filter: options?.filter,\n });\n}\n\n/**\n * Create a directory (and parents if needed)\n */\nexport async function ensureDir(dirPath: string): Promise<void> {\n await fs.ensureDir(dirPath);\n}\n\n/**\n * Remove a file or directory\n */\nexport async function remove(filePath: string): Promise<void> {\n await fs.remove(filePath);\n}\n\n/**\n * List files matching a pattern\n */\nexport async function listFiles(\n pattern: string,\n options?: { cwd?: string; ignore?: string[] }\n): Promise<string[]> {\n return glob(pattern, {\n cwd: options?.cwd,\n ignore: options?.ignore,\n nodir: true,\n });\n}\n\n/**\n * List directories matching a pattern\n */\nexport async function listDirs(pattern: string, options?: { cwd?: string }): Promise<string[]> {\n const matches = await glob(pattern, {\n cwd: options?.cwd,\n });\n\n const dirs: string[] = [];\n for (const match of matches) {\n const fullPath = options?.cwd ? path.join(options.cwd, match) : match;\n if (await isDirectory(fullPath)) {\n dirs.push(match);\n }\n }\n\n return dirs;\n}\n\n/**\n * Get file info\n */\nexport async function getFileInfo(filePath: string): Promise<{\n exists: boolean;\n isFile: boolean;\n isDirectory: boolean;\n size: number;\n modified: Date;\n} | null> {\n try {\n const stat = await fs.stat(filePath);\n return {\n exists: true,\n isFile: stat.isFile(),\n isDirectory: stat.isDirectory(),\n size: stat.size,\n modified: stat.mtime,\n };\n } catch {\n return null;\n }\n}\n\n/**\n * Read all files in a directory recursively\n */\nexport async function readDirRecursive(\n dirPath: string,\n options?: { extensions?: string[] }\n): Promise<string[]> {\n const pattern = options?.extensions ? `**/*.{${options.extensions.join(',')}}` : '**/*';\n\n return glob(pattern, {\n cwd: dirPath,\n nodir: true,\n });\n}\n\n/**\n * Calculate hash of a file for comparison\n */\nexport async function getFileHash(filePath: string): Promise<string> {\n const crypto = await import('node:crypto');\n const content = await fs.readFile(filePath);\n return crypto.createHash('sha256').update(content).digest('hex');\n}\n\n/**\n * Compare two files\n */\nexport async function filesAreEqual(file1: string, file2: string): Promise<boolean> {\n try {\n const [hash1, hash2] = await Promise.all([getFileHash(file1), getFileHash(file2)]);\n return hash1 === hash2;\n } catch {\n return false;\n }\n}\n\n/**\n * Get relative path from base\n */\nexport function relativePath(from: string, to: string): string {\n return path.relative(from, to);\n}\n\n/**\n * Resolve path segments\n */\nexport function resolvePath(...segments: string[]): string {\n return path.resolve(...segments);\n}\n\n/**\n * Join path segments\n */\nexport function joinPath(...segments: string[]): string {\n return path.join(...segments);\n}\n\n/**\n * Get directory name\n */\nexport function dirname(filePath: string): string {\n return path.dirname(filePath);\n}\n\n/**\n * Get base name\n */\nexport function basename(filePath: string, ext?: string): string {\n return path.basename(filePath, ext);\n}\n\n/**\n * Get file extension\n */\nexport function extname(filePath: string): string {\n return path.extname(filePath);\n}\n\n/**\n * Backup a file or directory\n */\nexport async function backup(src: string, suffix = '.backup'): Promise<string> {\n const backupPath = `${src}${suffix}`;\n await copy(src, backupPath, { overwrite: true });\n return backupPath;\n}\n\n/**\n * Make a file executable (Unix only)\n */\nexport async function makeExecutable(filePath: string): Promise<void> {\n try {\n await fs.chmod(filePath, 0o755);\n } catch {\n // Ignore on Windows\n }\n}\n\n/**\n * Temporary directory utilities\n */\nexport async function createTempDir(prefix = 'claude-config-'): Promise<string> {\n const os = await import('node:os');\n const tempBase = os.tmpdir();\n const tempDir = path.join(tempBase, `${prefix}${Date.now()}`);\n await ensureDir(tempDir);\n return tempDir;\n}\n\nexport async function cleanTempDir(tempDir: string): Promise<void> {\n await remove(tempDir);\n}\n","/**\n * @qazuor/claude-code-config\n *\n * CLI tool to install and manage Claude Code configurations\n */\n\n// Export types\nexport type {\n ClaudeConfig,\n ModuleSelection,\n HookConfig,\n TemplateSource,\n Preferences,\n ScaffoldConfig,\n Customizations,\n} from './types/config.js';\n\nexport type {\n ModuleRegistry,\n ModuleDefinition,\n ModuleCategory,\n ResolvedModule,\n} from './types/modules.js';\n\nexport type {\n BundleCategory,\n BundleDefinition,\n BundleSelectionResult,\n ResolvedBundle,\n} from './types/bundles.js';\n\nexport type {\n McpServerDefinition,\n McpCategory,\n McpConfigField,\n McpInstallation,\n} from './types/mcp.js';\n\nexport type {\n ScaffoldType,\n ProjectType,\n ScaffoldOptions,\n ScaffoldResult,\n ProjectDetectionResult,\n} from './types/scaffold.js';\n\nexport type { PermissionPreset, PermissionsConfig } from './types/permissions.js';\n\n// Export constants\nexport { BUNDLES, getAllBundles, getBundleById } from './constants/bundles.js';\nexport { MCP_SERVERS } from './constants/mcp-servers.js';\nexport { DEPENDENCIES } from './constants/dependencies.js';\nexport { PLACEHOLDERS } from './constants/placeholders.js';\nexport { PERMISSION_PRESETS } from './constants/permissions.js';\n\n// Export bundle resolver\nexport { resolveBundles, resolveBundle, mergeBundleSelection } from './lib/bundles/resolver.js';\n\n// Export programmatic API\nexport { readConfig, writeConfig, hasConfig, createDefaultConfig } from './lib/config/index.js';\nexport { loadRegistry, resolveModules, installModules } from './lib/modules/index.js';\nexport { replacePlaceholders } from './lib/placeholders/index.js';\nexport { detectProject } from './lib/scaffold/detector.js';\nexport { processTemplates, buildTemplateContext } from './lib/templates/index.js';\n\n// Export template types\nexport type {\n TemplateContext,\n TemplateResult,\n TemplateProcessingReport,\n} from './types/templates.js';\n","/**\n * Predefined bundles for grouping related modules\n */\n\nimport type { BundleDefinition } from '../types/bundles.js';\n\n/**\n * All available bundles\n */\nexport const BUNDLES: BundleDefinition[] = [\n // ===================\n // STACK BUNDLES\n // ===================\n {\n id: 'react-tanstack-stack',\n name: 'React + TanStack Stack',\n description: 'React with TanStack Router/Start for admin dashboards and SPAs',\n category: 'stack',\n longDescription:\n 'Complete stack for building React applications with TanStack Router and Start. Includes React component development, TanStack-specific patterns, and related testing/quality tools.',\n techStack: ['React', 'TanStack Start', 'TanStack Router', 'TanStack Query', 'TypeScript'],\n tags: ['react', 'tanstack', 'admin', 'spa'],\n complexity: 'comprehensive',\n responsibilities: [\n 'React component architecture and best practices',\n 'TanStack Router file-based routing patterns',\n 'Server state management with TanStack Query',\n 'Form handling with React Hook Form + Zod',\n 'UI components with Shadcn/Radix primitives',\n ],\n scope: 'Full frontend stack for React SPAs and admin dashboards',\n useCases: [\n 'Admin dashboards and internal tools',\n 'Complex single-page applications',\n 'Data-heavy applications with tables/forms',\n 'Projects using TanStack ecosystem',\n ],\n moduleDetails: {\n agents: [\n {\n id: 'react-senior-dev',\n role: 'React Architecture',\n responsibilities: ['Component design', 'State management', 'Performance optimization'],\n },\n {\n id: 'tanstack-start-engineer',\n role: 'TanStack Specialist',\n responsibilities: ['Router setup', 'Query patterns', 'SSR configuration'],\n },\n {\n id: 'ux-ui-designer',\n role: 'UI/UX Design',\n responsibilities: ['Component styling', 'Accessibility', 'Design system'],\n },\n ],\n skills: [\n { id: 'web-app-testing', purpose: 'React Testing Library patterns' },\n { id: 'shadcn-specialist', purpose: 'Shadcn UI component usage' },\n { id: 'accessibility-audit', purpose: 'WCAG compliance' },\n { id: 'tanstack-query-patterns', purpose: 'Query/mutation patterns' },\n { id: 'react-hook-form-patterns', purpose: 'Form validation patterns' },\n { id: 'zustand-patterns', purpose: 'Client state management' },\n ],\n commands: [],\n docs: [{ id: 'design-standards', topic: 'UI/UX design standards' }],\n },\n modules: [\n { id: 'react-senior-dev', category: 'agents' },\n { id: 'tanstack-start-engineer', category: 'agents' },\n { id: 'ux-ui-designer', category: 'agents' },\n { id: 'web-app-testing', category: 'skills' },\n { id: 'shadcn-specialist', category: 'skills' },\n { id: 'accessibility-audit', category: 'skills' },\n { id: 'tanstack-query-patterns', category: 'skills' },\n { id: 'react-hook-form-patterns', category: 'skills' },\n { id: 'zustand-patterns', category: 'skills', optional: true },\n { id: 'design-standards', category: 'docs', requiredBy: ['ux-ui-designer'], optional: true },\n ],\n },\n {\n id: 'astro-react-stack',\n name: 'Astro + React Stack',\n description: 'Astro with React islands for content-focused websites',\n category: 'stack',\n longDescription:\n 'Stack for building fast, content-focused websites with Astro and React components. Perfect for marketing sites, blogs, and documentation sites.',\n techStack: ['Astro', 'React', 'Tailwind CSS', 'MDX', 'TypeScript'],\n tags: ['astro', 'react', 'ssg', 'content'],\n complexity: 'standard',\n responsibilities: [\n 'Static site generation with Astro',\n 'Interactive React islands for dynamic content',\n 'SEO optimization and meta tags',\n 'Performance-first architecture',\n 'Content management with MDX',\n ],\n scope: 'Content-focused websites with selective interactivity',\n useCases: [\n 'Marketing and landing pages',\n 'Documentation sites',\n 'Blogs and content platforms',\n 'Portfolio websites',\n ],\n moduleDetails: {\n agents: [\n {\n id: 'astro-engineer',\n role: 'Astro Specialist',\n responsibilities: ['Routing', 'Islands architecture', 'Build optimization'],\n },\n {\n id: 'react-senior-dev',\n role: 'React Components',\n responsibilities: ['Interactive components', 'Client hydration'],\n },\n {\n id: 'seo-ai-specialist',\n role: 'SEO Optimization',\n responsibilities: ['Meta tags', 'Structured data', 'Performance'],\n },\n ],\n skills: [\n { id: 'web-app-testing', purpose: 'Component testing' },\n { id: 'vercel-specialist', purpose: 'Deployment optimization' },\n { id: 'performance-audit', purpose: 'Core Web Vitals' },\n ],\n commands: [],\n docs: [],\n },\n modules: [\n { id: 'astro-engineer', category: 'agents' },\n { id: 'react-senior-dev', category: 'agents' },\n { id: 'seo-ai-specialist', category: 'agents' },\n { id: 'web-app-testing', category: 'skills' },\n { id: 'vercel-specialist', category: 'skills' },\n { id: 'performance-audit', category: 'skills' },\n ],\n },\n {\n id: 'nextjs-prisma-stack',\n name: 'Next.js + Prisma Stack',\n description: 'Full-stack Next.js with Prisma for modern web apps',\n category: 'stack',\n longDescription:\n 'Complete full-stack setup with Next.js App Router and Prisma ORM. Includes React components, Server Actions, and database patterns.',\n techStack: ['Next.js', 'React', 'Prisma', 'Tailwind CSS', 'TypeScript'],\n tags: ['nextjs', 'prisma', 'fullstack', 'react'],\n complexity: 'comprehensive',\n alternativeTo: ['react-tanstack-stack', 'astro-react-stack'],\n responsibilities: [\n 'Full-stack React with Next.js App Router',\n 'Database modeling with Prisma ORM',\n 'Server Actions and API routes',\n 'Authentication with NextAuth.js',\n 'Deployment on Vercel',\n ],\n scope: 'Complete full-stack web application development',\n useCases: [\n 'SaaS applications',\n 'E-commerce platforms',\n 'Full-stack web apps with auth',\n 'Projects needing SSR/SSG flexibility',\n ],\n moduleDetails: {\n agents: [\n {\n id: 'nextjs-engineer',\n role: 'Next.js Specialist',\n responsibilities: ['App Router', 'Server Actions', 'Caching strategies'],\n },\n {\n id: 'react-senior-dev',\n role: 'React Components',\n responsibilities: ['Client components', 'State management'],\n },\n {\n id: 'prisma-engineer',\n role: 'Database',\n responsibilities: ['Schema design', 'Migrations', 'Query optimization'],\n },\n {\n id: 'ux-ui-designer',\n role: 'UI/UX',\n responsibilities: ['Design system', 'Responsive design'],\n },\n ],\n skills: [\n { id: 'web-app-testing', purpose: 'Next.js testing patterns' },\n { id: 'shadcn-specialist', purpose: 'UI components' },\n { id: 'vercel-specialist', purpose: 'Deployment' },\n { id: 'tanstack-query-patterns', purpose: 'Client data fetching' },\n { id: 'react-hook-form-patterns', purpose: 'Form handling' },\n { id: 'nextauth-patterns', purpose: 'Authentication' },\n ],\n commands: [],\n docs: [],\n },\n modules: [\n { id: 'nextjs-engineer', category: 'agents' },\n { id: 'react-senior-dev', category: 'agents' },\n { id: 'prisma-engineer', category: 'agents' },\n { id: 'ux-ui-designer', category: 'agents' },\n { id: 'web-app-testing', category: 'skills' },\n { id: 'shadcn-specialist', category: 'skills' },\n { id: 'vercel-specialist', category: 'skills' },\n { id: 'tanstack-query-patterns', category: 'skills' },\n { id: 'react-hook-form-patterns', category: 'skills' },\n { id: 'nextauth-patterns', category: 'skills', optional: true },\n ],\n },\n {\n id: 'express-prisma-stack',\n name: 'Express + Prisma API Stack',\n description: 'Express backend with Prisma ORM',\n category: 'stack',\n longDescription:\n 'Backend stack using Express for APIs and Prisma for database access. Classic, well-documented stack for traditional REST APIs.',\n techStack: ['Express.js', 'Prisma', 'PostgreSQL', 'Zod', 'TypeScript'],\n tags: ['express', 'prisma', 'api', 'backend'],\n complexity: 'standard',\n alternativeTo: ['hono-drizzle-stack'],\n responsibilities: [\n 'RESTful API design with Express',\n 'Database access with Prisma ORM',\n 'Request validation with Zod',\n 'Error handling and logging',\n 'Authentication middleware',\n ],\n scope: 'Backend API development with traditional Express patterns',\n useCases: [\n 'REST APIs for mobile apps',\n 'Backend services for SPAs',\n 'Microservices',\n 'Projects needing Express ecosystem',\n ],\n moduleDetails: {\n agents: [\n {\n id: 'express-engineer',\n role: 'Express Specialist',\n responsibilities: ['Route design', 'Middleware', 'Error handling'],\n },\n {\n id: 'prisma-engineer',\n role: 'Database',\n responsibilities: ['Schema', 'Migrations', 'Queries'],\n },\n {\n id: 'node-typescript-engineer',\n role: 'Node.js/TypeScript',\n responsibilities: ['Type safety', 'Build config', 'Shared packages'],\n },\n ],\n skills: [\n { id: 'api-app-testing', purpose: 'API testing with supertest' },\n { id: 'error-handling-patterns', purpose: 'Error middleware' },\n { id: 'security-testing', purpose: 'Security best practices' },\n ],\n commands: [],\n docs: [{ id: 'architecture-patterns', topic: 'API architecture patterns' }],\n },\n modules: [\n { id: 'express-engineer', category: 'agents' },\n { id: 'prisma-engineer', category: 'agents' },\n { id: 'node-typescript-engineer', category: 'agents' },\n { id: 'api-app-testing', category: 'skills' },\n { id: 'error-handling-patterns', category: 'skills' },\n { id: 'security-testing', category: 'skills' },\n { id: 'architecture-patterns', category: 'docs', optional: true },\n ],\n },\n {\n id: 'hono-drizzle-stack',\n name: 'Hono + Drizzle API Stack',\n description: 'Hono API framework with Drizzle ORM for type-safe backends',\n category: 'stack',\n longDescription:\n 'Complete backend stack using Hono for APIs and Drizzle for database access. Includes shared TypeScript packages, API testing, and quality tools.',\n techStack: ['Hono', 'Drizzle ORM', 'PostgreSQL', 'Zod', 'TypeScript'],\n tags: ['hono', 'drizzle', 'api', 'backend'],\n complexity: 'standard',\n alternativeTo: ['express-prisma-stack'],\n responsibilities: [\n 'High-performance APIs with Hono',\n 'Type-safe database queries with Drizzle',\n 'Schema validation with Zod',\n 'Edge-ready deployment',\n 'Monorepo-friendly architecture',\n ],\n scope: 'Modern, type-safe backend API development',\n useCases: [\n 'Edge/serverless APIs',\n 'Type-safe monorepo backends',\n 'High-performance REST APIs',\n 'Projects prioritizing type safety',\n ],\n moduleDetails: {\n agents: [\n {\n id: 'hono-engineer',\n role: 'Hono Specialist',\n responsibilities: ['Route handlers', 'Middleware', 'OpenAPI integration'],\n },\n {\n id: 'db-drizzle-engineer',\n role: 'Drizzle Database',\n responsibilities: ['Schema design', 'Migrations', 'Type-safe queries'],\n },\n {\n id: 'node-typescript-engineer',\n role: 'TypeScript/Node',\n responsibilities: ['Type inference', 'Build setup', 'Shared types'],\n },\n ],\n skills: [\n { id: 'api-app-testing', purpose: 'Hono testing patterns' },\n { id: 'error-handling-patterns', purpose: 'Error middleware' },\n { id: 'security-testing', purpose: 'Security validation' },\n ],\n commands: [],\n docs: [{ id: 'architecture-patterns', topic: 'API architecture patterns' }],\n },\n modules: [\n { id: 'hono-engineer', category: 'agents' },\n { id: 'db-drizzle-engineer', category: 'agents' },\n { id: 'node-typescript-engineer', category: 'agents' },\n { id: 'api-app-testing', category: 'skills' },\n { id: 'error-handling-patterns', category: 'skills' },\n { id: 'security-testing', category: 'skills' },\n { id: 'architecture-patterns', category: 'docs', optional: true },\n ],\n },\n\n // ===================\n // TESTING BUNDLES\n // ===================\n {\n id: 'testing-complete',\n name: 'Complete Testing Suite',\n description: 'All testing skills and QA tools for comprehensive test coverage',\n category: 'testing',\n longDescription:\n 'Everything you need for a robust testing strategy including TDD methodology, web testing, API testing, performance testing, and QA validation.',\n techStack: ['Vitest', 'Playwright', 'Testing Library', 'MSW'],\n tags: ['testing', 'tdd', 'qa', 'e2e'],\n complexity: 'comprehensive',\n responsibilities: [\n 'TDD workflow enforcement (Red-Green-Refactor)',\n 'Unit, integration, and E2E testing patterns',\n 'API testing with mocking and fixtures',\n 'Performance testing and benchmarking',\n 'QA validation and acceptance criteria',\n ],\n scope: 'Complete testing strategy from unit tests to E2E',\n useCases: [\n 'Projects requiring 90%+ test coverage',\n 'TDD-first development workflow',\n 'API-heavy applications needing thorough testing',\n 'Projects with QA validation requirements',\n ],\n moduleDetails: {\n agents: [\n {\n id: 'qa-engineer',\n role: 'Quality Assurance',\n responsibilities: [\n 'Test planning and strategy',\n 'Acceptance criteria validation',\n 'Bug triage and reporting',\n ],\n },\n ],\n skills: [\n { id: 'tdd-methodology', purpose: 'TDD workflow and best practices' },\n { id: 'web-app-testing', purpose: 'Frontend testing patterns' },\n { id: 'api-app-testing', purpose: 'API and backend testing' },\n { id: 'performance-testing', purpose: 'Performance benchmarks' },\n { id: 'qa-criteria-validator', purpose: 'Acceptance validation' },\n ],\n commands: [{ id: 'run-tests', usage: '/run-tests --coverage' }],\n docs: [{ id: 'testing-standards', topic: 'Testing conventions and standards' }],\n },\n modules: [\n { id: 'qa-engineer', category: 'agents' },\n { id: 'tdd-methodology', category: 'skills' },\n { id: 'web-app-testing', category: 'skills' },\n { id: 'api-app-testing', category: 'skills' },\n { id: 'performance-testing', category: 'skills' },\n { id: 'qa-criteria-validator', category: 'skills' },\n { id: 'run-tests', category: 'commands' },\n // Doc required by QA agent and TDD skill\n { id: 'testing-standards', category: 'docs', requiredBy: ['qa-engineer', 'tdd-methodology'] },\n ],\n },\n {\n id: 'testing-minimal',\n name: 'Minimal Testing',\n description: 'Essential testing tools for TDD workflow',\n category: 'testing',\n longDescription: 'Core testing tools for TDD development without the full QA suite.',\n techStack: ['Vitest', 'Testing Library'],\n tags: ['testing', 'tdd', 'minimal'],\n complexity: 'minimal',\n responsibilities: [\n 'Basic TDD workflow support',\n 'Unit and integration testing',\n 'Test execution and reporting',\n ],\n scope: 'Essential testing for small to medium projects',\n useCases: [\n 'Small projects with basic testing needs',\n 'Quick prototypes needing some test coverage',\n 'Projects where full QA suite is overkill',\n ],\n moduleDetails: {\n agents: [],\n skills: [\n { id: 'tdd-methodology', purpose: 'TDD workflow basics' },\n { id: 'api-app-testing', purpose: 'API testing patterns' },\n ],\n commands: [{ id: 'run-tests', usage: '/run-tests' }],\n docs: [],\n },\n modules: [\n { id: 'tdd-methodology', category: 'skills' },\n { id: 'api-app-testing', category: 'skills' },\n { id: 'run-tests', category: 'commands' },\n ],\n },\n\n // ===================\n // QUALITY BUNDLES\n // ===================\n {\n id: 'quality-complete',\n name: 'Complete Quality Suite',\n description: 'Full quality assurance with security, performance, and accessibility audits',\n category: 'quality',\n longDescription:\n 'Comprehensive quality assurance bundle including all audit types, code review, and debugging tools.',\n tags: ['quality', 'audit', 'security', 'performance'],\n complexity: 'comprehensive',\n responsibilities: [\n 'Security vulnerability detection and prevention',\n 'Performance profiling and optimization guidance',\n 'Accessibility compliance (WCAG) validation',\n 'Code quality review and best practices',\n 'Bug investigation and debugging assistance',\n ],\n scope: 'Complete quality assurance across security, performance, and accessibility',\n useCases: [\n 'Enterprise applications with strict security requirements',\n 'Public-facing apps needing accessibility compliance',\n 'Performance-critical applications',\n 'Projects requiring comprehensive code reviews',\n ],\n moduleDetails: {\n agents: [\n {\n id: 'qa-engineer',\n role: 'Quality Assurance Lead',\n responsibilities: [\n 'Test strategy and coverage',\n 'Acceptance criteria validation',\n 'Quality metrics tracking',\n ],\n },\n {\n id: 'debugger',\n role: 'Debug Specialist',\n responsibilities: ['Root cause analysis', 'Bug reproduction', 'Fix verification'],\n },\n ],\n skills: [\n { id: 'security-audit', purpose: 'OWASP vulnerability scanning' },\n { id: 'security-testing', purpose: 'Security test patterns' },\n { id: 'performance-audit', purpose: 'Performance bottleneck detection' },\n { id: 'performance-testing', purpose: 'Load and stress testing' },\n { id: 'accessibility-audit', purpose: 'WCAG compliance checking' },\n { id: 'qa-criteria-validator', purpose: 'Acceptance criteria validation' },\n ],\n commands: [\n { id: 'quality-check', usage: '/quality-check' },\n { id: 'code-check', usage: '/code-check src/' },\n { id: 'review-code', usage: '/review-code --thorough' },\n { id: 'review-security', usage: '/review-security' },\n { id: 'review-performance', usage: '/review-performance' },\n ],\n docs: [\n { id: 'code-standards', topic: 'Code quality standards' },\n { id: 'atomic-commits', topic: 'Atomic commit practices' },\n ],\n },\n modules: [\n { id: 'qa-engineer', category: 'agents' },\n { id: 'debugger', category: 'agents' },\n { id: 'security-audit', category: 'skills' },\n { id: 'security-testing', category: 'skills' },\n { id: 'performance-audit', category: 'skills' },\n { id: 'performance-testing', category: 'skills' },\n { id: 'accessibility-audit', category: 'skills' },\n { id: 'qa-criteria-validator', category: 'skills' },\n { id: 'quality-check', category: 'commands' },\n { id: 'code-check', category: 'commands' },\n { id: 'review-code', category: 'commands' },\n { id: 'review-security', category: 'commands' },\n { id: 'review-performance', category: 'commands' },\n // Docs required by agents\n { id: 'code-standards', category: 'docs', requiredBy: ['qa-engineer'] },\n { id: 'atomic-commits', category: 'docs', optional: true },\n ],\n },\n {\n id: 'quality-minimal',\n name: 'Minimal Quality',\n description: 'Essential quality checks for everyday development',\n category: 'quality',\n longDescription: 'Core quality tools without the full audit suite.',\n tags: ['quality', 'minimal'],\n complexity: 'minimal',\n responsibilities: [\n 'Basic code quality checks',\n 'Quick code reviews',\n 'Lint and format validation',\n ],\n scope: 'Essential quality checks for day-to-day development',\n useCases: [\n 'Small projects with basic quality needs',\n 'Quick PRs needing fast review',\n 'Projects where full audits are overkill',\n ],\n moduleDetails: {\n agents: [],\n skills: [],\n commands: [\n { id: 'quality-check', usage: '/quality-check' },\n { id: 'code-check', usage: '/code-check' },\n { id: 'review-code', usage: '/review-code' },\n ],\n docs: [],\n },\n modules: [\n { id: 'quality-check', category: 'commands' },\n { id: 'code-check', category: 'commands' },\n { id: 'review-code', category: 'commands' },\n ],\n },\n\n // ===================\n // DATABASE BUNDLES\n // ===================\n {\n id: 'drizzle-database',\n name: 'Drizzle Database',\n description: 'Drizzle ORM with type-safe database patterns',\n category: 'database',\n longDescription:\n 'Database development with Drizzle ORM including schema design, migrations, and data validation.',\n techStack: ['Drizzle ORM', 'PostgreSQL', 'SQLite', 'Zod'],\n tags: ['database', 'drizzle', 'orm'],\n alternativeTo: ['prisma-database', 'mongoose-database'],\n modules: [\n { id: 'db-drizzle-engineer', category: 'agents' },\n { id: 'json-data-auditor', category: 'skills' },\n ],\n },\n {\n id: 'prisma-database',\n name: 'Prisma Database',\n description: 'Prisma ORM with type-safe database patterns',\n category: 'database',\n longDescription:\n 'Database development with Prisma ORM including schema design, migrations, and data validation.',\n techStack: ['Prisma', 'PostgreSQL', 'MySQL', 'SQLite', 'MongoDB'],\n tags: ['database', 'prisma', 'orm'],\n alternativeTo: ['drizzle-database', 'mongoose-database'],\n modules: [\n { id: 'prisma-engineer', category: 'agents' },\n { id: 'json-data-auditor', category: 'skills' },\n ],\n },\n {\n id: 'mongoose-database',\n name: 'MongoDB + Mongoose',\n description: 'MongoDB with Mongoose ODM',\n category: 'database',\n longDescription:\n 'MongoDB development with Mongoose ODM including document schemas and aggregation pipelines.',\n techStack: ['Mongoose', 'MongoDB', 'TypeScript'],\n tags: ['database', 'mongodb', 'mongoose', 'nosql'],\n alternativeTo: ['drizzle-database', 'prisma-database'],\n modules: [\n { id: 'mongoose-engineer', category: 'agents' },\n { id: 'json-data-auditor', category: 'skills' },\n ],\n },\n\n // ===================\n // API BUNDLES\n // ===================\n {\n id: 'hono-api',\n name: 'Hono API',\n description: 'Hono framework for high-performance APIs',\n category: 'api',\n longDescription:\n 'API development with Hono framework including middleware, validation, and error handling.',\n techStack: ['Hono', 'Zod', 'TypeScript'],\n tags: ['api', 'hono', 'backend'],\n alternativeTo: ['express-api', 'fastify-api', 'nestjs-api'],\n modules: [\n { id: 'hono-engineer', category: 'agents' },\n { id: 'api-app-testing', category: 'skills' },\n { id: 'error-handling-patterns', category: 'skills' },\n ],\n },\n {\n id: 'express-api',\n name: 'Express API',\n description: 'Express.js framework for REST APIs',\n category: 'api',\n longDescription:\n 'API development with Express.js including middleware chains, validation, and error handling.',\n techStack: ['Express.js', 'Zod', 'TypeScript', 'Passport.js'],\n tags: ['api', 'express', 'backend'],\n alternativeTo: ['hono-api', 'fastify-api', 'nestjs-api'],\n modules: [\n { id: 'express-engineer', category: 'agents' },\n { id: 'api-app-testing', category: 'skills' },\n { id: 'error-handling-patterns', category: 'skills' },\n ],\n },\n {\n id: 'fastify-api',\n name: 'Fastify API',\n description: 'Fastify framework for high-performance APIs',\n category: 'api',\n longDescription:\n 'High-performance API development with Fastify plugin architecture and schema validation.',\n techStack: ['Fastify', 'TypeBox', 'TypeScript', 'Pino'],\n tags: ['api', 'fastify', 'backend', 'performance'],\n alternativeTo: ['hono-api', 'express-api', 'nestjs-api'],\n modules: [\n { id: 'fastify-engineer', category: 'agents' },\n { id: 'api-app-testing', category: 'skills' },\n { id: 'error-handling-patterns', category: 'skills' },\n ],\n },\n {\n id: 'nestjs-api',\n name: 'NestJS API',\n description: 'NestJS framework for enterprise APIs',\n category: 'api',\n longDescription:\n 'Enterprise API development with NestJS dependency injection and modular architecture.',\n techStack: ['NestJS', 'TypeScript', 'class-validator', 'TypeORM'],\n tags: ['api', 'nestjs', 'backend', 'enterprise'],\n alternativeTo: ['hono-api', 'express-api', 'fastify-api'],\n modules: [\n { id: 'nestjs-engineer', category: 'agents' },\n { id: 'api-app-testing', category: 'skills' },\n { id: 'error-handling-patterns', category: 'skills' },\n ],\n },\n\n // ===================\n // FRONTEND BUNDLES\n // ===================\n {\n id: 'react-ui',\n name: 'React UI Development',\n description: 'React component development with Shadcn UI',\n category: 'frontend',\n longDescription:\n 'React component development bundle with Shadcn UI, accessibility, and design system tools.',\n techStack: ['React', 'Shadcn UI', 'Tailwind CSS', 'Radix UI'],\n tags: ['react', 'ui', 'components'],\n modules: [\n { id: 'react-senior-dev', category: 'agents' },\n { id: 'ux-ui-designer', category: 'agents' },\n { id: 'shadcn-specialist', category: 'skills' },\n { id: 'brand-guidelines', category: 'skills' },\n { id: 'accessibility-audit', category: 'skills' },\n ],\n },\n {\n id: 'react-forms',\n name: 'React Forms',\n description: 'React Hook Form with Zod validation',\n category: 'frontend',\n longDescription:\n 'Form handling patterns with React Hook Form and Zod validation. Includes Shadcn form integration.',\n techStack: ['React Hook Form', 'Zod', 'React', 'TypeScript'],\n tags: ['react', 'forms', 'validation'],\n modules: [\n { id: 'react-senior-dev', category: 'agents' },\n { id: 'react-hook-form-patterns', category: 'skills' },\n { id: 'shadcn-specialist', category: 'skills' },\n ],\n },\n {\n id: 'react-state-zustand',\n name: 'React State (Zustand)',\n description: 'Zustand for lightweight state management',\n category: 'frontend',\n longDescription:\n 'State management with Zustand including slices, persist middleware, and TanStack Query integration.',\n techStack: ['Zustand', 'TanStack Query', 'React', 'TypeScript'],\n tags: ['react', 'state', 'zustand'],\n alternativeTo: ['react-state-redux'],\n modules: [\n { id: 'react-senior-dev', category: 'agents' },\n { id: 'zustand-patterns', category: 'skills' },\n { id: 'tanstack-query-patterns', category: 'skills' },\n ],\n },\n {\n id: 'react-state-redux',\n name: 'React State (Redux)',\n description: 'Redux Toolkit for complex state management',\n category: 'frontend',\n longDescription:\n 'State management with Redux Toolkit including RTK Query, async thunks, and enterprise patterns.',\n techStack: ['Redux Toolkit', 'RTK Query', 'React', 'TypeScript'],\n tags: ['react', 'state', 'redux'],\n alternativeTo: ['react-state-zustand'],\n modules: [\n { id: 'react-senior-dev', category: 'agents' },\n { id: 'redux-toolkit-patterns', category: 'skills' },\n { id: 'tanstack-query-patterns', category: 'skills', optional: true },\n ],\n },\n {\n id: 'nextjs-auth',\n name: 'Next.js Authentication',\n description: 'NextAuth.js authentication for Next.js apps',\n category: 'frontend',\n longDescription:\n 'Authentication patterns with NextAuth.js including OAuth providers, credentials, sessions, and RBAC.',\n techStack: ['NextAuth.js', 'Auth.js', 'Next.js', 'Prisma'],\n tags: ['nextjs', 'auth', 'oauth'],\n modules: [\n { id: 'nextjs-engineer', category: 'agents' },\n { id: 'nextauth-patterns', category: 'skills' },\n { id: 'security-testing', category: 'skills' },\n ],\n },\n {\n id: 'nextjs-i18n',\n name: 'Next.js Internationalization',\n description: 'Multi-language support for Next.js apps',\n category: 'frontend',\n longDescription:\n 'Internationalization with next-intl including locale routing, translations, and formatting.',\n techStack: ['next-intl', 'Next.js', 'React', 'TypeScript'],\n tags: ['nextjs', 'i18n', 'internationalization'],\n modules: [\n { id: 'nextjs-engineer', category: 'agents' },\n { id: 'i18n-specialist', category: 'agents', optional: true },\n { id: 'i18n-patterns', category: 'skills' },\n ],\n },\n\n // ===================\n // WORKFLOW BUNDLES\n // ===================\n {\n id: 'planning-complete',\n name: 'Complete Planning Workflow',\n description: 'Full planning workflow with PDR, tech analysis, and task tracking',\n category: 'workflow',\n longDescription:\n 'Complete planning workflow bundle including product definition, technical analysis, task breakdown, and sync to issue trackers.',\n tags: ['planning', 'workflow', 'pdr'],\n complexity: 'comprehensive',\n responsibilities: [\n 'Feature planning from requirements to implementation tasks',\n 'Technical analysis and architecture decision documentation',\n 'Task breakdown with atomic task methodology',\n 'Integration with issue trackers (GitHub, Linear)',\n ],\n scope: 'End-to-end planning workflow for features, refactors, and epics',\n useCases: [\n 'Starting a new feature from scratch',\n 'Planning a major refactor or migration',\n 'Breaking down epics into manageable tasks',\n 'Documenting technical decisions (ADRs)',\n ],\n moduleDetails: {\n agents: [\n {\n id: 'product-functional',\n role: 'Product Requirements',\n responsibilities: [\n 'Create PDR documents',\n 'Define acceptance criteria',\n 'User story mapping',\n ],\n },\n {\n id: 'product-technical',\n role: 'Technical Analysis',\n responsibilities: ['Architecture decisions', 'Tech stack evaluation', 'Risk assessment'],\n },\n {\n id: 'tech-lead',\n role: 'Coordination & Task Breakdown',\n responsibilities: ['Task atomization', 'Workflow selection', 'Team coordination'],\n },\n ],\n skills: [],\n commands: [\n { id: 'start-feature-plan', usage: '/start-feature-plan \"User authentication\"' },\n { id: 'start-refactor-plan', usage: '/start-refactor-plan \"Database optimization\"' },\n { id: 'sync-planning', usage: '/sync-planning' },\n ],\n docs: [\n { id: 'decision-tree', topic: 'Workflow selection guide' },\n { id: 'phase-1-planning', topic: 'Planning phase methodology' },\n { id: 'phase-2-implementation', topic: 'Implementation phase guide' },\n { id: 'phase-3-validation', topic: 'Validation and QA phase' },\n { id: 'phase-4-finalization', topic: 'Closing and documentation' },\n { id: 'pdr-template', topic: 'Product Definition Record template' },\n { id: 'tech-analysis-template', topic: 'Technical analysis template' },\n { id: 'todos-template', topic: 'Task tracking template' },\n ],\n },\n modules: [\n { id: 'product-functional', category: 'agents' },\n { id: 'product-technical', category: 'agents' },\n { id: 'tech-lead', category: 'agents' },\n { id: 'start-feature-plan', category: 'commands' },\n { id: 'start-refactor-plan', category: 'commands' },\n { id: 'sync-planning', category: 'commands' },\n // Required docs - needed for agents to work properly\n { id: 'decision-tree', category: 'docs', requiredBy: ['tech-lead'] },\n {\n id: 'phase-1-planning',\n category: 'docs',\n requiredBy: ['product-functional', 'product-technical'],\n },\n { id: 'phase-2-implementation', category: 'docs', requiredBy: ['tech-lead'] },\n { id: 'phase-3-validation', category: 'docs' },\n { id: 'phase-4-finalization', category: 'docs' },\n { id: 'pdr-template', category: 'docs', requiredBy: ['product-functional'] },\n { id: 'tech-analysis-template', category: 'docs', requiredBy: ['product-technical'] },\n { id: 'todos-template', category: 'docs', requiredBy: ['tech-lead'] },\n ],\n },\n {\n id: 'documentation-complete',\n name: 'Complete Documentation',\n description: 'All documentation standards, templates, and writing tools',\n category: 'workflow',\n longDescription:\n 'Everything for comprehensive documentation including standards, templates, diagrams, and writing guidelines.',\n tags: ['documentation', 'writing', 'standards'],\n complexity: 'standard',\n responsibilities: [\n 'Technical documentation writing',\n 'API documentation generation',\n 'Architecture diagram creation',\n 'Markdown formatting and standards',\n 'Glossary and terminology management',\n ],\n scope: 'Complete documentation workflow for technical projects',\n useCases: [\n 'Creating and maintaining project documentation',\n 'Writing API and SDK documentation',\n 'Creating architecture diagrams',\n 'Standardizing documentation across team',\n ],\n moduleDetails: {\n agents: [\n {\n id: 'tech-writer',\n role: 'Technical Writer',\n responsibilities: ['Documentation structure', 'Content writing', 'Style consistency'],\n },\n ],\n skills: [\n { id: 'documentation-writer', purpose: 'Documentation best practices' },\n { id: 'mermaid-diagram-specialist', purpose: 'Diagram creation' },\n ],\n commands: [\n { id: 'update-docs', usage: '/update-docs' },\n { id: 'markdown-format', usage: '/markdown-format' },\n ],\n docs: [\n { id: 'documentation-standards', topic: 'Documentation conventions' },\n { id: 'workflow-diagrams', topic: 'Diagram templates' },\n { id: 'glossary', topic: 'Project terminology' },\n ],\n },\n modules: [\n { id: 'tech-writer', category: 'agents' },\n { id: 'documentation-writer', category: 'skills' },\n { id: 'mermaid-diagram-specialist', category: 'skills' },\n { id: 'update-docs', category: 'commands' },\n { id: 'markdown-format', category: 'commands' },\n { id: 'documentation-standards', category: 'docs', requiredBy: ['tech-writer'] },\n { id: 'workflow-diagrams', category: 'docs', optional: true },\n { id: 'glossary', category: 'docs', optional: true },\n ],\n },\n {\n id: 'git-workflow',\n name: 'Git Workflow',\n description: 'Git commit conventions and atomic commit practices',\n category: 'workflow',\n longDescription: 'Git workflow tools including conventional commits and atomic commit helpers.',\n tags: ['git', 'commits', 'workflow'],\n complexity: 'minimal',\n responsibilities: [\n 'Conventional commit message formatting',\n 'Atomic commit enforcement',\n 'Commit message generation',\n ],\n scope: 'Git commit workflow and conventions',\n useCases: [\n 'Enforcing commit message standards',\n 'Generating semantic commit messages',\n 'Following atomic commit practices',\n ],\n moduleDetails: {\n agents: [],\n skills: [{ id: 'git-commit-helper', purpose: 'Commit message patterns' }],\n commands: [{ id: 'commit', usage: '/commit' }],\n docs: [{ id: 'atomic-commits', topic: 'Atomic commit guidelines' }],\n },\n modules: [\n { id: 'git-commit-helper', category: 'skills' },\n { id: 'commit', category: 'commands' },\n { id: 'atomic-commits', category: 'docs', optional: true },\n ],\n },\n {\n id: 'cicd-github-actions',\n name: 'GitHub Actions CI/CD',\n description: 'GitHub Actions workflows for CI/CD automation',\n category: 'workflow',\n longDescription:\n 'Complete CI/CD setup with GitHub Actions including testing, quality checks, security scanning, and deployment workflows.',\n techStack: ['GitHub Actions', 'Node.js', 'PNPM'],\n tags: ['cicd', 'github', 'automation', 'devops'],\n complexity: 'standard',\n responsibilities: [\n 'Continuous Integration workflows',\n 'Automated testing on PRs',\n 'Code quality checks',\n 'Security scanning',\n 'Deployment automation',\n ],\n scope: 'CI/CD pipeline automation with GitHub Actions',\n useCases: [\n 'Automating test runs on PRs',\n 'Automated deployments to staging/production',\n 'Code quality gates',\n 'Security vulnerability scanning',\n ],\n moduleDetails: {\n agents: [],\n skills: [{ id: 'github-actions-specialist', purpose: 'GitHub Actions workflow patterns' }],\n commands: [],\n docs: [{ id: 'cicd-workflows', topic: 'CI/CD workflow documentation' }],\n },\n modules: [\n { id: 'github-actions-specialist', category: 'skills', optional: true },\n { id: 'cicd-workflows', category: 'docs', optional: true },\n ],\n },\n];\n\n/**\n * Get all bundles\n */\nexport function getAllBundles(): BundleDefinition[] {\n return BUNDLES;\n}\n\n/**\n * Get bundles by category\n */\nexport function getBundlesByCategory(category: string): BundleDefinition[] {\n return BUNDLES.filter((b) => b.category === category);\n}\n\n/**\n * Get bundle by ID\n */\nexport function getBundleById(id: string): BundleDefinition | undefined {\n return BUNDLES.find((b) => b.id === id);\n}\n\n/**\n * Get bundles grouped by category\n */\nexport function getBundlesGroupedByCategory(): Record<string, BundleDefinition[]> {\n const grouped: Record<string, BundleDefinition[]> = {};\n\n for (const bundle of BUNDLES) {\n if (!grouped[bundle.category]) {\n grouped[bundle.category] = [];\n }\n grouped[bundle.category].push(bundle);\n }\n\n return grouped;\n}\n\n/**\n * Category display names\n */\nexport const BUNDLE_CATEGORY_NAMES: Record<string, string> = {\n stack: 'Tech Stacks',\n testing: 'Testing',\n quality: 'Quality Assurance',\n database: 'Database',\n api: 'API Frameworks',\n frontend: 'Frontend',\n workflow: 'Workflows',\n cicd: 'CI/CD & DevOps',\n};\n","/**\n * MCP Server definitions\n * Only includes verified, real npm packages\n */\n\nimport type { McpServerDefinition } from '../types/mcp.js';\n\n/**\n * Available MCP servers - all packages verified to exist on npm\n */\nexport const MCP_SERVERS: McpServerDefinition[] = [\n // ============================================\n // DOCUMENTATION & AI TOOLS\n // ============================================\n {\n id: 'context7',\n name: 'Context7',\n description: 'Up-to-date documentation lookup for libraries and frameworks',\n package: '@upstash/context7-mcp',\n category: 'documentation',\n requiresConfig: false,\n installInstructions:\n 'API keys provide higher rate limits. Get one at https://context7.com/dashboard',\n },\n {\n id: 'perplexity',\n name: 'Perplexity',\n description: 'Web search without leaving the MCP ecosystem via Sonar API',\n package: '@chatmcp/server-perplexity-ask',\n category: 'search',\n requiresConfig: true,\n configFields: [\n {\n name: 'apiKey',\n type: 'string',\n required: true,\n description: 'Perplexity/Sonar API Key',\n envVar: 'PERPLEXITY_API_KEY',\n },\n ],\n installInstructions: 'Get API key at https://www.perplexity.ai/settings/api',\n },\n {\n id: 'sequential-thinking',\n name: 'Sequential Thinking',\n description: 'Dynamic problem-solving through structured thinking process',\n package: '@modelcontextprotocol/server-sequential-thinking',\n category: 'ai',\n requiresConfig: false,\n installInstructions: 'Helps break down complex problems into manageable steps.',\n },\n\n // ============================================\n // TESTING & BROWSER AUTOMATION\n // ============================================\n {\n id: 'puppeteer',\n name: 'Puppeteer',\n description: 'Headless Chrome automation for testing and scraping',\n package: '@modelcontextprotocol/server-puppeteer',\n category: 'testing',\n requiresConfig: false,\n },\n {\n id: 'playwright',\n name: 'Playwright',\n description: 'Browser automation via accessibility snapshots, not screenshots',\n package: '@playwright/mcp',\n category: 'testing',\n requiresConfig: false,\n installInstructions: 'Requires Node.js 18+. Supports Chrome, Firefox, WebKit.',\n },\n {\n id: 'chrome-devtools',\n name: 'Chrome DevTools',\n description: 'Control and inspect live Chrome browser with DevTools Protocol',\n package: 'chrome-devtools-mcp',\n category: 'testing',\n requiresConfig: false,\n installInstructions:\n 'Requires Chrome installed. For Claude Code: claude mcp add chrome-devtools npx chrome-devtools-mcp@latest',\n },\n\n // ============================================\n // VERSION CONTROL\n // ============================================\n {\n id: 'github',\n name: 'GitHub',\n description: 'GitHub API integration (issues, PRs, repos, file operations)',\n package: '@modelcontextprotocol/server-github',\n category: 'version-control',\n requiresConfig: true,\n configFields: [\n {\n name: 'token',\n type: 'string',\n required: false,\n description: 'GitHub Personal Access Token',\n envVar: 'GITHUB_TOKEN',\n },\n ],\n installInstructions:\n 'Create a Personal Access Token at https://github.com/settings/tokens with repo scope.',\n },\n {\n id: 'gitlab',\n name: 'GitLab',\n description: 'GitLab API for project management, issues, and merge requests',\n package: '@modelcontextprotocol/server-gitlab',\n category: 'version-control',\n requiresConfig: true,\n configFields: [\n {\n name: 'token',\n type: 'string',\n required: true,\n description: 'GitLab Personal Access Token',\n envVar: 'GITLAB_PERSONAL_ACCESS_TOKEN',\n },\n {\n name: 'apiUrl',\n type: 'string',\n required: false,\n description: 'GitLab API URL (default: https://gitlab.com/api/v4)',\n envVar: 'GITLAB_API_URL',\n default: 'https://gitlab.com/api/v4',\n },\n ],\n installInstructions:\n 'Create PAT at GitLab User Settings > Access Tokens with api, read_repository, write_repository scopes.',\n },\n\n // ============================================\n // DATABASES\n // ============================================\n {\n id: 'postgres',\n name: 'PostgreSQL',\n description: 'Read-only PostgreSQL database access with schema inspection',\n package: '@modelcontextprotocol/server-postgres',\n category: 'database',\n requiresConfig: true,\n configFields: [\n {\n name: 'connectionString',\n type: 'string',\n required: false,\n description: 'PostgreSQL connection string',\n envVar: 'DATABASE_URL',\n },\n ],\n installInstructions: 'Connection string format: postgresql://user:password@host:port/database',\n },\n {\n id: 'mysql',\n name: 'MySQL',\n description: 'Read-only MySQL/MariaDB database access',\n package: '@modelcontextprotocol/server-mysql',\n category: 'database',\n requiresConfig: true,\n configFields: [\n {\n name: 'connectionString',\n type: 'string',\n required: true,\n description: 'MySQL connection URL',\n envVar: 'MYSQL_URL',\n },\n ],\n installInstructions: 'Connection format: mysql://user:password@host:port/database',\n },\n {\n id: 'neon',\n name: 'Neon',\n description: 'Neon serverless PostgreSQL with branch management',\n package: '@neondatabase/mcp-server-neon',\n category: 'database',\n requiresConfig: true,\n configFields: [\n {\n name: 'apiKey',\n type: 'string',\n required: false,\n description: 'Neon API Key',\n envVar: 'NEON_API_KEY',\n },\n ],\n installInstructions: 'Get your API key from https://console.neon.tech/app/settings/api-keys',\n },\n {\n id: 'sqlite',\n name: 'SQLite',\n description: 'SQLite database interaction and business intelligence',\n package: '@modelcontextprotocol/server-sqlite',\n category: 'database',\n requiresConfig: true,\n configFields: [\n {\n name: 'dbPath',\n type: 'string',\n required: false,\n description: 'Path to SQLite database file',\n default: './data.db',\n },\n ],\n },\n {\n id: 'supabase',\n name: 'Supabase',\n description: 'Supabase projects, database, Edge Functions, and type generation',\n package: '@supabase/mcp-server-supabase',\n category: 'database',\n requiresConfig: true,\n configFields: [\n {\n name: 'accessToken',\n type: 'string',\n required: false,\n description: 'Supabase Personal Access Token',\n envVar: 'SUPABASE_ACCESS_TOKEN',\n },\n ],\n installInstructions: 'Get your access token from https://supabase.com/dashboard/account/tokens',\n },\n\n // ============================================\n // CACHE & KEY-VALUE STORES\n // ============================================\n {\n id: 'redis',\n name: 'Redis',\n description: 'Redis key-value store operations (set, get, delete, list)',\n package: '@modelcontextprotocol/server-redis',\n category: 'cache',\n requiresConfig: true,\n configFields: [\n {\n name: 'url',\n type: 'string',\n required: false,\n description: 'Redis connection URL',\n envVar: 'REDIS_URL',\n default: 'redis://localhost:6379',\n },\n ],\n installInstructions:\n 'Pass Redis URL as argument: npx @modelcontextprotocol/server-redis redis://localhost:6379',\n },\n {\n id: 'upstash',\n name: 'Upstash',\n description: 'Upstash Redis database management and commands',\n package: '@upstash/mcp-server',\n category: 'cache',\n requiresConfig: true,\n configFields: [\n {\n name: 'email',\n type: 'string',\n required: false,\n description: 'Upstash account email',\n envVar: 'UPSTASH_EMAIL',\n },\n {\n name: 'apiKey',\n type: 'string',\n required: false,\n description: 'Upstash API Key',\n envVar: 'UPSTASH_API_KEY',\n },\n ],\n installInstructions: 'Get credentials from https://console.upstash.com',\n },\n\n // ============================================\n // DEPLOYMENT & INFRASTRUCTURE\n // ============================================\n {\n id: 'cloudflare',\n name: 'Cloudflare',\n description: 'Cloudflare Workers, D1, KV, R2, and DNS management',\n package: '@cloudflare/mcp-server-cloudflare',\n category: 'deployment',\n requiresConfig: true,\n configFields: [\n {\n name: 'accountId',\n type: 'string',\n required: false,\n description: 'Cloudflare Account ID',\n envVar: 'CLOUDFLARE_ACCOUNT_ID',\n },\n ],\n installInstructions: 'Run: npx @cloudflare/mcp-server-cloudflare init',\n },\n {\n id: 'vercel',\n name: 'Vercel',\n description: 'Vercel deployments, DNS records, and project management',\n package: 'vercel-mcp',\n category: 'deployment',\n requiresConfig: true,\n configFields: [\n {\n name: 'apiKey',\n type: 'string',\n required: true,\n description: 'Vercel API Key',\n envVar: 'VERCEL_API_KEY',\n },\n ],\n installInstructions: 'Get API key at https://vercel.com/account/tokens',\n },\n {\n id: 'filesystem',\n name: 'Filesystem',\n description: 'Secure file operations with configurable access controls',\n package: '@modelcontextprotocol/server-filesystem',\n category: 'infrastructure',\n requiresConfig: false,\n },\n {\n id: 'memory',\n name: 'Memory',\n description: 'Knowledge graph-based persistent memory system',\n package: '@modelcontextprotocol/server-memory',\n category: 'infrastructure',\n requiresConfig: false,\n installInstructions: 'Memory is stored in memory.jsonl in the server directory by default.',\n },\n\n // ============================================\n // PROJECT MANAGEMENT & PRODUCTIVITY\n // ============================================\n {\n id: 'notion',\n name: 'Notion',\n description: 'Official Notion API for pages, databases, and workspace',\n package: '@notionhq/notion-mcp-server',\n category: 'project-mgmt',\n requiresConfig: true,\n configFields: [\n {\n name: 'token',\n type: 'string',\n required: true,\n description: 'Notion Integration Token',\n envVar: 'NOTION_TOKEN',\n },\n ],\n installInstructions:\n 'Create integration at https://www.notion.so/profile/integrations and share pages with it.',\n },\n {\n id: 'obsidian',\n name: 'Obsidian',\n description: 'Read and search Obsidian vaults and Markdown directories',\n package: 'mcp-obsidian',\n category: 'project-mgmt',\n requiresConfig: true,\n configFields: [\n {\n name: 'vaultPath',\n type: 'string',\n required: true,\n description: 'Path to Obsidian vault',\n },\n ],\n installInstructions: 'Works with any Markdown directory. Point to your vault path.',\n },\n {\n id: 'n8n',\n name: 'n8n',\n description: 'n8n workflow automation node documentation and management',\n package: 'n8n-mcp',\n category: 'project-mgmt',\n requiresConfig: false,\n installInstructions: 'Provides access to 543 n8n nodes documentation.',\n },\n\n // ============================================\n // MONITORING & OBSERVABILITY\n // ============================================\n {\n id: 'sentry',\n name: 'Sentry',\n description: 'Query Sentry errors, issues, and project information',\n package: '@sentry/mcp-server',\n category: 'monitoring',\n requiresConfig: true,\n configFields: [\n {\n name: 'authToken',\n type: 'string',\n required: false,\n description: 'Sentry Auth Token',\n envVar: 'SENTRY_AUTH_TOKEN',\n },\n ],\n installInstructions:\n 'For Claude Code: claude mcp add --transport http sentry https://mcp.sentry.dev/mcp',\n },\n\n // ============================================\n // COMMUNICATION\n // ============================================\n {\n id: 'slack',\n name: 'Slack',\n description: 'Slack messaging, channels, and workspace interaction',\n package: '@modelcontextprotocol/server-slack',\n category: 'communication',\n requiresConfig: true,\n configFields: [\n {\n name: 'token',\n type: 'string',\n required: false,\n description: 'Slack Bot Token (xoxb-...)',\n envVar: 'SLACK_BOT_TOKEN',\n },\n ],\n installInstructions:\n 'Create a Slack app at https://api.slack.com/apps and install to your workspace.',\n },\n\n // ============================================\n // DESIGN\n // ============================================\n {\n id: 'figma',\n name: 'Figma',\n description: 'Figma layout information for AI coding agents',\n package: 'figma-developer-mcp',\n category: 'design',\n requiresConfig: true,\n configFields: [\n {\n name: 'apiKey',\n type: 'string',\n required: true,\n description: 'Figma Personal Access Token',\n envVar: 'FIGMA_API_KEY',\n },\n ],\n installInstructions: 'Create token at https://www.figma.com/developers/api#access-tokens',\n },\n {\n id: 'shadcn',\n name: 'shadcn/ui',\n description: 'shadcn/ui component docs, installation, and code generation',\n package: '@heilgar/shadcn-ui-mcp-server',\n category: 'ui-library',\n requiresConfig: false,\n installInstructions: 'Supports npm, pnpm, yarn, and bun package managers.',\n },\n {\n id: 'magic-ui',\n name: '21st.dev Magic',\n description: 'AI-driven UI component generation through natural language',\n package: '@21st-dev/magic',\n category: 'ui-library',\n requiresConfig: true,\n configFields: [\n {\n name: 'apiKey',\n type: 'string',\n required: true,\n description: '21st.dev Magic API Key',\n envVar: 'TWENTYFIRST_API_KEY',\n },\n ],\n installInstructions: 'Get API key at https://21st.dev/magic/console',\n },\n\n // ============================================\n // PAYMENTS\n // ============================================\n {\n id: 'stripe',\n name: 'Stripe',\n description: 'Stripe payments API with MCP support via Agent Toolkit',\n package: '@stripe/agent-toolkit',\n category: 'payments',\n requiresConfig: true,\n configFields: [\n {\n name: 'secretKey',\n type: 'string',\n required: false,\n description: 'Stripe Secret Key',\n envVar: 'STRIPE_SECRET_KEY',\n },\n ],\n installInstructions:\n 'Get API keys at https://dashboard.stripe.com/apikeys. Run: npx -y @stripe/mcp --tools=all --api-key=YOUR_KEY',\n },\n {\n id: 'mercadopago',\n name: 'Mercado Pago',\n description: 'Mercado Pago payments, refunds, and customer management',\n package: 'mercado-pago-mcp',\n category: 'payments',\n requiresConfig: true,\n configFields: [\n {\n name: 'accessToken',\n type: 'string',\n required: true,\n description: 'Mercado Pago Access Token',\n envVar: 'MERCADOPAGO_ACCESS_TOKEN',\n },\n {\n name: 'environment',\n type: 'string',\n required: false,\n description: 'Environment (sandbox or production)',\n default: 'sandbox',\n },\n ],\n installInstructions: 'Get credentials at https://www.mercadopago.com/developers/panel/app',\n },\n\n // ============================================\n // SEARCH\n // ============================================\n {\n id: 'brave-search',\n name: 'Brave Search',\n description: 'Web and local search using Brave Search API',\n package: '@modelcontextprotocol/server-brave-search',\n category: 'search',\n requiresConfig: true,\n configFields: [\n {\n name: 'apiKey',\n type: 'string',\n required: false,\n description: 'Brave Search API Key',\n envVar: 'BRAVE_API_KEY',\n },\n ],\n installInstructions: 'Get an API key at https://brave.com/search/api/',\n },\n];\n\n/**\n * Get MCP server by ID\n */\nexport function getMcpServer(id: string): McpServerDefinition | undefined {\n return MCP_SERVERS.find((s) => s.id === id);\n}\n\n/**\n * Get MCP servers by category\n */\nexport function getMcpServersByCategory(\n category: McpServerDefinition['category']\n): McpServerDefinition[] {\n return MCP_SERVERS.filter((s) => s.category === category);\n}\n\n/**\n * Get all MCP server IDs\n */\nexport function getMcpServerIds(): string[] {\n return MCP_SERVERS.map((s) => s.id);\n}\n","/**\n * System dependency definitions\n */\n\nimport type { DependencyInfo } from '../types/dependencies.js';\n\n/**\n * System dependencies required for various features\n */\nexport const DEPENDENCIES: DependencyInfo[] = [\n {\n id: 'piper-tts',\n name: 'Piper TTS',\n description: 'Text-to-speech for audio notifications',\n requiredFor: ['hook:notification:audio'],\n checkCommand: 'command -v piper',\n platforms: {\n linux: {\n commands: [\n 'pip install piper-tts',\n 'mkdir -p ~/.local/share/piper/voices',\n 'wget -O ~/.local/share/piper/voices/en_US-hfc_male-medium.onnx https://huggingface.co/rhasspy/piper-voices/resolve/main/en/en_US/hfc_male/medium/en_US-hfc_male-medium.onnx',\n 'wget -O ~/.local/share/piper/voices/en_US-hfc_male-medium.onnx.json https://huggingface.co/rhasspy/piper-voices/resolve/main/en/en_US/hfc_male/medium/en_US-hfc_male-medium.onnx.json',\n ],\n notes: 'Requires Python 3.9+ and pip',\n links: ['https://github.com/rhasspy/piper'],\n },\n macos: {\n commands: [\n 'pip3 install piper-tts',\n 'mkdir -p ~/.local/share/piper/voices',\n '# Download voice files from https://github.com/rhasspy/piper/releases',\n ],\n notes: 'May need to install portaudio: brew install portaudio',\n links: ['https://github.com/rhasspy/piper'],\n },\n },\n },\n {\n id: 'notify-send',\n name: 'libnotify',\n description: 'Desktop notifications for Linux',\n requiredFor: ['hook:notification:desktop'],\n checkCommand: 'command -v notify-send',\n platforms: {\n linux: {\n commands: [\n '# Ubuntu/Debian:',\n 'sudo apt install libnotify-bin',\n '# Fedora:',\n 'sudo dnf install libnotify',\n '# Arch:',\n 'sudo pacman -S libnotify',\n ],\n },\n },\n },\n {\n id: 'terminal-notifier',\n name: 'terminal-notifier',\n description: 'Desktop notifications for macOS',\n requiredFor: ['hook:notification:desktop'],\n checkCommand: 'command -v terminal-notifier',\n platforms: {\n macos: {\n commands: ['brew install terminal-notifier'],\n links: ['https://github.com/julienXX/terminal-notifier'],\n },\n },\n },\n {\n id: 'jq',\n name: 'jq',\n description: 'JSON processor for hook scripts',\n requiredFor: ['hooks'],\n checkCommand: 'command -v jq',\n platforms: {\n linux: {\n commands: [\n '# Ubuntu/Debian:',\n 'sudo apt install jq',\n '# Fedora:',\n 'sudo dnf install jq',\n '# Arch:',\n 'sudo pacman -S jq',\n ],\n },\n macos: {\n commands: ['brew install jq'],\n },\n windows: {\n commands: ['choco install jq', '# Or: winget install jqlang.jq'],\n },\n },\n },\n {\n id: 'aplay',\n name: 'ALSA Utils',\n description: 'Audio playback for Linux',\n requiredFor: ['hook:notification:audio'],\n checkCommand: 'command -v aplay',\n platforms: {\n linux: {\n commands: [\n '# Ubuntu/Debian:',\n 'sudo apt install alsa-utils',\n '# Fedora:',\n 'sudo dnf install alsa-utils',\n '# Arch:',\n 'sudo pacman -S alsa-utils',\n ],\n },\n },\n },\n {\n id: 'afplay',\n name: 'afplay',\n description: 'Audio playback for macOS (built-in)',\n requiredFor: ['hook:notification:audio'],\n checkCommand: 'command -v afplay',\n platforms: {\n macos: {\n commands: ['# Built-in on macOS, no installation needed'],\n notes: 'afplay is included with macOS by default',\n },\n },\n },\n {\n id: 'git',\n name: 'Git',\n description: 'Version control system',\n requiredFor: ['version-control', 'remote-templates'],\n checkCommand: 'git --version',\n platforms: {\n linux: {\n commands: [\n '# Ubuntu/Debian:',\n 'sudo apt install git',\n '# Fedora:',\n 'sudo dnf install git',\n '# Arch:',\n 'sudo pacman -S git',\n ],\n },\n macos: {\n commands: ['brew install git', '# Or: xcode-select --install'],\n },\n windows: {\n commands: ['choco install git', '# Or: winget install Git.Git'],\n links: ['https://git-scm.com/download/win'],\n },\n },\n },\n {\n id: 'node',\n name: 'Node.js',\n description: 'JavaScript runtime',\n requiredFor: ['cli', 'mcp-servers'],\n checkCommand: 'node --version',\n platforms: {\n linux: {\n commands: [\n '# Using nvm (recommended):',\n 'curl -o- https://raw.githubusercontent.com/nvm-sh/nvm/v0.40.0/install.sh | bash',\n 'nvm install --lts',\n '# Or using package manager:',\n 'sudo apt install nodejs npm',\n ],\n links: ['https://nodejs.org/', 'https://github.com/nvm-sh/nvm'],\n },\n macos: {\n commands: [\n '# Using nvm (recommended):',\n 'curl -o- https://raw.githubusercontent.com/nvm-sh/nvm/v0.40.0/install.sh | bash',\n 'nvm install --lts',\n '# Or using Homebrew:',\n 'brew install node',\n ],\n links: ['https://nodejs.org/', 'https://github.com/nvm-sh/nvm'],\n },\n windows: {\n commands: ['choco install nodejs-lts', '# Or: winget install OpenJS.NodeJS.LTS'],\n links: ['https://nodejs.org/'],\n },\n },\n },\n];\n\n/**\n * Get dependency by ID\n */\nexport function getDependency(id: string): DependencyInfo | undefined {\n return DEPENDENCIES.find((d) => d.id === id);\n}\n\n/**\n * Get dependencies required for a feature\n */\nexport function getDependenciesForFeature(feature: string): DependencyInfo[] {\n return DEPENDENCIES.filter((d) => d.requiredFor.includes(feature));\n}\n\n/**\n * Get all dependency IDs\n */\nexport function getDependencyIds(): string[] {\n return DEPENDENCIES.map((d) => d.id);\n}\n","/**\n * Placeholder definitions for template processing\n */\n\nimport type { PlaceholderDefinition } from '../types/placeholders.js';\n\n/**\n * All placeholder patterns that can be replaced in templates\n */\nexport const PLACEHOLDERS: PlaceholderDefinition[] = [\n // Project info placeholders\n {\n pattern: /\\[Project Name\\]/g,\n configKey: 'name',\n transform: 'none',\n description: 'Project name',\n example: 'My Awesome Project',\n required: true,\n },\n {\n pattern: /\\[project-name\\]/g,\n configKey: 'name',\n transform: 'lowercase',\n description: 'Project name in lowercase with dashes',\n example: 'my-awesome-project',\n required: true,\n },\n {\n pattern: /\\[PROJECT_NAME\\]/g,\n configKey: 'name',\n transform: 'uppercase',\n description: 'Project name in uppercase with underscores',\n example: 'MY_AWESOME_PROJECT',\n required: true,\n },\n {\n pattern: /\\[Project Description\\]/g,\n configKey: 'description',\n transform: 'none',\n description: 'Project description',\n example: 'A powerful CLI tool for managing configurations',\n required: true,\n },\n {\n pattern: /your-org/g,\n configKey: 'org',\n transform: 'lowercase',\n description: 'GitHub organization or username',\n example: 'acme-corp',\n required: true,\n },\n {\n pattern: /your-repo/g,\n configKey: 'repo',\n transform: 'lowercase',\n description: 'Repository name',\n example: 'my-project',\n required: true,\n },\n {\n pattern: /example\\.com/g,\n configKey: 'domain',\n transform: 'lowercase',\n description: 'Project domain',\n example: 'myproject.com',\n required: false,\n },\n\n // Entity placeholders\n {\n pattern: /\\[Entity\\]/g,\n configKey: 'entityType',\n transform: 'capitalize',\n description: 'Primary entity type (capitalized)',\n example: 'Product',\n required: true,\n },\n {\n pattern: /\\[entity\\]/g,\n configKey: 'entityType',\n transform: 'lowercase',\n description: 'Primary entity type (lowercase)',\n example: 'product',\n required: true,\n },\n {\n pattern: /\\[Entities\\]/g,\n configKey: 'entityTypePlural',\n transform: 'capitalize',\n description: 'Primary entity type plural (capitalized)',\n example: 'Products',\n required: true,\n },\n {\n pattern: /\\[entities\\]/g,\n configKey: 'entityTypePlural',\n transform: 'lowercase',\n description: 'Primary entity type plural (lowercase)',\n example: 'products',\n required: true,\n },\n\n // Location placeholders\n {\n pattern: /\\[City Name\\]/g,\n configKey: 'location',\n transform: 'capitalize',\n description: 'City or location name',\n example: 'San Francisco',\n required: false,\n },\n {\n pattern: /\\[Your Region\\/Product\\]/g,\n configKey: 'location',\n transform: 'none',\n description: 'Region or product area',\n example: 'Bay Area',\n required: false,\n },\n {\n pattern: /\\[Your product\\/service tagline here\\]/g,\n configKey: 'description',\n transform: 'none',\n description: 'Product tagline',\n example: 'The best way to manage your projects',\n required: false,\n },\n];\n\n/**\n * Get placeholder by pattern string\n */\nexport function getPlaceholder(pattern: string): PlaceholderDefinition | undefined {\n return PLACEHOLDERS.find((p) => {\n if (p.pattern instanceof RegExp) {\n return p.pattern.source === pattern || p.pattern.source === new RegExp(pattern).source;\n }\n return p.pattern === pattern;\n });\n}\n\n/**\n * Get all required placeholders\n */\nexport function getRequiredPlaceholders(): PlaceholderDefinition[] {\n return PLACEHOLDERS.filter((p) => p.required);\n}\n\n/**\n * Get all optional placeholders\n */\nexport function getOptionalPlaceholders(): PlaceholderDefinition[] {\n return PLACEHOLDERS.filter((p) => !p.required);\n}\n\n/**\n * Apply transformation to a value\n */\nexport function applyTransform(\n value: string,\n transform: PlaceholderDefinition['transform']\n): string {\n switch (transform) {\n case 'lowercase':\n return value.toLowerCase().replace(/\\s+/g, '-');\n case 'uppercase':\n return value.toUpperCase().replace(/\\s+/g, '_');\n case 'capitalize':\n return value\n .split(' ')\n .map((word) => word.charAt(0).toUpperCase() + word.slice(1).toLowerCase())\n .join(' ');\n case 'pluralize':\n // Simple pluralization rules\n if (value.endsWith('y')) {\n return `${value.slice(0, -1)}ies`;\n }\n if (\n value.endsWith('s') ||\n value.endsWith('x') ||\n value.endsWith('ch') ||\n value.endsWith('sh')\n ) {\n return `${value}es`;\n }\n return `${value}s`;\n default:\n return value;\n }\n}\n","/**\n * Permission preset definitions\n */\n\nimport type {\n BashPermissions,\n FilePermissions,\n GitPermissions,\n PermissionPreset,\n PermissionsConfig,\n WebPermissions,\n} from '../types/permissions.js';\n\n/**\n * Default file permissions\n */\nconst DEFAULT_FILE_PERMISSIONS: FilePermissions = {\n readAll: true,\n writeCode: true,\n writeConfig: true,\n writeMarkdown: true,\n writeOther: false,\n editTool: true,\n};\n\n/**\n * Trust file permissions\n */\nconst TRUST_FILE_PERMISSIONS: FilePermissions = {\n readAll: true,\n writeCode: true,\n writeConfig: true,\n writeMarkdown: true,\n writeOther: true,\n editTool: true,\n};\n\n/**\n * Restrictive file permissions\n */\nconst RESTRICTIVE_FILE_PERMISSIONS: FilePermissions = {\n readAll: true,\n writeCode: false,\n writeConfig: false,\n writeMarkdown: true,\n writeOther: false,\n editTool: false,\n};\n\n/**\n * Default git permissions\n */\nconst DEFAULT_GIT_PERMISSIONS: GitPermissions = {\n readOnly: true,\n staging: false,\n commit: false,\n push: false,\n branching: false,\n};\n\n/**\n * Trust git permissions\n */\nconst TRUST_GIT_PERMISSIONS: GitPermissions = {\n readOnly: true,\n staging: true,\n commit: true,\n push: false,\n branching: true,\n};\n\n/**\n * Restrictive git permissions\n */\nconst RESTRICTIVE_GIT_PERMISSIONS: GitPermissions = {\n readOnly: true,\n staging: false,\n commit: false,\n push: false,\n branching: false,\n};\n\n/**\n * Default bash permissions\n */\nconst DEFAULT_BASH_PERMISSIONS: BashPermissions = {\n packageManager: true,\n testing: true,\n building: true,\n docker: false,\n arbitrary: false,\n};\n\n/**\n * Trust bash permissions\n */\nconst TRUST_BASH_PERMISSIONS: BashPermissions = {\n packageManager: true,\n testing: true,\n building: true,\n docker: true,\n arbitrary: true,\n};\n\n/**\n * Restrictive bash permissions\n */\nconst RESTRICTIVE_BASH_PERMISSIONS: BashPermissions = {\n packageManager: false,\n testing: false,\n building: false,\n docker: false,\n arbitrary: false,\n};\n\n/**\n * Default web permissions\n */\nconst DEFAULT_WEB_PERMISSIONS: WebPermissions = {\n fetch: true,\n search: true,\n};\n\n/**\n * All permission presets\n */\nexport const PERMISSION_PRESETS: Record<\n PermissionPreset,\n Omit<PermissionsConfig, 'preset' | 'custom'>\n> = {\n default: {\n files: DEFAULT_FILE_PERMISSIONS,\n git: DEFAULT_GIT_PERMISSIONS,\n bash: DEFAULT_BASH_PERMISSIONS,\n web: DEFAULT_WEB_PERMISSIONS,\n },\n trust: {\n files: TRUST_FILE_PERMISSIONS,\n git: TRUST_GIT_PERMISSIONS,\n bash: TRUST_BASH_PERMISSIONS,\n web: DEFAULT_WEB_PERMISSIONS,\n },\n restrictive: {\n files: RESTRICTIVE_FILE_PERMISSIONS,\n git: RESTRICTIVE_GIT_PERMISSIONS,\n bash: RESTRICTIVE_BASH_PERMISSIONS,\n web: DEFAULT_WEB_PERMISSIONS,\n },\n custom: {\n files: DEFAULT_FILE_PERMISSIONS,\n git: DEFAULT_GIT_PERMISSIONS,\n bash: DEFAULT_BASH_PERMISSIONS,\n web: DEFAULT_WEB_PERMISSIONS,\n },\n};\n\n/**\n * Default deny rules (always applied)\n */\nexport const DEFAULT_DENY_RULES: string[] = [\n // Directories\n 'Write(node_modules/**)',\n 'Write(.git/**)',\n 'Write(dist/**)',\n 'Write(build/**)',\n 'Write(.next/**)',\n 'Write(.nuxt/**)',\n 'Write(.output/**)',\n\n // System files\n 'Write(/etc/**)',\n 'Write(/usr/**)',\n 'Write(/bin/**)',\n 'Write(/sbin/**)',\n 'Write(/var/**)',\n 'Write(/tmp/**)',\n\n // Dangerous commands\n 'Bash(rm -rf /)',\n 'Bash(sudo *)',\n 'Bash(chmod 777 *)',\n 'Bash(curl * | bash)',\n 'Bash(wget * | bash)',\n\n // Sensitive files\n 'Write(.env)',\n 'Write(.env.*)',\n 'Write(**/secrets/**)',\n 'Write(**/credentials/**)',\n 'Read(.env)',\n 'Read(.env.*)',\n];\n\n/**\n * Get permissions for a preset\n */\nexport function getPresetPermissions(\n preset: PermissionPreset\n): Omit<PermissionsConfig, 'preset' | 'custom'> {\n return PERMISSION_PRESETS[preset];\n}\n\n/**\n * Generate allow rules from permissions config\n */\nexport function generateAllowRules(config: PermissionsConfig): string[] {\n const rules: string[] = [];\n\n // File permissions\n if (config.files.readAll) {\n rules.push(\n 'Read(**/*)',\n 'Glob(**/*)',\n 'Grep(**/*)',\n 'LS(**/*)',\n 'TodoRead',\n 'WebFetch',\n 'WebSearch'\n );\n }\n if (config.files.writeCode) {\n rules.push(\n 'Write(**/*.ts)',\n 'Write(**/*.tsx)',\n 'Write(**/*.js)',\n 'Write(**/*.jsx)',\n 'Write(**/*.mts)',\n 'Write(**/*.mjs)',\n 'Write(**/*.vue)',\n 'Write(**/*.svelte)'\n );\n }\n if (config.files.writeConfig) {\n rules.push(\n 'Write(**/*.json)',\n 'Write(**/*.yaml)',\n 'Write(**/*.yml)',\n 'Write(**/*.toml)',\n 'Write(**/*.xml)',\n 'Write(**/.env.example)',\n 'Write(**/.gitignore)',\n 'Write(**/.npmrc)',\n 'Write(**/.nvmrc)'\n );\n }\n if (config.files.writeMarkdown) {\n rules.push('Write(**/*.md)', 'Write(**/*.mdx)');\n }\n if (config.files.writeOther) {\n rules.push(\n 'Write(**/*.css)',\n 'Write(**/*.scss)',\n 'Write(**/*.less)',\n 'Write(**/*.html)',\n 'Write(**/*.sql)',\n 'Write(**/*.graphql)',\n 'Write(**/*.prisma)'\n );\n }\n if (config.files.editTool) {\n rules.push('Edit(**/*)', 'MultiEdit(**/*)', 'NotebookEdit(**/*)', 'TodoWrite');\n }\n\n // Git permissions\n if (config.git.readOnly) {\n rules.push(\n 'Bash(git status*)',\n 'Bash(git diff*)',\n 'Bash(git log*)',\n 'Bash(git show*)',\n 'Bash(git branch*)'\n );\n }\n if (config.git.staging) {\n rules.push('Bash(git add*)');\n }\n if (config.git.commit) {\n rules.push('Bash(git commit*)');\n }\n if (config.git.push) {\n rules.push('Bash(git push*)');\n }\n if (config.git.branching) {\n rules.push('Bash(git checkout*)', 'Bash(git branch*)', 'Bash(git merge*)', 'Bash(git rebase*)');\n }\n\n // Bash permissions\n if (config.bash.packageManager) {\n rules.push(\n 'Bash(pnpm *)',\n 'Bash(npm *)',\n 'Bash(yarn *)',\n 'Bash(bun *)',\n 'Bash(npx *)',\n 'Bash(bunx *)'\n );\n }\n if (config.bash.testing) {\n rules.push(\n 'Bash(vitest*)',\n 'Bash(jest*)',\n 'Bash(playwright*)',\n 'Bash(cypress*)',\n 'Bash(pnpm test*)',\n 'Bash(npm test*)',\n 'Bash(pnpm run test*)',\n 'Bash(npm run test*)'\n );\n }\n if (config.bash.building) {\n rules.push(\n 'Bash(pnpm build*)',\n 'Bash(npm run build*)',\n 'Bash(pnpm run build*)',\n 'Bash(tsc*)',\n 'Bash(tsup*)',\n 'Bash(vite build*)',\n 'Bash(next build*)',\n 'Bash(astro build*)'\n );\n }\n if (config.bash.docker) {\n rules.push('Bash(docker *)', 'Bash(docker-compose *)');\n }\n if (config.bash.arbitrary) {\n rules.push('Bash(*)');\n }\n\n // Web permissions\n if (config.web.fetch) {\n rules.push('WebFetch');\n }\n if (config.web.search) {\n rules.push('WebSearch');\n }\n\n // Add custom allow rules\n if (config.custom?.allow) {\n rules.push(...config.custom.allow);\n }\n\n return [...new Set(rules)]; // Remove duplicates\n}\n\n/**\n * Generate deny rules from permissions config\n */\nexport function generateDenyRules(config: PermissionsConfig): string[] {\n const rules = [...DEFAULT_DENY_RULES];\n\n // Add custom deny rules\n if (config.custom?.deny) {\n rules.push(...config.custom.deny);\n }\n\n return [...new Set(rules)]; // Remove duplicates\n}\n\n/**\n * Preset descriptions for UI\n */\nexport const PRESET_DESCRIPTIONS: Record<PermissionPreset, { name: string; description: string }> =\n {\n default: {\n name: 'Default',\n description:\n 'Balanced permissions - read all, write code/config/docs, basic git, package manager & testing',\n },\n trust: {\n name: 'Trust',\n description:\n 'Extended permissions - full file access, git staging/commit/branching, docker, arbitrary bash',\n },\n restrictive: {\n name: 'Restrictive',\n description:\n 'Minimal permissions - read only, markdown writing, no git operations, no bash commands',\n },\n custom: {\n name: 'Custom',\n description: 'Configure each permission individually',\n },\n };\n","/**\n * Bundle resolver - resolves bundles to individual modules\n */\n\nimport {\n BUNDLE_CATEGORY_NAMES,\n getAllBundles,\n getBundleById,\n getBundlesGroupedByCategory,\n} from '../../constants/bundles.js';\nimport type {\n BundleDefinition,\n BundleSelectionResult,\n ResolvedBundle,\n} from '../../types/bundles.js';\nimport type { ModuleSelectionResult } from '../../types/modules.js';\n\n/**\n * Resolve a bundle to its constituent modules\n */\nexport function resolveBundle(bundle: BundleDefinition): ResolvedBundle {\n const modules: ResolvedBundle['modules'] = {\n agents: [],\n skills: [],\n commands: [],\n docs: [],\n };\n\n for (const moduleRef of bundle.modules) {\n switch (moduleRef.category) {\n case 'agents':\n modules.agents.push(moduleRef.id);\n break;\n case 'skills':\n modules.skills.push(moduleRef.id);\n break;\n case 'commands':\n modules.commands.push(moduleRef.id);\n break;\n case 'docs':\n modules.docs.push(moduleRef.id);\n break;\n }\n }\n\n return {\n bundle,\n modules,\n };\n}\n\n/**\n * Resolve multiple bundles to a combined module selection\n */\nexport function resolveBundles(bundleIds: string[]): ModuleSelectionResult {\n const result: ModuleSelectionResult = {\n agents: [],\n skills: [],\n commands: [],\n docs: [],\n };\n\n const seenModules = {\n agents: new Set<string>(),\n skills: new Set<string>(),\n commands: new Set<string>(),\n docs: new Set<string>(),\n };\n\n for (const bundleId of bundleIds) {\n const bundle = getBundleById(bundleId);\n if (!bundle) continue;\n\n const resolved = resolveBundle(bundle);\n\n // Add modules without duplicates\n for (const id of resolved.modules.agents) {\n if (!seenModules.agents.has(id)) {\n seenModules.agents.add(id);\n result.agents.push(id);\n }\n }\n for (const id of resolved.modules.skills) {\n if (!seenModules.skills.has(id)) {\n seenModules.skills.add(id);\n result.skills.push(id);\n }\n }\n for (const id of resolved.modules.commands) {\n if (!seenModules.commands.has(id)) {\n seenModules.commands.add(id);\n result.commands.push(id);\n }\n }\n for (const id of resolved.modules.docs) {\n if (!seenModules.docs.has(id)) {\n seenModules.docs.add(id);\n result.docs.push(id);\n }\n }\n }\n\n return result;\n}\n\n/**\n * Merge bundle selection with additional individual modules\n */\nexport function mergeBundleSelection(bundleResult: BundleSelectionResult): ModuleSelectionResult {\n // Start with resolved bundles\n const result = resolveBundles(bundleResult.selectedBundles);\n\n // Track what we have\n const seenModules = {\n agents: new Set(result.agents),\n skills: new Set(result.skills),\n commands: new Set(result.commands),\n docs: new Set(result.docs),\n };\n\n // Add additional modules without duplicates\n for (const id of bundleResult.additionalModules.agents) {\n if (!seenModules.agents.has(id)) {\n result.agents.push(id);\n }\n }\n for (const id of bundleResult.additionalModules.skills) {\n if (!seenModules.skills.has(id)) {\n result.skills.push(id);\n }\n }\n for (const id of bundleResult.additionalModules.commands) {\n if (!seenModules.commands.has(id)) {\n result.commands.push(id);\n }\n }\n for (const id of bundleResult.additionalModules.docs) {\n if (!seenModules.docs.has(id)) {\n result.docs.push(id);\n }\n }\n\n return result;\n}\n\n/**\n * Find bundles that contain a specific module\n */\nexport function findBundlesContainingModule(\n moduleId: string,\n category: 'agents' | 'skills' | 'commands' | 'docs'\n): BundleDefinition[] {\n return getAllBundles().filter((bundle) =>\n bundle.modules.some((m) => m.id === moduleId && m.category === category)\n );\n}\n\n/**\n * Get suggested bundles based on selected modules\n */\nexport function getSuggestedBundles(selectedModules: ModuleSelectionResult): BundleDefinition[] {\n const allBundles = getAllBundles();\n const suggestions: BundleDefinition[] = [];\n\n for (const bundle of allBundles) {\n const resolved = resolveBundle(bundle);\n\n // Check overlap with selected modules\n let matchCount = 0;\n let totalInBundle = 0;\n\n for (const agentId of resolved.modules.agents) {\n totalInBundle++;\n if (selectedModules.agents.includes(agentId)) matchCount++;\n }\n for (const skillId of resolved.modules.skills) {\n totalInBundle++;\n if (selectedModules.skills.includes(skillId)) matchCount++;\n }\n for (const commandId of resolved.modules.commands) {\n totalInBundle++;\n if (selectedModules.commands.includes(commandId)) matchCount++;\n }\n for (const docId of resolved.modules.docs) {\n totalInBundle++;\n if (selectedModules.docs.includes(docId)) matchCount++;\n }\n\n // Suggest if at least 30% overlap but not 100%\n const overlapRatio = totalInBundle > 0 ? matchCount / totalInBundle : 0;\n if (overlapRatio >= 0.3 && overlapRatio < 1.0) {\n suggestions.push(bundle);\n }\n }\n\n return suggestions;\n}\n\n/**\n * Format bundle for display (short version for list names)\n */\nexport function formatBundleForDisplay(bundle: BundleDefinition): string {\n const resolved = resolveBundle(bundle);\n const parts: string[] = [];\n\n if (resolved.modules.agents.length > 0) {\n parts.push(`${resolved.modules.agents.length} agents`);\n }\n if (resolved.modules.skills.length > 0) {\n parts.push(`${resolved.modules.skills.length} skills`);\n }\n if (resolved.modules.commands.length > 0) {\n parts.push(`${resolved.modules.commands.length} commands`);\n }\n if (resolved.modules.docs.length > 0) {\n parts.push(`${resolved.modules.docs.length} docs`);\n }\n\n return `${bundle.name} (${parts.join(', ')})`;\n}\n\n/**\n * Format bundle description with full details for selection prompts\n * Shows detailed multiline info that appears when hovering over a choice\n */\nexport function formatBundleDetailedDescription(bundle: BundleDefinition): string {\n const resolved = resolveBundle(bundle);\n const lines: string[] = [];\n\n // Main description\n lines.push(bundle.description);\n lines.push('');\n\n // Responsibilities (if available)\n if (bundle.responsibilities && bundle.responsibilities.length > 0) {\n lines.push('📋 Responsibilities:');\n for (const resp of bundle.responsibilities.slice(0, 3)) {\n lines.push(` • ${resp}`);\n }\n if (bundle.responsibilities.length > 3) {\n lines.push(` • ...and ${bundle.responsibilities.length - 3} more`);\n }\n lines.push('');\n }\n\n // Use cases (if available and no responsibilities)\n if (bundle.useCases && bundle.useCases.length > 0 && !bundle.responsibilities?.length) {\n lines.push('🎯 Use cases:');\n for (const uc of bundle.useCases.slice(0, 2)) {\n lines.push(` • ${uc}`);\n }\n lines.push('');\n }\n\n // Modules breakdown\n lines.push('📦 Includes:');\n if (resolved.modules.agents.length > 0) {\n lines.push(\n ` 🤖 Agents (${resolved.modules.agents.length}): ${resolved.modules.agents.join(', ')}`\n );\n }\n if (resolved.modules.skills.length > 0) {\n lines.push(\n ` ⚡ Skills (${resolved.modules.skills.length}): ${resolved.modules.skills.join(', ')}`\n );\n }\n if (resolved.modules.commands.length > 0) {\n const cmds = resolved.modules.commands.map((c) => `/${c}`).join(', ');\n lines.push(` 💻 Commands (${resolved.modules.commands.length}): ${cmds}`);\n }\n if (resolved.modules.docs.length > 0) {\n const docsPreview = resolved.modules.docs.slice(0, 4);\n const more =\n resolved.modules.docs.length > 4 ? `, +${resolved.modules.docs.length - 4} more` : '';\n lines.push(` 📚 Docs (${resolved.modules.docs.length}): ${docsPreview.join(', ')}${more}`);\n }\n\n // Tech stack\n if (bundle.techStack && bundle.techStack.length > 0) {\n lines.push('');\n lines.push(`🔧 Tech: ${bundle.techStack.join(', ')}`);\n }\n\n // Complexity indicator\n if (bundle.complexity) {\n const complexityLabel =\n bundle.complexity === 'minimal'\n ? '⚡ Minimal - Quick setup'\n : bundle.complexity === 'comprehensive'\n ? '🔥 Comprehensive - Full featured'\n : '⭐ Standard';\n lines.push(`📊 ${complexityLabel}`);\n }\n\n return lines.join('\\n');\n}\n\n/**\n * Format bundle with rich multi-line description for display\n * Use this when you can show multiple lines\n */\nexport function formatBundleRichDescription(bundle: BundleDefinition): string[] {\n const resolved = resolveBundle(bundle);\n const lines: string[] = [];\n\n // Main description\n lines.push(bundle.description);\n\n // Responsibilities preview\n if (bundle.responsibilities && bundle.responsibilities.length > 0) {\n lines.push('');\n lines.push('Responsibilities:');\n for (const resp of bundle.responsibilities.slice(0, 3)) {\n lines.push(` • ${resp}`);\n }\n if (bundle.responsibilities.length > 3) {\n lines.push(` • ...and ${bundle.responsibilities.length - 3} more`);\n }\n }\n\n // Use cases preview\n if (bundle.useCases && bundle.useCases.length > 0) {\n lines.push('');\n lines.push('Use cases:');\n for (const uc of bundle.useCases.slice(0, 2)) {\n lines.push(` • ${uc}`);\n }\n }\n\n // Modules breakdown\n lines.push('');\n lines.push('Includes:');\n if (resolved.modules.agents.length > 0) {\n lines.push(` 🤖 Agents: ${resolved.modules.agents.join(', ')}`);\n }\n if (resolved.modules.skills.length > 0) {\n lines.push(` ⚡ Skills: ${resolved.modules.skills.join(', ')}`);\n }\n if (resolved.modules.commands.length > 0) {\n lines.push(` 💻 Commands: /${resolved.modules.commands.join(', /')}`);\n }\n if (resolved.modules.docs.length > 0) {\n const docsPreview = resolved.modules.docs.slice(0, 5);\n const more =\n resolved.modules.docs.length > 5 ? `, +${resolved.modules.docs.length - 5} more` : '';\n lines.push(` 📚 Docs: ${docsPreview.join(', ')}${more}`);\n }\n\n // Tech stack\n if (bundle.techStack && bundle.techStack.length > 0) {\n lines.push('');\n lines.push(`🔧 Tech: ${bundle.techStack.join(', ')}`);\n }\n\n return lines;\n}\n\n/**\n * Get bundle category display name\n */\nexport function getBundleCategoryName(category: string): string {\n return BUNDLE_CATEGORY_NAMES[category] ?? category;\n}\n\n/**\n * Export convenience access to constants\n */\nexport { getAllBundles, getBundleById, getBundlesGroupedByCategory, BUNDLE_CATEGORY_NAMES };\n","/**\n * Config exports\n */\n\n// Reader\nexport {\n readConfig,\n hasConfig,\n hasClaudeDir,\n getConfigPath,\n getClaudeDirPath,\n readPartialConfig,\n getInstalledModulesFromConfig,\n getConfigVersion,\n needsMigration,\n} from './reader.js';\n\n// Writer\nexport {\n writeConfig,\n updateConfig,\n mergeConfig,\n createDefaultConfig,\n addModulesToConfig,\n removeModulesFromConfig,\n updateMcpConfig,\n updateExtrasConfig,\n} from './writer.js';\n\n// Global Defaults\nexport {\n getGlobalDefaultsPath,\n readGlobalDefaults,\n writeGlobalDefaults,\n updateGlobalDefaults,\n mergeWithGlobalDefaults,\n hasGlobalDefaults,\n clearGlobalDefaults,\n getGlobalTemplateConfig,\n formatGlobalDefaults,\n} from './global-defaults.js';\n","/**\n * Configuration reader - reads Claude config files\n */\n\nimport type { ClaudeConfig, PartialClaudeConfig } from '../../types/config.js';\nimport { joinPath, pathExists, readJson } from '../utils/fs.js';\nimport { logger } from '../utils/logger.js';\n\nconst CONFIG_FILE = 'config.json';\nconst CLAUDE_DIR = '.claude';\n\n/**\n * Read Claude configuration from a project\n */\nexport async function readConfig(projectPath: string): Promise<ClaudeConfig | null> {\n const configPath = joinPath(projectPath, CLAUDE_DIR, CONFIG_FILE);\n\n if (!(await pathExists(configPath))) {\n return null;\n }\n\n try {\n return await readJson<ClaudeConfig>(configPath);\n } catch (error) {\n logger.debug(`Failed to read config: ${error}`);\n return null;\n }\n}\n\n/**\n * Check if a Claude configuration exists\n */\nexport async function hasConfig(projectPath: string): Promise<boolean> {\n const configPath = joinPath(projectPath, CLAUDE_DIR, CONFIG_FILE);\n return pathExists(configPath);\n}\n\n/**\n * Check if Claude directory exists\n */\nexport async function hasClaudeDir(projectPath: string): Promise<boolean> {\n const claudePath = joinPath(projectPath, CLAUDE_DIR);\n return pathExists(claudePath);\n}\n\n/**\n * Get config file path\n */\nexport function getConfigPath(projectPath: string): string {\n return joinPath(projectPath, CLAUDE_DIR, CONFIG_FILE);\n}\n\n/**\n * Get Claude directory path\n */\nexport function getClaudeDirPath(projectPath: string): string {\n return joinPath(projectPath, CLAUDE_DIR);\n}\n\n/**\n * Read partial config (for updates/merges)\n */\nexport async function readPartialConfig(projectPath: string): Promise<PartialClaudeConfig | null> {\n return readConfig(projectPath) as Promise<PartialClaudeConfig | null>;\n}\n\n/**\n * Get installed module IDs from config\n */\nexport function getInstalledModulesFromConfig(config: ClaudeConfig): Record<string, string[]> {\n return {\n agents: config.modules.agents.selected,\n skills: config.modules.skills.selected,\n commands: config.modules.commands.selected,\n docs: config.modules.docs.selected,\n };\n}\n\n/**\n * Get config version\n */\nexport function getConfigVersion(config: ClaudeConfig): string {\n return config.version;\n}\n\n/**\n * Check if config needs migration\n */\nexport function needsMigration(config: ClaudeConfig, currentVersion: string): boolean {\n const configVersion = config.version;\n\n // Simple semver comparison\n const [configMajor, configMinor] = configVersion.split('.').map(Number);\n const [currentMajor, currentMinor] = currentVersion.split('.').map(Number);\n\n return configMajor < currentMajor || (configMajor === currentMajor && configMinor < currentMinor);\n}\n","/**\n * Logger utility with colored output\n */\n\nimport chalk from 'chalk';\n\nexport type LogLevel = 'debug' | 'info' | 'success' | 'warn' | 'error';\n\ninterface LoggerOptions {\n verbose?: boolean;\n silent?: boolean;\n}\n\nconst SYMBOLS = {\n info: chalk.blue('ℹ'),\n success: chalk.green('✔'),\n warn: chalk.yellow('⚠'),\n error: chalk.red('✖'),\n debug: chalk.gray('●'),\n arrow: chalk.cyan('→'),\n bullet: chalk.dim('•'),\n};\n\nclass Logger {\n private verbose = false;\n private silent = false;\n\n configure(options: LoggerOptions): void {\n if (options.verbose !== undefined) this.verbose = options.verbose;\n if (options.silent !== undefined) this.silent = options.silent;\n }\n\n private log(level: LogLevel, message: string, ...args: unknown[]): void {\n if (this.silent && level !== 'error') return;\n if (level === 'debug' && !this.verbose) return;\n\n const prefix = SYMBOLS[level];\n const formattedMessage = args.length > 0 ? `${message} ${args.join(' ')}` : message;\n\n switch (level) {\n case 'error':\n console.error(`${prefix} ${chalk.red(formattedMessage)}`);\n break;\n case 'warn':\n console.warn(`${prefix} ${chalk.yellow(formattedMessage)}`);\n break;\n case 'success':\n console.log(`${prefix} ${chalk.green(formattedMessage)}`);\n break;\n case 'debug':\n console.log(`${prefix} ${chalk.gray(formattedMessage)}`);\n break;\n default:\n console.log(`${prefix} ${formattedMessage}`);\n }\n }\n\n debug(message: string, ...args: unknown[]): void {\n this.log('debug', message, ...args);\n }\n\n info(message: string, ...args: unknown[]): void {\n this.log('info', message, ...args);\n }\n\n success(message: string, ...args: unknown[]): void {\n this.log('success', message, ...args);\n }\n\n warn(message: string, ...args: unknown[]): void {\n this.log('warn', message, ...args);\n }\n\n error(message: string, ...args: unknown[]): void {\n this.log('error', message, ...args);\n }\n\n /**\n * Print a blank line\n */\n newline(): void {\n if (!this.silent) console.log();\n }\n\n /**\n * Print a title/header\n */\n title(text: string): void {\n if (this.silent) return;\n console.log();\n console.log(chalk.bold(chalk.cyan(text)));\n console.log(chalk.dim('─'.repeat(Math.min(text.length + 4, 60))));\n }\n\n /**\n * Print a subtitle\n */\n subtitle(text: string): void {\n if (this.silent) return;\n console.log();\n console.log(chalk.bold(text));\n }\n\n /**\n * Print a large section header for major transitions\n * Creates a visually prominent divider between configuration sections\n */\n section(text: string, icon?: string): void {\n if (this.silent) return;\n const displayIcon = icon || '◆';\n const width = 60;\n const border = '═'.repeat(width);\n const innerWidth = width - 4;\n const paddedText = text.length > innerWidth ? text.slice(0, innerWidth) : text;\n const leftPad = Math.floor((innerWidth - paddedText.length) / 2);\n const rightPad = innerWidth - paddedText.length - leftPad;\n\n console.log();\n console.log(chalk.cyan(`╔${border}╗`));\n console.log(chalk.cyan('║') + ' '.repeat(width) + chalk.cyan('║'));\n console.log(\n `${\n chalk.cyan('║') + ' '.repeat(leftPad + 1) + chalk.hex('#FED330')(displayIcon)\n } ${chalk.bold.white(paddedText)}${' '.repeat(rightPad + 1)}${chalk.cyan('║')}`\n );\n console.log(chalk.cyan('║') + ' '.repeat(width) + chalk.cyan('║'));\n console.log(chalk.cyan(`╚${border}╝`));\n console.log();\n }\n\n /**\n * Print a step in a process\n */\n step(stepNumber: number, totalSteps: number, message: string): void {\n if (this.silent) return;\n const progress = chalk.dim(`[${stepNumber}/${totalSteps}]`);\n console.log(`${progress} ${message}`);\n }\n\n /**\n * Print a list item\n */\n item(text: string, indent = 0): void {\n if (this.silent) return;\n const spaces = ' '.repeat(indent);\n console.log(`${spaces}${SYMBOLS.bullet} ${text}`);\n }\n\n /**\n * Print a key-value pair\n */\n keyValue(key: string, value: string, indent = 0): void {\n if (this.silent) return;\n const spaces = ' '.repeat(indent);\n console.log(`${spaces}${chalk.dim(`${key}:`)} ${value}`);\n }\n\n /**\n * Print an arrow item (for showing changes/actions)\n */\n arrow(text: string, indent = 0): void {\n if (this.silent) return;\n const spaces = ' '.repeat(indent);\n console.log(`${spaces}${SYMBOLS.arrow} ${text}`);\n }\n\n /**\n * Print a boxed message\n */\n box(title: string, content: string[]): void {\n if (this.silent) return;\n const maxLength = Math.max(title.length, ...content.map((line) => line.length));\n const width = Math.min(maxLength + 4, 70);\n const border = '─'.repeat(width - 2);\n\n console.log();\n console.log(chalk.cyan(`┌${border}┐`));\n console.log(chalk.cyan('│') + chalk.bold(` ${title.padEnd(width - 3)}`) + chalk.cyan('│'));\n console.log(chalk.cyan(`├${border}┤`));\n for (const line of content) {\n console.log(`${chalk.cyan('│')} ${line.padEnd(width - 3)}${chalk.cyan('│')}`);\n }\n console.log(chalk.cyan(`└${border}┘`));\n console.log();\n }\n\n /**\n * Print a table\n */\n table(headers: string[], rows: string[][]): void {\n if (this.silent) return;\n\n // Calculate column widths\n const colWidths = headers.map((h, i) => {\n const maxRowWidth = Math.max(...rows.map((r) => (r[i] || '').length));\n return Math.max(h.length, maxRowWidth);\n });\n\n // Print header\n const headerRow = headers.map((h, i) => chalk.bold(h.padEnd(colWidths[i]))).join(' ');\n console.log(headerRow);\n console.log(chalk.dim(colWidths.map((w) => '─'.repeat(w)).join(' ')));\n\n // Print rows\n for (const row of rows) {\n const rowStr = row.map((cell, i) => (cell || '').padEnd(colWidths[i])).join(' ');\n console.log(rowStr);\n }\n }\n\n /**\n * Print a colored status\n */\n status(label: string, status: 'success' | 'error' | 'warn' | 'pending' | 'skip'): void {\n if (this.silent) return;\n const statusColors = {\n success: chalk.green('✔ done'),\n error: chalk.red('✖ failed'),\n warn: chalk.yellow('⚠ warning'),\n pending: chalk.blue('◯ pending'),\n skip: chalk.dim('○ skipped'),\n };\n console.log(` ${label}: ${statusColors[status]}`);\n }\n\n /**\n * Print instructions\n */\n instructions(title: string, steps: string[]): void {\n if (this.silent) return;\n console.log();\n console.log(chalk.bold(chalk.cyan(title)));\n console.log();\n steps.forEach((step, index) => {\n console.log(` ${chalk.dim(`${index + 1}.`)} ${step}`);\n });\n console.log();\n }\n\n /**\n * Print a dimmed note\n */\n note(text: string): void {\n if (this.silent) return;\n console.log(chalk.dim(` ${text}`));\n }\n\n /**\n * Print raw text without formatting\n */\n raw(text: string): void {\n if (this.silent) return;\n console.log(text);\n }\n}\n\n// Export singleton instance\nexport const logger = new Logger();\n\n// Export color utilities for direct use\nexport const colors = {\n primary: chalk.cyan,\n secondary: chalk.blue,\n success: chalk.green,\n warning: chalk.yellow,\n error: chalk.red,\n muted: chalk.dim,\n bold: chalk.bold,\n underline: chalk.underline,\n};\n","/**\n * Configuration writer - writes Claude config files\n */\n\nimport type { ClaudeConfig, PartialClaudeConfig } from '../../types/config.js';\nimport { backup, ensureDir, joinPath, pathExists, writeJson } from '../utils/fs.js';\nimport { logger } from '../utils/logger.js';\nimport { readConfig } from './reader.js';\n\nconst CONFIG_FILE = 'config.json';\nconst CLAUDE_DIR = '.claude';\n\n/**\n * Write Claude configuration\n */\nexport async function writeConfig(\n projectPath: string,\n config: ClaudeConfig,\n options?: { backup?: boolean }\n): Promise<void> {\n const claudePath = joinPath(projectPath, CLAUDE_DIR);\n const configPath = joinPath(claudePath, CONFIG_FILE);\n\n // Create .claude directory if needed\n await ensureDir(claudePath);\n\n // Backup existing config if requested\n if (options?.backup && (await pathExists(configPath))) {\n const backupPath = await backup(configPath, `.backup.${Date.now()}`);\n logger.debug(`Config backed up to: ${backupPath}`);\n }\n\n // Write config\n await writeJson(configPath, config, { spaces: 2 });\n logger.debug(`Config written to: ${configPath}`);\n}\n\n/**\n * Update existing configuration (merge)\n */\nexport async function updateConfig(\n projectPath: string,\n updates: PartialClaudeConfig\n): Promise<ClaudeConfig | null> {\n const existing = await readConfig(projectPath);\n\n if (!existing) {\n logger.warn('No existing config to update');\n return null;\n }\n\n const updated = mergeConfig(existing, updates);\n updated.customizations.lastUpdated = new Date().toISOString();\n\n await writeConfig(projectPath, updated);\n return updated;\n}\n\n/**\n * Merge partial config into existing config\n */\nexport function mergeConfig(existing: ClaudeConfig, updates: PartialClaudeConfig): ClaudeConfig {\n return {\n version: updates.version || existing.version,\n templateSource: updates.templateSource || existing.templateSource,\n project: {\n ...existing.project,\n ...updates.project,\n },\n preferences: {\n ...existing.preferences,\n ...updates.preferences,\n },\n mcp: updates.mcp || existing.mcp,\n modules: {\n agents: updates.modules?.agents || existing.modules.agents,\n skills: updates.modules?.skills || existing.modules.skills,\n commands: updates.modules?.commands || existing.modules.commands,\n docs: updates.modules?.docs || existing.modules.docs,\n },\n extras: {\n ...existing.extras,\n ...updates.extras,\n hooks: updates.extras?.hooks || existing.extras.hooks,\n },\n scaffold: updates.scaffold || existing.scaffold,\n customizations: {\n ...existing.customizations,\n ...updates.customizations,\n lastUpdated: new Date().toISOString(),\n },\n };\n}\n\n/**\n * Create a default configuration\n */\nexport function createDefaultConfig(options: {\n version: string;\n projectInfo: ClaudeConfig['project'];\n preferences: ClaudeConfig['preferences'];\n}): ClaudeConfig {\n return {\n version: options.version,\n templateSource: {\n type: 'local',\n installedAt: new Date().toISOString(),\n },\n project: options.projectInfo,\n preferences: options.preferences,\n mcp: {\n level: 'project',\n servers: [],\n },\n modules: {\n agents: { selected: [], excluded: [] },\n skills: { selected: [], excluded: [] },\n commands: { selected: [], excluded: [] },\n docs: { selected: [], excluded: [] },\n },\n extras: {\n schemas: false,\n scripts: false,\n hooks: { enabled: false },\n sessions: false,\n },\n scaffold: {\n type: 'claude-only',\n createdStructure: [],\n },\n customizations: {\n placeholdersReplaced: false,\n lastUpdated: new Date().toISOString(),\n customFiles: [],\n },\n };\n}\n\n/**\n * Add selected modules to config\n */\nexport function addModulesToConfig(\n config: ClaudeConfig,\n category: keyof ClaudeConfig['modules'],\n moduleIds: string[]\n): ClaudeConfig {\n const existing = new Set(config.modules[category].selected);\n\n for (const id of moduleIds) {\n existing.add(id);\n }\n\n return {\n ...config,\n modules: {\n ...config.modules,\n [category]: {\n ...config.modules[category],\n selected: Array.from(existing),\n },\n },\n };\n}\n\n/**\n * Remove modules from config\n */\nexport function removeModulesFromConfig(\n config: ClaudeConfig,\n category: keyof ClaudeConfig['modules'],\n moduleIds: string[]\n): ClaudeConfig {\n const toRemove = new Set(moduleIds);\n const remaining = config.modules[category].selected.filter((id) => !toRemove.has(id));\n\n return {\n ...config,\n modules: {\n ...config.modules,\n [category]: {\n ...config.modules[category],\n selected: remaining,\n excluded: [...config.modules[category].excluded, ...moduleIds],\n },\n },\n };\n}\n\n/**\n * Update MCP configuration\n */\nexport function updateMcpConfig(config: ClaudeConfig, mcp: ClaudeConfig['mcp']): ClaudeConfig {\n return {\n ...config,\n mcp,\n };\n}\n\n/**\n * Update extras configuration\n */\nexport function updateExtrasConfig(\n config: ClaudeConfig,\n extras: Partial<ClaudeConfig['extras']>\n): ClaudeConfig {\n return {\n ...config,\n extras: {\n ...config.extras,\n ...extras,\n },\n };\n}\n","/**\n * Global defaults management\n *\n * Manages global defaults stored in ~/.claude/defaults.json\n * These defaults are used as fallbacks for new projects.\n */\n\nimport * as fs from 'node:fs/promises';\nimport { homedir } from 'node:os';\nimport * as path from 'node:path';\nimport type { GlobalDefaults, TemplateConfig } from '../../types/template-config.js';\n\n/**\n * Get the path to the global defaults file\n */\nexport function getGlobalDefaultsPath(): string {\n return path.join(homedir(), '.claude', 'defaults.json');\n}\n\n/**\n * Ensure the ~/.claude directory exists\n */\nasync function ensureClaudeDir(): Promise<void> {\n const claudeDir = path.join(homedir(), '.claude');\n try {\n await fs.mkdir(claudeDir, { recursive: true });\n } catch {\n // Directory exists or can't be created\n }\n}\n\n/**\n * Read global defaults from ~/.claude/defaults.json\n */\nexport async function readGlobalDefaults(): Promise<GlobalDefaults> {\n const defaultsPath = getGlobalDefaultsPath();\n\n try {\n const content = await fs.readFile(defaultsPath, 'utf-8');\n return JSON.parse(content) as GlobalDefaults;\n } catch {\n // File doesn't exist or is invalid\n return {};\n }\n}\n\n/**\n * Write global defaults to ~/.claude/defaults.json\n */\nexport async function writeGlobalDefaults(defaults: GlobalDefaults): Promise<void> {\n await ensureClaudeDir();\n const defaultsPath = getGlobalDefaultsPath();\n\n const dataToWrite: GlobalDefaults = {\n ...defaults,\n lastUpdated: new Date().toISOString(),\n };\n\n await fs.writeFile(defaultsPath, JSON.stringify(dataToWrite, null, 2), 'utf-8');\n}\n\n/**\n * Update global defaults with new template config\n */\nexport async function updateGlobalDefaults(templateConfig: Partial<TemplateConfig>): Promise<void> {\n const existing = await readGlobalDefaults();\n\n const updated: GlobalDefaults = {\n ...existing,\n templateConfig: mergeTemplateConfigs(existing.templateConfig || {}, templateConfig),\n lastUpdated: new Date().toISOString(),\n };\n\n await writeGlobalDefaults(updated);\n}\n\n/**\n * Merge two template configs, with source taking precedence\n */\nfunction mergeTemplateConfigs(\n target: Partial<TemplateConfig>,\n source: Partial<TemplateConfig>\n): Partial<TemplateConfig> {\n return {\n commands: { ...target.commands, ...source.commands },\n paths: { ...target.paths, ...source.paths },\n targets: { ...target.targets, ...source.targets },\n tracking: { ...target.tracking, ...source.tracking },\n techStack: { ...target.techStack, ...source.techStack },\n environment: { ...target.environment, ...source.environment },\n brand: { ...target.brand, ...source.brand },\n };\n}\n\n/**\n * Merge detected values with global defaults\n * Priority: detected > global > hardcoded defaults\n */\nexport function mergeWithGlobalDefaults(\n detected: Partial<TemplateConfig>,\n globalDefaults: Partial<TemplateConfig>\n): Partial<TemplateConfig> {\n return {\n commands: {\n ...globalDefaults.commands,\n ...filterUndefined(detected.commands || {}),\n },\n paths: {\n ...globalDefaults.paths,\n ...filterUndefined(detected.paths || {}),\n },\n targets: {\n ...globalDefaults.targets,\n ...filterUndefined(detected.targets || {}),\n },\n tracking: {\n ...globalDefaults.tracking,\n ...filterUndefined(detected.tracking || {}),\n },\n techStack: {\n ...globalDefaults.techStack,\n ...filterUndefined(detected.techStack || {}),\n },\n environment: {\n ...globalDefaults.environment,\n ...filterUndefined(detected.environment || {}),\n },\n brand: {\n ...globalDefaults.brand,\n ...filterUndefined(detected.brand || {}),\n },\n };\n}\n\n/**\n * Filter out undefined values from an object\n */\nfunction filterUndefined<T extends object>(obj: T): Partial<T> {\n const result: Partial<T> = {};\n for (const [key, value] of Object.entries(obj)) {\n if (value !== undefined) {\n (result as Record<string, unknown>)[key] = value;\n }\n }\n return result;\n}\n\n/**\n * Check if global defaults exist\n */\nexport async function hasGlobalDefaults(): Promise<boolean> {\n try {\n const defaults = await readGlobalDefaults();\n return defaults.templateConfig !== undefined && Object.keys(defaults.templateConfig).length > 0;\n } catch {\n return false;\n }\n}\n\n/**\n * Clear global defaults\n */\nexport async function clearGlobalDefaults(): Promise<void> {\n const defaultsPath = getGlobalDefaultsPath();\n try {\n await fs.unlink(defaultsPath);\n } catch {\n // File doesn't exist\n }\n}\n\n/**\n * Get template config from global defaults\n */\nexport async function getGlobalTemplateConfig(): Promise<Partial<TemplateConfig>> {\n const defaults = await readGlobalDefaults();\n return defaults.templateConfig || {};\n}\n\n/**\n * Format global defaults for display\n */\nexport function formatGlobalDefaults(defaults: GlobalDefaults): string {\n const lines: string[] = [];\n\n lines.push('Global Defaults');\n lines.push('─'.repeat(40));\n\n if (defaults.lastUpdated) {\n lines.push(`Last updated: ${new Date(defaults.lastUpdated).toLocaleString()}`);\n lines.push('');\n }\n\n if (!defaults.templateConfig || Object.keys(defaults.templateConfig).length === 0) {\n lines.push('No template configuration saved');\n return lines.join('\\n');\n }\n\n const config = defaults.templateConfig;\n\n if (config.commands && Object.keys(config.commands).length > 0) {\n lines.push('Commands:');\n for (const [key, value] of Object.entries(config.commands)) {\n if (value) lines.push(` ${key}: ${value}`);\n }\n lines.push('');\n }\n\n if (config.paths && Object.keys(config.paths).length > 0) {\n lines.push('Paths:');\n for (const [key, value] of Object.entries(config.paths)) {\n if (value) lines.push(` ${key}: ${value}`);\n }\n lines.push('');\n }\n\n if (config.targets && Object.keys(config.targets).length > 0) {\n lines.push('Targets:');\n for (const [key, value] of Object.entries(config.targets)) {\n if (value !== undefined) lines.push(` ${key}: ${value}`);\n }\n lines.push('');\n }\n\n if (config.tracking && Object.keys(config.tracking).length > 0) {\n lines.push('Tracking:');\n for (const [key, value] of Object.entries(config.tracking)) {\n if (value !== undefined) lines.push(` ${key}: ${value}`);\n }\n lines.push('');\n }\n\n if (config.techStack && Object.keys(config.techStack).length > 0) {\n lines.push('Tech Stack:');\n for (const [key, value] of Object.entries(config.techStack)) {\n if (value) lines.push(` ${key}: ${value}`);\n }\n lines.push('');\n }\n\n if (config.environment && Object.keys(config.environment).length > 0) {\n lines.push('Environment:');\n for (const [key, value] of Object.entries(config.environment)) {\n if (value) lines.push(` ${key}: ${value}`);\n }\n lines.push('');\n }\n\n if (config.brand && Object.keys(config.brand).length > 0) {\n lines.push('Brand:');\n for (const [key, value] of Object.entries(config.brand)) {\n if (value) lines.push(` ${key}: ${value}`);\n }\n lines.push('');\n }\n\n return lines.join('\\n');\n}\n","/**\n * Modules exports\n */\n\n// Registry\nexport {\n loadRegistry,\n getModule,\n getAllModules,\n getModulesByTag,\n filterModules,\n getModuleIds,\n validateModuleIds,\n} from './registry.js';\n\n// Resolver\nexport {\n resolveModules,\n resolveAllModules,\n getDependents,\n checkRemovalImpact,\n getSuggestedModules,\n sortByDependencies,\n type ResolvedModule,\n type ResolutionResult,\n} from './resolver.js';\n\n// Installer\nexport {\n installModules,\n installAllModules,\n uninstallModule,\n isModuleInstalled,\n getInstalledModules,\n installExtras,\n removeConfigRequiredFromFrontmatter,\n type InstallOptions,\n type InstallResult,\n} from './installer.js';\n","/**\n * Module registry - reads and manages module definitions from templates\n */\n\nimport type {\n ModuleCategory,\n ModuleDefinition,\n ModuleRegistry,\n RegistryFile,\n} from '../../types/modules.js';\nimport { joinPath, listDirs, pathExists, readJson } from '../utils/fs.js';\nimport { logger } from '../utils/logger.js';\n\nconst REGISTRY_FILE = '_registry.json';\n\n/**\n * Load module registry from a templates directory\n */\nexport async function loadRegistry(templatesPath: string): Promise<ModuleRegistry> {\n const registry: ModuleRegistry = {\n agents: [],\n skills: [],\n commands: [],\n docs: [],\n };\n\n const categories: ModuleCategory[] = ['agents', 'skills', 'commands', 'docs'];\n\n for (const category of categories) {\n const categoryPath = joinPath(templatesPath, category);\n\n if (!(await pathExists(categoryPath))) {\n logger.debug(`Category path not found: ${categoryPath}`);\n continue;\n }\n\n const modules = await loadCategoryModules(categoryPath, category);\n registry[category] = modules;\n }\n\n return registry;\n}\n\n/**\n * Load modules for a specific category\n */\nasync function loadCategoryModules(\n categoryPath: string,\n category: ModuleCategory\n): Promise<ModuleDefinition[]> {\n const registryPath = joinPath(categoryPath, REGISTRY_FILE);\n\n // Try to load from _registry.json first\n if (await pathExists(registryPath)) {\n try {\n const registryFile = await readJson<RegistryFile>(registryPath);\n return registryFile.modules.map((item) => ({\n id: item.id,\n name: item.name,\n description: item.description || '',\n category,\n file: item.file,\n dependencies: item.dependencies || [],\n tags: item.tags || [],\n }));\n } catch (error) {\n logger.debug(`Failed to load registry from ${registryPath}: ${error}`);\n }\n }\n\n // Fallback: scan directory for .md files\n return scanCategoryDirectory(categoryPath, category);\n}\n\n/**\n * Scan directory for module files when no registry exists\n */\nasync function scanCategoryDirectory(\n categoryPath: string,\n category: ModuleCategory\n): Promise<ModuleDefinition[]> {\n const modules: ModuleDefinition[] = [];\n\n // Get subdirectories (groups like 'engineering', 'quality', etc.)\n const subdirs = await listDirs('*', { cwd: categoryPath });\n\n for (const subdir of subdirs) {\n if (subdir.startsWith('_')) continue; // Skip special directories\n\n const subdirPath = joinPath(categoryPath, subdir);\n const files = await scanForModuleFiles(subdirPath);\n\n for (const file of files) {\n const id = file.replace('.md', '');\n modules.push({\n id,\n name: formatName(id),\n description: '',\n category,\n file: `${subdir}/${file}`,\n dependencies: [],\n tags: [subdir],\n });\n }\n }\n\n // Also scan root of category\n const rootFiles = await scanForModuleFiles(categoryPath);\n for (const file of rootFiles) {\n if (file === REGISTRY_FILE) continue;\n\n const id = file.replace('.md', '');\n modules.push({\n id,\n name: formatName(id),\n description: '',\n category,\n file,\n dependencies: [],\n tags: [],\n });\n }\n\n return modules;\n}\n\n/**\n * Scan a directory for module files (.md)\n */\nasync function scanForModuleFiles(dirPath: string): Promise<string[]> {\n const { glob } = await import('glob');\n const files = await glob('*.md', { cwd: dirPath });\n return files.filter((f) => !f.startsWith('_') && f !== 'README.md');\n}\n\n/**\n * Format ID to display name\n */\nfunction formatName(id: string): string {\n return id\n .split('-')\n .map((word) => word.charAt(0).toUpperCase() + word.slice(1))\n .join(' ');\n}\n\n/**\n * Get module by ID from registry\n */\nexport function getModule(\n registry: ModuleRegistry,\n category: ModuleCategory,\n id: string\n): ModuleDefinition | undefined {\n return registry[category].find((m) => m.id === id);\n}\n\n/**\n * Get all modules from registry\n */\nexport function getAllModules(registry: ModuleRegistry): ModuleDefinition[] {\n return [...registry.agents, ...registry.skills, ...registry.commands, ...registry.docs];\n}\n\n/**\n * Get modules by tag\n */\nexport function getModulesByTag(\n registry: ModuleRegistry,\n category: ModuleCategory,\n tag: string\n): ModuleDefinition[] {\n return registry[category].filter((m) => m.tags?.includes(tag));\n}\n\n/**\n * Filter modules by IDs or tags\n * Presets use tags (e.g., 'core', 'quality'), so we match both IDs and tags\n */\nexport function filterModules(\n registry: ModuleRegistry,\n category: ModuleCategory,\n idsOrTags: string[]\n): ModuleDefinition[] {\n const filterSet = new Set(idsOrTags);\n return registry[category].filter((m) => {\n // Match by ID\n if (filterSet.has(m.id)) return true;\n // Match by any tag\n if (m.tags?.some((tag) => filterSet.has(tag))) return true;\n return false;\n });\n}\n\n/**\n * Get module IDs for a category\n */\nexport function getModuleIds(registry: ModuleRegistry, category: ModuleCategory): string[] {\n return registry[category].map((m) => m.id);\n}\n\n/**\n * Validate that all requested modules exist\n */\nexport function validateModuleIds(\n registry: ModuleRegistry,\n category: ModuleCategory,\n ids: string[]\n): { valid: string[]; invalid: string[] } {\n const available = new Set(getModuleIds(registry, category));\n const valid: string[] = [];\n const invalid: string[] = [];\n\n for (const id of ids) {\n if (available.has(id)) {\n valid.push(id);\n } else {\n invalid.push(id);\n }\n }\n\n return { valid, invalid };\n}\n","/**\n * Module resolver - resolves module dependencies and order\n */\n\nimport type { ModuleCategory, ModuleDefinition, ModuleRegistry } from '../../types/modules.js';\nimport { getAllModules, getModule } from './registry.js';\n\nexport interface ResolvedModule extends ModuleDefinition {\n resolvedDependencies: string[];\n installOrder: number;\n}\n\nexport interface ResolutionResult {\n resolved: ResolvedModule[];\n unresolved: string[];\n circular: string[];\n}\n\n/**\n * Resolve dependencies for selected modules\n */\nexport function resolveModules(\n registry: ModuleRegistry,\n category: ModuleCategory,\n selectedIds: string[]\n): ResolutionResult {\n const resolved: Map<string, ResolvedModule> = new Map();\n const unresolved: string[] = [];\n const circular: string[] = [];\n const visiting = new Set<string>();\n let order = 0;\n\n function visit(id: string): boolean {\n if (resolved.has(id)) return true;\n\n if (visiting.has(id)) {\n circular.push(id);\n return false;\n }\n\n const module = getModule(registry, category, id);\n if (!module) {\n unresolved.push(id);\n return false;\n }\n\n visiting.add(id);\n\n // Resolve dependencies first\n const resolvedDeps: string[] = [];\n for (const depId of module.dependencies || []) {\n if (visit(depId)) {\n resolvedDeps.push(depId);\n }\n }\n\n visiting.delete(id);\n\n // Add this module\n resolved.set(id, {\n ...module,\n resolvedDependencies: resolvedDeps,\n installOrder: order++,\n });\n\n return true;\n }\n\n // Visit all selected modules\n for (const id of selectedIds) {\n visit(id);\n }\n\n return {\n resolved: Array.from(resolved.values()).sort((a, b) => a.installOrder - b.installOrder),\n unresolved,\n circular,\n };\n}\n\n/**\n * Resolve all dependencies for a set of modules across all categories\n */\nexport function resolveAllModules(\n registry: ModuleRegistry,\n selection: Record<ModuleCategory, string[]>\n): Record<ModuleCategory, ResolutionResult> {\n const categories: ModuleCategory[] = ['agents', 'skills', 'commands', 'docs'];\n const results: Record<ModuleCategory, ResolutionResult> = {} as Record<\n ModuleCategory,\n ResolutionResult\n >;\n\n for (const category of categories) {\n results[category] = resolveModules(registry, category, selection[category] || []);\n }\n\n return results;\n}\n\n/**\n * Get modules that depend on a given module\n */\nexport function getDependents(\n registry: ModuleRegistry,\n category: ModuleCategory,\n moduleId: string\n): ModuleDefinition[] {\n return registry[category].filter((m) => m.dependencies?.includes(moduleId));\n}\n\n/**\n * Check if removing a module would break dependencies\n */\nexport function checkRemovalImpact(\n registry: ModuleRegistry,\n category: ModuleCategory,\n moduleId: string,\n installedIds: string[]\n): { canRemove: boolean; blockedBy: string[] } {\n const dependents = getDependents(registry, category, moduleId);\n const blockedBy = dependents.filter((d) => installedIds.includes(d.id)).map((d) => d.id);\n\n return {\n canRemove: blockedBy.length === 0,\n blockedBy,\n };\n}\n\n/**\n * Get suggested modules based on installed ones\n */\nexport function getSuggestedModules(\n registry: ModuleRegistry,\n installedModules: Record<ModuleCategory, string[]>\n): ModuleDefinition[] {\n const suggestions: ModuleDefinition[] = [];\n const allInstalled = new Set<string>();\n\n // Collect all installed module IDs\n for (const ids of Object.values(installedModules)) {\n for (const id of ids) {\n allInstalled.add(id);\n }\n }\n\n // Find modules with tags that match installed modules\n const allModules = getAllModules(registry);\n const installedTags = new Set<string>();\n\n for (const module of allModules) {\n if (allInstalled.has(module.id)) {\n for (const tag of module.tags || []) {\n installedTags.add(tag);\n }\n }\n }\n\n // Suggest modules with matching tags that aren't installed\n for (const module of allModules) {\n if (allInstalled.has(module.id)) continue;\n\n const hasMatchingTag = (module.tags || []).some((tag) => installedTags.has(tag));\n if (hasMatchingTag) {\n suggestions.push(module);\n }\n }\n\n return suggestions;\n}\n\n/**\n * Sort modules by install order (dependencies first)\n */\nexport function sortByDependencies(modules: ModuleDefinition[]): ModuleDefinition[] {\n const sorted: ModuleDefinition[] = [];\n const visited = new Set<string>();\n const moduleMap = new Map(modules.map((m) => [m.id, m]));\n\n function visit(module: ModuleDefinition): void {\n if (visited.has(module.id)) return;\n visited.add(module.id);\n\n // Visit dependencies first\n for (const depId of module.dependencies || []) {\n const dep = moduleMap.get(depId);\n if (dep) {\n visit(dep);\n }\n }\n\n sorted.push(module);\n }\n\n for (const module of modules) {\n visit(module);\n }\n\n return sorted;\n}\n","/**\n * Module installer - copies and configures module files\n */\n\nimport type { ModuleCategory, ModuleDefinition } from '../../types/modules.js';\nimport {\n copy,\n dirname,\n ensureDir,\n joinPath,\n pathExists,\n readFile,\n writeFile,\n} from '../utils/fs.js';\nimport { logger } from '../utils/logger.js';\nimport { withSpinner } from '../utils/spinner.js';\n\n/**\n * Remove config_required section from YAML frontmatter in markdown files\n * This cleans up template files after installation\n */\nexport function removeConfigRequiredFromFrontmatter(content: string): string {\n // Match YAML frontmatter (starts with ---, ends with ---)\n const frontmatterRegex = /^---\\n([\\s\\S]*?)\\n---/;\n const match = content.match(frontmatterRegex);\n\n if (!match) {\n return content;\n }\n\n const frontmatter = match[1];\n\n // Remove config_required section from frontmatter\n // It can be multi-line with indented items like:\n // config_required:\n // - KEY: \"description\"\n // - KEY2: \"description2\"\n // The regex needs to match the key and all following indented lines\n const configRequiredRegex = /config_required:\\s*\\n(?:\\s+-\\s+[^\\n]+\\n?)*/g;\n const cleanedFrontmatter = frontmatter.replace(configRequiredRegex, '').trim();\n\n // Reconstruct the file\n const restOfFile = content.slice(match[0].length);\n\n // If frontmatter is now empty except for required fields, keep it minimal\n if (cleanedFrontmatter.trim() === '') {\n return restOfFile.trim();\n }\n\n return `---\\n${cleanedFrontmatter}\\n---${restOfFile}`;\n}\n\n/**\n * Process a module file after copying to clean up config_required\n */\nasync function processModuleFile(filePath: string): Promise<void> {\n // Only process markdown files\n if (!filePath.endsWith('.md')) {\n return;\n }\n\n try {\n const content = await readFile(filePath);\n const cleanedContent = removeConfigRequiredFromFrontmatter(content);\n\n // Only write if content changed\n if (cleanedContent !== content) {\n await writeFile(filePath, cleanedContent);\n logger.debug(`Cleaned config_required from: ${filePath}`);\n }\n } catch (error) {\n logger.debug(`Failed to process module file ${filePath}: ${error}`);\n }\n}\n\nexport interface InstallOptions {\n templatesPath: string;\n targetPath: string;\n overwrite?: boolean;\n dryRun?: boolean;\n}\n\nexport interface InstallResult {\n success: boolean;\n installed: string[];\n skipped: string[];\n failed: Array<{ id: string; error: string }>;\n}\n\n/**\n * Install modules for a category\n */\nexport async function installModules(\n category: ModuleCategory,\n modules: ModuleDefinition[],\n options: InstallOptions\n): Promise<InstallResult> {\n const result: InstallResult = {\n success: true,\n installed: [],\n skipped: [],\n failed: [],\n };\n\n const categorySourcePath = joinPath(options.templatesPath, category);\n const categoryTargetPath = joinPath(options.targetPath, '.claude', category);\n\n // Ensure target directory exists\n if (!options.dryRun) {\n await ensureDir(categoryTargetPath);\n }\n\n for (const module of modules) {\n try {\n const sourcePath = joinPath(categorySourcePath, module.file);\n const targetPath = joinPath(categoryTargetPath, module.file);\n\n // Check if source exists\n if (!(await pathExists(sourcePath))) {\n result.failed.push({ id: module.id, error: `Source file not found: ${sourcePath}` });\n result.success = false;\n continue;\n }\n\n // Check if target exists\n const targetExists = await pathExists(targetPath);\n if (targetExists && !options.overwrite) {\n result.skipped.push(module.id);\n continue;\n }\n\n if (options.dryRun) {\n logger.debug(`Would install: ${module.id} -> ${targetPath}`);\n result.installed.push(module.id);\n continue;\n }\n\n // Ensure target directory exists\n await ensureDir(dirname(targetPath));\n\n // Copy file\n await copy(sourcePath, targetPath, { overwrite: options.overwrite });\n\n // Process the file to clean up config_required\n await processModuleFile(targetPath);\n\n result.installed.push(module.id);\n\n logger.debug(`Installed: ${module.id}`);\n } catch (error) {\n const errorMessage = error instanceof Error ? error.message : 'Unknown error';\n result.failed.push({ id: module.id, error: errorMessage });\n result.success = false;\n }\n }\n\n return result;\n}\n\n/**\n * Install README file for a category\n */\nasync function installCategoryReadme(\n category: ModuleCategory,\n options: InstallOptions\n): Promise<void> {\n const sourceReadme = joinPath(options.templatesPath, category, 'README.md');\n const targetReadme = joinPath(options.targetPath, '.claude', category, 'README.md');\n\n // Check if source README exists\n if (!(await pathExists(sourceReadme))) {\n logger.debug(`No README found for category: ${category}`);\n return;\n }\n\n // Check if target exists\n const targetExists = await pathExists(targetReadme);\n if (targetExists && !options.overwrite) {\n logger.debug(`README already exists for ${category}, skipping`);\n return;\n }\n\n if (options.dryRun) {\n logger.debug(`Would install README for ${category}`);\n return;\n }\n\n try {\n await copy(sourceReadme, targetReadme, { overwrite: options.overwrite });\n logger.debug(`Installed README for ${category}`);\n } catch (error) {\n logger.debug(`Failed to install README for ${category}: ${error}`);\n }\n}\n\n/**\n * Install all modules with progress tracking\n */\nexport async function installAllModules(\n modulesByCategory: Record<ModuleCategory, ModuleDefinition[]>,\n options: InstallOptions\n): Promise<Record<ModuleCategory, InstallResult>> {\n const results: Record<ModuleCategory, InstallResult> = {} as Record<\n ModuleCategory,\n InstallResult\n >;\n const categories: ModuleCategory[] = ['agents', 'skills', 'commands', 'docs'];\n\n for (const category of categories) {\n const modules = modulesByCategory[category] || [];\n if (modules.length === 0) {\n results[category] = {\n success: true,\n installed: [],\n skipped: [],\n failed: [],\n };\n continue;\n }\n\n results[category] = await withSpinner(\n `Installing ${category} (${modules.length} modules)...`,\n () => installModules(category, modules, options),\n {\n successText: `Installed ${modules.length} ${category}`,\n silent: options.dryRun,\n }\n );\n\n // Install README for this category\n await installCategoryReadme(category, options);\n }\n\n return results;\n}\n\n/**\n * Uninstall a module\n */\nexport async function uninstallModule(\n category: ModuleCategory,\n moduleId: string,\n targetPath: string\n): Promise<{ success: boolean; error?: string }> {\n const { remove } = await import('../utils/fs.js');\n\n try {\n const modulePath = joinPath(targetPath, '.claude', category, `${moduleId}.md`);\n\n if (!(await pathExists(modulePath))) {\n return { success: false, error: 'Module file not found' };\n }\n\n await remove(modulePath);\n return { success: true };\n } catch (error) {\n return {\n success: false,\n error: error instanceof Error ? error.message : 'Unknown error',\n };\n }\n}\n\n/**\n * Check if a module is installed\n */\nexport async function isModuleInstalled(\n category: ModuleCategory,\n moduleId: string,\n targetPath: string\n): Promise<boolean> {\n // Try common file patterns\n const patterns = [\n joinPath(targetPath, '.claude', category, `${moduleId}.md`),\n joinPath(targetPath, '.claude', category, '**', `${moduleId}.md`),\n ];\n\n for (const pattern of patterns) {\n if (await pathExists(pattern)) {\n return true;\n }\n }\n\n return false;\n}\n\n/**\n * Get installed modules for a category\n */\nexport async function getInstalledModules(\n category: ModuleCategory,\n targetPath: string\n): Promise<string[]> {\n const { listFiles } = await import('../utils/fs.js');\n\n const categoryPath = joinPath(targetPath, '.claude', category);\n if (!(await pathExists(categoryPath))) {\n return [];\n }\n\n const files = await listFiles('**/*.md', { cwd: categoryPath });\n return files\n .filter((f) => !f.startsWith('_') && f !== 'README.md')\n .map((f) => {\n const parts = f.replace(/\\.md$/, '').split('/');\n return parts[parts.length - 1] ?? '';\n })\n .filter(Boolean);\n}\n\n/**\n * Copy extra files (schemas, scripts, hooks, sessions)\n */\nexport async function installExtras(\n extras: { schemas?: boolean; scripts?: boolean; hooks?: boolean; sessions?: boolean },\n options: InstallOptions\n): Promise<InstallResult> {\n const result: InstallResult = {\n success: true,\n installed: [],\n skipped: [],\n failed: [],\n };\n\n const extraDirs = [\n { name: 'schemas', enabled: extras.schemas },\n { name: 'scripts', enabled: extras.scripts },\n { name: 'hooks', enabled: extras.hooks },\n { name: 'sessions', enabled: extras.sessions },\n ];\n\n for (const { name, enabled } of extraDirs) {\n if (!enabled) continue;\n\n const sourcePath = joinPath(options.templatesPath, name);\n const targetPath = joinPath(options.targetPath, '.claude', name);\n\n if (!(await pathExists(sourcePath))) {\n logger.debug(`Extra directory not found: ${sourcePath}`);\n continue;\n }\n\n try {\n if (options.dryRun) {\n logger.debug(`Would copy: ${name} -> ${targetPath}`);\n result.installed.push(name);\n continue;\n }\n\n const targetExists = await pathExists(targetPath);\n if (targetExists && !options.overwrite) {\n result.skipped.push(name);\n continue;\n }\n\n await copy(sourcePath, targetPath, { overwrite: options.overwrite });\n result.installed.push(name);\n } catch (error) {\n const errorMessage = error instanceof Error ? error.message : 'Unknown error';\n result.failed.push({ id: name, error: errorMessage });\n result.success = false;\n }\n }\n\n return result;\n}\n","/**\n * Spinner utility for progress indication\n */\n\nimport ora, { type Ora } from 'ora';\nimport pc from 'picocolors';\n\ninterface SpinnerOptions {\n text?: string;\n color?: 'black' | 'red' | 'green' | 'yellow' | 'blue' | 'magenta' | 'cyan' | 'white' | 'gray';\n}\n\nclass SpinnerManager {\n private spinner: Ora | null = null;\n private silent = false;\n\n configure(options: { silent?: boolean }): void {\n if (options.silent !== undefined) this.silent = options.silent;\n }\n\n /**\n * Start a spinner with a message\n */\n start(text: string, options?: SpinnerOptions): Ora | null {\n if (this.silent) return null;\n\n // Stop any existing spinner\n this.stop();\n\n this.spinner = ora({\n text,\n color: options?.color || 'cyan',\n spinner: 'dots',\n }).start();\n\n return this.spinner;\n }\n\n /**\n * Update spinner text\n */\n text(text: string): void {\n if (this.spinner) {\n this.spinner.text = text;\n }\n }\n\n /**\n * Stop spinner with success message\n */\n succeed(text?: string): void {\n if (this.spinner) {\n this.spinner.succeed(text);\n this.spinner = null;\n }\n }\n\n /**\n * Stop spinner with failure message\n */\n fail(text?: string): void {\n if (this.spinner) {\n this.spinner.fail(text);\n this.spinner = null;\n }\n }\n\n /**\n * Stop spinner with warning message\n */\n warn(text?: string): void {\n if (this.spinner) {\n this.spinner.warn(text);\n this.spinner = null;\n }\n }\n\n /**\n * Stop spinner with info message\n */\n info(text?: string): void {\n if (this.spinner) {\n this.spinner.info(text);\n this.spinner = null;\n }\n }\n\n /**\n * Stop spinner without message\n */\n stop(): void {\n if (this.spinner) {\n this.spinner.stop();\n this.spinner = null;\n }\n }\n\n /**\n * Check if spinner is running\n */\n isRunning(): boolean {\n return this.spinner?.isSpinning ?? false;\n }\n}\n\n// Export singleton instance\nexport const spinner = new SpinnerManager();\n\n/**\n * Execute an async operation with a spinner\n */\nexport async function withSpinner<T>(\n text: string,\n operation: () => Promise<T>,\n options?: {\n successText?: string;\n failText?: string;\n silent?: boolean;\n }\n): Promise<T> {\n if (options?.silent) {\n return operation();\n }\n\n spinner.start(text);\n\n try {\n const result = await operation();\n spinner.succeed(options?.successText || text);\n return result;\n } catch (error) {\n const errorMessage = error instanceof Error ? error.message : 'Unknown error';\n spinner.fail(options?.failText || `${text} - ${pc.red(errorMessage)}`);\n throw error;\n }\n}\n\n/**\n * Create a progress indicator for multiple steps\n */\nexport function createProgressTracker(totalSteps: number, options?: { silent?: boolean }) {\n let currentStep = 0;\n\n return {\n next(stepText: string): void {\n currentStep++;\n if (!options?.silent) {\n spinner.start(`[${currentStep}/${totalSteps}] ${stepText}`);\n }\n },\n\n complete(text?: string): void {\n if (!options?.silent) {\n spinner.succeed(text || `[${currentStep}/${totalSteps}] Done`);\n }\n },\n\n fail(text?: string): void {\n if (!options?.silent) {\n spinner.fail(text);\n }\n },\n\n get current(): number {\n return currentStep;\n },\n\n get total(): number {\n return totalSteps;\n },\n };\n}\n","/**\n * Placeholders exports\n */\n\nexport {\n replaceInFile,\n replaceInDirectory,\n replacePlaceholders,\n showReplacementReport,\n} from './replacer.js';\n","/**\n * Placeholder replacer - finds and replaces placeholders in files\n */\n\nimport { PLACEHOLDERS, applyTransform } from '../../constants/placeholders.js';\nimport type { ProjectInfo } from '../../types/config.js';\nimport type {\n PlaceholderDefinition,\n PlaceholderReplacement,\n PlaceholderReport,\n} from '../../types/placeholders.js';\nimport { joinPath, listFiles, readFile, writeFile } from '../utils/fs.js';\nimport { logger } from '../utils/logger.js';\nimport { withSpinner } from '../utils/spinner.js';\n\n/**\n * Replace placeholders in a single file\n */\nexport async function replaceInFile(\n filePath: string,\n projectInfo: ProjectInfo,\n placeholders: PlaceholderDefinition[] = PLACEHOLDERS\n): Promise<PlaceholderReplacement[]> {\n const replacements: PlaceholderReplacement[] = [];\n let content = await readFile(filePath);\n let modified = false;\n\n for (const placeholder of placeholders) {\n const value = projectInfo[placeholder.configKey];\n\n if (value === undefined || value === null) {\n continue;\n }\n\n const transformedValue = applyTransform(String(value), placeholder.transform);\n const pattern = placeholder.pattern;\n\n if (pattern instanceof RegExp) {\n const matches = content.matchAll(new RegExp(pattern.source, 'g'));\n\n for (const match of matches) {\n const lineNumber = getLineNumber(content, match.index ?? 0);\n replacements.push({\n file: filePath,\n line: lineNumber,\n original: match[0],\n replacement: transformedValue,\n placeholder,\n });\n }\n\n if (pattern.test(content)) {\n content = content.replace(pattern, transformedValue);\n modified = true;\n }\n } else {\n // String pattern\n const regex = new RegExp(escapeRegex(pattern), 'g');\n const matches = content.matchAll(regex);\n\n for (const match of matches) {\n const lineNumber = getLineNumber(content, match.index ?? 0);\n replacements.push({\n file: filePath,\n line: lineNumber,\n original: match[0],\n replacement: transformedValue,\n placeholder,\n });\n }\n\n if (content.includes(pattern)) {\n content = content.replace(regex, transformedValue);\n modified = true;\n }\n }\n }\n\n if (modified) {\n await writeFile(filePath, content);\n }\n\n return replacements;\n}\n\n/**\n * Replace placeholders in all files in a directory\n */\nexport async function replaceInDirectory(\n dirPath: string,\n projectInfo: ProjectInfo,\n options?: {\n extensions?: string[];\n exclude?: string[];\n dryRun?: boolean;\n }\n): Promise<PlaceholderReport> {\n const extensions = options?.extensions || ['md', 'json', 'yaml', 'yml', 'ts', 'js', 'tsx', 'jsx'];\n const exclude = options?.exclude || ['node_modules', '.git', 'dist', 'build'];\n\n const pattern = `**/*.{${extensions.join(',')}}`;\n const files = await listFiles(pattern, {\n cwd: dirPath,\n ignore: exclude.map((e) => `**/${e}/**`),\n });\n\n const report: PlaceholderReport = {\n totalFiles: files.length,\n filesModified: 0,\n replacements: [],\n unreplacedPlaceholders: [],\n };\n\n for (const file of files) {\n const filePath = joinPath(dirPath, file);\n\n try {\n const replacements = options?.dryRun\n ? await scanFile(filePath, projectInfo)\n : await replaceInFile(filePath, projectInfo);\n\n if (replacements.length > 0) {\n report.filesModified++;\n report.replacements.push(...replacements);\n }\n } catch (error) {\n logger.debug(`Failed to process ${file}: ${error}`);\n }\n }\n\n // Find unreplaced placeholders\n report.unreplacedPlaceholders = findUnreplacedPlaceholders(projectInfo);\n\n return report;\n}\n\n/**\n * Scan file for placeholders without replacing\n */\nasync function scanFile(\n filePath: string,\n projectInfo: ProjectInfo\n): Promise<PlaceholderReplacement[]> {\n const replacements: PlaceholderReplacement[] = [];\n const content = await readFile(filePath);\n\n for (const placeholder of PLACEHOLDERS) {\n const value = projectInfo[placeholder.configKey];\n\n if (value === undefined || value === null) {\n continue;\n }\n\n const transformedValue = applyTransform(String(value), placeholder.transform);\n const pattern = placeholder.pattern;\n\n const regex =\n pattern instanceof RegExp\n ? new RegExp(pattern.source, 'g')\n : new RegExp(escapeRegex(pattern), 'g');\n\n const matches = content.matchAll(regex);\n\n for (const match of matches) {\n const lineNumber = getLineNumber(content, match.index ?? 0);\n replacements.push({\n file: filePath,\n line: lineNumber,\n original: match[0],\n replacement: transformedValue,\n placeholder,\n });\n }\n }\n\n return replacements;\n}\n\n/**\n * Replace placeholders with spinner\n */\nexport async function replacePlaceholders(\n dirPath: string,\n projectInfo: ProjectInfo,\n options?: {\n extensions?: string[];\n exclude?: string[];\n dryRun?: boolean;\n silent?: boolean;\n }\n): Promise<PlaceholderReport> {\n return withSpinner(\n 'Replacing placeholders...',\n () => replaceInDirectory(dirPath, projectInfo, options),\n {\n successText: 'Placeholders replaced',\n silent: options?.silent || options?.dryRun,\n }\n );\n}\n\n/**\n * Find placeholders that couldn't be replaced due to missing values\n */\nfunction findUnreplacedPlaceholders(projectInfo: ProjectInfo): string[] {\n const unreplaced: string[] = [];\n\n for (const placeholder of PLACEHOLDERS) {\n if (!placeholder.required) continue;\n\n const value = projectInfo[placeholder.configKey];\n if (value === undefined || value === null || value === '') {\n const patternStr =\n placeholder.pattern instanceof RegExp ? placeholder.pattern.source : placeholder.pattern;\n unreplaced.push(patternStr);\n }\n }\n\n return unreplaced;\n}\n\n/**\n * Get line number from string index\n */\nfunction getLineNumber(content: string, index: number): number {\n return content.slice(0, index).split('\\n').length;\n}\n\n/**\n * Escape regex special characters\n */\nfunction escapeRegex(str: string): string {\n return str.replace(/[.*+?^${}()|[\\]\\\\]/g, '\\\\$&');\n}\n\n/**\n * Show replacement report\n */\nexport function showReplacementReport(report: PlaceholderReport): void {\n logger.newline();\n logger.subtitle('Placeholder Replacement Report');\n logger.keyValue('Files scanned', String(report.totalFiles));\n logger.keyValue('Files modified', String(report.filesModified));\n logger.keyValue('Replacements', String(report.replacements.length));\n\n if (report.unreplacedPlaceholders.length > 0) {\n logger.newline();\n logger.warn('Unreplaced placeholders (missing values):');\n for (const p of report.unreplacedPlaceholders) {\n logger.item(p);\n }\n }\n}\n","/**\n * Project detector - detects existing project type and configuration\n */\n\nimport type {\n DetectionSignal,\n PackageManager,\n ProjectDetectionResult,\n ProjectType,\n} from '../../types/scaffold.js';\nimport { joinPath, pathExists, readJson } from '../utils/fs.js';\n\ninterface PackageJson {\n name?: string;\n description?: string;\n dependencies?: Record<string, string>;\n devDependencies?: Record<string, string>;\n scripts?: Record<string, string>;\n workspaces?: string[] | { packages: string[] };\n}\n\n/**\n * Detect project type and configuration\n */\nexport async function detectProject(projectPath: string): Promise<ProjectDetectionResult> {\n const signals: DetectionSignal[] = [];\n\n // Check for package.json\n const packageJsonPath = joinPath(projectPath, 'package.json');\n const hasPackageJson = await pathExists(packageJsonPath);\n\n if (!hasPackageJson) {\n return {\n detected: false,\n confidence: 'low',\n signals: [{ file: 'package.json', exists: false, indicates: 'not a Node.js project' }],\n };\n }\n\n signals.push({ file: 'package.json', exists: true, indicates: 'Node.js project' });\n\n // Read package.json\n const packageJson = await readJson<PackageJson>(packageJsonPath).catch(() => ({}) as PackageJson);\n\n // Detect package manager\n const packageManager = await detectPackageManager(projectPath);\n if (packageManager) {\n signals.push({\n file: `${packageManager}-lock`,\n exists: true,\n indicates: `${packageManager} package manager`,\n });\n }\n\n // Detect project type\n const typeResult = await detectProjectType(projectPath, packageJson);\n const projectType = typeResult.type;\n signals.push(...typeResult.signals);\n\n // Determine confidence\n const confidence: 'high' | 'medium' | 'low' =\n projectType && packageManager ? 'high' : projectType || packageManager ? 'medium' : 'low';\n\n // Suggest bundles based on project type\n const suggestedBundles = suggestBundles(projectType, packageJson);\n\n return {\n detected: true,\n projectType,\n packageManager,\n suggestedBundles,\n confidence,\n signals,\n };\n}\n\n/**\n * Detect package manager\n */\nasync function detectPackageManager(projectPath: string): Promise<PackageManager | undefined> {\n const lockFiles: Array<{ file: string; manager: PackageManager }> = [\n { file: 'pnpm-lock.yaml', manager: 'pnpm' },\n { file: 'yarn.lock', manager: 'yarn' },\n { file: 'package-lock.json', manager: 'npm' },\n { file: 'bun.lockb', manager: 'bun' },\n ];\n\n for (const { file, manager } of lockFiles) {\n if (await pathExists(joinPath(projectPath, file))) {\n return manager;\n }\n }\n\n return undefined;\n}\n\n/**\n * Detect project type from configuration files\n */\nasync function detectProjectType(\n projectPath: string,\n packageJson: PackageJson\n): Promise<{ type: ProjectType | undefined; signals: DetectionSignal[] }> {\n const signals: DetectionSignal[] = [];\n const deps = { ...packageJson.dependencies, ...packageJson.devDependencies };\n\n // Check for monorepo\n if (\n (await pathExists(joinPath(projectPath, 'turbo.json'))) ||\n (await pathExists(joinPath(projectPath, 'pnpm-workspace.yaml'))) ||\n packageJson.workspaces\n ) {\n signals.push({ file: 'turbo.json/pnpm-workspace.yaml', exists: true, indicates: 'monorepo' });\n return { type: 'monorepo', signals };\n }\n\n // Check for Astro\n if (\n (await pathExists(joinPath(projectPath, 'astro.config.mjs'))) ||\n (await pathExists(joinPath(projectPath, 'astro.config.ts'))) ||\n deps.astro\n ) {\n signals.push({ file: 'astro.config.*', exists: true, indicates: 'Astro project' });\n return { type: 'astro', signals };\n }\n\n // Check for Next.js\n if (\n (await pathExists(joinPath(projectPath, 'next.config.js'))) ||\n (await pathExists(joinPath(projectPath, 'next.config.mjs'))) ||\n (await pathExists(joinPath(projectPath, 'next.config.ts'))) ||\n deps.next\n ) {\n signals.push({ file: 'next.config.*', exists: true, indicates: 'Next.js project' });\n return { type: 'nextjs', signals };\n }\n\n // Check for Vite + React\n if (\n ((await pathExists(joinPath(projectPath, 'vite.config.ts'))) ||\n (await pathExists(joinPath(projectPath, 'vite.config.js')))) &&\n (deps.react || deps['react-dom'])\n ) {\n signals.push({ file: 'vite.config.*', exists: true, indicates: 'Vite project' });\n signals.push({ file: 'react dependency', exists: true, indicates: 'React project' });\n return { type: 'vite-react', signals };\n }\n\n // Check for Hono\n if (deps.hono) {\n signals.push({ file: 'hono dependency', exists: true, indicates: 'Hono API project' });\n return { type: 'hono', signals };\n }\n\n // Default to Node.js\n if (deps.typescript || (await pathExists(joinPath(projectPath, 'tsconfig.json')))) {\n signals.push({ file: 'tsconfig.json', exists: true, indicates: 'TypeScript project' });\n return { type: 'node', signals };\n }\n\n return { type: 'node', signals };\n}\n\n/**\n * Suggest bundles based on project type and dependencies\n */\nfunction suggestBundles(projectType: ProjectType | undefined, packageJson: PackageJson): string[] {\n const deps = { ...packageJson.dependencies, ...packageJson.devDependencies };\n const suggestedBundles: string[] = [];\n\n // Detect backend framework\n const hasHono = deps.hono || deps['@hono/node-server'];\n const hasExpress = deps.express;\n const hasFastify = deps.fastify;\n const hasNestjs = deps['@nestjs/core'];\n\n // Detect database ORM\n const hasDrizzle = deps.drizzle || deps['drizzle-orm'];\n const hasPrisma = deps.prisma || deps['@prisma/client'];\n const hasMongoose = deps.mongoose;\n\n // Detect frontend framework\n const hasReact = deps.react;\n const hasTanstack = deps['@tanstack/react-router'] || deps['@tanstack/start'];\n\n // Stack bundles based on detected technologies\n switch (projectType) {\n case 'astro':\n suggestedBundles.push('astro-react-stack');\n break;\n\n case 'nextjs':\n if (hasPrisma) {\n suggestedBundles.push('nextjs-prisma-stack');\n } else {\n // Just React + TanStack for Next.js without Prisma\n suggestedBundles.push('react-tanstack-stack');\n }\n break;\n\n case 'vite-react':\n suggestedBundles.push('react-tanstack-stack');\n break;\n\n case 'hono':\n if (hasDrizzle) {\n suggestedBundles.push('hono-drizzle-stack');\n } else if (hasPrisma) {\n suggestedBundles.push('hono-api');\n suggestedBundles.push('prisma-database');\n } else {\n suggestedBundles.push('hono-api');\n }\n break;\n\n case 'monorepo':\n // For monorepos, suggest based on detected technologies\n if (hasReact && hasTanstack) {\n suggestedBundles.push('react-tanstack-stack');\n }\n if (hasHono && hasDrizzle) {\n suggestedBundles.push('hono-drizzle-stack');\n } else if (hasHono) {\n suggestedBundles.push('hono-api');\n }\n break;\n\n case 'node':\n // Detect API framework\n if (hasHono) {\n if (hasDrizzle) {\n suggestedBundles.push('hono-drizzle-stack');\n } else {\n suggestedBundles.push('hono-api');\n }\n } else if (hasExpress) {\n if (hasPrisma) {\n suggestedBundles.push('express-prisma-stack');\n } else {\n suggestedBundles.push('express-api');\n }\n } else if (hasFastify) {\n suggestedBundles.push('fastify-api');\n } else if (hasNestjs) {\n suggestedBundles.push('nestjs-api');\n }\n break;\n }\n\n // Add database bundle if ORM detected but not in a stack\n if (hasDrizzle && !suggestedBundles.some((b) => b.includes('drizzle'))) {\n suggestedBundles.push('drizzle-database');\n }\n if (hasPrisma && !suggestedBundles.some((b) => b.includes('prisma'))) {\n suggestedBundles.push('prisma-database');\n }\n if (hasMongoose) {\n suggestedBundles.push('mongoose-database');\n }\n\n // Always suggest minimal testing and quality\n if (suggestedBundles.length > 0) {\n suggestedBundles.push('testing-minimal');\n suggestedBundles.push('quality-minimal');\n }\n\n // Add git workflow for all projects\n suggestedBundles.push('git-workflow');\n\n return suggestedBundles;\n}\n\n/**\n * Get project name from package.json or directory\n */\nexport async function getProjectName(projectPath: string): Promise<string | undefined> {\n try {\n const packageJson = await readJson<PackageJson>(joinPath(projectPath, 'package.json'));\n return packageJson.name;\n } catch {\n // Return directory name\n const parts = projectPath.split('/');\n return parts[parts.length - 1];\n }\n}\n\n/**\n * Get project description from package.json\n */\nexport async function getProjectDescription(projectPath: string): Promise<string | undefined> {\n try {\n const packageJson = await readJson<PackageJson>(joinPath(projectPath, 'package.json'));\n return packageJson.description;\n } catch {\n return undefined;\n }\n}\n\n/**\n * Check if project has existing Claude configuration\n */\nexport async function hasExistingClaudeConfig(projectPath: string): Promise<boolean> {\n return pathExists(joinPath(projectPath, '.claude'));\n}\n","/**\n * Template processing module\n *\n * Provides template directive parsing and processing for dynamic content generation.\n *\n * Supported directives:\n * - {{#if condition}}...{{/if}} - Conditional blocks\n * - {{#unless condition}}...{{/unless}} - Inverse conditionals\n * - {{#each items}}...{{/each}} - Loops over arrays\n * - {{#section name}}...{{/section}} - Named sections\n * - {{variable}} - Variable replacement\n * - {{variable | transform}} - Variable with transform\n *\n * Available transforms:\n * - lowercase, upper - Case transforms\n * - capitalize, title - Title case\n * - kebab, snake, camel, pascal - Naming conventions\n * - json - JSON stringify\n * - count - Array/string length\n * - first, last - First/last element\n * - join, joinlines - Join arrays\n * - bullet, numbered - List formatting\n */\n\n// Parser exports\nexport { parseDirectives, parseExpression, parseVariable, findVariables, hasDirectives, validateTemplate } from './parser.js';\n\n// Evaluator exports\nexport {\n getContextValue,\n evaluateCondition,\n isTruthy,\n getIterable,\n applyTemplateTransform,\n createLoopContext,\n} from './evaluator.js';\n\n// Processor exports\nexport {\n processTemplate,\n processTemplateFile,\n processTemplatesInDirectory,\n processTemplates,\n showTemplateReport,\n} from './processor.js';\n\n// Context exports\nexport {\n buildTemplateContext,\n extendContext,\n addCustomVariable,\n hasModule,\n hasAnyModule,\n hasAllModules,\n getAllModules,\n} from './context.js';\n\n// Scanner exports\nexport {\n extractPlaceholders,\n scanForPlaceholders,\n getUnconfiguredPlaceholders,\n getMissingRequiredPlaceholders,\n formatScanSummary,\n listAllConfigurablePlaceholders,\n} from './scanner.js';\n\n// Config replacer exports\nexport {\n flattenTemplateConfig,\n replaceTemplatePlaceholders,\n replaceTemplateConfigWithSpinner,\n formatReplacementReport,\n previewReplacements,\n} from './config-replacer.js';\n","/**\n * Template directive parser\n * Parses template directives like {{#if}}, {{#each}}, etc.\n */\n\nimport type { TemplateDirective, TemplateDirectiveType } from '../../types/templates.js';\n\n/**\n * Directive patterns\n *\n * Supported syntax:\n * - {{#if condition}}...{{/if}}\n * - {{#unless condition}}...{{/unless}}\n * - {{#each items}}...{{/each}}\n * - {{#section name}}...{{/section}}\n * - {{> partialName}}\n * - {{variable}}\n * - {{variable | transform}}\n */\n\nconst DIRECTIVE_PATTERNS = {\n // Block directives: {{#type expression}}...{{/type}}\n block: /\\{\\{#(if|unless|each|section)\\s+([^}]+)\\}\\}([\\s\\S]*?)\\{\\{\\/\\1\\}\\}/g,\n\n // Include directive: {{> partialName}}\n include: /\\{\\{>\\s*([^}]+)\\}\\}/g,\n\n // Variable with optional transform: {{variable}} or {{variable | transform}}\n variable: /\\{\\{([^#/>][^}|]*?)(?:\\s*\\|\\s*(\\w+))?\\}\\}/g,\n};\n\n/**\n * Parse template content for directives\n */\nexport function parseDirectives(content: string): TemplateDirective[] {\n const directives: TemplateDirective[] = [];\n\n // Parse block directives\n const blockMatches = content.matchAll(DIRECTIVE_PATTERNS.block);\n for (const match of blockMatches) {\n const [fullMatch, type, expression, innerContent] = match;\n const startIndex = match.index ?? 0;\n\n directives.push({\n type: type as TemplateDirectiveType,\n match: fullMatch,\n expression: expression.trim(),\n content: innerContent,\n startIndex,\n endIndex: startIndex + fullMatch.length,\n nested: parseDirectives(innerContent), // Recursive parse for nested directives\n });\n }\n\n // Parse include directives\n const includeMatches = content.matchAll(DIRECTIVE_PATTERNS.include);\n for (const match of includeMatches) {\n const [fullMatch, partialName] = match;\n const startIndex = match.index ?? 0;\n\n directives.push({\n type: 'include',\n match: fullMatch,\n expression: partialName.trim(),\n startIndex,\n endIndex: startIndex + fullMatch.length,\n });\n }\n\n return directives;\n}\n\n/**\n * Parse a single expression into its parts\n */\nexport function parseExpression(expression: string): {\n variable: string;\n path: string[];\n operator?: string;\n compareValue?: string;\n} {\n // Handle comparison operators: variable == value, variable != value\n const comparisonMatch = expression.match(/^(\\S+)\\s*(==|!=|>=|<=|>|<)\\s*(.+)$/);\n if (comparisonMatch) {\n const [, variable, operator, compareValue] = comparisonMatch;\n return {\n variable: variable.trim(),\n path: variable.trim().split('.'),\n operator,\n compareValue: compareValue.trim().replace(/^[\"']|[\"']$/g, ''),\n };\n }\n\n // Handle negation: !variable\n if (expression.startsWith('!')) {\n const variable = expression.slice(1).trim();\n return {\n variable,\n path: variable.split('.'),\n operator: '!',\n };\n }\n\n // Simple variable path\n const variable = expression.trim();\n return {\n variable,\n path: variable.split('.'),\n };\n}\n\n/**\n * Parse variable reference with optional transform\n */\nexport function parseVariable(match: string): {\n variable: string;\n transform?: string;\n} {\n // Remove {{ and }}\n const inner = match.slice(2, -2).trim();\n\n // Check for transform pipe\n const pipeIndex = inner.indexOf('|');\n if (pipeIndex !== -1) {\n return {\n variable: inner.slice(0, pipeIndex).trim(),\n transform: inner.slice(pipeIndex + 1).trim(),\n };\n }\n\n return { variable: inner };\n}\n\n/**\n * Find all variable references in content\n */\nexport function findVariables(content: string): Array<{\n match: string;\n variable: string;\n transform?: string;\n index: number;\n}> {\n const variables: Array<{\n match: string;\n variable: string;\n transform?: string;\n index: number;\n }> = [];\n\n const matches = content.matchAll(DIRECTIVE_PATTERNS.variable);\n for (const match of matches) {\n const [fullMatch, variable, transform] = match;\n\n // Skip if it looks like a block directive\n if (variable.startsWith('#') || variable.startsWith('/') || variable.startsWith('>')) {\n continue;\n }\n\n variables.push({\n match: fullMatch,\n variable: variable.trim(),\n transform: transform?.trim(),\n index: match.index ?? 0,\n });\n }\n\n return variables;\n}\n\n/**\n * Check if content has any template directives\n */\nexport function hasDirectives(content: string): boolean {\n return /\\{\\{[#/>]?\\s*\\w/.test(content);\n}\n\n/**\n * Validate template syntax\n */\nexport function validateTemplate(content: string): {\n valid: boolean;\n errors: string[];\n} {\n const errors: string[] = [];\n\n // Check for unmatched block directives\n const openBlocks: Array<{ type: string; index: number }> = [];\n\n // Find opening blocks\n const openMatches = content.matchAll(/\\{\\{#(if|unless|each|section)\\s+[^}]+\\}\\}/g);\n for (const match of openMatches) {\n openBlocks.push({\n type: match[1],\n index: match.index ?? 0,\n });\n }\n\n // Find closing blocks and match them\n const closeMatches = content.matchAll(/\\{\\{\\/(if|unless|each|section)\\}\\}/g);\n const closeBlocks: string[] = [];\n for (const match of closeMatches) {\n closeBlocks.push(match[1]);\n }\n\n // Check for mismatched blocks\n if (openBlocks.length !== closeBlocks.length) {\n errors.push(\n `Mismatched block directives: ${openBlocks.length} opening, ${closeBlocks.length} closing`\n );\n }\n\n // Check for unclosed variables\n const unclosedVars = content.match(/\\{\\{(?![^}]*\\}\\})/g);\n if (unclosedVars) {\n errors.push(`Found ${unclosedVars.length} unclosed variable reference(s)`);\n }\n\n return {\n valid: errors.length === 0,\n errors,\n };\n}\n","/**\n * Template expression evaluator\n * Evaluates conditions and expressions against a context\n */\n\nimport type { TemplateContext } from '../../types/templates.js';\nimport { parseExpression } from './parser.js';\n\n/**\n * Get a value from context using dot notation path\n */\nexport function getContextValue(\n context: TemplateContext,\n path: string\n): string | boolean | number | string[] | undefined {\n const parts = path.split('.');\n // biome-ignore lint/suspicious/noExplicitAny: dynamic access required\n let current: any = context;\n\n for (const part of parts) {\n if (current === undefined || current === null) {\n return undefined;\n }\n current = current[part];\n }\n\n return current;\n}\n\n/**\n * Evaluate a boolean expression\n */\nexport function evaluateCondition(expression: string, context: TemplateContext): boolean {\n const parsed = parseExpression(expression);\n\n // Handle AND/OR operators\n if (expression.includes('&&')) {\n const parts = expression.split('&&').map((p) => p.trim());\n return parts.every((part) => evaluateCondition(part, context));\n }\n\n if (expression.includes('||')) {\n const parts = expression.split('||').map((p) => p.trim());\n return parts.some((part) => evaluateCondition(part, context));\n }\n\n const value = getContextValue(context, parsed.variable);\n\n // Handle negation\n if (parsed.operator === '!') {\n return !isTruthy(value);\n }\n\n // Handle comparisons\n if (parsed.operator && parsed.compareValue !== undefined) {\n const compareValue = parsed.compareValue;\n\n switch (parsed.operator) {\n case '==':\n return String(value) === compareValue;\n case '!=':\n return String(value) !== compareValue;\n case '>':\n return Number(value) > Number(compareValue);\n case '>=':\n return Number(value) >= Number(compareValue);\n case '<':\n return Number(value) < Number(compareValue);\n case '<=':\n return Number(value) <= Number(compareValue);\n default:\n return false;\n }\n }\n\n // Handle array membership checks: modules.agents.includes(\"tech-lead\")\n if (expression.includes('.includes(')) {\n const match = expression.match(/^(.+?)\\.includes\\([\"'](.+?)[\"']\\)$/);\n if (match) {\n const [, arrayPath, searchValue] = match;\n const arrayValue = getContextValue(context, arrayPath);\n if (Array.isArray(arrayValue)) {\n return arrayValue.includes(searchValue);\n }\n }\n return false;\n }\n\n // Handle \"has\" helper: has modules.agents \"tech-lead\"\n if (expression.startsWith('has ')) {\n const match = expression.match(/^has\\s+(\\S+)\\s+[\"']?(.+?)[\"']?$/);\n if (match) {\n const [, arrayPath, searchValue] = match;\n const arrayValue = getContextValue(context, arrayPath);\n if (Array.isArray(arrayValue)) {\n return arrayValue.includes(searchValue);\n }\n }\n return false;\n }\n\n // Simple truthy check\n return isTruthy(value);\n}\n\n/**\n * Check if a value is truthy\n */\nexport function isTruthy(value: unknown): boolean {\n if (value === undefined || value === null) {\n return false;\n }\n\n if (typeof value === 'boolean') {\n return value;\n }\n\n if (typeof value === 'string') {\n return value.length > 0;\n }\n\n if (typeof value === 'number') {\n return value !== 0;\n }\n\n if (Array.isArray(value)) {\n return value.length > 0;\n }\n\n if (typeof value === 'object') {\n return Object.keys(value).length > 0;\n }\n\n return Boolean(value);\n}\n\n/**\n * Get iterable for each loops\n */\nexport function getIterable(\n expression: string,\n context: TemplateContext\n): Array<{ item: unknown; index: number; key?: string }> {\n const value = getContextValue(context, expression);\n\n if (Array.isArray(value)) {\n return value.map((item, index) => ({ item, index }));\n }\n\n if (typeof value === 'object' && value !== null) {\n return Object.entries(value).map(([key, item], index) => ({\n item,\n index,\n key,\n }));\n }\n\n return [];\n}\n\n/**\n * Apply a transform to a value\n */\nexport function applyTemplateTransform(\n value: string | boolean | number | string[] | undefined,\n transform: string\n): string {\n if (value === undefined || value === null) {\n return '';\n }\n\n const strValue = Array.isArray(value) ? value.join(', ') : String(value);\n\n switch (transform.toLowerCase()) {\n case 'lowercase':\n case 'lower':\n return strValue.toLowerCase();\n\n case 'uppercase':\n case 'upper':\n return strValue.toUpperCase();\n\n case 'capitalize':\n case 'title':\n return strValue\n .split(' ')\n .map((word) => word.charAt(0).toUpperCase() + word.slice(1).toLowerCase())\n .join(' ');\n\n case 'kebab':\n case 'kebabcase':\n return strValue.toLowerCase().replace(/\\s+/g, '-');\n\n case 'snake':\n case 'snakecase':\n return strValue.toLowerCase().replace(/\\s+/g, '_');\n\n case 'camel':\n case 'camelcase':\n return strValue\n .split(/[\\s-_]+/)\n .map((word, i) =>\n i === 0 ? word.toLowerCase() : word.charAt(0).toUpperCase() + word.slice(1).toLowerCase()\n )\n .join('');\n\n case 'pascal':\n case 'pascalcase':\n return strValue\n .split(/[\\s-_]+/)\n .map((word) => word.charAt(0).toUpperCase() + word.slice(1).toLowerCase())\n .join('');\n\n case 'json':\n return JSON.stringify(value);\n\n case 'count':\n return String(Array.isArray(value) ? value.length : strValue.length);\n\n case 'first':\n if (Array.isArray(value)) {\n return String(value[0] ?? '');\n }\n return strValue;\n\n case 'last':\n if (Array.isArray(value)) {\n return String(value[value.length - 1] ?? '');\n }\n return strValue;\n\n case 'join':\n if (Array.isArray(value)) {\n return value.join(', ');\n }\n return strValue;\n\n case 'joinlines':\n if (Array.isArray(value)) {\n return value.join('\\n');\n }\n return strValue;\n\n case 'bullet':\n case 'bullets':\n if (Array.isArray(value)) {\n return value.map((v) => `- ${v}`).join('\\n');\n }\n return `- ${strValue}`;\n\n case 'numbered':\n if (Array.isArray(value)) {\n return value.map((v, i) => `${i + 1}. ${v}`).join('\\n');\n }\n return `1. ${strValue}`;\n\n default:\n return strValue;\n }\n}\n\n/**\n * Create a scoped context for loop iterations\n */\nexport function createLoopContext(\n parentContext: TemplateContext,\n itemValue: unknown,\n index: number,\n key?: string\n): TemplateContext & { item: unknown; index: number; key?: string } {\n return {\n ...parentContext,\n item: itemValue,\n index,\n key,\n };\n}\n","/**\n * Template processor\n * Processes templates by evaluating directives and replacing variables\n */\n\nimport type {\n TemplateContext,\n TemplateDirective,\n TemplateResult,\n TemplateProcessingReport,\n} from '../../types/templates.js';\nimport { parseDirectives, findVariables, hasDirectives, validateTemplate } from './parser.js';\nimport {\n evaluateCondition,\n getIterable,\n getContextValue,\n applyTemplateTransform,\n createLoopContext,\n} from './evaluator.js';\nimport { joinPath, listFiles, readFile, writeFile } from '../utils/fs.js';\nimport { logger } from '../utils/logger.js';\nimport { withSpinner } from '../utils/spinner.js';\n\n/**\n * Process a single template string\n */\nexport function processTemplate(content: string, context: TemplateContext): TemplateResult {\n const result: TemplateResult = {\n content,\n modified: false,\n directivesProcessed: 0,\n warnings: [],\n errors: [],\n };\n\n // Validate first\n const validation = validateTemplate(content);\n if (!validation.valid) {\n result.errors.push(...validation.errors);\n return result;\n }\n\n // Check if there are any directives to process\n if (!hasDirectives(content)) {\n return result;\n }\n\n try {\n // Process block directives (if, unless, each, section)\n result.content = processBlockDirectives(result.content, context, result);\n\n // Process variable replacements\n result.content = processVariables(result.content, context, result);\n\n // Remove empty lines left by removed blocks (but preserve intentional blank lines)\n result.content = cleanupEmptyLines(result.content);\n\n result.modified = result.content !== content;\n } catch (error) {\n result.errors.push(`Template processing error: ${error}`);\n }\n\n return result;\n}\n\n/**\n * Process block directives\n */\nfunction processBlockDirectives(\n content: string,\n context: TemplateContext,\n result: TemplateResult\n): string {\n const directives = parseDirectives(content);\n\n // Process from last to first to maintain correct indexes\n const sortedDirectives = [...directives].sort((a, b) => b.startIndex - a.startIndex);\n\n for (const directive of sortedDirectives) {\n const replacement = processDirective(directive, context, result);\n content =\n content.slice(0, directive.startIndex) + replacement + content.slice(directive.endIndex);\n result.directivesProcessed++;\n }\n\n return content;\n}\n\n/**\n * Process a single directive\n */\nfunction processDirective(\n directive: TemplateDirective,\n context: TemplateContext,\n result: TemplateResult\n): string {\n switch (directive.type) {\n case 'if':\n return processIfDirective(directive, context, result);\n\n case 'unless':\n return processUnlessDirective(directive, context, result);\n\n case 'each':\n return processEachDirective(directive, context, result);\n\n case 'section':\n return processSectionDirective(directive, context, result);\n\n case 'include':\n result.warnings.push(`Include directive not yet supported: ${directive.expression}`);\n return directive.match;\n\n default:\n result.warnings.push(`Unknown directive type: ${directive.type}`);\n return directive.match;\n }\n}\n\n/**\n * Process if directive\n */\nfunction processIfDirective(\n directive: TemplateDirective,\n context: TemplateContext,\n result: TemplateResult\n): string {\n const condition = evaluateCondition(directive.expression, context);\n\n if (condition) {\n // Process nested content\n const innerContent = directive.content ?? '';\n const innerResult = processTemplate(innerContent, context);\n result.warnings.push(...innerResult.warnings);\n result.errors.push(...innerResult.errors);\n return innerResult.content;\n }\n\n return '';\n}\n\n/**\n * Process unless directive\n */\nfunction processUnlessDirective(\n directive: TemplateDirective,\n context: TemplateContext,\n result: TemplateResult\n): string {\n const condition = evaluateCondition(directive.expression, context);\n\n if (!condition) {\n const innerContent = directive.content ?? '';\n const innerResult = processTemplate(innerContent, context);\n result.warnings.push(...innerResult.warnings);\n result.errors.push(...innerResult.errors);\n return innerResult.content;\n }\n\n return '';\n}\n\n/**\n * Process each directive\n */\nfunction processEachDirective(\n directive: TemplateDirective,\n context: TemplateContext,\n result: TemplateResult\n): string {\n const items = getIterable(directive.expression, context);\n\n if (items.length === 0) {\n return '';\n }\n\n const outputs: string[] = [];\n\n for (const { item, index, key } of items) {\n const loopContext = createLoopContext(context, item, index, key);\n const innerContent = directive.content ?? '';\n const innerResult = processTemplate(innerContent, loopContext as unknown as TemplateContext);\n result.warnings.push(...innerResult.warnings);\n result.errors.push(...innerResult.errors);\n outputs.push(innerResult.content);\n }\n\n return outputs.join('');\n}\n\n/**\n * Process section directive (just returns content, used for marking sections)\n */\nfunction processSectionDirective(\n directive: TemplateDirective,\n context: TemplateContext,\n result: TemplateResult\n): string {\n const innerContent = directive.content ?? '';\n const innerResult = processTemplate(innerContent, context);\n result.warnings.push(...innerResult.warnings);\n result.errors.push(...innerResult.errors);\n return innerResult.content;\n}\n\n/**\n * Process variable replacements\n */\nfunction processVariables(\n content: string,\n context: TemplateContext,\n result: TemplateResult\n): string {\n const variables = findVariables(content);\n\n // Process from last to first to maintain correct indexes\n const sortedVariables = [...variables].sort((a, b) => b.index - a.index);\n\n for (const { match, variable, transform, index } of sortedVariables) {\n const value = getContextValue(context, variable);\n\n if (value !== undefined) {\n const replacement = transform ? applyTemplateTransform(value, transform) : String(value);\n\n content = content.slice(0, index) + replacement + content.slice(index + match.length);\n result.directivesProcessed++;\n } else {\n result.warnings.push(`Variable not found: ${variable}`);\n }\n }\n\n return content;\n}\n\n/**\n * Clean up empty lines left by removed blocks\n */\nfunction cleanupEmptyLines(content: string): string {\n // Remove lines that only contain whitespace after a removed block\n // But preserve intentional blank lines (max 2 consecutive)\n return content.replace(/\\n{3,}/g, '\\n\\n').trim();\n}\n\n/**\n * Process a template file\n */\nexport async function processTemplateFile(\n filePath: string,\n context: TemplateContext\n): Promise<TemplateResult> {\n const content = await readFile(filePath);\n const result = processTemplate(content, context);\n\n if (result.modified && result.errors.length === 0) {\n await writeFile(filePath, result.content);\n }\n\n return result;\n}\n\n/**\n * Process all template files in a directory\n */\nexport async function processTemplatesInDirectory(\n dirPath: string,\n context: TemplateContext,\n options?: {\n extensions?: string[];\n exclude?: string[];\n dryRun?: boolean;\n }\n): Promise<TemplateProcessingReport> {\n const extensions = options?.extensions ?? ['md', 'json', 'yaml', 'yml'];\n const exclude = options?.exclude ?? ['node_modules', '.git', 'dist', 'build'];\n\n const pattern = `**/*.{${extensions.join(',')}}`;\n const files = await listFiles(pattern, {\n cwd: dirPath,\n ignore: exclude.map((e) => `**/${e}/**`),\n });\n\n const report: TemplateProcessingReport = {\n totalFiles: files.length,\n filesModified: 0,\n totalDirectives: 0,\n filesWithErrors: [],\n warnings: [],\n };\n\n for (const file of files) {\n const filePath = joinPath(dirPath, file);\n\n try {\n const content = await readFile(filePath);\n\n // Skip files without directives\n if (!hasDirectives(content)) {\n continue;\n }\n\n const result = processTemplate(content, context);\n\n if (result.errors.length > 0) {\n report.filesWithErrors.push(file);\n report.warnings.push(`${file}: ${result.errors.join(', ')}`);\n continue;\n }\n\n if (result.modified) {\n if (!options?.dryRun) {\n await writeFile(filePath, result.content);\n }\n report.filesModified++;\n }\n\n report.totalDirectives += result.directivesProcessed;\n report.warnings.push(...result.warnings.map((w) => `${file}: ${w}`));\n } catch (error) {\n logger.debug(`Failed to process template ${file}: ${error}`);\n report.filesWithErrors.push(file);\n }\n }\n\n return report;\n}\n\n/**\n * Process templates with spinner\n */\nexport async function processTemplates(\n dirPath: string,\n context: TemplateContext,\n options?: {\n extensions?: string[];\n exclude?: string[];\n dryRun?: boolean;\n silent?: boolean;\n }\n): Promise<TemplateProcessingReport> {\n return withSpinner(\n 'Processing templates...',\n () => processTemplatesInDirectory(dirPath, context, options),\n {\n successText: 'Templates processed',\n silent: options?.silent ?? options?.dryRun,\n }\n );\n}\n\n/**\n * Show template processing report\n */\nexport function showTemplateReport(report: TemplateProcessingReport): void {\n logger.newline();\n logger.subtitle('Template Processing Report');\n logger.keyValue('Files scanned', String(report.totalFiles));\n logger.keyValue('Files modified', String(report.filesModified));\n logger.keyValue('Directives processed', String(report.totalDirectives));\n\n if (report.filesWithErrors.length > 0) {\n logger.newline();\n logger.warn('Files with errors:');\n for (const file of report.filesWithErrors) {\n logger.item(file);\n }\n }\n\n if (report.warnings.length > 0 && report.warnings.length <= 5) {\n logger.newline();\n logger.warn('Warnings:');\n for (const warning of report.warnings) {\n logger.item(warning);\n }\n } else if (report.warnings.length > 5) {\n logger.newline();\n logger.warn(`${report.warnings.length} warnings (showing first 5):`);\n for (const warning of report.warnings.slice(0, 5)) {\n logger.item(warning);\n }\n }\n}\n","/**\n * Template context builder\n * Creates a context object from config and module selections\n */\n\nimport type { ClaudeConfig } from '../../types/config.js';\nimport type { TemplateContext } from '../../types/templates.js';\n\n/**\n * Build a template context from config\n */\nexport function buildTemplateContext(config: Partial<ClaudeConfig>): TemplateContext {\n // Extract module IDs from ModuleSelection objects\n const getModuleIds = (selection?: { selected?: string[] }): string[] => {\n return selection?.selected ?? [];\n };\n\n // Extract MCP server IDs from installations\n const getMcpServerIds = (servers?: Array<{ serverId: string }>): string[] => {\n return servers?.map((s) => s.serverId) ?? [];\n };\n\n const context: TemplateContext = {\n project: {\n name: config.project?.name,\n description: config.project?.description,\n org: config.project?.org,\n repo: config.project?.repo,\n domain: config.project?.domain,\n entityType: config.project?.entityType,\n location: config.project?.location,\n },\n modules: {\n agents: getModuleIds(config.modules?.agents),\n skills: getModuleIds(config.modules?.skills),\n commands: getModuleIds(config.modules?.commands),\n docs: getModuleIds(config.modules?.docs),\n },\n codeStyle: {\n formatter: config.extras?.codeStyle?.biome\n ? 'biome'\n : config.extras?.codeStyle?.prettier\n ? 'prettier'\n : 'none',\n linter: config.extras?.codeStyle?.biome ? 'biome' : 'none',\n editorConfig: config.extras?.codeStyle?.editorconfig,\n commitlint: config.extras?.codeStyle?.commitlint,\n },\n techStack: {},\n bundles: [],\n mcpServers: getMcpServerIds(config.mcp?.servers),\n custom: {},\n };\n\n // Infer tech stack from selected modules\n context.techStack = inferTechStack(context.modules);\n\n return context;\n}\n\n/**\n * Infer tech stack from module selections\n */\nfunction inferTechStack(modules: TemplateContext['modules']): TemplateContext['techStack'] {\n const techStack: TemplateContext['techStack'] = {};\n\n const allModules = [\n ...modules.agents,\n ...modules.skills,\n ...modules.commands,\n ...modules.docs,\n ];\n\n // Framework detection\n if (allModules.some((m) => m.includes('nextjs'))) {\n techStack.framework = 'nextjs';\n } else if (allModules.some((m) => m.includes('astro'))) {\n techStack.framework = 'astro';\n } else if (allModules.some((m) => m.includes('tanstack-start'))) {\n techStack.framework = 'tanstack-start';\n } else if (allModules.some((m) => m.includes('react'))) {\n techStack.framework = 'react';\n }\n\n // Database/ORM detection\n if (allModules.some((m) => m.includes('prisma'))) {\n techStack.orm = 'prisma';\n } else if (allModules.some((m) => m.includes('drizzle'))) {\n techStack.orm = 'drizzle';\n } else if (allModules.some((m) => m.includes('mongoose'))) {\n techStack.orm = 'mongoose';\n }\n\n // API framework detection\n if (allModules.some((m) => m.includes('hono'))) {\n techStack.database = 'hono';\n } else if (allModules.some((m) => m.includes('express'))) {\n techStack.database = 'express';\n } else if (allModules.some((m) => m.includes('fastify'))) {\n techStack.database = 'fastify';\n } else if (allModules.some((m) => m.includes('nestjs'))) {\n techStack.database = 'nestjs';\n }\n\n // Testing detection\n if (allModules.some((m) => m.includes('testing') || m.includes('tdd'))) {\n techStack.testing = 'vitest';\n }\n\n // Deployment detection\n if (allModules.some((m) => m.includes('vercel'))) {\n techStack.deployment = 'vercel';\n }\n\n return techStack;\n}\n\n/**\n * Merge additional context values\n */\nexport function extendContext(\n context: TemplateContext,\n additions: Partial<TemplateContext>\n): TemplateContext {\n return {\n ...context,\n project: {\n ...context.project,\n ...additions.project,\n },\n modules: {\n ...context.modules,\n ...additions.modules,\n },\n codeStyle: {\n ...context.codeStyle,\n ...additions.codeStyle,\n },\n techStack: {\n ...context.techStack,\n ...additions.techStack,\n },\n bundles: [...context.bundles, ...(additions.bundles ?? [])],\n mcpServers: [...context.mcpServers, ...(additions.mcpServers ?? [])],\n custom: {\n ...context.custom,\n ...additions.custom,\n },\n };\n}\n\n/**\n * Add custom variables to context\n */\nexport function addCustomVariable(\n context: TemplateContext,\n key: string,\n value: string | boolean | number | string[]\n): TemplateContext {\n return {\n ...context,\n custom: {\n ...context.custom,\n [key]: value,\n },\n };\n}\n\n/**\n * Check if a module is in the context\n */\nexport function hasModule(context: TemplateContext, moduleId: string): boolean {\n return (\n context.modules.agents.includes(moduleId) ||\n context.modules.skills.includes(moduleId) ||\n context.modules.commands.includes(moduleId) ||\n context.modules.docs.includes(moduleId)\n );\n}\n\n/**\n * Check if any module in a list is in the context\n */\nexport function hasAnyModule(context: TemplateContext, moduleIds: string[]): boolean {\n return moduleIds.some((id) => hasModule(context, id));\n}\n\n/**\n * Check if all modules in a list are in the context\n */\nexport function hasAllModules(context: TemplateContext, moduleIds: string[]): boolean {\n return moduleIds.every((id) => hasModule(context, id));\n}\n\n/**\n * Get all selected modules as a flat list\n */\nexport function getAllModules(context: TemplateContext): string[] {\n return [\n ...context.modules.agents,\n ...context.modules.skills,\n ...context.modules.commands,\n ...context.modules.docs,\n ];\n}\n","/**\n * Template placeholder scanner\n *\n * Scans template files to discover {{PLACEHOLDER}} patterns\n * and returns information about which placeholders are used.\n */\n\nimport * as fs from 'node:fs/promises';\nimport * as path from 'node:path';\nimport type {\n PlaceholderScanResult,\n TemplateConfig,\n TemplatePlaceholderCategory,\n} from '../../types/template-config.js';\nimport {\n getAllPlaceholderPatterns,\n getPlaceholderByPattern,\n isConfigurablePlaceholder,\n TEMPLATE_PLACEHOLDERS,\n} from '../../constants/template-placeholders.js';\n\n/**\n * Regex to match {{PLACEHOLDER}} patterns\n */\nconst PLACEHOLDER_REGEX = /\\{\\{([A-Z][A-Z0-9_]*)\\}\\}/g;\n\n/**\n * File extensions to scan\n */\nconst SCANNABLE_EXTENSIONS = ['.md', '.json', '.yaml', '.yml', '.txt'];\n\n/**\n * Directories to skip during scanning\n */\nconst SKIP_DIRECTORIES = ['node_modules', '.git', 'dist', 'build', '.next', '.turbo'];\n\n/**\n * Check if a path should be scanned\n */\nfunction shouldScanPath(filePath: string): boolean {\n const ext = path.extname(filePath).toLowerCase();\n return SCANNABLE_EXTENSIONS.includes(ext);\n}\n\n/**\n * Check if a directory should be skipped\n */\nfunction shouldSkipDirectory(dirName: string): boolean {\n return SKIP_DIRECTORIES.includes(dirName) || dirName.startsWith('.');\n}\n\n/**\n * Extract all placeholder patterns from content\n */\nexport function extractPlaceholders(content: string): string[] {\n const matches = content.matchAll(PLACEHOLDER_REGEX);\n const placeholders = new Set<string>();\n\n for (const match of matches) {\n placeholders.add(`{{${match[1]}}}`);\n }\n\n return Array.from(placeholders);\n}\n\n/**\n * Recursively get all files in a directory\n */\nasync function getAllFiles(dir: string): Promise<string[]> {\n const files: string[] = [];\n\n try {\n const entries = await fs.readdir(dir, { withFileTypes: true });\n\n for (const entry of entries) {\n const fullPath = path.join(dir, entry.name);\n\n if (entry.isDirectory()) {\n if (!shouldSkipDirectory(entry.name)) {\n const subFiles = await getAllFiles(fullPath);\n files.push(...subFiles);\n }\n } else if (entry.isFile() && shouldScanPath(entry.name)) {\n files.push(fullPath);\n }\n }\n } catch {\n // Directory doesn't exist or can't be read\n }\n\n return files;\n}\n\n/**\n * Scan a directory for template placeholders\n */\nexport async function scanForPlaceholders(\n dir: string\n): Promise<PlaceholderScanResult> {\n const allPlaceholders = new Set<string>();\n const filesByPlaceholder: Record<string, string[]> = {};\n const counts: Record<string, number> = {};\n const byCategory: Record<TemplatePlaceholderCategory, string[]> = {\n commands: [],\n paths: [],\n targets: [],\n tracking: [],\n techStack: [],\n performance: [],\n brand: [],\n environment: [],\n };\n\n const files = await getAllFiles(dir);\n\n for (const file of files) {\n try {\n const content = await fs.readFile(file, 'utf-8');\n const placeholders = extractPlaceholders(content);\n\n for (const placeholder of placeholders) {\n // Only track configurable placeholders\n if (!isConfigurablePlaceholder(placeholder)) continue;\n\n allPlaceholders.add(placeholder);\n\n // Track files\n if (!filesByPlaceholder[placeholder]) {\n filesByPlaceholder[placeholder] = [];\n }\n filesByPlaceholder[placeholder].push(path.relative(dir, file));\n\n // Count occurrences\n const regex = new RegExp(\n placeholder.replace(/[{}]/g, '\\\\$&'),\n 'g'\n );\n const matchCount = (content.match(regex) || []).length;\n counts[placeholder] = (counts[placeholder] || 0) + matchCount;\n }\n } catch {\n // File can't be read, skip\n }\n }\n\n // Group by category\n for (const placeholder of allPlaceholders) {\n const def = getPlaceholderByPattern(placeholder);\n if (def) {\n byCategory[def.category].push(placeholder);\n }\n }\n\n return {\n placeholders: Array.from(allPlaceholders).sort(),\n byCategory,\n filesByPlaceholder,\n counts,\n };\n}\n\n/**\n * Get unconfigured placeholders (placeholders found but not in config)\n */\nexport async function getUnconfiguredPlaceholders(\n dir: string,\n config: Partial<TemplateConfig>\n): Promise<string[]> {\n const scanResult = await scanForPlaceholders(dir);\n const unconfigured: string[] = [];\n\n // Flatten config to get configured keys\n const configuredKeys = new Set<string>();\n\n if (config.commands) {\n for (const [key] of Object.entries(config.commands)) {\n configuredKeys.add(key.toUpperCase() + '_COMMAND');\n }\n }\n if (config.paths) {\n for (const [key] of Object.entries(config.paths)) {\n configuredKeys.add(key.toUpperCase());\n }\n }\n if (config.targets) {\n for (const [key] of Object.entries(config.targets)) {\n configuredKeys.add(key.toUpperCase());\n }\n }\n if (config.tracking) {\n for (const [key] of Object.entries(config.tracking)) {\n configuredKeys.add(key.toUpperCase());\n }\n }\n if (config.techStack) {\n for (const [key] of Object.entries(config.techStack)) {\n configuredKeys.add(key.toUpperCase());\n }\n }\n if (config.environment) {\n for (const [key] of Object.entries(config.environment)) {\n configuredKeys.add(key.toUpperCase());\n }\n }\n if (config.brand) {\n for (const [key] of Object.entries(config.brand)) {\n configuredKeys.add(key.toUpperCase());\n }\n }\n\n // Check each found placeholder\n for (const placeholder of scanResult.placeholders) {\n const def = getPlaceholderByPattern(placeholder);\n if (def && !configuredKeys.has(def.key)) {\n unconfigured.push(placeholder);\n }\n }\n\n return unconfigured;\n}\n\n/**\n * Get placeholders that are required but not configured\n */\nexport async function getMissingRequiredPlaceholders(\n dir: string,\n config: Partial<TemplateConfig>\n): Promise<string[]> {\n const scanResult = await scanForPlaceholders(dir);\n const missing: string[] = [];\n\n for (const placeholder of scanResult.placeholders) {\n const def = getPlaceholderByPattern(placeholder);\n if (def?.required) {\n // Check if configured\n const isConfigured = isPlaceholderConfigured(def.key, config);\n if (!isConfigured) {\n missing.push(placeholder);\n }\n }\n }\n\n return missing;\n}\n\n/**\n * Check if a specific placeholder key is configured\n */\nfunction isPlaceholderConfigured(\n key: string,\n config: Partial<TemplateConfig>\n): boolean {\n const def = TEMPLATE_PLACEHOLDERS.find((p) => p.key === key);\n if (!def) return false;\n\n switch (def.category) {\n case 'commands': {\n const cmdKey = keyToConfigKey(key, 'commands');\n return Boolean(\n config.commands?.[cmdKey as keyof typeof config.commands]\n );\n }\n case 'paths': {\n const pathKey = keyToConfigKey(key, 'paths');\n return Boolean(config.paths?.[pathKey as keyof typeof config.paths]);\n }\n case 'targets':\n case 'performance': {\n const targetKey = keyToConfigKey(key, 'targets');\n return config.targets?.[targetKey as keyof typeof config.targets] !== undefined;\n }\n case 'tracking': {\n const trackKey = keyToConfigKey(key, 'tracking');\n return Boolean(\n config.tracking?.[trackKey as keyof typeof config.tracking]\n );\n }\n case 'techStack': {\n const techKey = keyToConfigKey(key, 'techStack');\n return Boolean(\n config.techStack?.[techKey as keyof typeof config.techStack]\n );\n }\n case 'environment': {\n const envKey = keyToConfigKey(key, 'environment');\n return Boolean(\n config.environment?.[envKey as keyof typeof config.environment]\n );\n }\n case 'brand': {\n const brandKey = keyToConfigKey(key, 'brand');\n return Boolean(config.brand?.[brandKey as keyof typeof config.brand]);\n }\n default:\n return false;\n }\n}\n\n/**\n * Convert placeholder key to config object key\n * e.g., TYPECHECK_COMMAND -> typecheck\n * COVERAGE_TARGET -> coverageTarget\n */\nfunction keyToConfigKey(key: string, category: string): string {\n // Remove category suffix if present\n let cleanKey = key;\n\n if (category === 'commands' && key.endsWith('_COMMAND')) {\n cleanKey = key.slice(0, -8);\n } else if (category === 'environment' && key.endsWith('_ENV')) {\n cleanKey = key.slice(0, -4);\n }\n\n // Convert SNAKE_CASE to camelCase\n return cleanKey\n .toLowerCase()\n .replace(/_([a-z])/g, (_, char) => char.toUpperCase());\n}\n\n/**\n * Get scan summary as formatted string\n */\nexport function formatScanSummary(result: PlaceholderScanResult): string {\n const lines: string[] = [];\n\n lines.push(`Found ${result.placeholders.length} configurable placeholders:\\n`);\n\n const categories = Object.entries(result.byCategory).filter(\n ([, placeholders]) => placeholders.length > 0\n );\n\n for (const [category, placeholders] of categories) {\n lines.push(` ${category} (${placeholders.length}):`);\n for (const placeholder of placeholders) {\n const count = result.counts[placeholder] || 0;\n const files = result.filesByPlaceholder[placeholder]?.length || 0;\n lines.push(` ${placeholder} - ${count} uses in ${files} files`);\n }\n lines.push('');\n }\n\n return lines.join('\\n');\n}\n\n/**\n * List all known configurable placeholder patterns\n */\nexport function listAllConfigurablePlaceholders(): string[] {\n return getAllPlaceholderPatterns();\n}\n","/**\n * Template placeholder definitions for configurable values\n *\n * These placeholders use the {{PLACEHOLDER}} syntax and are configured\n * during installation or via the `configure` command.\n */\n\nimport type {\n TemplateConfigContext,\n TemplatePlaceholderDefinition,\n} from '../types/template-config.js';\n\n/**\n * Detect package manager command prefix\n */\nfunction getPackageManagerPrefix(context: TemplateConfigContext): string {\n switch (context.packageManager) {\n case 'yarn':\n return 'yarn';\n case 'bun':\n return 'bun run';\n case 'npm':\n return 'npm run';\n default:\n return 'pnpm';\n }\n}\n\n/**\n * Check if a script exists in package.json\n */\nfunction hasScript(context: TemplateConfigContext, name: string): boolean {\n return Boolean(context.scripts?.[name]);\n}\n\n/**\n * Get script command if it exists\n */\nfunction getScriptCommand(context: TemplateConfigContext, scriptName: string): string | undefined {\n if (!hasScript(context, scriptName)) return undefined;\n const prefix = getPackageManagerPrefix(context);\n return `${prefix} ${scriptName}`;\n}\n\n/**\n * Check if a dependency exists\n */\nfunction hasDependency(context: TemplateConfigContext, name: string): boolean {\n return Boolean(context.dependencies?.[name]);\n}\n\n/**\n * All configurable template placeholders\n */\nexport const TEMPLATE_PLACEHOLDERS: TemplatePlaceholderDefinition[] = [\n // ==========================================\n // COMMANDS CATEGORY\n // ==========================================\n {\n key: 'TYPECHECK_COMMAND',\n pattern: '{{TYPECHECK_COMMAND}}',\n category: 'commands',\n label: 'TypeScript Check Command',\n description: 'Command to run TypeScript type checking',\n inputType: 'text',\n default: (ctx) =>\n getScriptCommand(ctx, 'typecheck') ||\n getScriptCommand(ctx, 'type-check') ||\n getScriptCommand(ctx, 'tsc') ||\n `${getPackageManagerPrefix(ctx)} typecheck`,\n required: true,\n example: 'pnpm typecheck',\n },\n {\n key: 'LINT_COMMAND',\n pattern: '{{LINT_COMMAND}}',\n category: 'commands',\n label: 'Lint Command',\n description: 'Command to run linting (ESLint, Biome, etc.)',\n inputType: 'text',\n default: (ctx) => getScriptCommand(ctx, 'lint') || `${getPackageManagerPrefix(ctx)} lint`,\n required: true,\n example: 'pnpm lint',\n },\n {\n key: 'LINT_FIX_COMMAND',\n pattern: '{{LINT_FIX_COMMAND}}',\n category: 'commands',\n label: 'Lint Fix Command',\n description: 'Command to run linting with auto-fix',\n inputType: 'text',\n default: (ctx) =>\n getScriptCommand(ctx, 'lint:fix') || `${getPackageManagerPrefix(ctx)} lint --fix`,\n required: false,\n relatedTo: ['LINT_COMMAND'],\n example: 'pnpm lint --fix',\n },\n {\n key: 'TEST_COMMAND',\n pattern: '{{TEST_COMMAND}}',\n category: 'commands',\n label: 'Test Command',\n description: 'Command to run tests',\n inputType: 'text',\n default: (ctx) => getScriptCommand(ctx, 'test') || `${getPackageManagerPrefix(ctx)} test`,\n required: true,\n example: 'pnpm test',\n },\n {\n key: 'TEST_WATCH_COMMAND',\n pattern: '{{TEST_WATCH_COMMAND}}',\n category: 'commands',\n label: 'Test Watch Command',\n description: 'Command to run tests in watch mode',\n inputType: 'text',\n default: (ctx) =>\n getScriptCommand(ctx, 'test:watch') || `${getPackageManagerPrefix(ctx)} test --watch`,\n required: false,\n relatedTo: ['TEST_COMMAND'],\n example: 'pnpm test --watch',\n },\n {\n key: 'COVERAGE_COMMAND',\n pattern: '{{COVERAGE_COMMAND}}',\n category: 'commands',\n label: 'Coverage Command',\n description: 'Command to run tests with coverage',\n inputType: 'text',\n default: (ctx) =>\n getScriptCommand(ctx, 'test:coverage') ||\n getScriptCommand(ctx, 'coverage') ||\n `${getPackageManagerPrefix(ctx)} test --coverage`,\n required: true,\n relatedTo: ['TEST_COMMAND'],\n example: 'pnpm test:coverage',\n },\n {\n key: 'BUILD_COMMAND',\n pattern: '{{BUILD_COMMAND}}',\n category: 'commands',\n label: 'Build Command',\n description: 'Command to build the project',\n inputType: 'text',\n default: (ctx) => getScriptCommand(ctx, 'build') || `${getPackageManagerPrefix(ctx)} build`,\n required: false,\n example: 'pnpm build',\n },\n {\n key: 'FORMAT_COMMAND',\n pattern: '{{FORMAT_COMMAND}}',\n category: 'commands',\n label: 'Format Command',\n description: 'Command to format code (Prettier, Biome, etc.)',\n inputType: 'text',\n default: (ctx) => getScriptCommand(ctx, 'format') || `${getPackageManagerPrefix(ctx)} format`,\n required: false,\n example: 'pnpm format',\n },\n {\n key: 'SECURITY_SCAN_COMMAND',\n pattern: '{{SECURITY_SCAN_COMMAND}}',\n category: 'commands',\n label: 'Security Scan Command',\n description: 'Command to run security vulnerability scanning',\n inputType: 'text',\n default: (ctx) => getScriptCommand(ctx, 'audit') || `${getPackageManagerPrefix(ctx)} audit`,\n required: false,\n example: 'pnpm audit',\n },\n {\n key: 'LIGHTHOUSE_COMMAND',\n pattern: '{{LIGHTHOUSE_COMMAND}}',\n category: 'commands',\n label: 'Lighthouse Command',\n description: 'Command to run Lighthouse performance audit',\n inputType: 'text',\n default: 'npx lighthouse http://localhost:3000 --output=json',\n required: false,\n example: 'npx lighthouse http://localhost:3000 --output=json',\n },\n {\n key: 'BUNDLE_ANALYZE_COMMAND',\n pattern: '{{BUNDLE_ANALYZE_COMMAND}}',\n category: 'commands',\n label: 'Bundle Analyze Command',\n description: 'Command to analyze bundle size',\n inputType: 'text',\n default: (ctx) =>\n getScriptCommand(ctx, 'analyze') || `${getPackageManagerPrefix(ctx)} build --analyze`,\n required: false,\n example: 'pnpm build --analyze',\n },\n\n // ==========================================\n // PATHS CATEGORY\n // ==========================================\n {\n key: 'PLANNING_PATH',\n pattern: '{{PLANNING_PATH}}',\n category: 'paths',\n label: 'Planning Directory',\n description: 'Path for planning session documents',\n inputType: 'path',\n default: '.claude/sessions/planning',\n required: true,\n example: '.claude/sessions/planning',\n },\n {\n key: 'REFACTOR_PATH',\n pattern: '{{REFACTOR_PATH}}',\n category: 'paths',\n label: 'Refactor Directory',\n description: 'Path for refactoring session documents',\n inputType: 'path',\n default: '.claude/sessions/refactor',\n required: false,\n relatedTo: ['PLANNING_PATH'],\n example: '.claude/sessions/refactor',\n },\n {\n key: 'ARCHIVE_PATH',\n pattern: '{{ARCHIVE_PATH}}',\n category: 'paths',\n label: 'Archive Directory',\n description: 'Path for archived planning sessions',\n inputType: 'path',\n default: '.claude/sessions/archive',\n required: false,\n relatedTo: ['PLANNING_PATH'],\n example: '.claude/sessions/archive',\n },\n {\n key: 'SCHEMAS_PATH',\n pattern: '{{SCHEMAS_PATH}}',\n category: 'paths',\n label: 'Schemas Directory',\n description: 'Path for JSON schemas',\n inputType: 'path',\n default: '.claude/schemas',\n required: false,\n example: '.claude/schemas',\n },\n {\n key: 'PROJECT_ROOT',\n pattern: '{{PROJECT_ROOT}}',\n category: 'paths',\n label: 'Project Root',\n description: 'Root directory of the project',\n inputType: 'path',\n default: (ctx) => ctx.projectPath || '.',\n required: true,\n example: '.',\n },\n\n // ==========================================\n // TARGETS CATEGORY\n // ==========================================\n {\n key: 'COVERAGE_TARGET',\n pattern: '{{COVERAGE_TARGET}}',\n category: 'targets',\n label: 'Coverage Target (%)',\n description: 'Minimum test coverage percentage',\n inputType: 'number',\n default: '90',\n validate: (value) => {\n const num = Number.parseInt(value, 10);\n if (Number.isNaN(num) || num < 0 || num > 100) {\n return 'Coverage must be between 0 and 100';\n }\n return true;\n },\n required: true,\n example: '90',\n },\n {\n key: 'BUNDLE_SIZE_TARGET',\n pattern: '{{BUNDLE_SIZE_TARGET}}',\n category: 'targets',\n label: 'Bundle Size Target (KB)',\n description: 'Maximum bundle size in kilobytes',\n inputType: 'number',\n default: '500',\n validate: (value) => {\n const num = Number.parseInt(value, 10);\n if (Number.isNaN(num) || num < 0) {\n return 'Bundle size must be a positive number';\n }\n return true;\n },\n required: false,\n example: '500',\n },\n {\n key: 'LCP_TARGET',\n pattern: '{{LCP_TARGET}}',\n category: 'performance',\n label: 'LCP Target (ms)',\n description: 'Largest Contentful Paint target in milliseconds',\n inputType: 'number',\n default: '2500',\n required: false,\n example: '2500',\n },\n {\n key: 'FID_TARGET',\n pattern: '{{FID_TARGET}}',\n category: 'performance',\n label: 'FID Target (ms)',\n description: 'First Input Delay target in milliseconds',\n inputType: 'number',\n default: '100',\n required: false,\n example: '100',\n },\n {\n key: 'CLS_TARGET',\n pattern: '{{CLS_TARGET}}',\n category: 'performance',\n label: 'CLS Target',\n description: 'Cumulative Layout Shift target',\n inputType: 'number',\n default: '0.1',\n required: false,\n example: '0.1',\n },\n {\n key: 'API_RESPONSE_TARGET',\n pattern: '{{API_RESPONSE_TARGET}}',\n category: 'performance',\n label: 'API Response Target (ms)',\n description: 'Maximum API response time in milliseconds',\n inputType: 'number',\n default: '200',\n required: false,\n example: '200',\n },\n {\n key: 'DB_QUERY_TARGET',\n pattern: '{{DB_QUERY_TARGET}}',\n category: 'performance',\n label: 'DB Query Target (ms)',\n description: 'Maximum database query time in milliseconds',\n inputType: 'number',\n default: '50',\n required: false,\n example: '50',\n },\n {\n key: 'WCAG_LEVEL',\n pattern: '{{WCAG_LEVEL}}',\n category: 'targets',\n label: 'WCAG Compliance Level',\n description: 'Target WCAG accessibility compliance level',\n inputType: 'select',\n choices: [\n { name: 'Level A (Minimum)', value: 'A' },\n { name: 'Level AA (Recommended)', value: 'AA' },\n { name: 'Level AAA (Highest)', value: 'AAA' },\n ],\n default: 'AA',\n required: false,\n example: 'AA',\n },\n\n // ==========================================\n // TRACKING CATEGORY\n // ==========================================\n {\n key: 'ISSUE_TRACKER',\n pattern: '{{ISSUE_TRACKER}}',\n category: 'tracking',\n label: 'Issue Tracker',\n description: 'Issue tracking system to use',\n inputType: 'select',\n choices: [\n { name: 'GitHub Issues', value: 'github', description: 'Use GitHub Issues for tracking' },\n { name: 'Linear', value: 'linear', description: 'Use Linear for tracking' },\n { name: 'Jira', value: 'jira', description: 'Use Jira for tracking' },\n { name: 'None', value: 'none', description: 'No issue tracker integration' },\n ],\n default: (ctx) => (ctx.hasGitHubRemote ? 'github' : 'none'),\n required: true,\n example: 'github',\n },\n {\n key: 'TRACKING_FILE',\n pattern: '{{TRACKING_FILE}}',\n category: 'tracking',\n label: 'Tracking File',\n description: 'Path to the task tracking file',\n inputType: 'path',\n default: '.claude/tracking/tasks.json',\n required: false,\n example: '.claude/tracking/tasks.json',\n },\n {\n key: 'REGISTRY_FILE',\n pattern: '{{REGISTRY_FILE}}',\n category: 'tracking',\n label: 'Registry File',\n description: 'Path to the code registry file',\n inputType: 'path',\n default: '.claude/tracking/registry.json',\n required: false,\n example: '.claude/tracking/registry.json',\n },\n {\n key: 'TASK_CODE_PATTERN',\n pattern: '{{TASK_CODE_PATTERN}}',\n category: 'tracking',\n label: 'Task Code Pattern',\n description: 'Pattern for task codes (e.g., PROJ-XXX)',\n inputType: 'text',\n default: 'TASK-',\n required: false,\n example: 'TASK-',\n },\n {\n key: 'CLOSED_DAYS',\n pattern: '{{CLOSED_DAYS}}',\n category: 'tracking',\n label: 'Closed Days Threshold',\n description: 'Days after which closed issues can be cleaned up',\n inputType: 'number',\n default: '30',\n required: false,\n example: '30',\n },\n {\n key: 'STALE_DAYS',\n pattern: '{{STALE_DAYS}}',\n category: 'tracking',\n label: 'Stale Days Threshold',\n description: 'Days of inactivity before an issue is considered stale',\n inputType: 'number',\n default: '14',\n required: false,\n example: '14',\n },\n\n // ==========================================\n // TECH STACK CATEGORY\n // ==========================================\n {\n key: 'FRONTEND_FRAMEWORK',\n pattern: '{{FRONTEND_FRAMEWORK}}',\n category: 'techStack',\n label: 'Frontend Framework',\n description: 'Primary frontend framework',\n inputType: 'select',\n choices: [\n { name: 'React', value: 'React' },\n { name: 'Next.js', value: 'Next.js' },\n { name: 'TanStack Start', value: 'TanStack Start' },\n { name: 'Vue', value: 'Vue' },\n { name: 'Nuxt', value: 'Nuxt' },\n { name: 'Svelte', value: 'Svelte' },\n { name: 'SvelteKit', value: 'SvelteKit' },\n { name: 'Astro', value: 'Astro' },\n { name: 'SolidJS', value: 'SolidJS' },\n { name: 'Remix', value: 'Remix' },\n { name: 'Angular', value: 'Angular' },\n { name: 'None', value: 'None' },\n ],\n default: (ctx) => {\n if (hasDependency(ctx, '@tanstack/start')) return 'TanStack Start';\n if (hasDependency(ctx, 'next')) return 'Next.js';\n if (hasDependency(ctx, 'nuxt')) return 'Nuxt';\n if (hasDependency(ctx, 'vue')) return 'Vue';\n if (hasDependency(ctx, 'svelte')) return 'Svelte';\n if (hasDependency(ctx, '@sveltejs/kit')) return 'SvelteKit';\n if (hasDependency(ctx, 'astro')) return 'Astro';\n if (hasDependency(ctx, 'solid-js')) return 'SolidJS';\n if (hasDependency(ctx, '@remix-run/react')) return 'Remix';\n if (hasDependency(ctx, '@angular/core')) return 'Angular';\n if (hasDependency(ctx, 'react')) return 'React';\n return 'None';\n },\n required: false,\n example: 'React',\n },\n {\n key: 'DATABASE_ORM',\n pattern: '{{DATABASE_ORM}}',\n category: 'techStack',\n label: 'Database/ORM',\n description: 'Database ORM or query builder',\n inputType: 'select',\n choices: [\n { name: 'Drizzle', value: 'Drizzle' },\n { name: 'Prisma', value: 'Prisma' },\n { name: 'TypeORM', value: 'TypeORM' },\n { name: 'Sequelize', value: 'Sequelize' },\n { name: 'Knex', value: 'Knex' },\n { name: 'Kysely', value: 'Kysely' },\n { name: 'MongoDB/Mongoose', value: 'Mongoose' },\n { name: 'None', value: 'None' },\n ],\n default: (ctx) => {\n if (hasDependency(ctx, 'drizzle-orm')) return 'Drizzle';\n if (hasDependency(ctx, 'prisma') || hasDependency(ctx, '@prisma/client')) return 'Prisma';\n if (hasDependency(ctx, 'typeorm')) return 'TypeORM';\n if (hasDependency(ctx, 'sequelize')) return 'Sequelize';\n if (hasDependency(ctx, 'knex')) return 'Knex';\n if (hasDependency(ctx, 'kysely')) return 'Kysely';\n if (hasDependency(ctx, 'mongoose')) return 'Mongoose';\n return 'None';\n },\n required: false,\n example: 'Drizzle',\n },\n {\n key: 'VALIDATION_LIBRARY',\n pattern: '{{VALIDATION_LIBRARY}}',\n category: 'techStack',\n label: 'Validation Library',\n description: 'Schema validation library',\n inputType: 'select',\n choices: [\n { name: 'Zod', value: 'Zod' },\n { name: 'Yup', value: 'Yup' },\n { name: 'Joi', value: 'Joi' },\n { name: 'Valibot', value: 'Valibot' },\n { name: 'ArkType', value: 'ArkType' },\n { name: 'None', value: 'None' },\n ],\n default: (ctx) => {\n if (hasDependency(ctx, 'zod')) return 'Zod';\n if (hasDependency(ctx, 'yup')) return 'Yup';\n if (hasDependency(ctx, 'joi')) return 'Joi';\n if (hasDependency(ctx, 'valibot')) return 'Valibot';\n if (hasDependency(ctx, 'arktype')) return 'ArkType';\n return 'None';\n },\n required: false,\n example: 'Zod',\n },\n {\n key: 'AUTH_PATTERN',\n pattern: '{{AUTH_PATTERN}}',\n category: 'techStack',\n label: 'Authentication Pattern',\n description: 'Authentication approach',\n inputType: 'select',\n choices: [\n { name: 'Better Auth', value: 'Better Auth' },\n { name: 'Clerk', value: 'Clerk' },\n { name: 'Auth.js (NextAuth)', value: 'Auth.js' },\n { name: 'Lucia', value: 'Lucia' },\n { name: 'Firebase Auth', value: 'Firebase' },\n { name: 'Supabase Auth', value: 'Supabase' },\n { name: 'Kinde', value: 'Kinde' },\n { name: 'WorkOS', value: 'WorkOS' },\n { name: 'Custom JWT', value: 'JWT' },\n { name: 'Session-based', value: 'Session' },\n { name: 'None', value: 'None' },\n ],\n default: (ctx) => {\n if (hasDependency(ctx, 'better-auth')) return 'Better Auth';\n if (hasDependency(ctx, '@clerk/nextjs') || hasDependency(ctx, '@clerk/clerk-react'))\n return 'Clerk';\n if (hasDependency(ctx, 'next-auth') || hasDependency(ctx, '@auth/core')) return 'Auth.js';\n if (hasDependency(ctx, 'lucia')) return 'Lucia';\n if (hasDependency(ctx, 'firebase')) return 'Firebase';\n if (hasDependency(ctx, '@supabase/supabase-js')) return 'Supabase';\n if (hasDependency(ctx, '@kinde-oss/kinde-auth-nextjs')) return 'Kinde';\n if (hasDependency(ctx, '@workos-inc/authkit-nextjs')) return 'WorkOS';\n return 'None';\n },\n required: false,\n example: 'Better Auth',\n },\n {\n key: 'STATE_MANAGEMENT',\n pattern: '{{STATE_MANAGEMENT}}',\n category: 'techStack',\n label: 'State Management',\n description: 'Client-side state management',\n inputType: 'select',\n choices: [\n { name: 'TanStack Query', value: 'TanStack Query' },\n { name: 'Zustand', value: 'Zustand' },\n { name: 'Jotai', value: 'Jotai' },\n { name: 'Redux Toolkit', value: 'Redux' },\n { name: 'MobX', value: 'MobX' },\n { name: 'Recoil', value: 'Recoil' },\n { name: 'Pinia (Vue)', value: 'Pinia' },\n { name: 'None/Context', value: 'None' },\n ],\n default: (ctx) => {\n if (hasDependency(ctx, '@tanstack/react-query')) return 'TanStack Query';\n if (hasDependency(ctx, 'zustand')) return 'Zustand';\n if (hasDependency(ctx, 'jotai')) return 'Jotai';\n if (hasDependency(ctx, '@reduxjs/toolkit')) return 'Redux';\n if (hasDependency(ctx, 'mobx')) return 'MobX';\n if (hasDependency(ctx, 'recoil')) return 'Recoil';\n if (hasDependency(ctx, 'pinia')) return 'Pinia';\n return 'None';\n },\n required: false,\n example: 'TanStack Query',\n },\n {\n key: 'TEST_FRAMEWORK',\n pattern: '{{TEST_FRAMEWORK}}',\n category: 'techStack',\n label: 'Test Framework',\n description: 'Testing framework',\n inputType: 'select',\n choices: [\n { name: 'Vitest', value: 'Vitest' },\n { name: 'Jest', value: 'Jest' },\n { name: 'Mocha', value: 'Mocha' },\n { name: 'Ava', value: 'Ava' },\n { name: 'Node Test Runner', value: 'Node' },\n { name: 'None', value: 'None' },\n ],\n default: (ctx) => {\n if (hasDependency(ctx, 'vitest')) return 'Vitest';\n if (hasDependency(ctx, 'jest')) return 'Jest';\n if (hasDependency(ctx, 'mocha')) return 'Mocha';\n if (hasDependency(ctx, 'ava')) return 'Ava';\n return 'None';\n },\n required: false,\n example: 'Vitest',\n },\n {\n key: 'BUNDLER',\n pattern: '{{BUNDLER}}',\n category: 'techStack',\n label: 'Bundler',\n description: 'Build tool/bundler',\n inputType: 'select',\n choices: [\n { name: 'Vite', value: 'Vite' },\n { name: 'Webpack', value: 'Webpack' },\n { name: 'Rollup', value: 'Rollup' },\n { name: 'esbuild', value: 'esbuild' },\n { name: 'Parcel', value: 'Parcel' },\n { name: 'Turbopack', value: 'Turbopack' },\n { name: 'tsup', value: 'tsup' },\n { name: 'None', value: 'None' },\n ],\n default: (ctx) => {\n if (hasDependency(ctx, 'vite')) return 'Vite';\n if (hasDependency(ctx, 'webpack')) return 'Webpack';\n if (hasDependency(ctx, 'rollup')) return 'Rollup';\n if (hasDependency(ctx, 'esbuild')) return 'esbuild';\n if (hasDependency(ctx, 'parcel')) return 'Parcel';\n if (hasDependency(ctx, 'tsup')) return 'tsup';\n return 'None';\n },\n required: false,\n example: 'Vite',\n },\n {\n key: 'API_FRAMEWORK',\n pattern: '{{API_FRAMEWORK}}',\n category: 'techStack',\n label: 'API Framework',\n description: 'Backend API framework',\n inputType: 'select',\n choices: [\n { name: 'Hono', value: 'Hono' },\n { name: 'Express', value: 'Express' },\n { name: 'Fastify', value: 'Fastify' },\n { name: 'Koa', value: 'Koa' },\n { name: 'NestJS', value: 'NestJS' },\n { name: 'tRPC', value: 'tRPC' },\n { name: 'Next.js API Routes', value: 'Next.js API' },\n { name: 'None', value: 'None' },\n ],\n default: (ctx) => {\n if (hasDependency(ctx, 'hono')) return 'Hono';\n if (hasDependency(ctx, 'express')) return 'Express';\n if (hasDependency(ctx, 'fastify')) return 'Fastify';\n if (hasDependency(ctx, 'koa')) return 'Koa';\n if (hasDependency(ctx, '@nestjs/core')) return 'NestJS';\n if (hasDependency(ctx, '@trpc/server')) return 'tRPC';\n if (hasDependency(ctx, 'next')) return 'Next.js API';\n return 'None';\n },\n required: false,\n example: 'Hono',\n },\n\n // ==========================================\n // ENVIRONMENT CATEGORY\n // ==========================================\n {\n key: 'GITHUB_TOKEN_ENV',\n pattern: '{{GITHUB_TOKEN_ENV}}',\n category: 'environment',\n label: 'GitHub Token Env Var',\n description: 'Environment variable name for GitHub token',\n inputType: 'envVar',\n default: 'GITHUB_TOKEN',\n required: false,\n example: 'GITHUB_TOKEN',\n },\n {\n key: 'GITHUB_OWNER_ENV',\n pattern: '{{GITHUB_OWNER_ENV}}',\n category: 'environment',\n label: 'GitHub Owner Env Var',\n description: 'Environment variable name for GitHub owner/org',\n inputType: 'envVar',\n default: 'GITHUB_OWNER',\n required: false,\n example: 'GITHUB_OWNER',\n },\n {\n key: 'GITHUB_REPO_ENV',\n pattern: '{{GITHUB_REPO_ENV}}',\n category: 'environment',\n label: 'GitHub Repo Env Var',\n description: 'Environment variable name for GitHub repository',\n inputType: 'envVar',\n default: 'GITHUB_REPO',\n required: false,\n example: 'GITHUB_REPO',\n },\n {\n key: 'ISSUE_TRACKER_TOKEN_ENV',\n pattern: '{{ISSUE_TRACKER_TOKEN_ENV}}',\n category: 'environment',\n label: 'Issue Tracker Token Env Var',\n description: 'Environment variable for issue tracker API token',\n inputType: 'envVar',\n default: (ctx) => {\n // Set based on selected tracker\n const tracker = ctx.values.ISSUE_TRACKER;\n if (tracker === 'linear') return 'LINEAR_API_KEY';\n if (tracker === 'jira') return 'JIRA_API_TOKEN';\n return 'GITHUB_TOKEN';\n },\n dependsOn: ['ISSUE_TRACKER'],\n required: false,\n example: 'GITHUB_TOKEN',\n },\n\n // ==========================================\n // BRAND CATEGORY\n // ==========================================\n {\n key: 'BRAND_NAME',\n pattern: '{{BRAND_NAME}}',\n category: 'brand',\n label: 'Brand Name',\n description: 'Your brand or product name',\n inputType: 'text',\n default: '',\n required: false,\n example: 'MyProduct',\n },\n {\n key: 'PRIMARY_COLOR',\n pattern: '{{PRIMARY_COLOR}}',\n category: 'brand',\n label: 'Primary Color',\n description: 'Primary brand color (hex)',\n inputType: 'text',\n validate: (value) => {\n if (!value) return true;\n if (!/^#[0-9A-Fa-f]{6}$/.test(value)) {\n return 'Must be a valid hex color (e.g., #3B82F6)';\n }\n return true;\n },\n default: '#3B82F6',\n required: false,\n example: '#3B82F6',\n },\n {\n key: 'SECONDARY_COLOR',\n pattern: '{{SECONDARY_COLOR}}',\n category: 'brand',\n label: 'Secondary Color',\n description: 'Secondary brand color (hex)',\n inputType: 'text',\n validate: (value) => {\n if (!value) return true;\n if (!/^#[0-9A-Fa-f]{6}$/.test(value)) {\n return 'Must be a valid hex color (e.g., #10B981)';\n }\n return true;\n },\n default: '#10B981',\n required: false,\n example: '#10B981',\n },\n {\n key: 'FONT_FAMILY',\n pattern: '{{FONT_FAMILY}}',\n category: 'brand',\n label: 'Font Family',\n description: 'Primary font family',\n inputType: 'text',\n default: 'Inter, system-ui, sans-serif',\n required: false,\n example: 'Inter, system-ui, sans-serif',\n },\n {\n key: 'TONE_OF_VOICE',\n pattern: '{{TONE_OF_VOICE}}',\n category: 'brand',\n label: 'Tone of Voice',\n description: 'Brand communication tone',\n inputType: 'select',\n choices: [\n { name: 'Professional', value: 'professional' },\n { name: 'Friendly', value: 'friendly' },\n { name: 'Casual', value: 'casual' },\n { name: 'Technical', value: 'technical' },\n { name: 'Playful', value: 'playful' },\n ],\n default: 'professional',\n required: false,\n example: 'professional',\n },\n];\n\n/**\n * Get placeholder definition by key\n */\nexport function getPlaceholderByKey(key: string): TemplatePlaceholderDefinition | undefined {\n return TEMPLATE_PLACEHOLDERS.find((p) => p.key === key);\n}\n\n/**\n * Get placeholder definition by pattern\n */\nexport function getPlaceholderByPattern(\n pattern: string\n): TemplatePlaceholderDefinition | undefined {\n return TEMPLATE_PLACEHOLDERS.find((p) => p.pattern === pattern);\n}\n\n/**\n * Get all placeholders for a category\n */\nexport function getPlaceholdersByCategory(category: string): TemplatePlaceholderDefinition[] {\n return TEMPLATE_PLACEHOLDERS.filter((p) => p.category === category);\n}\n\n/**\n * Get all required placeholders\n */\nexport function getRequiredPlaceholders(): TemplatePlaceholderDefinition[] {\n return TEMPLATE_PLACEHOLDERS.filter((p) => p.required);\n}\n\n/**\n * Get all placeholder keys\n */\nexport function getAllPlaceholderKeys(): string[] {\n return TEMPLATE_PLACEHOLDERS.map((p) => p.key);\n}\n\n/**\n * Get all placeholder patterns\n */\nexport function getAllPlaceholderPatterns(): string[] {\n return TEMPLATE_PLACEHOLDERS.map((p) => p.pattern);\n}\n\n/**\n * Check if a pattern is a configurable placeholder\n */\nexport function isConfigurablePlaceholder(pattern: string): boolean {\n return TEMPLATE_PLACEHOLDERS.some((p) => p.pattern === pattern);\n}\n\n/**\n * Compute default value for a placeholder\n */\nexport function computeDefaultValue(\n placeholder: TemplatePlaceholderDefinition,\n context: TemplateConfigContext\n): string | undefined {\n if (typeof placeholder.default === 'function') {\n return placeholder.default(context);\n }\n return placeholder.default;\n}\n","/**\n * Template configuration replacer\n *\n * Replaces {{PLACEHOLDER}} patterns in template files\n * with configured values from TemplateConfig.\n */\n\nimport * as fs from 'node:fs/promises';\nimport * as path from 'node:path';\nimport ora from 'ora';\nimport type {\n TemplateConfig,\n TemplatePlaceholderReport,\n} from '../../types/template-config.js';\nimport { TEMPLATE_PLACEHOLDERS } from '../../constants/template-placeholders.js';\n\n/**\n * File extensions to process\n */\nconst PROCESSABLE_EXTENSIONS = ['.md', '.json', '.yaml', '.yml', '.txt'];\n\n/**\n * Directories to skip\n */\nconst SKIP_DIRECTORIES = ['node_modules', '.git', 'dist', 'build', '.next', '.turbo'];\n\n/**\n * Flatten TemplateConfig into a key-value map for replacement\n */\nexport function flattenTemplateConfig(\n config: Partial<TemplateConfig>\n): Record<string, string> {\n const flattened: Record<string, string> = {};\n\n // Commands\n if (config.commands) {\n if (config.commands.typecheck)\n flattened['{{TYPECHECK_COMMAND}}'] = config.commands.typecheck;\n if (config.commands.lint)\n flattened['{{LINT_COMMAND}}'] = config.commands.lint;\n if (config.commands.test)\n flattened['{{TEST_COMMAND}}'] = config.commands.test;\n if (config.commands.coverage)\n flattened['{{COVERAGE_COMMAND}}'] = config.commands.coverage;\n if (config.commands.build)\n flattened['{{BUILD_COMMAND}}'] = config.commands.build;\n if (config.commands.format)\n flattened['{{FORMAT_COMMAND}}'] = config.commands.format;\n if (config.commands.securityScan)\n flattened['{{SECURITY_SCAN_COMMAND}}'] = config.commands.securityScan;\n if (config.commands.lighthouse)\n flattened['{{LIGHTHOUSE_COMMAND}}'] = config.commands.lighthouse;\n if (config.commands.bundleAnalyze)\n flattened['{{BUNDLE_ANALYZE_COMMAND}}'] = config.commands.bundleAnalyze;\n }\n\n // Paths\n if (config.paths) {\n if (config.paths.planningPath)\n flattened['{{PLANNING_PATH}}'] = config.paths.planningPath;\n if (config.paths.refactorPath)\n flattened['{{REFACTOR_PATH}}'] = config.paths.refactorPath;\n if (config.paths.archivePath)\n flattened['{{ARCHIVE_PATH}}'] = config.paths.archivePath;\n if (config.paths.schemasPath)\n flattened['{{SCHEMAS_PATH}}'] = config.paths.schemasPath;\n if (config.paths.projectRoot)\n flattened['{{PROJECT_ROOT}}'] = config.paths.projectRoot;\n }\n\n // Targets\n if (config.targets) {\n if (config.targets.coverageTarget !== undefined)\n flattened['{{COVERAGE_TARGET}}'] = String(config.targets.coverageTarget);\n if (config.targets.bundleSizeTarget !== undefined)\n flattened['{{BUNDLE_SIZE_TARGET}}'] = String(config.targets.bundleSizeTarget);\n if (config.targets.lcpTarget !== undefined)\n flattened['{{LCP_TARGET}}'] = String(config.targets.lcpTarget);\n if (config.targets.fidTarget !== undefined)\n flattened['{{FID_TARGET}}'] = String(config.targets.fidTarget);\n if (config.targets.clsTarget !== undefined)\n flattened['{{CLS_TARGET}}'] = String(config.targets.clsTarget);\n if (config.targets.apiResponseTarget !== undefined)\n flattened['{{API_RESPONSE_TARGET}}'] = String(config.targets.apiResponseTarget);\n if (config.targets.dbQueryTarget !== undefined)\n flattened['{{DB_QUERY_TARGET}}'] = String(config.targets.dbQueryTarget);\n if (config.targets.wcagLevel)\n flattened['{{WCAG_LEVEL}}'] = config.targets.wcagLevel;\n }\n\n // Tracking\n if (config.tracking) {\n if (config.tracking.issueTracker)\n flattened['{{ISSUE_TRACKER}}'] = config.tracking.issueTracker;\n if (config.tracking.trackingFile)\n flattened['{{TRACKING_FILE}}'] = config.tracking.trackingFile;\n if (config.tracking.registryFile)\n flattened['{{REGISTRY_FILE}}'] = config.tracking.registryFile;\n if (config.tracking.taskCodePattern)\n flattened['{{TASK_CODE_PATTERN}}'] = config.tracking.taskCodePattern;\n if (config.tracking.closedDays !== undefined)\n flattened['{{CLOSED_DAYS}}'] = String(config.tracking.closedDays);\n if (config.tracking.staleDays !== undefined)\n flattened['{{STALE_DAYS}}'] = String(config.tracking.staleDays);\n }\n\n // Tech Stack\n if (config.techStack) {\n if (config.techStack.frontendFramework)\n flattened['{{FRONTEND_FRAMEWORK}}'] = config.techStack.frontendFramework;\n if (config.techStack.databaseOrm)\n flattened['{{DATABASE_ORM}}'] = config.techStack.databaseOrm;\n if (config.techStack.validationLibrary)\n flattened['{{VALIDATION_LIBRARY}}'] = config.techStack.validationLibrary;\n if (config.techStack.authPattern)\n flattened['{{AUTH_PATTERN}}'] = config.techStack.authPattern;\n if (config.techStack.stateManagement)\n flattened['{{STATE_MANAGEMENT}}'] = config.techStack.stateManagement;\n if (config.techStack.testFramework)\n flattened['{{TEST_FRAMEWORK}}'] = config.techStack.testFramework;\n if (config.techStack.bundler)\n flattened['{{BUNDLER}}'] = config.techStack.bundler;\n if (config.techStack.apiFramework)\n flattened['{{API_FRAMEWORK}}'] = config.techStack.apiFramework;\n }\n\n // Environment\n if (config.environment) {\n if (config.environment.githubTokenEnv)\n flattened['{{GITHUB_TOKEN_ENV}}'] = config.environment.githubTokenEnv;\n if (config.environment.githubOwnerEnv)\n flattened['{{GITHUB_OWNER_ENV}}'] = config.environment.githubOwnerEnv;\n if (config.environment.githubRepoEnv)\n flattened['{{GITHUB_REPO_ENV}}'] = config.environment.githubRepoEnv;\n if (config.environment.issueTrackerTokenEnv)\n flattened['{{ISSUE_TRACKER_TOKEN_ENV}}'] = config.environment.issueTrackerTokenEnv;\n }\n\n // Brand\n if (config.brand) {\n if (config.brand.brandName)\n flattened['{{BRAND_NAME}}'] = config.brand.brandName;\n if (config.brand.primaryColor)\n flattened['{{PRIMARY_COLOR}}'] = config.brand.primaryColor;\n if (config.brand.secondaryColor)\n flattened['{{SECONDARY_COLOR}}'] = config.brand.secondaryColor;\n if (config.brand.fontFamily)\n flattened['{{FONT_FAMILY}}'] = config.brand.fontFamily;\n if (config.brand.toneOfVoice)\n flattened['{{TONE_OF_VOICE}}'] = config.brand.toneOfVoice;\n }\n\n return flattened;\n}\n\n/**\n * Check if file should be processed\n */\nfunction shouldProcessFile(filePath: string): boolean {\n const ext = path.extname(filePath).toLowerCase();\n return PROCESSABLE_EXTENSIONS.includes(ext);\n}\n\n/**\n * Check if directory should be skipped\n */\nfunction shouldSkipDirectory(dirName: string): boolean {\n return SKIP_DIRECTORIES.includes(dirName) || dirName.startsWith('.');\n}\n\n/**\n * Get all files in directory recursively\n */\nasync function getAllFiles(dir: string): Promise<string[]> {\n const files: string[] = [];\n\n try {\n const entries = await fs.readdir(dir, { withFileTypes: true });\n\n for (const entry of entries) {\n const fullPath = path.join(dir, entry.name);\n\n if (entry.isDirectory()) {\n if (!shouldSkipDirectory(entry.name)) {\n const subFiles = await getAllFiles(fullPath);\n files.push(...subFiles);\n }\n } else if (entry.isFile() && shouldProcessFile(entry.name)) {\n files.push(fullPath);\n }\n }\n } catch {\n // Directory doesn't exist or can't be read\n }\n\n return files;\n}\n\n/**\n * Replace placeholders in a single file\n */\nasync function replaceInFile(\n filePath: string,\n replacements: Record<string, string>\n): Promise<Array<{ placeholder: string; value: string }>> {\n const changes: Array<{ placeholder: string; value: string }> = [];\n\n try {\n let content = await fs.readFile(filePath, 'utf-8');\n let modified = false;\n\n for (const [placeholder, value] of Object.entries(replacements)) {\n if (content.includes(placeholder)) {\n content = content.split(placeholder).join(value);\n changes.push({ placeholder, value });\n modified = true;\n }\n }\n\n if (modified) {\n await fs.writeFile(filePath, content, 'utf-8');\n }\n } catch {\n // File can't be read/written, skip\n }\n\n return changes;\n}\n\n/**\n * Replace template placeholders in directory\n */\nexport async function replaceTemplatePlaceholders(\n dir: string,\n config: Partial<TemplateConfig>\n): Promise<TemplatePlaceholderReport> {\n const replacements = flattenTemplateConfig(config);\n const files = await getAllFiles(dir);\n const report: TemplatePlaceholderReport = {\n totalFiles: files.length,\n filesModified: 0,\n replacements: [],\n unreplaced: [],\n };\n\n for (const file of files) {\n const changes = await replaceInFile(file, replacements);\n if (changes.length > 0) {\n report.filesModified++;\n for (const change of changes) {\n report.replacements.push({\n file: path.relative(dir, file),\n placeholder: change.placeholder,\n value: change.value,\n });\n }\n }\n }\n\n // Find unreplaced placeholders\n const allPatterns = TEMPLATE_PLACEHOLDERS.map((p) => p.pattern);\n const replacedPatterns = new Set(Object.keys(replacements));\n report.unreplaced = allPatterns.filter((p) => !replacedPatterns.has(p));\n\n return report;\n}\n\n/**\n * Replace template placeholders with spinner UI\n */\nexport async function replaceTemplateConfigWithSpinner(\n dir: string,\n config: Partial<TemplateConfig>\n): Promise<TemplatePlaceholderReport> {\n const spinner = ora('Applying template configuration...').start();\n\n try {\n const report = await replaceTemplatePlaceholders(dir, config);\n\n if (report.filesModified > 0) {\n spinner.succeed(\n `Applied ${report.replacements.length} replacements in ${report.filesModified} files`\n );\n } else {\n spinner.info('No template placeholders found to replace');\n }\n\n return report;\n } catch (error) {\n spinner.fail('Failed to apply template configuration');\n throw error;\n }\n}\n\n/**\n * Get a summary of the replacement report\n */\nexport function formatReplacementReport(\n report: TemplatePlaceholderReport\n): string {\n const lines: string[] = [];\n\n lines.push(`Template Configuration Applied`);\n lines.push(`${'─'.repeat(40)}`);\n lines.push(`Total files scanned: ${report.totalFiles}`);\n lines.push(`Files modified: ${report.filesModified}`);\n lines.push(`Total replacements: ${report.replacements.length}`);\n\n if (report.replacements.length > 0) {\n lines.push('');\n lines.push('Replacements:');\n\n // Group by file\n const byFile: Record<string, string[]> = {};\n for (const r of report.replacements) {\n if (!byFile[r.file]) {\n byFile[r.file] = [];\n }\n byFile[r.file].push(` ${r.placeholder} → ${r.value}`);\n }\n\n for (const [file, changes] of Object.entries(byFile)) {\n lines.push(` ${file}:`);\n for (const change of changes) {\n lines.push(change);\n }\n }\n }\n\n if (report.unreplaced.length > 0) {\n lines.push('');\n lines.push('Not configured (using defaults or runtime values):');\n for (const p of report.unreplaced.slice(0, 10)) {\n lines.push(` ${p}`);\n }\n if (report.unreplaced.length > 10) {\n lines.push(` ... and ${report.unreplaced.length - 10} more`);\n }\n }\n\n return lines.join('\\n');\n}\n\n/**\n * Preview replacements without making changes\n */\nexport async function previewReplacements(\n dir: string,\n config: Partial<TemplateConfig>\n): Promise<{ file: string; placeholder: string; value: string }[]> {\n const replacements = flattenTemplateConfig(config);\n const files = await getAllFiles(dir);\n const preview: Array<{ file: string; placeholder: string; value: string }> = [];\n\n for (const file of files) {\n try {\n const content = await fs.readFile(file, 'utf-8');\n\n for (const [placeholder, value] of Object.entries(replacements)) {\n if (content.includes(placeholder)) {\n preview.push({\n file: path.relative(dir, file),\n placeholder,\n value,\n });\n }\n }\n } catch {\n // Skip unreadable files\n }\n }\n\n return preview;\n}\n"],"mappings":"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","names":["fs","path","chalk","CONFIG_FILE","CLAUDE_DIR","fs","path","glob","module","ora","pc","module","variable","path","getModuleIds","fs","path","fs","path","import_ora"]}