@codebakers/cli 3.0.0 → 3.0.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.
@@ -7,8 +7,23 @@ 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
+ }
12
27
  /**
13
28
  * Zero-friction entry point - start using CodeBakers instantly
14
29
  */
@@ -24,7 +39,9 @@ async function go() {
24
39
  const apiKey = (0, config_js_1.getApiKey)();
25
40
  if (apiKey) {
26
41
  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'));
42
+ // Still install patterns if not already installed
43
+ await installPatternsWithApiKey(apiKey);
44
+ await configureMCP();
28
45
  return;
29
46
  }
30
47
  // Check existing trial
@@ -36,6 +53,8 @@ async function go() {
36
53
  console.log(chalk_1.default.yellow(' ⚠️ Trial expiring soon! Extend with GitHub:\n'));
37
54
  console.log(chalk_1.default.cyan(' codebakers extend\n'));
38
55
  }
56
+ // Install patterns if not already installed
57
+ await installPatterns(existingTrial.trialId);
39
58
  await configureMCP();
40
59
  return;
41
60
  }
@@ -112,6 +131,8 @@ async function go() {
112
131
  (0, config_js_1.setTrialState)(trialState);
113
132
  spinner.succeed(`Trial started (${data.daysRemaining} days free)`);
114
133
  console.log('');
134
+ // Install patterns (CLAUDE.md and .claude/)
135
+ await installPatterns(data.trialId);
115
136
  // Configure MCP
116
137
  await configureMCP();
117
138
  // Show success message
@@ -166,8 +187,142 @@ async function configureMCP() {
166
187
  }
167
188
  }
168
189
  async function attemptAutoRestart() {
190
+ const cwd = process.cwd();
169
191
  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
192
+ console.log(chalk_1.default.gray(' Claude Code needs to restart to load CodeBakers.\n'));
193
+ const answer = await prompt(chalk_1.default.cyan(' Restart Claude Code now? (Y/n): '));
194
+ if (answer === 'n' || answer === 'no') {
195
+ console.log(chalk_1.default.gray('\n No problem! Just restart Claude Code manually when ready.\n'));
196
+ return;
197
+ }
198
+ // Attempt to restart Claude Code
199
+ console.log(chalk_1.default.gray('\n Restarting Claude Code...\n'));
200
+ try {
201
+ const isWindows = process.platform === 'win32';
202
+ if (isWindows) {
203
+ // On Windows, spawn a new Claude process detached and exit
204
+ (0, child_process_1.spawn)('cmd', ['/c', 'start', 'claude'], {
205
+ cwd,
206
+ detached: true,
207
+ stdio: 'ignore',
208
+ shell: true,
209
+ }).unref();
210
+ }
211
+ else {
212
+ // On Mac/Linux, spawn claude in new terminal
213
+ (0, child_process_1.spawn)('claude', [], {
214
+ cwd,
215
+ detached: true,
216
+ stdio: 'ignore',
217
+ shell: true,
218
+ }).unref();
219
+ }
220
+ console.log(chalk_1.default.green(' ✓ Claude Code is restarting...\n'));
221
+ console.log(chalk_1.default.gray(' This terminal will close. Claude Code will open in a new window.\n'));
222
+ // Give the spawn a moment to start
223
+ await new Promise(resolve => setTimeout(resolve, 1000));
224
+ // Exit this process
225
+ process.exit(0);
226
+ }
227
+ catch (error) {
228
+ console.log(chalk_1.default.yellow(' Could not auto-restart. Please restart Claude Code manually.\n'));
229
+ }
230
+ }
231
+ /**
232
+ * Install pattern files for API key users (paid users)
233
+ */
234
+ async function installPatternsWithApiKey(apiKey) {
235
+ const spinner = (0, ora_1.default)('Installing CodeBakers patterns...').start();
236
+ const cwd = process.cwd();
237
+ const apiUrl = (0, config_js_1.getApiUrl)();
238
+ try {
239
+ const response = await fetch(`${apiUrl}/api/content`, {
240
+ method: 'GET',
241
+ headers: {
242
+ 'Authorization': `Bearer ${apiKey}`,
243
+ },
244
+ });
245
+ if (!response.ok) {
246
+ spinner.warn('Could not download patterns');
247
+ return;
248
+ }
249
+ const content = await response.json();
250
+ await writePatternFiles(cwd, content, spinner);
251
+ }
252
+ catch (error) {
253
+ spinner.warn('Could not install patterns');
254
+ console.log(chalk_1.default.gray(' Check your internet connection.\n'));
255
+ }
256
+ }
257
+ /**
258
+ * Install pattern files (CLAUDE.md and .claude/) for trial users
259
+ */
260
+ async function installPatterns(trialId) {
261
+ const spinner = (0, ora_1.default)('Installing CodeBakers patterns...').start();
262
+ const cwd = process.cwd();
263
+ const apiUrl = (0, config_js_1.getApiUrl)();
264
+ try {
265
+ // Fetch patterns using trial ID
266
+ const response = await fetch(`${apiUrl}/api/content`, {
267
+ method: 'GET',
268
+ headers: {
269
+ 'X-Trial-ID': trialId,
270
+ },
271
+ });
272
+ if (!response.ok) {
273
+ // Try without auth - some patterns may be available for trial
274
+ const publicResponse = await fetch(`${apiUrl}/api/content/trial`, {
275
+ method: 'GET',
276
+ headers: {
277
+ 'X-Trial-ID': trialId,
278
+ },
279
+ });
280
+ if (!publicResponse.ok) {
281
+ spinner.warn('Could not download patterns (will use MCP tools)');
282
+ return;
283
+ }
284
+ const content = await publicResponse.json();
285
+ await writePatternFiles(cwd, content, spinner);
286
+ return;
287
+ }
288
+ const content = await response.json();
289
+ await writePatternFiles(cwd, content, spinner);
290
+ }
291
+ catch (error) {
292
+ spinner.warn('Could not install patterns (will use MCP tools)');
293
+ console.log(chalk_1.default.gray(' Patterns will be available via MCP tools.\n'));
294
+ }
295
+ }
296
+ async function writePatternFiles(cwd, content, spinner) {
297
+ // Check if patterns already exist
298
+ const claudeMdPath = (0, path_1.join)(cwd, 'CLAUDE.md');
299
+ if ((0, fs_1.existsSync)(claudeMdPath)) {
300
+ spinner.succeed('CodeBakers patterns already installed');
301
+ return;
302
+ }
303
+ // Write CLAUDE.md (router file)
304
+ if (content.router) {
305
+ (0, fs_1.writeFileSync)(claudeMdPath, content.router);
306
+ }
307
+ // Write pattern modules to .claude/
308
+ if (content.modules && Object.keys(content.modules).length > 0) {
309
+ const modulesDir = (0, path_1.join)(cwd, '.claude');
310
+ if (!(0, fs_1.existsSync)(modulesDir)) {
311
+ (0, fs_1.mkdirSync)(modulesDir, { recursive: true });
312
+ }
313
+ for (const [name, data] of Object.entries(content.modules)) {
314
+ (0, fs_1.writeFileSync)((0, path_1.join)(modulesDir, name), data);
315
+ }
316
+ }
317
+ // Update .gitignore to exclude encoded patterns
318
+ const gitignorePath = (0, path_1.join)(cwd, '.gitignore');
319
+ if ((0, fs_1.existsSync)(gitignorePath)) {
320
+ const { readFileSync } = await import('fs');
321
+ const gitignore = readFileSync(gitignorePath, 'utf-8');
322
+ if (!gitignore.includes('.claude/')) {
323
+ (0, fs_1.writeFileSync)(gitignorePath, gitignore + '\n# CodeBakers patterns\n.claude/\n');
324
+ }
325
+ }
326
+ spinner.succeed(`CodeBakers patterns installed (v${content.version})`);
327
+ console.log(chalk_1.default.gray(` ${Object.keys(content.modules || {}).length} pattern modules ready\n`));
173
328
  }