@codebakers/cli 1.0.10 → 1.1.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 (2) hide show
  1. package/dist/index.js +70 -114
  2. package/package.json +1 -1
package/dist/index.js CHANGED
@@ -14,7 +14,7 @@ import chalk2 from "chalk";
14
14
  import inquirer from "inquirer";
15
15
  import chalk from "chalk";
16
16
  import ora from "ora";
17
- import { writeFile, mkdir } from "fs/promises";
17
+ import { writeFile, mkdir, readFile } from "fs/promises";
18
18
  import { existsSync } from "fs";
19
19
  import { join } from "path";
20
20
 
@@ -63,7 +63,13 @@ async function validateApiKey(apiKey) {
63
63
  }
64
64
  });
65
65
  if (response.ok) {
66
- return { valid: true };
66
+ try {
67
+ const data = await response.json();
68
+ const user = data.user;
69
+ return { valid: true, userName: user?.name || void 0 };
70
+ } catch {
71
+ return { valid: true };
72
+ }
67
73
  }
68
74
  try {
69
75
  const data = await response.json();
@@ -85,36 +91,15 @@ async function fetchPatterns(patterns) {
85
91
  body: JSON.stringify({ patterns })
86
92
  });
87
93
  }
88
- async function fetchAllPatterns() {
89
- const list = await listPatterns();
90
- const allPatterns = {};
91
- const patternNames = list.patterns.map((p) => p.name);
92
- for (let i = 0; i < patternNames.length; i += 5) {
93
- const batch = patternNames.slice(i, i + 5);
94
- const result = await fetchPatterns(batch);
95
- Object.assign(allPatterns, result.patterns);
96
- }
97
- const routerResult = await fetchPatterns(["router"]);
98
- Object.assign(allPatterns, routerResult.patterns);
99
- return allPatterns;
100
- }
101
94
 
102
95
  // src/commands/setup.ts
103
96
  var IDE_CONFIGS = {
104
97
  cursor: {
105
- file: ".cursorrules",
98
+ file: ".cursor/mcp.json",
106
99
  description: "Cursor AI IDE"
107
100
  },
108
- windsurf: {
109
- file: ".windsurfrules",
110
- description: "Windsurf (Codeium) IDE"
111
- },
112
- aider: {
113
- file: ".aider.conf.yml",
114
- description: "Aider CLI"
115
- },
116
101
  "claude-code": {
117
- file: "CLAUDE.md",
102
+ file: ".claude/mcp.json",
118
103
  description: "Claude Code"
119
104
  }
120
105
  };
@@ -172,6 +157,7 @@ Validation failed: ${validation.error || "Unknown error"}`));
172
157
  }
173
158
  process.exit(1);
174
159
  }
160
+ const userName = validation.userName;
175
161
  spinner.succeed("API key validated");
176
162
  setApiKey(apiKey);
177
163
  console.log(chalk.green("\n\u2713 API key saved\n"));
@@ -185,8 +171,6 @@ Validation failed: ${validation.error || "Unknown error"}`));
185
171
  choices: [
186
172
  { name: "Cursor", value: "cursor" },
187
173
  { name: "Claude Code (VS Code extension or CLI)", value: "claude-code" },
188
- { name: "Windsurf (Codeium)", value: "windsurf" },
189
- { name: "Aider", value: "aider" },
190
174
  { name: "Skip for now", value: null }
191
175
  ]
192
176
  }
@@ -196,9 +180,16 @@ Validation failed: ${validation.error || "Unknown error"}`));
196
180
  if (ide) {
197
181
  await configureIDE(ide, options.force);
198
182
  }
183
+ const firstName = userName?.split(" ")[0];
184
+ const greeting = firstName ? `${firstName}, you're` : "You're";
199
185
  console.log(chalk.bold.green("\n\u{1F389} Setup complete!\n"));
200
- if (ide === "claude-code") {
201
- console.log(chalk.green("\u2713 CodeBakers is ready!\n"));
186
+ if (ide) {
187
+ console.log(chalk.green(`\u2713 ${greeting} ready to build!
188
+ `));
189
+ console.log(chalk.bold("How it works:"));
190
+ console.log(chalk.dim(" 1. Patterns are fetched securely from CodeBakers API"));
191
+ console.log(chalk.dim(" 2. No files stored locally - your subscription is protected"));
192
+ console.log(chalk.dim(" 3. Always get the latest patterns automatically\n"));
202
193
  console.log(chalk.bold("You say:"));
203
194
  console.log(chalk.cyan(' "Add a contact form"\n'));
204
195
  console.log(chalk.bold("CodeBakers generates:"));
@@ -213,110 +204,75 @@ Validation failed: ${validation.error || "Unknown error"}`));
213
204
  console.log(chalk.dim(" \u2502 ") + chalk.green("\u2713") + chalk.dim(" Accessible, responsive design \u2502"));
214
205
  console.log(chalk.dim(" \u2514\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2518\n"));
215
206
  console.log(chalk.dim("Start building: just describe what you need.\n"));
216
- } else if (ide) {
217
- console.log(chalk.dim(`Pattern file created. Restart ${IDE_CONFIGS[ide].description} to load it.
218
- `));
219
207
  }
220
208
  });
221
209
  }
222
210
  async function configureIDE(ide, force = false) {
223
211
  const config = IDE_CONFIGS[ide];
224
- const targetPath = join(process.cwd(), config.file);
225
- const spinner = ora(`Fetching CodeBakers patterns...`).start();
212
+ const spinner = ora(`Configuring ${config.description}...`).start();
226
213
  try {
227
- if (ide === "claude-code") {
228
- const claudeDir = join(process.cwd(), ".claude");
229
- if (!existsSync(claudeDir)) {
230
- await mkdir(claudeDir, { recursive: true });
231
- }
232
- }
233
- if (existsSync(targetPath) && !force) {
214
+ await configureMCP(ide, force, spinner);
215
+ } catch (error) {
216
+ spinner.fail("Failed to configure IDE");
217
+ const message = error instanceof Error ? error.message : "Unknown error";
218
+ console.log(chalk.red(`
219
+ Error: ${message}`));
220
+ process.exit(1);
221
+ }
222
+ }
223
+ async function configureMCP(ide, force, spinner) {
224
+ const config = IDE_CONFIGS[ide];
225
+ const targetDir = join(process.cwd(), ide === "cursor" ? ".cursor" : ".claude");
226
+ const targetPath = join(targetDir, "mcp.json");
227
+ if (!existsSync(targetDir)) {
228
+ await mkdir(targetDir, { recursive: true });
229
+ }
230
+ let existingConfig = {};
231
+ if (existsSync(targetPath)) {
232
+ if (!force) {
234
233
  spinner.stop();
235
- const { overwrite } = await inquirer.prompt([
234
+ const { merge } = await inquirer.prompt([
236
235
  {
237
236
  type: "confirm",
238
- name: "overwrite",
239
- message: `${config.file} already exists. Overwrite?`,
240
- default: false
237
+ name: "merge",
238
+ message: `${config.file} exists. Add CodeBakers to existing config?`,
239
+ default: true
241
240
  }
242
241
  ]);
243
- if (!overwrite) {
244
- console.log(chalk.yellow("\nSetup cancelled. Use --force to overwrite."));
242
+ if (!merge) {
243
+ console.log(chalk.yellow("\nSetup cancelled."));
245
244
  return;
246
245
  }
247
246
  spinner.start();
248
247
  }
249
- const patterns = await fetchAllPatterns();
250
- const patternList = await listPatterns();
251
- spinner.text = "Generating configuration...";
252
- let content;
253
- if (ide === "claude-code") {
254
- content = patterns["router"] || "";
255
- for (const [name, patternContent] of Object.entries(patterns)) {
256
- if (name !== "router") {
257
- const patternPath = join(process.cwd(), ".claude", `${name}.md`);
258
- await writeFile(patternPath, patternContent, "utf-8");
259
- }
260
- }
261
- } else if (ide === "aider") {
262
- content = generateAiderConfig(patterns);
263
- } else {
264
- content = generateRulesFile(patterns, patternList.version);
265
- }
266
- await writeFile(targetPath, content, "utf-8");
267
- spinner.succeed(`Created ${config.file}`);
268
- if (ide === "claude-code") {
269
- console.log(chalk.dim(` + Created .claude/ folder with ${Object.keys(patterns).length - 1} pattern files`));
248
+ try {
249
+ const existing = await readFile(targetPath, "utf-8");
250
+ existingConfig = JSON.parse(existing);
251
+ } catch {
270
252
  }
271
- console.log(chalk.green(`
272
- \u2713 ${IDE_CONFIGS[ide].description} configured`));
273
- } catch (error) {
274
- spinner.fail("Failed to configure IDE");
275
- const message = error instanceof Error ? error.message : "Unknown error";
276
- console.log(chalk.red(`
277
- Error: ${message}`));
278
- process.exit(1);
279
253
  }
280
- }
281
- function generateRulesFile(patterns, version) {
282
- const router = patterns["router"] || "";
283
- let content = `# CodeBakers Patterns v${version}
284
- # Generated by @codebakers/cli
285
- # https://codebakers.ai
286
-
287
- ${router}
288
-
289
- ---
290
-
291
- # PATTERN MODULES (Auto-loaded based on context)
292
-
293
- `;
294
- for (const [name, patternContent] of Object.entries(patterns)) {
295
- if (name !== "router" && patternContent) {
296
- content += `
297
- ## Module: ${name}
298
-
299
- ${patternContent}
300
-
301
- ---
302
- `;
254
+ spinner.text = "Configuring MCP server...";
255
+ const mcpConfig = {
256
+ ...existingConfig,
257
+ mcpServers: {
258
+ ...existingConfig.mcpServers || {},
259
+ codebakers: {
260
+ command: "npx",
261
+ args: ["@codebakers/cli", "serve"]
262
+ }
303
263
  }
264
+ };
265
+ await writeFile(targetPath, JSON.stringify(mcpConfig, null, 2), "utf-8");
266
+ spinner.succeed(`Configured MCP server in ${config.file}`);
267
+ console.log(chalk.green(`
268
+ \u2713 ${config.description} configured with MCP`));
269
+ console.log(chalk.dim("\nPatterns are fetched securely from the API on-demand."));
270
+ console.log(chalk.dim("No pattern files are stored locally.\n"));
271
+ if (ide === "cursor") {
272
+ console.log(chalk.yellow("Restart Cursor to activate the MCP server.\n"));
273
+ } else {
274
+ console.log(chalk.yellow("Restart your IDE to activate the MCP server.\n"));
304
275
  }
305
- return content;
306
- }
307
- function generateAiderConfig(patterns) {
308
- const router = patterns["router"] || "";
309
- return `# CodeBakers Aider Configuration
310
- # Generated by @codebakers/cli
311
- # https://codebakers.ai
312
-
313
- read:
314
- - .codebakers-patterns.md
315
-
316
- # System message with CodeBakers patterns
317
- message: |
318
- ${router.split("\n").map((line) => " " + line).join("\n")}
319
- `;
320
276
  }
321
277
 
322
278
  // src/commands/serve.ts
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@codebakers/cli",
3
- "version": "1.0.10",
3
+ "version": "1.1.0",
4
4
  "description": "CodeBakers CLI - AI prompt patterns for production-ready code",
5
5
  "main": "dist/index.js",
6
6
  "bin": {