@mindexec/cli 0.2.87 → 0.2.89

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.
Files changed (24) hide show
  1. package/package.json +3 -2
  2. package/scripts/auth-session-smoke.mjs +218 -0
  3. package/server.js +213 -11
  4. package/wwwroot/_content/MindExecution.Shared/js/mind-map-css3d-manager.js +40 -0
  5. package/wwwroot/_content/MindExecution.Shared/js/mind-map-interactions.js +13 -0
  6. package/wwwroot/_content/MindExecution.Shared/js/mind-map-lod-renderer.js +29 -46
  7. package/wwwroot/_framework/MindExecution.Core.qprj2wqc9a.dll +0 -0
  8. package/wwwroot/_framework/{MindExecution.Kernel.mdo1lzjvvp.dll → MindExecution.Kernel.ksznt6ppyj.dll} +0 -0
  9. package/wwwroot/_framework/{MindExecution.Plugins.Admin.5fctwf65dx.dll → MindExecution.Plugins.Admin.ziclnsvcvi.dll} +0 -0
  10. package/wwwroot/_framework/{MindExecution.Plugins.Business.nwivpk9djf.dll → MindExecution.Plugins.Business.q32f5kgky1.dll} +0 -0
  11. package/wwwroot/_framework/{MindExecution.Plugins.Concept.urf2igpscm.dll → MindExecution.Plugins.Concept.vrmey2vv08.dll} +0 -0
  12. package/wwwroot/_framework/{MindExecution.Plugins.Directory.jnzcrwl049.dll → MindExecution.Plugins.Directory.3pet73jp0m.dll} +0 -0
  13. package/wwwroot/_framework/{MindExecution.Plugins.PlanMaster.88ikwl696h.dll → MindExecution.Plugins.PlanMaster.0pdulhmw15.dll} +0 -0
  14. package/wwwroot/_framework/{MindExecution.Plugins.YouTube.wf48rh6hfh.dll → MindExecution.Plugins.YouTube.ye6w0jn4v9.dll} +0 -0
  15. package/wwwroot/_framework/{MindExecution.Shared.6aa15yqsqi.dll → MindExecution.Shared.oxf5h3gtl1.dll} +0 -0
  16. package/wwwroot/_framework/MindExecution.Web.s43m8j3bg0.dll +0 -0
  17. package/wwwroot/_framework/System.Text.Json.0v0qgmri0w.dll +0 -0
  18. package/wwwroot/_framework/blazor.boot.json +23 -23
  19. package/wwwroot/index.html +3 -3
  20. package/wwwroot/service-worker-assets.js +28 -28
  21. package/wwwroot/service-worker.js +1 -1
  22. package/wwwroot/_framework/MindExecution.Core.csfu1xtj3l.dll +0 -0
  23. package/wwwroot/_framework/MindExecution.Web.8gp839zb62.dll +0 -0
  24. package/wwwroot/_framework/System.Text.Json.4s25e3op6i.dll +0 -0
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@mindexec/cli",
3
- "version": "0.2.87",
3
+ "version": "0.2.89",
4
4
  "description": "MindExec local runtime and bridge CLI",
5
5
  "main": "server.js",
6
6
  "type": "module",
@@ -20,7 +20,8 @@
20
20
  "scripts": {
21
21
  "start": "node launch-bridge.cjs",
22
22
  "dev": "node launch-bridge.cjs --watch",
23
- "test:syntax": "node --check server.js && node --check remote-hub.js && node --check codex-runtime.js && node --check launch-bridge.cjs && node --check port-guard.cjs && node --check scripts/setup-tree-sitter-grammars.mjs && node --check scripts/remote-hub-smoke.mjs && node --check scripts/remote-hub-scale-smoke.mjs && node --check scripts/remote-fleet-render-smoke.mjs && node --check scripts/remote-http-smoke.mjs",
23
+ "test:syntax": "node --check server.js && node --check remote-hub.js && node --check codex-runtime.js && node --check launch-bridge.cjs && node --check port-guard.cjs && node --check scripts/setup-tree-sitter-grammars.mjs && node --check scripts/auth-session-smoke.mjs && node --check scripts/remote-hub-smoke.mjs && node --check scripts/remote-hub-scale-smoke.mjs && node --check scripts/remote-fleet-render-smoke.mjs && node --check scripts/remote-http-smoke.mjs",
24
+ "test:auth": "node scripts/auth-session-smoke.mjs",
24
25
  "test:remote": "node scripts/remote-hub-smoke.mjs",
25
26
  "test:remote:scale": "node scripts/remote-hub-scale-smoke.mjs",
26
27
  "test:remote:render": "node scripts/remote-fleet-render-smoke.mjs",
@@ -0,0 +1,218 @@
1
+ #!/usr/bin/env node
2
+
3
+ import assert from 'node:assert/strict';
4
+ import { spawn } from 'node:child_process';
5
+ import { mkdtemp, mkdir, rm, writeFile } from 'node:fs/promises';
6
+ import net from 'node:net';
7
+ import os from 'node:os';
8
+ import path from 'node:path';
9
+ import { fileURLToPath } from 'node:url';
10
+
11
+ const BRIDGE_TOKEN = 'auth-session-smoke-token';
12
+ const __dirname = path.dirname(fileURLToPath(import.meta.url));
13
+ const bridgeRoot = path.resolve(__dirname, '..');
14
+
15
+ function wait(ms) {
16
+ return new Promise(resolve => setTimeout(resolve, ms));
17
+ }
18
+
19
+ async function findFreePort() {
20
+ return await new Promise((resolve, reject) => {
21
+ const server = net.createServer();
22
+ server.unref();
23
+ server.once('error', reject);
24
+ server.listen(0, '127.0.0.1', () => {
25
+ const address = server.address();
26
+ const port = typeof address === 'object' && address ? address.port : 0;
27
+ server.close(() => resolve(port));
28
+ });
29
+ });
30
+ }
31
+
32
+ async function fetchJson(url, options = {}) {
33
+ const response = await fetch(url, {
34
+ ...options,
35
+ headers: {
36
+ ...(options.body ? { 'Content-Type': 'application/json' } : {}),
37
+ ...(options.token ? { 'X-Bridge-Token': options.token } : {}),
38
+ ...(options.headers || {})
39
+ }
40
+ });
41
+
42
+ let payload = null;
43
+ try {
44
+ payload = await response.json();
45
+ } catch {
46
+ // Ignore non-JSON responses.
47
+ }
48
+
49
+ return {
50
+ status: response.status,
51
+ ok: response.ok,
52
+ payload
53
+ };
54
+ }
55
+
56
+ function spawnBridge({ bridgePort, workspacePath, authDataRoot }) {
57
+ const child = spawn(process.execPath, ['server.js'], {
58
+ cwd: bridgeRoot,
59
+ stdio: ['ignore', 'pipe', 'pipe'],
60
+ windowsHide: true,
61
+ env: {
62
+ ...process.env,
63
+ BRIDGE_PORT: String(bridgePort),
64
+ BRIDGE_TOKEN,
65
+ BRIDGE_REQUIRE_TOKEN: '1',
66
+ WORKSPACE_PATH: workspacePath,
67
+ MINDEXEC_AUTH_DATA_ROOT: authDataRoot,
68
+ MINDEXEC_REMOTE_HUB: '0',
69
+ NO_COLOR: '1'
70
+ }
71
+ });
72
+
73
+ let stdout = '';
74
+ let stderr = '';
75
+ child.stdout.on('data', chunk => {
76
+ stdout += chunk.toString();
77
+ });
78
+ child.stderr.on('data', chunk => {
79
+ stderr += chunk.toString();
80
+ });
81
+
82
+ const details = () => `stdout=${stdout}\nstderr=${stderr}`;
83
+ const stop = async () => {
84
+ if (!child.killed) {
85
+ child.kill();
86
+ }
87
+ await Promise.race([
88
+ new Promise(resolve => child.once('exit', resolve)),
89
+ wait(3000)
90
+ ]);
91
+ };
92
+
93
+ return {
94
+ child,
95
+ details,
96
+ stop
97
+ };
98
+ }
99
+
100
+ async function waitForBridge(baseUrl, details) {
101
+ const startedAt = Date.now();
102
+ while (Date.now() - startedAt < 30000) {
103
+ try {
104
+ const response = await fetchJson(`${baseUrl}/api/status`);
105
+ if (response.ok && response.payload?.status) {
106
+ return;
107
+ }
108
+ } catch {
109
+ // Bridge is still starting.
110
+ }
111
+ await wait(100);
112
+ }
113
+
114
+ throw new Error(`Timed out waiting for LocalBridge.\n${details()}`);
115
+ }
116
+
117
+ async function withBridge({ workspacePath, authDataRoot }, action) {
118
+ const bridgePort = await findFreePort();
119
+ const bridge = spawnBridge({ bridgePort, workspacePath, authDataRoot });
120
+ const baseUrl = `http://127.0.0.1:${bridgePort}`;
121
+ try {
122
+ await waitForBridge(baseUrl, bridge.details);
123
+ await action(baseUrl);
124
+ } finally {
125
+ await bridge.stop();
126
+ }
127
+ }
128
+
129
+ const tempRoot = await mkdtemp(path.join(os.tmpdir(), 'mindexec-auth-session-smoke-'));
130
+ try {
131
+ const authDataRoot = path.join(tempRoot, 'stable-auth');
132
+ const workspaceA = path.join(tempRoot, 'workspace-a');
133
+ const workspaceB = path.join(tempRoot, 'workspace-b');
134
+ await mkdir(workspaceA, { recursive: true });
135
+ await mkdir(workspaceB, { recursive: true });
136
+
137
+ const sessionPayload = JSON.stringify({
138
+ access_token: 'access-token-a',
139
+ refresh_token: 'refresh-token-a',
140
+ user: {
141
+ id: 'user-a',
142
+ email: 'auth-smoke@example.com'
143
+ }
144
+ });
145
+
146
+ await withBridge({ workspacePath: workspaceA, authDataRoot }, async (baseUrl) => {
147
+ const unauthorized = await fetchJson(`${baseUrl}/api/auth/session`);
148
+ assert.equal(unauthorized.status, 401);
149
+
150
+ const missing = await fetchJson(`${baseUrl}/api/auth/session`, { token: BRIDGE_TOKEN });
151
+ assert.equal(missing.status, 404);
152
+
153
+ const invalid = await fetchJson(`${baseUrl}/api/auth/session`, {
154
+ method: 'POST',
155
+ token: BRIDGE_TOKEN,
156
+ body: JSON.stringify({ content: 'not-json' })
157
+ });
158
+ assert.equal(invalid.status, 400);
159
+
160
+ const saved = await fetchJson(`${baseUrl}/api/auth/session`, {
161
+ method: 'POST',
162
+ token: BRIDGE_TOKEN,
163
+ body: JSON.stringify({ content: sessionPayload })
164
+ });
165
+ assert.equal(saved.status, 200);
166
+ assert.equal(saved.payload?.success, true);
167
+
168
+ const loaded = await fetchJson(`${baseUrl}/api/auth/session`, { token: BRIDGE_TOKEN });
169
+ assert.equal(loaded.status, 200);
170
+ assert.equal(loaded.payload?.content, sessionPayload);
171
+ assert.equal(loaded.payload?.source, 'stable');
172
+ });
173
+
174
+ await withBridge({ workspacePath: workspaceB, authDataRoot }, async (baseUrl) => {
175
+ const loaded = await fetchJson(`${baseUrl}/api/auth/session`, { token: BRIDGE_TOKEN });
176
+ assert.equal(loaded.status, 200);
177
+ assert.equal(loaded.payload?.content, sessionPayload);
178
+ assert.equal(loaded.payload?.source, 'stable');
179
+
180
+ const deleted = await fetchJson(`${baseUrl}/api/auth/session`, {
181
+ method: 'DELETE',
182
+ token: BRIDGE_TOKEN
183
+ });
184
+ assert.equal(deleted.status, 200);
185
+ assert.equal(deleted.payload?.success, true);
186
+ });
187
+
188
+ const legacyPayload = JSON.stringify({
189
+ access_token: 'legacy-access-token',
190
+ refresh_token: 'legacy-refresh-token',
191
+ user: {
192
+ id: 'legacy-user',
193
+ email: 'legacy-auth-smoke@example.com'
194
+ }
195
+ });
196
+ const legacyPath = path.join(workspaceB, '.mindexec', 'auth', 'supabase-session.json');
197
+ await mkdir(path.dirname(legacyPath), { recursive: true });
198
+ await writeFile(legacyPath, legacyPayload, 'utf8');
199
+
200
+ await withBridge({ workspacePath: workspaceB, authDataRoot }, async (baseUrl) => {
201
+ const migrated = await fetchJson(`${baseUrl}/api/auth/session`, { token: BRIDGE_TOKEN });
202
+ assert.equal(migrated.status, 200);
203
+ assert.equal(migrated.payload?.content, legacyPayload);
204
+ assert.equal(migrated.payload?.source, 'legacy-workspace');
205
+ assert.equal(migrated.payload?.migrated, true);
206
+ });
207
+
208
+ await withBridge({ workspacePath: workspaceA, authDataRoot }, async (baseUrl) => {
209
+ const loaded = await fetchJson(`${baseUrl}/api/auth/session`, { token: BRIDGE_TOKEN });
210
+ assert.equal(loaded.status, 200);
211
+ assert.equal(loaded.payload?.content, legacyPayload);
212
+ assert.equal(loaded.payload?.source, 'stable');
213
+ });
214
+
215
+ console.log('Auth session persistence smoke OK');
216
+ } finally {
217
+ await rm(tempRoot, { recursive: true, force: true });
218
+ }
package/server.js CHANGED
@@ -424,10 +424,12 @@ let currentBrowserSessionId = null;
424
424
  let browserSessionSequence = 0;
425
425
  let playwrightModulePromise = null;
426
426
  let playwrightBrowserPromise = null;
427
- const DATA_ROOT_DIRNAME = '.mindexec';
428
- const LEGACY_MIGRATION_MARKER = '.legacy_migrated_v1.json';
429
- const DATA_GITIGNORE_FILE = '.gitignore';
430
- const DATA_GITIGNORE_CONTENT = [
427
+ const DATA_ROOT_DIRNAME = '.mindexec';
428
+ const LEGACY_MIGRATION_MARKER = '.legacy_migrated_v1.json';
429
+ const DATA_GITIGNORE_FILE = '.gitignore';
430
+ const AUTH_DATA_ROOT = resolveAuthDataRoot();
431
+ const AUTH_SESSION_FILE_NAME = 'supabase-session.json';
432
+ const DATA_GITIGNORE_CONTENT = [
431
433
  '# MindExec managed data',
432
434
  '# Keep boards/ and project.json for shared context by default.',
433
435
  '/cache/',
@@ -470,13 +472,150 @@ const PLAYWRIGHT_BROWSER_CANDIDATES = process.platform === 'win32'
470
472
  '/snap/bin/chromium'
471
473
  ];
472
474
 
473
- function getDataRoot(basePath = workspacePath) {
474
- return path.join(basePath, DATA_ROOT_DIRNAME);
475
- }
476
-
477
- function getBoardsPath(basePath = workspacePath) {
478
- return path.join(getDataRoot(basePath), 'boards');
479
- }
475
+ function getDataRoot(basePath = workspacePath) {
476
+ return path.join(basePath, DATA_ROOT_DIRNAME);
477
+ }
478
+
479
+ function resolveAuthDataRoot() {
480
+ const configuredRoot = String(process.env.MINDEXEC_AUTH_DATA_ROOT || '').trim();
481
+ if (configuredRoot) {
482
+ return path.resolve(configuredRoot);
483
+ }
484
+
485
+ return path.join(os.homedir(), '.mindexec', 'auth');
486
+ }
487
+
488
+ function getStableSupabaseSessionPath() {
489
+ return path.join(AUTH_DATA_ROOT, AUTH_SESSION_FILE_NAME);
490
+ }
491
+
492
+ function getLegacyWorkspaceSupabaseSessionPath(basePath = workspacePath) {
493
+ return path.join(getDataRoot(basePath), 'auth', AUTH_SESSION_FILE_NAME);
494
+ }
495
+
496
+ function getLegacySupabaseSessionCandidatePaths() {
497
+ const candidates = [
498
+ getLegacyWorkspaceSupabaseSessionPath(workspacePath),
499
+ getLegacyWorkspaceSupabaseSessionPath(DEFAULT_WORKSPACE)
500
+ ];
501
+
502
+ return Array.from(new Set(candidates.map(candidate => path.resolve(candidate))));
503
+ }
504
+
505
+ async function tryReadTextFile(filePath) {
506
+ try {
507
+ return await fs.readFile(filePath, 'utf8');
508
+ } catch (err) {
509
+ if (err?.code === 'ENOENT') {
510
+ return null;
511
+ }
512
+
513
+ throw err;
514
+ }
515
+ }
516
+
517
+ async function writePrivateTextFile(fullPath, content) {
518
+ await writeFileAtomically(fullPath, content, 'utf8');
519
+ try {
520
+ await fs.chmod(fullPath, 0o600);
521
+ } catch {
522
+ // Best effort only. Windows ACLs do not map cleanly to chmod.
523
+ }
524
+ }
525
+
526
+ function validateAuthSessionPayload(content) {
527
+ const payload = String(content || '');
528
+ if (!payload.trim()) {
529
+ const err = new Error('Session payload is required');
530
+ err.statusCode = 400;
531
+ throw err;
532
+ }
533
+
534
+ if (Buffer.byteLength(payload, 'utf8') > 512 * 1024) {
535
+ const err = new Error('Session payload is too large');
536
+ err.statusCode = 413;
537
+ throw err;
538
+ }
539
+
540
+ try {
541
+ JSON.parse(payload);
542
+ } catch {
543
+ const err = new Error('Session payload must be valid JSON');
544
+ err.statusCode = 400;
545
+ throw err;
546
+ }
547
+
548
+ return payload;
549
+ }
550
+
551
+ async function readStableAuthSessionPayload() {
552
+ const stablePath = getStableSupabaseSessionPath();
553
+ const stablePayload = await tryReadTextFile(stablePath);
554
+ if (stablePayload && stablePayload.trim()) {
555
+ return {
556
+ found: true,
557
+ content: stablePayload,
558
+ source: 'stable',
559
+ path: stablePath,
560
+ migrated: false
561
+ };
562
+ }
563
+
564
+ for (const legacyPath of getLegacySupabaseSessionCandidatePaths()) {
565
+ const legacyPayload = await tryReadTextFile(legacyPath);
566
+ if (!legacyPayload || !legacyPayload.trim()) {
567
+ continue;
568
+ }
569
+
570
+ await writePrivateTextFile(stablePath, legacyPayload);
571
+ return {
572
+ found: true,
573
+ content: legacyPayload,
574
+ source: 'legacy-workspace',
575
+ path: stablePath,
576
+ migrated: true,
577
+ legacyPath
578
+ };
579
+ }
580
+
581
+ return {
582
+ found: false,
583
+ content: null,
584
+ source: 'none',
585
+ path: stablePath,
586
+ migrated: false
587
+ };
588
+ }
589
+
590
+ async function writeStableAuthSessionPayload(content) {
591
+ const payload = validateAuthSessionPayload(content);
592
+ const stablePath = getStableSupabaseSessionPath();
593
+ await writePrivateTextFile(stablePath, payload);
594
+ return stablePath;
595
+ }
596
+
597
+ async function deleteStableAuthSessionPayload() {
598
+ const paths = [
599
+ getStableSupabaseSessionPath(),
600
+ ...getLegacySupabaseSessionCandidatePaths()
601
+ ];
602
+
603
+ const deleted = [];
604
+ for (const sessionPath of Array.from(new Set(paths.map(candidate => path.resolve(candidate))))) {
605
+ try {
606
+ await fs.rm(sessionPath, { force: true });
607
+ deleted.push(sessionPath);
608
+ } catch {
609
+ // Clearing auth should be best-effort across legacy mirrors.
610
+ }
611
+ }
612
+
613
+ return deleted;
614
+ }
615
+
616
+ function getBoardsPath(basePath = workspacePath) {
617
+ return path.join(getDataRoot(basePath), 'boards');
618
+ }
480
619
 
481
620
  function getAssetsPath(basePath = workspacePath) {
482
621
  return path.join(getDataRoot(basePath), 'assets');
@@ -1745,6 +1884,9 @@ const PROTECTED_BRIDGE_ROUTES = [
1745
1884
  { method: 'POST', exact: '/api/file/delete' },
1746
1885
  { method: 'POST', exact: '/api/file/copy' },
1747
1886
  { method: 'POST', exact: '/api/file/move' },
1887
+ { method: 'GET', exact: '/api/auth/session' },
1888
+ { method: 'POST', exact: '/api/auth/session' },
1889
+ { method: 'DELETE', exact: '/api/auth/session' },
1748
1890
  { method: 'POST', exact: '/api/dir/create' },
1749
1891
  { method: 'POST', exact: '/api/dir/delete' },
1750
1892
  { method: 'POST', prefix: '/api/assets/' },
@@ -1869,6 +2011,66 @@ app.use((req, res, next) => {
1869
2011
  requireBridgeToken(req, res, next);
1870
2012
  });
1871
2013
 
2014
+ app.get('/api/auth/session', async (req, res) => {
2015
+ try {
2016
+ const result = await readStableAuthSessionPayload();
2017
+ if (!result.found) {
2018
+ return res.status(404).json({
2019
+ success: false,
2020
+ found: false
2021
+ });
2022
+ }
2023
+
2024
+ res.json({
2025
+ success: true,
2026
+ found: true,
2027
+ content: result.content,
2028
+ source: result.source,
2029
+ migrated: result.migrated === true
2030
+ });
2031
+ } catch (err) {
2032
+ logError('auth', 'failed to read persisted auth session.', err);
2033
+ const statusCode = Number(err?.statusCode || 500);
2034
+ res.status(statusCode >= 400 && statusCode < 600 ? statusCode : 500).json({
2035
+ success: false,
2036
+ error: err?.message || 'Failed to read auth session'
2037
+ });
2038
+ }
2039
+ });
2040
+
2041
+ app.post('/api/auth/session', async (req, res) => {
2042
+ try {
2043
+ const content = req.body?.content;
2044
+ await writeStableAuthSessionPayload(content);
2045
+ res.json({
2046
+ success: true
2047
+ });
2048
+ } catch (err) {
2049
+ logError('auth', 'failed to persist auth session.', err);
2050
+ const statusCode = Number(err?.statusCode || 500);
2051
+ res.status(statusCode >= 400 && statusCode < 600 ? statusCode : 500).json({
2052
+ success: false,
2053
+ error: err?.message || 'Failed to persist auth session'
2054
+ });
2055
+ }
2056
+ });
2057
+
2058
+ app.delete('/api/auth/session', async (req, res) => {
2059
+ try {
2060
+ await deleteStableAuthSessionPayload();
2061
+ res.json({
2062
+ success: true
2063
+ });
2064
+ } catch (err) {
2065
+ logError('auth', 'failed to clear auth session.', err);
2066
+ const statusCode = Number(err?.statusCode || 500);
2067
+ res.status(statusCode >= 400 && statusCode < 600 ? statusCode : 500).json({
2068
+ success: false,
2069
+ error: err?.message || 'Failed to clear auth session'
2070
+ });
2071
+ }
2072
+ });
2073
+
1872
2074
  app.post('/api/local-files/register', async (req, res) => {
1873
2075
  try {
1874
2076
  const body = req.body || {};
@@ -12810,6 +12810,34 @@
12810
12810
  return button;
12811
12811
  }
12812
12812
 
12813
+ function selectRemoteFleetMonitorNodeFromPointer(nodeId, event) {
12814
+ const normalizedId = String(nodeId || '').trim();
12815
+ if (!normalizedId || event?.button !== 0) {
12816
+ return false;
12817
+ }
12818
+
12819
+ if (_module?.selectedNodeIdJs === normalizedId) {
12820
+ window.MindMapMenuManager?.showMenu?.(normalizedId);
12821
+ return true;
12822
+ }
12823
+
12824
+ const selected = window.MindMapInteractions?.selectNodeById?.(_module, normalizedId, {
12825
+ notifyBlazor: true,
12826
+ bringToFront: true,
12827
+ showMenu: true
12828
+ }) === true;
12829
+
12830
+ if (selected) {
12831
+ _module._forceUpdateFrames = Math.max(Number(_module._forceUpdateFrames || 0), 2);
12832
+ window.RuntimeTrace?.emit?.('remote.monitor.nodeSelected', {
12833
+ nodeId: normalizedId,
12834
+ source: 'remote-monitor-pointer'
12835
+ });
12836
+ }
12837
+
12838
+ return selected;
12839
+ }
12840
+
12813
12841
  function attachRemoteFleetTitleActions(bodyView, hostButton, hostState) {
12814
12842
  const container = bodyView?.closest?.('.map-node-remote-fleet');
12815
12843
  const header = container?.querySelector?.('.template-card__header')
@@ -15060,7 +15088,19 @@
15060
15088
  bodyView.dataset.src = `remote-fleet:${refreshedAt}:${devices.length}:${connected}`;
15061
15089
  bodyView.dataset.remoteFleetHostState = hostTargetState;
15062
15090
  bodyView.dataset.remoteFleetDensity = densityState;
15091
+ bodyView.dataset.remoteFleetMonitorNodeId = nodeId;
15063
15092
  bodyView.classList.add('map-node-remote-fleet__body');
15093
+ if (bodyView._remoteFleetNodeSelectionBound !== true) {
15094
+ bodyView._remoteFleetNodeSelectionBound = true;
15095
+ bodyView.addEventListener('mousedown', event => {
15096
+ const controlTarget = event.target?.closest?.('button, input, textarea, select, [contenteditable="true"]');
15097
+ if (controlTarget) {
15098
+ return;
15099
+ }
15100
+
15101
+ selectRemoteFleetMonitorNodeFromPointer(bodyView.dataset.remoteFleetMonitorNodeId, event);
15102
+ }, true);
15103
+ }
15064
15104
  bodyView.innerHTML = '';
15065
15105
  bodyView.style.cssText = `
15066
15106
  flex: 1 1 auto;
@@ -7589,6 +7589,19 @@ window.MindMapInteractions = (function () {
7589
7589
  onResize: onResize,
7590
7590
  syncViewportMetrics: syncViewportMetrics,
7591
7591
  // ▼▼▼ [New] Expose selectNode and startEditingNode ▼▼▼
7592
+ selectNodeById: function (module, nodeId, options = {}) {
7593
+ const normalizedId = String(nodeId || '').trim();
7594
+ if (!normalizedId || !module?.nodeObjectsById?.has?.(normalizedId)) {
7595
+ return false;
7596
+ }
7597
+
7598
+ finalizeSingleSelection(module, normalizedId, {
7599
+ notifyBlazor: options?.notifyBlazor !== false,
7600
+ bringToFront: options?.bringToFront !== false,
7601
+ showMenu: options?.showMenu !== false
7602
+ });
7603
+ return true;
7604
+ },
7592
7605
  selectNode: function (module, nodeObject) {
7593
7606
  const nodeId = nodeObject.userData?.nodeId;
7594
7607
  if (nodeId) {
@@ -366,8 +366,7 @@
366
366
  contentType === 'memo' ||
367
367
  contentType === 'markdown' ||
368
368
  contentType === 'code' ||
369
- isAgentLikeLodNode(model) ||
370
- isTemplateLauncherLodProxyModel(model);
369
+ isAgentLikeLodNode(model);
371
370
  }
372
371
 
373
372
  function isTemplateLauncherModel(model) {
@@ -380,10 +379,6 @@
380
379
  semanticType === REMOTE_FLEET_DEVICE_SEMANTIC_TYPE;
381
380
  }
382
381
 
383
- function isTemplateLauncherLodProxyModel(model) {
384
- return isTemplateLauncherModel(model) && !isRemoteFleetNodeModel(model);
385
- }
386
-
387
382
  function isCssMediaFallbackModel(model) {
388
383
  const contentType = getNodeContentType(model);
389
384
  return contentType === 'image' ||
@@ -940,7 +935,7 @@
940
935
  this._consoleNodeIdToIndex = new Map();
941
936
  this._lodConsoleProxyNodeIds = new Set();
942
937
  this._lodImageCssFallbackNodeIds = new Set();
943
- this._lodRemoteFleetCssNodeIds = new Set();
938
+ this._lodTemplateCssNodeIds = new Set();
944
939
  this._lodCleanupPending = true;
945
940
  this._lodCleanupDone = false;
946
941
  this._lodVisualEpoch = 0;
@@ -4242,7 +4237,7 @@
4242
4237
 
4243
4238
  const entry = nodeObjectsById.get(nodeId);
4244
4239
  if (!entry?.cssObject || !supportsCss3dNodeModel(entry.model)) continue;
4245
- if (isRemoteFleetNodeModel(entry.model)) continue;
4240
+ if (isTemplateLauncherModel(entry.model)) continue;
4246
4241
  if (shouldShowAgentConsoleInLodBand(lodBand) && hasAgentConsoleOpenForEntry(entry)) continue;
4247
4242
 
4248
4243
  nextWarmIds.add(nodeId);
@@ -4272,7 +4267,7 @@
4272
4267
  const nodeId = warmIds[i];
4273
4268
  if (keepAttachedIds?.has(nodeId)) continue;
4274
4269
  const entry = nodeObjectsById.get(nodeId);
4275
- if (isRemoteFleetNodeModel(entry?.model)) continue;
4270
+ if (isTemplateLauncherModel(entry?.model)) continue;
4276
4271
  this._detachCss3dObject(entry);
4277
4272
  }
4278
4273
  }
@@ -4407,31 +4402,19 @@
4407
4402
  for (const entry of nodeObjectsById.values()) {
4408
4403
  if (!entry || !isTemplateLauncherModel(entry.model)) continue;
4409
4404
 
4410
- if (isRemoteFleetNodeModel(entry.model)) {
4411
- const nodeId = String(entry.model?.id || entry.model?.Id || entry.glObject?.userData?.nodeId || '').trim();
4412
- if (isCss3dRendererEnabled(module)) {
4413
- if (this.isInLODMode === true && nodeId) {
4414
- this._lodRemoteFleetCssNodeIds.add(nodeId);
4415
- } else if (nodeId) {
4416
- this._lodRemoteFleetCssNodeIds.delete(nodeId);
4417
- }
4418
- this._showNodeCss3d(entry, module);
4419
- } else {
4420
- if (nodeId) {
4421
- this._lodRemoteFleetCssNodeIds.delete(nodeId);
4422
- }
4423
- this._hideNodeCss3d(entry);
4424
- }
4425
- continue;
4426
- }
4427
-
4428
- if (this.isInLODMode === true) {
4429
- if (entry.cssObject) {
4430
- this._hideNodeCss3d(entry);
4405
+ const nodeId = String(entry.model?.id || entry.model?.Id || entry.glObject?.userData?.nodeId || '').trim();
4406
+ if (isCss3dRendererEnabled(module)) {
4407
+ if (this.isInLODMode === true && nodeId) {
4408
+ this._lodTemplateCssNodeIds.add(nodeId);
4409
+ } else if (nodeId) {
4410
+ this._lodTemplateCssNodeIds.delete(nodeId);
4431
4411
  }
4432
- this._hideTextLodFullVisual(entry);
4433
- } else if (isCss3dRendererEnabled(module)) {
4434
4412
  this._showNodeCss3d(entry, module);
4413
+ } else {
4414
+ if (nodeId) {
4415
+ this._lodTemplateCssNodeIds.delete(nodeId);
4416
+ }
4417
+ this._hideNodeCss3d(entry);
4435
4418
  }
4436
4419
  }
4437
4420
  }
@@ -4651,7 +4634,7 @@
4651
4634
  if (nodeId) {
4652
4635
  this._nearCssVisibleIds.delete(nodeId);
4653
4636
  this._lodImageCssFallbackNodeIds.delete(nodeId);
4654
- this._lodRemoteFleetCssNodeIds.delete(nodeId);
4637
+ this._lodTemplateCssNodeIds.delete(nodeId);
4655
4638
  }
4656
4639
  if (this._module) {
4657
4640
  this._module._css3dVisualChangedThisFrame = true;
@@ -4886,24 +4869,24 @@
4886
4869
  shouldRenderCss3dInLod() {
4887
4870
  return this.isInLODMode === true &&
4888
4871
  (this._getActiveCssMediaLodFallbackCount(this._module) > 0 ||
4889
- this._getActiveRemoteFleetCssLodCount(this._module) > 0);
4872
+ this._getActiveTemplateCssLodCount(this._module) > 0);
4890
4873
  }
4891
4874
 
4892
- _getActiveRemoteFleetCssLodCount(module = this._module) {
4893
- if (this.isInLODMode !== true || !this._lodRemoteFleetCssNodeIds || this._lodRemoteFleetCssNodeIds.size === 0) {
4875
+ _getActiveTemplateCssLodCount(module = this._module) {
4876
+ if (this.isInLODMode !== true || !this._lodTemplateCssNodeIds || this._lodTemplateCssNodeIds.size === 0) {
4894
4877
  return 0;
4895
4878
  }
4896
4879
 
4897
4880
  const nodeObjectsById = module?.nodeObjectsById || this._module?.nodeObjectsById || null;
4898
4881
  if (!nodeObjectsById) {
4899
- return this._lodRemoteFleetCssNodeIds.size;
4882
+ return this._lodTemplateCssNodeIds.size;
4900
4883
  }
4901
4884
 
4902
4885
  let count = 0;
4903
- for (const nodeId of Array.from(this._lodRemoteFleetCssNodeIds)) {
4886
+ for (const nodeId of Array.from(this._lodTemplateCssNodeIds)) {
4904
4887
  const entry = nodeObjectsById.get(nodeId) || null;
4905
- if (!entry || !isRemoteFleetNodeModel(entry.model)) {
4906
- this._lodRemoteFleetCssNodeIds.delete(nodeId);
4888
+ if (!entry || !isTemplateLauncherModel(entry.model)) {
4889
+ this._lodTemplateCssNodeIds.delete(nodeId);
4907
4890
  continue;
4908
4891
  }
4909
4892
 
@@ -6054,13 +6037,13 @@
6054
6037
  }
6055
6038
  }
6056
6039
  }
6057
- const shouldSyncRemoteFleetCss3d =
6040
+ const shouldSyncTemplateCss3d =
6058
6041
  bandChangedWithoutModeSwitch === true ||
6059
6042
  this._instancesDirty === true ||
6060
6043
  this._isNodeArrayDirty === true ||
6061
- (this._lodRemoteFleetCssNodeIds?.size > 0 &&
6062
- this._getActiveRemoteFleetCssLodCount(module) <= 0);
6063
- if (shouldSyncRemoteFleetCss3d) {
6044
+ (this._lodTemplateCssNodeIds?.size > 0 &&
6045
+ this._getActiveTemplateCssLodCount(module) <= 0);
6046
+ if (shouldSyncTemplateCss3d) {
6064
6047
  this._syncTemplateLauncherCss3dForLod(nodeObjectsById, module);
6065
6048
  }
6066
6049
  this._setInstancedAgentBadgeVisibility(lodBand === 'MID');
@@ -9213,7 +9196,7 @@
9213
9196
  this._nearCssVisibleIds.clear();
9214
9197
  this._lodConsoleProxyNodeIds.clear();
9215
9198
  this._lodImageCssFallbackNodeIds.clear();
9216
- this._lodRemoteFleetCssNodeIds.clear();
9199
+ this._lodTemplateCssNodeIds.clear();
9217
9200
  this._clearCss3dQueue();
9218
9201
  this._clearCss3dPrewarmQueue();
9219
9202
  this._css3dProcessing = false;
@@ -9413,7 +9396,7 @@
9413
9396
  this._fullResImageVisualIds?.delete?.(nodeId);
9414
9397
  this._lodConsoleProxyNodeIds?.delete?.(nodeId);
9415
9398
  this._lodImageCssFallbackNodeIds?.delete?.(nodeId);
9416
- this._lodRemoteFleetCssNodeIds?.delete?.(nodeId);
9399
+ this._lodTemplateCssNodeIds?.delete?.(nodeId);
9417
9400
  removedAny = true;
9418
9401
  }
9419
9402
 
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "mainAssemblyName": "MindExecution.Web",
3
3
  "resources": {
4
- "hash": "sha256-4VaftOESBnQE+Q1Rm+Hxk+BcDEAXOHXNFE6dpmlgyyg=",
4
+ "hash": "sha256-UYjWF1Jxof/7OQBXUWs4OE4sIOguU3A5k8CVb4Nnh/8=",
5
5
  "fingerprinting": {
6
6
  "Google.Protobuf.9h59ukbel7.dll": "Google.Protobuf.dll",
7
7
  "Markdig.d1j7v41cl1.dll": "Markdig.dll",
@@ -110,7 +110,7 @@
110
110
  "System.Security.Cryptography.qqgybpoucx.dll": "System.Security.Cryptography.dll",
111
111
  "System.Text.Encoding.Extensions.9t3hs6kyll.dll": "System.Text.Encoding.Extensions.dll",
112
112
  "System.Text.Encodings.Web.wftjfh2crk.dll": "System.Text.Encodings.Web.dll",
113
- "System.Text.Json.4s25e3op6i.dll": "System.Text.Json.dll",
113
+ "System.Text.Json.0v0qgmri0w.dll": "System.Text.Json.dll",
114
114
  "System.Text.RegularExpressions.cvkox11l6l.dll": "System.Text.RegularExpressions.dll",
115
115
  "System.Threading.Channels.419493szqu.dll": "System.Threading.Channels.dll",
116
116
  "System.Threading.Thread.xhmys87xh5.dll": "System.Threading.Thread.dll",
@@ -123,16 +123,16 @@
123
123
  "System.brmz7yk5qh.dll": "System.dll",
124
124
  "netstandard.yvr3prsx0x.dll": "netstandard.dll",
125
125
  "System.Private.CoreLib.c1dbswx1b2.dll": "System.Private.CoreLib.dll",
126
- "MindExecution.Core.csfu1xtj3l.dll": "MindExecution.Core.dll",
127
- "MindExecution.Kernel.mdo1lzjvvp.dll": "MindExecution.Kernel.dll",
128
- "MindExecution.Plugins.Admin.5fctwf65dx.dll": "MindExecution.Plugins.Admin.dll",
129
- "MindExecution.Plugins.Business.nwivpk9djf.dll": "MindExecution.Plugins.Business.dll",
130
- "MindExecution.Plugins.Concept.urf2igpscm.dll": "MindExecution.Plugins.Concept.dll",
131
- "MindExecution.Plugins.Directory.jnzcrwl049.dll": "MindExecution.Plugins.Directory.dll",
132
- "MindExecution.Plugins.PlanMaster.88ikwl696h.dll": "MindExecution.Plugins.PlanMaster.dll",
133
- "MindExecution.Plugins.YouTube.wf48rh6hfh.dll": "MindExecution.Plugins.YouTube.dll",
134
- "MindExecution.Shared.6aa15yqsqi.dll": "MindExecution.Shared.dll",
135
- "MindExecution.Web.8gp839zb62.dll": "MindExecution.Web.dll",
126
+ "MindExecution.Core.qprj2wqc9a.dll": "MindExecution.Core.dll",
127
+ "MindExecution.Kernel.ksznt6ppyj.dll": "MindExecution.Kernel.dll",
128
+ "MindExecution.Plugins.Admin.ziclnsvcvi.dll": "MindExecution.Plugins.Admin.dll",
129
+ "MindExecution.Plugins.Business.q32f5kgky1.dll": "MindExecution.Plugins.Business.dll",
130
+ "MindExecution.Plugins.Concept.vrmey2vv08.dll": "MindExecution.Plugins.Concept.dll",
131
+ "MindExecution.Plugins.Directory.3pet73jp0m.dll": "MindExecution.Plugins.Directory.dll",
132
+ "MindExecution.Plugins.PlanMaster.0pdulhmw15.dll": "MindExecution.Plugins.PlanMaster.dll",
133
+ "MindExecution.Plugins.YouTube.ye6w0jn4v9.dll": "MindExecution.Plugins.YouTube.dll",
134
+ "MindExecution.Shared.oxf5h3gtl1.dll": "MindExecution.Shared.dll",
135
+ "MindExecution.Web.s43m8j3bg0.dll": "MindExecution.Web.dll",
136
136
  "dotnet.js": "dotnet.js",
137
137
  "dotnet.native.qc8g39g30v.js": "dotnet.native.js",
138
138
  "dotnet.native.boem75ye5i.wasm": "dotnet.native.wasm",
@@ -266,7 +266,7 @@
266
266
  "System.Security.Cryptography.qqgybpoucx.dll": "sha256-vofefYZi5S+7Rg61EmobeWUJQoIefwuF7PwjL7nrr+c=",
267
267
  "System.Text.Encoding.Extensions.9t3hs6kyll.dll": "sha256-c54L8A/dPQGmGXDWsmLgXCcq34jyZ/z2QWBpZogPwJs=",
268
268
  "System.Text.Encodings.Web.wftjfh2crk.dll": "sha256-NHGoSuaQLhC8vk+biDWqKZAlhpNTJdJwilcCbgbr8as=",
269
- "System.Text.Json.4s25e3op6i.dll": "sha256-VBeG+FY8NhlMOdQOTUozG5Zn+jrC3jPw6TfF0idE0RA=",
269
+ "System.Text.Json.0v0qgmri0w.dll": "sha256-3N6tKQuQtSdGn3qtvUdWOhhUlCzccYdgA25P3NFSLKI=",
270
270
  "System.Text.RegularExpressions.cvkox11l6l.dll": "sha256-WMuhtIW2iGfPEIJN2je+ijXB+VM7uodRrUIdvsXl4Q4=",
271
271
  "System.Threading.Channels.419493szqu.dll": "sha256-uBskY7pwTdtCHuVyY04ihoSM1DZ2QXqthW9t/BCLBIk=",
272
272
  "System.Threading.Thread.xhmys87xh5.dll": "sha256-ZRIAn9jRxhpyGpYyBH+MJbsb2SxgzNESn5/JGjqIVkY=",
@@ -278,18 +278,18 @@
278
278
  "System.Xml.XDocument.sn51jas17n.dll": "sha256-GNI2kFgFmPTwzuzwUn8gxK+AzGLUWRJFdg9JzIbrybQ=",
279
279
  "System.brmz7yk5qh.dll": "sha256-CfM2miyj1KHApFmqMdLYWio3S/jrdON2pW9Xr2nTwlo=",
280
280
  "netstandard.yvr3prsx0x.dll": "sha256-EksNn8Luo4bOWqJ6X7dIe9qG9oOqwOVzjH2xYyMNi+E=",
281
- "MindExecution.Core.csfu1xtj3l.dll": "sha256-lP9GUQU4xFLsUU4IOwpUjt09mQO5M/bgLAAS8UnjLMs=",
282
- "MindExecution.Kernel.mdo1lzjvvp.dll": "sha256-Vj21M+Th5MKfLG5Hvg6/uwlDDdwAJwzeIxfWsK9gYhM=",
283
- "MindExecution.Plugins.Concept.urf2igpscm.dll": "sha256-Wt70v+ewfVpQNKSMo/aRLfM1lB63lFl/gc8o3tJRsUE=",
284
- "MindExecution.Plugins.PlanMaster.88ikwl696h.dll": "sha256-uDJJpu3uYLPDj7P/pcAZfWQcSrwlMeJTE10hFgVqNrM=",
285
- "MindExecution.Shared.6aa15yqsqi.dll": "sha256-TneDrusLNLsSxPIeMiAAmkornUdHBE4lKZHTlBxG9mI=",
286
- "MindExecution.Web.8gp839zb62.dll": "sha256-KDaD6cqDNMvAoTAc6wfsq27l4tV/+tP3sOYx6r//KxA="
281
+ "MindExecution.Core.qprj2wqc9a.dll": "sha256-DnXZk8i9ukptBPjChSubsbWJIarYNileavZA4hihKJY=",
282
+ "MindExecution.Kernel.ksznt6ppyj.dll": "sha256-DAZ9Pzryh17vEhPOjVeFe+eCs/lgH5S0vxP9WFiTI2U=",
283
+ "MindExecution.Plugins.Concept.vrmey2vv08.dll": "sha256-y8SD/3+q7/5hBWFrizZ5w5QKJP8Nfz0NpV0XrT1eXxQ=",
284
+ "MindExecution.Plugins.PlanMaster.0pdulhmw15.dll": "sha256-LObinwzmz1i8etnhUMWcvdn6oZ7MSGkqfZnIcyakEFk=",
285
+ "MindExecution.Shared.oxf5h3gtl1.dll": "sha256-7Lze2YO8XmpwxtjLCUp/J9HND7AyKJyORksP8+XAua0=",
286
+ "MindExecution.Web.s43m8j3bg0.dll": "sha256-pCKvIt9SzRGSvNRSw/7lk7eG3RyzGrTZNolf1tx5T6A="
287
287
  },
288
288
  "lazyAssembly": {
289
- "MindExecution.Plugins.Admin.5fctwf65dx.dll": "sha256-37+Egd35menNv18hEZ64qjiu0x1r+wFOuO5zDiOGfug=",
290
- "MindExecution.Plugins.Business.nwivpk9djf.dll": "sha256-iTV0NyCB7fnU+l8brClBd+KYnBDw628yHCwoRrQdTWE=",
291
- "MindExecution.Plugins.Directory.jnzcrwl049.dll": "sha256-fwo2q8bt+WNuVUMnJCOcfLAy151cjLZCQa0Z+iKdsRs=",
292
- "MindExecution.Plugins.YouTube.wf48rh6hfh.dll": "sha256-hLixuuQuhimSYlTFe2yf75UnrSRfFv0PrkKxMdHtN0c="
289
+ "MindExecution.Plugins.Admin.ziclnsvcvi.dll": "sha256-VXbkR7uhooOS62ea02JNcfj2EpKxtIF4ZYRSvdO74kM=",
290
+ "MindExecution.Plugins.Business.q32f5kgky1.dll": "sha256-Zq3jwQKoz28lRtaqbPJgZenoBwrknjYBccYJhLOhYd4=",
291
+ "MindExecution.Plugins.Directory.3pet73jp0m.dll": "sha256-p7KSnHrHR4xFgP4WwKX0edQZgAhSsWqOcNRq4/oiH1I=",
292
+ "MindExecution.Plugins.YouTube.ye6w0jn4v9.dll": "sha256-eoQHQy2IbcBhJtbRR5HShNdMp7DJ4xOsFdwryQNoQrI="
293
293
  }
294
294
  },
295
295
  "cacheBootResources": true,
@@ -7,8 +7,8 @@
7
7
  <title>MindExec | Run your ideas as AI task graphs</title>
8
8
  <meta name="description" content="MindExec is an AI execution canvas for solo builders, researchers, developers, and creators. Start with free browser tools, then move serious work into saved MindCanvas projects." />
9
9
  <base href="/" />
10
- <link rel="stylesheet" href="_content/MindExecution.Shared/css/app.css?v=20260614-cloud-snapshot-rpc-v545" />
11
- <link rel="stylesheet" href="_content/MindExecution.Shared/css/mind-map-overrides.css?v=20260614-cloud-snapshot-rpc-v545" />
10
+ <link rel="stylesheet" href="_content/MindExecution.Shared/css/app.css?v=20260615-auth-session-v553" />
11
+ <link rel="stylesheet" href="_content/MindExecution.Shared/css/mind-map-overrides.css?v=20260615-auth-session-v553" />
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 = '20260614-cloud-snapshot-rpc-v545';
582
+ const scriptVersion = '20260615-auth-session-v553';
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": "fenz19NA",
2
+ "version": "mPvmdx5y",
3
3
  "assets": [
4
4
  {
5
5
  "hash": "sha256-+CSYMcqLNTsq3VnH11jgYyOCCdxvHzL74CBmo4sCmMU=",
@@ -86,7 +86,7 @@
86
86
  "url": "_content/MindExecution.Shared/js/mind-map-core.js.backup"
87
87
  },
88
88
  {
89
- "hash": "sha256-hzl6gNvjb9faAA2tUeCfriNvdohhGaDtasnYOCMum7E=",
89
+ "hash": "sha256-C/+w78To8XgmLIpNeOK3HtqkdKCQKklm792P0hSCaMk=",
90
90
  "url": "_content/MindExecution.Shared/js/mind-map-css3d-manager.js"
91
91
  },
92
92
  {
@@ -106,7 +106,7 @@
106
106
  "url": "_content/MindExecution.Shared/js/mind-map-glow-shader.js"
107
107
  },
108
108
  {
109
- "hash": "sha256-nseRIuaG6io+m/7GgaLuIS4srEQZYhVv8SQB2Z9aiF4=",
109
+ "hash": "sha256-QJh7a93uHYeGLXH8R87u9/oky9uJLW2p6eSMODlGjY0=",
110
110
  "url": "_content/MindExecution.Shared/js/mind-map-interactions.js"
111
111
  },
112
112
  {
@@ -114,7 +114,7 @@
114
114
  "url": "_content/MindExecution.Shared/js/mind-map-lod-plan-worker.js"
115
115
  },
116
116
  {
117
- "hash": "sha256-XwNOU+9TwMGIuKGjkijfVM68KlLN7k0fUYB/aInPg0k=",
117
+ "hash": "sha256-NTCDYnA/mG2tplidYmMv50OhHhdXjP985NlsjsyQ38g=",
118
118
  "url": "_content/MindExecution.Shared/js/mind-map-lod-renderer.js"
119
119
  },
120
120
  {
@@ -410,44 +410,44 @@
410
410
  "url": "_framework/MimeMapping.og9ys58ylm.dll"
411
411
  },
412
412
  {
413
- "hash": "sha256-lP9GUQU4xFLsUU4IOwpUjt09mQO5M/bgLAAS8UnjLMs=",
414
- "url": "_framework/MindExecution.Core.csfu1xtj3l.dll"
413
+ "hash": "sha256-DnXZk8i9ukptBPjChSubsbWJIarYNileavZA4hihKJY=",
414
+ "url": "_framework/MindExecution.Core.qprj2wqc9a.dll"
415
415
  },
416
416
  {
417
- "hash": "sha256-Vj21M+Th5MKfLG5Hvg6/uwlDDdwAJwzeIxfWsK9gYhM=",
418
- "url": "_framework/MindExecution.Kernel.mdo1lzjvvp.dll"
417
+ "hash": "sha256-DAZ9Pzryh17vEhPOjVeFe+eCs/lgH5S0vxP9WFiTI2U=",
418
+ "url": "_framework/MindExecution.Kernel.ksznt6ppyj.dll"
419
419
  },
420
420
  {
421
- "hash": "sha256-37+Egd35menNv18hEZ64qjiu0x1r+wFOuO5zDiOGfug=",
422
- "url": "_framework/MindExecution.Plugins.Admin.5fctwf65dx.dll"
421
+ "hash": "sha256-VXbkR7uhooOS62ea02JNcfj2EpKxtIF4ZYRSvdO74kM=",
422
+ "url": "_framework/MindExecution.Plugins.Admin.ziclnsvcvi.dll"
423
423
  },
424
424
  {
425
- "hash": "sha256-iTV0NyCB7fnU+l8brClBd+KYnBDw628yHCwoRrQdTWE=",
426
- "url": "_framework/MindExecution.Plugins.Business.nwivpk9djf.dll"
425
+ "hash": "sha256-Zq3jwQKoz28lRtaqbPJgZenoBwrknjYBccYJhLOhYd4=",
426
+ "url": "_framework/MindExecution.Plugins.Business.q32f5kgky1.dll"
427
427
  },
428
428
  {
429
- "hash": "sha256-Wt70v+ewfVpQNKSMo/aRLfM1lB63lFl/gc8o3tJRsUE=",
430
- "url": "_framework/MindExecution.Plugins.Concept.urf2igpscm.dll"
429
+ "hash": "sha256-y8SD/3+q7/5hBWFrizZ5w5QKJP8Nfz0NpV0XrT1eXxQ=",
430
+ "url": "_framework/MindExecution.Plugins.Concept.vrmey2vv08.dll"
431
431
  },
432
432
  {
433
- "hash": "sha256-fwo2q8bt+WNuVUMnJCOcfLAy151cjLZCQa0Z+iKdsRs=",
434
- "url": "_framework/MindExecution.Plugins.Directory.jnzcrwl049.dll"
433
+ "hash": "sha256-p7KSnHrHR4xFgP4WwKX0edQZgAhSsWqOcNRq4/oiH1I=",
434
+ "url": "_framework/MindExecution.Plugins.Directory.3pet73jp0m.dll"
435
435
  },
436
436
  {
437
- "hash": "sha256-uDJJpu3uYLPDj7P/pcAZfWQcSrwlMeJTE10hFgVqNrM=",
438
- "url": "_framework/MindExecution.Plugins.PlanMaster.88ikwl696h.dll"
437
+ "hash": "sha256-LObinwzmz1i8etnhUMWcvdn6oZ7MSGkqfZnIcyakEFk=",
438
+ "url": "_framework/MindExecution.Plugins.PlanMaster.0pdulhmw15.dll"
439
439
  },
440
440
  {
441
- "hash": "sha256-hLixuuQuhimSYlTFe2yf75UnrSRfFv0PrkKxMdHtN0c=",
442
- "url": "_framework/MindExecution.Plugins.YouTube.wf48rh6hfh.dll"
441
+ "hash": "sha256-eoQHQy2IbcBhJtbRR5HShNdMp7DJ4xOsFdwryQNoQrI=",
442
+ "url": "_framework/MindExecution.Plugins.YouTube.ye6w0jn4v9.dll"
443
443
  },
444
444
  {
445
- "hash": "sha256-TneDrusLNLsSxPIeMiAAmkornUdHBE4lKZHTlBxG9mI=",
446
- "url": "_framework/MindExecution.Shared.6aa15yqsqi.dll"
445
+ "hash": "sha256-7Lze2YO8XmpwxtjLCUp/J9HND7AyKJyORksP8+XAua0=",
446
+ "url": "_framework/MindExecution.Shared.oxf5h3gtl1.dll"
447
447
  },
448
448
  {
449
- "hash": "sha256-KDaD6cqDNMvAoTAc6wfsq27l4tV/+tP3sOYx6r//KxA=",
450
- "url": "_framework/MindExecution.Web.8gp839zb62.dll"
449
+ "hash": "sha256-pCKvIt9SzRGSvNRSw/7lk7eG3RyzGrTZNolf1tx5T6A=",
450
+ "url": "_framework/MindExecution.Web.s43m8j3bg0.dll"
451
451
  },
452
452
  {
453
453
  "hash": "sha256-IsZJ91/OW+fHzNqIgEc7Y072ns8z9dGritiSyvR9Wgc=",
@@ -722,8 +722,8 @@
722
722
  "url": "_framework/System.Text.Encodings.Web.wftjfh2crk.dll"
723
723
  },
724
724
  {
725
- "hash": "sha256-VBeG+FY8NhlMOdQOTUozG5Zn+jrC3jPw6TfF0idE0RA=",
726
- "url": "_framework/System.Text.Json.4s25e3op6i.dll"
725
+ "hash": "sha256-3N6tKQuQtSdGn3qtvUdWOhhUlCzccYdgA25P3NFSLKI=",
726
+ "url": "_framework/System.Text.Json.0v0qgmri0w.dll"
727
727
  },
728
728
  {
729
729
  "hash": "sha256-WMuhtIW2iGfPEIJN2je+ijXB+VM7uodRrUIdvsXl4Q4=",
@@ -770,7 +770,7 @@
770
770
  "url": "_framework/Websocket.Client.vapounvmnl.dll"
771
771
  },
772
772
  {
773
- "hash": "sha256-wQvF4BNyeJqPVcMEHfyJfBzt/cPWl4IlZ5aq0sIaI+A=",
773
+ "hash": "sha256-nFSI4H6aGg61G8/I7AXIvRFAlfAVhpij+EjRsJ4tctg=",
774
774
  "url": "_framework/blazor.boot.json"
775
775
  },
776
776
  {
@@ -834,7 +834,7 @@
834
834
  "url": "image-manifest.json"
835
835
  },
836
836
  {
837
- "hash": "sha256-6gWdXbSErtDsra/qSzpM3jZXQ5z+Ug6S53/VkuNS9uU=",
837
+ "hash": "sha256-voojFCn8RinDrshRS7nUvpusiYKr/QFSZS0h4auGgOM=",
838
838
  "url": "index.html"
839
839
  },
840
840
  {
@@ -1,4 +1,4 @@
1
- /* Manifest version: fenz19NA */
1
+ /* Manifest version: mPvmdx5y */
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