aios-core 4.2.0 → 4.2.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,8 @@
7
7
  # - SHA256 hashes for change detection
8
8
  # - File types for categorization
9
9
  #
10
- version: 4.2.0
11
- generated_at: "2026-02-16T00:03:48.806Z"
10
+ version: 4.2.1
11
+ generated_at: "2026-02-16T00:12:14.502Z"
12
12
  generator: scripts/generate-install-manifest.js
13
13
  file_count: 992
14
14
  files:
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "aios-core",
3
- "version": "4.2.0",
3
+ "version": "4.2.1",
4
4
  "description": "Synkra AIOS: AI-Orchestrated System for Full Stack Development - Core Framework",
5
5
  "bin": {
6
6
  "aios": "bin/aios.js",
@@ -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 with email and password (Recommended)',
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
  *
@@ -352,25 +434,34 @@ async function authenticateWithEmail(email, password) {
352
434
  emailVerified = loginResult.emailVerified;
353
435
  spinner.succeed('Authenticated successfully.');
354
436
  } catch (loginError) {
355
- // If invalid credentials, try signup for new users
437
+ // If invalid credentials, offer to create account
356
438
  if (loginError.code === 'INVALID_CREDENTIALS') {
357
- spinner.info('No account found. Creating a new account...');
439
+ spinner.info('No account found for this email.');
358
440
 
359
- try {
360
- await client.signup(email, password);
361
- showSuccess('Account created. Verification email sent!');
362
- emailVerified = false;
363
-
364
- // Login after signup to get session token
365
- const loginAfterSignup = await client.login(email, password);
366
- sessionToken = loginAfterSignup.sessionToken;
367
- } catch (signupError) {
368
- if (signupError.code === 'EMAIL_ALREADY_REGISTERED') {
369
- showError('An account exists with this email but the password is incorrect.');
370
- showInfo('Forgot your password? Visit https://pro.synkra.ai/reset-password or contact support@synkra.ai');
441
+ // In CI mode, auto-create without prompting
442
+ if (isCIEnvironment()) {
443
+ try {
444
+ await client.signup(email, password);
445
+ showSuccess('Account created. Verification email sent!');
446
+ emailVerified = false;
447
+ const loginAfterSignup = await client.login(email, password);
448
+ sessionToken = loginAfterSignup.sessionToken;
449
+ } catch (signupError) {
450
+ if (signupError.code === 'EMAIL_ALREADY_REGISTERED') {
451
+ showError('An account exists with this email but the password is incorrect.');
452
+ showInfo('Forgot your password? Visit https://pro.synkra.ai/reset-password or contact support@synkra.ai');
453
+ return { success: false, error: signupError.message };
454
+ }
371
455
  return { success: false, error: signupError.message };
372
456
  }
373
- return { success: false, error: signupError.message };
457
+ } else {
458
+ // Interactive: ask user if they want to create account
459
+ const signupResult = await promptCreateAccount(client, email);
460
+ if (!signupResult.success) {
461
+ return signupResult;
462
+ }
463
+ sessionToken = signupResult.sessionToken;
464
+ emailVerified = false;
374
465
  }
375
466
  } else if (loginError.code === 'AUTH_RATE_LIMITED') {
376
467
  spinner.fail(loginError.message);
@@ -918,6 +1009,7 @@ module.exports = {
918
1009
  stepLicenseGateWithKey,
919
1010
  stepLicenseGateWithKeyInteractive,
920
1011
  stepLicenseGateWithEmail,
1012
+ promptCreateAccount,
921
1013
  loadLicenseApi,
922
1014
  loadFeatureGate,
923
1015
  loadProScaffolder,