@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 +1 -1
- package/server.js +120 -4
- package/wwwroot/_content/MindExecution.Shared/css/mind-map-overrides.css +16 -5
- package/wwwroot/_content/MindExecution.Shared/js/mind-map-css3d-manager.js +0 -1
- package/wwwroot/index.html +2 -2
- package/wwwroot/service-worker-assets.js +4 -4
- package/wwwroot/service-worker.js +1 -1
package/package.json
CHANGED
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
|
-
|
|
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
|
|
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
|
|
2625
|
-
|
|
2626
|
-
|
|
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 {
|
package/wwwroot/index.html
CHANGED
|
@@ -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=
|
|
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-
|
|
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": "
|
|
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-
|
|
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-
|
|
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-
|
|
829
|
+
"hash": "sha256-0Gf0h8/sXPcC9sq1+w9IbEs2NZdf16v+cuObSCOWns8=",
|
|
830
830
|
"url": "index.html"
|
|
831
831
|
},
|
|
832
832
|
{
|