codebakers 2.3.0 → 2.3.5
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/index.js +331 -208
- package/installers/CodeBakers-Install.bat +207 -0
- package/installers/CodeBakers-Install.command +232 -0
- package/installers/README.md +157 -0
- package/installers/mac/assets/README.txt +31 -0
- package/installers/mac/build-mac-installer.sh +240 -0
- package/installers/windows/CodeBakers.iss +256 -0
- package/installers/windows/assets/README.txt +16 -0
- package/installers/windows/scripts/post-install.bat +15 -0
- package/package.json +1 -1
- package/src/commands/setup.ts +307 -169
- package/src/index.ts +92 -52
package/dist/index.js
CHANGED
|
@@ -13,7 +13,7 @@ import {
|
|
|
13
13
|
import { Command } from "commander";
|
|
14
14
|
import * as p21 from "@clack/prompts";
|
|
15
15
|
import chalk21 from "chalk";
|
|
16
|
-
import
|
|
16
|
+
import boxen2 from "boxen";
|
|
17
17
|
import gradient from "gradient-string";
|
|
18
18
|
import * as path16 from "path";
|
|
19
19
|
|
|
@@ -43,19 +43,26 @@ async function checkForUpdates() {
|
|
|
43
43
|
// src/commands/setup.ts
|
|
44
44
|
import * as p from "@clack/prompts";
|
|
45
45
|
import chalk2 from "chalk";
|
|
46
|
+
import boxen from "boxen";
|
|
46
47
|
import open from "open";
|
|
47
48
|
var SERVICES = {
|
|
48
49
|
anthropic: {
|
|
49
50
|
key: "anthropic",
|
|
50
51
|
name: "Anthropic (Claude)",
|
|
51
52
|
description: "Powers the AI coding agent",
|
|
52
|
-
whyNeeded: "Without
|
|
53
|
+
whyNeeded: "This is REQUIRED. Without it, CodeBakers cannot generate any code.",
|
|
53
54
|
url: "https://console.anthropic.com/settings/keys",
|
|
54
|
-
|
|
55
|
+
steps: [
|
|
56
|
+
"Sign up or log in to Anthropic Console",
|
|
57
|
+
'Click "Create Key"',
|
|
58
|
+
'Give it a name like "CodeBakers"',
|
|
59
|
+
"Copy the key (starts with sk-ant-)"
|
|
60
|
+
],
|
|
55
61
|
fields: [{
|
|
56
62
|
key: "apiKey",
|
|
57
|
-
label: "Anthropic API Key",
|
|
63
|
+
label: "Paste your Anthropic API Key",
|
|
58
64
|
placeholder: "sk-ant-...",
|
|
65
|
+
hint: "Starts with sk-ant-",
|
|
59
66
|
validate: (v) => {
|
|
60
67
|
if (!v) return "API key is required";
|
|
61
68
|
if (!v.startsWith("sk-ant-")) return "Should start with sk-ant-";
|
|
@@ -67,13 +74,19 @@ var SERVICES = {
|
|
|
67
74
|
key: "github",
|
|
68
75
|
name: "GitHub",
|
|
69
76
|
description: "Create repos and push code",
|
|
70
|
-
whyNeeded: "
|
|
77
|
+
whyNeeded: "Needed to create repositories and save your code. Skip if you'll manage git manually.",
|
|
71
78
|
url: "https://github.com/settings/tokens/new?scopes=repo,user&description=CodeBakers",
|
|
72
|
-
|
|
79
|
+
steps: [
|
|
80
|
+
"Log in to GitHub",
|
|
81
|
+
'The "repo" and "user" boxes should already be checked',
|
|
82
|
+
'Scroll down and click "Generate token"',
|
|
83
|
+
"Copy the token (starts with ghp_)"
|
|
84
|
+
],
|
|
73
85
|
fields: [{
|
|
74
86
|
key: "token",
|
|
75
|
-
label: "GitHub Token",
|
|
76
|
-
placeholder: "ghp_...
|
|
87
|
+
label: "Paste your GitHub Token",
|
|
88
|
+
placeholder: "ghp_...",
|
|
89
|
+
hint: "Starts with ghp_ or github_pat_",
|
|
77
90
|
validate: (v) => {
|
|
78
91
|
if (!v) return "Token is required";
|
|
79
92
|
if (!v.startsWith("ghp_") && !v.startsWith("github_pat_")) {
|
|
@@ -87,38 +100,55 @@ var SERVICES = {
|
|
|
87
100
|
key: "vercel",
|
|
88
101
|
name: "Vercel",
|
|
89
102
|
description: "Deploy your apps to production",
|
|
90
|
-
whyNeeded: "
|
|
103
|
+
whyNeeded: "Needed to deploy apps automatically. Skip if you'll deploy manually.",
|
|
91
104
|
url: "https://vercel.com/account/tokens",
|
|
92
|
-
|
|
105
|
+
steps: [
|
|
106
|
+
"Log in to Vercel",
|
|
107
|
+
'Click "Create" button',
|
|
108
|
+
'Name it "CodeBakers"',
|
|
109
|
+
'Click "Create Token"',
|
|
110
|
+
"Copy the token"
|
|
111
|
+
],
|
|
93
112
|
fields: [{
|
|
94
113
|
key: "token",
|
|
95
|
-
label: "Vercel Token",
|
|
96
|
-
placeholder: "vercel_..."
|
|
114
|
+
label: "Paste your Vercel Token",
|
|
115
|
+
placeholder: "vercel_...",
|
|
116
|
+
hint: "The token you just created"
|
|
97
117
|
}]
|
|
98
118
|
},
|
|
99
119
|
supabase: {
|
|
100
120
|
key: "supabase",
|
|
101
121
|
name: "Supabase",
|
|
102
122
|
description: "Database and authentication",
|
|
103
|
-
whyNeeded: "
|
|
123
|
+
whyNeeded: "Needed for database features. Skip if you'll set up databases manually.",
|
|
104
124
|
url: "https://supabase.com/dashboard/account/tokens",
|
|
105
|
-
|
|
125
|
+
steps: [
|
|
126
|
+
"Log in to Supabase",
|
|
127
|
+
'Click "Generate new token"',
|
|
128
|
+
'Name it "CodeBakers"',
|
|
129
|
+
"Copy the token"
|
|
130
|
+
],
|
|
106
131
|
fields: [{
|
|
107
132
|
key: "accessToken",
|
|
108
|
-
label: "Supabase
|
|
109
|
-
placeholder: "sbp_..."
|
|
133
|
+
label: "Paste your Supabase Token",
|
|
134
|
+
placeholder: "sbp_...",
|
|
135
|
+
hint: "Starts with sbp_"
|
|
110
136
|
}]
|
|
111
137
|
},
|
|
112
138
|
openai: {
|
|
113
139
|
key: "openai",
|
|
114
140
|
name: "OpenAI",
|
|
115
141
|
description: "GPT models, embeddings, DALL-E",
|
|
116
|
-
whyNeeded: "Optional. Only
|
|
142
|
+
whyNeeded: "Optional. Only if you want to use OpenAI alongside Claude.",
|
|
117
143
|
url: "https://platform.openai.com/api-keys",
|
|
118
|
-
|
|
144
|
+
steps: [
|
|
145
|
+
"Log in to OpenAI",
|
|
146
|
+
'Click "Create new secret key"',
|
|
147
|
+
"Copy the key"
|
|
148
|
+
],
|
|
119
149
|
fields: [{
|
|
120
150
|
key: "apiKey",
|
|
121
|
-
label: "OpenAI API Key",
|
|
151
|
+
label: "Paste your OpenAI API Key",
|
|
122
152
|
placeholder: "sk-..."
|
|
123
153
|
}]
|
|
124
154
|
},
|
|
@@ -126,12 +156,15 @@ var SERVICES = {
|
|
|
126
156
|
key: "stripe",
|
|
127
157
|
name: "Stripe",
|
|
128
158
|
description: "Payment processing",
|
|
129
|
-
whyNeeded: "Optional. Only
|
|
159
|
+
whyNeeded: "Optional. Only if your app accepts payments.",
|
|
130
160
|
url: "https://dashboard.stripe.com/apikeys",
|
|
131
|
-
|
|
161
|
+
steps: [
|
|
162
|
+
"Log in to Stripe",
|
|
163
|
+
"Copy your Secret key (starts with sk_)"
|
|
164
|
+
],
|
|
132
165
|
fields: [{
|
|
133
166
|
key: "secretKey",
|
|
134
|
-
label: "Stripe Secret Key",
|
|
167
|
+
label: "Paste your Stripe Secret Key",
|
|
135
168
|
placeholder: "sk_live_... or sk_test_..."
|
|
136
169
|
}]
|
|
137
170
|
},
|
|
@@ -139,9 +172,13 @@ var SERVICES = {
|
|
|
139
172
|
key: "twilio",
|
|
140
173
|
name: "Twilio",
|
|
141
174
|
description: "SMS, voice calls, WhatsApp",
|
|
142
|
-
whyNeeded: "Optional. Only
|
|
175
|
+
whyNeeded: "Optional. Only if your app sends SMS or makes calls.",
|
|
143
176
|
url: "https://console.twilio.com/",
|
|
144
|
-
|
|
177
|
+
steps: [
|
|
178
|
+
"Log in to Twilio",
|
|
179
|
+
"Find Account SID on the dashboard",
|
|
180
|
+
"Find Auth Token on the dashboard"
|
|
181
|
+
],
|
|
145
182
|
fields: [
|
|
146
183
|
{
|
|
147
184
|
key: "accountSid",
|
|
@@ -159,12 +196,16 @@ var SERVICES = {
|
|
|
159
196
|
key: "resend",
|
|
160
197
|
name: "Resend",
|
|
161
198
|
description: "Email sending",
|
|
162
|
-
whyNeeded: "Optional. Only
|
|
199
|
+
whyNeeded: "Optional. Only if your app sends emails.",
|
|
163
200
|
url: "https://resend.com/api-keys",
|
|
164
|
-
|
|
201
|
+
steps: [
|
|
202
|
+
"Log in to Resend",
|
|
203
|
+
'Click "Create API Key"',
|
|
204
|
+
"Copy the key"
|
|
205
|
+
],
|
|
165
206
|
fields: [{
|
|
166
207
|
key: "apiKey",
|
|
167
|
-
label: "Resend API Key",
|
|
208
|
+
label: "Paste your Resend API Key",
|
|
168
209
|
placeholder: "re_..."
|
|
169
210
|
}]
|
|
170
211
|
},
|
|
@@ -172,12 +213,16 @@ var SERVICES = {
|
|
|
172
213
|
key: "vapi",
|
|
173
214
|
name: "VAPI",
|
|
174
215
|
description: "Voice AI agents",
|
|
175
|
-
whyNeeded: "Optional. Only
|
|
216
|
+
whyNeeded: "Optional. Only if you're building voice agents.",
|
|
176
217
|
url: "https://dashboard.vapi.ai/",
|
|
177
|
-
|
|
218
|
+
steps: [
|
|
219
|
+
"Log in to VAPI",
|
|
220
|
+
"Go to Settings > API Keys",
|
|
221
|
+
"Copy your API key"
|
|
222
|
+
],
|
|
178
223
|
fields: [{
|
|
179
224
|
key: "apiKey",
|
|
180
|
-
label: "VAPI API Key",
|
|
225
|
+
label: "Paste your VAPI API Key",
|
|
181
226
|
placeholder: "..."
|
|
182
227
|
}]
|
|
183
228
|
},
|
|
@@ -185,12 +230,16 @@ var SERVICES = {
|
|
|
185
230
|
key: "elevenlabs",
|
|
186
231
|
name: "ElevenLabs",
|
|
187
232
|
description: "AI voice generation",
|
|
188
|
-
whyNeeded: "Optional. Only
|
|
233
|
+
whyNeeded: "Optional. Only if you want AI-generated voices.",
|
|
189
234
|
url: "https://elevenlabs.io/app/settings/api-keys",
|
|
190
|
-
|
|
235
|
+
steps: [
|
|
236
|
+
"Log in to ElevenLabs",
|
|
237
|
+
'Click "Create API Key"',
|
|
238
|
+
"Copy the key"
|
|
239
|
+
],
|
|
191
240
|
fields: [{
|
|
192
241
|
key: "apiKey",
|
|
193
|
-
label: "ElevenLabs API Key",
|
|
242
|
+
label: "Paste your ElevenLabs API Key",
|
|
194
243
|
placeholder: "..."
|
|
195
244
|
}]
|
|
196
245
|
}
|
|
@@ -199,171 +248,210 @@ var CORE_SERVICES = ["anthropic", "github", "vercel", "supabase"];
|
|
|
199
248
|
var OPTIONAL_SERVICES = ["openai", "stripe", "twilio", "resend", "vapi", "elevenlabs"];
|
|
200
249
|
async function setupCommand() {
|
|
201
250
|
const config = new Config();
|
|
202
|
-
|
|
203
|
-
if (
|
|
204
|
-
|
|
205
|
-
|
|
206
|
-
|
|
207
|
-
|
|
208
|
-
|
|
209
|
-
|
|
210
|
-
|
|
211
|
-
|
|
212
|
-
|
|
251
|
+
const hasAnthropic = !!config.getCredentials("anthropic")?.apiKey;
|
|
252
|
+
if (hasAnthropic) {
|
|
253
|
+
await showManagementMenu(config);
|
|
254
|
+
return;
|
|
255
|
+
}
|
|
256
|
+
console.log(boxen(
|
|
257
|
+
chalk2.bold.cyan("Welcome to CodeBakers Setup!\n\n") + chalk2.white("We need to connect a few services to get started.\n\n") + chalk2.dim("Your credentials are stored locally on your computer\n") + chalk2.dim("in ~/.codebakers/ and never sent to our servers.\n\n") + chalk2.yellow("Required: ") + chalk2.white("Anthropic API key (for AI)\n") + chalk2.dim("Optional: GitHub, Vercel, Supabase (for full features)"),
|
|
258
|
+
{ padding: 1, borderColor: "cyan", borderStyle: "round" }
|
|
259
|
+
));
|
|
260
|
+
console.log(chalk2.bold.cyan("\n\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501"));
|
|
261
|
+
console.log(chalk2.bold.cyan(" STEP 1 of 4: Anthropic API Key (Required)"));
|
|
262
|
+
console.log(chalk2.bold.cyan("\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\n"));
|
|
263
|
+
console.log(chalk2.white(" Anthropic (Claude)"));
|
|
264
|
+
console.log(chalk2.dim(" Powers the AI coding agent\n"));
|
|
265
|
+
const hasAccount = await p.select({
|
|
266
|
+
message: "Do you have an Anthropic account?",
|
|
267
|
+
options: [
|
|
268
|
+
{ value: "yes", label: "\u2713 Yes, I have an API key ready" },
|
|
269
|
+
{ value: "no", label: "\u2717 No, I need to sign up (free)" }
|
|
270
|
+
]
|
|
271
|
+
});
|
|
272
|
+
if (p.isCancel(hasAccount)) {
|
|
273
|
+
return;
|
|
274
|
+
}
|
|
275
|
+
if (hasAccount === "no") {
|
|
276
|
+
console.log(chalk2.yellow("\n No problem! Let's get you signed up.\n"));
|
|
277
|
+
console.log(chalk2.white(" Steps:"));
|
|
278
|
+
console.log(chalk2.cyan(" 1. ") + 'Click "Sign Up" on the page that opens');
|
|
279
|
+
console.log(chalk2.cyan(" 2. ") + "Create your account (email + password)");
|
|
280
|
+
console.log(chalk2.cyan(" 3. ") + "Once logged in, go to Settings \u2192 API Keys");
|
|
281
|
+
console.log(chalk2.cyan(" 4. ") + 'Click "Create Key"');
|
|
282
|
+
console.log(chalk2.cyan(" 5. ") + "Copy the key and paste it here\n");
|
|
283
|
+
const openSignup = await p.confirm({
|
|
284
|
+
message: "Open Anthropic signup page?",
|
|
285
|
+
initialValue: true
|
|
213
286
|
});
|
|
214
|
-
if (p.isCancel(
|
|
215
|
-
|
|
287
|
+
if (openSignup && !p.isCancel(openSignup)) {
|
|
288
|
+
await open("https://console.anthropic.com/");
|
|
289
|
+
console.log(chalk2.dim("\n Take your time - come back when you have your API key.\n"));
|
|
216
290
|
}
|
|
217
|
-
|
|
218
|
-
|
|
219
|
-
|
|
220
|
-
|
|
221
|
-
|
|
222
|
-
|
|
223
|
-
|
|
224
|
-
|
|
225
|
-
|
|
226
|
-
|
|
227
|
-
|
|
228
|
-
|
|
229
|
-
|
|
291
|
+
} else {
|
|
292
|
+
console.log(chalk2.bold.white("\n Here's what to do:\n"));
|
|
293
|
+
console.log(chalk2.cyan(" 1. ") + "Log in to Anthropic Console");
|
|
294
|
+
console.log(chalk2.cyan(" 2. ") + "Go to Settings \u2192 API Keys");
|
|
295
|
+
console.log(chalk2.cyan(" 3. ") + 'Click "Create Key"');
|
|
296
|
+
console.log(chalk2.cyan(" 4. ") + "Copy the key (starts with sk-ant-)");
|
|
297
|
+
console.log("");
|
|
298
|
+
const openBrowser = await p.confirm({
|
|
299
|
+
message: "Open Anthropic Console?",
|
|
300
|
+
initialValue: true
|
|
301
|
+
});
|
|
302
|
+
if (openBrowser && !p.isCancel(openBrowser)) {
|
|
303
|
+
await open("https://console.anthropic.com/settings/keys");
|
|
230
304
|
}
|
|
231
305
|
}
|
|
232
|
-
console.log(
|
|
233
|
-
|
|
234
|
-
|
|
235
|
-
|
|
236
|
-
|
|
237
|
-
|
|
238
|
-
|
|
239
|
-
|
|
240
|
-
|
|
241
|
-
`));
|
|
242
|
-
let skippedCore = [];
|
|
243
|
-
for (const serviceKey of CORE_SERVICES) {
|
|
244
|
-
const service = SERVICES[serviceKey];
|
|
245
|
-
const connected = await connectService(config, service);
|
|
246
|
-
if (!connected) {
|
|
247
|
-
skippedCore.push(service.name);
|
|
306
|
+
console.log("");
|
|
307
|
+
const apiKey = await p.text({
|
|
308
|
+
message: "Paste your Anthropic API Key:",
|
|
309
|
+
placeholder: "sk-ant-...",
|
|
310
|
+
validate: (v) => {
|
|
311
|
+
if (!v) return "API key is required";
|
|
312
|
+
if (!v.startsWith("sk-ant-")) return "Should start with sk-ant-";
|
|
313
|
+
return void 0;
|
|
248
314
|
}
|
|
249
|
-
}
|
|
250
|
-
if (skippedCore.length > 0) {
|
|
251
|
-
console.log(chalk2.yellow(`
|
|
252
|
-
\u26A0\uFE0F You skipped: ${skippedCore.join(", ")}
|
|
253
|
-
|
|
254
|
-
Some features won't work without these services.
|
|
255
|
-
Run ${chalk2.bold("codebakers setup")} anytime to add them.
|
|
256
|
-
`));
|
|
257
|
-
}
|
|
258
|
-
const addOptional = await p.confirm({
|
|
259
|
-
message: "Add optional services? (Stripe, Twilio, Resend, etc.)",
|
|
260
|
-
initialValue: false
|
|
261
315
|
});
|
|
262
|
-
if (
|
|
263
|
-
|
|
264
|
-
|
|
265
|
-
|
|
266
|
-
value: key,
|
|
267
|
-
label: `${SERVICES[key].name} - ${SERVICES[key].description}`
|
|
268
|
-
})),
|
|
269
|
-
required: false
|
|
270
|
-
});
|
|
271
|
-
if (!p.isCancel(selected) && Array.isArray(selected)) {
|
|
272
|
-
for (const serviceKey of selected) {
|
|
273
|
-
await connectService(config, SERVICES[serviceKey]);
|
|
274
|
-
}
|
|
275
|
-
}
|
|
316
|
+
if (p.isCancel(apiKey) || !apiKey) {
|
|
317
|
+
console.log(chalk2.red("\n \u274C Anthropic API key is required to use CodeBakers."));
|
|
318
|
+
console.log(chalk2.dim(" Run `codebakers setup` when you're ready to try again.\n"));
|
|
319
|
+
return;
|
|
276
320
|
}
|
|
277
|
-
|
|
278
|
-
|
|
279
|
-
)
|
|
280
|
-
console.log(chalk2.
|
|
281
|
-
\
|
|
282
|
-
|
|
321
|
+
config.setCredentials("anthropic", { apiKey });
|
|
322
|
+
console.log(chalk2.green("\n \u2713 Anthropic connected successfully!\n"));
|
|
323
|
+
console.log(chalk2.bold.cyan("\n\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501"));
|
|
324
|
+
console.log(chalk2.bold.cyan(" STEP 2 of 4: GitHub Token (Recommended)"));
|
|
325
|
+
console.log(chalk2.bold.cyan("\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\n"));
|
|
326
|
+
await connectServiceWithInstructions(config, SERVICES.github, false);
|
|
327
|
+
console.log(chalk2.bold.cyan("\n\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501"));
|
|
328
|
+
console.log(chalk2.bold.cyan(" STEP 3 of 4: Vercel Token (Recommended)"));
|
|
329
|
+
console.log(chalk2.bold.cyan("\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\n"));
|
|
330
|
+
await connectServiceWithInstructions(config, SERVICES.vercel, false);
|
|
331
|
+
console.log(chalk2.bold.cyan("\n\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501"));
|
|
332
|
+
console.log(chalk2.bold.cyan(" STEP 4 of 4: Supabase Token (Optional)"));
|
|
333
|
+
console.log(chalk2.bold.cyan("\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\n"));
|
|
334
|
+
await connectServiceWithInstructions(config, SERVICES.supabase, false);
|
|
335
|
+
const connectedServices = CORE_SERVICES.filter((key) => config.getCredentials(key)).map((key) => SERVICES[key].name);
|
|
336
|
+
console.log(boxen(
|
|
337
|
+
chalk2.bold.green("\u2713 Setup Complete!\n\n") + chalk2.white("Connected: ") + chalk2.cyan(connectedServices.join(", ")) + "\n\n" + chalk2.bold.white("What to do next:\n\n") + chalk2.cyan("1. ") + chalk2.white("Open a terminal and navigate to where you want to build:\n") + chalk2.dim(" cd C:\\dev\\my-project\n") + chalk2.dim(" (or any folder where you want to create your project)\n\n") + chalk2.cyan("2. ") + chalk2.white("Run CodeBakers:\n") + chalk2.dim(" codebakers\n\n") + chalk2.bold.white("Or try these commands directly:\n\n") + chalk2.dim(" codebakers website ") + chalk2.white("Build a website by describing it\n") + chalk2.dim(" codebakers init ") + chalk2.white("Create a new project from scratch\n") + chalk2.dim(" codebakers help ") + chalk2.white("See all available commands"),
|
|
338
|
+
{ padding: 1, borderColor: "green", borderStyle: "round" }
|
|
339
|
+
));
|
|
283
340
|
}
|
|
284
|
-
async function
|
|
285
|
-
console.log(
|
|
286
|
-
console.log(chalk2.
|
|
287
|
-
|
|
288
|
-
|
|
341
|
+
async function connectServiceWithInstructions(config, service, required) {
|
|
342
|
+
console.log(chalk2.white(` ${service.name}`));
|
|
343
|
+
console.log(chalk2.dim(` ${service.description}
|
|
344
|
+
`));
|
|
345
|
+
if (!required) {
|
|
346
|
+
console.log(chalk2.yellow(` ${service.whyNeeded}
|
|
347
|
+
`));
|
|
348
|
+
}
|
|
289
349
|
const action = await p.select({
|
|
290
350
|
message: `Connect ${service.name}?`,
|
|
291
|
-
options: [
|
|
292
|
-
{ value: "connect", label: "\u2713 Yes, connect
|
|
293
|
-
|
|
294
|
-
{ value: "
|
|
351
|
+
options: required ? [
|
|
352
|
+
{ value: "connect", label: "\u2713 Yes, let's connect it" }
|
|
353
|
+
] : [
|
|
354
|
+
{ value: "connect", label: "\u2713 Yes, connect it" },
|
|
355
|
+
{ value: "skip", label: "\u2192 Skip for now" }
|
|
295
356
|
]
|
|
296
357
|
});
|
|
297
|
-
if (p.isCancel(action))
|
|
298
|
-
|
|
299
|
-
|
|
300
|
-
${service.
|
|
358
|
+
if (p.isCancel(action) || action === "skip") {
|
|
359
|
+
if (!required) {
|
|
360
|
+
console.log(chalk2.dim(`
|
|
361
|
+
Skipped ${service.name}. You can add it later with: codebakers setup
|
|
301
362
|
`));
|
|
302
|
-
const proceed = await p.confirm({
|
|
303
|
-
message: `Connect ${service.name}?`,
|
|
304
|
-
initialValue: true
|
|
305
|
-
});
|
|
306
|
-
if (!proceed || p.isCancel(proceed)) {
|
|
307
|
-
console.log(chalk2.dim(` Skipped ${service.name}`));
|
|
308
|
-
return false;
|
|
309
363
|
}
|
|
310
|
-
} else if (action === "skip") {
|
|
311
|
-
console.log(chalk2.dim(` Skipped ${service.name}`));
|
|
312
|
-
console.log(chalk2.dim(` ${service.whyNeeded}`));
|
|
313
364
|
return false;
|
|
314
365
|
}
|
|
366
|
+
console.log(chalk2.bold.white("\n Here's what to do:\n"));
|
|
367
|
+
service.steps.forEach((step, i) => {
|
|
368
|
+
console.log(chalk2.cyan(` ${i + 1}. `) + chalk2.white(step));
|
|
369
|
+
});
|
|
370
|
+
console.log("");
|
|
315
371
|
const openBrowser = await p.confirm({
|
|
316
|
-
message: "Open
|
|
372
|
+
message: "Open the website in your browser?",
|
|
317
373
|
initialValue: true
|
|
318
374
|
});
|
|
319
375
|
if (openBrowser && !p.isCancel(openBrowser)) {
|
|
320
376
|
console.log(chalk2.dim(`
|
|
321
|
-
Opening: ${service.url}
|
|
322
|
-
console.log(chalk2.dim(` ${service.urlDescription}
|
|
377
|
+
Opening: ${service.url}
|
|
323
378
|
`));
|
|
324
379
|
await open(service.url);
|
|
380
|
+
console.log(chalk2.dim(" Complete the steps above, then paste your key below.\n"));
|
|
325
381
|
}
|
|
326
382
|
const credentials = {};
|
|
327
383
|
for (const field of service.fields) {
|
|
328
384
|
const value = await p.text({
|
|
329
|
-
message:
|
|
385
|
+
message: field.label + (field.hint ? chalk2.dim(` (${field.hint})`) : "") + ":",
|
|
330
386
|
placeholder: field.placeholder,
|
|
331
387
|
validate: field.validate
|
|
332
388
|
});
|
|
333
389
|
if (p.isCancel(value)) return false;
|
|
334
390
|
if (!value) {
|
|
335
|
-
|
|
391
|
+
if (required) {
|
|
392
|
+
console.log(chalk2.red(`
|
|
393
|
+
${field.label} is required.
|
|
394
|
+
`));
|
|
395
|
+
return false;
|
|
396
|
+
}
|
|
397
|
+
console.log(chalk2.dim(`
|
|
398
|
+
Skipped ${service.name}.
|
|
399
|
+
`));
|
|
336
400
|
return false;
|
|
337
401
|
}
|
|
338
402
|
credentials[field.key] = value;
|
|
339
403
|
}
|
|
340
404
|
config.setCredentials(service.key, credentials);
|
|
341
|
-
console.log(chalk2.green(`
|
|
405
|
+
console.log(chalk2.green(`
|
|
406
|
+
\u2713 ${service.name} connected successfully!
|
|
407
|
+
`));
|
|
342
408
|
return true;
|
|
343
409
|
}
|
|
344
|
-
function
|
|
345
|
-
console.log(chalk2.bold("\n
|
|
410
|
+
async function showManagementMenu(config) {
|
|
411
|
+
console.log(chalk2.bold.cyan("\n CodeBakers Settings\n"));
|
|
346
412
|
const allServices = [...CORE_SERVICES, ...OPTIONAL_SERVICES];
|
|
347
|
-
|
|
348
|
-
|
|
349
|
-
|
|
350
|
-
|
|
351
|
-
|
|
352
|
-
|
|
353
|
-
|
|
354
|
-
|
|
355
|
-
|
|
356
|
-
}
|
|
413
|
+
const connected = allServices.filter((key) => config.getCredentials(key));
|
|
414
|
+
const notConnected = allServices.filter((key) => !config.getCredentials(key));
|
|
415
|
+
console.log(chalk2.green(" Connected:"));
|
|
416
|
+
connected.forEach((key) => {
|
|
417
|
+
console.log(chalk2.green(` \u2713 ${SERVICES[key].name}`));
|
|
418
|
+
});
|
|
419
|
+
if (notConnected.length > 0) {
|
|
420
|
+
console.log(chalk2.dim("\n Not connected:"));
|
|
421
|
+
notConnected.forEach((key) => {
|
|
422
|
+
console.log(chalk2.dim(` \u25CB ${SERVICES[key].name}`));
|
|
423
|
+
});
|
|
424
|
+
}
|
|
425
|
+
console.log("");
|
|
426
|
+
const action = await p.select({
|
|
427
|
+
message: "What would you like to do?",
|
|
428
|
+
options: [
|
|
429
|
+
{ value: "add", label: "\u2795 Add a service" },
|
|
430
|
+
{ value: "update", label: "\u{1F504} Update a service" },
|
|
431
|
+
{ value: "reset", label: "\u{1F5D1}\uFE0F Reset all settings" },
|
|
432
|
+
{ value: "back", label: "\u2190 Back" }
|
|
433
|
+
]
|
|
434
|
+
});
|
|
435
|
+
if (p.isCancel(action) || action === "back") {
|
|
436
|
+
return;
|
|
437
|
+
}
|
|
438
|
+
switch (action) {
|
|
439
|
+
case "add":
|
|
440
|
+
await addService(config);
|
|
441
|
+
break;
|
|
442
|
+
case "update":
|
|
443
|
+
await updateService(config);
|
|
444
|
+
break;
|
|
445
|
+
case "reset":
|
|
446
|
+
await resetConfig(config);
|
|
447
|
+
break;
|
|
357
448
|
}
|
|
358
|
-
console.log(chalk2.dim(`
|
|
359
|
-
${connectedCount}/${allServices.length} services connected
|
|
360
|
-
`));
|
|
361
449
|
}
|
|
362
450
|
async function addService(config) {
|
|
363
451
|
const allServices = [...CORE_SERVICES, ...OPTIONAL_SERVICES];
|
|
364
452
|
const unconnected = allServices.filter((key) => !config.getCredentials(key));
|
|
365
453
|
if (unconnected.length === 0) {
|
|
366
|
-
|
|
454
|
+
console.log(chalk2.green("\n All services are already connected!\n"));
|
|
367
455
|
return;
|
|
368
456
|
}
|
|
369
457
|
const selected = await p.select({
|
|
@@ -374,13 +462,13 @@ async function addService(config) {
|
|
|
374
462
|
}))
|
|
375
463
|
});
|
|
376
464
|
if (p.isCancel(selected)) return;
|
|
377
|
-
await
|
|
465
|
+
await connectServiceWithInstructions(config, SERVICES[selected], false);
|
|
378
466
|
}
|
|
379
467
|
async function updateService(config) {
|
|
380
468
|
const allServices = [...CORE_SERVICES, ...OPTIONAL_SERVICES];
|
|
381
469
|
const connected = allServices.filter((key) => config.getCredentials(key));
|
|
382
470
|
if (connected.length === 0) {
|
|
383
|
-
|
|
471
|
+
console.log(chalk2.yellow("\n No services connected yet.\n"));
|
|
384
472
|
return;
|
|
385
473
|
}
|
|
386
474
|
const selected = await p.select({
|
|
@@ -391,19 +479,24 @@ async function updateService(config) {
|
|
|
391
479
|
}))
|
|
392
480
|
});
|
|
393
481
|
if (p.isCancel(selected)) return;
|
|
394
|
-
await
|
|
482
|
+
await connectServiceWithInstructions(config, SERVICES[selected], false);
|
|
395
483
|
}
|
|
396
484
|
async function resetConfig(config) {
|
|
485
|
+
console.log(chalk2.yellow("\n \u26A0\uFE0F This will remove ALL your saved API keys.\n"));
|
|
397
486
|
const confirm13 = await p.confirm({
|
|
398
|
-
message: "Are you sure?
|
|
487
|
+
message: "Are you sure?",
|
|
399
488
|
initialValue: false
|
|
400
489
|
});
|
|
401
|
-
if (!confirm13 || p.isCancel(confirm13))
|
|
490
|
+
if (!confirm13 || p.isCancel(confirm13)) {
|
|
491
|
+
console.log(chalk2.dim("\n Cancelled.\n"));
|
|
492
|
+
return;
|
|
493
|
+
}
|
|
402
494
|
const allServices = [...CORE_SERVICES, ...OPTIONAL_SERVICES];
|
|
403
495
|
for (const key of allServices) {
|
|
404
496
|
config.setCredentials(key, null);
|
|
405
497
|
}
|
|
406
|
-
|
|
498
|
+
console.log(chalk2.green("\n \u2713 All settings reset.\n"));
|
|
499
|
+
console.log(chalk2.dim(" Run `codebakers setup` to configure again.\n"));
|
|
407
500
|
}
|
|
408
501
|
|
|
409
502
|
// src/commands/init.ts
|
|
@@ -7539,7 +7632,7 @@ If unclear between multiple commands, use the most likely one with lower confide
|
|
|
7539
7632
|
}
|
|
7540
7633
|
|
|
7541
7634
|
// src/index.ts
|
|
7542
|
-
var VERSION2 = "2.3.
|
|
7635
|
+
var VERSION2 = "2.3.5";
|
|
7543
7636
|
var logo = `
|
|
7544
7637
|
\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
|
|
7545
7638
|
\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
|
|
@@ -7555,7 +7648,7 @@ async function showMainMenu() {
|
|
|
7555
7648
|
`));
|
|
7556
7649
|
const hasAnthropic = !!config.getCredentials("anthropic")?.apiKey;
|
|
7557
7650
|
if (!hasAnthropic) {
|
|
7558
|
-
console.log(
|
|
7651
|
+
console.log(boxen2(
|
|
7559
7652
|
chalk21.yellow("Welcome to CodeBakers!\n\n") + chalk21.white("Let's connect your Anthropic API key so the AI can work.\n") + chalk21.dim("(Takes about 1 minute)"),
|
|
7560
7653
|
{ padding: 1, borderColor: "yellow", borderStyle: "round" }
|
|
7561
7654
|
));
|
|
@@ -7581,55 +7674,85 @@ async function showMainMenu() {
|
|
|
7581
7674
|
}
|
|
7582
7675
|
}
|
|
7583
7676
|
async function showStartMenu(config) {
|
|
7584
|
-
|
|
7585
|
-
|
|
7586
|
-
|
|
7587
|
-
|
|
7588
|
-
|
|
7589
|
-
|
|
7590
|
-
|
|
7591
|
-
|
|
7592
|
-
|
|
7593
|
-
|
|
7594
|
-
|
|
7595
|
-
|
|
7596
|
-
|
|
7597
|
-
}
|
|
7598
|
-
|
|
7599
|
-
|
|
7600
|
-
|
|
7601
|
-
|
|
7602
|
-
|
|
7603
|
-
|
|
7604
|
-
|
|
7677
|
+
console.log(chalk21.cyan("\n \u2139\uFE0F This folder doesn't have a project yet."));
|
|
7678
|
+
console.log(chalk21.dim(" Use the arrow keys to select an option, then press Enter.\n"));
|
|
7679
|
+
let keepRunning = true;
|
|
7680
|
+
while (keepRunning) {
|
|
7681
|
+
const action = await p21.select({
|
|
7682
|
+
message: "What would you like to do?",
|
|
7683
|
+
options: [
|
|
7684
|
+
{ value: "website", label: "\u{1F310} Build a website", hint: "Describe it, AI builds it" },
|
|
7685
|
+
{ value: "new", label: "\u{1F195} Create new project", hint: "Start with Next.js, React, etc." },
|
|
7686
|
+
{ value: "prd-maker", label: "\u270F\uFE0F Plan my project", hint: "Create a detailed plan first" },
|
|
7687
|
+
{ value: "build", label: "\u{1F3D7}\uFE0F Build from plan", hint: "I already have a PRD file" },
|
|
7688
|
+
{ value: "advisors", label: "\u{1F31F} Get expert advice", hint: "AI consultants help you decide" },
|
|
7689
|
+
{ value: "integrate", label: "\u{1F50C} Add a service", hint: "Stripe, Supabase, Auth, etc." },
|
|
7690
|
+
{ value: "settings", label: "\u2699\uFE0F Settings", hint: "API keys & preferences" },
|
|
7691
|
+
{ value: "help", label: "\u2753 Help", hint: "Learn how CodeBakers works" },
|
|
7692
|
+
{ value: "exit", label: "\u{1F6AA} Return to terminal", hint: "Go back to command line" }
|
|
7693
|
+
]
|
|
7694
|
+
});
|
|
7695
|
+
if (p21.isCancel(action) || action === "exit") {
|
|
7696
|
+
console.log("");
|
|
7697
|
+
console.log(chalk21.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"));
|
|
7698
|
+
console.log(chalk21.white(" You're back in the terminal."));
|
|
7699
|
+
console.log("");
|
|
7700
|
+
console.log(chalk21.dim(" To start CodeBakers again, type:"));
|
|
7701
|
+
console.log(chalk21.green(" codebakers"));
|
|
7702
|
+
console.log("");
|
|
7703
|
+
console.log(chalk21.dim(" Quick commands you can run directly:"));
|
|
7704
|
+
console.log(chalk21.dim(" codebakers website") + chalk21.gray(" - Build a website"));
|
|
7705
|
+
console.log(chalk21.dim(" codebakers code") + chalk21.gray(" - Code with AI"));
|
|
7706
|
+
console.log(chalk21.dim(" codebakers help") + chalk21.gray(" - See all commands"));
|
|
7707
|
+
console.log(chalk21.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"));
|
|
7708
|
+
console.log("");
|
|
7709
|
+
keepRunning = false;
|
|
7710
|
+
break;
|
|
7711
|
+
}
|
|
7712
|
+
await handleAction(action, config);
|
|
7713
|
+
console.log("");
|
|
7605
7714
|
}
|
|
7606
|
-
await handleAction(action, config);
|
|
7607
7715
|
}
|
|
7608
7716
|
async function showProjectMenu(config) {
|
|
7609
|
-
|
|
7610
|
-
|
|
7611
|
-
|
|
7612
|
-
|
|
7613
|
-
|
|
7614
|
-
|
|
7615
|
-
|
|
7616
|
-
|
|
7617
|
-
|
|
7618
|
-
|
|
7619
|
-
|
|
7620
|
-
|
|
7621
|
-
|
|
7622
|
-
|
|
7623
|
-
}
|
|
7624
|
-
|
|
7625
|
-
|
|
7626
|
-
|
|
7627
|
-
|
|
7628
|
-
|
|
7629
|
-
|
|
7630
|
-
|
|
7717
|
+
console.log(chalk21.cyan("\n \u2139\uFE0F I found an existing project in this folder."));
|
|
7718
|
+
console.log(chalk21.dim(" Use the arrow keys to select an option, then press Enter.\n"));
|
|
7719
|
+
let keepRunning = true;
|
|
7720
|
+
while (keepRunning) {
|
|
7721
|
+
const action = await p21.select({
|
|
7722
|
+
message: "What would you like to do with this project?",
|
|
7723
|
+
options: [
|
|
7724
|
+
{ value: "code", label: "\u{1F4AC} Code with AI", hint: "Tell AI what to build or fix" },
|
|
7725
|
+
{ value: "deploy", label: "\u{1F680} Deploy to production", hint: "Make your site live" },
|
|
7726
|
+
{ value: "check", label: "\u{1F50D} Check my code", hint: "Find issues & improvements" },
|
|
7727
|
+
{ value: "fix", label: "\u{1F527} Fix errors for me", hint: "AI repairs broken code" },
|
|
7728
|
+
{ value: "integrate", label: "\u{1F50C} Add a service", hint: "Stripe, Supabase, Auth, etc." },
|
|
7729
|
+
{ value: "generate", label: "\u26A1 Create new files", hint: "Components, pages, APIs" },
|
|
7730
|
+
{ value: "new", label: "\u{1F195} Start fresh project", hint: "Begin something new" },
|
|
7731
|
+
{ value: "settings", label: "\u2699\uFE0F Settings", hint: "API keys & preferences" },
|
|
7732
|
+
{ value: "help", label: "\u2753 Help", hint: "Learn how CodeBakers works" },
|
|
7733
|
+
{ value: "exit", label: "\u{1F6AA} Return to terminal", hint: "Go back to command line" }
|
|
7734
|
+
]
|
|
7735
|
+
});
|
|
7736
|
+
if (p21.isCancel(action) || action === "exit") {
|
|
7737
|
+
console.log("");
|
|
7738
|
+
console.log(chalk21.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"));
|
|
7739
|
+
console.log(chalk21.white(" You're back in the terminal."));
|
|
7740
|
+
console.log("");
|
|
7741
|
+
console.log(chalk21.dim(" To start CodeBakers again, type:"));
|
|
7742
|
+
console.log(chalk21.green(" codebakers"));
|
|
7743
|
+
console.log("");
|
|
7744
|
+
console.log(chalk21.dim(" Quick commands you can run directly:"));
|
|
7745
|
+
console.log(chalk21.dim(" codebakers code") + chalk21.gray(" - Code with AI"));
|
|
7746
|
+
console.log(chalk21.dim(" codebakers deploy") + chalk21.gray(" - Deploy your project"));
|
|
7747
|
+
console.log(chalk21.dim(" codebakers help") + chalk21.gray(" - See all commands"));
|
|
7748
|
+
console.log(chalk21.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"));
|
|
7749
|
+
console.log("");
|
|
7750
|
+
keepRunning = false;
|
|
7751
|
+
break;
|
|
7752
|
+
}
|
|
7753
|
+
await handleAction(action, config);
|
|
7754
|
+
console.log("");
|
|
7631
7755
|
}
|
|
7632
|
-
await handleAction(action, config);
|
|
7633
7756
|
}
|
|
7634
7757
|
async function handleAction(action, config) {
|
|
7635
7758
|
switch (action) {
|
|
@@ -7686,14 +7809,14 @@ async function handleAction(action, config) {
|
|
|
7686
7809
|
}
|
|
7687
7810
|
}
|
|
7688
7811
|
function showPostSetupInstructions() {
|
|
7689
|
-
console.log(
|
|
7812
|
+
console.log(boxen2(
|
|
7690
7813
|
chalk21.green.bold("\u2713 Setup complete!\n\n") + chalk21.white("What's next?\n\n") + chalk21.cyan("1. ") + "Navigate to where you want to build:\n" + chalk21.dim(" cd C:\\dev\\my-project\n\n") + chalk21.cyan("2. ") + "Run CodeBakers:\n" + chalk21.dim(" codebakers\n\n") + chalk21.white("Or build a website right now:\n") + chalk21.dim(" codebakers website"),
|
|
7691
7814
|
{ padding: 1, borderColor: "green", borderStyle: "round" }
|
|
7692
7815
|
));
|
|
7693
7816
|
}
|
|
7694
7817
|
function showPostBuildInstructions(projectName, projectPath) {
|
|
7695
7818
|
const displayPath = projectPath || projectName;
|
|
7696
|
-
console.log(
|
|
7819
|
+
console.log(boxen2(
|
|
7697
7820
|
chalk21.green.bold(`\u2713 ${projectName} created!
|
|
7698
7821
|
|
|
7699
7822
|
`) + chalk21.white("Next steps:\n\n") + chalk21.cyan("1. ") + "Go to your project:\n" + chalk21.dim(` cd ${displayPath}
|
|
@@ -7703,7 +7826,7 @@ function showPostBuildInstructions(projectName, projectPath) {
|
|
|
7703
7826
|
));
|
|
7704
7827
|
}
|
|
7705
7828
|
function showHelp2() {
|
|
7706
|
-
console.log(
|
|
7829
|
+
console.log(boxen2(`
|
|
7707
7830
|
${chalk21.bold("CodeBakers CLI v" + VERSION2)} \u2014 AI dev team that follows the rules
|
|
7708
7831
|
|
|
7709
7832
|
${chalk21.bold.cyan("Getting Started:")}
|