@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.
- package/dist/commands/scaffold.js +110 -8
- package/dist/index.js +1 -1
- package/package.json +1 -1
- package/src/commands/scaffold.ts +117 -10
- package/src/index.ts +1 -1
|
@@ -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
|
-
//
|
|
519
|
-
|
|
520
|
-
|
|
521
|
-
|
|
522
|
-
|
|
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
|
-
|
|
525
|
-
//
|
|
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.
|
|
56
|
+
.version('1.6.0');
|
|
57
57
|
// Primary command - one-time setup
|
|
58
58
|
program
|
|
59
59
|
.command('setup')
|
package/package.json
CHANGED
package/src/commands/scaffold.ts
CHANGED
|
@@ -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
|
-
//
|
|
536
|
-
|
|
537
|
-
|
|
538
|
-
|
|
539
|
-
|
|
540
|
-
|
|
541
|
-
|
|
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
|
-
|
|
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