@raftlabs/raftstack 1.7.2 → 1.8.0

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.
Files changed (3) hide show
  1. package/dist/cli.js +1066 -203
  2. package/dist/cli.js.map +1 -1
  3. package/package.json +1 -1
package/dist/cli.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/cli.ts","../src/commands/init.ts","../src/prompts/index.ts","../src/utils/detect-project.ts","../src/utils/detect-package-manager.ts","../src/generators/husky.ts","../src/utils/file-system.ts","../src/generators/commitlint.ts","../src/generators/cz-git.ts","../src/generators/lint-staged.ts","../src/utils/package-json.ts","../src/generators/branch-validation.ts","../src/generators/pr-template.ts","../src/generators/github-workflows.ts","../src/generators/codeowners.ts","../src/generators/ai-review.ts","../src/generators/branch-protection.ts","../src/generators/contributing.ts","../src/generators/prettier.ts","../src/generators/claude-skills.ts","../src/generators/eslint.ts","../src/generators/quick-reference.ts","../src/utils/git.ts","../src/commands/setup-protection.ts","../src/commands/metrics.ts","../package.json"],"sourcesContent":["import { Command } from \"commander\";\nimport { runInit } from \"./commands/init.js\";\nimport { runSetupProtection } from \"./commands/setup-protection.js\";\nimport { runMetrics } from \"./commands/metrics.js\";\nimport pkg from \"../package.json\" assert { type: \"json\" };\n\nconst program = new Command();\n\nprogram\n .name(\"raftstack\")\n .description(\n \"CLI tool for setting up Git hooks, commit conventions, and GitHub integration\"\n )\n .version(pkg.version);\n\nprogram\n .command(\"init\")\n .description(\"Initialize RaftStack configuration in your project\")\n .action(async () => {\n await runInit(process.cwd());\n });\n\nprogram\n .command(\"setup-protection\")\n .description(\"Configure GitHub branch protection rules via API\")\n .action(async () => {\n await runSetupProtection(process.cwd());\n });\n\nprogram\n .command(\"metrics\")\n .description(\"Analyze repository compliance with RaftStack conventions\")\n .action(async () => {\n await runMetrics(process.cwd());\n });\n\nprogram.parse();\n","import * as p from \"@clack/prompts\";\nimport pc from \"picocolors\";\nimport type { GeneratorResult, RaftStackConfig } from \"../types/config.js\";\nimport { collectConfig } from \"../prompts/index.js\";\nimport {\n generateHuskyHooks,\n generateCommitlint,\n generateCzGit,\n getLintStagedConfig,\n generateBranchValidation,\n generatePRTemplate,\n generateGitHubWorkflows,\n generateCodeowners,\n generateAIReview,\n generateBranchProtectionDocs,\n generateContributing,\n generatePrettier,\n generateClaudeSkills,\n generateQuickReference,\n generateEslint,\n detectReact,\n} from \"../generators/index.js\";\nimport {\n addPackageJsonConfig,\n mergeScripts,\n readPackageJson,\n writePackageJson,\n installPackages,\n RAFTSTACK_PACKAGES,\n REACT_ESLINT_PACKAGES,\n} from \"../utils/package-json.js\";\nimport { isGitRepo } from \"../utils/git.js\";\n\n/**\n * Merge generator results\n */\nfunction mergeResults(results: GeneratorResult[]): GeneratorResult {\n return results.reduce(\n (acc, result) => ({\n created: [...acc.created, ...result.created],\n modified: [...acc.modified, ...result.modified],\n skipped: [...acc.skipped, ...result.skipped],\n backedUp: [...acc.backedUp, ...result.backedUp],\n }),\n { created: [], modified: [], skipped: [], backedUp: [] }\n );\n}\n\n/**\n * Update package.json with required scripts and lint-staged config\n * (Dependencies are installed separately via CLI)\n */\nasync function updateProjectPackageJson(\n targetDir: string,\n config: RaftStackConfig\n): Promise<GeneratorResult> {\n const result: GeneratorResult = {\n created: [],\n modified: [],\n skipped: [],\n backedUp: [],\n };\n\n try {\n let pkg = await readPackageJson(targetDir);\n\n // Add scripts\n const scripts: Record<string, string> = {\n prepare: \"husky\",\n commit: \"czg\",\n // ESLint scripts (always added since we install ESLint)\n lint: \"eslint .\",\n \"lint:fix\": \"eslint . --fix\",\n // Prettier scripts (always added since we install Prettier)\n format: \"prettier --write .\",\n \"format:check\": \"prettier --check .\",\n };\n\n // Add typecheck script if TypeScript is detected\n if (config.usesTypeScript) {\n scripts.typecheck = \"tsc --noEmit\";\n }\n\n pkg = mergeScripts(pkg, scripts, false);\n\n // Add lint-staged config to package.json (instead of separate file)\n // Always enable eslint and prettier since we're installing them\n const lintStagedConfig = getLintStagedConfig(\n true, // usesEslint - always true now since we install it\n true, // usesPrettier - always true now since we install it\n config.usesTypeScript\n );\n pkg = addPackageJsonConfig(pkg, \"lint-staged\", lintStagedConfig, true);\n\n await writePackageJson(pkg, targetDir);\n result.modified.push(\"package.json\");\n } catch (error) {\n result.skipped.push(\"package.json (error updating)\");\n }\n\n return result;\n}\n\n/**\n * Run the init command\n */\nexport async function runInit(targetDir: string = process.cwd()): Promise<void> {\n // Check if this is a git repository\n const isRepo = await isGitRepo(targetDir);\n if (!isRepo) {\n p.log.warn(\n pc.yellow(\n \"This directory is not a git repository. Some features may not work correctly.\"\n )\n );\n const proceed = await p.confirm({\n message: \"Continue anyway?\",\n initialValue: false,\n });\n\n if (p.isCancel(proceed) || !proceed) {\n p.cancel(\"Setup cancelled.\");\n process.exit(0);\n }\n }\n\n // Collect configuration from user\n const config = await collectConfig(targetDir);\n\n if (!config) {\n return;\n }\n\n // Detect React for conditional dependencies\n const usesReact = await detectReact(targetDir);\n\n // Install dependencies using CLI\n const installSpinner = p.spinner();\n const packagesToInstall = usesReact\n ? [...RAFTSTACK_PACKAGES, ...REACT_ESLINT_PACKAGES]\n : RAFTSTACK_PACKAGES;\n\n installSpinner.start(\"Installing dependencies...\");\n const installResult = await installPackages(\n config.packageManager,\n packagesToInstall,\n targetDir\n );\n\n let installFailed = false;\n if (installResult.success) {\n installSpinner.stop(\"Dependencies installed!\");\n } else {\n installSpinner.stop(\"Failed to install dependencies\");\n p.log.warn(\n pc.yellow(\n `Could not install dependencies automatically: ${installResult.error || \"Unknown error\"}`\n )\n );\n p.log.info(\n pc.dim(\n `You can install them manually with: ${config.packageManager.name} ${config.packageManager.addDev} ${packagesToInstall.join(\" \")}`\n )\n );\n installFailed = true;\n }\n\n // Generate files with progress spinner\n const spinner = p.spinner();\n spinner.start(\"Generating configuration files...\");\n\n const results: GeneratorResult[] = [];\n\n try {\n // Core Git hooks and commit conventions\n results.push(\n await generateHuskyHooks(targetDir, config.projectType, config.packageManager)\n );\n results.push(await generateCommitlint(targetDir, config.asanaBaseUrl));\n results.push(await generateCzGit(targetDir, config.asanaBaseUrl));\n results.push(await generateBranchValidation(targetDir));\n\n // ESLint configuration (always generate since we install it)\n results.push(await generateEslint(targetDir, config.usesTypeScript, false));\n\n // Prettier (always generate since we install it)\n results.push(await generatePrettier(targetDir));\n\n // GitHub integration\n results.push(await generatePRTemplate(targetDir, !!config.asanaBaseUrl));\n results.push(\n await generateGitHubWorkflows(\n targetDir,\n config.projectType,\n config.usesTypeScript,\n true, // usesEslint - always true now\n config.packageManager\n )\n );\n results.push(await generateCodeowners(targetDir, config.codeowners));\n results.push(await generateAIReview(targetDir, config.aiReviewTool));\n results.push(await generateBranchProtectionDocs(targetDir));\n\n // Documentation\n results.push(\n await generateContributing(targetDir, !!config.asanaBaseUrl, config.packageManager)\n );\n results.push(await generateQuickReference(targetDir, config.packageManager));\n\n // Claude Code skills for AI-assisted development\n results.push(await generateClaudeSkills(targetDir, {\n includeAsana: !!config.asanaBaseUrl\n }));\n\n // Update package.json (scripts and lint-staged config)\n results.push(await updateProjectPackageJson(targetDir, config));\n\n spinner.stop(\"Configuration files generated!\");\n } catch (error) {\n spinner.stop(\"Error generating files\");\n p.log.error(\n pc.red(\n `Error: ${error instanceof Error ? error.message : \"Unknown error\"}`\n )\n );\n process.exit(1);\n }\n\n // Merge all results\n const finalResult = mergeResults(results);\n\n // Show summary\n console.log();\n\n if (finalResult.created.length > 0) {\n p.log.success(pc.green(\"Created files:\"));\n for (const file of finalResult.created) {\n console.log(` ${pc.dim(\"+\")} ${file}`);\n }\n }\n\n if (finalResult.modified.length > 0) {\n console.log();\n p.log.info(pc.blue(\"Modified files:\"));\n for (const file of finalResult.modified) {\n console.log(` ${pc.dim(\"~\")} ${file}`);\n }\n }\n\n if (finalResult.skipped.length > 0) {\n console.log();\n p.log.warn(pc.yellow(\"Skipped (already exist):\"));\n for (const file of finalResult.skipped) {\n console.log(` ${pc.dim(\"-\")} ${file}`);\n }\n }\n\n if (finalResult.backedUp.length > 0) {\n console.log();\n p.log.info(pc.dim(\"Backed up files:\"));\n for (const file of finalResult.backedUp) {\n console.log(` ${pc.dim(\"→\")} ${file}`);\n }\n }\n\n // Show next steps\n console.log();\n const nextSteps = installFailed\n ? [\n `${pc.cyan(\"1.\")} Run ${pc.yellow(config.packageManager.install)} to install dependencies`,\n `${pc.cyan(\"2.\")} Review the generated configuration files`,\n `${pc.cyan(\"3.\")} Use ${pc.yellow(`${config.packageManager.run} commit`)} for interactive commits`,\n `${pc.cyan(\"4.\")} Set up branch protection rules (see .github/BRANCH_PROTECTION_SETUP.md)`,\n ]\n : [\n `${pc.cyan(\"1.\")} Review the generated configuration files`,\n `${pc.cyan(\"2.\")} Use ${pc.yellow(`${config.packageManager.run} commit`)} for interactive commits`,\n `${pc.cyan(\"3.\")} Set up branch protection rules (see .github/BRANCH_PROTECTION_SETUP.md)`,\n ];\n p.note(nextSteps.join(\"\\n\"), \"Next Steps\");\n\n p.outro(pc.green(\"RaftStack setup complete! Happy coding! 🚀\"));\n}\n","import * as p from \"@clack/prompts\";\nimport pc from \"picocolors\";\nimport type {\n AIReviewTool,\n DetectionResult,\n PackageManager,\n PackageManagerInfo,\n ProjectType,\n RaftStackConfig,\n} from \"../types/config.js\";\nimport {\n detectProjectType,\n getProjectTypeDescription,\n hasTypeScript,\n hasEslint,\n hasPrettier,\n detectPackageManager,\n getPackageManagerInfo,\n getPackageManagerDescription,\n} from \"../utils/detect-project.js\";\n\n/**\n * Show welcome banner\n */\nexport function showWelcome(): void {\n console.log();\n p.intro(pc.bgCyan(pc.black(\" RaftStack \")));\n console.log(\n pc.dim(\" Setting up Git hooks, commit conventions, and GitHub integration\\n\")\n );\n}\n\n/**\n * Prompt for project type confirmation\n */\nexport async function promptProjectType(\n detection: DetectionResult\n): Promise<ProjectType> {\n const description = getProjectTypeDescription(detection.type);\n const confidenceText =\n detection.confidence === \"high\"\n ? pc.green(\"high confidence\")\n : detection.confidence === \"medium\"\n ? pc.yellow(\"medium confidence\")\n : pc.red(\"low confidence\");\n\n const confirmed = await p.confirm({\n message: `Detected ${pc.cyan(description)} (${confidenceText}). Is this correct?`,\n initialValue: true,\n });\n\n if (p.isCancel(confirmed)) {\n p.cancel(\"Setup cancelled.\");\n process.exit(0);\n }\n\n if (confirmed) {\n return detection.type;\n }\n\n const selected = await p.select({\n message: \"Select your project type:\",\n options: [\n { value: \"nx\", label: \"NX Monorepo\" },\n { value: \"turbo\", label: \"Turborepo\" },\n { value: \"pnpm-workspace\", label: \"pnpm Workspace\" },\n { value: \"single\", label: \"Single Package\" },\n ],\n });\n\n if (p.isCancel(selected)) {\n p.cancel(\"Setup cancelled.\");\n process.exit(0);\n }\n\n return selected as ProjectType;\n}\n\n/**\n * Prompt for Asana configuration\n */\nexport async function promptAsanaConfig(): Promise<string | undefined> {\n const useAsana = await p.confirm({\n message: \"Do you want to link commits to Asana tasks?\",\n initialValue: true,\n });\n\n if (p.isCancel(useAsana)) {\n p.cancel(\"Setup cancelled.\");\n process.exit(0);\n }\n\n if (!useAsana) {\n return undefined;\n }\n\n const baseUrl = await p.text({\n message: \"Enter your Asana workspace URL:\",\n placeholder: \"https://app.asana.com/0/workspace-id\",\n validate: (value) => {\n if (!value) return \"URL is required\";\n if (!value.startsWith(\"https://app.asana.com/\")) {\n return \"URL must start with https://app.asana.com/\";\n }\n return undefined;\n },\n });\n\n if (p.isCancel(baseUrl)) {\n p.cancel(\"Setup cancelled.\");\n process.exit(0);\n }\n\n return baseUrl;\n}\n\n/**\n * Prompt for AI review tool selection\n */\nexport async function promptAIReview(): Promise<AIReviewTool> {\n const selected = await p.select({\n message: \"Select an AI code review tool (optional):\",\n options: [\n {\n value: \"none\",\n label: \"None\",\n hint: \"Skip AI review setup\",\n },\n {\n value: \"coderabbit\",\n label: \"CodeRabbit\",\n hint: \"AI-powered code review\",\n },\n {\n value: \"copilot\",\n label: \"GitHub Copilot\",\n hint: \"GitHub's AI code review\",\n },\n ],\n });\n\n if (p.isCancel(selected)) {\n p.cancel(\"Setup cancelled.\");\n process.exit(0);\n }\n\n return selected as AIReviewTool;\n}\n\n/**\n * Prompt for CODEOWNERS\n */\nexport async function promptCodeowners(): Promise<string[]> {\n const addOwners = await p.confirm({\n message: \"Do you want to set up CODEOWNERS for automatic PR reviewers?\",\n initialValue: true,\n });\n\n if (p.isCancel(addOwners)) {\n p.cancel(\"Setup cancelled.\");\n process.exit(0);\n }\n\n if (!addOwners) {\n return [];\n }\n\n const owners = await p.text({\n message: \"Enter GitHub usernames (comma-separated):\",\n placeholder: \"@username1, @username2\",\n validate: (value) => {\n if (!value.trim()) return \"At least one username is required\";\n return undefined;\n },\n });\n\n if (p.isCancel(owners)) {\n p.cancel(\"Setup cancelled.\");\n process.exit(0);\n }\n\n return owners\n .split(\",\")\n .map((u) => u.trim())\n .filter(Boolean)\n .map((u) => (u.startsWith(\"@\") ? u : `@${u}`));\n}\n\n/**\n * Prompt for package manager selection\n */\nexport async function promptPackageManager(\n targetDir: string\n): Promise<PackageManagerInfo> {\n // Try to auto-detect from lockfiles\n const detected = detectPackageManager(targetDir);\n\n if (detected) {\n const description = getPackageManagerDescription(detected);\n p.log.info(`Detected ${pc.cyan(description)} from lockfile`);\n return detected;\n }\n\n // No lockfile found - prompt user to select\n p.log.warn(\"No package manager lockfile detected\");\n\n const selected = await p.select({\n message: \"Select your package manager:\",\n options: [\n {\n value: \"npm\",\n label: \"npm\",\n hint: \"Node Package Manager (default)\",\n },\n {\n value: \"pnpm\",\n label: \"pnpm\",\n hint: \"Performant npm\",\n },\n {\n value: \"yarn\",\n label: \"Yarn Classic (1.x)\",\n hint: \"Classic Yarn\",\n },\n {\n value: \"yarn-berry\",\n label: \"Yarn Berry (2+)\",\n hint: \"Modern Yarn\",\n },\n ],\n });\n\n if (p.isCancel(selected)) {\n p.cancel(\"Setup cancelled.\");\n process.exit(0);\n }\n\n return getPackageManagerInfo(selected as PackageManager);\n}\n\n/**\n * Show summary before generating files\n */\nexport async function promptConfirmation(\n config: RaftStackConfig\n): Promise<boolean> {\n console.log();\n p.note(\n [\n `${pc.cyan(\"Project Type:\")} ${getProjectTypeDescription(config.projectType)}`,\n `${pc.cyan(\"Package Manager:\")} ${getPackageManagerDescription(config.packageManager)}`,\n `${pc.cyan(\"TypeScript:\")} ${config.usesTypeScript ? \"Yes\" : \"No\"}`,\n `${pc.cyan(\"ESLint:\")} ${config.usesEslint ? \"Yes\" : \"No\"}`,\n `${pc.cyan(\"Prettier:\")} ${config.usesPrettier ? \"Yes\" : \"No\"}`,\n `${pc.cyan(\"Asana Integration:\")} ${config.asanaBaseUrl ? \"Yes\" : \"No\"}`,\n `${pc.cyan(\"AI Review:\")} ${config.aiReviewTool === \"none\" ? \"None\" : config.aiReviewTool}`,\n `${pc.cyan(\"CODEOWNERS:\")} ${config.codeowners.length > 0 ? config.codeowners.join(\", \") : \"None\"}`,\n ].join(\"\\n\"),\n \"Configuration Summary\"\n );\n\n const confirmed = await p.confirm({\n message: \"Generate configuration files?\",\n initialValue: true,\n });\n\n if (p.isCancel(confirmed)) {\n p.cancel(\"Setup cancelled.\");\n process.exit(0);\n }\n\n return confirmed;\n}\n\n/**\n * Run full prompt flow and collect configuration\n */\nexport async function collectConfig(\n targetDir: string = process.cwd()\n): Promise<RaftStackConfig | null> {\n showWelcome();\n\n // Detect project type\n const detection = await detectProjectType(targetDir);\n const projectType = await promptProjectType(detection);\n\n // Detect package manager\n const packageManager = await promptPackageManager(targetDir);\n\n // Detect existing tooling\n const usesTypeScript = await hasTypeScript(targetDir);\n const usesEslint = await hasEslint(targetDir);\n const usesPrettier = await hasPrettier(targetDir);\n\n // Collect user preferences\n const asanaBaseUrl = await promptAsanaConfig();\n const aiReviewTool = await promptAIReview();\n const codeowners = await promptCodeowners();\n\n const config: RaftStackConfig = {\n projectType,\n packageManager,\n asanaBaseUrl,\n aiReviewTool,\n codeowners,\n usesTypeScript,\n usesEslint,\n usesPrettier,\n };\n\n // Confirm before proceeding\n const confirmed = await promptConfirmation(config);\n\n if (!confirmed) {\n p.cancel(\"Setup cancelled.\");\n return null;\n }\n\n return config;\n}\n","import { existsSync } from \"node:fs\";\nimport { readFile } from \"node:fs/promises\";\nimport { join } from \"node:path\";\nimport type { DetectionResult, ProjectType } from \"../types/config.js\";\n\ninterface IndicatorCheck {\n file: string;\n type: ProjectType;\n confidence: \"high\" | \"medium\";\n}\n\nconst INDICATORS: IndicatorCheck[] = [\n { file: \"nx.json\", type: \"nx\", confidence: \"high\" },\n { file: \"turbo.json\", type: \"turbo\", confidence: \"high\" },\n { file: \"pnpm-workspace.yaml\", type: \"pnpm-workspace\", confidence: \"high\" },\n { file: \"lerna.json\", type: \"pnpm-workspace\", confidence: \"medium\" },\n];\n\n/**\n * Detect the project type based on configuration files\n */\nexport async function detectProjectType(\n targetDir: string = process.cwd()\n): Promise<DetectionResult> {\n const foundIndicators: string[] = [];\n let detectedType: ProjectType = \"single\";\n let confidence: \"high\" | \"medium\" | \"low\" = \"low\";\n\n for (const indicator of INDICATORS) {\n const filePath = join(targetDir, indicator.file);\n if (existsSync(filePath)) {\n foundIndicators.push(indicator.file);\n\n // First match with highest confidence wins\n if (\n confidence === \"low\" ||\n (confidence === \"medium\" && indicator.confidence === \"high\")\n ) {\n detectedType = indicator.type;\n confidence = indicator.confidence;\n }\n }\n }\n\n // If we found indicators but couldn't determine type, it's still better than nothing\n if (foundIndicators.length > 0 && confidence === \"low\") {\n confidence = \"medium\";\n }\n\n return {\n type: detectedType,\n confidence,\n indicators: foundIndicators,\n };\n}\n\n/**\n * Check if project uses TypeScript\n */\nexport async function hasTypeScript(\n targetDir: string = process.cwd()\n): Promise<boolean> {\n const tsConfigPath = join(targetDir, \"tsconfig.json\");\n return existsSync(tsConfigPath);\n}\n\n/**\n * Check if project uses ESLint\n */\nexport async function hasEslint(\n targetDir: string = process.cwd()\n): Promise<boolean> {\n const eslintFiles = [\n \".eslintrc\",\n \".eslintrc.js\",\n \".eslintrc.cjs\",\n \".eslintrc.json\",\n \".eslintrc.yaml\",\n \".eslintrc.yml\",\n \"eslint.config.js\",\n \"eslint.config.mjs\",\n \"eslint.config.cjs\",\n ];\n\n for (const file of eslintFiles) {\n if (existsSync(join(targetDir, file))) {\n return true;\n }\n }\n\n // Also check package.json for eslintConfig\n try {\n const pkgPath = join(targetDir, \"package.json\");\n if (existsSync(pkgPath)) {\n const content = await readFile(pkgPath, \"utf-8\");\n const pkg = JSON.parse(content);\n if (pkg.eslintConfig) {\n return true;\n }\n }\n } catch {\n // Ignore parse errors\n }\n\n return false;\n}\n\n/**\n * Check if project uses Prettier\n */\nexport async function hasPrettier(\n targetDir: string = process.cwd()\n): Promise<boolean> {\n const prettierFiles = [\n \".prettierrc\",\n \".prettierrc.js\",\n \".prettierrc.cjs\",\n \".prettierrc.json\",\n \".prettierrc.yaml\",\n \".prettierrc.yml\",\n \".prettierrc.toml\",\n \"prettier.config.js\",\n \"prettier.config.cjs\",\n \"prettier.config.mjs\",\n ];\n\n for (const file of prettierFiles) {\n if (existsSync(join(targetDir, file))) {\n return true;\n }\n }\n\n // Also check package.json for prettier config\n try {\n const pkgPath = join(targetDir, \"package.json\");\n if (existsSync(pkgPath)) {\n const content = await readFile(pkgPath, \"utf-8\");\n const pkg = JSON.parse(content);\n if (pkg.prettier) {\n return true;\n }\n }\n } catch {\n // Ignore parse errors\n }\n\n return false;\n}\n\n/**\n * Check if project uses React\n */\nexport async function hasReact(\n targetDir: string = process.cwd()\n): Promise<boolean> {\n try {\n const pkgPath = join(targetDir, \"package.json\");\n if (existsSync(pkgPath)) {\n const content = await readFile(pkgPath, \"utf-8\");\n const pkg = JSON.parse(content);\n const deps = { ...pkg.dependencies, ...pkg.devDependencies };\n return \"react\" in deps || \"react-dom\" in deps;\n }\n } catch {\n // Ignore parse errors\n }\n return false;\n}\n\n/**\n * Get a human-readable description of the project type\n */\nexport function getProjectTypeDescription(type: ProjectType): string {\n switch (type) {\n case \"nx\":\n return \"NX Monorepo\";\n case \"turbo\":\n return \"Turborepo\";\n case \"pnpm-workspace\":\n return \"pnpm Workspace\";\n case \"single\":\n return \"Single Package\";\n }\n}\n\n/**\n * Re-export package manager detection utilities for convenience\n */\nexport {\n detectPackageManager,\n detectYarnVersion,\n getPackageManagerInfo,\n getPackageManagerDescription,\n PACKAGE_MANAGERS,\n} from \"./detect-package-manager.js\";\n","import { existsSync, readFileSync } from \"node:fs\";\nimport { join } from \"node:path\";\nimport type { PackageManager, PackageManagerInfo, PackageJson } from \"../types/config.js\";\n\n/**\n * Package manager metadata and commands\n */\nexport const PACKAGE_MANAGERS: Record<PackageManager, PackageManagerInfo> = {\n npm: {\n name: \"npm\",\n install: \"npm install\",\n run: \"npm run\",\n exec: \"npx\",\n lockfile: \"package-lock.json\",\n installFrozen: \"npm ci\",\n addDev: \"install -D\",\n needsSetupAction: false,\n cacheKey: \"npm-${{ hashFiles('**/package-lock.json') }}\",\n },\n pnpm: {\n name: \"pnpm\",\n install: \"pnpm install\",\n run: \"pnpm\",\n exec: \"pnpm dlx\",\n lockfile: \"pnpm-lock.yaml\",\n installFrozen: \"pnpm install --frozen-lockfile\",\n addDev: \"add -D\",\n needsSetupAction: true,\n cacheKey: \"pnpm-${{ hashFiles('**/pnpm-lock.yaml') }}\",\n },\n yarn: {\n name: \"yarn\",\n install: \"yarn install\",\n run: \"yarn\",\n exec: \"yarn\",\n lockfile: \"yarn.lock\",\n installFrozen: \"yarn install --frozen-lockfile\",\n addDev: \"add -D\",\n needsSetupAction: false,\n cacheKey: \"yarn-${{ hashFiles('**/yarn.lock') }}\",\n },\n \"yarn-berry\": {\n name: \"yarn-berry\",\n install: \"yarn install\",\n run: \"yarn\",\n exec: \"yarn dlx\",\n lockfile: \"yarn.lock\",\n installFrozen: \"yarn install --immutable\",\n addDev: \"add -D\",\n needsSetupAction: false,\n cacheKey: \"yarn-${{ hashFiles('**/yarn.lock') }}\",\n },\n};\n\n/**\n * Detect Yarn version from package.json packageManager field\n * @param targetDir Directory to check\n * @returns \"yarn\" for 1.x, \"yarn-berry\" for 2+, or null if not specified\n */\nexport function detectYarnVersion(targetDir: string): \"yarn\" | \"yarn-berry\" | null {\n const packageJsonPath = join(targetDir, \"package.json\");\n\n if (!existsSync(packageJsonPath)) {\n return null;\n }\n\n try {\n const packageJson: PackageJson = JSON.parse(readFileSync(packageJsonPath, \"utf-8\"));\n const packageManager = packageJson.packageManager as string | undefined;\n\n if (!packageManager) {\n return null;\n }\n\n // Parse packageManager field (e.g., \"yarn@3.6.0\", \"yarn@1.22.19\")\n const match = packageManager.match(/^yarn@(\\d+)\\./);\n if (match) {\n const majorVersion = Number.parseInt(match[1], 10);\n return majorVersion >= 2 ? \"yarn-berry\" : \"yarn\";\n }\n\n return null;\n } catch {\n return null;\n }\n}\n\n/**\n * Detect package manager from lockfiles\n * Priority: pnpm-lock.yaml > yarn.lock > package-lock.json\n * @param targetDir Directory to check for lockfiles\n * @returns Detected package manager or null if no lockfile found\n */\nexport function detectPackageManager(targetDir: string): PackageManagerInfo | null {\n // Check pnpm first (highest priority)\n if (existsSync(join(targetDir, \"pnpm-lock.yaml\"))) {\n return PACKAGE_MANAGERS.pnpm;\n }\n\n // Check yarn second\n if (existsSync(join(targetDir, \"yarn.lock\"))) {\n const yarnVersion = detectYarnVersion(targetDir);\n\n // If packageManager field specifies version, use that\n if (yarnVersion === \"yarn-berry\") {\n return PACKAGE_MANAGERS[\"yarn-berry\"];\n }\n\n // Default to Yarn 1.x (classic)\n return PACKAGE_MANAGERS.yarn;\n }\n\n // Check npm last (lowest priority)\n if (existsSync(join(targetDir, \"package-lock.json\"))) {\n return PACKAGE_MANAGERS.npm;\n }\n\n // No lockfile found\n return null;\n}\n\n/**\n * Get package manager metadata by name\n * @param name Package manager name\n * @returns Package manager metadata\n */\nexport function getPackageManagerInfo(name: PackageManager): PackageManagerInfo {\n return PACKAGE_MANAGERS[name];\n}\n\n/**\n * Get human-readable description of package manager\n * @param pm Package manager info\n * @returns Human-readable description\n */\nexport function getPackageManagerDescription(pm: PackageManagerInfo): string {\n switch (pm.name) {\n case \"npm\":\n return \"npm (Node Package Manager)\";\n case \"pnpm\":\n return \"pnpm (Performant npm)\";\n case \"yarn\":\n return \"Yarn Classic (1.x)\";\n case \"yarn-berry\":\n return \"Yarn Berry (2+)\";\n default:\n return pm.name;\n }\n}\n","import { join } from \"node:path\";\nimport type { GeneratorResult, ProjectType } from \"../types/config.js\";\nimport { ensureDir, writeFileSafe } from \"../utils/file-system.js\";\n\n/**\n * Generate Husky pre-commit hook with direct command execution\n *\n * Uses Husky v9+ format (just the command, no shim).\n * Direct commands work because Husky adds node_modules/.bin to PATH.\n */\nfunction getPreCommitHook(_projectType: ProjectType): string {\n return `lint-staged\n`;\n}\n\n/**\n * Generate Husky commit-msg hook for commitlint\n */\nfunction getCommitMsgHook(): string {\n return `commitlint --edit \"$1\"\n`;\n}\n\n/**\n * Generate Husky pre-push hook for branch validation\n */\nfunction getPrePushHook(): string {\n return `validate-branch-name\n`;\n}\n\n/**\n * Generate all Husky hooks\n *\n * Note: The pm parameter is kept for backward compatibility but is no longer\n * used since hooks now use direct commands.\n */\nexport async function generateHuskyHooks(\n targetDir: string,\n projectType: ProjectType,\n _pm?: unknown\n): Promise<GeneratorResult> {\n const result: GeneratorResult = {\n created: [],\n modified: [],\n skipped: [],\n backedUp: [],\n };\n\n const huskyDir = join(targetDir, \".husky\");\n await ensureDir(huskyDir);\n\n // Pre-commit hook\n const preCommitPath = join(huskyDir, \"pre-commit\");\n const preCommitResult = await writeFileSafe(\n preCommitPath,\n getPreCommitHook(projectType),\n { executable: true, backup: true }\n );\n if (preCommitResult.created) {\n result.created.push(\".husky/pre-commit\");\n if (preCommitResult.backedUp) {\n result.backedUp.push(preCommitResult.backedUp);\n }\n }\n\n // Commit-msg hook\n const commitMsgPath = join(huskyDir, \"commit-msg\");\n const commitMsgResult = await writeFileSafe(\n commitMsgPath,\n getCommitMsgHook(),\n { executable: true, backup: true }\n );\n if (commitMsgResult.created) {\n result.created.push(\".husky/commit-msg\");\n if (commitMsgResult.backedUp) {\n result.backedUp.push(commitMsgResult.backedUp);\n }\n }\n\n // Pre-push hook\n const prePushPath = join(huskyDir, \"pre-push\");\n const prePushResult = await writeFileSafe(prePushPath, getPrePushHook(), {\n executable: true,\n backup: true,\n });\n if (prePushResult.created) {\n result.created.push(\".husky/pre-push\");\n if (prePushResult.backedUp) {\n result.backedUp.push(prePushResult.backedUp);\n }\n }\n\n return result;\n}\n","import { existsSync } from \"node:fs\";\nimport {\n mkdir,\n readFile,\n writeFile,\n copyFile,\n chmod,\n} from \"node:fs/promises\";\nimport { dirname, join } from \"node:path\";\n\n/**\n * Ensure a directory exists, creating it if necessary\n */\nexport async function ensureDir(dirPath: string): Promise<void> {\n if (!existsSync(dirPath)) {\n await mkdir(dirPath, { recursive: true });\n }\n}\n\n/**\n * Backup a file if it exists\n * Returns the backup path if a backup was created, null otherwise\n */\nexport async function backupFile(filePath: string): Promise<string | null> {\n if (!existsSync(filePath)) {\n return null;\n }\n\n const backupPath = `${filePath}.backup`;\n await copyFile(filePath, backupPath);\n return backupPath;\n}\n\n/**\n * Write a file safely with optional backup\n */\nexport async function writeFileSafe(\n filePath: string,\n content: string,\n options: {\n backup?: boolean;\n overwrite?: boolean;\n executable?: boolean;\n } = {}\n): Promise<{ created: boolean; backedUp: string | null }> {\n const { backup = true, overwrite = true, executable = false } = options;\n\n // Check if file exists\n const exists = existsSync(filePath);\n\n // If file exists and we shouldn't overwrite, skip\n if (exists && !overwrite) {\n return { created: false, backedUp: null };\n }\n\n // Backup existing file if requested\n let backedUp: string | null = null;\n if (exists && backup) {\n backedUp = await backupFile(filePath);\n }\n\n // Ensure directory exists\n await ensureDir(dirname(filePath));\n\n // Write the file\n await writeFile(filePath, content, \"utf-8\");\n\n // Make executable if requested\n if (executable) {\n await chmod(filePath, 0o755);\n }\n\n return { created: true, backedUp };\n}\n\n/**\n * Read a file, returning null if it doesn't exist\n */\nexport async function readFileSafe(filePath: string): Promise<string | null> {\n if (!existsSync(filePath)) {\n return null;\n }\n return readFile(filePath, \"utf-8\");\n}\n\n/**\n * Check if a file exists\n */\nexport function fileExists(filePath: string): boolean {\n return existsSync(filePath);\n}\n\n/**\n * Get relative path from target directory\n */\nexport function getRelativePath(\n filePath: string,\n targetDir: string = process.cwd()\n): string {\n if (filePath.startsWith(targetDir)) {\n return filePath.slice(targetDir.length + 1);\n }\n return filePath;\n}\n\n/**\n * Join paths and normalize\n */\nexport function joinPath(...paths: string[]): string {\n return join(...paths);\n}\n","import { join } from \"node:path\";\nimport type { GeneratorResult } from \"../types/config.js\";\nimport { writeFileSafe } from \"../utils/file-system.js\";\n\n/**\n * Generate commitlint configuration\n *\n * Uses ES module syntax (export default) for compatibility with\n * projects that have \"type\": \"module\" in package.json.\n *\n * Note: Asana task link uses level 1 (warning) not level 2 (error)\n * Commits without task links will show a warning but won't be blocked\n */\nfunction getCommitlintConfig(asanaBaseUrl?: string): string {\n const baseConfig = `/** @type {import('@commitlint/types').UserConfig} */\nexport default {\n extends: ['@commitlint/config-conventional'],\n rules: {\n // Type must be one of the conventional types\n 'type-enum': [\n 2,\n 'always',\n [\n 'feat', // New feature\n 'fix', // Bug fix\n 'docs', // Documentation changes\n 'style', // Code style changes (formatting, etc.)\n 'refactor', // Code refactoring\n 'perf', // Performance improvements\n 'test', // Adding or updating tests\n 'build', // Build system changes\n 'ci', // CI configuration changes\n 'chore', // Other changes (maintenance, etc.)\n 'revert', // Reverting changes\n ],\n ],\n // Subject should not be empty\n 'subject-empty': [2, 'never'],\n // Type should not be empty\n 'type-empty': [2, 'never'],\n // Subject should be lowercase\n 'subject-case': [2, 'always', 'lower-case'],\n // Header max length\n 'header-max-length': [2, 'always', 100],`;\n\n if (asanaBaseUrl) {\n // Add Asana task link validation as a WARNING (level 1), not error (level 2)\n return `${baseConfig}\n // Asana task link (warning only - won't block commits)\n 'asana-task-link': [1, 'always'],\n },\n plugins: [\n {\n rules: {\n 'asana-task-link': ({ body, footer }) => {\n const fullMessage = [body, footer].filter(Boolean).join('\\\\n');\n const asanaPattern = /https:\\\\/\\\\/app\\\\.asana\\\\.com\\\\/\\\\d+\\\\/\\\\d+\\\\/\\\\d+/;\n const hasAsanaLink = asanaPattern.test(fullMessage);\n return [\n hasAsanaLink,\n hasAsanaLink\n ? null\n : 'Consider adding an Asana task link in the commit body or footer (e.g., Task: https://app.asana.com/0/...)',\n ];\n },\n },\n },\n ],\n};\n`;\n }\n\n return `${baseConfig}\n },\n};\n`;\n}\n\n/**\n * Generate commitlint configuration file\n */\nexport async function generateCommitlint(\n targetDir: string,\n asanaBaseUrl?: string\n): Promise<GeneratorResult> {\n const result: GeneratorResult = {\n created: [],\n modified: [],\n skipped: [],\n backedUp: [],\n };\n\n const configPath = join(targetDir, \"commitlint.config.js\");\n const writeResult = await writeFileSafe(\n configPath,\n getCommitlintConfig(asanaBaseUrl),\n { backup: true }\n );\n\n if (writeResult.created) {\n result.created.push(\"commitlint.config.js\");\n if (writeResult.backedUp) {\n result.backedUp.push(writeResult.backedUp);\n }\n }\n\n return result;\n}\n","import { join } from \"node:path\";\nimport type { GeneratorResult } from \"../types/config.js\";\nimport { writeFileSafe } from \"../utils/file-system.js\";\n\n/**\n * Generate cz-git configuration\n */\nfunction getCzGitConfig(asanaBaseUrl?: string): string {\n const asanaSection = asanaBaseUrl\n ? `\n // Asana task reference settings\n allowCustomIssuePrefix: true,\n allowEmptyIssuePrefix: true,\n issuePrefixes: [\n { value: 'asana', name: 'asana: Link to Asana task' },\n { value: 'closes', name: 'closes: Close an issue' },\n { value: 'fixes', name: 'fixes: Fix an issue' },\n ],\n customIssuePrefixAlign: 'top',`\n : `\n allowCustomIssuePrefix: false,\n allowEmptyIssuePrefix: true,`;\n\n return `// @ts-check\n\n/** @type {import('cz-git').UserConfig} */\nmodule.exports = {\n extends: ['@commitlint/config-conventional'],\n prompt: {\n alias: {\n fd: 'docs: fix typos',\n ur: 'docs: update README',\n },\n messages: {\n type: \"Select the type of change you're committing:\",\n scope: 'Denote the scope of this change (optional):',\n customScope: 'Denote the scope of this change:',\n subject: 'Write a short, imperative description of the change:\\\\n',\n body: 'Provide a longer description of the change (optional). Use \"|\" to break new line:\\\\n',\n breaking: 'List any BREAKING CHANGES (optional). Use \"|\" to break new line:\\\\n',\n footerPrefixSelect: 'Select the ISSUES type of change (optional):',\n customFooterPrefix: 'Input ISSUES prefix:',\n footer: 'List any ISSUES affected by this change (optional). E.g.: #31, #34:\\\\n',\n confirmCommit: 'Are you sure you want to proceed with the commit above?',\n },\n types: [\n { value: 'feat', name: 'feat: ✨ A new feature', emoji: ':sparkles:' },\n { value: 'fix', name: 'fix: 🐛 A bug fix', emoji: ':bug:' },\n { value: 'docs', name: 'docs: 📝 Documentation changes', emoji: ':memo:' },\n { value: 'style', name: 'style: 💄 Code style changes', emoji: ':lipstick:' },\n { value: 'refactor', name: 'refactor: ♻️ Code refactoring', emoji: ':recycle:' },\n { value: 'perf', name: 'perf: ⚡️ Performance improvements', emoji: ':zap:' },\n { value: 'test', name: 'test: ✅ Adding or updating tests', emoji: ':white_check_mark:' },\n { value: 'build', name: 'build: 📦 Build system changes', emoji: ':package:' },\n { value: 'ci', name: 'ci: 🎡 CI configuration changes', emoji: ':ferris_wheel:' },\n { value: 'chore', name: 'chore: 🔧 Other changes', emoji: ':wrench:' },\n { value: 'revert', name: 'revert: ⏪ Reverting changes', emoji: ':rewind:' },\n ],\n useEmoji: true,\n emojiAlign: 'center',\n useAI: false,\n aiNumber: 1,\n themeColorCode: '',\n scopes: [],\n allowCustomScopes: true,\n allowEmptyScopes: true,\n customScopesAlign: 'bottom',\n customScopesAlias: 'custom',\n emptyScopesAlias: 'empty',\n upperCaseSubject: false,\n markBreakingChangeMode: false,\n allowBreakingChanges: ['feat', 'fix'],\n breaklineNumber: 100,\n breaklineChar: '|',\n skipQuestions: [],${asanaSection}\n confirmColorize: true,\n minSubjectLength: 0,\n defaultBody: '',\n defaultIssues: '',\n defaultScope: '',\n defaultSubject: '',\n },\n};\n`;\n}\n\n/**\n * Generate cz-git configuration file\n */\nexport async function generateCzGit(\n targetDir: string,\n asanaBaseUrl?: string\n): Promise<GeneratorResult> {\n const result: GeneratorResult = {\n created: [],\n modified: [],\n skipped: [],\n backedUp: [],\n };\n\n const configPath = join(targetDir, \".czrc\");\n const writeResult = await writeFileSafe(\n configPath,\n JSON.stringify({ path: \"node_modules/cz-git\" }, null, 2) + \"\\n\",\n { backup: true }\n );\n\n if (writeResult.created) {\n result.created.push(\".czrc\");\n if (writeResult.backedUp) {\n result.backedUp.push(writeResult.backedUp);\n }\n }\n\n // Also generate the cz.config.js for more detailed config\n const czConfigPath = join(targetDir, \"cz.config.js\");\n const czConfigResult = await writeFileSafe(\n czConfigPath,\n getCzGitConfig(asanaBaseUrl),\n { backup: true }\n );\n\n if (czConfigResult.created) {\n result.created.push(\"cz.config.js\");\n if (czConfigResult.backedUp) {\n result.backedUp.push(czConfigResult.backedUp);\n }\n }\n\n return result;\n}\n","import type { GeneratorResult } from \"../types/config.js\";\n\n/**\n * Lint-staged configuration type for package.json\n */\nexport type LintStagedConfig = Record<string, string | string[]>;\n\n/**\n * Generate lint-staged configuration for package.json (matching zero-to-one pattern)\n *\n * This function returns a configuration object to be added to package.json\n * instead of creating a separate file.\n */\nexport function getLintStagedConfig(\n usesEslint: boolean,\n usesPrettier: boolean,\n usesTypeScript: boolean\n): LintStagedConfig {\n const config: LintStagedConfig = {};\n\n // Determine which file patterns to lint\n const codePatterns: string[] = [];\n\n if (usesTypeScript) {\n codePatterns.push(\"ts\", \"mts\", \"cts\", \"tsx\");\n }\n // Always include JavaScript patterns\n codePatterns.push(\"js\", \"mjs\", \"cjs\", \"jsx\");\n\n // Build commands for code files\n const codeCommands: string[] = [];\n if (usesEslint) {\n codeCommands.push(\"eslint --fix\");\n }\n if (usesPrettier) {\n codeCommands.push(\"prettier --write\");\n }\n\n // Add code file pattern if we have any commands\n if (codeCommands.length > 0) {\n const pattern = `*.{${codePatterns.join(\",\")}}`;\n config[pattern] = codeCommands;\n }\n\n // Add non-code files for Prettier only\n if (usesPrettier) {\n config[\"*.{json,css,md}\"] = [\"prettier --write\"];\n }\n\n return config;\n}\n\n/**\n * Generate lint-staged configuration\n *\n * Note: This generator doesn't create files - instead it returns a GeneratorResult\n * and the config should be merged into package.json by the init command.\n *\n * @deprecated Use getLintStagedConfig() instead and merge into package.json\n */\nexport async function generateLintStaged(\n _targetDir: string,\n _projectType: string,\n usesEslint: boolean,\n usesPrettier: boolean,\n usesTypeScript: boolean\n): Promise<GeneratorResult & { config: LintStagedConfig }> {\n const result: GeneratorResult = {\n created: [],\n modified: [],\n skipped: [],\n backedUp: [],\n };\n\n const config = getLintStagedConfig(usesEslint, usesPrettier, usesTypeScript);\n\n // Note: The actual addition to package.json is handled by init.ts\n // This function now just returns the config\n\n return {\n ...result,\n config,\n };\n}\n","import { readFile, writeFile } from \"node:fs/promises\";\nimport { existsSync } from \"node:fs\";\nimport { join } from \"node:path\";\nimport spawn from \"cross-spawn\";\nimport type { PackageJson, PackageManagerInfo } from \"../types/config.js\";\n\n/**\n * Read package.json from a directory\n */\nexport async function readPackageJson(\n targetDir: string = process.cwd()\n): Promise<PackageJson> {\n const pkgPath = join(targetDir, \"package.json\");\n\n if (!existsSync(pkgPath)) {\n throw new Error(`No package.json found in ${targetDir}`);\n }\n\n const content = await readFile(pkgPath, \"utf-8\");\n return JSON.parse(content) as PackageJson;\n}\n\n/**\n * Write package.json to a directory\n */\nexport async function writePackageJson(\n pkg: PackageJson,\n targetDir: string = process.cwd()\n): Promise<void> {\n const pkgPath = join(targetDir, \"package.json\");\n const content = JSON.stringify(pkg, null, 2) + \"\\n\";\n await writeFile(pkgPath, content, \"utf-8\");\n}\n\n/**\n * Merge scripts into package.json without overwriting existing ones\n */\nexport function mergeScripts(\n pkg: PackageJson,\n scripts: Record<string, string>,\n overwrite: boolean = false\n): PackageJson {\n const existingScripts = pkg.scripts || {};\n const newScripts: Record<string, string> = { ...existingScripts };\n\n for (const [name, command] of Object.entries(scripts)) {\n if (overwrite || !existingScripts[name]) {\n newScripts[name] = command;\n }\n }\n\n return {\n ...pkg,\n scripts: newScripts,\n };\n}\n\n\n/**\n * Add a config section to package.json (e.g., lint-staged, validate-branch-name)\n */\nexport function addPackageJsonConfig<T>(\n pkg: PackageJson,\n key: string,\n config: T,\n overwrite: boolean = false\n): PackageJson {\n if (!overwrite && pkg[key]) {\n return pkg;\n }\n\n return {\n ...pkg,\n [key]: config,\n };\n}\n\n/**\n * Update package.json with multiple changes at once\n */\nexport async function updatePackageJson(\n targetDir: string,\n updater: (pkg: PackageJson) => PackageJson\n): Promise<PackageJson> {\n const pkg = await readPackageJson(targetDir);\n const updated = updater(pkg);\n await writePackageJson(updated, targetDir);\n return updated;\n}\n\n/**\n * Core packages that RaftStack will install in the target project\n */\nexport const RAFTSTACK_PACKAGES: string[] = [\n // Commit tooling\n \"@commitlint/cli\",\n \"@commitlint/config-conventional\",\n \"cz-git\",\n \"czg\",\n \"husky\",\n \"lint-staged\",\n \"validate-branch-name\",\n\n // Linting & formatting\n \"eslint\",\n \"@eslint/js\",\n \"typescript-eslint\",\n \"eslint-config-prettier\",\n \"prettier\",\n \"globals\",\n];\n\n/**\n * Additional ESLint packages for React projects\n */\nexport const REACT_ESLINT_PACKAGES: string[] = [\n \"eslint-plugin-react\",\n \"eslint-plugin-react-hooks\",\n];\n\n/**\n * Result of package installation\n */\nexport interface InstallResult {\n success: boolean;\n error?: string;\n}\n\n/**\n * Check if directory is a pnpm workspace root\n */\nfunction isPnpmWorkspace(targetDir: string): boolean {\n return existsSync(join(targetDir, \"pnpm-workspace.yaml\"));\n}\n\n/**\n * Install packages using the package manager CLI\n *\n * Uses cross-spawn with shell: true for reliable PATH resolution\n * in sandboxed environments (pnpm dlx, npx). This is the industry\n * standard approach used by create-next-app, create-vite, etc.\n */\nexport async function installPackages(\n pm: PackageManagerInfo,\n packages: string[],\n targetDir: string\n): Promise<InstallResult> {\n if (packages.length === 0) {\n return { success: true };\n }\n\n return new Promise((resolve) => {\n // Build the command: e.g., \"pnpm add -D pkg1 pkg2 ...\"\n const pmCommand = pm.name === \"npm\" ? \"npm\" : pm.name.replace(\"-berry\", \"\");\n const parts = [pmCommand, ...pm.addDev.split(\" \")];\n\n // For pnpm workspaces, add -w flag to install at workspace root\n if (pm.name === \"pnpm\" && isPnpmWorkspace(targetDir)) {\n parts.push(\"-w\");\n }\n\n parts.push(...packages);\n\n // Join as single command string to avoid Node.js deprecation warning\n // about passing args with shell: true\n const fullCommand = parts.join(\" \");\n\n const child = spawn(fullCommand, [], {\n cwd: targetDir,\n stdio: \"inherit\", // Show install progress to user\n shell: true, // Key: use shell to resolve PATH in sandboxed envs\n });\n\n child.on(\"close\", (code) => {\n if (code === 0) {\n resolve({ success: true });\n } else {\n resolve({\n success: false,\n error: `Installation failed with exit code ${code}`,\n });\n }\n });\n\n child.on(\"error\", (err) => {\n resolve({\n success: false,\n error: err.message,\n });\n });\n });\n}\n\n/**\n * Get package manager-specific scripts\n * This can be used in the future to add PM-specific setup scripts\n */\nexport function getPackageManagerScripts(\n _pm: PackageManagerInfo\n): Record<string, string> {\n // Currently, all package managers use the same scripts\n // This function is here for future extensibility if we need\n // different scripts for different package managers\n return {\n commit: \"czg\",\n prepare: \"husky\",\n };\n}\n","import type { GeneratorResult } from \"../types/config.js\";\nimport {\n addPackageJsonConfig,\n readPackageJson,\n writePackageJson,\n} from \"../utils/package-json.js\";\n\n/**\n * Branch naming pattern configuration\n */\ninterface BranchValidationConfig {\n pattern: string;\n errorMsg: string;\n}\n\n/**\n * Get the default branch validation configuration\n */\nfunction getBranchValidationConfig(): BranchValidationConfig {\n return {\n pattern:\n \"^(main|master|develop|staging|production)$|^(feature|fix|hotfix|bugfix|release|chore|docs|refactor|test|ci)\\\\/[a-z0-9._-]+$\",\n errorMsg:\n \"Branch name must follow pattern: feature/*, fix/*, hotfix/*, bugfix/*, release/*, chore/*, docs/*, refactor/*, test/*, ci/* or be main/master/develop/staging/production\",\n };\n}\n\n/**\n * Add validate-branch-name configuration to package.json\n */\nexport async function generateBranchValidation(\n targetDir: string\n): Promise<GeneratorResult> {\n const result: GeneratorResult = {\n created: [],\n modified: [],\n skipped: [],\n backedUp: [],\n };\n\n try {\n const pkg = await readPackageJson(targetDir);\n const config = getBranchValidationConfig();\n\n const updatedPkg = addPackageJsonConfig(\n pkg,\n \"validate-branch-name\",\n config,\n false // Don't overwrite if exists\n );\n\n // Check if we actually added something\n if (JSON.stringify(pkg) !== JSON.stringify(updatedPkg)) {\n await writePackageJson(updatedPkg, targetDir);\n result.modified.push(\"package.json (validate-branch-name)\");\n } else {\n result.skipped.push(\"validate-branch-name config (already exists)\");\n }\n } catch (error) {\n // If package.json doesn't exist or can't be read, skip\n result.skipped.push(\"validate-branch-name config (no package.json)\");\n }\n\n return result;\n}\n","import { join } from \"node:path\";\nimport type { GeneratorResult } from \"../types/config.js\";\nimport { ensureDir, writeFileSafe } from \"../utils/file-system.js\";\n\n/**\n * Get the PR template content\n */\nfunction getPRTemplate(hasAsana: boolean): string {\n const asanaSection = hasAsana\n ? `## Asana Task\n<!-- Link to the Asana task -->\n- [ ] https://app.asana.com/0/...\n\n`\n : \"\";\n\n return `## Description\n<!-- Provide a brief description of the changes in this PR -->\n\n## Type of Change\n<!-- Mark the appropriate option with an \"x\" -->\n- [ ] 🐛 Bug fix (non-breaking change that fixes an issue)\n- [ ] ✨ New feature (non-breaking change that adds functionality)\n- [ ] 💥 Breaking change (fix or feature that would cause existing functionality to not work as expected)\n- [ ] 📝 Documentation update\n- [ ] 🔧 Configuration change\n- [ ] ♻️ Refactoring (no functional changes)\n- [ ] ✅ Test update\n\n${asanaSection}## Changes Made\n<!-- List the specific changes made in this PR -->\n-\n\n## Testing\n<!-- Describe how you tested your changes -->\n- [ ] Unit tests added/updated\n- [ ] Integration tests added/updated\n- [ ] Manual testing performed\n\n## Screenshots (if applicable)\n<!-- Add screenshots to help explain your changes -->\n\n## Checklist\n- [ ] My code follows the project's coding standards\n- [ ] I have performed a self-review of my code\n- [ ] I have commented my code, particularly in hard-to-understand areas\n- [ ] I have made corresponding changes to the documentation\n- [ ] My changes generate no new warnings\n- [ ] Any dependent changes have been merged and published\n\n## Additional Notes\n<!-- Add any additional information that reviewers should know -->\n`;\n}\n\n/**\n * Generate GitHub PR template\n */\nexport async function generatePRTemplate(\n targetDir: string,\n hasAsana: boolean\n): Promise<GeneratorResult> {\n const result: GeneratorResult = {\n created: [],\n modified: [],\n skipped: [],\n backedUp: [],\n };\n\n const githubDir = join(targetDir, \".github\");\n await ensureDir(githubDir);\n\n const templatePath = join(githubDir, \"PULL_REQUEST_TEMPLATE.md\");\n const writeResult = await writeFileSafe(\n templatePath,\n getPRTemplate(hasAsana),\n { backup: true }\n );\n\n if (writeResult.created) {\n result.created.push(\".github/PULL_REQUEST_TEMPLATE.md\");\n if (writeResult.backedUp) {\n result.backedUp.push(writeResult.backedUp);\n }\n }\n\n return result;\n}\n","import { join } from \"node:path\";\nimport type { GeneratorResult, PackageManagerInfo, ProjectType } from \"../types/config.js\";\nimport { ensureDir, writeFileSafe } from \"../utils/file-system.js\";\n\n/**\n * Get the PR checks workflow content\n */\nfunction getPRChecksWorkflow(\n projectType: ProjectType,\n usesTypeScript: boolean,\n usesEslint: boolean,\n pm: PackageManagerInfo\n): string {\n const steps: string[] = [];\n\n // Checkout\n steps.push(` - name: Checkout\n uses: actions/checkout@v4`);\n\n // Setup Node\n steps.push(`\n - name: Setup Node.js\n uses: actions/setup-node@v4\n with:\n node-version: '20'`);\n\n // Setup pnpm (only if needed)\n if (pm.needsSetupAction) {\n steps.push(`\n - name: Setup pnpm\n uses: pnpm/action-setup@v3\n with:\n version: 9`);\n }\n\n // Install dependencies\n steps.push(`\n - name: Install dependencies\n run: ${pm.installFrozen}`);\n\n // TypeScript check\n if (usesTypeScript) {\n steps.push(`\n - name: Type check\n run: ${pm.run} typecheck`);\n }\n\n // ESLint\n if (usesEslint) {\n steps.push(`\n - name: Lint\n run: ${pm.run} lint`);\n }\n\n // Build (for NX/Turbo, use their commands)\n if (projectType === \"nx\") {\n steps.push(`\n - name: Build\n run: ${pm.run} nx affected --target=build --parallel=3`);\n } else if (projectType === \"turbo\") {\n steps.push(`\n - name: Build\n run: ${pm.run} turbo build`);\n } else {\n steps.push(`\n - name: Build\n run: ${pm.run} build`);\n }\n\n // Tests\n if (projectType === \"nx\") {\n steps.push(`\n - name: Test\n run: ${pm.run} nx affected --target=test --parallel=3`);\n } else if (projectType === \"turbo\") {\n steps.push(`\n - name: Test\n run: ${pm.run} turbo test`);\n } else {\n steps.push(`\n - name: Test\n run: ${pm.run} test`);\n }\n\n return `name: PR Checks\n\non:\n pull_request:\n branches: [main, master, develop]\n\nconcurrency:\n group: \\${{ github.workflow }}-\\${{ github.ref }}\n cancel-in-progress: true\n\njobs:\n check:\n name: Check\n runs-on: ubuntu-latest\n steps:\n${steps.join(\"\\n\")}\n`;\n}\n\n/**\n * Generate GitHub workflow files\n */\nexport async function generateGitHubWorkflows(\n targetDir: string,\n projectType: ProjectType,\n usesTypeScript: boolean,\n usesEslint: boolean,\n pm: PackageManagerInfo\n): Promise<GeneratorResult> {\n const result: GeneratorResult = {\n created: [],\n modified: [],\n skipped: [],\n backedUp: [],\n };\n\n const workflowsDir = join(targetDir, \".github\", \"workflows\");\n await ensureDir(workflowsDir);\n\n // PR Checks workflow\n const prChecksPath = join(workflowsDir, \"pr-checks.yml\");\n const writeResult = await writeFileSafe(\n prChecksPath,\n getPRChecksWorkflow(projectType, usesTypeScript, usesEslint, pm),\n { backup: true }\n );\n\n if (writeResult.created) {\n result.created.push(\".github/workflows/pr-checks.yml\");\n if (writeResult.backedUp) {\n result.backedUp.push(writeResult.backedUp);\n }\n }\n\n return result;\n}\n","import { join } from \"node:path\";\nimport type { GeneratorResult } from \"../types/config.js\";\nimport { ensureDir, writeFileSafe } from \"../utils/file-system.js\";\n\n/**\n * Get the CODEOWNERS content\n */\nfunction getCodeownersContent(owners: string[]): string {\n if (owners.length === 0) {\n return `# CODEOWNERS file\n# Learn about CODEOWNERS: https://docs.github.com/en/repositories/managing-your-repositorys-settings-and-features/customizing-your-repository/about-code-owners\n\n# Default owners for everything in the repo\n# Uncomment and modify the line below to set default owners\n# * @owner1 @owner2\n`;\n }\n\n const ownersList = owners.join(\" \");\n\n return `# CODEOWNERS file\n# Learn about CODEOWNERS: https://docs.github.com/en/repositories/managing-your-repositorys-settings-and-features/customizing-your-repository/about-code-owners\n\n# Default owners for everything in the repo\n* ${ownersList}\n\n# You can also specify owners for specific paths:\n# /docs/ @docs-team\n# /src/api/ @backend-team\n# /src/ui/ @frontend-team\n# *.ts @typescript-team\n`;\n}\n\n/**\n * Generate CODEOWNERS file\n */\nexport async function generateCodeowners(\n targetDir: string,\n owners: string[]\n): Promise<GeneratorResult> {\n const result: GeneratorResult = {\n created: [],\n modified: [],\n skipped: [],\n backedUp: [],\n };\n\n const githubDir = join(targetDir, \".github\");\n await ensureDir(githubDir);\n\n const codeownersPath = join(githubDir, \"CODEOWNERS\");\n const writeResult = await writeFileSafe(\n codeownersPath,\n getCodeownersContent(owners),\n { backup: true }\n );\n\n if (writeResult.created) {\n result.created.push(\".github/CODEOWNERS\");\n if (writeResult.backedUp) {\n result.backedUp.push(writeResult.backedUp);\n }\n }\n\n return result;\n}\n","import { join } from \"node:path\";\nimport type { AIReviewTool, GeneratorResult } from \"../types/config.js\";\nimport { ensureDir, writeFileSafe } from \"../utils/file-system.js\";\n\n/**\n * Get CodeRabbit configuration\n */\nfunction getCodeRabbitConfig(): string {\n return `# CodeRabbit Configuration\n# Learn more: https://docs.coderabbit.ai/guides/configure-coderabbit\n\nlanguage: \"en-US\"\n\nreviews:\n request_changes_workflow: true\n high_level_summary: true\n poem: false\n review_status: true\n collapse_walkthrough: false\n auto_review:\n enabled: true\n drafts: false\n\nchat:\n auto_reply: true\n`;\n}\n\n/**\n * Get GitHub Copilot PR review workflow\n */\nfunction getCopilotWorkflow(): string {\n return `name: Copilot Code Review\n\non:\n pull_request:\n types: [opened, synchronize, reopened]\n\npermissions:\n contents: read\n pull-requests: write\n\njobs:\n review:\n name: Copilot Review\n runs-on: ubuntu-latest\n steps:\n - name: Checkout\n uses: actions/checkout@v4\n\n # Note: GitHub Copilot code review is automatically enabled\n # when you have Copilot Enterprise. This workflow is a placeholder\n # for any additional AI review configuration you might need.\n\n - name: Add review comment\n uses: actions/github-script@v7\n with:\n script: |\n // GitHub Copilot will automatically review PRs if enabled\n // This is a placeholder for additional review logic\n console.log('Copilot review enabled for this repository');\n`;\n}\n\n/**\n * Generate AI review configuration\n */\nexport async function generateAIReview(\n targetDir: string,\n tool: AIReviewTool\n): Promise<GeneratorResult> {\n const result: GeneratorResult = {\n created: [],\n modified: [],\n skipped: [],\n backedUp: [],\n };\n\n if (tool === \"none\") {\n return result;\n }\n\n if (tool === \"coderabbit\") {\n const configPath = join(targetDir, \".coderabbit.yaml\");\n const writeResult = await writeFileSafe(configPath, getCodeRabbitConfig(), {\n backup: true,\n });\n\n if (writeResult.created) {\n result.created.push(\".coderabbit.yaml\");\n if (writeResult.backedUp) {\n result.backedUp.push(writeResult.backedUp);\n }\n }\n }\n\n if (tool === \"copilot\") {\n const workflowsDir = join(targetDir, \".github\", \"workflows\");\n await ensureDir(workflowsDir);\n\n const workflowPath = join(workflowsDir, \"copilot-review.yml\");\n const writeResult = await writeFileSafe(workflowPath, getCopilotWorkflow(), {\n backup: true,\n });\n\n if (writeResult.created) {\n result.created.push(\".github/workflows/copilot-review.yml\");\n if (writeResult.backedUp) {\n result.backedUp.push(writeResult.backedUp);\n }\n }\n }\n\n return result;\n}\n","import { join } from \"node:path\";\nimport type { GeneratorResult } from \"../types/config.js\";\nimport { ensureDir, writeFileSafe } from \"../utils/file-system.js\";\n\n/**\n * Get branch protection setup documentation\n */\nfunction getBranchProtectionDocs(): string {\n return `# Branch Protection Setup Guide\n\nThis guide explains how to configure branch protection rules for your repository.\n\n## Quick Setup\n\nRun the automated setup command:\n\n\\`\\`\\`bash\nraftstack setup-protection\n\\`\\`\\`\n\nThis command supports:\n- **Multiple branches**: main, staging, production, development, etc.\n- **Merge strategies**: Rebase (recommended), squash, or merge commits\n- **Review requirements**: Configurable number of required approvals\n\n## Recommended Settings\n\n### For \\`main\\` / \\`master\\` branch:\n\n1. **Require a pull request before merging**\n - ✅ Require approvals: 1 (or more for larger teams)\n - ✅ Dismiss stale pull request approvals when new commits are pushed\n - ✅ Require review from Code Owners\n\n2. **Require status checks to pass before merging**\n - ✅ Require branches to be up to date before merging\n - Select required status checks:\n - \\`check\\` (from pr-checks.yml workflow)\n\n3. **Require conversation resolution before merging**\n - ✅ All conversations on code must be resolved\n\n4. **Do not allow bypassing the above settings**\n - ✅ Apply rules to administrators\n\n5. **Restrict who can push to matching branches**\n - Only allow merges through pull requests\n\n6. **Block force pushes**\n - ✅ Do not allow force pushes\n\n7. **Block deletions**\n - ✅ Do not allow this branch to be deleted\n\n## Manual Setup via GitHub UI\n\n1. Go to your repository on GitHub\n2. Click **Settings** > **Branches**\n3. Click **Add branch protection rule**\n4. Enter \\`main\\` (or \\`master\\`) as the branch name pattern\n5. Configure the settings as described above\n6. Click **Create** or **Save changes**\n\n## Automated Setup (Recommended)\n\nUse the \\`raftstack setup-protection\\` command to configure\nbranch protection rules automatically using the GitHub CLI.\n\nRequirements:\n- GitHub CLI (\\`gh\\`) installed and authenticated\n- Admin access to the repository\n\n\\`\\`\\`bash\nraftstack setup-protection\n\\`\\`\\`\n\n### Features\n\nThe setup command will:\n1. Prompt you to select branches to protect (main, staging, production, etc.)\n2. Let you choose a merge strategy (rebase, squash, or merge commits)\n3. Configure required review count\n4. Apply branch protection rules to all selected branches\n5. Set repository merge settings\n\n### Merge Strategy Recommendations\n\n| Strategy | Use Case |\n|----------|----------|\n| **Rebase** (recommended) | Clean linear history, easy to follow |\n| **Squash** | Single commit per PR, cleaner history |\n| **Merge commit** | Preserve all commits, show PR merge points |\n\n## Branch Naming Convention\n\nThis project enforces branch naming conventions via \\`validate-branch-name\\`.\n\nAllowed patterns:\n- \\`main\\`, \\`master\\`, \\`develop\\`, \\`staging\\`, \\`production\\`\n- \\`feature/*\\` - New features\n- \\`fix/*\\` or \\`bugfix/*\\` - Bug fixes\n- \\`hotfix/*\\` - Urgent fixes\n- \\`release/*\\` - Release preparation\n- \\`chore/*\\` - Maintenance tasks\n- \\`docs/*\\` - Documentation updates\n- \\`refactor/*\\` - Code refactoring\n- \\`test/*\\` - Test additions/updates\n- \\`ci/*\\` - CI/CD changes\n\nExamples:\n- \\`feature/user-authentication\\`\n- \\`fix/login-validation\\`\n- \\`hotfix/security-patch\\`\n- \\`release/v1.2.0\\`\n`;\n}\n\n/**\n * Generate branch protection documentation\n */\nexport async function generateBranchProtectionDocs(\n targetDir: string\n): Promise<GeneratorResult> {\n const result: GeneratorResult = {\n created: [],\n modified: [],\n skipped: [],\n backedUp: [],\n };\n\n const docsDir = join(targetDir, \".github\");\n await ensureDir(docsDir);\n\n const docsPath = join(docsDir, \"BRANCH_PROTECTION_SETUP.md\");\n const writeResult = await writeFileSafe(docsPath, getBranchProtectionDocs(), {\n backup: true,\n });\n\n if (writeResult.created) {\n result.created.push(\".github/BRANCH_PROTECTION_SETUP.md\");\n if (writeResult.backedUp) {\n result.backedUp.push(writeResult.backedUp);\n }\n }\n\n return result;\n}\n","import { join } from \"node:path\";\nimport type { GeneratorResult, PackageManagerInfo } from \"../types/config.js\";\nimport { writeFileSafe } from \"../utils/file-system.js\";\n\n/**\n * Get CONTRIBUTING.md content\n */\nfunction getContributingContent(hasAsana: boolean, pm: PackageManagerInfo): string {\n const asanaSection = hasAsana\n ? `\n## Linking to Asana\n\nWhen working on a task:\n1. Create a branch following the naming convention (e.g., \\`feature/task-description\\`)\n2. Include the Asana task link in your commit body or footer\n3. Reference the Asana task in your PR description\n\nExample commit:\n\\`\\`\\`\nfeat(auth): add password reset functionality\n\nImplement password reset flow with email verification.\n\nAsana: https://app.asana.com/0/workspace/task-id\n\\`\\`\\`\n`\n : \"\";\n\n return `# Contributing Guide\n\nThank you for your interest in contributing! This document outlines our development workflow and standards.\n\n## Getting Started\n\n1. Clone the repository\n2. Install dependencies: \\`${pm.install}\\`\n3. Create a new branch following our naming convention\n\n## Branch Naming Convention\n\nWe use structured branch names to keep our repository organized:\n\n| Prefix | Purpose | Example |\n|--------|---------|---------|\n| \\`feature/\\` | New features | \\`feature/user-authentication\\` |\n| \\`fix/\\` | Bug fixes | \\`fix/login-validation\\` |\n| \\`hotfix/\\` | Urgent fixes | \\`hotfix/security-patch\\` |\n| \\`bugfix/\\` | Bug fixes (alternative) | \\`bugfix/form-submission\\` |\n| \\`release/\\` | Release preparation | \\`release/v1.2.0\\` |\n| \\`chore/\\` | Maintenance tasks | \\`chore/update-dependencies\\` |\n| \\`docs/\\` | Documentation | \\`docs/api-reference\\` |\n| \\`refactor/\\` | Code refactoring | \\`refactor/auth-module\\` |\n| \\`test/\\` | Test additions | \\`test/user-service\\` |\n| \\`ci/\\` | CI/CD changes | \\`ci/github-actions\\` |\n\n## Commit Convention\n\nWe follow [Conventional Commits](https://www.conventionalcommits.org/). Use the interactive commit tool:\n\n\\`\\`\\`bash\n${pm.run} commit\n\\`\\`\\`\n\n### Commit Types\n\n| Type | Description |\n|------|-------------|\n| \\`feat\\` | New feature |\n| \\`fix\\` | Bug fix |\n| \\`docs\\` | Documentation changes |\n| \\`style\\` | Code style changes (formatting, etc.) |\n| \\`refactor\\` | Code refactoring |\n| \\`perf\\` | Performance improvements |\n| \\`test\\` | Adding or updating tests |\n| \\`build\\` | Build system changes |\n| \\`ci\\` | CI configuration changes |\n| \\`chore\\` | Other changes |\n| \\`revert\\` | Reverting changes |\n\n### Commit Message Format\n\n\\`\\`\\`\n<type>(<scope>): <subject>\n\n<body>\n\n<footer>\n\\`\\`\\`\n\nExample:\n\\`\\`\\`\nfeat(auth): add social login support\n\nImplement OAuth2 login for Google and GitHub providers.\nIncludes user profile sync and token refresh.\n\nCloses #123\n\\`\\`\\`\n${asanaSection}\n## Pull Request Process\n\n1. Ensure your branch is up to date with \\`main\\`/\\`master\\`\n2. Run tests and linting locally\n3. Create a pull request using the provided template\n4. Request review from code owners\n5. Address any feedback\n6. Merge once approved and all checks pass\n\n### PR Size Guidelines\n\nKeep pull requests small and focused for faster reviews:\n\n| Size | Lines Changed | Review Time |\n|------|---------------|-------------|\n| XS | 0-10 lines | Minutes |\n| S | 11-50 lines | < 30 min |\n| M | 51-200 lines | < 1 hour |\n| L | 201-400 lines | 1-2 hours |\n| XL | 400+ lines | Needs justification |\n\n**Target: < 400 lines per PR**\n\nIf your PR is large:\n- Consider splitting it into smaller, logical PRs\n- Explain in the description why it can't be split\n\n## Code Quality\n\nBefore committing, the following checks run automatically:\n\n- **Linting**: ESLint checks for code quality\n- **Formatting**: Prettier ensures consistent style\n- **Type checking**: TypeScript validates types\n- **Commit messages**: Commitlint validates format\n- **Branch names**: validate-branch-name checks naming\n\n## Questions?\n\nIf you have questions, please open an issue or reach out to the maintainers.\n`;\n}\n\n/**\n * Generate CONTRIBUTING.md\n */\nexport async function generateContributing(\n targetDir: string,\n hasAsana: boolean,\n pm: PackageManagerInfo\n): Promise<GeneratorResult> {\n const result: GeneratorResult = {\n created: [],\n modified: [],\n skipped: [],\n backedUp: [],\n };\n\n const contributingPath = join(targetDir, \"CONTRIBUTING.md\");\n const writeResult = await writeFileSafe(\n contributingPath,\n getContributingContent(hasAsana, pm),\n { backup: true }\n );\n\n if (writeResult.created) {\n result.created.push(\"CONTRIBUTING.md\");\n if (writeResult.backedUp) {\n result.backedUp.push(writeResult.backedUp);\n }\n }\n\n return result;\n}\n","import { join } from \"node:path\";\nimport type { GeneratorResult } from \"../types/config.js\";\nimport { fileExists, writeFileSafe } from \"../utils/file-system.js\";\n\n/**\n * Get Prettier configuration (matching zero-to-one project pattern)\n */\nfunction getPrettierConfig(): string {\n return (\n JSON.stringify(\n {\n semi: true,\n trailingComma: \"es5\",\n singleQuote: false,\n printWidth: 80,\n tabWidth: 2,\n useTabs: false,\n arrowParens: \"always\",\n endOfLine: \"lf\",\n },\n null,\n 2\n ) + \"\\n\"\n );\n}\n\n/**\n * Get Prettier ignore file content (matching zero-to-one project pattern)\n */\nfunction getPrettierIgnore(): string {\n return `node_modules\ndist\nbuild\n.turbo\n.next\n*.lock\npnpm-lock.yaml\ncoverage\n`;\n}\n\n/**\n * Check if Prettier is already configured\n */\nfunction hasPrettierConfig(targetDir: string): boolean {\n const prettierFiles = [\n \".prettierrc\",\n \".prettierrc.js\",\n \".prettierrc.cjs\",\n \".prettierrc.json\",\n \".prettierrc.yaml\",\n \".prettierrc.yml\",\n \".prettierrc.toml\",\n \"prettier.config.js\",\n \"prettier.config.cjs\",\n \"prettier.config.mjs\",\n ];\n\n return prettierFiles.some((file) => fileExists(join(targetDir, file)));\n}\n\n/**\n * Generate Prettier configuration\n */\nexport async function generatePrettier(\n targetDir: string\n): Promise<GeneratorResult> {\n const result: GeneratorResult = {\n created: [],\n modified: [],\n skipped: [],\n backedUp: [],\n };\n\n // Skip if Prettier is already configured\n if (hasPrettierConfig(targetDir)) {\n result.skipped.push(\".prettierrc (already exists)\");\n return result;\n }\n\n // Create .prettierrc\n const configPath = join(targetDir, \".prettierrc\");\n const configResult = await writeFileSafe(configPath, getPrettierConfig(), {\n backup: true,\n });\n\n if (configResult.created) {\n result.created.push(\".prettierrc\");\n if (configResult.backedUp) {\n result.backedUp.push(configResult.backedUp);\n }\n }\n\n // Create .prettierignore\n const ignorePath = join(targetDir, \".prettierignore\");\n const ignoreResult = await writeFileSafe(ignorePath, getPrettierIgnore(), {\n backup: true,\n overwrite: false, // Don't overwrite existing ignore file\n });\n\n if (ignoreResult.created) {\n result.created.push(\".prettierignore\");\n if (ignoreResult.backedUp) {\n result.backedUp.push(ignoreResult.backedUp);\n }\n } else {\n result.skipped.push(\".prettierignore (already exists)\");\n }\n\n return result;\n}\n","import { existsSync } from \"node:fs\";\nimport { readdir, copyFile } from \"node:fs/promises\";\nimport { join, dirname } from \"node:path\";\nimport { fileURLToPath } from \"node:url\";\nimport type { GeneratorResult } from \"../types/config.js\";\nimport { ensureDir, backupFile } from \"../utils/file-system.js\";\n\n/**\n * Get the path to the skills directory in the installed package\n */\nfunction getPackageSkillsDir(): string {\n // In ESM, we use import.meta.url to find the package location\n // tsup bundles everything into dist/cli.js, so we only need to go up 1 level\n const currentFilePath = fileURLToPath(import.meta.url);\n const packageRoot = join(dirname(currentFilePath), \"..\");\n return join(packageRoot, \".claude\", \"skills\");\n}\n\n/**\n * Recursively copy a directory\n */\nasync function copyDirectory(\n srcDir: string,\n destDir: string,\n result: GeneratorResult,\n baseDir: string,\n skipDirs?: string[]\n): Promise<void> {\n await ensureDir(destDir);\n\n const entries = await readdir(srcDir, { withFileTypes: true });\n\n for (const entry of entries) {\n // Skip directories in the skipDirs list\n if (skipDirs && entry.isDirectory() && skipDirs.includes(entry.name)) {\n continue;\n }\n\n const srcPath = join(srcDir, entry.name);\n const destPath = join(destDir, entry.name);\n const relativePath = destPath.replace(baseDir + \"/\", \"\");\n\n if (entry.isDirectory()) {\n await copyDirectory(srcPath, destPath, result, baseDir, skipDirs);\n } else {\n // Check if destination exists\n if (existsSync(destPath)) {\n // Backup existing file\n const backupPath = await backupFile(destPath);\n if (backupPath) {\n result.backedUp.push(relativePath);\n }\n }\n\n // Copy the file\n await copyFile(srcPath, destPath);\n result.created.push(relativePath);\n }\n }\n}\n\n/**\n * Generate Claude Code skills by copying them to the target project\n *\n * This copies the bundled .claude/skills/ directory to the target project,\n * enabling AI-assisted code quality enforcement when using Claude Code.\n */\nexport async function generateClaudeSkills(\n targetDir: string,\n options?: { includeAsana?: boolean }\n): Promise<GeneratorResult> {\n const result: GeneratorResult = {\n created: [],\n modified: [],\n skipped: [],\n backedUp: [],\n };\n\n const packageSkillsDir = getPackageSkillsDir();\n const targetSkillsDir = join(targetDir, \".claude\", \"skills\");\n\n // Check if source skills directory exists\n if (!existsSync(packageSkillsDir)) {\n // Skills not bundled (development mode or missing)\n console.warn(\n \"Warning: Skills directory not found in package. Skipping skills generation.\"\n );\n return result;\n }\n\n // Ensure target .claude directory exists\n await ensureDir(join(targetDir, \".claude\"));\n\n // Build list of directories to skip based on options\n const skipDirs: string[] = [];\n if (!options?.includeAsana) {\n skipDirs.push(\"asana\");\n }\n\n // Copy all skills (excluding skipped directories)\n await copyDirectory(packageSkillsDir, targetSkillsDir, result, targetDir, skipDirs);\n\n return result;\n}","import { existsSync } from \"node:fs\";\nimport { readFile } from \"node:fs/promises\";\nimport { join } from \"node:path\";\nimport type { GeneratorResult } from \"../types/config.js\";\nimport { writeFileSafe } from \"../utils/file-system.js\";\nimport { hasEslint } from \"../utils/detect-project.js\";\n\n/**\n * Check if project uses React\n */\nasync function hasReact(targetDir: string): Promise<boolean> {\n try {\n const pkgPath = join(targetDir, \"package.json\");\n if (existsSync(pkgPath)) {\n const content = await readFile(pkgPath, \"utf-8\");\n const pkg = JSON.parse(content);\n const deps = { ...pkg.dependencies, ...pkg.devDependencies };\n return \"react\" in deps || \"react-dom\" in deps;\n }\n } catch {\n // Ignore parse errors\n }\n return false;\n}\n\n/**\n * Generate ESLint flat config content for TypeScript projects (matching zero-to-one pattern)\n */\nfunction generateTsConfig(hasReactDep: boolean): string {\n if (hasReactDep) {\n return `import eslint from \"@eslint/js\";\nimport tseslint from \"typescript-eslint\";\nimport eslintConfigPrettier from \"eslint-config-prettier\";\nimport reactPlugin from \"eslint-plugin-react\";\nimport reactHooksPlugin from \"eslint-plugin-react-hooks\";\nimport globals from \"globals\";\n\nexport default tseslint.config(\n eslint.configs.recommended,\n ...tseslint.configs.strict,\n eslintConfigPrettier,\n {\n files: [\"**/*.{ts,tsx}\"],\n languageOptions: {\n parserOptions: {\n ecmaFeatures: {\n jsx: true,\n },\n },\n globals: {\n ...globals.browser,\n ...globals.node,\n },\n },\n plugins: {\n react: reactPlugin,\n \"react-hooks\": reactHooksPlugin,\n },\n rules: {\n // TypeScript rules\n \"@typescript-eslint/no-unused-vars\": [\n \"error\",\n { argsIgnorePattern: \"^_\", varsIgnorePattern: \"^_\" },\n ],\n \"@typescript-eslint/no-explicit-any\": \"warn\",\n \"@typescript-eslint/consistent-type-imports\": [\n \"warn\",\n { prefer: \"type-imports\" },\n ],\n\n // React rules\n \"react/react-in-jsx-scope\": \"off\",\n \"react/prop-types\": \"off\",\n \"react-hooks/rules-of-hooks\": \"error\",\n \"react-hooks/exhaustive-deps\": \"warn\",\n\n // General rules\n \"no-console\": [\"warn\", { allow: [\"warn\", \"error\"] }],\n },\n settings: {\n react: {\n version: \"detect\",\n },\n },\n },\n {\n // CommonJS config files (cz.config.js, commitlint.config.js, etc.)\n files: [\"*.config.js\", \"*.config.cjs\"],\n languageOptions: {\n globals: {\n ...globals.node,\n },\n sourceType: \"commonjs\",\n },\n },\n {\n ignores: [\"node_modules/\", \"dist/\", \"build/\", \".next/\", \"coverage/\", \".turbo/\"],\n }\n);\n`;\n }\n\n return `import eslint from \"@eslint/js\";\nimport tseslint from \"typescript-eslint\";\nimport eslintConfigPrettier from \"eslint-config-prettier\";\nimport globals from \"globals\";\n\nexport default tseslint.config(\n eslint.configs.recommended,\n ...tseslint.configs.strict,\n eslintConfigPrettier,\n {\n files: [\"**/*.{ts,tsx}\"],\n languageOptions: {\n globals: {\n ...globals.node,\n },\n },\n rules: {\n // TypeScript rules\n \"@typescript-eslint/no-unused-vars\": [\n \"error\",\n { argsIgnorePattern: \"^_\", varsIgnorePattern: \"^_\" },\n ],\n \"@typescript-eslint/no-explicit-any\": \"warn\",\n \"@typescript-eslint/consistent-type-imports\": [\n \"warn\",\n { prefer: \"type-imports\" },\n ],\n\n // General rules\n \"no-console\": [\"warn\", { allow: [\"warn\", \"error\"] }],\n },\n },\n {\n // CommonJS config files (cz.config.js, commitlint.config.js, etc.)\n files: [\"*.config.js\", \"*.config.cjs\"],\n languageOptions: {\n globals: {\n ...globals.node,\n },\n sourceType: \"commonjs\",\n },\n },\n {\n ignores: [\"node_modules/\", \"dist/\", \"build/\", \"coverage/\", \".turbo/\"],\n }\n);\n`;\n}\n\n/**\n * Generate ESLint flat config content for JavaScript projects\n */\nfunction generateJsConfig(hasReactDep: boolean): string {\n if (hasReactDep) {\n return `import eslint from \"@eslint/js\";\nimport eslintConfigPrettier from \"eslint-config-prettier\";\nimport reactPlugin from \"eslint-plugin-react\";\nimport reactHooksPlugin from \"eslint-plugin-react-hooks\";\nimport globals from \"globals\";\n\nexport default [\n eslint.configs.recommended,\n eslintConfigPrettier,\n {\n files: [\"**/*.{js,jsx}\"],\n languageOptions: {\n ecmaVersion: \"latest\",\n sourceType: \"module\",\n parserOptions: {\n ecmaFeatures: {\n jsx: true,\n },\n },\n globals: {\n ...globals.browser,\n ...globals.node,\n },\n },\n plugins: {\n react: reactPlugin,\n \"react-hooks\": reactHooksPlugin,\n },\n rules: {\n // React rules\n \"react/react-in-jsx-scope\": \"off\",\n \"react/prop-types\": \"warn\",\n \"react-hooks/rules-of-hooks\": \"error\",\n \"react-hooks/exhaustive-deps\": \"warn\",\n\n // General rules\n \"no-console\": [\"warn\", { allow: [\"warn\", \"error\"] }],\n \"no-unused-vars\": [\"error\", { argsIgnorePattern: \"^_\", varsIgnorePattern: \"^_\" }],\n },\n settings: {\n react: {\n version: \"detect\",\n },\n },\n },\n {\n // CommonJS config files (cz.config.js, commitlint.config.js, etc.)\n files: [\"*.config.js\", \"*.config.cjs\"],\n languageOptions: {\n globals: {\n ...globals.node,\n },\n sourceType: \"commonjs\",\n },\n },\n {\n ignores: [\"node_modules/\", \"dist/\", \"build/\", \".next/\", \"coverage/\", \".turbo/\"],\n },\n];\n`;\n }\n\n return `import eslint from \"@eslint/js\";\nimport eslintConfigPrettier from \"eslint-config-prettier\";\nimport globals from \"globals\";\n\nexport default [\n eslint.configs.recommended,\n eslintConfigPrettier,\n {\n files: [\"**/*.js\"],\n languageOptions: {\n ecmaVersion: \"latest\",\n sourceType: \"module\",\n globals: {\n ...globals.node,\n },\n },\n rules: {\n // General rules\n \"no-console\": [\"warn\", { allow: [\"warn\", \"error\"] }],\n \"no-unused-vars\": [\"error\", { argsIgnorePattern: \"^_\", varsIgnorePattern: \"^_\" }],\n },\n },\n {\n // CommonJS config files (cz.config.js, commitlint.config.js, etc.)\n files: [\"*.config.js\", \"*.config.cjs\"],\n languageOptions: {\n globals: {\n ...globals.node,\n },\n sourceType: \"commonjs\",\n },\n },\n {\n ignores: [\"node_modules/\", \"dist/\", \"build/\", \"coverage/\", \".turbo/\"],\n },\n];\n`;\n}\n\n/**\n * Check if project uses React (exported for use by other modules)\n */\nexport async function detectReact(targetDir: string): Promise<boolean> {\n return hasReact(targetDir);\n}\n\n/**\n * Generate ESLint configuration file\n *\n * @param targetDir - The target directory to write to\n * @param usesTypeScript - Whether the project uses TypeScript\n * @param force - Force generation even if ESLint is already configured\n */\nexport async function generateEslint(\n targetDir: string,\n usesTypeScript: boolean,\n force: boolean = false\n): Promise<GeneratorResult> {\n const result: GeneratorResult = {\n created: [],\n modified: [],\n skipped: [],\n backedUp: [],\n };\n\n // Check if ESLint is already configured (unless force)\n if (!force && (await hasEslint(targetDir))) {\n result.skipped.push(\"eslint.config.js (ESLint already configured)\");\n return result;\n }\n\n // Detect React\n const usesReact = await hasReact(targetDir);\n\n // Generate appropriate config\n const config = usesTypeScript\n ? generateTsConfig(usesReact)\n : generateJsConfig(usesReact);\n\n // Write config file\n const configPath = join(targetDir, \"eslint.config.js\");\n const writeResult = await writeFileSafe(configPath, config);\n\n if (writeResult.backedUp) {\n result.backedUp.push(\"eslint.config.js\");\n }\n\n result.created.push(\"eslint.config.js\");\n\n return result;\n}\n","import { join } from \"node:path\";\nimport { writeFileSafe } from \"../utils/file-system.js\";\nimport type { GeneratorResult, PackageManagerInfo } from \"../types/config.js\";\n\n/**\n * Generate Quick Reference guide for developers\n */\nexport async function generateQuickReference(\n targetDir: string,\n pm: PackageManagerInfo\n): Promise<GeneratorResult> {\n const result: GeneratorResult = {\n created: [],\n modified: [],\n skipped: [],\n backedUp: [],\n };\n\n const quickRefPath = join(targetDir, \".github\", \"QUICK_REFERENCE.md\");\n\n const content = `# RaftStack Quick Reference\n\n> One-page guide for the RaftStack Git workflow\n\n## 🚀 Daily Workflow\n\n### 1. Create a Branch\n\n\\`\\`\\`bash\n# Format: <type>/<short-description>\ngit checkout -b feature/user-authentication\ngit checkout -b bugfix/login-redirect\ngit checkout -b hotfix/payment-timeout\n\\`\\`\\`\n\n**Branch types:** \\`feature\\`, \\`bugfix\\`, \\`hotfix\\`, \\`chore\\`, \\`refactor\\`\n\n### 2. Make Commits\n\n\\`\\`\\`bash\n# Use the interactive commit tool\n${pm.run} commit\n\\`\\`\\`\n\nThis will prompt you for:\n- Type (feat, fix, docs, etc.)\n- Scope (optional)\n- Description\n- Body (optional)\n- **Task link (required)**\n\n### 3. Commit Message Format\n\n\\`\\`\\`\n✨ feat(auth): add user login form\n\n- Created LoginForm component\n- Added form validation\n- Integrated with API\n\nTask: https://app.asana.com/0/project/task\n\\`\\`\\`\n\n### 4. Create Pull Request\n\n\\`\\`\\`bash\ngit push -u origin feature/my-feature\n# Then create PR on GitHub\n\\`\\`\\`\n\n---\n\n## 📝 Commit Types\n\n| Type | Emoji | Use For |\n|------|-------|---------|\n| feat | ✨ | New feature |\n| fix | 🐛 | Bug fix |\n| docs | 📝 | Documentation |\n| style | 💄 | Formatting (no logic change) |\n| refactor | ♻️ | Code restructuring |\n| perf | ⚡ | Performance improvement |\n| test | ✅ | Adding tests |\n| build | 📦 | Build system changes |\n| ci | 👷 | CI configuration |\n| chore | 🔧 | Maintenance |\n\n---\n\n## ✅ PR Checklist\n\nBefore submitting:\n- [ ] Branch name follows convention\n- [ ] All commits have task links\n- [ ] Tests pass locally\n- [ ] PR description filled out\n- [ ] Size is reasonable (< 400 lines)\n\n---\n\n## 🔧 Useful Commands\n\n\\`\\`\\`bash\n# Interactive commit\n${pm.run} commit\n\n# Check compliance metrics\n${pm.exec} @raftlabs/raftstack metrics\n\n# Run linting\n${pm.run} lint\n\n# Run tests\n${pm.run} test\n\\`\\`\\`\n\n---\n\n## ❌ Common Mistakes\n\n| Wrong | Right |\n|-------|-------|\n| \\`Feature/UserAuth\\` | \\`feature/user-auth\\` |\n| \\`fixed bug\\` | \\`fix(auth): resolve login redirect\\` |\n| No task link | Always include \\`Task: <url>\\` |\n| 1000+ line PR | Split into smaller PRs |\n\n---\n\n## 📚 More Info\n\n- [CONTRIBUTING.md](../CONTRIBUTING.md) - Full contribution guide\n- [RaftStack Docs](https://github.com/Raft-Labs/raftstack) - CLI documentation\n\n---\n\n*Generated by RaftStack - Git workflow standardization for teams*\n`;\n\n const writeResult = await writeFileSafe(quickRefPath, content);\n\n if (writeResult.created) {\n if (writeResult.backedUp) {\n result.modified.push(\".github/QUICK_REFERENCE.md\");\n result.backedUp.push(\".github/QUICK_REFERENCE.md\");\n } else {\n result.created.push(\".github/QUICK_REFERENCE.md\");\n }\n } else {\n result.skipped.push(\".github/QUICK_REFERENCE.md\");\n }\n\n return result;\n}\n","import { execa } from \"execa\";\nimport { existsSync } from \"node:fs\";\nimport { join } from \"node:path\";\n\n/**\n * Check if directory is a git repository\n */\nexport async function isGitRepo(\n targetDir: string = process.cwd()\n): Promise<boolean> {\n // Quick check for .git directory\n if (existsSync(join(targetDir, \".git\"))) {\n return true;\n }\n\n // Fallback to git command (handles worktrees, etc.)\n try {\n await execa(\"git\", [\"rev-parse\", \"--git-dir\"], { cwd: targetDir });\n return true;\n } catch {\n return false;\n }\n}\n\n/**\n * Get the root directory of the git repository\n */\nexport async function getGitRoot(\n targetDir: string = process.cwd()\n): Promise<string | null> {\n try {\n const { stdout } = await execa(\"git\", [\"rev-parse\", \"--show-toplevel\"], {\n cwd: targetDir,\n });\n return stdout.trim();\n } catch {\n return null;\n }\n}\n\n/**\n * Get current branch name\n */\nexport async function getCurrentBranch(\n targetDir: string = process.cwd()\n): Promise<string | null> {\n try {\n const { stdout } = await execa(\"git\", [\"branch\", \"--show-current\"], {\n cwd: targetDir,\n });\n return stdout.trim() || null;\n } catch {\n return null;\n }\n}\n\n/**\n * Check if gh CLI is available and authenticated\n */\nexport async function isGhCliAvailable(): Promise<boolean> {\n try {\n await execa(\"gh\", [\"auth\", \"status\"]);\n return true;\n } catch {\n return false;\n }\n}\n\n/**\n * Get GitHub repository info (owner/repo)\n */\nexport async function getGitHubRepoInfo(\n targetDir: string = process.cwd()\n): Promise<{ owner: string; repo: string } | null> {\n try {\n const { stdout } = await execa(\"gh\", [\"repo\", \"view\", \"--json\", \"owner,name\"], {\n cwd: targetDir,\n });\n const data = JSON.parse(stdout);\n return {\n owner: data.owner.login,\n repo: data.name,\n };\n } catch {\n return null;\n }\n}\n\n/**\n * Initialize husky in the repository\n */\nexport async function initHusky(\n targetDir: string = process.cwd()\n): Promise<void> {\n await execa(\"npx\", [\"husky\", \"init\"], { cwd: targetDir });\n}\n\n/**\n * Run a git command\n */\nexport async function runGitCommand(\n args: string[],\n targetDir: string = process.cwd()\n): Promise<string> {\n const { stdout } = await execa(\"git\", args, { cwd: targetDir });\n return stdout;\n}\n","import * as p from \"@clack/prompts\";\nimport pc from \"picocolors\";\nimport { execa } from \"execa\";\nimport { isGhCliAvailable, getGitHubRepoInfo } from \"../utils/git.js\";\n\n/**\n * Merge strategy options\n */\nexport type MergeStrategy = \"rebase\" | \"squash\" | \"merge\";\n\n/**\n * Branch protection settings\n */\nexport interface BranchProtectionSettings {\n branch: string;\n requiredReviews: number;\n dismissStaleReviews: boolean;\n requireCodeOwners: boolean;\n requireStatusChecks: boolean;\n statusChecks: string[];\n requireConversationResolution: boolean;\n restrictPushes: boolean;\n blockForcePushes: boolean;\n blockDeletions: boolean;\n}\n\n/**\n * Repository settings for merge strategies\n */\nexport interface RepositorySettings {\n allowMergeCommit: boolean;\n allowSquashMerge: boolean;\n allowRebaseMerge: boolean;\n deleteBranchOnMerge: boolean;\n}\n\n/**\n * Default branch protection settings\n */\nfunction getDefaultSettings(branch: string): BranchProtectionSettings {\n return {\n branch,\n requiredReviews: 1,\n dismissStaleReviews: true,\n requireCodeOwners: true,\n requireStatusChecks: true,\n statusChecks: [\"check\"],\n requireConversationResolution: true,\n restrictPushes: false,\n blockForcePushes: true,\n blockDeletions: true,\n };\n}\n\n/**\n * Get repository settings based on merge strategy\n */\nfunction getMergeStrategySettings(strategy: MergeStrategy): RepositorySettings {\n switch (strategy) {\n case \"rebase\":\n return {\n allowMergeCommit: false,\n allowSquashMerge: false,\n allowRebaseMerge: true,\n deleteBranchOnMerge: true,\n };\n case \"squash\":\n return {\n allowMergeCommit: false,\n allowSquashMerge: true,\n allowRebaseMerge: false,\n deleteBranchOnMerge: true,\n };\n case \"merge\":\n return {\n allowMergeCommit: true,\n allowSquashMerge: false,\n allowRebaseMerge: false,\n deleteBranchOnMerge: true,\n };\n }\n}\n\n/**\n * Apply branch protection using gh CLI\n */\nasync function applyBranchProtection(\n owner: string,\n repo: string,\n settings: BranchProtectionSettings\n): Promise<void> {\n const args = [\n \"api\",\n \"-X\",\n \"PUT\",\n `/repos/${owner}/${repo}/branches/${settings.branch}/protection`,\n \"-f\",\n `required_pull_request_reviews[required_approving_review_count]=${settings.requiredReviews}`,\n \"-f\",\n `required_pull_request_reviews[dismiss_stale_reviews]=${settings.dismissStaleReviews}`,\n \"-f\",\n `required_pull_request_reviews[require_code_owner_reviews]=${settings.requireCodeOwners}`,\n \"-f\",\n `required_status_checks[strict]=true`,\n \"-f\",\n `enforce_admins=true`,\n \"-f\",\n `allow_force_pushes=${!settings.blockForcePushes}`,\n \"-f\",\n `allow_deletions=${!settings.blockDeletions}`,\n \"-f\",\n `required_conversation_resolution=${settings.requireConversationResolution}`,\n ];\n\n // Add status checks\n if (settings.requireStatusChecks && settings.statusChecks.length > 0) {\n for (const check of settings.statusChecks) {\n args.push(\"-f\", `required_status_checks[contexts][]=${check}`);\n }\n } else {\n args.push(\"-F\", \"required_status_checks=null\");\n }\n\n // Add restrictions (null means no restrictions beyond PRs)\n args.push(\"-F\", \"restrictions=null\");\n\n await execa(\"gh\", args);\n}\n\n/**\n * Apply repository merge settings using gh CLI\n */\nasync function applyMergeStrategy(\n owner: string,\n repo: string,\n settings: RepositorySettings\n): Promise<void> {\n const args = [\n \"api\",\n \"-X\",\n \"PATCH\",\n `/repos/${owner}/${repo}`,\n \"-f\",\n `allow_merge_commit=${settings.allowMergeCommit}`,\n \"-f\",\n `allow_squash_merge=${settings.allowSquashMerge}`,\n \"-f\",\n `allow_rebase_merge=${settings.allowRebaseMerge}`,\n \"-f\",\n `delete_branch_on_merge=${settings.deleteBranchOnMerge}`,\n ];\n\n await execa(\"gh\", args);\n}\n\n/**\n * Run the setup-protection command\n */\nexport async function runSetupProtection(\n targetDir: string = process.cwd()\n): Promise<void> {\n console.log();\n p.intro(pc.bgCyan(pc.black(\" Branch Protection Setup \")));\n\n // Check gh CLI\n const spinner = p.spinner();\n spinner.start(\"Checking GitHub CLI...\");\n\n const ghAvailable = await isGhCliAvailable();\n\n if (!ghAvailable) {\n spinner.stop(\"GitHub CLI not found or not authenticated\");\n console.log();\n p.log.error(pc.red(\"The GitHub CLI (gh) is required for this command.\"));\n p.log.info(\"Install it from: https://cli.github.com/\");\n p.log.info(\"Then run: gh auth login\");\n console.log();\n p.log.info(\n pc.dim(\n \"Alternatively, see .github/BRANCH_PROTECTION_SETUP.md for manual instructions.\"\n )\n );\n process.exit(1);\n }\n\n spinner.stop(\"GitHub CLI ready\");\n\n // Get repo info\n spinner.start(\"Getting repository info...\");\n const repoInfo = await getGitHubRepoInfo(targetDir);\n\n if (!repoInfo) {\n spinner.stop(\"Could not determine repository\");\n p.log.error(\n pc.red(\"Could not determine the GitHub repository for this directory.\")\n );\n p.log.info(\"Make sure you're in a git repository with a GitHub remote.\");\n process.exit(1);\n }\n\n spinner.stop(`Repository: ${pc.cyan(`${repoInfo.owner}/${repoInfo.repo}`)}`);\n\n // Ask which branches to protect\n const branches = await p.multiselect({\n message: \"Which branches need protection?\",\n options: [\n { value: \"main\", label: \"main\", hint: \"recommended\" },\n { value: \"master\", label: \"master\", hint: \"legacy default\" },\n { value: \"staging\", label: \"staging\", hint: \"staging environment\" },\n { value: \"production\", label: \"production\", hint: \"production environment\" },\n { value: \"development\", label: \"development\", hint: \"development branch\" },\n { value: \"develop\", label: \"develop\", hint: \"alternative dev branch\" },\n ],\n required: true,\n initialValues: [\"main\"],\n });\n\n if (p.isCancel(branches)) {\n p.cancel(\"Setup cancelled.\");\n process.exit(0);\n }\n\n // Ask for merge strategy\n const mergeStrategy = await p.select({\n message: \"Default merge strategy for PRs?\",\n options: [\n {\n value: \"rebase\",\n label: \"Rebase merge\",\n hint: \"recommended - clean linear history\",\n },\n {\n value: \"squash\",\n label: \"Squash merge\",\n hint: \"single commit per PR\",\n },\n {\n value: \"merge\",\n label: \"Merge commit\",\n hint: \"preserve all commits with merge commit\",\n },\n ],\n initialValue: \"rebase\",\n });\n\n if (p.isCancel(mergeStrategy)) {\n p.cancel(\"Setup cancelled.\");\n process.exit(0);\n }\n\n // Ask for number of required reviews\n const reviews = await p.text({\n message: \"How many approving reviews are required?\",\n placeholder: \"1\",\n initialValue: \"1\",\n validate: (value) => {\n const num = parseInt(value, 10);\n if (isNaN(num) || num < 0 || num > 6) {\n return \"Must be a number between 0 and 6\";\n }\n return undefined;\n },\n });\n\n if (p.isCancel(reviews)) {\n p.cancel(\"Setup cancelled.\");\n process.exit(0);\n }\n\n const requiredReviews = parseInt(reviews, 10);\n\n // Confirm settings\n const mergeStrategyLabels: Record<MergeStrategy, string> = {\n rebase: \"Rebase merge\",\n squash: \"Squash merge\",\n merge: \"Merge commit\",\n };\n\n console.log();\n p.note(\n [\n `${pc.cyan(\"Repository:\")} ${repoInfo.owner}/${repoInfo.repo}`,\n `${pc.cyan(\"Protected branches:\")} ${(branches as string[]).join(\", \")}`,\n `${pc.cyan(\"Merge strategy:\")} ${mergeStrategyLabels[mergeStrategy as MergeStrategy]}`,\n `${pc.cyan(\"Required reviews:\")} ${requiredReviews}`,\n `${pc.cyan(\"Dismiss stale reviews:\")} Yes`,\n `${pc.cyan(\"Require code owners:\")} Yes`,\n `${pc.cyan(\"Require status checks:\")} Yes`,\n `${pc.cyan(\"Block force pushes:\")} Yes`,\n `${pc.cyan(\"Block deletions:\")} Yes`,\n `${pc.cyan(\"Delete branch on merge:\")} Yes`,\n ].join(\"\\n\"),\n \"Branch Protection Settings\"\n );\n\n const confirmed = await p.confirm({\n message: \"Apply these branch protection rules?\",\n initialValue: true,\n });\n\n if (p.isCancel(confirmed) || !confirmed) {\n p.cancel(\"Setup cancelled.\");\n process.exit(0);\n }\n\n // Apply merge strategy settings first\n spinner.start(\"Configuring merge strategy...\");\n\n try {\n const repoSettings = getMergeStrategySettings(mergeStrategy as MergeStrategy);\n await applyMergeStrategy(repoInfo.owner, repoInfo.repo, repoSettings);\n spinner.stop(\"Merge strategy configured!\");\n } catch (error) {\n spinner.stop(\"Failed to configure merge strategy\");\n const errorMsg = error instanceof Error ? error.message : \"Unknown error\";\n p.log.warn(pc.yellow(`Warning: Could not set merge strategy: ${errorMsg}`));\n p.log.info(pc.dim(\"Continuing with branch protection...\"));\n }\n\n // Apply branch protection for each branch\n const protectedBranches: string[] = [];\n const failedBranches: string[] = [];\n\n for (const branch of branches as string[]) {\n spinner.start(`Protecting branch: ${branch}...`);\n\n try {\n const settings = getDefaultSettings(branch);\n settings.requiredReviews = requiredReviews;\n\n await applyBranchProtection(repoInfo.owner, repoInfo.repo, settings);\n protectedBranches.push(branch);\n spinner.stop(`Protected: ${pc.green(branch)}`);\n } catch (error) {\n failedBranches.push(branch);\n spinner.stop(`Failed: ${pc.red(branch)}`);\n\n const errorMsg = error instanceof Error ? error.message : \"Unknown error\";\n p.log.warn(\n pc.yellow(\n `Could not protect ${branch}: ${errorMsg.includes(\"Branch not found\") ? \"branch does not exist\" : errorMsg}`\n )\n );\n }\n }\n\n // Show summary\n console.log();\n\n if (protectedBranches.length > 0) {\n p.log.success(\n pc.green(`Branch protection enabled for: ${pc.cyan(protectedBranches.join(\", \"))}`)\n );\n }\n\n if (failedBranches.length > 0) {\n p.log.warn(\n pc.yellow(\n `Could not protect: ${pc.red(failedBranches.join(\", \"))} (branches may not exist yet)`\n )\n );\n p.log.info(pc.dim(\"Create these branches first, then run this command again.\"));\n }\n\n if (protectedBranches.length > 0) {\n p.outro(pc.green(\"Setup complete!\"));\n } else {\n p.outro(pc.yellow(\"No branches were protected.\"));\n process.exit(1);\n }\n}\n","import { execa } from \"execa\";\nimport * as p from \"@clack/prompts\";\nimport pc from \"picocolors\";\nimport { isGitRepo } from \"../utils/git.js\";\n\ninterface MetricsResult {\n totalCommits: number;\n commitsWithTaskLinks: number;\n taskLinkCompliance: number;\n branchNames: string[];\n validBranches: number;\n invalidBranches: number;\n branchCompliance: number;\n}\n\n/**\n * Get commits from the last N days\n */\nasync function getRecentCommits(\n targetDir: string,\n days: number\n): Promise<string[]> {\n try {\n const { stdout } = await execa(\n \"git\",\n [\"log\", `--since=${days} days ago`, \"--oneline\", \"--no-merges\"],\n { cwd: targetDir }\n );\n return stdout.trim().split(\"\\n\").filter(Boolean);\n } catch {\n return [];\n }\n}\n\n/**\n * Get commit messages with full body\n */\nasync function getCommitMessages(\n targetDir: string,\n days: number\n): Promise<string[]> {\n try {\n const { stdout } = await execa(\n \"git\",\n [\n \"log\",\n `--since=${days} days ago`,\n \"--format=%B---COMMIT_SEPARATOR---\",\n \"--no-merges\",\n ],\n { cwd: targetDir }\n );\n return stdout.split(\"---COMMIT_SEPARATOR---\").filter((m) => m.trim());\n } catch {\n return [];\n }\n}\n\n/**\n * Get all branch names\n */\nasync function getBranchNames(targetDir: string): Promise<string[]> {\n try {\n const { stdout } = await execa(\n \"git\",\n [\"branch\", \"-a\", \"--format=%(refname:short)\"],\n { cwd: targetDir }\n );\n return stdout\n .trim()\n .split(\"\\n\")\n .filter(Boolean)\n .map((b) => b.replace(\"origin/\", \"\"))\n .filter((b, i, arr) => arr.indexOf(b) === i); // unique\n } catch {\n return [];\n }\n}\n\n/**\n * Validate branch name against convention\n */\nfunction isValidBranchName(name: string): boolean {\n const pattern =\n /^(main|staging|development|master)$|^(feature|bugfix|hotfix|chore|refactor)\\/[a-z0-9-]+$/;\n return pattern.test(name);\n}\n\n/**\n * Check if commit has task link\n */\nfunction hasTaskLink(message: string): boolean {\n return (\n message.includes(\"app.asana.com\") ||\n message.includes(\"Task:\") ||\n message.includes(\"task:\") ||\n message.includes(\"Closes #\") ||\n message.includes(\"Fixes #\")\n );\n}\n\n/**\n * Calculate metrics for the repository\n */\nasync function calculateMetrics(\n targetDir: string,\n days: number\n): Promise<MetricsResult> {\n const [commits, commitMessages, branches] = await Promise.all([\n getRecentCommits(targetDir, days),\n getCommitMessages(targetDir, days),\n getBranchNames(targetDir),\n ]);\n\n const commitsWithTaskLinks = commitMessages.filter(hasTaskLink).length;\n const validBranches = branches.filter(isValidBranchName);\n const invalidBranches = branches.filter((b) => !isValidBranchName(b));\n\n return {\n totalCommits: commits.length,\n commitsWithTaskLinks,\n taskLinkCompliance:\n commits.length > 0\n ? Math.round((commitsWithTaskLinks / commits.length) * 100)\n : 100,\n branchNames: branches,\n validBranches: validBranches.length,\n invalidBranches: invalidBranches.length,\n branchCompliance:\n branches.length > 0\n ? Math.round((validBranches.length / branches.length) * 100)\n : 100,\n };\n}\n\n/**\n * Format compliance percentage with color\n */\nfunction formatCompliance(percentage: number): string {\n if (percentage >= 90) return pc.green(`${percentage}%`);\n if (percentage >= 70) return pc.yellow(`${percentage}%`);\n return pc.red(`${percentage}%`);\n}\n\n/**\n * Run the metrics command\n */\nexport async function runMetrics(targetDir: string): Promise<void> {\n p.intro(pc.bgCyan(pc.black(\" RaftStack Metrics \")));\n\n if (!(await isGitRepo(targetDir))) {\n p.cancel(\"Not a git repository\");\n process.exit(1);\n }\n\n const daysOption = await p.select({\n message: \"Time period to analyze:\",\n options: [\n { value: 7, label: \"Last 7 days\" },\n { value: 14, label: \"Last 14 days\" },\n { value: 30, label: \"Last 30 days\" },\n { value: 90, label: \"Last 90 days\" },\n ],\n });\n\n if (p.isCancel(daysOption)) {\n p.cancel(\"Operation cancelled\");\n process.exit(0);\n }\n\n const days = daysOption as number;\n\n const spinner = p.spinner();\n spinner.start(\"Analyzing repository...\");\n\n const metrics = await calculateMetrics(targetDir, days);\n\n spinner.stop(\"Analysis complete\");\n\n p.note(\n `${pc.bold(\"Commits\")} (last ${days} days)\n Total: ${metrics.totalCommits}\n With task links: ${metrics.commitsWithTaskLinks}\n Compliance: ${formatCompliance(metrics.taskLinkCompliance)}\n\n${pc.bold(\"Branches\")}\n Total: ${metrics.branchNames.length}\n Valid naming: ${metrics.validBranches}\n Invalid naming: ${metrics.invalidBranches}\n Compliance: ${formatCompliance(metrics.branchCompliance)}`,\n \"Repository Metrics\"\n );\n\n if (metrics.invalidBranches > 0) {\n const invalidBranches = metrics.branchNames.filter(\n (b) => !isValidBranchName(b)\n );\n p.log.warn(\n `Invalid branch names:\\n ${invalidBranches.slice(0, 10).join(\"\\n \")}${\n invalidBranches.length > 10\n ? `\\n ... and ${invalidBranches.length - 10} more`\n : \"\"\n }`\n );\n }\n\n const overallCompliance = Math.round(\n (metrics.taskLinkCompliance + metrics.branchCompliance) / 2\n );\n\n if (overallCompliance >= 90) {\n p.outro(pc.green(\"✓ Excellent compliance! Keep up the good work.\"));\n } else if (overallCompliance >= 70) {\n p.outro(pc.yellow(\"⚠ Good progress, but there's room for improvement.\"));\n } else {\n p.outro(pc.red(\"✗ Compliance needs attention. Review the guidelines.\"));\n }\n}\n","{\n \"name\": \"@raftlabs/raftstack\",\n \"version\": \"1.7.2\",\n \"description\": \"CLI tool for setting up Git hooks, commit conventions, and GitHub integration\",\n \"type\": \"module\",\n \"main\": \"./dist/index.js\",\n \"types\": \"./dist/index.d.ts\",\n \"bin\": {\n \"raftstack\": \"./dist/cli.js\"\n },\n \"exports\": {\n \".\": {\n \"types\": \"./dist/index.d.ts\",\n \"import\": \"./dist/index.js\"\n }\n },\n \"files\": [\n \"dist\",\n \"templates\",\n \".claude/skills\"\n ],\n \"scripts\": {\n \"build\": \"tsup\",\n \"dev\": \"tsup --watch\",\n \"typecheck\": \"tsc --noEmit\",\n \"test\": \"vitest\",\n \"test:run\": \"vitest run\",\n \"prepublishOnly\": \"pnpm build\",\n \"prepublish\": \"pnpm test:run && pnpm build\",\n \"pack:test\": \"pnpm pack --dry-run\",\n \"publish:test\": \"pnpm pack && tar -xvzf raftlabs-raftstack-*.tgz && rm -rf package raftlabs-raftstack-*.tgz\",\n \"release\": \"standard-version\",\n \"release:patch\": \"standard-version --release-as patch\",\n \"release:minor\": \"standard-version --release-as minor\",\n \"release:major\": \"standard-version --release-as major\",\n \"release:first\": \"standard-version --first-release\"\n },\n \"keywords\": [\n \"cli\",\n \"git-hooks\",\n \"husky\",\n \"commitlint\",\n \"lint-staged\",\n \"developer-experience\"\n ],\n \"author\": \"Aravind Jaimon <dev@aravindjaimon.com>\",\n \"license\": \"MIT\",\n \"repository\": {\n \"type\": \"git\",\n \"url\": \"git+https://github.com/Raft-Labs/raftstack.git\"\n },\n \"homepage\": \"https://github.com/Raft-Labs/raftstack#readme\",\n \"readme\": \"README.npm.md\",\n \"bugs\": {\n \"url\": \"https://github.com/Raft-Labs/raftstack/issues\"\n },\n \"publishConfig\": {\n \"access\": \"public\",\n \"registry\": \"https://registry.npmjs.org/\"\n },\n \"packageManager\": \"pnpm@10.23.0\",\n \"engines\": {\n \"node\": \">=18\"\n },\n \"devDependencies\": {\n \"@types/cross-spawn\": \"^6.0.6\",\n \"@types/node\": \"^20.10.0\",\n \"standard-version\": \"^9.5.0\",\n \"tsup\": \"^8.0.0\",\n \"typescript\": \"^5.3.0\",\n \"vitest\": \"^1.0.0\"\n },\n \"dependencies\": {\n \"@clack/prompts\": \"^0.7.0\",\n \"commander\": \"^12.0.0\",\n \"cross-spawn\": \"^7.0.6\",\n \"execa\": \"^9.6.1\",\n \"picocolors\": \"^1.0.0\"\n }\n}\n"],"mappings":"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","names":["p","pc","existsSync","join","join","existsSync","join","existsSync","readFile","join","existsSync","join","join","join","join","join","readFile","writeFile","existsSync","join","existsSync","join","join","join","join","join","join","join","join","join","join","join","join","join","join","join","existsSync","copyFile","join","dirname","join","dirname","existsSync","copyFile","existsSync","readFile","join","join","existsSync","readFile","join","join","existsSync","join","pc","spinner","p","pc","execa","execa","pc","spinner","execa","p","pc","execa","pc","spinner"]}
1
+ {"version":3,"sources":["../src/cli.ts","../src/commands/init.ts","../src/prompts/index.ts","../src/utils/detect-project.ts","../src/utils/detect-package-manager.ts","../src/generators/husky.ts","../src/utils/file-system.ts","../src/generators/commitlint.ts","../src/generators/cz-git.ts","../src/generators/lint-staged.ts","../src/utils/package-json.ts","../src/generators/branch-validation.ts","../src/generators/pr-template.ts","../src/generators/github-workflows.ts","../src/generators/codeowners.ts","../src/generators/ai-review.ts","../src/generators/branch-protection.ts","../src/generators/contributing.ts","../src/generators/prettier.ts","../src/generators/claude-skills.ts","../src/generators/eslint.ts","../src/generators/quick-reference.ts","../src/generators/shared-configs.ts","../src/utils/git.ts","../src/commands/setup-protection.ts","../src/commands/metrics.ts","../src/utils/code-analyzer.ts","../package.json"],"sourcesContent":["import { Command } from \"commander\";\nimport { runInit } from \"./commands/init.js\";\nimport { runSetupProtection } from \"./commands/setup-protection.js\";\nimport { runMetrics } from \"./commands/metrics.js\";\nimport pkg from \"../package.json\" assert { type: \"json\" };\n\nconst program = new Command();\n\nprogram\n .name(\"raftstack\")\n .description(\n \"CLI tool for setting up Git hooks, commit conventions, and GitHub integration\"\n )\n .version(pkg.version);\n\nprogram\n .command(\"init\")\n .description(\"Initialize RaftStack configuration in your project\")\n .action(async () => {\n await runInit(process.cwd());\n });\n\nprogram\n .command(\"setup-protection\")\n .description(\"Configure GitHub branch protection rules via API\")\n .action(async () => {\n await runSetupProtection(process.cwd());\n });\n\nprogram\n .command(\"metrics\")\n .description(\"Analyze repository compliance with RaftStack conventions\")\n .option(\"--git\", \"Only show Git metrics (commits, branches, authors)\")\n .option(\"--code\", \"Only show codebase compliance metrics\")\n .option(\"--ci\", \"CI mode: exit 1 if below threshold\")\n .option(\n \"--threshold <n>\",\n \"Minimum compliance percentage (default: 70)\",\n \"70\"\n )\n .option(\"--days <n>\", \"Time period in days (default: 30 in CI mode)\")\n .action(\n async (options: {\n git?: boolean;\n code?: boolean;\n ci?: boolean;\n threshold?: string;\n days?: string;\n }) => {\n await runMetrics(process.cwd(), {\n git: options.git,\n code: options.code,\n ci: options.ci,\n threshold: options.threshold ? parseInt(options.threshold, 10) : 70,\n days: options.days ? parseInt(options.days, 10) : undefined,\n });\n }\n );\n\nprogram.parse();\n","import * as p from \"@clack/prompts\";\nimport pc from \"picocolors\";\nimport type { GeneratorResult, RaftStackConfig } from \"../types/config.js\";\nimport { collectConfig } from \"../prompts/index.js\";\nimport {\n generateHuskyHooks,\n generateCommitlint,\n generateCzGit,\n getLintStagedConfig,\n generateBranchValidation,\n generatePRTemplate,\n generateGitHubWorkflows,\n generateCodeowners,\n generateAIReview,\n generateBranchProtectionDocs,\n generateContributing,\n generatePrettier,\n generateClaudeSkills,\n generateQuickReference,\n generateEslint,\n detectReact,\n detectNextJs,\n generateSharedConfigs,\n isMonorepo,\n} from \"../generators/index.js\";\nimport {\n addPackageJsonConfig,\n mergeScripts,\n readPackageJson,\n writePackageJson,\n installPackages,\n RAFTSTACK_PACKAGES,\n REACT_ESLINT_PACKAGES,\n NEXTJS_ESLINT_PACKAGES,\n} from \"../utils/package-json.js\";\nimport { isGitRepo } from \"../utils/git.js\";\n\n/**\n * Merge generator results\n */\nfunction mergeResults(results: GeneratorResult[]): GeneratorResult {\n return results.reduce(\n (acc, result) => ({\n created: [...acc.created, ...result.created],\n modified: [...acc.modified, ...result.modified],\n skipped: [...acc.skipped, ...result.skipped],\n backedUp: [...acc.backedUp, ...result.backedUp],\n }),\n { created: [], modified: [], skipped: [], backedUp: [] }\n );\n}\n\n/**\n * Update package.json with required scripts and lint-staged config\n * (Dependencies are installed separately via CLI)\n */\nasync function updateProjectPackageJson(\n targetDir: string,\n config: RaftStackConfig\n): Promise<GeneratorResult> {\n const result: GeneratorResult = {\n created: [],\n modified: [],\n skipped: [],\n backedUp: [],\n };\n\n try {\n let pkg = await readPackageJson(targetDir);\n\n // Add scripts\n const scripts: Record<string, string> = {\n prepare: \"husky\",\n commit: \"czg\",\n // ESLint scripts (always added since we install ESLint)\n lint: \"eslint .\",\n \"lint:fix\": \"eslint . --fix\",\n // Prettier scripts (always added since we install Prettier)\n format: \"prettier --write .\",\n \"format:check\": \"prettier --check .\",\n };\n\n // Add typecheck script if TypeScript is detected\n if (config.usesTypeScript) {\n scripts.typecheck = \"tsc --noEmit\";\n }\n\n pkg = mergeScripts(pkg, scripts, false);\n\n // Add lint-staged config to package.json (instead of separate file)\n // Always enable eslint and prettier since we're installing them\n const lintStagedConfig = getLintStagedConfig(\n true, // usesEslint - always true now since we install it\n true, // usesPrettier - always true now since we install it\n config.usesTypeScript\n );\n pkg = addPackageJsonConfig(pkg, \"lint-staged\", lintStagedConfig, true);\n\n await writePackageJson(pkg, targetDir);\n result.modified.push(\"package.json\");\n } catch (error) {\n result.skipped.push(\"package.json (error updating)\");\n }\n\n return result;\n}\n\n/**\n * Run the init command\n */\nexport async function runInit(targetDir: string = process.cwd()): Promise<void> {\n // Check if this is a git repository\n const isRepo = await isGitRepo(targetDir);\n if (!isRepo) {\n p.log.warn(\n pc.yellow(\n \"This directory is not a git repository. Some features may not work correctly.\"\n )\n );\n const proceed = await p.confirm({\n message: \"Continue anyway?\",\n initialValue: false,\n });\n\n if (p.isCancel(proceed) || !proceed) {\n p.cancel(\"Setup cancelled.\");\n process.exit(0);\n }\n }\n\n // Collect configuration from user\n const config = await collectConfig(targetDir);\n\n if (!config) {\n return;\n }\n\n // Detect frameworks for conditional dependencies\n const usesReact = await detectReact(targetDir);\n const usesNextJs = await detectNextJs(targetDir);\n\n // Install dependencies using CLI\n const installSpinner = p.spinner();\n let packagesToInstall = [...RAFTSTACK_PACKAGES];\n\n // Add framework-specific packages\n if (usesNextJs) {\n // Next.js includes React, so only add Next.js ESLint packages\n packagesToInstall = [...packagesToInstall, ...NEXTJS_ESLINT_PACKAGES];\n } else if (usesReact) {\n // Non-Next.js React projects need React ESLint packages\n packagesToInstall = [...packagesToInstall, ...REACT_ESLINT_PACKAGES];\n }\n\n installSpinner.start(\"Installing dependencies...\");\n const installResult = await installPackages(\n config.packageManager,\n packagesToInstall,\n targetDir\n );\n\n let installFailed = false;\n if (installResult.success) {\n installSpinner.stop(\"Dependencies installed!\");\n } else {\n installSpinner.stop(\"Failed to install dependencies\");\n p.log.warn(\n pc.yellow(\n `Could not install dependencies automatically: ${installResult.error || \"Unknown error\"}`\n )\n );\n p.log.info(\n pc.dim(\n `You can install them manually with: ${config.packageManager.name} ${config.packageManager.addDev} ${packagesToInstall.join(\" \")}`\n )\n );\n installFailed = true;\n }\n\n // Generate files with progress spinner\n const spinner = p.spinner();\n spinner.start(\"Generating configuration files...\");\n\n const results: GeneratorResult[] = [];\n\n try {\n // Core Git hooks and commit conventions\n results.push(\n await generateHuskyHooks(targetDir, config.projectType, config.packageManager)\n );\n results.push(await generateCommitlint(targetDir, config.asanaBaseUrl));\n results.push(await generateCzGit(targetDir, config.asanaBaseUrl));\n results.push(await generateBranchValidation(targetDir));\n\n // ESLint configuration (always generate since we install it)\n results.push(await generateEslint(targetDir, config.usesTypeScript, false));\n\n // Prettier (always generate since we install it)\n results.push(await generatePrettier(targetDir));\n\n // Shared config packages for monorepos (ESLint + TypeScript configs)\n if (isMonorepo(config.projectType)) {\n results.push(await generateSharedConfigs(targetDir, config.projectType));\n }\n\n // GitHub integration\n results.push(await generatePRTemplate(targetDir, !!config.asanaBaseUrl));\n results.push(\n await generateGitHubWorkflows(\n targetDir,\n config.projectType,\n config.usesTypeScript,\n true, // usesEslint - always true now\n config.packageManager\n )\n );\n results.push(await generateCodeowners(targetDir, config.codeowners));\n results.push(await generateAIReview(targetDir, config.aiReviewTool));\n results.push(await generateBranchProtectionDocs(targetDir));\n\n // Documentation\n results.push(\n await generateContributing(targetDir, !!config.asanaBaseUrl, config.packageManager)\n );\n results.push(await generateQuickReference(targetDir, config.packageManager));\n\n // Claude Code skills for AI-assisted development\n results.push(await generateClaudeSkills(targetDir, {\n includeAsana: !!config.asanaBaseUrl\n }));\n\n // Update package.json (scripts and lint-staged config)\n results.push(await updateProjectPackageJson(targetDir, config));\n\n spinner.stop(\"Configuration files generated!\");\n } catch (error) {\n spinner.stop(\"Error generating files\");\n p.log.error(\n pc.red(\n `Error: ${error instanceof Error ? error.message : \"Unknown error\"}`\n )\n );\n process.exit(1);\n }\n\n // Merge all results\n const finalResult = mergeResults(results);\n\n // Show summary\n console.log();\n\n if (finalResult.created.length > 0) {\n p.log.success(pc.green(\"Created files:\"));\n for (const file of finalResult.created) {\n console.log(` ${pc.dim(\"+\")} ${file}`);\n }\n }\n\n if (finalResult.modified.length > 0) {\n console.log();\n p.log.info(pc.blue(\"Modified files:\"));\n for (const file of finalResult.modified) {\n console.log(` ${pc.dim(\"~\")} ${file}`);\n }\n }\n\n if (finalResult.skipped.length > 0) {\n console.log();\n p.log.warn(pc.yellow(\"Skipped (already exist):\"));\n for (const file of finalResult.skipped) {\n console.log(` ${pc.dim(\"-\")} ${file}`);\n }\n }\n\n if (finalResult.backedUp.length > 0) {\n console.log();\n p.log.info(pc.dim(\"Backed up files:\"));\n for (const file of finalResult.backedUp) {\n console.log(` ${pc.dim(\"→\")} ${file}`);\n }\n }\n\n // Show next steps\n console.log();\n const nextSteps = installFailed\n ? [\n `${pc.cyan(\"1.\")} Run ${pc.yellow(config.packageManager.install)} to install dependencies`,\n `${pc.cyan(\"2.\")} Review the generated configuration files`,\n `${pc.cyan(\"3.\")} Use ${pc.yellow(`${config.packageManager.run} commit`)} for interactive commits`,\n `${pc.cyan(\"4.\")} Set up branch protection rules (see .github/BRANCH_PROTECTION_SETUP.md)`,\n ]\n : [\n `${pc.cyan(\"1.\")} Review the generated configuration files`,\n `${pc.cyan(\"2.\")} Use ${pc.yellow(`${config.packageManager.run} commit`)} for interactive commits`,\n `${pc.cyan(\"3.\")} Set up branch protection rules (see .github/BRANCH_PROTECTION_SETUP.md)`,\n ];\n p.note(nextSteps.join(\"\\n\"), \"Next Steps\");\n\n p.outro(pc.green(\"RaftStack setup complete! Happy coding! 🚀\"));\n}\n","import * as p from \"@clack/prompts\";\nimport pc from \"picocolors\";\nimport type {\n AIReviewTool,\n DetectionResult,\n PackageManager,\n PackageManagerInfo,\n ProjectType,\n RaftStackConfig,\n} from \"../types/config.js\";\nimport {\n detectProjectType,\n getProjectTypeDescription,\n hasTypeScript,\n hasEslint,\n hasPrettier,\n detectPackageManager,\n getPackageManagerInfo,\n getPackageManagerDescription,\n} from \"../utils/detect-project.js\";\n\n/**\n * Show welcome banner\n */\nexport function showWelcome(): void {\n console.log();\n p.intro(pc.bgCyan(pc.black(\" RaftStack \")));\n console.log(\n pc.dim(\" Setting up Git hooks, commit conventions, and GitHub integration\\n\")\n );\n}\n\n/**\n * Prompt for project type confirmation\n */\nexport async function promptProjectType(\n detection: DetectionResult\n): Promise<ProjectType> {\n const description = getProjectTypeDescription(detection.type);\n const confidenceText =\n detection.confidence === \"high\"\n ? pc.green(\"high confidence\")\n : detection.confidence === \"medium\"\n ? pc.yellow(\"medium confidence\")\n : pc.red(\"low confidence\");\n\n const confirmed = await p.confirm({\n message: `Detected ${pc.cyan(description)} (${confidenceText}). Is this correct?`,\n initialValue: true,\n });\n\n if (p.isCancel(confirmed)) {\n p.cancel(\"Setup cancelled.\");\n process.exit(0);\n }\n\n if (confirmed) {\n return detection.type;\n }\n\n const selected = await p.select({\n message: \"Select your project type:\",\n options: [\n { value: \"nx\", label: \"NX Monorepo\" },\n { value: \"turbo\", label: \"Turborepo\" },\n { value: \"pnpm-workspace\", label: \"pnpm Workspace\" },\n { value: \"single\", label: \"Single Package\" },\n ],\n });\n\n if (p.isCancel(selected)) {\n p.cancel(\"Setup cancelled.\");\n process.exit(0);\n }\n\n return selected as ProjectType;\n}\n\n/**\n * Prompt for Asana configuration\n */\nexport async function promptAsanaConfig(): Promise<string | undefined> {\n const useAsana = await p.confirm({\n message: \"Do you want to link commits to Asana tasks?\",\n initialValue: true,\n });\n\n if (p.isCancel(useAsana)) {\n p.cancel(\"Setup cancelled.\");\n process.exit(0);\n }\n\n if (!useAsana) {\n return undefined;\n }\n\n const baseUrl = await p.text({\n message: \"Enter your Asana workspace URL:\",\n placeholder: \"https://app.asana.com/0/workspace-id\",\n validate: (value) => {\n if (!value) return \"URL is required\";\n if (!value.startsWith(\"https://app.asana.com/\")) {\n return \"URL must start with https://app.asana.com/\";\n }\n return undefined;\n },\n });\n\n if (p.isCancel(baseUrl)) {\n p.cancel(\"Setup cancelled.\");\n process.exit(0);\n }\n\n return baseUrl;\n}\n\n/**\n * Prompt for AI review tool selection\n */\nexport async function promptAIReview(): Promise<AIReviewTool> {\n const selected = await p.select({\n message: \"Select an AI code review tool (optional):\",\n options: [\n {\n value: \"none\",\n label: \"None\",\n hint: \"Skip AI review setup\",\n },\n {\n value: \"coderabbit\",\n label: \"CodeRabbit\",\n hint: \"AI-powered code review\",\n },\n {\n value: \"copilot\",\n label: \"GitHub Copilot\",\n hint: \"GitHub's AI code review\",\n },\n ],\n });\n\n if (p.isCancel(selected)) {\n p.cancel(\"Setup cancelled.\");\n process.exit(0);\n }\n\n return selected as AIReviewTool;\n}\n\n/**\n * Prompt for CODEOWNERS\n */\nexport async function promptCodeowners(): Promise<string[]> {\n const addOwners = await p.confirm({\n message: \"Do you want to set up CODEOWNERS for automatic PR reviewers?\",\n initialValue: true,\n });\n\n if (p.isCancel(addOwners)) {\n p.cancel(\"Setup cancelled.\");\n process.exit(0);\n }\n\n if (!addOwners) {\n return [];\n }\n\n const owners = await p.text({\n message: \"Enter GitHub usernames (comma-separated):\",\n placeholder: \"@username1, @username2\",\n validate: (value) => {\n if (!value.trim()) return \"At least one username is required\";\n return undefined;\n },\n });\n\n if (p.isCancel(owners)) {\n p.cancel(\"Setup cancelled.\");\n process.exit(0);\n }\n\n return owners\n .split(\",\")\n .map((u) => u.trim())\n .filter(Boolean)\n .map((u) => (u.startsWith(\"@\") ? u : `@${u}`));\n}\n\n/**\n * Prompt for package manager selection\n */\nexport async function promptPackageManager(\n targetDir: string\n): Promise<PackageManagerInfo> {\n // Try to auto-detect from lockfiles\n const detected = detectPackageManager(targetDir);\n\n if (detected) {\n const description = getPackageManagerDescription(detected);\n p.log.info(`Detected ${pc.cyan(description)} from lockfile`);\n return detected;\n }\n\n // No lockfile found - prompt user to select\n p.log.warn(\"No package manager lockfile detected\");\n\n const selected = await p.select({\n message: \"Select your package manager:\",\n options: [\n {\n value: \"npm\",\n label: \"npm\",\n hint: \"Node Package Manager (default)\",\n },\n {\n value: \"pnpm\",\n label: \"pnpm\",\n hint: \"Performant npm\",\n },\n {\n value: \"yarn\",\n label: \"Yarn Classic (1.x)\",\n hint: \"Classic Yarn\",\n },\n {\n value: \"yarn-berry\",\n label: \"Yarn Berry (2+)\",\n hint: \"Modern Yarn\",\n },\n ],\n });\n\n if (p.isCancel(selected)) {\n p.cancel(\"Setup cancelled.\");\n process.exit(0);\n }\n\n return getPackageManagerInfo(selected as PackageManager);\n}\n\n/**\n * Show summary before generating files\n */\nexport async function promptConfirmation(\n config: RaftStackConfig\n): Promise<boolean> {\n console.log();\n p.note(\n [\n `${pc.cyan(\"Project Type:\")} ${getProjectTypeDescription(config.projectType)}`,\n `${pc.cyan(\"Package Manager:\")} ${getPackageManagerDescription(config.packageManager)}`,\n `${pc.cyan(\"TypeScript:\")} ${config.usesTypeScript ? \"Yes\" : \"No\"}`,\n `${pc.cyan(\"ESLint:\")} ${config.usesEslint ? \"Yes\" : \"No\"}`,\n `${pc.cyan(\"Prettier:\")} ${config.usesPrettier ? \"Yes\" : \"No\"}`,\n `${pc.cyan(\"Asana Integration:\")} ${config.asanaBaseUrl ? \"Yes\" : \"No\"}`,\n `${pc.cyan(\"AI Review:\")} ${config.aiReviewTool === \"none\" ? \"None\" : config.aiReviewTool}`,\n `${pc.cyan(\"CODEOWNERS:\")} ${config.codeowners.length > 0 ? config.codeowners.join(\", \") : \"None\"}`,\n ].join(\"\\n\"),\n \"Configuration Summary\"\n );\n\n const confirmed = await p.confirm({\n message: \"Generate configuration files?\",\n initialValue: true,\n });\n\n if (p.isCancel(confirmed)) {\n p.cancel(\"Setup cancelled.\");\n process.exit(0);\n }\n\n return confirmed;\n}\n\n/**\n * Run full prompt flow and collect configuration\n */\nexport async function collectConfig(\n targetDir: string = process.cwd()\n): Promise<RaftStackConfig | null> {\n showWelcome();\n\n // Detect project type\n const detection = await detectProjectType(targetDir);\n const projectType = await promptProjectType(detection);\n\n // Detect package manager\n const packageManager = await promptPackageManager(targetDir);\n\n // Detect existing tooling\n const usesTypeScript = await hasTypeScript(targetDir);\n const usesEslint = await hasEslint(targetDir);\n const usesPrettier = await hasPrettier(targetDir);\n\n // Collect user preferences\n const asanaBaseUrl = await promptAsanaConfig();\n const aiReviewTool = await promptAIReview();\n const codeowners = await promptCodeowners();\n\n const config: RaftStackConfig = {\n projectType,\n packageManager,\n asanaBaseUrl,\n aiReviewTool,\n codeowners,\n usesTypeScript,\n usesEslint,\n usesPrettier,\n };\n\n // Confirm before proceeding\n const confirmed = await promptConfirmation(config);\n\n if (!confirmed) {\n p.cancel(\"Setup cancelled.\");\n return null;\n }\n\n return config;\n}\n","import { existsSync } from \"node:fs\";\nimport { readFile } from \"node:fs/promises\";\nimport { join } from \"node:path\";\nimport type { DetectionResult, ProjectType } from \"../types/config.js\";\n\ninterface IndicatorCheck {\n file: string;\n type: ProjectType;\n confidence: \"high\" | \"medium\";\n}\n\nconst INDICATORS: IndicatorCheck[] = [\n { file: \"nx.json\", type: \"nx\", confidence: \"high\" },\n { file: \"turbo.json\", type: \"turbo\", confidence: \"high\" },\n { file: \"pnpm-workspace.yaml\", type: \"pnpm-workspace\", confidence: \"high\" },\n { file: \"lerna.json\", type: \"pnpm-workspace\", confidence: \"medium\" },\n];\n\n/**\n * Detect the project type based on configuration files\n */\nexport async function detectProjectType(\n targetDir: string = process.cwd()\n): Promise<DetectionResult> {\n const foundIndicators: string[] = [];\n let detectedType: ProjectType = \"single\";\n let confidence: \"high\" | \"medium\" | \"low\" = \"low\";\n\n for (const indicator of INDICATORS) {\n const filePath = join(targetDir, indicator.file);\n if (existsSync(filePath)) {\n foundIndicators.push(indicator.file);\n\n // First match with highest confidence wins\n if (\n confidence === \"low\" ||\n (confidence === \"medium\" && indicator.confidence === \"high\")\n ) {\n detectedType = indicator.type;\n confidence = indicator.confidence;\n }\n }\n }\n\n // If we found indicators but couldn't determine type, it's still better than nothing\n if (foundIndicators.length > 0 && confidence === \"low\") {\n confidence = \"medium\";\n }\n\n return {\n type: detectedType,\n confidence,\n indicators: foundIndicators,\n };\n}\n\n/**\n * Check if project uses TypeScript\n */\nexport async function hasTypeScript(\n targetDir: string = process.cwd()\n): Promise<boolean> {\n const tsConfigPath = join(targetDir, \"tsconfig.json\");\n return existsSync(tsConfigPath);\n}\n\n/**\n * Check if project uses ESLint\n */\nexport async function hasEslint(\n targetDir: string = process.cwd()\n): Promise<boolean> {\n const eslintFiles = [\n \".eslintrc\",\n \".eslintrc.js\",\n \".eslintrc.cjs\",\n \".eslintrc.json\",\n \".eslintrc.yaml\",\n \".eslintrc.yml\",\n \"eslint.config.js\",\n \"eslint.config.mjs\",\n \"eslint.config.cjs\",\n ];\n\n for (const file of eslintFiles) {\n if (existsSync(join(targetDir, file))) {\n return true;\n }\n }\n\n // Also check package.json for eslintConfig\n try {\n const pkgPath = join(targetDir, \"package.json\");\n if (existsSync(pkgPath)) {\n const content = await readFile(pkgPath, \"utf-8\");\n const pkg = JSON.parse(content);\n if (pkg.eslintConfig) {\n return true;\n }\n }\n } catch {\n // Ignore parse errors\n }\n\n return false;\n}\n\n/**\n * Check if project uses Prettier\n */\nexport async function hasPrettier(\n targetDir: string = process.cwd()\n): Promise<boolean> {\n const prettierFiles = [\n \".prettierrc\",\n \".prettierrc.js\",\n \".prettierrc.cjs\",\n \".prettierrc.json\",\n \".prettierrc.yaml\",\n \".prettierrc.yml\",\n \".prettierrc.toml\",\n \"prettier.config.js\",\n \"prettier.config.cjs\",\n \"prettier.config.mjs\",\n ];\n\n for (const file of prettierFiles) {\n if (existsSync(join(targetDir, file))) {\n return true;\n }\n }\n\n // Also check package.json for prettier config\n try {\n const pkgPath = join(targetDir, \"package.json\");\n if (existsSync(pkgPath)) {\n const content = await readFile(pkgPath, \"utf-8\");\n const pkg = JSON.parse(content);\n if (pkg.prettier) {\n return true;\n }\n }\n } catch {\n // Ignore parse errors\n }\n\n return false;\n}\n\n/**\n * Check if project uses React\n */\nexport async function hasReact(\n targetDir: string = process.cwd()\n): Promise<boolean> {\n try {\n const pkgPath = join(targetDir, \"package.json\");\n if (existsSync(pkgPath)) {\n const content = await readFile(pkgPath, \"utf-8\");\n const pkg = JSON.parse(content);\n const deps = { ...pkg.dependencies, ...pkg.devDependencies };\n return \"react\" in deps || \"react-dom\" in deps;\n }\n } catch {\n // Ignore parse errors\n }\n return false;\n}\n\n/**\n * Get a human-readable description of the project type\n */\nexport function getProjectTypeDescription(type: ProjectType): string {\n switch (type) {\n case \"nx\":\n return \"NX Monorepo\";\n case \"turbo\":\n return \"Turborepo\";\n case \"pnpm-workspace\":\n return \"pnpm Workspace\";\n case \"single\":\n return \"Single Package\";\n }\n}\n\n/**\n * Re-export package manager detection utilities for convenience\n */\nexport {\n detectPackageManager,\n detectYarnVersion,\n getPackageManagerInfo,\n getPackageManagerDescription,\n PACKAGE_MANAGERS,\n} from \"./detect-package-manager.js\";\n","import { existsSync, readFileSync } from \"node:fs\";\nimport { join } from \"node:path\";\nimport type { PackageManager, PackageManagerInfo, PackageJson } from \"../types/config.js\";\n\n/**\n * Package manager metadata and commands\n */\nexport const PACKAGE_MANAGERS: Record<PackageManager, PackageManagerInfo> = {\n npm: {\n name: \"npm\",\n install: \"npm install\",\n run: \"npm run\",\n exec: \"npx\",\n lockfile: \"package-lock.json\",\n installFrozen: \"npm ci\",\n addDev: \"install -D\",\n needsSetupAction: false,\n cacheKey: \"npm-${{ hashFiles('**/package-lock.json') }}\",\n },\n pnpm: {\n name: \"pnpm\",\n install: \"pnpm install\",\n run: \"pnpm\",\n exec: \"pnpm dlx\",\n lockfile: \"pnpm-lock.yaml\",\n installFrozen: \"pnpm install --frozen-lockfile\",\n addDev: \"add -D\",\n needsSetupAction: true,\n cacheKey: \"pnpm-${{ hashFiles('**/pnpm-lock.yaml') }}\",\n },\n yarn: {\n name: \"yarn\",\n install: \"yarn install\",\n run: \"yarn\",\n exec: \"yarn\",\n lockfile: \"yarn.lock\",\n installFrozen: \"yarn install --frozen-lockfile\",\n addDev: \"add -D\",\n needsSetupAction: false,\n cacheKey: \"yarn-${{ hashFiles('**/yarn.lock') }}\",\n },\n \"yarn-berry\": {\n name: \"yarn-berry\",\n install: \"yarn install\",\n run: \"yarn\",\n exec: \"yarn dlx\",\n lockfile: \"yarn.lock\",\n installFrozen: \"yarn install --immutable\",\n addDev: \"add -D\",\n needsSetupAction: false,\n cacheKey: \"yarn-${{ hashFiles('**/yarn.lock') }}\",\n },\n};\n\n/**\n * Detect Yarn version from package.json packageManager field\n * @param targetDir Directory to check\n * @returns \"yarn\" for 1.x, \"yarn-berry\" for 2+, or null if not specified\n */\nexport function detectYarnVersion(targetDir: string): \"yarn\" | \"yarn-berry\" | null {\n const packageJsonPath = join(targetDir, \"package.json\");\n\n if (!existsSync(packageJsonPath)) {\n return null;\n }\n\n try {\n const packageJson: PackageJson = JSON.parse(readFileSync(packageJsonPath, \"utf-8\"));\n const packageManager = packageJson.packageManager as string | undefined;\n\n if (!packageManager) {\n return null;\n }\n\n // Parse packageManager field (e.g., \"yarn@3.6.0\", \"yarn@1.22.19\")\n const match = packageManager.match(/^yarn@(\\d+)\\./);\n if (match) {\n const majorVersion = Number.parseInt(match[1], 10);\n return majorVersion >= 2 ? \"yarn-berry\" : \"yarn\";\n }\n\n return null;\n } catch {\n return null;\n }\n}\n\n/**\n * Detect package manager from lockfiles\n * Priority: pnpm-lock.yaml > yarn.lock > package-lock.json\n * @param targetDir Directory to check for lockfiles\n * @returns Detected package manager or null if no lockfile found\n */\nexport function detectPackageManager(targetDir: string): PackageManagerInfo | null {\n // Check pnpm first (highest priority)\n if (existsSync(join(targetDir, \"pnpm-lock.yaml\"))) {\n return PACKAGE_MANAGERS.pnpm;\n }\n\n // Check yarn second\n if (existsSync(join(targetDir, \"yarn.lock\"))) {\n const yarnVersion = detectYarnVersion(targetDir);\n\n // If packageManager field specifies version, use that\n if (yarnVersion === \"yarn-berry\") {\n return PACKAGE_MANAGERS[\"yarn-berry\"];\n }\n\n // Default to Yarn 1.x (classic)\n return PACKAGE_MANAGERS.yarn;\n }\n\n // Check npm last (lowest priority)\n if (existsSync(join(targetDir, \"package-lock.json\"))) {\n return PACKAGE_MANAGERS.npm;\n }\n\n // No lockfile found\n return null;\n}\n\n/**\n * Get package manager metadata by name\n * @param name Package manager name\n * @returns Package manager metadata\n */\nexport function getPackageManagerInfo(name: PackageManager): PackageManagerInfo {\n return PACKAGE_MANAGERS[name];\n}\n\n/**\n * Get human-readable description of package manager\n * @param pm Package manager info\n * @returns Human-readable description\n */\nexport function getPackageManagerDescription(pm: PackageManagerInfo): string {\n switch (pm.name) {\n case \"npm\":\n return \"npm (Node Package Manager)\";\n case \"pnpm\":\n return \"pnpm (Performant npm)\";\n case \"yarn\":\n return \"Yarn Classic (1.x)\";\n case \"yarn-berry\":\n return \"Yarn Berry (2+)\";\n default:\n return pm.name;\n }\n}\n","import { join } from \"node:path\";\nimport type { GeneratorResult, ProjectType } from \"../types/config.js\";\nimport { ensureDir, writeFileSafe } from \"../utils/file-system.js\";\n\n/**\n * Generate Husky pre-commit hook with direct command execution\n *\n * Uses Husky v9+ format (just the command, no shim).\n * Direct commands work because Husky adds node_modules/.bin to PATH.\n */\nfunction getPreCommitHook(_projectType: ProjectType): string {\n return `lint-staged\n`;\n}\n\n/**\n * Generate Husky commit-msg hook for commitlint\n */\nfunction getCommitMsgHook(): string {\n return `commitlint --edit \"$1\"\n`;\n}\n\n/**\n * Get the appropriate build command based on project type\n */\nfunction getBuildCommand(projectType: ProjectType): string {\n switch (projectType) {\n case \"turbo\":\n return \"pnpm turbo build\";\n case \"nx\":\n return \"pnpm nx affected --target=build --parallel=3\";\n case \"pnpm-workspace\":\n // pnpm workspaces without turbo/nx - run build in all packages\n return \"pnpm -r build\";\n default:\n return \"pnpm build\";\n }\n}\n\n/**\n * Generate Husky pre-push hook for branch validation and build\n */\nfunction getPrePushHook(projectType: ProjectType): string {\n const buildCommand = getBuildCommand(projectType);\n return `# Validate branch naming convention\nvalidate-branch-name\n\n# Build all packages - push only succeeds if builds pass\necho \"🔨 Building...\"\n${buildCommand}\n`;\n}\n\n/**\n * Generate all Husky hooks\n *\n * Note: The pm parameter is kept for backward compatibility but is no longer\n * used since hooks now use direct commands.\n */\nexport async function generateHuskyHooks(\n targetDir: string,\n projectType: ProjectType,\n _pm?: unknown\n): Promise<GeneratorResult> {\n const result: GeneratorResult = {\n created: [],\n modified: [],\n skipped: [],\n backedUp: [],\n };\n\n const huskyDir = join(targetDir, \".husky\");\n await ensureDir(huskyDir);\n\n // Pre-commit hook\n const preCommitPath = join(huskyDir, \"pre-commit\");\n const preCommitResult = await writeFileSafe(\n preCommitPath,\n getPreCommitHook(projectType),\n { executable: true, backup: true }\n );\n if (preCommitResult.created) {\n result.created.push(\".husky/pre-commit\");\n if (preCommitResult.backedUp) {\n result.backedUp.push(preCommitResult.backedUp);\n }\n }\n\n // Commit-msg hook\n const commitMsgPath = join(huskyDir, \"commit-msg\");\n const commitMsgResult = await writeFileSafe(\n commitMsgPath,\n getCommitMsgHook(),\n { executable: true, backup: true }\n );\n if (commitMsgResult.created) {\n result.created.push(\".husky/commit-msg\");\n if (commitMsgResult.backedUp) {\n result.backedUp.push(commitMsgResult.backedUp);\n }\n }\n\n // Pre-push hook\n const prePushPath = join(huskyDir, \"pre-push\");\n const prePushResult = await writeFileSafe(prePushPath, getPrePushHook(projectType), {\n executable: true,\n backup: true,\n });\n if (prePushResult.created) {\n result.created.push(\".husky/pre-push\");\n if (prePushResult.backedUp) {\n result.backedUp.push(prePushResult.backedUp);\n }\n }\n\n return result;\n}\n","import { existsSync } from \"node:fs\";\nimport {\n mkdir,\n readFile,\n writeFile,\n copyFile,\n chmod,\n} from \"node:fs/promises\";\nimport { dirname, join } from \"node:path\";\n\n/**\n * Ensure a directory exists, creating it if necessary\n */\nexport async function ensureDir(dirPath: string): Promise<void> {\n if (!existsSync(dirPath)) {\n await mkdir(dirPath, { recursive: true });\n }\n}\n\n/**\n * Backup a file if it exists\n * Returns the backup path if a backup was created, null otherwise\n */\nexport async function backupFile(filePath: string): Promise<string | null> {\n if (!existsSync(filePath)) {\n return null;\n }\n\n const backupPath = `${filePath}.backup`;\n await copyFile(filePath, backupPath);\n return backupPath;\n}\n\n/**\n * Write a file safely with optional backup\n */\nexport async function writeFileSafe(\n filePath: string,\n content: string,\n options: {\n backup?: boolean;\n overwrite?: boolean;\n executable?: boolean;\n } = {}\n): Promise<{ created: boolean; backedUp: string | null }> {\n const { backup = true, overwrite = true, executable = false } = options;\n\n // Check if file exists\n const exists = existsSync(filePath);\n\n // If file exists and we shouldn't overwrite, skip\n if (exists && !overwrite) {\n return { created: false, backedUp: null };\n }\n\n // Backup existing file if requested\n let backedUp: string | null = null;\n if (exists && backup) {\n backedUp = await backupFile(filePath);\n }\n\n // Ensure directory exists\n await ensureDir(dirname(filePath));\n\n // Write the file\n await writeFile(filePath, content, \"utf-8\");\n\n // Make executable if requested\n if (executable) {\n await chmod(filePath, 0o755);\n }\n\n return { created: true, backedUp };\n}\n\n/**\n * Read a file, returning null if it doesn't exist\n */\nexport async function readFileSafe(filePath: string): Promise<string | null> {\n if (!existsSync(filePath)) {\n return null;\n }\n return readFile(filePath, \"utf-8\");\n}\n\n/**\n * Check if a file exists\n */\nexport function fileExists(filePath: string): boolean {\n return existsSync(filePath);\n}\n\n/**\n * Get relative path from target directory\n */\nexport function getRelativePath(\n filePath: string,\n targetDir: string = process.cwd()\n): string {\n if (filePath.startsWith(targetDir)) {\n return filePath.slice(targetDir.length + 1);\n }\n return filePath;\n}\n\n/**\n * Join paths and normalize\n */\nexport function joinPath(...paths: string[]): string {\n return join(...paths);\n}\n","import { join } from \"node:path\";\nimport type { GeneratorResult } from \"../types/config.js\";\nimport { writeFileSafe } from \"../utils/file-system.js\";\n\n/**\n * Generate combined commitlint + cz-git configuration\n *\n * Per cz-git docs, the prompt configuration is read directly from commitlint config.\n * This eliminates the need for a separate cz.config.js file.\n *\n * Uses ES module syntax (export default) for compatibility with\n * projects that have \"type\": \"module\" in package.json.\n *\n * Note: Asana task link uses level 1 (warning) not level 2 (error)\n * Commits without task links will show a warning but won't be blocked\n */\nfunction getCommitlintConfig(asanaBaseUrl?: string): string {\n const asanaIssueSection = asanaBaseUrl\n ? `\n allowCustomIssuePrefix: true,\n issuePrefixes: [\n { value: 'asana', name: 'asana: Link to Asana task' },\n { value: 'closes', name: 'closes: Close an issue' },\n { value: 'fixes', name: 'fixes: Fix an issue' },\n ],`\n : `\n allowCustomIssuePrefix: false,`;\n\n const asanaPluginSection = asanaBaseUrl\n ? `\n plugins: [\n {\n rules: {\n 'asana-task-link': ({ body, footer }) => {\n const fullMessage = [body, footer].filter(Boolean).join('\\\\n');\n const asanaPattern = /https:\\\\/\\\\/app\\\\.asana\\\\.com\\\\/\\\\d+\\\\/\\\\d+\\\\/\\\\d+/;\n const hasAsanaLink = asanaPattern.test(fullMessage);\n return [\n hasAsanaLink,\n hasAsanaLink\n ? null\n : 'Consider adding an Asana task link in the commit body or footer (e.g., Task: https://app.asana.com/0/...)',\n ];\n },\n },\n },\n ],`\n : \"\";\n\n const asanaRule = asanaBaseUrl\n ? `\n // Asana task link (warning only - won't block commits)\n 'asana-task-link': [1, 'always'],`\n : \"\";\n\n return `/** @type {import('cz-git').UserConfig} */\nexport default {\n extends: ['@commitlint/config-conventional'],\n // Parser preset to support emoji prefixes in commit messages\n parserPreset: {\n parserOpts: {\n headerPattern:\n /^(?:(?:\\\\p{Emoji_Presentation}|\\\\p{Emoji}\\\\uFE0F?)|:[a-z_]+:)?\\\\s*(\\\\w+)(?:\\\\(([^)]*)\\\\))?:\\\\s*(.+)$/u,\n headerCorrespondence: ['type', 'scope', 'subject'],\n },\n },\n // cz-git prompt configuration (read directly from commitlint config)\n prompt: {\n alias: {\n fd: 'docs: fix typos',\n ur: 'docs: update README',\n },\n messages: {\n type: \"Select the type of change you're committing:\",\n scope: 'Denote the scope of this change (optional):',\n customScope: 'Denote the scope of this change:',\n subject: 'Write a short, imperative description of the change:\\\\n',\n body: 'Provide a longer description of the change (optional). Use \"|\" to break new line:\\\\n',\n breaking: 'List any BREAKING CHANGES (optional). Use \"|\" to break new line:\\\\n',\n footerPrefixSelect: 'Select the ISSUES type of change (optional):',\n customFooterPrefix: 'Input ISSUES prefix:',\n footer: 'List any ISSUES affected by this change (optional). E.g.: #31, #34:\\\\n',\n confirmCommit: 'Are you sure you want to proceed with the commit above?',\n },\n types: [\n { value: 'feat', name: 'feat: ✨ A new feature', emoji: ':sparkles:' },\n { value: 'fix', name: 'fix: 🐛 A bug fix', emoji: ':bug:' },\n { value: 'docs', name: 'docs: 📝 Documentation changes', emoji: ':memo:' },\n { value: 'style', name: 'style: 💄 Code style changes', emoji: ':lipstick:' },\n { value: 'refactor', name: 'refactor: ♻️ Code refactoring', emoji: ':recycle:' },\n { value: 'perf', name: 'perf: ⚡️ Performance improvements', emoji: ':zap:' },\n { value: 'test', name: 'test: ✅ Adding or updating tests', emoji: ':white_check_mark:' },\n { value: 'build', name: 'build: 📦 Build system changes', emoji: ':package:' },\n { value: 'ci', name: 'ci: 🎡 CI configuration changes', emoji: ':ferris_wheel:' },\n { value: 'chore', name: 'chore: 🔧 Other changes', emoji: ':wrench:' },\n { value: 'revert', name: 'revert: ⏪ Reverting changes', emoji: ':rewind:' },\n ],\n useEmoji: true,\n emojiAlign: 'left',\n useAI: false,\n scopes: [],\n allowCustomScopes: true,\n allowEmptyScopes: true,\n allowBreakingChanges: ['feat', 'fix'],\n breaklineNumber: 100,${asanaIssueSection}\n allowEmptyIssuePrefix: true,\n },\n rules: {\n // Type must be one of the conventional types\n 'type-enum': [\n 2,\n 'always',\n [\n 'feat',\n 'fix',\n 'docs',\n 'style',\n 'refactor',\n 'perf',\n 'test',\n 'build',\n 'ci',\n 'chore',\n 'revert',\n ],\n ],\n // Subject should not be empty\n 'subject-empty': [2, 'never'],\n // Type should not be empty\n 'type-empty': [2, 'never'],\n // Subject should be lowercase\n 'subject-case': [2, 'always', 'lower-case'],\n // Header max length\n 'header-max-length': [2, 'always', 100],${asanaRule}\n },${asanaPluginSection}\n};\n`;\n}\n\n/**\n * Generate commitlint configuration file\n */\nexport async function generateCommitlint(\n targetDir: string,\n asanaBaseUrl?: string\n): Promise<GeneratorResult> {\n const result: GeneratorResult = {\n created: [],\n modified: [],\n skipped: [],\n backedUp: [],\n };\n\n const configPath = join(targetDir, \"commitlint.config.js\");\n const writeResult = await writeFileSafe(\n configPath,\n getCommitlintConfig(asanaBaseUrl),\n { backup: true }\n );\n\n if (writeResult.created) {\n result.created.push(\"commitlint.config.js\");\n if (writeResult.backedUp) {\n result.backedUp.push(writeResult.backedUp);\n }\n }\n\n return result;\n}\n","import { join } from \"node:path\";\nimport type { GeneratorResult } from \"../types/config.js\";\nimport { writeFileSafe } from \"../utils/file-system.js\";\n\n/**\n * Generate cz-git configuration file\n *\n * Only generates .czrc pointing to cz-git.\n * The prompt configuration is now read directly from commitlint.config.js\n * per cz-git documentation: https://cz-git.qbb.sh/config/\n */\nexport async function generateCzGit(\n targetDir: string,\n _asanaBaseUrl?: string\n): Promise<GeneratorResult> {\n const result: GeneratorResult = {\n created: [],\n modified: [],\n skipped: [],\n backedUp: [],\n };\n\n const configPath = join(targetDir, \".czrc\");\n const writeResult = await writeFileSafe(\n configPath,\n JSON.stringify({ path: \"node_modules/cz-git\" }, null, 2) + \"\\n\",\n { backup: true }\n );\n\n if (writeResult.created) {\n result.created.push(\".czrc\");\n if (writeResult.backedUp) {\n result.backedUp.push(writeResult.backedUp);\n }\n }\n\n return result;\n}\n","import type { GeneratorResult } from \"../types/config.js\";\n\n/**\n * Lint-staged configuration type for package.json\n */\nexport type LintStagedConfig = Record<string, string | string[]>;\n\n/**\n * Generate lint-staged configuration for package.json (matching zero-to-one pattern)\n *\n * This function returns a configuration object to be added to package.json\n * instead of creating a separate file.\n */\nexport function getLintStagedConfig(\n usesEslint: boolean,\n usesPrettier: boolean,\n usesTypeScript: boolean\n): LintStagedConfig {\n const config: LintStagedConfig = {};\n\n // Determine which file patterns to lint\n const codePatterns: string[] = [];\n\n if (usesTypeScript) {\n codePatterns.push(\"ts\", \"mts\", \"cts\", \"tsx\");\n }\n // Always include JavaScript patterns\n codePatterns.push(\"js\", \"mjs\", \"cjs\", \"jsx\");\n\n // Build commands for code files\n const codeCommands: string[] = [];\n if (usesEslint) {\n codeCommands.push(\"eslint --fix\");\n }\n if (usesPrettier) {\n codeCommands.push(\"prettier --write\");\n }\n\n // Add code file pattern if we have any commands\n if (codeCommands.length > 0) {\n const pattern = `*.{${codePatterns.join(\",\")}}`;\n config[pattern] = codeCommands;\n }\n\n // Add non-code files for Prettier only\n if (usesPrettier) {\n config[\"*.{json,css,md}\"] = [\"prettier --write\"];\n }\n\n return config;\n}\n\n/**\n * Generate lint-staged configuration\n *\n * Note: This generator doesn't create files - instead it returns a GeneratorResult\n * and the config should be merged into package.json by the init command.\n *\n * @deprecated Use getLintStagedConfig() instead and merge into package.json\n */\nexport async function generateLintStaged(\n _targetDir: string,\n _projectType: string,\n usesEslint: boolean,\n usesPrettier: boolean,\n usesTypeScript: boolean\n): Promise<GeneratorResult & { config: LintStagedConfig }> {\n const result: GeneratorResult = {\n created: [],\n modified: [],\n skipped: [],\n backedUp: [],\n };\n\n const config = getLintStagedConfig(usesEslint, usesPrettier, usesTypeScript);\n\n // Note: The actual addition to package.json is handled by init.ts\n // This function now just returns the config\n\n return {\n ...result,\n config,\n };\n}\n","import { readFile, writeFile } from \"node:fs/promises\";\nimport { existsSync } from \"node:fs\";\nimport { join } from \"node:path\";\nimport spawn from \"cross-spawn\";\nimport type { PackageJson, PackageManagerInfo } from \"../types/config.js\";\n\n/**\n * Read package.json from a directory\n */\nexport async function readPackageJson(\n targetDir: string = process.cwd()\n): Promise<PackageJson> {\n const pkgPath = join(targetDir, \"package.json\");\n\n if (!existsSync(pkgPath)) {\n throw new Error(`No package.json found in ${targetDir}`);\n }\n\n const content = await readFile(pkgPath, \"utf-8\");\n return JSON.parse(content) as PackageJson;\n}\n\n/**\n * Write package.json to a directory\n */\nexport async function writePackageJson(\n pkg: PackageJson,\n targetDir: string = process.cwd()\n): Promise<void> {\n const pkgPath = join(targetDir, \"package.json\");\n const content = JSON.stringify(pkg, null, 2) + \"\\n\";\n await writeFile(pkgPath, content, \"utf-8\");\n}\n\n/**\n * Merge scripts into package.json without overwriting existing ones\n */\nexport function mergeScripts(\n pkg: PackageJson,\n scripts: Record<string, string>,\n overwrite: boolean = false\n): PackageJson {\n const existingScripts = pkg.scripts || {};\n const newScripts: Record<string, string> = { ...existingScripts };\n\n for (const [name, command] of Object.entries(scripts)) {\n if (overwrite || !existingScripts[name]) {\n newScripts[name] = command;\n }\n }\n\n return {\n ...pkg,\n scripts: newScripts,\n };\n}\n\n\n/**\n * Add a config section to package.json (e.g., lint-staged, validate-branch-name)\n */\nexport function addPackageJsonConfig<T>(\n pkg: PackageJson,\n key: string,\n config: T,\n overwrite: boolean = false\n): PackageJson {\n if (!overwrite && pkg[key]) {\n return pkg;\n }\n\n return {\n ...pkg,\n [key]: config,\n };\n}\n\n/**\n * Update package.json with multiple changes at once\n */\nexport async function updatePackageJson(\n targetDir: string,\n updater: (pkg: PackageJson) => PackageJson\n): Promise<PackageJson> {\n const pkg = await readPackageJson(targetDir);\n const updated = updater(pkg);\n await writePackageJson(updated, targetDir);\n return updated;\n}\n\n/**\n * Core packages that RaftStack will install in the target project\n * Version comments for reference - actual versions resolved by package manager\n */\nexport const RAFTSTACK_PACKAGES: string[] = [\n // Commit tooling\n \"@commitlint/cli\", // ^20.3.0\n \"@commitlint/config-conventional\", // ^20.3.0\n \"cz-git\", // ^1.12.0\n \"czg\", // ^1.12.0\n \"husky\", // ^9.1.7\n \"lint-staged\", // ^16.2.0\n \"validate-branch-name\", // ^1.3.2\n\n // Linting & formatting\n \"eslint\", // ^9.39.0\n \"@eslint/js\", // ^9.39.0\n \"typescript-eslint\", // ^8.39.0\n \"eslint-config-prettier\", // ^10.1.0\n \"prettier\", // ^3.8.0\n \"globals\", // ^17.0.0\n];\n\n/**\n * Additional ESLint packages for React projects (non-Next.js)\n */\nexport const REACT_ESLINT_PACKAGES: string[] = [\n \"eslint-plugin-react\", // ^7.37.0\n \"eslint-plugin-react-hooks\", // ^5.2.0\n];\n\n/**\n * Additional ESLint packages for Next.js projects\n * eslint-config-next includes React plugin configurations\n */\nexport const NEXTJS_ESLINT_PACKAGES: string[] = [\n \"eslint-config-next\", // ^16.1.0\n];\n\n/**\n * Result of package installation\n */\nexport interface InstallResult {\n success: boolean;\n error?: string;\n}\n\n/**\n * Check if directory is a pnpm workspace root\n */\nfunction isPnpmWorkspace(targetDir: string): boolean {\n return existsSync(join(targetDir, \"pnpm-workspace.yaml\"));\n}\n\n/**\n * Install packages using the package manager CLI\n *\n * Uses cross-spawn with shell: true for reliable PATH resolution\n * in sandboxed environments (pnpm dlx, npx). This is the industry\n * standard approach used by create-next-app, create-vite, etc.\n */\nexport async function installPackages(\n pm: PackageManagerInfo,\n packages: string[],\n targetDir: string\n): Promise<InstallResult> {\n if (packages.length === 0) {\n return { success: true };\n }\n\n return new Promise((resolve) => {\n // Build the command: e.g., \"pnpm add -D pkg1 pkg2 ...\"\n const pmCommand = pm.name === \"npm\" ? \"npm\" : pm.name.replace(\"-berry\", \"\");\n const parts = [pmCommand, ...pm.addDev.split(\" \")];\n\n // For pnpm workspaces, add -w flag to install at workspace root\n if (pm.name === \"pnpm\" && isPnpmWorkspace(targetDir)) {\n parts.push(\"-w\");\n }\n\n parts.push(...packages);\n\n // Join as single command string to avoid Node.js deprecation warning\n // about passing args with shell: true\n const fullCommand = parts.join(\" \");\n\n const child = spawn(fullCommand, [], {\n cwd: targetDir,\n stdio: \"inherit\", // Show install progress to user\n shell: true, // Key: use shell to resolve PATH in sandboxed envs\n });\n\n child.on(\"close\", (code) => {\n if (code === 0) {\n resolve({ success: true });\n } else {\n resolve({\n success: false,\n error: `Installation failed with exit code ${code}`,\n });\n }\n });\n\n child.on(\"error\", (err) => {\n resolve({\n success: false,\n error: err.message,\n });\n });\n });\n}\n\n/**\n * Get package manager-specific scripts\n * This can be used in the future to add PM-specific setup scripts\n */\nexport function getPackageManagerScripts(\n _pm: PackageManagerInfo\n): Record<string, string> {\n // Currently, all package managers use the same scripts\n // This function is here for future extensibility if we need\n // different scripts for different package managers\n return {\n commit: \"czg\",\n prepare: \"husky\",\n };\n}\n","import type { GeneratorResult } from \"../types/config.js\";\nimport {\n addPackageJsonConfig,\n readPackageJson,\n writePackageJson,\n} from \"../utils/package-json.js\";\n\n/**\n * Branch naming pattern configuration\n */\ninterface BranchValidationConfig {\n pattern: string;\n errorMsg: string;\n}\n\n/**\n * Get the default branch validation configuration\n */\nfunction getBranchValidationConfig(): BranchValidationConfig {\n return {\n pattern:\n \"^(main|master|develop|staging|production)$|^(feature|fix|hotfix|bugfix|release|chore|docs|refactor|test|ci)\\\\/[a-z0-9._-]+$\",\n errorMsg:\n \"Branch name must follow pattern: feature/*, fix/*, hotfix/*, bugfix/*, release/*, chore/*, docs/*, refactor/*, test/*, ci/* or be main/master/develop/staging/production\",\n };\n}\n\n/**\n * Add validate-branch-name configuration to package.json\n */\nexport async function generateBranchValidation(\n targetDir: string\n): Promise<GeneratorResult> {\n const result: GeneratorResult = {\n created: [],\n modified: [],\n skipped: [],\n backedUp: [],\n };\n\n try {\n const pkg = await readPackageJson(targetDir);\n const config = getBranchValidationConfig();\n\n const updatedPkg = addPackageJsonConfig(\n pkg,\n \"validate-branch-name\",\n config,\n false // Don't overwrite if exists\n );\n\n // Check if we actually added something\n if (JSON.stringify(pkg) !== JSON.stringify(updatedPkg)) {\n await writePackageJson(updatedPkg, targetDir);\n result.modified.push(\"package.json (validate-branch-name)\");\n } else {\n result.skipped.push(\"validate-branch-name config (already exists)\");\n }\n } catch (error) {\n // If package.json doesn't exist or can't be read, skip\n result.skipped.push(\"validate-branch-name config (no package.json)\");\n }\n\n return result;\n}\n","import { join } from \"node:path\";\nimport type { GeneratorResult } from \"../types/config.js\";\nimport { ensureDir, writeFileSafe } from \"../utils/file-system.js\";\n\n/**\n * Get the PR template content\n */\nfunction getPRTemplate(hasAsana: boolean): string {\n const asanaSection = hasAsana\n ? `## Asana Task\n<!-- Link to the Asana task -->\n- [ ] https://app.asana.com/0/...\n\n`\n : \"\";\n\n return `## Description\n<!-- Provide a brief description of the changes in this PR -->\n\n## Type of Change\n<!-- Mark the appropriate option with an \"x\" -->\n- [ ] 🐛 Bug fix (non-breaking change that fixes an issue)\n- [ ] ✨ New feature (non-breaking change that adds functionality)\n- [ ] 💥 Breaking change (fix or feature that would cause existing functionality to not work as expected)\n- [ ] 📝 Documentation update\n- [ ] 🔧 Configuration change\n- [ ] ♻️ Refactoring (no functional changes)\n- [ ] ✅ Test update\n\n${asanaSection}## Changes Made\n<!-- List the specific changes made in this PR -->\n-\n\n## Testing\n<!-- Describe how you tested your changes -->\n- [ ] Unit tests added/updated\n- [ ] Integration tests added/updated\n- [ ] Manual testing performed\n\n## Screenshots (if applicable)\n<!-- Add screenshots to help explain your changes -->\n\n## Checklist\n- [ ] My code follows the project's coding standards\n- [ ] I have performed a self-review of my code\n- [ ] I have commented my code, particularly in hard-to-understand areas\n- [ ] I have made corresponding changes to the documentation\n- [ ] My changes generate no new warnings\n- [ ] Any dependent changes have been merged and published\n\n## Additional Notes\n<!-- Add any additional information that reviewers should know -->\n`;\n}\n\n/**\n * Generate GitHub PR template\n */\nexport async function generatePRTemplate(\n targetDir: string,\n hasAsana: boolean\n): Promise<GeneratorResult> {\n const result: GeneratorResult = {\n created: [],\n modified: [],\n skipped: [],\n backedUp: [],\n };\n\n const githubDir = join(targetDir, \".github\");\n await ensureDir(githubDir);\n\n const templatePath = join(githubDir, \"PULL_REQUEST_TEMPLATE.md\");\n const writeResult = await writeFileSafe(\n templatePath,\n getPRTemplate(hasAsana),\n { backup: true }\n );\n\n if (writeResult.created) {\n result.created.push(\".github/PULL_REQUEST_TEMPLATE.md\");\n if (writeResult.backedUp) {\n result.backedUp.push(writeResult.backedUp);\n }\n }\n\n return result;\n}\n","import { join } from \"node:path\";\nimport type { GeneratorResult, PackageManagerInfo, ProjectType } from \"../types/config.js\";\nimport { ensureDir, writeFileSafe } from \"../utils/file-system.js\";\n\n/**\n * Get the PR checks workflow content\n */\nfunction getPRChecksWorkflow(\n projectType: ProjectType,\n usesTypeScript: boolean,\n usesEslint: boolean,\n pm: PackageManagerInfo\n): string {\n const steps: string[] = [];\n\n // Checkout\n steps.push(` - name: Checkout\n uses: actions/checkout@v4`);\n\n // Setup Node\n steps.push(`\n - name: Setup Node.js\n uses: actions/setup-node@v4\n with:\n node-version: '20'`);\n\n // Setup pnpm (only if needed)\n if (pm.needsSetupAction) {\n steps.push(`\n - name: Setup pnpm\n uses: pnpm/action-setup@v3\n with:\n version: 9`);\n }\n\n // Install dependencies\n steps.push(`\n - name: Install dependencies\n run: ${pm.installFrozen}`);\n\n // TypeScript check\n if (usesTypeScript) {\n steps.push(`\n - name: Type check\n run: ${pm.run} typecheck`);\n }\n\n // ESLint\n if (usesEslint) {\n steps.push(`\n - name: Lint\n run: ${pm.run} lint`);\n }\n\n // Build (for NX/Turbo, use their commands)\n if (projectType === \"nx\") {\n steps.push(`\n - name: Build\n run: ${pm.run} nx affected --target=build --parallel=3`);\n } else if (projectType === \"turbo\") {\n steps.push(`\n - name: Build\n run: ${pm.run} turbo build`);\n } else {\n steps.push(`\n - name: Build\n run: ${pm.run} build`);\n }\n\n // Tests\n if (projectType === \"nx\") {\n steps.push(`\n - name: Test\n run: ${pm.run} nx affected --target=test --parallel=3`);\n } else if (projectType === \"turbo\") {\n steps.push(`\n - name: Test\n run: ${pm.run} turbo test`);\n } else {\n steps.push(`\n - name: Test\n run: ${pm.run} test`);\n }\n\n return `name: PR Checks\n\non:\n pull_request:\n branches: [main, master, develop]\n\nconcurrency:\n group: \\${{ github.workflow }}-\\${{ github.ref }}\n cancel-in-progress: true\n\njobs:\n check:\n name: Check\n runs-on: ubuntu-latest\n steps:\n${steps.join(\"\\n\")}\n`;\n}\n\n/**\n * Generate GitHub workflow files\n */\nexport async function generateGitHubWorkflows(\n targetDir: string,\n projectType: ProjectType,\n usesTypeScript: boolean,\n usesEslint: boolean,\n pm: PackageManagerInfo\n): Promise<GeneratorResult> {\n const result: GeneratorResult = {\n created: [],\n modified: [],\n skipped: [],\n backedUp: [],\n };\n\n const workflowsDir = join(targetDir, \".github\", \"workflows\");\n await ensureDir(workflowsDir);\n\n // PR Checks workflow\n const prChecksPath = join(workflowsDir, \"pr-checks.yml\");\n const writeResult = await writeFileSafe(\n prChecksPath,\n getPRChecksWorkflow(projectType, usesTypeScript, usesEslint, pm),\n { backup: true }\n );\n\n if (writeResult.created) {\n result.created.push(\".github/workflows/pr-checks.yml\");\n if (writeResult.backedUp) {\n result.backedUp.push(writeResult.backedUp);\n }\n }\n\n return result;\n}\n","import { join } from \"node:path\";\nimport type { GeneratorResult } from \"../types/config.js\";\nimport { ensureDir, writeFileSafe } from \"../utils/file-system.js\";\n\n/**\n * Get the CODEOWNERS content\n */\nfunction getCodeownersContent(owners: string[]): string {\n if (owners.length === 0) {\n return `# CODEOWNERS file\n# Learn about CODEOWNERS: https://docs.github.com/en/repositories/managing-your-repositorys-settings-and-features/customizing-your-repository/about-code-owners\n\n# Default owners for everything in the repo\n# Uncomment and modify the line below to set default owners\n# * @owner1 @owner2\n`;\n }\n\n const ownersList = owners.join(\" \");\n\n return `# CODEOWNERS file\n# Learn about CODEOWNERS: https://docs.github.com/en/repositories/managing-your-repositorys-settings-and-features/customizing-your-repository/about-code-owners\n\n# Default owners for everything in the repo\n* ${ownersList}\n\n# You can also specify owners for specific paths:\n# /docs/ @docs-team\n# /src/api/ @backend-team\n# /src/ui/ @frontend-team\n# *.ts @typescript-team\n`;\n}\n\n/**\n * Generate CODEOWNERS file\n */\nexport async function generateCodeowners(\n targetDir: string,\n owners: string[]\n): Promise<GeneratorResult> {\n const result: GeneratorResult = {\n created: [],\n modified: [],\n skipped: [],\n backedUp: [],\n };\n\n const githubDir = join(targetDir, \".github\");\n await ensureDir(githubDir);\n\n const codeownersPath = join(githubDir, \"CODEOWNERS\");\n const writeResult = await writeFileSafe(\n codeownersPath,\n getCodeownersContent(owners),\n { backup: true }\n );\n\n if (writeResult.created) {\n result.created.push(\".github/CODEOWNERS\");\n if (writeResult.backedUp) {\n result.backedUp.push(writeResult.backedUp);\n }\n }\n\n return result;\n}\n","import { join } from \"node:path\";\nimport type { AIReviewTool, GeneratorResult } from \"../types/config.js\";\nimport { ensureDir, writeFileSafe } from \"../utils/file-system.js\";\n\n/**\n * Get CodeRabbit configuration\n */\nfunction getCodeRabbitConfig(): string {\n return `# CodeRabbit Configuration\n# Learn more: https://docs.coderabbit.ai/guides/configure-coderabbit\n\nlanguage: \"en-US\"\n\nreviews:\n request_changes_workflow: true\n high_level_summary: true\n poem: false\n review_status: true\n collapse_walkthrough: false\n auto_review:\n enabled: true\n drafts: false\n\nchat:\n auto_reply: true\n`;\n}\n\n/**\n * Get GitHub Copilot PR review workflow\n */\nfunction getCopilotWorkflow(): string {\n return `name: Copilot Code Review\n\non:\n pull_request:\n types: [opened, synchronize, reopened]\n\npermissions:\n contents: read\n pull-requests: write\n\njobs:\n review:\n name: Copilot Review\n runs-on: ubuntu-latest\n steps:\n - name: Checkout\n uses: actions/checkout@v4\n\n # Note: GitHub Copilot code review is automatically enabled\n # when you have Copilot Enterprise. This workflow is a placeholder\n # for any additional AI review configuration you might need.\n\n - name: Add review comment\n uses: actions/github-script@v7\n with:\n script: |\n // GitHub Copilot will automatically review PRs if enabled\n // This is a placeholder for additional review logic\n console.log('Copilot review enabled for this repository');\n`;\n}\n\n/**\n * Generate AI review configuration\n */\nexport async function generateAIReview(\n targetDir: string,\n tool: AIReviewTool\n): Promise<GeneratorResult> {\n const result: GeneratorResult = {\n created: [],\n modified: [],\n skipped: [],\n backedUp: [],\n };\n\n if (tool === \"none\") {\n return result;\n }\n\n if (tool === \"coderabbit\") {\n const configPath = join(targetDir, \".coderabbit.yaml\");\n const writeResult = await writeFileSafe(configPath, getCodeRabbitConfig(), {\n backup: true,\n });\n\n if (writeResult.created) {\n result.created.push(\".coderabbit.yaml\");\n if (writeResult.backedUp) {\n result.backedUp.push(writeResult.backedUp);\n }\n }\n }\n\n if (tool === \"copilot\") {\n const workflowsDir = join(targetDir, \".github\", \"workflows\");\n await ensureDir(workflowsDir);\n\n const workflowPath = join(workflowsDir, \"copilot-review.yml\");\n const writeResult = await writeFileSafe(workflowPath, getCopilotWorkflow(), {\n backup: true,\n });\n\n if (writeResult.created) {\n result.created.push(\".github/workflows/copilot-review.yml\");\n if (writeResult.backedUp) {\n result.backedUp.push(writeResult.backedUp);\n }\n }\n }\n\n return result;\n}\n","import { join } from \"node:path\";\nimport type { GeneratorResult } from \"../types/config.js\";\nimport { ensureDir, writeFileSafe } from \"../utils/file-system.js\";\n\n/**\n * Get branch protection setup documentation\n */\nfunction getBranchProtectionDocs(): string {\n return `# Branch Protection Setup Guide\n\nThis guide explains how to configure branch protection rules for your repository.\n\n## Quick Setup\n\nRun the automated setup command:\n\n\\`\\`\\`bash\nraftstack setup-protection\n\\`\\`\\`\n\nThis command supports:\n- **Multiple branches**: main, staging, production, development, etc.\n- **Merge strategies**: Rebase (recommended), squash, or merge commits\n- **Review requirements**: Configurable number of required approvals\n\n## Recommended Settings\n\n### For \\`main\\` / \\`master\\` branch:\n\n1. **Require a pull request before merging**\n - ✅ Require approvals: 1 (or more for larger teams)\n - ✅ Dismiss stale pull request approvals when new commits are pushed\n - ✅ Require review from Code Owners\n\n2. **Require status checks to pass before merging**\n - ✅ Require branches to be up to date before merging\n - Select required status checks:\n - \\`check\\` (from pr-checks.yml workflow)\n\n3. **Require conversation resolution before merging**\n - ✅ All conversations on code must be resolved\n\n4. **Do not allow bypassing the above settings**\n - ✅ Apply rules to administrators\n\n5. **Restrict who can push to matching branches**\n - Only allow merges through pull requests\n\n6. **Block force pushes**\n - ✅ Do not allow force pushes\n\n7. **Block deletions**\n - ✅ Do not allow this branch to be deleted\n\n## Manual Setup via GitHub UI\n\n1. Go to your repository on GitHub\n2. Click **Settings** > **Branches**\n3. Click **Add branch protection rule**\n4. Enter \\`main\\` (or \\`master\\`) as the branch name pattern\n5. Configure the settings as described above\n6. Click **Create** or **Save changes**\n\n## Automated Setup (Recommended)\n\nUse the \\`raftstack setup-protection\\` command to configure\nbranch protection rules automatically using the GitHub CLI.\n\nRequirements:\n- GitHub CLI (\\`gh\\`) installed and authenticated\n- Admin access to the repository\n\n\\`\\`\\`bash\nraftstack setup-protection\n\\`\\`\\`\n\n### Features\n\nThe setup command will:\n1. Prompt you to select branches to protect (main, staging, production, etc.)\n2. Let you choose a merge strategy (rebase, squash, or merge commits)\n3. Configure required review count\n4. Apply branch protection rules to all selected branches\n5. Set repository merge settings\n\n### Merge Strategy Recommendations\n\n| Strategy | Use Case |\n|----------|----------|\n| **Rebase** (recommended) | Clean linear history, easy to follow |\n| **Squash** | Single commit per PR, cleaner history |\n| **Merge commit** | Preserve all commits, show PR merge points |\n\n## Branch Naming Convention\n\nThis project enforces branch naming conventions via \\`validate-branch-name\\`.\n\nAllowed patterns:\n- \\`main\\`, \\`master\\`, \\`develop\\`, \\`staging\\`, \\`production\\`\n- \\`feature/*\\` - New features\n- \\`fix/*\\` or \\`bugfix/*\\` - Bug fixes\n- \\`hotfix/*\\` - Urgent fixes\n- \\`release/*\\` - Release preparation\n- \\`chore/*\\` - Maintenance tasks\n- \\`docs/*\\` - Documentation updates\n- \\`refactor/*\\` - Code refactoring\n- \\`test/*\\` - Test additions/updates\n- \\`ci/*\\` - CI/CD changes\n\nExamples:\n- \\`feature/user-authentication\\`\n- \\`fix/login-validation\\`\n- \\`hotfix/security-patch\\`\n- \\`release/v1.2.0\\`\n`;\n}\n\n/**\n * Generate branch protection documentation\n */\nexport async function generateBranchProtectionDocs(\n targetDir: string\n): Promise<GeneratorResult> {\n const result: GeneratorResult = {\n created: [],\n modified: [],\n skipped: [],\n backedUp: [],\n };\n\n const docsDir = join(targetDir, \".github\");\n await ensureDir(docsDir);\n\n const docsPath = join(docsDir, \"BRANCH_PROTECTION_SETUP.md\");\n const writeResult = await writeFileSafe(docsPath, getBranchProtectionDocs(), {\n backup: true,\n });\n\n if (writeResult.created) {\n result.created.push(\".github/BRANCH_PROTECTION_SETUP.md\");\n if (writeResult.backedUp) {\n result.backedUp.push(writeResult.backedUp);\n }\n }\n\n return result;\n}\n","import { join } from \"node:path\";\nimport type { GeneratorResult, PackageManagerInfo } from \"../types/config.js\";\nimport { writeFileSafe } from \"../utils/file-system.js\";\n\n/**\n * Get CONTRIBUTING.md content\n */\nfunction getContributingContent(hasAsana: boolean, pm: PackageManagerInfo): string {\n const asanaSection = hasAsana\n ? `\n## Linking to Asana\n\nWhen working on a task:\n1. Create a branch following the naming convention (e.g., \\`feature/task-description\\`)\n2. Include the Asana task link in your commit body or footer\n3. Reference the Asana task in your PR description\n\nExample commit:\n\\`\\`\\`\nfeat(auth): add password reset functionality\n\nImplement password reset flow with email verification.\n\nAsana: https://app.asana.com/0/workspace/task-id\n\\`\\`\\`\n`\n : \"\";\n\n return `# Contributing Guide\n\nThank you for your interest in contributing! This document outlines our development workflow and standards.\n\n## Getting Started\n\n1. Clone the repository\n2. Install dependencies: \\`${pm.install}\\`\n3. Create a new branch following our naming convention\n\n## Branch Naming Convention\n\nWe use structured branch names to keep our repository organized:\n\n| Prefix | Purpose | Example |\n|--------|---------|---------|\n| \\`feature/\\` | New features | \\`feature/user-authentication\\` |\n| \\`fix/\\` | Bug fixes | \\`fix/login-validation\\` |\n| \\`hotfix/\\` | Urgent fixes | \\`hotfix/security-patch\\` |\n| \\`bugfix/\\` | Bug fixes (alternative) | \\`bugfix/form-submission\\` |\n| \\`release/\\` | Release preparation | \\`release/v1.2.0\\` |\n| \\`chore/\\` | Maintenance tasks | \\`chore/update-dependencies\\` |\n| \\`docs/\\` | Documentation | \\`docs/api-reference\\` |\n| \\`refactor/\\` | Code refactoring | \\`refactor/auth-module\\` |\n| \\`test/\\` | Test additions | \\`test/user-service\\` |\n| \\`ci/\\` | CI/CD changes | \\`ci/github-actions\\` |\n\n## Commit Convention\n\nWe follow [Conventional Commits](https://www.conventionalcommits.org/). Use the interactive commit tool:\n\n\\`\\`\\`bash\n${pm.run} commit\n\\`\\`\\`\n\n### Commit Types\n\n| Type | Description |\n|------|-------------|\n| \\`feat\\` | New feature |\n| \\`fix\\` | Bug fix |\n| \\`docs\\` | Documentation changes |\n| \\`style\\` | Code style changes (formatting, etc.) |\n| \\`refactor\\` | Code refactoring |\n| \\`perf\\` | Performance improvements |\n| \\`test\\` | Adding or updating tests |\n| \\`build\\` | Build system changes |\n| \\`ci\\` | CI configuration changes |\n| \\`chore\\` | Other changes |\n| \\`revert\\` | Reverting changes |\n\n### Commit Message Format\n\n\\`\\`\\`\n<type>(<scope>): <subject>\n\n<body>\n\n<footer>\n\\`\\`\\`\n\nExample:\n\\`\\`\\`\nfeat(auth): add social login support\n\nImplement OAuth2 login for Google and GitHub providers.\nIncludes user profile sync and token refresh.\n\nCloses #123\n\\`\\`\\`\n${asanaSection}\n## Pull Request Process\n\n1. Ensure your branch is up to date with \\`main\\`/\\`master\\`\n2. Run tests and linting locally\n3. Create a pull request using the provided template\n4. Request review from code owners\n5. Address any feedback\n6. Merge once approved and all checks pass\n\n### PR Size Guidelines\n\nKeep pull requests small and focused for faster reviews:\n\n| Size | Lines Changed | Review Time |\n|------|---------------|-------------|\n| XS | 0-10 lines | Minutes |\n| S | 11-50 lines | < 30 min |\n| M | 51-200 lines | < 1 hour |\n| L | 201-400 lines | 1-2 hours |\n| XL | 400+ lines | Needs justification |\n\n**Target: < 400 lines per PR**\n\nIf your PR is large:\n- Consider splitting it into smaller, logical PRs\n- Explain in the description why it can't be split\n\n## Code Quality\n\nBefore committing, the following checks run automatically:\n\n- **Linting**: ESLint checks for code quality\n- **Formatting**: Prettier ensures consistent style\n- **Type checking**: TypeScript validates types\n- **Commit messages**: Commitlint validates format\n- **Branch names**: validate-branch-name checks naming\n\n## Questions?\n\nIf you have questions, please open an issue or reach out to the maintainers.\n`;\n}\n\n/**\n * Generate CONTRIBUTING.md\n */\nexport async function generateContributing(\n targetDir: string,\n hasAsana: boolean,\n pm: PackageManagerInfo\n): Promise<GeneratorResult> {\n const result: GeneratorResult = {\n created: [],\n modified: [],\n skipped: [],\n backedUp: [],\n };\n\n const contributingPath = join(targetDir, \"CONTRIBUTING.md\");\n const writeResult = await writeFileSafe(\n contributingPath,\n getContributingContent(hasAsana, pm),\n { backup: true }\n );\n\n if (writeResult.created) {\n result.created.push(\"CONTRIBUTING.md\");\n if (writeResult.backedUp) {\n result.backedUp.push(writeResult.backedUp);\n }\n }\n\n return result;\n}\n","import { join } from \"node:path\";\nimport type { GeneratorResult } from \"../types/config.js\";\nimport { fileExists, writeFileSafe } from \"../utils/file-system.js\";\n\n/**\n * Get Prettier configuration (matching zero-to-one project pattern)\n */\nfunction getPrettierConfig(): string {\n return (\n JSON.stringify(\n {\n semi: true,\n trailingComma: \"es5\",\n singleQuote: false,\n printWidth: 80,\n tabWidth: 2,\n useTabs: false,\n arrowParens: \"always\",\n endOfLine: \"lf\",\n },\n null,\n 2\n ) + \"\\n\"\n );\n}\n\n/**\n * Get Prettier ignore file content (matching zero-to-one project pattern)\n */\nfunction getPrettierIgnore(): string {\n return `node_modules\ndist\nbuild\n.turbo\n.next\n*.lock\npnpm-lock.yaml\ncoverage\n# Generated files\n**/routeTree.gen.ts\n`;\n}\n\n/**\n * Check if Prettier is already configured\n */\nfunction hasPrettierConfig(targetDir: string): boolean {\n const prettierFiles = [\n \".prettierrc\",\n \".prettierrc.js\",\n \".prettierrc.cjs\",\n \".prettierrc.json\",\n \".prettierrc.yaml\",\n \".prettierrc.yml\",\n \".prettierrc.toml\",\n \"prettier.config.js\",\n \"prettier.config.cjs\",\n \"prettier.config.mjs\",\n ];\n\n return prettierFiles.some((file) => fileExists(join(targetDir, file)));\n}\n\n/**\n * Generate Prettier configuration\n */\nexport async function generatePrettier(\n targetDir: string\n): Promise<GeneratorResult> {\n const result: GeneratorResult = {\n created: [],\n modified: [],\n skipped: [],\n backedUp: [],\n };\n\n // Skip if Prettier is already configured\n if (hasPrettierConfig(targetDir)) {\n result.skipped.push(\".prettierrc (already exists)\");\n return result;\n }\n\n // Create .prettierrc\n const configPath = join(targetDir, \".prettierrc\");\n const configResult = await writeFileSafe(configPath, getPrettierConfig(), {\n backup: true,\n });\n\n if (configResult.created) {\n result.created.push(\".prettierrc\");\n if (configResult.backedUp) {\n result.backedUp.push(configResult.backedUp);\n }\n }\n\n // Create .prettierignore\n const ignorePath = join(targetDir, \".prettierignore\");\n const ignoreResult = await writeFileSafe(ignorePath, getPrettierIgnore(), {\n backup: true,\n overwrite: false, // Don't overwrite existing ignore file\n });\n\n if (ignoreResult.created) {\n result.created.push(\".prettierignore\");\n if (ignoreResult.backedUp) {\n result.backedUp.push(ignoreResult.backedUp);\n }\n } else {\n result.skipped.push(\".prettierignore (already exists)\");\n }\n\n return result;\n}\n","import { existsSync } from \"node:fs\";\nimport { readdir, copyFile } from \"node:fs/promises\";\nimport { join, dirname } from \"node:path\";\nimport { fileURLToPath } from \"node:url\";\nimport type { GeneratorResult } from \"../types/config.js\";\nimport { ensureDir, backupFile } from \"../utils/file-system.js\";\n\n/**\n * Get the path to the skills directory in the installed package\n */\nfunction getPackageSkillsDir(): string {\n // In ESM, we use import.meta.url to find the package location\n // tsup bundles everything into dist/cli.js, so we only need to go up 1 level\n const currentFilePath = fileURLToPath(import.meta.url);\n const packageRoot = join(dirname(currentFilePath), \"..\");\n return join(packageRoot, \".claude\", \"skills\");\n}\n\n/**\n * Recursively copy a directory\n */\nasync function copyDirectory(\n srcDir: string,\n destDir: string,\n result: GeneratorResult,\n baseDir: string,\n skipDirs?: string[]\n): Promise<void> {\n await ensureDir(destDir);\n\n const entries = await readdir(srcDir, { withFileTypes: true });\n\n for (const entry of entries) {\n // Skip directories in the skipDirs list\n if (skipDirs && entry.isDirectory() && skipDirs.includes(entry.name)) {\n continue;\n }\n\n const srcPath = join(srcDir, entry.name);\n const destPath = join(destDir, entry.name);\n const relativePath = destPath.replace(baseDir + \"/\", \"\");\n\n if (entry.isDirectory()) {\n await copyDirectory(srcPath, destPath, result, baseDir, skipDirs);\n } else {\n // Check if destination exists\n if (existsSync(destPath)) {\n // Backup existing file\n const backupPath = await backupFile(destPath);\n if (backupPath) {\n result.backedUp.push(relativePath);\n }\n }\n\n // Copy the file\n await copyFile(srcPath, destPath);\n result.created.push(relativePath);\n }\n }\n}\n\n/**\n * Generate Claude Code skills by copying them to the target project\n *\n * This copies the bundled .claude/skills/ directory to the target project,\n * enabling AI-assisted code quality enforcement when using Claude Code.\n */\nexport async function generateClaudeSkills(\n targetDir: string,\n options?: { includeAsana?: boolean }\n): Promise<GeneratorResult> {\n const result: GeneratorResult = {\n created: [],\n modified: [],\n skipped: [],\n backedUp: [],\n };\n\n const packageSkillsDir = getPackageSkillsDir();\n const targetSkillsDir = join(targetDir, \".claude\", \"skills\");\n\n // Check if source skills directory exists\n if (!existsSync(packageSkillsDir)) {\n // Skills not bundled (development mode or missing)\n console.warn(\n \"Warning: Skills directory not found in package. Skipping skills generation.\"\n );\n return result;\n }\n\n // Ensure target .claude directory exists\n await ensureDir(join(targetDir, \".claude\"));\n\n // Build list of directories to skip based on options\n const skipDirs: string[] = [];\n if (!options?.includeAsana) {\n skipDirs.push(\"asana\");\n }\n\n // Copy all skills (excluding skipped directories)\n await copyDirectory(packageSkillsDir, targetSkillsDir, result, targetDir, skipDirs);\n\n return result;\n}","import { existsSync } from \"node:fs\";\nimport { readFile } from \"node:fs/promises\";\nimport { join } from \"node:path\";\nimport type { GeneratorResult } from \"../types/config.js\";\nimport { writeFileSafe } from \"../utils/file-system.js\";\nimport { hasEslint } from \"../utils/detect-project.js\";\n\n/**\n * Check if project uses React\n */\nasync function hasReact(targetDir: string): Promise<boolean> {\n try {\n const pkgPath = join(targetDir, \"package.json\");\n if (existsSync(pkgPath)) {\n const content = await readFile(pkgPath, \"utf-8\");\n const pkg = JSON.parse(content);\n const deps = { ...pkg.dependencies, ...pkg.devDependencies };\n return \"react\" in deps || \"react-dom\" in deps;\n }\n } catch {\n // Ignore parse errors\n }\n return false;\n}\n\n/**\n * Check if project uses Next.js\n */\nasync function hasNextJs(targetDir: string): Promise<boolean> {\n try {\n const pkgPath = join(targetDir, \"package.json\");\n if (existsSync(pkgPath)) {\n const content = await readFile(pkgPath, \"utf-8\");\n const pkg = JSON.parse(content);\n const deps = { ...pkg.dependencies, ...pkg.devDependencies };\n return \"next\" in deps;\n }\n } catch {\n // Ignore parse errors\n }\n return false;\n}\n\n/**\n * Generate ESLint flat config for Next.js projects (TypeScript)\n * Uses eslint-config-next which provides pre-configured rules\n */\nfunction generateNextJsConfig(): string {\n return `import { defineConfig, globalIgnores } from \"eslint/config\";\nimport nextVitals from \"eslint-config-next/core-web-vitals\";\nimport nextTs from \"eslint-config-next/typescript\";\nimport prettier from \"eslint-config-prettier\";\n\nconst eslintConfig = defineConfig([\n ...nextVitals,\n ...nextTs,\n prettier,\n globalIgnores([\".next/**\", \"out/**\", \"build/**\", \"next-env.d.ts\"]),\n]);\n\nexport default eslintConfig;\n`;\n}\n\n/**\n * Generate ESLint flat config for React TypeScript projects (non-Next.js)\n */\nfunction generateReactTsConfig(): string {\n return `import eslint from \"@eslint/js\";\nimport tseslint from \"typescript-eslint\";\nimport eslintConfigPrettier from \"eslint-config-prettier\";\nimport reactPlugin from \"eslint-plugin-react\";\nimport reactHooksPlugin from \"eslint-plugin-react-hooks\";\nimport globals from \"globals\";\n\nexport default tseslint.config(\n eslint.configs.recommended,\n ...tseslint.configs.strict,\n eslintConfigPrettier,\n {\n files: [\"**/*.{ts,tsx}\"],\n languageOptions: {\n parserOptions: {\n ecmaFeatures: {\n jsx: true,\n },\n },\n globals: {\n ...globals.browser,\n ...globals.node,\n },\n },\n plugins: {\n react: reactPlugin,\n \"react-hooks\": reactHooksPlugin,\n },\n rules: {\n // TypeScript rules\n \"@typescript-eslint/no-unused-vars\": [\n \"error\",\n { argsIgnorePattern: \"^_\", varsIgnorePattern: \"^_\" },\n ],\n \"@typescript-eslint/no-explicit-any\": \"warn\",\n \"@typescript-eslint/consistent-type-imports\": [\n \"warn\",\n { prefer: \"type-imports\" },\n ],\n\n // React rules\n \"react/react-in-jsx-scope\": \"off\",\n \"react/prop-types\": \"off\",\n \"react-hooks/rules-of-hooks\": \"error\",\n \"react-hooks/exhaustive-deps\": \"warn\",\n\n // General rules\n \"no-console\": [\"warn\", { allow: [\"warn\", \"error\"] }],\n },\n settings: {\n react: {\n version: \"detect\",\n },\n },\n },\n {\n // CommonJS config files (commitlint.config.js, etc.)\n files: [\"*.config.js\", \"*.config.cjs\"],\n languageOptions: {\n globals: {\n ...globals.node,\n },\n sourceType: \"commonjs\",\n },\n },\n {\n ignores: [\"node_modules/\", \"dist/\", \"build/\", \".next/\", \"coverage/\", \".turbo/\"],\n }\n);\n`;\n}\n\n/**\n * Generate ESLint flat config for TypeScript projects (non-React)\n */\nfunction generateTsConfig(): string {\n return `import eslint from \"@eslint/js\";\nimport tseslint from \"typescript-eslint\";\nimport eslintConfigPrettier from \"eslint-config-prettier\";\nimport globals from \"globals\";\n\nexport default tseslint.config(\n eslint.configs.recommended,\n ...tseslint.configs.strict,\n eslintConfigPrettier,\n {\n files: [\"**/*.{ts,tsx}\"],\n languageOptions: {\n globals: {\n ...globals.node,\n },\n },\n rules: {\n // TypeScript rules\n \"@typescript-eslint/no-unused-vars\": [\n \"error\",\n { argsIgnorePattern: \"^_\", varsIgnorePattern: \"^_\" },\n ],\n \"@typescript-eslint/no-explicit-any\": \"warn\",\n \"@typescript-eslint/consistent-type-imports\": [\n \"warn\",\n { prefer: \"type-imports\" },\n ],\n\n // General rules\n \"no-console\": [\"warn\", { allow: [\"warn\", \"error\"] }],\n },\n },\n {\n // CommonJS config files (commitlint.config.js, etc.)\n files: [\"*.config.js\", \"*.config.cjs\"],\n languageOptions: {\n globals: {\n ...globals.node,\n },\n sourceType: \"commonjs\",\n },\n },\n {\n ignores: [\"node_modules/\", \"dist/\", \"build/\", \"coverage/\", \".turbo/\"],\n }\n);\n`;\n}\n\n/**\n * Generate ESLint flat config for React JavaScript projects\n */\nfunction generateReactJsConfig(): string {\n return `import eslint from \"@eslint/js\";\nimport eslintConfigPrettier from \"eslint-config-prettier\";\nimport reactPlugin from \"eslint-plugin-react\";\nimport reactHooksPlugin from \"eslint-plugin-react-hooks\";\nimport globals from \"globals\";\n\nexport default [\n eslint.configs.recommended,\n eslintConfigPrettier,\n {\n files: [\"**/*.{js,jsx}\"],\n languageOptions: {\n ecmaVersion: \"latest\",\n sourceType: \"module\",\n parserOptions: {\n ecmaFeatures: {\n jsx: true,\n },\n },\n globals: {\n ...globals.browser,\n ...globals.node,\n },\n },\n plugins: {\n react: reactPlugin,\n \"react-hooks\": reactHooksPlugin,\n },\n rules: {\n // React rules\n \"react/react-in-jsx-scope\": \"off\",\n \"react/prop-types\": \"warn\",\n \"react-hooks/rules-of-hooks\": \"error\",\n \"react-hooks/exhaustive-deps\": \"warn\",\n\n // General rules\n \"no-console\": [\"warn\", { allow: [\"warn\", \"error\"] }],\n \"no-unused-vars\": [\"error\", { argsIgnorePattern: \"^_\", varsIgnorePattern: \"^_\" }],\n },\n settings: {\n react: {\n version: \"detect\",\n },\n },\n },\n {\n // CommonJS config files (commitlint.config.js, etc.)\n files: [\"*.config.js\", \"*.config.cjs\"],\n languageOptions: {\n globals: {\n ...globals.node,\n },\n sourceType: \"commonjs\",\n },\n },\n {\n ignores: [\"node_modules/\", \"dist/\", \"build/\", \".next/\", \"coverage/\", \".turbo/\"],\n },\n];\n`;\n}\n\n/**\n * Generate ESLint flat config for JavaScript projects (non-React)\n */\nfunction generateJsConfig(): string {\n return `import eslint from \"@eslint/js\";\nimport eslintConfigPrettier from \"eslint-config-prettier\";\nimport globals from \"globals\";\n\nexport default [\n eslint.configs.recommended,\n eslintConfigPrettier,\n {\n files: [\"**/*.js\"],\n languageOptions: {\n ecmaVersion: \"latest\",\n sourceType: \"module\",\n globals: {\n ...globals.node,\n },\n },\n rules: {\n // General rules\n \"no-console\": [\"warn\", { allow: [\"warn\", \"error\"] }],\n \"no-unused-vars\": [\"error\", { argsIgnorePattern: \"^_\", varsIgnorePattern: \"^_\" }],\n },\n },\n {\n // CommonJS config files (commitlint.config.js, etc.)\n files: [\"*.config.js\", \"*.config.cjs\"],\n languageOptions: {\n globals: {\n ...globals.node,\n },\n sourceType: \"commonjs\",\n },\n },\n {\n ignores: [\"node_modules/\", \"dist/\", \"build/\", \"coverage/\", \".turbo/\"],\n },\n];\n`;\n}\n\n/**\n * Check if project uses React (exported for use by other modules)\n */\nexport async function detectReact(targetDir: string): Promise<boolean> {\n return hasReact(targetDir);\n}\n\n/**\n * Check if project uses Next.js (exported for use by other modules)\n */\nexport async function detectNextJs(targetDir: string): Promise<boolean> {\n return hasNextJs(targetDir);\n}\n\n/**\n * Generate ESLint configuration file\n *\n * @param targetDir - The target directory to write to\n * @param usesTypeScript - Whether the project uses TypeScript\n * @param force - Force generation even if ESLint is already configured\n */\nexport async function generateEslint(\n targetDir: string,\n usesTypeScript: boolean,\n force: boolean = false\n): Promise<GeneratorResult> {\n const result: GeneratorResult = {\n created: [],\n modified: [],\n skipped: [],\n backedUp: [],\n };\n\n // Check if ESLint is already configured (unless force)\n if (!force && (await hasEslint(targetDir))) {\n result.skipped.push(\"eslint.config.mjs (ESLint already configured)\");\n return result;\n }\n\n // Detect project framework\n const usesNextJs = await hasNextJs(targetDir);\n const usesReact = await hasReact(targetDir);\n\n // Generate appropriate config based on project type\n let config: string;\n\n if (usesNextJs && usesTypeScript) {\n // Next.js with TypeScript - use eslint-config-next\n config = generateNextJsConfig();\n } else if (usesReact && usesTypeScript) {\n // React + TypeScript (non-Next.js)\n config = generateReactTsConfig();\n } else if (usesTypeScript) {\n // TypeScript only\n config = generateTsConfig();\n } else if (usesReact) {\n // React + JavaScript\n config = generateReactJsConfig();\n } else {\n // Plain JavaScript\n config = generateJsConfig();\n }\n\n // Write config file with .mjs extension for ESM compatibility\n const configPath = join(targetDir, \"eslint.config.mjs\");\n const writeResult = await writeFileSafe(configPath, config);\n\n if (writeResult.backedUp) {\n result.backedUp.push(\"eslint.config.mjs\");\n }\n\n result.created.push(\"eslint.config.mjs\");\n\n return result;\n}\n","import { join } from \"node:path\";\nimport { writeFileSafe } from \"../utils/file-system.js\";\nimport type { GeneratorResult, PackageManagerInfo } from \"../types/config.js\";\n\n/**\n * Generate Quick Reference guide for developers\n */\nexport async function generateQuickReference(\n targetDir: string,\n pm: PackageManagerInfo\n): Promise<GeneratorResult> {\n const result: GeneratorResult = {\n created: [],\n modified: [],\n skipped: [],\n backedUp: [],\n };\n\n const quickRefPath = join(targetDir, \".github\", \"QUICK_REFERENCE.md\");\n\n const content = `# RaftStack Quick Reference\n\n> One-page guide for the RaftStack Git workflow\n\n## 🚀 Daily Workflow\n\n### 1. Create a Branch\n\n\\`\\`\\`bash\n# Format: <type>/<short-description>\ngit checkout -b feature/user-authentication\ngit checkout -b bugfix/login-redirect\ngit checkout -b hotfix/payment-timeout\n\\`\\`\\`\n\n**Branch types:** \\`feature\\`, \\`bugfix\\`, \\`hotfix\\`, \\`chore\\`, \\`refactor\\`\n\n### 2. Make Commits\n\n\\`\\`\\`bash\n# Use the interactive commit tool\n${pm.run} commit\n\\`\\`\\`\n\nThis will prompt you for:\n- Type (feat, fix, docs, etc.)\n- Scope (optional)\n- Description\n- Body (optional)\n- **Task link (required)**\n\n### 3. Commit Message Format\n\n\\`\\`\\`\n✨ feat(auth): add user login form\n\n- Created LoginForm component\n- Added form validation\n- Integrated with API\n\nTask: https://app.asana.com/0/project/task\n\\`\\`\\`\n\n### 4. Create Pull Request\n\n\\`\\`\\`bash\ngit push -u origin feature/my-feature\n# Then create PR on GitHub\n\\`\\`\\`\n\n---\n\n## 📝 Commit Types\n\n| Type | Emoji | Use For |\n|------|-------|---------|\n| feat | ✨ | New feature |\n| fix | 🐛 | Bug fix |\n| docs | 📝 | Documentation |\n| style | 💄 | Formatting (no logic change) |\n| refactor | ♻️ | Code restructuring |\n| perf | ⚡ | Performance improvement |\n| test | ✅ | Adding tests |\n| build | 📦 | Build system changes |\n| ci | 👷 | CI configuration |\n| chore | 🔧 | Maintenance |\n\n---\n\n## ✅ PR Checklist\n\nBefore submitting:\n- [ ] Branch name follows convention\n- [ ] All commits have task links\n- [ ] Tests pass locally\n- [ ] PR description filled out\n- [ ] Size is reasonable (< 400 lines)\n\n---\n\n## 🔧 Useful Commands\n\n\\`\\`\\`bash\n# Interactive commit\n${pm.run} commit\n\n# Check compliance metrics\n${pm.exec} @raftlabs/raftstack metrics\n\n# Run linting\n${pm.run} lint\n\n# Run tests\n${pm.run} test\n\\`\\`\\`\n\n---\n\n## ❌ Common Mistakes\n\n| Wrong | Right |\n|-------|-------|\n| \\`Feature/UserAuth\\` | \\`feature/user-auth\\` |\n| \\`fixed bug\\` | \\`fix(auth): resolve login redirect\\` |\n| No task link | Always include \\`Task: <url>\\` |\n| 1000+ line PR | Split into smaller PRs |\n\n---\n\n## 📚 More Info\n\n- [CONTRIBUTING.md](../CONTRIBUTING.md) - Full contribution guide\n- [RaftStack Docs](https://github.com/Raft-Labs/raftstack) - CLI documentation\n\n---\n\n*Generated by RaftStack - Git workflow standardization for teams*\n`;\n\n const writeResult = await writeFileSafe(quickRefPath, content);\n\n if (writeResult.created) {\n if (writeResult.backedUp) {\n result.modified.push(\".github/QUICK_REFERENCE.md\");\n result.backedUp.push(\".github/QUICK_REFERENCE.md\");\n } else {\n result.created.push(\".github/QUICK_REFERENCE.md\");\n }\n } else {\n result.skipped.push(\".github/QUICK_REFERENCE.md\");\n }\n\n return result;\n}\n","import { join } from \"node:path\";\nimport type { GeneratorResult, ProjectType } from \"../types/config.js\";\nimport { ensureDir, writeFileSafe } from \"../utils/file-system.js\";\n\n/**\n * Generate shared ESLint configuration package for monorepos\n * Creates packages/eslint-config/ with base, next.js, react-internal, and vite configs\n */\n\n// ESLint config package.json\nfunction getEslintConfigPackageJson(): string {\n return JSON.stringify(\n {\n name: \"@workspace/eslint-config\",\n version: \"0.0.0\",\n type: \"module\",\n private: true,\n exports: {\n \"./base\": \"./base.js\",\n \"./next-js\": \"./next.js\",\n \"./react-internal\": \"./react-internal.js\",\n \"./vite\": \"./vite.js\",\n },\n devDependencies: {\n \"@eslint/js\": \"^9.39.0\",\n \"@next/eslint-plugin-next\": \"^16.1.0\",\n eslint: \"^9.39.0\",\n \"eslint-config-prettier\": \"^10.1.0\",\n \"eslint-plugin-only-warn\": \"^1.1.0\",\n \"eslint-plugin-react\": \"^7.37.0\",\n \"eslint-plugin-react-hooks\": \"^5.2.0\",\n \"eslint-plugin-turbo\": \"^2.6.0\",\n globals: \"^17.0.0\",\n \"typescript-eslint\": \"^8.39.0\",\n },\n },\n null,\n 2\n ) + \"\\n\";\n}\n\n// Base ESLint config (TypeScript + Turbo)\nfunction getBaseEslintConfig(): string {\n return `import js from \"@eslint/js\";\nimport eslintConfigPrettier from \"eslint-config-prettier\";\nimport onlyWarn from \"eslint-plugin-only-warn\";\nimport turboPlugin from \"eslint-plugin-turbo\";\nimport tseslint from \"typescript-eslint\";\n\n/**\n * Base ESLint configuration for all packages\n * Includes TypeScript, Prettier, and Turborepo rules\n */\nexport const config = [\n js.configs.recommended,\n eslintConfigPrettier,\n ...tseslint.configs.recommended,\n {\n plugins: { turbo: turboPlugin },\n rules: { \"turbo/no-undeclared-env-vars\": \"warn\" },\n },\n { plugins: { onlyWarn } },\n { ignores: [\"dist/**\"] },\n];\n`;\n}\n\n// Next.js ESLint config\nfunction getNextJsEslintConfig(): string {\n return `import { defineConfig, globalIgnores } from \"eslint/config\";\nimport nextVitals from \"eslint-config-next/core-web-vitals\";\nimport nextTs from \"eslint-config-next/typescript\";\nimport prettier from \"eslint-config-prettier\";\nimport { config as baseConfig } from \"./base.js\";\n\n/**\n * ESLint configuration for Next.js applications\n * Extends base config with Next.js specific rules\n */\nexport const nextJsConfig = defineConfig([\n ...baseConfig,\n ...nextVitals,\n ...nextTs,\n prettier,\n globalIgnores([\".next/**\", \"out/**\", \"build/**\", \"next-env.d.ts\"]),\n]);\n\nexport default nextJsConfig;\n`;\n}\n\n// React internal library config\nfunction getReactInternalEslintConfig(): string {\n return `import eslintConfigPrettier from \"eslint-config-prettier\";\nimport reactPlugin from \"eslint-plugin-react\";\nimport reactHooksPlugin from \"eslint-plugin-react-hooks\";\nimport globals from \"globals\";\nimport { config as baseConfig } from \"./base.js\";\n\n/**\n * ESLint configuration for internal React libraries/packages\n * Extends base config with React-specific rules\n */\nexport const reactInternalConfig = [\n ...baseConfig,\n eslintConfigPrettier,\n {\n languageOptions: {\n parserOptions: {\n ecmaFeatures: { jsx: true },\n },\n globals: {\n ...globals.browser,\n },\n },\n plugins: {\n react: reactPlugin,\n \"react-hooks\": reactHooksPlugin,\n },\n rules: {\n \"react/react-in-jsx-scope\": \"off\",\n \"react/prop-types\": \"off\",\n \"react-hooks/rules-of-hooks\": \"error\",\n \"react-hooks/exhaustive-deps\": \"warn\",\n },\n settings: {\n react: { version: \"detect\" },\n },\n },\n { ignores: [\"dist/**\", \"node_modules/**\"] },\n];\n\nexport default reactInternalConfig;\n`;\n}\n\n// Vite config\nfunction getViteEslintConfig(): string {\n return `import eslintConfigPrettier from \"eslint-config-prettier\";\nimport reactPlugin from \"eslint-plugin-react\";\nimport reactHooksPlugin from \"eslint-plugin-react-hooks\";\nimport globals from \"globals\";\nimport { config as baseConfig } from \"./base.js\";\n\n/**\n * ESLint configuration for Vite-based applications\n * Extends base config with React and browser globals\n */\nexport const viteConfig = [\n ...baseConfig,\n eslintConfigPrettier,\n {\n languageOptions: {\n parserOptions: {\n ecmaFeatures: { jsx: true },\n },\n globals: {\n ...globals.browser,\n ...globals.node,\n },\n },\n plugins: {\n react: reactPlugin,\n \"react-hooks\": reactHooksPlugin,\n },\n rules: {\n \"react/react-in-jsx-scope\": \"off\",\n \"react/prop-types\": \"off\",\n \"react-hooks/rules-of-hooks\": \"error\",\n \"react-hooks/exhaustive-deps\": \"warn\",\n },\n settings: {\n react: { version: \"detect\" },\n },\n },\n { ignores: [\"dist/**\", \"node_modules/**\"] },\n];\n\nexport default viteConfig;\n`;\n}\n\n/**\n * Generate shared TypeScript configuration package for monorepos\n * Creates packages/typescript-config/ with base and nextjs configs\n */\n\n// TypeScript config package.json\nfunction getTsConfigPackageJson(): string {\n return JSON.stringify(\n {\n name: \"@workspace/typescript-config\",\n version: \"0.0.0\",\n private: true,\n },\n null,\n 2\n ) + \"\\n\";\n}\n\n// Base TypeScript config\nfunction getBaseTsConfig(): string {\n return JSON.stringify(\n {\n $schema: \"https://json.schemastore.org/tsconfig\",\n display: \"Default\",\n compilerOptions: {\n declaration: true,\n declarationMap: true,\n esModuleInterop: true,\n incremental: false,\n isolatedModules: true,\n lib: [\"es2022\", \"DOM\", \"DOM.Iterable\"],\n module: \"NodeNext\",\n moduleDetection: \"force\",\n moduleResolution: \"NodeNext\",\n noUncheckedIndexedAccess: true,\n resolveJsonModule: true,\n skipLibCheck: true,\n strict: true,\n target: \"ES2022\",\n },\n },\n null,\n 2\n ) + \"\\n\";\n}\n\n// Next.js TypeScript config\nfunction getNextJsTsConfig(): string {\n return JSON.stringify(\n {\n $schema: \"https://json.schemastore.org/tsconfig\",\n display: \"Next.js\",\n extends: \"./base.json\",\n compilerOptions: {\n plugins: [{ name: \"next\" }],\n module: \"ESNext\",\n moduleResolution: \"Bundler\",\n allowJs: true,\n jsx: \"preserve\",\n noEmit: true,\n },\n },\n null,\n 2\n ) + \"\\n\";\n}\n\n// React library TypeScript config\nfunction getReactLibraryTsConfig(): string {\n return JSON.stringify(\n {\n $schema: \"https://json.schemastore.org/tsconfig\",\n display: \"React Library\",\n extends: \"./base.json\",\n compilerOptions: {\n jsx: \"react-jsx\",\n lib: [\"ES2022\", \"DOM\", \"DOM.Iterable\"],\n module: \"ESNext\",\n moduleResolution: \"Bundler\",\n },\n },\n null,\n 2\n ) + \"\\n\";\n}\n\n// Node library TypeScript config\nfunction getNodeLibraryTsConfig(): string {\n return JSON.stringify(\n {\n $schema: \"https://json.schemastore.org/tsconfig\",\n display: \"Node Library\",\n extends: \"./base.json\",\n compilerOptions: {\n lib: [\"ES2022\"],\n module: \"NodeNext\",\n moduleResolution: \"NodeNext\",\n },\n },\n null,\n 2\n ) + \"\\n\";\n}\n\n/**\n * Check if this is a monorepo project type\n */\nexport function isMonorepo(projectType: ProjectType): boolean {\n return projectType === \"turbo\" || projectType === \"nx\" || projectType === \"pnpm-workspace\";\n}\n\n/**\n * Generate shared configuration packages for monorepos\n *\n * Creates:\n * - packages/eslint-config/ with base, next-js, react-internal, vite configs\n * - packages/typescript-config/ with base, nextjs, react-library, node-library configs\n */\nexport async function generateSharedConfigs(\n targetDir: string,\n projectType: ProjectType\n): Promise<GeneratorResult> {\n const result: GeneratorResult = {\n created: [],\n modified: [],\n skipped: [],\n backedUp: [],\n };\n\n // Only generate for monorepos\n if (!isMonorepo(projectType)) {\n return result;\n }\n\n const packagesDir = join(targetDir, \"packages\");\n\n // Generate ESLint config package\n const eslintConfigDir = join(packagesDir, \"eslint-config\");\n await ensureDir(eslintConfigDir);\n\n const eslintFiles: Array<{ path: string; content: string; name: string }> = [\n { path: join(eslintConfigDir, \"package.json\"), content: getEslintConfigPackageJson(), name: \"packages/eslint-config/package.json\" },\n { path: join(eslintConfigDir, \"base.js\"), content: getBaseEslintConfig(), name: \"packages/eslint-config/base.js\" },\n { path: join(eslintConfigDir, \"next.js\"), content: getNextJsEslintConfig(), name: \"packages/eslint-config/next.js\" },\n { path: join(eslintConfigDir, \"react-internal.js\"), content: getReactInternalEslintConfig(), name: \"packages/eslint-config/react-internal.js\" },\n { path: join(eslintConfigDir, \"vite.js\"), content: getViteEslintConfig(), name: \"packages/eslint-config/vite.js\" },\n ];\n\n for (const file of eslintFiles) {\n const writeResult = await writeFileSafe(file.path, file.content, { backup: true });\n if (writeResult.created) {\n result.created.push(file.name);\n if (writeResult.backedUp) {\n result.backedUp.push(file.name);\n }\n }\n }\n\n // Generate TypeScript config package\n const tsConfigDir = join(packagesDir, \"typescript-config\");\n await ensureDir(tsConfigDir);\n\n const tsFiles: Array<{ path: string; content: string; name: string }> = [\n { path: join(tsConfigDir, \"package.json\"), content: getTsConfigPackageJson(), name: \"packages/typescript-config/package.json\" },\n { path: join(tsConfigDir, \"base.json\"), content: getBaseTsConfig(), name: \"packages/typescript-config/base.json\" },\n { path: join(tsConfigDir, \"nextjs.json\"), content: getNextJsTsConfig(), name: \"packages/typescript-config/nextjs.json\" },\n { path: join(tsConfigDir, \"react-library.json\"), content: getReactLibraryTsConfig(), name: \"packages/typescript-config/react-library.json\" },\n { path: join(tsConfigDir, \"node-library.json\"), content: getNodeLibraryTsConfig(), name: \"packages/typescript-config/node-library.json\" },\n ];\n\n for (const file of tsFiles) {\n const writeResult = await writeFileSafe(file.path, file.content, { backup: true });\n if (writeResult.created) {\n result.created.push(file.name);\n if (writeResult.backedUp) {\n result.backedUp.push(file.name);\n }\n }\n }\n\n return result;\n}\n","import { execa } from \"execa\";\nimport { existsSync } from \"node:fs\";\nimport { join } from \"node:path\";\n\n/**\n * Check if directory is a git repository\n */\nexport async function isGitRepo(\n targetDir: string = process.cwd()\n): Promise<boolean> {\n // Quick check for .git directory\n if (existsSync(join(targetDir, \".git\"))) {\n return true;\n }\n\n // Fallback to git command (handles worktrees, etc.)\n try {\n await execa(\"git\", [\"rev-parse\", \"--git-dir\"], { cwd: targetDir });\n return true;\n } catch {\n return false;\n }\n}\n\n/**\n * Get the root directory of the git repository\n */\nexport async function getGitRoot(\n targetDir: string = process.cwd()\n): Promise<string | null> {\n try {\n const { stdout } = await execa(\"git\", [\"rev-parse\", \"--show-toplevel\"], {\n cwd: targetDir,\n });\n return stdout.trim();\n } catch {\n return null;\n }\n}\n\n/**\n * Get current branch name\n */\nexport async function getCurrentBranch(\n targetDir: string = process.cwd()\n): Promise<string | null> {\n try {\n const { stdout } = await execa(\"git\", [\"branch\", \"--show-current\"], {\n cwd: targetDir,\n });\n return stdout.trim() || null;\n } catch {\n return null;\n }\n}\n\n/**\n * Check if gh CLI is available and authenticated\n */\nexport async function isGhCliAvailable(): Promise<boolean> {\n try {\n await execa(\"gh\", [\"auth\", \"status\"]);\n return true;\n } catch {\n return false;\n }\n}\n\n/**\n * Get GitHub repository info (owner/repo)\n */\nexport async function getGitHubRepoInfo(\n targetDir: string = process.cwd()\n): Promise<{ owner: string; repo: string } | null> {\n try {\n const { stdout } = await execa(\"gh\", [\"repo\", \"view\", \"--json\", \"owner,name\"], {\n cwd: targetDir,\n });\n const data = JSON.parse(stdout);\n return {\n owner: data.owner.login,\n repo: data.name,\n };\n } catch {\n return null;\n }\n}\n\n/**\n * Initialize husky in the repository\n */\nexport async function initHusky(\n targetDir: string = process.cwd()\n): Promise<void> {\n await execa(\"npx\", [\"husky\", \"init\"], { cwd: targetDir });\n}\n\n/**\n * Run a git command\n */\nexport async function runGitCommand(\n args: string[],\n targetDir: string = process.cwd()\n): Promise<string> {\n const { stdout } = await execa(\"git\", args, { cwd: targetDir });\n return stdout;\n}\n","import * as p from \"@clack/prompts\";\nimport pc from \"picocolors\";\nimport { execa } from \"execa\";\nimport { isGhCliAvailable, getGitHubRepoInfo } from \"../utils/git.js\";\n\n/**\n * Merge strategy options\n */\nexport type MergeStrategy = \"rebase\" | \"squash\" | \"merge\";\n\n/**\n * Branch protection settings\n */\nexport interface BranchProtectionSettings {\n branch: string;\n requiredReviews: number;\n dismissStaleReviews: boolean;\n requireCodeOwners: boolean;\n requireStatusChecks: boolean;\n statusChecks: string[];\n requireConversationResolution: boolean;\n restrictPushes: boolean;\n blockForcePushes: boolean;\n blockDeletions: boolean;\n}\n\n/**\n * Repository settings for merge strategies\n */\nexport interface RepositorySettings {\n allowMergeCommit: boolean;\n allowSquashMerge: boolean;\n allowRebaseMerge: boolean;\n deleteBranchOnMerge: boolean;\n}\n\n/**\n * Default branch protection settings\n */\nfunction getDefaultSettings(branch: string): BranchProtectionSettings {\n return {\n branch,\n requiredReviews: 1,\n dismissStaleReviews: true,\n requireCodeOwners: true,\n requireStatusChecks: true,\n statusChecks: [\"check\"],\n requireConversationResolution: true,\n restrictPushes: false,\n blockForcePushes: true,\n blockDeletions: true,\n };\n}\n\n/**\n * Get repository settings based on merge strategy\n */\nfunction getMergeStrategySettings(strategy: MergeStrategy): RepositorySettings {\n switch (strategy) {\n case \"rebase\":\n return {\n allowMergeCommit: false,\n allowSquashMerge: false,\n allowRebaseMerge: true,\n deleteBranchOnMerge: true,\n };\n case \"squash\":\n return {\n allowMergeCommit: false,\n allowSquashMerge: true,\n allowRebaseMerge: false,\n deleteBranchOnMerge: true,\n };\n case \"merge\":\n return {\n allowMergeCommit: true,\n allowSquashMerge: false,\n allowRebaseMerge: false,\n deleteBranchOnMerge: true,\n };\n }\n}\n\n/**\n * Apply branch protection using gh CLI\n */\nasync function applyBranchProtection(\n owner: string,\n repo: string,\n settings: BranchProtectionSettings\n): Promise<void> {\n const args = [\n \"api\",\n \"-X\",\n \"PUT\",\n `/repos/${owner}/${repo}/branches/${settings.branch}/protection`,\n \"-f\",\n `required_pull_request_reviews[required_approving_review_count]=${settings.requiredReviews}`,\n \"-f\",\n `required_pull_request_reviews[dismiss_stale_reviews]=${settings.dismissStaleReviews}`,\n \"-f\",\n `required_pull_request_reviews[require_code_owner_reviews]=${settings.requireCodeOwners}`,\n \"-f\",\n `required_status_checks[strict]=true`,\n \"-f\",\n `enforce_admins=true`,\n \"-f\",\n `allow_force_pushes=${!settings.blockForcePushes}`,\n \"-f\",\n `allow_deletions=${!settings.blockDeletions}`,\n \"-f\",\n `required_conversation_resolution=${settings.requireConversationResolution}`,\n ];\n\n // Add status checks\n if (settings.requireStatusChecks && settings.statusChecks.length > 0) {\n for (const check of settings.statusChecks) {\n args.push(\"-f\", `required_status_checks[contexts][]=${check}`);\n }\n } else {\n args.push(\"-F\", \"required_status_checks=null\");\n }\n\n // Add restrictions (null means no restrictions beyond PRs)\n args.push(\"-F\", \"restrictions=null\");\n\n await execa(\"gh\", args);\n}\n\n/**\n * Apply repository merge settings using gh CLI\n */\nasync function applyMergeStrategy(\n owner: string,\n repo: string,\n settings: RepositorySettings\n): Promise<void> {\n const args = [\n \"api\",\n \"-X\",\n \"PATCH\",\n `/repos/${owner}/${repo}`,\n \"-f\",\n `allow_merge_commit=${settings.allowMergeCommit}`,\n \"-f\",\n `allow_squash_merge=${settings.allowSquashMerge}`,\n \"-f\",\n `allow_rebase_merge=${settings.allowRebaseMerge}`,\n \"-f\",\n `delete_branch_on_merge=${settings.deleteBranchOnMerge}`,\n ];\n\n await execa(\"gh\", args);\n}\n\n/**\n * Run the setup-protection command\n */\nexport async function runSetupProtection(\n targetDir: string = process.cwd()\n): Promise<void> {\n console.log();\n p.intro(pc.bgCyan(pc.black(\" Branch Protection Setup \")));\n\n // Check gh CLI\n const spinner = p.spinner();\n spinner.start(\"Checking GitHub CLI...\");\n\n const ghAvailable = await isGhCliAvailable();\n\n if (!ghAvailable) {\n spinner.stop(\"GitHub CLI not found or not authenticated\");\n console.log();\n p.log.error(pc.red(\"The GitHub CLI (gh) is required for this command.\"));\n p.log.info(\"Install it from: https://cli.github.com/\");\n p.log.info(\"Then run: gh auth login\");\n console.log();\n p.log.info(\n pc.dim(\n \"Alternatively, see .github/BRANCH_PROTECTION_SETUP.md for manual instructions.\"\n )\n );\n process.exit(1);\n }\n\n spinner.stop(\"GitHub CLI ready\");\n\n // Get repo info\n spinner.start(\"Getting repository info...\");\n const repoInfo = await getGitHubRepoInfo(targetDir);\n\n if (!repoInfo) {\n spinner.stop(\"Could not determine repository\");\n p.log.error(\n pc.red(\"Could not determine the GitHub repository for this directory.\")\n );\n p.log.info(\"Make sure you're in a git repository with a GitHub remote.\");\n process.exit(1);\n }\n\n spinner.stop(`Repository: ${pc.cyan(`${repoInfo.owner}/${repoInfo.repo}`)}`);\n\n // Ask which branches to protect\n const branches = await p.multiselect({\n message: \"Which branches need protection?\",\n options: [\n { value: \"main\", label: \"main\", hint: \"recommended\" },\n { value: \"master\", label: \"master\", hint: \"legacy default\" },\n { value: \"staging\", label: \"staging\", hint: \"staging environment\" },\n { value: \"production\", label: \"production\", hint: \"production environment\" },\n { value: \"development\", label: \"development\", hint: \"development branch\" },\n { value: \"develop\", label: \"develop\", hint: \"alternative dev branch\" },\n ],\n required: true,\n initialValues: [\"main\"],\n });\n\n if (p.isCancel(branches)) {\n p.cancel(\"Setup cancelled.\");\n process.exit(0);\n }\n\n // Ask for merge strategy\n const mergeStrategy = await p.select({\n message: \"Default merge strategy for PRs?\",\n options: [\n {\n value: \"rebase\",\n label: \"Rebase merge\",\n hint: \"recommended - clean linear history\",\n },\n {\n value: \"squash\",\n label: \"Squash merge\",\n hint: \"single commit per PR\",\n },\n {\n value: \"merge\",\n label: \"Merge commit\",\n hint: \"preserve all commits with merge commit\",\n },\n ],\n initialValue: \"rebase\",\n });\n\n if (p.isCancel(mergeStrategy)) {\n p.cancel(\"Setup cancelled.\");\n process.exit(0);\n }\n\n // Ask for number of required reviews\n const reviews = await p.text({\n message: \"How many approving reviews are required?\",\n placeholder: \"1\",\n initialValue: \"1\",\n validate: (value) => {\n const num = parseInt(value, 10);\n if (isNaN(num) || num < 0 || num > 6) {\n return \"Must be a number between 0 and 6\";\n }\n return undefined;\n },\n });\n\n if (p.isCancel(reviews)) {\n p.cancel(\"Setup cancelled.\");\n process.exit(0);\n }\n\n const requiredReviews = parseInt(reviews, 10);\n\n // Confirm settings\n const mergeStrategyLabels: Record<MergeStrategy, string> = {\n rebase: \"Rebase merge\",\n squash: \"Squash merge\",\n merge: \"Merge commit\",\n };\n\n console.log();\n p.note(\n [\n `${pc.cyan(\"Repository:\")} ${repoInfo.owner}/${repoInfo.repo}`,\n `${pc.cyan(\"Protected branches:\")} ${(branches as string[]).join(\", \")}`,\n `${pc.cyan(\"Merge strategy:\")} ${mergeStrategyLabels[mergeStrategy as MergeStrategy]}`,\n `${pc.cyan(\"Required reviews:\")} ${requiredReviews}`,\n `${pc.cyan(\"Dismiss stale reviews:\")} Yes`,\n `${pc.cyan(\"Require code owners:\")} Yes`,\n `${pc.cyan(\"Require status checks:\")} Yes`,\n `${pc.cyan(\"Block force pushes:\")} Yes`,\n `${pc.cyan(\"Block deletions:\")} Yes`,\n `${pc.cyan(\"Delete branch on merge:\")} Yes`,\n ].join(\"\\n\"),\n \"Branch Protection Settings\"\n );\n\n const confirmed = await p.confirm({\n message: \"Apply these branch protection rules?\",\n initialValue: true,\n });\n\n if (p.isCancel(confirmed) || !confirmed) {\n p.cancel(\"Setup cancelled.\");\n process.exit(0);\n }\n\n // Apply merge strategy settings first\n spinner.start(\"Configuring merge strategy...\");\n\n try {\n const repoSettings = getMergeStrategySettings(mergeStrategy as MergeStrategy);\n await applyMergeStrategy(repoInfo.owner, repoInfo.repo, repoSettings);\n spinner.stop(\"Merge strategy configured!\");\n } catch (error) {\n spinner.stop(\"Failed to configure merge strategy\");\n const errorMsg = error instanceof Error ? error.message : \"Unknown error\";\n p.log.warn(pc.yellow(`Warning: Could not set merge strategy: ${errorMsg}`));\n p.log.info(pc.dim(\"Continuing with branch protection...\"));\n }\n\n // Apply branch protection for each branch\n const protectedBranches: string[] = [];\n const failedBranches: string[] = [];\n\n for (const branch of branches as string[]) {\n spinner.start(`Protecting branch: ${branch}...`);\n\n try {\n const settings = getDefaultSettings(branch);\n settings.requiredReviews = requiredReviews;\n\n await applyBranchProtection(repoInfo.owner, repoInfo.repo, settings);\n protectedBranches.push(branch);\n spinner.stop(`Protected: ${pc.green(branch)}`);\n } catch (error) {\n failedBranches.push(branch);\n spinner.stop(`Failed: ${pc.red(branch)}`);\n\n const errorMsg = error instanceof Error ? error.message : \"Unknown error\";\n p.log.warn(\n pc.yellow(\n `Could not protect ${branch}: ${errorMsg.includes(\"Branch not found\") ? \"branch does not exist\" : errorMsg}`\n )\n );\n }\n }\n\n // Show summary\n console.log();\n\n if (protectedBranches.length > 0) {\n p.log.success(\n pc.green(`Branch protection enabled for: ${pc.cyan(protectedBranches.join(\", \"))}`)\n );\n }\n\n if (failedBranches.length > 0) {\n p.log.warn(\n pc.yellow(\n `Could not protect: ${pc.red(failedBranches.join(\", \"))} (branches may not exist yet)`\n )\n );\n p.log.info(pc.dim(\"Create these branches first, then run this command again.\"));\n }\n\n if (protectedBranches.length > 0) {\n p.outro(pc.green(\"Setup complete!\"));\n } else {\n p.outro(pc.yellow(\"No branches were protected.\"));\n process.exit(1);\n }\n}\n","import { execa } from \"execa\";\nimport * as p from \"@clack/prompts\";\nimport pc from \"picocolors\";\nimport { isGitRepo } from \"../utils/git.js\";\nimport { analyzeCodebase } from \"../utils/code-analyzer.js\";\nimport type {\n CommitInfo,\n AuthorMetrics,\n MetricsOptions,\n CodebaseMetrics,\n CodeQualityRule,\n} from \"../types/metrics.js\";\n\ninterface BranchMetricsResult {\n branchNames: string[];\n validBranches: number;\n invalidBranches: number;\n branchCompliance: number;\n}\n\n/**\n * Full conventional commit pattern with emoji + type(scope): desc\n * Supported emojis: ✨(feat) 🐛(fix) 📝(docs) 💄(style) ♻️(refactor)\n * ⚡(perf) ✅(test) 📦(build) 👷(ci) 🔧(chore) ⏪(revert)\n */\nconst CONVENTIONAL_COMMIT_PATTERN =\n /^(✨|🐛|📝|💄|♻️|⚡|✅|📦|👷|🔧|⏪)\\s+(feat|fix|docs|style|refactor|perf|test|build|ci|chore|revert)(\\([a-z0-9-]+\\))?:\\s.+/;\n\n/**\n * Get commits with full author information\n */\nasync function getCommitsWithAuthors(\n targetDir: string,\n days: number\n): Promise<CommitInfo[]> {\n try {\n const { stdout } = await execa(\n \"git\",\n [\n \"log\",\n `--since=${days} days ago`,\n \"--format=%H|%an|%ae|%s---BODY---%B---END---\",\n \"--no-merges\",\n ],\n { cwd: targetDir }\n );\n\n const commits: CommitInfo[] = [];\n const entries = stdout.split(\"---END---\").filter((e) => e.trim());\n\n for (const entry of entries) {\n const bodyMarker = entry.indexOf(\"---BODY---\");\n if (bodyMarker === -1) continue;\n\n const headerPart = entry.substring(0, bodyMarker).trim();\n const bodyPart = entry.substring(bodyMarker + 10).trim();\n\n const parts = headerPart.split(\"|\");\n if (parts.length >= 4) {\n commits.push({\n hash: parts[0],\n authorName: parts[1],\n authorEmail: parts[2],\n subject: parts.slice(3).join(\"|\"), // Subject might contain |\n body: bodyPart,\n });\n }\n }\n\n return commits;\n } catch {\n return [];\n }\n}\n\n/**\n * Check if commit follows conventional commit format with emoji\n */\nexport function isConventionalCommit(subject: string): boolean {\n return CONVENTIONAL_COMMIT_PATTERN.test(subject);\n}\n\n/**\n * Check if commit has a task link\n */\nfunction hasTaskLink(commit: CommitInfo): boolean {\n const fullMessage = `${commit.subject}\\n${commit.body}`;\n return (\n fullMessage.includes(\"app.asana.com\") ||\n fullMessage.includes(\"Task:\") ||\n fullMessage.includes(\"task:\") ||\n fullMessage.includes(\"Closes #\") ||\n fullMessage.includes(\"Fixes #\") ||\n fullMessage.includes(\"Resolves #\") ||\n /https:\\/\\/github\\.com\\/[^/]+\\/[^/]+\\/issues\\/\\d+/.test(fullMessage)\n );\n}\n\n/**\n * Calculate metrics for each author\n */\nexport function calculateAuthorMetrics(commits: CommitInfo[]): AuthorMetrics[] {\n const authorMap = new Map<\n string,\n {\n name: string;\n email: string;\n commits: CommitInfo[];\n }\n >();\n\n // Group commits by author email\n for (const commit of commits) {\n const existing = authorMap.get(commit.authorEmail);\n if (existing) {\n existing.commits.push(commit);\n // Use most recent name\n existing.name = commit.authorName;\n } else {\n authorMap.set(commit.authorEmail, {\n name: commit.authorName,\n email: commit.authorEmail,\n commits: [commit],\n });\n }\n }\n\n // Calculate metrics for each author\n const authorMetrics: AuthorMetrics[] = [];\n\n for (const [, author] of authorMap) {\n const totalCommits = author.commits.length;\n const withTaskLinks = author.commits.filter(hasTaskLink).length;\n const conventional = author.commits.filter((c) =>\n isConventionalCommit(c.subject)\n ).length;\n\n const taskLinkCompliance =\n totalCommits > 0 ? Math.round((withTaskLinks / totalCommits) * 100) : 100;\n const conventionalCompliance =\n totalCommits > 0 ? Math.round((conventional / totalCommits) * 100) : 100;\n\n // Weighted score: 40% task links, 60% conventional commits\n const overallScore = Math.round(\n taskLinkCompliance * 0.4 + conventionalCompliance * 0.6\n );\n\n authorMetrics.push({\n name: author.name,\n email: author.email,\n totalCommits,\n taskLinkCompliance,\n conventionalCompliance,\n overallScore,\n });\n }\n\n // Sort by overall score descending\n return authorMetrics.sort((a, b) => b.overallScore - a.overallScore);\n}\n\n/**\n * Get all branch names\n */\nasync function getBranchNames(targetDir: string): Promise<string[]> {\n try {\n const { stdout } = await execa(\n \"git\",\n [\"branch\", \"-a\", \"--format=%(refname:short)\"],\n { cwd: targetDir }\n );\n return stdout\n .trim()\n .split(\"\\n\")\n .filter(Boolean)\n .map((b) => b.replace(\"origin/\", \"\"))\n .filter((b, i, arr) => arr.indexOf(b) === i); // unique\n } catch {\n return [];\n }\n}\n\n/**\n * Validate branch name against convention\n */\nfunction isValidBranchName(name: string): boolean {\n const pattern =\n /^(main|staging|development|master)$|^(feature|bugfix|hotfix|chore|refactor)\\/[a-z0-9-]+$/;\n return pattern.test(name);\n}\n\n/**\n * Calculate branch metrics\n */\nasync function calculateBranchMetrics(\n targetDir: string\n): Promise<BranchMetricsResult> {\n const branches = await getBranchNames(targetDir);\n const validBranches = branches.filter(isValidBranchName);\n const invalidBranches = branches.filter((b) => !isValidBranchName(b));\n\n return {\n branchNames: branches,\n validBranches: validBranches.length,\n invalidBranches: invalidBranches.length,\n branchCompliance:\n branches.length > 0\n ? Math.round((validBranches.length / branches.length) * 100)\n : 100,\n };\n}\n\n/**\n * Format compliance percentage with color\n */\nfunction formatCompliance(percentage: number): string {\n if (percentage >= 90) return pc.green(`${percentage}%`);\n if (percentage >= 70) return pc.yellow(`${percentage}%`);\n return pc.red(`${percentage}%`);\n}\n\n/**\n * Format author leaderboard\n */\nfunction formatLeaderboard(\n authors: AuthorMetrics[],\n title: string,\n limit: number\n): string {\n if (authors.length === 0) return \"\";\n\n const lines = [pc.bold(title)];\n\n const displayed = authors.slice(0, limit);\n displayed.forEach((author, index) => {\n const score = formatCompliance(author.overallScore);\n const truncatedEmail =\n author.email.length > 25\n ? author.email.substring(0, 22) + \"...\"\n : author.email;\n lines.push(\n ` ${index + 1}. ${author.name} (${truncatedEmail}) - ${score} - ${author.totalCommits} commits`\n );\n });\n\n return lines.join(\"\\n\");\n}\n\n/**\n * Format codebase metrics display\n */\nfunction formatCodebaseMetrics(metrics: CodebaseMetrics): string {\n const ruleNames: Record<CodeQualityRule, string> = {\n \"file-length\": `File length (≤300)`,\n \"function-length\": `Function length (≤30)`,\n \"max-params\": `Max parameters (≤3)`,\n \"cyclomatic-complexity\": `Cyclomatic complexity`,\n \"magic-number\": `Magic numbers`,\n };\n\n const lines = [\n pc.bold(\"CODEBASE COMPLIANCE\"),\n ` Files analyzed: ${metrics.filesAnalyzed}`,\n ` Total lines: ${metrics.totalLines.toLocaleString()}`,\n \"\",\n pc.bold(\" RULE COMPLIANCE\"),\n ];\n\n for (const rule of Object.keys(ruleNames) as CodeQualityRule[]) {\n const compliance = metrics.complianceByRule[rule];\n const label = ruleNames[rule].padEnd(28);\n lines.push(` ${label}${formatCompliance(compliance)}`);\n }\n\n lines.push(\"\");\n lines.push(` ${pc.bold(\"OVERALL:\")} ${formatCompliance(metrics.overallCompliance)}`);\n\n if (metrics.worstFiles.length > 0) {\n lines.push(\"\");\n lines.push(pc.bold(\" TOP VIOLATIONS\"));\n\n for (const file of metrics.worstFiles.slice(0, 5)) {\n lines.push(` ${file.path} (${file.count} violations)`);\n\n // Group violations by rule for this file\n const fileViolations = metrics.violations.filter(\n (v) => v.filePath === file.path\n );\n const byRule = new Map<CodeQualityRule, number>();\n for (const v of fileViolations) {\n byRule.set(v.rule, (byRule.get(v.rule) || 0) + 1);\n }\n\n for (const [rule, count] of byRule) {\n lines.push(` - ${count}x ${rule}`);\n }\n }\n }\n\n return lines.join(\"\\n\");\n}\n\n/**\n * Run the metrics command\n */\nexport async function runMetrics(\n targetDir: string,\n options: MetricsOptions = {}\n): Promise<void> {\n const { git: gitOnly, code: codeOnly, ci: ciMode, threshold = 70 } = options;\n const showGit = !codeOnly;\n const showCode = !gitOnly;\n\n // In CI mode, skip interactive prompts\n const days = options.days || (ciMode ? 30 : null);\n\n if (!ciMode) {\n p.intro(pc.bgCyan(pc.black(\" RaftStack Metrics \")));\n }\n\n if (!(await isGitRepo(targetDir))) {\n if (ciMode) {\n console.error(\"Error: Not a git repository\");\n process.exit(1);\n }\n p.cancel(\"Not a git repository\");\n process.exit(1);\n }\n\n let selectedDays = days;\n if (!selectedDays && !ciMode) {\n const daysOption = await p.select({\n message: \"Time period to analyze:\",\n options: [\n { value: 7, label: \"Last 7 days\" },\n { value: 14, label: \"Last 14 days\" },\n { value: 30, label: \"Last 30 days\" },\n { value: 90, label: \"Last 90 days\" },\n ],\n });\n\n if (p.isCancel(daysOption)) {\n p.cancel(\"Operation cancelled\");\n process.exit(0);\n }\n\n selectedDays = daysOption as number;\n }\n\n const analyzeDays = selectedDays || 30;\n\n const spinner = ciMode ? null : p.spinner();\n spinner?.start(\"Analyzing repository...\");\n\n let overallCompliance = 100;\n const complianceScores: number[] = [];\n\n // Git metrics (commits, branches, authors)\n if (showGit) {\n const [commits, branchMetrics] = await Promise.all([\n getCommitsWithAuthors(targetDir, analyzeDays),\n calculateBranchMetrics(targetDir),\n ]);\n\n const authorMetrics = calculateAuthorMetrics(commits);\n\n // Calculate overall git compliance\n const totalCommits = commits.length;\n const withTaskLinks = commits.filter(hasTaskLink).length;\n const conventional = commits.filter((c) =>\n isConventionalCommit(c.subject)\n ).length;\n\n const taskLinkCompliance =\n totalCommits > 0 ? Math.round((withTaskLinks / totalCommits) * 100) : 100;\n const conventionalCompliance =\n totalCommits > 0 ? Math.round((conventional / totalCommits) * 100) : 100;\n\n complianceScores.push(\n taskLinkCompliance,\n conventionalCompliance,\n branchMetrics.branchCompliance\n );\n\n spinner?.stop(\"Git analysis complete\");\n\n if (ciMode) {\n console.log(\"\\n=== GIT METRICS ===\");\n console.log(`Commits (last ${analyzeDays} days): ${totalCommits}`);\n console.log(`Task link compliance: ${taskLinkCompliance}%`);\n console.log(`Conventional commit compliance: ${conventionalCompliance}%`);\n console.log(`Branch compliance: ${branchMetrics.branchCompliance}%`);\n } else {\n // Display git metrics\n p.note(\n `${pc.bold(\"Commits\")} (last ${analyzeDays} days)\n Total: ${totalCommits}\n With task links: ${withTaskLinks} (${formatCompliance(taskLinkCompliance)})\n Conventional format: ${conventional} (${formatCompliance(conventionalCompliance)})\n\n${pc.bold(\"Branches\")}\n Total: ${branchMetrics.branchNames.length}\n Valid naming: ${branchMetrics.validBranches}\n Invalid naming: ${branchMetrics.invalidBranches}\n Compliance: ${formatCompliance(branchMetrics.branchCompliance)}`,\n \"Git Metrics\"\n );\n\n // Author leaderboard\n if (authorMetrics.length > 0) {\n const topPerformers = authorMetrics.filter((a) => a.overallScore >= 70);\n const needsImprovement = authorMetrics\n .filter((a) => a.overallScore < 70)\n .reverse(); // Worst first\n\n let leaderboardText = \"\";\n\n if (topPerformers.length > 0) {\n leaderboardText += formatLeaderboard(\n topPerformers,\n \"TOP PERFORMERS\",\n 5\n );\n }\n\n if (needsImprovement.length > 0) {\n if (leaderboardText) leaderboardText += \"\\n\\n\";\n leaderboardText += formatLeaderboard(\n needsImprovement,\n \"NEEDS IMPROVEMENT\",\n 5\n );\n }\n\n if (leaderboardText) {\n p.note(leaderboardText, \"Author Leaderboard\");\n }\n }\n\n // Show invalid branches\n if (branchMetrics.invalidBranches > 0) {\n const invalidBranches = branchMetrics.branchNames.filter(\n (b) => !isValidBranchName(b)\n );\n p.log.warn(\n `Invalid branch names:\\n ${invalidBranches.slice(0, 10).join(\"\\n \")}${\n invalidBranches.length > 10\n ? `\\n ... and ${invalidBranches.length - 10} more`\n : \"\"\n }`\n );\n }\n }\n }\n\n // Codebase metrics\n if (showCode) {\n if (!ciMode && showGit) {\n spinner?.start(\"Analyzing codebase...\");\n } else if (!ciMode) {\n spinner?.start(\"Analyzing codebase...\");\n }\n\n const codebaseMetrics = await analyzeCodebase(targetDir);\n complianceScores.push(codebaseMetrics.overallCompliance);\n\n spinner?.stop(\"Codebase analysis complete\");\n\n if (ciMode) {\n console.log(\"\\n=== CODEBASE METRICS ===\");\n console.log(`Files analyzed: ${codebaseMetrics.filesAnalyzed}`);\n console.log(`Overall compliance: ${codebaseMetrics.overallCompliance}%`);\n\n for (const [rule, compliance] of Object.entries(\n codebaseMetrics.complianceByRule\n )) {\n console.log(` ${rule}: ${compliance}%`);\n }\n } else {\n p.note(formatCodebaseMetrics(codebaseMetrics), \"Codebase Analysis\");\n }\n }\n\n // Calculate overall compliance\n if (complianceScores.length > 0) {\n overallCompliance = Math.round(\n complianceScores.reduce((a, b) => a + b, 0) / complianceScores.length\n );\n }\n\n // CI mode exit handling\n if (ciMode) {\n console.log(`\\nOVERALL COMPLIANCE: ${overallCompliance}%`);\n console.log(`THRESHOLD: ${threshold}%`);\n\n if (overallCompliance < threshold) {\n console.log(\n `\\nFAILED: Compliance ${overallCompliance}% is below threshold ${threshold}%`\n );\n process.exit(1);\n } else {\n console.log(`\\nPASSED: Compliance meets threshold`);\n process.exit(0);\n }\n }\n\n // Interactive outro\n if (overallCompliance >= 90) {\n p.outro(pc.green(\"✓ Excellent compliance! Keep up the good work.\"));\n } else if (overallCompliance >= 70) {\n p.outro(pc.yellow(\"⚠ Good progress, but there's room for improvement.\"));\n } else {\n p.outro(pc.red(\"✗ Compliance needs attention. Review the guidelines.\"));\n }\n}\n","import { execa } from \"execa\";\nimport { readFileSync } from \"node:fs\";\nimport type {\n CodeQualityRule,\n FileViolation,\n CodebaseMetrics,\n} from \"../types/metrics.js\";\n\n/**\n * Thresholds for code quality rules\n */\nconst THRESHOLDS = {\n \"file-length\": 300,\n \"function-length\": 30,\n \"max-params\": 3,\n \"cyclomatic-complexity\": 10,\n} as const;\n\n/**\n * Information about an extracted function\n */\ninterface FunctionInfo {\n name: string;\n startLine: number;\n endLine: number;\n paramCount: number;\n body: string;\n}\n\n/**\n * Get all source files in a git repository\n */\nexport async function findSourceFiles(targetDir: string): Promise<string[]> {\n try {\n const { stdout } = await execa(\n \"git\",\n [\"ls-files\", \"*.ts\", \"*.tsx\", \"*.js\", \"*.jsx\"],\n { cwd: targetDir }\n );\n return stdout\n .trim()\n .split(\"\\n\")\n .filter(Boolean)\n .filter(\n (f) =>\n !f.includes(\"node_modules\") &&\n !f.includes(\"dist/\") &&\n !f.includes(\"build/\") &&\n !f.includes(\".min.\") &&\n !f.endsWith(\".d.ts\")\n );\n } catch {\n return [];\n }\n}\n\n/**\n * Extract functions from source code using regex patterns\n * Handles: function declarations, arrow functions, and class methods\n */\nexport function extractFunctions(\n source: string,\n _filePath: string\n): FunctionInfo[] {\n const functions: FunctionInfo[] = [];\n const lines = source.split(\"\\n\");\n\n // Patterns for function starts\n const functionPatterns = [\n // function name(params) or async function name(params)\n /^(\\s*)(?:export\\s+)?(?:async\\s+)?function\\s+(\\w+)\\s*\\(([^)]*)\\)/,\n // const name = (params) => or const name = async (params) =>\n /^(\\s*)(?:export\\s+)?(?:const|let|var)\\s+(\\w+)\\s*=\\s*(?:async\\s+)?\\(([^)]*)\\)\\s*(?::\\s*[^=]+)?\\s*=>/,\n // const name = function(params)\n /^(\\s*)(?:export\\s+)?(?:const|let|var)\\s+(\\w+)\\s*=\\s*(?:async\\s+)?function\\s*\\(([^)]*)\\)/,\n // class method: name(params) { or async name(params) {\n /^(\\s*)(?:async\\s+)?(\\w+)\\s*\\(([^)]*)\\)\\s*(?::\\s*[^{]+)?\\s*\\{/,\n ];\n\n for (let i = 0; i < lines.length; i++) {\n const line = lines[i];\n\n for (const pattern of functionPatterns) {\n const match = line.match(pattern);\n if (match) {\n const [, indent, name, params] = match;\n // Skip constructors and certain patterns\n if (\n name === \"constructor\" ||\n name === \"if\" ||\n name === \"for\" ||\n name === \"while\" ||\n name === \"switch\" ||\n name === \"catch\"\n ) {\n continue;\n }\n\n const paramCount = countParameters(params);\n const endLine = findFunctionEnd(lines, i, indent.length);\n\n if (endLine > i) {\n const body = lines.slice(i, endLine + 1).join(\"\\n\");\n functions.push({\n name,\n startLine: i + 1, // 1-indexed\n endLine: endLine + 1,\n paramCount,\n body,\n });\n }\n break;\n }\n }\n }\n\n return functions;\n}\n\n/**\n * Count parameters in a parameter list string\n */\nfunction countParameters(params: string): number {\n const trimmed = params.trim();\n if (!trimmed) return 0;\n\n // Handle destructured params and type annotations\n let depth = 0;\n let count = 1;\n\n for (const char of trimmed) {\n if (char === \"(\" || char === \"{\" || char === \"[\" || char === \"<\") {\n depth++;\n } else if (char === \")\" || char === \"}\" || char === \"]\" || char === \">\") {\n depth--;\n } else if (char === \",\" && depth === 0) {\n count++;\n }\n }\n\n return count;\n}\n\n/**\n * Find the closing brace of a function by tracking brace depth\n */\nfunction findFunctionEnd(\n lines: string[],\n startLine: number,\n _baseIndent: number\n): number {\n let braceDepth = 0;\n let foundOpenBrace = false;\n\n for (let i = startLine; i < lines.length; i++) {\n const line = lines[i];\n\n for (const char of line) {\n if (char === \"{\") {\n braceDepth++;\n foundOpenBrace = true;\n } else if (char === \"}\") {\n braceDepth--;\n if (foundOpenBrace && braceDepth === 0) {\n return i;\n }\n }\n }\n }\n\n // Fallback: look for line with matching indent and closing brace\n return startLine;\n}\n\n/**\n * Calculate cyclomatic complexity of a code block\n * Counts: if, else if, case, &&, ||, ?:, catch, for, while, do\n */\nexport function countComplexity(code: string): number {\n let complexity = 1; // Base complexity\n\n // Decision points that increase complexity\n const patterns = [\n /\\bif\\s*\\(/g,\n /\\belse\\s+if\\s*\\(/g,\n /\\bcase\\s+/g,\n /\\bfor\\s*\\(/g,\n /\\bwhile\\s*\\(/g,\n /\\bdo\\s*\\{/g,\n /\\bcatch\\s*\\(/g,\n /&&/g,\n /\\|\\|/g,\n /\\?\\?/g, // nullish coalescing\n ];\n\n // Ternary operator (but not in type annotations)\n const ternaryPattern = /\\?[^:?]+:/g;\n\n for (const pattern of patterns) {\n const matches = code.match(pattern);\n if (matches) {\n complexity += matches.length;\n }\n }\n\n // Count ternary operators (excluding type declarations)\n const ternaryMatches = code.match(ternaryPattern);\n if (ternaryMatches) {\n complexity += ternaryMatches.length;\n }\n\n return complexity;\n}\n\n/**\n * Find magic numbers in source code\n * Magic numbers are numeric literals not in const declarations or common patterns\n */\nexport function findMagicNumbers(\n source: string,\n filePath: string\n): FileViolation[] {\n const violations: FileViolation[] = [];\n const lines = source.split(\"\\n\");\n\n // Allowed numbers (common and acceptable)\n const allowedNumbers = new Set([\n \"0\",\n \"1\",\n \"-1\",\n \"2\",\n \"100\",\n \"1000\",\n \"0.5\",\n \"0.1\",\n ]);\n\n // Pattern to match numbers (including decimals and negative)\n const numberPattern = /-?\\d+\\.?\\d*/g;\n\n for (let i = 0; i < lines.length; i++) {\n const line = lines[i];\n const trimmedLine = line.trim();\n\n // Skip const/let declarations (these define named constants)\n if (/^\\s*(?:export\\s+)?const\\s+\\w+\\s*[:=]/.test(line)) {\n continue;\n }\n\n // Skip import statements\n if (trimmedLine.startsWith(\"import \")) {\n continue;\n }\n\n // Skip comments\n if (trimmedLine.startsWith(\"//\") || trimmedLine.startsWith(\"*\")) {\n continue;\n }\n\n // Skip array index access [0], [1], etc. and common patterns\n const cleanedLine = line\n .replace(/\\[\\d+\\]/g, \"\") // array indices\n .replace(/\\.length\\s*[<>=]+\\s*\\d+/g, \"\") // length comparisons\n .replace(/:\\s*number/g, \"\") // type annotations\n .replace(/[<>=]+\\s*0\\b/g, \"\") // comparisons with 0\n .replace(/\\+\\+|--/g, \"\"); // increment/decrement\n\n const matches = cleanedLine.match(numberPattern);\n if (matches) {\n for (const match of matches) {\n // Skip if it's an allowed number\n if (allowedNumbers.has(match)) continue;\n\n // Skip hex/octal/binary literals (like 0x1F, 0b1010)\n if (/0[xXbBoO]/.test(match)) continue;\n\n // Skip version-like numbers (in strings)\n if (line.includes(`\"${match}`) || line.includes(`'${match}`)) continue;\n\n violations.push({\n filePath,\n rule: \"magic-number\",\n line: i + 1,\n message: `Magic number ${match} should be a named constant`,\n });\n }\n }\n }\n\n return violations;\n}\n\n/**\n * Analyze a single file for all code quality rules\n */\nexport function analyzeFile(\n filePath: string,\n source: string\n): FileViolation[] {\n const violations: FileViolation[] = [];\n const lines = source.split(\"\\n\");\n const lineCount = lines.length;\n\n // Rule: file-length\n if (lineCount > THRESHOLDS[\"file-length\"]) {\n violations.push({\n filePath,\n rule: \"file-length\",\n line: 1,\n message: `File has ${lineCount} lines (max: ${THRESHOLDS[\"file-length\"]})`,\n });\n }\n\n // Extract functions for detailed analysis\n const functions = extractFunctions(source, filePath);\n\n for (const fn of functions) {\n const fnLineCount = fn.endLine - fn.startLine + 1;\n\n // Rule: function-length\n if (fnLineCount > THRESHOLDS[\"function-length\"]) {\n violations.push({\n filePath,\n rule: \"function-length\",\n line: fn.startLine,\n message: `Function '${fn.name}' has ${fnLineCount} lines (max: ${THRESHOLDS[\"function-length\"]})`,\n });\n }\n\n // Rule: max-params\n if (fn.paramCount > THRESHOLDS[\"max-params\"]) {\n violations.push({\n filePath,\n rule: \"max-params\",\n line: fn.startLine,\n message: `Function '${fn.name}' has ${fn.paramCount} parameters (max: ${THRESHOLDS[\"max-params\"]})`,\n });\n }\n\n // Rule: cyclomatic-complexity\n const complexity = countComplexity(fn.body);\n if (complexity > THRESHOLDS[\"cyclomatic-complexity\"]) {\n violations.push({\n filePath,\n rule: \"cyclomatic-complexity\",\n line: fn.startLine,\n message: `Function '${fn.name}' has complexity ${complexity} (max: ${THRESHOLDS[\"cyclomatic-complexity\"]})`,\n });\n }\n }\n\n // Rule: magic-number\n const magicViolations = findMagicNumbers(source, filePath);\n violations.push(...magicViolations);\n\n return violations;\n}\n\n/**\n * Analyze the entire codebase for compliance\n */\nexport async function analyzeCodebase(\n targetDir: string\n): Promise<CodebaseMetrics> {\n const files = await findSourceFiles(targetDir);\n const allViolations: FileViolation[] = [];\n let totalLines = 0;\n\n // Track violations by rule and by file\n const violationsByRule: Record<CodeQualityRule, number> = {\n \"file-length\": 0,\n \"function-length\": 0,\n \"max-params\": 0,\n \"cyclomatic-complexity\": 0,\n \"magic-number\": 0,\n };\n\n const violationsByFile: Map<string, number> = new Map();\n\n for (const file of files) {\n try {\n const fullPath = `${targetDir}/${file}`;\n const source = readFileSync(fullPath, \"utf-8\");\n totalLines += source.split(\"\\n\").length;\n\n const violations = analyzeFile(file, source);\n\n for (const v of violations) {\n violationsByRule[v.rule]++;\n violationsByFile.set(file, (violationsByFile.get(file) || 0) + 1);\n }\n\n allViolations.push(...violations);\n } catch {\n // Skip files that can't be read\n }\n }\n\n // Calculate compliance percentages\n // For file-based rules (file-length), compliance is % of files without violations\n // For function-based rules, we estimate based on total functions analyzed\n const filesWithoutFileLengthViolation =\n files.length - violationsByRule[\"file-length\"];\n const fileLengthCompliance =\n files.length > 0\n ? Math.round((filesWithoutFileLengthViolation / files.length) * 100)\n : 100;\n\n // For other rules, use a simpler heuristic: fewer violations = higher compliance\n // Base it on a reasonable expectation (1 violation per 10 files is acceptable)\n const calculateRuleCompliance = (\n violations: number,\n fileCount: number\n ): number => {\n if (fileCount === 0) return 100;\n const expectedMax = Math.max(1, Math.floor(fileCount / 5)); // Allow ~1 per 5 files\n const ratio = Math.min(1, violations / expectedMax);\n return Math.round((1 - ratio * 0.5) * 100); // Scale from 50-100%\n };\n\n const complianceByRule: Record<CodeQualityRule, number> = {\n \"file-length\": fileLengthCompliance,\n \"function-length\": calculateRuleCompliance(\n violationsByRule[\"function-length\"],\n files.length\n ),\n \"max-params\": calculateRuleCompliance(\n violationsByRule[\"max-params\"],\n files.length\n ),\n \"cyclomatic-complexity\": calculateRuleCompliance(\n violationsByRule[\"cyclomatic-complexity\"],\n files.length\n ),\n \"magic-number\": calculateRuleCompliance(\n violationsByRule[\"magic-number\"],\n files.length\n ),\n };\n\n // Overall compliance is average of all rules\n const overallCompliance = Math.round(\n Object.values(complianceByRule).reduce((a, b) => a + b, 0) / 5\n );\n\n // Get worst files\n const worstFiles = Array.from(violationsByFile.entries())\n .sort((a, b) => b[1] - a[1])\n .slice(0, 10)\n .map(([path, count]) => ({ path, count }));\n\n return {\n filesAnalyzed: files.length,\n totalLines,\n violations: allViolations,\n complianceByRule,\n overallCompliance,\n worstFiles,\n };\n}\n","{\n \"name\": \"@raftlabs/raftstack\",\n \"version\": \"1.8.0\",\n \"description\": \"CLI tool for setting up Git hooks, commit conventions, and GitHub integration\",\n \"type\": \"module\",\n \"main\": \"./dist/index.js\",\n \"types\": \"./dist/index.d.ts\",\n \"bin\": {\n \"raftstack\": \"./dist/cli.js\"\n },\n \"exports\": {\n \".\": {\n \"types\": \"./dist/index.d.ts\",\n \"import\": \"./dist/index.js\"\n }\n },\n \"files\": [\n \"dist\",\n \"templates\",\n \".claude/skills\"\n ],\n \"scripts\": {\n \"build\": \"tsup\",\n \"dev\": \"tsup --watch\",\n \"typecheck\": \"tsc --noEmit\",\n \"test\": \"vitest\",\n \"test:run\": \"vitest run\",\n \"prepublishOnly\": \"pnpm build\",\n \"prepublish\": \"pnpm test:run && pnpm build\",\n \"pack:test\": \"pnpm pack --dry-run\",\n \"publish:test\": \"pnpm pack && tar -xvzf raftlabs-raftstack-*.tgz && rm -rf package raftlabs-raftstack-*.tgz\",\n \"release\": \"standard-version\",\n \"release:patch\": \"standard-version --release-as patch\",\n \"release:minor\": \"standard-version --release-as minor\",\n \"release:major\": \"standard-version --release-as major\",\n \"release:first\": \"standard-version --first-release\"\n },\n \"keywords\": [\n \"cli\",\n \"git-hooks\",\n \"husky\",\n \"commitlint\",\n \"lint-staged\",\n \"developer-experience\"\n ],\n \"author\": \"Aravind Jaimon <dev@aravindjaimon.com>\",\n \"license\": \"MIT\",\n \"repository\": {\n \"type\": \"git\",\n \"url\": \"git+https://github.com/Raft-Labs/raftstack.git\"\n },\n \"homepage\": \"https://github.com/Raft-Labs/raftstack#readme\",\n \"readme\": \"README.npm.md\",\n \"bugs\": {\n \"url\": \"https://github.com/Raft-Labs/raftstack/issues\"\n },\n \"publishConfig\": {\n \"access\": \"public\",\n \"registry\": \"https://registry.npmjs.org/\"\n },\n \"packageManager\": \"pnpm@10.23.0\",\n \"engines\": {\n \"node\": \">=18\"\n },\n \"devDependencies\": {\n \"@types/cross-spawn\": \"^6.0.6\",\n \"@types/node\": \"^20.10.0\",\n \"standard-version\": \"^9.5.0\",\n \"tsup\": \"^8.0.0\",\n \"typescript\": \"^5.3.0\",\n \"vitest\": \"^1.0.0\"\n },\n \"dependencies\": {\n \"@clack/prompts\": \"^0.7.0\",\n \"commander\": \"^12.0.0\",\n \"cross-spawn\": \"^7.0.6\",\n \"execa\": \"^9.6.1\",\n \"picocolors\": \"^1.0.0\"\n }\n}\n"],"mappings":"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","names":["p","pc","existsSync","join","join","existsSync","join","existsSync","readFile","join","existsSync","join","join","join","join","join","readFile","writeFile","existsSync","join","existsSync","join","join","join","join","join","join","join","join","join","join","join","join","join","join","join","existsSync","copyFile","join","dirname","join","dirname","existsSync","copyFile","existsSync","readFile","join","join","existsSync","readFile","join","join","join","join","existsSync","join","pc","spinner","p","pc","execa","execa","pc","spinner","execa","p","pc","execa","readFileSync","execa","pc","spinner"]}