codebakers 2.3.8 → 2.5.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/index.js CHANGED
@@ -1,10 +1,10 @@
1
1
  #!/usr/bin/env node
2
2
  import {
3
3
  prdCommand
4
- } from "./chunk-ND6T4UDY.js";
4
+ } from "./chunk-LANM5XQW.js";
5
5
  import {
6
6
  advisorsCommand
7
- } from "./chunk-YUSDTJD6.js";
7
+ } from "./chunk-D44U3IEA.js";
8
8
  import {
9
9
  Config
10
10
  } from "./chunk-ASIJIQYC.js";
@@ -12,9 +12,8 @@ import {
12
12
  // src/index.ts
13
13
  import { Command } from "commander";
14
14
  import * as p21 from "@clack/prompts";
15
- import chalk20 from "chalk";
15
+ import chalk22 from "chalk";
16
16
  import boxen2 from "boxen";
17
- import gradient from "gradient-string";
18
17
  import * as path16 from "path";
19
18
 
20
19
  // src/utils/updates.ts
@@ -484,9 +483,9 @@ async function resetConfig(config) {
484
483
  // src/commands/init.ts
485
484
  import * as p2 from "@clack/prompts";
486
485
  import chalk2 from "chalk";
487
- import * as fs from "fs-extra";
486
+ import fs from "fs-extra";
488
487
  import * as path from "path";
489
- import { execa as execa3 } from "execa";
488
+ import { execa as execa2 } from "execa";
490
489
 
491
490
  // src/services/github.ts
492
491
  import { Octokit } from "@octokit/rest";
@@ -536,7 +535,7 @@ var GitHubService = class {
536
535
  };
537
536
 
538
537
  // src/services/vercel.ts
539
- import { execa as execa2 } from "execa";
538
+ import { execa } from "execa";
540
539
  var VercelService = class {
541
540
  config;
542
541
  token;
@@ -567,7 +566,7 @@ var VercelService = class {
567
566
  async deploy(projectPath, production = false) {
568
567
  const args2 = ["vercel", "--yes"];
569
568
  if (production) args2.push("--prod");
570
- const result = await execa2("npx", args2, {
569
+ const result = await execa("npx", args2, {
571
570
  cwd: projectPath,
572
571
  env: { ...process.env, VERCEL_TOKEN: this.token }
573
572
  });
@@ -1120,51 +1119,92 @@ Domain: ${domain || "Vercel default"}`,
1120
1119
  await createLocalProject(projectPath, projectConfig);
1121
1120
  spinner16.stop("Local project created");
1122
1121
  spinner16.start("Installing dependencies...");
1122
+ let installSuccess = false;
1123
1123
  try {
1124
- await execa3("npm", ["install"], { cwd: projectPath });
1124
+ await execa2("npm", ["install"], { cwd: projectPath, stdio: "inherit" });
1125
+ installSuccess = true;
1125
1126
  } catch {
1126
1127
  try {
1127
- await execa3("pnpm", ["install"], { cwd: projectPath });
1128
+ await execa2("pnpm", ["install"], { cwd: projectPath, stdio: "inherit" });
1129
+ installSuccess = true;
1128
1130
  } catch {
1129
- await execa3("yarn", ["install"], { cwd: projectPath });
1131
+ try {
1132
+ await execa2("yarn", ["install"], { cwd: projectPath, stdio: "inherit" });
1133
+ installSuccess = true;
1134
+ } catch {
1135
+ }
1130
1136
  }
1131
1137
  }
1132
- spinner16.stop("Dependencies installed");
1138
+ if (installSuccess) {
1139
+ spinner16.stop("Dependencies installed");
1140
+ } else {
1141
+ spinner16.stop("Dependencies installation failed");
1142
+ console.log(chalk2.yellow(' \u26A0\uFE0F Run "npm install" manually in the project folder'));
1143
+ }
1133
1144
  if (services.includes("github")) {
1134
1145
  spinner16.start("Creating GitHub repository...");
1135
- const github = new GitHubService(config);
1136
- const repo = await github.createRepo(projectName, { private: true });
1137
- spinner16.stop(`GitHub repo created: ${repo.html_url}`);
1138
- await execa3("git", ["init"], { cwd: projectPath });
1139
- await execa3("git", ["add", "."], { cwd: projectPath });
1140
- await execa3("git", ["commit", "-m", "Initial commit by CodeBakers"], { cwd: projectPath });
1141
- await execa3("git", ["remote", "add", "origin", repo.clone_url], { cwd: projectPath });
1142
- await execa3("git", ["push", "-u", "origin", "main"], { cwd: projectPath });
1146
+ try {
1147
+ const github = new GitHubService(config);
1148
+ const repo = await github.createRepo(projectName, { private: true });
1149
+ spinner16.stop(`GitHub repo created: ${repo.html_url}`);
1150
+ try {
1151
+ await execa2("git", ["init"], { cwd: projectPath });
1152
+ await execa2("git", ["add", "."], { cwd: projectPath });
1153
+ await execa2("git", ["commit", "-m", "Initial commit by CodeBakers"], { cwd: projectPath });
1154
+ await execa2("git", ["remote", "add", "origin", repo.clone_url], { cwd: projectPath });
1155
+ await execa2("git", ["push", "-u", "origin", "main"], { cwd: projectPath });
1156
+ } catch (gitError) {
1157
+ console.log(chalk2.yellow(" \u26A0\uFE0F Git push failed. You can push manually later."));
1158
+ }
1159
+ } catch (error) {
1160
+ spinner16.stop("GitHub setup failed");
1161
+ console.log(chalk2.yellow(" \u26A0\uFE0F Could not create GitHub repo. Check your GitHub token."));
1162
+ }
1143
1163
  }
1144
1164
  if (services.includes("supabase")) {
1145
1165
  spinner16.start("Creating Supabase project...");
1146
- const supabase = new SupabaseService(config);
1147
- const project = await supabase.createProject(projectName);
1148
- spinner16.stop(`Supabase project created: ${project.name}`);
1149
- await fs.writeJson(
1150
- path.join(projectPath, ".codebakers", "supabase.json"),
1151
- { projectId: project.id, projectUrl: project.api_url },
1152
- { spaces: 2 }
1153
- );
1166
+ try {
1167
+ const supabase = new SupabaseService(config);
1168
+ const project = await supabase.createProject(projectName);
1169
+ spinner16.stop(`Supabase project created: ${project.name}`);
1170
+ await fs.writeJson(
1171
+ path.join(projectPath, ".codebakers", "supabase.json"),
1172
+ { projectId: project.id, projectUrl: project.api_url },
1173
+ { spaces: 2 }
1174
+ );
1175
+ } catch (error) {
1176
+ spinner16.stop("Supabase setup failed");
1177
+ console.log(chalk2.yellow(" \u26A0\uFE0F Could not create Supabase project. Check your Supabase token."));
1178
+ }
1154
1179
  }
1155
1180
  if (services.includes("vercel")) {
1156
1181
  spinner16.start("Creating Vercel project...");
1157
- const vercel = new VercelService(config);
1158
- const project = await vercel.createProject(projectName);
1159
- spinner16.stop(`Vercel project created`);
1160
- if (domain) {
1161
- spinner16.start(`Configuring domain: ${domain}...`);
1162
- await vercel.addDomain(projectName, domain);
1163
- spinner16.stop("Domain configured");
1182
+ try {
1183
+ const vercel = new VercelService(config);
1184
+ const project = await vercel.createProject(projectName);
1185
+ spinner16.stop(`Vercel project created`);
1186
+ if (domain) {
1187
+ spinner16.start(`Configuring domain: ${domain}...`);
1188
+ try {
1189
+ await vercel.addDomain(projectName, domain);
1190
+ spinner16.stop("Domain configured");
1191
+ } catch {
1192
+ spinner16.stop("Domain configuration failed");
1193
+ console.log(chalk2.yellow(" \u26A0\uFE0F Could not configure domain. Add it manually in Vercel."));
1194
+ }
1195
+ }
1196
+ spinner16.start("Deploying to Vercel...");
1197
+ try {
1198
+ const deployment = await vercel.deploy(projectPath);
1199
+ spinner16.stop(`Deployed: ${deployment.url}`);
1200
+ } catch {
1201
+ spinner16.stop("Deployment failed");
1202
+ console.log(chalk2.yellow(' \u26A0\uFE0F Could not deploy. Run "vercel" manually later.'));
1203
+ }
1204
+ } catch (error) {
1205
+ spinner16.stop("Vercel setup failed");
1206
+ console.log(chalk2.yellow(" \u26A0\uFE0F Could not create Vercel project. Check your Vercel token."));
1164
1207
  }
1165
- spinner16.start("Deploying to Vercel...");
1166
- const deployment = await vercel.deploy(projectPath);
1167
- spinner16.stop(`Deployed: ${deployment.url}`);
1168
1208
  }
1169
1209
  spinner16.start("Generating CLAUDE.md...");
1170
1210
  const claudeMd = generateClaudeMd(projectConfig);
@@ -1427,7 +1467,7 @@ coverage/
1427
1467
  async function setupGitHooks(projectPath) {
1428
1468
  const hooksDir = path.join(projectPath, ".git", "hooks");
1429
1469
  if (!await fs.pathExists(path.join(projectPath, ".git"))) {
1430
- await execa3("git", ["init"], { cwd: projectPath });
1470
+ await execa2("git", ["init"], { cwd: projectPath });
1431
1471
  }
1432
1472
  await fs.ensureDir(hooksDir);
1433
1473
  const preCommitHook = `#!/bin/sh
@@ -1453,10 +1493,10 @@ echo "\u2713 CodeBakers check passed"
1453
1493
  // src/commands/code.ts
1454
1494
  import * as p6 from "@clack/prompts";
1455
1495
  import chalk6 from "chalk";
1456
- import * as fs6 from "fs-extra";
1496
+ import fs6 from "fs-extra";
1457
1497
  import * as path5 from "path";
1458
1498
  import Anthropic from "@anthropic-ai/sdk";
1459
- import { execa as execa6 } from "execa";
1499
+ import { execa as execa5 } from "execa";
1460
1500
 
1461
1501
  // src/patterns/loader.ts
1462
1502
  import * as fs2 from "fs-extra";
@@ -1761,7 +1801,7 @@ async function loadPatterns(config) {
1761
1801
  // src/commands/check.ts
1762
1802
  import * as p3 from "@clack/prompts";
1763
1803
  import chalk3 from "chalk";
1764
- import * as fs3 from "fs-extra";
1804
+ import fs3 from "fs-extra";
1765
1805
  import * as path3 from "path";
1766
1806
  import glob from "fast-glob";
1767
1807
  var RULES = [
@@ -2059,8 +2099,8 @@ async function autoFix(violations) {
2059
2099
  // src/utils/voice.ts
2060
2100
  import * as p4 from "@clack/prompts";
2061
2101
  import chalk4 from "chalk";
2062
- import * as fs4 from "fs-extra";
2063
- import { execa as execa4 } from "execa";
2102
+ import fs4 from "fs-extra";
2103
+ import { execa as execa3 } from "execa";
2064
2104
  var voiceAvailable = null;
2065
2105
  async function checkVoiceAvailability() {
2066
2106
  if (voiceAvailable !== null) return voiceAvailable;
@@ -2068,14 +2108,14 @@ async function checkVoiceAvailability() {
2068
2108
  if (process.platform === "win32") {
2069
2109
  voiceAvailable = true;
2070
2110
  } else if (process.platform === "darwin") {
2071
- await execa4("which", ["sox"], { reject: true });
2111
+ await execa3("which", ["sox"], { reject: true });
2072
2112
  voiceAvailable = true;
2073
2113
  } else {
2074
2114
  try {
2075
- await execa4("which", ["sox"], { reject: true });
2115
+ await execa3("which", ["sox"], { reject: true });
2076
2116
  voiceAvailable = true;
2077
2117
  } catch {
2078
- await execa4("which", ["arecord"], { reject: true });
2118
+ await execa3("which", ["arecord"], { reject: true });
2079
2119
  voiceAvailable = true;
2080
2120
  }
2081
2121
  }
@@ -2186,14 +2226,14 @@ async function getVoiceInput(prompt) {
2186
2226
  async function playBeep() {
2187
2227
  try {
2188
2228
  if (process.platform === "win32") {
2189
- await execa4("powershell", ["-Command", "[console]::beep(800,200)"], { reject: false });
2229
+ await execa3("powershell", ["-Command", "[console]::beep(800,200)"], { reject: false });
2190
2230
  } else if (process.platform === "darwin") {
2191
- await execa4("afplay", ["/System/Library/Sounds/Tink.aiff"], { reject: false });
2231
+ await execa3("afplay", ["/System/Library/Sounds/Tink.aiff"], { reject: false });
2192
2232
  } else {
2193
2233
  try {
2194
- await execa4("beep", ["-f", "800", "-l", "200"], { reject: false });
2234
+ await execa3("beep", ["-f", "800", "-l", "200"], { reject: false });
2195
2235
  } catch {
2196
- await execa4("paplay", ["/usr/share/sounds/freedesktop/stereo/message.oga"], { reject: false });
2236
+ await execa3("paplay", ["/usr/share/sounds/freedesktop/stereo/message.oga"], { reject: false });
2197
2237
  }
2198
2238
  }
2199
2239
  } catch {
@@ -2216,7 +2256,7 @@ try {
2216
2256
  }
2217
2257
  `;
2218
2258
  try {
2219
- const result = await execa4("powershell", ["-Command", psScript], {
2259
+ const result = await execa3("powershell", ["-Command", psScript], {
2220
2260
  timeout: 15e3
2221
2261
  });
2222
2262
  return result.stdout.trim();
@@ -2227,7 +2267,7 @@ try {
2227
2267
  async function recordWithMacOS() {
2228
2268
  const tempFile = `/tmp/codebakers-voice-${Date.now()}.wav`;
2229
2269
  try {
2230
- await execa4("sox", [
2270
+ await execa3("sox", [
2231
2271
  "-d",
2232
2272
  // default input
2233
2273
  "-r",
@@ -2264,7 +2304,7 @@ async function recordWithLinux() {
2264
2304
  const tempFile = `/tmp/codebakers-voice-${Date.now()}.wav`;
2265
2305
  try {
2266
2306
  try {
2267
- await execa4("sox", [
2307
+ await execa3("sox", [
2268
2308
  "-d",
2269
2309
  tempFile,
2270
2310
  "rate",
@@ -2283,7 +2323,7 @@ async function recordWithLinux() {
2283
2323
  "30"
2284
2324
  ], { timeout: 35e3 });
2285
2325
  } catch {
2286
- await execa4("arecord", [
2326
+ await execa3("arecord", [
2287
2327
  "-f",
2288
2328
  "S16_LE",
2289
2329
  "-r",
@@ -2304,7 +2344,7 @@ async function recordWithLinux() {
2304
2344
  async function transcribeWithWhisper(audioFile) {
2305
2345
  try {
2306
2346
  const outputBase = audioFile.replace(".wav", "");
2307
- await execa4("whisper", [
2347
+ await execa3("whisper", [
2308
2348
  audioFile,
2309
2349
  "--language",
2310
2350
  "en",
@@ -2328,23 +2368,23 @@ async function transcribeWithWhisper(audioFile) {
2328
2368
  // src/utils/files.ts
2329
2369
  import * as p5 from "@clack/prompts";
2330
2370
  import chalk5 from "chalk";
2331
- import * as fs5 from "fs-extra";
2371
+ import fs5 from "fs-extra";
2332
2372
  import * as path4 from "path";
2333
- import { execa as execa5 } from "execa";
2373
+ import { execa as execa4 } from "execa";
2334
2374
  async function readClipboard() {
2335
2375
  try {
2336
2376
  if (process.platform === "win32") {
2337
- const result = await execa5("powershell", ["-Command", "Get-Clipboard"], { timeout: 5e3 });
2377
+ const result = await execa4("powershell", ["-Command", "Get-Clipboard"], { timeout: 5e3 });
2338
2378
  return result.stdout;
2339
2379
  } else if (process.platform === "darwin") {
2340
- const result = await execa5("pbpaste", [], { timeout: 5e3 });
2380
+ const result = await execa4("pbpaste", [], { timeout: 5e3 });
2341
2381
  return result.stdout;
2342
2382
  } else {
2343
2383
  try {
2344
- const result = await execa5("xclip", ["-selection", "clipboard", "-o"], { timeout: 5e3 });
2384
+ const result = await execa4("xclip", ["-selection", "clipboard", "-o"], { timeout: 5e3 });
2345
2385
  return result.stdout;
2346
2386
  } catch {
2347
- const result = await execa5("xsel", ["--clipboard", "--output"], { timeout: 5e3 });
2387
+ const result = await execa4("xsel", ["--clipboard", "--output"], { timeout: 5e3 });
2348
2388
  return result.stdout;
2349
2389
  }
2350
2390
  }
@@ -2352,7 +2392,7 @@ async function readClipboard() {
2352
2392
  return null;
2353
2393
  }
2354
2394
  }
2355
- async function readFile5(filePath) {
2395
+ async function readFile2(filePath) {
2356
2396
  try {
2357
2397
  let cleanPath = filePath.trim();
2358
2398
  if (cleanPath.startsWith('"') && cleanPath.endsWith('"') || cleanPath.startsWith("'") && cleanPath.endsWith("'")) {
@@ -2460,7 +2500,7 @@ async function readFile5(filePath) {
2460
2500
  }
2461
2501
  async function extractPdfText(filePath) {
2462
2502
  try {
2463
- const result = await execa5("pdftotext", [filePath, "-"], { timeout: 3e4 });
2503
+ const result = await execa4("pdftotext", [filePath, "-"], { timeout: 3e4 });
2464
2504
  return result.stdout;
2465
2505
  } catch {
2466
2506
  return null;
@@ -2669,7 +2709,7 @@ async function codeCommand(prompt, options = {}) {
2669
2709
  \u{1F4CB} Read ${clipContent.length} characters from clipboard
2670
2710
  `));
2671
2711
  if (await fs6.pathExists(clipContent.trim())) {
2672
- const file = await readFile5(clipContent.trim());
2712
+ const file = await readFile2(clipContent.trim());
2673
2713
  if (file) {
2674
2714
  fileContext = formatFilesForContext([file]);
2675
2715
  console.log(chalk6.green(`\u{1F4C4} Loaded file: ${file.name}
@@ -2721,7 +2761,7 @@ ${clipContent}
2721
2761
  continue;
2722
2762
  }
2723
2763
  } else if (await fs6.pathExists(userInput)) {
2724
- const file = await readFile5(userInput);
2764
+ const file = await readFile2(userInput);
2725
2765
  if (file) {
2726
2766
  fileContext = formatFilesForContext([file]);
2727
2767
  console.log(chalk6.green(`
@@ -2755,7 +2795,7 @@ async function processUserInput(userInput, messages, anthropic, systemPrompt, pr
2755
2795
  try {
2756
2796
  spinner16.start("Thinking...");
2757
2797
  const response = await anthropic.messages.create({
2758
- model: "claude-sonnet-4-20250514",
2798
+ model: "claude-sonnet-4-5-20250929",
2759
2799
  max_tokens: 8192,
2760
2800
  system: systemPrompt,
2761
2801
  messages: messages.map((m) => ({
@@ -2943,7 +2983,7 @@ async function executeAction(action, spinner16) {
2943
2983
  case "RUN_COMMAND": {
2944
2984
  spinner16.message(`Running: ${action.command}`);
2945
2985
  const [cmd, ...args2] = action.command.split(" ");
2946
- await execa6(cmd, args2, { cwd, stdio: "pipe" });
2986
+ await execa5(cmd, args2, { cwd, stdio: "pipe" });
2947
2987
  break;
2948
2988
  }
2949
2989
  case "DELETE_FILE": {
@@ -3172,7 +3212,7 @@ ${content}
3172
3212
 
3173
3213
  Output only the fixed file content, no explanation.`;
3174
3214
  const response = await anthropic.messages.create({
3175
- model: "claude-sonnet-4-20250514",
3215
+ model: "claude-sonnet-4-5-20250929",
3176
3216
  max_tokens: 8192,
3177
3217
  system: systemPrompt,
3178
3218
  messages: [{ role: "user", content: fixPrompt }]
@@ -3187,8 +3227,8 @@ Output only the fixed file content, no explanation.`;
3187
3227
  // src/commands/deploy.ts
3188
3228
  import * as p7 from "@clack/prompts";
3189
3229
  import chalk7 from "chalk";
3190
- import { execa as execa7 } from "execa";
3191
- import * as fs7 from "fs-extra";
3230
+ import { execa as execa6 } from "execa";
3231
+ import fs7 from "fs-extra";
3192
3232
  import * as path6 from "path";
3193
3233
  import Anthropic2 from "@anthropic-ai/sdk";
3194
3234
  async function deployCommand(options = {}) {
@@ -3262,7 +3302,7 @@ async function deployCommand(options = {}) {
3262
3302
  }
3263
3303
  spinner16.start("Running TypeScript check...");
3264
3304
  try {
3265
- await execa7("npx", ["tsc", "--noEmit"], { cwd: process.cwd() });
3305
+ await execa6("npx", ["tsc", "--noEmit"], { cwd: process.cwd() });
3266
3306
  spinner16.stop("TypeScript check passed");
3267
3307
  } catch (error) {
3268
3308
  spinner16.stop("");
@@ -3287,12 +3327,12 @@ async function deployCommand(options = {}) {
3287
3327
  spinner16.start("Building project...");
3288
3328
  try {
3289
3329
  try {
3290
- await execa7("npm", ["run", "build"], { cwd: process.cwd() });
3330
+ await execa6("npm", ["run", "build"], { cwd: process.cwd() });
3291
3331
  } catch {
3292
3332
  try {
3293
- await execa7("pnpm", ["build"], { cwd: process.cwd() });
3333
+ await execa6("pnpm", ["build"], { cwd: process.cwd() });
3294
3334
  } catch {
3295
- await execa7("yarn", ["build"], { cwd: process.cwd() });
3335
+ await execa6("yarn", ["build"], { cwd: process.cwd() });
3296
3336
  }
3297
3337
  }
3298
3338
  spinner16.stop("Build successful");
@@ -3312,7 +3352,7 @@ async function deployCommand(options = {}) {
3312
3352
  if (fixed) {
3313
3353
  spinner16.start("Retrying build...");
3314
3354
  try {
3315
- await execa7("pnpm", ["build"], { cwd: process.cwd() });
3355
+ await execa6("pnpm", ["build"], { cwd: process.cwd() });
3316
3356
  spinner16.stop("Build successful");
3317
3357
  } catch {
3318
3358
  spinner16.stop("Build still failing");
@@ -3329,7 +3369,7 @@ async function deployCommand(options = {}) {
3329
3369
  }
3330
3370
  }
3331
3371
  spinner16.start("Checking for uncommitted changes...");
3332
- const { stdout: gitStatus } = await execa7("git", ["status", "--porcelain"], { cwd: process.cwd() });
3372
+ const { stdout: gitStatus } = await execa6("git", ["status", "--porcelain"], { cwd: process.cwd() });
3333
3373
  if (gitStatus.trim()) {
3334
3374
  spinner16.stop("");
3335
3375
  const commit = await p7.confirm({
@@ -3343,10 +3383,10 @@ async function deployCommand(options = {}) {
3343
3383
  initialValue: "Pre-deploy changes"
3344
3384
  });
3345
3385
  if (!p7.isCancel(message)) {
3346
- await execa7("git", ["add", "."], { cwd: process.cwd() });
3347
- await execa7("git", ["commit", "-m", message], { cwd: process.cwd() });
3386
+ await execa6("git", ["add", "."], { cwd: process.cwd() });
3387
+ await execa6("git", ["commit", "-m", message], { cwd: process.cwd() });
3348
3388
  spinner16.start("Pushing to GitHub...");
3349
- await execa7("git", ["push"], { cwd: process.cwd() });
3389
+ await execa6("git", ["push"], { cwd: process.cwd() });
3350
3390
  spinner16.stop("Pushed to GitHub");
3351
3391
  }
3352
3392
  }
@@ -3367,7 +3407,7 @@ ${chalk7.bold("Type:")} ${deployType}
3367
3407
  ${chalk7.bold("Time:")} ${(/* @__PURE__ */ new Date()).toLocaleTimeString()}
3368
3408
 
3369
3409
  ${chalk7.dim("View in Vercel Dashboard:")}
3370
- ${chalk7.dim(deployment.dashboardUrl || "https://vercel.com/dashboard")}
3410
+ ${chalk7.dim("https://vercel.com/dashboard")}
3371
3411
  `));
3372
3412
  } catch (error) {
3373
3413
  spinner16.stop("");
@@ -3416,7 +3456,7 @@ ${content}
3416
3456
 
3417
3457
  Output ONLY the corrected file content, no explanations. Keep all existing functionality.`;
3418
3458
  const response = await anthropic.messages.create({
3419
- model: "claude-sonnet-4-20250514",
3459
+ model: "claude-sonnet-4-5-20250929",
3420
3460
  max_tokens: 8192,
3421
3461
  messages: [{ role: "user", content: prompt }]
3422
3462
  });
@@ -3430,7 +3470,7 @@ Output ONLY the corrected file content, no explanations. Keep all existing funct
3430
3470
  }
3431
3471
  async function fixTypeScriptErrors(config) {
3432
3472
  try {
3433
- const { stderr } = await execa7("npx", ["tsc", "--noEmit"], {
3473
+ const { stderr } = await execa6("npx", ["tsc", "--noEmit"], {
3434
3474
  cwd: process.cwd(),
3435
3475
  reject: false
3436
3476
  });
@@ -3463,7 +3503,7 @@ ${content}
3463
3503
 
3464
3504
  Output ONLY the corrected file content, no explanations.`;
3465
3505
  const response = await anthropic.messages.create({
3466
- model: "claude-sonnet-4-20250514",
3506
+ model: "claude-sonnet-4-5-20250929",
3467
3507
  max_tokens: 8192,
3468
3508
  messages: [{ role: "user", content: prompt }]
3469
3509
  });
@@ -3508,7 +3548,7 @@ ${content}
3508
3548
  Output ONLY the corrected file content, no explanations.`;
3509
3549
  try {
3510
3550
  const response = await anthropic.messages.create({
3511
- model: "claude-sonnet-4-20250514",
3551
+ model: "claude-sonnet-4-5-20250929",
3512
3552
  max_tokens: 8192,
3513
3553
  messages: [{ role: "user", content: prompt }]
3514
3554
  });
@@ -3542,7 +3582,7 @@ async function connectCommand(service) {
3542
3582
  // src/commands/status.ts
3543
3583
  import * as p8 from "@clack/prompts";
3544
3584
  import chalk8 from "chalk";
3545
- import * as fs8 from "fs-extra";
3585
+ import fs8 from "fs-extra";
3546
3586
  import * as path7 from "path";
3547
3587
  async function statusCommand() {
3548
3588
  const config = new Config();
@@ -4096,7 +4136,7 @@ async function learnCommand() {
4096
4136
  // src/commands/security.ts
4097
4137
  import * as p11 from "@clack/prompts";
4098
4138
  import chalk11 from "chalk";
4099
- import * as fs9 from "fs-extra";
4139
+ import fs9 from "fs-extra";
4100
4140
  import glob2 from "fast-glob";
4101
4141
  import * as path8 from "path";
4102
4142
  async function securityCommand() {
@@ -4176,7 +4216,7 @@ function displaySecurityScore(score) {
4176
4216
  // src/commands/generate.ts
4177
4217
  import * as p12 from "@clack/prompts";
4178
4218
  import chalk12 from "chalk";
4179
- import * as fs10 from "fs-extra";
4219
+ import fs10 from "fs-extra";
4180
4220
  import * as path9 from "path";
4181
4221
  async function generateCommand(type) {
4182
4222
  p12.intro(chalk12.bgCyan.black(" Generate "));
@@ -4360,7 +4400,7 @@ async function fixCommand() {
4360
4400
  // src/commands/design.ts
4361
4401
  import * as p14 from "@clack/prompts";
4362
4402
  import chalk14 from "chalk";
4363
- import * as fs11 from "fs-extra";
4403
+ import fs11 from "fs-extra";
4364
4404
  import * as path10 from "path";
4365
4405
  var DESIGN_PROFILES = {
4366
4406
  minimal: {
@@ -4616,8 +4656,8 @@ async function viewSettings() {
4616
4656
  // src/commands/migrate.ts
4617
4657
  import * as p15 from "@clack/prompts";
4618
4658
  import chalk15 from "chalk";
4619
- import { execa as execa8 } from "execa";
4620
- import * as fs12 from "fs-extra";
4659
+ import { execa as execa7 } from "execa";
4660
+ import fs12 from "fs-extra";
4621
4661
  import * as path11 from "path";
4622
4662
  async function migrateCommand(options = {}) {
4623
4663
  const config = new Config();
@@ -4684,13 +4724,13 @@ async function checkMigrationStatus(tool) {
4684
4724
  let result;
4685
4725
  switch (tool) {
4686
4726
  case "drizzle":
4687
- result = await execa8("npx", ["drizzle-kit", "check"], { cwd: process.cwd(), reject: false });
4727
+ result = await execa7("npx", ["drizzle-kit", "check"], { cwd: process.cwd(), reject: false });
4688
4728
  break;
4689
4729
  case "prisma":
4690
- result = await execa8("npx", ["prisma", "migrate", "status"], { cwd: process.cwd(), reject: false });
4730
+ result = await execa7("npx", ["prisma", "migrate", "status"], { cwd: process.cwd(), reject: false });
4691
4731
  break;
4692
4732
  case "supabase":
4693
- result = await execa8("npx", ["supabase", "migration", "list"], { cwd: process.cwd(), reject: false });
4733
+ result = await execa7("npx", ["supabase", "migration", "list"], { cwd: process.cwd(), reject: false });
4694
4734
  break;
4695
4735
  }
4696
4736
  spinner16.stop("Status check complete");
@@ -4718,13 +4758,13 @@ async function generateMigration(tool) {
4718
4758
  let result;
4719
4759
  switch (tool) {
4720
4760
  case "drizzle":
4721
- result = await execa8("npx", ["drizzle-kit", "generate", "--name", name], { cwd: process.cwd(), reject: false });
4761
+ result = await execa7("npx", ["drizzle-kit", "generate", "--name", name], { cwd: process.cwd(), reject: false });
4722
4762
  break;
4723
4763
  case "prisma":
4724
- result = await execa8("npx", ["prisma", "migrate", "dev", "--name", name, "--create-only"], { cwd: process.cwd(), reject: false });
4764
+ result = await execa7("npx", ["prisma", "migrate", "dev", "--name", name, "--create-only"], { cwd: process.cwd(), reject: false });
4725
4765
  break;
4726
4766
  case "supabase":
4727
- result = await execa8("npx", ["supabase", "migration", "new", name], { cwd: process.cwd(), reject: false });
4767
+ result = await execa7("npx", ["supabase", "migration", "new", name], { cwd: process.cwd(), reject: false });
4728
4768
  break;
4729
4769
  }
4730
4770
  spinner16.stop("Migration generated");
@@ -4744,20 +4784,20 @@ async function pushMigration(tool) {
4744
4784
  let migrationSql = "";
4745
4785
  switch (tool) {
4746
4786
  case "drizzle":
4747
- result = await execa8("npx", ["drizzle-kit", "push"], {
4787
+ result = await execa7("npx", ["drizzle-kit", "push"], {
4748
4788
  cwd: process.cwd(),
4749
4789
  reject: false,
4750
4790
  env: { ...process.env }
4751
4791
  });
4752
4792
  break;
4753
4793
  case "prisma":
4754
- result = await execa8("npx", ["prisma", "db", "push"], {
4794
+ result = await execa7("npx", ["prisma", "db", "push"], {
4755
4795
  cwd: process.cwd(),
4756
4796
  reject: false
4757
4797
  });
4758
4798
  break;
4759
4799
  case "supabase":
4760
- result = await execa8("npx", ["supabase", "db", "push"], {
4800
+ result = await execa7("npx", ["supabase", "db", "push"], {
4761
4801
  cwd: process.cwd(),
4762
4802
  reject: false
4763
4803
  });
@@ -4841,13 +4881,13 @@ async function pullSchema(tool) {
4841
4881
  let result;
4842
4882
  switch (tool) {
4843
4883
  case "drizzle":
4844
- result = await execa8("npx", ["drizzle-kit", "introspect"], { cwd: process.cwd(), reject: false });
4884
+ result = await execa7("npx", ["drizzle-kit", "introspect"], { cwd: process.cwd(), reject: false });
4845
4885
  break;
4846
4886
  case "prisma":
4847
- result = await execa8("npx", ["prisma", "db", "pull"], { cwd: process.cwd(), reject: false });
4887
+ result = await execa7("npx", ["prisma", "db", "pull"], { cwd: process.cwd(), reject: false });
4848
4888
  break;
4849
4889
  case "supabase":
4850
- result = await execa8("npx", ["supabase", "db", "pull"], { cwd: process.cwd(), reject: false });
4890
+ result = await execa7("npx", ["supabase", "db", "pull"], { cwd: process.cwd(), reject: false });
4851
4891
  break;
4852
4892
  }
4853
4893
  spinner16.stop("Schema pulled");
@@ -4873,7 +4913,7 @@ async function extractMigrationSQL(tool, errorOutput) {
4873
4913
  return latestMigration;
4874
4914
  }
4875
4915
  }
4876
- const result = await execa8("npx", ["drizzle-kit", "generate", "--sql"], {
4916
+ const result = await execa7("npx", ["drizzle-kit", "generate", "--sql"], {
4877
4917
  cwd,
4878
4918
  reject: false
4879
4919
  });
@@ -4922,17 +4962,17 @@ async function copyToClipboard(text17) {
4922
4962
  try {
4923
4963
  const platform = process.platform;
4924
4964
  if (platform === "win32") {
4925
- const proc = await execa8("clip", { input: text17, reject: false });
4965
+ const proc = await execa7("clip", { input: text17, reject: false });
4926
4966
  return proc.exitCode === 0;
4927
4967
  } else if (platform === "darwin") {
4928
- const proc = await execa8("pbcopy", { input: text17, reject: false });
4968
+ const proc = await execa7("pbcopy", { input: text17, reject: false });
4929
4969
  return proc.exitCode === 0;
4930
4970
  } else {
4931
4971
  try {
4932
- const proc = await execa8("xclip", ["-selection", "clipboard"], { input: text17, reject: false });
4972
+ const proc = await execa7("xclip", ["-selection", "clipboard"], { input: text17, reject: false });
4933
4973
  return proc.exitCode === 0;
4934
4974
  } catch {
4935
- const proc = await execa8("xsel", ["--clipboard", "--input"], { input: text17, reject: false });
4975
+ const proc = await execa7("xsel", ["--clipboard", "--input"], { input: text17, reject: false });
4936
4976
  return proc.exitCode === 0;
4937
4977
  }
4938
4978
  }
@@ -4944,9 +4984,10 @@ async function copyToClipboard(text17) {
4944
4984
  // src/commands/prd-maker.ts
4945
4985
  import * as p16 from "@clack/prompts";
4946
4986
  import chalk16 from "chalk";
4947
- import * as fs13 from "fs-extra";
4987
+ import fs13 from "fs-extra";
4948
4988
  import * as path12 from "path";
4949
4989
  import Anthropic3 from "@anthropic-ai/sdk";
4990
+ import { execa as execa8 } from "execa";
4950
4991
  async function prdMakerCommand() {
4951
4992
  const config = new Config();
4952
4993
  if (!config.isConfigured()) {
@@ -5041,10 +5082,10 @@ async function prdMakerCommand() {
5041
5082
  return;
5042
5083
  }
5043
5084
  if (nextStep === "build") {
5044
- const { prdCommand: prdCommand2 } = await import("./prd-AIEY63YY.js");
5085
+ const { prdCommand: prdCommand2 } = await import("./prd-RYITSL6Q.js");
5045
5086
  await prdCommand2(filepath);
5046
5087
  } else if (nextStep === "advisors") {
5047
- const { advisorsCommand: advisorsCommand2 } = await import("./advisors-GGUCFS4E.js");
5088
+ const { advisorsCommand: advisorsCommand2 } = await import("./advisors-RWRTSJRR.js");
5048
5089
  await advisorsCommand2();
5049
5090
  }
5050
5091
  }
@@ -5175,7 +5216,7 @@ async function conductPRDInterview(inputMethod) {
5175
5216
  }
5176
5217
  async function checkVoiceAvailability2() {
5177
5218
  try {
5178
- await execa("sox", ["--version"], { reject: true });
5219
+ await execa8("sox", ["--version"], { reject: true });
5179
5220
  return true;
5180
5221
  } catch {
5181
5222
  try {
@@ -5183,7 +5224,7 @@ async function checkVoiceAvailability2() {
5183
5224
  return true;
5184
5225
  }
5185
5226
  if (process.platform === "darwin") {
5186
- await execa("which", ["say"], { reject: true });
5227
+ await execa8("which", ["say"], { reject: true });
5187
5228
  return true;
5188
5229
  }
5189
5230
  } catch {
@@ -5261,7 +5302,7 @@ $result = $recognizer.Recognize()
5261
5302
  if ($result) { Write-Output $result.Text }
5262
5303
  `;
5263
5304
  try {
5264
- const result = await execa("powershell", ["-Command", psScript], {
5305
+ const result = await execa8("powershell", ["-Command", psScript], {
5265
5306
  timeout: 3e4
5266
5307
  // 30 second timeout
5267
5308
  });
@@ -5274,7 +5315,7 @@ async function recordWithMacOS2() {
5274
5315
  const tempFile = `/tmp/codebakers-voice-${Date.now()}.wav`;
5275
5316
  try {
5276
5317
  console.log(chalk16.dim(" Recording for up to 10 seconds..."));
5277
- await execa("sox", [
5318
+ await execa8("sox", [
5278
5319
  "-d",
5279
5320
  // default input device
5280
5321
  "-r",
@@ -5298,7 +5339,7 @@ async function recordWithMacOS2() {
5298
5339
  // stop on silence
5299
5340
  ], { timeout: 15e3 });
5300
5341
  try {
5301
- const result = await execa("whisper", [tempFile, "--language", "en", "--output_format", "txt"], {
5342
+ const result = await execa8("whisper", [tempFile, "--language", "en", "--output_format", "txt"], {
5302
5343
  timeout: 3e4
5303
5344
  });
5304
5345
  const txtFile = tempFile.replace(".wav", ".txt");
@@ -5319,7 +5360,7 @@ async function recordWithLinux2() {
5319
5360
  const tempFile = `/tmp/codebakers-voice-${Date.now()}.wav`;
5320
5361
  try {
5321
5362
  try {
5322
- await execa("sox", [
5363
+ await execa8("sox", [
5323
5364
  "-d",
5324
5365
  tempFile,
5325
5366
  "rate",
@@ -5335,7 +5376,7 @@ async function recordWithLinux2() {
5335
5376
  "1%"
5336
5377
  ], { timeout: 15e3 });
5337
5378
  } catch {
5338
- await execa("arecord", [
5379
+ await execa8("arecord", [
5339
5380
  "-f",
5340
5381
  "S16_LE",
5341
5382
  "-r",
@@ -5348,7 +5389,7 @@ async function recordWithLinux2() {
5348
5389
  ], { timeout: 15e3 });
5349
5390
  }
5350
5391
  try {
5351
- const result = await execa("whisper", [tempFile, "--language", "en", "--output_format", "txt"], {
5392
+ const result = await execa8("whisper", [tempFile, "--language", "en", "--output_format", "txt"], {
5352
5393
  timeout: 3e4
5353
5394
  });
5354
5395
  const txtFile = tempFile.replace(".wav", ".txt");
@@ -5367,7 +5408,7 @@ async function recordWithLinux2() {
5367
5408
  }
5368
5409
  async function generatePRD(anthropic, input) {
5369
5410
  const response = await anthropic.messages.create({
5370
- model: "claude-sonnet-4-20250514",
5411
+ model: "claude-sonnet-4-5-20250929",
5371
5412
  max_tokens: 8192,
5372
5413
  messages: [{
5373
5414
  role: "user",
@@ -5448,7 +5489,7 @@ Make it professional, detailed, and actionable. This should be ready to hand off
5448
5489
  // src/commands/build.ts
5449
5490
  import * as p17 from "@clack/prompts";
5450
5491
  import chalk17 from "chalk";
5451
- import * as fs14 from "fs-extra";
5492
+ import fs14 from "fs-extra";
5452
5493
  import * as path13 from "path";
5453
5494
  import Anthropic4 from "@anthropic-ai/sdk";
5454
5495
  import { execa as execa9 } from "execa";
@@ -5556,8 +5597,13 @@ async function buildCommand(prdPath, options = {}) {
5556
5597
  }
5557
5598
  await runIntegrationPhase(anthropic, buildPlan, projectPath);
5558
5599
  spinner16.start("Installing dependencies...");
5559
- await execa9("npm", ["install"], { cwd: projectPath, reject: false });
5560
- spinner16.stop("Dependencies installed");
5600
+ try {
5601
+ await execa9("npm", ["install"], { cwd: projectPath, stdio: "inherit" });
5602
+ spinner16.stop("Dependencies installed");
5603
+ } catch (error) {
5604
+ spinner16.stop("Dependencies installation failed");
5605
+ console.log(chalk17.yellow(' \u26A0\uFE0F Run "npm install" manually in the project folder'));
5606
+ }
5561
5607
  const elapsed = Math.round((Date.now() - startTime) / 1e3);
5562
5608
  const minutes = Math.floor(elapsed / 60);
5563
5609
  const seconds = elapsed % 60;
@@ -5579,7 +5625,7 @@ async function buildCommand(prdPath, options = {}) {
5579
5625
  }
5580
5626
  async function analyzePRD(anthropic, prdContent) {
5581
5627
  const response = await anthropic.messages.create({
5582
- model: "claude-sonnet-4-20250514",
5628
+ model: "claude-sonnet-4-5-20250929",
5583
5629
  max_tokens: 4096,
5584
5630
  messages: [{
5585
5631
  role: "user",
@@ -5677,7 +5723,7 @@ async function runSetupPhase(anthropic, plan, projectPath) {
5677
5723
  await fs14.ensureDir(path13.join(projectPath, "src/features"));
5678
5724
  await fs14.ensureDir(path13.join(projectPath, ".codebakers"));
5679
5725
  const setupResponse = await anthropic.messages.create({
5680
- model: "claude-sonnet-4-20250514",
5726
+ model: "claude-sonnet-4-5-20250929",
5681
5727
  max_tokens: 8192,
5682
5728
  messages: [{
5683
5729
  role: "user",
@@ -5869,7 +5915,7 @@ Start with the index.ts that exports everything.`
5869
5915
  while (iteration < maxIterations) {
5870
5916
  iteration++;
5871
5917
  const response = await anthropic.messages.create({
5872
- model: "claude-sonnet-4-20250514",
5918
+ model: "claude-sonnet-4-5-20250929",
5873
5919
  max_tokens: 8192,
5874
5920
  messages
5875
5921
  });
@@ -5950,7 +5996,7 @@ async function askUserQuestion(agent, question, onProgress) {
5950
5996
  }
5951
5997
  async function healerAgent(anthropic, agent, error, projectPath, plan) {
5952
5998
  const response = await anthropic.messages.create({
5953
- model: "claude-sonnet-4-20250514",
5999
+ model: "claude-sonnet-4-5-20250929",
5954
6000
  max_tokens: 4096,
5955
6001
  messages: [{
5956
6002
  role: "user",
@@ -6004,7 +6050,7 @@ async function runIntegrationPhase(anthropic, plan, projectPath) {
6004
6050
  spinner16.start("Running integration...");
6005
6051
  const features = plan.waves.flatMap((w) => w.agents);
6006
6052
  const response = await anthropic.messages.create({
6007
- model: "claude-sonnet-4-20250514",
6053
+ model: "claude-sonnet-4-5-20250929",
6008
6054
  max_tokens: 8192,
6009
6055
  messages: [{
6010
6056
  role: "user",
@@ -6141,7 +6187,7 @@ function sleep(ms) {
6141
6187
  // src/commands/integrate.ts
6142
6188
  import * as p18 from "@clack/prompts";
6143
6189
  import chalk18 from "chalk";
6144
- import * as fs15 from "fs-extra";
6190
+ import fs15 from "fs-extra";
6145
6191
  import * as path14 from "path";
6146
6192
  import open2 from "open";
6147
6193
  import { execa as execa10 } from "execa";
@@ -6928,11 +6974,398 @@ function sleep2(ms) {
6928
6974
 
6929
6975
  // src/commands/website.ts
6930
6976
  import * as p19 from "@clack/prompts";
6931
- import chalk19 from "chalk";
6932
- import * as fs16 from "fs-extra";
6977
+ import chalk21 from "chalk";
6978
+ import fs16 from "fs-extra";
6933
6979
  import * as path15 from "path";
6934
6980
  import Anthropic5 from "@anthropic-ai/sdk";
6935
6981
  import { execa as execa11 } from "execa";
6982
+
6983
+ // src/utils/display.ts
6984
+ import chalk19 from "chalk";
6985
+ var StepTracker = class {
6986
+ steps;
6987
+ currentIndex = -1;
6988
+ startTime = Date.now();
6989
+ constructor(stepNames) {
6990
+ this.steps = stepNames.map((name) => ({ name, status: "pending" }));
6991
+ }
6992
+ start(index) {
6993
+ if (index !== void 0) {
6994
+ this.currentIndex = index;
6995
+ } else {
6996
+ this.currentIndex++;
6997
+ }
6998
+ if (this.currentIndex < this.steps.length) {
6999
+ this.steps[this.currentIndex].status = "running";
7000
+ }
7001
+ this.render();
7002
+ }
7003
+ complete() {
7004
+ if (this.currentIndex >= 0 && this.currentIndex < this.steps.length) {
7005
+ this.steps[this.currentIndex].status = "done";
7006
+ }
7007
+ this.render();
7008
+ }
7009
+ error() {
7010
+ if (this.currentIndex >= 0 && this.currentIndex < this.steps.length) {
7011
+ this.steps[this.currentIndex].status = "error";
7012
+ }
7013
+ this.render();
7014
+ }
7015
+ skip() {
7016
+ if (this.currentIndex >= 0 && this.currentIndex < this.steps.length) {
7017
+ this.steps[this.currentIndex].status = "skipped";
7018
+ }
7019
+ this.render();
7020
+ }
7021
+ render() {
7022
+ const output = [];
7023
+ output.push("");
7024
+ for (let i = 0; i < this.steps.length; i++) {
7025
+ const step = this.steps[i];
7026
+ const icon = this.getIcon(step.status);
7027
+ const color = this.getColor(step.status);
7028
+ const suffix = step.status === "running" ? chalk19.dim(" ...") : "";
7029
+ output.push(` ${icon} ${color(step.name)}${suffix}`);
7030
+ }
7031
+ const completed = this.steps.filter((s) => s.status === "done").length;
7032
+ const total = this.steps.length;
7033
+ const percent = Math.round(completed / total * 100);
7034
+ const barWidth = 30;
7035
+ const filled = Math.round(completed / total * barWidth);
7036
+ const empty = barWidth - filled;
7037
+ output.push("");
7038
+ output.push(` ${chalk19.green("\u2588".repeat(filled))}${chalk19.gray("\u2591".repeat(empty))} ${percent}%`);
7039
+ output.push("");
7040
+ console.log(output.join("\n"));
7041
+ }
7042
+ getIcon(status) {
7043
+ switch (status) {
7044
+ case "pending":
7045
+ return chalk19.gray("\u25CB");
7046
+ case "running":
7047
+ return chalk19.blue("\u25CF");
7048
+ case "done":
7049
+ return chalk19.green("\u2713");
7050
+ case "error":
7051
+ return chalk19.red("\u2717");
7052
+ case "skipped":
7053
+ return chalk19.yellow("\u2298");
7054
+ }
7055
+ }
7056
+ getColor(status) {
7057
+ switch (status) {
7058
+ case "pending":
7059
+ return chalk19.gray;
7060
+ case "running":
7061
+ return chalk19.white;
7062
+ case "done":
7063
+ return chalk19.green;
7064
+ case "error":
7065
+ return chalk19.red;
7066
+ case "skipped":
7067
+ return chalk19.yellow;
7068
+ }
7069
+ }
7070
+ getElapsedTime() {
7071
+ const elapsed = Math.round((Date.now() - this.startTime) / 1e3);
7072
+ const minutes = Math.floor(elapsed / 60);
7073
+ const seconds = elapsed % 60;
7074
+ return minutes > 0 ? `${minutes}m ${seconds}s` : `${seconds}s`;
7075
+ }
7076
+ };
7077
+ function showError(error) {
7078
+ console.log("");
7079
+ console.log(chalk19.red(` \u274C ${error.title}`));
7080
+ console.log("");
7081
+ console.log(chalk19.white(` What went wrong:`));
7082
+ console.log(chalk19.gray(` ${error.message}`));
7083
+ if (error.fixes && error.fixes.length > 0) {
7084
+ console.log("");
7085
+ console.log(chalk19.white(` Possible fixes:`));
7086
+ error.fixes.forEach((fix, i) => {
7087
+ console.log(chalk19.gray(` ${i + 1}. ${fix}`));
7088
+ });
7089
+ }
7090
+ if (error.command) {
7091
+ console.log("");
7092
+ console.log(chalk19.white(` Try running:`));
7093
+ console.log(chalk19.cyan(` ${error.command}`));
7094
+ }
7095
+ if (error.docs) {
7096
+ console.log("");
7097
+ console.log(chalk19.dim(` Docs: ${error.docs}`));
7098
+ }
7099
+ console.log("");
7100
+ }
7101
+ var ERRORS = {
7102
+ nodeNotInstalled: {
7103
+ title: "Node.js not found",
7104
+ message: "Node.js 18 or higher is required",
7105
+ fixes: [
7106
+ "Install Node.js from https://nodejs.org",
7107
+ "Use nvm to install: nvm install 18",
7108
+ "Restart your terminal after installing"
7109
+ ],
7110
+ docs: "https://nodejs.org/en/download"
7111
+ },
7112
+ npmFailed: {
7113
+ title: "Package installation failed",
7114
+ message: "npm install encountered an error",
7115
+ fixes: [
7116
+ "Check your internet connection",
7117
+ "Clear npm cache: npm cache clean --force",
7118
+ "Delete node_modules and try again",
7119
+ "Try using yarn instead: yarn install"
7120
+ ]
7121
+ },
7122
+ createNextAppFailed: {
7123
+ title: "Project creation failed",
7124
+ message: "create-next-app could not complete",
7125
+ fixes: [
7126
+ "Make sure Node.js 18+ is installed",
7127
+ "Check your internet connection",
7128
+ "Try running manually: npx create-next-app@latest"
7129
+ ]
7130
+ },
7131
+ apiKeyMissing: {
7132
+ title: "API key not configured",
7133
+ message: "Anthropic API key is required for AI features",
7134
+ fixes: [
7135
+ "Run: codebakers setup",
7136
+ "Get an API key at: https://console.anthropic.com"
7137
+ ],
7138
+ command: "codebakers setup"
7139
+ },
7140
+ notConfigured: {
7141
+ title: "CodeBakers not configured",
7142
+ message: "Run setup before using this command",
7143
+ command: "codebakers setup"
7144
+ },
7145
+ notInProject: {
7146
+ title: "Not in a project folder",
7147
+ message: "This command must be run inside a project",
7148
+ fixes: [
7149
+ "Navigate to your project: cd my-project",
7150
+ "Create a new project: codebakers init",
7151
+ "Or build a website: codebakers website"
7152
+ ]
7153
+ }
7154
+ };
7155
+
7156
+ // src/utils/ui.ts
7157
+ import chalk20 from "chalk";
7158
+ import gradient from "gradient-string";
7159
+ var colors = {
7160
+ primary: chalk20.hex("#ff6b6b"),
7161
+ // Red (matches logo)
7162
+ secondary: chalk20.hex("#4ecdc4"),
7163
+ // Teal
7164
+ accent: chalk20.hex("#ffe66d"),
7165
+ // Yellow
7166
+ success: chalk20.hex("#7ee787"),
7167
+ // Green
7168
+ error: chalk20.hex("#f85149"),
7169
+ // Red error
7170
+ warning: chalk20.hex("#d29922"),
7171
+ // Orange
7172
+ muted: chalk20.hex("#6e7681"),
7173
+ // Gray
7174
+ white: chalk20.hex("#ffffff"),
7175
+ dim: chalk20.dim
7176
+ };
7177
+ var headerGradient = gradient(["#ff6b6b", "#ff8e53", "#ffb347"]);
7178
+ var successGradient = gradient(["#7ee787", "#4ecdc4"]);
7179
+ function showLogo() {
7180
+ console.log("");
7181
+ console.log(headerGradient(" \u2554\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2557"));
7182
+ console.log(headerGradient(" \u2551 \u2551"));
7183
+ console.log(headerGradient(" \u2551") + colors.white(" \u{1F35E} C O D E B A K E R S ") + headerGradient("\u2551"));
7184
+ console.log(headerGradient(" \u2551 \u2551"));
7185
+ console.log(headerGradient(" \u2551") + colors.muted(" AI Dev Team That Follows The Rules ") + headerGradient("\u2551"));
7186
+ console.log(headerGradient(" \u2551 \u2551"));
7187
+ console.log(headerGradient(" \u255A\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u255D"));
7188
+ console.log("");
7189
+ }
7190
+ function showMiniLogo() {
7191
+ console.log("");
7192
+ console.log(headerGradient(" \u2554\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2557"));
7193
+ console.log(headerGradient(" \u2551") + colors.white(" \u{1F35E} CODEBAKERS ") + headerGradient("\u2551"));
7194
+ console.log(headerGradient(" \u255A\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u255D"));
7195
+ console.log("");
7196
+ }
7197
+ function box(content, style = "default") {
7198
+ const borderColor = {
7199
+ default: colors.muted,
7200
+ success: colors.success,
7201
+ error: colors.error,
7202
+ warning: colors.warning
7203
+ }[style];
7204
+ const maxLen = Math.max(...content.map((l) => stripAnsi(l).length), 50);
7205
+ const width = maxLen + 4;
7206
+ const top = borderColor(" \u256D" + "\u2500".repeat(width) + "\u256E");
7207
+ const bottom = borderColor(" \u2570" + "\u2500".repeat(width) + "\u256F");
7208
+ console.log(top);
7209
+ content.forEach((line) => {
7210
+ const stripped = stripAnsi(line);
7211
+ const padding = width - stripped.length - 2;
7212
+ console.log(borderColor(" \u2502") + " " + line + " ".repeat(Math.max(0, padding)) + borderColor("\u2502"));
7213
+ });
7214
+ console.log(bottom);
7215
+ console.log("");
7216
+ }
7217
+ function doubleBox(content, style = "default") {
7218
+ const borderColor = {
7219
+ default: colors.primary,
7220
+ success: colors.success,
7221
+ error: colors.error
7222
+ }[style];
7223
+ const maxLen = Math.max(...content.map((l) => stripAnsi(l).length), 50);
7224
+ const width = maxLen + 4;
7225
+ const top = borderColor(" \u2554" + "\u2550".repeat(width) + "\u2557");
7226
+ const bottom = borderColor(" \u255A" + "\u2550".repeat(width) + "\u255D");
7227
+ console.log(top);
7228
+ content.forEach((line) => {
7229
+ const stripped = stripAnsi(line);
7230
+ const padding = width - stripped.length - 2;
7231
+ console.log(borderColor(" \u2551") + " " + line + " ".repeat(Math.max(0, padding)) + borderColor("\u2551"));
7232
+ });
7233
+ console.log(bottom);
7234
+ console.log("");
7235
+ }
7236
+ function sectionHeader(title) {
7237
+ const line = "\u2501".repeat(60);
7238
+ console.log("");
7239
+ console.log(colors.muted(` ${line}`));
7240
+ console.log(colors.white(` ${title.toUpperCase()}`));
7241
+ console.log(colors.muted(` ${line}`));
7242
+ console.log("");
7243
+ }
7244
+ function showMenuCards(items) {
7245
+ console.log("");
7246
+ console.log(colors.muted(" \u250C\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2510"));
7247
+ items.forEach((item, i) => {
7248
+ const num = colors.primary(item.key);
7249
+ const icon = item.icon;
7250
+ const label = colors.white(item.label.padEnd(20));
7251
+ const desc = colors.muted(item.description.substring(0, 30).padEnd(30));
7252
+ console.log(colors.muted(" \u2502") + ` ${num} ${icon} ${label} ${desc}` + colors.muted("\u2502"));
7253
+ });
7254
+ console.log(colors.muted(" \u2514\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2518"));
7255
+ console.log("");
7256
+ }
7257
+ function showSuccessScreen(details) {
7258
+ console.log("");
7259
+ console.log(colors.success(" \u2554\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2557"));
7260
+ console.log(colors.success(" \u2551 \u2551"));
7261
+ console.log(colors.success(" \u2551") + successGradient(" \u2705 SUCCESS ") + colors.success("\u2551"));
7262
+ console.log(colors.success(" \u2551 \u2551"));
7263
+ console.log(colors.success(" \u2551") + colors.white(" " + details.title.padEnd(60)) + colors.success("\u2551"));
7264
+ if (details.message) {
7265
+ console.log(colors.success(" \u2551") + colors.muted(" " + details.message.substring(0, 60).padEnd(60)) + colors.success("\u2551"));
7266
+ }
7267
+ console.log(colors.success(" \u2551 \u2551"));
7268
+ if (details.stats && details.stats.length > 0) {
7269
+ console.log(colors.success(" \u2551") + colors.muted(" \u250C\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2510 ") + colors.success("\u2551"));
7270
+ details.stats.forEach((stat) => {
7271
+ const line = ` \u2502 ${stat.label.padEnd(14)} ${colors.white(stat.value.padEnd(40))}\u2502 `;
7272
+ console.log(colors.success(" \u2551") + colors.muted(line) + colors.success("\u2551"));
7273
+ });
7274
+ console.log(colors.success(" \u2551") + colors.muted(" \u2514\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2518 ") + colors.success("\u2551"));
7275
+ console.log(colors.success(" \u2551 \u2551"));
7276
+ }
7277
+ if (details.nextSteps && details.nextSteps.length > 0) {
7278
+ console.log(colors.success(" \u2551") + colors.white(" NEXT STEPS ") + colors.success("\u2551"));
7279
+ console.log(colors.success(" \u2551") + colors.muted(" \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500") + colors.success("\u2551"));
7280
+ details.nextSteps.forEach((step) => {
7281
+ console.log(colors.success(" \u2551") + colors.secondary(" " + step.padEnd(60)) + colors.success("\u2551"));
7282
+ });
7283
+ console.log(colors.success(" \u2551 \u2551"));
7284
+ }
7285
+ if (details.command) {
7286
+ console.log(colors.success(" \u2551") + colors.muted(" Quick start: ") + colors.white(details.command.padEnd(44)) + colors.success("\u2551"));
7287
+ console.log(colors.success(" \u2551 \u2551"));
7288
+ }
7289
+ console.log(colors.success(" \u255A\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u255D"));
7290
+ console.log("");
7291
+ }
7292
+ function showErrorScreen(details) {
7293
+ console.log("");
7294
+ console.log(colors.error(" \u2554\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2557"));
7295
+ console.log(colors.error(" \u2551 \u2551"));
7296
+ console.log(colors.error(" \u2551 \u274C ERROR \u2551"));
7297
+ console.log(colors.error(" \u2551 \u2551"));
7298
+ console.log(colors.error(" \u2551") + colors.white(" " + details.title.padEnd(60)) + colors.error("\u2551"));
7299
+ console.log(colors.error(" \u2551 \u2551"));
7300
+ console.log(colors.error(" \u2551") + colors.muted(" \u250C\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2510 ") + colors.error("\u2551"));
7301
+ console.log(colors.error(" \u2551") + colors.muted(" \u2502") + colors.white(" WHAT HAPPENED ") + colors.muted("\u2502 ") + colors.error("\u2551"));
7302
+ const words = details.message.split(" ");
7303
+ let line = "";
7304
+ words.forEach((word) => {
7305
+ if ((line + " " + word).length > 55) {
7306
+ console.log(colors.error(" \u2551") + colors.muted(" \u2502") + colors.muted(" " + line.padEnd(56)) + colors.muted("\u2502 ") + colors.error("\u2551"));
7307
+ line = word;
7308
+ } else {
7309
+ line = line ? line + " " + word : word;
7310
+ }
7311
+ });
7312
+ if (line) {
7313
+ console.log(colors.error(" \u2551") + colors.muted(" \u2502") + colors.muted(" " + line.padEnd(56)) + colors.muted("\u2502 ") + colors.error("\u2551"));
7314
+ }
7315
+ console.log(colors.error(" \u2551") + colors.muted(" \u2502 \u2502 ") + colors.error("\u2551"));
7316
+ if (details.fixes && details.fixes.length > 0) {
7317
+ console.log(colors.error(" \u2551") + colors.muted(" \u2502") + colors.white(" POSSIBLE FIXES ") + colors.muted("\u2502 ") + colors.error("\u2551"));
7318
+ details.fixes.forEach((fix, i) => {
7319
+ const fixText = ` ${i + 1}. ${fix}`.substring(0, 56).padEnd(56);
7320
+ console.log(colors.error(" \u2551") + colors.muted(" \u2502") + colors.muted(fixText) + colors.muted("\u2502 ") + colors.error("\u2551"));
7321
+ });
7322
+ }
7323
+ console.log(colors.error(" \u2551") + colors.muted(" \u2514\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2518 ") + colors.error("\u2551"));
7324
+ if (details.command) {
7325
+ console.log(colors.error(" \u2551 \u2551"));
7326
+ console.log(colors.error(" \u2551") + colors.muted(" Try: ") + colors.secondary(details.command.padEnd(53)) + colors.error("\u2551"));
7327
+ }
7328
+ console.log(colors.error(" \u2551 \u2551"));
7329
+ console.log(colors.error(" \u255A\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u255D"));
7330
+ console.log("");
7331
+ }
7332
+ function showFileTree(title, files) {
7333
+ console.log("");
7334
+ console.log(colors.white(` \u{1F4C1} ${title}`));
7335
+ console.log("");
7336
+ files.forEach((file, i) => {
7337
+ const isLast = i === files.length - 1;
7338
+ const prefix = isLast ? "\u2514\u2500\u2500" : "\u251C\u2500\u2500";
7339
+ const icon = getFileIcon(file);
7340
+ console.log(colors.muted(` ${prefix} `) + icon + " " + colors.white(file));
7341
+ });
7342
+ console.log("");
7343
+ }
7344
+ function getFileIcon(filename) {
7345
+ const ext = filename.split(".").pop()?.toLowerCase();
7346
+ const icons = {
7347
+ "tsx": "\u269B\uFE0F ",
7348
+ "ts": "\u{1F4D8}",
7349
+ "js": "\u{1F4D2}",
7350
+ "jsx": "\u269B\uFE0F ",
7351
+ "css": "\u{1F3A8}",
7352
+ "json": "\u{1F4CB}",
7353
+ "md": "\u{1F4DD}",
7354
+ "html": "\u{1F310}",
7355
+ "env": "\u{1F510}"
7356
+ };
7357
+ return icons[ext || ""] || "\u{1F4C4}";
7358
+ }
7359
+ function divider() {
7360
+ console.log("");
7361
+ console.log(colors.muted(" " + "\u2500".repeat(60)));
7362
+ console.log("");
7363
+ }
7364
+ function stripAnsi(str) {
7365
+ return str.replace(/\x1B\[[0-9;]*[mGKH]/g, "");
7366
+ }
7367
+
7368
+ // src/commands/website.ts
6936
7369
  var TEMPLATES = [
6937
7370
  {
6938
7371
  id: "landing",
@@ -7042,37 +7475,34 @@ var TEMPLATES = [
7042
7475
  async function websiteCommand() {
7043
7476
  const config = new Config();
7044
7477
  if (!config.isConfigured()) {
7045
- console.log(chalk19.yellow(`
7046
- \u26A0\uFE0F CodeBakers isn't set up yet.
7047
-
7048
- Run this first:
7049
- ${chalk19.cyan("codebakers setup")}
7050
- `));
7478
+ showErrorScreen({
7479
+ title: "CodeBakers not configured",
7480
+ message: "Run setup first to connect your API keys.",
7481
+ command: "codebakers setup"
7482
+ });
7051
7483
  return;
7052
7484
  }
7053
7485
  const anthropicCreds = config.getCredentials("anthropic");
7054
7486
  if (!anthropicCreds?.apiKey) {
7055
- console.log(chalk19.yellow(`
7056
- \u26A0\uFE0F Anthropic API key not configured.
7057
-
7058
- The website builder needs Claude AI to generate code.
7059
-
7060
- Run this to add your API key:
7061
- ${chalk19.cyan("codebakers setup")}
7062
-
7063
- Get an API key at:
7064
- ${chalk19.dim("https://console.anthropic.com/settings/keys")}
7065
- `));
7487
+ showErrorScreen({
7488
+ title: "Anthropic API key not configured",
7489
+ message: "The website builder needs Claude AI to generate code.",
7490
+ fixes: [
7491
+ "Run: codebakers setup",
7492
+ "Get an API key at: console.anthropic.com"
7493
+ ],
7494
+ command: "codebakers setup"
7495
+ });
7066
7496
  return;
7067
7497
  }
7068
- console.log(chalk19.cyan(`
7069
- \u2554\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2557
7070
- \u2551 \u{1F310} WEBSITE BUILDER \u2551
7071
- \u2551 \u2551
7072
- \u2551 Describe your website in plain English. \u2551
7073
- \u2551 AI builds it in minutes. \u2551
7074
- \u255A\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u255D
7075
- `));
7498
+ console.clear();
7499
+ showMiniLogo();
7500
+ doubleBox([
7501
+ colors.primary("\u{1F310} WEBSITE BUILDER"),
7502
+ "",
7503
+ colors.white("Describe your website in plain English."),
7504
+ colors.muted("AI builds it in minutes.")
7505
+ ]);
7076
7506
  const approach = await p19.select({
7077
7507
  message: "How would you like to build your website?",
7078
7508
  options: [
@@ -7092,14 +7522,14 @@ async function websiteCommand() {
7092
7522
  websiteSpec = await cloneDesign(anthropic);
7093
7523
  }
7094
7524
  if (!websiteSpec) return;
7095
- console.log(chalk19.cyan(`
7525
+ console.log(chalk21.cyan(`
7096
7526
  \u{1F4CB} Website Plan:
7097
7527
  `));
7098
- console.log(chalk19.bold(` ${websiteSpec.name}`));
7099
- console.log(chalk19.dim(` ${websiteSpec.description}
7528
+ console.log(chalk21.bold(` ${websiteSpec.name}`));
7529
+ console.log(chalk21.dim(` ${websiteSpec.description}
7100
7530
  `));
7101
- console.log(chalk19.dim(` Style: ${websiteSpec.style}`));
7102
- console.log(chalk19.dim(` Sections: ${websiteSpec.sections.join(", ")}
7531
+ console.log(chalk21.dim(` Style: ${websiteSpec.style}`));
7532
+ console.log(chalk21.dim(` Sections: ${websiteSpec.sections.join(", ")}
7103
7533
  `));
7104
7534
  const confirm13 = await p19.confirm({
7105
7535
  message: "Build this website?",
@@ -7109,11 +7539,11 @@ async function websiteCommand() {
7109
7539
  await buildWebsite(anthropic, websiteSpec, config);
7110
7540
  }
7111
7541
  async function describeWebsite(anthropic) {
7112
- console.log(chalk19.dim("\n Describe your website. Be as detailed as you want.\n"));
7113
- console.log(chalk19.dim(" Examples:"));
7114
- console.log(chalk19.dim(' \u2022 "A landing page for my AI writing tool called WriteBot"'));
7115
- console.log(chalk19.dim(' \u2022 "Portfolio site for a photographer, dark theme, minimal"'));
7116
- console.log(chalk19.dim(' \u2022 "Coffee shop website with menu, location, and online ordering"\n'));
7542
+ console.log(chalk21.dim("\n Describe your website. Be as detailed as you want.\n"));
7543
+ console.log(chalk21.dim(" Examples:"));
7544
+ console.log(chalk21.dim(' \u2022 "A landing page for my AI writing tool called WriteBot"'));
7545
+ console.log(chalk21.dim(' \u2022 "Portfolio site for a photographer, dark theme, minimal"'));
7546
+ console.log(chalk21.dim(' \u2022 "Coffee shop website with menu, location, and online ordering"\n'));
7117
7547
  const description = await textWithVoice({
7118
7548
  message: "Describe your website:",
7119
7549
  placeholder: "A landing page for..."
@@ -7122,7 +7552,7 @@ async function describeWebsite(anthropic) {
7122
7552
  const spinner16 = p19.spinner();
7123
7553
  spinner16.start("Understanding your vision...");
7124
7554
  const response = await anthropic.messages.create({
7125
- model: "claude-sonnet-4-20250514",
7555
+ model: "claude-sonnet-4-5-20250929",
7126
7556
  max_tokens: 2048,
7127
7557
  messages: [{
7128
7558
  role: "user",
@@ -7198,7 +7628,7 @@ async function templateWebsite(anthropic) {
7198
7628
  const spinner16 = p19.spinner();
7199
7629
  spinner16.start("Customizing template...");
7200
7630
  const response = await anthropic.messages.create({
7201
- model: "claude-sonnet-4-20250514",
7631
+ model: "claude-sonnet-4-5-20250929",
7202
7632
  max_tokens: 2048,
7203
7633
  messages: [{
7204
7634
  role: "user",
@@ -7244,11 +7674,11 @@ Make the content specific and compelling for this business.`
7244
7674
  return JSON.parse(jsonMatch[0]);
7245
7675
  }
7246
7676
  async function cloneDesign(anthropic) {
7247
- console.log(chalk19.dim("\n Describe a website design you like.\n"));
7248
- console.log(chalk19.dim(" Examples:"));
7249
- console.log(chalk19.dim(' \u2022 "Like Linear.app - minimal, clean, dark mode"'));
7250
- console.log(chalk19.dim(' \u2022 "Like Stripe - professional, lots of gradients"'));
7251
- console.log(chalk19.dim(' \u2022 "Like Notion - simple, friendly, illustrated"\n'));
7677
+ console.log(chalk21.dim("\n Describe a website design you like.\n"));
7678
+ console.log(chalk21.dim(" Examples:"));
7679
+ console.log(chalk21.dim(' \u2022 "Like Linear.app - minimal, clean, dark mode"'));
7680
+ console.log(chalk21.dim(' \u2022 "Like Stripe - professional, lots of gradients"'));
7681
+ console.log(chalk21.dim(' \u2022 "Like Notion - simple, friendly, illustrated"\n'));
7252
7682
  const inspiration = await textWithVoice({
7253
7683
  message: "What site do you want to be inspired by?",
7254
7684
  placeholder: "Like Linear.app but for..."
@@ -7262,7 +7692,7 @@ async function cloneDesign(anthropic) {
7262
7692
  const spinner16 = p19.spinner();
7263
7693
  spinner16.start("Analyzing design inspiration...");
7264
7694
  const response = await anthropic.messages.create({
7265
- model: "claude-sonnet-4-20250514",
7695
+ model: "claude-sonnet-4-5-20250929",
7266
7696
  max_tokens: 2048,
7267
7697
  messages: [{
7268
7698
  role: "user",
@@ -7314,37 +7744,96 @@ async function buildWebsite(anthropic, spec, config) {
7314
7744
  if (!overwrite || p19.isCancel(overwrite)) return;
7315
7745
  await fs16.remove(projectPath);
7316
7746
  }
7317
- console.log(chalk19.cyan(`
7318
- \u{1F3D7}\uFE0F Building ${spec.name}...
7747
+ console.log(chalk21.cyan(`
7748
+ \u{1F3D7}\uFE0F Building ${chalk21.bold(spec.name)}
7319
7749
  `));
7320
- const spinner16 = p19.spinner();
7321
- spinner16.start("Creating Next.js project...");
7322
- await execa11("npx", [
7323
- "create-next-app@latest",
7324
- spec.name,
7325
- "--typescript",
7326
- "--tailwind",
7327
- "--eslint",
7328
- "--app",
7329
- "--src-dir",
7330
- "--import-alias",
7331
- "@/*",
7332
- "--no-git"
7333
- ], { cwd: process.cwd(), reject: false });
7334
- spinner16.stop("Project created");
7335
- spinner16.start("Setting up shadcn/ui...");
7336
- await execa11("npx", ["shadcn@latest", "init", "-y", "-d"], {
7337
- cwd: projectPath,
7338
- reject: false
7339
- });
7340
- await execa11("npx", ["shadcn@latest", "add", "button", "card", "input", "badge", "-y"], {
7341
- cwd: projectPath,
7342
- reject: false
7343
- });
7344
- spinner16.stop("UI components ready");
7345
- spinner16.start("Generating website code...");
7750
+ const steps = new StepTracker([
7751
+ "Create project structure",
7752
+ "Install dependencies",
7753
+ "Set up UI components",
7754
+ "Generate website code",
7755
+ "Create additional pages",
7756
+ "Initialize git repository"
7757
+ ]);
7758
+ const createdFiles = [];
7759
+ steps.start();
7760
+ try {
7761
+ await execa11("npx", [
7762
+ "create-next-app@latest",
7763
+ spec.name,
7764
+ "--typescript",
7765
+ "--tailwind",
7766
+ "--eslint",
7767
+ "--app",
7768
+ "--src-dir",
7769
+ "--import-alias",
7770
+ "@/*",
7771
+ "--no-git",
7772
+ "--yes"
7773
+ ], {
7774
+ cwd: process.cwd(),
7775
+ stdio: "pipe"
7776
+ // Hide output for cleaner display
7777
+ });
7778
+ steps.complete();
7779
+ } catch (error) {
7780
+ steps.error();
7781
+ showError({
7782
+ title: "Project creation failed",
7783
+ message: "create-next-app could not complete",
7784
+ fixes: [
7785
+ "Make sure Node.js 18+ is installed",
7786
+ "Check your internet connection",
7787
+ "Try running manually: npx create-next-app@latest " + spec.name
7788
+ ],
7789
+ command: "npx create-next-app@latest " + spec.name
7790
+ });
7791
+ return;
7792
+ }
7793
+ if (!await fs16.pathExists(projectPath)) {
7794
+ steps.error();
7795
+ showError({
7796
+ title: "Project folder not created",
7797
+ message: "The project directory was not found after creation",
7798
+ fixes: [
7799
+ "Check if you have write permissions in this folder",
7800
+ "Try creating the project in a different location"
7801
+ ]
7802
+ });
7803
+ return;
7804
+ }
7805
+ steps.start();
7806
+ try {
7807
+ await execa11("npm", ["install", "lucide-react"], {
7808
+ cwd: projectPath,
7809
+ stdio: "pipe"
7810
+ });
7811
+ steps.complete();
7812
+ } catch (error) {
7813
+ steps.error();
7814
+ showError({
7815
+ ...ERRORS.npmFailed,
7816
+ command: `cd ${spec.name} && npm install`
7817
+ });
7818
+ return;
7819
+ }
7820
+ steps.start();
7821
+ try {
7822
+ await execa11("npx", ["shadcn@latest", "init", "-y", "-d"], {
7823
+ cwd: projectPath,
7824
+ stdio: "pipe"
7825
+ });
7826
+ await execa11("npx", ["shadcn@latest", "add", "button", "card", "input", "badge", "-y"], {
7827
+ cwd: projectPath,
7828
+ stdio: "pipe"
7829
+ });
7830
+ steps.complete();
7831
+ } catch (error) {
7832
+ steps.skip();
7833
+ }
7834
+ steps.start();
7346
7835
  const response = await anthropic.messages.create({
7347
- model: "claude-sonnet-4-20250514",
7836
+ model: "claude-sonnet-4-5-20250929",
7348
7837
  max_tokens: 16e3,
7349
7838
  messages: [{
7350
7839
  role: "user",
@@ -7399,45 +7888,52 @@ Make it production-quality and visually impressive.`
7399
7888
  const text17 = response.content[0].type === "text" ? response.content[0].text : "";
7400
7889
  const fileRegex = /<<<FILE:\s*(.+?)>>>([\s\S]*?)<<<END_FILE>>>/g;
7401
7890
  let match;
7402
- let fileCount = 0;
7403
7891
  while ((match = fileRegex.exec(text17)) !== null) {
7404
7892
  const filePath = path15.join(projectPath, match[1].trim());
7405
7893
  const content = match[2].trim();
7406
7894
  await fs16.ensureDir(path15.dirname(filePath));
7407
7895
  await fs16.writeFile(filePath, content);
7408
- fileCount++;
7409
- }
7410
- spinner16.stop(`Generated ${fileCount} files`);
7411
- spinner16.start("Initializing git...");
7412
- await execa11("git", ["init"], { cwd: projectPath, reject: false });
7413
- await execa11("git", ["add", "."], { cwd: projectPath, reject: false });
7414
- await execa11("git", ["commit", "-m", "Initial website build by CodeBakers"], { cwd: projectPath, reject: false });
7415
- spinner16.stop("Git initialized");
7416
- console.log(chalk19.green(`
7417
- \u2554\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2557
7418
- \u2551 \u2705 Website built successfully! \u2551
7419
- \u2560\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2563
7420
- \u2551 \u2551
7421
- \u2551 ${spec.name.padEnd(55)}\u2551
7422
- \u2551 ${spec.description.substring(0, 55).padEnd(55)}\u2551
7423
- \u2551 \u2551
7424
- \u2551 Next steps: \u2551
7425
- \u2551 cd ${spec.name.padEnd(52)}\u2551
7426
- \u2551 npm run dev \u2551
7427
- \u2551 \u2551
7428
- \u2551 Then open http://localhost:3000 \u2551
7429
- \u2551 \u2551
7430
- \u2551 Ready to deploy? \u2551
7431
- \u2551 codebakers deploy \u2551
7432
- \u2551 \u2551
7433
- \u255A\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u255D
7434
- `));
7896
+ createdFiles.push(match[1].trim());
7897
+ }
7898
+ steps.complete();
7899
+ steps.start();
7900
+ steps.complete();
7901
+ steps.start();
7902
+ try {
7903
+ await execa11("git", ["init"], { cwd: projectPath, stdio: "pipe" });
7904
+ await execa11("git", ["add", "."], { cwd: projectPath, stdio: "pipe" });
7905
+ await execa11("git", ["commit", "-m", "Initial website build by CodeBakers"], { cwd: projectPath, stdio: "pipe" });
7906
+ steps.complete();
7907
+ } catch (error) {
7908
+ steps.skip();
7909
+ }
7910
+ if (createdFiles.length > 0) {
7911
+ showFileTree("Files created", createdFiles.slice(0, 10));
7912
+ if (createdFiles.length > 10) {
7913
+ console.log(colors.muted(` ... and ${createdFiles.length - 10} more files`));
7914
+ }
7915
+ }
7916
+ showSuccessScreen({
7917
+ title: "Website built successfully!",
7918
+ message: spec.description,
7919
+ stats: [
7920
+ { label: "Project", value: spec.name },
7921
+ { label: "Files", value: createdFiles.length.toString() + " created" },
7922
+ { label: "Sections", value: spec.sections.length.toString() },
7923
+ { label: "Time", value: steps.getElapsedTime() }
7924
+ ],
7925
+ nextSteps: [
7926
+ `cd ${spec.name}`,
7927
+ "npm run dev"
7928
+ ],
7929
+ command: `cd ${spec.name} && npm run dev`
7930
+ });
7435
7931
  const openDev = await p19.confirm({
7436
7932
  message: "Start development server now?",
7437
7933
  initialValue: true
7438
7934
  });
7439
7935
  if (openDev && !p19.isCancel(openDev)) {
7440
- console.log(chalk19.dim("\n Starting dev server...\n"));
7936
+ console.log(colors.muted("\n Starting dev server...\n"));
7441
7937
  process.chdir(projectPath);
7442
7938
  await execa11("npm", ["run", "dev"], {
7443
7939
  stdio: "inherit",
@@ -7614,26 +8110,21 @@ If unclear between multiple commands, use the most likely one with lower confide
7614
8110
  }
7615
8111
 
7616
8112
  // src/index.ts
7617
- var VERSION = "2.3.8";
7618
- var logo = `
7619
- \u2588\u2588\u2588\u2588\u2588\u2588\u2557 \u2588\u2588\u2588\u2588\u2588\u2588\u2557 \u2588\u2588\u2588\u2588\u2588\u2588\u2557 \u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2557\u2588\u2588\u2588\u2588\u2588\u2588\u2557 \u2588\u2588\u2588\u2588\u2588\u2557 \u2588\u2588\u2557 \u2588\u2588\u2557\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2557\u2588\u2588\u2588\u2588\u2588\u2588\u2557 \u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2557
7620
- \u2588\u2588\u2554\u2550\u2550\u2550\u2550\u255D\u2588\u2588\u2554\u2550\u2550\u2550\u2588\u2588\u2557\u2588\u2588\u2554\u2550\u2550\u2588\u2588\u2557\u2588\u2588\u2554\u2550\u2550\u2550\u2550\u255D\u2588\u2588\u2554\u2550\u2550\u2588\u2588\u2557\u2588\u2588\u2554\u2550\u2550\u2588\u2588\u2557\u2588\u2588\u2551 \u2588\u2588\u2554\u255D\u2588\u2588\u2554\u2550\u2550\u2550\u2550\u255D\u2588\u2588\u2554\u2550\u2550\u2588\u2588\u2557\u2588\u2588\u2554\u2550\u2550\u2550\u2550\u255D
7621
- \u2588\u2588\u2551 \u2588\u2588\u2551 \u2588\u2588\u2551\u2588\u2588\u2551 \u2588\u2588\u2551\u2588\u2588\u2588\u2588\u2588\u2557 \u2588\u2588\u2588\u2588\u2588\u2588\u2554\u255D\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2551\u2588\u2588\u2588\u2588\u2588\u2554\u255D \u2588\u2588\u2588\u2588\u2588\u2557 \u2588\u2588\u2588\u2588\u2588\u2588\u2554\u255D\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2557
7622
- \u2588\u2588\u2551 \u2588\u2588\u2551 \u2588\u2588\u2551\u2588\u2588\u2551 \u2588\u2588\u2551\u2588\u2588\u2554\u2550\u2550\u255D \u2588\u2588\u2554\u2550\u2550\u2588\u2588\u2557\u2588\u2588\u2554\u2550\u2550\u2588\u2588\u2551\u2588\u2588\u2554\u2550\u2588\u2588\u2557 \u2588\u2588\u2554\u2550\u2550\u255D \u2588\u2588\u2554\u2550\u2550\u2588\u2588\u2557\u255A\u2550\u2550\u2550\u2550\u2588\u2588\u2551
7623
- \u255A\u2588\u2588\u2588\u2588\u2588\u2588\u2557\u255A\u2588\u2588\u2588\u2588\u2588\u2588\u2554\u255D\u2588\u2588\u2588\u2588\u2588\u2588\u2554\u255D\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2557\u2588\u2588\u2588\u2588\u2588\u2588\u2554\u255D\u2588\u2588\u2551 \u2588\u2588\u2551\u2588\u2588\u2551 \u2588\u2588\u2557\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2557\u2588\u2588\u2551 \u2588\u2588\u2551\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2551
7624
- \u255A\u2550\u2550\u2550\u2550\u2550\u255D \u255A\u2550\u2550\u2550\u2550\u2550\u255D \u255A\u2550\u2550\u2550\u2550\u2550\u255D \u255A\u2550\u2550\u2550\u2550\u2550\u2550\u255D\u255A\u2550\u2550\u2550\u2550\u2550\u255D \u255A\u2550\u255D \u255A\u2550\u255D\u255A\u2550\u255D \u255A\u2550\u255D\u255A\u2550\u2550\u2550\u2550\u2550\u2550\u255D\u255A\u2550\u255D \u255A\u2550\u255D\u255A\u2550\u2550\u2550\u2550\u2550\u2550\u255D
7625
- `;
8113
+ var VERSION = "2.5.3";
7626
8114
  async function showMainMenu() {
7627
8115
  const config = new Config();
7628
- console.log(gradient.pastel.multiline(logo));
7629
- console.log(chalk20.dim(` v${VERSION} \u2014 AI dev team that follows the rules
7630
- `));
8116
+ console.clear();
8117
+ showLogo();
8118
+ console.log(colors.muted(` v${VERSION}`));
8119
+ console.log("");
7631
8120
  const hasAnthropic = !!config.getCredentials("anthropic")?.apiKey;
7632
8121
  if (!hasAnthropic) {
7633
- console.log(boxen2(
7634
- chalk20.yellow("Welcome to CodeBakers!\n\n") + chalk20.white("Let's connect your Anthropic API key so the AI can work.\n") + chalk20.dim("(Takes about 1 minute)"),
7635
- { padding: 1, borderColor: "yellow", borderStyle: "round" }
7636
- ));
8122
+ doubleBox([
8123
+ colors.warning("\u{1F44B} Welcome to CodeBakers!"),
8124
+ "",
8125
+ colors.white("Let's connect your Anthropic API key so the AI can work."),
8126
+ colors.muted("(Takes about 1 minute)")
8127
+ ], "default");
7637
8128
  await setupCommand();
7638
8129
  showPostSetupInstructions();
7639
8130
  return;
@@ -7644,34 +8135,38 @@ async function showMainMenu() {
7644
8135
  const folderName = path16.basename(cwd);
7645
8136
  if (inProject && projectConfig) {
7646
8137
  const framework = projectConfig.framework || "detected";
7647
- console.log(chalk20.cyan(` \u{1F4C1} Working in: ${chalk20.bold(folderName)}`));
7648
- console.log(chalk20.dim(` ${framework} project
7649
- `));
8138
+ box([
8139
+ colors.secondary("\u{1F4C1} ") + colors.white(folderName),
8140
+ colors.muted(` ${framework} project`)
8141
+ ]);
7650
8142
  await showProjectMenu(config);
7651
8143
  } else {
7652
- console.log(chalk20.cyan(` \u{1F4C1} Current folder: ${chalk20.bold(cwd)}`));
7653
- console.log(chalk20.dim(` Not a project folder
7654
- `));
8144
+ box([
8145
+ colors.secondary("\u{1F4C1} ") + colors.white(cwd),
8146
+ colors.muted(" Not a project folder")
8147
+ ]);
7655
8148
  await showStartMenu(config);
7656
8149
  }
7657
8150
  }
7658
8151
  async function showStartMenu(config) {
7659
- console.log(chalk20.cyan("\n \u2139\uFE0F This folder doesn't have a project yet.\n"));
8152
+ console.log(colors.muted(" This folder doesn't have a project yet."));
8153
+ console.log("");
7660
8154
  let keepRunning = true;
7661
8155
  while (keepRunning) {
7662
- console.log(chalk20.white(" What would you like to do?\n"));
7663
- console.log(chalk20.green(" 1.") + " \u{1F310} Build a website " + chalk20.dim("- Describe it, AI builds it"));
7664
- console.log(chalk20.green(" 2.") + " \u{1F195} Create new project " + chalk20.dim("- Start with Next.js, React, etc."));
7665
- console.log(chalk20.green(" 3.") + " \u270F\uFE0F Plan my project " + chalk20.dim("- Create a detailed plan first"));
7666
- console.log(chalk20.green(" 4.") + " \u{1F3D7}\uFE0F Build from plan " + chalk20.dim("- I already have a PRD file"));
7667
- console.log(chalk20.green(" 5.") + " \u{1F31F} Get expert advice " + chalk20.dim("- AI consultants help you decide"));
7668
- console.log(chalk20.green(" 6.") + " \u{1F50C} Add a service " + chalk20.dim("- Stripe, Supabase, Auth, etc."));
7669
- console.log(chalk20.green(" 7.") + " \u2699\uFE0F Settings " + chalk20.dim("- API keys & preferences"));
7670
- console.log(chalk20.green(" 8.") + " \u2753 Help " + chalk20.dim("- Learn how CodeBakers works"));
7671
- console.log(chalk20.green(" 0.") + " \u{1F6AA} Return to terminal " + chalk20.dim("- Go back to command line"));
7672
- console.log("");
8156
+ sectionHeader("What would you like to do?");
8157
+ showMenuCards([
8158
+ { key: "1", icon: "\u{1F310}", label: "Build a Website", description: "Describe it, AI builds it" },
8159
+ { key: "2", icon: "\u{1F195}", label: "Create New Project", description: "Start with Next.js, React" },
8160
+ { key: "3", icon: "\u270F\uFE0F", label: "Plan My Project", description: "Create a detailed plan" },
8161
+ { key: "4", icon: "\u{1F3D7}\uFE0F", label: "Build from Plan", description: "I have a PRD file" },
8162
+ { key: "5", icon: "\u{1F31F}", label: "Get Expert Advice", description: "AI consultants help" },
8163
+ { key: "6", icon: "\u{1F50C}", label: "Add a Service", description: "Stripe, Supabase, Auth" },
8164
+ { key: "7", icon: "\u2699\uFE0F", label: "Settings", description: "API keys & preferences" },
8165
+ { key: "8", icon: "\u2753", label: "Help", description: "Learn how it works" },
8166
+ { key: "0", icon: "\u{1F6AA}", label: "Exit", description: "Return to terminal" }
8167
+ ]);
7673
8168
  const choice = await p21.text({
7674
- message: "Enter a number (0-8):",
8169
+ message: colors.primary("Enter a number (0-8):"),
7675
8170
  placeholder: "1",
7676
8171
  validate: (value) => {
7677
8172
  if (!/^[0-8]$/.test(value) && value !== "") return "Please enter a number 0-8";
@@ -7720,34 +8215,34 @@ async function showStartMenu(config) {
7720
8215
  }
7721
8216
  function showExitMessage() {
7722
8217
  console.log("");
7723
- console.log(chalk20.cyan(" \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500"));
7724
- console.log(chalk20.white(" You're back in the terminal."));
8218
+ divider();
8219
+ console.log(colors.white(" You're back in the terminal."));
7725
8220
  console.log("");
7726
- console.log(chalk20.dim(" To start CodeBakers again, type:"));
7727
- console.log(chalk20.green(" codebakers"));
8221
+ console.log(colors.muted(" To start CodeBakers again, type:"));
8222
+ console.log(colors.success(" codebakers"));
7728
8223
  console.log("");
7729
- console.log(chalk20.dim(" Quick commands you can run directly:"));
7730
- console.log(chalk20.dim(" codebakers website") + chalk20.gray(" - Build a website"));
7731
- console.log(chalk20.dim(" codebakers code") + chalk20.gray(" - Code with AI"));
7732
- console.log(chalk20.dim(" codebakers help") + chalk20.gray(" - See all commands"));
7733
- console.log(chalk20.cyan(" \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500"));
8224
+ console.log(chalk22.dim(" Quick commands you can run directly:"));
8225
+ console.log(chalk22.dim(" codebakers website") + chalk22.gray(" - Build a website"));
8226
+ console.log(chalk22.dim(" codebakers code") + chalk22.gray(" - Code with AI"));
8227
+ console.log(chalk22.dim(" codebakers help") + chalk22.gray(" - See all commands"));
8228
+ console.log(chalk22.cyan(" \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500"));
7734
8229
  console.log("");
7735
8230
  }
7736
8231
  async function showProjectMenu(config) {
7737
- console.log(chalk20.cyan("\n \u2139\uFE0F I found an existing project in this folder.\n"));
8232
+ console.log(chalk22.cyan("\n \u2139\uFE0F I found an existing project in this folder.\n"));
7738
8233
  let keepRunning = true;
7739
8234
  while (keepRunning) {
7740
- console.log(chalk20.white(" What would you like to do with this project?\n"));
7741
- console.log(chalk20.green(" 1.") + " \u{1F4AC} Code with AI " + chalk20.dim("- Tell AI what to build or fix"));
7742
- console.log(chalk20.green(" 2.") + " \u{1F680} Deploy to production " + chalk20.dim("- Make your site live"));
7743
- console.log(chalk20.green(" 3.") + " \u{1F50D} Check my code " + chalk20.dim("- Find issues & improvements"));
7744
- console.log(chalk20.green(" 4.") + " \u{1F527} Fix errors for me " + chalk20.dim("- AI repairs broken code"));
7745
- console.log(chalk20.green(" 5.") + " \u{1F50C} Add a service " + chalk20.dim("- Stripe, Supabase, Auth, etc."));
7746
- console.log(chalk20.green(" 6.") + " \u26A1 Create new files " + chalk20.dim("- Components, pages, APIs"));
7747
- console.log(chalk20.green(" 7.") + " \u{1F195} Start fresh project " + chalk20.dim("- Begin something new"));
7748
- console.log(chalk20.green(" 8.") + " \u2699\uFE0F Settings " + chalk20.dim("- API keys & preferences"));
7749
- console.log(chalk20.green(" 9.") + " \u2753 Help " + chalk20.dim("- Learn how CodeBakers works"));
7750
- console.log(chalk20.green(" 0.") + " \u{1F6AA} Return to terminal " + chalk20.dim("- Go back to command line"));
8235
+ console.log(chalk22.white(" What would you like to do with this project?\n"));
8236
+ console.log(chalk22.green(" 1.") + " \u{1F4AC} Code with AI " + chalk22.dim("- Tell AI what to build or fix"));
8237
+ console.log(chalk22.green(" 2.") + " \u{1F680} Deploy to production " + chalk22.dim("- Make your site live"));
8238
+ console.log(chalk22.green(" 3.") + " \u{1F50D} Check my code " + chalk22.dim("- Find issues & improvements"));
8239
+ console.log(chalk22.green(" 4.") + " \u{1F527} Fix errors for me " + chalk22.dim("- AI repairs broken code"));
8240
+ console.log(chalk22.green(" 5.") + " \u{1F50C} Add a service " + chalk22.dim("- Stripe, Supabase, Auth, etc."));
8241
+ console.log(chalk22.green(" 6.") + " \u26A1 Create new files " + chalk22.dim("- Components, pages, APIs"));
8242
+ console.log(chalk22.green(" 7.") + " \u{1F195} Start fresh project " + chalk22.dim("- Begin something new"));
8243
+ console.log(chalk22.green(" 8.") + " \u2699\uFE0F Settings " + chalk22.dim("- API keys & preferences"));
8244
+ console.log(chalk22.green(" 9.") + " \u2753 Help " + chalk22.dim("- Learn how CodeBakers works"));
8245
+ console.log(chalk22.green(" 0.") + " \u{1F6AA} Return to terminal " + chalk22.dim("- Go back to command line"));
7751
8246
  console.log("");
7752
8247
  const choice = await p21.text({
7753
8248
  message: "Enter a number (0-9):",
@@ -7851,52 +8346,52 @@ async function handleAction(action, config) {
7851
8346
  showHelp2();
7852
8347
  break;
7853
8348
  default:
7854
- console.log(chalk20.yellow("Coming soon!"));
8349
+ console.log(chalk22.yellow("Coming soon!"));
7855
8350
  }
7856
8351
  }
7857
8352
  function showPostSetupInstructions() {
7858
8353
  console.log(boxen2(
7859
- chalk20.green.bold("\u2713 Setup complete!\n\n") + chalk20.white("What's next?\n\n") + chalk20.cyan("1. ") + "Navigate to where you want to build:\n" + chalk20.dim(" cd C:\\dev\\my-project\n\n") + chalk20.cyan("2. ") + "Run CodeBakers:\n" + chalk20.dim(" codebakers\n\n") + chalk20.white("Or build a website right now:\n") + chalk20.dim(" codebakers website"),
8354
+ chalk22.green.bold("\u2713 Setup complete!\n\n") + chalk22.white("What's next?\n\n") + chalk22.cyan("1. ") + "Navigate to where you want to build:\n" + chalk22.dim(" cd C:\\dev\\my-project\n\n") + chalk22.cyan("2. ") + "Run CodeBakers:\n" + chalk22.dim(" codebakers\n\n") + chalk22.white("Or build a website right now:\n") + chalk22.dim(" codebakers website"),
7860
8355
  { padding: 1, borderColor: "green", borderStyle: "round" }
7861
8356
  ));
7862
8357
  }
7863
8358
  function showPostBuildInstructions(projectName, projectPath) {
7864
8359
  const displayPath = projectPath || projectName;
7865
8360
  console.log(boxen2(
7866
- chalk20.green.bold(`\u2713 ${projectName} created!
8361
+ chalk22.green.bold(`\u2713 ${projectName} created!
7867
8362
 
7868
- `) + chalk20.white("Next steps:\n\n") + chalk20.cyan("1. ") + "Go to your project:\n" + chalk20.dim(` cd ${displayPath}
8363
+ `) + chalk22.white("Next steps:\n\n") + chalk22.cyan("1. ") + "Go to your project:\n" + chalk22.dim(` cd ${displayPath}
7869
8364
 
7870
- `) + chalk20.cyan("2. ") + "Install dependencies:\n" + chalk20.dim(" npm install\n\n") + chalk20.cyan("3. ") + "Start the dev server:\n" + chalk20.dim(" npm run dev\n\n") + chalk20.cyan("4. ") + "Open in browser:\n" + chalk20.dim(" http://localhost:3000\n\n") + chalk20.white("Ready to deploy?\n") + chalk20.dim(" codebakers deploy"),
8365
+ `) + chalk22.cyan("2. ") + "Install dependencies:\n" + chalk22.dim(" npm install\n\n") + chalk22.cyan("3. ") + "Start the dev server:\n" + chalk22.dim(" npm run dev\n\n") + chalk22.cyan("4. ") + "Open in browser:\n" + chalk22.dim(" http://localhost:3000\n\n") + chalk22.white("Ready to deploy?\n") + chalk22.dim(" codebakers deploy"),
7871
8366
  { padding: 1, borderColor: "green", borderStyle: "round" }
7872
8367
  ));
7873
8368
  }
7874
8369
  function showHelp2() {
7875
8370
  console.log(boxen2(`
7876
- ${chalk20.bold("CodeBakers CLI v" + VERSION)} \u2014 AI dev team that follows the rules
7877
-
7878
- ${chalk20.bold.cyan("Getting Started:")}
7879
- ${chalk20.cyan("codebakers")} Interactive menu
7880
- ${chalk20.cyan("codebakers setup")} Connect API keys
7881
- ${chalk20.cyan("codebakers website")} Build website by describing it
7882
- ${chalk20.cyan("codebakers init")} Create new project
7883
-
7884
- ${chalk20.bold.cyan("In a Project:")}
7885
- ${chalk20.cyan("codebakers code")} Chat with AI to build features
7886
- ${chalk20.cyan("codebakers deploy")} Deploy to Vercel
7887
- ${chalk20.cyan("codebakers check")} Check code quality
7888
- ${chalk20.cyan("codebakers fix")} Auto-fix errors
7889
-
7890
- ${chalk20.bold.cyan("Planning:")}
7891
- ${chalk20.cyan("codebakers prd-maker")} Create PRD through interview
7892
- ${chalk20.cyan("codebakers build")} Build from PRD (parallel agents)
7893
- ${chalk20.cyan("codebakers advisors")} Consult AI experts
7894
-
7895
- ${chalk20.bold.cyan("Integrations:")}
7896
- ${chalk20.cyan("codebakers integrate")} 50+ one-click integrations
7897
- ${chalk20.cyan("codebakers gateway")} WhatsApp, Telegram, Discord
7898
-
7899
- ${chalk20.bold("Docs:")} ${chalk20.dim("https://codebakers.dev/docs")}
8371
+ ${chalk22.bold("CodeBakers CLI v" + VERSION)} \u2014 AI dev team that follows the rules
8372
+
8373
+ ${chalk22.bold.cyan("Getting Started:")}
8374
+ ${chalk22.cyan("codebakers")} Interactive menu
8375
+ ${chalk22.cyan("codebakers setup")} Connect API keys
8376
+ ${chalk22.cyan("codebakers website")} Build website by describing it
8377
+ ${chalk22.cyan("codebakers init")} Create new project
8378
+
8379
+ ${chalk22.bold.cyan("In a Project:")}
8380
+ ${chalk22.cyan("codebakers code")} Chat with AI to build features
8381
+ ${chalk22.cyan("codebakers deploy")} Deploy to Vercel
8382
+ ${chalk22.cyan("codebakers check")} Check code quality
8383
+ ${chalk22.cyan("codebakers fix")} Auto-fix errors
8384
+
8385
+ ${chalk22.bold.cyan("Planning:")}
8386
+ ${chalk22.cyan("codebakers prd-maker")} Create PRD through interview
8387
+ ${chalk22.cyan("codebakers build")} Build from PRD (parallel agents)
8388
+ ${chalk22.cyan("codebakers advisors")} Consult AI experts
8389
+
8390
+ ${chalk22.bold.cyan("Integrations:")}
8391
+ ${chalk22.cyan("codebakers integrate")} 50+ one-click integrations
8392
+ ${chalk22.cyan("codebakers gateway")} WhatsApp, Telegram, Discord
8393
+
8394
+ ${chalk22.bold("Docs:")} ${chalk22.dim("https://codebakers.dev/docs")}
7900
8395
  `, { padding: 1, borderColor: "cyan", borderStyle: "round" }));
7901
8396
  }
7902
8397
  var program = new Command();
@@ -7924,7 +8419,7 @@ program.command("website").alias("site").description("Build website by describin
7924
8419
  program.command("help").description("Show help").action(showHelp2);
7925
8420
  async function handleNaturalLanguage(input) {
7926
8421
  const config = new Config();
7927
- console.log(chalk20.dim("\n Understanding your request...\n"));
8422
+ console.log(chalk22.dim("\n Understanding your request...\n"));
7928
8423
  const parsed = await parseNaturalLanguage(input, config);
7929
8424
  if (!parsed) {
7930
8425
  await codeCommand(input);