@codebakers/cli 1.5.0 → 1.6.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.
@@ -46,6 +46,40 @@ const child_process_1 = require("child_process");
46
46
  const templates = __importStar(require("../templates/nextjs-supabase.js"));
47
47
  const config_js_1 = require("../config.js");
48
48
  const provision_js_1 = require("./provision.js");
49
+ /**
50
+ * Fetch service keys from CodeBakers server
51
+ */
52
+ async function fetchServerKeys() {
53
+ const apiKey = (0, config_js_1.getApiKey)();
54
+ if (!apiKey)
55
+ return null;
56
+ try {
57
+ const apiUrl = (0, config_js_1.getApiUrl)();
58
+ const response = await fetch(`${apiUrl}/api/cli/service-keys`, {
59
+ headers: {
60
+ Authorization: `Bearer ${apiKey}`,
61
+ },
62
+ });
63
+ if (response.ok) {
64
+ return await response.json();
65
+ }
66
+ }
67
+ catch {
68
+ // Server unreachable or error
69
+ }
70
+ return null;
71
+ }
72
+ /**
73
+ * Sync server keys to local storage
74
+ */
75
+ function syncKeysToLocal(keys) {
76
+ if (keys.github)
77
+ (0, config_js_1.setServiceKey)('github', keys.github);
78
+ if (keys.supabase)
79
+ (0, config_js_1.setServiceKey)('supabase', keys.supabase);
80
+ if (keys.vercel)
81
+ (0, config_js_1.setServiceKey)('vercel', keys.vercel);
82
+ }
49
83
  // Cursor IDE configuration templates
50
84
  const CURSORRULES_TEMPLATE = `# CODEBAKERS CURSOR RULES
51
85
  # Zero-friction AI assistance - everything is automatic
@@ -515,16 +549,84 @@ async function scaffold() {
515
549
  const wantProvision = await confirm(' Auto-provision services?');
516
550
  let provisionResult = {};
517
551
  if (wantProvision) {
518
- // Initialize git first if not already
519
- try {
520
- (0, child_process_1.execSync)('git init', { cwd, stdio: 'pipe' });
521
- (0, child_process_1.execSync)('git add .', { cwd, stdio: 'pipe' });
522
- (0, child_process_1.execSync)('git commit -m "Initial commit from CodeBakers scaffold"', { cwd, stdio: 'pipe' });
552
+ // Check for saved keys in CodeBakers back office
553
+ const serverKeys = await fetchServerKeys();
554
+ const hasServerKeys = serverKeys && (serverKeys.github || serverKeys.supabase || serverKeys.vercel);
555
+ const localGithub = (0, config_js_1.getServiceKey)('github');
556
+ const localSupabase = (0, config_js_1.getServiceKey)('supabase');
557
+ const localVercel = (0, config_js_1.getServiceKey)('vercel');
558
+ const hasLocalKeys = localGithub || localSupabase || localVercel;
559
+ if (hasServerKeys || hasLocalKeys) {
560
+ // Show which keys are available
561
+ console.log(chalk_1.default.white('\n Available service keys:\n'));
562
+ if (hasServerKeys) {
563
+ console.log(chalk_1.default.gray(' From CodeBakers account:'));
564
+ if (serverKeys?.github)
565
+ console.log(chalk_1.default.green(' ✓ GitHub'));
566
+ if (serverKeys?.supabase)
567
+ console.log(chalk_1.default.green(' ✓ Supabase'));
568
+ if (serverKeys?.vercel)
569
+ console.log(chalk_1.default.green(' ✓ Vercel'));
570
+ }
571
+ if (hasLocalKeys) {
572
+ console.log(chalk_1.default.gray(' Stored locally:'));
573
+ if (localGithub)
574
+ console.log(chalk_1.default.green(' ✓ GitHub'));
575
+ if (localSupabase)
576
+ console.log(chalk_1.default.green(' ✓ Supabase'));
577
+ if (localVercel)
578
+ console.log(chalk_1.default.green(' ✓ Vercel'));
579
+ }
580
+ console.log('');
581
+ // Ask which keys to use
582
+ console.log(chalk_1.default.white(' Which keys would you like to use?\n'));
583
+ console.log(chalk_1.default.gray(' 1. ') + chalk_1.default.cyan('Use saved keys') + chalk_1.default.gray(' - Use keys from your account/local storage'));
584
+ console.log(chalk_1.default.gray(' 2. ') + chalk_1.default.cyan('Enter new keys') + chalk_1.default.gray(' - For a client project or different account'));
585
+ console.log(chalk_1.default.gray(' 3. ') + chalk_1.default.cyan('Skip') + chalk_1.default.gray(' - Don\'t provision, I\'ll do it manually\n'));
586
+ let keyChoice = '';
587
+ while (!['1', '2', '3'].includes(keyChoice)) {
588
+ keyChoice = await prompt(' Enter 1, 2, or 3: ');
589
+ }
590
+ if (keyChoice === '3') {
591
+ console.log(chalk_1.default.gray('\n Skipping auto-provisioning.\n'));
592
+ }
593
+ else {
594
+ if (keyChoice === '1' && hasServerKeys) {
595
+ // Sync server keys to local storage for this session
596
+ syncKeysToLocal(serverKeys);
597
+ console.log(chalk_1.default.green('\n ✓ Using saved keys from CodeBakers account\n'));
598
+ }
599
+ else if (keyChoice === '2') {
600
+ // Clear local keys so provision.ts will prompt for new ones
601
+ console.log(chalk_1.default.gray('\n You\'ll be prompted to enter keys for each service.\n'));
602
+ }
603
+ // Initialize git first if not already
604
+ try {
605
+ (0, child_process_1.execSync)('git init', { cwd, stdio: 'pipe' });
606
+ (0, child_process_1.execSync)('git add .', { cwd, stdio: 'pipe' });
607
+ (0, child_process_1.execSync)('git commit -m "Initial commit from CodeBakers scaffold"', { cwd, stdio: 'pipe' });
608
+ }
609
+ catch {
610
+ // Git might already be initialized or have issues
611
+ }
612
+ provisionResult = await (0, provision_js_1.provisionAll)(projectName, `${projectName} - Built with CodeBakers`);
613
+ }
523
614
  }
524
- catch {
525
- // Git might already be initialized or have issues
615
+ else {
616
+ // No saved keys - proceed with provisioning (will prompt for keys)
617
+ console.log(chalk_1.default.gray('\n No saved keys found. You\'ll be prompted to enter keys for each service.\n'));
618
+ console.log(chalk_1.default.gray(' Tip: Save keys in your CodeBakers dashboard to auto-provision future projects!\n'));
619
+ // Initialize git first if not already
620
+ try {
621
+ (0, child_process_1.execSync)('git init', { cwd, stdio: 'pipe' });
622
+ (0, child_process_1.execSync)('git add .', { cwd, stdio: 'pipe' });
623
+ (0, child_process_1.execSync)('git commit -m "Initial commit from CodeBakers scaffold"', { cwd, stdio: 'pipe' });
624
+ }
625
+ catch {
626
+ // Git might already be initialized or have issues
627
+ }
628
+ provisionResult = await (0, provision_js_1.provisionAll)(projectName, `${projectName} - Built with CodeBakers`);
526
629
  }
527
- provisionResult = await (0, provision_js_1.provisionAll)(projectName, `${projectName} - Built with CodeBakers`);
528
630
  // Update .env.local with Supabase credentials if available
529
631
  if (provisionResult.supabase) {
530
632
  const envPath = (0, path_1.join)(cwd, '.env.local');
package/dist/index.js CHANGED
@@ -53,7 +53,7 @@ const program = new commander_1.Command();
53
53
  program
54
54
  .name('codebakers')
55
55
  .description('CodeBakers CLI - Production patterns for AI-assisted development')
56
- .version('1.5.0');
56
+ .version('1.6.0');
57
57
  // Primary command - one-time setup
58
58
  program
59
59
  .command('setup')
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@codebakers/cli",
3
- "version": "1.5.0",
3
+ "version": "1.6.0",
4
4
  "description": "CodeBakers CLI - Production patterns for AI-assisted development",
5
5
  "main": "dist/index.js",
6
6
  "bin": {
@@ -5,9 +5,48 @@ import { writeFileSync, mkdirSync, existsSync, readdirSync, readFileSync } from
5
5
  import { join } from 'path';
6
6
  import { execSync } from 'child_process';
7
7
  import * as templates from '../templates/nextjs-supabase.js';
8
- import { getApiKey, getApiUrl } from '../config.js';
8
+ import { getApiKey, getApiUrl, setServiceKey, getServiceKey } from '../config.js';
9
9
  import { provisionAll, type ProvisionResult } from './provision.js';
10
10
 
11
+ interface ServerServiceKeys {
12
+ github: string | null;
13
+ supabase: string | null;
14
+ vercel: string | null;
15
+ }
16
+
17
+ /**
18
+ * Fetch service keys from CodeBakers server
19
+ */
20
+ async function fetchServerKeys(): Promise<ServerServiceKeys | null> {
21
+ const apiKey = getApiKey();
22
+ if (!apiKey) return null;
23
+
24
+ try {
25
+ const apiUrl = getApiUrl();
26
+ const response = await fetch(`${apiUrl}/api/cli/service-keys`, {
27
+ headers: {
28
+ Authorization: `Bearer ${apiKey}`,
29
+ },
30
+ });
31
+
32
+ if (response.ok) {
33
+ return await response.json();
34
+ }
35
+ } catch {
36
+ // Server unreachable or error
37
+ }
38
+ return null;
39
+ }
40
+
41
+ /**
42
+ * Sync server keys to local storage
43
+ */
44
+ function syncKeysToLocal(keys: ServerServiceKeys): void {
45
+ if (keys.github) setServiceKey('github', keys.github);
46
+ if (keys.supabase) setServiceKey('supabase', keys.supabase);
47
+ if (keys.vercel) setServiceKey('vercel', keys.vercel);
48
+ }
49
+
11
50
  // Cursor IDE configuration templates
12
51
  const CURSORRULES_TEMPLATE = `# CODEBAKERS CURSOR RULES
13
52
  # Zero-friction AI assistance - everything is automatic
@@ -532,16 +571,84 @@ export async function scaffold(): Promise<void> {
532
571
  let provisionResult: ProvisionResult = {};
533
572
 
534
573
  if (wantProvision) {
535
- // Initialize git first if not already
536
- try {
537
- execSync('git init', { cwd, stdio: 'pipe' });
538
- execSync('git add .', { cwd, stdio: 'pipe' });
539
- execSync('git commit -m "Initial commit from CodeBakers scaffold"', { cwd, stdio: 'pipe' });
540
- } catch {
541
- // Git might already be initialized or have issues
542
- }
574
+ // Check for saved keys in CodeBakers back office
575
+ const serverKeys = await fetchServerKeys();
576
+ const hasServerKeys = serverKeys && (serverKeys.github || serverKeys.supabase || serverKeys.vercel);
577
+ const localGithub = getServiceKey('github');
578
+ const localSupabase = getServiceKey('supabase');
579
+ const localVercel = getServiceKey('vercel');
580
+ const hasLocalKeys = localGithub || localSupabase || localVercel;
581
+
582
+ if (hasServerKeys || hasLocalKeys) {
583
+ // Show which keys are available
584
+ console.log(chalk.white('\n Available service keys:\n'));
585
+
586
+ if (hasServerKeys) {
587
+ console.log(chalk.gray(' From CodeBakers account:'));
588
+ if (serverKeys?.github) console.log(chalk.green(' ✓ GitHub'));
589
+ if (serverKeys?.supabase) console.log(chalk.green(' ✓ Supabase'));
590
+ if (serverKeys?.vercel) console.log(chalk.green(' ✓ Vercel'));
591
+ }
592
+
593
+ if (hasLocalKeys) {
594
+ console.log(chalk.gray(' Stored locally:'));
595
+ if (localGithub) console.log(chalk.green(' ✓ GitHub'));
596
+ if (localSupabase) console.log(chalk.green(' ✓ Supabase'));
597
+ if (localVercel) console.log(chalk.green(' ✓ Vercel'));
598
+ }
599
+
600
+ console.log('');
543
601
 
544
- provisionResult = await provisionAll(projectName, `${projectName} - Built with CodeBakers`);
602
+ // Ask which keys to use
603
+ console.log(chalk.white(' Which keys would you like to use?\n'));
604
+ console.log(chalk.gray(' 1. ') + chalk.cyan('Use saved keys') + chalk.gray(' - Use keys from your account/local storage'));
605
+ console.log(chalk.gray(' 2. ') + chalk.cyan('Enter new keys') + chalk.gray(' - For a client project or different account'));
606
+ console.log(chalk.gray(' 3. ') + chalk.cyan('Skip') + chalk.gray(' - Don\'t provision, I\'ll do it manually\n'));
607
+
608
+ let keyChoice = '';
609
+ while (!['1', '2', '3'].includes(keyChoice)) {
610
+ keyChoice = await prompt(' Enter 1, 2, or 3: ');
611
+ }
612
+
613
+ if (keyChoice === '3') {
614
+ console.log(chalk.gray('\n Skipping auto-provisioning.\n'));
615
+ } else {
616
+ if (keyChoice === '1' && hasServerKeys) {
617
+ // Sync server keys to local storage for this session
618
+ syncKeysToLocal(serverKeys!);
619
+ console.log(chalk.green('\n ✓ Using saved keys from CodeBakers account\n'));
620
+ } else if (keyChoice === '2') {
621
+ // Clear local keys so provision.ts will prompt for new ones
622
+ console.log(chalk.gray('\n You\'ll be prompted to enter keys for each service.\n'));
623
+ }
624
+
625
+ // Initialize git first if not already
626
+ try {
627
+ execSync('git init', { cwd, stdio: 'pipe' });
628
+ execSync('git add .', { cwd, stdio: 'pipe' });
629
+ execSync('git commit -m "Initial commit from CodeBakers scaffold"', { cwd, stdio: 'pipe' });
630
+ } catch {
631
+ // Git might already be initialized or have issues
632
+ }
633
+
634
+ provisionResult = await provisionAll(projectName, `${projectName} - Built with CodeBakers`);
635
+ }
636
+ } else {
637
+ // No saved keys - proceed with provisioning (will prompt for keys)
638
+ console.log(chalk.gray('\n No saved keys found. You\'ll be prompted to enter keys for each service.\n'));
639
+ console.log(chalk.gray(' Tip: Save keys in your CodeBakers dashboard to auto-provision future projects!\n'));
640
+
641
+ // Initialize git first if not already
642
+ try {
643
+ execSync('git init', { cwd, stdio: 'pipe' });
644
+ execSync('git add .', { cwd, stdio: 'pipe' });
645
+ execSync('git commit -m "Initial commit from CodeBakers scaffold"', { cwd, stdio: 'pipe' });
646
+ } catch {
647
+ // Git might already be initialized or have issues
648
+ }
649
+
650
+ provisionResult = await provisionAll(projectName, `${projectName} - Built with CodeBakers`);
651
+ }
545
652
 
546
653
  // Update .env.local with Supabase credentials if available
547
654
  if (provisionResult.supabase) {
package/src/index.ts CHANGED
@@ -57,7 +57,7 @@ const program = new Command();
57
57
  program
58
58
  .name('codebakers')
59
59
  .description('CodeBakers CLI - Production patterns for AI-assisted development')
60
- .version('1.5.0');
60
+ .version('1.6.0');
61
61
 
62
62
  // Primary command - one-time setup
63
63
  program