clauderc 1.0.1 → 1.0.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/bin/cli.js +3 -201
- package/package.json +1 -1
package/bin/cli.js
CHANGED
|
@@ -497,210 +497,12 @@ function showChangelog() {
|
|
|
497
497
|
// PROJECT COMMAND - Setup .claude/ in current project
|
|
498
498
|
// ============================================================
|
|
499
499
|
|
|
500
|
-
import {
|
|
501
|
-
import { detectStack, generateCommands } from '../src/detector.js';
|
|
502
|
-
|
|
503
|
-
function createPrompt() {
|
|
504
|
-
const rl = createInterface({ input: process.stdin, output: process.stdout });
|
|
505
|
-
return {
|
|
506
|
-
ask: (q) => new Promise(r => rl.question(q, a => r(a.trim()))),
|
|
507
|
-
confirm: async (q) => {
|
|
508
|
-
const a = await new Promise(r => rl.question(`${q} (Y/n): `, r));
|
|
509
|
-
return a.toLowerCase() !== 'n';
|
|
510
|
-
},
|
|
511
|
-
close: () => rl.close(),
|
|
512
|
-
};
|
|
513
|
-
}
|
|
514
|
-
|
|
515
|
-
function generateClaudeMd(config) {
|
|
516
|
-
const { projectName, stack, commands, customRules } = config;
|
|
517
|
-
let content = `# ${projectName}\n\n## Stack\n`;
|
|
518
|
-
|
|
519
|
-
if (stack.stacks.length > 0) content += `- **Language**: ${stack.stacks.map(s => s.name).join(', ')}\n`;
|
|
520
|
-
if (stack.framework) content += `- **Framework**: ${stack.framework.name}\n`;
|
|
521
|
-
if (stack.packageManager) content += `- **Package Manager**: ${stack.packageManager.name}\n`;
|
|
522
|
-
if (stack.monorepo) content += `- **Monorepo**: ${stack.monorepo.name}\n`;
|
|
523
|
-
|
|
524
|
-
content += `\n## Commands\n\n\`\`\`bash\n`;
|
|
525
|
-
if (commands.setup) content += `# Setup\n${commands.setup}\n\n`;
|
|
526
|
-
if (commands.dev) content += `# Development\n${commands.dev}\n\n`;
|
|
527
|
-
if (commands.test) content += `# Test\n${commands.test}\n\n`;
|
|
528
|
-
if (commands.lint) content += `# Lint\n${commands.lint}\n\n`;
|
|
529
|
-
if (commands.build) content += `# Build\n${commands.build}\n\n`;
|
|
530
|
-
if (commands.verify) content += `# Full verification\n${commands.verify}\n`;
|
|
531
|
-
content += `\`\`\`\n\n`;
|
|
532
|
-
|
|
533
|
-
content += `## Workflow\n\n### Plan Mode\nUse Plan Mode (Shift+Tab 2x) for:\n- Refactoring > 3 files\n- New feature implementation\n- Architecture changes\n\n`;
|
|
534
|
-
content += `### Verification\n- ALWAYS run tests before committing\n- NEVER skip tests without explicit approval\n`;
|
|
535
|
-
|
|
536
|
-
if (customRules?.length > 0) {
|
|
537
|
-
content += `\n## Project Rules\n\n${customRules.map(r => `- ${r}`).join('\n')}\n`;
|
|
538
|
-
}
|
|
539
|
-
|
|
540
|
-
content += `\n## Documentation\n@README.md\n`;
|
|
541
|
-
return content;
|
|
542
|
-
}
|
|
543
|
-
|
|
544
|
-
function generateProjectSettings(config) {
|
|
545
|
-
const { stack, commands } = config;
|
|
546
|
-
const pm = stack.packageManager?.name || 'npm';
|
|
547
|
-
const allowedCommands = ['Bash(git:*)', 'Bash(gh:*)'];
|
|
548
|
-
|
|
549
|
-
// Add package manager
|
|
550
|
-
const pmCommands = { bun: 'bun', pnpm: 'pnpm', yarn: 'yarn', npm: 'npm', poetry: 'poetry', cargo: 'cargo' };
|
|
551
|
-
if (pmCommands[pm]) allowedCommands.push(`Bash(${pmCommands[pm]}:*)`);
|
|
552
|
-
|
|
553
|
-
// Add stack-specific
|
|
554
|
-
const stackId = stack.stacks[0]?.id;
|
|
555
|
-
const stackCommands = {
|
|
556
|
-
go: ['go', 'golangci-lint'],
|
|
557
|
-
rust: ['cargo'],
|
|
558
|
-
python: ['pytest', 'ruff', 'mypy', 'python'],
|
|
559
|
-
dotnet: ['dotnet'],
|
|
560
|
-
elixir: ['mix'],
|
|
561
|
-
ruby: ['bundle', 'rails'],
|
|
562
|
-
php: ['composer', 'php'],
|
|
563
|
-
java: ['mvn', 'gradle'],
|
|
564
|
-
};
|
|
565
|
-
(stackCommands[stackId] || []).forEach(cmd => allowedCommands.push(`Bash(${cmd}:*)`));
|
|
566
|
-
|
|
567
|
-
const settings = { permissions: { allow: allowedCommands } };
|
|
568
|
-
|
|
569
|
-
if (commands.format || commands.lint) {
|
|
570
|
-
settings.hooks = {
|
|
571
|
-
PostToolUse: [{
|
|
572
|
-
matcher: 'Edit|Write',
|
|
573
|
-
hooks: [{ type: 'command', command: `${commands.format || commands.lint} || true` }],
|
|
574
|
-
}],
|
|
575
|
-
};
|
|
576
|
-
}
|
|
577
|
-
|
|
578
|
-
return settings;
|
|
579
|
-
}
|
|
580
|
-
|
|
581
|
-
function generateCommandFile(name, commands, stackName) {
|
|
582
|
-
const templates = {
|
|
583
|
-
test: `# Run tests\n\n\`\`\`bash\n${commands.test || '# Configure test command'}\n\`\`\``,
|
|
584
|
-
lint: `# Lint code\n\n\`\`\`bash\n${commands.lint || '# Configure lint command'}\n\`\`\``,
|
|
585
|
-
verify: `# Full verification\n\nRuns lint, test, and build.\n\n\`\`\`bash\n${commands.verify || '# Configure verify command'}\n\`\`\``,
|
|
586
|
-
setup: `# Setup project\n\n\`\`\`bash\n${commands.setup || '# Configure setup command'}\n\`\`\``,
|
|
587
|
-
pr: `# Create Pull Request\n\n1. Run /verify\n2. Commit changes\n3. Push to remote\n4. Create PR with \`gh pr create\``,
|
|
588
|
-
};
|
|
589
|
-
return templates[name] || '';
|
|
590
|
-
}
|
|
500
|
+
import { runProjectWizard } from '../src/project.js';
|
|
591
501
|
|
|
592
502
|
async function projectSetup(options = {}) {
|
|
593
|
-
const { dryRun = false } = options;
|
|
594
|
-
const projectPath = process.cwd();
|
|
595
|
-
const projectName = basename(projectPath);
|
|
596
|
-
|
|
597
503
|
banner();
|
|
598
|
-
|
|
599
|
-
|
|
600
|
-
console.log(` ${c.dim}Path:${c.reset} ${projectPath}\n`);
|
|
601
|
-
|
|
602
|
-
console.log(` ${c.bold}Analyzing...${c.reset}\n`);
|
|
603
|
-
|
|
604
|
-
const stack = detectStack(projectPath);
|
|
605
|
-
const commands = generateCommands(stack);
|
|
606
|
-
|
|
607
|
-
// Show detection
|
|
608
|
-
console.log(` ${c.bold}Detected Stack${c.reset}\n`);
|
|
609
|
-
if (stack.stacks.length > 0) {
|
|
610
|
-
console.log(` Language: ${c.green}${stack.stacks.map(s => s.name).join(', ')}${c.reset}`);
|
|
611
|
-
} else {
|
|
612
|
-
console.log(` Language: ${c.yellow}Not detected${c.reset}`);
|
|
613
|
-
}
|
|
614
|
-
if (stack.framework) console.log(` Framework: ${c.green}${stack.framework.name}${c.reset}`);
|
|
615
|
-
if (stack.packageManager) console.log(` Package Manager: ${c.green}${stack.packageManager.name}${c.reset}`);
|
|
616
|
-
if (stack.monorepo) console.log(` Monorepo: ${c.green}${stack.monorepo.name}${c.reset}`);
|
|
617
|
-
if (stack.ci) console.log(` CI/CD: ${c.green}${stack.ci.name}${c.reset}`);
|
|
618
|
-
|
|
619
|
-
console.log(`\n ${c.bold}Generated Commands${c.reset}\n`);
|
|
620
|
-
if (commands.setup) console.log(` ${c.dim}setup:${c.reset} ${commands.setup}`);
|
|
621
|
-
if (commands.dev) console.log(` ${c.dim}dev:${c.reset} ${commands.dev}`);
|
|
622
|
-
if (commands.test) console.log(` ${c.dim}test:${c.reset} ${commands.test}`);
|
|
623
|
-
if (commands.lint) console.log(` ${c.dim}lint:${c.reset} ${commands.lint}`);
|
|
624
|
-
if (commands.build) console.log(` ${c.dim}build:${c.reset} ${commands.build}`);
|
|
625
|
-
|
|
626
|
-
const prompt = createPrompt();
|
|
627
|
-
|
|
628
|
-
try {
|
|
629
|
-
console.log('');
|
|
630
|
-
const confirmed = await prompt.confirm(' Proceed with this configuration?');
|
|
631
|
-
|
|
632
|
-
if (!confirmed) {
|
|
633
|
-
console.log(`\n ${c.yellow}Setup cancelled.${c.reset}\n`);
|
|
634
|
-
prompt.close();
|
|
635
|
-
return;
|
|
636
|
-
}
|
|
637
|
-
|
|
638
|
-
// Custom rules
|
|
639
|
-
console.log(`\n ${c.dim}Add project-specific rules (empty to skip):${c.reset}\n`);
|
|
640
|
-
const customRules = [];
|
|
641
|
-
let rule = await prompt.ask(' Rule: ');
|
|
642
|
-
while (rule) {
|
|
643
|
-
customRules.push(rule);
|
|
644
|
-
rule = await prompt.ask(' Rule: ');
|
|
645
|
-
}
|
|
646
|
-
|
|
647
|
-
prompt.close();
|
|
648
|
-
|
|
649
|
-
const config = { projectName, stack, commands, customRules };
|
|
650
|
-
const claudeDir = join(projectPath, '.claude');
|
|
651
|
-
|
|
652
|
-
if (dryRun) {
|
|
653
|
-
console.log(`\n ${c.yellow}DRY RUN${c.reset} - Would create:\n`);
|
|
654
|
-
console.log(' CLAUDE.md');
|
|
655
|
-
console.log(' .claude/settings.json');
|
|
656
|
-
console.log(' .claude/commands/test.md');
|
|
657
|
-
console.log(' .claude/commands/lint.md');
|
|
658
|
-
console.log(' .claude/commands/verify.md');
|
|
659
|
-
console.log(' .claude/commands/setup.md');
|
|
660
|
-
console.log(' .claude/commands/pr.md\n');
|
|
661
|
-
return;
|
|
662
|
-
}
|
|
663
|
-
|
|
664
|
-
// Create files
|
|
665
|
-
mkdirSync(join(claudeDir, 'commands'), { recursive: true });
|
|
666
|
-
|
|
667
|
-
const stackName = stack.stacks[0]?.name || 'Project';
|
|
668
|
-
const files = [
|
|
669
|
-
{ path: 'CLAUDE.md', content: generateClaudeMd(config) },
|
|
670
|
-
{ path: '.claude/settings.json', content: JSON.stringify(generateProjectSettings(config), null, 2) },
|
|
671
|
-
{ path: '.claude/commands/test.md', content: generateCommandFile('test', commands, stackName) },
|
|
672
|
-
{ path: '.claude/commands/lint.md', content: generateCommandFile('lint', commands, stackName) },
|
|
673
|
-
{ path: '.claude/commands/verify.md', content: generateCommandFile('verify', commands, stackName) },
|
|
674
|
-
{ path: '.claude/commands/setup.md', content: generateCommandFile('setup', commands, stackName) },
|
|
675
|
-
{ path: '.claude/commands/pr.md', content: generateCommandFile('pr', commands, stackName) },
|
|
676
|
-
];
|
|
677
|
-
|
|
678
|
-
console.log(`\n ${c.bold}Creating files${c.reset}\n`);
|
|
679
|
-
for (const file of files) {
|
|
680
|
-
writeFileSync(join(projectPath, file.path), file.content);
|
|
681
|
-
console.log(` ${c.green}+${c.reset} ${file.path}`);
|
|
682
|
-
}
|
|
683
|
-
|
|
684
|
-
console.log(`
|
|
685
|
-
${c.green}${c.bold}╔═══════════════════════════════════════════════════════════╗${c.reset}
|
|
686
|
-
${c.green}${c.bold}║${c.reset} ${c.green}${c.bold}║${c.reset}
|
|
687
|
-
${c.green}${c.bold}║${c.reset} ${c.green}${c.bold}✓ Project Setup Complete!${c.reset} ${c.green}${c.bold}║${c.reset}
|
|
688
|
-
${c.green}${c.bold}║${c.reset} ${c.green}${c.bold}║${c.reset}
|
|
689
|
-
${c.green}${c.bold}╚═══════════════════════════════════════════════════════════╝${c.reset}
|
|
690
|
-
|
|
691
|
-
${c.bold}Next steps:${c.reset}
|
|
692
|
-
|
|
693
|
-
1. Review ${c.cyan}CLAUDE.md${c.reset} and adjust as needed
|
|
694
|
-
2. Commit ${c.cyan}.claude/${c.reset} to your repository
|
|
695
|
-
3. Use ${c.cyan}/test${c.reset}, ${c.cyan}/lint${c.reset}, ${c.cyan}/verify${c.reset} in Claude Code
|
|
696
|
-
|
|
697
|
-
`);
|
|
698
|
-
showFooter();
|
|
699
|
-
|
|
700
|
-
} catch (error) {
|
|
701
|
-
prompt.close();
|
|
702
|
-
throw error;
|
|
703
|
-
}
|
|
504
|
+
await runProjectWizard(options);
|
|
505
|
+
showFooter();
|
|
704
506
|
}
|
|
705
507
|
|
|
706
508
|
function showHelp() {
|