codebakers 2.3.7 → 2.5.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/{advisors-GGUCFS4E.js → advisors-3PWAN6UL.js} +1 -1
- package/dist/{chunk-YUSDTJD6.js → chunk-URNRSXPU.js} +2 -2
- package/dist/{chunk-ND6T4UDY.js → chunk-WZQNFV7Q.js} +3 -3
- package/dist/index.js +762 -441
- package/dist/{prd-AIEY63YY.js → prd-YAUSAL5V.js} +1 -1
- package/package.json +1 -1
- package/src/commands/advisors.ts +2 -2
- package/src/commands/build.ts +12 -7
- package/src/commands/code.ts +2 -2
- package/src/commands/deploy.ts +3 -3
- package/src/commands/init.ts +81 -38
- package/src/commands/prd-maker.ts +1 -1
- package/src/commands/prd.ts +3 -3
- package/src/commands/website.ts +139 -64
- package/src/index.ts +1 -1
- package/src/utils/display.ts +325 -0
- package/src/utils/updates.ts +2 -21
package/package.json
CHANGED
package/src/commands/advisors.ts
CHANGED
|
@@ -328,7 +328,7 @@ async function getAdvisorFeedback(
|
|
|
328
328
|
brief: ProjectBrief
|
|
329
329
|
): Promise<AdvisorFeedback> {
|
|
330
330
|
const response = await anthropic.messages.create({
|
|
331
|
-
model: 'claude-sonnet-4-
|
|
331
|
+
model: 'claude-sonnet-4-5-20250929',
|
|
332
332
|
max_tokens: 2048,
|
|
333
333
|
messages: [{
|
|
334
334
|
role: 'user',
|
|
@@ -397,7 +397,7 @@ async function generateReport(
|
|
|
397
397
|
const avgScore = advisorFeedback.reduce((sum, f) => sum + f.score, 0) / advisorFeedback.length;
|
|
398
398
|
|
|
399
399
|
const response = await anthropic.messages.create({
|
|
400
|
-
model: 'claude-sonnet-4-
|
|
400
|
+
model: 'claude-sonnet-4-5-20250929',
|
|
401
401
|
max_tokens: 8192,
|
|
402
402
|
messages: [{
|
|
403
403
|
role: 'user',
|
package/src/commands/build.ts
CHANGED
|
@@ -206,8 +206,13 @@ export async function buildCommand(prdPath?: string, options: { sequential?: boo
|
|
|
206
206
|
|
|
207
207
|
// Step 7: Final setup
|
|
208
208
|
spinner.start('Installing dependencies...');
|
|
209
|
-
|
|
210
|
-
|
|
209
|
+
try {
|
|
210
|
+
await execa('npm', ['install'], { cwd: projectPath, stdio: 'inherit' });
|
|
211
|
+
spinner.stop('Dependencies installed');
|
|
212
|
+
} catch (error) {
|
|
213
|
+
spinner.stop('Dependencies installation failed');
|
|
214
|
+
console.log(chalk.yellow(' ⚠️ Run "npm install" manually in the project folder'));
|
|
215
|
+
}
|
|
211
216
|
|
|
212
217
|
// Done!
|
|
213
218
|
const elapsed = Math.round((Date.now() - startTime) / 1000);
|
|
@@ -237,7 +242,7 @@ export async function buildCommand(prdPath?: string, options: { sequential?: boo
|
|
|
237
242
|
|
|
238
243
|
async function analyzePRD(anthropic: Anthropic, prdContent: string): Promise<BuildPlan> {
|
|
239
244
|
const response = await anthropic.messages.create({
|
|
240
|
-
model: 'claude-sonnet-4-
|
|
245
|
+
model: 'claude-sonnet-4-5-20250929',
|
|
241
246
|
max_tokens: 4096,
|
|
242
247
|
messages: [{
|
|
243
248
|
role: 'user',
|
|
@@ -362,7 +367,7 @@ async function runSetupPhase(
|
|
|
362
367
|
|
|
363
368
|
// Generate shared setup code
|
|
364
369
|
const setupResponse = await anthropic.messages.create({
|
|
365
|
-
model: 'claude-sonnet-4-
|
|
370
|
+
model: 'claude-sonnet-4-5-20250929',
|
|
366
371
|
max_tokens: 8192,
|
|
367
372
|
messages: [{
|
|
368
373
|
role: 'user',
|
|
@@ -648,7 +653,7 @@ Start with the index.ts that exports everything.`
|
|
|
648
653
|
iteration++;
|
|
649
654
|
|
|
650
655
|
const response = await anthropic.messages.create({
|
|
651
|
-
model: 'claude-sonnet-4-
|
|
656
|
+
model: 'claude-sonnet-4-5-20250929',
|
|
652
657
|
max_tokens: 8192,
|
|
653
658
|
messages,
|
|
654
659
|
});
|
|
@@ -783,7 +788,7 @@ async function healerAgent(
|
|
|
783
788
|
plan: BuildPlan
|
|
784
789
|
): Promise<HealerSolution> {
|
|
785
790
|
const response = await anthropic.messages.create({
|
|
786
|
-
model: 'claude-sonnet-4-
|
|
791
|
+
model: 'claude-sonnet-4-5-20250929',
|
|
787
792
|
max_tokens: 4096,
|
|
788
793
|
messages: [{
|
|
789
794
|
role: 'user',
|
|
@@ -852,7 +857,7 @@ async function runIntegrationPhase(
|
|
|
852
857
|
const features = plan.waves.flatMap(w => w.agents);
|
|
853
858
|
|
|
854
859
|
const response = await anthropic.messages.create({
|
|
855
|
-
model: 'claude-sonnet-4-
|
|
860
|
+
model: 'claude-sonnet-4-5-20250929',
|
|
856
861
|
max_tokens: 8192,
|
|
857
862
|
messages: [{
|
|
858
863
|
role: 'user',
|
package/src/commands/code.ts
CHANGED
|
@@ -266,7 +266,7 @@ async function processUserInput(
|
|
|
266
266
|
|
|
267
267
|
// Call Claude
|
|
268
268
|
const response = await anthropic.messages.create({
|
|
269
|
-
model: 'claude-sonnet-4-
|
|
269
|
+
model: 'claude-sonnet-4-5-20250929',
|
|
270
270
|
max_tokens: 8192,
|
|
271
271
|
system: systemPrompt,
|
|
272
272
|
messages: messages.map(m => ({
|
|
@@ -787,7 +787,7 @@ ${content}
|
|
|
787
787
|
Output only the fixed file content, no explanation.`;
|
|
788
788
|
|
|
789
789
|
const response = await anthropic.messages.create({
|
|
790
|
-
model: 'claude-sonnet-4-
|
|
790
|
+
model: 'claude-sonnet-4-5-20250929',
|
|
791
791
|
max_tokens: 8192,
|
|
792
792
|
system: systemPrompt,
|
|
793
793
|
messages: [{ role: 'user', content: fixPrompt }],
|
package/src/commands/deploy.ts
CHANGED
|
@@ -295,7 +295,7 @@ ${content}
|
|
|
295
295
|
Output ONLY the corrected file content, no explanations. Keep all existing functionality.`;
|
|
296
296
|
|
|
297
297
|
const response = await anthropic.messages.create({
|
|
298
|
-
model: 'claude-sonnet-4-
|
|
298
|
+
model: 'claude-sonnet-4-5-20250929',
|
|
299
299
|
max_tokens: 8192,
|
|
300
300
|
messages: [{ role: 'user', content: prompt }],
|
|
301
301
|
});
|
|
@@ -359,7 +359,7 @@ ${content}
|
|
|
359
359
|
Output ONLY the corrected file content, no explanations.`;
|
|
360
360
|
|
|
361
361
|
const response = await anthropic.messages.create({
|
|
362
|
-
model: 'claude-sonnet-4-
|
|
362
|
+
model: 'claude-sonnet-4-5-20250929',
|
|
363
363
|
max_tokens: 8192,
|
|
364
364
|
messages: [{ role: 'user', content: prompt }],
|
|
365
365
|
});
|
|
@@ -417,7 +417,7 @@ Output ONLY the corrected file content, no explanations.`;
|
|
|
417
417
|
|
|
418
418
|
try {
|
|
419
419
|
const response = await anthropic.messages.create({
|
|
420
|
-
model: 'claude-sonnet-4-
|
|
420
|
+
model: 'claude-sonnet-4-5-20250929',
|
|
421
421
|
max_tokens: 8192,
|
|
422
422
|
messages: [{ role: 'user', content: prompt }],
|
|
423
423
|
});
|
package/src/commands/init.ts
CHANGED
|
@@ -190,65 +190,108 @@ Domain: ${domain || 'Vercel default'}`,
|
|
|
190
190
|
spinner.start('Installing dependencies...');
|
|
191
191
|
|
|
192
192
|
// Try npm first (most common), fall back to pnpm or yarn
|
|
193
|
+
let installSuccess = false;
|
|
193
194
|
try {
|
|
194
|
-
await execa('npm', ['install'], { cwd: projectPath });
|
|
195
|
+
await execa('npm', ['install'], { cwd: projectPath, stdio: 'inherit' });
|
|
196
|
+
installSuccess = true;
|
|
195
197
|
} catch {
|
|
196
198
|
try {
|
|
197
|
-
await execa('pnpm', ['install'], { cwd: projectPath });
|
|
199
|
+
await execa('pnpm', ['install'], { cwd: projectPath, stdio: 'inherit' });
|
|
200
|
+
installSuccess = true;
|
|
198
201
|
} catch {
|
|
199
|
-
|
|
202
|
+
try {
|
|
203
|
+
await execa('yarn', ['install'], { cwd: projectPath, stdio: 'inherit' });
|
|
204
|
+
installSuccess = true;
|
|
205
|
+
} catch {
|
|
206
|
+
// All failed
|
|
207
|
+
}
|
|
200
208
|
}
|
|
201
209
|
}
|
|
202
|
-
|
|
210
|
+
|
|
211
|
+
if (installSuccess) {
|
|
212
|
+
spinner.stop('Dependencies installed');
|
|
213
|
+
} else {
|
|
214
|
+
spinner.stop('Dependencies installation failed');
|
|
215
|
+
console.log(chalk.yellow(' ⚠️ Run "npm install" manually in the project folder'));
|
|
216
|
+
}
|
|
203
217
|
|
|
204
218
|
// Step 3: GitHub
|
|
205
219
|
if ((services as string[]).includes('github')) {
|
|
206
220
|
spinner.start('Creating GitHub repository...');
|
|
207
|
-
|
|
208
|
-
|
|
209
|
-
|
|
210
|
-
|
|
211
|
-
|
|
212
|
-
|
|
213
|
-
|
|
214
|
-
|
|
215
|
-
|
|
216
|
-
|
|
221
|
+
try {
|
|
222
|
+
const github = new GitHubService(config);
|
|
223
|
+
const repo = await github.createRepo(projectName, { private: true });
|
|
224
|
+
spinner.stop(`GitHub repo created: ${repo.html_url}`);
|
|
225
|
+
|
|
226
|
+
// Init git and push
|
|
227
|
+
try {
|
|
228
|
+
await execa('git', ['init'], { cwd: projectPath });
|
|
229
|
+
await execa('git', ['add', '.'], { cwd: projectPath });
|
|
230
|
+
await execa('git', ['commit', '-m', 'Initial commit by CodeBakers'], { cwd: projectPath });
|
|
231
|
+
await execa('git', ['remote', 'add', 'origin', repo.clone_url], { cwd: projectPath });
|
|
232
|
+
await execa('git', ['push', '-u', 'origin', 'main'], { cwd: projectPath });
|
|
233
|
+
} catch (gitError) {
|
|
234
|
+
console.log(chalk.yellow(' ⚠️ Git push failed. You can push manually later.'));
|
|
235
|
+
}
|
|
236
|
+
} catch (error) {
|
|
237
|
+
spinner.stop('GitHub setup failed');
|
|
238
|
+
console.log(chalk.yellow(' ⚠️ Could not create GitHub repo. Check your GitHub token.'));
|
|
239
|
+
}
|
|
217
240
|
}
|
|
218
241
|
|
|
219
242
|
// Step 4: Supabase
|
|
220
243
|
if ((services as string[]).includes('supabase')) {
|
|
221
244
|
spinner.start('Creating Supabase project...');
|
|
222
|
-
|
|
223
|
-
|
|
224
|
-
|
|
225
|
-
|
|
226
|
-
|
|
227
|
-
|
|
228
|
-
|
|
229
|
-
|
|
230
|
-
|
|
231
|
-
|
|
245
|
+
try {
|
|
246
|
+
const supabase = new SupabaseService(config);
|
|
247
|
+
const project = await supabase.createProject(projectName);
|
|
248
|
+
spinner.stop(`Supabase project created: ${project.name}`);
|
|
249
|
+
|
|
250
|
+
// Save Supabase config
|
|
251
|
+
await fs.writeJson(
|
|
252
|
+
path.join(projectPath, '.codebakers', 'supabase.json'),
|
|
253
|
+
{ projectId: project.id, projectUrl: project.api_url },
|
|
254
|
+
{ spaces: 2 }
|
|
255
|
+
);
|
|
256
|
+
} catch (error) {
|
|
257
|
+
spinner.stop('Supabase setup failed');
|
|
258
|
+
console.log(chalk.yellow(' ⚠️ Could not create Supabase project. Check your Supabase token.'));
|
|
259
|
+
}
|
|
232
260
|
}
|
|
233
261
|
|
|
234
262
|
// Step 5: Vercel
|
|
235
263
|
if ((services as string[]).includes('vercel')) {
|
|
236
264
|
spinner.start('Creating Vercel project...');
|
|
237
|
-
|
|
238
|
-
|
|
239
|
-
|
|
240
|
-
|
|
241
|
-
|
|
242
|
-
|
|
243
|
-
|
|
244
|
-
|
|
245
|
-
|
|
265
|
+
try {
|
|
266
|
+
const vercel = new VercelService(config);
|
|
267
|
+
const project = await vercel.createProject(projectName);
|
|
268
|
+
spinner.stop(`Vercel project created`);
|
|
269
|
+
|
|
270
|
+
// Configure domain if specified
|
|
271
|
+
if (domain) {
|
|
272
|
+
spinner.start(`Configuring domain: ${domain}...`);
|
|
273
|
+
try {
|
|
274
|
+
await vercel.addDomain(projectName, domain);
|
|
275
|
+
spinner.stop('Domain configured');
|
|
276
|
+
} catch {
|
|
277
|
+
spinner.stop('Domain configuration failed');
|
|
278
|
+
console.log(chalk.yellow(' ⚠️ Could not configure domain. Add it manually in Vercel.'));
|
|
279
|
+
}
|
|
280
|
+
}
|
|
281
|
+
|
|
282
|
+
// Deploy
|
|
283
|
+
spinner.start('Deploying to Vercel...');
|
|
284
|
+
try {
|
|
285
|
+
const deployment = await vercel.deploy(projectPath);
|
|
286
|
+
spinner.stop(`Deployed: ${deployment.url}`);
|
|
287
|
+
} catch {
|
|
288
|
+
spinner.stop('Deployment failed');
|
|
289
|
+
console.log(chalk.yellow(' ⚠️ Could not deploy. Run "vercel" manually later.'));
|
|
290
|
+
}
|
|
291
|
+
} catch (error) {
|
|
292
|
+
spinner.stop('Vercel setup failed');
|
|
293
|
+
console.log(chalk.yellow(' ⚠️ Could not create Vercel project. Check your Vercel token.'));
|
|
246
294
|
}
|
|
247
|
-
|
|
248
|
-
// Deploy
|
|
249
|
-
spinner.start('Deploying to Vercel...');
|
|
250
|
-
const deployment = await vercel.deploy(projectPath);
|
|
251
|
-
spinner.stop(`Deployed: ${deployment.url}`);
|
|
252
295
|
}
|
|
253
296
|
|
|
254
297
|
// Step 6: Generate CLAUDE.md
|
|
@@ -507,7 +507,7 @@ async function recordWithLinux(): Promise<string> {
|
|
|
507
507
|
|
|
508
508
|
async function generatePRD(anthropic: Anthropic, input: PRDInput): Promise<string> {
|
|
509
509
|
const response = await anthropic.messages.create({
|
|
510
|
-
model: 'claude-sonnet-4-
|
|
510
|
+
model: 'claude-sonnet-4-5-20250929',
|
|
511
511
|
max_tokens: 8192,
|
|
512
512
|
messages: [{
|
|
513
513
|
role: 'user',
|
package/src/commands/prd.ts
CHANGED
|
@@ -141,7 +141,7 @@ export async function prdCommand(filePath?: string): Promise<void> {
|
|
|
141
141
|
|
|
142
142
|
async function parsePRD(anthropic: Anthropic, content: string): Promise<ParsedPRD> {
|
|
143
143
|
const response = await anthropic.messages.create({
|
|
144
|
-
model: 'claude-sonnet-4-
|
|
144
|
+
model: 'claude-sonnet-4-5-20250929',
|
|
145
145
|
max_tokens: 4096,
|
|
146
146
|
messages: [{
|
|
147
147
|
role: 'user',
|
|
@@ -308,7 +308,7 @@ async function generateBuildPlan(
|
|
|
308
308
|
designProfile: string
|
|
309
309
|
): Promise<{ phases: Array<{ name: string; tasks: string[] }> }> {
|
|
310
310
|
const response = await anthropic.messages.create({
|
|
311
|
-
model: 'claude-sonnet-4-
|
|
311
|
+
model: 'claude-sonnet-4-5-20250929',
|
|
312
312
|
max_tokens: 4096,
|
|
313
313
|
messages: [{
|
|
314
314
|
role: 'user',
|
|
@@ -362,7 +362,7 @@ async function executeTask(
|
|
|
362
362
|
designProfile: string
|
|
363
363
|
): Promise<void> {
|
|
364
364
|
const response = await anthropic.messages.create({
|
|
365
|
-
model: 'claude-sonnet-4-
|
|
365
|
+
model: 'claude-sonnet-4-5-20250929',
|
|
366
366
|
max_tokens: 8192,
|
|
367
367
|
messages: [{
|
|
368
368
|
role: 'user',
|
package/src/commands/website.ts
CHANGED
|
@@ -6,6 +6,7 @@ import Anthropic from '@anthropic-ai/sdk';
|
|
|
6
6
|
import { execa } from 'execa';
|
|
7
7
|
import { Config } from '../utils/config.js';
|
|
8
8
|
import { textWithVoice } from '../utils/voice.js';
|
|
9
|
+
import { StepTracker, showError, showSuccess, showFileList, ERRORS } from '../utils/display.js';
|
|
9
10
|
|
|
10
11
|
// ============================================================================
|
|
11
12
|
// WEBSITE TEMPLATES
|
|
@@ -254,7 +255,7 @@ async function describeWebsite(anthropic: Anthropic): Promise<WebsiteSpec | null
|
|
|
254
255
|
spinner.start('Understanding your vision...');
|
|
255
256
|
|
|
256
257
|
const response = await anthropic.messages.create({
|
|
257
|
-
model: 'claude-sonnet-4-
|
|
258
|
+
model: 'claude-sonnet-4-5-20250929',
|
|
258
259
|
max_tokens: 2048,
|
|
259
260
|
messages: [{
|
|
260
261
|
role: 'user',
|
|
@@ -350,7 +351,7 @@ async function templateWebsite(anthropic: Anthropic): Promise<WebsiteSpec | null
|
|
|
350
351
|
spinner.start('Customizing template...');
|
|
351
352
|
|
|
352
353
|
const response = await anthropic.messages.create({
|
|
353
|
-
model: 'claude-sonnet-4-
|
|
354
|
+
model: 'claude-sonnet-4-5-20250929',
|
|
354
355
|
max_tokens: 2048,
|
|
355
356
|
messages: [{
|
|
356
357
|
role: 'user',
|
|
@@ -429,7 +430,7 @@ async function cloneDesign(anthropic: Anthropic): Promise<WebsiteSpec | null> {
|
|
|
429
430
|
spinner.start('Analyzing design inspiration...');
|
|
430
431
|
|
|
431
432
|
const response = await anthropic.messages.create({
|
|
432
|
-
model: 'claude-sonnet-4-
|
|
433
|
+
model: 'claude-sonnet-4-5-20250929',
|
|
433
434
|
max_tokens: 2048,
|
|
434
435
|
messages: [{
|
|
435
436
|
role: 'user',
|
|
@@ -497,48 +498,110 @@ async function buildWebsite(
|
|
|
497
498
|
await fs.remove(projectPath);
|
|
498
499
|
}
|
|
499
500
|
|
|
500
|
-
console.log(chalk.cyan(`\n 🏗️ Building ${spec.name}
|
|
501
|
+
console.log(chalk.cyan(`\n 🏗️ Building ${chalk.bold(spec.name)}\n`));
|
|
501
502
|
|
|
502
|
-
|
|
503
|
+
// Initialize step tracker
|
|
504
|
+
const steps = new StepTracker([
|
|
505
|
+
'Create project structure',
|
|
506
|
+
'Install dependencies',
|
|
507
|
+
'Set up UI components',
|
|
508
|
+
'Generate website code',
|
|
509
|
+
'Create additional pages',
|
|
510
|
+
'Initialize git repository',
|
|
511
|
+
]);
|
|
512
|
+
|
|
513
|
+
const createdFiles: string[] = [];
|
|
503
514
|
|
|
504
515
|
// Step 1: Create project
|
|
505
|
-
|
|
516
|
+
steps.start();
|
|
506
517
|
|
|
507
|
-
|
|
508
|
-
'
|
|
509
|
-
|
|
510
|
-
|
|
511
|
-
|
|
512
|
-
|
|
513
|
-
|
|
514
|
-
|
|
515
|
-
|
|
516
|
-
|
|
517
|
-
|
|
518
|
-
|
|
519
|
-
|
|
520
|
-
|
|
521
|
-
|
|
522
|
-
|
|
518
|
+
try {
|
|
519
|
+
await execa('npx', [
|
|
520
|
+
'create-next-app@latest',
|
|
521
|
+
spec.name,
|
|
522
|
+
'--typescript',
|
|
523
|
+
'--tailwind',
|
|
524
|
+
'--eslint',
|
|
525
|
+
'--app',
|
|
526
|
+
'--src-dir',
|
|
527
|
+
'--import-alias', '@/*',
|
|
528
|
+
'--no-git',
|
|
529
|
+
'--yes',
|
|
530
|
+
], {
|
|
531
|
+
cwd: process.cwd(),
|
|
532
|
+
stdio: 'pipe', // Hide output for cleaner display
|
|
533
|
+
});
|
|
534
|
+
steps.complete();
|
|
535
|
+
} catch (error) {
|
|
536
|
+
steps.error();
|
|
537
|
+
showError({
|
|
538
|
+
title: 'Project creation failed',
|
|
539
|
+
message: 'create-next-app could not complete',
|
|
540
|
+
fixes: [
|
|
541
|
+
'Make sure Node.js 18+ is installed',
|
|
542
|
+
'Check your internet connection',
|
|
543
|
+
'Try running manually: npx create-next-app@latest ' + spec.name,
|
|
544
|
+
],
|
|
545
|
+
command: 'npx create-next-app@latest ' + spec.name,
|
|
546
|
+
});
|
|
547
|
+
return;
|
|
548
|
+
}
|
|
549
|
+
|
|
550
|
+
// Verify project was created
|
|
551
|
+
if (!(await fs.pathExists(projectPath))) {
|
|
552
|
+
steps.error();
|
|
553
|
+
showError({
|
|
554
|
+
title: 'Project folder not created',
|
|
555
|
+
message: 'The project directory was not found after creation',
|
|
556
|
+
fixes: [
|
|
557
|
+
'Check if you have write permissions in this folder',
|
|
558
|
+
'Try creating the project in a different location',
|
|
559
|
+
],
|
|
560
|
+
});
|
|
561
|
+
return;
|
|
562
|
+
}
|
|
563
|
+
|
|
564
|
+
// Step 2: Install dependencies
|
|
565
|
+
steps.start();
|
|
523
566
|
|
|
524
|
-
|
|
525
|
-
|
|
526
|
-
|
|
527
|
-
|
|
567
|
+
try {
|
|
568
|
+
await execa('npm', ['install', 'lucide-react'], {
|
|
569
|
+
cwd: projectPath,
|
|
570
|
+
stdio: 'pipe',
|
|
571
|
+
});
|
|
572
|
+
steps.complete();
|
|
573
|
+
} catch (error) {
|
|
574
|
+
steps.error();
|
|
575
|
+
showError({
|
|
576
|
+
...ERRORS.npmFailed,
|
|
577
|
+
command: `cd ${spec.name} && npm install`,
|
|
578
|
+
});
|
|
579
|
+
return;
|
|
580
|
+
}
|
|
528
581
|
|
|
529
|
-
// Install
|
|
530
|
-
|
|
531
|
-
|
|
532
|
-
|
|
533
|
-
|
|
582
|
+
// Step 3: Install shadcn
|
|
583
|
+
steps.start();
|
|
584
|
+
|
|
585
|
+
try {
|
|
586
|
+
await execa('npx', ['shadcn@latest', 'init', '-y', '-d'], {
|
|
587
|
+
cwd: projectPath,
|
|
588
|
+
stdio: 'pipe',
|
|
589
|
+
});
|
|
534
590
|
|
|
535
|
-
|
|
591
|
+
await execa('npx', ['shadcn@latest', 'add', 'button', 'card', 'input', 'badge', '-y'], {
|
|
592
|
+
cwd: projectPath,
|
|
593
|
+
stdio: 'pipe',
|
|
594
|
+
});
|
|
595
|
+
steps.complete();
|
|
596
|
+
} catch (error) {
|
|
597
|
+
steps.skip(); // Not critical, continue anyway
|
|
598
|
+
}
|
|
536
599
|
|
|
537
|
-
// Step
|
|
538
|
-
|
|
600
|
+
// Step 4: Generate pages
|
|
601
|
+
steps.start();
|
|
539
602
|
|
|
540
603
|
const response = await anthropic.messages.create({
|
|
541
|
-
model: 'claude-sonnet-4-
|
|
604
|
+
model: 'claude-sonnet-4-5-20250929',
|
|
542
605
|
max_tokens: 16000,
|
|
543
606
|
messages: [{
|
|
544
607
|
role: 'user',
|
|
@@ -596,7 +659,6 @@ Make it production-quality and visually impressive.`
|
|
|
596
659
|
// Write files
|
|
597
660
|
const fileRegex = /<<<FILE:\s*(.+?)>>>([\s\S]*?)<<<END_FILE>>>/g;
|
|
598
661
|
let match;
|
|
599
|
-
let fileCount = 0;
|
|
600
662
|
|
|
601
663
|
while ((match = fileRegex.exec(text)) !== null) {
|
|
602
664
|
const filePath = path.join(projectPath, match[1].trim());
|
|
@@ -604,38 +666,51 @@ Make it production-quality and visually impressive.`
|
|
|
604
666
|
|
|
605
667
|
await fs.ensureDir(path.dirname(filePath));
|
|
606
668
|
await fs.writeFile(filePath, content);
|
|
607
|
-
|
|
669
|
+
createdFiles.push(match[1].trim());
|
|
608
670
|
}
|
|
609
671
|
|
|
610
|
-
|
|
672
|
+
steps.complete();
|
|
611
673
|
|
|
612
|
-
// Step
|
|
613
|
-
|
|
614
|
-
|
|
615
|
-
await execa('git', ['add', '.'], { cwd: projectPath, reject: false });
|
|
616
|
-
await execa('git', ['commit', '-m', 'Initial website build by CodeBakers'], { cwd: projectPath, reject: false });
|
|
617
|
-
spinner.stop('Git initialized');
|
|
674
|
+
// Step 5: Additional pages (placeholder for now)
|
|
675
|
+
steps.start();
|
|
676
|
+
steps.complete();
|
|
618
677
|
|
|
619
|
-
//
|
|
620
|
-
|
|
621
|
-
|
|
622
|
-
|
|
623
|
-
|
|
624
|
-
|
|
625
|
-
|
|
626
|
-
|
|
627
|
-
|
|
628
|
-
|
|
629
|
-
|
|
630
|
-
|
|
631
|
-
|
|
632
|
-
|
|
633
|
-
|
|
634
|
-
|
|
635
|
-
|
|
636
|
-
|
|
637
|
-
|
|
638
|
-
|
|
678
|
+
// Step 6: Git init
|
|
679
|
+
steps.start();
|
|
680
|
+
|
|
681
|
+
try {
|
|
682
|
+
await execa('git', ['init'], { cwd: projectPath, stdio: 'pipe' });
|
|
683
|
+
await execa('git', ['add', '.'], { cwd: projectPath, stdio: 'pipe' });
|
|
684
|
+
await execa('git', ['commit', '-m', 'Initial website build by CodeBakers'], { cwd: projectPath, stdio: 'pipe' });
|
|
685
|
+
steps.complete();
|
|
686
|
+
} catch (error) {
|
|
687
|
+
steps.skip();
|
|
688
|
+
}
|
|
689
|
+
|
|
690
|
+
// Show created files
|
|
691
|
+
if (createdFiles.length > 0) {
|
|
692
|
+
showFileList('Files created', createdFiles.slice(0, 10));
|
|
693
|
+
if (createdFiles.length > 10) {
|
|
694
|
+
console.log(chalk.dim(` ... and ${createdFiles.length - 10} more files`));
|
|
695
|
+
}
|
|
696
|
+
}
|
|
697
|
+
|
|
698
|
+
// Success message
|
|
699
|
+
showSuccess({
|
|
700
|
+
title: 'Website built successfully!',
|
|
701
|
+
message: spec.description,
|
|
702
|
+
stats: [
|
|
703
|
+
{ label: 'Project', value: spec.name },
|
|
704
|
+
{ label: 'Files created', value: createdFiles.length.toString() },
|
|
705
|
+
{ label: 'Sections', value: spec.sections.length.toString() },
|
|
706
|
+
{ label: 'Build time', value: steps.getElapsedTime() },
|
|
707
|
+
],
|
|
708
|
+
nextSteps: [
|
|
709
|
+
`cd ${spec.name}`,
|
|
710
|
+
'npm run dev',
|
|
711
|
+
],
|
|
712
|
+
command: `cd ${spec.name} && npm run dev`,
|
|
713
|
+
});
|
|
639
714
|
|
|
640
715
|
// Offer to open in browser
|
|
641
716
|
const openDev = await p.confirm({
|
package/src/index.ts
CHANGED
|
@@ -30,7 +30,7 @@ import { integrateCommand, INTEGRATIONS } from './commands/integrate.js';
|
|
|
30
30
|
import { websiteCommand } from './commands/website.js';
|
|
31
31
|
import { parseNaturalLanguage } from './utils/nlp.js';
|
|
32
32
|
|
|
33
|
-
const VERSION = '2.
|
|
33
|
+
const VERSION = '2.5.0';
|
|
34
34
|
|
|
35
35
|
// ASCII art logo
|
|
36
36
|
const logo = `
|