aios-core 4.2.0 → 4.2.2
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,8 @@
|
|
|
7
7
|
# - SHA256 hashes for change detection
|
|
8
8
|
# - File types for categorization
|
|
9
9
|
#
|
|
10
|
-
version: 4.2.
|
|
11
|
-
generated_at: "2026-02-16T00:
|
|
10
|
+
version: 4.2.2
|
|
11
|
+
generated_at: "2026-02-16T00:23:14.678Z"
|
|
12
12
|
generator: scripts/generate-install-manifest.js
|
|
13
13
|
file_count: 992
|
|
14
14
|
files:
|
package/package.json
CHANGED
|
@@ -215,11 +215,11 @@ async function stepLicenseGate(options = {}) {
|
|
|
215
215
|
message: colors.primary('How would you like to activate Pro?'),
|
|
216
216
|
choices: [
|
|
217
217
|
{
|
|
218
|
-
name: 'Login
|
|
218
|
+
name: 'Login or create account (Recommended)',
|
|
219
219
|
value: 'email',
|
|
220
220
|
},
|
|
221
221
|
{
|
|
222
|
-
name: 'Enter license key',
|
|
222
|
+
name: 'Enter license key (legacy)',
|
|
223
223
|
value: 'key',
|
|
224
224
|
},
|
|
225
225
|
],
|
|
@@ -306,6 +306,88 @@ async function stepLicenseGateWithEmail() {
|
|
|
306
306
|
return authenticateWithEmail(email.trim(), password);
|
|
307
307
|
}
|
|
308
308
|
|
|
309
|
+
/**
|
|
310
|
+
* Prompt user to create a new account interactively.
|
|
311
|
+
*
|
|
312
|
+
* Asks for confirmation, then password with confirmation.
|
|
313
|
+
* Calls signup API and logs in to get session token.
|
|
314
|
+
*
|
|
315
|
+
* @param {object} client - LicenseApiClient instance
|
|
316
|
+
* @param {string} email - User email
|
|
317
|
+
* @returns {Promise<Object>} Result with { success, sessionToken } or { success: false, error }
|
|
318
|
+
*/
|
|
319
|
+
async function promptCreateAccount(client, email) {
|
|
320
|
+
const inquirer = require('inquirer');
|
|
321
|
+
|
|
322
|
+
console.log('');
|
|
323
|
+
showInfo(`No account found for ${email}.`);
|
|
324
|
+
|
|
325
|
+
const { wantCreate } = await inquirer.prompt([
|
|
326
|
+
{
|
|
327
|
+
type: 'confirm',
|
|
328
|
+
name: 'wantCreate',
|
|
329
|
+
message: colors.primary('Would you like to create an account?'),
|
|
330
|
+
default: true,
|
|
331
|
+
},
|
|
332
|
+
]);
|
|
333
|
+
|
|
334
|
+
if (!wantCreate) {
|
|
335
|
+
return { success: false, error: 'Account creation cancelled.' };
|
|
336
|
+
}
|
|
337
|
+
|
|
338
|
+
// Ask for password with confirmation
|
|
339
|
+
const { newPassword } = await inquirer.prompt([
|
|
340
|
+
{
|
|
341
|
+
type: 'password',
|
|
342
|
+
name: 'newPassword',
|
|
343
|
+
message: colors.primary('Choose a password:'),
|
|
344
|
+
mask: '*',
|
|
345
|
+
validate: (input) => {
|
|
346
|
+
if (!input || input.length < MIN_PASSWORD_LENGTH) {
|
|
347
|
+
return `Password must be at least ${MIN_PASSWORD_LENGTH} characters`;
|
|
348
|
+
}
|
|
349
|
+
return true;
|
|
350
|
+
},
|
|
351
|
+
},
|
|
352
|
+
]);
|
|
353
|
+
|
|
354
|
+
const { confirmPassword } = await inquirer.prompt([
|
|
355
|
+
{
|
|
356
|
+
type: 'password',
|
|
357
|
+
name: 'confirmPassword',
|
|
358
|
+
message: colors.primary('Confirm password:'),
|
|
359
|
+
mask: '*',
|
|
360
|
+
validate: (input) => {
|
|
361
|
+
if (input !== newPassword) {
|
|
362
|
+
return 'Passwords do not match';
|
|
363
|
+
}
|
|
364
|
+
return true;
|
|
365
|
+
},
|
|
366
|
+
},
|
|
367
|
+
]);
|
|
368
|
+
|
|
369
|
+
// Create account
|
|
370
|
+
const spinner = createSpinner('Creating account...');
|
|
371
|
+
spinner.start();
|
|
372
|
+
|
|
373
|
+
try {
|
|
374
|
+
await client.signup(email, confirmPassword);
|
|
375
|
+
spinner.succeed('Account created! Verification email sent.');
|
|
376
|
+
|
|
377
|
+
// Login to get session token
|
|
378
|
+
const loginResult = await client.login(email, confirmPassword);
|
|
379
|
+
return { success: true, sessionToken: loginResult.sessionToken };
|
|
380
|
+
} catch (signupError) {
|
|
381
|
+
if (signupError.code === 'EMAIL_ALREADY_REGISTERED') {
|
|
382
|
+
spinner.fail('An account already exists with this email but the password is incorrect.');
|
|
383
|
+
showInfo('Forgot your password? Visit https://pro.synkra.ai/reset-password or contact support@synkra.ai');
|
|
384
|
+
return { success: false, error: signupError.message };
|
|
385
|
+
}
|
|
386
|
+
spinner.fail(`Account creation failed: ${signupError.message}`);
|
|
387
|
+
return { success: false, error: signupError.message };
|
|
388
|
+
}
|
|
389
|
+
}
|
|
390
|
+
|
|
309
391
|
/**
|
|
310
392
|
* Authenticate with email and password.
|
|
311
393
|
*
|
|
@@ -339,48 +421,122 @@ async function authenticateWithEmail(email, password) {
|
|
|
339
421
|
};
|
|
340
422
|
}
|
|
341
423
|
|
|
342
|
-
// Try login first
|
|
343
|
-
const spinner = createSpinner('Authenticating...');
|
|
344
|
-
spinner.start();
|
|
345
|
-
|
|
346
424
|
let sessionToken;
|
|
347
425
|
let emailVerified;
|
|
426
|
+
let currentPassword = password;
|
|
348
427
|
|
|
349
|
-
|
|
350
|
-
|
|
351
|
-
|
|
352
|
-
|
|
353
|
-
spinner.succeed('Authenticated successfully.');
|
|
354
|
-
} catch (loginError) {
|
|
355
|
-
// If invalid credentials, try signup for new users
|
|
356
|
-
if (loginError.code === 'INVALID_CREDENTIALS') {
|
|
357
|
-
spinner.info('No account found. Creating a new account...');
|
|
428
|
+
// Login with retry loop (max 3 attempts for wrong password)
|
|
429
|
+
for (let attempt = 1; attempt <= MAX_RETRIES; attempt++) {
|
|
430
|
+
const spinner = createSpinner('Authenticating...');
|
|
431
|
+
spinner.start();
|
|
358
432
|
|
|
359
|
-
|
|
360
|
-
|
|
361
|
-
|
|
362
|
-
|
|
363
|
-
|
|
364
|
-
|
|
365
|
-
|
|
366
|
-
|
|
367
|
-
|
|
368
|
-
|
|
369
|
-
|
|
370
|
-
|
|
371
|
-
|
|
433
|
+
try {
|
|
434
|
+
const loginResult = await client.login(email, currentPassword);
|
|
435
|
+
sessionToken = loginResult.sessionToken;
|
|
436
|
+
emailVerified = loginResult.emailVerified;
|
|
437
|
+
spinner.succeed('Authenticated successfully.');
|
|
438
|
+
break; // Success, exit retry loop
|
|
439
|
+
} catch (loginError) {
|
|
440
|
+
if (loginError.code === 'INVALID_CREDENTIALS') {
|
|
441
|
+
spinner.stop();
|
|
442
|
+
|
|
443
|
+
// Try to determine if account exists by attempting signup
|
|
444
|
+
// If signup fails with EMAIL_ALREADY_REGISTERED, account exists (wrong password)
|
|
445
|
+
// If signup succeeds or would succeed, account doesn't exist (new user)
|
|
446
|
+
if (isCIEnvironment()) {
|
|
447
|
+
// CI mode: try auto-signup
|
|
448
|
+
try {
|
|
449
|
+
await client.signup(email, currentPassword);
|
|
450
|
+
showSuccess('Account created. Verification email sent!');
|
|
451
|
+
emailVerified = false;
|
|
452
|
+
const loginAfterSignup = await client.login(email, currentPassword);
|
|
453
|
+
sessionToken = loginAfterSignup.sessionToken;
|
|
454
|
+
break;
|
|
455
|
+
} catch (signupError) {
|
|
456
|
+
if (signupError.code === 'EMAIL_ALREADY_REGISTERED') {
|
|
457
|
+
showError('Account exists but the password is incorrect.');
|
|
458
|
+
showInfo('Forgot your password? Visit https://pro.synkra.ai/reset-password or contact support@synkra.ai');
|
|
459
|
+
return { success: false, error: signupError.message };
|
|
460
|
+
}
|
|
461
|
+
return { success: false, error: signupError.message };
|
|
462
|
+
}
|
|
372
463
|
}
|
|
373
|
-
|
|
464
|
+
|
|
465
|
+
// Interactive mode: check if account exists
|
|
466
|
+
const accountCheckSpinner = createSpinner('Checking account...');
|
|
467
|
+
accountCheckSpinner.start();
|
|
468
|
+
|
|
469
|
+
let accountExists = false;
|
|
470
|
+
try {
|
|
471
|
+
// Try a lightweight signup to probe. If EMAIL_ALREADY_REGISTERED, account exists.
|
|
472
|
+
await client.signup(email, currentPassword);
|
|
473
|
+
// Signup succeeded — account was just created
|
|
474
|
+
accountCheckSpinner.succeed('Account created! Verification email sent.');
|
|
475
|
+
const loginAfterSignup = await client.login(email, currentPassword);
|
|
476
|
+
sessionToken = loginAfterSignup.sessionToken;
|
|
477
|
+
emailVerified = false;
|
|
478
|
+
break;
|
|
479
|
+
} catch (probeError) {
|
|
480
|
+
if (probeError.code === 'EMAIL_ALREADY_REGISTERED') {
|
|
481
|
+
accountExists = true;
|
|
482
|
+
accountCheckSpinner.stop();
|
|
483
|
+
} else {
|
|
484
|
+
accountCheckSpinner.stop();
|
|
485
|
+
// Unknown error during probe — offer create account flow
|
|
486
|
+
const signupResult = await promptCreateAccount(client, email);
|
|
487
|
+
if (!signupResult.success) {
|
|
488
|
+
return signupResult;
|
|
489
|
+
}
|
|
490
|
+
sessionToken = signupResult.sessionToken;
|
|
491
|
+
emailVerified = false;
|
|
492
|
+
break;
|
|
493
|
+
}
|
|
494
|
+
}
|
|
495
|
+
|
|
496
|
+
if (accountExists) {
|
|
497
|
+
// Account exists but password is wrong — retry
|
|
498
|
+
const remaining = MAX_RETRIES - attempt;
|
|
499
|
+
if (remaining > 0) {
|
|
500
|
+
showError(`Incorrect password. ${remaining} attempt${remaining > 1 ? 's' : ''} remaining.`);
|
|
501
|
+
showInfo('Forgot your password? Visit https://pro.synkra.ai/reset-password');
|
|
502
|
+
|
|
503
|
+
const inquirer = require('inquirer');
|
|
504
|
+
const { retryPassword } = await inquirer.prompt([
|
|
505
|
+
{
|
|
506
|
+
type: 'password',
|
|
507
|
+
name: 'retryPassword',
|
|
508
|
+
message: colors.primary('Password:'),
|
|
509
|
+
mask: '*',
|
|
510
|
+
validate: (input) => {
|
|
511
|
+
if (!input || input.length < MIN_PASSWORD_LENGTH) {
|
|
512
|
+
return `Password must be at least ${MIN_PASSWORD_LENGTH} characters`;
|
|
513
|
+
}
|
|
514
|
+
return true;
|
|
515
|
+
},
|
|
516
|
+
},
|
|
517
|
+
]);
|
|
518
|
+
currentPassword = retryPassword;
|
|
519
|
+
continue; // Retry login
|
|
520
|
+
} else {
|
|
521
|
+
showError('Maximum login attempts reached.');
|
|
522
|
+
showInfo('Forgot your password? Visit https://pro.synkra.ai/reset-password or contact support@synkra.ai');
|
|
523
|
+
return { success: false, error: 'Maximum login attempts reached.' };
|
|
524
|
+
}
|
|
525
|
+
}
|
|
526
|
+
} else if (loginError.code === 'AUTH_RATE_LIMITED') {
|
|
527
|
+
spinner.fail(loginError.message);
|
|
528
|
+
return { success: false, error: loginError.message };
|
|
529
|
+
} else {
|
|
530
|
+
spinner.fail(`Authentication failed: ${loginError.message}`);
|
|
531
|
+
return { success: false, error: loginError.message };
|
|
374
532
|
}
|
|
375
|
-
} else if (loginError.code === 'AUTH_RATE_LIMITED') {
|
|
376
|
-
spinner.fail(loginError.message);
|
|
377
|
-
return { success: false, error: loginError.message };
|
|
378
|
-
} else {
|
|
379
|
-
spinner.fail(`Authentication failed: ${loginError.message}`);
|
|
380
|
-
return { success: false, error: loginError.message };
|
|
381
533
|
}
|
|
382
534
|
}
|
|
383
535
|
|
|
536
|
+
if (!sessionToken) {
|
|
537
|
+
return { success: false, error: 'Authentication failed after all attempts.' };
|
|
538
|
+
}
|
|
539
|
+
|
|
384
540
|
// Wait for email verification if needed
|
|
385
541
|
if (!emailVerified) {
|
|
386
542
|
const verifyResult = await waitForEmailVerification(client, sessionToken);
|
|
@@ -918,6 +1074,7 @@ module.exports = {
|
|
|
918
1074
|
stepLicenseGateWithKey,
|
|
919
1075
|
stepLicenseGateWithKeyInteractive,
|
|
920
1076
|
stepLicenseGateWithEmail,
|
|
1077
|
+
promptCreateAccount,
|
|
921
1078
|
loadLicenseApi,
|
|
922
1079
|
loadFeatureGate,
|
|
923
1080
|
loadProScaffolder,
|