@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 +276 -174
- package/dist/bin.cjs.map +1 -1
- package/dist/bin.js +276 -174
- package/dist/bin.js.map +1 -1
- package/package.json +1 -1
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
|
|
6079
|
+
let content;
|
|
6103
6080
|
if (options?.customTemplate) {
|
|
6104
|
-
|
|
6081
|
+
content = processCustomTemplate(options.customTemplate, projectInfo);
|
|
6105
6082
|
} else {
|
|
6106
|
-
|
|
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
|
|
6139
|
-
|
|
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
|
-
|
|
6148
|
-
|
|
6149
|
-
|
|
6150
|
-
|
|
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
|
-
|
|
6153
|
-
} else {
|
|
6154
|
-
content = content.replace(/\{\{#if DOMAIN\}\}[\s\S]*?\{\{\/if\}\}/g, "");
|
|
6132
|
+
lines.push(`- **Domain:** ${projectInfo.domain}`);
|
|
6155
6133
|
}
|
|
6156
|
-
|
|
6157
|
-
|
|
6158
|
-
|
|
6159
|
-
|
|
6160
|
-
|
|
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
|
-
|
|
6163
|
-
|
|
6164
|
-
|
|
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
|
-
|
|
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
|
-
|
|
6169
|
-
|
|
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
|
|
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
|
|
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
|
|
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
|
|
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
|
|
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
|
|
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
|
|
7080
|
-
var
|
|
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 =
|
|
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
|
|
8037
|
+
const entries = await fs3.readdir(dir, { withFileTypes: true });
|
|
7998
8038
|
for (const entry of entries) {
|
|
7999
|
-
const fullPath =
|
|
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
|
|
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
|
|
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:
|
|
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
|
|
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:
|
|
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
|
|
10701
|
-
|
|
10702
|
-
|
|
10703
|
-
|
|
10704
|
-
|
|
10705
|
-
|
|
10706
|
-
|
|
10707
|
-
|
|
10708
|
-
|
|
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}:`,
|