codebakers 2.5.0 → 2.5.4
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-3PWAN6UL.js → advisors-RWRTSJRR.js} +1 -1
- package/dist/{chunk-URNRSXPU.js → chunk-D44U3IEA.js} +1 -1
- package/dist/{chunk-WZQNFV7Q.js → chunk-LANM5XQW.js} +1 -1
- package/dist/index.js +439 -283
- package/dist/{prd-YAUSAL5V.js → prd-RYITSL6Q.js} +1 -1
- package/package.json +1 -1
- package/src/commands/advisors.ts +1 -1
- package/src/commands/build.ts +1 -1
- package/src/commands/check.ts +1 -1
- package/src/commands/code.ts +1 -1
- package/src/commands/deploy.ts +2 -2
- package/src/commands/design.ts +1 -1
- package/src/commands/generate.ts +1 -1
- package/src/commands/init.ts +9 -2
- package/src/commands/integrate.ts +1 -1
- package/src/commands/migrate.ts +1 -1
- package/src/commands/prd-maker.ts +3 -2
- package/src/commands/prd.ts +1 -1
- package/src/commands/security.ts +1 -1
- package/src/commands/status.ts +1 -1
- package/src/commands/website.ts +41 -33
- package/src/index.ts +54 -42
- package/src/patterns/loader.ts +1 -1
- package/src/utils/display.ts +13 -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
|
});
|
|
@@ -1122,15 +1121,15 @@ Domain: ${domain || "Vercel default"}`,
|
|
|
1122
1121
|
spinner16.start("Installing dependencies...");
|
|
1123
1122
|
let installSuccess = false;
|
|
1124
1123
|
try {
|
|
1125
|
-
await
|
|
1124
|
+
await execa2("npm", ["install"], { cwd: projectPath, stdio: "inherit" });
|
|
1126
1125
|
installSuccess = true;
|
|
1127
1126
|
} catch {
|
|
1128
1127
|
try {
|
|
1129
|
-
await
|
|
1128
|
+
await execa2("pnpm", ["install"], { cwd: projectPath, stdio: "inherit" });
|
|
1130
1129
|
installSuccess = true;
|
|
1131
1130
|
} catch {
|
|
1132
1131
|
try {
|
|
1133
|
-
await
|
|
1132
|
+
await execa2("yarn", ["install"], { cwd: projectPath, stdio: "inherit" });
|
|
1134
1133
|
installSuccess = true;
|
|
1135
1134
|
} catch {
|
|
1136
1135
|
}
|
|
@@ -1149,11 +1148,11 @@ Domain: ${domain || "Vercel default"}`,
|
|
|
1149
1148
|
const repo = await github.createRepo(projectName, { private: true });
|
|
1150
1149
|
spinner16.stop(`GitHub repo created: ${repo.html_url}`);
|
|
1151
1150
|
try {
|
|
1152
|
-
await
|
|
1153
|
-
await
|
|
1154
|
-
await
|
|
1155
|
-
await
|
|
1156
|
-
await
|
|
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 });
|
|
1157
1156
|
} catch (gitError) {
|
|
1158
1157
|
console.log(chalk2.yellow(" \u26A0\uFE0F Git push failed. You can push manually later."));
|
|
1159
1158
|
}
|
|
@@ -1468,7 +1467,7 @@ coverage/
|
|
|
1468
1467
|
async function setupGitHooks(projectPath) {
|
|
1469
1468
|
const hooksDir = path.join(projectPath, ".git", "hooks");
|
|
1470
1469
|
if (!await fs.pathExists(path.join(projectPath, ".git"))) {
|
|
1471
|
-
await
|
|
1470
|
+
await execa2("git", ["init"], { cwd: projectPath });
|
|
1472
1471
|
}
|
|
1473
1472
|
await fs.ensureDir(hooksDir);
|
|
1474
1473
|
const preCommitHook = `#!/bin/sh
|
|
@@ -1494,13 +1493,13 @@ echo "\u2713 CodeBakers check passed"
|
|
|
1494
1493
|
// src/commands/code.ts
|
|
1495
1494
|
import * as p6 from "@clack/prompts";
|
|
1496
1495
|
import chalk6 from "chalk";
|
|
1497
|
-
import
|
|
1496
|
+
import fs6 from "fs-extra";
|
|
1498
1497
|
import * as path5 from "path";
|
|
1499
1498
|
import Anthropic from "@anthropic-ai/sdk";
|
|
1500
|
-
import { execa as
|
|
1499
|
+
import { execa as execa5 } from "execa";
|
|
1501
1500
|
|
|
1502
1501
|
// src/patterns/loader.ts
|
|
1503
|
-
import
|
|
1502
|
+
import fs2 from "fs-extra";
|
|
1504
1503
|
import * as path2 from "path";
|
|
1505
1504
|
var CORE_PATTERNS = `
|
|
1506
1505
|
# CODEBAKERS CORE PATTERNS
|
|
@@ -1802,7 +1801,7 @@ async function loadPatterns(config) {
|
|
|
1802
1801
|
// src/commands/check.ts
|
|
1803
1802
|
import * as p3 from "@clack/prompts";
|
|
1804
1803
|
import chalk3 from "chalk";
|
|
1805
|
-
import
|
|
1804
|
+
import fs3 from "fs-extra";
|
|
1806
1805
|
import * as path3 from "path";
|
|
1807
1806
|
import glob from "fast-glob";
|
|
1808
1807
|
var RULES = [
|
|
@@ -2100,8 +2099,8 @@ async function autoFix(violations) {
|
|
|
2100
2099
|
// src/utils/voice.ts
|
|
2101
2100
|
import * as p4 from "@clack/prompts";
|
|
2102
2101
|
import chalk4 from "chalk";
|
|
2103
|
-
import
|
|
2104
|
-
import { execa as
|
|
2102
|
+
import fs4 from "fs-extra";
|
|
2103
|
+
import { execa as execa3 } from "execa";
|
|
2105
2104
|
var voiceAvailable = null;
|
|
2106
2105
|
async function checkVoiceAvailability() {
|
|
2107
2106
|
if (voiceAvailable !== null) return voiceAvailable;
|
|
@@ -2109,14 +2108,14 @@ async function checkVoiceAvailability() {
|
|
|
2109
2108
|
if (process.platform === "win32") {
|
|
2110
2109
|
voiceAvailable = true;
|
|
2111
2110
|
} else if (process.platform === "darwin") {
|
|
2112
|
-
await
|
|
2111
|
+
await execa3("which", ["sox"], { reject: true });
|
|
2113
2112
|
voiceAvailable = true;
|
|
2114
2113
|
} else {
|
|
2115
2114
|
try {
|
|
2116
|
-
await
|
|
2115
|
+
await execa3("which", ["sox"], { reject: true });
|
|
2117
2116
|
voiceAvailable = true;
|
|
2118
2117
|
} catch {
|
|
2119
|
-
await
|
|
2118
|
+
await execa3("which", ["arecord"], { reject: true });
|
|
2120
2119
|
voiceAvailable = true;
|
|
2121
2120
|
}
|
|
2122
2121
|
}
|
|
@@ -2227,14 +2226,14 @@ async function getVoiceInput(prompt) {
|
|
|
2227
2226
|
async function playBeep() {
|
|
2228
2227
|
try {
|
|
2229
2228
|
if (process.platform === "win32") {
|
|
2230
|
-
await
|
|
2229
|
+
await execa3("powershell", ["-Command", "[console]::beep(800,200)"], { reject: false });
|
|
2231
2230
|
} else if (process.platform === "darwin") {
|
|
2232
|
-
await
|
|
2231
|
+
await execa3("afplay", ["/System/Library/Sounds/Tink.aiff"], { reject: false });
|
|
2233
2232
|
} else {
|
|
2234
2233
|
try {
|
|
2235
|
-
await
|
|
2234
|
+
await execa3("beep", ["-f", "800", "-l", "200"], { reject: false });
|
|
2236
2235
|
} catch {
|
|
2237
|
-
await
|
|
2236
|
+
await execa3("paplay", ["/usr/share/sounds/freedesktop/stereo/message.oga"], { reject: false });
|
|
2238
2237
|
}
|
|
2239
2238
|
}
|
|
2240
2239
|
} catch {
|
|
@@ -2257,7 +2256,7 @@ try {
|
|
|
2257
2256
|
}
|
|
2258
2257
|
`;
|
|
2259
2258
|
try {
|
|
2260
|
-
const result = await
|
|
2259
|
+
const result = await execa3("powershell", ["-Command", psScript], {
|
|
2261
2260
|
timeout: 15e3
|
|
2262
2261
|
});
|
|
2263
2262
|
return result.stdout.trim();
|
|
@@ -2268,7 +2267,7 @@ try {
|
|
|
2268
2267
|
async function recordWithMacOS() {
|
|
2269
2268
|
const tempFile = `/tmp/codebakers-voice-${Date.now()}.wav`;
|
|
2270
2269
|
try {
|
|
2271
|
-
await
|
|
2270
|
+
await execa3("sox", [
|
|
2272
2271
|
"-d",
|
|
2273
2272
|
// default input
|
|
2274
2273
|
"-r",
|
|
@@ -2305,7 +2304,7 @@ async function recordWithLinux() {
|
|
|
2305
2304
|
const tempFile = `/tmp/codebakers-voice-${Date.now()}.wav`;
|
|
2306
2305
|
try {
|
|
2307
2306
|
try {
|
|
2308
|
-
await
|
|
2307
|
+
await execa3("sox", [
|
|
2309
2308
|
"-d",
|
|
2310
2309
|
tempFile,
|
|
2311
2310
|
"rate",
|
|
@@ -2324,7 +2323,7 @@ async function recordWithLinux() {
|
|
|
2324
2323
|
"30"
|
|
2325
2324
|
], { timeout: 35e3 });
|
|
2326
2325
|
} catch {
|
|
2327
|
-
await
|
|
2326
|
+
await execa3("arecord", [
|
|
2328
2327
|
"-f",
|
|
2329
2328
|
"S16_LE",
|
|
2330
2329
|
"-r",
|
|
@@ -2345,7 +2344,7 @@ async function recordWithLinux() {
|
|
|
2345
2344
|
async function transcribeWithWhisper(audioFile) {
|
|
2346
2345
|
try {
|
|
2347
2346
|
const outputBase = audioFile.replace(".wav", "");
|
|
2348
|
-
await
|
|
2347
|
+
await execa3("whisper", [
|
|
2349
2348
|
audioFile,
|
|
2350
2349
|
"--language",
|
|
2351
2350
|
"en",
|
|
@@ -2369,23 +2368,23 @@ async function transcribeWithWhisper(audioFile) {
|
|
|
2369
2368
|
// src/utils/files.ts
|
|
2370
2369
|
import * as p5 from "@clack/prompts";
|
|
2371
2370
|
import chalk5 from "chalk";
|
|
2372
|
-
import
|
|
2371
|
+
import fs5 from "fs-extra";
|
|
2373
2372
|
import * as path4 from "path";
|
|
2374
|
-
import { execa as
|
|
2373
|
+
import { execa as execa4 } from "execa";
|
|
2375
2374
|
async function readClipboard() {
|
|
2376
2375
|
try {
|
|
2377
2376
|
if (process.platform === "win32") {
|
|
2378
|
-
const result = await
|
|
2377
|
+
const result = await execa4("powershell", ["-Command", "Get-Clipboard"], { timeout: 5e3 });
|
|
2379
2378
|
return result.stdout;
|
|
2380
2379
|
} else if (process.platform === "darwin") {
|
|
2381
|
-
const result = await
|
|
2380
|
+
const result = await execa4("pbpaste", [], { timeout: 5e3 });
|
|
2382
2381
|
return result.stdout;
|
|
2383
2382
|
} else {
|
|
2384
2383
|
try {
|
|
2385
|
-
const result = await
|
|
2384
|
+
const result = await execa4("xclip", ["-selection", "clipboard", "-o"], { timeout: 5e3 });
|
|
2386
2385
|
return result.stdout;
|
|
2387
2386
|
} catch {
|
|
2388
|
-
const result = await
|
|
2387
|
+
const result = await execa4("xsel", ["--clipboard", "--output"], { timeout: 5e3 });
|
|
2389
2388
|
return result.stdout;
|
|
2390
2389
|
}
|
|
2391
2390
|
}
|
|
@@ -2393,7 +2392,7 @@ async function readClipboard() {
|
|
|
2393
2392
|
return null;
|
|
2394
2393
|
}
|
|
2395
2394
|
}
|
|
2396
|
-
async function
|
|
2395
|
+
async function readFile(filePath) {
|
|
2397
2396
|
try {
|
|
2398
2397
|
let cleanPath = filePath.trim();
|
|
2399
2398
|
if (cleanPath.startsWith('"') && cleanPath.endsWith('"') || cleanPath.startsWith("'") && cleanPath.endsWith("'")) {
|
|
@@ -2501,7 +2500,7 @@ async function readFile5(filePath) {
|
|
|
2501
2500
|
}
|
|
2502
2501
|
async function extractPdfText(filePath) {
|
|
2503
2502
|
try {
|
|
2504
|
-
const result = await
|
|
2503
|
+
const result = await execa4("pdftotext", [filePath, "-"], { timeout: 3e4 });
|
|
2505
2504
|
return result.stdout;
|
|
2506
2505
|
} catch {
|
|
2507
2506
|
return null;
|
|
@@ -2710,7 +2709,7 @@ async function codeCommand(prompt, options = {}) {
|
|
|
2710
2709
|
\u{1F4CB} Read ${clipContent.length} characters from clipboard
|
|
2711
2710
|
`));
|
|
2712
2711
|
if (await fs6.pathExists(clipContent.trim())) {
|
|
2713
|
-
const file = await
|
|
2712
|
+
const file = await readFile(clipContent.trim());
|
|
2714
2713
|
if (file) {
|
|
2715
2714
|
fileContext = formatFilesForContext([file]);
|
|
2716
2715
|
console.log(chalk6.green(`\u{1F4C4} Loaded file: ${file.name}
|
|
@@ -2762,7 +2761,7 @@ ${clipContent}
|
|
|
2762
2761
|
continue;
|
|
2763
2762
|
}
|
|
2764
2763
|
} else if (await fs6.pathExists(userInput)) {
|
|
2765
|
-
const file = await
|
|
2764
|
+
const file = await readFile(userInput);
|
|
2766
2765
|
if (file) {
|
|
2767
2766
|
fileContext = formatFilesForContext([file]);
|
|
2768
2767
|
console.log(chalk6.green(`
|
|
@@ -2984,7 +2983,7 @@ async function executeAction(action, spinner16) {
|
|
|
2984
2983
|
case "RUN_COMMAND": {
|
|
2985
2984
|
spinner16.message(`Running: ${action.command}`);
|
|
2986
2985
|
const [cmd, ...args2] = action.command.split(" ");
|
|
2987
|
-
await
|
|
2986
|
+
await execa5(cmd, args2, { cwd, stdio: "pipe" });
|
|
2988
2987
|
break;
|
|
2989
2988
|
}
|
|
2990
2989
|
case "DELETE_FILE": {
|
|
@@ -3228,8 +3227,8 @@ Output only the fixed file content, no explanation.`;
|
|
|
3228
3227
|
// src/commands/deploy.ts
|
|
3229
3228
|
import * as p7 from "@clack/prompts";
|
|
3230
3229
|
import chalk7 from "chalk";
|
|
3231
|
-
import { execa as
|
|
3232
|
-
import
|
|
3230
|
+
import { execa as execa6 } from "execa";
|
|
3231
|
+
import fs7 from "fs-extra";
|
|
3233
3232
|
import * as path6 from "path";
|
|
3234
3233
|
import Anthropic2 from "@anthropic-ai/sdk";
|
|
3235
3234
|
async function deployCommand(options = {}) {
|
|
@@ -3303,7 +3302,7 @@ async function deployCommand(options = {}) {
|
|
|
3303
3302
|
}
|
|
3304
3303
|
spinner16.start("Running TypeScript check...");
|
|
3305
3304
|
try {
|
|
3306
|
-
await
|
|
3305
|
+
await execa6("npx", ["tsc", "--noEmit"], { cwd: process.cwd() });
|
|
3307
3306
|
spinner16.stop("TypeScript check passed");
|
|
3308
3307
|
} catch (error) {
|
|
3309
3308
|
spinner16.stop("");
|
|
@@ -3328,12 +3327,12 @@ async function deployCommand(options = {}) {
|
|
|
3328
3327
|
spinner16.start("Building project...");
|
|
3329
3328
|
try {
|
|
3330
3329
|
try {
|
|
3331
|
-
await
|
|
3330
|
+
await execa6("npm", ["run", "build"], { cwd: process.cwd() });
|
|
3332
3331
|
} catch {
|
|
3333
3332
|
try {
|
|
3334
|
-
await
|
|
3333
|
+
await execa6("pnpm", ["build"], { cwd: process.cwd() });
|
|
3335
3334
|
} catch {
|
|
3336
|
-
await
|
|
3335
|
+
await execa6("yarn", ["build"], { cwd: process.cwd() });
|
|
3337
3336
|
}
|
|
3338
3337
|
}
|
|
3339
3338
|
spinner16.stop("Build successful");
|
|
@@ -3353,7 +3352,7 @@ async function deployCommand(options = {}) {
|
|
|
3353
3352
|
if (fixed) {
|
|
3354
3353
|
spinner16.start("Retrying build...");
|
|
3355
3354
|
try {
|
|
3356
|
-
await
|
|
3355
|
+
await execa6("pnpm", ["build"], { cwd: process.cwd() });
|
|
3357
3356
|
spinner16.stop("Build successful");
|
|
3358
3357
|
} catch {
|
|
3359
3358
|
spinner16.stop("Build still failing");
|
|
@@ -3370,7 +3369,7 @@ async function deployCommand(options = {}) {
|
|
|
3370
3369
|
}
|
|
3371
3370
|
}
|
|
3372
3371
|
spinner16.start("Checking for uncommitted changes...");
|
|
3373
|
-
const { stdout: gitStatus } = await
|
|
3372
|
+
const { stdout: gitStatus } = await execa6("git", ["status", "--porcelain"], { cwd: process.cwd() });
|
|
3374
3373
|
if (gitStatus.trim()) {
|
|
3375
3374
|
spinner16.stop("");
|
|
3376
3375
|
const commit = await p7.confirm({
|
|
@@ -3384,10 +3383,10 @@ async function deployCommand(options = {}) {
|
|
|
3384
3383
|
initialValue: "Pre-deploy changes"
|
|
3385
3384
|
});
|
|
3386
3385
|
if (!p7.isCancel(message)) {
|
|
3387
|
-
await
|
|
3388
|
-
await
|
|
3386
|
+
await execa6("git", ["add", "."], { cwd: process.cwd() });
|
|
3387
|
+
await execa6("git", ["commit", "-m", message], { cwd: process.cwd() });
|
|
3389
3388
|
spinner16.start("Pushing to GitHub...");
|
|
3390
|
-
await
|
|
3389
|
+
await execa6("git", ["push"], { cwd: process.cwd() });
|
|
3391
3390
|
spinner16.stop("Pushed to GitHub");
|
|
3392
3391
|
}
|
|
3393
3392
|
}
|
|
@@ -3408,7 +3407,7 @@ ${chalk7.bold("Type:")} ${deployType}
|
|
|
3408
3407
|
${chalk7.bold("Time:")} ${(/* @__PURE__ */ new Date()).toLocaleTimeString()}
|
|
3409
3408
|
|
|
3410
3409
|
${chalk7.dim("View in Vercel Dashboard:")}
|
|
3411
|
-
${chalk7.dim(
|
|
3410
|
+
${chalk7.dim("https://vercel.com/dashboard")}
|
|
3412
3411
|
`));
|
|
3413
3412
|
} catch (error) {
|
|
3414
3413
|
spinner16.stop("");
|
|
@@ -3471,7 +3470,7 @@ Output ONLY the corrected file content, no explanations. Keep all existing funct
|
|
|
3471
3470
|
}
|
|
3472
3471
|
async function fixTypeScriptErrors(config) {
|
|
3473
3472
|
try {
|
|
3474
|
-
const { stderr } = await
|
|
3473
|
+
const { stderr } = await execa6("npx", ["tsc", "--noEmit"], {
|
|
3475
3474
|
cwd: process.cwd(),
|
|
3476
3475
|
reject: false
|
|
3477
3476
|
});
|
|
@@ -3583,7 +3582,7 @@ async function connectCommand(service) {
|
|
|
3583
3582
|
// src/commands/status.ts
|
|
3584
3583
|
import * as p8 from "@clack/prompts";
|
|
3585
3584
|
import chalk8 from "chalk";
|
|
3586
|
-
import
|
|
3585
|
+
import fs8 from "fs-extra";
|
|
3587
3586
|
import * as path7 from "path";
|
|
3588
3587
|
async function statusCommand() {
|
|
3589
3588
|
const config = new Config();
|
|
@@ -4137,7 +4136,7 @@ async function learnCommand() {
|
|
|
4137
4136
|
// src/commands/security.ts
|
|
4138
4137
|
import * as p11 from "@clack/prompts";
|
|
4139
4138
|
import chalk11 from "chalk";
|
|
4140
|
-
import
|
|
4139
|
+
import fs9 from "fs-extra";
|
|
4141
4140
|
import glob2 from "fast-glob";
|
|
4142
4141
|
import * as path8 from "path";
|
|
4143
4142
|
async function securityCommand() {
|
|
@@ -4217,7 +4216,7 @@ function displaySecurityScore(score) {
|
|
|
4217
4216
|
// src/commands/generate.ts
|
|
4218
4217
|
import * as p12 from "@clack/prompts";
|
|
4219
4218
|
import chalk12 from "chalk";
|
|
4220
|
-
import
|
|
4219
|
+
import fs10 from "fs-extra";
|
|
4221
4220
|
import * as path9 from "path";
|
|
4222
4221
|
async function generateCommand(type) {
|
|
4223
4222
|
p12.intro(chalk12.bgCyan.black(" Generate "));
|
|
@@ -4401,7 +4400,7 @@ async function fixCommand() {
|
|
|
4401
4400
|
// src/commands/design.ts
|
|
4402
4401
|
import * as p14 from "@clack/prompts";
|
|
4403
4402
|
import chalk14 from "chalk";
|
|
4404
|
-
import
|
|
4403
|
+
import fs11 from "fs-extra";
|
|
4405
4404
|
import * as path10 from "path";
|
|
4406
4405
|
var DESIGN_PROFILES = {
|
|
4407
4406
|
minimal: {
|
|
@@ -4657,8 +4656,8 @@ async function viewSettings() {
|
|
|
4657
4656
|
// src/commands/migrate.ts
|
|
4658
4657
|
import * as p15 from "@clack/prompts";
|
|
4659
4658
|
import chalk15 from "chalk";
|
|
4660
|
-
import { execa as
|
|
4661
|
-
import
|
|
4659
|
+
import { execa as execa7 } from "execa";
|
|
4660
|
+
import fs12 from "fs-extra";
|
|
4662
4661
|
import * as path11 from "path";
|
|
4663
4662
|
async function migrateCommand(options = {}) {
|
|
4664
4663
|
const config = new Config();
|
|
@@ -4725,13 +4724,13 @@ async function checkMigrationStatus(tool) {
|
|
|
4725
4724
|
let result;
|
|
4726
4725
|
switch (tool) {
|
|
4727
4726
|
case "drizzle":
|
|
4728
|
-
result = await
|
|
4727
|
+
result = await execa7("npx", ["drizzle-kit", "check"], { cwd: process.cwd(), reject: false });
|
|
4729
4728
|
break;
|
|
4730
4729
|
case "prisma":
|
|
4731
|
-
result = await
|
|
4730
|
+
result = await execa7("npx", ["prisma", "migrate", "status"], { cwd: process.cwd(), reject: false });
|
|
4732
4731
|
break;
|
|
4733
4732
|
case "supabase":
|
|
4734
|
-
result = await
|
|
4733
|
+
result = await execa7("npx", ["supabase", "migration", "list"], { cwd: process.cwd(), reject: false });
|
|
4735
4734
|
break;
|
|
4736
4735
|
}
|
|
4737
4736
|
spinner16.stop("Status check complete");
|
|
@@ -4759,13 +4758,13 @@ async function generateMigration(tool) {
|
|
|
4759
4758
|
let result;
|
|
4760
4759
|
switch (tool) {
|
|
4761
4760
|
case "drizzle":
|
|
4762
|
-
result = await
|
|
4761
|
+
result = await execa7("npx", ["drizzle-kit", "generate", "--name", name], { cwd: process.cwd(), reject: false });
|
|
4763
4762
|
break;
|
|
4764
4763
|
case "prisma":
|
|
4765
|
-
result = await
|
|
4764
|
+
result = await execa7("npx", ["prisma", "migrate", "dev", "--name", name, "--create-only"], { cwd: process.cwd(), reject: false });
|
|
4766
4765
|
break;
|
|
4767
4766
|
case "supabase":
|
|
4768
|
-
result = await
|
|
4767
|
+
result = await execa7("npx", ["supabase", "migration", "new", name], { cwd: process.cwd(), reject: false });
|
|
4769
4768
|
break;
|
|
4770
4769
|
}
|
|
4771
4770
|
spinner16.stop("Migration generated");
|
|
@@ -4785,20 +4784,20 @@ async function pushMigration(tool) {
|
|
|
4785
4784
|
let migrationSql = "";
|
|
4786
4785
|
switch (tool) {
|
|
4787
4786
|
case "drizzle":
|
|
4788
|
-
result = await
|
|
4787
|
+
result = await execa7("npx", ["drizzle-kit", "push"], {
|
|
4789
4788
|
cwd: process.cwd(),
|
|
4790
4789
|
reject: false,
|
|
4791
4790
|
env: { ...process.env }
|
|
4792
4791
|
});
|
|
4793
4792
|
break;
|
|
4794
4793
|
case "prisma":
|
|
4795
|
-
result = await
|
|
4794
|
+
result = await execa7("npx", ["prisma", "db", "push"], {
|
|
4796
4795
|
cwd: process.cwd(),
|
|
4797
4796
|
reject: false
|
|
4798
4797
|
});
|
|
4799
4798
|
break;
|
|
4800
4799
|
case "supabase":
|
|
4801
|
-
result = await
|
|
4800
|
+
result = await execa7("npx", ["supabase", "db", "push"], {
|
|
4802
4801
|
cwd: process.cwd(),
|
|
4803
4802
|
reject: false
|
|
4804
4803
|
});
|
|
@@ -4882,13 +4881,13 @@ async function pullSchema(tool) {
|
|
|
4882
4881
|
let result;
|
|
4883
4882
|
switch (tool) {
|
|
4884
4883
|
case "drizzle":
|
|
4885
|
-
result = await
|
|
4884
|
+
result = await execa7("npx", ["drizzle-kit", "introspect"], { cwd: process.cwd(), reject: false });
|
|
4886
4885
|
break;
|
|
4887
4886
|
case "prisma":
|
|
4888
|
-
result = await
|
|
4887
|
+
result = await execa7("npx", ["prisma", "db", "pull"], { cwd: process.cwd(), reject: false });
|
|
4889
4888
|
break;
|
|
4890
4889
|
case "supabase":
|
|
4891
|
-
result = await
|
|
4890
|
+
result = await execa7("npx", ["supabase", "db", "pull"], { cwd: process.cwd(), reject: false });
|
|
4892
4891
|
break;
|
|
4893
4892
|
}
|
|
4894
4893
|
spinner16.stop("Schema pulled");
|
|
@@ -4914,7 +4913,7 @@ async function extractMigrationSQL(tool, errorOutput) {
|
|
|
4914
4913
|
return latestMigration;
|
|
4915
4914
|
}
|
|
4916
4915
|
}
|
|
4917
|
-
const result = await
|
|
4916
|
+
const result = await execa7("npx", ["drizzle-kit", "generate", "--sql"], {
|
|
4918
4917
|
cwd,
|
|
4919
4918
|
reject: false
|
|
4920
4919
|
});
|
|
@@ -4963,17 +4962,17 @@ async function copyToClipboard(text17) {
|
|
|
4963
4962
|
try {
|
|
4964
4963
|
const platform = process.platform;
|
|
4965
4964
|
if (platform === "win32") {
|
|
4966
|
-
const proc = await
|
|
4965
|
+
const proc = await execa7("clip", { input: text17, reject: false });
|
|
4967
4966
|
return proc.exitCode === 0;
|
|
4968
4967
|
} else if (platform === "darwin") {
|
|
4969
|
-
const proc = await
|
|
4968
|
+
const proc = await execa7("pbcopy", { input: text17, reject: false });
|
|
4970
4969
|
return proc.exitCode === 0;
|
|
4971
4970
|
} else {
|
|
4972
4971
|
try {
|
|
4973
|
-
const proc = await
|
|
4972
|
+
const proc = await execa7("xclip", ["-selection", "clipboard"], { input: text17, reject: false });
|
|
4974
4973
|
return proc.exitCode === 0;
|
|
4975
4974
|
} catch {
|
|
4976
|
-
const proc = await
|
|
4975
|
+
const proc = await execa7("xsel", ["--clipboard", "--input"], { input: text17, reject: false });
|
|
4977
4976
|
return proc.exitCode === 0;
|
|
4978
4977
|
}
|
|
4979
4978
|
}
|
|
@@ -4985,9 +4984,10 @@ async function copyToClipboard(text17) {
|
|
|
4985
4984
|
// src/commands/prd-maker.ts
|
|
4986
4985
|
import * as p16 from "@clack/prompts";
|
|
4987
4986
|
import chalk16 from "chalk";
|
|
4988
|
-
import
|
|
4987
|
+
import fs13 from "fs-extra";
|
|
4989
4988
|
import * as path12 from "path";
|
|
4990
4989
|
import Anthropic3 from "@anthropic-ai/sdk";
|
|
4990
|
+
import { execa as execa8 } from "execa";
|
|
4991
4991
|
async function prdMakerCommand() {
|
|
4992
4992
|
const config = new Config();
|
|
4993
4993
|
if (!config.isConfigured()) {
|
|
@@ -5082,10 +5082,10 @@ async function prdMakerCommand() {
|
|
|
5082
5082
|
return;
|
|
5083
5083
|
}
|
|
5084
5084
|
if (nextStep === "build") {
|
|
5085
|
-
const { prdCommand: prdCommand2 } = await import("./prd-
|
|
5085
|
+
const { prdCommand: prdCommand2 } = await import("./prd-RYITSL6Q.js");
|
|
5086
5086
|
await prdCommand2(filepath);
|
|
5087
5087
|
} else if (nextStep === "advisors") {
|
|
5088
|
-
const { advisorsCommand: advisorsCommand2 } = await import("./advisors-
|
|
5088
|
+
const { advisorsCommand: advisorsCommand2 } = await import("./advisors-RWRTSJRR.js");
|
|
5089
5089
|
await advisorsCommand2();
|
|
5090
5090
|
}
|
|
5091
5091
|
}
|
|
@@ -5216,7 +5216,7 @@ async function conductPRDInterview(inputMethod) {
|
|
|
5216
5216
|
}
|
|
5217
5217
|
async function checkVoiceAvailability2() {
|
|
5218
5218
|
try {
|
|
5219
|
-
await
|
|
5219
|
+
await execa8("sox", ["--version"], { reject: true });
|
|
5220
5220
|
return true;
|
|
5221
5221
|
} catch {
|
|
5222
5222
|
try {
|
|
@@ -5224,7 +5224,7 @@ async function checkVoiceAvailability2() {
|
|
|
5224
5224
|
return true;
|
|
5225
5225
|
}
|
|
5226
5226
|
if (process.platform === "darwin") {
|
|
5227
|
-
await
|
|
5227
|
+
await execa8("which", ["say"], { reject: true });
|
|
5228
5228
|
return true;
|
|
5229
5229
|
}
|
|
5230
5230
|
} catch {
|
|
@@ -5302,7 +5302,7 @@ $result = $recognizer.Recognize()
|
|
|
5302
5302
|
if ($result) { Write-Output $result.Text }
|
|
5303
5303
|
`;
|
|
5304
5304
|
try {
|
|
5305
|
-
const result = await
|
|
5305
|
+
const result = await execa8("powershell", ["-Command", psScript], {
|
|
5306
5306
|
timeout: 3e4
|
|
5307
5307
|
// 30 second timeout
|
|
5308
5308
|
});
|
|
@@ -5315,7 +5315,7 @@ async function recordWithMacOS2() {
|
|
|
5315
5315
|
const tempFile = `/tmp/codebakers-voice-${Date.now()}.wav`;
|
|
5316
5316
|
try {
|
|
5317
5317
|
console.log(chalk16.dim(" Recording for up to 10 seconds..."));
|
|
5318
|
-
await
|
|
5318
|
+
await execa8("sox", [
|
|
5319
5319
|
"-d",
|
|
5320
5320
|
// default input device
|
|
5321
5321
|
"-r",
|
|
@@ -5339,7 +5339,7 @@ async function recordWithMacOS2() {
|
|
|
5339
5339
|
// stop on silence
|
|
5340
5340
|
], { timeout: 15e3 });
|
|
5341
5341
|
try {
|
|
5342
|
-
const result = await
|
|
5342
|
+
const result = await execa8("whisper", [tempFile, "--language", "en", "--output_format", "txt"], {
|
|
5343
5343
|
timeout: 3e4
|
|
5344
5344
|
});
|
|
5345
5345
|
const txtFile = tempFile.replace(".wav", ".txt");
|
|
@@ -5360,7 +5360,7 @@ async function recordWithLinux2() {
|
|
|
5360
5360
|
const tempFile = `/tmp/codebakers-voice-${Date.now()}.wav`;
|
|
5361
5361
|
try {
|
|
5362
5362
|
try {
|
|
5363
|
-
await
|
|
5363
|
+
await execa8("sox", [
|
|
5364
5364
|
"-d",
|
|
5365
5365
|
tempFile,
|
|
5366
5366
|
"rate",
|
|
@@ -5376,7 +5376,7 @@ async function recordWithLinux2() {
|
|
|
5376
5376
|
"1%"
|
|
5377
5377
|
], { timeout: 15e3 });
|
|
5378
5378
|
} catch {
|
|
5379
|
-
await
|
|
5379
|
+
await execa8("arecord", [
|
|
5380
5380
|
"-f",
|
|
5381
5381
|
"S16_LE",
|
|
5382
5382
|
"-r",
|
|
@@ -5389,7 +5389,7 @@ async function recordWithLinux2() {
|
|
|
5389
5389
|
], { timeout: 15e3 });
|
|
5390
5390
|
}
|
|
5391
5391
|
try {
|
|
5392
|
-
const result = await
|
|
5392
|
+
const result = await execa8("whisper", [tempFile, "--language", "en", "--output_format", "txt"], {
|
|
5393
5393
|
timeout: 3e4
|
|
5394
5394
|
});
|
|
5395
5395
|
const txtFile = tempFile.replace(".wav", ".txt");
|
|
@@ -5489,7 +5489,7 @@ Make it professional, detailed, and actionable. This should be ready to hand off
|
|
|
5489
5489
|
// src/commands/build.ts
|
|
5490
5490
|
import * as p17 from "@clack/prompts";
|
|
5491
5491
|
import chalk17 from "chalk";
|
|
5492
|
-
import
|
|
5492
|
+
import fs14 from "fs-extra";
|
|
5493
5493
|
import * as path13 from "path";
|
|
5494
5494
|
import Anthropic4 from "@anthropic-ai/sdk";
|
|
5495
5495
|
import { execa as execa9 } from "execa";
|
|
@@ -6187,7 +6187,7 @@ function sleep(ms) {
|
|
|
6187
6187
|
// src/commands/integrate.ts
|
|
6188
6188
|
import * as p18 from "@clack/prompts";
|
|
6189
6189
|
import chalk18 from "chalk";
|
|
6190
|
-
import
|
|
6190
|
+
import fs15 from "fs-extra";
|
|
6191
6191
|
import * as path14 from "path";
|
|
6192
6192
|
import open2 from "open";
|
|
6193
6193
|
import { execa as execa10 } from "execa";
|
|
@@ -6974,8 +6974,8 @@ function sleep2(ms) {
|
|
|
6974
6974
|
|
|
6975
6975
|
// src/commands/website.ts
|
|
6976
6976
|
import * as p19 from "@clack/prompts";
|
|
6977
|
-
import
|
|
6978
|
-
import
|
|
6977
|
+
import chalk21 from "chalk";
|
|
6978
|
+
import fs16 from "fs-extra";
|
|
6979
6979
|
import * as path15 from "path";
|
|
6980
6980
|
import Anthropic5 from "@anthropic-ai/sdk";
|
|
6981
6981
|
import { execa as execa11 } from "execa";
|
|
@@ -7098,58 +7098,6 @@ function showError(error) {
|
|
|
7098
7098
|
}
|
|
7099
7099
|
console.log("");
|
|
7100
7100
|
}
|
|
7101
|
-
function showSuccess(success) {
|
|
7102
|
-
console.log("");
|
|
7103
|
-
console.log(chalk19.green(` \u2705 ${success.title}`));
|
|
7104
|
-
if (success.message) {
|
|
7105
|
-
console.log(chalk19.gray(` ${success.message}`));
|
|
7106
|
-
}
|
|
7107
|
-
if (success.stats && success.stats.length > 0) {
|
|
7108
|
-
console.log("");
|
|
7109
|
-
console.log(chalk19.white(` \u{1F4CA} Summary:`));
|
|
7110
|
-
success.stats.forEach((stat2) => {
|
|
7111
|
-
console.log(chalk19.gray(` ${stat2.label}: ${chalk19.white(stat2.value)}`));
|
|
7112
|
-
});
|
|
7113
|
-
}
|
|
7114
|
-
if (success.nextSteps && success.nextSteps.length > 0) {
|
|
7115
|
-
console.log("");
|
|
7116
|
-
console.log(chalk19.white(` Next steps:`));
|
|
7117
|
-
success.nextSteps.forEach((step) => {
|
|
7118
|
-
console.log(chalk19.cyan(` ${step}`));
|
|
7119
|
-
});
|
|
7120
|
-
}
|
|
7121
|
-
if (success.command) {
|
|
7122
|
-
console.log("");
|
|
7123
|
-
console.log(chalk19.white(` Quick start:`));
|
|
7124
|
-
console.log(chalk19.cyan(` ${success.command}`));
|
|
7125
|
-
}
|
|
7126
|
-
console.log("");
|
|
7127
|
-
}
|
|
7128
|
-
function showFileList(title, files) {
|
|
7129
|
-
console.log("");
|
|
7130
|
-
console.log(chalk19.white(` \u{1F4C1} ${title}`));
|
|
7131
|
-
files.forEach((file, i) => {
|
|
7132
|
-
const isLast = i === files.length - 1;
|
|
7133
|
-
const prefix = isLast ? "\u2514\u2500\u2500" : "\u251C\u2500\u2500";
|
|
7134
|
-
const icon = getFileIcon(file);
|
|
7135
|
-
console.log(chalk19.gray(` ${prefix} ${icon} ${file}`));
|
|
7136
|
-
});
|
|
7137
|
-
console.log("");
|
|
7138
|
-
}
|
|
7139
|
-
function getFileIcon(filename) {
|
|
7140
|
-
const ext = filename.split(".").pop()?.toLowerCase();
|
|
7141
|
-
const icons = {
|
|
7142
|
-
"tsx": "\u269B\uFE0F",
|
|
7143
|
-
"ts": "\u{1F4D8}",
|
|
7144
|
-
"js": "\u{1F4D2}",
|
|
7145
|
-
"jsx": "\u269B\uFE0F",
|
|
7146
|
-
"css": "\u{1F3A8}",
|
|
7147
|
-
"json": "\u{1F4CB}",
|
|
7148
|
-
"md": "\u{1F4DD}",
|
|
7149
|
-
"html": "\u{1F310}"
|
|
7150
|
-
};
|
|
7151
|
-
return icons[ext || ""] || "\u{1F4C4}";
|
|
7152
|
-
}
|
|
7153
7101
|
var ERRORS = {
|
|
7154
7102
|
nodeNotInstalled: {
|
|
7155
7103
|
title: "Node.js not found",
|
|
@@ -7205,6 +7153,218 @@ var ERRORS = {
|
|
|
7205
7153
|
}
|
|
7206
7154
|
};
|
|
7207
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
|
+
|
|
7208
7368
|
// src/commands/website.ts
|
|
7209
7369
|
var TEMPLATES = [
|
|
7210
7370
|
{
|
|
@@ -7315,37 +7475,34 @@ var TEMPLATES = [
|
|
|
7315
7475
|
async function websiteCommand() {
|
|
7316
7476
|
const config = new Config();
|
|
7317
7477
|
if (!config.isConfigured()) {
|
|
7318
|
-
|
|
7319
|
-
|
|
7320
|
-
|
|
7321
|
-
|
|
7322
|
-
|
|
7323
|
-
`));
|
|
7478
|
+
showErrorScreen({
|
|
7479
|
+
title: "CodeBakers not configured",
|
|
7480
|
+
message: "Run setup first to connect your API keys.",
|
|
7481
|
+
command: "codebakers setup"
|
|
7482
|
+
});
|
|
7324
7483
|
return;
|
|
7325
7484
|
}
|
|
7326
7485
|
const anthropicCreds = config.getCredentials("anthropic");
|
|
7327
7486
|
if (!anthropicCreds?.apiKey) {
|
|
7328
|
-
|
|
7329
|
-
|
|
7330
|
-
|
|
7331
|
-
|
|
7332
|
-
|
|
7333
|
-
|
|
7334
|
-
|
|
7335
|
-
|
|
7336
|
-
|
|
7337
|
-
${chalk20.dim("https://console.anthropic.com/settings/keys")}
|
|
7338
|
-
`));
|
|
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
|
+
});
|
|
7339
7496
|
return;
|
|
7340
7497
|
}
|
|
7341
|
-
console.
|
|
7342
|
-
|
|
7343
|
-
|
|
7344
|
-
\
|
|
7345
|
-
|
|
7346
|
-
|
|
7347
|
-
|
|
7348
|
-
|
|
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
|
+
]);
|
|
7349
7506
|
const approach = await p19.select({
|
|
7350
7507
|
message: "How would you like to build your website?",
|
|
7351
7508
|
options: [
|
|
@@ -7365,14 +7522,14 @@ async function websiteCommand() {
|
|
|
7365
7522
|
websiteSpec = await cloneDesign(anthropic);
|
|
7366
7523
|
}
|
|
7367
7524
|
if (!websiteSpec) return;
|
|
7368
|
-
console.log(
|
|
7525
|
+
console.log(chalk21.cyan(`
|
|
7369
7526
|
\u{1F4CB} Website Plan:
|
|
7370
7527
|
`));
|
|
7371
|
-
console.log(
|
|
7372
|
-
console.log(
|
|
7528
|
+
console.log(chalk21.bold(` ${websiteSpec.name}`));
|
|
7529
|
+
console.log(chalk21.dim(` ${websiteSpec.description}
|
|
7373
7530
|
`));
|
|
7374
|
-
console.log(
|
|
7375
|
-
console.log(
|
|
7531
|
+
console.log(chalk21.dim(` Style: ${websiteSpec.style}`));
|
|
7532
|
+
console.log(chalk21.dim(` Sections: ${websiteSpec.sections.join(", ")}
|
|
7376
7533
|
`));
|
|
7377
7534
|
const confirm13 = await p19.confirm({
|
|
7378
7535
|
message: "Build this website?",
|
|
@@ -7382,11 +7539,11 @@ async function websiteCommand() {
|
|
|
7382
7539
|
await buildWebsite(anthropic, websiteSpec, config);
|
|
7383
7540
|
}
|
|
7384
7541
|
async function describeWebsite(anthropic) {
|
|
7385
|
-
console.log(
|
|
7386
|
-
console.log(
|
|
7387
|
-
console.log(
|
|
7388
|
-
console.log(
|
|
7389
|
-
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'));
|
|
7390
7547
|
const description = await textWithVoice({
|
|
7391
7548
|
message: "Describe your website:",
|
|
7392
7549
|
placeholder: "A landing page for..."
|
|
@@ -7517,11 +7674,11 @@ Make the content specific and compelling for this business.`
|
|
|
7517
7674
|
return JSON.parse(jsonMatch[0]);
|
|
7518
7675
|
}
|
|
7519
7676
|
async function cloneDesign(anthropic) {
|
|
7520
|
-
console.log(
|
|
7521
|
-
console.log(
|
|
7522
|
-
console.log(
|
|
7523
|
-
console.log(
|
|
7524
|
-
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'));
|
|
7525
7682
|
const inspiration = await textWithVoice({
|
|
7526
7683
|
message: "What site do you want to be inspired by?",
|
|
7527
7684
|
placeholder: "Like Linear.app but for..."
|
|
@@ -7587,8 +7744,8 @@ async function buildWebsite(anthropic, spec, config) {
|
|
|
7587
7744
|
if (!overwrite || p19.isCancel(overwrite)) return;
|
|
7588
7745
|
await fs16.remove(projectPath);
|
|
7589
7746
|
}
|
|
7590
|
-
console.log(
|
|
7591
|
-
\u{1F3D7}\uFE0F Building ${
|
|
7747
|
+
console.log(chalk21.cyan(`
|
|
7748
|
+
\u{1F3D7}\uFE0F Building ${chalk21.bold(spec.name)}
|
|
7592
7749
|
`));
|
|
7593
7750
|
const steps = new StepTracker([
|
|
7594
7751
|
"Create project structure",
|
|
@@ -7751,19 +7908,19 @@ Make it production-quality and visually impressive.`
|
|
|
7751
7908
|
steps.skip();
|
|
7752
7909
|
}
|
|
7753
7910
|
if (createdFiles.length > 0) {
|
|
7754
|
-
|
|
7911
|
+
showFileTree("Files created", createdFiles.slice(0, 10));
|
|
7755
7912
|
if (createdFiles.length > 10) {
|
|
7756
|
-
console.log(
|
|
7913
|
+
console.log(colors.muted(` ... and ${createdFiles.length - 10} more files`));
|
|
7757
7914
|
}
|
|
7758
7915
|
}
|
|
7759
|
-
|
|
7916
|
+
showSuccessScreen({
|
|
7760
7917
|
title: "Website built successfully!",
|
|
7761
7918
|
message: spec.description,
|
|
7762
7919
|
stats: [
|
|
7763
7920
|
{ label: "Project", value: spec.name },
|
|
7764
|
-
{ label: "Files
|
|
7921
|
+
{ label: "Files", value: createdFiles.length.toString() + " created" },
|
|
7765
7922
|
{ label: "Sections", value: spec.sections.length.toString() },
|
|
7766
|
-
{ label: "
|
|
7923
|
+
{ label: "Time", value: steps.getElapsedTime() }
|
|
7767
7924
|
],
|
|
7768
7925
|
nextSteps: [
|
|
7769
7926
|
`cd ${spec.name}`,
|
|
@@ -7776,7 +7933,7 @@ Make it production-quality and visually impressive.`
|
|
|
7776
7933
|
initialValue: true
|
|
7777
7934
|
});
|
|
7778
7935
|
if (openDev && !p19.isCancel(openDev)) {
|
|
7779
|
-
console.log(
|
|
7936
|
+
console.log(colors.muted("\n Starting dev server...\n"));
|
|
7780
7937
|
process.chdir(projectPath);
|
|
7781
7938
|
await execa11("npm", ["run", "dev"], {
|
|
7782
7939
|
stdio: "inherit",
|
|
@@ -7953,26 +8110,21 @@ If unclear between multiple commands, use the most likely one with lower confide
|
|
|
7953
8110
|
}
|
|
7954
8111
|
|
|
7955
8112
|
// src/index.ts
|
|
7956
|
-
var VERSION = "2.5.
|
|
7957
|
-
var logo = `
|
|
7958
|
-
\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
|
|
7959
|
-
\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
|
|
7960
|
-
\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
|
|
7961
|
-
\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
|
|
7962
|
-
\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
|
|
7963
|
-
\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
|
|
7964
|
-
`;
|
|
8113
|
+
var VERSION = "2.5.4";
|
|
7965
8114
|
async function showMainMenu() {
|
|
7966
8115
|
const config = new Config();
|
|
7967
|
-
console.
|
|
7968
|
-
|
|
7969
|
-
`));
|
|
8116
|
+
console.clear();
|
|
8117
|
+
showLogo();
|
|
8118
|
+
console.log(colors.muted(` v${VERSION}`));
|
|
8119
|
+
console.log("");
|
|
7970
8120
|
const hasAnthropic = !!config.getCredentials("anthropic")?.apiKey;
|
|
7971
8121
|
if (!hasAnthropic) {
|
|
7972
|
-
|
|
7973
|
-
|
|
7974
|
-
|
|
7975
|
-
|
|
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");
|
|
7976
8128
|
await setupCommand();
|
|
7977
8129
|
showPostSetupInstructions();
|
|
7978
8130
|
return;
|
|
@@ -7983,34 +8135,38 @@ async function showMainMenu() {
|
|
|
7983
8135
|
const folderName = path16.basename(cwd);
|
|
7984
8136
|
if (inProject && projectConfig) {
|
|
7985
8137
|
const framework = projectConfig.framework || "detected";
|
|
7986
|
-
|
|
7987
|
-
|
|
7988
|
-
`)
|
|
8138
|
+
box([
|
|
8139
|
+
colors.secondary("\u{1F4C1} ") + colors.white(folderName),
|
|
8140
|
+
colors.muted(` ${framework} project`)
|
|
8141
|
+
]);
|
|
7989
8142
|
await showProjectMenu(config);
|
|
7990
8143
|
} else {
|
|
7991
|
-
|
|
7992
|
-
|
|
7993
|
-
|
|
8144
|
+
box([
|
|
8145
|
+
colors.secondary("\u{1F4C1} ") + colors.white(cwd),
|
|
8146
|
+
colors.muted(" Not a project folder")
|
|
8147
|
+
]);
|
|
7994
8148
|
await showStartMenu(config);
|
|
7995
8149
|
}
|
|
7996
8150
|
}
|
|
7997
8151
|
async function showStartMenu(config) {
|
|
7998
|
-
console.log(
|
|
8152
|
+
console.log(colors.muted(" This folder doesn't have a project yet."));
|
|
8153
|
+
console.log("");
|
|
7999
8154
|
let keepRunning = true;
|
|
8000
8155
|
while (keepRunning) {
|
|
8001
|
-
|
|
8002
|
-
|
|
8003
|
-
|
|
8004
|
-
|
|
8005
|
-
|
|
8006
|
-
|
|
8007
|
-
|
|
8008
|
-
|
|
8009
|
-
|
|
8010
|
-
|
|
8011
|
-
|
|
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
|
+
]);
|
|
8012
8168
|
const choice = await p21.text({
|
|
8013
|
-
message: "Enter a number (0-8):",
|
|
8169
|
+
message: colors.primary("Enter a number (0-8):"),
|
|
8014
8170
|
placeholder: "1",
|
|
8015
8171
|
validate: (value) => {
|
|
8016
8172
|
if (!/^[0-8]$/.test(value) && value !== "") return "Please enter a number 0-8";
|
|
@@ -8059,34 +8215,34 @@ async function showStartMenu(config) {
|
|
|
8059
8215
|
}
|
|
8060
8216
|
function showExitMessage() {
|
|
8061
8217
|
console.log("");
|
|
8062
|
-
|
|
8063
|
-
console.log(
|
|
8218
|
+
divider();
|
|
8219
|
+
console.log(colors.white(" You're back in the terminal."));
|
|
8064
8220
|
console.log("");
|
|
8065
|
-
console.log(
|
|
8066
|
-
console.log(
|
|
8221
|
+
console.log(colors.muted(" To start CodeBakers again, type:"));
|
|
8222
|
+
console.log(colors.success(" codebakers"));
|
|
8067
8223
|
console.log("");
|
|
8068
|
-
console.log(
|
|
8069
|
-
console.log(
|
|
8070
|
-
console.log(
|
|
8071
|
-
console.log(
|
|
8072
|
-
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"));
|
|
8073
8229
|
console.log("");
|
|
8074
8230
|
}
|
|
8075
8231
|
async function showProjectMenu(config) {
|
|
8076
|
-
console.log(
|
|
8232
|
+
console.log(chalk22.cyan("\n \u2139\uFE0F I found an existing project in this folder.\n"));
|
|
8077
8233
|
let keepRunning = true;
|
|
8078
8234
|
while (keepRunning) {
|
|
8079
|
-
console.log(
|
|
8080
|
-
console.log(
|
|
8081
|
-
console.log(
|
|
8082
|
-
console.log(
|
|
8083
|
-
console.log(
|
|
8084
|
-
console.log(
|
|
8085
|
-
console.log(
|
|
8086
|
-
console.log(
|
|
8087
|
-
console.log(
|
|
8088
|
-
console.log(
|
|
8089
|
-
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"));
|
|
8090
8246
|
console.log("");
|
|
8091
8247
|
const choice = await p21.text({
|
|
8092
8248
|
message: "Enter a number (0-9):",
|
|
@@ -8190,52 +8346,52 @@ async function handleAction(action, config) {
|
|
|
8190
8346
|
showHelp2();
|
|
8191
8347
|
break;
|
|
8192
8348
|
default:
|
|
8193
|
-
console.log(
|
|
8349
|
+
console.log(chalk22.yellow("Coming soon!"));
|
|
8194
8350
|
}
|
|
8195
8351
|
}
|
|
8196
8352
|
function showPostSetupInstructions() {
|
|
8197
8353
|
console.log(boxen2(
|
|
8198
|
-
|
|
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"),
|
|
8199
8355
|
{ padding: 1, borderColor: "green", borderStyle: "round" }
|
|
8200
8356
|
));
|
|
8201
8357
|
}
|
|
8202
8358
|
function showPostBuildInstructions(projectName, projectPath) {
|
|
8203
8359
|
const displayPath = projectPath || projectName;
|
|
8204
8360
|
console.log(boxen2(
|
|
8205
|
-
|
|
8361
|
+
chalk22.green.bold(`\u2713 ${projectName} created!
|
|
8206
8362
|
|
|
8207
|
-
`) +
|
|
8363
|
+
`) + chalk22.white("Next steps:\n\n") + chalk22.cyan("1. ") + "Go to your project:\n" + chalk22.dim(` cd ${displayPath}
|
|
8208
8364
|
|
|
8209
|
-
`) +
|
|
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"),
|
|
8210
8366
|
{ padding: 1, borderColor: "green", borderStyle: "round" }
|
|
8211
8367
|
));
|
|
8212
8368
|
}
|
|
8213
8369
|
function showHelp2() {
|
|
8214
8370
|
console.log(boxen2(`
|
|
8215
|
-
${
|
|
8216
|
-
|
|
8217
|
-
${
|
|
8218
|
-
${
|
|
8219
|
-
${
|
|
8220
|
-
${
|
|
8221
|
-
${
|
|
8222
|
-
|
|
8223
|
-
${
|
|
8224
|
-
${
|
|
8225
|
-
${
|
|
8226
|
-
${
|
|
8227
|
-
${
|
|
8228
|
-
|
|
8229
|
-
${
|
|
8230
|
-
${
|
|
8231
|
-
${
|
|
8232
|
-
${
|
|
8233
|
-
|
|
8234
|
-
${
|
|
8235
|
-
${
|
|
8236
|
-
${
|
|
8237
|
-
|
|
8238
|
-
${
|
|
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")}
|
|
8239
8395
|
`, { padding: 1, borderColor: "cyan", borderStyle: "round" }));
|
|
8240
8396
|
}
|
|
8241
8397
|
var program = new Command();
|
|
@@ -8263,7 +8419,7 @@ program.command("website").alias("site").description("Build website by describin
|
|
|
8263
8419
|
program.command("help").description("Show help").action(showHelp2);
|
|
8264
8420
|
async function handleNaturalLanguage(input) {
|
|
8265
8421
|
const config = new Config();
|
|
8266
|
-
console.log(
|
|
8422
|
+
console.log(chalk22.dim("\n Understanding your request...\n"));
|
|
8267
8423
|
const parsed = await parseNaturalLanguage(input, config);
|
|
8268
8424
|
if (!parsed) {
|
|
8269
8425
|
await codeCommand(input);
|