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/AUDIT_REPORT.md +138 -0
- package/dist/{advisors-GGUCFS4E.js → advisors-RWRTSJRR.js} +1 -1
- package/dist/{chunk-YUSDTJD6.js → chunk-D44U3IEA.js} +3 -3
- package/dist/{chunk-ND6T4UDY.js → chunk-LANM5XQW.js} +4 -4
- package/dist/index.js +813 -318
- package/dist/{prd-AIEY63YY.js → prd-RYITSL6Q.js} +1 -1
- package/package.json +1 -1
- package/src/commands/advisors.ts +3 -3
- package/src/commands/build.ts +13 -8
- package/src/commands/check.ts +1 -1
- package/src/commands/code.ts +3 -3
- package/src/commands/deploy.ts +5 -5
- package/src/commands/design.ts +1 -1
- package/src/commands/generate.ts +1 -1
- package/src/commands/init.ts +90 -40
- package/src/commands/integrate.ts +1 -1
- package/src/commands/migrate.ts +1 -1
- package/src/commands/prd-maker.ts +4 -3
- package/src/commands/prd.ts +4 -4
- package/src/commands/security.ts +1 -1
- package/src/commands/status.ts +1 -1
- package/src/commands/website.ts +176 -93
- package/src/index.ts +54 -42
- package/src/utils/display.ts +338 -0
- package/src/utils/files.ts +1 -1
- package/src/utils/ui.ts +441 -0
- package/src/utils/voice.ts +1 -1
package/dist/index.js
CHANGED
|
@@ -1,10 +1,10 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
2
|
import {
|
|
3
3
|
prdCommand
|
|
4
|
-
} from "./chunk-
|
|
4
|
+
} from "./chunk-LANM5XQW.js";
|
|
5
5
|
import {
|
|
6
6
|
advisorsCommand
|
|
7
|
-
} from "./chunk-
|
|
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
|
|
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
|
|
486
|
+
import fs from "fs-extra";
|
|
488
487
|
import * as path from "path";
|
|
489
|
-
import { execa as
|
|
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
|
|
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
|
|
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
|
|
1124
|
+
await execa2("npm", ["install"], { cwd: projectPath, stdio: "inherit" });
|
|
1125
|
+
installSuccess = true;
|
|
1125
1126
|
} catch {
|
|
1126
1127
|
try {
|
|
1127
|
-
await
|
|
1128
|
+
await execa2("pnpm", ["install"], { cwd: projectPath, stdio: "inherit" });
|
|
1129
|
+
installSuccess = true;
|
|
1128
1130
|
} catch {
|
|
1129
|
-
|
|
1131
|
+
try {
|
|
1132
|
+
await execa2("yarn", ["install"], { cwd: projectPath, stdio: "inherit" });
|
|
1133
|
+
installSuccess = true;
|
|
1134
|
+
} catch {
|
|
1135
|
+
}
|
|
1130
1136
|
}
|
|
1131
1137
|
}
|
|
1132
|
-
|
|
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
|
-
|
|
1136
|
-
|
|
1137
|
-
|
|
1138
|
-
|
|
1139
|
-
|
|
1140
|
-
|
|
1141
|
-
|
|
1142
|
-
|
|
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
|
-
|
|
1147
|
-
|
|
1148
|
-
|
|
1149
|
-
|
|
1150
|
-
|
|
1151
|
-
|
|
1152
|
-
|
|
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
|
-
|
|
1158
|
-
|
|
1159
|
-
|
|
1160
|
-
|
|
1161
|
-
|
|
1162
|
-
|
|
1163
|
-
|
|
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
|
|
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
|
|
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
|
|
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
|
|
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
|
|
2063
|
-
import { execa as
|
|
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
|
|
2111
|
+
await execa3("which", ["sox"], { reject: true });
|
|
2072
2112
|
voiceAvailable = true;
|
|
2073
2113
|
} else {
|
|
2074
2114
|
try {
|
|
2075
|
-
await
|
|
2115
|
+
await execa3("which", ["sox"], { reject: true });
|
|
2076
2116
|
voiceAvailable = true;
|
|
2077
2117
|
} catch {
|
|
2078
|
-
await
|
|
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
|
|
2229
|
+
await execa3("powershell", ["-Command", "[console]::beep(800,200)"], { reject: false });
|
|
2190
2230
|
} else if (process.platform === "darwin") {
|
|
2191
|
-
await
|
|
2231
|
+
await execa3("afplay", ["/System/Library/Sounds/Tink.aiff"], { reject: false });
|
|
2192
2232
|
} else {
|
|
2193
2233
|
try {
|
|
2194
|
-
await
|
|
2234
|
+
await execa3("beep", ["-f", "800", "-l", "200"], { reject: false });
|
|
2195
2235
|
} catch {
|
|
2196
|
-
await
|
|
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
|
|
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
|
|
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
|
|
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
|
|
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
|
|
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
|
|
2371
|
+
import fs5 from "fs-extra";
|
|
2332
2372
|
import * as path4 from "path";
|
|
2333
|
-
import { execa as
|
|
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
|
|
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
|
|
2380
|
+
const result = await execa4("pbpaste", [], { timeout: 5e3 });
|
|
2341
2381
|
return result.stdout;
|
|
2342
2382
|
} else {
|
|
2343
2383
|
try {
|
|
2344
|
-
const result = await
|
|
2384
|
+
const result = await execa4("xclip", ["-selection", "clipboard", "-o"], { timeout: 5e3 });
|
|
2345
2385
|
return result.stdout;
|
|
2346
2386
|
} catch {
|
|
2347
|
-
const result = await
|
|
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
|
|
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
|
|
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
|
|
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
|
|
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-
|
|
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
|
|
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-
|
|
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
|
|
3191
|
-
import
|
|
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
|
|
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
|
|
3330
|
+
await execa6("npm", ["run", "build"], { cwd: process.cwd() });
|
|
3291
3331
|
} catch {
|
|
3292
3332
|
try {
|
|
3293
|
-
await
|
|
3333
|
+
await execa6("pnpm", ["build"], { cwd: process.cwd() });
|
|
3294
3334
|
} catch {
|
|
3295
|
-
await
|
|
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
|
|
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
|
|
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
|
|
3347
|
-
await
|
|
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
|
|
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(
|
|
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-
|
|
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
|
|
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-
|
|
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-
|
|
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
|
|
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
|
|
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
|
|
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
|
|
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
|
|
4620
|
-
import
|
|
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
|
|
4727
|
+
result = await execa7("npx", ["drizzle-kit", "check"], { cwd: process.cwd(), reject: false });
|
|
4688
4728
|
break;
|
|
4689
4729
|
case "prisma":
|
|
4690
|
-
result = await
|
|
4730
|
+
result = await execa7("npx", ["prisma", "migrate", "status"], { cwd: process.cwd(), reject: false });
|
|
4691
4731
|
break;
|
|
4692
4732
|
case "supabase":
|
|
4693
|
-
result = await
|
|
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
|
|
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
|
|
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
|
|
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
|
|
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
|
|
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
|
|
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
|
|
4884
|
+
result = await execa7("npx", ["drizzle-kit", "introspect"], { cwd: process.cwd(), reject: false });
|
|
4845
4885
|
break;
|
|
4846
4886
|
case "prisma":
|
|
4847
|
-
result = await
|
|
4887
|
+
result = await execa7("npx", ["prisma", "db", "pull"], { cwd: process.cwd(), reject: false });
|
|
4848
4888
|
break;
|
|
4849
4889
|
case "supabase":
|
|
4850
|
-
result = await
|
|
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
|
|
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
|
|
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
|
|
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
|
|
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
|
|
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
|
|
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-
|
|
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-
|
|
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
|
|
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
|
|
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
|
|
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
|
|
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
|
|
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
|
|
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
|
|
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
|
|
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-
|
|
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
|
|
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
|
-
|
|
5560
|
-
|
|
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-
|
|
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-
|
|
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-
|
|
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-
|
|
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-
|
|
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
|
|
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
|
|
6932
|
-
import
|
|
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
|
-
|
|
7046
|
-
|
|
7047
|
-
|
|
7048
|
-
|
|
7049
|
-
|
|
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
|
-
|
|
7056
|
-
|
|
7057
|
-
|
|
7058
|
-
|
|
7059
|
-
|
|
7060
|
-
|
|
7061
|
-
|
|
7062
|
-
|
|
7063
|
-
|
|
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.
|
|
7069
|
-
|
|
7070
|
-
|
|
7071
|
-
\
|
|
7072
|
-
|
|
7073
|
-
|
|
7074
|
-
|
|
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(
|
|
7525
|
+
console.log(chalk21.cyan(`
|
|
7096
7526
|
\u{1F4CB} Website Plan:
|
|
7097
7527
|
`));
|
|
7098
|
-
console.log(
|
|
7099
|
-
console.log(
|
|
7528
|
+
console.log(chalk21.bold(` ${websiteSpec.name}`));
|
|
7529
|
+
console.log(chalk21.dim(` ${websiteSpec.description}
|
|
7100
7530
|
`));
|
|
7101
|
-
console.log(
|
|
7102
|
-
console.log(
|
|
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(
|
|
7113
|
-
console.log(
|
|
7114
|
-
console.log(
|
|
7115
|
-
console.log(
|
|
7116
|
-
console.log(
|
|
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-
|
|
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-
|
|
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(
|
|
7248
|
-
console.log(
|
|
7249
|
-
console.log(
|
|
7250
|
-
console.log(
|
|
7251
|
-
console.log(
|
|
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-
|
|
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(
|
|
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
|
|
7321
|
-
|
|
7322
|
-
|
|
7323
|
-
"
|
|
7324
|
-
|
|
7325
|
-
"
|
|
7326
|
-
"
|
|
7327
|
-
|
|
7328
|
-
|
|
7329
|
-
|
|
7330
|
-
|
|
7331
|
-
"
|
|
7332
|
-
|
|
7333
|
-
|
|
7334
|
-
|
|
7335
|
-
|
|
7336
|
-
|
|
7337
|
-
|
|
7338
|
-
|
|
7339
|
-
|
|
7340
|
-
|
|
7341
|
-
|
|
7342
|
-
|
|
7343
|
-
|
|
7344
|
-
|
|
7345
|
-
|
|
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-
|
|
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
|
-
|
|
7409
|
-
}
|
|
7410
|
-
|
|
7411
|
-
|
|
7412
|
-
|
|
7413
|
-
|
|
7414
|
-
|
|
7415
|
-
|
|
7416
|
-
|
|
7417
|
-
|
|
7418
|
-
|
|
7419
|
-
|
|
7420
|
-
|
|
7421
|
-
|
|
7422
|
-
|
|
7423
|
-
|
|
7424
|
-
|
|
7425
|
-
|
|
7426
|
-
|
|
7427
|
-
|
|
7428
|
-
|
|
7429
|
-
|
|
7430
|
-
|
|
7431
|
-
|
|
7432
|
-
|
|
7433
|
-
|
|
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(
|
|
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
|
|
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.
|
|
7629
|
-
|
|
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
|
-
|
|
7634
|
-
|
|
7635
|
-
|
|
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
|
-
|
|
7648
|
-
|
|
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
|
-
|
|
7653
|
-
|
|
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(
|
|
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
|
-
|
|
7663
|
-
|
|
7664
|
-
|
|
7665
|
-
|
|
7666
|
-
|
|
7667
|
-
|
|
7668
|
-
|
|
7669
|
-
|
|
7670
|
-
|
|
7671
|
-
|
|
7672
|
-
|
|
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
|
-
|
|
7724
|
-
console.log(
|
|
8218
|
+
divider();
|
|
8219
|
+
console.log(colors.white(" You're back in the terminal."));
|
|
7725
8220
|
console.log("");
|
|
7726
|
-
console.log(
|
|
7727
|
-
console.log(
|
|
8221
|
+
console.log(colors.muted(" To start CodeBakers again, type:"));
|
|
8222
|
+
console.log(colors.success(" codebakers"));
|
|
7728
8223
|
console.log("");
|
|
7729
|
-
console.log(
|
|
7730
|
-
console.log(
|
|
7731
|
-
console.log(
|
|
7732
|
-
console.log(
|
|
7733
|
-
console.log(
|
|
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(
|
|
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(
|
|
7741
|
-
console.log(
|
|
7742
|
-
console.log(
|
|
7743
|
-
console.log(
|
|
7744
|
-
console.log(
|
|
7745
|
-
console.log(
|
|
7746
|
-
console.log(
|
|
7747
|
-
console.log(
|
|
7748
|
-
console.log(
|
|
7749
|
-
console.log(
|
|
7750
|
-
console.log(
|
|
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(
|
|
8349
|
+
console.log(chalk22.yellow("Coming soon!"));
|
|
7855
8350
|
}
|
|
7856
8351
|
}
|
|
7857
8352
|
function showPostSetupInstructions() {
|
|
7858
8353
|
console.log(boxen2(
|
|
7859
|
-
|
|
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
|
-
|
|
8361
|
+
chalk22.green.bold(`\u2713 ${projectName} created!
|
|
7867
8362
|
|
|
7868
|
-
`) +
|
|
8363
|
+
`) + chalk22.white("Next steps:\n\n") + chalk22.cyan("1. ") + "Go to your project:\n" + chalk22.dim(` cd ${displayPath}
|
|
7869
8364
|
|
|
7870
|
-
`) +
|
|
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
|
-
${
|
|
7877
|
-
|
|
7878
|
-
${
|
|
7879
|
-
${
|
|
7880
|
-
${
|
|
7881
|
-
${
|
|
7882
|
-
${
|
|
7883
|
-
|
|
7884
|
-
${
|
|
7885
|
-
${
|
|
7886
|
-
${
|
|
7887
|
-
${
|
|
7888
|
-
${
|
|
7889
|
-
|
|
7890
|
-
${
|
|
7891
|
-
${
|
|
7892
|
-
${
|
|
7893
|
-
${
|
|
7894
|
-
|
|
7895
|
-
${
|
|
7896
|
-
${
|
|
7897
|
-
${
|
|
7898
|
-
|
|
7899
|
-
${
|
|
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(
|
|
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);
|