@mindexec/cli 0.2.21 → 0.2.23

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 (21) hide show
  1. package/package.json +1 -1
  2. package/remote-hub.js +4 -4
  3. package/scripts/remote-fleet-render-smoke.mjs +71 -3
  4. package/scripts/remote-http-smoke.mjs +31 -4
  5. package/scripts/remote-hub-scale-smoke.mjs +5 -4
  6. package/server.js +22 -3
  7. package/wwwroot/_content/MindExecution.Shared/js/mind-map-css3d-manager.js +1 -1
  8. package/wwwroot/_framework/{MindExecution.Core.ckgjbdvvxl.dll → MindExecution.Core.c9fyqe953v.dll} +0 -0
  9. package/wwwroot/_framework/{MindExecution.Kernel.lm7kgq8l8h.dll → MindExecution.Kernel.badrt1tkvv.dll} +0 -0
  10. package/wwwroot/_framework/{MindExecution.Plugins.Admin.k085kt3dls.dll → MindExecution.Plugins.Admin.73w1bvz4r1.dll} +0 -0
  11. package/wwwroot/_framework/{MindExecution.Plugins.Business.dsz9uwkxih.dll → MindExecution.Plugins.Business.dvd82y422m.dll} +0 -0
  12. package/wwwroot/_framework/{MindExecution.Plugins.Concept.wnkch6jqjz.dll → MindExecution.Plugins.Concept.m3ukc0xvom.dll} +0 -0
  13. package/wwwroot/_framework/{MindExecution.Plugins.Directory.ufbriq6js4.dll → MindExecution.Plugins.Directory.23tm2uvfvu.dll} +0 -0
  14. package/wwwroot/_framework/{MindExecution.Plugins.PlanMaster.ygbsp1z4z0.dll → MindExecution.Plugins.PlanMaster.8nrc7ge4ob.dll} +0 -0
  15. package/wwwroot/_framework/{MindExecution.Plugins.YouTube.a992061fhz.dll → MindExecution.Plugins.YouTube.3ox59073d8.dll} +0 -0
  16. package/wwwroot/_framework/{MindExecution.Shared.y27t6njaw0.dll → MindExecution.Shared.va1gxp0crd.dll} +0 -0
  17. package/wwwroot/_framework/{MindExecution.Web.bqamgu5gq1.dll → MindExecution.Web.jmawk7z8d3.dll} +0 -0
  18. package/wwwroot/_framework/blazor.boot.json +21 -21
  19. package/wwwroot/index.html +1 -1
  20. package/wwwroot/service-worker-assets.js +24 -24
  21. package/wwwroot/service-worker.js +1 -1
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@mindexec/cli",
3
- "version": "0.2.21",
3
+ "version": "0.2.23",
4
4
  "description": "MindExec local runtime and bridge CLI",
5
5
  "main": "server.js",
6
6
  "type": "module",
package/remote-hub.js CHANGED
@@ -289,7 +289,7 @@ export function createRemoteHub(options = {}) {
289
289
  mimeType: 'image/png',
290
290
  format: 'image/png',
291
291
  mode,
292
- fps: clampNumber(options.fps, 1, 24, mode === 'remote-fast' ? 12 : 1),
292
+ fps: clampNumber(options.fps, 1, 24, mode === 'remote-fast' ? 20 : 1),
293
293
  capturedAt: now,
294
294
  receivedAt: now,
295
295
  byteLength: 68,
@@ -503,7 +503,7 @@ export function createRemoteHub(options = {}) {
503
503
  commandId: `synthetic-live-command-${ordinal}`,
504
504
  active: true,
505
505
  mode: 'remote-fast',
506
- fps: 12,
506
+ fps: 20,
507
507
  startedAt: seenAt,
508
508
  stoppedAt: '',
509
509
  stopReason: '',
@@ -513,7 +513,7 @@ export function createRemoteHub(options = {}) {
513
513
  };
514
514
  applySyntheticLiveFrame(device, device.activeLiveStream.streamId, {
515
515
  commandId: device.activeLiveStream.commandId,
516
- fps: 12
516
+ fps: 20
517
517
  });
518
518
  live += 1;
519
519
  }
@@ -1528,7 +1528,7 @@ export function createRemoteHub(options = {}) {
1528
1528
 
1529
1529
  const now = new Date().toISOString();
1530
1530
  const streamId = safeString(options.streamId, 128) || `live-${Date.now()}`;
1531
- const fps = clampNumber(options.fps, 1, 24, 12);
1531
+ const fps = clampNumber(options.fps, 1, 24, 20);
1532
1532
  const commandId = safeString(options.commandId, 128) || crypto.randomUUID();
1533
1533
  device.counters.commandsSent += 1;
1534
1534
  device.activeLiveStream = {
@@ -7,7 +7,7 @@ import vm from 'node:vm';
7
7
  import { fileURLToPath } from 'node:url';
8
8
  import { createRemoteHub } from '../remote-hub.js';
9
9
 
10
- const SYNTHETIC_COUNT = Number(process.env.REMOTE_FLEET_RENDER_SMOKE_COUNT || 250);
10
+ const SYNTHETIC_COUNT = Number(process.env.REMOTE_FLEET_RENDER_SMOKE_COUNT || 500);
11
11
 
12
12
  function dataAttributeToDatasetKey(name) {
13
13
  return String(name || '').replace(/^data-/, '').replace(/-([a-z])/g, (_, char) => char.toUpperCase());
@@ -526,12 +526,25 @@ try {
526
526
  });
527
527
  assert.equal(renderAiTask.ok, true);
528
528
 
529
+ const seededLiveTarget = hub.listDevices().find(device =>
530
+ device.connected && device.capabilities?.liveStream);
531
+ assert.ok(seededLiveTarget);
532
+ const renderLive = hub.startLiveStream(seededLiveTarget.deviceId, {
533
+ streamId: 'render-smoke-live',
534
+ fps: 20,
535
+ maxWidth: 960,
536
+ maxHeight: 540,
537
+ quality: 60
538
+ });
539
+ assert.equal(renderLive.ok, true);
540
+
529
541
  const rawDevices = hub.listDevices();
530
542
  const devices = rawDevices.map(projectDevice);
531
543
  const connectedCount = devices.filter(device => device.Connected).length;
532
544
  const offlineCount = devices.length - connectedCount;
533
545
  const aiCount = devices.filter(device => device.Connected && device.AiAssistEnabled).length;
534
- const focusedDevice = devices.find(device => device.Connected);
546
+ const focusedDevice = devices.find(device => device.Connected && device.LiveStreamActive)
547
+ || devices.find(device => device.Connected);
535
548
  assert.ok(focusedDevice);
536
549
  focusedDevice.LatestTaskId = 'render-smoke-timeout-task';
537
550
  focusedDevice.LatestTaskCommandId = 'render-smoke-timeout-command';
@@ -614,6 +627,18 @@ try {
614
627
  };
615
628
  }
616
629
 
630
+ if (methodName === 'DispatchRemoteFleetTaskFromJs') {
631
+ const useAiAssist = args[3] === true;
632
+ const total = useAiAssist ? aiCount : connectedCount;
633
+ return {
634
+ success: true,
635
+ total,
636
+ queued: total,
637
+ failed: 0,
638
+ approvalLevel: useAiAssist ? 'ai-assist' : 'task-only'
639
+ };
640
+ }
641
+
617
642
  return { success: true };
618
643
  }
619
644
  };
@@ -632,9 +657,11 @@ try {
632
657
  assert.equal(bodyView.querySelectorAll('[data-remote-fleet-action="pin-device"]').length, SYNTHETIC_COUNT);
633
658
  assert.equal(bodyView.querySelectorAll('[data-remote-fleet-action="task-device"]').length, connectedCount);
634
659
  assert.equal(bodyView.querySelectorAll('[data-remote-fleet-action="thumbnail-device"]').length, devices.filter(device => device.Connected && device.ThumbnailEnabled).length);
635
- assert.equal(bodyView.querySelector('[data-remote-fleet-live-panel="true"]')?.dataset.deviceId, focusedDevice.DeviceId);
660
+ const livePanel = bodyView.querySelector('[data-remote-fleet-live-panel="true"]');
661
+ assert.equal(livePanel?.dataset.deviceId, focusedDevice.DeviceId);
636
662
  assert.equal(bodyView.querySelector('[data-remote-fleet-action="task-visible"]')?.disabled, false);
637
663
  assert.ok(bodyView.textContent.includes('all devices, no paging'));
664
+ assert.ok(livePanel?.textContent.includes('RemoteFast 20 fps'), livePanel?.textContent || bodyView.textContent);
638
665
  assert.ok(bodyView.querySelector('code')?.textContent.includes('npx @mindexec/remote connect'));
639
666
  assert.ok(bodyView.textContent.includes('synthetic-render-ai'));
640
667
  assert.ok(bodyView.textContent.includes('Task timed out waiting for the agent response.'));
@@ -702,6 +729,47 @@ try {
702
729
  assert.match(feedback.textContent, new RegExp(`Queued ${connectedCount - 1}/${connectedCount} visible remote task\\(s\\); 1 failed`));
703
730
  assert.match(feedback.textContent, /device-ai-assist-unavailable/);
704
731
 
732
+ const activeSelects = bodyView.querySelectorAll('select');
733
+ assert.equal(activeSelects.length, 4);
734
+ const [aiFilterSelect] = activeSelects;
735
+ const aiToggle = bodyView.querySelector('[data-remote-fleet-ai-toggle="true"]');
736
+ assert.ok(aiToggle);
737
+ aiFilterSelect.value = 'ai';
738
+ aiFilterSelect.dispatchEvent({ type: 'change' });
739
+ aiToggle.checked = true;
740
+ aiToggle.dispatchEvent({ type: 'change' });
741
+ assert.equal(bodyView.querySelector('[data-remote-fleet-match-count="true"]')?.textContent, `${aiCount}/${SYNTHETIC_COUNT}`);
742
+ assert.equal(sendVisibleButton.disabled, false);
743
+ taskInput.value = 'Dispatch visible AI smoke';
744
+ const aiDispatchCallStart = dotNetCalls.length;
745
+ sendVisibleButton.dispatchEvent({ type: 'click' });
746
+ await wait();
747
+ const aiBatchCall = dotNetCalls
748
+ .slice(aiDispatchCallStart)
749
+ .find(call => call.methodName === 'DispatchRemoteFleetTaskBatchFromJs');
750
+ assert.ok(aiBatchCall);
751
+ const aiTargetIds = Array.isArray(aiBatchCall.args[1]) ? aiBatchCall.args[1] : [];
752
+ const expectedAiTargetIds = devices
753
+ .filter(device => device.Connected && device.AiAssistEnabled)
754
+ .map(device => device.DeviceId)
755
+ .sort();
756
+ assert.deepEqual([...aiTargetIds].sort(), expectedAiTargetIds);
757
+ assert.equal(aiBatchCall.args[3], true);
758
+
759
+ const sendConnectedButton = bodyView.querySelector('[data-remote-fleet-action="task-connected"]');
760
+ assert.ok(sendConnectedButton);
761
+ taskInput.value = 'Dispatch all AI smoke';
762
+ const allAiDispatchCallStart = dotNetCalls.length;
763
+ sendConnectedButton.dispatchEvent({ type: 'click' });
764
+ await wait();
765
+ const allAiCall = dotNetCalls
766
+ .slice(allAiDispatchCallStart)
767
+ .find(call => call.methodName === 'DispatchRemoteFleetTaskFromJs');
768
+ assert.ok(allAiCall);
769
+ assert.equal(allAiCall.args[1], '');
770
+ assert.equal(allAiCall.args[3], true);
771
+ assert.match(feedback.textContent, new RegExp(`Queued ${aiCount}/${aiCount} AI task\\(s\\)`));
772
+
705
773
  const deviceBody = document.createElement('div');
706
774
  document.body.appendChild(deviceBody);
707
775
  manager.renderRemoteFleetDeviceForTest(deviceBody, buildDeviceNode(focusedDevice, hub.getStatus()));
@@ -8,7 +8,7 @@ import { fileURLToPath } from 'node:url';
8
8
 
9
9
  const BRIDGE_TOKEN = 'remote-http-smoke-token';
10
10
  const PAIR_TOKEN = 'remote-http-pair-token';
11
- const SYNTHETIC_COUNT = Number(process.env.REMOTE_HTTP_SMOKE_COUNT || 250);
11
+ const SYNTHETIC_COUNT = Number(process.env.REMOTE_HTTP_SMOKE_COUNT || 500);
12
12
 
13
13
  function wait(ms) {
14
14
  return new Promise(resolve => setTimeout(resolve, ms));
@@ -148,9 +148,9 @@ try {
148
148
 
149
149
  const connectedTargets = devicesResult.payload.devices
150
150
  .filter(device => device.connected && device.capabilities?.taskDispatch)
151
- .slice(0, 200)
151
+ .slice(0, 500)
152
152
  .map(device => device.deviceId);
153
- assert.ok(connectedTargets.length >= 100);
153
+ assert.ok(connectedTargets.length >= 400);
154
154
 
155
155
  const batch = await fetchJson(`${baseUrl}/api/remote/tasks`, {
156
156
  method: 'POST',
@@ -171,6 +171,32 @@ try {
171
171
  assert.equal(batch.payload?.batch?.failed, 0);
172
172
  assert.equal(batch.payload?.batch?.status, 'completed');
173
173
 
174
+ const aiTargets = devicesResult.payload.devices
175
+ .filter(device => device.connected && device.capabilities?.taskDispatch && device.capabilities?.aiAssist)
176
+ .map(device => device.deviceId);
177
+ assert.ok(aiTargets.length >= 200);
178
+ const allAiBatch = await fetchJson(`${baseUrl}/api/remote/tasks`, {
179
+ method: 'POST',
180
+ token: BRIDGE_TOKEN,
181
+ body: JSON.stringify({
182
+ allConnected: true,
183
+ title: 'HTTP smoke all AI task batch',
184
+ instruction: 'HTTP smoke AI batch: summarize fleet condition only on AI-capable agents.',
185
+ approvalLevel: 'ai-assist'
186
+ })
187
+ });
188
+ assert.equal(allAiBatch.ok, true, JSON.stringify(allAiBatch.payload));
189
+ assert.equal(allAiBatch.payload?.ok, true);
190
+ assert.equal(allAiBatch.payload?.approvalLevel, 'ai-assist');
191
+ assert.equal(allAiBatch.payload?.total, aiTargets.length);
192
+ assert.equal(allAiBatch.payload?.queued, aiTargets.length);
193
+ assert.equal(allAiBatch.payload?.batch?.completed, aiTargets.length);
194
+ assert.equal(allAiBatch.payload?.batch?.failed, 0);
195
+ assert.equal(allAiBatch.payload?.batch?.status, 'completed');
196
+ assert.deepEqual(
197
+ [...(allAiBatch.payload?.results || []).map(result => result.deviceId)].sort(),
198
+ [...aiTargets].sort());
199
+
174
200
  const aiTarget = devicesResult.payload.devices.find(device =>
175
201
  device.connected && device.capabilities?.taskDispatch && device.capabilities?.aiAssist);
176
202
  assert.ok(aiTarget);
@@ -218,7 +244,7 @@ try {
218
244
  token: BRIDGE_TOKEN,
219
245
  body: JSON.stringify({
220
246
  streamId: 'http-smoke-live',
221
- fps: 12,
247
+ fps: 20,
222
248
  maxWidth: 960,
223
249
  maxHeight: 540,
224
250
  quality: 60
@@ -233,6 +259,7 @@ try {
233
259
  assert.equal(liveFrame.ok, true, JSON.stringify(liveFrame.payload));
234
260
  assert.equal(liveFrame.payload?.frame?.streamId, 'http-smoke-live');
235
261
  assert.equal(liveFrame.payload?.frame?.mode, 'remote-fast');
262
+ assert.equal(liveFrame.payload?.frame?.fps, 20);
236
263
 
237
264
  const liveStop = await fetchJson(`${baseUrl}/api/remote/devices/${encodeURIComponent(liveTarget.deviceId)}/live/stop`, {
238
265
  method: 'POST',
@@ -3,7 +3,7 @@
3
3
  import assert from 'assert/strict';
4
4
  import { createRemoteHub } from '../remote-hub.js';
5
5
 
6
- const SYNTHETIC_COUNT = Number(process.env.REMOTE_HUB_SCALE_SMOKE_COUNT || 250);
6
+ const SYNTHETIC_COUNT = Number(process.env.REMOTE_HUB_SCALE_SMOKE_COUNT || 500);
7
7
 
8
8
  const hub = createRemoteHub({
9
9
  env: {
@@ -63,20 +63,21 @@ try {
63
63
  assert.ok(liveTarget);
64
64
  const liveResult = hub.startLiveStream(liveTarget.deviceId, {
65
65
  streamId: 'scale-live',
66
- fps: 12,
66
+ fps: 20,
67
67
  maxWidth: 960,
68
68
  maxHeight: 540,
69
69
  quality: 60
70
70
  });
71
71
  assert.equal(liveResult.ok, true);
72
72
  assert.equal(hub.getDeviceLiveFrame(liveTarget.deviceId).streamId, 'scale-live');
73
+ assert.equal(hub.getDeviceLiveFrame(liveTarget.deviceId).fps, 20);
73
74
  const stopResult = hub.stopLiveStream(liveTarget.deviceId, { streamId: 'scale-live' });
74
75
  assert.equal(stopResult.ok, true);
75
76
 
76
77
  const connectedTargets = hub.listDevices()
77
78
  .filter(device => device.connected && device.capabilities?.taskDispatch)
78
- .slice(0, 200);
79
- assert.ok(connectedTargets.length >= 100);
79
+ .slice(0, 500);
80
+ assert.ok(connectedTargets.length >= 400);
80
81
  const scaleBatch = hub.requestAgentTaskBatch(connectedTargets.map(device => device.deviceId), {
81
82
  instruction: 'Synthetic scale task: report current status to the manager.',
82
83
  title: 'Scale task batch'
package/server.js CHANGED
@@ -7038,15 +7038,21 @@ app.post('/api/remote/tasks', (req, res) => {
7038
7038
  ? req.body.deviceIds.map(value => String(value || '').trim()).filter(Boolean)
7039
7039
  : [];
7040
7040
  const allConnected = req.body?.allConnected !== false;
7041
+ const approvalLevel = req.body?.approvalLevel === 'ai-assist' ? 'ai-assist' : 'task-only';
7041
7042
  const devices = remoteHub.listDevices();
7042
7043
  const targetIds = requestedDeviceIds.length > 0
7043
7044
  ? requestedDeviceIds
7044
- : (allConnected ? devices.filter(device => device.connected).map(device => device.deviceId) : []);
7045
+ : (allConnected
7046
+ ? devices
7047
+ .filter(device => device.connected)
7048
+ .filter(device => approvalLevel !== 'ai-assist' || isRemoteCapabilityEnabled(device, 'aiAssist'))
7049
+ .map(device => device.deviceId)
7050
+ : []);
7045
7051
  const uniqueTargetIds = [...new Set(targetIds)].slice(0, 500);
7046
7052
  const result = remoteHub.requestAgentTaskBatch(uniqueTargetIds, {
7047
7053
  instruction: req.body?.instruction,
7048
7054
  title: req.body?.title,
7049
- approvalLevel: req.body?.approvalLevel,
7055
+ approvalLevel,
7050
7056
  model: req.body?.model,
7051
7057
  batchId: req.body?.batchId
7052
7058
  });
@@ -7055,11 +7061,24 @@ app.post('/api/remote/tasks', (req, res) => {
7055
7061
  ok: result.ok === true,
7056
7062
  total: uniqueTargetIds.length,
7057
7063
  queued: result.queued || 0,
7058
- approvalLevel: req.body?.approvalLevel === 'ai-assist' ? 'ai-assist' : 'task-only',
7064
+ approvalLevel,
7059
7065
  error: result.ok === true ? undefined : (uniqueTargetIds.length === 0 ? 'no-target-devices' : (result.error || 'no-task-queued'))
7060
7066
  });
7061
7067
  });
7062
7068
 
7069
+ function isRemoteCapabilityEnabled(device, key) {
7070
+ const value = device?.capabilities?.[key];
7071
+ if (typeof value === 'boolean') {
7072
+ return value;
7073
+ }
7074
+
7075
+ if (typeof value === 'number') {
7076
+ return value !== 0;
7077
+ }
7078
+
7079
+ return /^(1|true|yes|on)$/i.test(String(value || '').trim());
7080
+ }
7081
+
7063
7082
  app.get('/api/remote/devices/:deviceId/thumbnail', (req, res) => {
7064
7083
  res.setHeader('Cache-Control', 'no-store');
7065
7084
  const thumbnail = remoteHub.getDeviceThumbnail(req.params.deviceId);
@@ -13554,7 +13554,7 @@
13554
13554
  liveName.style.cssText = 'color:#0f172a;font-size:15px;font-weight:950;line-height:1.15;overflow:hidden;text-overflow:ellipsis;white-space:nowrap;letter-spacing:0;';
13555
13555
  const liveMeta = document.createElement('span');
13556
13556
  liveMeta.textContent = liveActive
13557
- ? `RemoteFast ${getRemoteFleetDeviceField(focusedDevice, 'liveStreamFps', 'LiveStreamFps', 0) || 12} fps`
13557
+ ? `RemoteFast ${getRemoteFleetDeviceField(focusedDevice, 'liveStreamFps', 'LiveStreamFps', 0) || 20} fps`
13558
13558
  : 'View-only focused screen stream';
13559
13559
  liveMeta.style.cssText = 'color:#475569;font-size:11px;font-weight:800;line-height:1.25;overflow:hidden;text-overflow:ellipsis;white-space:nowrap;letter-spacing:0;';
13560
13560
  liveTitle.appendChild(liveName);
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "mainAssemblyName": "MindExecution.Web",
3
3
  "resources": {
4
- "hash": "sha256-uiy622hnTDJkSexxzoeajNAT7LDKXgnVH7DvRNAiX9w=",
4
+ "hash": "sha256-U10u85TRNQ5EuHSJ6CDlslJbcSBCmbE+UPKJl/T8OtY=",
5
5
  "fingerprinting": {
6
6
  "Google.Protobuf.9h59ukbel7.dll": "Google.Protobuf.dll",
7
7
  "Markdig.d1j7v41cl1.dll": "Markdig.dll",
@@ -123,16 +123,16 @@
123
123
  "System.m05i39uvk9.dll": "System.dll",
124
124
  "netstandard.0xet7jg7ky.dll": "netstandard.dll",
125
125
  "System.Private.CoreLib.rkafq04oma.dll": "System.Private.CoreLib.dll",
126
- "MindExecution.Core.ckgjbdvvxl.dll": "MindExecution.Core.dll",
127
- "MindExecution.Kernel.lm7kgq8l8h.dll": "MindExecution.Kernel.dll",
128
- "MindExecution.Plugins.Admin.k085kt3dls.dll": "MindExecution.Plugins.Admin.dll",
129
- "MindExecution.Plugins.Business.dsz9uwkxih.dll": "MindExecution.Plugins.Business.dll",
130
- "MindExecution.Plugins.Concept.wnkch6jqjz.dll": "MindExecution.Plugins.Concept.dll",
131
- "MindExecution.Plugins.Directory.ufbriq6js4.dll": "MindExecution.Plugins.Directory.dll",
132
- "MindExecution.Plugins.PlanMaster.ygbsp1z4z0.dll": "MindExecution.Plugins.PlanMaster.dll",
133
- "MindExecution.Plugins.YouTube.a992061fhz.dll": "MindExecution.Plugins.YouTube.dll",
134
- "MindExecution.Shared.y27t6njaw0.dll": "MindExecution.Shared.dll",
135
- "MindExecution.Web.bqamgu5gq1.dll": "MindExecution.Web.dll",
126
+ "MindExecution.Core.c9fyqe953v.dll": "MindExecution.Core.dll",
127
+ "MindExecution.Kernel.badrt1tkvv.dll": "MindExecution.Kernel.dll",
128
+ "MindExecution.Plugins.Admin.73w1bvz4r1.dll": "MindExecution.Plugins.Admin.dll",
129
+ "MindExecution.Plugins.Business.dvd82y422m.dll": "MindExecution.Plugins.Business.dll",
130
+ "MindExecution.Plugins.Concept.m3ukc0xvom.dll": "MindExecution.Plugins.Concept.dll",
131
+ "MindExecution.Plugins.Directory.23tm2uvfvu.dll": "MindExecution.Plugins.Directory.dll",
132
+ "MindExecution.Plugins.PlanMaster.8nrc7ge4ob.dll": "MindExecution.Plugins.PlanMaster.dll",
133
+ "MindExecution.Plugins.YouTube.3ox59073d8.dll": "MindExecution.Plugins.YouTube.dll",
134
+ "MindExecution.Shared.va1gxp0crd.dll": "MindExecution.Shared.dll",
135
+ "MindExecution.Web.jmawk7z8d3.dll": "MindExecution.Web.dll",
136
136
  "dotnet.js": "dotnet.js",
137
137
  "dotnet.native.xsn1d6x2kd.js": "dotnet.native.js",
138
138
  "dotnet.native.vz0adxojrz.wasm": "dotnet.native.wasm",
@@ -278,18 +278,18 @@
278
278
  "System.Xml.XDocument.c539ki6cuq.dll": "sha256-MPTRJkptrL9nGa2tl4kF46+wErNUYRPCGblX3ANoKoY=",
279
279
  "System.m05i39uvk9.dll": "sha256-5jDfIdbYAigw7/Q/lMzt5W/+cayGbW9ko9FvuaN1GsQ=",
280
280
  "netstandard.0xet7jg7ky.dll": "sha256-xENDv620uJ8fHwLJ2bdhrTHz4QPjvqXOztnk2a4wr0c=",
281
- "MindExecution.Core.ckgjbdvvxl.dll": "sha256-ZDas50sgMQGCNt0UC1ZErP+uv7PQ7z/skK7zCwnmU2I=",
282
- "MindExecution.Kernel.lm7kgq8l8h.dll": "sha256-ndscepu8d8g/nrJmBP8VrkIOTIkSA57t5shOq/rp/ys=",
283
- "MindExecution.Plugins.Concept.wnkch6jqjz.dll": "sha256-nCycvHAVswddeF1J0XSbpQSsVsutbCpx+52o7ne+kZw=",
284
- "MindExecution.Plugins.PlanMaster.ygbsp1z4z0.dll": "sha256-ErbKkuXxJANIiJahFjEUZq9TH1Kz/y2LEuepW6ZxJnU=",
285
- "MindExecution.Shared.y27t6njaw0.dll": "sha256-Gvuf30dJMtENks7FSoBydnPkKJp4NS10DjvJmsTLEV0=",
286
- "MindExecution.Web.bqamgu5gq1.dll": "sha256-LYhJEP8rDmDCLhf8aQxkiGEmpsffoNzT6S37CxSfNQ8="
281
+ "MindExecution.Core.c9fyqe953v.dll": "sha256-QFzKrrCvQhHKuzHmjZNnWfLRs8Zvg90nlG23JMRuPiA=",
282
+ "MindExecution.Kernel.badrt1tkvv.dll": "sha256-Ay3ypEtsJuNsBYsha1gUwQ98jBnWGZFyOEEd2TmsNew=",
283
+ "MindExecution.Plugins.Concept.m3ukc0xvom.dll": "sha256-YjENe8QVAOo4XYknnQD3hSMouQMSQQQ7sryMHObA0Qc=",
284
+ "MindExecution.Plugins.PlanMaster.8nrc7ge4ob.dll": "sha256-DGJpulGGAuvc9KS9plHJi8BLX8EBiqV3A90QMAadYCY=",
285
+ "MindExecution.Shared.va1gxp0crd.dll": "sha256-ly99wDAapShB+jZ1V95wYNfWyd1Q+JNGxL870fY6XKI=",
286
+ "MindExecution.Web.jmawk7z8d3.dll": "sha256-yz2Mpwuz+oEBj6sVtdQOjSPIrLj4cQICK7ZDFVWwy5o="
287
287
  },
288
288
  "lazyAssembly": {
289
- "MindExecution.Plugins.Admin.k085kt3dls.dll": "sha256-LLDLGzE3yaP+rL+8CMZGWBmGQZBfrRWgUMijX/fxTxw=",
290
- "MindExecution.Plugins.Business.dsz9uwkxih.dll": "sha256-bfvFu7Pq58deN7TnwfhsUZdvWhS4RpA0LdO77UsBnY8=",
291
- "MindExecution.Plugins.Directory.ufbriq6js4.dll": "sha256-qoxaegrVr9oaXJgQqU7t7CrCf0EYgsd22BcWXg/+91I=",
292
- "MindExecution.Plugins.YouTube.a992061fhz.dll": "sha256-orw8lB1/+iy3s9EoeG+MDueyomsbPTC7vq0UIjUwtfQ="
289
+ "MindExecution.Plugins.Admin.73w1bvz4r1.dll": "sha256-s0/shhl1o5sjys9RDDMPM5TWYZNk64K5RggeZ8gsDKA=",
290
+ "MindExecution.Plugins.Business.dvd82y422m.dll": "sha256-OcLlpkGPe6VinOzGw5cDKNjIcQLZW+nv6zGjvzewc8w=",
291
+ "MindExecution.Plugins.Directory.23tm2uvfvu.dll": "sha256-vmai+Tkzmk5CeReKLxTMz/gp+uPrt8EaftPIbljEZ0E=",
292
+ "MindExecution.Plugins.YouTube.3ox59073d8.dll": "sha256-Te3jpmTgl3HFoKoMct4HMXhg6a9PgTHmVaQltQjKrak="
293
293
  }
294
294
  },
295
295
  "cacheBootResources": true,
@@ -558,7 +558,7 @@
558
558
  }
559
559
 
560
560
  const base = '_content/MindExecution.Shared/js/';
561
- const scriptVersion = '20260612-remote-task-follow-v478';
561
+ const scriptVersion = '20260612-remote-fast-20fps-v479';
562
562
  const scriptUrl = (script) => `${base}${script}?v=${scriptVersion}`;
563
563
  console.log(`[Script Loader] Shared JS version: ${scriptVersion}`);
564
564
  const criticalScripts = [
@@ -1,5 +1,5 @@
1
1
  self.assetsManifest = {
2
- "version": "dr5Y7e+X",
2
+ "version": "4y4C9wve",
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-r/rKyK7pwOufIiynKaiu7pt8CgoBdLd7u+FmbZHVbko=",
89
+ "hash": "sha256-E6d/sEnHvzwsyrryEFowSagM2Y3LCxsotUHJe+5X9mE=",
90
90
  "url": "_content/MindExecution.Shared/js/mind-map-css3d-manager.js"
91
91
  },
92
92
  {
@@ -410,44 +410,44 @@
410
410
  "url": "_framework/MimeMapping.og9ys58ylm.dll"
411
411
  },
412
412
  {
413
- "hash": "sha256-ZDas50sgMQGCNt0UC1ZErP+uv7PQ7z/skK7zCwnmU2I=",
414
- "url": "_framework/MindExecution.Core.ckgjbdvvxl.dll"
413
+ "hash": "sha256-QFzKrrCvQhHKuzHmjZNnWfLRs8Zvg90nlG23JMRuPiA=",
414
+ "url": "_framework/MindExecution.Core.c9fyqe953v.dll"
415
415
  },
416
416
  {
417
- "hash": "sha256-ndscepu8d8g/nrJmBP8VrkIOTIkSA57t5shOq/rp/ys=",
418
- "url": "_framework/MindExecution.Kernel.lm7kgq8l8h.dll"
417
+ "hash": "sha256-Ay3ypEtsJuNsBYsha1gUwQ98jBnWGZFyOEEd2TmsNew=",
418
+ "url": "_framework/MindExecution.Kernel.badrt1tkvv.dll"
419
419
  },
420
420
  {
421
- "hash": "sha256-LLDLGzE3yaP+rL+8CMZGWBmGQZBfrRWgUMijX/fxTxw=",
422
- "url": "_framework/MindExecution.Plugins.Admin.k085kt3dls.dll"
421
+ "hash": "sha256-s0/shhl1o5sjys9RDDMPM5TWYZNk64K5RggeZ8gsDKA=",
422
+ "url": "_framework/MindExecution.Plugins.Admin.73w1bvz4r1.dll"
423
423
  },
424
424
  {
425
- "hash": "sha256-bfvFu7Pq58deN7TnwfhsUZdvWhS4RpA0LdO77UsBnY8=",
426
- "url": "_framework/MindExecution.Plugins.Business.dsz9uwkxih.dll"
425
+ "hash": "sha256-OcLlpkGPe6VinOzGw5cDKNjIcQLZW+nv6zGjvzewc8w=",
426
+ "url": "_framework/MindExecution.Plugins.Business.dvd82y422m.dll"
427
427
  },
428
428
  {
429
- "hash": "sha256-nCycvHAVswddeF1J0XSbpQSsVsutbCpx+52o7ne+kZw=",
430
- "url": "_framework/MindExecution.Plugins.Concept.wnkch6jqjz.dll"
429
+ "hash": "sha256-YjENe8QVAOo4XYknnQD3hSMouQMSQQQ7sryMHObA0Qc=",
430
+ "url": "_framework/MindExecution.Plugins.Concept.m3ukc0xvom.dll"
431
431
  },
432
432
  {
433
- "hash": "sha256-qoxaegrVr9oaXJgQqU7t7CrCf0EYgsd22BcWXg/+91I=",
434
- "url": "_framework/MindExecution.Plugins.Directory.ufbriq6js4.dll"
433
+ "hash": "sha256-vmai+Tkzmk5CeReKLxTMz/gp+uPrt8EaftPIbljEZ0E=",
434
+ "url": "_framework/MindExecution.Plugins.Directory.23tm2uvfvu.dll"
435
435
  },
436
436
  {
437
- "hash": "sha256-ErbKkuXxJANIiJahFjEUZq9TH1Kz/y2LEuepW6ZxJnU=",
438
- "url": "_framework/MindExecution.Plugins.PlanMaster.ygbsp1z4z0.dll"
437
+ "hash": "sha256-DGJpulGGAuvc9KS9plHJi8BLX8EBiqV3A90QMAadYCY=",
438
+ "url": "_framework/MindExecution.Plugins.PlanMaster.8nrc7ge4ob.dll"
439
439
  },
440
440
  {
441
- "hash": "sha256-orw8lB1/+iy3s9EoeG+MDueyomsbPTC7vq0UIjUwtfQ=",
442
- "url": "_framework/MindExecution.Plugins.YouTube.a992061fhz.dll"
441
+ "hash": "sha256-Te3jpmTgl3HFoKoMct4HMXhg6a9PgTHmVaQltQjKrak=",
442
+ "url": "_framework/MindExecution.Plugins.YouTube.3ox59073d8.dll"
443
443
  },
444
444
  {
445
- "hash": "sha256-Gvuf30dJMtENks7FSoBydnPkKJp4NS10DjvJmsTLEV0=",
446
- "url": "_framework/MindExecution.Shared.y27t6njaw0.dll"
445
+ "hash": "sha256-ly99wDAapShB+jZ1V95wYNfWyd1Q+JNGxL870fY6XKI=",
446
+ "url": "_framework/MindExecution.Shared.va1gxp0crd.dll"
447
447
  },
448
448
  {
449
- "hash": "sha256-LYhJEP8rDmDCLhf8aQxkiGEmpsffoNzT6S37CxSfNQ8=",
450
- "url": "_framework/MindExecution.Web.bqamgu5gq1.dll"
449
+ "hash": "sha256-yz2Mpwuz+oEBj6sVtdQOjSPIrLj4cQICK7ZDFVWwy5o=",
450
+ "url": "_framework/MindExecution.Web.jmawk7z8d3.dll"
451
451
  },
452
452
  {
453
453
  "hash": "sha256-IsZJ91/OW+fHzNqIgEc7Y072ns8z9dGritiSyvR9Wgc=",
@@ -770,7 +770,7 @@
770
770
  "url": "_framework/Websocket.Client.vapounvmnl.dll"
771
771
  },
772
772
  {
773
- "hash": "sha256-6xyfZZneOcB1qKLApN7yPISkoN/wp8qEwfDnH0h9JhA=",
773
+ "hash": "sha256-YFYbUXsuU5KT0E7N+xUyIA0vztkOHHRPlmdp4kBB67c=",
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-0dZRFimqvytlX0CmLM1UGW//sqP9ru7W0usTp/5Z570=",
837
+ "hash": "sha256-tL38lnMES1WBgTPkRcwiazc1i1T3td1aYgwrUvoxQOo=",
838
838
  "url": "index.html"
839
839
  },
840
840
  {
@@ -1,4 +1,4 @@
1
- /* Manifest version: dr5Y7e+X */
1
+ /* Manifest version: 4y4C9wve */
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