codebakers 2.1.2 → 2.2.1

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.
@@ -135,13 +135,28 @@ export async function websiteCommand(): Promise<void> {
135
135
  const config = new Config();
136
136
 
137
137
  if (!config.isConfigured()) {
138
- p.log.error('Please run `codebakers setup` first.');
138
+ console.log(chalk.yellow(`
139
+ ⚠️ CodeBakers isn't set up yet.
140
+
141
+ Run this first:
142
+ ${chalk.cyan('codebakers setup')}
143
+ `));
139
144
  return;
140
145
  }
141
146
 
142
147
  const anthropicCreds = config.getCredentials('anthropic');
143
148
  if (!anthropicCreds?.apiKey) {
144
- p.log.error('Anthropic API key not configured.');
149
+ console.log(chalk.yellow(`
150
+ ⚠️ Anthropic API key not configured.
151
+
152
+ The website builder needs Claude AI to generate code.
153
+
154
+ Run this to add your API key:
155
+ ${chalk.cyan('codebakers setup')}
156
+
157
+ Get an API key at:
158
+ ${chalk.dim('https://console.anthropic.com/settings/keys')}
159
+ `));
145
160
  return;
146
161
  }
147
162
 
package/src/index.ts CHANGED
@@ -29,7 +29,7 @@ import { integrateCommand, INTEGRATIONS } from './commands/integrate.js';
29
29
  import { websiteCommand } from './commands/website.js';
30
30
  import { parseNaturalLanguage, clarifyCommand, clarifyDeployTarget } from './utils/nlp.js';
31
31
 
32
- const VERSION = '2.1.1';
32
+ const VERSION = '2.2.1';
33
33
 
34
34
  // ASCII art logo
35
35
  const logo = `
@@ -186,27 +186,34 @@ async function showMainMenu(): Promise<void> {
186
186
 
187
187
  function showHelp(): void {
188
188
  console.log(boxen(`
189
- ${chalk.bold('CodeBakers CLI')} — AI dev team that follows the rules
190
-
191
- ${chalk.bold('Commands:')}
192
- ${chalk.cyan('codebakers')} Interactive menu (or just run with no args)
193
- ${chalk.cyan('codebakers init')} Create a new project
194
- ${chalk.cyan('codebakers code')} Start AI coding session
195
- ${chalk.cyan('codebakers check')} Run pattern enforcement
196
- ${chalk.cyan('codebakers deploy')} Deploy to production
197
- ${chalk.cyan('codebakers fix')} Auto-fix errors
198
- ${chalk.cyan('codebakers generate')} Generate components/pages
199
- ${chalk.cyan('codebakers connect')} Connect external services
200
- ${chalk.cyan('codebakers gateway')} Manage messaging channels
201
- ${chalk.cyan('codebakers status')} View project status
202
- ${chalk.cyan('codebakers security')} Run security audit
203
- ${chalk.cyan('codebakers learn')} View/manage learning
204
-
205
- ${chalk.bold('Help at any time:')}
206
- Press ${chalk.yellow('?')} during any command to get contextual help
207
-
208
- ${chalk.bold('Documentation:')}
209
- ${chalk.dim('https://codebakers.dev/docs')}
189
+ ${chalk.bold('CodeBakers CLI v' + VERSION)} — AI dev team that follows the rules
190
+
191
+ ${chalk.bold.cyan('Getting Started:')}
192
+ ${chalk.cyan('codebakers setup')} Connect your accounts (GitHub, Vercel, etc.)
193
+ ${chalk.cyan('codebakers init')} Create a new project from scratch
194
+ ${chalk.cyan('codebakers website')} Build a website by describing it
195
+ ${chalk.cyan('codebakers build')} Build from PRD with parallel AI agents
196
+
197
+ ${chalk.bold.cyan('Daily Development:')}
198
+ ${chalk.cyan('codebakers code')} Chat with AI to build features
199
+ ${chalk.cyan('codebakers check')} Check code quality & patterns
200
+ ${chalk.cyan('codebakers fix')} Auto-fix errors with AI
201
+ ${chalk.cyan('codebakers deploy')} Deploy to Vercel
202
+
203
+ ${chalk.bold.cyan('Integrations:')}
204
+ ${chalk.cyan('codebakers integrate')} 50+ one-click integrations (Stripe, Supabase, etc.)
205
+ ${chalk.cyan('codebakers gateway')} Connect WhatsApp, Telegram, Discord, etc.
206
+
207
+ ${chalk.bold.cyan('Planning:')}
208
+ ${chalk.cyan('codebakers prd-maker')} Create PRD through interview (voice supported)
209
+ ${chalk.cyan('codebakers advisors')} Consult AI experts (CEO, CTO, Designer, etc.)
210
+
211
+ ${chalk.bold.cyan('Tips:')}
212
+ • Type naturally: ${chalk.dim('codebakers "add a contact form"')}
213
+ • Voice input: Type ${chalk.yellow('"v"')} at any prompt
214
+ • Clipboard: Type ${chalk.yellow('"clip"')} to paste from clipboard
215
+
216
+ ${chalk.bold('Docs:')} ${chalk.dim('https://codebakers.dev/docs')}
210
217
  `, { padding: 1, borderColor: 'cyan', borderStyle: 'round' }));
211
218
  }
212
219
 
@@ -1,5 +1,6 @@
1
1
  import Conf from 'conf';
2
- import * as fs from 'fs-extra';
2
+ import fsExtra from 'fs-extra';
3
+ import { existsSync, readFileSync, appendFileSync } from 'fs';
3
4
  import * as path from 'path';
4
5
  import os from 'os';
5
6
  import { z } from 'zod';
@@ -106,10 +107,10 @@ export class Config {
106
107
  this.configDir = path.join(os.homedir(), '.codebakers');
107
108
 
108
109
  // Ensure config directory exists
109
- fs.ensureDirSync(this.configDir);
110
- fs.ensureDirSync(path.join(this.configDir, 'patterns'));
111
- fs.ensureDirSync(path.join(this.configDir, 'templates'));
112
- fs.ensureDirSync(path.join(this.configDir, 'learning'));
110
+ fsExtra.ensureDirSync(this.configDir);
111
+ fsExtra.ensureDirSync(path.join(this.configDir, 'patterns'));
112
+ fsExtra.ensureDirSync(path.join(this.configDir, 'templates'));
113
+ fsExtra.ensureDirSync(path.join(this.configDir, 'learning'));
113
114
 
114
115
  this.conf = new Conf<ConfigType>({
115
116
  projectName: 'codebakers',
@@ -143,7 +144,7 @@ export class Config {
143
144
  const claudeFile = path.join(cwd, 'CLAUDE.md');
144
145
 
145
146
  // Already a CodeBakers project
146
- if (fs.existsSync(codebakersDir) || fs.existsSync(claudeFile)) {
147
+ if (existsSync(codebakersDir) || existsSync(claudeFile)) {
147
148
  return true;
148
149
  }
149
150
 
@@ -160,7 +161,7 @@ export class Config {
160
161
  ];
161
162
 
162
163
  const hasProjectFile = projectIndicators.some(file =>
163
- fs.existsSync(path.join(cwd, file))
164
+ existsSync(path.join(cwd, file))
164
165
  );
165
166
 
166
167
  // If it's a project but no .codebakers, auto-initialize
@@ -179,23 +180,23 @@ export class Config {
179
180
  let framework = 'unknown';
180
181
  let ui = 'unknown';
181
182
 
182
- if (fs.existsSync(path.join(cwd, 'next.config.js')) ||
183
- fs.existsSync(path.join(cwd, 'next.config.mjs')) ||
184
- fs.existsSync(path.join(cwd, 'next.config.ts'))) {
183
+ if (existsSync(path.join(cwd, 'next.config.js')) ||
184
+ existsSync(path.join(cwd, 'next.config.mjs')) ||
185
+ existsSync(path.join(cwd, 'next.config.ts'))) {
185
186
  framework = 'nextjs';
186
- } else if (fs.existsSync(path.join(cwd, 'vite.config.ts')) ||
187
- fs.existsSync(path.join(cwd, 'vite.config.js'))) {
187
+ } else if (existsSync(path.join(cwd, 'vite.config.ts')) ||
188
+ existsSync(path.join(cwd, 'vite.config.js'))) {
188
189
  framework = 'vite';
189
- } else if (fs.existsSync(path.join(cwd, 'remix.config.js'))) {
190
+ } else if (existsSync(path.join(cwd, 'remix.config.js'))) {
190
191
  framework = 'remix';
191
- } else if (fs.existsSync(path.join(cwd, 'astro.config.mjs'))) {
192
+ } else if (existsSync(path.join(cwd, 'astro.config.mjs'))) {
192
193
  framework = 'astro';
193
194
  }
194
195
 
195
196
  // Check for UI libraries in package.json
196
197
  const pkgPath = path.join(cwd, 'package.json');
197
- if (fs.existsSync(pkgPath)) {
198
- const pkg = fs.readJsonSync(pkgPath);
198
+ if (existsSync(pkgPath)) {
199
+ const pkg = fsExtra.readJsonSync(pkgPath);
199
200
  const deps = { ...pkg.dependencies, ...pkg.devDependencies };
200
201
 
201
202
  if (deps['@shadcn/ui'] || deps['class-variance-authority']) {
@@ -211,7 +212,7 @@ export class Config {
211
212
 
212
213
  // Create .codebakers config
213
214
  const configDir = path.join(cwd, '.codebakers');
214
- fs.ensureDirSync(configDir);
215
+ fsExtra.ensureDirSync(configDir);
215
216
 
216
217
  const config = {
217
218
  name: path.basename(cwd),
@@ -221,14 +222,14 @@ export class Config {
221
222
  autoDetected: true,
222
223
  };
223
224
 
224
- fs.writeJsonSync(path.join(configDir, 'config.json'), config, { spaces: 2 });
225
+ fsExtra.writeJsonSync(path.join(configDir, 'config.json'), config, { spaces: 2 });
225
226
 
226
227
  // Add to .gitignore if exists
227
228
  const gitignorePath = path.join(cwd, '.gitignore');
228
- if (fs.existsSync(gitignorePath)) {
229
- const gitignore = fs.readFileSync(gitignorePath, 'utf-8');
229
+ if (existsSync(gitignorePath)) {
230
+ const gitignore = readFileSync(gitignorePath, 'utf-8');
230
231
  if (!gitignore.includes('.codebakers')) {
231
- fs.appendFileSync(gitignorePath, '\n# CodeBakers\n.codebakers/\n');
232
+ appendFileSync(gitignorePath, '\n# CodeBakers\n.codebakers/\n');
232
233
  }
233
234
  }
234
235
  } catch {
@@ -240,8 +241,8 @@ export class Config {
240
241
  getProjectConfig(): Record<string, unknown> | null {
241
242
  const cwd = process.cwd();
242
243
  const configPath = path.join(cwd, '.codebakers', 'config.json');
243
- if (fs.existsSync(configPath)) {
244
- return fs.readJsonSync(configPath);
244
+ if (existsSync(configPath)) {
245
+ return fsExtra.readJsonSync(configPath);
245
246
  }
246
247
  return null;
247
248
  }
@@ -1,7 +0,0 @@
1
- import {
2
- advisorsCommand
3
- } from "./chunk-FWQNLNTI.js";
4
- import "./chunk-RCC7FYEU.js";
5
- export {
6
- advisorsCommand
7
- };
@@ -1,7 +0,0 @@
1
- import {
2
- prdCommand
3
- } from "./chunk-YGVDLNXY.js";
4
- import "./chunk-RCC7FYEU.js";
5
- export {
6
- prdCommand
7
- };