codebakers 2.5.3 → 3.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (60) hide show
  1. package/README.md +54 -255
  2. package/dist/chunk-HOWR3YTF.js +146 -0
  3. package/dist/index.d.ts +0 -3
  4. package/dist/index.js +10489 -7994
  5. package/dist/terminal-6ZQVP6R7.js +10 -0
  6. package/package.json +26 -41
  7. package/AUDIT_REPORT.md +0 -138
  8. package/dist/advisors-RWRTSJRR.js +0 -7
  9. package/dist/chunk-ASIJIQYC.js +0 -320
  10. package/dist/chunk-D44U3IEA.js +0 -565
  11. package/dist/chunk-LANM5XQW.js +0 -326
  12. package/dist/prd-RYITSL6Q.js +0 -7
  13. package/install.bat +0 -9
  14. package/installers/CodeBakers-Install.bat +0 -207
  15. package/installers/CodeBakers-Install.command +0 -232
  16. package/installers/README.md +0 -157
  17. package/installers/mac/assets/README.txt +0 -31
  18. package/installers/mac/build-mac-installer.sh +0 -240
  19. package/installers/windows/CodeBakers.iss +0 -256
  20. package/installers/windows/assets/README.txt +0 -16
  21. package/installers/windows/scripts/post-install.bat +0 -15
  22. package/src/channels/discord.ts +0 -5
  23. package/src/channels/slack.ts +0 -5
  24. package/src/channels/sms.ts +0 -4
  25. package/src/channels/telegram.ts +0 -5
  26. package/src/channels/whatsapp.ts +0 -7
  27. package/src/commands/advisors.ts +0 -699
  28. package/src/commands/build.ts +0 -1025
  29. package/src/commands/check.ts +0 -365
  30. package/src/commands/code.ts +0 -806
  31. package/src/commands/connect.ts +0 -12
  32. package/src/commands/deploy.ts +0 -448
  33. package/src/commands/design.ts +0 -298
  34. package/src/commands/fix.ts +0 -20
  35. package/src/commands/gateway.ts +0 -604
  36. package/src/commands/generate.ts +0 -178
  37. package/src/commands/init.ts +0 -634
  38. package/src/commands/integrate.ts +0 -884
  39. package/src/commands/learn.ts +0 -36
  40. package/src/commands/migrate.ts +0 -419
  41. package/src/commands/prd-maker.ts +0 -588
  42. package/src/commands/prd.ts +0 -419
  43. package/src/commands/security.ts +0 -102
  44. package/src/commands/setup.ts +0 -600
  45. package/src/commands/status.ts +0 -56
  46. package/src/commands/website.ts +0 -741
  47. package/src/index.ts +0 -627
  48. package/src/patterns/loader.ts +0 -337
  49. package/src/services/github.ts +0 -61
  50. package/src/services/supabase.ts +0 -147
  51. package/src/services/vercel.ts +0 -61
  52. package/src/utils/claude-md.ts +0 -287
  53. package/src/utils/config.ts +0 -375
  54. package/src/utils/display.ts +0 -338
  55. package/src/utils/files.ts +0 -418
  56. package/src/utils/nlp.ts +0 -312
  57. package/src/utils/ui.ts +0 -441
  58. package/src/utils/updates.ts +0 -8
  59. package/src/utils/voice.ts +0 -323
  60. package/tsconfig.json +0 -26
@@ -1,600 +0,0 @@
1
- import * as p from '@clack/prompts';
2
- import chalk from 'chalk';
3
- import boxen from 'boxen';
4
- import open from 'open';
5
- import { Config } from '../utils/config.js';
6
-
7
- // ============================================================================
8
- // SERVICE DEFINITIONS
9
- // ============================================================================
10
-
11
- interface ServiceDef {
12
- key: string;
13
- name: string;
14
- description: string;
15
- whyNeeded: string;
16
- url: string;
17
- steps: string[]; // Step-by-step instructions
18
- fields: Array<{
19
- key: string;
20
- label: string;
21
- placeholder: string;
22
- hint?: string;
23
- validate?: (v: string) => string | undefined;
24
- }>;
25
- }
26
-
27
- const SERVICES: Record<string, ServiceDef> = {
28
- anthropic: {
29
- key: 'anthropic',
30
- name: 'Anthropic (Claude)',
31
- description: 'Powers the AI coding agent',
32
- whyNeeded: 'This is REQUIRED. Without it, CodeBakers cannot generate any code.',
33
- url: 'https://console.anthropic.com/settings/keys',
34
- steps: [
35
- 'Sign up or log in to Anthropic Console',
36
- 'Click "Create Key"',
37
- 'Give it a name like "CodeBakers"',
38
- 'Copy the key (starts with sk-ant-)',
39
- ],
40
- fields: [{
41
- key: 'apiKey',
42
- label: 'Paste your Anthropic API Key',
43
- placeholder: 'sk-ant-...',
44
- hint: 'Starts with sk-ant-',
45
- validate: (v) => {
46
- if (!v) return 'API key is required';
47
- if (!v.startsWith('sk-ant-')) return 'Should start with sk-ant-';
48
- return undefined;
49
- },
50
- }],
51
- },
52
- github: {
53
- key: 'github',
54
- name: 'GitHub',
55
- description: 'Create repos and push code',
56
- whyNeeded: 'Needed to create repositories and save your code. Skip if you\'ll manage git manually.',
57
- url: 'https://github.com/settings/tokens/new?scopes=repo,user&description=CodeBakers',
58
- steps: [
59
- 'Log in to GitHub',
60
- 'The "repo" and "user" boxes should already be checked',
61
- 'Scroll down and click "Generate token"',
62
- 'Copy the token (starts with ghp_)',
63
- ],
64
- fields: [{
65
- key: 'token',
66
- label: 'Paste your GitHub Token',
67
- placeholder: 'ghp_...',
68
- hint: 'Starts with ghp_ or github_pat_',
69
- validate: (v) => {
70
- if (!v) return 'Token is required';
71
- if (!v.startsWith('ghp_') && !v.startsWith('github_pat_')) {
72
- return 'Should start with ghp_ or github_pat_';
73
- }
74
- return undefined;
75
- },
76
- }],
77
- },
78
- vercel: {
79
- key: 'vercel',
80
- name: 'Vercel',
81
- description: 'Deploy your apps to production',
82
- whyNeeded: 'Needed to deploy apps automatically. Skip if you\'ll deploy manually.',
83
- url: 'https://vercel.com/account/tokens',
84
- steps: [
85
- 'Log in to Vercel',
86
- 'Click "Create" button',
87
- 'Name it "CodeBakers"',
88
- 'Click "Create Token"',
89
- 'Copy the token',
90
- ],
91
- fields: [{
92
- key: 'token',
93
- label: 'Paste your Vercel Token',
94
- placeholder: 'vercel_...',
95
- hint: 'The token you just created',
96
- }],
97
- },
98
- supabase: {
99
- key: 'supabase',
100
- name: 'Supabase',
101
- description: 'Database and authentication',
102
- whyNeeded: 'Needed for database features. Skip if you\'ll set up databases manually.',
103
- url: 'https://supabase.com/dashboard/account/tokens',
104
- steps: [
105
- 'Log in to Supabase',
106
- 'Click "Generate new token"',
107
- 'Name it "CodeBakers"',
108
- 'Copy the token',
109
- ],
110
- fields: [{
111
- key: 'accessToken',
112
- label: 'Paste your Supabase Token',
113
- placeholder: 'sbp_...',
114
- hint: 'Starts with sbp_',
115
- }],
116
- },
117
- openai: {
118
- key: 'openai',
119
- name: 'OpenAI',
120
- description: 'GPT models, embeddings, DALL-E',
121
- whyNeeded: 'Optional. Only if you want to use OpenAI alongside Claude.',
122
- url: 'https://platform.openai.com/api-keys',
123
- steps: [
124
- 'Log in to OpenAI',
125
- 'Click "Create new secret key"',
126
- 'Copy the key',
127
- ],
128
- fields: [{
129
- key: 'apiKey',
130
- label: 'Paste your OpenAI API Key',
131
- placeholder: 'sk-...',
132
- }],
133
- },
134
- stripe: {
135
- key: 'stripe',
136
- name: 'Stripe',
137
- description: 'Payment processing',
138
- whyNeeded: 'Optional. Only if your app accepts payments.',
139
- url: 'https://dashboard.stripe.com/apikeys',
140
- steps: [
141
- 'Log in to Stripe',
142
- 'Copy your Secret key (starts with sk_)',
143
- ],
144
- fields: [{
145
- key: 'secretKey',
146
- label: 'Paste your Stripe Secret Key',
147
- placeholder: 'sk_live_... or sk_test_...',
148
- }],
149
- },
150
- twilio: {
151
- key: 'twilio',
152
- name: 'Twilio',
153
- description: 'SMS, voice calls, WhatsApp',
154
- whyNeeded: 'Optional. Only if your app sends SMS or makes calls.',
155
- url: 'https://console.twilio.com/',
156
- steps: [
157
- 'Log in to Twilio',
158
- 'Find Account SID on the dashboard',
159
- 'Find Auth Token on the dashboard',
160
- ],
161
- fields: [
162
- {
163
- key: 'accountSid',
164
- label: 'Account SID',
165
- placeholder: 'AC...',
166
- },
167
- {
168
- key: 'authToken',
169
- label: 'Auth Token',
170
- placeholder: '...',
171
- },
172
- ],
173
- },
174
- resend: {
175
- key: 'resend',
176
- name: 'Resend',
177
- description: 'Email sending',
178
- whyNeeded: 'Optional. Only if your app sends emails.',
179
- url: 'https://resend.com/api-keys',
180
- steps: [
181
- 'Log in to Resend',
182
- 'Click "Create API Key"',
183
- 'Copy the key',
184
- ],
185
- fields: [{
186
- key: 'apiKey',
187
- label: 'Paste your Resend API Key',
188
- placeholder: 're_...',
189
- }],
190
- },
191
- vapi: {
192
- key: 'vapi',
193
- name: 'VAPI',
194
- description: 'Voice AI agents',
195
- whyNeeded: 'Optional. Only if you\'re building voice agents.',
196
- url: 'https://dashboard.vapi.ai/',
197
- steps: [
198
- 'Log in to VAPI',
199
- 'Go to Settings > API Keys',
200
- 'Copy your API key',
201
- ],
202
- fields: [{
203
- key: 'apiKey',
204
- label: 'Paste your VAPI API Key',
205
- placeholder: '...',
206
- }],
207
- },
208
- elevenlabs: {
209
- key: 'elevenlabs',
210
- name: 'ElevenLabs',
211
- description: 'AI voice generation',
212
- whyNeeded: 'Optional. Only if you want AI-generated voices.',
213
- url: 'https://elevenlabs.io/app/settings/api-keys',
214
- steps: [
215
- 'Log in to ElevenLabs',
216
- 'Click "Create API Key"',
217
- 'Copy the key',
218
- ],
219
- fields: [{
220
- key: 'apiKey',
221
- label: 'Paste your ElevenLabs API Key',
222
- placeholder: '...',
223
- }],
224
- },
225
- };
226
-
227
- const CORE_SERVICES = ['anthropic', 'github', 'vercel', 'supabase'];
228
- const OPTIONAL_SERVICES = ['openai', 'stripe', 'twilio', 'resend', 'vapi', 'elevenlabs'];
229
-
230
- // ============================================================================
231
- // MAIN SETUP COMMAND
232
- // ============================================================================
233
-
234
- export async function setupCommand(): Promise<void> {
235
- const config = new Config();
236
-
237
- // Check if already configured
238
- const hasAnthropic = !!config.getCredentials('anthropic')?.apiKey;
239
-
240
- if (hasAnthropic) {
241
- // Already has minimum setup - show management menu
242
- await showManagementMenu(config);
243
- return;
244
- }
245
-
246
- // =========================================================================
247
- // FIRST TIME SETUP - Step by step with clear instructions
248
- // =========================================================================
249
-
250
- console.log(boxen(
251
- chalk.bold.cyan('Welcome to CodeBakers Setup!\n\n') +
252
- chalk.white('We need to connect a few services to get started.\n\n') +
253
- chalk.dim('Your credentials are stored locally on your computer\n') +
254
- chalk.dim('in ~/.codebakers/ and never sent to our servers.\n\n') +
255
- chalk.yellow('Required: ') + chalk.white('Anthropic API key (for AI)\n') +
256
- chalk.dim('Optional: GitHub, Vercel, Supabase (for full features)'),
257
- { padding: 1, borderColor: 'cyan', borderStyle: 'round' }
258
- ));
259
-
260
- // STEP 1: Anthropic (REQUIRED)
261
- console.log(chalk.bold.cyan('\n━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━'));
262
- console.log(chalk.bold.cyan(' STEP 1 of 4: Anthropic API Key (Required)'));
263
- console.log(chalk.bold.cyan('━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\n'));
264
-
265
- console.log(chalk.white(' Anthropic (Claude)'));
266
- console.log(chalk.dim(' Powers the AI coding agent\n'));
267
-
268
- // Check if they have an account
269
- const hasAccount = await p.select({
270
- message: 'Do you have an Anthropic account?',
271
- options: [
272
- { value: 'yes', label: '✓ Yes, I have an API key ready' },
273
- { value: 'no', label: '✗ No, I need to sign up (free)' },
274
- ],
275
- });
276
-
277
- if (p.isCancel(hasAccount)) {
278
- return;
279
- }
280
-
281
- if (hasAccount === 'no') {
282
- console.log(chalk.yellow('\n No problem! Let\'s get you signed up.\n'));
283
- console.log(chalk.white(' Steps:'));
284
- console.log(chalk.cyan(' 1. ') + 'Click "Sign Up" on the page that opens');
285
- console.log(chalk.cyan(' 2. ') + 'Create your account (email + password)');
286
- console.log(chalk.cyan(' 3. ') + 'Once logged in, go to Settings → API Keys');
287
- console.log(chalk.cyan(' 4. ') + 'Click "Create Key"');
288
- console.log(chalk.cyan(' 5. ') + 'Copy the key and paste it here\n');
289
-
290
- const openSignup = await p.confirm({
291
- message: 'Open Anthropic signup page?',
292
- initialValue: true,
293
- });
294
-
295
- if (openSignup && !p.isCancel(openSignup)) {
296
- await open('https://console.anthropic.com/');
297
- console.log(chalk.dim('\n Take your time - come back when you have your API key.\n'));
298
- }
299
- } else {
300
- // They have an account, show regular instructions
301
- console.log(chalk.bold.white('\n Here\'s what to do:\n'));
302
- console.log(chalk.cyan(' 1. ') + 'Log in to Anthropic Console');
303
- console.log(chalk.cyan(' 2. ') + 'Go to Settings → API Keys');
304
- console.log(chalk.cyan(' 3. ') + 'Click "Create Key"');
305
- console.log(chalk.cyan(' 4. ') + 'Copy the key (starts with sk-ant-)');
306
- console.log('');
307
-
308
- const openBrowser = await p.confirm({
309
- message: 'Open Anthropic Console?',
310
- initialValue: true,
311
- });
312
-
313
- if (openBrowser && !p.isCancel(openBrowser)) {
314
- await open('https://console.anthropic.com/settings/keys');
315
- }
316
- }
317
-
318
- // Now collect the API key
319
- console.log('');
320
- const apiKey = await p.text({
321
- message: 'Paste your Anthropic API Key:',
322
- placeholder: 'sk-ant-...',
323
- validate: (v) => {
324
- if (!v) return 'API key is required';
325
- if (!v.startsWith('sk-ant-')) return 'Should start with sk-ant-';
326
- return undefined;
327
- },
328
- });
329
-
330
- if (p.isCancel(apiKey) || !apiKey) {
331
- console.log(chalk.red('\n ❌ Anthropic API key is required to use CodeBakers.'));
332
- console.log(chalk.dim(' Run `codebakers setup` when you\'re ready to try again.\n'));
333
- return;
334
- }
335
-
336
- config.setCredentials('anthropic', { apiKey: apiKey as string });
337
- console.log(chalk.green('\n ✓ Anthropic connected successfully!\n'));
338
-
339
- // STEP 2: GitHub (Optional but recommended)
340
- console.log(chalk.bold.cyan('\n━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━'));
341
- console.log(chalk.bold.cyan(' STEP 2 of 4: GitHub Token (Recommended)'));
342
- console.log(chalk.bold.cyan('━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\n'));
343
-
344
- await connectServiceWithInstructions(config, SERVICES.github, false);
345
-
346
- // STEP 3: Vercel (Optional but recommended)
347
- console.log(chalk.bold.cyan('\n━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━'));
348
- console.log(chalk.bold.cyan(' STEP 3 of 4: Vercel Token (Recommended)'));
349
- console.log(chalk.bold.cyan('━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\n'));
350
-
351
- await connectServiceWithInstructions(config, SERVICES.vercel, false);
352
-
353
- // STEP 4: Supabase (Optional)
354
- console.log(chalk.bold.cyan('\n━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━'));
355
- console.log(chalk.bold.cyan(' STEP 4 of 4: Supabase Token (Optional)'));
356
- console.log(chalk.bold.cyan('━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\n'));
357
-
358
- await connectServiceWithInstructions(config, SERVICES.supabase, false);
359
-
360
- // =========================================================================
361
- // SETUP COMPLETE - Show what to do next
362
- // =========================================================================
363
-
364
- const connectedServices = CORE_SERVICES.filter(key => config.getCredentials(key)).map(key => SERVICES[key].name);
365
-
366
- console.log(boxen(
367
- chalk.bold.green('✓ Setup Complete!\n\n') +
368
- chalk.white('Connected: ') + chalk.cyan(connectedServices.join(', ')) + '\n\n' +
369
- chalk.bold.white('What to do next:\n\n') +
370
- chalk.cyan('1. ') + chalk.white('Open a terminal and navigate to where you want to build:\n') +
371
- chalk.dim(' cd C:\\dev\\my-project\n') +
372
- chalk.dim(' (or any folder where you want to create your project)\n\n') +
373
- chalk.cyan('2. ') + chalk.white('Run CodeBakers:\n') +
374
- chalk.dim(' codebakers\n\n') +
375
- chalk.bold.white('Or try these commands directly:\n\n') +
376
- chalk.dim(' codebakers website ') + chalk.white('Build a website by describing it\n') +
377
- chalk.dim(' codebakers init ') + chalk.white('Create a new project from scratch\n') +
378
- chalk.dim(' codebakers help ') + chalk.white('See all available commands'),
379
- { padding: 1, borderColor: 'green', borderStyle: 'round' }
380
- ));
381
- }
382
-
383
- // ============================================================================
384
- // CONNECT SERVICE WITH DETAILED INSTRUCTIONS
385
- // ============================================================================
386
-
387
- async function connectServiceWithInstructions(
388
- config: Config,
389
- service: ServiceDef,
390
- required: boolean
391
- ): Promise<boolean> {
392
-
393
- // Show what this service does
394
- console.log(chalk.white(` ${service.name}`));
395
- console.log(chalk.dim(` ${service.description}\n`));
396
-
397
- if (!required) {
398
- console.log(chalk.yellow(` ${service.whyNeeded}\n`));
399
- }
400
-
401
- // Ask if they want to connect or skip
402
- const action = await p.select({
403
- message: `Connect ${service.name}?`,
404
- options: required ? [
405
- { value: 'connect', label: '✓ Yes, let\'s connect it' },
406
- ] : [
407
- { value: 'connect', label: '✓ Yes, connect it' },
408
- { value: 'skip', label: '→ Skip for now' },
409
- ],
410
- });
411
-
412
- if (p.isCancel(action) || action === 'skip') {
413
- if (!required) {
414
- console.log(chalk.dim(`\n Skipped ${service.name}. You can add it later with: codebakers setup\n`));
415
- }
416
- return false;
417
- }
418
-
419
- // Show step-by-step instructions
420
- console.log(chalk.bold.white('\n Here\'s what to do:\n'));
421
- service.steps.forEach((step, i) => {
422
- console.log(chalk.cyan(` ${i + 1}. `) + chalk.white(step));
423
- });
424
- console.log('');
425
-
426
- // Ask to open browser
427
- const openBrowser = await p.confirm({
428
- message: 'Open the website in your browser?',
429
- initialValue: true,
430
- });
431
-
432
- if (openBrowser && !p.isCancel(openBrowser)) {
433
- console.log(chalk.dim(`\n Opening: ${service.url}\n`));
434
- await open(service.url);
435
-
436
- // Give user time to get the key
437
- console.log(chalk.dim(' Complete the steps above, then paste your key below.\n'));
438
- }
439
-
440
- // Collect credentials
441
- const credentials: Record<string, string> = {};
442
-
443
- for (const field of service.fields) {
444
- const value = await p.text({
445
- message: field.label + (field.hint ? chalk.dim(` (${field.hint})`) : '') + ':',
446
- placeholder: field.placeholder,
447
- validate: field.validate,
448
- });
449
-
450
- if (p.isCancel(value)) return false;
451
-
452
- if (!value) {
453
- if (required) {
454
- console.log(chalk.red(`\n ${field.label} is required.\n`));
455
- return false;
456
- }
457
- console.log(chalk.dim(`\n Skipped ${service.name}.\n`));
458
- return false;
459
- }
460
-
461
- credentials[field.key] = value as string;
462
- }
463
-
464
- // Save credentials
465
- config.setCredentials(service.key, credentials);
466
- console.log(chalk.green(`\n ✓ ${service.name} connected successfully!\n`));
467
-
468
- return true;
469
- }
470
-
471
- // ============================================================================
472
- // MANAGEMENT MENU (for already-configured users)
473
- // ============================================================================
474
-
475
- async function showManagementMenu(config: Config): Promise<void> {
476
- // Show current status
477
- console.log(chalk.bold.cyan('\n CodeBakers Settings\n'));
478
-
479
- const allServices = [...CORE_SERVICES, ...OPTIONAL_SERVICES];
480
- const connected = allServices.filter(key => config.getCredentials(key));
481
- const notConnected = allServices.filter(key => !config.getCredentials(key));
482
-
483
- console.log(chalk.green(' Connected:'));
484
- connected.forEach(key => {
485
- console.log(chalk.green(` ✓ ${SERVICES[key].name}`));
486
- });
487
-
488
- if (notConnected.length > 0) {
489
- console.log(chalk.dim('\n Not connected:'));
490
- notConnected.forEach(key => {
491
- console.log(chalk.dim(` ○ ${SERVICES[key].name}`));
492
- });
493
- }
494
- console.log('');
495
-
496
- const action = await p.select({
497
- message: 'What would you like to do?',
498
- options: [
499
- { value: 'add', label: '➕ Add a service' },
500
- { value: 'update', label: '🔄 Update a service' },
501
- { value: 'reset', label: '🗑️ Reset all settings' },
502
- { value: 'back', label: '← Back' },
503
- ],
504
- });
505
-
506
- if (p.isCancel(action) || action === 'back') {
507
- return;
508
- }
509
-
510
- switch (action) {
511
- case 'add':
512
- await addService(config);
513
- break;
514
- case 'update':
515
- await updateService(config);
516
- break;
517
- case 'reset':
518
- await resetConfig(config);
519
- break;
520
- }
521
- }
522
-
523
- // ============================================================================
524
- // ADD SERVICE
525
- // ============================================================================
526
-
527
- async function addService(config: Config): Promise<void> {
528
- const allServices = [...CORE_SERVICES, ...OPTIONAL_SERVICES];
529
- const unconnected = allServices.filter(key => !config.getCredentials(key));
530
-
531
- if (unconnected.length === 0) {
532
- console.log(chalk.green('\n All services are already connected!\n'));
533
- return;
534
- }
535
-
536
- const selected = await p.select({
537
- message: 'Select service to add:',
538
- options: unconnected.map(key => ({
539
- value: key,
540
- label: `${SERVICES[key].name} - ${SERVICES[key].description}`,
541
- })),
542
- });
543
-
544
- if (p.isCancel(selected)) return;
545
-
546
- await connectServiceWithInstructions(config, SERVICES[selected as string], false);
547
- }
548
-
549
- // ============================================================================
550
- // UPDATE SERVICE
551
- // ============================================================================
552
-
553
- async function updateService(config: Config): Promise<void> {
554
- const allServices = [...CORE_SERVICES, ...OPTIONAL_SERVICES];
555
- const connected = allServices.filter(key => config.getCredentials(key));
556
-
557
- if (connected.length === 0) {
558
- console.log(chalk.yellow('\n No services connected yet.\n'));
559
- return;
560
- }
561
-
562
- const selected = await p.select({
563
- message: 'Select service to update:',
564
- options: connected.map(key => ({
565
- value: key,
566
- label: SERVICES[key].name,
567
- })),
568
- });
569
-
570
- if (p.isCancel(selected)) return;
571
-
572
- await connectServiceWithInstructions(config, SERVICES[selected as string], false);
573
- }
574
-
575
- // ============================================================================
576
- // RESET CONFIG
577
- // ============================================================================
578
-
579
- async function resetConfig(config: Config): Promise<void> {
580
- console.log(chalk.yellow('\n ⚠️ This will remove ALL your saved API keys.\n'));
581
-
582
- const confirm = await p.confirm({
583
- message: 'Are you sure?',
584
- initialValue: false,
585
- });
586
-
587
- if (!confirm || p.isCancel(confirm)) {
588
- console.log(chalk.dim('\n Cancelled.\n'));
589
- return;
590
- }
591
-
592
- // Clear all credentials
593
- const allServices = [...CORE_SERVICES, ...OPTIONAL_SERVICES];
594
- for (const key of allServices) {
595
- config.setCredentials(key, null as any);
596
- }
597
-
598
- console.log(chalk.green('\n ✓ All settings reset.\n'));
599
- console.log(chalk.dim(' Run `codebakers setup` to configure again.\n'));
600
- }
@@ -1,56 +0,0 @@
1
- // src/commands/status.ts
2
- import * as p from '@clack/prompts';
3
- import chalk from 'chalk';
4
- import fs from 'fs-extra';
5
- import * as path from 'path';
6
- import { Config } from '../utils/config.js';
7
-
8
- export async function statusCommand(): Promise<void> {
9
- const config = new Config();
10
- const cwd = process.cwd();
11
-
12
- p.intro(chalk.bgCyan.black(' Project Status '));
13
-
14
- if (!config.isInProject()) {
15
- // Show all projects
16
- const projects = config.getProjects();
17
-
18
- if (projects.length === 0) {
19
- p.log.info('No projects found. Run `codebakers init` to create one.');
20
- return;
21
- }
22
-
23
- console.log(chalk.bold('\nYour Projects:\n'));
24
-
25
- for (const project of projects) {
26
- const exists = await fs.pathExists(project.path);
27
- const status = exists ? chalk.green('✓') : chalk.red('✗');
28
- console.log(` ${status} ${project.name}`);
29
- console.log(chalk.dim(` ${project.path}`));
30
- console.log('');
31
- }
32
- return;
33
- }
34
-
35
- // Show current project status
36
- const projectConfig = await fs.readJson(
37
- path.join(cwd, '.codebakers', 'config.json')
38
- ).catch(() => ({}));
39
-
40
- const packageJson = await fs.readJson(
41
- path.join(cwd, 'package.json')
42
- ).catch(() => ({}));
43
-
44
- console.log(`
45
- ${chalk.bold('Project:')} ${packageJson.name || path.basename(cwd)}
46
- ${chalk.bold('Framework:')} ${projectConfig.framework || 'unknown'}
47
- ${chalk.bold('UI:')} ${projectConfig.ui || 'unknown'}
48
-
49
- ${chalk.bold('Quick Actions:')}
50
- ${chalk.cyan('codebakers code')} — AI coding agent
51
- ${chalk.cyan('codebakers check')} — Pattern enforcement
52
- ${chalk.cyan('codebakers deploy')} — Deploy to production
53
- `);
54
-
55
- p.outro('');
56
- }