@robbiesrobotics/alice-agents 1.5.4 → 1.5.5

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/lib/installer.mjs CHANGED
@@ -499,48 +499,92 @@ function printSummaryWithOptions(mode, tier, agents, preset, userInfo, detectedM
499
499
  * Uses alice-cloud CLI spawned as a child process (CJS ↔ ESM boundary).
500
500
  */
501
501
  async function _runCloudOnboarding(auto, options, existingMissionControl) {
502
- const { execSync: execSyncLocal, spawn: spawnLocal } = await import('node:child_process');
502
+ const { execFileSync } = await import('node:child_process');
503
+ const { mkdirSync, readFileSync, writeFileSync, existsSync: fsExists } = await import('node:fs');
503
504
  const aliceCloudBin = join(__dirname, '..', 'bin', 'alice-cloud.cjs');
504
505
  const defaults = getDefaultMissionControlSettings();
506
+ const cloudConfigPath = join(homedir(), '.openclaw', 'alice-cloud.json');
507
+
508
+ function readCloudJson() {
509
+ try { return JSON.parse(readFileSync(cloudConfigPath, 'utf8')); } catch { return {}; }
510
+ }
511
+ function writeCloudJson(data) {
512
+ mkdirSync(join(homedir(), '.openclaw'), { recursive: true });
513
+ writeFileSync(cloudConfigPath, JSON.stringify(data, null, 2));
514
+ }
505
515
 
506
516
  try {
507
- // Step 1: Login — open browser for Supabase OAuth
517
+ // Step 1: Login
508
518
  console.log('');
509
519
  console.log(` ${icons.pkg} ${bold('Setting up A.L.I.C.E. Cloud...')}`);
510
- console.log(` Opening your browser to sign in with GitHub...`);
511
520
  console.log('');
512
521
 
513
- // Spawn alice-cloud login as a child process
514
- // In non-interactive mode, use env var for token
515
522
  if (auto && options.cloudSupabaseToken) {
516
- execSyncLocal(
517
- `node ${JSON.stringify(aliceCloudBin)} login --non-interactive`,
518
- {
519
- stdio: 'inherit',
520
- env: { ...process.env, ALICE_SUPABASE_TOKEN: options.cloudSupabaseToken, ALICE_NON_INTERACTIVE: '1' },
521
- }
522
- );
523
+ // Non-interactive: use provided token
524
+ const cloudData = readCloudJson();
525
+ cloudData.supabaseToken = options.cloudSupabaseToken;
526
+ writeCloudJson(cloudData);
527
+ printStepDone('Cloud token saved');
523
528
  } else if (!auto) {
524
- // Interactive: spawn login which opens browser and waits for token paste
525
- execSyncLocal(`node ${JSON.stringify(aliceCloudBin)} login`, { stdio: 'inherit' });
529
+ // Interactive: open browser and prompt for token using our own readline
530
+ console.log(` ${dim('A.L.I.C.E. Cloud uses your GitHub account for authentication.')}`);
531
+ console.log(` ${dim('We\'ll open your browser to sign in, then you\'ll paste a token back here.')}`);
532
+ console.log('');
533
+
534
+ try {
535
+ const open = (await import('open')).default;
536
+ const supabaseUrl = 'https://xxxgvtwnlbtdgmlgccee.supabase.co';
537
+ const oauthUrl = `${supabaseUrl}/auth/v1/authorize?provider=github&redirect_to=${encodeURIComponent('https://alice.av3.ai/api/cloud/auth/callback')}`;
538
+ await open(oauthUrl);
539
+ console.log(` ${green('Browser opened!')} Sign in with GitHub and copy the token shown.`);
540
+ } catch {
541
+ console.log(` ${yellow('Could not open browser.')} Visit this URL to sign in:`);
542
+ console.log(` ${cyan('https://alice.av3.ai/login')}`);
543
+ }
544
+ console.log('');
545
+
546
+ const token = await promptCloudToken();
547
+
548
+ if (token) {
549
+ const cloudData = readCloudJson();
550
+ cloudData.supabaseToken = token;
551
+ writeCloudJson(cloudData);
552
+ printStepDone('Cloud token saved');
553
+ } else {
554
+ console.log(` ${dim('Skipped — you can authenticate later with:')} ${cyan('alice-cloud login')}`);
555
+ }
526
556
  }
527
557
 
528
- // Step 2: Register gateway
558
+ // Step 2: Register gateway (use child process for this — no stdin needed)
529
559
  if (isCloudAuthenticated()) {
530
560
  console.log('');
531
561
  console.log(` ${icons.pkg} ${bold('Registering gateway with A.L.I.C.E. Cloud...')}`);
532
- execSyncLocal(`node ${JSON.stringify(aliceCloudBin)} register`, { stdio: 'inherit' });
533
- printStepDone('Cloud login and registration complete');
562
+ try {
563
+ execFileSync(process.execPath, [aliceCloudBin, 'register'], {
564
+ stdio: ['ignore', 'inherit', 'inherit'],
565
+ timeout: 15000,
566
+ });
567
+ printStepDone('Gateway registered with A.L.I.C.E. Cloud');
568
+ } catch {
569
+ console.log(` ${yellow('Gateway registration failed — you can retry later with:')} ${cyan('alice-cloud register')}`);
570
+ }
534
571
 
535
572
  // Step 3: Ask about heartbeat daemon
536
573
  const startHeartbeat = auto ? false : await promptCloudHeartbeat();
537
574
  if (startHeartbeat) {
538
575
  console.log(` ${dim('Starting heartbeat daemon...')}`);
539
- execSyncLocal(`node ${JSON.stringify(aliceCloudBin)} watch --daemon`, { stdio: 'inherit' });
540
- printStepDone('Heartbeat daemon started');
576
+ try {
577
+ execFileSync(process.execPath, [aliceCloudBin, 'watch', '--daemon'], {
578
+ stdio: ['ignore', 'inherit', 'inherit'],
579
+ timeout: 10000,
580
+ });
581
+ printStepDone('Heartbeat daemon started');
582
+ } catch {
583
+ console.log(` ${dim('Could not start daemon — run:')} ${cyan('alice-cloud watch --daemon')}`);
584
+ }
541
585
  }
542
586
  } else {
543
- printStepSkip('Cloud registration', 'login was skipped or failed — run `alice-cloud login` later');
587
+ printStepSkip('Cloud registration', 'no token provided — run `alice-cloud login` later');
544
588
  }
545
589
  } catch (err) {
546
590
  console.log(` ${icons.warn} ${yellow('Cloud setup encountered an issue: ' + (err.message || 'unknown error'))}`);
package/lib/license.mjs CHANGED
@@ -168,7 +168,10 @@ export async function checkProLicense(options = {}) {
168
168
  };
169
169
  }
170
170
 
171
- if (refreshed.transient) {
171
+ // Revalidation failed — but if the license was previously validated successfully,
172
+ // honor it with a grace period rather than immediately invalidating.
173
+ // This prevents API outages or temporary endpoint issues from breaking existing installs.
174
+ if (refreshed.transient || record.status === 'validated') {
172
175
  return {
173
176
  licensed: true,
174
177
  key: record.key,
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@robbiesrobotics/alice-agents",
3
- "version": "1.5.4",
3
+ "version": "1.5.5",
4
4
  "description": "A.L.I.C.E. \u2014 31 AI agents for OpenClaw. One conversation, one team.",
5
5
  "bin": {
6
6
  "alice-agents": "bin/alice-install.mjs",