@qazuor/claude-code-config 0.6.0 → 0.6.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/bin.cjs CHANGED
@@ -6065,29 +6065,6 @@ function showReplacementReport(report) {
6065
6065
  // src/lib/scaffold/claude-md-generator.ts
6066
6066
  init_cjs_shims();
6067
6067
  init_fs();
6068
-
6069
- // src/lib/utils/paths.ts
6070
- init_cjs_shims();
6071
- var import_node_fs = __toESM(require("fs"), 1);
6072
- var import_node_path3 = __toESM(require("path"), 1);
6073
- var import_node_url = require("url");
6074
- function getPackageRoot() {
6075
- const currentFilePath = (0, import_node_url.fileURLToPath)(importMetaUrl);
6076
- let currentDir = import_node_path3.default.dirname(currentFilePath);
6077
- while (currentDir !== import_node_path3.default.dirname(currentDir)) {
6078
- const packageJsonPath = import_node_path3.default.join(currentDir, "package.json");
6079
- if (import_node_fs.default.existsSync(packageJsonPath)) {
6080
- return currentDir;
6081
- }
6082
- currentDir = import_node_path3.default.dirname(currentDir);
6083
- }
6084
- throw new Error("Could not find package root (no package.json found in parent directories)");
6085
- }
6086
- function getTemplatesPath() {
6087
- return import_node_path3.default.join(getPackageRoot(), "templates");
6088
- }
6089
-
6090
- // src/lib/scaffold/claude-md-generator.ts
6091
6068
  async function generateClaudeMd(projectPath, projectInfo, options) {
6092
6069
  const claudeMdPath = joinPath(projectPath, "CLAUDE.md");
6093
6070
  const exists = await pathExists(claudeMdPath);
@@ -6099,18 +6076,12 @@ async function generateClaudeMd(projectPath, projectInfo, options) {
6099
6076
  };
6100
6077
  }
6101
6078
  try {
6102
- let template;
6079
+ let content;
6103
6080
  if (options?.customTemplate) {
6104
- template = options.customTemplate;
6081
+ content = processCustomTemplate(options.customTemplate, projectInfo);
6105
6082
  } else {
6106
- const templatePath = joinPath(getTemplatesPath(), "CLAUDE.md.template");
6107
- if (await pathExists(templatePath)) {
6108
- template = await readFile(templatePath);
6109
- } else {
6110
- template = getMinimalTemplate();
6111
- }
6083
+ content = generateClaudeMdContent(projectInfo, options);
6112
6084
  }
6113
- const content = processTemplate(template, projectInfo, options);
6114
6085
  await writeFile(claudeMdPath, content);
6115
6086
  return {
6116
6087
  created: true,
@@ -6135,41 +6106,165 @@ async function generateClaudeMdWithSpinner(projectPath, projectInfo, options) {
6135
6106
  }
6136
6107
  );
6137
6108
  }
6138
- function processTemplate(template, projectInfo, options) {
6139
- let content = template;
6109
+ function processCustomTemplate(template, projectInfo) {
6110
+ return template.replace(/\{\{PROJECT_NAME\}\}/g, projectInfo.name).replace(/\{\{PROJECT_DESCRIPTION\}\}/g, projectInfo.description).replace(/\{\{ORG\}\}/g, projectInfo.org).replace(/\{\{REPO\}\}/g, projectInfo.repo).replace(/\{\{ENTITY_TYPE\}\}/g, projectInfo.entityType).replace(/\{\{ENTITY_TYPE_PLURAL\}\}/g, projectInfo.entityTypePlural).replace(/\{\{DOMAIN\}\}/g, projectInfo.domain || "").replace(/\{\{LOCATION\}\}/g, projectInfo.location || "");
6111
+ }
6112
+ function generateClaudeMdContent(projectInfo, options) {
6140
6113
  const techStack = options?.templateConfig?.techStack;
6141
6114
  const commands = options?.templateConfig?.commands;
6142
6115
  const targets = options?.templateConfig?.targets;
6143
6116
  const preferences = options?.claudeConfig?.preferences;
6144
6117
  const standards = options?.claudeConfig?.extras?.standards;
6145
- content = content.replace(/\{\{PROJECT_NAME\}\}/g, projectInfo.name).replace(/\{\{PROJECT_DESCRIPTION\}\}/g, projectInfo.description).replace(/\{\{ORG\}\}/g, projectInfo.org).replace(/\{\{REPO\}\}/g, projectInfo.repo).replace(/\{\{ENTITY_TYPE\}\}/g, projectInfo.entityType).replace(/\{\{ENTITY_TYPE_PLURAL\}\}/g, projectInfo.entityTypePlural).replace(/\{\{LOCATION\}\}/g, projectInfo.location || "");
6146
6118
  const packageManager = preferences?.packageManager || "pnpm";
6147
- content = content.replace(/\{\{PACKAGE_MANAGER\}\}/g, packageManager);
6148
- const coverageTarget = standards?.testing?.coverageTarget ? String(standards.testing.coverageTarget) : targets && "coverage" in targets ? String(targets.coverage) : "90";
6149
- content = content.replace(/\{\{COVERAGE_TARGET\}\}/g, coverageTarget);
6150
- content = processStandardsPlaceholders(content, standards, preferences);
6119
+ const lines = [];
6120
+ lines.push("# CLAUDE.md");
6121
+ lines.push("");
6122
+ lines.push("## Project Overview");
6123
+ lines.push("");
6124
+ lines.push(`**${projectInfo.name}** - ${projectInfo.description}`);
6125
+ lines.push("");
6126
+ lines.push("## Repository");
6127
+ lines.push("");
6128
+ lines.push(`- **Organization:** ${projectInfo.org}`);
6129
+ lines.push(`- **Repository:** ${projectInfo.repo}`);
6130
+ lines.push(`- **GitHub:** https://github.com/${projectInfo.org}/${projectInfo.repo}`);
6151
6131
  if (projectInfo.domain) {
6152
- content = content.replace(/\{\{#if DOMAIN\}\}/g, "").replace(/\{\{\/if\}\}/g, "").replace(/\{\{DOMAIN\}\}/g, projectInfo.domain);
6153
- } else {
6154
- content = content.replace(/\{\{#if DOMAIN\}\}[\s\S]*?\{\{\/if\}\}/g, "");
6132
+ lines.push(`- **Domain:** ${projectInfo.domain}`);
6155
6133
  }
6156
- if (techStack && Object.keys(techStack).length > 0) {
6157
- const techStackContent = generateTechStackSection(techStack);
6158
- content = content.replace(/\{\{#if TECH_STACK\}\}/g, "").replace(/\{\{TECH_STACK\}\}\n\{\{else\}\}[\s\S]*?\{\{\/if\}\}/g, techStackContent);
6159
- } else {
6160
- content = content.replace(/\{\{#if TECH_STACK\}\}[\s\S]*?\{\{else\}\}/g, "").replace(/\{\{\/if\}\}/g, "");
6134
+ lines.push("");
6135
+ lines.push("## Tech Stack");
6136
+ lines.push("");
6137
+ lines.push(generateTechStackSection(techStack));
6138
+ lines.push("## Project Structure");
6139
+ lines.push("");
6140
+ lines.push("```text");
6141
+ lines.push(`${projectInfo.name}/`);
6142
+ lines.push("\u251C\u2500\u2500 src/ # Source code");
6143
+ lines.push("\u251C\u2500\u2500 tests/ # Test files");
6144
+ lines.push("\u251C\u2500\u2500 docs/ # Documentation");
6145
+ lines.push("\u2514\u2500\u2500 .claude/ # Claude configuration");
6146
+ lines.push(" \u251C\u2500\u2500 agents/ # AI agent definitions");
6147
+ lines.push(" \u251C\u2500\u2500 commands/ # Custom slash commands");
6148
+ lines.push(" \u251C\u2500\u2500 skills/ # Specialized skills");
6149
+ lines.push(" \u2514\u2500\u2500 docs/ # AI-specific documentation");
6150
+ lines.push("```");
6151
+ lines.push("");
6152
+ lines.push("## Quick Commands");
6153
+ lines.push("");
6154
+ lines.push(generateCommandsSection(commands, packageManager));
6155
+ lines.push("## Development Guidelines");
6156
+ lines.push("");
6157
+ lines.push("### Code Standards");
6158
+ lines.push("");
6159
+ lines.push("- Primary language: TypeScript");
6160
+ lines.push("- Follow TypeScript best practices");
6161
+ if (standards?.code?.namedExportsOnly) {
6162
+ lines.push("- Use named exports only (no default exports)");
6161
6163
  }
6162
- if (commands && Object.keys(commands).length > 0) {
6163
- const commandsContent = generateCommandsSection(commands, packageManager);
6164
- content = content.replace(/\{\{#if COMMANDS\}\}/g, "").replace(/\{\{COMMANDS\}\}\n\{\{else\}\}[\s\S]*?\{\{\/if\}\}/g, commandsContent);
6164
+ const maxLines = standards?.code?.maxFileLines || 500;
6165
+ lines.push(`- Maximum ${maxLines} lines per file`);
6166
+ if (standards?.code?.jsDocRequired) {
6167
+ lines.push("- Document all exports with JSDoc");
6168
+ }
6169
+ if (standards?.code?.roroPattern) {
6170
+ lines.push("- Use RO-RO pattern (Receive Object, Return Object)");
6171
+ }
6172
+ lines.push("");
6173
+ lines.push("### Testing");
6174
+ lines.push("");
6175
+ if (standards?.testing?.tddRequired) {
6176
+ lines.push("- Methodology: TDD (Test-Driven Development)");
6177
+ lines.push("- Write tests first: Red -> Green -> Refactor");
6165
6178
  } else {
6166
- content = content.replace(/\{\{#if COMMANDS\}\}[\s\S]*?\{\{else\}\}/g, "").replace(/\{\{\/if\}\}/g, "");
6179
+ lines.push("- Write comprehensive tests for all features");
6180
+ }
6181
+ const coverageTarget = standards?.testing?.coverageTarget || (targets && "coverage" in targets ? targets.coverage : 90);
6182
+ lines.push(`- Maintain ${coverageTarget}%+ code coverage`);
6183
+ const testPattern = standards?.testing?.testPattern === "gwt" ? "GWT (Given-When-Then)" : "AAA (Arrange, Act, Assert)";
6184
+ lines.push(`- Test pattern: ${testPattern}`);
6185
+ if (standards?.testing?.testLocation) {
6186
+ const testLocationText = standards.testing.testLocation === "colocated" ? "Co-located with source" : "Separate test directory";
6187
+ lines.push(`- Test location: ${testLocationText}`);
6188
+ }
6189
+ lines.push("");
6190
+ lines.push("### Git Workflow");
6191
+ lines.push("");
6192
+ lines.push("- Use conventional commits: `type(scope): description`");
6193
+ lines.push("- Types: feat, fix, docs, style, refactor, test, chore");
6194
+ lines.push("- Keep commits atomic and focused");
6195
+ if (preferences?.includeCoAuthor) {
6196
+ lines.push("");
6197
+ lines.push("#### Commit Attribution");
6198
+ lines.push("");
6199
+ lines.push("Include the following in commit messages:");
6200
+ lines.push("```");
6201
+ lines.push("\u{1F916} Generated with [Claude Code](https://claude.com/claude-code)");
6202
+ lines.push("");
6203
+ lines.push("Co-Authored-By: Claude <noreply@anthropic.com>");
6204
+ lines.push("```");
6205
+ }
6206
+ lines.push("");
6207
+ lines.push("## Claude Behavior Guidelines");
6208
+ lines.push("");
6209
+ lines.push("### Critical Thinking");
6210
+ lines.push("");
6211
+ lines.push("- You are an expert who double-checks things, you are skeptical and do research");
6212
+ lines.push("- Neither the user nor you are always right, but both strive for accuracy");
6213
+ lines.push("- When the user asks something, reason with these questions:");
6214
+ lines.push(' - "Why might the user be wrong?"');
6215
+ lines.push(' - "What arguments exist against what the user thinks?"');
6216
+ lines.push(` - "Act as devil's advocate - why might this proposal fail?"`);
6217
+ lines.push(` - "Imagine you're in a debate - how would you refute this?"`);
6218
+ lines.push(
6219
+ "- Always ask to better understand the context of the requested change before implementing"
6220
+ );
6221
+ lines.push("");
6222
+ lines.push("### Communication Style");
6223
+ lines.push("");
6224
+ if (preferences?.responseLanguage) {
6225
+ const langDisplay = preferences.responseLanguage === "es" ? "Spanish" : preferences.responseLanguage === "en" ? "English" : preferences.responseLanguage;
6226
+ lines.push(`- Respond in ${langDisplay}`);
6167
6227
  }
6168
- content = content.replace(/\{\{#if PROJECT_STRUCTURE\}\}[\s\S]*?\{\{else\}\}/g, "").replace(/\{\{\/if\}\}/g, "");
6169
- return content;
6228
+ lines.push("- Code and comments should always be in English");
6229
+ lines.push("- Be direct and concise");
6230
+ lines.push('- Explain the "why" behind decisions when relevant');
6231
+ lines.push("");
6232
+ lines.push("### Writing Style");
6233
+ lines.push("");
6234
+ lines.push(
6235
+ '- Systematically replace em-dashes ("\u2014") with a period (".") to start a new sentence, or a comma (",") to continue the sentence'
6236
+ );
6237
+ lines.push("- Avoid unnecessary filler words");
6238
+ lines.push("- Use clear, technical language");
6239
+ lines.push("");
6240
+ lines.push("## Claude Configuration");
6241
+ lines.push("");
6242
+ lines.push("This project uses `@qazuor/claude-code-config` for AI-assisted development.");
6243
+ lines.push("");
6244
+ lines.push("### Available Commands");
6245
+ lines.push("");
6246
+ lines.push("Run `/help` in Claude to see all available commands.");
6247
+ lines.push("");
6248
+ lines.push("### Documentation");
6249
+ lines.push("");
6250
+ lines.push("- Quick Start: `.claude/docs/quick-start.md`");
6251
+ lines.push("- Workflows: `.claude/docs/workflows/README.md`");
6252
+ lines.push("- Standards: `.claude/docs/standards/`");
6253
+ lines.push("");
6254
+ lines.push("---");
6255
+ lines.push("");
6256
+ lines.push(
6257
+ "*Generated by [@qazuor/claude-code-config](https://github.com/qazuor/claude-code-config)*"
6258
+ );
6259
+ lines.push("");
6260
+ return lines.join("\n");
6170
6261
  }
6171
6262
  function generateTechStackSection(techStack) {
6263
+ if (!techStack) {
6264
+ return getDefaultTechStack();
6265
+ }
6172
6266
  const lines = [];
6267
+ let hasContent = false;
6173
6268
  if (techStack.frontendFramework && techStack.frontendFramework !== "None") {
6174
6269
  lines.push("**Frontend:**");
6175
6270
  lines.push(`- Framework: ${techStack.frontendFramework}`);
@@ -6177,6 +6272,7 @@ function generateTechStackSection(techStack) {
6177
6272
  lines.push(`- State: ${techStack.stateManagement}`);
6178
6273
  }
6179
6274
  lines.push("");
6275
+ hasContent = true;
6180
6276
  }
6181
6277
  if (techStack.apiFramework && techStack.apiFramework !== "None") {
6182
6278
  lines.push("**Backend:**");
@@ -6185,145 +6281,89 @@ function generateTechStackSection(techStack) {
6185
6281
  lines.push(`- Validation: ${techStack.validationLibrary}`);
6186
6282
  }
6187
6283
  lines.push("");
6284
+ hasContent = true;
6188
6285
  }
6189
6286
  if (techStack.databaseOrm && techStack.databaseOrm !== "None") {
6190
6287
  lines.push("**Database:**");
6191
6288
  lines.push(`- ORM: ${techStack.databaseOrm}`);
6192
6289
  lines.push("");
6290
+ hasContent = true;
6193
6291
  }
6194
6292
  if (techStack.authPattern && techStack.authPattern !== "None") {
6195
6293
  lines.push("**Authentication:**");
6196
6294
  lines.push(`- Provider: ${techStack.authPattern}`);
6197
6295
  lines.push("");
6296
+ hasContent = true;
6198
6297
  }
6199
6298
  if (techStack.testFramework && techStack.testFramework !== "None") {
6200
6299
  lines.push("**Testing:**");
6201
6300
  lines.push(`- Framework: ${techStack.testFramework}`);
6202
6301
  lines.push("");
6302
+ hasContent = true;
6203
6303
  }
6204
6304
  if (techStack.bundler && techStack.bundler !== "None") {
6205
6305
  lines.push("**Build:**");
6206
6306
  lines.push(`- Bundler: ${techStack.bundler}`);
6207
6307
  lines.push("");
6308
+ hasContent = true;
6309
+ }
6310
+ if (!hasContent) {
6311
+ return getDefaultTechStack();
6208
6312
  }
6209
6313
  return lines.join("\n");
6210
6314
  }
6211
- function generateCommandsSection(commands, packageManager) {
6315
+ function getDefaultTechStack() {
6316
+ return `**Frontend:**
6317
+ - Framework: Not configured
6318
+
6319
+ **Backend:**
6320
+ - API: Not configured
6321
+
6322
+ **Database:**
6323
+ - ORM: Not configured
6324
+
6325
+ **Testing:**
6326
+ - Framework: Not configured
6327
+
6328
+ `;
6329
+ }
6330
+ function generateCommandsSection(commands, packageManager = "pnpm") {
6212
6331
  const lines = ["```bash"];
6213
6332
  lines.push("# Development");
6214
6333
  lines.push(`${packageManager} dev # Start development server`);
6215
6334
  lines.push("");
6216
6335
  lines.push("# Testing");
6217
- if (commands.test) {
6336
+ if (commands?.test) {
6218
6337
  lines.push(`${commands.test} # Run tests`);
6219
6338
  } else {
6220
6339
  lines.push(`${packageManager} test # Run tests`);
6221
6340
  }
6222
- if (commands.coverage) {
6341
+ if (commands?.coverage) {
6223
6342
  lines.push(`${commands.coverage} # Run tests with coverage`);
6224
6343
  } else {
6225
6344
  lines.push(`${packageManager} test:coverage # Run tests with coverage`);
6226
6345
  }
6227
6346
  lines.push("");
6228
6347
  lines.push("# Quality");
6229
- if (commands.lint) {
6348
+ if (commands?.lint) {
6230
6349
  lines.push(`${commands.lint} # Run linter`);
6231
6350
  } else {
6232
6351
  lines.push(`${packageManager} lint # Run linter`);
6233
6352
  }
6234
- if (commands.typecheck) {
6353
+ if (commands?.typecheck) {
6235
6354
  lines.push(`${commands.typecheck} # Type checking`);
6236
6355
  } else {
6237
6356
  lines.push(`${packageManager} typecheck # Type checking`);
6238
6357
  }
6239
- if (commands.build) {
6358
+ if (commands?.build) {
6240
6359
  lines.push("");
6241
6360
  lines.push("# Build");
6242
6361
  lines.push(`${commands.build} # Build for production`);
6243
6362
  }
6244
6363
  lines.push("```");
6364
+ lines.push("");
6245
6365
  return lines.join("\n");
6246
6366
  }
6247
- function processStandardsPlaceholders(content, standards, preferences) {
6248
- let result = content;
6249
- const primaryLanguage = "TypeScript";
6250
- result = result.replace(/\{\{PRIMARY_LANGUAGE\}\}/g, primaryLanguage);
6251
- const maxFileLines = standards?.code?.maxFileLines?.toString() || "500";
6252
- result = result.replace(/\{\{MAX_FILE_LINES\}\}/g, maxFileLines);
6253
- const testPattern = standards?.testing?.testPattern === "gwt" ? "GWT (Given-When-Then)" : "AAA (Arrange, Act, Assert)";
6254
- result = result.replace(/\{\{TEST_PATTERN\}\}/g, testPattern);
6255
- const responseLanguage = preferences?.responseLanguage === "es" ? "Spanish" : preferences?.responseLanguage === "en" ? "English" : "Spanish";
6256
- result = result.replace(/\{\{RESPONSE_LANGUAGE\}\}/g, responseLanguage);
6257
- if (standards?.code?.namedExportsOnly) {
6258
- result = result.replace(/\{\{#if NAMED_EXPORTS_ONLY\}\}/g, "").replace(/\{\{\/if\}\}/g, "");
6259
- } else {
6260
- result = result.replace(/\{\{#if NAMED_EXPORTS_ONLY\}\}[\s\S]*?\{\{\/if\}\}/g, "");
6261
- }
6262
- if (standards?.code?.jsDocRequired) {
6263
- result = result.replace(/\{\{#if JSDOC_REQUIRED\}\}/g, "").replace(/\{\{\/if\}\}/g, "");
6264
- } else {
6265
- result = result.replace(/\{\{#if JSDOC_REQUIRED\}\}[\s\S]*?\{\{\/if\}\}/g, "");
6266
- }
6267
- if (standards?.code?.roroPattern) {
6268
- result = result.replace(/\{\{#if RORO_PATTERN\}\}/g, "").replace(/\{\{\/if\}\}/g, "");
6269
- } else {
6270
- result = result.replace(/\{\{#if RORO_PATTERN\}\}[\s\S]*?\{\{\/if\}\}/g, "");
6271
- }
6272
- if (standards?.testing?.tddRequired) {
6273
- result = result.replace(/\{\{#if TDD_REQUIRED\}\}/g, "").replace(/\{\{else\}\}[\s\S]*?\{\{\/if\}\}/g, "");
6274
- } else {
6275
- result = result.replace(/\{\{#if TDD_REQUIRED\}\}[\s\S]*?\{\{else\}\}/g, "").replace(/\{\{\/if\}\}/g, "");
6276
- }
6277
- const testLocation = standards?.testing?.testLocation;
6278
- if (testLocation) {
6279
- const testLocationText = testLocation === "colocated" ? "Co-located with source" : "Separate test directory";
6280
- result = result.replace(/\{\{#if TEST_LOCATION\}\}/g, "").replace(/\{\{\/if\}\}/g, "").replace(/\{\{TEST_LOCATION\}\}/g, testLocationText);
6281
- } else {
6282
- result = result.replace(/\{\{#if TEST_LOCATION\}\}[\s\S]*?\{\{\/if\}\}/g, "");
6283
- }
6284
- if (preferences?.includeCoAuthor) {
6285
- result = result.replace(/\{\{#if INCLUDE_CO_AUTHOR\}\}/g, "").replace(/\{\{\/if\}\}/g, "");
6286
- } else {
6287
- result = result.replace(/\{\{#if INCLUDE_CO_AUTHOR\}\}[\s\S]*?\{\{\/if\}\}/g, "");
6288
- }
6289
- if (preferences?.responseLanguage) {
6290
- result = result.replace(/\{\{#if RESPONSE_LANGUAGE\}\}/g, "").replace(/\{\{\/if\}\}/g, "");
6291
- } else {
6292
- result = result.replace(/\{\{#if RESPONSE_LANGUAGE\}\}[\s\S]*?\{\{\/if\}\}/g, "");
6293
- }
6294
- return result;
6295
- }
6296
- function getMinimalTemplate() {
6297
- return `# CLAUDE.md
6298
-
6299
- ## Project Overview
6300
-
6301
- **{{PROJECT_NAME}}** - {{PROJECT_DESCRIPTION}}
6302
-
6303
- ## Repository
6304
-
6305
- - **GitHub:** https://github.com/{{ORG}}/{{REPO}}
6306
-
6307
- ## Quick Commands
6308
-
6309
- \`\`\`bash
6310
- {{PACKAGE_MANAGER}} dev # Start development
6311
- {{PACKAGE_MANAGER}} test # Run tests
6312
- {{PACKAGE_MANAGER}} lint # Run linter
6313
- {{PACKAGE_MANAGER}} build # Build project
6314
- \`\`\`
6315
-
6316
- ## Claude Configuration
6317
-
6318
- This project uses \`@qazuor/claude-code-config\` for AI-assisted development.
6319
-
6320
- See \`.claude/docs/quick-start.md\` for getting started.
6321
-
6322
- ---
6323
-
6324
- *Generated by [@qazuor/claude-code-config](https://github.com/qazuor/claude-code-config)*
6325
- `;
6326
- }
6327
6367
 
6328
6368
  // src/lib/scaffold/index.ts
6329
6369
  init_cjs_shims();
@@ -7076,8 +7116,8 @@ function buildSettingsLocalJson(options) {
7076
7116
 
7077
7117
  // src/lib/templates/config-replacer.ts
7078
7118
  init_cjs_shims();
7079
- var fs4 = __toESM(require("fs/promises"), 1);
7080
- var path5 = __toESM(require("path"), 1);
7119
+ var fs3 = __toESM(require("fs/promises"), 1);
7120
+ var path4 = __toESM(require("path"), 1);
7081
7121
  var import_ora2 = __toESM(require("ora"), 1);
7082
7122
 
7083
7123
  // src/constants/template-placeholders.ts
@@ -7985,7 +8025,7 @@ function flattenTemplateConfig(config) {
7985
8025
  return flattened;
7986
8026
  }
7987
8027
  function shouldProcessFile(filePath) {
7988
- const ext = path5.extname(filePath).toLowerCase();
8028
+ const ext = path4.extname(filePath).toLowerCase();
7989
8029
  return PROCESSABLE_EXTENSIONS.includes(ext);
7990
8030
  }
7991
8031
  function shouldSkipDirectory(dirName) {
@@ -7994,9 +8034,9 @@ function shouldSkipDirectory(dirName) {
7994
8034
  async function getAllFiles(dir) {
7995
8035
  const files = [];
7996
8036
  try {
7997
- const entries = await fs4.readdir(dir, { withFileTypes: true });
8037
+ const entries = await fs3.readdir(dir, { withFileTypes: true });
7998
8038
  for (const entry of entries) {
7999
- const fullPath = path5.join(dir, entry.name);
8039
+ const fullPath = path4.join(dir, entry.name);
8000
8040
  if (entry.isDirectory()) {
8001
8041
  if (!shouldSkipDirectory(entry.name)) {
8002
8042
  const subFiles = await getAllFiles(fullPath);
@@ -8013,7 +8053,7 @@ async function getAllFiles(dir) {
8013
8053
  async function replaceInFile2(filePath, replacements) {
8014
8054
  const changes = [];
8015
8055
  try {
8016
- let content = await fs4.readFile(filePath, "utf-8");
8056
+ let content = await fs3.readFile(filePath, "utf-8");
8017
8057
  let modified = false;
8018
8058
  for (const [placeholder, value] of Object.entries(replacements)) {
8019
8059
  if (content.includes(placeholder)) {
@@ -8023,7 +8063,7 @@ async function replaceInFile2(filePath, replacements) {
8023
8063
  }
8024
8064
  }
8025
8065
  if (modified) {
8026
- await fs4.writeFile(filePath, content, "utf-8");
8066
+ await fs3.writeFile(filePath, content, "utf-8");
8027
8067
  }
8028
8068
  } catch {
8029
8069
  }
@@ -8044,7 +8084,7 @@ async function replaceTemplatePlaceholders(dir, config) {
8044
8084
  report.filesModified++;
8045
8085
  for (const change of changes) {
8046
8086
  report.replacements.push({
8047
- file: path5.relative(dir, file),
8087
+ file: path4.relative(dir, file),
8048
8088
  placeholder: change.placeholder,
8049
8089
  value: change.value
8050
8090
  });
@@ -8115,11 +8155,11 @@ async function previewReplacements(dir, config) {
8115
8155
  const preview = [];
8116
8156
  for (const file of files) {
8117
8157
  try {
8118
- const content = await fs4.readFile(file, "utf-8");
8158
+ const content = await fs3.readFile(file, "utf-8");
8119
8159
  for (const [placeholder, value] of Object.entries(replacements)) {
8120
8160
  if (content.includes(placeholder)) {
8121
8161
  preview.push({
8122
- file: path5.relative(dir, file),
8162
+ file: path4.relative(dir, file),
8123
8163
  placeholder,
8124
8164
  value
8125
8165
  });
@@ -8134,6 +8174,27 @@ async function previewReplacements(dir, config) {
8134
8174
  // src/cli/commands/init.ts
8135
8175
  init_fs();
8136
8176
 
8177
+ // src/lib/utils/paths.ts
8178
+ init_cjs_shims();
8179
+ var import_node_fs = __toESM(require("fs"), 1);
8180
+ var import_node_path3 = __toESM(require("path"), 1);
8181
+ var import_node_url = require("url");
8182
+ function getPackageRoot() {
8183
+ const currentFilePath = (0, import_node_url.fileURLToPath)(importMetaUrl);
8184
+ let currentDir = import_node_path3.default.dirname(currentFilePath);
8185
+ while (currentDir !== import_node_path3.default.dirname(currentDir)) {
8186
+ const packageJsonPath = import_node_path3.default.join(currentDir, "package.json");
8187
+ if (import_node_fs.default.existsSync(packageJsonPath)) {
8188
+ return currentDir;
8189
+ }
8190
+ currentDir = import_node_path3.default.dirname(currentDir);
8191
+ }
8192
+ throw new Error("Could not find package root (no package.json found in parent directories)");
8193
+ }
8194
+ function getTemplatesPath() {
8195
+ return import_node_path3.default.join(getPackageRoot(), "templates");
8196
+ }
8197
+
8137
8198
  // src/lib/utils/prompt-cancel.ts
8138
8199
  init_cjs_shims();
8139
8200
  var readline = __toESM(require("readline"), 1);
@@ -10664,6 +10725,61 @@ async function promptMcpConfig(options) {
10664
10725
  const installedServers = await getInstalledMcpServers(projectPath);
10665
10726
  const userInstalledSet = new Set(installedServers.user);
10666
10727
  const projectInstalledSet = new Set(installedServers.project);
10728
+ const availableServers = MCP_SERVERS.filter(
10729
+ (s) => !userInstalledSet.has(s.id) && !projectInstalledSet.has(s.id)
10730
+ );
10731
+ if (availableServers.length === 0) {
10732
+ logger.newline();
10733
+ logger.success("All MCP servers are already installed!");
10734
+ const parts = [];
10735
+ if (userInstalledSet.size > 0) {
10736
+ parts.push(`${userInstalledSet.size} at user level`);
10737
+ }
10738
+ if (projectInstalledSet.size > 0) {
10739
+ parts.push(`${projectInstalledSet.size} at project level`);
10740
+ }
10741
+ logger.info(colors.muted(` (${parts.join(", ")})`));
10742
+ logger.newline();
10743
+ const wantCustom2 = await confirm({
10744
+ message: "Do you want to add a custom MCP server?",
10745
+ default: false
10746
+ });
10747
+ if (wantCustom2) {
10748
+ const level2 = await select({
10749
+ message: "Where should the custom server be configured?",
10750
+ choices: [
10751
+ {
10752
+ name: "Project level (.claude/settings.local.json)",
10753
+ value: "project",
10754
+ description: "Specific to this project"
10755
+ },
10756
+ {
10757
+ name: "User level (~/.claude/settings.json)",
10758
+ value: "user",
10759
+ description: "Available in all projects"
10760
+ }
10761
+ ],
10762
+ default: options?.defaults?.level || "project"
10763
+ });
10764
+ const customInstallation = await promptCustomServer(level2);
10765
+ if (customInstallation) {
10766
+ return {
10767
+ config: {
10768
+ level: level2,
10769
+ servers: [customInstallation]
10770
+ },
10771
+ skippedConfigs: []
10772
+ };
10773
+ }
10774
+ }
10775
+ return {
10776
+ config: {
10777
+ level: "project",
10778
+ servers: []
10779
+ },
10780
+ skippedConfigs: []
10781
+ };
10782
+ }
10667
10783
  const level = await select({
10668
10784
  message: "Where should MCP servers be configured?",
10669
10785
  choices: [
@@ -10697,31 +10813,17 @@ async function promptMcpConfig(options) {
10697
10813
  }
10698
10814
  logger.newline();
10699
10815
  for (const [category, servers] of Object.entries(serversByCategory)) {
10700
- const choices = servers.map((s) => {
10701
- const isInstalledAtUserLevel = userInstalledSet.has(s.id);
10702
- const isInstalledAtProjectLevel = projectInstalledSet.has(s.id);
10703
- if (isInstalledAtUserLevel) {
10704
- return {
10705
- name: `${s.name} - ${s.description} ${colors.muted("(already installed at user level)")}`,
10706
- value: s.id,
10707
- checked: false,
10708
- disabled: "already installed at user level"
10709
- };
10710
- }
10711
- if (isInstalledAtProjectLevel) {
10712
- return {
10713
- name: `${s.name} - ${s.description} ${colors.muted("(already installed at project level)")}`,
10714
- value: s.id,
10715
- checked: false,
10716
- disabled: "already installed at project level"
10717
- };
10718
- }
10719
- return {
10720
- name: `${s.name} - ${s.description}`,
10721
- value: s.id,
10722
- checked: options?.defaults?.servers?.some((i) => i.serverId === s.id) ?? false
10723
- };
10724
- });
10816
+ const availableInCategory = servers.filter(
10817
+ (s) => !userInstalledSet.has(s.id) && !projectInstalledSet.has(s.id)
10818
+ );
10819
+ if (availableInCategory.length === 0) {
10820
+ continue;
10821
+ }
10822
+ const choices = availableInCategory.map((s) => ({
10823
+ name: `${s.name} - ${s.description}`,
10824
+ value: s.id,
10825
+ checked: options?.defaults?.servers?.some((i) => i.serverId === s.id) ?? false
10826
+ }));
10725
10827
  const categoryLabel = formatCategory(category);
10726
10828
  const selected = await checkbox({
10727
10829
  message: `${categoryLabel}:`,