@codebakers/cli 1.4.1 → 1.4.3
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/install-hook.js +5 -2
- package/dist/commands/mcp-config.js +5 -3
- package/dist/commands/scaffold.js +306 -8
- package/dist/commands/serve.js +6 -3
- package/dist/commands/setup.js +7 -4
- package/dist/config.d.ts +3 -0
- package/dist/config.js +9 -0
- package/dist/index.js +1 -1
- package/dist/mcp/server.js +380 -0
- package/package.json +2 -3
- package/src/commands/install-hook.ts +5 -2
- package/src/commands/mcp-config.ts +5 -3
- package/src/commands/scaffold.ts +330 -9
- package/src/commands/serve.ts +6 -3
- package/src/commands/setup.ts +7 -4
- package/src/config.ts +12 -0
- package/src/index.ts +1 -1
- package/src/mcp/server.ts +429 -1
package/src/commands/scaffold.ts
CHANGED
|
@@ -1,10 +1,246 @@
|
|
|
1
1
|
import chalk from 'chalk';
|
|
2
2
|
import ora from 'ora';
|
|
3
3
|
import { createInterface } from 'readline';
|
|
4
|
-
import { writeFileSync, mkdirSync, existsSync, readdirSync } from 'fs';
|
|
4
|
+
import { writeFileSync, mkdirSync, existsSync, readdirSync, readFileSync } from 'fs';
|
|
5
5
|
import { join } from 'path';
|
|
6
6
|
import { execSync } from 'child_process';
|
|
7
7
|
import * as templates from '../templates/nextjs-supabase.js';
|
|
8
|
+
import { getApiKey, getApiUrl } from '../config.js';
|
|
9
|
+
|
|
10
|
+
// Cursor IDE configuration templates
|
|
11
|
+
const CURSORRULES_TEMPLATE = `# CODEBAKERS CURSOR RULES
|
|
12
|
+
# Zero-friction AI assistance - everything is automatic
|
|
13
|
+
|
|
14
|
+
## ON EVERY MESSAGE - AUTOMATIC WORKFLOW
|
|
15
|
+
|
|
16
|
+
### PHASE 1: CONTEXT LOAD (automatic)
|
|
17
|
+
1. Read CLAUDE.md → Load router
|
|
18
|
+
2. Read PRD.md → Understand what we're building
|
|
19
|
+
3. Read PROJECT-CONTEXT.md → Understand codebase
|
|
20
|
+
4. Read PROJECT-STATE.md → Check what's in progress
|
|
21
|
+
5. Read DECISIONS.md → Know past decisions
|
|
22
|
+
|
|
23
|
+
### PHASE 2: PRE-FLIGHT CHECK (before writing code)
|
|
24
|
+
Ask yourself silently:
|
|
25
|
+
- [ ] What existing code does this touch? (check PROJECT-CONTEXT.md)
|
|
26
|
+
- [ ] Is similar code already in the codebase? (copy that pattern)
|
|
27
|
+
- [ ] What's the data model involved?
|
|
28
|
+
- [ ] What are the error cases?
|
|
29
|
+
- [ ] Is someone else working on this? (check PROJECT-STATE.md)
|
|
30
|
+
|
|
31
|
+
### PHASE 3: EXECUTE
|
|
32
|
+
- State: \`📋 CodeBakers | [Type] | Modules: [list]\`
|
|
33
|
+
- Load required modules from .claude/
|
|
34
|
+
- Follow patterns EXACTLY
|
|
35
|
+
|
|
36
|
+
### PHASE 4: SELF-REVIEW (before saying "done")
|
|
37
|
+
- [ ] TypeScript compiles? (npx tsc --noEmit)
|
|
38
|
+
- [ ] Imports resolve correctly?
|
|
39
|
+
- [ ] Error handling exists?
|
|
40
|
+
- [ ] Matches existing patterns in codebase?
|
|
41
|
+
- [ ] Tests written?
|
|
42
|
+
- [ ] PROJECT-STATE.md updated?
|
|
43
|
+
|
|
44
|
+
If ANY check fails, fix it before responding.
|
|
45
|
+
|
|
46
|
+
## REMEMBER
|
|
47
|
+
- You are a full product team, not just a code assistant
|
|
48
|
+
- The modules contain production-tested patterns — USE THEM
|
|
49
|
+
- When in doubt, check existing code first
|
|
50
|
+
`;
|
|
51
|
+
|
|
52
|
+
const CURSORIGNORE_TEMPLATE = `# CodeBakers - Files to ignore in Cursor context
|
|
53
|
+
|
|
54
|
+
# Dependencies
|
|
55
|
+
node_modules/
|
|
56
|
+
.pnpm-store/
|
|
57
|
+
|
|
58
|
+
# Build outputs
|
|
59
|
+
dist/
|
|
60
|
+
build/
|
|
61
|
+
.next/
|
|
62
|
+
.nuxt/
|
|
63
|
+
out/
|
|
64
|
+
|
|
65
|
+
# Cache
|
|
66
|
+
.cache/
|
|
67
|
+
.turbo/
|
|
68
|
+
.eslintcache
|
|
69
|
+
*.tsbuildinfo
|
|
70
|
+
|
|
71
|
+
# Logs
|
|
72
|
+
logs/
|
|
73
|
+
*.log
|
|
74
|
+
|
|
75
|
+
# Environment files
|
|
76
|
+
.env
|
|
77
|
+
.env.local
|
|
78
|
+
.env.*.local
|
|
79
|
+
|
|
80
|
+
# IDE
|
|
81
|
+
.idea/
|
|
82
|
+
*.swp
|
|
83
|
+
|
|
84
|
+
# OS
|
|
85
|
+
.DS_Store
|
|
86
|
+
Thumbs.db
|
|
87
|
+
|
|
88
|
+
# Test coverage
|
|
89
|
+
coverage/
|
|
90
|
+
|
|
91
|
+
# Package locks
|
|
92
|
+
package-lock.json
|
|
93
|
+
yarn.lock
|
|
94
|
+
pnpm-lock.yaml
|
|
95
|
+
|
|
96
|
+
# Generated files
|
|
97
|
+
*.min.js
|
|
98
|
+
*.min.css
|
|
99
|
+
*.map
|
|
100
|
+
`;
|
|
101
|
+
|
|
102
|
+
function createPrdTemplate(projectName: string): string {
|
|
103
|
+
const date = new Date().toISOString().split('T')[0];
|
|
104
|
+
return `# Product Requirements Document
|
|
105
|
+
# Project: ${projectName}
|
|
106
|
+
# Created: ${date}
|
|
107
|
+
|
|
108
|
+
## Overview
|
|
109
|
+
**One-liner:** [Describe this project in one sentence]
|
|
110
|
+
|
|
111
|
+
**Problem:** [What problem does this solve?]
|
|
112
|
+
|
|
113
|
+
**Solution:** [How does this solve it?]
|
|
114
|
+
|
|
115
|
+
## Target Users
|
|
116
|
+
- **Primary:** [Who is the main user?]
|
|
117
|
+
- **Secondary:** [Other users?]
|
|
118
|
+
|
|
119
|
+
## Core Features (MVP)
|
|
120
|
+
<!-- List the MINIMUM features needed to launch -->
|
|
121
|
+
|
|
122
|
+
1. [ ] **Feature 1:** [Description]
|
|
123
|
+
- Acceptance criteria: [How do we know it's done?]
|
|
124
|
+
|
|
125
|
+
2. [ ] **Feature 2:** [Description]
|
|
126
|
+
- Acceptance criteria: [How do we know it's done?]
|
|
127
|
+
|
|
128
|
+
3. [ ] **Feature 3:** [Description]
|
|
129
|
+
- Acceptance criteria: [How do we know it's done?]
|
|
130
|
+
|
|
131
|
+
## Nice-to-Have Features (Post-MVP)
|
|
132
|
+
|
|
133
|
+
1. [ ] [Feature description]
|
|
134
|
+
2. [ ] [Feature description]
|
|
135
|
+
|
|
136
|
+
## Technical Requirements
|
|
137
|
+
|
|
138
|
+
- **Must use:** [Required technologies, APIs, etc.]
|
|
139
|
+
- **Must avoid:** [Things you don't want]
|
|
140
|
+
- **Performance:** [Any speed/scale requirements?]
|
|
141
|
+
- **Security:** [Auth requirements, data sensitivity?]
|
|
142
|
+
|
|
143
|
+
## Success Metrics
|
|
144
|
+
- [ ] [How will you measure success?]
|
|
145
|
+
- [ ] [What does "done" look like?]
|
|
146
|
+
|
|
147
|
+
---
|
|
148
|
+
<!-- AI INSTRUCTIONS -->
|
|
149
|
+
<!-- When building features, reference this PRD -->
|
|
150
|
+
<!-- Check off features as they're completed -->
|
|
151
|
+
`;
|
|
152
|
+
}
|
|
153
|
+
|
|
154
|
+
function createProjectState(projectName: string): string {
|
|
155
|
+
const date = new Date().toISOString().split('T')[0];
|
|
156
|
+
return `# PROJECT STATE
|
|
157
|
+
# Last Updated: ${date}
|
|
158
|
+
# Auto-maintained by AI - update when starting/completing tasks
|
|
159
|
+
|
|
160
|
+
## Project Info
|
|
161
|
+
name: ${projectName}
|
|
162
|
+
phase: setup
|
|
163
|
+
|
|
164
|
+
## In Progress
|
|
165
|
+
<!-- AI: Add tasks here when you START working on them -->
|
|
166
|
+
|
|
167
|
+
## Completed
|
|
168
|
+
<!-- AI: Move tasks here when DONE -->
|
|
169
|
+
|
|
170
|
+
## Next Up
|
|
171
|
+
<!-- AI: Queue of upcoming tasks -->
|
|
172
|
+
`;
|
|
173
|
+
}
|
|
174
|
+
|
|
175
|
+
function createProjectContext(projectName: string): string {
|
|
176
|
+
const date = new Date().toISOString().split('T')[0];
|
|
177
|
+
return `# PROJECT CONTEXT
|
|
178
|
+
# Last Scanned: ${date}
|
|
179
|
+
# AI: Update this when you first analyze the project
|
|
180
|
+
|
|
181
|
+
## Overview
|
|
182
|
+
name: ${projectName}
|
|
183
|
+
description: [AI will fill after scanning]
|
|
184
|
+
|
|
185
|
+
## Tech Stack
|
|
186
|
+
framework: Next.js 14
|
|
187
|
+
language: TypeScript
|
|
188
|
+
database: Drizzle ORM + Supabase
|
|
189
|
+
auth: Supabase Auth
|
|
190
|
+
styling: Tailwind CSS
|
|
191
|
+
|
|
192
|
+
## Project Structure
|
|
193
|
+
\`\`\`
|
|
194
|
+
src/
|
|
195
|
+
├── app/ ← Pages & layouts
|
|
196
|
+
├── components/ ← React components
|
|
197
|
+
├── lib/ ← Utilities & clients
|
|
198
|
+
│ └── supabase/ ← Supabase clients
|
|
199
|
+
├── db/ ← Database schema & queries
|
|
200
|
+
├── services/ ← Business logic
|
|
201
|
+
└── types/ ← TypeScript types
|
|
202
|
+
\`\`\`
|
|
203
|
+
|
|
204
|
+
## Key Files
|
|
205
|
+
- Entry point: src/app/page.tsx
|
|
206
|
+
- Database schema: src/db/schema.ts
|
|
207
|
+
- API routes: src/app/api/
|
|
208
|
+
|
|
209
|
+
## Notes
|
|
210
|
+
<!-- AI: Any important context about this specific project -->
|
|
211
|
+
`;
|
|
212
|
+
}
|
|
213
|
+
|
|
214
|
+
function createDecisionsLog(projectName: string): string {
|
|
215
|
+
const date = new Date().toISOString().split('T')[0];
|
|
216
|
+
return `# ARCHITECTURAL DECISIONS
|
|
217
|
+
# Project: ${projectName}
|
|
218
|
+
# AI: Add entries here when making significant technical choices
|
|
219
|
+
|
|
220
|
+
## How to Use This File
|
|
221
|
+
When you make a decision that affects architecture, add an entry:
|
|
222
|
+
- Date
|
|
223
|
+
- Decision
|
|
224
|
+
- Reason
|
|
225
|
+
- Alternatives considered
|
|
226
|
+
|
|
227
|
+
---
|
|
228
|
+
|
|
229
|
+
## ${date}: Project Initialized
|
|
230
|
+
**Decision:** Using CodeBakers pattern system with Next.js + Supabase + Drizzle
|
|
231
|
+
**Reason:** Production-ready stack with type safety and excellent DX
|
|
232
|
+
|
|
233
|
+
---
|
|
234
|
+
|
|
235
|
+
<!-- AI: Add new decisions above this line -->
|
|
236
|
+
`;
|
|
237
|
+
}
|
|
238
|
+
|
|
239
|
+
interface ContentResponse {
|
|
240
|
+
version: string;
|
|
241
|
+
router: string;
|
|
242
|
+
modules: Record<string, string>;
|
|
243
|
+
}
|
|
8
244
|
|
|
9
245
|
async function prompt(question: string): Promise<string> {
|
|
10
246
|
const rl = createInterface({
|
|
@@ -64,7 +300,6 @@ export async function scaffold(): Promise<void> {
|
|
|
64
300
|
}
|
|
65
301
|
|
|
66
302
|
const isBeginnerMode = experienceLevel === '1';
|
|
67
|
-
const showBriefExplanations = experienceLevel === '2';
|
|
68
303
|
|
|
69
304
|
// Select stack with explanations for beginners
|
|
70
305
|
console.log(chalk.white('\n Select your stack:\n'));
|
|
@@ -200,16 +435,96 @@ export async function scaffold(): Promise<void> {
|
|
|
200
435
|
}
|
|
201
436
|
}
|
|
202
437
|
|
|
438
|
+
spinner.succeed('Project structure created!');
|
|
439
|
+
|
|
440
|
+
// Auto-install CodeBakers patterns
|
|
441
|
+
console.log(chalk.white('\n Installing CodeBakers patterns...\n'));
|
|
442
|
+
|
|
443
|
+
const apiKey = getApiKey();
|
|
444
|
+
let patternsInstalled = false;
|
|
445
|
+
|
|
446
|
+
if (apiKey) {
|
|
447
|
+
const patternSpinner = ora(' Downloading patterns...').start();
|
|
448
|
+
|
|
449
|
+
try {
|
|
450
|
+
const apiUrl = getApiUrl();
|
|
451
|
+
const response = await fetch(`${apiUrl}/api/content`, {
|
|
452
|
+
method: 'GET',
|
|
453
|
+
headers: {
|
|
454
|
+
Authorization: `Bearer ${apiKey}`,
|
|
455
|
+
},
|
|
456
|
+
});
|
|
457
|
+
|
|
458
|
+
if (response.ok) {
|
|
459
|
+
const content: ContentResponse = await response.json();
|
|
460
|
+
|
|
461
|
+
// Write CLAUDE.md (main router)
|
|
462
|
+
if (content.router) {
|
|
463
|
+
writeFileSync(join(cwd, 'CLAUDE.md'), content.router);
|
|
464
|
+
}
|
|
465
|
+
|
|
466
|
+
// Write pattern modules to .claude/
|
|
467
|
+
if (content.modules && Object.keys(content.modules).length > 0) {
|
|
468
|
+
const modulesDir = join(cwd, '.claude');
|
|
469
|
+
if (!existsSync(modulesDir)) {
|
|
470
|
+
mkdirSync(modulesDir, { recursive: true });
|
|
471
|
+
}
|
|
472
|
+
for (const [name, data] of Object.entries(content.modules)) {
|
|
473
|
+
writeFileSync(join(modulesDir, name), data);
|
|
474
|
+
}
|
|
475
|
+
}
|
|
476
|
+
|
|
477
|
+
// Write project management files
|
|
478
|
+
writeFileSync(join(cwd, 'PRD.md'), createPrdTemplate(projectName));
|
|
479
|
+
writeFileSync(join(cwd, 'PROJECT-STATE.md'), createProjectState(projectName));
|
|
480
|
+
writeFileSync(join(cwd, 'PROJECT-CONTEXT.md'), createProjectContext(projectName));
|
|
481
|
+
writeFileSync(join(cwd, 'DECISIONS.md'), createDecisionsLog(projectName));
|
|
482
|
+
|
|
483
|
+
// Write Cursor IDE files
|
|
484
|
+
writeFileSync(join(cwd, '.cursorrules'), CURSORRULES_TEMPLATE);
|
|
485
|
+
writeFileSync(join(cwd, '.cursorignore'), CURSORIGNORE_TEMPLATE);
|
|
486
|
+
|
|
487
|
+
// Create .vscode settings
|
|
488
|
+
const vscodeDir = join(cwd, '.vscode');
|
|
489
|
+
if (!existsSync(vscodeDir)) {
|
|
490
|
+
mkdirSync(vscodeDir, { recursive: true });
|
|
491
|
+
}
|
|
492
|
+
writeFileSync(join(vscodeDir, 'settings.json'), JSON.stringify({
|
|
493
|
+
"cursor.chat.defaultContext": ["CLAUDE.md", "PRD.md", "PROJECT-CONTEXT.md"],
|
|
494
|
+
"cursor.chat.alwaysIncludeRules": true
|
|
495
|
+
}, null, 2));
|
|
496
|
+
|
|
497
|
+
// Update .gitignore
|
|
498
|
+
const gitignorePath = join(cwd, '.gitignore');
|
|
499
|
+
if (existsSync(gitignorePath)) {
|
|
500
|
+
const gitignore = readFileSync(gitignorePath, 'utf-8');
|
|
501
|
+
if (!gitignore.includes('.cursorrules')) {
|
|
502
|
+
writeFileSync(gitignorePath, gitignore + '\n# CodeBakers\n.cursorrules\n.claude/\n');
|
|
503
|
+
}
|
|
504
|
+
}
|
|
505
|
+
|
|
506
|
+
patternSpinner.succeed(`Patterns installed! (v${content.version})`);
|
|
507
|
+
patternsInstalled = true;
|
|
508
|
+
} else {
|
|
509
|
+
patternSpinner.warn('Could not download patterns (will need to run codebakers init later)');
|
|
510
|
+
}
|
|
511
|
+
} catch {
|
|
512
|
+
patternSpinner.warn('Could not download patterns (will need to run codebakers init later)');
|
|
513
|
+
}
|
|
514
|
+
} else {
|
|
515
|
+
console.log(chalk.yellow(' ⚠️ Not logged in - run `codebakers setup` first to get patterns\n'));
|
|
516
|
+
}
|
|
517
|
+
|
|
203
518
|
// Success message
|
|
204
519
|
console.log(chalk.green(`
|
|
205
520
|
╔═══════════════════════════════════════════════════════════╗
|
|
206
521
|
║ ║
|
|
207
|
-
║ ${chalk.bold('✓ Project
|
|
522
|
+
║ ${chalk.bold('✓ Project created successfully!')} ║
|
|
208
523
|
║ ║
|
|
209
524
|
╚═══════════════════════════════════════════════════════════╝
|
|
210
525
|
`));
|
|
211
526
|
|
|
212
|
-
console.log(chalk.white('
|
|
527
|
+
console.log(chalk.white(' What was created:\n'));
|
|
213
528
|
if (isBeginnerMode) {
|
|
214
529
|
console.log(chalk.gray(' src/'));
|
|
215
530
|
console.log(chalk.gray(' ├── app/ ') + chalk.cyan('← Your pages (what users see)'));
|
|
@@ -229,6 +544,13 @@ export async function scaffold(): Promise<void> {
|
|
|
229
544
|
console.log(chalk.gray(' ├── services/ ') + chalk.cyan('← Business logic'));
|
|
230
545
|
console.log(chalk.gray(' └── types/ ') + chalk.cyan('← TypeScript types'));
|
|
231
546
|
}
|
|
547
|
+
|
|
548
|
+
if (patternsInstalled) {
|
|
549
|
+
console.log('');
|
|
550
|
+
console.log(chalk.gray(' CLAUDE.md ') + chalk.cyan('← AI instructions (reads automatically!)'));
|
|
551
|
+
console.log(chalk.gray(' PRD.md ') + chalk.cyan('← Your product requirements'));
|
|
552
|
+
console.log(chalk.gray(' .claude/ ') + chalk.cyan('← 34 production patterns'));
|
|
553
|
+
}
|
|
232
554
|
console.log('');
|
|
233
555
|
|
|
234
556
|
console.log(chalk.white(' Next steps:\n'));
|
|
@@ -244,14 +566,13 @@ export async function scaffold(): Promise<void> {
|
|
|
244
566
|
console.log(chalk.gray(' Run: npm run dev'));
|
|
245
567
|
console.log(chalk.gray(' Open: http://localhost:3000 in your browser'));
|
|
246
568
|
console.log('');
|
|
247
|
-
console.log(chalk.cyan(' 4. ') + chalk.white('
|
|
248
|
-
console.log(chalk.gray('
|
|
249
|
-
console.log(chalk.gray('
|
|
569
|
+
console.log(chalk.cyan(' 4. ') + chalk.white('Start building!'));
|
|
570
|
+
console.log(chalk.gray(' Tell your AI: "Build me a [feature]"'));
|
|
571
|
+
console.log(chalk.gray(' The AI already has all the patterns loaded!\n'));
|
|
250
572
|
} else {
|
|
251
573
|
console.log(chalk.cyan(' 1. ') + chalk.gray('Update .env.local with your Supabase credentials'));
|
|
252
574
|
console.log(chalk.cyan(' 2. ') + chalk.gray('Run `npm run dev` to start development'));
|
|
253
|
-
console.log(chalk.cyan(' 3. ') + chalk.gray('
|
|
254
|
-
console.log(chalk.cyan(' 4. ') + chalk.gray('Start building with AI assistance!\n'));
|
|
575
|
+
console.log(chalk.cyan(' 3. ') + chalk.gray('Tell your AI what to build - patterns are already loaded!\n'));
|
|
255
576
|
|
|
256
577
|
console.log(chalk.white(' Supabase setup:\n'));
|
|
257
578
|
console.log(chalk.gray(' 1. Create a project at https://supabase.com'));
|
package/src/commands/serve.ts
CHANGED
|
@@ -13,9 +13,12 @@ export async function serve(): Promise<void> {
|
|
|
13
13
|
console.error(chalk.green(' Starting MCP server on stdio...'));
|
|
14
14
|
console.error(chalk.gray(' This server provides pattern tools to Claude Code.\n'));
|
|
15
15
|
console.error(chalk.gray(' Available tools:'));
|
|
16
|
-
console.error(chalk.gray(' -
|
|
17
|
-
console.error(chalk.gray(' -
|
|
18
|
-
console.error(chalk.gray(' -
|
|
16
|
+
console.error(chalk.gray(' - scaffold_project: Create a new project from AI chat'));
|
|
17
|
+
console.error(chalk.gray(' - init_project: Add patterns to existing project'));
|
|
18
|
+
console.error(chalk.gray(' - set_experience_level: Set beginner/intermediate/advanced mode'));
|
|
19
|
+
console.error(chalk.gray(' - get_experience_level: Check current experience mode'));
|
|
20
|
+
console.error(chalk.gray(' - optimize_and_build: AI-powered prompt optimization'));
|
|
21
|
+
console.error(chalk.gray(' - get_pattern, list_patterns, search_patterns\n'));
|
|
19
22
|
|
|
20
23
|
// Dynamically import and run the MCP server
|
|
21
24
|
const { runServer } = await import('../mcp/server.js');
|
package/src/commands/setup.ts
CHANGED
|
@@ -104,7 +104,7 @@ function showFinalInstructions(): void {
|
|
|
104
104
|
console.log(chalk.yellow(' ⚠️ Could not auto-install MCP server.\n'));
|
|
105
105
|
console.log(chalk.white(' Run this command manually in your terminal:\n'));
|
|
106
106
|
console.log(chalk.bgBlue.white('\n ' + mcpCmd + ' \n'));
|
|
107
|
-
console.log(chalk.
|
|
107
|
+
console.log(chalk.yellow('\n ⚠️ Then close this terminal and open a new one in your project.\n'));
|
|
108
108
|
return;
|
|
109
109
|
}
|
|
110
110
|
}
|
|
@@ -113,10 +113,13 @@ function showFinalInstructions(): void {
|
|
|
113
113
|
console.log(chalk.white.bold('\n 🎉 Setup Complete!\n'));
|
|
114
114
|
console.log(chalk.blue(' ══════════════════════════════════════════════════════════\n'));
|
|
115
115
|
|
|
116
|
-
console.log(chalk.white('
|
|
117
|
-
console.log(chalk.cyan('
|
|
116
|
+
console.log(chalk.white.bold(' 👉 NEXT: Close this terminal and open your AI:\n'));
|
|
117
|
+
console.log(chalk.cyan(' • Claude Code') + chalk.gray(' - Open any project folder'));
|
|
118
|
+
console.log(chalk.cyan(' • Cursor') + chalk.gray(' - Open Composer (Cmd+I / Ctrl+I)\n'));
|
|
118
119
|
|
|
119
|
-
console.log(chalk.
|
|
120
|
+
console.log(chalk.white(' Then just describe what you want to build:\n'));
|
|
121
|
+
console.log(chalk.green(' "Build me a todo app with user authentication"\n'));
|
|
120
122
|
|
|
123
|
+
console.log(chalk.gray(' The AI will use CodeBakers patterns automatically.'));
|
|
121
124
|
console.log(chalk.gray(' Need help? https://codebakers.ai/docs\n'));
|
|
122
125
|
}
|
package/src/config.ts
CHANGED
|
@@ -1,8 +1,11 @@
|
|
|
1
1
|
import Conf from 'conf';
|
|
2
2
|
|
|
3
|
+
export type ExperienceLevel = 'beginner' | 'intermediate' | 'advanced';
|
|
4
|
+
|
|
3
5
|
interface ConfigSchema {
|
|
4
6
|
apiKey: string | null;
|
|
5
7
|
apiUrl: string;
|
|
8
|
+
experienceLevel: ExperienceLevel;
|
|
6
9
|
}
|
|
7
10
|
|
|
8
11
|
const config = new Conf<ConfigSchema>({
|
|
@@ -10,6 +13,7 @@ const config = new Conf<ConfigSchema>({
|
|
|
10
13
|
defaults: {
|
|
11
14
|
apiKey: null,
|
|
12
15
|
apiUrl: 'https://codebakers.ai',
|
|
16
|
+
experienceLevel: 'intermediate',
|
|
13
17
|
},
|
|
14
18
|
});
|
|
15
19
|
|
|
@@ -32,3 +36,11 @@ export function getApiUrl(): string {
|
|
|
32
36
|
export function setApiUrl(url: string): void {
|
|
33
37
|
config.set('apiUrl', url);
|
|
34
38
|
}
|
|
39
|
+
|
|
40
|
+
export function getExperienceLevel(): ExperienceLevel {
|
|
41
|
+
return config.get('experienceLevel');
|
|
42
|
+
}
|
|
43
|
+
|
|
44
|
+
export function setExperienceLevel(level: ExperienceLevel): void {
|
|
45
|
+
config.set('experienceLevel', level);
|
|
46
|
+
}
|
package/src/index.ts
CHANGED