@nextsparkjs/cli 0.1.0-beta.100 → 0.1.0-beta.101
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.
- package/dist/add-plugin-KIJLCOEQ.js +8 -0
- package/dist/{chunk-5GBCARGX.js → chunk-DXL5CEZD.js} +9 -2
- package/dist/cli.js +962 -490
- package/package.json +1 -1
- package/dist/add-plugin-Q7DOR7XO.js +0 -10
- package/dist/add-plugin-Q7DOR7XO.js.map +0 -1
- package/dist/chunk-5GBCARGX.js.map +0 -1
- package/dist/chunk-DGUM43GV.js +0 -11
- package/dist/chunk-DGUM43GV.js.map +0 -1
- package/dist/chunk-QXD4PBX6.js +0 -435
- package/dist/chunk-QXD4PBX6.js.map +0 -1
- package/dist/cli.js.map +0 -1
- package/dist/index.d.ts +0 -46
- package/dist/index.js +0 -24
- package/dist/index.js.map +0 -1
package/dist/cli.js.map
DELETED
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/cli.ts","../src/commands/init.ts","../src/wizard/index.ts","../src/wizard/banner.ts","../src/wizard/prompts/project-info.ts","../src/wizard/prompts/project-type.ts","../src/wizard/prompts/team-config.ts","../src/wizard/types.ts","../src/wizard/prompts/i18n-config.ts","../src/wizard/prompts/billing-config.ts","../src/wizard/prompts/features-config.ts","../src/wizard/prompts/content-features-config.ts","../src/wizard/prompts/auth-config.ts","../src/wizard/prompts/dashboard-config.ts","../src/wizard/prompts/dev-config.ts","../src/wizard/prompts/theme-selection.ts","../src/wizard/prompts/plugins-selection.ts","../src/wizard/prompts/env-config.ts","../src/wizard/prompts/git-config.ts","../src/wizard/prompts/index.ts","../src/wizard/generators/index.ts","../src/wizard/generators/theme-renamer.ts","../src/wizard/generators/config-generator.ts","../src/wizard/generators/messages-generator.ts","../src/wizard/generators/content-features-generator.ts","../src/wizard/generators/theme-plugins-installer.ts","../src/commands/add-theme.ts","../src/wizard/generators/env-setup.ts","../src/wizard/generators/git-init.ts","../src/wizard/generators/monorepo-generator.ts","../src/wizard/presets.ts","../src/wizard/preview.ts","../src/commands/add-mobile.ts","../src/commands/doctor.ts","../src/doctor/index.ts","../src/doctor/checks/dependencies.ts","../src/doctor/checks/config.ts","../src/doctor/checks/database.ts","../src/doctor/checks/imports.ts","../src/commands/db.ts","../src/commands/sync-app.ts","../src/commands/setup-ai.ts","../src/commands/sync-ai.ts"],"sourcesContent":["#!/usr/bin/env node\n\nimport { config } from 'dotenv';\nimport { Command } from 'commander';\nimport chalk from 'chalk';\nimport { readFileSync } from 'fs';\nimport { devCommand } from './commands/dev.js';\n\n// Load .env from project root\nconfig();\nimport { buildCommand } from './commands/build.js';\nimport { generateCommand } from './commands/generate.js';\nimport { registryBuildCommand, registryWatchCommand } from './commands/registry.js';\nimport { initCommand } from './commands/init.js';\nimport { addPluginCommand } from './commands/add-plugin.js';\nimport { addThemeCommand } from './commands/add-theme.js';\nimport { addMobileCommand } from './commands/add-mobile.js';\nimport { doctorCommand } from './commands/doctor.js';\nimport { dbMigrateCommand, dbSeedCommand } from './commands/db.js';\nimport { syncAppCommand } from './commands/sync-app.js';\nimport { setupAICommand } from './commands/setup-ai.js';\nimport { syncAICommand } from './commands/sync-ai.js';\n\n// Read version from package.json dynamically\nconst pkg = JSON.parse(readFileSync(new URL('../package.json', import.meta.url), 'utf-8'));\n\nconst program = new Command();\n\nprogram\n .name('nextspark')\n .description('NextSpark CLI - Professional SaaS Boilerplate')\n .version(pkg.version);\n\n// Dev command\nprogram\n .command('dev')\n .description('Start development server with registry watcher')\n .option('-p, --port <port>', 'Port to run the dev server on', process.env.PORT || '3000')\n .option('--no-registry', 'Disable registry watcher')\n .action(devCommand);\n\n// Build command\nprogram\n .command('build')\n .description('Build for production')\n .option('--no-registry', 'Skip registry generation before build')\n .action(buildCommand);\n\n// Generate command\nprogram\n .command('generate')\n .description('Generate all registries')\n .option('-w, --watch', 'Watch for changes')\n .action(generateCommand);\n\n// Registry commands\nconst registry = program\n .command('registry')\n .description('Registry management commands');\n\nregistry\n .command('build')\n .description('Build all registries')\n .action(registryBuildCommand);\n\nregistry\n .command('watch')\n .description('Watch and rebuild registries on changes')\n .action(registryWatchCommand);\n\n// Shorthand aliases for registry commands\nprogram\n .command('registry:build')\n .description('Build all registries (alias)')\n .action(registryBuildCommand);\n\nprogram\n .command('registry:watch')\n .description('Watch and rebuild registries (alias)')\n .action(registryWatchCommand);\n\n// Init command\nprogram\n .command('init')\n .description('Initialize NextSpark project')\n .option('-f, --force', 'Overwrite existing configuration')\n .option('--wizard', 'Run full project wizard')\n .option('--quick', 'Quick wizard mode (essential steps only)')\n .option('--expert', 'Expert wizard mode (all options)')\n .option('--preset <name>', 'Use preset configuration (saas, blog, crm)')\n .option('--theme <name>', 'Pre-select theme (default, blog, crm, productivity, none)')\n .option('--plugins <list>', 'Pre-select plugins (comma-separated)')\n .option('-y, --yes', 'Skip confirmations')\n .option('--registries-only', 'Only create registries (no wizard)')\n .option('--name <name>', 'Project name (non-interactive mode)')\n .option('--slug <slug>', 'Project slug (non-interactive mode)')\n .option('--description <desc>', 'Project description (non-interactive mode)')\n .option('--type <type>', 'Project type: web or web-mobile (non-interactive mode)')\n .action(initCommand);\n\n// Add plugin command\nprogram\n .command('add:plugin <package>')\n .description('Add a plugin to your project')\n .option('-v, --version <version>', 'Specific version to install')\n .option('-f, --force', 'Overwrite if already exists')\n .option('--skip-postinstall', 'Skip postinstall hooks')\n .option('--no-deps', 'Skip installing dependencies')\n .option('--dry-run', 'Show what would be done without making changes')\n .action(addPluginCommand);\n\n// Add theme command\nprogram\n .command('add:theme <package>')\n .description('Add a theme to your project')\n .option('-v, --version <version>', 'Specific version to install')\n .option('-f, --force', 'Overwrite if already exists')\n .option('--skip-postinstall', 'Skip postinstall hooks')\n .option('--no-deps', 'Skip installing dependencies')\n .option('--dry-run', 'Show what would be done without making changes')\n .action(addThemeCommand);\n\n// Add mobile command\nprogram\n .command('add:mobile')\n .description('Add mobile app to your project')\n .option('-f, --force', 'Overwrite if already exists')\n .option('--skip-install', 'Skip npm install')\n .action(addMobileCommand);\n\n// Doctor command (health check)\nprogram\n .command('doctor')\n .description('Run health check on NextSpark project')\n .action(doctorCommand);\n\n// Database commands\nconst db = program\n .command('db')\n .description('Database management commands');\n\ndb\n .command('migrate')\n .description('Run database migrations')\n .action(dbMigrateCommand);\n\ndb\n .command('seed')\n .description('Seed database with sample data')\n .action(dbSeedCommand);\n\n// Shorthand aliases for database commands\nprogram\n .command('db:migrate')\n .description('Run database migrations (alias)')\n .action(dbMigrateCommand);\n\nprogram\n .command('db:seed')\n .description('Seed database with sample data (alias)')\n .action(dbSeedCommand);\n\n// Sync app command\nprogram\n .command('sync:app')\n .description('Sync /app folder with @nextsparkjs/core templates')\n .option('--dry-run', 'Preview changes without applying')\n .option('-f, --force', 'Skip confirmation prompt')\n .option('--backup', 'Backup existing files before overwriting')\n .option('-v, --verbose', 'Show detailed file operations')\n .action(syncAppCommand);\n\n// Setup AI workflow\nprogram\n .command('setup:ai')\n .description('Setup AI workflow for your editor (Claude Code, Cursor, Antigravity)')\n .option('-e, --editor <editor>', 'Editor to setup (claude, cursor, antigravity, all)', 'claude')\n .action(setupAICommand);\n\n// Sync AI workflow\nprogram\n .command('sync:ai')\n .description('Sync AI workflow files from @nextsparkjs/ai-workflow')\n .option('-e, --editor <editor>', 'Editor to sync (claude, cursor, antigravity, all)', 'claude')\n .option('-f, --force', 'Skip confirmation prompt')\n .action(syncAICommand);\n\n// Error handling\nprogram.showHelpAfterError();\n\nprogram.configureOutput({\n writeErr: (str) => process.stderr.write(chalk.red(str)),\n});\n\n// Parse arguments\nprogram.parse();\n","import { existsSync, mkdirSync, writeFileSync, readFileSync } from 'node:fs';\nimport { join } from 'node:path';\nimport chalk from 'chalk';\nimport ora from 'ora';\nimport { runWizard } from '../wizard/index.js';\nimport type { CLIOptions, WizardMode, PresetName, ThemeOption, PluginOption, ProjectType } from '../wizard/types.js';\n\ninterface InitOptions {\n force?: boolean;\n wizard?: boolean;\n quick?: boolean;\n expert?: boolean;\n preset?: string;\n theme?: string;\n plugins?: string;\n yes?: boolean;\n registriesOnly?: boolean;\n name?: string;\n slug?: string;\n description?: string;\n type?: string;\n}\n\n/**\n * Determine wizard mode from options\n */\nfunction getWizardMode(options: InitOptions): WizardMode {\n if (options.quick) return 'quick';\n if (options.expert) return 'expert';\n return 'interactive';\n}\n\n/**\n * Parse plugins from comma-separated string\n */\nfunction parsePlugins(pluginsStr: string | undefined): PluginOption[] | undefined {\n if (!pluginsStr) return undefined;\n return pluginsStr.split(',').map(p => p.trim()) as PluginOption[];\n}\n\n/**\n * Check if this is an existing NextSpark project\n */\nfunction hasExistingProject(): boolean {\n const projectRoot = process.cwd();\n // Check for contents/ directory or .nextspark/ directory\n return existsSync(join(projectRoot, 'contents')) ||\n existsSync(join(projectRoot, '.nextspark'));\n}\n\n/**\n * Generate initial empty registries with valid structure\n */\nfunction generateInitialRegistries(registriesDir: string): void {\n // Block Registry\n writeFileSync(join(registriesDir, 'block-registry.ts'), `// Auto-generated by nextspark init\nimport type { ComponentType } from 'react'\n\nexport const BLOCK_REGISTRY: Record<string, {\n name: string\n slug: string\n componentPath: string\n fields?: unknown[]\n examples?: unknown[]\n}> = {}\n\nexport const BLOCK_COMPONENTS: Record<string, React.LazyExoticComponent<ComponentType<any>>> = {}\n`);\n\n // Theme Registry\n writeFileSync(join(registriesDir, 'theme-registry.ts'), `// Auto-generated by nextspark init\nexport const THEME_REGISTRY: Record<string, unknown> = {}\n`);\n\n // Entity Registry\n writeFileSync(join(registriesDir, 'entity-registry.ts'), `// Auto-generated by nextspark init\nexport const ENTITY_REGISTRY: Record<string, unknown> = {}\n`);\n\n writeFileSync(join(registriesDir, 'entity-registry.client.ts'), `// Auto-generated by nextspark init\nexport const CLIENT_ENTITY_REGISTRY: Record<string, unknown> = {}\nexport function parseChildEntity(path: string) { return null }\nexport function getEntityApiPath(entity: string) { return \\`/api/\\${entity}\\` }\nexport function clientMetaSystemAdapter() { return {} }\nexport type ClientEntityConfig = Record<string, unknown>\n`);\n\n // Billing Registry\n writeFileSync(join(registriesDir, 'billing-registry.ts'), `// Auto-generated by nextspark init\nexport const BILLING_REGISTRY = { plans: [], features: [] }\n`);\n\n // Plugin Registry\n writeFileSync(join(registriesDir, 'plugin-registry.ts'), `// Auto-generated by nextspark init\nexport const PLUGIN_REGISTRY: Record<string, unknown> = {}\n`);\n\n // Testing Registry\n writeFileSync(join(registriesDir, 'testing-registry.ts'), `// Auto-generated by nextspark init\nexport const FLOW_REGISTRY: Record<string, unknown> = {}\nexport const FEATURE_REGISTRY: Record<string, unknown> = {}\nexport const TAGS_REGISTRY: Record<string, unknown> = {}\nexport const COVERAGE_SUMMARY = { total: 0, covered: 0 }\nexport type FlowEntry = unknown\nexport type FeatureEntry = unknown\n`);\n\n // Docs Registry\n writeFileSync(join(registriesDir, 'docs-registry.ts'), `// Auto-generated by nextspark init\nexport const DOCS_REGISTRY = { sections: [], pages: [] }\nexport type DocSectionMeta = { title: string; slug: string }\n`);\n\n // Index\n writeFileSync(join(registriesDir, 'index.ts'), `// Auto-generated by nextspark init\nexport * from './block-registry'\nexport * from './theme-registry'\nexport * from './entity-registry'\nexport * from './entity-registry.client'\nexport * from './billing-registry'\nexport * from './plugin-registry'\nexport * from './testing-registry'\nexport * from './docs-registry'\n`);\n}\n\n/**\n * Simple init - only create registries\n */\nasync function simpleInit(options: InitOptions): Promise<void> {\n const spinner = ora('Initializing NextSpark project...').start();\n const projectRoot = process.cwd();\n\n try {\n // 1. Create .nextspark/registries directory\n const nextspark = join(projectRoot, '.nextspark');\n const registriesDir = join(nextspark, 'registries');\n\n if (!existsSync(registriesDir) || options.force) {\n mkdirSync(registriesDir, { recursive: true });\n spinner.text = 'Creating .nextspark/registries/';\n\n // 2. Generate initial registries\n generateInitialRegistries(registriesDir);\n spinner.text = 'Generated initial registries';\n }\n\n // 3. Create/update tsconfig.json paths\n const tsconfigPath = join(projectRoot, 'tsconfig.json');\n if (existsSync(tsconfigPath)) {\n spinner.text = 'Updating tsconfig.json paths...';\n const tsconfig = JSON.parse(readFileSync(tsconfigPath, 'utf-8'));\n tsconfig.compilerOptions = tsconfig.compilerOptions || {};\n tsconfig.compilerOptions.paths = {\n ...tsconfig.compilerOptions.paths,\n \"@nextsparkjs/registries\": [\"./.nextspark/registries/index.ts\"],\n \"@nextsparkjs/registries/*\": [\"./.nextspark/registries/*\"],\n };\n writeFileSync(tsconfigPath, JSON.stringify(tsconfig, null, 2));\n }\n\n // 4. Create .env.example if not exists\n const envExample = join(projectRoot, '.env.example');\n if (!existsSync(envExample)) {\n const envContent = `# NextSpark Configuration\nDATABASE_URL=\"postgresql://user:password@localhost:5432/db\"\nBETTER_AUTH_SECRET=\"your-secret-here-min-32-chars\"\nBETTER_AUTH_URL=http://localhost:3000\nNEXT_PUBLIC_APP_URL=http://localhost:3000\n`;\n writeFileSync(envExample, envContent);\n spinner.text = 'Created .env.example';\n }\n\n spinner.succeed('NextSpark initialized successfully!');\n\n console.log(chalk.blue('\\nNext steps:'));\n console.log(' 1. Copy .env.example to .env and configure');\n console.log(' 2. Run: nextspark generate');\n console.log(' 3. Run: nextspark dev');\n\n } catch (error) {\n spinner.fail('Initialization failed');\n if (error instanceof Error) {\n console.error(chalk.red(error.message));\n }\n process.exit(1);\n }\n}\n\n/**\n * Main init command handler\n */\nexport async function initCommand(options: InitOptions): Promise<void> {\n // If --registries-only or existing project without --wizard flag, do simple init\n if (options.registriesOnly) {\n await simpleInit(options);\n return;\n }\n\n // If existing project and not explicitly requesting wizard\n if (hasExistingProject() && !options.wizard && !options.preset && !options.theme) {\n console.log(chalk.yellow('Existing NextSpark project detected.'));\n console.log(chalk.gray('Use --wizard to run the full wizard, or --registries-only for just registries.'));\n await simpleInit(options);\n return;\n }\n\n // Run the full wizard\n const wizardOptions: CLIOptions = {\n mode: getWizardMode(options),\n preset: options.preset as PresetName | undefined,\n theme: options.theme as ThemeOption | undefined,\n plugins: parsePlugins(options.plugins),\n yes: options.yes,\n name: options.name,\n slug: options.slug,\n description: options.description,\n type: options.type as ProjectType | undefined,\n };\n\n await runWizard(wizardOptions);\n}\n","/**\n * NextSpark Wizard Orchestrator\n *\n * Main wizard entry point that runs all prompts in sequence\n * and generates the project based on user responses.\n */\n\nimport chalk from 'chalk'\nimport ora from 'ora'\nimport { confirm, select } from '@inquirer/prompts'\nimport { execSync } from 'child_process'\nimport { existsSync, readdirSync } from 'fs'\nimport { join, resolve } from 'path'\nimport { showBanner, showSection, showSuccess, showError, showInfo, showWarning } from './banner.js'\nimport { runAllPrompts, runQuickPrompts, runExpertPrompts } from './prompts/index.js'\nimport { generateProject, isMonorepoProject, getWebDir } from './generators/index.js'\nimport { getPreset, applyPreset, PRESET_DESCRIPTIONS } from './presets.js'\nimport type { WizardConfig, CLIOptions } from './types.js'\nimport { promptProjectInfo } from './prompts/project-info.js'\n// Theme & Plugin Selection\nimport { promptThemeSelection, promptPluginsSelection, getRequiredPlugins, type ThemeChoice, type PluginChoice } from './prompts/index.js'\nimport { installThemeAndPlugins } from './generators/theme-plugins-installer.js'\nimport { showConfigPreview } from './preview.js'\n\n/**\n * Project info type for non-interactive mode\n */\ninterface ProjectInfo {\n projectName: string\n projectSlug: string\n projectDescription: string\n}\n\n/**\n * Get project info from CLI options for non-interactive mode\n * Returns null if any required field is missing\n */\nfunction getProjectInfoFromOptions(options: CLIOptions): ProjectInfo | null {\n if (options.name && options.slug && options.description) {\n return {\n projectName: options.name,\n projectSlug: options.slug,\n projectDescription: options.description,\n }\n }\n return null\n}\n\n/**\n * Run the complete wizard with mode support\n */\nexport async function runWizard(options: CLIOptions = { mode: 'interactive' }): Promise<void> {\n // Show welcome banner\n showBanner()\n\n // Show mode indicator\n showModeIndicator(options)\n\n try {\n let selectedTheme: ThemeChoice = null\n let selectedPlugins: PluginChoice[] = []\n let config: WizardConfig\n\n if (options.preset) {\n // Preset mode: get project info then apply preset\n config = await runPresetMode(options.preset, options)\n } else {\n // Run prompts based on mode\n // Order: 1. Type, 2. Info, 3-10. Config options\n switch (options.mode) {\n case 'quick':\n config = await runQuickPrompts()\n break\n case 'expert':\n config = await runExpertPrompts()\n break\n case 'interactive':\n default:\n config = await runAllPrompts()\n break\n }\n }\n\n // Theme & Plugin Selection (AFTER project type and info)\n // This ensures we know the project structure before asking about themes\n if (options.theme !== undefined) {\n // Non-interactive mode: use CLI flags\n selectedTheme = options.theme === 'none' ? null : options.theme as ThemeChoice\n showInfo(`Reference theme: ${selectedTheme || 'None'}`)\n } else if (!options.preset && options.mode !== 'quick') {\n // Interactive mode: prompt user (only if not using preset)\n selectedTheme = await promptThemeSelection()\n }\n\n // Plugins selection\n if (options.plugins !== undefined) {\n selectedPlugins = options.plugins as PluginChoice[]\n if (selectedPlugins.length > 0) {\n showInfo(`Selected plugins: ${selectedPlugins.join(', ')}`)\n }\n } else if (!options.preset && options.mode !== 'quick' && !options.yes) {\n // Interactive mode: prompt user (skip in --yes mode or preset mode)\n selectedPlugins = await promptPluginsSelection(selectedTheme)\n } else if (selectedTheme) {\n // In quick/yes/preset mode, auto-include required plugins for theme\n selectedPlugins = getRequiredPlugins(selectedTheme)\n }\n\n // Show summary before generating\n showConfigSummary(config)\n\n // Show interactive preview of files to be created\n showConfigPreview(config)\n\n // Ask for confirmation before proceeding (skip with --yes flag)\n if (!options.yes) {\n console.log('')\n const proceed = await confirm({\n message: 'Proceed with project generation?',\n default: true,\n })\n\n if (!proceed) {\n console.log('')\n showInfo('Project generation cancelled. No changes were made.')\n process.exit(0)\n }\n }\n\n // Install @nextsparkjs/core first (required for templates)\n console.log('')\n const coreInstalled = await installCore()\n if (!coreInstalled) {\n showError('Failed to install @nextsparkjs/core. Cannot generate project.')\n process.exit(1)\n }\n\n // For monorepo projects, also install @nextsparkjs/mobile (required for mobile templates)\n if (config.projectType === 'web-mobile') {\n console.log('')\n const mobileInstalled = await installMobile()\n if (!mobileInstalled) {\n showError('Failed to install @nextsparkjs/mobile. Cannot generate monorepo project.')\n process.exit(1)\n }\n }\n\n // Generate the project\n console.log('')\n const spinner = ora({\n text: 'Generating your NextSpark project...',\n prefixText: ' ',\n }).start()\n\n try {\n await generateProject(config)\n spinner.succeed('Project generated successfully!')\n } catch (error) {\n spinner.fail('Failed to generate project')\n throw error\n }\n\n // Install theme and plugins after project generation\n if (selectedTheme || selectedPlugins.length > 0) {\n await installThemeAndPlugins(selectedTheme, selectedPlugins)\n }\n\n // Determine the web directory for monorepo projects\n const projectRoot = process.cwd()\n const webDir = getWebDir(projectRoot, config)\n const isMonorepo = isMonorepoProject(config)\n\n // Install all dependencies\n const installSpinner = ora({\n text: isMonorepo ? 'Installing dependencies (monorepo)...' : 'Installing dependencies...',\n prefixText: ' ',\n }).start()\n\n try {\n // TODO: Change back to stdio: 'pipe' once Windows issues are resolved\n installSpinner.stop()\n execSync('pnpm install --force', {\n cwd: projectRoot, // Always install from root (works for both flat and monorepo)\n stdio: 'inherit',\n })\n installSpinner.succeed('Dependencies installed!')\n } catch (error) {\n installSpinner.fail('Failed to install dependencies')\n console.log(chalk.yellow(' Run \"pnpm install\" manually to install dependencies'))\n }\n\n // Build registries using the core's registry builder\n const registrySpinner = ora({\n text: 'Building registries...',\n prefixText: ' ',\n }).start()\n\n try {\n // For monorepo, registry script is in web/node_modules\n const registryScript = join(webDir, 'node_modules/@nextsparkjs/core/scripts/build/registry.mjs')\n // TODO: Change back to stdio: 'pipe' once Windows issues are resolved\n registrySpinner.stop()\n execSync(`node \"${registryScript}\" --build`, {\n cwd: webDir, // Run from web directory\n stdio: 'inherit',\n env: {\n ...process.env,\n NEXTSPARK_PROJECT_ROOT: webDir,\n },\n })\n registrySpinner.succeed('Registries built!')\n } catch (error) {\n registrySpinner.fail('Failed to build registries')\n const devCmd = isMonorepo ? 'pnpm dev' : 'pnpm dev'\n console.log(chalk.yellow(` Registries will be built automatically when you run \"${devCmd}\"`))\n }\n\n // AI Workflow setup (optional)\n const aiChoice = await promptAIWorkflowSetup(config)\n\n // Show next steps\n showNextSteps(config, selectedTheme, aiChoice)\n } catch (error) {\n if (error instanceof Error) {\n if (error.message.includes('User force closed')) {\n console.log('')\n showInfo('Wizard cancelled. No changes were made.')\n process.exit(0)\n }\n showError(error.message)\n }\n process.exit(1)\n }\n}\n\n/**\n * Show mode indicator at the start\n */\nfunction showModeIndicator(options: CLIOptions): void {\n if (options.preset) {\n showInfo(`Using preset: ${chalk.cyan(options.preset)} - ${PRESET_DESCRIPTIONS[options.preset]}`)\n console.log('')\n } else if (options.mode === 'quick') {\n showInfo('Quick mode: Running essential prompts only (steps 1-5)')\n console.log('')\n } else if (options.mode === 'expert') {\n showInfo('Expert mode: Running all prompts with advanced options')\n console.log('')\n }\n}\n\n/**\n * Run preset mode: only project info, then apply preset defaults\n * Supports non-interactive mode when CLI options provide all project info\n */\nasync function runPresetMode(presetName: CLIOptions['preset'], options: CLIOptions): Promise<WizardConfig> {\n if (!presetName) {\n throw new Error('Preset name is required for preset mode')\n }\n\n // Check for non-interactive mode\n const projectInfoFromOptions = getProjectInfoFromOptions(options)\n\n let projectInfo: ProjectInfo\n\n if (projectInfoFromOptions) {\n // Non-interactive mode: use CLI options\n projectInfo = projectInfoFromOptions\n showInfo(`Project: ${projectInfo.projectName} (${projectInfo.projectSlug})`)\n } else {\n // Interactive mode: prompt for project info\n showSection('Project Information', 1, 1)\n showInfo('Using preset defaults. Only project information is required.')\n console.log('')\n\n // Get project info from user\n projectInfo = await promptProjectInfo()\n }\n\n // Apply preset to project info (with optional type override from CLI)\n const config = applyPreset(projectInfo, presetName, options.type)\n\n return config\n}\n\n/**\n * Display configuration summary before generating\n */\nfunction showConfigSummary(config: WizardConfig): void {\n console.log('')\n console.log(chalk.cyan(' ' + '='.repeat(60)))\n console.log(chalk.bold.white(' Configuration Summary'))\n console.log(chalk.cyan(' ' + '='.repeat(60)))\n console.log('')\n\n console.log(chalk.white(' Project:'))\n console.log(chalk.gray(` Name: ${chalk.white(config.projectName)}`))\n console.log(chalk.gray(` Slug: ${chalk.white(config.projectSlug)}`))\n console.log(chalk.gray(` Description: ${chalk.white(config.projectDescription)}`))\n console.log(chalk.gray(` Type: ${chalk.white(config.projectType === 'web-mobile' ? 'Web + Mobile (Monorepo)' : 'Web only')}`))\n console.log('')\n\n console.log(chalk.white(' Team Mode:'))\n console.log(chalk.gray(` Mode: ${chalk.white(config.teamMode)}`))\n console.log(chalk.gray(` Roles: ${chalk.white(config.teamRoles.join(', '))}`))\n console.log('')\n\n console.log(chalk.white(' Internationalization:'))\n console.log(chalk.gray(` Default: ${chalk.white(config.defaultLocale)}`))\n console.log(chalk.gray(` Languages: ${chalk.white(config.supportedLocales.join(', '))}`))\n console.log('')\n\n console.log(chalk.white(' Billing:'))\n console.log(chalk.gray(` Model: ${chalk.white(config.billingModel)}`))\n console.log(chalk.gray(` Currency: ${chalk.white(config.currency.toUpperCase())}`))\n console.log('')\n\n console.log(chalk.white(' Features:'))\n const enabledFeatures = Object.entries(config.features)\n .filter(([_, enabled]) => enabled)\n .map(([feature]) => feature)\n console.log(chalk.gray(` Enabled: ${chalk.white(enabledFeatures.join(', ') || 'None')}`))\n console.log('')\n\n console.log(chalk.white(' Authentication:'))\n const enabledAuth = Object.entries(config.auth)\n .filter(([_, enabled]) => enabled)\n .map(([method]) => formatAuthMethod(method))\n console.log(chalk.gray(` Methods: ${chalk.white(enabledAuth.join(', ') || 'None')}`))\n console.log('')\n\n console.log(chalk.white(' Dashboard:'))\n const enabledDashboard = Object.entries(config.dashboard)\n .filter(([_, enabled]) => enabled)\n .map(([feature]) => formatDashboardFeature(feature))\n console.log(chalk.gray(` Features: ${chalk.white(enabledDashboard.join(', ') || 'None')}`))\n console.log('')\n\n console.log(chalk.white(' Dev Tools:'))\n const enabledDevTools = Object.entries(config.dev)\n .filter(([_, enabled]) => enabled)\n .map(([tool]) => formatDevTool(tool))\n console.log(chalk.gray(` Enabled: ${chalk.white(enabledDevTools.join(', ') || 'None')}`))\n}\n\n/**\n * Format authentication method name for display\n */\nfunction formatAuthMethod(method: string): string {\n const mapping: Record<string, string> = {\n emailPassword: 'Email/Password',\n googleOAuth: 'Google',\n emailVerification: 'Email Verification',\n }\n return mapping[method] || method\n}\n\n/**\n * Format dashboard feature name for display\n */\nfunction formatDashboardFeature(feature: string): string {\n const mapping: Record<string, string> = {\n search: 'Search',\n notifications: 'Notifications',\n themeToggle: 'Theme Toggle',\n sidebarCollapsed: 'Sidebar Collapsed',\n }\n return mapping[feature] || feature\n}\n\n/**\n * Format dev tool name for display\n */\nfunction formatDevTool(tool: string): string {\n const mapping: Record<string, string> = {\n devKeyring: 'Dev Keyring',\n debugMode: 'Debug Mode',\n }\n return mapping[tool] || tool\n}\n\n/**\n * Display next steps after successful generation\n */\nfunction showNextSteps(config: WizardConfig, referenceTheme: ThemeChoice = null, aiChoice: string = 'skip'): void {\n const isMonorepo = config.projectType === 'web-mobile'\n const aiSetupDone = aiChoice === 'claude'\n\n console.log('')\n console.log(chalk.cyan(' ' + '='.repeat(60)))\n console.log(chalk.bold.green(' ✨ NextSpark project ready!'))\n console.log(chalk.cyan(' ' + '='.repeat(60)))\n console.log('')\n\n console.log(chalk.bold.white(' Next steps:'))\n console.log('')\n\n // Step 1: Configure .env\n const envPath = isMonorepo ? 'web/.env' : '.env'\n console.log(chalk.white(' 1. Configure your environment:'))\n console.log(chalk.gray(` Edit ${envPath} with your credentials:`))\n console.log('')\n console.log(chalk.yellow(' DATABASE_URL'))\n console.log(chalk.gray(' PostgreSQL connection string'))\n console.log(chalk.gray(` Recommended: ${chalk.cyan('https://supabase.com')} | ${chalk.cyan('https://neon.com')}`))\n console.log('')\n console.log(chalk.yellow(' BETTER_AUTH_SECRET'))\n console.log(chalk.gray(' Generate with:'))\n console.log(chalk.cyan(' openssl rand -base64 32'))\n console.log('')\n\n // Step 2: Run migrations\n console.log(chalk.white(' 2. Run database migrations:'))\n console.log(chalk.cyan(' pnpm db:migrate'))\n console.log('')\n\n // Step 3: Start dev server\n console.log(chalk.white(' 3. Start the development server:'))\n console.log(chalk.cyan(' pnpm dev'))\n console.log('')\n\n let nextStep = 4\n\n // Mobile-specific step for monorepo\n if (isMonorepo) {\n console.log(chalk.white(` ${nextStep}. (Optional) Start the mobile app:`))\n console.log(chalk.cyan(' pnpm dev:mobile'))\n console.log(chalk.gray(' Or: cd mobile && pnpm start'))\n console.log('')\n nextStep++\n }\n\n // AI step — conditional on what the user chose\n if (aiSetupDone) {\n console.log(chalk.white(` ${nextStep}. Start building with AI:`))\n console.log(chalk.gray(' Open Claude Code in your project and run:'))\n console.log(chalk.cyan(' /how-to:start'))\n console.log('')\n } else {\n console.log(chalk.white(` ${nextStep}. (Optional) Setup AI workflows:`))\n console.log(chalk.cyan(' nextspark setup:ai'))\n console.log('')\n }\n\n // Footer info\n console.log(chalk.gray(' ' + '-'.repeat(60)))\n\n if (isMonorepo) {\n console.log(chalk.gray(` Structure: ${chalk.white('Monorepo (web/ + mobile/)')}`))\n console.log(chalk.gray(` Web theme: ${chalk.white(`web/contents/themes/${config.projectSlug}/`)}`))\n console.log(chalk.gray(` Mobile app: ${chalk.white('mobile/')}`))\n console.log(chalk.gray(` Active theme: ${chalk.green(`NEXT_PUBLIC_ACTIVE_THEME=${config.projectSlug}`)}`))\n } else {\n console.log(chalk.gray(` Theme: ${chalk.white(`contents/themes/${config.projectSlug}/`)}`))\n console.log(chalk.gray(` Active theme: ${chalk.green(`NEXT_PUBLIC_ACTIVE_THEME=${config.projectSlug}`)}`))\n }\n\n if (referenceTheme) {\n const refPath = isMonorepo ? `web/contents/themes/${referenceTheme}/` : `contents/themes/${referenceTheme}/`\n console.log(chalk.gray(` Reference: ${chalk.white(refPath)}`))\n }\n\n console.log(chalk.gray(` Docs: ${chalk.cyan('https://nextspark.dev/docs')}`))\n console.log('')\n}\n\n/**\n * Prompt user for AI workflow setup (optional step at end of wizard)\n * Returns the choice made ('claude', 'cursor', 'antigravity', or 'skip')\n */\nasync function promptAIWorkflowSetup(config: WizardConfig): Promise<string> {\n console.log('')\n\n const choice = await select({\n message: 'Setup AI-assisted development workflows?',\n choices: [\n { name: 'Claude Code (Recommended)', value: 'claude' },\n { name: 'Cursor (Coming soon)', value: 'cursor' },\n { name: 'Antigravity (Coming soon)', value: 'antigravity' },\n { name: 'Skip for now', value: 'skip' },\n ],\n })\n\n if (choice === 'skip') {\n return 'skip'\n }\n\n if (choice === 'cursor' || choice === 'antigravity') {\n showInfo(`${choice} support is coming soon. For now, use Claude Code.`)\n return 'skip'\n }\n\n const projectRoot = process.cwd()\n const isMonorepo = isMonorepoProject(config)\n\n // All generated projects use pnpm workspaces (web-only for themes/plugins,\n // monorepo for web/ + mobile/), so -w flag is always required\n try {\n execSync('pnpm add -D -w @nextsparkjs/ai-workflow', {\n cwd: projectRoot,\n stdio: 'inherit',\n })\n\n // Find setup script — check root node_modules first, then web/ for monorepo hoisting\n let setupScript = join(projectRoot, 'node_modules', '@nextsparkjs', 'ai-workflow', 'scripts', 'setup.mjs')\n if (!existsSync(setupScript) && isMonorepo) {\n setupScript = join(projectRoot, 'web', 'node_modules', '@nextsparkjs', 'ai-workflow', 'scripts', 'setup.mjs')\n }\n\n if (existsSync(setupScript)) {\n // .claude/ always goes at project root (applies to both web and mobile)\n execSync(`node \"${setupScript}\" ${choice}`, {\n cwd: projectRoot,\n stdio: 'inherit',\n })\n showSuccess('AI workflow setup complete!')\n } else {\n showWarning('AI workflow package installed but setup script not found. Run \"nextspark setup:ai\" manually.')\n }\n } catch (error) {\n showError('Failed to install AI workflow package. Run \"nextspark setup:ai\" later.')\n return 'skip'\n }\n\n return choice\n}\n\n/**\n * Find local tarball for core package\n * Looks for .tgz files in current directory\n */\nfunction findLocalCoreTarball(): string | null {\n const cwd = process.cwd()\n\n try {\n const files = readdirSync(cwd)\n const coreTarball = files.find((f) =>\n f.includes('nextsparkjs-core') && f.endsWith('.tgz')\n )\n if (coreTarball) {\n return join(cwd, coreTarball)\n }\n } catch {\n // Ignore errors\n }\n\n return null\n}\n\n/**\n * Check if core is already installed\n */\nfunction isCoreInstalled(): boolean {\n const corePath = join(process.cwd(), 'node_modules', '@nextsparkjs', 'core')\n return existsSync(corePath)\n}\n\n/**\n * Install @nextsparkjs/core package\n * Required before project generation (provides templates)\n */\nasync function installCore(): Promise<boolean> {\n // Skip if already installed\n if (isCoreInstalled()) {\n return true\n }\n\n const spinner = ora({\n text: 'Installing @nextsparkjs/core...',\n prefixText: ' ',\n }).start()\n\n try {\n // Check for local tarball first\n const localTarball = findLocalCoreTarball()\n\n let packageSpec = '@nextsparkjs/core'\n if (localTarball) {\n packageSpec = localTarball\n spinner.text = 'Installing @nextsparkjs/core from local tarball...'\n }\n\n // Detect package manager\n const useYarn = existsSync(join(process.cwd(), 'yarn.lock'))\n const usePnpm = existsSync(join(process.cwd(), 'pnpm-lock.yaml'))\n\n let installCmd: string\n if (usePnpm) {\n installCmd = `pnpm add ${packageSpec}`\n } else if (useYarn) {\n installCmd = `yarn add ${packageSpec}`\n } else {\n installCmd = `npm install ${packageSpec}`\n }\n\n // TODO: Change back to stdio: 'pipe' once Windows issues are resolved\n spinner.stop()\n execSync(installCmd, {\n stdio: 'inherit',\n cwd: process.cwd(),\n })\n\n spinner.succeed(chalk.green('@nextsparkjs/core installed successfully!'))\n return true\n } catch (error) {\n spinner.fail(chalk.red('Failed to install @nextsparkjs/core'))\n if (error instanceof Error) {\n console.log(chalk.red(` Error: ${error.message}`))\n }\n console.log(chalk.gray(' Hint: Make sure the package is available (npm registry or local tarball)'))\n return false\n }\n}\n\n/**\n * Check if mobile is already installed\n */\nfunction isMobileInstalled(): boolean {\n const mobilePath = join(process.cwd(), 'node_modules', '@nextsparkjs', 'mobile')\n return existsSync(mobilePath)\n}\n\n/**\n * Find local tarball for mobile package\n */\nfunction findLocalMobileTarball(): string | null {\n const cwd = process.cwd()\n\n try {\n const files = readdirSync(cwd)\n const mobileTarball = files.find((f) =>\n f.includes('nextsparkjs-mobile') && f.endsWith('.tgz')\n )\n if (mobileTarball) {\n return join(cwd, mobileTarball)\n }\n } catch {\n // Ignore errors\n }\n\n return null\n}\n\n/**\n * Install @nextsparkjs/mobile package\n * Required before monorepo project generation (provides mobile templates)\n */\nasync function installMobile(): Promise<boolean> {\n // Skip if already installed\n if (isMobileInstalled()) {\n return true\n }\n\n const spinner = ora({\n text: 'Installing @nextsparkjs/mobile...',\n prefixText: ' ',\n }).start()\n\n try {\n // Check for local tarball first\n const localTarball = findLocalMobileTarball()\n\n let packageSpec = '@nextsparkjs/mobile'\n if (localTarball) {\n packageSpec = localTarball\n spinner.text = 'Installing @nextsparkjs/mobile from local tarball...'\n }\n\n // Detect package manager\n const useYarn = existsSync(join(process.cwd(), 'yarn.lock'))\n const usePnpm = existsSync(join(process.cwd(), 'pnpm-lock.yaml'))\n\n let installCmd: string\n if (usePnpm) {\n installCmd = `pnpm add ${packageSpec}`\n } else if (useYarn) {\n installCmd = `yarn add ${packageSpec}`\n } else {\n installCmd = `npm install ${packageSpec}`\n }\n\n spinner.stop()\n execSync(installCmd, {\n stdio: 'inherit',\n cwd: process.cwd(),\n })\n\n spinner.succeed(chalk.green('@nextsparkjs/mobile installed successfully!'))\n return true\n } catch (error) {\n spinner.fail(chalk.red('Failed to install @nextsparkjs/mobile'))\n if (error instanceof Error) {\n console.log(chalk.red(` Error: ${error.message}`))\n }\n console.log(chalk.gray(' Hint: Make sure the package is available (npm registry or local tarball)'))\n return false\n }\n}\n\n","/**\n * NextSpark ASCII Banner\n *\n * Beautiful ASCII art banner for the CLI wizard.\n */\n\nimport chalk from 'chalk'\nimport { readFileSync } from 'fs'\nimport { fileURLToPath } from 'url'\nimport { dirname, join } from 'path'\n\nconst __filename = fileURLToPath(import.meta.url)\nconst __dirname = dirname(__filename)\n\n/**\n * Get CLI version from package.json\n */\nfunction getCliVersion(): string {\n // Try multiple possible paths (bundled in dist/ or running from src/)\n const possiblePaths = [\n join(__dirname, '../package.json'), // from dist/\n join(__dirname, '../../package.json'), // from dist/wizard/ or src/wizard/\n join(__dirname, '../../../package.json'), // fallback\n ]\n\n for (const packageJsonPath of possiblePaths) {\n try {\n const packageJson = JSON.parse(readFileSync(packageJsonPath, 'utf-8'))\n if (packageJson.name === '@nextsparkjs/cli' && packageJson.version) {\n return packageJson.version\n }\n } catch {\n // Try next path\n }\n }\n\n return 'unknown'\n}\n\n/**\n * NextSpark ASCII logo\n */\nconst BANNER = `\n _ __ __ _____ __\n / | / /__ _ __/ /_/ ___/____ ____ ______/ /__\n / |/ / _ \\\\| |/_/ __/\\\\__ \\\\/ __ \\\\/ __ \\`/ ___/ //_/\n / /| / __/> </ /_ ___/ / /_/ / /_/ / / / ,<\n/_/ |_/\\\\___/_/|_|\\\\__//____/ .___/\\\\__,_/_/ /_/|_|\n /_/\n`\n\n/**\n * Display the welcome banner\n */\nexport function showBanner(): void {\n const version = getCliVersion()\n console.log(chalk.cyan(BANNER))\n console.log(chalk.bold.white(' Welcome to NextSpark - The Complete SaaS Framework for Next.js'))\n console.log(chalk.gray(` Version ${version} - Create production-ready SaaS applications in minutes\\n`))\n console.log(chalk.gray(' ' + '='.repeat(60) + '\\n'))\n}\n\n/**\n * Display section header\n */\nexport function showSection(title: string, step: number, totalSteps: number): void {\n console.log('')\n console.log(chalk.cyan(` Step ${step}/${totalSteps}: ${title}`))\n console.log(chalk.gray(' ' + '-'.repeat(40)))\n console.log('')\n}\n\n/**\n * Display success message\n */\nexport function showSuccess(message: string): void {\n console.log(chalk.green(` ✓ ${message}`))\n}\n\n/**\n * Display warning message\n */\nexport function showWarning(message: string): void {\n console.log(chalk.yellow(` ⚠ ${message}`))\n}\n\n/**\n * Display error message\n */\nexport function showError(message: string): void {\n console.log(chalk.red(` ✗ ${message}`))\n}\n\n/**\n * Display info message\n */\nexport function showInfo(message: string): void {\n console.log(chalk.blue(` ℹ ${message}`))\n}\n","/**\n * Project Info Prompts (Step 2)\n *\n * Collects basic project information: name, slug, and description.\n */\n\nimport { input } from '@inquirer/prompts'\nimport { showSection } from '../banner.js'\nimport type { WizardConfig } from '../types.js'\n\n/**\n * Convert a string to a URL-safe slug\n */\nfunction toSlug(str: string): string {\n return str\n .toLowerCase()\n .trim()\n .replace(/[^a-z0-9]+/g, '-')\n .replace(/^-|-$/g, '')\n}\n\n/**\n * Validate project name\n */\nfunction validateProjectName(name: string): string | true {\n if (!name || name.trim().length === 0) {\n return 'Project name is required'\n }\n if (name.trim().length < 2) {\n return 'Project name must be at least 2 characters'\n }\n if (name.trim().length > 50) {\n return 'Project name must be less than 50 characters'\n }\n return true\n}\n\n/**\n * Validate slug format\n */\nfunction validateSlug(slug: string): string | true {\n if (!slug || slug.trim().length === 0) {\n return 'Slug is required'\n }\n if (!/^[a-z][a-z0-9-]*$/.test(slug)) {\n return 'Slug must start with a letter and contain only lowercase letters, numbers, and hyphens'\n }\n if (slug.length < 2) {\n return 'Slug must be at least 2 characters'\n }\n if (slug.length > 30) {\n return 'Slug must be less than 30 characters'\n }\n return true\n}\n\n/**\n * Run project info prompts\n */\nexport async function promptProjectInfo(): Promise<Pick<WizardConfig, 'projectName' | 'projectSlug' | 'projectDescription'>> {\n showSection('Project Information', 2, 10)\n\n // Get project name\n const projectName = await input({\n message: 'What is your project name?',\n default: 'My SaaS App',\n validate: validateProjectName,\n })\n\n // Get project slug (with auto-generated default)\n const suggestedSlug = toSlug(projectName)\n const projectSlug = await input({\n message: 'Project slug (used for theme folder and URLs):',\n default: suggestedSlug,\n validate: validateSlug,\n })\n\n // Get project description\n const projectDescription = await input({\n message: 'Short description of your project:',\n default: 'A modern SaaS application built with NextSpark',\n })\n\n return {\n projectName,\n projectSlug,\n projectDescription,\n }\n}\n","/**\n * Project Type Prompts (Step 1)\n *\n * Collects project type configuration (web only vs web + mobile).\n * This is the FIRST step so we know the folder structure early.\n */\n\nimport { select } from '@inquirer/prompts'\nimport { showSection, showInfo } from '../banner.js'\nimport type { WizardConfig, ProjectType } from '../types.js'\n\n/**\n * Project type options with descriptions\n */\nconst PROJECT_TYPE_OPTIONS = [\n {\n name: 'Web only',\n value: 'web' as ProjectType,\n description: 'Next.js web application with NextSpark. Standard flat project structure.',\n },\n {\n name: 'Web + Mobile',\n value: 'web-mobile' as ProjectType,\n description: 'Monorepo with Next.js web app and Expo mobile app sharing the same backend.',\n },\n]\n\n/**\n * Run project type prompt\n */\nexport async function promptProjectType(): Promise<Pick<WizardConfig, 'projectType'>> {\n showSection('Project Type', 1, 10)\n\n const projectType = await select({\n message: 'What type of project do you want to create?',\n choices: PROJECT_TYPE_OPTIONS,\n default: 'web',\n })\n\n // Show info about selected type\n const selectedOption = PROJECT_TYPE_OPTIONS.find(o => o.value === projectType)\n if (selectedOption) {\n showInfo(selectedOption.description)\n }\n\n if (projectType === 'web-mobile') {\n console.log('')\n showInfo('Your project will be a pnpm monorepo with web/ and mobile/ directories.')\n showInfo('The mobile app will use Expo and share the same backend API.')\n }\n\n return {\n projectType,\n }\n}\n\n/**\n * Get default project type (for quick mode or non-interactive)\n */\nexport function getDefaultProjectType(): ProjectType {\n return 'web'\n}\n","/**\n * Team Configuration Prompts (Step 3)\n *\n * Collects team mode and role configuration.\n */\n\nimport { select, checkbox } from '@inquirer/prompts'\nimport { showSection, showInfo } from '../banner.js'\nimport type { WizardConfig, TeamMode } from '../types.js'\nimport { DEFAULT_ROLES } from '../types.js'\n\n/**\n * Team mode options with descriptions\n */\nconst TEAM_MODE_OPTIONS = [\n {\n name: 'Multi-tenant (Multiple teams, team switching)',\n value: 'multi-tenant' as TeamMode,\n description: 'Users can create and join multiple teams. Perfect for CRM, project management, or collaboration tools.',\n },\n {\n name: 'Single-tenant (One organization, no switching)',\n value: 'single-tenant' as TeamMode,\n description: 'All users belong to one organization. Ideal for internal tools or company-specific applications.',\n },\n {\n name: 'Single-user (Personal app, no teams)',\n value: 'single-user' as TeamMode,\n description: 'Individual user accounts without team features. Perfect for personal dashboards or blogs.',\n },\n]\n\n/**\n * Role options with descriptions\n */\nconst ROLE_OPTIONS = [\n { name: 'Owner (Full control, can delete team)', value: 'owner', checked: true },\n { name: 'Admin (Can manage members and settings)', value: 'admin', checked: true },\n { name: 'Member (Standard access)', value: 'member', checked: true },\n { name: 'Viewer (Read-only access)', value: 'viewer', checked: true },\n]\n\n/**\n * Run team configuration prompts\n */\nexport async function promptTeamConfig(): Promise<Pick<WizardConfig, 'teamMode' | 'teamRoles'>> {\n showSection('Team Configuration', 3, 10)\n\n // Select team mode\n const teamMode = await select({\n message: 'What team mode do you need?',\n choices: TEAM_MODE_OPTIONS,\n default: 'multi-tenant',\n })\n\n // Show info about selected mode\n const selectedOption = TEAM_MODE_OPTIONS.find(o => o.value === teamMode)\n if (selectedOption) {\n showInfo(selectedOption.description)\n }\n\n // Only ask for roles if not single-user mode\n let teamRoles: string[] = DEFAULT_ROLES\n\n if (teamMode !== 'single-user') {\n console.log('')\n teamRoles = await checkbox({\n message: 'Which roles do you want to include?',\n choices: ROLE_OPTIONS,\n required: true,\n })\n\n // Ensure owner is always included\n if (!teamRoles.includes('owner')) {\n teamRoles = ['owner', ...teamRoles]\n showInfo('Owner role is required and has been added automatically.')\n }\n\n // Show info about custom roles\n console.log('')\n showInfo('You can add custom roles later by editing app.config.ts')\n }\n\n return {\n teamMode,\n teamRoles,\n }\n}\n","/**\n * NextSpark Wizard Types\n *\n * Shared type definitions for the wizard prompts and generators.\n */\n\n/**\n * Project type options (web only vs web + mobile monorepo)\n */\nexport type ProjectType = 'web' | 'web-mobile'\n\n/**\n * Team mode options for the project\n */\nexport type TeamMode = 'multi-tenant' | 'single-tenant' | 'single-user'\n\n/**\n * Billing model options\n */\nexport type BillingModel = 'free' | 'freemium' | 'paid'\n\n/**\n * CLI execution modes\n */\nexport type WizardMode = 'interactive' | 'quick' | 'expert'\n\n/**\n * Available presets\n */\nexport type PresetName = 'saas' | 'blog' | 'crm'\n\n/**\n * Available feature flags\n */\nexport interface FeatureFlags {\n analytics: boolean\n teams: boolean\n billing: boolean\n api: boolean\n docs: boolean\n}\n\n/**\n * Authentication configuration (Step 8)\n * Note: Only email/password and Google OAuth are currently supported\n */\nexport interface AuthConfig {\n emailPassword: boolean\n googleOAuth: boolean\n emailVerification: boolean\n}\n\n/**\n * Dashboard configuration (Step 9)\n */\nexport interface DashboardConfig {\n search: boolean\n notifications: boolean\n themeToggle: boolean\n support: boolean\n quickCreate: boolean\n superadminAccess: boolean\n devtoolsAccess: boolean\n sidebarCollapsed: boolean\n}\n\n/**\n * Content features configuration (Step 7)\n * Optional content types: Pages with Page Builder and Blog\n */\nexport interface ContentFeaturesConfig {\n pages: boolean // Enable pages with page builder\n blog: boolean // Enable blog with posts\n}\n\n/**\n * Development tools configuration (Step 10)\n */\nexport interface DevConfig {\n devKeyring: boolean\n debugMode: boolean\n}\n\n/**\n * Theme selection options for CLI\n */\nexport type ThemeOption = 'default' | 'blog' | 'crm' | 'productivity' | 'none'\n\n/**\n * Plugin selection options for CLI\n */\nexport type PluginOption = 'ai' | 'langchain' | 'social-media-publisher'\n\n/**\n * CLI options parsed from command line arguments\n */\nexport interface CLIOptions {\n mode: WizardMode\n preset?: PresetName\n // Non-interactive options\n theme?: ThemeOption\n plugins?: PluginOption[]\n yes?: boolean // Skip confirmations for automation\n // Project info for non-interactive mode\n name?: string\n slug?: string\n description?: string\n type?: ProjectType // Project type override for non-interactive mode\n}\n\n/**\n * Complete wizard configuration collected from all prompts\n */\nexport interface WizardConfig {\n // Step 1: Project Info\n projectName: string\n projectSlug: string\n projectDescription: string\n\n // Step 2: Project Type (web only or web + mobile monorepo)\n projectType: ProjectType\n\n // Step 3: Team Configuration\n teamMode: TeamMode\n teamRoles: string[]\n\n // Step 4: Internationalization\n defaultLocale: string\n supportedLocales: string[]\n\n // Step 5: Billing Configuration\n billingModel: BillingModel\n currency: string\n\n // Step 6: Features\n features: FeatureFlags\n\n // Step 7: Content Features\n contentFeatures: ContentFeaturesConfig\n\n // Step 8: Authentication\n auth: AuthConfig\n\n // Step 9: Dashboard\n dashboard: DashboardConfig\n\n // Step 10: Dev Tools\n dev: DevConfig\n}\n\n/**\n * Supported locales with their display names\n */\nexport const AVAILABLE_LOCALES: Record<string, string> = {\n en: 'English',\n es: 'Spanish',\n fr: 'French',\n de: 'German',\n it: 'Italian',\n pt: 'Portuguese',\n}\n\n/**\n * Default roles available in the system\n */\nexport const DEFAULT_ROLES = ['owner', 'admin', 'member', 'viewer']\n\n/**\n * Currency options\n */\nexport const CURRENCIES = [\n { value: 'usd', label: 'USD - US Dollar' },\n { value: 'eur', label: 'EUR - Euro' },\n { value: 'gbp', label: 'GBP - British Pound' },\n { value: 'cad', label: 'CAD - Canadian Dollar' },\n { value: 'aud', label: 'AUD - Australian Dollar' },\n { value: 'ars', label: 'ARS - Argentine Peso' },\n { value: 'brl', label: 'BRL - Brazilian Real' },\n { value: 'mxn', label: 'MXN - Mexican Peso' },\n]\n","/**\n * Internationalization Prompts (Step 4)\n *\n * Collects language and locale configuration.\n */\n\nimport { select, checkbox } from '@inquirer/prompts'\nimport { showSection, showInfo } from '../banner.js'\nimport type { WizardConfig } from '../types.js'\nimport { AVAILABLE_LOCALES } from '../types.js'\n\n/**\n * Locale options for selection\n */\nconst LOCALE_OPTIONS = Object.entries(AVAILABLE_LOCALES).map(([value, name]) => ({\n name: `${name} (${value})`,\n value,\n checked: value === 'en', // English selected by default\n}))\n\n/**\n * Run i18n configuration prompts\n */\nexport async function promptI18nConfig(): Promise<Pick<WizardConfig, 'defaultLocale' | 'supportedLocales'>> {\n showSection('Internationalization', 4, 10)\n\n // Select supported languages\n const supportedLocales = await checkbox({\n message: 'Which languages do you want to support?',\n choices: LOCALE_OPTIONS,\n required: true,\n })\n\n // Ensure at least one language is selected\n if (supportedLocales.length === 0) {\n showInfo('At least one language is required. English has been selected.')\n supportedLocales.push('en')\n }\n\n // Select default language from the selected ones\n let defaultLocale: string = 'en'\n\n if (supportedLocales.length === 1) {\n defaultLocale = supportedLocales[0]\n showInfo(`Default language set to ${AVAILABLE_LOCALES[defaultLocale]}`)\n } else {\n console.log('')\n defaultLocale = await select({\n message: 'Which should be the default language?',\n choices: supportedLocales.map(locale => ({\n name: `${AVAILABLE_LOCALES[locale]} (${locale})`,\n value: locale,\n })),\n default: supportedLocales.includes('en') ? 'en' : supportedLocales[0],\n })\n }\n\n return {\n defaultLocale,\n supportedLocales,\n }\n}\n","/**\n * Billing Configuration Prompts (Step 5)\n *\n * Collects billing model and payment configuration.\n */\n\nimport { select } from '@inquirer/prompts'\nimport { showSection, showInfo } from '../banner.js'\nimport type { WizardConfig, BillingModel } from '../types.js'\nimport { CURRENCIES } from '../types.js'\n\n/**\n * Billing model options with descriptions\n */\nconst BILLING_MODEL_OPTIONS = [\n {\n name: 'Free (No payments)',\n value: 'free' as BillingModel,\n description: 'All features are free. No payment processing needed.',\n },\n {\n name: 'Freemium (Free + Paid tiers)',\n value: 'freemium' as BillingModel,\n description: 'Free tier with optional paid upgrades (Free + Pro plans).',\n },\n {\n name: 'Paid (Subscription required)',\n value: 'paid' as BillingModel,\n description: 'Subscription-based access with optional trial period.',\n },\n]\n\n/**\n * Run billing configuration prompts\n */\nexport async function promptBillingConfig(): Promise<Pick<WizardConfig, 'billingModel' | 'currency'>> {\n showSection('Billing Configuration', 5, 10)\n\n // Select billing model\n const billingModel = await select({\n message: 'What billing model do you want to use?',\n choices: BILLING_MODEL_OPTIONS,\n default: 'freemium',\n })\n\n // Show info about selected model\n const selectedOption = BILLING_MODEL_OPTIONS.find(o => o.value === billingModel)\n if (selectedOption) {\n showInfo(selectedOption.description)\n }\n\n // Only ask for currency if not free\n let currency = 'usd'\n\n if (billingModel !== 'free') {\n console.log('')\n currency = await select({\n message: 'What currency will you use?',\n choices: CURRENCIES.map(c => ({\n name: c.label,\n value: c.value,\n })),\n default: 'usd',\n })\n }\n\n // Show info about customizing plans\n console.log('')\n showInfo('You can customize plans and pricing in billing.config.ts')\n\n return {\n billingModel,\n currency,\n }\n}\n","/**\n * Features Configuration Prompts (Step 6)\n *\n * Collects feature flags and optional modules.\n */\n\nimport { checkbox } from '@inquirer/prompts'\nimport { showSection, showInfo } from '../banner.js'\nimport type { WizardConfig, FeatureFlags } from '../types.js'\n\n/**\n * Feature options with descriptions\n */\nconst FEATURE_OPTIONS = [\n {\n name: 'Analytics Dashboard',\n value: 'analytics',\n description: 'Built-in analytics and metrics dashboard',\n checked: true,\n },\n {\n name: 'Team Management',\n value: 'teams',\n description: 'Team invitations, roles, and member management',\n checked: true,\n },\n {\n name: 'Billing & Subscriptions',\n value: 'billing',\n description: 'Stripe integration for payments and subscriptions',\n checked: true,\n },\n {\n name: 'API Access',\n value: 'api',\n description: 'REST API endpoints with authentication',\n checked: true,\n },\n {\n name: 'Documentation Site',\n value: 'docs',\n description: 'Built-in documentation system with markdown support',\n checked: false,\n },\n]\n\n/**\n * Run features configuration prompts\n */\nexport async function promptFeaturesConfig(): Promise<Pick<WizardConfig, 'features'>> {\n showSection('Features', 6, 10)\n\n showInfo('Select the features you want to include in your project.')\n showInfo('You can add or remove features later by editing your config files.')\n console.log('')\n\n // Select features\n const selectedFeatures = await checkbox({\n message: 'Which features do you want to enable?',\n choices: FEATURE_OPTIONS,\n })\n\n // Convert to feature flags object\n const features: FeatureFlags = {\n analytics: selectedFeatures.includes('analytics'),\n teams: selectedFeatures.includes('teams'),\n billing: selectedFeatures.includes('billing'),\n api: selectedFeatures.includes('api'),\n docs: selectedFeatures.includes('docs'),\n }\n\n return {\n features,\n }\n}\n","/**\n * Content Features Configuration Prompts (Step 7)\n *\n * Collects optional content features: Pages with Page Builder and Blog.\n */\n\nimport { checkbox } from '@inquirer/prompts'\nimport { showSection, showInfo } from '../banner.js'\nimport type { WizardConfig, ContentFeaturesConfig, WizardMode } from '../types.js'\n\n/**\n * Content feature options with descriptions\n */\nconst CONTENT_FEATURE_OPTIONS = [\n {\n name: 'Pages with Page Builder',\n value: 'pages',\n description: \"Adds the 'page' entity with full page builder support. Build custom pages using blocks.\",\n checked: false,\n },\n {\n name: 'Blog',\n value: 'blog',\n description: \"Adds the 'post' entity for blog articles with the Post Content block for rich editorial content.\",\n checked: false,\n },\n]\n\n/**\n * Get default content features configuration\n */\nexport function getDefaultContentFeaturesConfig(): ContentFeaturesConfig {\n return {\n pages: false,\n blog: false,\n }\n}\n\n/**\n * Run content features configuration prompts\n */\nexport async function promptContentFeaturesConfig(\n mode: WizardMode = 'interactive',\n totalSteps: number = 9\n): Promise<Pick<WizardConfig, 'contentFeatures'>> {\n showSection('Content Features', 7, totalSteps)\n\n showInfo('Enable optional content features for your project.')\n showInfo('These features add entities and blocks for building pages and blog posts.')\n console.log('')\n\n // Select content features\n const selectedFeatures = await checkbox({\n message: 'Which content features do you want to enable?',\n choices: CONTENT_FEATURE_OPTIONS,\n })\n\n console.log('')\n showInfo('You can add more blocks later in contents/themes/[your-theme]/blocks/')\n\n // Convert to content features config object\n const contentFeatures: ContentFeaturesConfig = {\n pages: selectedFeatures.includes('pages'),\n blog: selectedFeatures.includes('blog'),\n }\n\n return {\n contentFeatures,\n }\n}\n","/**\n * Authentication Configuration Prompts (Step 8)\n *\n * Collects authentication method preferences and security settings.\n * Currently supports: Email/Password and Google OAuth\n */\n\nimport { checkbox } from '@inquirer/prompts'\nimport { showSection, showInfo } from '../banner.js'\nimport type { WizardConfig, AuthConfig, WizardMode } from '../types.js'\n\n/**\n * Authentication method options\n * Note: Only email/password and Google OAuth are currently implemented\n */\nconst AUTH_METHOD_OPTIONS = [\n {\n name: 'Email & Password',\n value: 'emailPassword',\n description: 'Traditional email and password authentication',\n checked: true,\n },\n {\n name: 'Google OAuth',\n value: 'googleOAuth',\n description: 'Sign in with Google accounts',\n checked: false,\n },\n]\n\n/**\n * Security feature options\n */\nconst SECURITY_OPTIONS = [\n {\n name: 'Email Verification',\n value: 'emailVerification',\n description: 'Require users to verify their email address',\n checked: true,\n },\n]\n\n/**\n * Get default auth configuration\n */\nexport function getDefaultAuthConfig(): AuthConfig {\n return {\n emailPassword: true,\n googleOAuth: false,\n emailVerification: true,\n }\n}\n\n/**\n * Run authentication configuration prompts\n */\nexport async function promptAuthConfig(\n mode: WizardMode = 'interactive',\n totalSteps: number = 8\n): Promise<Pick<WizardConfig, 'auth'>> {\n showSection('Authentication', 8, totalSteps)\n\n showInfo('Configure how users will authenticate to your application.')\n console.log('')\n\n // Select authentication methods\n const selectedMethods = await checkbox({\n message: 'Which authentication methods do you want to enable?',\n choices: AUTH_METHOD_OPTIONS,\n })\n\n // In expert mode, also ask about security features\n let selectedSecurity: string[] = ['emailVerification']\n\n if (mode === 'expert') {\n console.log('')\n showInfo('Configure additional security features.')\n console.log('')\n\n selectedSecurity = await checkbox({\n message: 'Which security features do you want to enable?',\n choices: SECURITY_OPTIONS,\n })\n }\n\n const auth: AuthConfig = {\n emailPassword: selectedMethods.includes('emailPassword'),\n googleOAuth: selectedMethods.includes('googleOAuth'),\n emailVerification: selectedSecurity.includes('emailVerification'),\n }\n\n return { auth }\n}\n","/**\n * Dashboard Configuration Prompts (Step 9)\n *\n * Collects dashboard UI preferences and layout options.\n */\n\nimport { checkbox, confirm } from '@inquirer/prompts'\nimport { showSection, showInfo } from '../banner.js'\nimport type { WizardConfig, DashboardConfig, WizardMode } from '../types.js'\n\n/**\n * Dashboard feature options\n */\nconst DASHBOARD_FEATURE_OPTIONS = [\n {\n name: 'Global Search',\n value: 'search',\n description: 'Search across your application from the dashboard',\n checked: false,\n },\n {\n name: 'Notifications',\n value: 'notifications',\n description: 'In-app notification system with bell icon',\n checked: false,\n },\n {\n name: 'Theme Toggle',\n value: 'themeToggle',\n description: 'Allow users to switch between light and dark themes',\n checked: true,\n },\n {\n name: 'Support/Help Menu',\n value: 'support',\n description: 'Help dropdown with documentation and support links',\n checked: true,\n },\n {\n name: 'Quick Create',\n value: 'quickCreate',\n description: 'Quick create button for creating new entities',\n checked: true,\n },\n {\n name: 'Superadmin Access',\n value: 'superadminAccess',\n description: 'Button to access superadmin area (only visible to superadmins)',\n checked: true,\n },\n {\n name: 'DevTools Access',\n value: 'devtoolsAccess',\n description: 'Button to access developer tools (only visible to developers)',\n checked: true,\n },\n]\n\n/**\n * Get default dashboard configuration\n */\nexport function getDefaultDashboardConfig(): DashboardConfig {\n return {\n search: false,\n notifications: false,\n themeToggle: true,\n support: true,\n quickCreate: true,\n superadminAccess: true,\n devtoolsAccess: true,\n sidebarCollapsed: false,\n }\n}\n\n/**\n * Run dashboard configuration prompts\n */\nexport async function promptDashboardConfig(\n mode: WizardMode = 'interactive',\n totalSteps: number = 8\n): Promise<Pick<WizardConfig, 'dashboard'>> {\n showSection('Dashboard', 9, totalSteps)\n\n showInfo('Configure your dashboard user interface.')\n showInfo('These settings can be changed later in your theme config.')\n console.log('')\n\n // Select dashboard features\n const selectedFeatures = await checkbox({\n message: 'Which dashboard features do you want to enable?',\n choices: DASHBOARD_FEATURE_OPTIONS,\n })\n\n // In expert mode, ask about sidebar default state\n let sidebarCollapsed = false\n\n if (mode === 'expert') {\n console.log('')\n sidebarCollapsed = await confirm({\n message: 'Start with sidebar collapsed by default?',\n default: false,\n })\n }\n\n const dashboard: DashboardConfig = {\n search: selectedFeatures.includes('search'),\n notifications: selectedFeatures.includes('notifications'),\n themeToggle: selectedFeatures.includes('themeToggle'),\n support: selectedFeatures.includes('support'),\n quickCreate: selectedFeatures.includes('quickCreate'),\n superadminAccess: selectedFeatures.includes('superadminAccess'),\n devtoolsAccess: selectedFeatures.includes('devtoolsAccess'),\n sidebarCollapsed,\n }\n\n return { dashboard }\n}\n","/**\n * Development Tools Configuration Prompts (Step 10)\n *\n * Collects development and debugging preferences.\n */\n\nimport { checkbox, confirm } from '@inquirer/prompts'\nimport { showSection, showInfo, showWarning } from '../banner.js'\nimport type { WizardConfig, DevConfig, WizardMode } from '../types.js'\n\n/**\n * Development tool options\n */\nconst DEV_TOOL_OPTIONS = [\n {\n name: 'Dev Keyring',\n value: 'devKeyring',\n description: 'Quick login as different users during development',\n checked: true,\n },\n {\n name: 'Debug Mode',\n value: 'debugMode',\n description: 'Enable verbose logging and debugging tools',\n checked: false,\n },\n]\n\n/**\n * Get default dev configuration\n */\nexport function getDefaultDevConfig(): DevConfig {\n return {\n devKeyring: true,\n debugMode: false,\n }\n}\n\n/**\n * Run development tools configuration prompts\n */\nexport async function promptDevConfig(\n mode: WizardMode = 'interactive',\n totalSteps: number = 8\n): Promise<Pick<WizardConfig, 'dev'>> {\n showSection('Development Tools', 10, totalSteps)\n\n showInfo('Configure development and debugging tools.')\n showWarning('These tools are disabled in production builds.')\n console.log('')\n\n let devKeyring = true\n let debugMode = false\n\n if (mode === 'expert') {\n // Expert mode: show all options\n const selectedTools = await checkbox({\n message: 'Which development tools do you want to enable?',\n choices: DEV_TOOL_OPTIONS,\n })\n\n devKeyring = selectedTools.includes('devKeyring')\n debugMode = selectedTools.includes('debugMode')\n } else {\n // Interactive mode: just ask about dev keyring\n devKeyring = await confirm({\n message: 'Enable dev keyring for quick user switching during development?',\n default: true,\n })\n }\n\n const dev: DevConfig = {\n devKeyring,\n debugMode,\n }\n\n return { dev }\n}\n","/**\n * Theme Selection Prompt\n *\n * Asks the user which reference theme they want to install.\n * The reference theme provides a complete example to learn from,\n * while the user's custom theme (based on starter) is the active theme.\n */\n\nimport { select } from '@inquirer/prompts'\nimport chalk from 'chalk'\n\nexport type ThemeChoice = 'default' | 'blog' | 'crm' | 'productivity' | null\n\n/**\n * Prompt the user to select a reference theme\n */\nexport async function promptThemeSelection(): Promise<ThemeChoice> {\n console.log('')\n console.log(chalk.cyan(' Reference Theme Installation'))\n console.log(chalk.gray(' ' + '-'.repeat(40)))\n console.log('')\n console.log(chalk.gray(' A reference theme provides a complete example to learn from.'))\n console.log(chalk.gray(' Your custom theme (based on starter) will be your active theme.'))\n console.log('')\n\n const theme = await select<ThemeChoice>({\n message: 'Which reference theme would you like to install?',\n choices: [\n {\n name: 'None (skip)',\n value: null,\n description: 'Only my custom theme, no reference (add later with add:theme)',\n },\n {\n name: 'Default (SaaS boilerplate)',\n value: 'default',\n description: 'Full-featured SaaS with dashboard, billing, AI chat',\n },\n {\n name: 'Blog',\n value: 'blog',\n description: 'Content management and publishing platform',\n },\n {\n name: 'CRM',\n value: 'crm',\n description: 'Customer relationship management',\n },\n {\n name: 'Productivity',\n value: 'productivity',\n description: 'Tasks, projects, and calendar management',\n },\n ],\n default: null,\n })\n\n return theme\n}\n","/**\n * Plugins Selection Prompt\n *\n * Asks the user which additional plugins they want to install.\n * Some plugins may be required by the selected theme and will be pre-selected.\n */\n\nimport { checkbox } from '@inquirer/prompts'\nimport chalk from 'chalk'\nimport type { ThemeChoice } from './theme-selection.js'\n\nexport type PluginChoice = 'ai' | 'langchain' | 'social-media-publisher'\n\n/**\n * Plugins required by each theme\n * These will be pre-selected and marked as required\n */\nconst THEME_REQUIRED_PLUGINS: Record<string, PluginChoice[]> = {\n 'default': ['langchain'],\n 'blog': [],\n 'crm': [],\n 'productivity': [],\n}\n\n/**\n * Prompt the user to select additional plugins\n *\n * @param selectedTheme - The theme selected by the user (to show required plugins)\n * @returns Array of selected plugin choices\n */\nexport async function promptPluginsSelection(\n selectedTheme: ThemeChoice\n): Promise<PluginChoice[]> {\n const requiredPlugins = selectedTheme\n ? THEME_REQUIRED_PLUGINS[selectedTheme] || []\n : []\n\n console.log('')\n console.log(chalk.cyan(' Plugin Selection'))\n console.log(chalk.gray(' ' + '-'.repeat(40)))\n\n if (requiredPlugins.length > 0) {\n console.log('')\n console.log(chalk.gray(` Note: ${requiredPlugins.join(', ')} will be installed (required by theme)`))\n }\n console.log('')\n\n const plugins = await checkbox<PluginChoice>({\n message: 'Select plugins to install (Enter to skip, Space to select):',\n choices: [\n {\n name: 'AI',\n value: 'ai',\n description: 'AI SDK with OpenAI, Anthropic, Ollama support',\n checked: false,\n },\n {\n name: 'LangChain',\n value: 'langchain',\n description: 'AI agents, chains, and advanced AI features',\n checked: requiredPlugins.includes('langchain'),\n disabled: requiredPlugins.includes('langchain') ? '(required by theme)' : false,\n },\n {\n name: 'Social Media Publisher',\n value: 'social-media-publisher',\n description: 'Multi-platform social media publishing',\n checked: false,\n },\n ],\n })\n\n // Merge with required plugins (ensure no duplicates)\n const allPlugins = [...new Set([...requiredPlugins, ...plugins])]\n return allPlugins\n}\n\n/**\n * Get the list of required plugins for a theme\n */\nexport function getRequiredPlugins(theme: ThemeChoice): PluginChoice[] {\n if (!theme) return []\n return THEME_REQUIRED_PLUGINS[theme] || []\n}\n","/**\n * Environment Configuration Prompts\n *\n * Collects environment setup preferences for the project.\n */\n\nimport { confirm, input } from '@inquirer/prompts'\nimport { showSection, showInfo } from '../banner.js'\n\n/**\n * Environment setup answers from prompts\n */\nexport interface EnvSetupAnswers {\n setupEnv: boolean\n generateSecrets: boolean\n databaseUrl?: string\n}\n\n/**\n * Get default environment setup answers\n */\nexport function getDefaultEnvSetupAnswers(): EnvSetupAnswers {\n return {\n setupEnv: true,\n generateSecrets: true,\n databaseUrl: undefined,\n }\n}\n\n/**\n * Run environment configuration prompts\n */\nexport async function promptEnvSetup(): Promise<EnvSetupAnswers> {\n showSection('Environment Setup', 9, 9)\n\n showInfo('Configure your environment variables.')\n showInfo('This will create a .env file based on .env.example.')\n console.log('')\n\n // Ask if user wants to set up .env\n const setupEnv = await confirm({\n message: 'Would you like to configure .env file?',\n default: true,\n })\n\n if (!setupEnv) {\n return {\n setupEnv: false,\n generateSecrets: false,\n databaseUrl: undefined,\n }\n }\n\n console.log('')\n\n // Ask if user wants to generate secrets\n const generateSecrets = await confirm({\n message: 'Generate secure BETTER_AUTH_SECRET automatically?',\n default: true,\n })\n\n console.log('')\n\n // Ask for database URL (optional)\n const databaseUrl = await input({\n message: 'Enter DATABASE_URL (leave empty to use default):',\n default: '',\n validate: (value) => {\n if (value === '') return true\n // Basic validation for postgres URL format\n if (value.startsWith('postgresql://') || value.startsWith('postgres://')) {\n return true\n }\n return 'Please enter a valid PostgreSQL connection string (postgresql://...)'\n },\n })\n\n return {\n setupEnv,\n generateSecrets,\n databaseUrl: databaseUrl || undefined,\n }\n}\n","/**\n * Git Configuration Prompts\n *\n * Collects Git initialization and commit preferences.\n */\n\nimport { confirm, input } from '@inquirer/prompts'\nimport { showSection } from '../banner.js'\n\n/**\n * Git setup answers from user prompts\n */\nexport interface GitSetupAnswers {\n initGit: boolean\n createCommit: boolean\n commitMessage?: string\n}\n\n/**\n * Validate commit message\n */\nfunction validateCommitMessage(message: string): string | true {\n if (!message || message.trim().length === 0) {\n return 'Commit message is required'\n }\n if (message.trim().length < 5) {\n return 'Commit message must be at least 5 characters'\n }\n if (message.trim().length > 100) {\n return 'Commit message must be less than 100 characters'\n }\n return true\n}\n\n/**\n * Get default git setup answers (for quick mode)\n */\nexport function getDefaultGitSetupAnswers(): GitSetupAnswers {\n return {\n initGit: true,\n createCommit: true,\n commitMessage: 'Initial commit: NextSpark project setup',\n }\n}\n\n/**\n * Run git configuration prompts\n */\nexport async function promptGitSetup(): Promise<GitSetupAnswers> {\n showSection('Git Configuration', 9, 9)\n\n // Ask if user wants to initialize git\n const initGit = await confirm({\n message: 'Initialize a Git repository?',\n default: true,\n })\n\n if (!initGit) {\n return {\n initGit: false,\n createCommit: false,\n }\n }\n\n // Ask if user wants to create initial commit\n const createCommit = await confirm({\n message: 'Create an initial commit?',\n default: true,\n })\n\n if (!createCommit) {\n return {\n initGit: true,\n createCommit: false,\n }\n }\n\n // Get commit message\n const commitMessage = await input({\n message: 'Commit message:',\n default: 'Initial commit: NextSpark project setup',\n validate: validateCommitMessage,\n })\n\n return {\n initGit,\n createCommit,\n commitMessage,\n }\n}\n","/**\n * Prompts Index\n *\n * Exports all prompts and provides functions to run prompts in sequence.\n * Supports different modes: interactive (all 10 steps), quick (all 10 steps), expert (all with extra options).\n */\n\nimport type { WizardConfig } from '../types.js'\nimport { promptProjectInfo } from './project-info.js'\nimport { promptProjectType, getDefaultProjectType } from './project-type.js'\nimport { promptTeamConfig } from './team-config.js'\nimport { promptI18nConfig } from './i18n-config.js'\nimport { promptBillingConfig } from './billing-config.js'\nimport { promptFeaturesConfig } from './features-config.js'\nimport { promptContentFeaturesConfig, getDefaultContentFeaturesConfig } from './content-features-config.js'\nimport { promptAuthConfig, getDefaultAuthConfig } from './auth-config.js'\nimport { promptDashboardConfig, getDefaultDashboardConfig } from './dashboard-config.js'\nimport { promptDevConfig, getDefaultDevConfig } from './dev-config.js'\n// Theme & Plugin Selection\nimport { promptThemeSelection, type ThemeChoice } from './theme-selection.js'\nimport { promptPluginsSelection, getRequiredPlugins, type PluginChoice } from './plugins-selection.js'\n// DX improvement prompts\nimport { promptEnvSetup, getDefaultEnvSetupAnswers, type EnvSetupAnswers } from './env-config.js'\nimport { promptGitSetup, getDefaultGitSetupAnswers, type GitSetupAnswers } from './git-config.js'\n\nexport {\n promptProjectInfo,\n promptProjectType,\n getDefaultProjectType,\n promptTeamConfig,\n promptI18nConfig,\n promptBillingConfig,\n promptFeaturesConfig,\n promptContentFeaturesConfig,\n getDefaultContentFeaturesConfig,\n promptAuthConfig,\n promptDashboardConfig,\n promptDevConfig,\n // Theme & Plugin Selection\n promptThemeSelection,\n promptPluginsSelection,\n getRequiredPlugins,\n // DX prompts\n promptEnvSetup,\n getDefaultEnvSetupAnswers,\n promptGitSetup,\n getDefaultGitSetupAnswers,\n}\n\nexport type { EnvSetupAnswers, GitSetupAnswers, ThemeChoice, PluginChoice }\n\n/**\n * Run all prompts in sequence (interactive mode - 10 steps)\n */\nexport async function runAllPrompts(): Promise<WizardConfig> {\n // Step 1: Project Type (web only or web + mobile) - FIRST to determine folder structure\n const projectTypeConfig = await promptProjectType()\n\n // Step 2: Project Info (name, slug, description)\n const projectInfo = await promptProjectInfo()\n\n // Step 3: Team Configuration\n const teamConfig = await promptTeamConfig()\n\n // Step 4: i18n Configuration\n const i18nConfig = await promptI18nConfig()\n\n // Step 5: Billing Configuration\n const billingConfig = await promptBillingConfig()\n\n // Step 6: Features Configuration\n const featuresConfig = await promptFeaturesConfig()\n\n // Step 7: Content Features Configuration\n const contentFeaturesConfig = await promptContentFeaturesConfig('interactive', 10)\n\n // Step 8: Authentication Configuration\n const authConfig = await promptAuthConfig('interactive', 10)\n\n // Step 9: Dashboard Configuration\n const dashboardConfig = await promptDashboardConfig('interactive', 10)\n\n // Step 10: Dev Tools Configuration\n const devConfig = await promptDevConfig('interactive', 10)\n\n // Combine all configurations\n return {\n ...projectInfo,\n ...projectTypeConfig,\n ...teamConfig,\n ...i18nConfig,\n ...billingConfig,\n ...featuresConfig,\n ...contentFeaturesConfig,\n ...authConfig,\n ...dashboardConfig,\n ...devConfig,\n }\n}\n\n/**\n * Run quick prompts (steps 1-7) with defaults for steps 8-10\n */\nexport async function runQuickPrompts(): Promise<WizardConfig> {\n // Step 1: Project Type (web only or web + mobile) - FIRST to determine folder structure\n const projectTypeConfig = await promptProjectType()\n\n // Step 2: Project Info (name, slug, description)\n const projectInfo = await promptProjectInfo()\n\n // Step 3: Team Configuration\n const teamConfig = await promptTeamConfig()\n\n // Step 4: i18n Configuration\n const i18nConfig = await promptI18nConfig()\n\n // Step 5: Billing Configuration\n const billingConfig = await promptBillingConfig()\n\n // Step 6: Features Configuration\n const featuresConfig = await promptFeaturesConfig()\n\n // Step 7: Content Features Configuration (shown in all modes)\n const contentFeaturesConfig = await promptContentFeaturesConfig('quick', 10)\n\n // Use defaults for steps 8-10\n const authConfig = { auth: getDefaultAuthConfig() }\n const dashboardConfig = { dashboard: getDefaultDashboardConfig() }\n const devConfig = { dev: getDefaultDevConfig() }\n\n // Combine all configurations\n return {\n ...projectInfo,\n ...projectTypeConfig,\n ...teamConfig,\n ...i18nConfig,\n ...billingConfig,\n ...featuresConfig,\n ...contentFeaturesConfig,\n ...authConfig,\n ...dashboardConfig,\n ...devConfig,\n }\n}\n\n/**\n * Run all prompts with expert options (all 10 steps with advanced settings)\n */\nexport async function runExpertPrompts(): Promise<WizardConfig> {\n // Step 1: Project Type (web only or web + mobile) - FIRST to determine folder structure\n const projectTypeConfig = await promptProjectType()\n\n // Step 2: Project Info (name, slug, description)\n const projectInfo = await promptProjectInfo()\n\n // Step 3: Team Configuration\n const teamConfig = await promptTeamConfig()\n\n // Step 4: i18n Configuration\n const i18nConfig = await promptI18nConfig()\n\n // Step 5: Billing Configuration\n const billingConfig = await promptBillingConfig()\n\n // Step 6: Features Configuration\n const featuresConfig = await promptFeaturesConfig()\n\n // Step 7: Content Features Configuration\n const contentFeaturesConfig = await promptContentFeaturesConfig('expert', 10)\n\n // Step 8: Authentication Configuration (expert mode)\n const authConfig = await promptAuthConfig('expert', 10)\n\n // Step 9: Dashboard Configuration (expert mode)\n const dashboardConfig = await promptDashboardConfig('expert', 10)\n\n // Step 10: Dev Tools Configuration (expert mode)\n const devConfig = await promptDevConfig('expert', 10)\n\n // Combine all configurations\n return {\n ...projectInfo,\n ...projectTypeConfig,\n ...teamConfig,\n ...i18nConfig,\n ...billingConfig,\n ...featuresConfig,\n ...contentFeaturesConfig,\n ...authConfig,\n ...dashboardConfig,\n ...devConfig,\n }\n}\n","/**\n * Generators Index\n *\n * Orchestrates all generators to create the complete project.\n * Supports both flat (web-only) and monorepo (web+mobile) structures.\n */\n\nimport fs from 'fs-extra'\nimport path from 'path'\nimport { fileURLToPath } from 'url'\nimport type { WizardConfig } from '../types.js'\nimport {\n copyStarterTheme,\n updateThemeConfig,\n updateDevConfig,\n updateAppConfig,\n updateBillingConfig,\n updateMigrations,\n updateRolesConfig,\n updateTestFiles,\n} from './theme-renamer.js'\nimport {\n updatePermissionsConfig,\n updateEntityPermissions,\n updateDashboardConfig,\n generateEnvExample,\n updateReadme,\n updateAuthConfig,\n updateDashboardUIConfig,\n updateDevToolsConfig,\n copyEnvExampleToEnv,\n updateGlobalsCss,\n} from './config-generator.js'\nimport { processI18n } from './messages-generator.js'\nimport { copyContentFeatures } from './content-features-generator.js'\n// Theme & Plugin installation\nimport { installThemeAndPlugins } from './theme-plugins-installer.js'\n// DX improvement generators\nimport { setupEnvironment } from './env-setup.js'\nimport { setupGit } from './git-init.js'\n// Monorepo generator\nimport { generateMonorepoStructure, isMonorepoProject, getWebDir } from './monorepo-generator.js'\n\nconst __filename = fileURLToPath(import.meta.url)\nconst __dirname = path.dirname(__filename)\n\nexport {\n copyStarterTheme,\n updateThemeConfig,\n updateDevConfig,\n updateAppConfig,\n updateBillingConfig,\n updateMigrations,\n updateRolesConfig,\n updateTestFiles,\n updatePermissionsConfig,\n updateEntityPermissions,\n updateDashboardConfig,\n generateEnvExample,\n updateReadme,\n processI18n,\n updateAuthConfig,\n updateDashboardUIConfig,\n updateDevToolsConfig,\n copyContentFeatures,\n copyEnvExampleToEnv,\n updateGlobalsCss,\n // Theme & Plugin installation\n installThemeAndPlugins,\n // DX generators\n setupEnvironment,\n setupGit,\n // Monorepo generators\n generateMonorepoStructure,\n isMonorepoProject,\n getWebDir,\n}\n\n/**\n * Get the templates directory path from @nextsparkjs/core\n * @param projectRoot - The original project root directory (important for monorepo where CWD may change)\n */\nfunction getTemplatesDir(projectRoot?: string): string {\n const rootDir = projectRoot || process.cwd()\n\n // Check multiple possible paths for templates directory\n // Priority: installed package in node_modules > development monorepo paths\n const possiblePaths = [\n // From project root node_modules (most common for installed packages)\n path.resolve(rootDir, 'node_modules/@nextsparkjs/core/templates'),\n // From CLI dist folder for development\n path.resolve(__dirname, '../../core/templates'),\n // Legacy paths for different build structures\n path.resolve(__dirname, '../../../../../core/templates'),\n path.resolve(__dirname, '../../../../core/templates'),\n ];\n\n for (const p of possiblePaths) {\n if (fs.existsSync(p)) {\n return p;\n }\n }\n\n throw new Error(`Could not find @nextsparkjs/core templates directory. Searched: ${possiblePaths.join(', ')}`);\n}\n\n// Cache the templates directory to avoid recalculating after chdir\nlet cachedTemplatesDir: string | null = null;\n\n/**\n * Copy core project files (app/, public/, config files)\n * Uses cached templates directory to work correctly after chdir\n */\nasync function copyProjectFiles(): Promise<void> {\n if (!cachedTemplatesDir) {\n throw new Error('Templates directory not cached. Call cacheTemplatesDir() first.')\n }\n const templatesDir = cachedTemplatesDir\n const projectDir = process.cwd()\n\n // Files and directories to copy\n const itemsToCopy = [\n { src: 'app', dest: 'app', force: true },\n { src: 'public', dest: 'public', force: true },\n { src: 'proxy.ts', dest: 'proxy.ts', force: true }, // Next.js 16+ proxy (formerly middleware.ts)\n { src: 'next.config.mjs', dest: 'next.config.mjs', force: true },\n { src: 'tsconfig.json', dest: 'tsconfig.json', force: true },\n { src: 'postcss.config.mjs', dest: 'postcss.config.mjs', force: true },\n { src: 'i18n.ts', dest: 'i18n.ts', force: true },\n { src: 'pnpm-workspace.yaml', dest: 'pnpm-workspace.yaml', force: true }, // Enable workspace for themes/plugins - REQUIRED\n // Note: .npmrc is NOT copied for web-only projects (not needed, pnpm default hoisting works fine)\n // For monorepo projects, monorepo-generator.ts creates a specific .npmrc with expo/react-native patterns\n { src: 'tsconfig.cypress.json', dest: 'tsconfig.cypress.json', force: false },\n { src: 'cypress.d.ts', dest: 'cypress.d.ts', force: false },\n { src: 'eslint.config.mjs', dest: 'eslint.config.mjs', force: false },\n { src: 'scripts/cy-run-prod.cjs', dest: 'scripts/cy-run-prod.cjs', force: false },\n ]\n\n for (const item of itemsToCopy) {\n const srcPath = path.join(templatesDir, item.src)\n const destPath = path.join(projectDir, item.dest)\n\n if (await fs.pathExists(srcPath)) {\n if (item.force || !await fs.pathExists(destPath)) {\n await fs.copy(srcPath, destPath)\n }\n }\n }\n}\n\n/**\n * Update or create package.json with required scripts and dependencies\n */\nasync function updatePackageJson(config: WizardConfig): Promise<void> {\n const packageJsonPath = path.resolve(process.cwd(), 'package.json')\n\n // Create package.json if it doesn't exist\n let packageJson: {\n name?: string\n version?: string\n private?: boolean\n scripts?: Record<string, string>\n dependencies?: Record<string, string>\n devDependencies?: Record<string, string>\n }\n if (!await fs.pathExists(packageJsonPath)) {\n packageJson = {\n name: isMonorepoProject(config) ? 'web' : config.projectSlug,\n version: '0.1.0',\n private: true,\n scripts: {},\n dependencies: {},\n devDependencies: {},\n }\n } else {\n packageJson = await fs.readJson(packageJsonPath)\n }\n\n // Ensure scripts object exists\n packageJson.scripts = packageJson.scripts || {}\n\n // Add NextSpark scripts (using CLI commands where possible)\n const scriptsToAdd: Record<string, string> = {\n 'dev': 'nextspark dev',\n 'build': 'nextspark build',\n 'start': 'next start',\n 'lint': 'next lint',\n 'build:registries': 'nextspark registry:build',\n 'db:migrate': 'nextspark db:migrate',\n 'db:seed': 'nextspark db:seed',\n 'test': 'node node_modules/@nextsparkjs/core/scripts/test/jest-theme.mjs',\n 'cy:open': 'node node_modules/@nextsparkjs/core/scripts/test/cy.mjs open',\n 'cy:run': 'node node_modules/@nextsparkjs/core/scripts/test/cy.mjs run',\n 'cy:tags': 'node node_modules/@nextsparkjs/core/scripts/test/cy.mjs tags',\n 'cy:run:prod': 'node scripts/cy-run-prod.cjs',\n 'allure:generate': `allure generate contents/themes/${config.projectSlug}/tests/cypress/allure-results --clean -o contents/themes/${config.projectSlug}/tests/cypress/allure-report`,\n 'allure:open': `allure open contents/themes/${config.projectSlug}/tests/cypress/allure-report`,\n }\n\n for (const [name, command] of Object.entries(scriptsToAdd)) {\n if (!packageJson.scripts[name]) {\n packageJson.scripts[name] = command\n }\n }\n\n // Ensure dependencies object exists\n packageJson.dependencies = packageJson.dependencies || {}\n\n // Core dependencies (required for Next.js + NextSpark)\n const depsToAdd: Record<string, string> = {\n // NextSpark\n '@nextsparkjs/core': 'latest',\n '@nextsparkjs/cli': 'latest',\n // Next.js + React\n 'next': '^15.1.0',\n 'react': '^19.0.0',\n 'react-dom': '^19.0.0',\n // Auth\n 'better-auth': '^1.4.0',\n // i18n\n 'next-intl': '^4.0.2',\n // Database\n 'drizzle-orm': '^0.41.0',\n 'postgres': '^3.4.5',\n // State & Data\n '@tanstack/react-query': '^5.64.2',\n // Forms & Validation\n 'zod': '^4.1.5',\n 'react-hook-form': '^7.54.2',\n '@hookform/resolvers': '^5.0.1',\n // UI\n 'tailwindcss': '^4.0.0',\n 'class-variance-authority': '^0.7.1',\n 'clsx': '^2.1.1',\n 'tailwind-merge': '^2.6.0',\n 'lucide-react': '^0.469.0',\n 'sonner': '^1.7.4',\n // Utilities\n 'date-fns': '^4.1.0',\n 'nanoid': '^5.0.9',\n 'slugify': '^1.6.6',\n }\n\n for (const [name, version] of Object.entries(depsToAdd)) {\n // Always set our core packages to 'latest' for consistency\n // pnpm may have resolved to specific versions during initial install,\n // but we want package.json to use 'latest' semantic versioning\n if (name.startsWith('@nextsparkjs/')) {\n packageJson.dependencies[name] = version\n } else if (!packageJson.dependencies[name]) {\n packageJson.dependencies[name] = version\n }\n }\n\n // Ensure devDependencies object exists\n packageJson.devDependencies = packageJson.devDependencies || {}\n\n // Dev dependencies\n const devDepsToAdd: Record<string, string> = {\n // TypeScript\n 'typescript': '^5.7.3',\n '@types/node': '^22.10.7',\n '@types/react': '^19.0.7',\n '@types/react-dom': '^19.0.3',\n // Tailwind\n '@tailwindcss/postcss': '^4.0.0',\n // ESLint\n 'eslint': '^9.18.0',\n 'eslint-config-next': '^15.1.0',\n '@eslint/eslintrc': '^3.2.0',\n // Database\n 'drizzle-kit': '^0.31.4',\n // Jest\n 'jest': '^29.7.0',\n 'ts-jest': '^29.2.5',\n 'ts-node': '^10.9.2',\n '@types/jest': '^29.5.14',\n '@testing-library/jest-dom': '^6.6.3',\n '@testing-library/react': '^16.3.0',\n 'jest-environment-jsdom': '^29.7.0',\n // Cypress\n 'cypress': '^15.8.2',\n '@testing-library/cypress': '^10.0.2',\n '@cypress/webpack-preprocessor': '^6.0.2',\n '@cypress/grep': '^5.0.1',\n 'ts-loader': '^9.5.1',\n 'webpack': '^5.97.0',\n 'allure-cypress': '^3.0.0',\n 'allure-commandline': '^2.27.0',\n // NextSpark Testing\n '@nextsparkjs/testing': 'latest',\n }\n\n for (const [name, version] of Object.entries(devDepsToAdd)) {\n // Always set our core packages to 'latest' for consistency\n if (name.startsWith('@nextsparkjs/')) {\n packageJson.devDependencies[name] = version\n } else if (!packageJson.devDependencies[name]) {\n packageJson.devDependencies[name] = version\n }\n }\n\n await fs.writeJson(packageJsonPath, packageJson, { spaces: 2 })\n}\n\n/**\n * Update .gitignore with NextSpark entries\n */\nasync function updateGitignore(config: WizardConfig): Promise<void> {\n const gitignorePath = path.resolve(process.cwd(), '.gitignore')\n\n const entriesToAdd = `\n# NextSpark\n.nextspark/\n\n# Cypress (theme-based)\ncontents/themes/*/tests/cypress/videos\ncontents/themes/*/tests/cypress/screenshots\ncontents/themes/*/tests/cypress/allure-results\ncontents/themes/*/tests/cypress/allure-report\n\n# Jest (theme-based)\ncontents/themes/*/tests/jest/coverage\n\n# Environment\n.env\n.env.local\n`\n\n if (await fs.pathExists(gitignorePath)) {\n const currentContent = await fs.readFile(gitignorePath, 'utf-8')\n if (!currentContent.includes('.nextspark/')) {\n await fs.appendFile(gitignorePath, entriesToAdd)\n }\n } else {\n await fs.writeFile(gitignorePath, entriesToAdd.trim())\n }\n}\n\n/**\n * Generate complete project based on wizard configuration\n * Supports both flat (web-only) and monorepo (web+mobile) structures.\n */\nexport async function generateProject(config: WizardConfig): Promise<void> {\n const projectDir = process.cwd()\n\n // IMPORTANT: Cache templates directory BEFORE changing directories\n // This ensures we can find templates even after chdir for monorepo\n cachedTemplatesDir = getTemplatesDir(projectDir)\n\n // Determine the web directory based on project type\n const webDir = getWebDir(projectDir, config)\n\n // For monorepo projects, create the root structure first\n if (isMonorepoProject(config)) {\n await generateMonorepoStructure(projectDir, config)\n }\n\n // Change to web directory for web-specific generation (monorepo only)\n const originalCwd = process.cwd()\n if (isMonorepoProject(config)) {\n process.chdir(webDir)\n }\n\n try {\n // 1. Copy core project files\n await copyProjectFiles()\n\n // 1.1 Update globals.css to use the correct theme path\n await updateGlobalsCss(config)\n\n // 2. Copy and rename starter theme\n await copyStarterTheme(config)\n\n // 2.1 Ensure contents/plugins/ directory exists (even without plugins selected)\n await fs.ensureDir(path.join(process.cwd(), 'contents', 'plugins'))\n\n // 3. Copy optional content features (pages entity, blog entity + block)\n await copyContentFeatures(config)\n\n // 4. Update theme configuration files\n await updateThemeConfig(config)\n await updateDevConfig(config)\n await updateAppConfig(config)\n await updateBillingConfig(config)\n await updateRolesConfig(config)\n\n // 5. Update migrations\n await updateMigrations(config)\n\n // 6. Update test files (replace starter path with project slug)\n await updateTestFiles(config)\n\n // 7. Update additional configs\n await updatePermissionsConfig(config)\n await updateEntityPermissions(config) // Uncomment entity permissions based on content features\n await updateDashboardConfig(config)\n\n // 8. Update Phase 3 configs (auth, dashboard UI, dev tools)\n await updateAuthConfig(config)\n await updateDashboardUIConfig(config)\n await updateDevToolsConfig(config)\n\n // 9. Process i18n files\n await processI18n(config)\n\n // 10. Update project files\n await updatePackageJson(config)\n if (!isMonorepoProject(config)) {\n // Only update root gitignore for flat projects\n // Monorepo has its own root gitignore created by generateMonorepoStructure\n await updateGitignore(config)\n }\n await generateEnvExample(config)\n if (!isMonorepoProject(config)) {\n // Only update root README for flat projects\n // Monorepo has its own root README created by generateMonorepoStructure\n await updateReadme(config)\n }\n\n // 11. Setup environment for immediate use\n await copyEnvExampleToEnv()\n // Note: Registries are built after pnpm install in wizard/index.ts\n } finally {\n // Restore original directory\n if (isMonorepoProject(config)) {\n process.chdir(originalCwd)\n }\n // Clear cache\n cachedTemplatesDir = null\n }\n}\n","/**\n * Theme Renamer Generator\n *\n * Copies the starter theme to a new name and updates all references.\n */\n\nimport fs from 'fs-extra'\nimport path from 'path'\nimport { fileURLToPath } from 'url'\nimport type { WizardConfig } from '../types.js'\n\nconst __filename = fileURLToPath(import.meta.url)\nconst __dirname = path.dirname(__filename)\n\n/**\n * Get the templates directory path from @nextsparkjs/core\n */\nfunction getTemplatesDir(): string {\n const rootDir = process.cwd()\n\n // Check multiple possible paths for templates directory\n // Priority: installed package in node_modules > development monorepo paths\n const possiblePaths = [\n // From project root node_modules (most common for installed packages)\n path.resolve(rootDir, 'node_modules/@nextsparkjs/core/templates'),\n // From CLI dist folder for development\n path.resolve(__dirname, '../../core/templates'),\n // Legacy paths for different build structures\n path.resolve(__dirname, '../../../../../core/templates'),\n path.resolve(__dirname, '../../../../core/templates'),\n ];\n\n for (const p of possiblePaths) {\n if (fs.existsSync(p)) {\n return p;\n }\n }\n\n throw new Error(`Could not find @nextsparkjs/core templates directory. Searched: ${possiblePaths.join(', ')}`);\n}\n\n/**\n * Get the target themes directory in the user's project\n */\nfunction getTargetThemesDir(): string {\n return path.resolve(process.cwd(), 'contents', 'themes')\n}\n\n/**\n * Copy starter theme to new location with new name\n */\nexport async function copyStarterTheme(config: WizardConfig): Promise<void> {\n const templatesDir = getTemplatesDir()\n const starterThemePath = path.join(templatesDir, 'contents', 'themes', 'starter')\n const targetThemesDir = getTargetThemesDir()\n const newThemePath = path.join(targetThemesDir, config.projectSlug)\n\n // Check if starter theme exists\n if (!await fs.pathExists(starterThemePath)) {\n throw new Error(`Starter theme not found at: ${starterThemePath}`)\n }\n\n // Check if target theme already exists\n if (await fs.pathExists(newThemePath)) {\n throw new Error(`Theme already exists at: ${newThemePath}. Please choose a different name or remove the existing theme.`)\n }\n\n // Ensure themes directory exists\n await fs.ensureDir(targetThemesDir)\n\n // Copy the entire starter theme\n await fs.copy(starterThemePath, newThemePath)\n}\n\n/**\n * Update theme.config.ts with new name and display name\n */\nexport async function updateThemeConfig(config: WizardConfig): Promise<void> {\n const themeConfigPath = path.join(getTargetThemesDir(), config.projectSlug, 'config', 'theme.config.ts')\n\n if (!await fs.pathExists(themeConfigPath)) {\n throw new Error(`theme.config.ts not found at: ${themeConfigPath}`)\n }\n\n let content = await fs.readFile(themeConfigPath, 'utf-8')\n\n // Update name\n content = content.replace(\n /name:\\s*['\"]starter['\"]/g,\n `name: '${config.projectSlug}'`\n )\n\n // Update displayName\n content = content.replace(\n /displayName:\\s*['\"]Starter['\"]/g,\n `displayName: '${config.projectName}'`\n )\n\n // Update description\n content = content.replace(\n /description:\\s*['\"]Minimal starter theme for NextSpark['\"]/g,\n `description: '${config.projectDescription}'`\n )\n\n // Update variable name\n content = content.replace(\n /export const starterThemeConfig/g,\n `export const ${toCamelCase(config.projectSlug)}ThemeConfig`\n )\n\n // Update default export reference (if it exists)\n content = content.replace(\n /export default starterThemeConfig/g,\n `export default ${toCamelCase(config.projectSlug)}ThemeConfig`\n )\n\n await fs.writeFile(themeConfigPath, content, 'utf-8')\n}\n\n/**\n * Update dev.config.ts comments only\n *\n * NOTE: The dev keyring users (superadmin, developer) are created by core migrations\n * with fixed credentials (@nextspark.dev, Pandora1234). These should NOT be modified\n * as they are the only users that exist at init time.\n */\nexport async function updateDevConfig(config: WizardConfig): Promise<void> {\n const devConfigPath = path.join(getTargetThemesDir(), config.projectSlug, 'config', 'dev.config.ts')\n\n if (!await fs.pathExists(devConfigPath)) {\n // dev.config.ts is optional, skip if not found\n return\n }\n\n let content = await fs.readFile(devConfigPath, 'utf-8')\n\n // Only update comments - DO NOT modify user emails/passwords\n // The initial users (superadmin, developer) come from core with fixed credentials\n content = content.replace(/STARTER THEME/g, `${config.projectName.toUpperCase()}`)\n content = content.replace(/Starter Theme/g, config.projectName)\n\n await fs.writeFile(devConfigPath, content, 'utf-8')\n}\n\n/**\n * Update app.config.ts with project settings\n */\nexport async function updateAppConfig(config: WizardConfig): Promise<void> {\n const appConfigPath = path.join(getTargetThemesDir(), config.projectSlug, 'config', 'app.config.ts')\n\n if (!await fs.pathExists(appConfigPath)) {\n throw new Error(`app.config.ts not found at: ${appConfigPath}`)\n }\n\n let content = await fs.readFile(appConfigPath, 'utf-8')\n\n // Update app name\n content = content.replace(\n /name:\\s*['\"]Starter['\"]/g,\n `name: '${config.projectName}'`\n )\n\n // Update team mode\n content = content.replace(\n /mode:\\s*['\"]multi-tenant['\"]\\s*as\\s*const/g,\n `mode: '${config.teamMode}' as const`\n )\n\n // Update supported locales\n const localesArray = config.supportedLocales.map(l => `'${l}'`).join(', ')\n content = content.replace(\n /supportedLocales:\\s*\\[.*?\\]/g,\n `supportedLocales: [${localesArray}]`\n )\n\n // Update default locale\n content = content.replace(\n /defaultLocale:\\s*['\"]en['\"]\\s*as\\s*const/g,\n `defaultLocale: '${config.defaultLocale}' as const`\n )\n\n // Update docs label\n content = content.replace(\n /label:\\s*['\"]Starter['\"]/g,\n `label: '${config.projectName}'`\n )\n\n await fs.writeFile(appConfigPath, content, 'utf-8')\n}\n\n/**\n * Update app.config.ts with selected team roles\n */\nexport async function updateRolesConfig(config: WizardConfig): Promise<void> {\n const appConfigPath = path.join(getTargetThemesDir(), config.projectSlug, 'config', 'app.config.ts')\n\n if (!await fs.pathExists(appConfigPath)) {\n return\n }\n\n let content = await fs.readFile(appConfigPath, 'utf-8')\n\n // Update availableTeamRoles if it exists\n const rolesArray = config.teamRoles.map(r => `'${r}'`).join(', ')\n content = content.replace(\n /availableTeamRoles:\\s*\\[.*?\\]/g,\n `availableTeamRoles: [${rolesArray}]`\n )\n\n await fs.writeFile(appConfigPath, content, 'utf-8')\n}\n\n/**\n * Update billing.config.ts with billing settings and generate plans\n */\nexport async function updateBillingConfig(config: WizardConfig): Promise<void> {\n const billingConfigPath = path.join(getTargetThemesDir(), config.projectSlug, 'config', 'billing.config.ts')\n\n if (!await fs.pathExists(billingConfigPath)) {\n // billing.config.ts is optional, skip if not found\n return\n }\n\n let content = await fs.readFile(billingConfigPath, 'utf-8')\n\n // Update currency\n content = content.replace(\n /currency:\\s*['\"]usd['\"]/g,\n `currency: '${config.currency}'`\n )\n\n // Generate plans based on billing model\n const plansContent = generateBillingPlans(config.billingModel, config.currency)\n\n // Replace the plans array\n content = content.replace(\n /plans:\\s*\\[[\\s\\S]*?\\],\\s*\\n\\s*\\/\\/ ===+\\s*\\n\\s*\\/\\/ ACTION MAPPINGS/,\n `plans: ${plansContent},\n\n // ===========================================\n // ACTION MAPPINGS`\n )\n\n await fs.writeFile(billingConfigPath, content, 'utf-8')\n}\n\n/**\n * Generate billing plans based on the selected billing model\n */\nfunction generateBillingPlans(billingModel: string, currency: string): string {\n if (billingModel === 'free') {\n return '[]'\n }\n\n const currencySymbol = currency === 'eur' ? '€' : currency === 'gbp' ? '£' : '$'\n\n if (billingModel === 'freemium') {\n // Free + Pro plans\n return `[\n // Free Plan\n {\n slug: 'free',\n name: 'billing.plans.free.name',\n description: 'billing.plans.free.description',\n type: 'free',\n visibility: 'public',\n price: { monthly: 0, yearly: 0 },\n trialDays: 0,\n features: ['basic_analytics'],\n limits: {\n team_members: 3,\n tasks: 50,\n api_calls: 1000,\n storage_gb: 1,\n },\n stripePriceIdMonthly: null,\n stripePriceIdYearly: null,\n },\n // Pro Plan - ${currencySymbol}29/month\n {\n slug: 'pro',\n name: 'billing.plans.pro.name',\n description: 'billing.plans.pro.description',\n type: 'paid',\n visibility: 'public',\n price: {\n monthly: 2900, // ${currencySymbol}29.00\n yearly: 29000, // ${currencySymbol}290.00 (16% savings)\n },\n trialDays: 14,\n features: [\n 'basic_analytics',\n 'advanced_analytics',\n 'api_access',\n 'priority_support',\n ],\n limits: {\n team_members: 15,\n tasks: 1000,\n api_calls: 100000,\n storage_gb: 50,\n },\n stripePriceIdMonthly: 'price_pro_monthly',\n stripePriceIdYearly: 'price_pro_yearly',\n },\n ]`\n }\n\n // paid model: Starter + Pro + Business\n return `[\n // Starter Plan - ${currencySymbol}15/month\n {\n slug: 'starter',\n name: 'billing.plans.starter.name',\n description: 'billing.plans.starter.description',\n type: 'paid',\n visibility: 'public',\n price: {\n monthly: 1500, // ${currencySymbol}15.00\n yearly: 14400, // ${currencySymbol}144.00 (20% savings)\n },\n trialDays: 7,\n features: [\n 'basic_analytics',\n 'api_access',\n ],\n limits: {\n team_members: 5,\n tasks: 200,\n api_calls: 10000,\n storage_gb: 10,\n },\n stripePriceIdMonthly: 'price_starter_monthly',\n stripePriceIdYearly: 'price_starter_yearly',\n },\n // Pro Plan - ${currencySymbol}29/month\n {\n slug: 'pro',\n name: 'billing.plans.pro.name',\n description: 'billing.plans.pro.description',\n type: 'paid',\n visibility: 'public',\n price: {\n monthly: 2900, // ${currencySymbol}29.00\n yearly: 29000, // ${currencySymbol}290.00 (16% savings)\n },\n trialDays: 14,\n features: [\n 'basic_analytics',\n 'advanced_analytics',\n 'api_access',\n 'priority_support',\n ],\n limits: {\n team_members: 15,\n tasks: 1000,\n api_calls: 100000,\n storage_gb: 50,\n },\n stripePriceIdMonthly: 'price_pro_monthly',\n stripePriceIdYearly: 'price_pro_yearly',\n },\n // Business Plan - ${currencySymbol}79/month\n {\n slug: 'business',\n name: 'billing.plans.business.name',\n description: 'billing.plans.business.description',\n type: 'paid',\n visibility: 'public',\n price: {\n monthly: 7900, // ${currencySymbol}79.00\n yearly: 79000, // ${currencySymbol}790.00 (16% savings)\n },\n trialDays: 14,\n features: [\n 'basic_analytics',\n 'advanced_analytics',\n 'api_access',\n 'sso',\n 'audit_logs',\n 'priority_support',\n 'dedicated_support',\n ],\n limits: {\n team_members: 50,\n tasks: 5000,\n api_calls: 500000,\n storage_gb: 200,\n },\n stripePriceIdMonthly: 'price_business_monthly',\n stripePriceIdYearly: 'price_business_yearly',\n },\n ]`\n}\n\n/**\n * Update SQL migration files with new email domain\n */\nexport async function updateMigrations(config: WizardConfig): Promise<void> {\n const migrationsDir = path.join(getTargetThemesDir(), config.projectSlug, 'migrations')\n\n if (!await fs.pathExists(migrationsDir)) {\n return\n }\n\n const files = await fs.readdir(migrationsDir)\n const sqlFiles = files.filter(f => f.endsWith('.sql'))\n\n for (const file of sqlFiles) {\n const filePath = path.join(migrationsDir, file)\n let content = await fs.readFile(filePath, 'utf-8')\n\n // Replace @starter.dev with @{slug}.dev\n content = content.replace(/@starter\\.dev/g, `@${config.projectSlug}.dev`)\n\n // Update comments\n content = content.replace(/Starter Theme/g, config.projectName)\n content = content.replace(/starter theme/g, config.projectSlug)\n\n await fs.writeFile(filePath, content, 'utf-8')\n }\n}\n\n/**\n * Update test files with new theme name\n * Replace @/contents/themes/starter/ with @/contents/themes/{projectSlug}/\n */\nexport async function updateTestFiles(config: WizardConfig): Promise<void> {\n const testsDir = path.join(getTargetThemesDir(), config.projectSlug, 'tests')\n\n if (!await fs.pathExists(testsDir)) {\n return\n }\n\n // Find all .ts and .tsx files in tests directory recursively\n const processDir = async (dir: string) => {\n const items = await fs.readdir(dir)\n\n for (const item of items) {\n const itemPath = path.join(dir, item)\n const stat = await fs.stat(itemPath)\n\n if (stat.isDirectory()) {\n await processDir(itemPath)\n } else if (item.endsWith('.ts') || item.endsWith('.tsx')) {\n let content = await fs.readFile(itemPath, 'utf-8')\n\n // Replace theme path references\n const hasChanges = content.includes('@/contents/themes/starter/')\n if (hasChanges) {\n content = content.replace(\n /@\\/contents\\/themes\\/starter\\//g,\n `@/contents/themes/${config.projectSlug}/`\n )\n await fs.writeFile(itemPath, content, 'utf-8')\n }\n }\n }\n }\n\n await processDir(testsDir)\n}\n\n/**\n * Convert string to camelCase\n */\nfunction toCamelCase(str: string): string {\n return str\n .split('-')\n .map((word, index) => {\n if (index === 0) {\n return word.toLowerCase()\n }\n return word.charAt(0).toUpperCase() + word.slice(1).toLowerCase()\n })\n .join('')\n}\n","/**\n * Config Generator\n *\n * Generates and updates configuration files based on wizard responses.\n */\n\nimport fs from 'fs-extra'\nimport path from 'path'\nimport type { WizardConfig } from '../types.js'\n\n/**\n * Get the target themes directory in the user's project\n */\nfunction getTargetThemesDir(): string {\n return path.resolve(process.cwd(), 'contents', 'themes')\n}\n\n/**\n * Update authentication config based on wizard responses\n * Note: Only email/password and Google OAuth are currently supported\n */\nexport async function updateAuthConfig(config: WizardConfig): Promise<void> {\n const authConfigPath = path.join(\n getTargetThemesDir(),\n config.projectSlug,\n 'config',\n 'auth.config.ts'\n )\n\n if (!await fs.pathExists(authConfigPath)) {\n return\n }\n\n let content = await fs.readFile(authConfigPath, 'utf-8')\n\n // Update email/password enabled\n content = content.replace(\n /(emailPassword:\\s*{[^}]*enabled:\\s*)(?:true|false)/gs,\n `$1${config.auth.emailPassword}`\n )\n\n // Update Google OAuth enabled\n content = content.replace(\n /(google:\\s*{[^}]*enabled:\\s*)(?:true|false)/gs,\n `$1${config.auth.googleOAuth}`\n )\n\n // Update email verification\n content = content.replace(\n /(emailVerification:\\s*)(?:true|false)/g,\n `$1${config.auth.emailVerification}`\n )\n\n await fs.writeFile(authConfigPath, content, 'utf-8')\n}\n\n/**\n * Update dashboard UI config based on wizard responses\n */\nexport async function updateDashboardUIConfig(config: WizardConfig): Promise<void> {\n const dashboardConfigPath = path.join(\n getTargetThemesDir(),\n config.projectSlug,\n 'config',\n 'dashboard.config.ts'\n )\n\n if (!await fs.pathExists(dashboardConfigPath)) {\n return\n }\n\n let content = await fs.readFile(dashboardConfigPath, 'utf-8')\n\n // Update search enabled\n content = content.replace(\n /(search:\\s*{[^}]*enabled:\\s*)(?:true|false)/gs,\n `$1${config.dashboard.search}`\n )\n\n // Update notifications enabled\n content = content.replace(\n /(notifications:\\s*{[^}]*enabled:\\s*)(?:true|false)/gs,\n `$1${config.dashboard.notifications}`\n )\n\n // Update theme toggle enabled\n content = content.replace(\n /(themeToggle:\\s*{[^}]*enabled:\\s*)(?:true|false)/gs,\n `$1${config.dashboard.themeToggle}`\n )\n\n // Update support enabled\n content = content.replace(\n /(support:\\s*{[^}]*enabled:\\s*)(?:true|false)/gs,\n `$1${config.dashboard.support}`\n )\n\n // Update quickCreate enabled\n content = content.replace(\n /(quickCreate:\\s*{[^}]*enabled:\\s*)(?:true|false)/gs,\n `$1${config.dashboard.quickCreate}`\n )\n\n // Update adminAccess enabled (mapped from wizard's superadminAccess)\n content = content.replace(\n /(adminAccess:\\s*{[^}]*enabled:\\s*)(?:true|false)/gs,\n `$1${config.dashboard.superadminAccess}`\n )\n\n // Update devtoolsAccess enabled\n content = content.replace(\n /(devtoolsAccess:\\s*{[^}]*enabled:\\s*)(?:true|false)/gs,\n `$1${config.dashboard.devtoolsAccess}`\n )\n\n // Update sidebar collapsed default\n content = content.replace(\n /(defaultCollapsed:\\s*)(?:true|false)/g,\n `$1${config.dashboard.sidebarCollapsed}`\n )\n\n await fs.writeFile(dashboardConfigPath, content, 'utf-8')\n}\n\n/**\n * Update dev tools config based on wizard responses\n */\nexport async function updateDevToolsConfig(config: WizardConfig): Promise<void> {\n const devConfigPath = path.join(\n getTargetThemesDir(),\n config.projectSlug,\n 'config',\n 'dev.config.ts'\n )\n\n if (!await fs.pathExists(devConfigPath)) {\n return\n }\n\n let content = await fs.readFile(devConfigPath, 'utf-8')\n\n // Update dev keyring enabled\n content = content.replace(\n /(devKeyring:\\s*{[^}]*enabled:\\s*)(?:true|false)/gs,\n `$1${config.dev.devKeyring}`\n )\n\n // Update debug mode enabled\n content = content.replace(\n /(debugMode:\\s*)(?:true|false)/g,\n `$1${config.dev.debugMode}`\n )\n\n await fs.writeFile(devConfigPath, content, 'utf-8')\n}\n\n/**\n * Generate permissions config based on team roles\n */\nexport async function updatePermissionsConfig(config: WizardConfig): Promise<void> {\n const permissionsConfigPath = path.join(\n getTargetThemesDir(),\n config.projectSlug,\n 'config',\n 'permissions.config.ts'\n )\n\n if (!await fs.pathExists(permissionsConfigPath)) {\n return\n }\n\n let content = await fs.readFile(permissionsConfigPath, 'utf-8')\n\n // Update role arrays in permissions based on selected roles\n const availableRoles = config.teamRoles\n\n // Build regex pattern to match role arrays\n // This updates roles: ['owner', 'admin', 'member', 'viewer'] patterns\n const roleArrayPattern = /roles:\\s*\\[(.*?)\\]/g\n\n content = content.replace(roleArrayPattern, (match, rolesStr) => {\n // Parse current roles\n const currentRoles = rolesStr\n .split(',')\n .map((r: string) => r.trim().replace(/['\"]/g, ''))\n .filter((r: string) => r.length > 0)\n\n // Filter to only include available roles\n const filteredRoles = currentRoles.filter((r: string) => availableRoles.includes(r))\n\n // If no roles remain, keep at least owner\n if (filteredRoles.length === 0) {\n filteredRoles.push('owner')\n }\n\n return `roles: [${filteredRoles.map((r: string) => `'${r}'`).join(', ')}]`\n })\n\n await fs.writeFile(permissionsConfigPath, content, 'utf-8')\n}\n\n/**\n * Uncomment entity permissions based on content feature selection\n * The starter template has pages/posts permissions commented out with markers\n */\nexport async function updateEntityPermissions(config: WizardConfig): Promise<void> {\n const permissionsConfigPath = path.join(\n getTargetThemesDir(),\n config.projectSlug,\n 'config',\n 'permissions.config.ts'\n )\n\n if (!await fs.pathExists(permissionsConfigPath)) {\n return\n }\n\n let content = await fs.readFile(permissionsConfigPath, 'utf-8')\n\n // Uncomment pages permissions if pages feature is enabled\n if (config.contentFeatures.pages) {\n content = uncommentPermissionBlock(content, 'PAGES')\n }\n\n // Uncomment posts permissions if blog feature is enabled\n if (config.contentFeatures.blog) {\n content = uncommentPermissionBlock(content, 'POSTS')\n }\n\n await fs.writeFile(permissionsConfigPath, content, 'utf-8')\n}\n\n/**\n * Uncomment a permission block by its marker name\n * Removes the // comments and the marker lines\n */\nfunction uncommentPermissionBlock(content: string, markerName: string): string {\n const startMarker = `// __${markerName}_PERMISSIONS_START__`\n const endMarker = `// __${markerName}_PERMISSIONS_END__`\n\n const startIndex = content.indexOf(startMarker)\n const endIndex = content.indexOf(endMarker)\n\n if (startIndex === -1 || endIndex === -1) {\n return content\n }\n\n // Extract the block between markers\n const beforeBlock = content.slice(0, startIndex)\n const block = content.slice(startIndex + startMarker.length, endIndex)\n const afterBlock = content.slice(endIndex + endMarker.length)\n\n // Uncomment the block by removing leading \"// \" from each line\n const uncommentedBlock = block\n .split('\\n')\n .map(line => {\n // Remove \" // \" at the start of entity permission lines\n if (line.match(/^\\s*\\/\\/\\s+/)) {\n return line.replace(/^(\\s*)\\/\\/\\s*/, '$1')\n }\n return line\n })\n .join('\\n')\n\n return beforeBlock + uncommentedBlock + afterBlock\n}\n\n/**\n * Update dashboard config with feature flags\n */\nexport async function updateDashboardConfig(config: WizardConfig): Promise<void> {\n const dashboardConfigPath = path.join(\n getTargetThemesDir(),\n config.projectSlug,\n 'config',\n 'dashboard.config.ts'\n )\n\n if (!await fs.pathExists(dashboardConfigPath)) {\n return\n }\n\n let content = await fs.readFile(dashboardConfigPath, 'utf-8')\n\n // Update analytics visibility\n if (!config.features.analytics) {\n // Comment out analytics-related navigation items or set enabled: false\n content = content.replace(\n /(id:\\s*['\"]analytics['\"].*?enabled:\\s*)true/gs,\n '$1false'\n )\n }\n\n // Update billing visibility\n if (!config.features.billing) {\n content = content.replace(\n /(id:\\s*['\"]billing['\"].*?enabled:\\s*)true/gs,\n '$1false'\n )\n }\n\n // Update teams visibility based on team mode\n if (config.teamMode === 'single-user') {\n content = content.replace(\n /(id:\\s*['\"]team['\"].*?enabled:\\s*)true/gs,\n '$1false'\n )\n content = content.replace(\n /(id:\\s*['\"]members['\"].*?enabled:\\s*)true/gs,\n '$1false'\n )\n }\n\n await fs.writeFile(dashboardConfigPath, content, 'utf-8')\n}\n\n/**\n * Generate .env.example file with project-specific values\n */\nexport async function generateEnvExample(config: WizardConfig): Promise<void> {\n const envExamplePath = path.resolve(process.cwd(), '.env.example')\n\n // Build OAuth section based on enabled providers\n let oauthSection = ''\n if (config.auth.googleOAuth) {\n oauthSection = `# =============================================================================\n# OAUTH PROVIDERS\n# =============================================================================\nGOOGLE_CLIENT_ID=\"your-google-client-id\"\nGOOGLE_CLIENT_SECRET=\"your-google-client-secret\"\n`\n } else {\n oauthSection = `# =============================================================================\n# OAUTH (Optional - enable in auth.config.ts)\n# =============================================================================\n# GOOGLE_CLIENT_ID=\"\"\n# GOOGLE_CLIENT_SECRET=\"\"\n`\n }\n\n const envContent = `# NextSpark Environment Configuration\n# Generated for: ${config.projectName}\n\n# =============================================================================\n# DATABASE\n# =============================================================================\nDATABASE_URL=\"postgresql://user:password@localhost:5432/database\"\n\n# =============================================================================\n# AUTHENTICATION (better-auth)\n# =============================================================================\n# Generate with: openssl rand -base64 32\nBETTER_AUTH_SECRET=\"your-secret-key-here\"\n\n# =============================================================================\n# THEME\n# =============================================================================\nNEXT_PUBLIC_ACTIVE_THEME=\"${config.projectSlug}\"\n\n# =============================================================================\n# APPLICATION\n# =============================================================================\nNEXT_PUBLIC_APP_URL=\"http://localhost:3000\"\nNODE_ENV=\"development\"\n\n${config.features.billing ? `# =============================================================================\n# STRIPE (Billing)\n# =============================================================================\nSTRIPE_SECRET_KEY=\"sk_test_...\"\nSTRIPE_WEBHOOK_SECRET=\"whsec_...\"\nNEXT_PUBLIC_STRIPE_PUBLISHABLE_KEY=\"pk_test_...\"\n` : '# Billing is disabled - no Stripe configuration needed'}\n\n# =============================================================================\n# EMAIL (Resend)\n# =============================================================================\nRESEND_API_KEY=\"re_...\"\n\n${oauthSection}`\n\n // Only create if it doesn't exist\n if (!await fs.pathExists(envExamplePath)) {\n await fs.writeFile(envExamplePath, envContent, 'utf-8')\n }\n}\n\n/**\n * Update README.md with project-specific information\n */\nexport async function updateReadme(config: WizardConfig): Promise<void> {\n const readmePath = path.join(getTargetThemesDir(), config.projectSlug, 'README.md')\n\n if (!await fs.pathExists(readmePath)) {\n return\n }\n\n let content = await fs.readFile(readmePath, 'utf-8')\n\n // Update title and description\n content = content.replace(/# Starter Theme/g, `# ${config.projectName}`)\n content = content.replace(\n /Minimal starter theme for NextSpark/g,\n config.projectDescription\n )\n\n await fs.writeFile(readmePath, content, 'utf-8')\n}\n\n/**\n * Copy .env.example to .env for immediate use\n * This allows the project to compile out-of-the-box\n */\nexport async function copyEnvExampleToEnv(): Promise<void> {\n const projectRoot = process.cwd()\n const envExamplePath = path.resolve(projectRoot, '.env.example')\n const envPath = path.resolve(projectRoot, '.env')\n\n if (await fs.pathExists(envExamplePath) && !await fs.pathExists(envPath)) {\n await fs.copy(envExamplePath, envPath)\n }\n}\n\n/**\n * Update app/globals.css to import from the correct theme\n * The template has \"default\" hardcoded, this updates it to the project's theme\n */\nexport async function updateGlobalsCss(config: WizardConfig): Promise<void> {\n const globalsCssPath = path.resolve(process.cwd(), 'app', 'globals.css')\n\n if (!await fs.pathExists(globalsCssPath)) {\n return\n }\n\n let content = await fs.readFile(globalsCssPath, 'utf-8')\n\n // Replace the default theme import with the project's theme\n content = content.replace(\n /@import\\s+[\"']\\.\\.\\/contents\\/themes\\/[^/]+\\/styles\\/globals\\.css[\"'];?/,\n `@import \"../contents/themes/${config.projectSlug}/styles/globals.css\";`\n )\n\n await fs.writeFile(globalsCssPath, content, 'utf-8')\n}\n","/**\n * Messages Generator\n *\n * Manages i18n message files - removes unused languages and ensures\n * selected languages have complete message files.\n */\n\nimport fs from 'fs-extra'\nimport path from 'path'\nimport type { WizardConfig } from '../types.js'\nimport { AVAILABLE_LOCALES } from '../types.js'\n\n/**\n * Get the target themes directory in the user's project\n */\nfunction getTargetThemesDir(): string {\n return path.resolve(process.cwd(), 'contents', 'themes')\n}\n\n/**\n * Remove unused language folders from messages directory\n */\nexport async function removeUnusedLanguages(config: WizardConfig): Promise<void> {\n const messagesDir = path.join(getTargetThemesDir(), config.projectSlug, 'messages')\n\n if (!await fs.pathExists(messagesDir)) {\n return\n }\n\n // Get all language folders\n const folders = await fs.readdir(messagesDir)\n const languageFolders = folders.filter(f => {\n const folderPath = path.join(messagesDir, f)\n return fs.statSync(folderPath).isDirectory() && Object.keys(AVAILABLE_LOCALES).includes(f)\n })\n\n // Remove folders that are not in supported locales\n for (const folder of languageFolders) {\n if (!config.supportedLocales.includes(folder)) {\n await fs.remove(path.join(messagesDir, folder))\n }\n }\n}\n\n/**\n * Remove unused language files from entity messages\n */\nexport async function removeUnusedEntityMessages(config: WizardConfig): Promise<void> {\n const entitiesDir = path.join(getTargetThemesDir(), config.projectSlug, 'entities')\n\n if (!await fs.pathExists(entitiesDir)) {\n return\n }\n\n // Get all entity folders\n const entityFolders = await fs.readdir(entitiesDir)\n\n for (const entity of entityFolders) {\n const messagesDir = path.join(entitiesDir, entity, 'messages')\n\n if (!await fs.pathExists(messagesDir)) {\n continue\n }\n\n // Get all message files\n const files = await fs.readdir(messagesDir)\n\n for (const file of files) {\n // Extract locale from filename (e.g., en.json -> en)\n const locale = path.basename(file, '.json')\n\n // Remove if not in supported locales\n if (Object.keys(AVAILABLE_LOCALES).includes(locale) && !config.supportedLocales.includes(locale)) {\n await fs.remove(path.join(messagesDir, file))\n }\n }\n }\n}\n\n/**\n * Create missing language folders with copied translations from default locale\n */\nexport async function ensureLanguageFolders(config: WizardConfig): Promise<void> {\n const messagesDir = path.join(getTargetThemesDir(), config.projectSlug, 'messages')\n\n if (!await fs.pathExists(messagesDir)) {\n return\n }\n\n const defaultLocaleDir = path.join(messagesDir, config.defaultLocale)\n\n // Ensure default locale exists\n if (!await fs.pathExists(defaultLocaleDir)) {\n // If default doesn't exist, try to copy from 'en'\n const enDir = path.join(messagesDir, 'en')\n if (await fs.pathExists(enDir)) {\n await fs.copy(enDir, defaultLocaleDir)\n }\n }\n\n // Create missing locale folders by copying from default\n for (const locale of config.supportedLocales) {\n const localeDir = path.join(messagesDir, locale)\n\n if (!await fs.pathExists(localeDir) && await fs.pathExists(defaultLocaleDir)) {\n // Copy from default locale as a starting point\n await fs.copy(defaultLocaleDir, localeDir)\n }\n }\n}\n\n/**\n * Update message files with project-specific values\n */\nexport async function updateMessageFiles(config: WizardConfig): Promise<void> {\n const messagesDir = path.join(getTargetThemesDir(), config.projectSlug, 'messages')\n\n if (!await fs.pathExists(messagesDir)) {\n return\n }\n\n // Update common.json in each language folder\n for (const locale of config.supportedLocales) {\n const commonPath = path.join(messagesDir, locale, 'common.json')\n\n if (await fs.pathExists(commonPath)) {\n try {\n const content = await fs.readJson(commonPath)\n\n // Update app name if it exists in the translations\n if (content.app) {\n content.app.name = config.projectName\n if (content.app.description) {\n content.app.description = config.projectDescription\n }\n }\n\n await fs.writeJson(commonPath, content, { spaces: 2 })\n } catch {\n // Skip if JSON parsing fails\n }\n }\n }\n}\n\n/**\n * Main function to process all i18n-related tasks\n */\nexport async function processI18n(config: WizardConfig): Promise<void> {\n // Remove unused languages\n await removeUnusedLanguages(config)\n await removeUnusedEntityMessages(config)\n\n // Ensure all selected languages have folders\n await ensureLanguageFolders(config)\n\n // Update message files with project values\n await updateMessageFiles(config)\n}\n","/**\n * Content Features Generator\n *\n * Copies optional entities and blocks based on content feature selections:\n * - Pages: Copies pages entity + hero block\n * - Blog: Copies posts entity + post-content block\n * - Neither: No entities or blocks are copied\n */\n\nimport fs from 'fs-extra'\nimport path from 'path'\nimport { fileURLToPath } from 'url'\nimport type { WizardConfig } from '../types.js'\n\nconst __filename = fileURLToPath(import.meta.url)\nconst __dirname = path.dirname(__filename)\n\n/**\n * Get the templates directory path from @nextsparkjs/core\n */\nfunction getTemplatesDir(): string {\n const rootDir = process.cwd()\n\n // Check multiple possible paths for templates directory\n // Priority: installed package in node_modules > development monorepo paths\n const possiblePaths = [\n // From project root node_modules (most common for installed packages)\n path.resolve(rootDir, 'node_modules/@nextsparkjs/core/templates'),\n // From CLI dist folder for development\n path.resolve(__dirname, '../../core/templates'),\n // Legacy paths for different build structures\n path.resolve(__dirname, '../../../../../core/templates'),\n path.resolve(__dirname, '../../../../core/templates'),\n ];\n\n for (const p of possiblePaths) {\n if (fs.existsSync(p)) {\n return p;\n }\n }\n\n throw new Error(`Could not find @nextsparkjs/core templates directory. Searched: ${possiblePaths.join(', ')}`);\n}\n\n/**\n * Get the features directory path\n */\nfunction getFeaturesDir(): string {\n return path.join(getTemplatesDir(), 'features')\n}\n\n/**\n * Get the target theme directory in the user's project\n */\nfunction getTargetThemeDir(projectSlug: string): string {\n return path.resolve(process.cwd(), 'contents', 'themes', projectSlug)\n}\n\n/**\n * Copy pages feature (pages entity + hero block)\n */\nasync function copyPagesFeature(config: WizardConfig): Promise<void> {\n const featuresDir = getFeaturesDir()\n const targetThemeDir = getTargetThemeDir(config.projectSlug)\n\n // Copy pages entity\n const sourcePagesEntity = path.join(featuresDir, 'pages', 'entities', 'pages')\n const targetEntitiesDir = path.join(targetThemeDir, 'entities', 'pages')\n\n if (await fs.pathExists(sourcePagesEntity)) {\n await fs.copy(sourcePagesEntity, targetEntitiesDir)\n } else {\n console.warn(`Warning: Pages entity not found at: ${sourcePagesEntity}`)\n }\n\n // Copy hero block\n const sourceHeroBlock = path.join(featuresDir, 'pages', 'blocks', 'hero')\n const targetHeroBlock = path.join(targetThemeDir, 'blocks', 'hero')\n\n if (await fs.pathExists(sourceHeroBlock)) {\n await fs.copy(sourceHeroBlock, targetHeroBlock)\n } else {\n console.warn(`Warning: Hero block not found at: ${sourceHeroBlock}`)\n }\n}\n\n/**\n * Copy blog feature (posts entity + post-content block)\n */\nasync function copyBlogFeature(config: WizardConfig): Promise<void> {\n const featuresDir = getFeaturesDir()\n const targetThemeDir = getTargetThemeDir(config.projectSlug)\n\n // Copy posts entity\n const sourcePostsEntity = path.join(featuresDir, 'blog', 'entities', 'posts')\n const targetPostsEntity = path.join(targetThemeDir, 'entities', 'posts')\n\n if (await fs.pathExists(sourcePostsEntity)) {\n await fs.copy(sourcePostsEntity, targetPostsEntity)\n } else {\n console.warn(`Warning: Posts entity not found at: ${sourcePostsEntity}`)\n }\n\n // Copy post-content block\n const sourcePostContentBlock = path.join(featuresDir, 'blog', 'blocks', 'post-content')\n const targetPostContentBlock = path.join(targetThemeDir, 'blocks', 'post-content')\n\n if (await fs.pathExists(sourcePostContentBlock)) {\n await fs.copy(sourcePostContentBlock, targetPostContentBlock)\n } else {\n console.warn(`Warning: Post-content block not found at: ${sourcePostContentBlock}`)\n }\n}\n\n/**\n * Copy content features based on wizard configuration\n *\n * Combinations:\n * - Neither: No entities or blocks copied\n * - Pages only: pages entity + hero block copied\n * - Blog only: posts entity + post-content block copied\n * - Both: pages entity + hero block + posts entity + post-content block copied\n */\nexport async function copyContentFeatures(config: WizardConfig): Promise<void> {\n // Skip if no content features are enabled\n if (!config.contentFeatures.pages && !config.contentFeatures.blog) {\n return\n }\n\n // Copy pages feature if enabled\n if (config.contentFeatures.pages) {\n await copyPagesFeature(config)\n }\n\n // Copy blog feature if enabled\n if (config.contentFeatures.blog) {\n await copyBlogFeature(config)\n }\n}\n","/**\n * Theme & Plugins Installer\n *\n * Installs themes and plugins for the wizard.\n * - In monorepo mode: copies files directly from local directories\n * - In npm mode: uses add:theme/add:plugin commands directly (same package)\n */\n\nimport { existsSync, cpSync, mkdirSync, readFileSync, writeFileSync } from 'fs'\nimport { join, resolve } from 'path'\nimport chalk from 'chalk'\nimport ora from 'ora'\nimport type { ThemeChoice } from '../prompts/theme-selection.js'\nimport type { PluginChoice } from '../prompts/plugins-selection.js'\nimport { addTheme } from '../../commands/add-theme.js'\nimport { addPlugin } from '../../commands/add-plugin.js'\n\n/**\n * NPM package names for themes\n */\nconst THEME_PACKAGES: Record<string, string> = {\n 'default': '@nextsparkjs/theme-default',\n 'blog': '@nextsparkjs/theme-blog',\n 'crm': '@nextsparkjs/theme-crm',\n 'productivity': '@nextsparkjs/theme-productivity',\n}\n\n/**\n * NPM package names for plugins\n */\nconst PLUGIN_PACKAGES: Record<PluginChoice, string> = {\n 'ai': '@nextsparkjs/plugin-ai',\n 'langchain': '@nextsparkjs/plugin-langchain',\n 'social-media-publisher': '@nextsparkjs/plugin-social-media-publisher',\n}\n\n/**\n * Required plugins for each theme\n */\nconst THEME_REQUIRED_PLUGINS: Record<string, PluginChoice[]> = {\n 'default': ['langchain'],\n 'blog': [],\n 'crm': [],\n 'productivity': [],\n}\n\n/**\n * Detect if running in monorepo development mode\n * Checks for pnpm-workspace.yaml in parent directories\n */\nfunction isMonorepoMode(): boolean {\n const possiblePaths = [\n join(process.cwd(), 'pnpm-workspace.yaml'),\n join(process.cwd(), '..', 'pnpm-workspace.yaml'),\n join(process.cwd(), '..', '..', 'pnpm-workspace.yaml'),\n ]\n\n return possiblePaths.some((p) => existsSync(p))\n}\n\n/**\n * Get the monorepo root directory\n */\nfunction getMonorepoRoot(): string | null {\n const possibleRoots = [\n process.cwd(),\n join(process.cwd(), '..'),\n join(process.cwd(), '..', '..'),\n ]\n\n for (const root of possibleRoots) {\n if (existsSync(join(root, 'pnpm-workspace.yaml'))) {\n return resolve(root)\n }\n }\n\n return null\n}\n\n/**\n * Get local package directory for development\n */\nfunction getLocalPackageDir(type: 'theme' | 'plugin', name: string): string | null {\n const monorepoRoot = getMonorepoRoot()\n if (!monorepoRoot) return null\n\n const baseDir = type === 'theme' ? 'themes' : 'plugins'\n const packageDir = join(monorepoRoot, baseDir, name)\n\n if (existsSync(packageDir) && existsSync(join(packageDir, 'package.json'))) {\n return packageDir\n }\n\n return null\n}\n\n/**\n * Copy a local theme directly (monorepo mode)\n */\nasync function copyLocalTheme(name: string, sourceDir: string): Promise<boolean> {\n const targetDir = join(process.cwd(), 'contents', 'themes', name)\n\n // Ensure target parent directory exists\n const themesDir = join(process.cwd(), 'contents', 'themes')\n if (!existsSync(themesDir)) {\n mkdirSync(themesDir, { recursive: true })\n }\n\n // Skip if already exists\n if (existsSync(targetDir)) {\n console.log(chalk.gray(` Theme ${name} already exists, skipping...`))\n return true\n }\n\n // Copy the theme\n cpSync(sourceDir, targetDir, { recursive: true })\n\n // Update tsconfig.json paths\n await updateTsConfigPaths(name, 'theme')\n\n return true\n}\n\n/**\n * Copy a local plugin directly (monorepo mode)\n */\nasync function copyLocalPlugin(name: string, sourceDir: string): Promise<boolean> {\n const targetDir = join(process.cwd(), 'contents', 'plugins', name)\n\n // Ensure target parent directory exists\n const pluginsDir = join(process.cwd(), 'contents', 'plugins')\n if (!existsSync(pluginsDir)) {\n mkdirSync(pluginsDir, { recursive: true })\n }\n\n // Skip if already exists\n if (existsSync(targetDir)) {\n console.log(chalk.gray(` Plugin ${name} already exists, skipping...`))\n return true\n }\n\n // Copy the plugin\n cpSync(sourceDir, targetDir, { recursive: true })\n\n // Update tsconfig.json paths\n await updateTsConfigPaths(name, 'plugin')\n\n return true\n}\n\n/**\n * Update tsconfig.json with paths for the installed theme/plugin\n */\nasync function updateTsConfigPaths(name: string, type: 'theme' | 'plugin'): Promise<void> {\n const tsconfigPath = join(process.cwd(), 'tsconfig.json')\n\n if (!existsSync(tsconfigPath)) {\n return\n }\n\n try {\n const content = readFileSync(tsconfigPath, 'utf-8')\n const tsconfig = JSON.parse(content)\n\n if (!tsconfig.compilerOptions) {\n tsconfig.compilerOptions = {}\n }\n if (!tsconfig.compilerOptions.paths) {\n tsconfig.compilerOptions.paths = {}\n }\n\n const basePath = type === 'theme'\n ? `contents/themes/${name}`\n : `contents/plugins/${name}`\n\n // Add the path alias\n const aliasKey = type === 'theme'\n ? `@themes/${name}/*`\n : `@plugins/${name}/*`\n\n tsconfig.compilerOptions.paths[aliasKey] = [`./${basePath}/*`]\n\n writeFileSync(tsconfigPath, JSON.stringify(tsconfig, null, 2))\n } catch {\n // Ignore errors - tsconfig update is optional\n }\n}\n\n/**\n * Install a theme using direct import (same package)\n */\nasync function installThemeViaCli(packageSpec: string): Promise<boolean> {\n try {\n await addTheme(packageSpec, {});\n return true;\n } catch {\n return false;\n }\n}\n\n/**\n * Install a plugin using direct import (same package)\n */\nasync function installPluginViaCli(packageSpec: string): Promise<boolean> {\n try {\n await addPlugin(packageSpec, {});\n return true;\n } catch {\n return false;\n }\n}\n\n/**\n * Install a theme\n */\nexport async function installTheme(theme: ThemeChoice): Promise<boolean> {\n if (!theme) {\n return true\n }\n\n const spinner = ora({\n text: `Installing reference theme: ${theme}...`,\n prefixText: ' ',\n }).start()\n\n try {\n // Check if already installed\n const targetDir = join(process.cwd(), 'contents', 'themes', theme)\n if (existsSync(targetDir)) {\n spinner.info(chalk.gray(`Reference theme ${theme} already exists`))\n return true\n }\n\n // In monorepo mode, copy directly\n if (isMonorepoMode()) {\n const localDir = getLocalPackageDir('theme', theme)\n if (localDir) {\n spinner.text = `Copying reference theme from local: ${theme}...`\n const success = await copyLocalTheme(theme, localDir)\n\n if (success) {\n // Also install required plugins for this theme\n const requiredPlugins = THEME_REQUIRED_PLUGINS[theme] || []\n for (const plugin of requiredPlugins) {\n const pluginDir = getLocalPackageDir('plugin', plugin)\n if (pluginDir) {\n await copyLocalPlugin(plugin, pluginDir)\n }\n }\n\n spinner.succeed(chalk.green(`Reference theme ${theme} installed!`))\n return true\n }\n }\n }\n\n // NPM mode: use CLI command\n spinner.text = `Installing reference theme: ${theme}...`\n const packageSpec = THEME_PACKAGES[theme]\n const success = await installThemeViaCli(packageSpec)\n\n if (success) {\n spinner.succeed(chalk.green(`Reference theme ${theme} installed!`))\n return true\n } else {\n spinner.fail(chalk.red(`Failed to install theme: ${theme}`))\n console.log(chalk.gray(' Hint: Make sure @nextsparkjs/cli is installed or the theme package is published'))\n return false\n }\n } catch (error) {\n spinner.fail(chalk.red(`Failed to install theme: ${theme}`))\n if (error instanceof Error) {\n console.log(chalk.red(` Error: ${error.message}`))\n }\n return false\n }\n}\n\n/**\n * Install plugins\n */\nexport async function installPlugins(plugins: PluginChoice[]): Promise<boolean> {\n if (plugins.length === 0) {\n return true\n }\n\n let allSuccess = true\n\n for (const plugin of plugins) {\n const spinner = ora({\n text: `Installing plugin: ${plugin}...`,\n prefixText: ' ',\n }).start()\n\n try {\n // Check if already installed\n const pluginDir = join(process.cwd(), 'contents', 'plugins', plugin)\n if (existsSync(pluginDir)) {\n spinner.info(chalk.gray(`Plugin ${plugin} already installed`))\n continue\n }\n\n // In monorepo mode, copy directly\n if (isMonorepoMode()) {\n const localDir = getLocalPackageDir('plugin', plugin)\n if (localDir) {\n spinner.text = `Copying plugin from local: ${plugin}...`\n const success = await copyLocalPlugin(plugin, localDir)\n\n if (success) {\n spinner.succeed(chalk.green(`Plugin ${plugin} installed!`))\n continue\n }\n }\n }\n\n // NPM mode: use CLI command\n spinner.text = `Installing plugin: ${plugin}...`\n const packageSpec = PLUGIN_PACKAGES[plugin]\n const success = await installPluginViaCli(packageSpec)\n\n if (success) {\n spinner.succeed(chalk.green(`Plugin ${plugin} installed!`))\n } else {\n spinner.fail(chalk.red(`Failed to install plugin: ${plugin}`))\n console.log(chalk.gray(' Hint: Make sure @nextsparkjs/cli is installed or the plugin package is published'))\n allSuccess = false\n }\n } catch (error) {\n spinner.fail(chalk.red(`Failed to install plugin: ${plugin}`))\n if (error instanceof Error) {\n console.log(chalk.red(` Error: ${error.message}`))\n }\n allSuccess = false\n }\n }\n\n return allSuccess\n}\n\n/**\n * Get required plugins for a theme\n */\nexport function getRequiredPlugins(theme: ThemeChoice): PluginChoice[] {\n if (!theme) return []\n return THEME_REQUIRED_PLUGINS[theme] || []\n}\n\n/**\n * Install theme and plugins\n */\nexport async function installThemeAndPlugins(\n theme: ThemeChoice,\n plugins: PluginChoice[]\n): Promise<boolean> {\n // Skip if nothing to install\n if (!theme && plugins.length === 0) {\n return true\n }\n\n console.log('')\n console.log(chalk.cyan(' Installing Reference Theme & Plugins'))\n console.log(chalk.gray(' ' + '-'.repeat(40)))\n console.log('')\n\n // Install theme first (may auto-install required plugins)\n const themeSuccess = await installTheme(theme)\n if (!themeSuccess && theme) {\n console.log(chalk.yellow(' Warning: Theme installation failed, continuing with plugins...'))\n }\n\n // Install additional plugins (skip those already installed by theme)\n const pluginsSuccess = await installPlugins(plugins)\n\n // Summary\n console.log('')\n if (themeSuccess && pluginsSuccess) {\n console.log(chalk.green(' All installations completed successfully!'))\n } else {\n console.log(chalk.yellow(' Some installations had issues. Check the messages above.'))\n }\n\n return themeSuccess && pluginsSuccess\n}\n","import chalk from 'chalk'\nimport ora from 'ora'\nimport { fetchPackage } from '../lib/package-fetcher.js'\nimport { validateTheme } from '../lib/validator.js'\nimport { installTheme } from '../lib/installer.js'\nimport { runPostinstall } from '../lib/postinstall/index.js'\nimport { addPlugin } from './add-plugin.js'\nimport { existsSync, readFileSync } from 'fs'\nimport { join } from 'path'\nimport type { InstallOptions, PostinstallContext } from '../types/nextspark-package.js'\n\nexport async function addTheme(\n packageSpec: string,\n options: InstallOptions = {}\n): Promise<void> {\n const spinner = ora(`Adding theme ${packageSpec}`).start()\n\n let cleanup: (() => void) | null = null\n\n try {\n // Pre-checks\n const contentsDir = join(process.cwd(), 'contents')\n if (!existsSync(contentsDir)) {\n spinner.fail('contents/ directory not found. Run \"nextspark init\" first.')\n return\n }\n\n // Fetch package\n spinner.text = 'Downloading package...'\n const { packageJson, extractedPath, cleanup: cleanupFn } = await fetchPackage(\n packageSpec,\n options.version\n )\n cleanup = cleanupFn\n\n // Validate\n spinner.text = 'Validating theme...'\n const validation = validateTheme(packageJson, extractedPath)\n\n if (!validation.valid) {\n spinner.fail('Invalid theme')\n validation.errors.forEach(e => console.log(chalk.red(` ✗ ${e}`)))\n return\n }\n\n if (validation.warnings.length > 0) {\n validation.warnings.forEach(w => console.log(chalk.yellow(` ⚠ ${w}`)))\n }\n\n // Install required plugins first (from root-level requiredPlugins)\n if (packageJson.requiredPlugins?.length && !options.skipPostinstall) {\n spinner.stop()\n console.log(chalk.blue('\\n Installing required plugins...'))\n\n const installingPlugins = new Set<string>()\n for (const plugin of packageJson.requiredPlugins) {\n if (!checkPluginExists(plugin)) {\n await addPlugin(plugin, { installingPlugins })\n }\n }\n }\n\n // Install theme\n spinner.text = 'Installing theme...'\n spinner.stop()\n\n const result = await installTheme(extractedPath, packageJson, options)\n\n // Postinstall\n if (!options.skipPostinstall) {\n const coreVersion = getCoreVersion()\n const context: PostinstallContext = {\n activeTheme: result.name, // The newly installed theme\n projectRoot: process.cwd(),\n themeName: result.name,\n coreVersion,\n timestamp: Date.now(),\n installingPlugins: new Set()\n }\n\n await runPostinstall(packageJson, result.installedPath, context)\n }\n\n console.log(chalk.green(`\\n ✓ Theme ${result.name} installed successfully!`))\n console.log(chalk.gray(` Location: contents/themes/${result.name}/`))\n console.log(chalk.gray(` Set NEXT_PUBLIC_ACTIVE_THEME=${result.name} to activate`))\n\n } catch (error) {\n spinner.fail('Failed to add theme')\n if (error instanceof Error) {\n console.log(chalk.red(` ${error.message}`))\n }\n throw error\n } finally {\n if (cleanup) cleanup()\n }\n}\n\nfunction checkPluginExists(pluginName: string): boolean {\n const name = pluginName\n .replace(/^@[^/]+\\//, '')\n .replace(/^nextspark-plugin-/, '')\n .replace(/^plugin-/, '')\n\n return existsSync(join(process.cwd(), 'contents', 'plugins', name))\n}\n\nfunction getCoreVersion(): string {\n const pkgPath = join(process.cwd(), 'node_modules', '@nextsparkjs', 'core', 'package.json')\n if (existsSync(pkgPath)) {\n try {\n const pkg = JSON.parse(readFileSync(pkgPath, 'utf-8'))\n return pkg.version || '0.0.0'\n } catch {\n return '0.0.0'\n }\n }\n return '0.0.0'\n}\n\nexport function addThemeCommand(packageSpec: string, options: Record<string, unknown>): Promise<void> {\n return addTheme(packageSpec, {\n force: options.force as boolean,\n skipDeps: options.noDeps as boolean,\n dryRun: options.dryRun as boolean,\n skipPostinstall: options.skipPostinstall as boolean,\n version: options.version as string\n })\n}\n","/**\n * Environment Setup Generator\n *\n * Generates and configures the .env file based on wizard responses.\n * Uses env.template file as the source for new .env files.\n */\n\nimport crypto from 'crypto'\nimport fs from 'fs-extra'\nimport path from 'path'\nimport { fileURLToPath } from 'url'\nimport type { WizardConfig } from '../types.js'\nimport type { EnvSetupAnswers } from '../prompts/env-config.js'\nimport { showSuccess, showInfo, showWarning } from '../banner.js'\n\n// Get the directory of this file (ESM compatible)\nconst __filename = fileURLToPath(import.meta.url)\nconst __dirname = path.dirname(__filename)\n\n// Path to the env template file\nconst ENV_TEMPLATE_PATH = path.resolve(__dirname, '../../../templates/env.template')\n\n/**\n * Generate a secure random secret\n */\nfunction generateSecret(): string {\n return crypto.randomBytes(32).toString('hex')\n}\n\n/**\n * Sanitize project name to prevent newlines and control characters\n * that could break the env file format\n */\nfunction sanitizeProjectName(name: string): string {\n return name.replace(/[\\r\\n\\t]/g, ' ').trim()\n}\n\n/**\n * Read and process the env template file\n * Replaces placeholders with actual values\n */\nasync function processEnvTemplate(\n answers: EnvSetupAnswers,\n config: WizardConfig\n): Promise<string> {\n // Read the template file\n const template = await fs.readFile(ENV_TEMPLATE_PATH, 'utf-8')\n\n // Prepare values\n const authSecret = answers.generateSecrets ? generateSecret() : 'your-secret-key-min-32-chars'\n const databaseUrl = answers.databaseUrl || 'postgresql://user:password@localhost:5432/nextspark'\n const projectName = sanitizeProjectName(config.projectName)\n\n // Replace placeholders\n const content = template\n .replace(/\\{\\{PROJECT_NAME\\}\\}/g, projectName)\n .replace(/\\{\\{DATABASE_URL\\}\\}/g, databaseUrl)\n .replace(/\\{\\{BETTER_AUTH_SECRET\\}\\}/g, authSecret)\n .replace(/\\{\\{ACTIVE_THEME\\}\\}/g, config.projectSlug)\n\n return content\n}\n\n/**\n * Setup environment configuration for the project\n *\n * @param projectPath - Path to the project directory\n * @param answers - Environment setup answers from prompts\n * @param config - Full wizard configuration\n */\nexport async function setupEnvironment(\n projectPath: string,\n answers: EnvSetupAnswers,\n config: WizardConfig\n): Promise<void> {\n if (!answers.setupEnv) {\n showInfo('Skipping .env setup')\n return\n }\n\n const envExamplePath = path.join(projectPath, '.env.example')\n const envPath = path.join(projectPath, '.env')\n\n // Check if .env.example exists\n if (!await fs.pathExists(envExamplePath)) {\n showWarning('.env.example not found, creating default .env file')\n await createDefaultEnv(envPath, answers, config)\n return\n }\n\n // Check if .env already exists\n if (await fs.pathExists(envPath)) {\n showWarning('.env already exists, updating existing file')\n await updateExistingEnv(envPath, answers, config)\n return\n }\n\n // Copy .env.example to .env\n await fs.copy(envExamplePath, envPath)\n showSuccess('Copied .env.example to .env')\n\n // Update the .env file with wizard values\n await updateEnvFile(envPath, answers, config)\n}\n\n/**\n * Update an existing .env file with new values\n */\nasync function updateExistingEnv(\n envPath: string,\n answers: EnvSetupAnswers,\n config: WizardConfig\n): Promise<void> {\n let content = await fs.readFile(envPath, 'utf-8')\n\n // Update NEXT_PUBLIC_ACTIVE_THEME\n content = updateEnvVar(content, 'NEXT_PUBLIC_ACTIVE_THEME', config.projectSlug)\n showSuccess(`Set NEXT_PUBLIC_ACTIVE_THEME=${config.projectSlug}`)\n\n // Generate and set secrets if requested\n if (answers.generateSecrets) {\n const authSecret = generateSecret()\n content = updateEnvVar(content, 'BETTER_AUTH_SECRET', authSecret)\n showSuccess('Generated secure BETTER_AUTH_SECRET')\n }\n\n // Set DATABASE_URL if provided\n if (answers.databaseUrl) {\n content = updateEnvVar(content, 'DATABASE_URL', answers.databaseUrl)\n showSuccess('Set DATABASE_URL')\n }\n\n await fs.writeFile(envPath, content, 'utf-8')\n}\n\n/**\n * Update the .env file with wizard configuration values\n */\nasync function updateEnvFile(\n envPath: string,\n answers: EnvSetupAnswers,\n config: WizardConfig\n): Promise<void> {\n let content = await fs.readFile(envPath, 'utf-8')\n\n // Update NEXT_PUBLIC_ACTIVE_THEME with project slug\n content = updateEnvVar(content, 'NEXT_PUBLIC_ACTIVE_THEME', config.projectSlug)\n showSuccess(`Set NEXT_PUBLIC_ACTIVE_THEME=${config.projectSlug}`)\n\n // Generate and set secrets if requested\n if (answers.generateSecrets) {\n const authSecret = generateSecret()\n content = updateEnvVar(content, 'BETTER_AUTH_SECRET', authSecret)\n showSuccess('Generated secure BETTER_AUTH_SECRET')\n }\n\n // Set DATABASE_URL if provided\n if (answers.databaseUrl) {\n content = updateEnvVar(content, 'DATABASE_URL', answers.databaseUrl)\n showSuccess('Set DATABASE_URL')\n }\n\n await fs.writeFile(envPath, content, 'utf-8')\n}\n\n/**\n * Update or add an environment variable in content\n */\nfunction updateEnvVar(content: string, key: string, value: string): string {\n // Pattern to match the env var (with or without quotes, commented or not)\n const pattern = new RegExp(`^(#?\\\\s*${key}\\\\s*=).*$`, 'm')\n\n if (pattern.test(content)) {\n // Update existing variable\n return content.replace(pattern, `${key}=${value}`)\n } else {\n // Add new variable at the end\n return content.trimEnd() + `\\n${key}=${value}\\n`\n }\n}\n\n/**\n * Create a default .env file from template when .env.example doesn't exist\n */\nasync function createDefaultEnv(\n envPath: string,\n answers: EnvSetupAnswers,\n config: WizardConfig\n): Promise<void> {\n // Check if template exists\n if (!await fs.pathExists(ENV_TEMPLATE_PATH)) {\n showWarning('Template file not found, creating minimal .env')\n await createMinimalEnv(envPath, answers, config)\n return\n }\n\n // Process template and write to .env\n const content = await processEnvTemplate(answers, config)\n await fs.writeFile(envPath, content, 'utf-8')\n showSuccess('Created .env file from template')\n\n if (answers.generateSecrets) {\n showSuccess('Generated secure BETTER_AUTH_SECRET')\n }\n\n if (answers.databaseUrl) {\n showSuccess('Set DATABASE_URL')\n }\n}\n\n/**\n * Fallback: Create minimal .env file if template is not available\n */\nasync function createMinimalEnv(\n envPath: string,\n answers: EnvSetupAnswers,\n config: WizardConfig\n): Promise<void> {\n const authSecret = answers.generateSecrets ? generateSecret() : 'your-secret-key-min-32-chars'\n const databaseUrl = answers.databaseUrl || 'postgresql://user:password@localhost:5432/nextspark'\n const projectName = sanitizeProjectName(config.projectName)\n\n const content = `# NextSpark Environment Configuration\n# Generated by NextSpark Wizard for: ${projectName}\n\nDATABASE_URL=${databaseUrl}\nBETTER_AUTH_SECRET=${authSecret}\nNEXT_PUBLIC_APP_URL=http://localhost:3000\nNEXT_PUBLIC_APP_NAME=\"${projectName}\"\nNEXT_PUBLIC_ACTIVE_THEME=${config.projectSlug}\n`\n\n await fs.writeFile(envPath, content, 'utf-8')\n showSuccess('Created minimal .env file')\n}\n","/**\n * Git Initialization Generator\n *\n * Handles Git repository initialization, .gitignore creation, and initial commit.\n */\n\nimport { execSync } from 'child_process'\nimport fs from 'fs-extra'\nimport path from 'path'\nimport type { GitSetupAnswers } from '../prompts/git-config.js'\nimport type { WizardConfig } from '../types.js'\n\n/**\n * NextSpark .gitignore content\n * Keep in sync with packages/core/templates/.gitignore\n */\nconst GITIGNORE_CONTENT = `# Dependencies\nnode_modules/\n\n# Build\n.next/\nout/\ndist/\n\n# NextSpark\n.nextspark/\n\n# Auto-generated templates (from theme templates at build time)\napp/(templates)/\n\n# Mocks\napp/(public)/mock-demo/\n_tmp/\n\n# Claude Code\n.claude/\n\n# Playwright MCP\n.playwright-mcp/\n\n# Cypress (theme-based)\ncontents/themes/*/tests/cypress/videos\ncontents/themes/*/tests/cypress/screenshots\ncontents/themes/*/tests/cypress/allure-results\ncontents/themes/*/tests/cypress/allure-report\n\n# Jest (theme-based)\ncontents/themes/*/tests/jest/coverage\n\n# Environment\n.env\n.env.local\n.env*.local\n\n# TypeScript\n*.tsbuildinfo\n\n# IDE\n.idea/\n.vscode/\n*.swp\n*.swo\n\n# OS\n.DS_Store\nThumbs.db\n\n# Logs\n*.log\nnpm-debug.log*\nyarn-debug.log*\nyarn-error.log*\n\n# Misc\n*.pem\n`\n\n/**\n * Check if Git is installed and available\n */\nfunction isGitAvailable(): boolean {\n try {\n execSync('git --version', { stdio: 'ignore' })\n return true\n } catch {\n return false\n }\n}\n\n/**\n * Check if the directory is already a Git repository\n */\nasync function isGitRepository(projectPath: string): Promise<boolean> {\n const gitDir = path.join(projectPath, '.git')\n return fs.pathExists(gitDir)\n}\n\n/**\n * Initialize a new Git repository\n */\nfunction initGitRepository(projectPath: string): void {\n execSync('git init', {\n cwd: projectPath,\n stdio: 'pipe',\n })\n}\n\n/**\n * Create or update .gitignore file\n */\nasync function createGitignore(projectPath: string): Promise<void> {\n const gitignorePath = path.join(projectPath, '.gitignore')\n\n if (await fs.pathExists(gitignorePath)) {\n // Append NextSpark entries if not already present\n const currentContent = await fs.readFile(gitignorePath, 'utf-8')\n if (!currentContent.includes('.nextspark/')) {\n const separator = currentContent.endsWith('\\n') ? '' : '\\n'\n await fs.appendFile(gitignorePath, `${separator}\\n# NextSpark additions\\n.nextspark/\\n`)\n }\n } else {\n // Create new .gitignore\n await fs.writeFile(gitignorePath, GITIGNORE_CONTENT)\n }\n}\n\n/**\n * Stage all files and create initial commit\n */\nfunction createInitialCommit(projectPath: string, message: string): void {\n execSync('git add .', {\n cwd: projectPath,\n stdio: 'pipe',\n })\n\n execSync(`git commit -m \"${message.replace(/\"/g, '\\\\\"')}\"`, {\n cwd: projectPath,\n stdio: 'pipe',\n })\n}\n\n/**\n * Setup Git repository based on user preferences\n *\n * @param projectPath - Path to the project directory\n * @param answers - User's git setup preferences\n * @param config - Wizard configuration (for future extensibility)\n */\nexport async function setupGit(\n projectPath: string,\n answers: GitSetupAnswers,\n config: WizardConfig\n): Promise<void> {\n // If user doesn't want git, skip everything\n if (!answers.initGit) {\n return\n }\n\n // Check if Git is available\n if (!isGitAvailable()) {\n console.warn('\\n Warning: Git is not installed or not available in PATH.')\n console.warn(' Skipping Git initialization.\\n')\n return\n }\n\n try {\n // Check if already a Git repository\n const isExistingRepo = await isGitRepository(projectPath)\n\n if (!isExistingRepo) {\n // Initialize new Git repository\n initGitRepository(projectPath)\n console.log(' Initialized Git repository.')\n } else {\n console.log(' Git repository already exists, skipping init.')\n }\n\n // Create or update .gitignore\n await createGitignore(projectPath)\n console.log(' Created .gitignore file.')\n\n // Create initial commit if requested\n if (answers.createCommit && answers.commitMessage) {\n try {\n createInitialCommit(projectPath, answers.commitMessage)\n console.log(` Created initial commit: \"${answers.commitMessage}\"`)\n } catch (commitError) {\n // Commit might fail if there's nothing to commit or git user not configured\n const errorMessage = commitError instanceof Error ? commitError.message : String(commitError)\n if (errorMessage.includes('nothing to commit')) {\n console.log(' No changes to commit.')\n } else if (errorMessage.includes('user.email') || errorMessage.includes('user.name')) {\n console.warn('\\n Warning: Git user not configured.')\n console.warn(' Run: git config --global user.name \"Your Name\"')\n console.warn(' Run: git config --global user.email \"your@email.com\"\\n')\n } else {\n console.warn(`\\n Warning: Could not create commit: ${errorMessage}\\n`)\n }\n }\n }\n } catch (error) {\n const errorMessage = error instanceof Error ? error.message : String(error)\n console.warn(`\\n Warning: Git setup failed: ${errorMessage}`)\n console.warn(' You can initialize Git manually later.\\n')\n }\n}\n","/**\n * Monorepo Generator\n *\n * Generates a monorepo structure with web/ and mobile/ directories\n * for projects that need both Next.js web and Expo mobile apps.\n */\n\nimport fs from 'fs-extra'\nimport path from 'path'\nimport { fileURLToPath } from 'url'\nimport type { WizardConfig } from '../types.js'\n\nconst __filename = fileURLToPath(import.meta.url)\nconst __dirname = path.dirname(__filename)\n\n// ============================================================================\n// Constants\n// ============================================================================\n\n/** Directory names used in monorepo structure */\nconst DIRS = {\n WEB: 'web',\n MOBILE: 'mobile',\n ASSETS: 'assets',\n} as const\n\n/** File names used in monorepo structure */\nconst FILES = {\n PNPM_WORKSPACE: 'pnpm-workspace.yaml',\n NPMRC: '.npmrc',\n GITIGNORE: '.gitignore',\n TSCONFIG: 'tsconfig.json',\n PACKAGE_JSON: 'package.json',\n README: 'README.md',\n APP_CONFIG: 'app.config.ts',\n} as const\n\n/** Required files in mobile template for validation */\nconst REQUIRED_MOBILE_TEMPLATE_FILES = [\n 'app',\n 'src',\n 'babel.config.js',\n 'metro.config.js',\n] as const\n\n/** Files to copy from mobile template */\nconst MOBILE_TEMPLATE_FILES = [\n 'app',\n 'src',\n 'assets',\n 'babel.config.js',\n 'metro.config.js',\n 'tailwind.config.js',\n 'tsconfig.json',\n 'jest.config.js',\n 'eas.json',\n] as const\n\n// ============================================================================\n// Package Versions (centralized for easy updates)\n// ============================================================================\n\n/**\n * Centralized package versions for mobile dependencies.\n * Update these when releasing new versions of NextSpark packages.\n */\nconst VERSIONS = {\n // NextSpark packages - use 'latest' for consistency with web packages\n NEXTSPARK_MOBILE: 'latest',\n NEXTSPARK_UI: 'latest',\n\n // Core dependencies\n TANSTACK_QUERY: '^5.62.0',\n EXPO: '^54.0.0',\n REACT: '19.1.0',\n REACT_NATIVE: '0.81.5',\n TYPESCRIPT: '^5.3.0',\n\n // Expo modules (use ~ for patch compatibility)\n EXPO_CONSTANTS: '~18.0.13',\n EXPO_LINKING: '~8.0.11',\n EXPO_ROUTER: '~6.0.22',\n EXPO_SECURE_STORE: '~15.0.8',\n EXPO_STATUS_BAR: '~3.0.9',\n\n // React Native modules\n RN_GESTURE_HANDLER: '~2.28.0',\n RN_REANIMATED: '~4.1.1',\n RN_SAFE_AREA: '~5.6.0',\n RN_SCREENS: '~4.16.0',\n RN_SVG: '15.12.1',\n RN_WEB: '^0.21.0',\n\n // Styling\n NATIVEWIND: '^4.2.1',\n TAILWINDCSS: '^3',\n TAILWIND_MERGE: '^3.4.0',\n LUCIDE_RN: '^0.563.0',\n\n // Dev dependencies\n BABEL_CORE: '^7.25.0',\n JEST: '^29.7.0',\n JEST_EXPO: '^54.0.16',\n TESTING_LIBRARY_JEST_NATIVE: '^5.4.3',\n TESTING_LIBRARY_RN: '^13.3.3',\n} as const\n\n// ============================================================================\n// Helper Functions\n// ============================================================================\n\n/**\n * Get the mobile templates directory path from @nextsparkjs/mobile.\n * Searches multiple possible paths for maximum compatibility.\n *\n * @throws {Error} If templates directory cannot be found with actionable guidance\n * @returns The absolute path to the mobile templates directory\n */\nfunction getMobileTemplatesDir(): string {\n const possiblePaths = [\n // From CWD node_modules (installed package)\n path.resolve(process.cwd(), 'node_modules/@nextsparkjs/mobile/templates'),\n // From CLI dist folder: ../../mobile/templates (development)\n path.resolve(__dirname, '../../mobile/templates'),\n // Legacy paths for different build structures\n path.resolve(__dirname, '../../../../../mobile/templates'),\n path.resolve(__dirname, '../../../../mobile/templates'),\n ]\n\n for (const p of possiblePaths) {\n if (fs.existsSync(p)) {\n return p\n }\n }\n\n // Provide actionable error message\n const searchedPaths = possiblePaths.map(p => ` - ${p}`).join('\\n')\n throw new Error(\n `Could not find @nextsparkjs/mobile templates directory.\\n\\n` +\n `Searched paths:\\n${searchedPaths}\\n\\n` +\n `To fix this, ensure @nextsparkjs/mobile is installed:\\n` +\n ` pnpm add @nextsparkjs/mobile\\n\\n` +\n `If you're developing locally, make sure the mobile package is built:\\n` +\n ` cd packages/mobile && pnpm build`\n )\n}\n\n/**\n * Validate that the mobile template has all required files.\n * This prevents partial or corrupted template copies.\n *\n * @param templateDir - Path to the mobile templates directory\n * @throws {Error} If required files are missing\n */\nasync function validateMobileTemplate(templateDir: string): Promise<void> {\n const missing: string[] = []\n\n for (const file of REQUIRED_MOBILE_TEMPLATE_FILES) {\n const filePath = path.join(templateDir, file)\n if (!await fs.pathExists(filePath)) {\n missing.push(file)\n }\n }\n\n if (missing.length > 0) {\n throw new Error(\n `Mobile template is incomplete. Missing required files:\\n` +\n missing.map(f => ` - ${f}`).join('\\n') + '\\n\\n' +\n `Template location: ${templateDir}\\n` +\n `Please ensure @nextsparkjs/mobile is properly installed and built.`\n )\n }\n}\n\n/**\n * Convert a project slug to a valid iOS/Android bundle identifier.\n * Transforms \"my-awesome-app\" to \"my.awesome.app\" for better readability.\n *\n * @param slug - The project slug (e.g., \"my-awesome-app\")\n * @returns A valid bundle identifier (e.g., \"my.awesome.app\")\n */\nfunction slugToBundleId(slug: string): string {\n return slug\n .toLowerCase()\n // Replace hyphens, underscores, and other non-alphanumeric chars with dots\n .replace(/[^a-z0-9]+/g, '.')\n // Remove leading/trailing dots\n .replace(/^\\.+|\\.+$/g, '')\n // Replace multiple consecutive dots with single dot\n .replace(/\\.{2,}/g, '.')\n}\n\n// ============================================================================\n// File Generators\n// ============================================================================\n\n/**\n * Create the root monorepo package.json\n */\nasync function createRootPackageJson(targetDir: string, config: WizardConfig): Promise<void> {\n const rootPkg = {\n name: config.projectSlug,\n version: '0.1.0',\n private: true,\n scripts: {\n // Web commands\n 'dev': `pnpm --filter ${DIRS.WEB} dev`,\n 'build': `pnpm --filter ${DIRS.WEB} build`,\n 'start': `pnpm --filter ${DIRS.WEB} start`,\n 'lint': 'pnpm -r lint',\n // Mobile commands\n 'dev:mobile': `pnpm --filter ${DIRS.MOBILE} start`,\n 'ios': `pnpm --filter ${DIRS.MOBILE} ios`,\n 'android': `pnpm --filter ${DIRS.MOBILE} android`,\n // Shared commands\n 'typecheck': 'pnpm -r typecheck',\n 'test': 'pnpm -r test',\n // Web-specific CLI commands (run from root)\n 'db:migrate': `pnpm --filter ${DIRS.WEB} db:migrate`,\n 'db:seed': `pnpm --filter ${DIRS.WEB} db:seed`,\n 'build:registries': `pnpm --filter ${DIRS.WEB} build:registries`,\n },\n devDependencies: {\n 'typescript': VERSIONS.TYPESCRIPT,\n }\n }\n\n await fs.writeJson(path.join(targetDir, FILES.PACKAGE_JSON), rootPkg, { spaces: 2 })\n}\n\n/**\n * Create the pnpm-workspace.yaml file\n */\nasync function createPnpmWorkspace(targetDir: string): Promise<void> {\n const workspaceContent = `packages:\n - '${DIRS.WEB}'\n - '${DIRS.MOBILE}'\n`\n await fs.writeFile(path.join(targetDir, FILES.PNPM_WORKSPACE), workspaceContent)\n}\n\n/**\n * Create the root .npmrc file for proper hoisting\n */\nasync function createNpmrc(targetDir: string): Promise<void> {\n const npmrcContent = `# Enable proper hoisting for monorepo\npublic-hoist-pattern[]=*@nextsparkjs/*\npublic-hoist-pattern[]=*expo*\npublic-hoist-pattern[]=*react-native*\nshamefully-hoist=true\n`\n await fs.writeFile(path.join(targetDir, FILES.NPMRC), npmrcContent)\n}\n\n/**\n * Create the root .gitignore file\n */\nasync function createGitignore(targetDir: string): Promise<void> {\n const gitignoreContent = `# Dependencies\nnode_modules/\n\n# Build outputs\n.next/\ndist/\nout/\nbuild/\n.expo/\n\n# NextSpark\n.nextspark/\n\n# Environment\n.env\n.env.local\n.env.*.local\n\n# IDE\n.idea/\n.vscode/\n*.swp\n*.swo\n\n# OS\n.DS_Store\nThumbs.db\n\n# Testing\ncoverage/\n.nyc_output/\n\n# Cypress (theme-based in web/)\n${DIRS.WEB}/contents/themes/*/tests/cypress/videos\n${DIRS.WEB}/contents/themes/*/tests/cypress/screenshots\n${DIRS.WEB}/contents/themes/*/tests/cypress/allure-results\n${DIRS.WEB}/contents/themes/*/tests/cypress/allure-report\n\n# Jest (theme-based in web/)\n${DIRS.WEB}/contents/themes/*/tests/jest/coverage\n\n# Mobile specific\n${DIRS.MOBILE}/.expo/\n*.jks\n*.p8\n*.p12\n*.key\n*.mobileprovision\n*.orig.*\nweb-build/\n`\n await fs.writeFile(path.join(targetDir, FILES.GITIGNORE), gitignoreContent)\n}\n\n/**\n * Create root tsconfig.json for monorepo\n */\nasync function createRootTsConfig(targetDir: string): Promise<void> {\n const tsConfig = {\n compilerOptions: {\n target: 'ES2022',\n module: 'ESNext',\n moduleResolution: 'bundler',\n strict: true,\n skipLibCheck: true,\n esModuleInterop: true,\n },\n references: [\n { path: `./${DIRS.WEB}` },\n { path: `./${DIRS.MOBILE}` }\n ]\n }\n\n await fs.writeJson(path.join(targetDir, FILES.TSCONFIG), tsConfig, { spaces: 2 })\n}\n\n/**\n * Copy mobile template files and customize them\n */\nasync function copyMobileTemplate(targetDir: string, config: WizardConfig): Promise<void> {\n const mobileTemplatesDir = getMobileTemplatesDir()\n\n // Validate template before copying\n await validateMobileTemplate(mobileTemplatesDir)\n\n const mobileDir = path.join(targetDir, DIRS.MOBILE)\n\n // Ensure mobile directory exists\n await fs.ensureDir(mobileDir)\n\n // Copy all template files\n for (const item of MOBILE_TEMPLATE_FILES) {\n const srcPath = path.join(mobileTemplatesDir, item)\n const destPath = path.join(mobileDir, item)\n\n if (await fs.pathExists(srcPath)) {\n await fs.copy(srcPath, destPath)\n }\n }\n\n // Create customized package.json\n await createMobilePackageJson(mobileDir, config)\n\n // Create customized app.config.ts\n await createMobileAppConfig(mobileDir, config)\n\n // Create assets directory with placeholders\n await createMobileAssets(mobileDir, config)\n}\n\n/**\n * Create mobile package.json with project-specific values\n */\nasync function createMobilePackageJson(mobileDir: string, config: WizardConfig): Promise<void> {\n const mobileSlug = `${config.projectSlug}-mobile`\n\n const packageJson = {\n name: mobileSlug,\n version: '0.1.0',\n private: true,\n main: 'expo-router/entry',\n scripts: {\n start: 'expo start',\n android: 'expo start --android',\n ios: 'expo start --ios',\n web: 'expo start --web',\n lint: 'eslint .',\n typecheck: 'tsc --noEmit',\n test: 'jest',\n 'test:watch': 'jest --watch',\n 'test:coverage': 'jest --coverage'\n },\n dependencies: {\n '@nextsparkjs/mobile': VERSIONS.NEXTSPARK_MOBILE,\n '@nextsparkjs/ui': VERSIONS.NEXTSPARK_UI,\n '@tanstack/react-query': VERSIONS.TANSTACK_QUERY,\n 'expo': VERSIONS.EXPO,\n 'expo-constants': VERSIONS.EXPO_CONSTANTS,\n 'expo-linking': VERSIONS.EXPO_LINKING,\n 'expo-router': VERSIONS.EXPO_ROUTER,\n 'expo-secure-store': VERSIONS.EXPO_SECURE_STORE,\n 'expo-status-bar': VERSIONS.EXPO_STATUS_BAR,\n 'lucide-react-native': VERSIONS.LUCIDE_RN,\n 'nativewind': VERSIONS.NATIVEWIND,\n 'react': VERSIONS.REACT,\n 'react-dom': VERSIONS.REACT,\n 'react-native': VERSIONS.REACT_NATIVE,\n 'react-native-web': VERSIONS.RN_WEB,\n 'react-native-gesture-handler': VERSIONS.RN_GESTURE_HANDLER,\n 'react-native-reanimated': VERSIONS.RN_REANIMATED,\n 'react-native-safe-area-context': VERSIONS.RN_SAFE_AREA,\n 'react-native-screens': VERSIONS.RN_SCREENS,\n 'react-native-svg': VERSIONS.RN_SVG,\n 'tailwind-merge': VERSIONS.TAILWIND_MERGE,\n 'tailwindcss': VERSIONS.TAILWINDCSS\n },\n devDependencies: {\n '@babel/core': VERSIONS.BABEL_CORE,\n '@testing-library/jest-native': VERSIONS.TESTING_LIBRARY_JEST_NATIVE,\n '@testing-library/react-native': VERSIONS.TESTING_LIBRARY_RN,\n '@types/jest': '^29.5.0',\n '@types/react': '^19',\n 'jest': VERSIONS.JEST,\n 'jest-expo': VERSIONS.JEST_EXPO,\n 'react-test-renderer': VERSIONS.REACT,\n 'typescript': VERSIONS.TYPESCRIPT\n }\n }\n\n await fs.writeJson(path.join(mobileDir, FILES.PACKAGE_JSON), packageJson, { spaces: 2 })\n}\n\n/**\n * Create mobile app.config.ts with project-specific values\n */\nasync function createMobileAppConfig(mobileDir: string, config: WizardConfig): Promise<void> {\n // Convert project slug to bundle identifier format\n // \"my-awesome-app\" → \"my.awesome.app\"\n const bundleId = slugToBundleId(config.projectSlug)\n\n const appConfigContent = `import { ExpoConfig, ConfigContext } from 'expo/config'\n\nexport default ({ config }: ConfigContext): ExpoConfig => ({\n ...config,\n name: '${config.projectName}',\n slug: '${config.projectSlug}',\n version: '1.0.0',\n orientation: 'portrait',\n icon: './${DIRS.ASSETS}/icon.png',\n userInterfaceStyle: 'automatic',\n splash: {\n image: './${DIRS.ASSETS}/splash.png',\n resizeMode: 'contain',\n backgroundColor: '#ffffff',\n },\n assetBundlePatterns: ['**/*'],\n ios: {\n supportsTablet: true,\n bundleIdentifier: 'com.${bundleId}.app',\n },\n android: {\n adaptiveIcon: {\n foregroundImage: './${DIRS.ASSETS}/adaptive-icon.png',\n backgroundColor: '#ffffff',\n },\n package: 'com.${bundleId}.app',\n },\n web: {\n favicon: './${DIRS.ASSETS}/favicon.png',\n },\n extra: {\n // API URL - Configure for your environment\n // Development: point to your local web app (e.g., http://localhost:3000)\n // Production: set via EAS environment variables\n apiUrl: process.env.EXPO_PUBLIC_API_URL,\n },\n plugins: ['expo-router', 'expo-secure-store'],\n scheme: '${config.projectSlug}',\n})\n`\n\n await fs.writeFile(path.join(mobileDir, FILES.APP_CONFIG), appConfigContent)\n}\n\n/**\n * Create mobile assets directory with placeholder files and documentation.\n * Includes detailed instructions for generating proper app icons.\n */\nasync function createMobileAssets(mobileDir: string, config: WizardConfig): Promise<void> {\n const assetsDir = path.join(mobileDir, DIRS.ASSETS)\n await fs.ensureDir(assetsDir)\n\n // Create .gitkeep to ensure directory is tracked\n await fs.writeFile(\n path.join(assetsDir, '.gitkeep'),\n '# Placeholder - replace with your app icons and splash screens\\n'\n )\n\n // Create detailed README for assets\n const assetsReadme = `# Mobile App Assets for ${config.projectName}\n\nThis directory contains your mobile app icons and splash screens.\n\n## Required Files\n\n| File | Size | Description |\n|------|------|-------------|\n| \\`icon.png\\` | 1024x1024px | Main app icon (iOS & Android) |\n| \\`splash.png\\` | 1284x2778px | Splash screen image |\n| \\`adaptive-icon.png\\` | 1024x1024px | Android adaptive icon (foreground) |\n| \\`favicon.png\\` | 48x48px | Web favicon |\n\n## How to Generate\n\n### Option 1: Expo Asset Generator (Recommended)\n\n1. Create a 1024x1024px icon image\n2. Use Expo's icon generator:\n \\`\\`\\`bash\n npx expo-optimize\n \\`\\`\\`\n\n### Option 2: Online Tools\n\n- [Expo Icon Generator](https://docs.expo.dev/develop/user-interface/app-icons/)\n- [App Icon Generator](https://appicon.co/)\n- [Figma App Icon Template](https://www.figma.com/community/file/824894885635013116)\n\n### Option 3: Manual Creation\n\nCreate each file at the specified sizes above. Use PNG format with transparency for icons.\n\n## Tips\n\n- Use a simple, recognizable design that works at small sizes\n- Test your icon on both light and dark backgrounds\n- Avoid text in the icon (it becomes illegible at small sizes)\n- Keep important content within the \"safe zone\" (center 80%)\n\n## Resources\n\n- [Expo App Icons Documentation](https://docs.expo.dev/develop/user-interface/app-icons/)\n- [iOS Human Interface Guidelines](https://developer.apple.com/design/human-interface-guidelines/app-icons)\n- [Android Adaptive Icons](https://developer.android.com/develop/ui/views/launch/icon_design_adaptive)\n`\n await fs.writeFile(path.join(assetsDir, 'README.md'), assetsReadme)\n}\n\n/**\n * Create monorepo README.md\n */\nasync function createMonorepoReadme(targetDir: string, config: WizardConfig): Promise<void> {\n const readmeContent = `# ${config.projectName}\n\n${config.projectDescription}\n\n## Project Structure\n\nThis is a monorepo containing both web and mobile applications:\n\n\\`\\`\\`\n${config.projectSlug}/\n├── ${DIRS.WEB}/ # Next.js web application\n│ ├── app/ # Next.js App Router\n│ ├── contents/ # Themes and plugins\n│ └── package.json\n├── ${DIRS.MOBILE}/ # Expo mobile application\n│ ├── app/ # Expo Router screens\n│ ├── src/ # Mobile-specific code\n│ └── package.json\n├── package.json # Root monorepo\n└── ${FILES.PNPM_WORKSPACE}\n\\`\\`\\`\n\n## Getting Started\n\n### Prerequisites\n\n- Node.js 20+\n- pnpm 9+\n- For mobile: Expo CLI (\\`npm install -g expo-cli\\`)\n\n### Installation\n\n\\`\\`\\`bash\n# Install all dependencies\npnpm install\n\n# Set up environment variables\ncp ${DIRS.WEB}/.env.example ${DIRS.WEB}/.env\n# Edit ${DIRS.WEB}/.env with your configuration\n\\`\\`\\`\n\n### Development\n\n**Web Application:**\n\\`\\`\\`bash\n# From root directory\npnpm dev\n\n# Or from web directory\ncd ${DIRS.WEB} && pnpm dev\n\\`\\`\\`\n\n**Mobile Application:**\n\\`\\`\\`bash\n# From root directory\npnpm dev:mobile\n\n# Or from mobile directory\ncd ${DIRS.MOBILE} && pnpm start\n\\`\\`\\`\n\n### Running Tests\n\n\\`\\`\\`bash\n# Run all tests\npnpm test\n\n# Run web tests only\npnpm --filter ${DIRS.WEB} test\n\n# Run mobile tests only\npnpm --filter ${DIRS.MOBILE} test\n\\`\\`\\`\n\n## Mobile App Configuration\n\nThe mobile app connects to your web API. Configure the API URL:\n\n- **Development:** The mobile app will auto-detect your local server\n- **Production:** Set \\`EXPO_PUBLIC_API_URL\\` in your EAS environment\n\n## Building for Production\n\n**Web:**\n\\`\\`\\`bash\npnpm build\n\\`\\`\\`\n\n**Mobile:**\n\\`\\`\\`bash\ncd ${DIRS.MOBILE}\neas build --platform ios\neas build --platform android\n\\`\\`\\`\n\n## Learn More\n\n- [NextSpark Documentation](https://nextspark.dev/docs)\n- [Expo Documentation](https://docs.expo.dev)\n- [Next.js Documentation](https://nextjs.org/docs)\n`\n\n await fs.writeFile(path.join(targetDir, FILES.README), readmeContent)\n}\n\n// ============================================================================\n// Public API\n// ============================================================================\n\n/**\n * Generate the monorepo project structure.\n *\n * This creates the root structure and mobile app, then delegates\n * to the web generator for the web/ directory.\n *\n * @param targetDir - The root directory where the project will be created\n * @param config - The wizard configuration with project settings\n */\nexport async function generateMonorepoStructure(targetDir: string, config: WizardConfig): Promise<void> {\n // 1. Create root monorepo files\n await createRootPackageJson(targetDir, config)\n await createPnpmWorkspace(targetDir)\n await createNpmrc(targetDir)\n await createGitignore(targetDir)\n await createRootTsConfig(targetDir)\n await createMonorepoReadme(targetDir, config)\n\n // 2. Create web/ directory\n const webDir = path.join(targetDir, DIRS.WEB)\n await fs.ensureDir(webDir)\n\n // 3. Copy mobile template\n await copyMobileTemplate(targetDir, config)\n}\n\n/**\n * Check if a project is using monorepo structure.\n *\n * @param config - The wizard configuration\n * @returns True if the project type is 'web-mobile' (monorepo)\n */\nexport function isMonorepoProject(config: WizardConfig): boolean {\n return config.projectType === 'web-mobile'\n}\n\n/**\n * Get the web directory path based on project type.\n *\n * For monorepo projects, returns the path to the web/ subdirectory.\n * For flat projects, returns the target directory itself.\n *\n * @param targetDir - The project root directory\n * @param config - The wizard configuration\n * @returns The absolute path to the web directory\n */\nexport function getWebDir(targetDir: string, config: WizardConfig): string {\n return config.projectType === 'web-mobile'\n ? path.join(targetDir, DIRS.WEB)\n : targetDir\n}\n","/**\n * NextSpark Wizard Presets\n *\n * Pre-configured project templates for common use cases.\n * Presets pre-fill all configuration values but still allow customization.\n */\n\nimport type {\n WizardConfig,\n PresetName,\n ProjectType,\n TeamMode,\n BillingModel,\n FeatureFlags,\n ContentFeaturesConfig,\n AuthConfig,\n DashboardConfig,\n DevConfig,\n} from './types.js'\n\n/**\n * Partial preset configuration (projectName, projectSlug, projectDescription\n * are always prompted even with presets)\n */\nexport interface PresetConfig {\n projectType: ProjectType\n teamMode: TeamMode\n teamRoles: string[]\n defaultLocale: string\n supportedLocales: string[]\n billingModel: BillingModel\n currency: string\n features: FeatureFlags\n contentFeatures: ContentFeaturesConfig\n auth: AuthConfig\n dashboard: DashboardConfig\n dev: DevConfig\n}\n\n/**\n * SaaS Preset\n *\n * Multi-tenant SaaS application with freemium billing,\n * team management, and authentication options.\n */\nconst SAAS_PRESET: PresetConfig = {\n projectType: 'web',\n teamMode: 'multi-tenant',\n teamRoles: ['owner', 'admin', 'member', 'viewer'],\n defaultLocale: 'en',\n supportedLocales: ['en'],\n billingModel: 'freemium',\n currency: 'usd',\n features: {\n analytics: true,\n teams: true,\n billing: true,\n api: true,\n docs: false,\n },\n contentFeatures: {\n pages: false,\n blog: false,\n },\n auth: {\n emailPassword: true,\n googleOAuth: true,\n emailVerification: true,\n },\n dashboard: {\n search: true,\n notifications: true,\n themeToggle: true,\n support: true,\n quickCreate: true,\n superadminAccess: true,\n devtoolsAccess: true,\n sidebarCollapsed: false,\n },\n dev: {\n devKeyring: true,\n debugMode: false,\n },\n}\n\n/**\n * Blog Preset\n *\n * Single-user blog or content site with no billing,\n * minimal authentication, and simple dashboard.\n */\nconst BLOG_PRESET: PresetConfig = {\n projectType: 'web',\n teamMode: 'single-user',\n teamRoles: ['owner'],\n defaultLocale: 'en',\n supportedLocales: ['en'],\n billingModel: 'free',\n currency: 'usd',\n features: {\n analytics: true,\n teams: false,\n billing: false,\n api: false,\n docs: true,\n },\n contentFeatures: {\n pages: false,\n blog: true,\n },\n auth: {\n emailPassword: true,\n googleOAuth: false,\n emailVerification: false,\n },\n dashboard: {\n search: false,\n notifications: false,\n themeToggle: true,\n support: true,\n quickCreate: false,\n superadminAccess: true,\n devtoolsAccess: true,\n sidebarCollapsed: false,\n },\n dev: {\n devKeyring: true,\n debugMode: false,\n },\n}\n\n/**\n * CRM Preset\n *\n * Single-tenant CRM or internal tool with paid subscription,\n * team roles, and full dashboard features.\n */\nconst CRM_PRESET: PresetConfig = {\n projectType: 'web',\n teamMode: 'single-tenant',\n teamRoles: ['owner', 'admin', 'member'],\n defaultLocale: 'en',\n supportedLocales: ['en'],\n billingModel: 'paid',\n currency: 'usd',\n features: {\n analytics: true,\n teams: true,\n billing: true,\n api: true,\n docs: false,\n },\n contentFeatures: {\n pages: true,\n blog: false,\n },\n auth: {\n emailPassword: true,\n googleOAuth: true,\n emailVerification: true,\n },\n dashboard: {\n search: true,\n notifications: true,\n themeToggle: true,\n support: true,\n quickCreate: true,\n superadminAccess: true,\n devtoolsAccess: true,\n sidebarCollapsed: false,\n },\n dev: {\n devKeyring: true,\n debugMode: false,\n },\n}\n\n/**\n * All available presets\n */\nexport const PRESETS: Record<PresetName, PresetConfig> = {\n saas: SAAS_PRESET,\n blog: BLOG_PRESET,\n crm: CRM_PRESET,\n}\n\n/**\n * Preset descriptions for display\n */\nexport const PRESET_DESCRIPTIONS: Record<PresetName, string> = {\n saas: 'Multi-tenant SaaS with freemium billing and team management',\n blog: 'Single-user blog or content site with minimal features',\n crm: 'Single-tenant CRM or internal tool with paid subscription',\n}\n\n/**\n * Get a preset configuration by name\n */\nexport function getPreset(name: PresetName): PresetConfig {\n const preset = PRESETS[name]\n if (!preset) {\n throw new Error(`Unknown preset: ${name}. Available presets: ${Object.keys(PRESETS).join(', ')}`)\n }\n return preset\n}\n\n/**\n * Check if a preset name is valid\n */\nexport function isValidPreset(name: string): name is PresetName {\n return name in PRESETS\n}\n\n/**\n * Get all available preset names\n */\nexport function getAvailablePresets(): PresetName[] {\n return Object.keys(PRESETS) as PresetName[]\n}\n\n/**\n * Apply preset to partial config\n * (merges project info with preset defaults)\n * Optional typeOverride allows CLI to specify project type\n */\nexport function applyPreset(\n projectInfo: Pick<WizardConfig, 'projectName' | 'projectSlug' | 'projectDescription'>,\n presetName: PresetName,\n typeOverride?: ProjectType\n): WizardConfig {\n const preset = getPreset(presetName)\n return {\n ...projectInfo,\n ...preset,\n // Apply type override if provided\n ...(typeOverride && { projectType: typeOverride }),\n }\n}\n\n/**\n * Get default configuration (used when no preset is specified)\n * This provides sensible defaults for all fields.\n */\nexport function getDefaultConfig(): PresetConfig {\n return {\n projectType: 'web',\n teamMode: 'multi-tenant',\n teamRoles: ['owner', 'admin', 'member', 'viewer'],\n defaultLocale: 'en',\n supportedLocales: ['en'],\n billingModel: 'freemium',\n currency: 'usd',\n features: {\n analytics: true,\n teams: true,\n billing: true,\n api: true,\n docs: false,\n },\n contentFeatures: {\n pages: false,\n blog: false,\n },\n auth: {\n emailPassword: true,\n googleOAuth: false,\n emailVerification: true,\n },\n dashboard: {\n search: true,\n notifications: true,\n themeToggle: true,\n support: true,\n quickCreate: true,\n superadminAccess: true,\n devtoolsAccess: true,\n sidebarCollapsed: false,\n },\n dev: {\n devKeyring: true,\n debugMode: false,\n },\n }\n}\n","/**\n * NextSpark Interactive Theme Preview\n *\n * Provides visual preview of files that will be generated based on wizard configuration.\n */\n\nimport chalk from 'chalk'\nimport type { WizardConfig } from './types.js'\n\n/**\n * Box drawing characters for tree visualization\n */\nconst BOX = {\n vertical: '\\u2502', // |\n horizontal: '\\u2500', // -\n corner: '\\u2514', // L\n tee: '\\u251C', // |-\n topLeft: '\\u250C', // top-left corner\n topRight: '\\u2510', // top-right corner\n bottomLeft: '\\u2514', // bottom-left corner\n bottomRight: '\\u2518', // bottom-right corner\n} as const\n\n/**\n * Get the list of files that will be created based on configuration\n */\nexport function getFileTree(config: WizardConfig): string[] {\n const files: string[] = []\n const themeDir = `contents/themes/${config.projectSlug}`\n\n // Config files\n files.push(`${themeDir}/config/app.config.ts`)\n files.push(`${themeDir}/config/billing.config.ts`)\n files.push(`${themeDir}/config/dashboard.config.ts`)\n files.push(`${themeDir}/config/dev.config.ts`)\n files.push(`${themeDir}/config/permissions.config.ts`)\n files.push(`${themeDir}/config/theme.config.ts`)\n files.push(`${themeDir}/config/auth.config.ts`)\n files.push(`${themeDir}/config/dashboard-ui.config.ts`)\n files.push(`${themeDir}/config/dev-tools.config.ts`)\n\n // Entity files (tasks example entity)\n files.push(`${themeDir}/entities/tasks/entity.ts`)\n files.push(`${themeDir}/entities/tasks/schema.ts`)\n files.push(`${themeDir}/entities/tasks/permissions.ts`)\n\n // Block files (hero example block)\n files.push(`${themeDir}/blocks/hero/block.tsx`)\n files.push(`${themeDir}/blocks/hero/schema.ts`)\n files.push(`${themeDir}/blocks/hero/styles.ts`)\n\n // Messages files - only for supported locales\n for (const locale of config.supportedLocales) {\n files.push(`${themeDir}/messages/${locale}/common.json`)\n files.push(`${themeDir}/messages/${locale}/auth.json`)\n files.push(`${themeDir}/messages/${locale}/dashboard.json`)\n files.push(`${themeDir}/messages/${locale}/errors.json`)\n }\n\n // Migration files\n files.push(`${themeDir}/migrations/0001_initial_schema.sql`)\n files.push(`${themeDir}/migrations/0002_auth_tables.sql`)\n files.push(`${themeDir}/migrations/0003_tasks_entity.sql`)\n\n // Style files\n files.push(`${themeDir}/styles/globals.css`)\n files.push(`${themeDir}/styles/theme.css`)\n files.push(`${themeDir}/styles/components.css`)\n\n // Test files\n files.push(`${themeDir}/tests/cypress.config.ts`)\n files.push(`${themeDir}/tests/jest/jest.config.cjs`)\n files.push(`${themeDir}/tests/cypress/e2e/auth.cy.ts`)\n files.push(`${themeDir}/tests/cypress/e2e/dashboard.cy.ts`)\n files.push(`${themeDir}/tests/jest/components/hero.test.tsx`)\n\n return files\n}\n\n/**\n * Group files by category for display\n */\nfunction groupFilesByCategory(files: string[]): Record<string, string[]> {\n const groups: Record<string, string[]> = {\n config: [],\n entities: [],\n blocks: [],\n messages: [],\n migrations: [],\n styles: [],\n tests: [],\n }\n\n for (const file of files) {\n if (file.includes('/config/')) {\n groups.config.push(file)\n } else if (file.includes('/entities/')) {\n groups.entities.push(file)\n } else if (file.includes('/blocks/')) {\n groups.blocks.push(file)\n } else if (file.includes('/messages/')) {\n groups.messages.push(file)\n } else if (file.includes('/migrations/')) {\n groups.migrations.push(file)\n } else if (file.includes('/styles/')) {\n groups.styles.push(file)\n } else if (file.includes('/tests/')) {\n groups.tests.push(file)\n }\n }\n\n return groups\n}\n\n/**\n * Format file path for display (extract relative part after theme dir)\n */\nfunction formatFilePath(file: string, themeDir: string): string {\n return file.replace(`${themeDir}/`, '')\n}\n\n/**\n * Display configuration preview with visual tree\n */\nexport function showConfigPreview(config: WizardConfig): void {\n const files = getFileTree(config)\n const groups = groupFilesByCategory(files)\n const themeDir = `contents/themes/${config.projectSlug}`\n\n console.log('')\n console.log(chalk.cyan.bold(' Theme Preview'))\n console.log(chalk.gray(' ' + '='.repeat(50)))\n console.log('')\n\n // Display theme directory header\n console.log(chalk.white.bold(` ${BOX.topLeft}${'─'.repeat(48)}${BOX.topRight}`))\n console.log(chalk.white.bold(` ${BOX.vertical}`) + chalk.cyan(` ${themeDir}/`) + ' '.repeat(48 - themeDir.length - 2) + chalk.white.bold(BOX.vertical))\n console.log(chalk.white.bold(` ${BOX.vertical}${'─'.repeat(48)}${BOX.vertical}`))\n\n // Display each category\n const categoryLabels: Record<string, string> = {\n config: 'Configuration',\n entities: 'Entities',\n blocks: 'Blocks',\n messages: 'Messages (i18n)',\n migrations: 'Migrations',\n styles: 'Styles',\n tests: 'Tests',\n }\n\n const categoryIcons: Record<string, string> = {\n config: '*',\n entities: '@',\n blocks: '#',\n messages: '%',\n migrations: '~',\n styles: '&',\n tests: '!',\n }\n\n const categoryOrder = ['config', 'entities', 'blocks', 'messages', 'migrations', 'styles', 'tests']\n\n for (const category of categoryOrder) {\n const categoryFiles = groups[category]\n if (categoryFiles.length === 0) continue\n\n const label = categoryLabels[category]\n const icon = categoryIcons[category]\n\n console.log(chalk.white.bold(` ${BOX.vertical} `) + chalk.yellow(`[${icon}] ${label}`) + chalk.gray(` (${categoryFiles.length} files)`))\n\n for (let i = 0; i < categoryFiles.length; i++) {\n const file = categoryFiles[i]\n const isLast = i === categoryFiles.length - 1\n const prefix = isLast ? BOX.corner : BOX.tee\n const formattedPath = formatFilePath(file, themeDir)\n\n console.log(chalk.white.bold(` ${BOX.vertical} `) + chalk.gray(` ${prefix}${BOX.horizontal} `) + chalk.white(formattedPath))\n }\n\n console.log(chalk.white.bold(` ${BOX.vertical}`))\n }\n\n console.log(chalk.white.bold(` ${BOX.bottomLeft}${'─'.repeat(48)}${BOX.bottomRight}`))\n console.log('')\n\n // Display summary\n console.log(chalk.cyan.bold(' Summary'))\n console.log(chalk.gray(' ' + '-'.repeat(30)))\n console.log('')\n\n const totalFiles = files.length\n const estimatedSize = '~350KB'\n\n console.log(chalk.white(` Total files: `) + chalk.green.bold(totalFiles.toString()))\n console.log(chalk.white(` Estimated size: `) + chalk.green.bold(estimatedSize))\n console.log('')\n\n // Category breakdown\n console.log(chalk.gray(' By category:'))\n for (const category of categoryOrder) {\n const count = groups[category].length\n if (count > 0) {\n const label = categoryLabels[category].padEnd(16)\n console.log(chalk.gray(` ${label}`) + chalk.white(count.toString().padStart(3)) + chalk.gray(' files'))\n }\n }\n\n console.log('')\n\n // Locale information\n console.log(chalk.gray(' Locales configured:'))\n for (const locale of config.supportedLocales) {\n const isDefault = locale === config.defaultLocale\n const suffix = isDefault ? chalk.cyan(' (default)') : ''\n console.log(chalk.gray(` - `) + chalk.white(locale) + suffix)\n }\n\n console.log('')\n}\n","import { existsSync, cpSync, readFileSync, writeFileSync, renameSync, mkdirSync } from 'node:fs'\nimport { join, dirname } from 'node:path'\nimport chalk from 'chalk'\nimport ora from 'ora'\nimport { execSync } from 'node:child_process'\n\ninterface AddMobileOptions {\n force?: boolean\n skipInstall?: boolean\n}\n\n/**\n * Find the @nextsparkjs/mobile package directory\n */\nfunction findMobileCoreDir(): string {\n const projectRoot = process.cwd()\n\n // Check node_modules (npm mode)\n const npmPath = join(projectRoot, 'node_modules', '@nextsparkjs', 'mobile')\n if (existsSync(npmPath)) {\n return npmPath\n }\n\n // Check monorepo packages (development mode)\n const monoPath = join(projectRoot, 'packages', 'mobile')\n if (existsSync(monoPath)) {\n return monoPath\n }\n\n // Check parent directories (consumer in monorepo)\n const parentNpmPath = join(projectRoot, '..', 'node_modules', '@nextsparkjs', 'mobile')\n if (existsSync(parentNpmPath)) {\n return parentNpmPath\n }\n\n throw new Error(\n 'Could not find @nextsparkjs/mobile package.\\n' +\n 'Run: npm install @nextsparkjs/mobile'\n )\n}\n\n/**\n * Add mobile app to project\n */\nexport async function addMobileCommand(options: AddMobileOptions = {}): Promise<void> {\n const projectRoot = process.cwd()\n const mobileDir = join(projectRoot, 'mobile')\n\n console.log()\n console.log(chalk.bold('Adding NextSpark Mobile App'))\n console.log()\n\n // 1. Check if already exists\n if (existsSync(mobileDir) && !options.force) {\n console.log(chalk.red('Error: Mobile app already exists at mobile/'))\n console.log(chalk.gray('Use --force to overwrite'))\n process.exit(1)\n }\n\n // 2. Find mobile templates\n let mobileCoreDir: string\n try {\n mobileCoreDir = findMobileCoreDir()\n } catch (error) {\n console.log(chalk.red((error as Error).message))\n process.exit(1)\n }\n\n const templatesDir = join(mobileCoreDir, 'templates')\n\n if (!existsSync(templatesDir)) {\n console.log(chalk.red('Error: Could not find mobile templates'))\n console.log(chalk.gray(`Expected at: ${templatesDir}`))\n process.exit(1)\n }\n\n // 3. Copy templates\n const copySpinner = ora('Copying mobile app template...').start()\n\n try {\n // Create mobile directory\n mkdirSync(mobileDir, { recursive: true })\n\n // Copy all templates\n cpSync(templatesDir, mobileDir, { recursive: true })\n\n // Rename package.json.template\n const pkgTemplatePath = join(mobileDir, 'package.json.template')\n const pkgPath = join(mobileDir, 'package.json')\n\n if (existsSync(pkgTemplatePath)) {\n renameSync(pkgTemplatePath, pkgPath)\n\n // Update project name\n const pkg = JSON.parse(readFileSync(pkgPath, 'utf-8'))\n\n // Try to get project name from root package.json\n const rootPkgPath = join(projectRoot, 'package.json')\n if (existsSync(rootPkgPath)) {\n const rootPkg = JSON.parse(readFileSync(rootPkgPath, 'utf-8'))\n const rawName = rootPkg.name || 'my-project'\n\n // Preserve scope if present (e.g., @company/my-app -> @company/my-app-mobile)\n if (rawName.startsWith('@')) {\n const scopeMatch = rawName.match(/^@[\\w-]+/)\n const scope = scopeMatch ? scopeMatch[0] : ''\n const projectName = rawName.replace(/^@[\\w-]+\\//, '')\n pkg.name = `${scope}/${projectName}-mobile`\n } else {\n pkg.name = `${rawName}-mobile`\n }\n }\n\n writeFileSync(pkgPath, JSON.stringify(pkg, null, 2))\n }\n\n copySpinner.succeed('Mobile app template copied')\n } catch (error) {\n copySpinner.fail('Failed to copy templates')\n console.log(chalk.red((error as Error).message))\n process.exit(1)\n }\n\n // 4. Install dependencies\n if (!options.skipInstall) {\n const installSpinner = ora('Installing dependencies...').start()\n\n try {\n execSync('npm install', {\n cwd: mobileDir,\n stdio: 'pipe',\n timeout: 300000, // 5 minutes\n })\n installSpinner.succeed('Dependencies installed')\n } catch (error) {\n installSpinner.fail('Failed to install dependencies')\n console.log(chalk.yellow(' Run `npm install` in mobile/ manually'))\n }\n }\n\n // 5. Show next steps\n console.log()\n console.log(chalk.green.bold(' Mobile app created successfully!'))\n console.log()\n console.log(chalk.bold(' Next steps:'))\n console.log()\n console.log(` ${chalk.cyan('1.')} cd mobile`)\n console.log(` ${chalk.cyan('2.')} Update ${chalk.bold('app.config.ts')} with your app name and bundle ID`)\n console.log(` ${chalk.cyan('3.')} Add your entities in ${chalk.bold('src/entities/')}`)\n console.log(` ${chalk.cyan('4.')} npm start`)\n console.log()\n console.log(chalk.gray(' Documentation: https://nextspark.dev/docs/mobile'))\n console.log()\n}\n","import chalk from 'chalk';\nimport { runDoctorCommand } from '../doctor/index.js';\n\nexport async function doctorCommand(): Promise<void> {\n try {\n await runDoctorCommand();\n } catch (error) {\n if (error instanceof Error) {\n console.error(chalk.red(`Error: ${error.message}`));\n }\n process.exit(1);\n }\n}\n","/**\n * NextSpark Health Check Command (Doctor)\n *\n * Runs a comprehensive health check on a NextSpark project\n * to identify configuration issues, missing dependencies,\n * and other potential problems.\n *\n * Usage:\n * npx nextspark doctor\n */\n\nimport chalk from 'chalk'\nimport { checkDependencies } from './checks/dependencies.js'\nimport { checkConfigs } from './checks/config.js'\nimport { checkDatabase } from './checks/database.js'\nimport { checkImports } from './checks/imports.js'\n\n/**\n * Result of a health check\n */\nexport interface HealthCheckResult {\n /** Name of the check */\n name: string\n /** Status of the check */\n status: 'pass' | 'warn' | 'fail'\n /** Human-readable message */\n message: string\n /** Suggested fix for warnings/failures */\n fix?: string\n}\n\n/**\n * Status icons for display\n */\nconst STATUS_ICONS = {\n pass: chalk.green('\\u2713'),\n warn: chalk.yellow('\\u26A0'),\n fail: chalk.red('\\u2717'),\n} as const\n\n/**\n * Format a health check result for console output\n */\nfunction formatResult(result: HealthCheckResult): string {\n const icon = STATUS_ICONS[result.status]\n const nameColor = result.status === 'fail' ? chalk.red : result.status === 'warn' ? chalk.yellow : chalk.white\n const name = nameColor(result.name.padEnd(18))\n const message = chalk.gray(result.message)\n\n let output = `${icon} ${name} ${message}`\n\n // Add fix suggestion on a new line for warnings and failures\n if (result.fix && result.status !== 'pass') {\n output += `\\n${' '.repeat(22)}${chalk.cyan('\\u2192')} ${chalk.cyan(result.fix)}`\n }\n\n return output\n}\n\n/**\n * Display the health check header\n */\nfunction showHeader(): void {\n console.log('')\n console.log(chalk.cyan('\\uD83E\\uDE7A NextSpark Health Check'))\n console.log('')\n}\n\n/**\n * Display the health check summary\n */\nfunction showSummary(results: HealthCheckResult[]): void {\n const passed = results.filter(r => r.status === 'pass').length\n const warnings = results.filter(r => r.status === 'warn').length\n const failed = results.filter(r => r.status === 'fail').length\n\n console.log('')\n console.log(chalk.gray('-'.repeat(50)))\n\n const summary = [\n chalk.green(`${passed} passed`),\n warnings > 0 ? chalk.yellow(`${warnings} warning${warnings > 1 ? 's' : ''}`) : null,\n failed > 0 ? chalk.red(`${failed} failed`) : null,\n ].filter(Boolean).join(', ')\n\n console.log(`Summary: ${summary}`)\n console.log('')\n\n // Exit code based on results\n if (failed > 0) {\n process.exitCode = 1\n }\n}\n\n/**\n * Run all health checks and return the results\n */\nexport async function runHealthCheck(): Promise<HealthCheckResult[]> {\n const results: HealthCheckResult[] = []\n\n // Run checks in sequence\n const checks = [\n { name: 'Dependencies', fn: checkDependencies },\n { name: 'Configuration', fn: checkConfigs },\n { name: 'Database', fn: checkDatabase },\n { name: 'Imports', fn: checkImports },\n ]\n\n for (const check of checks) {\n try {\n const result = await check.fn()\n results.push(result)\n } catch (error) {\n results.push({\n name: check.name,\n status: 'fail',\n message: error instanceof Error ? error.message : 'Unknown error occurred',\n fix: 'Check the error message and try again',\n })\n }\n }\n\n return results\n}\n\n/**\n * Run the health check command with formatted output\n */\nexport async function runDoctorCommand(): Promise<void> {\n showHeader()\n\n const results = await runHealthCheck()\n\n // Display each result\n for (const result of results) {\n console.log(formatResult(result))\n }\n\n showSummary(results)\n}\n\n// Run if executed directly\nconst isDirectExecution = process.argv[1]?.includes('doctor') ||\n process.argv.includes('doctor')\n\nif (isDirectExecution && typeof require !== 'undefined') {\n runDoctorCommand().catch((error: Error) => {\n console.error(chalk.red('An unexpected error occurred:'), error.message)\n process.exit(1)\n })\n}\n","/**\n * Dependencies Health Check\n *\n * Verifies that node_modules are installed and match package.json dependencies.\n */\n\nimport fs from 'fs-extra'\nimport path from 'path'\nimport type { HealthCheckResult } from '../index.js'\n\n/**\n * Check if dependencies are installed by comparing node_modules with package.json\n */\nexport async function checkDependencies(): Promise<HealthCheckResult> {\n const cwd = process.cwd()\n const nodeModulesPath = path.join(cwd, 'node_modules')\n const packageJsonPath = path.join(cwd, 'package.json')\n\n // Check if package.json exists\n if (!await fs.pathExists(packageJsonPath)) {\n return {\n name: 'Dependencies',\n status: 'fail',\n message: 'package.json not found',\n fix: 'Ensure you are in a NextSpark project directory',\n }\n }\n\n // Check if node_modules exists\n if (!await fs.pathExists(nodeModulesPath)) {\n return {\n name: 'Dependencies',\n status: 'fail',\n message: 'node_modules not found',\n fix: 'Run: pnpm install',\n }\n }\n\n // Read package.json\n let packageJson: { dependencies?: Record<string, string>; devDependencies?: Record<string, string> }\n try {\n packageJson = await fs.readJson(packageJsonPath)\n } catch {\n return {\n name: 'Dependencies',\n status: 'fail',\n message: 'Failed to read package.json',\n fix: 'Ensure package.json is valid JSON',\n }\n }\n\n // Collect all dependencies\n const allDependencies = {\n ...packageJson.dependencies,\n ...packageJson.devDependencies,\n }\n\n // Check for missing critical dependencies\n const missingDeps: string[] = []\n const criticalDeps = ['next', 'react', 'react-dom']\n\n for (const dep of criticalDeps) {\n if (allDependencies[dep]) {\n const depPath = path.join(nodeModulesPath, dep)\n if (!await fs.pathExists(depPath)) {\n missingDeps.push(dep)\n }\n }\n }\n\n // Check for @nextsparkjs/core\n const nextsparksCorePath = path.join(nodeModulesPath, '@nextsparkjs', 'core')\n const hasNextSparkCore = await fs.pathExists(nextsparksCorePath)\n\n if (missingDeps.length > 0) {\n return {\n name: 'Dependencies',\n status: 'fail',\n message: `Missing packages: ${missingDeps.join(', ')}`,\n fix: 'Run: pnpm install',\n }\n }\n\n if (!hasNextSparkCore && allDependencies['@nextsparkjs/core']) {\n return {\n name: 'Dependencies',\n status: 'warn',\n message: '@nextsparkjs/core not installed',\n fix: 'Run: pnpm install',\n }\n }\n\n // All dependencies are installed\n return {\n name: 'Dependencies',\n status: 'pass',\n message: 'All packages installed',\n }\n}\n","/**\n * Configuration Health Check\n *\n * Verifies that configuration files exist and have valid syntax.\n */\n\nimport fs from 'fs-extra'\nimport path from 'path'\nimport type { HealthCheckResult } from '../index.js'\n\n/**\n * Required configuration files for a NextSpark project\n */\nconst REQUIRED_CONFIG_FILES = [\n 'next.config.ts',\n 'tailwind.config.ts',\n 'tsconfig.json',\n]\n\n/**\n * Optional configuration files that should be valid if they exist\n */\nconst OPTIONAL_CONFIG_FILES = [\n 'next.config.js',\n 'next.config.mjs',\n 'tailwind.config.js',\n 'tailwind.config.mjs',\n]\n\n/**\n * Check if configuration files exist and are valid\n */\nexport async function checkConfigs(): Promise<HealthCheckResult> {\n const cwd = process.cwd()\n const missingFiles: string[] = []\n const invalidFiles: string[] = []\n\n // Check required config files\n for (const file of REQUIRED_CONFIG_FILES) {\n const filePath = path.join(cwd, file)\n\n // Check for alternative extensions\n if (file.endsWith('.ts')) {\n const jsPath = path.join(cwd, file.replace('.ts', '.js'))\n const mjsPath = path.join(cwd, file.replace('.ts', '.mjs'))\n\n const tsExists = await fs.pathExists(filePath)\n const jsExists = await fs.pathExists(jsPath)\n const mjsExists = await fs.pathExists(mjsPath)\n\n if (!tsExists && !jsExists && !mjsExists) {\n // Skip next.config.ts since it may be .mjs by default\n if (!file.includes('next.config') && !file.includes('tailwind.config')) {\n missingFiles.push(file)\n }\n }\n continue\n }\n\n if (!await fs.pathExists(filePath)) {\n missingFiles.push(file)\n }\n }\n\n // Check tsconfig.json specifically and validate JSON syntax\n const tsconfigPath = path.join(cwd, 'tsconfig.json')\n if (await fs.pathExists(tsconfigPath)) {\n try {\n const content = await fs.readFile(tsconfigPath, 'utf-8')\n JSON.parse(content)\n } catch {\n invalidFiles.push('tsconfig.json')\n }\n } else {\n missingFiles.push('tsconfig.json')\n }\n\n // Check config directory if it exists\n const configDir = path.join(cwd, 'config')\n if (await fs.pathExists(configDir)) {\n const configFiles = await fs.readdir(configDir)\n const tsConfigFiles = configFiles.filter(f => f.endsWith('.ts'))\n\n // We don't validate TS syntax here since that requires compilation\n // but we check that the files are not empty\n for (const file of tsConfigFiles) {\n const filePath = path.join(configDir, file)\n try {\n const content = await fs.readFile(filePath, 'utf-8')\n if (content.trim().length === 0) {\n invalidFiles.push(`config/${file}`)\n }\n } catch {\n invalidFiles.push(`config/${file}`)\n }\n }\n }\n\n // Report results\n if (invalidFiles.length > 0) {\n return {\n name: 'Configuration',\n status: 'fail',\n message: `Invalid config files: ${invalidFiles.join(', ')}`,\n fix: 'Check the syntax of the invalid configuration files',\n }\n }\n\n if (missingFiles.length > 0) {\n return {\n name: 'Configuration',\n status: 'warn',\n message: `Missing config files: ${missingFiles.join(', ')}`,\n fix: 'Run: npx nextspark init to regenerate configuration',\n }\n }\n\n return {\n name: 'Configuration',\n status: 'pass',\n message: 'All config files valid',\n }\n}\n","/**\n * Database Health Check\n *\n * Verifies that DATABASE_URL is configured in the environment.\n */\n\nimport fs from 'fs-extra'\nimport path from 'path'\nimport type { HealthCheckResult } from '../index.js'\n\n/**\n * Parse a .env file and return key-value pairs\n */\nfunction parseEnvFile(content: string): Record<string, string> {\n const result: Record<string, string> = {}\n const lines = content.split('\\n')\n\n for (const line of lines) {\n const trimmed = line.trim()\n\n // Skip empty lines and comments\n if (!trimmed || trimmed.startsWith('#')) {\n continue\n }\n\n // Parse key=value\n const equalsIndex = trimmed.indexOf('=')\n if (equalsIndex > 0) {\n const key = trimmed.substring(0, equalsIndex).trim()\n let value = trimmed.substring(equalsIndex + 1).trim()\n\n // Remove quotes if present\n if ((value.startsWith('\"') && value.endsWith('\"')) ||\n (value.startsWith(\"'\") && value.endsWith(\"'\"))) {\n value = value.slice(1, -1)\n }\n\n result[key] = value\n }\n }\n\n return result\n}\n\n/**\n * Check if DATABASE_URL is configured\n */\nexport async function checkDatabase(): Promise<HealthCheckResult> {\n const cwd = process.cwd()\n\n // Check .env file\n const envPath = path.join(cwd, '.env')\n const envLocalPath = path.join(cwd, '.env.local')\n\n let envVars: Record<string, string> = {}\n\n // Try to read .env.local first (has priority)\n if (await fs.pathExists(envLocalPath)) {\n try {\n const content = await fs.readFile(envLocalPath, 'utf-8')\n envVars = { ...envVars, ...parseEnvFile(content) }\n } catch {\n // Ignore read errors\n }\n }\n\n // Then read .env\n if (await fs.pathExists(envPath)) {\n try {\n const content = await fs.readFile(envPath, 'utf-8')\n envVars = { ...envVars, ...parseEnvFile(content) }\n } catch {\n // Ignore read errors\n }\n }\n\n // Also check environment variable directly\n const databaseUrl = envVars['DATABASE_URL'] || process.env.DATABASE_URL\n\n // No .env files found\n if (!await fs.pathExists(envPath) && !await fs.pathExists(envLocalPath)) {\n return {\n name: 'Database',\n status: 'warn',\n message: 'No .env file found',\n fix: 'Copy .env.example to .env and configure DATABASE_URL',\n }\n }\n\n // DATABASE_URL not configured\n if (!databaseUrl) {\n return {\n name: 'Database',\n status: 'warn',\n message: 'DATABASE_URL not configured',\n fix: 'Add DATABASE_URL to .env',\n }\n }\n\n // DATABASE_URL is a placeholder\n if (databaseUrl.includes('your-') ||\n databaseUrl.includes('example') ||\n databaseUrl.includes('placeholder') ||\n databaseUrl === 'postgresql://') {\n return {\n name: 'Database',\n status: 'warn',\n message: 'DATABASE_URL appears to be a placeholder',\n fix: 'Update DATABASE_URL in .env with your actual database connection string',\n }\n }\n\n // Check if it looks like a valid connection string\n const isValidFormat = databaseUrl.startsWith('postgresql://') ||\n databaseUrl.startsWith('postgres://') ||\n databaseUrl.startsWith('mysql://') ||\n databaseUrl.startsWith('sqlite:')\n\n if (!isValidFormat) {\n return {\n name: 'Database',\n status: 'warn',\n message: 'DATABASE_URL format may be invalid',\n fix: 'Ensure DATABASE_URL is a valid database connection string',\n }\n }\n\n return {\n name: 'Database',\n status: 'pass',\n message: 'DATABASE_URL configured',\n }\n}\n","/**\n * Imports Health Check\n *\n * Verifies that core imports are accessible and not broken.\n */\n\nimport fs from 'fs-extra'\nimport path from 'path'\nimport type { HealthCheckResult } from '../index.js'\n\n/**\n * Core NextSpark imports that should be accessible\n */\nconst CORE_IMPORTS = [\n '@nextsparkjs/core',\n]\n\n/**\n * Common patterns that indicate broken imports in source files\n */\nconst BROKEN_IMPORT_PATTERNS = [\n // Non-existent local imports\n /from ['\"]\\.\\.?\\/.+['\"]/g,\n]\n\n/**\n * Check if @nextsparkjs/core is accessible\n */\nasync function checkCorePackage(cwd: string): Promise<{ accessible: boolean; reason?: string }> {\n const nodeModulesPath = path.join(cwd, 'node_modules', '@nextsparkjs', 'core')\n\n // Check if the package exists in node_modules\n if (!await fs.pathExists(nodeModulesPath)) {\n return { accessible: false, reason: '@nextsparkjs/core not found in node_modules' }\n }\n\n // Check if package.json exists\n const packageJsonPath = path.join(nodeModulesPath, 'package.json')\n if (!await fs.pathExists(packageJsonPath)) {\n return { accessible: false, reason: '@nextsparkjs/core package.json not found' }\n }\n\n // Check if main entry point exists\n try {\n const packageJson = await fs.readJson(packageJsonPath)\n const mainEntry = packageJson.main || packageJson.module || './dist/index.js'\n const mainPath = path.join(nodeModulesPath, mainEntry)\n\n if (!await fs.pathExists(mainPath)) {\n return { accessible: false, reason: '@nextsparkjs/core entry point not found' }\n }\n } catch {\n return { accessible: false, reason: 'Failed to read @nextsparkjs/core package.json' }\n }\n\n return { accessible: true }\n}\n\n/**\n * Scan source files for potentially broken imports\n */\nasync function scanForBrokenImports(cwd: string): Promise<string[]> {\n const brokenImports: string[] = []\n\n // Common source directories to scan\n const srcDirs = ['src', 'app', 'pages', 'components', 'lib']\n const existingDirs: string[] = []\n\n for (const dir of srcDirs) {\n const dirPath = path.join(cwd, dir)\n if (await fs.pathExists(dirPath)) {\n existingDirs.push(dirPath)\n }\n }\n\n // Scan each directory for .ts/.tsx files (limited to prevent performance issues)\n const maxFilesToScan = 50\n let filesScanned = 0\n\n for (const dir of existingDirs) {\n if (filesScanned >= maxFilesToScan) break\n\n try {\n const files = await fs.readdir(dir, { withFileTypes: true })\n\n for (const file of files) {\n if (filesScanned >= maxFilesToScan) break\n\n if (file.isFile() && (file.name.endsWith('.ts') || file.name.endsWith('.tsx'))) {\n const filePath = path.join(dir, file.name)\n try {\n const content = await fs.readFile(filePath, 'utf-8')\n\n // Check for imports from non-existent paths\n const importMatches = content.match(/from ['\"](@?[^'\"]+)['\"]/g)\n if (importMatches) {\n for (const match of importMatches) {\n const importPath = match.replace(/from ['\"]/g, '').replace(/['\"]/g, '')\n\n // Only check local imports\n if (importPath.startsWith('.')) {\n const absoluteImportPath = path.resolve(path.dirname(filePath), importPath)\n\n // Check for .ts, .tsx, .js, .jsx extensions and index files\n const possiblePaths = [\n absoluteImportPath,\n `${absoluteImportPath}.ts`,\n `${absoluteImportPath}.tsx`,\n `${absoluteImportPath}.js`,\n `${absoluteImportPath}.jsx`,\n path.join(absoluteImportPath, 'index.ts'),\n path.join(absoluteImportPath, 'index.tsx'),\n path.join(absoluteImportPath, 'index.js'),\n ]\n\n const exists = await Promise.any(\n possiblePaths.map(async p => {\n if (await fs.pathExists(p)) return true\n throw new Error('Not found')\n })\n ).catch(() => false)\n\n if (!exists) {\n brokenImports.push(`${file.name}: ${importPath}`)\n }\n }\n }\n }\n\n filesScanned++\n } catch {\n // Skip files that can't be read\n }\n }\n }\n } catch {\n // Skip directories that can't be read\n }\n }\n\n return brokenImports\n}\n\n/**\n * Check for broken imports in the project\n */\nexport async function checkImports(): Promise<HealthCheckResult> {\n const cwd = process.cwd()\n\n // Check if @nextsparkjs/core is accessible\n const coreCheck = await checkCorePackage(cwd)\n\n if (!coreCheck.accessible) {\n // Only warn if package.json lists it as a dependency\n const packageJsonPath = path.join(cwd, 'package.json')\n let hasCoreDep = false\n\n if (await fs.pathExists(packageJsonPath)) {\n try {\n const packageJson = await fs.readJson(packageJsonPath)\n hasCoreDep = !!(packageJson.dependencies?.['@nextsparkjs/core'] ||\n packageJson.devDependencies?.['@nextsparkjs/core'])\n } catch {\n // Ignore\n }\n }\n\n if (hasCoreDep) {\n return {\n name: 'Imports',\n status: 'fail',\n message: coreCheck.reason || '@nextsparkjs/core not accessible',\n fix: 'Run: pnpm install',\n }\n }\n }\n\n // Scan for broken local imports (quick check)\n try {\n const brokenImports = await scanForBrokenImports(cwd)\n\n if (brokenImports.length > 0) {\n const displayImports = brokenImports.slice(0, 3).join(', ')\n const remaining = brokenImports.length > 3 ? ` (+${brokenImports.length - 3} more)` : ''\n\n return {\n name: 'Imports',\n status: 'warn',\n message: `Potentially broken imports: ${displayImports}${remaining}`,\n fix: 'Check the import paths in the mentioned files',\n }\n }\n } catch {\n // If scanning fails, we still consider it a pass\n // since it might be a permissions issue\n }\n\n return {\n name: 'Imports',\n status: 'pass',\n message: 'No broken imports found',\n }\n}\n","import { spawn } from 'node:child_process';\nimport { existsSync, readFileSync } from 'node:fs';\nimport { join } from 'node:path';\nimport chalk from 'chalk';\nimport ora from 'ora';\nimport { getCoreDir, getProjectRoot } from '../utils/paths.js';\n\n/**\n * Load environment variables from project root .env file\n */\nfunction loadProjectEnv(projectRoot: string): Record<string, string> {\n const envPath = join(projectRoot, '.env');\n const envVars: Record<string, string> = {};\n\n if (existsSync(envPath)) {\n const content = readFileSync(envPath, 'utf-8');\n for (const line of content.split('\\n')) {\n const trimmed = line.trim();\n if (trimmed && !trimmed.startsWith('#')) {\n const [key, ...valueParts] = trimmed.split('=');\n if (key && valueParts.length > 0) {\n let value = valueParts.join('=');\n // Remove surrounding quotes\n if ((value.startsWith('\"') && value.endsWith('\"')) ||\n (value.startsWith(\"'\") && value.endsWith(\"'\"))) {\n value = value.slice(1, -1);\n }\n envVars[key] = value;\n }\n }\n }\n }\n\n return envVars;\n}\n\n/**\n * Run database migrations\n */\nexport async function dbMigrateCommand(): Promise<void> {\n const spinner = ora('Preparing to run migrations...').start();\n\n try {\n const coreDir = getCoreDir();\n const projectRoot = getProjectRoot();\n\n // Validate that core package exists\n const migrationsScript = join(coreDir, 'scripts', 'db', 'run-migrations.mjs');\n if (!existsSync(migrationsScript)) {\n spinner.fail('Migrations script not found');\n console.error(chalk.red(`Expected script at: ${migrationsScript}`));\n process.exit(1);\n }\n\n spinner.succeed('Core package found');\n\n // Load project .env file\n const projectEnv = loadProjectEnv(projectRoot);\n\n // Validate required environment variables\n if (!projectEnv.DATABASE_URL) {\n spinner.fail('DATABASE_URL not found in .env file');\n console.error(chalk.red('Please configure DATABASE_URL in your .env file'));\n process.exit(1);\n }\n\n if (!projectEnv.NEXT_PUBLIC_ACTIVE_THEME) {\n spinner.fail('NEXT_PUBLIC_ACTIVE_THEME not found in .env file');\n console.error(chalk.red('Please configure NEXT_PUBLIC_ACTIVE_THEME in your .env file'));\n process.exit(1);\n }\n\n spinner.start('Running database migrations...');\n\n const migrateProcess = spawn('node', [migrationsScript], {\n cwd: projectRoot,\n stdio: 'inherit',\n env: {\n ...projectEnv,\n ...process.env,\n NEXTSPARK_PROJECT_ROOT: projectRoot,\n NEXTSPARK_CORE_DIR: coreDir,\n },\n });\n\n migrateProcess.on('error', (err) => {\n spinner.fail('Migration failed');\n console.error(chalk.red(err.message));\n process.exit(1);\n });\n\n migrateProcess.on('close', (code) => {\n if (code === 0) {\n console.log(chalk.green('\\n✅ Migrations completed successfully!'));\n process.exit(0);\n } else {\n console.error(chalk.red(`\\n❌ Migrations failed with exit code ${code}`));\n process.exit(code ?? 1);\n }\n });\n } catch (error) {\n spinner.fail('Migration preparation failed');\n if (error instanceof Error) {\n console.error(chalk.red(error.message));\n }\n process.exit(1);\n }\n}\n\n/**\n * Seed the database with sample data\n * Note: This runs the same migration script as db:migrate,\n * which handles sample data as part of the migration process.\n */\nexport async function dbSeedCommand(): Promise<void> {\n console.log(chalk.cyan('ℹ️ Sample data is included as part of the migration process.'));\n console.log(chalk.cyan(' Running db:migrate to apply all migrations including sample data...\\n'));\n\n await dbMigrateCommand();\n}\n","import { existsSync, statSync, readdirSync, mkdirSync, copyFileSync, readFileSync } from 'node:fs';\nimport { join, dirname, relative } from 'node:path';\nimport chalk from 'chalk';\nimport ora from 'ora';\nimport { getCoreDir, getProjectRoot } from '../utils/paths.js';\n\ninterface SyncAppOptions {\n dryRun?: boolean;\n force?: boolean;\n backup?: boolean;\n verbose?: boolean;\n}\n\n// Patterns to exclude from template sync\n// (templates) = Next.js route groups auto-generated by theme system\nconst EXCLUDED_TEMPLATE_PATTERNS = ['(templates)'];\n\n// Root template files that should be synced to project root (not /app)\n// These are critical files that must stay in sync with core\nconst ROOT_TEMPLATE_FILES = [\n 'proxy.ts', // Next.js 16+ proxy (formerly middleware.ts) - required for auth/permission validation\n 'next.config.mjs', // Required for webpack aliases, transpilePackages, security headers\n 'tsconfig.json', // Required for proper path aliases and test file exclusions\n 'i18n.ts', // Required for next-intl configuration\n];\n\n// Display limits for file listings\nconst MAX_VERBOSE_FILES = 10;\nconst MAX_SUMMARY_FILES = 5;\n\n/**\n * Recursively get all files in a directory\n */\nfunction getAllFiles(dir: string, baseDir: string = dir): string[] {\n const files: string[] = [];\n\n if (!existsSync(dir)) {\n return files;\n }\n\n const entries = readdirSync(dir, { withFileTypes: true });\n\n for (const entry of entries) {\n const fullPath = join(dir, entry.name);\n const relativePath = relative(baseDir, fullPath);\n\n if (entry.isDirectory()) {\n files.push(...getAllFiles(fullPath, baseDir));\n } else if (entry.isFile()) {\n // Skip .DS_Store and README.md\n if (entry.name !== '.DS_Store' && entry.name !== 'README.md') {\n files.push(relativePath);\n }\n }\n }\n\n return files;\n}\n\n/**\n * Copy a file, creating parent directories if needed\n */\nfunction copyFile(source: string, target: string): void {\n const targetDir = dirname(target);\n if (!existsSync(targetDir)) {\n mkdirSync(targetDir, { recursive: true });\n }\n copyFileSync(source, target);\n}\n\n/**\n * Backup a directory by copying it\n */\nfunction backupDirectory(source: string, target: string): void {\n if (!existsSync(source)) {\n return;\n }\n\n const files = getAllFiles(source);\n for (const file of files) {\n const sourcePath = join(source, file);\n const targetPath = join(target, file);\n copyFile(sourcePath, targetPath);\n }\n}\n\n/**\n * Get core package version\n */\nfunction getCoreVersion(coreDir: string): string {\n try {\n const pkgPath = join(coreDir, 'package.json');\n const pkg = JSON.parse(readFileSync(pkgPath, 'utf-8'));\n return pkg.version || 'unknown';\n } catch {\n return 'unknown';\n }\n}\n\nexport async function syncAppCommand(options: SyncAppOptions): Promise<void> {\n const spinner = ora({ text: 'Preparing sync...', isSilent: options.dryRun }).start();\n\n try {\n const coreDir = getCoreDir();\n const projectRoot = getProjectRoot();\n const coreVersion = getCoreVersion(coreDir);\n\n // Templates directory in core\n const templatesDir = join(coreDir, 'templates', 'app');\n\n // Target app directory in project\n const appDir = join(projectRoot, 'app');\n\n // Verify templates directory exists\n if (!existsSync(templatesDir)) {\n spinner.fail('Templates directory not found in @nextsparkjs/core');\n console.error(chalk.red(`\\n Expected path: ${templatesDir}`));\n process.exit(1);\n }\n\n // Verify app directory exists (project must be initialized)\n if (!existsSync(appDir)) {\n spinner.fail('No /app directory found');\n console.error(chalk.red('\\n This project does not have an /app folder.'));\n console.error(chalk.yellow(' Run \"nextspark init\" first to initialize your project.\\n'));\n process.exit(1);\n }\n\n spinner.text = 'Scanning template files...';\n\n // Get all template files (excluding auto-generated folders)\n const templateFiles = getAllFiles(templatesDir)\n .filter(f => !EXCLUDED_TEMPLATE_PATTERNS.some(pattern => f.startsWith(pattern)));\n\n // Get all existing app files\n const existingAppFiles = getAllFiles(appDir);\n\n // Determine which files are custom (not in templates)\n const customFiles = existingAppFiles.filter(f => !templateFiles.includes(f));\n\n // Files that will be updated\n const filesToUpdate = templateFiles;\n\n spinner.succeed('Scan complete');\n\n // Show summary\n console.log(chalk.cyan(`\\n Syncing /app with @nextsparkjs/core@${coreVersion}...\\n`));\n\n if (options.dryRun) {\n console.log(chalk.yellow(' [DRY RUN] No changes will be made\\n'));\n }\n\n if (options.verbose) {\n console.log(chalk.gray(' Files to sync:'));\n for (const file of filesToUpdate) {\n const targetPath = join(appDir, file);\n const status = existsSync(targetPath) ? chalk.yellow('update') : chalk.green('create');\n console.log(chalk.gray(` ${status} ${file}`));\n }\n console.log();\n }\n\n // Show stats\n console.log(chalk.white(` Template files: ${filesToUpdate.length}`));\n console.log(chalk.white(` Custom files preserved: ${customFiles.length}`));\n\n if (customFiles.length > 0 && options.verbose) {\n console.log(chalk.gray('\\n Custom files (will be preserved):'));\n for (const file of customFiles.slice(0, MAX_VERBOSE_FILES)) {\n console.log(chalk.gray(` - ${file}`));\n }\n if (customFiles.length > MAX_VERBOSE_FILES) {\n console.log(chalk.gray(` ... and ${customFiles.length - MAX_VERBOSE_FILES} more`));\n }\n }\n\n // Confirmation prompt (unless --force or --dry-run)\n if (!options.force && !options.dryRun) {\n console.log(chalk.yellow(`\\n This will overwrite ${filesToUpdate.length} core template files.`));\n console.log(chalk.gray(' Run with --dry-run to preview changes, or --force to skip this prompt.\\n'));\n\n try {\n const { confirm } = await import('@inquirer/prompts');\n const confirmed = await confirm({\n message: 'Proceed with sync?',\n default: true,\n });\n\n if (!confirmed) {\n console.log(chalk.yellow('\\n Sync cancelled.\\n'));\n process.exit(0);\n }\n } catch (promptError) {\n console.error(chalk.red('\\n Failed to load confirmation prompt. Use --force to skip.\\n'));\n process.exit(1);\n }\n }\n\n // Perform backup if requested\n if (options.backup && !options.dryRun) {\n const backupDir = join(projectRoot, `app.backup.v${coreVersion}.${Date.now()}`);\n spinner.start('Creating backup...');\n backupDirectory(appDir, backupDir);\n spinner.succeed(`Backup created: ${relative(projectRoot, backupDir)}`);\n }\n\n // Perform sync\n if (!options.dryRun) {\n spinner.start('Syncing files...');\n\n let updated = 0;\n let created = 0;\n\n for (const file of filesToUpdate) {\n const sourcePath = join(templatesDir, file);\n const targetPath = join(appDir, file);\n const isNew = !existsSync(targetPath);\n\n copyFile(sourcePath, targetPath);\n\n if (isNew) {\n created++;\n } else {\n updated++;\n }\n\n if (options.verbose) {\n spinner.text = `Syncing: ${file}`;\n }\n }\n\n spinner.succeed(`Synced ${filesToUpdate.length} files (${updated} updated, ${created} created)`);\n\n // Sync root template files (proxy.ts, next.config.mjs, etc.)\n const rootTemplatesDir = join(coreDir, 'templates');\n let rootUpdated = 0;\n let rootCreated = 0;\n\n for (const file of ROOT_TEMPLATE_FILES) {\n const sourcePath = join(rootTemplatesDir, file);\n const targetPath = join(projectRoot, file);\n\n if (existsSync(sourcePath)) {\n const isNew = !existsSync(targetPath);\n copyFile(sourcePath, targetPath);\n\n if (isNew) {\n rootCreated++;\n if (options.verbose) {\n console.log(chalk.green(` + Created: ${file}`));\n }\n } else {\n rootUpdated++;\n if (options.verbose) {\n console.log(chalk.yellow(` ~ Updated: ${file}`));\n }\n }\n }\n }\n\n if (rootUpdated + rootCreated > 0) {\n console.log(chalk.gray(` Root files: ${rootUpdated} updated, ${rootCreated} created`));\n }\n }\n\n // Success message\n console.log(chalk.green('\\n \\u2705 Sync complete!\\n'));\n\n if (customFiles.length > 0) {\n console.log(chalk.gray(` Preserved ${customFiles.length} custom file(s):`));\n for (const file of customFiles.slice(0, MAX_SUMMARY_FILES)) {\n console.log(chalk.gray(` - app/${file}`));\n }\n if (customFiles.length > MAX_SUMMARY_FILES) {\n console.log(chalk.gray(` ... and ${customFiles.length - MAX_SUMMARY_FILES} more\\n`));\n } else {\n console.log();\n }\n }\n\n } catch (error) {\n spinner.fail('Sync failed');\n if (error instanceof Error) {\n console.error(chalk.red(`\\n Error: ${error.message}\\n`));\n if (options.verbose && error.stack) {\n console.error(chalk.gray(` Stack trace:\\n${error.stack}\\n`));\n }\n }\n process.exit(1);\n }\n}\n","import { existsSync } from 'node:fs';\nimport { join } from 'node:path';\nimport { execSync } from 'node:child_process';\nimport chalk from 'chalk';\nimport ora from 'ora';\nimport { getAIWorkflowDir } from '../utils/paths.js';\n\ninterface SetupAIOptions {\n editor?: string;\n}\n\nconst VALID_EDITORS = ['claude', 'cursor', 'antigravity', 'all'];\n\nexport async function setupAICommand(options: SetupAIOptions): Promise<void> {\n const editor = options.editor || 'claude';\n\n if (!VALID_EDITORS.includes(editor)) {\n console.log(chalk.red(` Unknown editor: ${editor}`));\n console.log(chalk.gray(` Available: ${VALID_EDITORS.join(', ')}`));\n process.exit(1);\n }\n\n console.log('');\n console.log(chalk.cyan(' AI Workflow Setup'));\n console.log(chalk.gray(' ' + '-'.repeat(40)));\n console.log('');\n\n // 1. Find ai-workflow package\n const pkgPath = getAIWorkflowDir();\n\n if (!pkgPath) {\n console.log(chalk.red(' @nextsparkjs/ai-workflow package not found.'));\n console.log('');\n console.log(chalk.gray(' Install it first:'));\n console.log(chalk.cyan(' pnpm add -D -w @nextsparkjs/ai-workflow'));\n console.log('');\n process.exit(1);\n }\n\n // 2. Verify setup script exists\n const setupScript = join(pkgPath, 'scripts', 'setup.mjs');\n if (!existsSync(setupScript)) {\n console.log(chalk.red(' Setup script not found in ai-workflow package.'));\n console.log(chalk.gray(` Expected: ${setupScript}`));\n process.exit(1);\n }\n\n // 3. Run setup script\n const spinner = ora({\n text: `Setting up AI workflow for ${editor}...`,\n prefixText: ' ',\n }).start();\n\n try {\n spinner.stop();\n execSync(`node \"${setupScript}\" ${editor}`, {\n cwd: process.cwd(),\n stdio: 'inherit',\n });\n } catch (error) {\n console.log('');\n console.log(chalk.red(' AI workflow setup failed.'));\n if (error instanceof Error) {\n console.log(chalk.gray(` ${error.message}`));\n }\n process.exit(1);\n }\n}\n","import { existsSync } from 'node:fs';\nimport { join } from 'node:path';\nimport { execSync } from 'node:child_process';\nimport chalk from 'chalk';\nimport ora from 'ora';\nimport { getAIWorkflowDir } from '../utils/paths.js';\n\ninterface SyncAIOptions {\n editor?: string;\n force?: boolean;\n}\n\nconst VALID_EDITORS = ['claude', 'cursor', 'antigravity', 'all'];\n\nexport async function syncAICommand(options: SyncAIOptions): Promise<void> {\n const editor = options.editor || 'claude';\n\n if (!VALID_EDITORS.includes(editor)) {\n console.log(chalk.red(` Unknown editor: ${editor}`));\n console.log(chalk.gray(` Available: ${VALID_EDITORS.join(', ')}`));\n process.exit(1);\n }\n\n console.log('');\n console.log(chalk.cyan(' AI Workflow Sync'));\n console.log(chalk.gray(' ' + '-'.repeat(40)));\n console.log('');\n\n // 1. Verify .claude/ exists (must have been set up already)\n const editorDir = editor === 'cursor' ? '.cursor' : '.claude';\n const editorDirPath = join(process.cwd(), editorDir);\n\n if (!existsSync(editorDirPath)) {\n console.log(chalk.red(` No ${editorDir}/ directory found.`));\n console.log('');\n console.log(chalk.gray(' AI workflow must be set up first. Run:'));\n console.log(chalk.cyan(' nextspark setup:ai --editor ' + editor));\n console.log('');\n process.exit(1);\n }\n\n // 2. Find ai-workflow package\n const pkgPath = getAIWorkflowDir();\n\n if (!pkgPath) {\n console.log(chalk.red(' @nextsparkjs/ai-workflow package not found.'));\n console.log('');\n console.log(chalk.gray(' Install it first:'));\n console.log(chalk.cyan(' pnpm add -D -w @nextsparkjs/ai-workflow'));\n console.log('');\n process.exit(1);\n }\n\n // 3. Verify setup script exists\n const setupScript = join(pkgPath, 'scripts', 'setup.mjs');\n if (!existsSync(setupScript)) {\n console.log(chalk.red(' Setup script not found in ai-workflow package.'));\n console.log(chalk.gray(` Expected: ${setupScript}`));\n process.exit(1);\n }\n\n // 4. Confirmation prompt (unless --force)\n if (!options.force) {\n console.log(chalk.yellow(' This will sync AI workflow files from @nextsparkjs/ai-workflow.'));\n console.log(chalk.gray(' Framework files will be overwritten. Custom files will be preserved.'));\n console.log(chalk.gray(' Config JSON files will never be overwritten.\\n'));\n\n try {\n const { confirm } = await import('@inquirer/prompts');\n const confirmed = await confirm({\n message: 'Proceed with sync?',\n default: true,\n });\n\n if (!confirmed) {\n console.log(chalk.yellow('\\n Sync cancelled.\\n'));\n process.exit(0);\n }\n } catch {\n console.error(chalk.red('\\n Failed to load confirmation prompt. Use --force to skip.\\n'));\n process.exit(1);\n }\n }\n\n // 5. Run setup script\n const spinner = ora({\n text: `Syncing AI workflow for ${editor}...`,\n prefixText: ' ',\n }).start();\n\n try {\n spinner.stop();\n execSync(`node \"${setupScript}\" ${editor}`, {\n cwd: process.cwd(),\n stdio: 'inherit',\n });\n } catch (error) {\n console.log('');\n console.log(chalk.red(' AI workflow sync failed.'));\n if (error instanceof Error) {\n console.log(chalk.gray(` ${error.message}`));\n }\n process.exit(1);\n }\n}\n"],"mappings":"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","names":["chalk","readFileSync","existsSync","mkdirSync","writeFileSync","readFileSync","join","chalk","ora","chalk","ora","confirm","select","existsSync","join","select","select","select","checkbox","checkbox","select","select","select","checkbox","checkbox","checkbox","checkbox","checkbox","checkbox","checkbox","checkbox","checkbox","confirm","checkbox","confirm","select","chalk","checkbox","chalk","confirm","input","confirm","input","fs","path","fileURLToPath","fileURLToPath","__filename","__dirname","config","fs","path","getTargetThemesDir","config","fs","path","getTargetThemesDir","path","config","fs","fs","path","fileURLToPath","__filename","__dirname","getTemplatesDir","config","existsSync","readFileSync","join","chalk","ora","chalk","readFileSync","join","chalk","pkg","THEME_REQUIRED_PLUGINS","join","existsSync","chalk","readFileSync","installTheme","ora","success","chalk","installTheme","fs","path","fileURLToPath","__filename","fileURLToPath","__dirname","path","fs","fs","path","fileURLToPath","__filename","__dirname","config","__filename","fileURLToPath","__dirname","path","getTemplatesDir","path","__dirname","fs","config","chalk","config","config","confirm","ora","chalk","join","select","existsSync","existsSync","join","writeFileSync","ora","mkdirSync","readFileSync","chalk","existsSync","cpSync","readFileSync","writeFileSync","mkdirSync","join","chalk","ora","execSync","pkg","chalk","chalk","fs","path","fs","path","path","fs","fs","path","fs","path","path","fs","chalk","chalk","existsSync","readFileSync","join","chalk","ora","join","existsSync","readFileSync","ora","chalk","existsSync","readdirSync","mkdirSync","readFileSync","join","dirname","chalk","ora","existsSync","readdirSync","join","dirname","mkdirSync","getCoreVersion","pkg","readFileSync","ora","chalk","confirm","existsSync","join","execSync","chalk","ora","chalk","join","existsSync","ora","execSync","existsSync","join","execSync","chalk","ora","VALID_EDITORS","chalk","join","existsSync","confirm","ora","execSync","readFileSync","chalk"]}
|