@mindexec/cli 0.2.421 → 0.2.423

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/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@mindexec/cli",
3
- "version": "0.2.421",
3
+ "version": "0.2.423",
4
4
  "description": "MindExec local runtime and bridge CLI",
5
5
  "main": "server.js",
6
6
  "type": "module",
package/server.js CHANGED
@@ -699,6 +699,7 @@ async function writeStableAuthSessionPayload(content) {
699
699
  }
700
700
 
701
701
  await writePrivateTextFile(stablePath, payload);
702
+ clearRemoteRegistryAuthRefreshBackoff('auth-session-write');
702
703
  return stablePath;
703
704
  }
704
705
 
@@ -3677,6 +3678,15 @@ const REMOTE_REGISTRY_FOLLOWER_FAST_RETRY_MS = Math.max(500, Number(process.env.
3677
3678
  const REMOTE_REGISTRY_FOLLOWER_MISSING_SESSION_FAST_RETRY_COUNT = Math.max(
3678
3679
  1,
3679
3680
  Number(process.env.MINDEXEC_REMOTE_REGISTRY_MISSING_SESSION_FAST_RETRY_COUNT || 5) || 5);
3681
+ const REMOTE_REGISTRY_AUTH_REFRESH_BACKOFF_BASE_MS = Math.max(
3682
+ 5000,
3683
+ Number(process.env.MINDEXEC_REMOTE_REGISTRY_AUTH_REFRESH_BACKOFF_BASE_MS || 30000) || 30000);
3684
+ const REMOTE_REGISTRY_AUTH_REFRESH_BACKOFF_MAX_MS = Math.max(
3685
+ REMOTE_REGISTRY_AUTH_REFRESH_BACKOFF_BASE_MS,
3686
+ Number(process.env.MINDEXEC_REMOTE_REGISTRY_AUTH_REFRESH_BACKOFF_MAX_MS || 300000) || 300000);
3687
+ const REMOTE_REGISTRY_AUTH_REFRESH_LOG_REPEAT_MS = Math.max(
3688
+ 10000,
3689
+ Number(process.env.MINDEXEC_REMOTE_REGISTRY_AUTH_REFRESH_LOG_REPEAT_MS || 60000) || 60000);
3680
3690
  const REMOTE_REGISTRY_FOLLOWER_INACTIVE_STOP_COUNT = Math.max(2, Number(process.env.MINDEXEC_REMOTE_REGISTRY_INACTIVE_STOP_COUNT || 8) || 8);
3681
3691
  const REMOTE_REGISTRY_FOLLOWER_INACTIVE_GRACE_MS = Math.max(500, Number(process.env.MINDEXEC_REMOTE_REGISTRY_INACTIVE_GRACE_MS || 60000) || 60000);
3682
3692
  const REMOTE_REGISTRY_INACTIVE_TARGET_RECOVERY_MS = Math.max(
@@ -3724,6 +3734,13 @@ let remoteRegistryFollowerConsecutiveMissingSession = 0;
3724
3734
  let remoteRegistryFollowerConsecutiveInactiveTarget = 0;
3725
3735
  let remoteRegistryFollowerInactiveTargetFirstAt = 0;
3726
3736
  let remoteRegistrySessionRefreshPromise = null;
3737
+ let remoteRegistryAuthRefreshBackoff = {
3738
+ key: '',
3739
+ until: 0,
3740
+ failureCount: 0,
3741
+ lastError: '',
3742
+ lastLogAt: 0
3743
+ };
3727
3744
  let remoteRegistryRealtimeSocket = null;
3728
3745
  let remoteRegistryRealtimeSessionKey = '';
3729
3746
  let remoteRegistryRealtimeTopic = '';
@@ -6270,6 +6287,98 @@ function parseSupabaseSessionForRegistry(content) {
6270
6287
  };
6271
6288
  }
6272
6289
 
6290
+ function getRemoteRegistryAuthRefreshKey(session) {
6291
+ const refreshToken = String(session?.refreshToken || '').trim();
6292
+ if (!refreshToken) {
6293
+ return '';
6294
+ }
6295
+
6296
+ const digest = crypto.createHash('sha256').update(refreshToken).digest('hex').slice(0, 24);
6297
+ return `${safeRemoteAgentField(session?.userId || '', 80)}|${digest}|${Number(session?.expiresAtMs || 0)}`;
6298
+ }
6299
+
6300
+ function clearRemoteRegistryAuthRefreshBackoff(reason = 'cleared') {
6301
+ if (!remoteRegistryAuthRefreshBackoff?.key) {
6302
+ return false;
6303
+ }
6304
+
6305
+ remoteRegistryAuthRefreshBackoff = {
6306
+ key: '',
6307
+ until: 0,
6308
+ failureCount: 0,
6309
+ lastError: '',
6310
+ lastLogAt: 0
6311
+ };
6312
+ if (VERBOSE_REMOTE_AGENT_LOGS) {
6313
+ logEvent('remote', `registry auth refresh backoff cleared ${formatKeyValue('reason', reason)}`, 'remote');
6314
+ }
6315
+ return true;
6316
+ }
6317
+
6318
+ function getRemoteRegistryAuthRefreshBackoff(session) {
6319
+ const key = getRemoteRegistryAuthRefreshKey(session);
6320
+ if (!key) {
6321
+ return { blocked: false, key: '' };
6322
+ }
6323
+
6324
+ if (remoteRegistryAuthRefreshBackoff.key !== key) {
6325
+ return { blocked: false, key };
6326
+ }
6327
+
6328
+ const now = Date.now();
6329
+ const until = Number(remoteRegistryAuthRefreshBackoff.until || 0);
6330
+ if (until > now) {
6331
+ return {
6332
+ blocked: true,
6333
+ key,
6334
+ retryInMs: Math.max(0, until - now),
6335
+ error: remoteRegistryAuthRefreshBackoff.lastError || 'auth-refresh-backoff',
6336
+ failureCount: Number(remoteRegistryAuthRefreshBackoff.failureCount || 0)
6337
+ };
6338
+ }
6339
+
6340
+ return { blocked: false, key };
6341
+ }
6342
+
6343
+ function recordRemoteRegistryAuthRefreshFailure(session, error, reason = 'registry') {
6344
+ const key = getRemoteRegistryAuthRefreshKey(session);
6345
+ const now = Date.now();
6346
+ const previousCount = remoteRegistryAuthRefreshBackoff.key === key
6347
+ ? Number(remoteRegistryAuthRefreshBackoff.failureCount || 0)
6348
+ : 0;
6349
+ const failureCount = previousCount + 1;
6350
+ const backoffMs = Math.min(
6351
+ REMOTE_REGISTRY_AUTH_REFRESH_BACKOFF_MAX_MS,
6352
+ REMOTE_REGISTRY_AUTH_REFRESH_BACKOFF_BASE_MS * Math.max(1, Math.pow(2, Math.min(4, failureCount - 1))));
6353
+ const message = error?.message || String(error || 'auth-refresh-failed');
6354
+ const lastLogAt = remoteRegistryAuthRefreshBackoff.key === key
6355
+ ? Number(remoteRegistryAuthRefreshBackoff.lastLogAt || 0)
6356
+ : 0;
6357
+ const shouldLog = lastLogAt <= 0 ||
6358
+ now - lastLogAt >= REMOTE_REGISTRY_AUTH_REFRESH_LOG_REPEAT_MS ||
6359
+ remoteRegistryAuthRefreshBackoff.lastError !== message;
6360
+
6361
+ remoteRegistryAuthRefreshBackoff = {
6362
+ key,
6363
+ until: now + backoffMs,
6364
+ failureCount,
6365
+ lastError: message,
6366
+ lastLogAt: shouldLog ? now : lastLogAt
6367
+ };
6368
+
6369
+ if (shouldLog) {
6370
+ logWarn(
6371
+ 'remote',
6372
+ `registry auth refresh failed ${formatKeyValue('reason', reason || 'registry')} ${formatKeyValue('error', message)} ${formatKeyValue('retryInMs', backoffMs)}`);
6373
+ }
6374
+
6375
+ return {
6376
+ retryInMs: backoffMs,
6377
+ failureCount,
6378
+ error: message
6379
+ };
6380
+ }
6381
+
6273
6382
  async function refreshSupabaseSessionForRegistry(config, sessionPayload, reason = 'registry') {
6274
6383
  const currentSession = parseSupabaseSessionForRegistry(sessionPayload?.content);
6275
6384
  if (!currentSession?.refreshToken) {
@@ -6283,6 +6392,14 @@ async function refreshSupabaseSessionForRegistry(config, sessionPayload, reason
6283
6392
  return await remoteRegistrySessionRefreshPromise;
6284
6393
  }
6285
6394
 
6395
+ const backoff = getRemoteRegistryAuthRefreshBackoff(currentSession);
6396
+ if (backoff.blocked === true) {
6397
+ return {
6398
+ ok: false,
6399
+ reason: `auth-refresh-backoff:${Math.ceil(Number(backoff.retryInMs || 0) / 1000)}s`
6400
+ };
6401
+ }
6402
+
6286
6403
  remoteRegistrySessionRefreshPromise = (async () => {
6287
6404
  const url = new URL('/auth/v1/token', config.url);
6288
6405
  url.searchParams.set('grant_type', 'refresh_token');
@@ -6321,6 +6438,7 @@ async function refreshSupabaseSessionForRegistry(config, sessionPayload, reason
6321
6438
  `registry auth refreshed ${formatKeyValue('reason', reason || 'registry')} ${formatKeyValue('expiresInMs', Math.max(0, session.expiresAtMs - Date.now()))}`,
6322
6439
  'remote');
6323
6440
 
6441
+ clearRemoteRegistryAuthRefreshBackoff('auth-refresh-success');
6324
6442
  return {
6325
6443
  ok: true,
6326
6444
  reason: 'refreshed',
@@ -6387,16 +6505,14 @@ async function readFreshSupabaseSessionForRegistry(config, reason = 'registry')
6387
6505
  refreshError: refreshed.reason || 'auth-refresh-skipped'
6388
6506
  };
6389
6507
  } catch (error) {
6390
- logWarn(
6391
- 'remote',
6392
- `registry auth refresh failed ${formatKeyValue('reason', reason || 'registry')} ${formatKeyValue('error', error?.message || String(error || ''))}`);
6508
+ const failure = recordRemoteRegistryAuthRefreshFailure(session, error, reason);
6393
6509
  return {
6394
6510
  found: true,
6395
6511
  payload: sessionPayload,
6396
6512
  session,
6397
6513
  refreshed: false,
6398
6514
  expired: session.expiresAtMs > 0 && session.expiresAtMs <= Date.now(),
6399
- refreshError: error?.message || String(error || '')
6515
+ refreshError: failure.error
6400
6516
  };
6401
6517
  }
6402
6518
  }
@@ -2611,8 +2611,6 @@ html body .css3d-resolution-wrapper.lod-low.node-type-csv-table .csv-table td {
2611
2611
 
2612
2612
  .css3d-resolution-wrapper.node-type-templatelauncher:has(> .map-node-template-card.map-node-remote-fleet) {
2613
2613
  outline: none !important;
2614
- -webkit-box-shadow: none !important;
2615
- box-shadow: none !important;
2616
2614
  -webkit-filter: none !important;
2617
2615
  filter: none !important;
2618
2616
  }
@@ -2621,9 +2619,9 @@ html body .css3d-resolution-wrapper.lod-low.node-type-csv-table .csv-table td {
2621
2619
  border: 2px solid var(--node-selection-edge, #2563eb) !important;
2622
2620
  }
2623
2621
 
2624
- /* Template launcher and Multi Desktop Monitor own their visual chrome on the
2625
- card itself. Keep the CSS3D wrapper neutral so motion CSS3D and the passive
2626
- DOM overlay do not stack different selection chrome. */
2622
+ /* Template launcher cards own their internal border chrome. The Multi Desktop
2623
+ Monitor still keeps the canonical CSS3D wrapper depth shadow so it reads like
2624
+ a normal canvas node while its screen-wall body stays flat. */
2627
2625
  .css3d-resolution-wrapper.node-type-templatelauncher.selected {
2628
2626
  outline: none !important;
2629
2627
  -webkit-box-shadow: none !important;
@@ -2636,6 +2634,19 @@ html body .css3d-resolution-wrapper.lod-low.node-type-csv-table .csv-table td {
2636
2634
  box-shadow: none !important;
2637
2635
  }
2638
2636
 
2637
+ html body .css3d-resolution-wrapper.node-type-templatelauncher:not(.lod-low):has(> .map-node-template-card.map-node-remote-fleet) {
2638
+ -webkit-box-shadow:
2639
+ 0 0 6px rgba(15, 23, 42, 0.25),
2640
+ 0 0 16px rgba(15, 23, 42, 0.18),
2641
+ 0 0 30px rgba(15, 23, 42, 0.12),
2642
+ 0 0 50px rgba(15, 23, 42, 0.08) !important;
2643
+ box-shadow:
2644
+ 0 0 6px rgba(15, 23, 42, 0.25),
2645
+ 0 0 16px rgba(15, 23, 42, 0.18),
2646
+ 0 0 30px rgba(15, 23, 42, 0.12),
2647
+ 0 0 50px rgba(15, 23, 42, 0.08) !important;
2648
+ }
2649
+
2639
2650
  .map-node-template-card,
2640
2651
  .map-node-template-card * {
2641
2652
  box-sizing: border-box;
@@ -418,7 +418,6 @@
418
418
  }
419
419
  .css3d-resolution-wrapper.node-type-templatelauncher:has(> .map-node-template-card.map-node-remote-fleet) {
420
420
  outline: none !important;
421
- box-shadow: none !important;
422
421
  filter: none !important;
423
422
  }
424
423
  .css3d-resolution-wrapper.node-type-templatelauncher.selected > .map-node-template-card.map-node-remote-fleet {
@@ -8,7 +8,7 @@
8
8
  <meta name="description" content="MindExec is an AI business execution OS for solo builders who want to turn notes, research, assets, and repeatable execution Skills into revenue-producing work." />
9
9
  <base href="/" />
10
10
  <link rel="stylesheet" href="_content/MindExecution.Shared/css/app.css?v=20260628-local-oauth-v838" />
11
- <link rel="stylesheet" href="_content/MindExecution.Shared/css/mind-map-overrides.css?v=20260627-local-oauth-relay-v836" />
11
+ <link rel="stylesheet" href="_content/MindExecution.Shared/css/mind-map-overrides.css?v=20260629-mdm-shadow-v856" />
12
12
  <!-- ??좎뜦堉??Font Awesome (local) ??좎뜦堉??-->
13
13
  <link rel="stylesheet" href="_content/MindExecution.Shared/lib/font-awesome/css/all.min.css" />
14
14
  <!-- ??좎뜦堉??-->
@@ -579,7 +579,7 @@
579
579
  }
580
580
 
581
581
  const base = '_content/MindExecution.Shared/js/';
582
- const scriptVersion = '20260629-wheel-zoom-immediate-lite-v855';
582
+ const scriptVersion = '20260629-mdm-shadow-v856';
583
583
  const scriptUrl = (script) => `${base}${script}?v=${scriptVersion}`;
584
584
  console.log(`[Script Loader] Shared JS version: ${scriptVersion}`);
585
585
  const criticalScripts = [
@@ -1,5 +1,5 @@
1
1
  self.assetsManifest = {
2
- "version": "XIia70hb",
2
+ "version": "fA2W79ZH",
3
3
  "assets": [
4
4
  {
5
5
  "hash": "sha256-+CSYMcqLNTsq3VnH11jgYyOCCdxvHzL74CBmo4sCmMU=",
@@ -42,7 +42,7 @@
42
42
  "url": "_content/MindExecution.Shared/css/app.css"
43
43
  },
44
44
  {
45
- "hash": "sha256-5H2C1LgV4x6yd6MJWyrR8rOgzngsEF5SfIROGDWenxc=",
45
+ "hash": "sha256-uoZWP9rvAR8US7KYwnM+F7X/1sozQpAiyOlyUr0cWeU=",
46
46
  "url": "_content/MindExecution.Shared/css/mind-map-overrides.css"
47
47
  },
48
48
  {
@@ -86,7 +86,7 @@
86
86
  "url": "_content/MindExecution.Shared/js/mind-map-core.js.backup"
87
87
  },
88
88
  {
89
- "hash": "sha256-xGt9LTobfy8NmStfgnMGnwq4rmbMaDLpp41TSFZcxEA=",
89
+ "hash": "sha256-UFpa7SNYN+/9N9usMa7jWfvlI/mji1W6A27p4c2nQUs=",
90
90
  "url": "_content/MindExecution.Shared/js/mind-map-css3d-manager.js"
91
91
  },
92
92
  {
@@ -826,7 +826,7 @@
826
826
  "url": "icon-512.png"
827
827
  },
828
828
  {
829
- "hash": "sha256-c7bd5qxUiH3yqT95Xt6vckY20uqzasgvEGQnonVsO1M=",
829
+ "hash": "sha256-0Gf0h8/sXPcC9sq1+w9IbEs2NZdf16v+cuObSCOWns8=",
830
830
  "url": "index.html"
831
831
  },
832
832
  {
@@ -1,4 +1,4 @@
1
- /* Manifest version: XIia70hb */
1
+ /* Manifest version: fA2W79ZH */
2
2
  // Hosted deployments should prefer the network over stale offline caches.
3
3
  // This service worker immediately clears old Blazor offline caches and unregisters itself.
4
4