@codebakers/cli 3.8.4 → 3.8.6
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/commands/init.js +101 -11
- package/package.json +1 -1
- package/src/commands/init.ts +102 -11
package/dist/commands/init.js
CHANGED
|
@@ -684,6 +684,58 @@ function setupCursorIDE(cwd) {
|
|
|
684
684
|
spinner.warn('Could not configure Cursor IDE (continuing anyway)');
|
|
685
685
|
}
|
|
686
686
|
}
|
|
687
|
+
function setupClaudeCode() {
|
|
688
|
+
const spinner = (0, ora_1.default)(' Setting up Claude Code MCP...').start();
|
|
689
|
+
try {
|
|
690
|
+
const homeDir = process.env.USERPROFILE || process.env.HOME || '';
|
|
691
|
+
let configPath;
|
|
692
|
+
const isWindows = process.platform === 'win32';
|
|
693
|
+
// Determine config path based on platform
|
|
694
|
+
if (isWindows) {
|
|
695
|
+
configPath = (0, path_1.join)(homeDir, 'AppData', 'Roaming', 'Claude', 'claude_desktop_config.json');
|
|
696
|
+
}
|
|
697
|
+
else if (process.platform === 'darwin') {
|
|
698
|
+
configPath = (0, path_1.join)(homeDir, 'Library', 'Application Support', 'Claude', 'claude_desktop_config.json');
|
|
699
|
+
}
|
|
700
|
+
else {
|
|
701
|
+
configPath = (0, path_1.join)(homeDir, '.config', 'claude', 'claude_desktop_config.json');
|
|
702
|
+
}
|
|
703
|
+
// Ensure directory exists
|
|
704
|
+
const configDir = (0, path_1.join)(configPath, '..');
|
|
705
|
+
if (!(0, fs_1.existsSync)(configDir)) {
|
|
706
|
+
(0, fs_1.mkdirSync)(configDir, { recursive: true });
|
|
707
|
+
}
|
|
708
|
+
// MCP config for Claude Code
|
|
709
|
+
const mcpConfig = {
|
|
710
|
+
mcpServers: {
|
|
711
|
+
codebakers: isWindows
|
|
712
|
+
? { command: 'cmd', args: ['/c', 'npx', '-y', '@codebakers/cli', 'serve'] }
|
|
713
|
+
: { command: 'npx', args: ['-y', '@codebakers/cli', 'serve'] }
|
|
714
|
+
}
|
|
715
|
+
};
|
|
716
|
+
// Read existing or create new
|
|
717
|
+
if ((0, fs_1.existsSync)(configPath)) {
|
|
718
|
+
try {
|
|
719
|
+
const existing = JSON.parse((0, fs_1.readFileSync)(configPath, 'utf-8'));
|
|
720
|
+
if (!existing.mcpServers) {
|
|
721
|
+
existing.mcpServers = {};
|
|
722
|
+
}
|
|
723
|
+
existing.mcpServers.codebakers = mcpConfig.mcpServers.codebakers;
|
|
724
|
+
(0, fs_1.writeFileSync)(configPath, JSON.stringify(existing, null, 2));
|
|
725
|
+
}
|
|
726
|
+
catch {
|
|
727
|
+
(0, fs_1.writeFileSync)(configPath, JSON.stringify(mcpConfig, null, 2));
|
|
728
|
+
}
|
|
729
|
+
}
|
|
730
|
+
else {
|
|
731
|
+
(0, fs_1.writeFileSync)(configPath, JSON.stringify(mcpConfig, null, 2));
|
|
732
|
+
}
|
|
733
|
+
spinner.succeed('Claude Code MCP configured!');
|
|
734
|
+
}
|
|
735
|
+
catch {
|
|
736
|
+
spinner.warn('Could not configure Claude Code MCP (continuing anyway)');
|
|
737
|
+
}
|
|
738
|
+
}
|
|
687
739
|
function updateGitignore(cwd) {
|
|
688
740
|
const gitignorePath = (0, path_1.join)(cwd, '.gitignore');
|
|
689
741
|
if ((0, fs_1.existsSync)(gitignorePath)) {
|
|
@@ -754,20 +806,22 @@ async function initNewProject(cwd) {
|
|
|
754
806
|
// Create tracking files
|
|
755
807
|
const structure = buildStructureString(cwd);
|
|
756
808
|
createTrackingFiles(cwd, projectName, {}, structure, false);
|
|
757
|
-
// Setup
|
|
809
|
+
// Setup IDEs and MCP
|
|
758
810
|
console.log('');
|
|
759
811
|
setupCursorIDE(cwd);
|
|
812
|
+
setupClaudeCode();
|
|
760
813
|
// Update .gitignore
|
|
761
814
|
updateGitignore(cwd);
|
|
762
815
|
// How to describe project
|
|
763
816
|
console.log(chalk_1.default.white('\n 📝 How would you like to describe your project?\n'));
|
|
764
817
|
console.log(chalk_1.default.gray(' 1. ') + chalk_1.default.cyan('GUIDED QUESTIONS') + chalk_1.default.gray(' - I\'ll ask you step by step'));
|
|
765
|
-
console.log(chalk_1.default.gray(' 2. ') + chalk_1.default.cyan('WRITE A PRD') + chalk_1.default.gray(' - Create a
|
|
766
|
-
console.log(chalk_1.default.gray(' 3. ') + chalk_1.default.cyan('
|
|
767
|
-
console.log(chalk_1.default.gray(' 4. ') + chalk_1.default.cyan('
|
|
818
|
+
console.log(chalk_1.default.gray(' 2. ') + chalk_1.default.cyan('WRITE A PRD') + chalk_1.default.gray(' - Create a blank template to fill out'));
|
|
819
|
+
console.log(chalk_1.default.gray(' 3. ') + chalk_1.default.cyan('PASTE/UPLOAD PRD') + chalk_1.default.gray(' - I already have requirements written'));
|
|
820
|
+
console.log(chalk_1.default.gray(' 4. ') + chalk_1.default.cyan('DESCRIBE IN CHAT') + chalk_1.default.gray(' - Just tell the AI what you want'));
|
|
821
|
+
console.log(chalk_1.default.gray(' 5. ') + chalk_1.default.cyan('SHARE FILES') + chalk_1.default.gray(' - I\'ll share docs/mockups/screenshots\n'));
|
|
768
822
|
let describeChoice = '';
|
|
769
|
-
while (!['1', '2', '3', '4'].includes(describeChoice)) {
|
|
770
|
-
describeChoice = await prompt(' Enter 1
|
|
823
|
+
while (!['1', '2', '3', '4', '5'].includes(describeChoice)) {
|
|
824
|
+
describeChoice = await prompt(' Enter 1-5: ');
|
|
771
825
|
}
|
|
772
826
|
let prdCreated = false;
|
|
773
827
|
if (describeChoice === '1') {
|
|
@@ -788,16 +842,51 @@ async function initNewProject(cwd) {
|
|
|
788
842
|
prdCreated = true;
|
|
789
843
|
}
|
|
790
844
|
else if (describeChoice === '3') {
|
|
845
|
+
// Paste/upload existing PRD
|
|
846
|
+
console.log(chalk_1.default.cyan('\n ━━━ Paste Your Requirements ━━━\n'));
|
|
847
|
+
console.log(chalk_1.default.gray(' Paste your PRD, requirements, or spec below.'));
|
|
848
|
+
console.log(chalk_1.default.gray(' When done, type ') + chalk_1.default.cyan('END') + chalk_1.default.gray(' on a new line and press Enter.\n'));
|
|
849
|
+
const lines = [];
|
|
850
|
+
let line = '';
|
|
851
|
+
while (true) {
|
|
852
|
+
line = await prompt(' ');
|
|
853
|
+
if (line.toUpperCase() === 'END')
|
|
854
|
+
break;
|
|
855
|
+
lines.push(line);
|
|
856
|
+
}
|
|
857
|
+
if (lines.length > 0) {
|
|
858
|
+
const content = lines.join('\n');
|
|
859
|
+
const prdContent = `# Product Requirements Document
|
|
860
|
+
# Project: ${projectName}
|
|
861
|
+
# Created: ${new Date().toISOString().split('T')[0]}
|
|
862
|
+
# Type: ${projectType}
|
|
863
|
+
# Source: Pasted by user
|
|
864
|
+
|
|
865
|
+
${content}
|
|
866
|
+
|
|
867
|
+
---
|
|
868
|
+
<!-- User-provided requirements - AI reads this to build your project -->
|
|
869
|
+
`;
|
|
870
|
+
(0, fs_1.writeFileSync)((0, path_1.join)(cwd, 'PRD.md'), prdContent);
|
|
871
|
+
console.log(chalk_1.default.green('\n ✓ Saved to PRD.md'));
|
|
872
|
+
console.log(chalk_1.default.yellow(' → The AI will read this when you start building\n'));
|
|
873
|
+
prdCreated = true;
|
|
874
|
+
}
|
|
875
|
+
else {
|
|
876
|
+
console.log(chalk_1.default.gray('\n No content pasted. You can add PRD.md manually later.\n'));
|
|
877
|
+
}
|
|
878
|
+
}
|
|
879
|
+
else if (describeChoice === '4') {
|
|
791
880
|
// Describe in chat
|
|
792
881
|
console.log(chalk_1.default.gray('\n Perfect! Just describe your project to the AI when you\'re ready.\n'));
|
|
793
882
|
console.log(chalk_1.default.gray(' Example: "Build me a SaaS for invoice management with Stripe payments"\n'));
|
|
794
883
|
}
|
|
795
884
|
else {
|
|
796
|
-
//
|
|
885
|
+
// Share files (option 5)
|
|
797
886
|
console.log(chalk_1.default.gray('\n Great! When chatting with the AI:\n'));
|
|
798
|
-
console.log(chalk_1.default.gray(' •
|
|
799
|
-
console.log(chalk_1.default.gray(' •
|
|
800
|
-
console.log(chalk_1.default.gray(' • Reference
|
|
887
|
+
console.log(chalk_1.default.gray(' • Drag and drop your mockups or screenshots'));
|
|
888
|
+
console.log(chalk_1.default.gray(' • Share links to Figma, design files, or websites'));
|
|
889
|
+
console.log(chalk_1.default.gray(' • Reference existing apps: "Make it look like Linear"\n'));
|
|
801
890
|
console.log(chalk_1.default.cyan(' The AI will analyze them and start building.\n'));
|
|
802
891
|
}
|
|
803
892
|
// Success
|
|
@@ -866,9 +955,10 @@ async function initExistingProject(cwd, projectInfo) {
|
|
|
866
955
|
// Create tracking files with detected stack
|
|
867
956
|
const structure = buildStructureString(cwd);
|
|
868
957
|
createTrackingFiles(cwd, projectName, projectInfo.stack, structure, true, auditScore);
|
|
869
|
-
// Setup
|
|
958
|
+
// Setup IDEs and MCP
|
|
870
959
|
console.log('');
|
|
871
960
|
setupCursorIDE(cwd);
|
|
961
|
+
setupClaudeCode();
|
|
872
962
|
// Update .gitignore
|
|
873
963
|
updateGitignore(cwd);
|
|
874
964
|
// Success
|
package/package.json
CHANGED
package/src/commands/init.ts
CHANGED
|
@@ -739,6 +739,60 @@ function setupCursorIDE(cwd: string): void {
|
|
|
739
739
|
}
|
|
740
740
|
}
|
|
741
741
|
|
|
742
|
+
function setupClaudeCode(): void {
|
|
743
|
+
const spinner = ora(' Setting up Claude Code MCP...').start();
|
|
744
|
+
|
|
745
|
+
try {
|
|
746
|
+
const homeDir = process.env.USERPROFILE || process.env.HOME || '';
|
|
747
|
+
let configPath: string;
|
|
748
|
+
const isWindows = process.platform === 'win32';
|
|
749
|
+
|
|
750
|
+
// Determine config path based on platform
|
|
751
|
+
if (isWindows) {
|
|
752
|
+
configPath = join(homeDir, 'AppData', 'Roaming', 'Claude', 'claude_desktop_config.json');
|
|
753
|
+
} else if (process.platform === 'darwin') {
|
|
754
|
+
configPath = join(homeDir, 'Library', 'Application Support', 'Claude', 'claude_desktop_config.json');
|
|
755
|
+
} else {
|
|
756
|
+
configPath = join(homeDir, '.config', 'claude', 'claude_desktop_config.json');
|
|
757
|
+
}
|
|
758
|
+
|
|
759
|
+
// Ensure directory exists
|
|
760
|
+
const configDir = join(configPath, '..');
|
|
761
|
+
if (!existsSync(configDir)) {
|
|
762
|
+
mkdirSync(configDir, { recursive: true });
|
|
763
|
+
}
|
|
764
|
+
|
|
765
|
+
// MCP config for Claude Code
|
|
766
|
+
const mcpConfig = {
|
|
767
|
+
mcpServers: {
|
|
768
|
+
codebakers: isWindows
|
|
769
|
+
? { command: 'cmd', args: ['/c', 'npx', '-y', '@codebakers/cli', 'serve'] }
|
|
770
|
+
: { command: 'npx', args: ['-y', '@codebakers/cli', 'serve'] }
|
|
771
|
+
}
|
|
772
|
+
};
|
|
773
|
+
|
|
774
|
+
// Read existing or create new
|
|
775
|
+
if (existsSync(configPath)) {
|
|
776
|
+
try {
|
|
777
|
+
const existing = JSON.parse(readFileSync(configPath, 'utf-8'));
|
|
778
|
+
if (!existing.mcpServers) {
|
|
779
|
+
existing.mcpServers = {};
|
|
780
|
+
}
|
|
781
|
+
existing.mcpServers.codebakers = mcpConfig.mcpServers.codebakers;
|
|
782
|
+
writeFileSync(configPath, JSON.stringify(existing, null, 2));
|
|
783
|
+
} catch {
|
|
784
|
+
writeFileSync(configPath, JSON.stringify(mcpConfig, null, 2));
|
|
785
|
+
}
|
|
786
|
+
} else {
|
|
787
|
+
writeFileSync(configPath, JSON.stringify(mcpConfig, null, 2));
|
|
788
|
+
}
|
|
789
|
+
|
|
790
|
+
spinner.succeed('Claude Code MCP configured!');
|
|
791
|
+
} catch {
|
|
792
|
+
spinner.warn('Could not configure Claude Code MCP (continuing anyway)');
|
|
793
|
+
}
|
|
794
|
+
}
|
|
795
|
+
|
|
742
796
|
function updateGitignore(cwd: string): void {
|
|
743
797
|
const gitignorePath = join(cwd, '.gitignore');
|
|
744
798
|
if (existsSync(gitignorePath)) {
|
|
@@ -827,9 +881,10 @@ async function initNewProject(cwd: string): Promise<void> {
|
|
|
827
881
|
const structure = buildStructureString(cwd);
|
|
828
882
|
createTrackingFiles(cwd, projectName, {}, structure, false);
|
|
829
883
|
|
|
830
|
-
// Setup
|
|
884
|
+
// Setup IDEs and MCP
|
|
831
885
|
console.log('');
|
|
832
886
|
setupCursorIDE(cwd);
|
|
887
|
+
setupClaudeCode();
|
|
833
888
|
|
|
834
889
|
// Update .gitignore
|
|
835
890
|
updateGitignore(cwd);
|
|
@@ -837,13 +892,14 @@ async function initNewProject(cwd: string): Promise<void> {
|
|
|
837
892
|
// How to describe project
|
|
838
893
|
console.log(chalk.white('\n 📝 How would you like to describe your project?\n'));
|
|
839
894
|
console.log(chalk.gray(' 1. ') + chalk.cyan('GUIDED QUESTIONS') + chalk.gray(' - I\'ll ask you step by step'));
|
|
840
|
-
console.log(chalk.gray(' 2. ') + chalk.cyan('WRITE A PRD') + chalk.gray(' - Create a
|
|
841
|
-
console.log(chalk.gray(' 3. ') + chalk.cyan('
|
|
842
|
-
console.log(chalk.gray(' 4. ') + chalk.cyan('
|
|
895
|
+
console.log(chalk.gray(' 2. ') + chalk.cyan('WRITE A PRD') + chalk.gray(' - Create a blank template to fill out'));
|
|
896
|
+
console.log(chalk.gray(' 3. ') + chalk.cyan('PASTE/UPLOAD PRD') + chalk.gray(' - I already have requirements written'));
|
|
897
|
+
console.log(chalk.gray(' 4. ') + chalk.cyan('DESCRIBE IN CHAT') + chalk.gray(' - Just tell the AI what you want'));
|
|
898
|
+
console.log(chalk.gray(' 5. ') + chalk.cyan('SHARE FILES') + chalk.gray(' - I\'ll share docs/mockups/screenshots\n'));
|
|
843
899
|
|
|
844
900
|
let describeChoice = '';
|
|
845
|
-
while (!['1', '2', '3', '4'].includes(describeChoice)) {
|
|
846
|
-
describeChoice = await prompt(' Enter 1
|
|
901
|
+
while (!['1', '2', '3', '4', '5'].includes(describeChoice)) {
|
|
902
|
+
describeChoice = await prompt(' Enter 1-5: ');
|
|
847
903
|
}
|
|
848
904
|
|
|
849
905
|
let prdCreated = false;
|
|
@@ -864,15 +920,49 @@ async function initNewProject(cwd: string): Promise<void> {
|
|
|
864
920
|
console.log(chalk.yellow('\n → Open PRD.md and fill in your requirements\n'));
|
|
865
921
|
prdCreated = true;
|
|
866
922
|
} else if (describeChoice === '3') {
|
|
923
|
+
// Paste/upload existing PRD
|
|
924
|
+
console.log(chalk.cyan('\n ━━━ Paste Your Requirements ━━━\n'));
|
|
925
|
+
console.log(chalk.gray(' Paste your PRD, requirements, or spec below.'));
|
|
926
|
+
console.log(chalk.gray(' When done, type ') + chalk.cyan('END') + chalk.gray(' on a new line and press Enter.\n'));
|
|
927
|
+
|
|
928
|
+
const lines: string[] = [];
|
|
929
|
+
let line = '';
|
|
930
|
+
while (true) {
|
|
931
|
+
line = await prompt(' ');
|
|
932
|
+
if (line.toUpperCase() === 'END') break;
|
|
933
|
+
lines.push(line);
|
|
934
|
+
}
|
|
935
|
+
|
|
936
|
+
if (lines.length > 0) {
|
|
937
|
+
const content = lines.join('\n');
|
|
938
|
+
const prdContent = `# Product Requirements Document
|
|
939
|
+
# Project: ${projectName}
|
|
940
|
+
# Created: ${new Date().toISOString().split('T')[0]}
|
|
941
|
+
# Type: ${projectType}
|
|
942
|
+
# Source: Pasted by user
|
|
943
|
+
|
|
944
|
+
${content}
|
|
945
|
+
|
|
946
|
+
---
|
|
947
|
+
<!-- User-provided requirements - AI reads this to build your project -->
|
|
948
|
+
`;
|
|
949
|
+
writeFileSync(join(cwd, 'PRD.md'), prdContent);
|
|
950
|
+
console.log(chalk.green('\n ✓ Saved to PRD.md'));
|
|
951
|
+
console.log(chalk.yellow(' → The AI will read this when you start building\n'));
|
|
952
|
+
prdCreated = true;
|
|
953
|
+
} else {
|
|
954
|
+
console.log(chalk.gray('\n No content pasted. You can add PRD.md manually later.\n'));
|
|
955
|
+
}
|
|
956
|
+
} else if (describeChoice === '4') {
|
|
867
957
|
// Describe in chat
|
|
868
958
|
console.log(chalk.gray('\n Perfect! Just describe your project to the AI when you\'re ready.\n'));
|
|
869
959
|
console.log(chalk.gray(' Example: "Build me a SaaS for invoice management with Stripe payments"\n'));
|
|
870
960
|
} else {
|
|
871
|
-
//
|
|
961
|
+
// Share files (option 5)
|
|
872
962
|
console.log(chalk.gray('\n Great! When chatting with the AI:\n'));
|
|
873
|
-
console.log(chalk.gray(' •
|
|
874
|
-
console.log(chalk.gray(' •
|
|
875
|
-
console.log(chalk.gray(' • Reference
|
|
963
|
+
console.log(chalk.gray(' • Drag and drop your mockups or screenshots'));
|
|
964
|
+
console.log(chalk.gray(' • Share links to Figma, design files, or websites'));
|
|
965
|
+
console.log(chalk.gray(' • Reference existing apps: "Make it look like Linear"\n'));
|
|
876
966
|
console.log(chalk.cyan(' The AI will analyze them and start building.\n'));
|
|
877
967
|
}
|
|
878
968
|
|
|
@@ -955,9 +1045,10 @@ async function initExistingProject(cwd: string, projectInfo: ReturnType<typeof d
|
|
|
955
1045
|
const structure = buildStructureString(cwd);
|
|
956
1046
|
createTrackingFiles(cwd, projectName, projectInfo.stack, structure, true, auditScore);
|
|
957
1047
|
|
|
958
|
-
// Setup
|
|
1048
|
+
// Setup IDEs and MCP
|
|
959
1049
|
console.log('');
|
|
960
1050
|
setupCursorIDE(cwd);
|
|
1051
|
+
setupClaudeCode();
|
|
961
1052
|
|
|
962
1053
|
// Update .gitignore
|
|
963
1054
|
updateGitignore(cwd);
|