@codebakers/cli 1.0.11 → 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 +58 -112
  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
 
@@ -91,36 +91,15 @@ async function fetchPatterns(patterns) {
91
91
  body: JSON.stringify({ patterns })
92
92
  });
93
93
  }
94
- async function fetchAllPatterns() {
95
- const list = await listPatterns();
96
- const allPatterns = {};
97
- const patternNames = list.patterns.map((p) => p.name);
98
- for (let i = 0; i < patternNames.length; i += 5) {
99
- const batch = patternNames.slice(i, i + 5);
100
- const result = await fetchPatterns(batch);
101
- Object.assign(allPatterns, result.patterns);
102
- }
103
- const routerResult = await fetchPatterns(["router"]);
104
- Object.assign(allPatterns, routerResult.patterns);
105
- return allPatterns;
106
- }
107
94
 
108
95
  // src/commands/setup.ts
109
96
  var IDE_CONFIGS = {
110
97
  cursor: {
111
- file: ".cursorrules",
98
+ file: ".cursor/mcp.json",
112
99
  description: "Cursor AI IDE"
113
100
  },
114
- windsurf: {
115
- file: ".windsurfrules",
116
- description: "Windsurf (Codeium) IDE"
117
- },
118
- aider: {
119
- file: ".aider.conf.yml",
120
- description: "Aider CLI"
121
- },
122
101
  "claude-code": {
123
- file: "CLAUDE.md",
102
+ file: ".claude/mcp.json",
124
103
  description: "Claude Code"
125
104
  }
126
105
  };
@@ -192,8 +171,6 @@ Validation failed: ${validation.error || "Unknown error"}`));
192
171
  choices: [
193
172
  { name: "Cursor", value: "cursor" },
194
173
  { name: "Claude Code (VS Code extension or CLI)", value: "claude-code" },
195
- { name: "Windsurf (Codeium)", value: "windsurf" },
196
- { name: "Aider", value: "aider" },
197
174
  { name: "Skip for now", value: null }
198
175
  ]
199
176
  }
@@ -206,9 +183,13 @@ Validation failed: ${validation.error || "Unknown error"}`));
206
183
  const firstName = userName?.split(" ")[0];
207
184
  const greeting = firstName ? `${firstName}, you're` : "You're";
208
185
  console.log(chalk.bold.green("\n\u{1F389} Setup complete!\n"));
209
- if (ide === "claude-code") {
186
+ if (ide) {
210
187
  console.log(chalk.green(`\u2713 ${greeting} ready to build!
211
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"));
212
193
  console.log(chalk.bold("You say:"));
213
194
  console.log(chalk.cyan(' "Add a contact form"\n'));
214
195
  console.log(chalk.bold("CodeBakers generates:"));
@@ -223,110 +204,75 @@ Validation failed: ${validation.error || "Unknown error"}`));
223
204
  console.log(chalk.dim(" \u2502 ") + chalk.green("\u2713") + chalk.dim(" Accessible, responsive design \u2502"));
224
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"));
225
206
  console.log(chalk.dim("Start building: just describe what you need.\n"));
226
- } else if (ide) {
227
- console.log(chalk.dim(`Pattern file created. Restart ${IDE_CONFIGS[ide].description} to load it.
228
- `));
229
207
  }
230
208
  });
231
209
  }
232
210
  async function configureIDE(ide, force = false) {
233
211
  const config = IDE_CONFIGS[ide];
234
- const targetPath = join(process.cwd(), config.file);
235
- const spinner = ora(`Fetching CodeBakers patterns...`).start();
212
+ const spinner = ora(`Configuring ${config.description}...`).start();
236
213
  try {
237
- if (ide === "claude-code") {
238
- const claudeDir = join(process.cwd(), ".claude");
239
- if (!existsSync(claudeDir)) {
240
- await mkdir(claudeDir, { recursive: true });
241
- }
242
- }
243
- 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) {
244
233
  spinner.stop();
245
- const { overwrite } = await inquirer.prompt([
234
+ const { merge } = await inquirer.prompt([
246
235
  {
247
236
  type: "confirm",
248
- name: "overwrite",
249
- message: `${config.file} already exists. Overwrite?`,
250
- default: false
237
+ name: "merge",
238
+ message: `${config.file} exists. Add CodeBakers to existing config?`,
239
+ default: true
251
240
  }
252
241
  ]);
253
- if (!overwrite) {
254
- console.log(chalk.yellow("\nSetup cancelled. Use --force to overwrite."));
242
+ if (!merge) {
243
+ console.log(chalk.yellow("\nSetup cancelled."));
255
244
  return;
256
245
  }
257
246
  spinner.start();
258
247
  }
259
- const patterns = await fetchAllPatterns();
260
- const patternList = await listPatterns();
261
- spinner.text = "Generating configuration...";
262
- let content;
263
- if (ide === "claude-code") {
264
- content = patterns["router"] || "";
265
- for (const [name, patternContent] of Object.entries(patterns)) {
266
- if (name !== "router") {
267
- const patternPath = join(process.cwd(), ".claude", `${name}.md`);
268
- await writeFile(patternPath, patternContent, "utf-8");
269
- }
270
- }
271
- } else if (ide === "aider") {
272
- content = generateAiderConfig(patterns);
273
- } else {
274
- content = generateRulesFile(patterns, patternList.version);
275
- }
276
- await writeFile(targetPath, content, "utf-8");
277
- spinner.succeed(`Created ${config.file}`);
278
- if (ide === "claude-code") {
279
- 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 {
280
252
  }
281
- console.log(chalk.green(`
282
- \u2713 ${IDE_CONFIGS[ide].description} configured`));
283
- } catch (error) {
284
- spinner.fail("Failed to configure IDE");
285
- const message = error instanceof Error ? error.message : "Unknown error";
286
- console.log(chalk.red(`
287
- Error: ${message}`));
288
- process.exit(1);
289
253
  }
290
- }
291
- function generateRulesFile(patterns, version) {
292
- const router = patterns["router"] || "";
293
- let content = `# CodeBakers Patterns v${version}
294
- # Generated by @codebakers/cli
295
- # https://codebakers.ai
296
-
297
- ${router}
298
-
299
- ---
300
-
301
- # PATTERN MODULES (Auto-loaded based on context)
302
-
303
- `;
304
- for (const [name, patternContent] of Object.entries(patterns)) {
305
- if (name !== "router" && patternContent) {
306
- content += `
307
- ## Module: ${name}
308
-
309
- ${patternContent}
310
-
311
- ---
312
- `;
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
+ }
313
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"));
314
275
  }
315
- return content;
316
- }
317
- function generateAiderConfig(patterns) {
318
- const router = patterns["router"] || "";
319
- return `# CodeBakers Aider Configuration
320
- # Generated by @codebakers/cli
321
- # https://codebakers.ai
322
-
323
- read:
324
- - .codebakers-patterns.md
325
-
326
- # System message with CodeBakers patterns
327
- message: |
328
- ${router.split("\n").map((line) => " " + line).join("\n")}
329
- `;
330
276
  }
331
277
 
332
278
  // src/commands/serve.ts
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@codebakers/cli",
3
- "version": "1.0.11",
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": {