@codebakers/cli 3.4.0 → 3.4.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.
- package/dist/commands/go.d.ts +1 -0
- package/dist/commands/go.js +75 -33
- package/package.json +1 -1
- package/src/commands/go.ts +91 -36
package/dist/commands/go.d.ts
CHANGED
package/dist/commands/go.js
CHANGED
|
@@ -11,6 +11,7 @@ const fs_1 = require("fs");
|
|
|
11
11
|
const path_1 = require("path");
|
|
12
12
|
const readline_1 = require("readline");
|
|
13
13
|
const config_js_1 = require("../config.js");
|
|
14
|
+
const api_js_1 = require("../lib/api.js");
|
|
14
15
|
const fingerprint_js_1 = require("../lib/fingerprint.js");
|
|
15
16
|
function prompt(question) {
|
|
16
17
|
const rl = (0, readline_1.createInterface)({
|
|
@@ -68,6 +69,7 @@ function log(message, options) {
|
|
|
68
69
|
}
|
|
69
70
|
/**
|
|
70
71
|
* Zero-friction entry point - start using CodeBakers instantly
|
|
72
|
+
* Single command for both trial and paid users
|
|
71
73
|
*/
|
|
72
74
|
async function go(options = {}) {
|
|
73
75
|
log('Starting go command...', options);
|
|
@@ -76,19 +78,20 @@ async function go(options = {}) {
|
|
|
76
78
|
console.log(chalk_1.default.blue(`
|
|
77
79
|
╔═══════════════════════════════════════════════════════════╗
|
|
78
80
|
║ ║
|
|
79
|
-
║ ${chalk_1.default.bold.white('CodeBakers -
|
|
81
|
+
║ ${chalk_1.default.bold.white('CodeBakers - Get Started')} ║
|
|
80
82
|
║ ║
|
|
81
83
|
╚═══════════════════════════════════════════════════════════╝
|
|
82
84
|
`));
|
|
83
85
|
// Check if user already has an API key (paid user)
|
|
84
86
|
log('Checking for existing API key...', options);
|
|
85
|
-
const
|
|
86
|
-
if (
|
|
87
|
-
log(`Found API key: ${
|
|
88
|
-
console.log(chalk_1.default.green(' ✓ You\'re already logged in
|
|
89
|
-
//
|
|
90
|
-
await installPatternsWithApiKey(
|
|
87
|
+
const existingApiKey = (0, config_js_1.getApiKey)();
|
|
88
|
+
if (existingApiKey) {
|
|
89
|
+
log(`Found API key: ${existingApiKey.substring(0, 8)}...`, options);
|
|
90
|
+
console.log(chalk_1.default.green(' ✓ You\'re already logged in!\n'));
|
|
91
|
+
// Install patterns if not already installed
|
|
92
|
+
await installPatternsWithApiKey(existingApiKey, options);
|
|
91
93
|
await configureMCP(options);
|
|
94
|
+
await showSuccessAndRestart();
|
|
92
95
|
return;
|
|
93
96
|
}
|
|
94
97
|
log('No API key found, checking trial state...', options);
|
|
@@ -104,21 +107,33 @@ async function go(options = {}) {
|
|
|
104
107
|
// Install patterns if not already installed
|
|
105
108
|
await installPatterns(existingTrial.trialId, options);
|
|
106
109
|
await configureMCP(options);
|
|
110
|
+
await showSuccessAndRestart();
|
|
107
111
|
return;
|
|
108
112
|
}
|
|
109
113
|
// Check if trial expired
|
|
110
114
|
if (existingTrial && (0, config_js_1.isTrialExpired)()) {
|
|
111
115
|
console.log(chalk_1.default.yellow(' ⚠️ Your trial has expired.\n'));
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
116
|
+
// Offer to login with API key or extend
|
|
117
|
+
console.log(chalk_1.default.white(' Options:\n'));
|
|
118
|
+
console.log(chalk_1.default.cyan(' [1] Login with API key') + chalk_1.default.gray(' (I have an account)'));
|
|
119
|
+
console.log(chalk_1.default.cyan(' [2] Extend trial') + chalk_1.default.gray(' (7 more days with GitHub)\n'));
|
|
120
|
+
const choice = await prompt(chalk_1.default.gray(' Enter 1 or 2: '));
|
|
121
|
+
if (choice === '1') {
|
|
122
|
+
await handleApiKeyLogin(options);
|
|
123
|
+
return;
|
|
117
124
|
}
|
|
118
125
|
else {
|
|
119
|
-
console.log(chalk_1.default.
|
|
120
|
-
|
|
126
|
+
console.log(chalk_1.default.cyan('\n Run: codebakers extend\n'));
|
|
127
|
+
return;
|
|
121
128
|
}
|
|
129
|
+
}
|
|
130
|
+
// New user - ask how they want to proceed
|
|
131
|
+
console.log(chalk_1.default.white(' How would you like to get started?\n'));
|
|
132
|
+
console.log(chalk_1.default.cyan(' [1] Start free 7-day trial') + chalk_1.default.gray(' (no signup required)'));
|
|
133
|
+
console.log(chalk_1.default.cyan(' [2] Login with API key') + chalk_1.default.gray(' (I have an account)\n'));
|
|
134
|
+
const choice = await prompt(chalk_1.default.gray(' Enter 1 or 2: '));
|
|
135
|
+
if (choice === '2') {
|
|
136
|
+
await handleApiKeyLogin(options);
|
|
122
137
|
return;
|
|
123
138
|
}
|
|
124
139
|
// Start new trial
|
|
@@ -183,18 +198,8 @@ async function go(options = {}) {
|
|
|
183
198
|
await installPatterns(data.trialId, options);
|
|
184
199
|
// Configure MCP
|
|
185
200
|
await configureMCP(options);
|
|
186
|
-
// Show success
|
|
187
|
-
|
|
188
|
-
╔═══════════════════════════════════════════════════════════╗
|
|
189
|
-
║ ✅ CodeBakers is ready! ║
|
|
190
|
-
║ ║
|
|
191
|
-
║ ${chalk_1.default.white('Your 7-day free trial has started.')} ║
|
|
192
|
-
║ ║
|
|
193
|
-
║ ${chalk_1.default.gray('Try: "Build me a todo app with authentication"')} ║
|
|
194
|
-
╚═══════════════════════════════════════════════════════════╝
|
|
195
|
-
`));
|
|
196
|
-
// Attempt auto-restart Claude Code
|
|
197
|
-
await attemptAutoRestart();
|
|
201
|
+
// Show success and restart
|
|
202
|
+
await showSuccessAndRestart();
|
|
198
203
|
}
|
|
199
204
|
catch (error) {
|
|
200
205
|
spinner.fail('Failed to start trial');
|
|
@@ -235,9 +240,50 @@ async function configureMCP(options = {}) {
|
|
|
235
240
|
}
|
|
236
241
|
}
|
|
237
242
|
}
|
|
238
|
-
|
|
243
|
+
/**
|
|
244
|
+
* Handle API key login flow (for paid users)
|
|
245
|
+
*/
|
|
246
|
+
async function handleApiKeyLogin(options = {}) {
|
|
247
|
+
console.log(chalk_1.default.white('\n Enter your API key\n'));
|
|
248
|
+
console.log(chalk_1.default.gray(' Find it at: https://codebakers.ai/dashboard\n'));
|
|
249
|
+
const apiKey = await prompt(chalk_1.default.cyan(' API Key: '));
|
|
250
|
+
if (!apiKey) {
|
|
251
|
+
console.log(chalk_1.default.red('\n API key is required.\n'));
|
|
252
|
+
return;
|
|
253
|
+
}
|
|
254
|
+
const spinner = (0, ora_1.default)('Validating API key...').start();
|
|
255
|
+
try {
|
|
256
|
+
await (0, api_js_1.validateApiKey)(apiKey);
|
|
257
|
+
spinner.succeed('API key validated');
|
|
258
|
+
// Save API key
|
|
259
|
+
(0, config_js_1.setApiKey)(apiKey);
|
|
260
|
+
console.log(chalk_1.default.green(' ✓ Logged in successfully!\n'));
|
|
261
|
+
// Install patterns
|
|
262
|
+
await installPatternsWithApiKey(apiKey, options);
|
|
263
|
+
// Configure MCP
|
|
264
|
+
await configureMCP(options);
|
|
265
|
+
// Show success
|
|
266
|
+
await showSuccessAndRestart();
|
|
267
|
+
}
|
|
268
|
+
catch (error) {
|
|
269
|
+
spinner.fail('Invalid API key');
|
|
270
|
+
console.log(chalk_1.default.red('\n Could not validate API key.'));
|
|
271
|
+
console.log(chalk_1.default.gray(' Check your key at: https://codebakers.ai/dashboard\n'));
|
|
272
|
+
}
|
|
273
|
+
}
|
|
274
|
+
/**
|
|
275
|
+
* Show success message and offer to restart
|
|
276
|
+
*/
|
|
277
|
+
async function showSuccessAndRestart() {
|
|
239
278
|
const cwd = process.cwd();
|
|
240
|
-
console.log(chalk_1.default.
|
|
279
|
+
console.log(chalk_1.default.green(`
|
|
280
|
+
╔═══════════════════════════════════════════════════════════╗
|
|
281
|
+
║ ✅ CodeBakers is ready! ║
|
|
282
|
+
║ ║
|
|
283
|
+
║ ${chalk_1.default.gray('Try: "Build me a todo app with authentication"')} ║
|
|
284
|
+
╚═══════════════════════════════════════════════════════════╝
|
|
285
|
+
`));
|
|
286
|
+
console.log(chalk_1.default.yellow(' ⚠️ RESTART REQUIRED\n'));
|
|
241
287
|
console.log(chalk_1.default.gray(' Claude Code needs to restart to load CodeBakers.\n'));
|
|
242
288
|
const answer = await prompt(chalk_1.default.cyan(' Restart Claude Code now? (Y/n): '));
|
|
243
289
|
if (answer === 'n' || answer === 'no') {
|
|
@@ -249,7 +295,6 @@ async function attemptAutoRestart() {
|
|
|
249
295
|
try {
|
|
250
296
|
const isWindows = process.platform === 'win32';
|
|
251
297
|
if (isWindows) {
|
|
252
|
-
// On Windows, spawn a new Claude process detached and exit
|
|
253
298
|
(0, child_process_1.spawn)('cmd', ['/c', 'start', 'claude'], {
|
|
254
299
|
cwd,
|
|
255
300
|
detached: true,
|
|
@@ -258,7 +303,6 @@ async function attemptAutoRestart() {
|
|
|
258
303
|
}).unref();
|
|
259
304
|
}
|
|
260
305
|
else {
|
|
261
|
-
// On Mac/Linux, spawn claude in new terminal
|
|
262
306
|
(0, child_process_1.spawn)('claude', [], {
|
|
263
307
|
cwd,
|
|
264
308
|
detached: true,
|
|
@@ -268,12 +312,10 @@ async function attemptAutoRestart() {
|
|
|
268
312
|
}
|
|
269
313
|
console.log(chalk_1.default.green(' ✓ Claude Code is restarting...\n'));
|
|
270
314
|
console.log(chalk_1.default.gray(' This terminal will close. Claude Code will open in a new window.\n'));
|
|
271
|
-
// Give the spawn a moment to start
|
|
272
315
|
await new Promise(resolve => setTimeout(resolve, 1000));
|
|
273
|
-
// Exit this process
|
|
274
316
|
process.exit(0);
|
|
275
317
|
}
|
|
276
|
-
catch
|
|
318
|
+
catch {
|
|
277
319
|
console.log(chalk_1.default.yellow(' Could not auto-restart. Please restart Claude Code manually.\n'));
|
|
278
320
|
}
|
|
279
321
|
}
|
package/package.json
CHANGED
package/src/commands/go.ts
CHANGED
|
@@ -9,10 +9,12 @@ import {
|
|
|
9
9
|
setTrialState,
|
|
10
10
|
getApiUrl,
|
|
11
11
|
getApiKey,
|
|
12
|
+
setApiKey,
|
|
12
13
|
isTrialExpired,
|
|
13
14
|
getTrialDaysRemaining,
|
|
14
15
|
type TrialState,
|
|
15
16
|
} from '../config.js';
|
|
17
|
+
import { validateApiKey } from '../lib/api.js';
|
|
16
18
|
import { getDeviceFingerprint } from '../lib/fingerprint.js';
|
|
17
19
|
|
|
18
20
|
function prompt(question: string): Promise<string> {
|
|
@@ -98,6 +100,7 @@ function log(message: string, options?: GoOptions): void {
|
|
|
98
100
|
|
|
99
101
|
/**
|
|
100
102
|
* Zero-friction entry point - start using CodeBakers instantly
|
|
103
|
+
* Single command for both trial and paid users
|
|
101
104
|
*/
|
|
102
105
|
export async function go(options: GoOptions = {}): Promise<void> {
|
|
103
106
|
log('Starting go command...', options);
|
|
@@ -107,21 +110,22 @@ export async function go(options: GoOptions = {}): Promise<void> {
|
|
|
107
110
|
console.log(chalk.blue(`
|
|
108
111
|
╔═══════════════════════════════════════════════════════════╗
|
|
109
112
|
║ ║
|
|
110
|
-
║ ${chalk.bold.white('CodeBakers -
|
|
113
|
+
║ ${chalk.bold.white('CodeBakers - Get Started')} ║
|
|
111
114
|
║ ║
|
|
112
115
|
╚═══════════════════════════════════════════════════════════╝
|
|
113
116
|
`));
|
|
114
117
|
|
|
115
118
|
// Check if user already has an API key (paid user)
|
|
116
119
|
log('Checking for existing API key...', options);
|
|
117
|
-
const
|
|
118
|
-
if (
|
|
119
|
-
log(`Found API key: ${
|
|
120
|
-
console.log(chalk.green(' ✓ You\'re already logged in
|
|
120
|
+
const existingApiKey = getApiKey();
|
|
121
|
+
if (existingApiKey) {
|
|
122
|
+
log(`Found API key: ${existingApiKey.substring(0, 8)}...`, options);
|
|
123
|
+
console.log(chalk.green(' ✓ You\'re already logged in!\n'));
|
|
121
124
|
|
|
122
|
-
//
|
|
123
|
-
await installPatternsWithApiKey(
|
|
125
|
+
// Install patterns if not already installed
|
|
126
|
+
await installPatternsWithApiKey(existingApiKey, options);
|
|
124
127
|
await configureMCP(options);
|
|
128
|
+
await showSuccessAndRestart();
|
|
125
129
|
return;
|
|
126
130
|
}
|
|
127
131
|
log('No API key found, checking trial state...', options);
|
|
@@ -140,8 +144,8 @@ export async function go(options: GoOptions = {}): Promise<void> {
|
|
|
140
144
|
|
|
141
145
|
// Install patterns if not already installed
|
|
142
146
|
await installPatterns(existingTrial.trialId, options);
|
|
143
|
-
|
|
144
147
|
await configureMCP(options);
|
|
148
|
+
await showSuccessAndRestart();
|
|
145
149
|
return;
|
|
146
150
|
}
|
|
147
151
|
|
|
@@ -149,15 +153,31 @@ export async function go(options: GoOptions = {}): Promise<void> {
|
|
|
149
153
|
if (existingTrial && isTrialExpired()) {
|
|
150
154
|
console.log(chalk.yellow(' ⚠️ Your trial has expired.\n'));
|
|
151
155
|
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
156
|
+
// Offer to login with API key or extend
|
|
157
|
+
console.log(chalk.white(' Options:\n'));
|
|
158
|
+
console.log(chalk.cyan(' [1] Login with API key') + chalk.gray(' (I have an account)'));
|
|
159
|
+
console.log(chalk.cyan(' [2] Extend trial') + chalk.gray(' (7 more days with GitHub)\n'));
|
|
160
|
+
|
|
161
|
+
const choice = await prompt(chalk.gray(' Enter 1 or 2: '));
|
|
162
|
+
|
|
163
|
+
if (choice === '1') {
|
|
164
|
+
await handleApiKeyLogin(options);
|
|
165
|
+
return;
|
|
157
166
|
} else {
|
|
158
|
-
console.log(chalk.
|
|
159
|
-
|
|
167
|
+
console.log(chalk.cyan('\n Run: codebakers extend\n'));
|
|
168
|
+
return;
|
|
160
169
|
}
|
|
170
|
+
}
|
|
171
|
+
|
|
172
|
+
// New user - ask how they want to proceed
|
|
173
|
+
console.log(chalk.white(' How would you like to get started?\n'));
|
|
174
|
+
console.log(chalk.cyan(' [1] Start free 7-day trial') + chalk.gray(' (no signup required)'));
|
|
175
|
+
console.log(chalk.cyan(' [2] Login with API key') + chalk.gray(' (I have an account)\n'));
|
|
176
|
+
|
|
177
|
+
const choice = await prompt(chalk.gray(' Enter 1 or 2: '));
|
|
178
|
+
|
|
179
|
+
if (choice === '2') {
|
|
180
|
+
await handleApiKeyLogin(options);
|
|
161
181
|
return;
|
|
162
182
|
}
|
|
163
183
|
|
|
@@ -235,19 +255,8 @@ export async function go(options: GoOptions = {}): Promise<void> {
|
|
|
235
255
|
// Configure MCP
|
|
236
256
|
await configureMCP(options);
|
|
237
257
|
|
|
238
|
-
// Show success
|
|
239
|
-
|
|
240
|
-
╔═══════════════════════════════════════════════════════════╗
|
|
241
|
-
║ ✅ CodeBakers is ready! ║
|
|
242
|
-
║ ║
|
|
243
|
-
║ ${chalk.white('Your 7-day free trial has started.')} ║
|
|
244
|
-
║ ║
|
|
245
|
-
║ ${chalk.gray('Try: "Build me a todo app with authentication"')} ║
|
|
246
|
-
╚═══════════════════════════════════════════════════════════╝
|
|
247
|
-
`));
|
|
248
|
-
|
|
249
|
-
// Attempt auto-restart Claude Code
|
|
250
|
-
await attemptAutoRestart();
|
|
258
|
+
// Show success and restart
|
|
259
|
+
await showSuccessAndRestart();
|
|
251
260
|
|
|
252
261
|
} catch (error) {
|
|
253
262
|
spinner.fail('Failed to start trial');
|
|
@@ -289,10 +298,61 @@ async function configureMCP(options: GoOptions = {}): Promise<void> {
|
|
|
289
298
|
}
|
|
290
299
|
}
|
|
291
300
|
|
|
292
|
-
|
|
301
|
+
/**
|
|
302
|
+
* Handle API key login flow (for paid users)
|
|
303
|
+
*/
|
|
304
|
+
async function handleApiKeyLogin(options: GoOptions = {}): Promise<void> {
|
|
305
|
+
console.log(chalk.white('\n Enter your API key\n'));
|
|
306
|
+
console.log(chalk.gray(' Find it at: https://codebakers.ai/dashboard\n'));
|
|
307
|
+
|
|
308
|
+
const apiKey = await prompt(chalk.cyan(' API Key: '));
|
|
309
|
+
|
|
310
|
+
if (!apiKey) {
|
|
311
|
+
console.log(chalk.red('\n API key is required.\n'));
|
|
312
|
+
return;
|
|
313
|
+
}
|
|
314
|
+
|
|
315
|
+
const spinner = ora('Validating API key...').start();
|
|
316
|
+
|
|
317
|
+
try {
|
|
318
|
+
await validateApiKey(apiKey);
|
|
319
|
+
spinner.succeed('API key validated');
|
|
320
|
+
|
|
321
|
+
// Save API key
|
|
322
|
+
setApiKey(apiKey);
|
|
323
|
+
console.log(chalk.green(' ✓ Logged in successfully!\n'));
|
|
324
|
+
|
|
325
|
+
// Install patterns
|
|
326
|
+
await installPatternsWithApiKey(apiKey, options);
|
|
327
|
+
|
|
328
|
+
// Configure MCP
|
|
329
|
+
await configureMCP(options);
|
|
330
|
+
|
|
331
|
+
// Show success
|
|
332
|
+
await showSuccessAndRestart();
|
|
333
|
+
|
|
334
|
+
} catch (error) {
|
|
335
|
+
spinner.fail('Invalid API key');
|
|
336
|
+
console.log(chalk.red('\n Could not validate API key.'));
|
|
337
|
+
console.log(chalk.gray(' Check your key at: https://codebakers.ai/dashboard\n'));
|
|
338
|
+
}
|
|
339
|
+
}
|
|
340
|
+
|
|
341
|
+
/**
|
|
342
|
+
* Show success message and offer to restart
|
|
343
|
+
*/
|
|
344
|
+
async function showSuccessAndRestart(): Promise<void> {
|
|
293
345
|
const cwd = process.cwd();
|
|
294
346
|
|
|
295
|
-
console.log(chalk.
|
|
347
|
+
console.log(chalk.green(`
|
|
348
|
+
╔═══════════════════════════════════════════════════════════╗
|
|
349
|
+
║ ✅ CodeBakers is ready! ║
|
|
350
|
+
║ ║
|
|
351
|
+
║ ${chalk.gray('Try: "Build me a todo app with authentication"')} ║
|
|
352
|
+
╚═══════════════════════════════════════════════════════════╝
|
|
353
|
+
`));
|
|
354
|
+
|
|
355
|
+
console.log(chalk.yellow(' ⚠️ RESTART REQUIRED\n'));
|
|
296
356
|
console.log(chalk.gray(' Claude Code needs to restart to load CodeBakers.\n'));
|
|
297
357
|
|
|
298
358
|
const answer = await prompt(chalk.cyan(' Restart Claude Code now? (Y/n): '));
|
|
@@ -309,7 +369,6 @@ async function attemptAutoRestart(): Promise<void> {
|
|
|
309
369
|
const isWindows = process.platform === 'win32';
|
|
310
370
|
|
|
311
371
|
if (isWindows) {
|
|
312
|
-
// On Windows, spawn a new Claude process detached and exit
|
|
313
372
|
spawn('cmd', ['/c', 'start', 'claude'], {
|
|
314
373
|
cwd,
|
|
315
374
|
detached: true,
|
|
@@ -317,7 +376,6 @@ async function attemptAutoRestart(): Promise<void> {
|
|
|
317
376
|
shell: true,
|
|
318
377
|
}).unref();
|
|
319
378
|
} else {
|
|
320
|
-
// On Mac/Linux, spawn claude in new terminal
|
|
321
379
|
spawn('claude', [], {
|
|
322
380
|
cwd,
|
|
323
381
|
detached: true,
|
|
@@ -329,13 +387,10 @@ async function attemptAutoRestart(): Promise<void> {
|
|
|
329
387
|
console.log(chalk.green(' ✓ Claude Code is restarting...\n'));
|
|
330
388
|
console.log(chalk.gray(' This terminal will close. Claude Code will open in a new window.\n'));
|
|
331
389
|
|
|
332
|
-
// Give the spawn a moment to start
|
|
333
390
|
await new Promise(resolve => setTimeout(resolve, 1000));
|
|
334
|
-
|
|
335
|
-
// Exit this process
|
|
336
391
|
process.exit(0);
|
|
337
392
|
|
|
338
|
-
} catch
|
|
393
|
+
} catch {
|
|
339
394
|
console.log(chalk.yellow(' Could not auto-restart. Please restart Claude Code manually.\n'));
|
|
340
395
|
}
|
|
341
396
|
}
|