@codebakers/cli 3.0.0 → 3.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.
@@ -118,13 +118,20 @@ function checkProject() {
118
118
  try {
119
119
  const files = (0, fs_1.readdirSync)(claudeDir).filter(f => f.endsWith('.md'));
120
120
  const moduleCount = files.length;
121
- if (moduleCount >= 10) {
122
- results.push({ ok: true, message: `${moduleCount} modules present` });
121
+ if (moduleCount >= 40) {
122
+ results.push({ ok: true, message: `${moduleCount} modules present (full set)` });
123
+ }
124
+ else if (moduleCount >= 10) {
125
+ results.push({
126
+ ok: true,
127
+ message: `${moduleCount} modules present (partial set)`,
128
+ details: 'Run: codebakers upgrade to get all 47 modules'
129
+ });
123
130
  }
124
131
  else if (moduleCount > 0) {
125
132
  results.push({
126
133
  ok: false,
127
- message: `Only ${moduleCount} modules found (expected 10+)`,
134
+ message: `Only ${moduleCount} modules found (expected 47)`,
128
135
  details: 'Run: codebakers upgrade to get all modules'
129
136
  });
130
137
  }
@@ -1,4 +1,8 @@
1
+ interface GoOptions {
2
+ verbose?: boolean;
3
+ }
1
4
  /**
2
5
  * Zero-friction entry point - start using CodeBakers instantly
3
6
  */
4
- export declare function go(): Promise<void>;
7
+ export declare function go(options?: GoOptions): Promise<void>;
8
+ export {};
@@ -7,12 +7,35 @@ exports.go = go;
7
7
  const chalk_1 = __importDefault(require("chalk"));
8
8
  const ora_1 = __importDefault(require("ora"));
9
9
  const child_process_1 = require("child_process");
10
+ const fs_1 = require("fs");
11
+ const path_1 = require("path");
12
+ const readline_1 = require("readline");
10
13
  const config_js_1 = require("../config.js");
11
14
  const fingerprint_js_1 = require("../lib/fingerprint.js");
15
+ function prompt(question) {
16
+ const rl = (0, readline_1.createInterface)({
17
+ input: process.stdin,
18
+ output: process.stdout,
19
+ });
20
+ return new Promise((resolve) => {
21
+ rl.question(question, (answer) => {
22
+ rl.close();
23
+ resolve(answer.trim().toLowerCase());
24
+ });
25
+ });
26
+ }
27
+ function log(message, options) {
28
+ if (options?.verbose) {
29
+ console.log(chalk_1.default.gray(` [verbose] ${message}`));
30
+ }
31
+ }
12
32
  /**
13
33
  * Zero-friction entry point - start using CodeBakers instantly
14
34
  */
15
- async function go() {
35
+ async function go(options = {}) {
36
+ log('Starting go command...', options);
37
+ log(`API URL: ${(0, config_js_1.getApiUrl)()}`, options);
38
+ log(`Working directory: ${process.cwd()}`, options);
16
39
  console.log(chalk_1.default.blue(`
17
40
  ╔═══════════════════════════════════════════════════════════╗
18
41
  ║ ║
@@ -21,12 +44,17 @@ async function go() {
21
44
  ╚═══════════════════════════════════════════════════════════╝
22
45
  `));
23
46
  // Check if user already has an API key (paid user)
47
+ log('Checking for existing API key...', options);
24
48
  const apiKey = (0, config_js_1.getApiKey)();
25
49
  if (apiKey) {
50
+ log(`Found API key: ${apiKey.substring(0, 8)}...`, options);
26
51
  console.log(chalk_1.default.green(' ✓ You\'re already logged in with an API key!\n'));
27
- console.log(chalk_1.default.gray(' Run ') + chalk_1.default.cyan('codebakers status') + chalk_1.default.gray(' to check your setup.\n'));
52
+ // Still install patterns if not already installed
53
+ await installPatternsWithApiKey(apiKey, options);
54
+ await configureMCP(options);
28
55
  return;
29
56
  }
57
+ log('No API key found, checking trial state...', options);
30
58
  // Check existing trial
31
59
  const existingTrial = (0, config_js_1.getTrialState)();
32
60
  if (existingTrial && !(0, config_js_1.isTrialExpired)()) {
@@ -36,7 +64,9 @@ async function go() {
36
64
  console.log(chalk_1.default.yellow(' ⚠️ Trial expiring soon! Extend with GitHub:\n'));
37
65
  console.log(chalk_1.default.cyan(' codebakers extend\n'));
38
66
  }
39
- await configureMCP();
67
+ // Install patterns if not already installed
68
+ await installPatterns(existingTrial.trialId, options);
69
+ await configureMCP(options);
40
70
  return;
41
71
  }
42
72
  // Check if trial expired
@@ -112,8 +142,10 @@ async function go() {
112
142
  (0, config_js_1.setTrialState)(trialState);
113
143
  spinner.succeed(`Trial started (${data.daysRemaining} days free)`);
114
144
  console.log('');
145
+ // Install patterns (CLAUDE.md and .claude/)
146
+ await installPatterns(data.trialId, options);
115
147
  // Configure MCP
116
- await configureMCP();
148
+ await configureMCP(options);
117
149
  // Show success message
118
150
  console.log(chalk_1.default.green(`
119
151
  ╔═══════════════════════════════════════════════════════════╗
@@ -143,7 +175,8 @@ async function go() {
143
175
  }
144
176
  }
145
177
  }
146
- async function configureMCP() {
178
+ async function configureMCP(options = {}) {
179
+ log('Configuring MCP integration...', options);
147
180
  const spinner = (0, ora_1.default)('Configuring Claude Code integration...').start();
148
181
  const isWindows = process.platform === 'win32';
149
182
  const mcpCmd = isWindows
@@ -166,8 +199,156 @@ async function configureMCP() {
166
199
  }
167
200
  }
168
201
  async function attemptAutoRestart() {
202
+ const cwd = process.cwd();
169
203
  console.log(chalk_1.default.yellow('\n ⚠️ RESTART REQUIRED\n'));
170
- console.log(chalk_1.default.gray(' Close this terminal and open a new one to activate CodeBakers.\n'));
171
- // Note: Auto-restart is risky and could lose user work
172
- // We show instructions instead of forcibly restarting
204
+ console.log(chalk_1.default.gray(' Claude Code needs to restart to load CodeBakers.\n'));
205
+ const answer = await prompt(chalk_1.default.cyan(' Restart Claude Code now? (Y/n): '));
206
+ if (answer === 'n' || answer === 'no') {
207
+ console.log(chalk_1.default.gray('\n No problem! Just restart Claude Code manually when ready.\n'));
208
+ return;
209
+ }
210
+ // Attempt to restart Claude Code
211
+ console.log(chalk_1.default.gray('\n Restarting Claude Code...\n'));
212
+ try {
213
+ const isWindows = process.platform === 'win32';
214
+ if (isWindows) {
215
+ // On Windows, spawn a new Claude process detached and exit
216
+ (0, child_process_1.spawn)('cmd', ['/c', 'start', 'claude'], {
217
+ cwd,
218
+ detached: true,
219
+ stdio: 'ignore',
220
+ shell: true,
221
+ }).unref();
222
+ }
223
+ else {
224
+ // On Mac/Linux, spawn claude in new terminal
225
+ (0, child_process_1.spawn)('claude', [], {
226
+ cwd,
227
+ detached: true,
228
+ stdio: 'ignore',
229
+ shell: true,
230
+ }).unref();
231
+ }
232
+ console.log(chalk_1.default.green(' ✓ Claude Code is restarting...\n'));
233
+ console.log(chalk_1.default.gray(' This terminal will close. Claude Code will open in a new window.\n'));
234
+ // Give the spawn a moment to start
235
+ await new Promise(resolve => setTimeout(resolve, 1000));
236
+ // Exit this process
237
+ process.exit(0);
238
+ }
239
+ catch (error) {
240
+ console.log(chalk_1.default.yellow(' Could not auto-restart. Please restart Claude Code manually.\n'));
241
+ }
242
+ }
243
+ /**
244
+ * Install pattern files for API key users (paid users)
245
+ */
246
+ async function installPatternsWithApiKey(apiKey, options = {}) {
247
+ log('Installing patterns with API key...', options);
248
+ const spinner = (0, ora_1.default)('Installing CodeBakers patterns...').start();
249
+ const cwd = process.cwd();
250
+ const apiUrl = (0, config_js_1.getApiUrl)();
251
+ log(`Fetching from: ${apiUrl}/api/content`, options);
252
+ try {
253
+ const response = await fetch(`${apiUrl}/api/content`, {
254
+ method: 'GET',
255
+ headers: {
256
+ 'Authorization': `Bearer ${apiKey}`,
257
+ },
258
+ });
259
+ if (!response.ok) {
260
+ log(`Response not OK: ${response.status} ${response.statusText}`, options);
261
+ spinner.warn('Could not download patterns');
262
+ return;
263
+ }
264
+ log('Response OK, parsing JSON...', options);
265
+ const content = await response.json();
266
+ log(`Received version: ${content.version}, modules: ${Object.keys(content.modules || {}).length}`, options);
267
+ await writePatternFiles(cwd, content, spinner, options);
268
+ }
269
+ catch (error) {
270
+ log(`Error: ${error instanceof Error ? error.message : String(error)}`, options);
271
+ spinner.warn('Could not install patterns');
272
+ console.log(chalk_1.default.gray(' Check your internet connection.\n'));
273
+ }
274
+ }
275
+ /**
276
+ * Install pattern files (CLAUDE.md and .claude/) for trial users
277
+ */
278
+ async function installPatterns(trialId, options = {}) {
279
+ log(`Installing patterns with trial ID: ${trialId.substring(0, 8)}...`, options);
280
+ const spinner = (0, ora_1.default)('Installing CodeBakers patterns...').start();
281
+ const cwd = process.cwd();
282
+ const apiUrl = (0, config_js_1.getApiUrl)();
283
+ try {
284
+ // Fetch patterns using trial ID
285
+ log(`Fetching from: ${apiUrl}/api/content`, options);
286
+ const response = await fetch(`${apiUrl}/api/content`, {
287
+ method: 'GET',
288
+ headers: {
289
+ 'X-Trial-ID': trialId,
290
+ },
291
+ });
292
+ if (!response.ok) {
293
+ log(`Primary endpoint failed: ${response.status}, trying trial endpoint...`, options);
294
+ // Try without auth - some patterns may be available for trial
295
+ const publicResponse = await fetch(`${apiUrl}/api/content/trial`, {
296
+ method: 'GET',
297
+ headers: {
298
+ 'X-Trial-ID': trialId,
299
+ },
300
+ });
301
+ if (!publicResponse.ok) {
302
+ log(`Trial endpoint also failed: ${publicResponse.status}`, options);
303
+ spinner.warn('Could not download patterns (will use MCP tools)');
304
+ return;
305
+ }
306
+ const content = await publicResponse.json();
307
+ log(`Received version: ${content.version}, modules: ${Object.keys(content.modules || {}).length}`, options);
308
+ await writePatternFiles(cwd, content, spinner, options);
309
+ return;
310
+ }
311
+ const content = await response.json();
312
+ log(`Received version: ${content.version}, modules: ${Object.keys(content.modules || {}).length}`, options);
313
+ await writePatternFiles(cwd, content, spinner, options);
314
+ }
315
+ catch (error) {
316
+ log(`Error: ${error instanceof Error ? error.message : String(error)}`, options);
317
+ spinner.warn('Could not install patterns (will use MCP tools)');
318
+ console.log(chalk_1.default.gray(' Patterns will be available via MCP tools.\n'));
319
+ }
320
+ }
321
+ async function writePatternFiles(cwd, content, spinner, options = {}) {
322
+ log(`Writing pattern files to ${cwd}...`, options);
323
+ // Check if patterns already exist
324
+ const claudeMdPath = (0, path_1.join)(cwd, 'CLAUDE.md');
325
+ if ((0, fs_1.existsSync)(claudeMdPath)) {
326
+ spinner.succeed('CodeBakers patterns already installed');
327
+ return;
328
+ }
329
+ // Write CLAUDE.md (router file)
330
+ if (content.router) {
331
+ (0, fs_1.writeFileSync)(claudeMdPath, content.router);
332
+ }
333
+ // Write pattern modules to .claude/
334
+ if (content.modules && Object.keys(content.modules).length > 0) {
335
+ const modulesDir = (0, path_1.join)(cwd, '.claude');
336
+ if (!(0, fs_1.existsSync)(modulesDir)) {
337
+ (0, fs_1.mkdirSync)(modulesDir, { recursive: true });
338
+ }
339
+ for (const [name, data] of Object.entries(content.modules)) {
340
+ (0, fs_1.writeFileSync)((0, path_1.join)(modulesDir, name), data);
341
+ }
342
+ }
343
+ // Update .gitignore to exclude encoded patterns
344
+ const gitignorePath = (0, path_1.join)(cwd, '.gitignore');
345
+ if ((0, fs_1.existsSync)(gitignorePath)) {
346
+ const { readFileSync } = await import('fs');
347
+ const gitignore = readFileSync(gitignorePath, 'utf-8');
348
+ if (!gitignore.includes('.claude/')) {
349
+ (0, fs_1.writeFileSync)(gitignorePath, gitignore + '\n# CodeBakers patterns\n.claude/\n');
350
+ }
351
+ }
352
+ spinner.succeed(`CodeBakers patterns installed (v${content.version})`);
353
+ console.log(chalk_1.default.gray(` ${Object.keys(content.modules || {}).length} pattern modules ready\n`));
173
354
  }
package/dist/index.js CHANGED
@@ -67,13 +67,14 @@ const program = new commander_1.Command();
67
67
  program
68
68
  .name('codebakers')
69
69
  .description('CodeBakers CLI - Production patterns for AI-assisted development')
70
- .version('2.9.0');
70
+ .version('3.1.0');
71
71
  // Zero-friction trial entry (no signup required)
72
72
  program
73
73
  .command('go')
74
74
  .alias('start')
75
75
  .description('Start using CodeBakers instantly (no signup required)')
76
- .action(go_js_1.go);
76
+ .option('-v, --verbose', 'Show detailed debug output for troubleshooting')
77
+ .action((options) => (0, go_js_1.go)({ verbose: options.verbose }));
77
78
  program
78
79
  .command('extend')
79
80
  .description('Extend your free trial with GitHub')