@codebakers/cli 3.9.18 → 3.9.20

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.
@@ -2158,9 +2158,17 @@ phase: setup
2158
2158
  results.push(...deployResults);
2159
2159
  }
2160
2160
  else {
2161
+ // Check for missing services and offer setup help
2162
+ const serviceCheck = this.checkMissingServices(cwd);
2163
+ results.push('### šŸ”§ Service Configuration\n');
2164
+ if (serviceCheck.missing.length > 0) {
2165
+ results.push(`Missing configuration for: **${serviceCheck.missing.join(', ')}**\n`);
2166
+ results.push('Run `setup_services` for step-by-step instructions to get your API keys.');
2167
+ results.push('You can paste your keys in chat and I\'ll add them to `.env.local` for you!\n');
2168
+ }
2161
2169
  results.push('### Next Steps:\n');
2162
- results.push('1. **Set up Supabase:** Go to https://supabase.com and create a free project');
2163
- results.push('2. **Add credentials:** Copy your Supabase URL and anon key to `.env.local`');
2170
+ results.push('1. **Configure services:** Run `setup_services` to set up Supabase, OpenAI, etc.');
2171
+ results.push('2. **Paste your keys:** Get your API keys and paste them in chat');
2164
2172
  results.push('3. **Start building:** Just tell me what features you want!\n');
2165
2173
  results.push('### Example:\n');
2166
2174
  results.push('> "Add user authentication with email/password"');
@@ -2559,6 +2567,15 @@ You cannot write code without calling this tool first.
2559
2567
  results.push('3. Call `validate_complete` before marking done');
2560
2568
  results.push('4. Server verifies compliance\n');
2561
2569
  results.push('No local pattern files needed - everything is server-side!');
2570
+ // Check for missing services and offer setup help
2571
+ const serviceCheck = this.checkMissingServices(cwd);
2572
+ if (serviceCheck.missing.length > 0) {
2573
+ results.push('\n---\n');
2574
+ results.push('## šŸ”§ Service Configuration\n');
2575
+ results.push(`Missing configuration for: **${serviceCheck.missing.join(', ')}**\n`);
2576
+ results.push('Run `setup_services` to get step-by-step instructions for getting your API keys.');
2577
+ results.push('You can paste your keys in chat and I\'ll add them to `.env.local` for you!');
2578
+ }
2562
2579
  }
2563
2580
  catch (error) {
2564
2581
  const message = error instanceof Error ? error.message : 'Unknown error';
@@ -2571,6 +2588,46 @@ You cannot write code without calling this tool first.
2571
2588
  }],
2572
2589
  };
2573
2590
  }
2591
+ /**
2592
+ * Check which services are missing from .env
2593
+ */
2594
+ checkMissingServices(cwd) {
2595
+ const SERVICE_ENV_VARS = {
2596
+ 'Supabase': ['NEXT_PUBLIC_SUPABASE_URL', 'NEXT_PUBLIC_SUPABASE_ANON_KEY'],
2597
+ 'OpenAI': ['OPENAI_API_KEY'],
2598
+ 'Anthropic': ['ANTHROPIC_API_KEY'],
2599
+ };
2600
+ // Read .env file
2601
+ const envPath = path.join(cwd, '.env');
2602
+ const envLocalPath = path.join(cwd, '.env.local');
2603
+ let envContent = '';
2604
+ if (fs.existsSync(envLocalPath)) {
2605
+ envContent = fs.readFileSync(envLocalPath, 'utf-8');
2606
+ }
2607
+ else if (fs.existsSync(envPath)) {
2608
+ envContent = fs.readFileSync(envPath, 'utf-8');
2609
+ }
2610
+ // Parse existing env vars
2611
+ const existingVars = new Set();
2612
+ for (const line of envContent.split('\n')) {
2613
+ const match = line.match(/^([A-Z_][A-Z0-9_]*)=/);
2614
+ if (match) {
2615
+ existingVars.add(match[1]);
2616
+ }
2617
+ }
2618
+ const missing = [];
2619
+ const configured = [];
2620
+ for (const [service, vars] of Object.entries(SERVICE_ENV_VARS)) {
2621
+ const hasMissing = vars.some(v => !existingVars.has(v));
2622
+ if (hasMissing) {
2623
+ missing.push(service);
2624
+ }
2625
+ else {
2626
+ configured.push(service);
2627
+ }
2628
+ }
2629
+ return { missing, configured };
2630
+ }
2574
2631
  handleSetExperienceLevel(args) {
2575
2632
  const { level } = args;
2576
2633
  // Validate level
@@ -3770,16 +3827,21 @@ If you want AI features and prefer Claude over GPT (or want both as fallback).`,
3770
3827
  else {
3771
3828
  response += `## Next Steps\n\n`;
3772
3829
  response += `1. Decide which services you actually need for your project\n`;
3773
- response += `2. Create accounts and get API keys for those services\n`;
3774
- response += `3. Add the keys to your \`.env.local\` file:\n\n`;
3775
- response += `\`\`\`bash\n`;
3830
+ response += `2. Create accounts and get API keys using the instructions above\n`;
3831
+ response += `3. **Paste your keys here in chat** and I'll add them to your \`.env.local\` file for you!\n\n`;
3832
+ response += `Example: Just paste something like:\n`;
3833
+ response += `\`\`\`\n`;
3834
+ response += `Here are my keys:\n`;
3776
3835
  for (const r of missing) {
3777
- for (const v of r.missingVars) {
3778
- response += `${v}=your_key_here\n`;
3836
+ if (r.missingVars.length > 0) {
3837
+ response += `${r.info.name}: sk-xxx... (your actual key)\n`;
3779
3838
  }
3780
3839
  }
3781
3840
  response += `\`\`\`\n\n`;
3782
- response += `4. Restart your dev server after adding keys\n\n`;
3841
+ response += `I'll automatically:\n`;
3842
+ response += `- Create \`.env.local\` if it doesn't exist\n`;
3843
+ response += `- Add the correct variable names\n`;
3844
+ response += `- Keep your existing env vars safe\n\n`;
3783
3845
  response += `**Don't need a service?** That's fine! Only configure what you'll actually use.\n`;
3784
3846
  }
3785
3847
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@codebakers/cli",
3
- "version": "3.9.18",
3
+ "version": "3.9.20",
4
4
  "description": "CodeBakers CLI - Production patterns for AI-assisted development",
5
5
  "main": "dist/index.js",
6
6
  "bin": {
package/src/mcp/server.ts CHANGED
@@ -2480,9 +2480,19 @@ phase: setup
2480
2480
  const deployResults = await this.executeFullDeploy(projectName, cwd, description);
2481
2481
  results.push(...deployResults);
2482
2482
  } else {
2483
+ // Check for missing services and offer setup help
2484
+ const serviceCheck = this.checkMissingServices(cwd);
2485
+
2486
+ results.push('### šŸ”§ Service Configuration\n');
2487
+ if (serviceCheck.missing.length > 0) {
2488
+ results.push(`Missing configuration for: **${serviceCheck.missing.join(', ')}**\n`);
2489
+ results.push('Run `setup_services` for step-by-step instructions to get your API keys.');
2490
+ results.push('You can paste your keys in chat and I\'ll add them to `.env.local` for you!\n');
2491
+ }
2492
+
2483
2493
  results.push('### Next Steps:\n');
2484
- results.push('1. **Set up Supabase:** Go to https://supabase.com and create a free project');
2485
- results.push('2. **Add credentials:** Copy your Supabase URL and anon key to `.env.local`');
2494
+ results.push('1. **Configure services:** Run `setup_services` to set up Supabase, OpenAI, etc.');
2495
+ results.push('2. **Paste your keys:** Get your API keys and paste them in chat');
2486
2496
  results.push('3. **Start building:** Just tell me what features you want!\n');
2487
2497
  results.push('### Example:\n');
2488
2498
  results.push('> "Add user authentication with email/password"');
@@ -2907,6 +2917,16 @@ You cannot write code without calling this tool first.
2907
2917
  results.push('4. Server verifies compliance\n');
2908
2918
  results.push('No local pattern files needed - everything is server-side!');
2909
2919
 
2920
+ // Check for missing services and offer setup help
2921
+ const serviceCheck = this.checkMissingServices(cwd);
2922
+ if (serviceCheck.missing.length > 0) {
2923
+ results.push('\n---\n');
2924
+ results.push('## šŸ”§ Service Configuration\n');
2925
+ results.push(`Missing configuration for: **${serviceCheck.missing.join(', ')}**\n`);
2926
+ results.push('Run `setup_services` to get step-by-step instructions for getting your API keys.');
2927
+ results.push('You can paste your keys in chat and I\'ll add them to `.env.local` for you!');
2928
+ }
2929
+
2910
2930
  } catch (error) {
2911
2931
  const message = error instanceof Error ? error.message : 'Unknown error';
2912
2932
  results.push(`\nāŒ Error: ${message}`);
@@ -2920,6 +2940,51 @@ You cannot write code without calling this tool first.
2920
2940
  };
2921
2941
  }
2922
2942
 
2943
+ /**
2944
+ * Check which services are missing from .env
2945
+ */
2946
+ private checkMissingServices(cwd: string): { missing: string[]; configured: string[] } {
2947
+ const SERVICE_ENV_VARS: Record<string, string[]> = {
2948
+ 'Supabase': ['NEXT_PUBLIC_SUPABASE_URL', 'NEXT_PUBLIC_SUPABASE_ANON_KEY'],
2949
+ 'OpenAI': ['OPENAI_API_KEY'],
2950
+ 'Anthropic': ['ANTHROPIC_API_KEY'],
2951
+ };
2952
+
2953
+ // Read .env file
2954
+ const envPath = path.join(cwd, '.env');
2955
+ const envLocalPath = path.join(cwd, '.env.local');
2956
+ let envContent = '';
2957
+
2958
+ if (fs.existsSync(envLocalPath)) {
2959
+ envContent = fs.readFileSync(envLocalPath, 'utf-8');
2960
+ } else if (fs.existsSync(envPath)) {
2961
+ envContent = fs.readFileSync(envPath, 'utf-8');
2962
+ }
2963
+
2964
+ // Parse existing env vars
2965
+ const existingVars = new Set<string>();
2966
+ for (const line of envContent.split('\n')) {
2967
+ const match = line.match(/^([A-Z_][A-Z0-9_]*)=/);
2968
+ if (match) {
2969
+ existingVars.add(match[1]);
2970
+ }
2971
+ }
2972
+
2973
+ const missing: string[] = [];
2974
+ const configured: string[] = [];
2975
+
2976
+ for (const [service, vars] of Object.entries(SERVICE_ENV_VARS)) {
2977
+ const hasMissing = vars.some(v => !existingVars.has(v));
2978
+ if (hasMissing) {
2979
+ missing.push(service);
2980
+ } else {
2981
+ configured.push(service);
2982
+ }
2983
+ }
2984
+
2985
+ return { missing, configured };
2986
+ }
2987
+
2923
2988
  private handleSetExperienceLevel(args: { level: ExperienceLevel }) {
2924
2989
  const { level } = args;
2925
2990
 
@@ -4238,16 +4303,21 @@ If you want AI features and prefer Claude over GPT (or want both as fallback).`,
4238
4303
  } else {
4239
4304
  response += `## Next Steps\n\n`;
4240
4305
  response += `1. Decide which services you actually need for your project\n`;
4241
- response += `2. Create accounts and get API keys for those services\n`;
4242
- response += `3. Add the keys to your \`.env.local\` file:\n\n`;
4243
- response += `\`\`\`bash\n`;
4306
+ response += `2. Create accounts and get API keys using the instructions above\n`;
4307
+ response += `3. **Paste your keys here in chat** and I'll add them to your \`.env.local\` file for you!\n\n`;
4308
+ response += `Example: Just paste something like:\n`;
4309
+ response += `\`\`\`\n`;
4310
+ response += `Here are my keys:\n`;
4244
4311
  for (const r of missing) {
4245
- for (const v of r.missingVars) {
4246
- response += `${v}=your_key_here\n`;
4312
+ if (r.missingVars.length > 0) {
4313
+ response += `${r.info.name}: sk-xxx... (your actual key)\n`;
4247
4314
  }
4248
4315
  }
4249
4316
  response += `\`\`\`\n\n`;
4250
- response += `4. Restart your dev server after adding keys\n\n`;
4317
+ response += `I'll automatically:\n`;
4318
+ response += `- Create \`.env.local\` if it doesn't exist\n`;
4319
+ response += `- Add the correct variable names\n`;
4320
+ response += `- Keep your existing env vars safe\n\n`;
4251
4321
  response += `**Don't need a service?** That's fine! Only configure what you'll actually use.\n`;
4252
4322
  }
4253
4323
  }