@codebakers/cli 3.5.0 → 3.6.0
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/doctor.d.ts +1 -1
- package/dist/commands/doctor.js +40 -82
- package/dist/commands/init.js +56 -41
- package/dist/commands/install-hook.js +8 -8
- package/dist/commands/install.js +54 -55
- package/dist/commands/scaffold.js +39 -22
- package/dist/commands/status.js +41 -13
- package/dist/mcp/server.js +425 -147
- package/package.json +1 -1
- package/src/commands/doctor.ts +39 -81
- package/src/commands/init.ts +55 -43
- package/src/commands/install-hook.ts +8 -8
- package/src/commands/install.ts +59 -68
- package/src/commands/scaffold.ts +39 -22
- package/src/commands/status.ts +45 -15
- package/src/mcp/server.ts +428 -161
package/package.json
CHANGED
package/src/commands/doctor.ts
CHANGED
|
@@ -1,11 +1,10 @@
|
|
|
1
1
|
import chalk from 'chalk';
|
|
2
|
-
import { existsSync,
|
|
2
|
+
import { existsSync, readFileSync } from 'fs';
|
|
3
3
|
import { join } from 'path';
|
|
4
4
|
import { homedir } from 'os';
|
|
5
5
|
import { isHookInstalled } from './install-hook.js';
|
|
6
6
|
import { getApiKey } from '../config.js';
|
|
7
7
|
import { checkApiKeyValidity, checkForUpdates, getCliVersion } from '../lib/api.js';
|
|
8
|
-
import { CODEBAKERS_STATS } from '../lib/stats.js';
|
|
9
8
|
|
|
10
9
|
interface CheckResult {
|
|
11
10
|
ok: boolean;
|
|
@@ -17,7 +16,7 @@ interface CheckResult {
|
|
|
17
16
|
* Run all health checks for CodeBakers setup
|
|
18
17
|
*/
|
|
19
18
|
export async function doctor(): Promise<void> {
|
|
20
|
-
console.log(chalk.blue('\n CodeBakers Doctor\n'));
|
|
19
|
+
console.log(chalk.blue('\n CodeBakers Doctor (v6.0)\n'));
|
|
21
20
|
|
|
22
21
|
// Show version
|
|
23
22
|
const version = getCliVersion();
|
|
@@ -73,7 +72,7 @@ export async function doctor(): Promise<void> {
|
|
|
73
72
|
|
|
74
73
|
const claudeMdCheck = projectChecks.find(c => c.message.includes('CLAUDE.md'));
|
|
75
74
|
if (claudeMdCheck && !claudeMdCheck.ok) {
|
|
76
|
-
console.log(chalk.gray(' • Run: codebakers
|
|
75
|
+
console.log(chalk.gray(' • Run: codebakers go'));
|
|
77
76
|
}
|
|
78
77
|
|
|
79
78
|
const hookCheck = systemChecks.find(c => c.message.includes('Hook'));
|
|
@@ -98,112 +97,70 @@ export async function doctor(): Promise<void> {
|
|
|
98
97
|
}
|
|
99
98
|
|
|
100
99
|
/**
|
|
101
|
-
* Check project-level setup
|
|
100
|
+
* Check project-level setup (v6.0 bootstrap files)
|
|
102
101
|
*/
|
|
103
102
|
function checkProject(): CheckResult[] {
|
|
104
103
|
const results: CheckResult[] = [];
|
|
105
104
|
const cwd = process.cwd();
|
|
106
105
|
|
|
107
|
-
// Check CLAUDE.md
|
|
106
|
+
// Check CLAUDE.md with v6 content
|
|
108
107
|
const claudeMdPath = join(cwd, 'CLAUDE.md');
|
|
109
108
|
if (existsSync(claudeMdPath)) {
|
|
110
109
|
const content = readFileSync(claudeMdPath, 'utf-8');
|
|
111
|
-
if (content.includes('
|
|
112
|
-
results.push({ ok: true, message: 'CLAUDE.md exists (
|
|
110
|
+
if (content.includes('discover_patterns') || content.includes('v6.0')) {
|
|
111
|
+
results.push({ ok: true, message: 'CLAUDE.md exists (v6.0 gateway)' });
|
|
112
|
+
} else if (content.includes('CodeBakers') || content.includes('.claude')) {
|
|
113
|
+
results.push({
|
|
114
|
+
ok: false,
|
|
115
|
+
message: 'CLAUDE.md exists but is v5 format',
|
|
116
|
+
details: 'Run: codebakers go --upgrade'
|
|
117
|
+
});
|
|
113
118
|
} else {
|
|
114
119
|
results.push({
|
|
115
120
|
ok: false,
|
|
116
|
-
message: 'CLAUDE.md exists but
|
|
117
|
-
details: 'Run: codebakers
|
|
121
|
+
message: 'CLAUDE.md exists but not CodeBakers',
|
|
122
|
+
details: 'Run: codebakers go'
|
|
118
123
|
});
|
|
119
124
|
}
|
|
120
125
|
} else {
|
|
121
126
|
results.push({
|
|
122
127
|
ok: false,
|
|
123
128
|
message: 'CLAUDE.md not found',
|
|
124
|
-
details: 'Run: codebakers
|
|
129
|
+
details: 'Run: codebakers go'
|
|
125
130
|
});
|
|
126
131
|
}
|
|
127
132
|
|
|
128
|
-
// Check .
|
|
129
|
-
const
|
|
130
|
-
if (existsSync(
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
const files = readdirSync(claudeDir).filter(f => f.endsWith('.md'));
|
|
136
|
-
const moduleCount = files.length;
|
|
137
|
-
|
|
138
|
-
if (moduleCount >= 50) {
|
|
139
|
-
results.push({ ok: true, message: `${moduleCount} modules present (full set)` });
|
|
140
|
-
} else if (moduleCount >= 10) {
|
|
141
|
-
results.push({
|
|
142
|
-
ok: true,
|
|
143
|
-
message: `${moduleCount} modules present (partial set)`,
|
|
144
|
-
details: `Run: codebakers upgrade to get all ${CODEBAKERS_STATS.moduleCount} modules`
|
|
145
|
-
});
|
|
146
|
-
} else if (moduleCount > 0) {
|
|
147
|
-
results.push({
|
|
148
|
-
ok: false,
|
|
149
|
-
message: `Only ${moduleCount} modules found (expected ${CODEBAKERS_STATS.moduleCount})`,
|
|
150
|
-
details: 'Run: codebakers upgrade to get all modules'
|
|
151
|
-
});
|
|
152
|
-
} else {
|
|
153
|
-
results.push({
|
|
154
|
-
ok: false,
|
|
155
|
-
message: 'No modules found in .claude/',
|
|
156
|
-
details: 'Run: codebakers install'
|
|
157
|
-
});
|
|
158
|
-
}
|
|
159
|
-
|
|
160
|
-
// Check for 00-core.md
|
|
161
|
-
const corePath = join(claudeDir, '00-core.md');
|
|
162
|
-
if (existsSync(corePath)) {
|
|
163
|
-
results.push({ ok: true, message: '00-core.md exists (base patterns)' });
|
|
164
|
-
} else {
|
|
165
|
-
results.push({
|
|
166
|
-
ok: false,
|
|
167
|
-
message: '00-core.md not found',
|
|
168
|
-
details: 'This module is loaded on every task'
|
|
169
|
-
});
|
|
170
|
-
}
|
|
171
|
-
|
|
172
|
-
// Check for 00-system.md
|
|
173
|
-
const systemPath = join(claudeDir, '00-system.md');
|
|
174
|
-
if (existsSync(systemPath)) {
|
|
175
|
-
results.push({ ok: true, message: '00-system.md exists (workflow module)' });
|
|
176
|
-
} else {
|
|
177
|
-
results.push({
|
|
178
|
-
ok: true, // Not required, just recommended
|
|
179
|
-
message: '00-system.md not found (optional workflow module)',
|
|
180
|
-
details: 'Contains 9-step execution flow'
|
|
181
|
-
});
|
|
182
|
-
}
|
|
183
|
-
} catch {
|
|
133
|
+
// Check .cursorrules with v6 content
|
|
134
|
+
const cursorRulesPath = join(cwd, '.cursorrules');
|
|
135
|
+
if (existsSync(cursorRulesPath)) {
|
|
136
|
+
const content = readFileSync(cursorRulesPath, 'utf-8');
|
|
137
|
+
if (content.includes('discover_patterns') || content.includes('v6.0')) {
|
|
138
|
+
results.push({ ok: true, message: '.cursorrules exists (v6.0 gateway)' });
|
|
139
|
+
} else {
|
|
184
140
|
results.push({
|
|
185
141
|
ok: false,
|
|
186
|
-
message: '
|
|
187
|
-
details: '
|
|
142
|
+
message: '.cursorrules exists but is old format',
|
|
143
|
+
details: 'Run: codebakers go --upgrade'
|
|
188
144
|
});
|
|
189
145
|
}
|
|
190
146
|
} else {
|
|
191
147
|
results.push({
|
|
192
148
|
ok: false,
|
|
193
|
-
message: '.
|
|
194
|
-
details: 'Run: codebakers
|
|
149
|
+
message: '.cursorrules not found',
|
|
150
|
+
details: 'Run: codebakers go'
|
|
195
151
|
});
|
|
196
152
|
}
|
|
197
153
|
|
|
198
|
-
// Check
|
|
199
|
-
const
|
|
200
|
-
if (existsSync(
|
|
201
|
-
results.push({ ok: true, message: 'PROJECT-STATE.md exists' });
|
|
202
|
-
} else {
|
|
154
|
+
// Check for legacy .claude folder (should be removed in v6)
|
|
155
|
+
const claudeDir = join(cwd, '.claude');
|
|
156
|
+
if (existsSync(claudeDir)) {
|
|
203
157
|
results.push({
|
|
204
|
-
ok:
|
|
205
|
-
message: '
|
|
158
|
+
ok: false,
|
|
159
|
+
message: 'Legacy .claude/ folder found',
|
|
160
|
+
details: 'v6.0 uses server-side patterns. Run: codebakers go --upgrade'
|
|
206
161
|
});
|
|
162
|
+
} else {
|
|
163
|
+
results.push({ ok: true, message: 'No legacy .claude/ folder (v6.0 clean)' });
|
|
207
164
|
}
|
|
208
165
|
|
|
209
166
|
return results;
|
|
@@ -289,15 +246,16 @@ async function checkAuth(): Promise<CheckResult[]> {
|
|
|
289
246
|
}
|
|
290
247
|
|
|
291
248
|
/**
|
|
292
|
-
* Quick check - returns true if
|
|
249
|
+
* Quick check - returns true if v6 setup is complete
|
|
293
250
|
*/
|
|
294
251
|
export function isSetupComplete(): boolean {
|
|
295
252
|
const cwd = process.cwd();
|
|
296
253
|
|
|
297
254
|
const hasClaudeMd = existsSync(join(cwd, 'CLAUDE.md'));
|
|
298
|
-
const
|
|
255
|
+
const hasCursorRules = existsSync(join(cwd, '.cursorrules'));
|
|
299
256
|
const hasHook = isHookInstalled();
|
|
300
257
|
const hasApiKey = !!getApiKey();
|
|
301
258
|
|
|
302
|
-
|
|
259
|
+
// v6: No .claude folder required
|
|
260
|
+
return hasClaudeMd && hasCursorRules && hasHook && hasApiKey;
|
|
303
261
|
}
|
package/src/commands/init.ts
CHANGED
|
@@ -33,9 +33,9 @@ If PROJECT-CONTEXT.md is empty or stale (>7 days), SCAN THE PROJECT FIRST:
|
|
|
33
33
|
- Update PROJECT-CONTEXT.md
|
|
34
34
|
|
|
35
35
|
### PHASE 3: EXECUTE
|
|
36
|
-
- State: \`📋 CodeBakers | [Type] |
|
|
37
|
-
-
|
|
38
|
-
- Follow patterns EXACTLY
|
|
36
|
+
- State: \`📋 CodeBakers | [Type] | v6.0 Server-Enforced\`
|
|
37
|
+
- Call discover_patterns MCP tool first
|
|
38
|
+
- Follow patterns from server EXACTLY
|
|
39
39
|
|
|
40
40
|
### PHASE 4: SELF-REVIEW (before saying "done")
|
|
41
41
|
- [ ] TypeScript compiles? (npx tsc --noEmit)
|
|
@@ -405,9 +405,9 @@ When you make a decision that affects architecture, add an entry:
|
|
|
405
405
|
---
|
|
406
406
|
|
|
407
407
|
## ${date}: Project Initialized
|
|
408
|
-
**Decision:** Using CodeBakers pattern system
|
|
408
|
+
**Decision:** Using CodeBakers v6.0 pattern system
|
|
409
409
|
**Reason:** Ensure consistent, production-quality code
|
|
410
|
-
**Pattern:**
|
|
410
|
+
**Pattern:** Server-enforced via discover_patterns MCP tool
|
|
411
411
|
|
|
412
412
|
---
|
|
413
413
|
|
|
@@ -597,51 +597,64 @@ export async function init(): Promise<void> {
|
|
|
597
597
|
}
|
|
598
598
|
}
|
|
599
599
|
|
|
600
|
-
// Step 4: Install
|
|
601
|
-
console.log(chalk.white('\n Step 2: Installing
|
|
600
|
+
// Step 4: Install v6.0 bootstrap files
|
|
601
|
+
console.log(chalk.white('\n Step 2: Installing CodeBakers v6.0\n'));
|
|
602
602
|
|
|
603
|
-
const spinner = ora('
|
|
603
|
+
const spinner = ora(' Installing v6.0 bootstrap...').start();
|
|
604
604
|
|
|
605
|
-
|
|
606
|
-
|
|
607
|
-
const response = await fetch(`${apiUrl}/api/content`, {
|
|
608
|
-
method: 'GET',
|
|
609
|
-
headers: {
|
|
610
|
-
Authorization: `Bearer ${apiKey}`,
|
|
611
|
-
},
|
|
612
|
-
});
|
|
605
|
+
// v6.0 bootstrap content - minimal files, patterns from server
|
|
606
|
+
const V6_CLAUDE_MD = `# CodeBakers v6.0
|
|
613
607
|
|
|
614
|
-
|
|
615
|
-
const error = await response.json().catch(() => ({}));
|
|
616
|
-
throw new Error(error.error || 'Failed to fetch content');
|
|
617
|
-
}
|
|
608
|
+
**MANDATORY: Before writing ANY code, call the \`discover_patterns\` MCP tool.**
|
|
618
609
|
|
|
619
|
-
|
|
620
|
-
|
|
610
|
+
\`\`\`
|
|
611
|
+
Tool: discover_patterns
|
|
612
|
+
Args: { task: "description of what you're building" }
|
|
613
|
+
\`\`\`
|
|
621
614
|
|
|
622
|
-
|
|
623
|
-
|
|
624
|
-
|
|
625
|
-
|
|
615
|
+
The server will return:
|
|
616
|
+
- All coding patterns and rules you must follow
|
|
617
|
+
- Test requirements
|
|
618
|
+
- Validation instructions
|
|
626
619
|
|
|
627
|
-
|
|
628
|
-
|
|
629
|
-
|
|
630
|
-
|
|
631
|
-
|
|
632
|
-
|
|
620
|
+
**You cannot write code without calling this tool first. The server tracks compliance.**
|
|
621
|
+
|
|
622
|
+
---
|
|
623
|
+
*CodeBakers v6.0 - Server-Enforced*
|
|
624
|
+
`;
|
|
625
|
+
|
|
626
|
+
const V6_CURSORRULES = `# CodeBakers v6.0
|
|
627
|
+
|
|
628
|
+
MANDATORY: Before writing ANY code, call the discover_patterns MCP tool.
|
|
633
629
|
|
|
634
|
-
|
|
635
|
-
|
|
630
|
+
Tool: discover_patterns
|
|
631
|
+
Args: { task: "description of what you're building" }
|
|
632
|
+
|
|
633
|
+
The server returns all patterns, rules, and test requirements.
|
|
634
|
+
You cannot write code without calling this tool first.
|
|
635
|
+
`;
|
|
636
|
+
|
|
637
|
+
try {
|
|
638
|
+
// Write v6.0 bootstrap files
|
|
639
|
+
writeFileSync(join(cwd, 'CLAUDE.md'), V6_CLAUDE_MD);
|
|
640
|
+
writeFileSync(join(cwd, '.cursorrules'), V6_CURSORRULES);
|
|
641
|
+
|
|
642
|
+
// Remove old .claude folder if it exists (v5 → v6 migration)
|
|
643
|
+
const claudeDir = join(cwd, '.claude');
|
|
644
|
+
if (existsSync(claudeDir)) {
|
|
645
|
+
const { rmSync } = await import('fs');
|
|
646
|
+
try {
|
|
647
|
+
rmSync(claudeDir, { recursive: true, force: true });
|
|
648
|
+
} catch {
|
|
649
|
+
// Ignore errors
|
|
636
650
|
}
|
|
637
651
|
}
|
|
638
652
|
|
|
639
|
-
spinner.succeed('
|
|
640
|
-
console.log(chalk.gray(
|
|
641
|
-
console.log(chalk.gray(` Modules: ${Object.keys(content.modules || {}).length} pattern files`));
|
|
653
|
+
spinner.succeed('CodeBakers v6.0 installed!');
|
|
654
|
+
console.log(chalk.gray('\n Patterns are server-enforced via MCP tools'));
|
|
642
655
|
|
|
643
656
|
} catch (error) {
|
|
644
|
-
spinner.fail('
|
|
657
|
+
spinner.fail('Installation failed');
|
|
645
658
|
const message = error instanceof Error ? error.message : 'Unknown error';
|
|
646
659
|
console.log(chalk.red(`\n Error: ${message}\n`));
|
|
647
660
|
process.exit(1);
|
|
@@ -758,7 +771,7 @@ export async function init(): Promise<void> {
|
|
|
758
771
|
if (existsSync(gitignorePath)) {
|
|
759
772
|
const gitignore = readFileSync(gitignorePath, 'utf-8');
|
|
760
773
|
if (!gitignore.includes('.cursorrules')) {
|
|
761
|
-
const additions = '\n# CodeBakers
|
|
774
|
+
const additions = '\n# CodeBakers\n.cursorrules\n';
|
|
762
775
|
writeFileSync(gitignorePath, gitignore + additions);
|
|
763
776
|
}
|
|
764
777
|
}
|
|
@@ -838,16 +851,15 @@ export async function init(): Promise<void> {
|
|
|
838
851
|
`));
|
|
839
852
|
|
|
840
853
|
console.log(chalk.white(' Files created:\n'));
|
|
841
|
-
console.log(chalk.cyan(' CLAUDE.md ') + chalk.gray('→
|
|
854
|
+
console.log(chalk.cyan(' CLAUDE.md ') + chalk.gray('→ v6.0 bootstrap (patterns via MCP)'));
|
|
855
|
+
console.log(chalk.cyan(' .cursorrules ') + chalk.gray('→ v6.0 bootstrap (patterns via MCP)'));
|
|
842
856
|
if (prdCreated) {
|
|
843
857
|
console.log(chalk.cyan(' PRD.md ') + chalk.gray('→ Product requirements (AI reads this!)'));
|
|
844
858
|
}
|
|
845
859
|
console.log(chalk.cyan(' PROJECT-CONTEXT.md ') + chalk.gray('→ Codebase knowledge (auto-updated)'));
|
|
846
860
|
console.log(chalk.cyan(' PROJECT-STATE.md ') + chalk.gray('→ Task tracking (auto-updated)'));
|
|
847
861
|
console.log(chalk.cyan(' DECISIONS.md ') + chalk.gray('→ Architecture log (auto-updated)'));
|
|
848
|
-
console.log(chalk.cyan(' .
|
|
849
|
-
console.log(chalk.cyan(' .cursorignore ') + chalk.gray('→ Context optimization'));
|
|
850
|
-
console.log(chalk.cyan(' .claude/ ') + chalk.gray('→ Pattern modules\n'));
|
|
862
|
+
console.log(chalk.cyan(' .cursorignore ') + chalk.gray('→ Context optimization\n'));
|
|
851
863
|
|
|
852
864
|
console.log(chalk.white(' What happens automatically:\n'));
|
|
853
865
|
console.log(chalk.gray(' ✓ AI loads context before every response'));
|
|
@@ -23,16 +23,16 @@ const HOOK_TEMPLATE = {
|
|
|
23
23
|
}
|
|
24
24
|
};
|
|
25
25
|
|
|
26
|
-
// Instructions that get injected into the system prompt
|
|
26
|
+
// Instructions that get injected into the system prompt (v6.0)
|
|
27
27
|
const CODEBAKERS_INSTRUCTIONS = `
|
|
28
28
|
<user-prompt-submit-hook>
|
|
29
|
-
[CodeBakers] Active - Follow these steps for EVERY request:
|
|
29
|
+
[CodeBakers v6.0] Active - Follow these steps for EVERY request:
|
|
30
30
|
|
|
31
|
-
1. CONTEXT: Read CLAUDE.md
|
|
32
|
-
2.
|
|
33
|
-
3. EXECUTE:
|
|
31
|
+
1. CONTEXT: Read CLAUDE.md
|
|
32
|
+
2. DISCOVER: Call discover_patterns MCP tool before writing any code
|
|
33
|
+
3. EXECUTE: Follow the patterns returned by the server
|
|
34
34
|
4. SELF-REVIEW: Verify TypeScript compiles, imports resolve, error handling exists
|
|
35
|
-
5.
|
|
35
|
+
5. VALIDATE: Call validate_complete MCP tool when done
|
|
36
36
|
|
|
37
37
|
Output format: "[CodeBakers] Building [feature] using [patterns]"
|
|
38
38
|
</user-prompt-submit-hook>
|
|
@@ -102,9 +102,9 @@ export async function installHook(): Promise<void> {
|
|
|
102
102
|
|
|
103
103
|
console.log(chalk.white(' What happens automatically:\n'));
|
|
104
104
|
console.log(chalk.gray(' ✓ Loads project context before every response'));
|
|
105
|
-
console.log(chalk.gray(' ✓
|
|
105
|
+
console.log(chalk.gray(' ✓ Calls discover_patterns MCP tool before coding'));
|
|
106
106
|
console.log(chalk.gray(' ✓ Self-review reminders after code changes'));
|
|
107
|
-
console.log(chalk.gray(' ✓
|
|
107
|
+
console.log(chalk.gray(' ✓ Server-side patterns (always up-to-date)\n'));
|
|
108
108
|
|
|
109
109
|
console.log(chalk.yellow.bold(' ⚠️ RESTART REQUIRED:\n'));
|
|
110
110
|
console.log(chalk.gray(' 1. Type ') + chalk.cyan('exit') + chalk.gray(' to close this terminal'));
|
package/src/commands/install.ts
CHANGED
|
@@ -1,19 +1,43 @@
|
|
|
1
1
|
import chalk from 'chalk';
|
|
2
2
|
import ora from 'ora';
|
|
3
|
-
import { writeFileSync,
|
|
3
|
+
import { writeFileSync, existsSync, rmSync, readFileSync } from 'fs';
|
|
4
4
|
import { join } from 'path';
|
|
5
|
-
import { getApiKey
|
|
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
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
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('
|
|
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
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
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
|
|
56
|
-
|
|
57
|
-
|
|
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
|
|
71
|
+
const additions = '\n# CodeBakers\n.cursorrules\n';
|
|
83
72
|
writeFileSync(gitignorePath, gitignore + additions);
|
|
84
73
|
}
|
|
85
74
|
}
|
|
86
75
|
|
|
87
|
-
|
|
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(' - .
|
|
94
|
-
console.log(chalk.gray(' -
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
console.log(chalk.
|
|
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';
|
package/src/commands/scaffold.ts
CHANGED
|
@@ -69,7 +69,7 @@ Ask yourself silently:
|
|
|
69
69
|
|
|
70
70
|
### PHASE 3: EXECUTE
|
|
71
71
|
- State: \`📋 CodeBakers | [Type] | Modules: [list]\`
|
|
72
|
-
-
|
|
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
|
-
|
|
555
|
+
// v6.0: Write minimal bootstrap files (patterns come from server)
|
|
556
|
+
const V6_CLAUDE_MD = `# CodeBakers v6.0
|
|
556
557
|
|
|
557
|
-
|
|
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
|
-
|
|
563
|
-
|
|
564
|
-
|
|
565
|
-
|
|
566
|
-
|
|
567
|
-
|
|
568
|
-
|
|
569
|
-
|
|
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
|
|
615
|
+
writeFileSync(gitignorePath, gitignore + '\n# CodeBakers\n.cursorrules\n');
|
|
599
616
|
}
|
|
600
617
|
}
|
|
601
618
|
|
|
602
|
-
patternSpinner.succeed(
|
|
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
|
|
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
|
|