@codebakers/cli 3.4.1 → 3.5.1

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.
@@ -1,19 +1,43 @@
1
1
  import chalk from 'chalk';
2
2
  import ora from 'ora';
3
- import { writeFileSync, mkdirSync, existsSync } from 'fs';
3
+ import { writeFileSync, existsSync, rmSync, readFileSync } from 'fs';
4
4
  import { join } from 'path';
5
- import { getApiKey, getApiUrl } from '../config.js';
5
+ import { getApiKey } from '../config.js';
6
6
  import { getCliVersion } from '../lib/api.js';
7
- import { CODEBAKERS_STATS } from '../lib/stats.js';
8
7
 
9
- interface ContentResponse {
10
- version: string;
11
- router: string;
12
- modules: Record<string, string>;
13
- }
8
+ // v6.0 Bootstrap files - patterns come from server via MCP
9
+ const V6_CLAUDE_MD = `# CodeBakers v6.0
10
+
11
+ **MANDATORY: Before writing ANY code, call the \`discover_patterns\` MCP tool.**
12
+
13
+ Tool: discover_patterns
14
+ Args: { task: "description of what you're building" }
15
+
16
+ The server will return:
17
+ - All coding patterns and rules you must follow
18
+ - Test requirements
19
+ - Validation instructions
20
+
21
+ **You cannot write code without calling this tool first. The server tracks compliance.**
22
+ `;
23
+
24
+ const V6_CURSORRULES = `# CodeBakers v6.0
25
+
26
+ **MANDATORY: Before writing ANY code, call the \`discover_patterns\` MCP tool.**
27
+
28
+ Tool: discover_patterns
29
+ Args: { task: "description of what you're building" }
30
+
31
+ The server will return:
32
+ - All coding patterns and rules you must follow
33
+ - Test requirements
34
+ - Validation instructions
35
+
36
+ **You cannot write code without calling this tool first. The server tracks compliance.**
37
+ `;
14
38
 
15
39
  export async function install(): Promise<void> {
16
- console.log(chalk.blue('\n CodeBakers Install\n'));
40
+ console.log(chalk.blue('\n CodeBakers Install (v6.0)\n'));
17
41
 
18
42
  const apiKey = getApiKey();
19
43
  if (!apiKey) {
@@ -21,81 +45,48 @@ export async function install(): Promise<void> {
21
45
  process.exit(1);
22
46
  }
23
47
 
24
- const spinner = ora('Downloading patterns...').start();
48
+ const spinner = ora('Installing CodeBakers v6.0...').start();
25
49
 
26
50
  try {
27
- const apiUrl = getApiUrl();
28
- const response = await fetch(`${apiUrl}/api/content`, {
29
- method: 'GET',
30
- headers: {
31
- Authorization: `Bearer ${apiKey}`,
32
- },
33
- });
34
-
35
- if (!response.ok) {
36
- const error = await response.json().catch(() => ({}));
37
- throw new Error(error.error || 'Failed to fetch content');
38
- }
39
-
40
- const content: ContentResponse = await response.json();
41
- spinner.text = 'Installing patterns...';
42
-
43
51
  const cwd = process.cwd();
44
-
45
- // Write router file
46
- if (content.router) {
47
- writeFileSync(join(cwd, '.cursorrules'), content.router);
48
- }
49
-
50
- // Create CLAUDE.md symlink/copy for Claude Code
51
- if (content.router) {
52
- writeFileSync(join(cwd, 'CLAUDE.md'), content.router);
52
+ const claudeMdPath = join(cwd, 'CLAUDE.md');
53
+ const cursorRulesPath = join(cwd, '.cursorrules');
54
+ const claudeDir = join(cwd, '.claude');
55
+
56
+ // Check for existing v5 installation and migrate
57
+ if (existsSync(claudeDir)) {
58
+ spinner.text = 'Migrating from v5 to v6...';
59
+ rmSync(claudeDir, { recursive: true, force: true });
53
60
  }
54
61
 
55
- // Write modules
56
- const modulesDir = join(cwd, '.claude');
57
- if (content.modules && Object.keys(content.modules).length > 0) {
58
- if (!existsSync(modulesDir)) {
59
- mkdirSync(modulesDir, { recursive: true });
60
- }
61
-
62
- for (const [name, data] of Object.entries(content.modules)) {
63
- writeFileSync(join(modulesDir, name), data);
64
- }
65
-
66
- // Write version file for tracking
67
- const versionInfo = {
68
- version: content.version,
69
- moduleCount: Object.keys(content.modules).length,
70
- installedAt: new Date().toISOString(),
71
- cliVersion: getCliVersion(),
72
- };
73
- writeFileSync(join(modulesDir, '.version.json'), JSON.stringify(versionInfo, null, 2));
74
- }
62
+ // Write v6 bootstrap files
63
+ writeFileSync(claudeMdPath, V6_CLAUDE_MD);
64
+ writeFileSync(cursorRulesPath, V6_CURSORRULES);
75
65
 
76
- // Add to .gitignore if not present
66
+ // Add .cursorrules to .gitignore if not present
77
67
  const gitignorePath = join(cwd, '.gitignore');
78
68
  if (existsSync(gitignorePath)) {
79
- const { readFileSync } = await import('fs');
80
69
  const gitignore = readFileSync(gitignorePath, 'utf-8');
81
70
  if (!gitignore.includes('.cursorrules')) {
82
- const additions = '\n# CodeBakers (encoded patterns)\n.cursorrules\n.claude/\n';
71
+ const additions = '\n# CodeBakers\n.cursorrules\n';
83
72
  writeFileSync(gitignorePath, gitignore + additions);
84
73
  }
85
74
  }
86
75
 
87
- const moduleCount = Object.keys(content.modules || {}).length;
88
- spinner.succeed('Patterns installed successfully!');
76
+ spinner.succeed('CodeBakers v6.0 installed!');
89
77
 
90
- console.log(chalk.green(`\n Version: ${content.version}`));
91
- console.log(chalk.green(` Modules: ${moduleCount}`));
92
78
  console.log(chalk.gray('\n Files created:'));
93
- console.log(chalk.gray(' - .cursorrules (for Cursor IDE)'));
94
- console.log(chalk.gray(' - CLAUDE.md (for Claude Code)'));
95
- if (moduleCount > 0) {
96
- console.log(chalk.gray(` - .claude/ (${moduleCount} pattern modules)`));
97
- }
98
- console.log(chalk.blue(`\n Start building! Your AI now knows ${CODEBAKERS_STATS.moduleCount} production modules.\n`));
79
+ console.log(chalk.gray(' - CLAUDE.md (Claude Code gateway)'));
80
+ console.log(chalk.gray(' - .cursorrules (Cursor IDE gateway)'));
81
+
82
+ console.log(chalk.cyan('\n What\'s new in v6.0:'));
83
+ console.log(chalk.gray(' - Patterns are now server-side'));
84
+ console.log(chalk.gray(' - AI calls discover_patterns before coding'));
85
+ console.log(chalk.gray(' - Real-time pattern updates'));
86
+ console.log(chalk.gray(' - Usage tracking & compliance'));
87
+
88
+ console.log(chalk.gray(`\n CLI version: ${getCliVersion()}`));
89
+ console.log(chalk.blue('\n Start building! AI will fetch patterns via MCP.\n'));
99
90
  } catch (error) {
100
91
  spinner.fail('Installation failed');
101
92
  const message = error instanceof Error ? error.message : 'Unknown error';
@@ -69,7 +69,7 @@ Ask yourself silently:
69
69
 
70
70
  ### PHASE 3: EXECUTE
71
71
  - State: \`📋 CodeBakers | [Type] | Modules: [list]\`
72
- - Load required modules from .claude/
72
+ - Call discover_patterns MCP tool first
73
73
  - Follow patterns EXACTLY
74
74
 
75
75
  ### PHASE 4: SELF-REVIEW (before saying "done")
@@ -552,23 +552,41 @@ export async function scaffold(): Promise<void> {
552
552
  });
553
553
 
554
554
  if (response.ok) {
555
- const content: ContentResponse = await response.json();
555
+ // v6.0: Write minimal bootstrap files (patterns come from server)
556
+ const V6_CLAUDE_MD = `# CodeBakers v6.0
556
557
 
557
- // Write CLAUDE.md (main router)
558
- if (content.router) {
559
- writeFileSync(join(cwd, 'CLAUDE.md'), content.router);
560
- }
558
+ **MANDATORY: Before writing ANY code, call the \`discover_patterns\` MCP tool.**
561
559
 
562
- // Write pattern modules to .claude/
563
- if (content.modules && Object.keys(content.modules).length > 0) {
564
- const modulesDir = join(cwd, '.claude');
565
- if (!existsSync(modulesDir)) {
566
- mkdirSync(modulesDir, { recursive: true });
567
- }
568
- for (const [name, data] of Object.entries(content.modules)) {
569
- writeFileSync(join(modulesDir, name), data);
570
- }
571
- }
560
+ \`\`\`
561
+ Tool: discover_patterns
562
+ Args: { task: "description of what you're building" }
563
+ \`\`\`
564
+
565
+ The server will return:
566
+ - All coding patterns and rules you must follow
567
+ - Test requirements
568
+ - Validation instructions
569
+
570
+ **You cannot write code without calling this tool first. The server tracks compliance.**
571
+
572
+ ---
573
+ *CodeBakers v6.0 - Server-Enforced*
574
+ `;
575
+
576
+ const V6_CURSORRULES = `# CodeBakers v6.0
577
+
578
+ MANDATORY: Before writing ANY code, call the discover_patterns MCP tool.
579
+
580
+ Tool: discover_patterns
581
+ Args: { task: "description of what you're building" }
582
+
583
+ The server returns all patterns, rules, and test requirements.
584
+ You cannot write code without calling this tool first.
585
+ `;
586
+
587
+ // Write v6.0 bootstrap files
588
+ writeFileSync(join(cwd, 'CLAUDE.md'), V6_CLAUDE_MD);
589
+ writeFileSync(join(cwd, '.cursorrules'), V6_CURSORRULES);
572
590
 
573
591
  // Write project management files
574
592
  writeFileSync(join(cwd, 'PRD.md'), createPrdTemplate(projectName));
@@ -577,7 +595,6 @@ export async function scaffold(): Promise<void> {
577
595
  writeFileSync(join(cwd, 'DECISIONS.md'), createDecisionsLog(projectName));
578
596
 
579
597
  // Write Cursor IDE files
580
- writeFileSync(join(cwd, '.cursorrules'), CURSORRULES_TEMPLATE);
581
598
  writeFileSync(join(cwd, '.cursorignore'), CURSORIGNORE_TEMPLATE);
582
599
 
583
600
  // Create .vscode settings
@@ -590,16 +607,16 @@ export async function scaffold(): Promise<void> {
590
607
  "cursor.chat.alwaysIncludeRules": true
591
608
  }, null, 2));
592
609
 
593
- // Update .gitignore
610
+ // Update .gitignore (no .claude/ needed in v6)
594
611
  const gitignorePath = join(cwd, '.gitignore');
595
612
  if (existsSync(gitignorePath)) {
596
613
  const gitignore = readFileSync(gitignorePath, 'utf-8');
597
614
  if (!gitignore.includes('.cursorrules')) {
598
- writeFileSync(gitignorePath, gitignore + '\n# CodeBakers\n.cursorrules\n.claude/\n');
615
+ writeFileSync(gitignorePath, gitignore + '\n# CodeBakers\n.cursorrules\n');
599
616
  }
600
617
  }
601
618
 
602
- patternSpinner.succeed(`Patterns installed! (v${content.version})`);
619
+ patternSpinner.succeed('CodeBakers v6.0 installed!');
603
620
  patternsInstalled = true;
604
621
  } else {
605
622
  patternSpinner.warn('Could not download patterns (will need to run codebakers init later)');
@@ -773,9 +790,9 @@ export async function scaffold(): Promise<void> {
773
790
 
774
791
  if (patternsInstalled) {
775
792
  console.log('');
776
- console.log(chalk.gray(' CLAUDE.md ') + chalk.cyan('← AI instructions (reads automatically!)'));
793
+ console.log(chalk.gray(' CLAUDE.md ') + chalk.cyan('← AI gateway (calls MCP for patterns)'));
794
+ console.log(chalk.gray(' .cursorrules ') + chalk.cyan('← Cursor IDE gateway'));
777
795
  console.log(chalk.gray(' PRD.md ') + chalk.cyan('← Your product requirements'));
778
- console.log(chalk.gray(' .claude/ ') + chalk.cyan('← 34 production patterns'));
779
796
  }
780
797
  console.log('');
781
798
 
@@ -1,10 +1,15 @@
1
1
  import chalk from 'chalk';
2
- import { existsSync } from 'fs';
2
+ import { existsSync, readFileSync } from 'fs';
3
3
  import { join } from 'path';
4
4
  import { getApiKey } from '../config.js';
5
+ import { getCliVersion } from '../lib/api.js';
5
6
 
6
7
  export async function status(): Promise<void> {
7
- console.log(chalk.blue('\n CodeBakers Status\n'));
8
+ console.log(chalk.blue('\n CodeBakers Status (v6.0)\n'));
9
+
10
+ // Show version
11
+ const version = getCliVersion();
12
+ console.log(chalk.gray(` CLI Version: ${version}\n`));
8
13
 
9
14
  // Check login status
10
15
  const apiKey = getApiKey();
@@ -13,7 +18,7 @@ export async function status(): Promise<void> {
13
18
  console.log(chalk.gray(` Key: ${apiKey.slice(0, 10)}...`));
14
19
  } else {
15
20
  console.log(chalk.red(' ✗ Not logged in'));
16
- console.log(chalk.gray(' Run `codebakers login` to authenticate'));
21
+ console.log(chalk.gray(' Run `codebakers setup` to authenticate'));
17
22
  }
18
23
 
19
24
  console.log('');
@@ -28,20 +33,45 @@ export async function status(): Promise<void> {
28
33
  const hasClaudeMd = existsSync(claudemd);
29
34
  const hasClaudeDir = existsSync(claudeDir);
30
35
 
31
- if (hasCursorRules || hasClaudeMd || hasClaudeDir) {
32
- console.log(chalk.green(' Patterns installed in this directory'));
33
- if (hasCursorRules) {
34
- console.log(chalk.gray(' - .cursorrules (Cursor IDE)'));
35
- }
36
- if (hasClaudeMd) {
37
- console.log(chalk.gray(' - CLAUDE.md (Claude Code)'));
38
- }
39
- if (hasClaudeDir) {
40
- console.log(chalk.gray(' - .claude/ (Pattern modules)'));
36
+ // Check version of installed files
37
+ let isV6 = false;
38
+ if (hasClaudeMd) {
39
+ const content = readFileSync(claudemd, 'utf-8');
40
+ isV6 = content.includes('discover_patterns') || content.includes('v6.0');
41
+ }
42
+
43
+ if (hasCursorRules || hasClaudeMd) {
44
+ if (isV6) {
45
+ console.log(chalk.green(' CodeBakers v6.0 installed'));
46
+ console.log(chalk.gray(' - CLAUDE.md (Claude Code gateway)'));
47
+ console.log(chalk.gray(' - .cursorrules (Cursor IDE gateway)'));
48
+ console.log(chalk.cyan('\n v6.0 Features:'));
49
+ console.log(chalk.gray(' - Server-side patterns (always up-to-date)'));
50
+ console.log(chalk.gray(' - AI calls discover_patterns before coding'));
51
+ console.log(chalk.gray(' - Usage tracking & compliance'));
52
+ } else {
53
+ console.log(chalk.yellow(' ⚠ CodeBakers v5 installed (legacy)'));
54
+ if (hasCursorRules) {
55
+ console.log(chalk.gray(' - .cursorrules'));
56
+ }
57
+ if (hasClaudeMd) {
58
+ console.log(chalk.gray(' - CLAUDE.md'));
59
+ }
60
+ if (hasClaudeDir) {
61
+ console.log(chalk.gray(' - .claude/ (local modules)'));
62
+ }
63
+ console.log(chalk.yellow('\n Upgrade to v6.0:'));
64
+ console.log(chalk.gray(' Run `codebakers go` to upgrade'));
41
65
  }
42
66
  } else {
43
- console.log(chalk.yellow(' ○ Patterns not installed in this directory'));
44
- console.log(chalk.gray(' Run `codebakers install` to install'));
67
+ console.log(chalk.yellow(' ○ CodeBakers not installed in this directory'));
68
+ console.log(chalk.gray(' Run `codebakers go` to install'));
69
+ }
70
+
71
+ // Warn about legacy folder
72
+ if (hasClaudeDir && isV6) {
73
+ console.log(chalk.yellow('\n ⚠ Legacy .claude/ folder found'));
74
+ console.log(chalk.gray(' This can be removed - v6.0 uses server-side patterns'));
45
75
  }
46
76
 
47
77
  console.log('');