@mindexec/cli 0.2.457 → 0.2.458

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 (20) hide show
  1. package/package.json +1 -1
  2. package/remote-fast/osx-arm64/mindexec-remote-fast.dll +0 -0
  3. package/remote-fast/osx-x64/mindexec-remote-fast.dll +0 -0
  4. package/remote-fast/win-x64/mindexec-remote-fast.dll +0 -0
  5. package/scripts/remote-fleet-render-smoke.mjs +29 -186
  6. package/wwwroot/_content/MindExecution.Shared/js/mind-map-css3d-manager.js +51 -346
  7. package/wwwroot/_framework/{MindExecution.Core.speado072l.dll → MindExecution.Core.2ch68iyy8o.dll} +0 -0
  8. package/wwwroot/_framework/{MindExecution.Kernel.mjy31ssdac.dll → MindExecution.Kernel.dh617xfv36.dll} +0 -0
  9. package/wwwroot/_framework/{MindExecution.Plugins.Admin.vbjjmdaao2.dll → MindExecution.Plugins.Admin.0sm50hbae9.dll} +0 -0
  10. package/wwwroot/_framework/{MindExecution.Plugins.Business.0cr5jc6wqe.dll → MindExecution.Plugins.Business.3wq01orrbu.dll} +0 -0
  11. package/wwwroot/_framework/{MindExecution.Plugins.Concept.m7p666e0jd.dll → MindExecution.Plugins.Concept.z8yl28fa2a.dll} +0 -0
  12. package/wwwroot/_framework/{MindExecution.Plugins.Directory.kmdtirnljl.dll → MindExecution.Plugins.Directory.m7murp5oes.dll} +0 -0
  13. package/wwwroot/_framework/{MindExecution.Plugins.PlanMaster.m1pfeozacj.dll → MindExecution.Plugins.PlanMaster.yuyrbpf0vh.dll} +0 -0
  14. package/wwwroot/_framework/{MindExecution.Plugins.YouTube.nvsc9q4s6b.dll → MindExecution.Plugins.YouTube.rwxvn00rm2.dll} +0 -0
  15. package/wwwroot/_framework/{MindExecution.Shared.9jaznballd.dll → MindExecution.Shared.r9k48iyijb.dll} +0 -0
  16. package/wwwroot/_framework/{MindExecution.Web.k5jxwawryl.dll → MindExecution.Web.742aribkxm.dll} +0 -0
  17. package/wwwroot/_framework/blazor.boot.json +21 -21
  18. package/wwwroot/index.html +722 -722
  19. package/wwwroot/service-worker-assets.js +24 -24
  20. package/wwwroot/service-worker.js +1 -1
@@ -14627,8 +14627,6 @@
14627
14627
  const REMOTE_FLEET_BINARY_FRAME_CACHE_MS = 10000;
14628
14628
  const REMOTE_FLEET_BINARY_FRAME_CACHE_LIMIT = 240;
14629
14629
  const REMOTE_FLEET_BINARY_FRAME_SESSION_IDLE_MS = 8000;
14630
- const REMOTE_FLEET_AUTO_LIVE_START_MAX_PARALLEL = 8;
14631
- const REMOTE_FLEET_AUTO_LIVE_START_COOLDOWN_MS = 3000;
14632
14630
  const REMOTE_FLEET_TASK_FOLLOW_INITIAL_MS = 250;
14633
14631
  const REMOTE_FLEET_TASK_FOLLOW_REFRESH_MS = 2000;
14634
14632
  const REMOTE_FLEET_TASK_FOLLOW_MAX_TICKS = 60;
@@ -18969,8 +18967,7 @@
18969
18967
 
18970
18968
  function renderRemoteFleetMonitor(bodyView, nodeModel) {
18971
18969
  if (!bodyView) return;
18972
- clearRemoteFleetTimers(bodyView, { keepBinaryFrameSocket: true });
18973
- const preservedFrameSurfaces = collectRemoteFleetPreviewFrameSurfaces(bodyView);
18970
+ clearRemoteFleetTimers(bodyView);
18974
18971
 
18975
18972
  const nodeId = String(nodeModel?.id ?? nodeModel?.Id ?? '');
18976
18973
  const searchState = bodyView.dataset.remoteFleetSearch || '';
@@ -18980,7 +18977,6 @@
18980
18977
  const densityState = normalizeRemoteFleetMonitorSize(bodyView.dataset.remoteFleetDensity || 'cards');
18981
18978
  const aiAssistState = bodyView.dataset.remoteFleetAiAssist === 'true';
18982
18979
  const autoMonitorState = bodyView.dataset.remoteFleetAutoMonitor !== 'false';
18983
- const focusState = bodyView.dataset.remoteFleetFocusDeviceId || '';
18984
18980
  const latestTaskBatch = parseRemoteFleetLatestTaskBatch(nodeModel);
18985
18981
  const recentTaskBatches = parseRemoteFleetRecentTaskBatches(nodeModel);
18986
18982
  const latestTaskBatchKey = getRemoteFleetTaskBatchKey(latestTaskBatch);
@@ -18999,18 +18995,10 @@
18999
18995
  : [...sortedDevices].sort((left, right) =>
19000
18996
  compareRemoteFleetGroups(left, right, groupState)
19001
18997
  || compareRemoteFleetDevices(left, right, sortState));
19002
- const hasActiveLiveStream = devices.some(isRemoteFleetLiveActive);
19003
18998
  const hasMonitorTargets = devices.some(device =>
19004
18999
  isRemoteFleetDeviceConnected(device) && isRemoteFleetThumbnailCapable(device));
19005
- const focusedDevice = devices.find(device => getRemoteFleetDeviceId(device) === focusState)
19006
- || devices.find(device => isRemoteFleetLiveActive(device))
19007
- || null;
19008
- if (focusedDevice) {
19009
- bodyView.dataset.remoteFleetFocusDeviceId = getRemoteFleetDeviceId(focusedDevice);
19010
- }
19011
- const selectedState = bodyView.dataset.remoteFleetSelectedDeviceId || focusState || '';
19000
+ const selectedState = bodyView.dataset.remoteFleetSelectedDeviceId || '';
19012
19001
  const selectedDevice = devices.find(device => getRemoteFleetDeviceId(device) === selectedState)
19013
- || focusedDevice
19014
19002
  || devices[0]
19015
19003
  || null;
19016
19004
  if (selectedDevice) {
@@ -19162,8 +19150,7 @@
19162
19150
  { value: 'offline', label: 'Offline' },
19163
19151
  { value: 'task', label: 'Task' },
19164
19152
  { value: 'ai', label: 'AI' },
19165
- { value: 'live', label: 'Live' },
19166
- { value: 'frames', label: 'Frames' },
19153
+ { value: 'frames', label: 'Thumbnails' },
19167
19154
  { value: 'issues', label: 'Issues' }
19168
19155
  ], filterState, 'Device filter');
19169
19156
 
@@ -19276,7 +19263,7 @@
19276
19263
  aiToggleText.textContent = 'AI';
19277
19264
  aiToggleLabel.appendChild(aiToggle);
19278
19265
  aiToggleLabel.appendChild(aiToggleText);
19279
- const sendVisibleButton = createRemoteFleetButton('Send visible', 'Dispatch task to visible connected task-capable devices', 'task-visible');
19266
+ const sendVisibleButton = createRemoteFleetButton('Send selected', 'Dispatch task to the selected agent', 'task-selected');
19280
19267
  sendVisibleButton.style.height = '54px';
19281
19268
  const sendConnectedButton = createRemoteFleetButton('Send all', 'Dispatch task to all connected task-capable devices', 'task-connected');
19282
19269
  sendConnectedButton.style.height = '54px';
@@ -19476,23 +19463,16 @@
19476
19463
  const createDevicePreview = (device, mode = 'tile') => {
19477
19464
  const name = getRemoteFleetDeviceName(device);
19478
19465
  const connectedDevice = isRemoteFleetDeviceConnected(device);
19479
- const thumbnailCapturedAt = String(device?.thumbnailCapturedAt || device?.ThumbnailCapturedAt || '');
19480
- const liveFrameReceivedAt = String(device?.liveFrameReceivedAt || device?.LiveFrameReceivedAt || '');
19481
19466
  const hasThumbnail = hasRemoteFleetThumbnail(device);
19482
- const hasLiveFrame = hasRemoteFleetLiveFrame(device);
19483
- const previewSource = hasLiveFrame
19484
- ? getRemoteFleetFrameSource(device, 'live')
19485
- : getRemoteFleetFrameSource(device, 'thumbnail');
19467
+ const previewSource = getRemoteFleetFrameSource(device, 'thumbnail');
19486
19468
  const hasPreviewSource = isRemoteFleetFrameSource(previewSource);
19487
- const isDetail = mode === 'detail';
19488
19469
 
19489
19470
  const preview = document.createElement('div');
19490
19471
  preview.dataset.remoteFleetDevicePreview = mode;
19491
19472
  preview.dataset.deviceId = getRemoteFleetDeviceId(device);
19492
- preview.dataset.remoteFleetFrameKind = hasLiveFrame ? 'live' : (hasThumbnail ? 'thumbnail' : '');
19493
- preview.dataset.remoteFleetFrameSeq = String(hasLiveFrame
19494
- ? getRemoteFleetDeviceField(device, 'liveFrameSeq', 'LiveFrameSeq', 0)
19495
- : getRemoteFleetDeviceField(device, 'thumbnailFrameSeq', 'ThumbnailFrameSeq', 0));
19473
+ preview.dataset.remoteFleetFrameKind = hasThumbnail ? 'thumbnail' : '';
19474
+ preview.dataset.remoteFleetFrameSeq = String(
19475
+ getRemoteFleetDeviceField(device, 'thumbnailFrameSeq', 'ThumbnailFrameSeq', 0));
19496
19476
  preview.title = getRemoteFleetDeviceTooltip(device);
19497
19477
  preview.style.cssText = `
19498
19478
  position: relative;
@@ -19508,13 +19488,13 @@
19508
19488
  `;
19509
19489
  ensureRemoteFleetFrameCanvas(preview);
19510
19490
 
19511
- if ((hasLiveFrame || hasThumbnail) && hasPreviewSource) {
19491
+ if (hasThumbnail && hasPreviewSource) {
19512
19492
  const image = document.createElement('img');
19513
19493
  image.dataset.remoteFleetFrameImage = 'true';
19514
- image.dataset.remoteFleetFrameKind = hasLiveFrame ? 'live' : 'thumbnail';
19494
+ image.dataset.remoteFleetFrameKind = 'thumbnail';
19515
19495
  image.dataset.remoteFleetFrameSeq = preview.dataset.remoteFleetFrameSeq;
19516
19496
  image.src = previewSource;
19517
- image.alt = hasLiveFrame ? `${name} live frame` : `${name} thumbnail`;
19497
+ image.alt = `${name} thumbnail`;
19518
19498
  image.loading = 'lazy';
19519
19499
  image.decoding = 'async';
19520
19500
  image.style.cssText = `
@@ -19535,7 +19515,6 @@
19535
19515
  preview.appendChild(placeholder);
19536
19516
  }
19537
19517
 
19538
- restoreRemoteFleetPreviewFrameSurface(preview, preservedFrameSurfaces, getRemoteFleetDeviceId(device));
19539
19518
  return preview;
19540
19519
  };
19541
19520
 
@@ -19603,10 +19582,7 @@
19603
19582
  const connectedDevice = isRemoteFleetDeviceConnected(device);
19604
19583
  const name = getRemoteFleetDeviceName(device);
19605
19584
  const deviceId = getRemoteFleetDeviceId(device);
19606
- const liveStreamEnabled = isRemoteFleetLiveCapable(device);
19607
- const liveStreamActive = isRemoteFleetLiveActive(device);
19608
19585
  const hasThumbnail = hasRemoteFleetThumbnail(device);
19609
- const hasLiveFrame = hasRemoteFleetLiveFrame(device);
19610
19586
  const taskEnabled = isRemoteFleetDeviceTaskCapable(device);
19611
19587
  const aiAssistEnabled = isRemoteFleetDeviceAiCapable(device);
19612
19588
  const latestTaskStatus = String(device?.latestTaskStatus || device?.LatestTaskStatus || '');
@@ -19654,15 +19630,13 @@
19654
19630
  card.dataset.remoteFleetConnected = connectedDevice ? 'true' : 'false';
19655
19631
  card.dataset.remoteFleetTaskCapable = taskEnabled ? 'true' : 'false';
19656
19632
  card.dataset.remoteFleetAiCapable = aiAssistEnabled ? 'true' : 'false';
19657
- card.dataset.remoteFleetHasFrame = (hasThumbnail || hasLiveFrame) ? 'true' : 'false';
19658
- card.dataset.remoteFleetLiveCapable = liveStreamEnabled ? 'true' : 'false';
19659
- card.dataset.remoteFleetLiveActive = liveStreamActive ? 'true' : 'false';
19633
+ card.dataset.remoteFleetHasFrame = hasThumbnail ? 'true' : 'false';
19660
19634
  card.dataset.remoteFleetIssue = (!connectedDevice || latestTaskStatus === 'failed' || !!latestTaskError) ? 'true' : 'false';
19661
19635
  card.dataset.remoteFleetSelected = isSelected ? 'true' : 'false';
19662
19636
  card.dataset.remoteFleetAction = 'select-device';
19663
19637
  card.setAttribute('role', 'button');
19664
19638
  card.setAttribute('aria-pressed', isSelected ? 'true' : 'false');
19665
- card.setAttribute('aria-label', `Open remote workstation for ${name}`);
19639
+ card.setAttribute('aria-label', `Select ${name} as the agent task target`);
19666
19640
  card.tabIndex = 0;
19667
19641
  card.title = getRemoteFleetDeviceTooltip(device);
19668
19642
  card.style.cssText = `
@@ -19770,121 +19744,12 @@
19770
19744
  const readTaskInstruction = () => String(taskInput.value || '').trim();
19771
19745
  const useAiAssist = () => aiToggle.checked === true;
19772
19746
  const getDeviceCards = () => Array.from(grid.querySelectorAll('article[data-device-id]'));
19773
- const pushUniqueFrameDeviceId = (ids, device) => {
19774
- const id = getRemoteFleetDeviceId(device);
19775
- if (id && !ids.includes(id)) {
19776
- ids.push(id);
19777
- }
19778
- };
19779
- const getVisibleFrameDeviceIds = () => {
19780
- const ids = getDeviceCards()
19747
+ const getVisibleFrameDeviceIds = () => Array.from(new Set(
19748
+ getDeviceCards()
19781
19749
  .filter(card => card.style.display !== 'none')
19782
19750
  .map(card => String(card.dataset.deviceId || '').trim())
19783
- .filter(Boolean);
19784
- return Array.from(new Set(ids)).slice(0, 120);
19785
- };
19786
- const getVisibleLiveDevices = () => {
19787
- const visibleIds = new Set(getVisibleFrameDeviceIds());
19788
- return devices
19789
- .filter(device => {
19790
- const id = getRemoteFleetDeviceId(device);
19791
- return id
19792
- && visibleIds.has(id)
19793
- && isRemoteFleetDeviceConnected(device)
19794
- && isRemoteFleetLiveCapable(device);
19795
- })
19796
- .slice(0, 120);
19797
- };
19798
- const getVisibleLiveFrameDeviceIds = () => {
19799
- const ids = [];
19800
- getVisibleLiveDevices().forEach(device => pushUniqueFrameDeviceId(ids, device));
19801
- devices
19802
- .filter(device => isRemoteFleetDeviceConnected(device) && isRemoteFleetLiveActive(device))
19803
- .forEach(device => pushUniqueFrameDeviceId(ids, device));
19804
- return ids.slice(0, 120);
19805
- };
19806
- const ensureVisibleRemoteFleetLiveStreams = async () => {
19807
- if (!(bodyView._remoteFleetAutoLiveStartInFlight instanceof Set)) {
19808
- bodyView._remoteFleetAutoLiveStartInFlight = new Set();
19809
- }
19810
- if (!(bodyView._remoteFleetAutoLiveStartAttemptAt instanceof Map)) {
19811
- bodyView._remoteFleetAutoLiveStartAttemptAt = new Map();
19812
- }
19813
- const now = Date.now();
19814
- const targets = getVisibleLiveDevices()
19815
- .filter(device => {
19816
- const deviceId = getRemoteFleetDeviceId(device);
19817
- const lastAttemptAt = Number(bodyView._remoteFleetAutoLiveStartAttemptAt.get(deviceId) || 0);
19818
- return deviceId
19819
- && !isRemoteFleetLiveActive(device)
19820
- && !bodyView._remoteFleetAutoLiveStartInFlight.has(deviceId)
19821
- && (now - lastAttemptAt >= REMOTE_FLEET_AUTO_LIVE_START_COOLDOWN_MS);
19822
- });
19823
- if (targets.length === 0) {
19824
- return null;
19825
- }
19826
-
19827
- let started = 0;
19828
- let lastResult = null;
19829
- const queue = targets.slice(0, 120);
19830
- const startOne = async target => {
19831
- const deviceId = getRemoteFleetDeviceId(target);
19832
- if (!deviceId || bodyView._remoteFleetAutoLiveStartInFlight.has(deviceId)) {
19833
- return;
19834
- }
19835
-
19836
- bodyView._remoteFleetAutoLiveStartInFlight.add(deviceId);
19837
- bodyView._remoteFleetAutoLiveStartAttemptAt.set(deviceId, Date.now());
19838
- try {
19839
- const result = await invokeDotNetAsync('StartRemoteFleetLiveStreamFromJs', nodeId, deviceId, REMOTE_FLEET_MONITOR_LIVE_FPS);
19840
- lastResult = result;
19841
- const success = isRemoteFleetResultSuccess(result);
19842
- window.RuntimeTrace?.emit?.('remote.live.autoStart', {
19843
- nodeId,
19844
- deviceId,
19845
- success,
19846
- fps: result?.fps || result?.Fps || 0,
19847
- mode: 'visible-grid',
19848
- error: result?.error || result?.Error || ''
19849
- });
19850
- if (success) {
19851
- started += 1;
19852
- }
19853
- } finally {
19854
- bodyView._remoteFleetAutoLiveStartInFlight.delete(deviceId);
19855
- }
19856
- };
19857
-
19858
- const workerCount = Math.min(REMOTE_FLEET_AUTO_LIVE_START_MAX_PARALLEL, queue.length);
19859
- await Promise.all(Array.from({ length: workerCount }, async () => {
19860
- while (queue.length > 0) {
19861
- const target = queue.shift();
19862
- if (target) {
19863
- await startOne(target);
19864
- }
19865
- }
19866
- }));
19867
-
19868
- if (started > 0) {
19869
- try {
19870
- await refreshRemoteFleetNode();
19871
- } catch (error) {
19872
- window.RuntimeTrace?.emit?.('remote.live.autoRefreshFailed', {
19873
- nodeId,
19874
- started,
19875
- error: error?.message || String(error || '')
19876
- });
19877
- }
19878
-
19879
- window.RuntimeTrace?.emit?.('remote.live.awaitingBinaryFrames', {
19880
- nodeId,
19881
- started,
19882
- transport: 'ws-binary'
19883
- });
19884
- }
19885
-
19886
- return lastResult || { success: started > 0, started };
19887
- };
19751
+ .filter(Boolean)))
19752
+ .slice(0, 120);
19888
19753
  const refreshRemoteFleetNode = async () => {
19889
19754
  if (bodyView._remoteFleetRefreshInFlight === true) {
19890
19755
  return null;
@@ -19901,7 +19766,9 @@
19901
19766
  };
19902
19767
  const refreshRemoteFleetVisibleFrames = async (requestThumbnails = false) => {
19903
19768
  const result = await invokeDotNetAsync('RefreshRemoteFleetFramesFromJs', nodeId, getVisibleFrameDeviceIds(), requestThumbnails === true);
19904
- applyRemoteFleetFramePatches(bodyView, normalizeRemoteFleetDeviceFramePatches(result));
19769
+ const thumbnailPatches = normalizeRemoteFleetDeviceFramePatches(result)
19770
+ .filter(frame => String(frame?.kind || '').toLowerCase() === 'thumbnail');
19771
+ applyRemoteFleetFramePatches(bodyView, thumbnailPatches);
19905
19772
  return result;
19906
19773
  };
19907
19774
  const startRemoteFleetMonitorRefreshTimer = (intervalMs, reason = 'monitor') => {
@@ -20003,15 +19870,18 @@
20003
19870
  scheduleRemoteFleetTaskFollow();
20004
19871
  }
20005
19872
  };
20006
- const getVisibleEligibleDeviceIds = () => {
19873
+ const getSelectedEligibleDeviceId = () => {
19874
+ const selectedId = String(bodyView.dataset.remoteFleetSelectedDeviceId || '').trim();
19875
+ if (!selectedId) return '';
19876
+ const card = getDeviceCards().find(item => String(item.dataset.deviceId || '').trim() === selectedId);
20007
19877
  const wantsAi = useAiAssist();
20008
- return getDeviceCards()
20009
- .filter(card => card.style.display !== 'none'
20010
- && card.dataset.remoteFleetConnected === 'true'
20011
- && card.dataset.remoteFleetTaskCapable === 'true'
20012
- && (!wantsAi || card.dataset.remoteFleetAiCapable === 'true'))
20013
- .map(card => String(card.dataset.deviceId || '').trim())
20014
- .filter(Boolean);
19878
+ return card
19879
+ && card.style.display !== 'none'
19880
+ && card.dataset.remoteFleetConnected === 'true'
19881
+ && card.dataset.remoteFleetTaskCapable === 'true'
19882
+ && (!wantsAi || card.dataset.remoteFleetAiCapable === 'true')
19883
+ ? selectedId
19884
+ : '';
20015
19885
  };
20016
19886
 
20017
19887
  const applyRemoteFleetFilters = () => {
@@ -20030,7 +19900,6 @@
20030
19900
  || (filterMode === 'offline' && card.dataset.remoteFleetConnected !== 'true')
20031
19901
  || (filterMode === 'task' && card.dataset.remoteFleetConnected === 'true' && card.dataset.remoteFleetTaskCapable === 'true')
20032
19902
  || (filterMode === 'ai' && card.dataset.remoteFleetConnected === 'true' && card.dataset.remoteFleetAiCapable === 'true')
20033
- || (filterMode === 'live' && card.dataset.remoteFleetLiveActive === 'true')
20034
19903
  || (filterMode === 'frames' && card.dataset.remoteFleetHasFrame === 'true')
20035
19904
  || (filterMode === 'issues' && card.dataset.remoteFleetIssue === 'true');
20036
19905
  const show = matchesSearch && matchesMode;
@@ -20064,10 +19933,11 @@
20064
19933
 
20065
19934
  matchCount.textContent = `${visible}/${devices.length}`;
20066
19935
  matchCount.title = `${visible} visible, ${eligible} targetable`;
20067
- sendVisibleButton.disabled = eligible <= 0;
20068
- sendVisibleButton.title = eligible > 0
20069
- ? `Dispatch to ${eligible} visible target(s)`
20070
- : 'No visible targetable devices';
19936
+ const selectedTargetId = getSelectedEligibleDeviceId();
19937
+ sendVisibleButton.disabled = !selectedTargetId;
19938
+ sendVisibleButton.title = selectedTargetId
19939
+ ? `Dispatch to selected agent ${selectedTargetId}`
19940
+ : 'Select an online task-capable agent';
20071
19941
  const allTargetCount = wantsAi ? aiCapableCount : taskCapableCount;
20072
19942
  sendConnectedButton.disabled = allTargetCount <= 0;
20073
19943
  sendConnectedButton.title = allTargetCount > 0
@@ -20141,6 +20011,7 @@
20141
20011
  deviceId: normalizedSelectedId,
20142
20012
  mode: 'dom-patch'
20143
20013
  });
20014
+ applyRemoteFleetFilters();
20144
20015
  };
20145
20016
  getDeviceCards().forEach(card => {
20146
20017
  ['pointerdown', 'mousedown', 'mouseup'].forEach(eventName => {
@@ -20156,40 +20027,6 @@
20156
20027
  event.stopImmediatePropagation?.();
20157
20028
  });
20158
20029
  });
20159
- card.addEventListener('dblclick', event => {
20160
- event.preventDefault();
20161
- event.stopPropagation();
20162
- event.stopImmediatePropagation?.();
20163
- const deviceId = String(card.dataset.deviceId || '').trim();
20164
- if (!deviceId) return;
20165
- applySelectedDeviceVisualState(deviceId);
20166
- if (card.dataset.remoteFleetOpeningControlNode === 'true') {
20167
- return;
20168
- }
20169
-
20170
- card.dataset.remoteFleetOpeningControlNode = 'true';
20171
- invokeDotNetAsync('AddRemoteFleetDeviceNodeFromJs', nodeId, deviceId)
20172
- .then(async result => {
20173
- await syncRemoteFleetNodeStateFromResult(result);
20174
- if (result?.success) {
20175
- const controlNodeId = String(result.nodeId || result.NodeId || '').trim();
20176
- if (controlNodeId) {
20177
- window.mindMap?.focusNode?.(controlNodeId, { selectNode: true });
20178
- window.mindMap?.selectNode?.(controlNodeId);
20179
- invokeDotNetAsync('SelectNodeInBlazor', controlNodeId).catch(() => undefined);
20180
- }
20181
- setTaskFeedback('');
20182
- } else {
20183
- setTaskFeedback(result?.error || result?.Error || 'Remote workstation node failed.', 'error');
20184
- }
20185
- })
20186
- .catch(error => {
20187
- setTaskFeedback(error?.message || 'Remote workstation node failed.', 'error');
20188
- })
20189
- .finally(() => {
20190
- delete card.dataset.remoteFleetOpeningControlNode;
20191
- });
20192
- });
20193
20030
  const selectCard = event => {
20194
20031
  event.preventDefault();
20195
20032
  event.stopPropagation();
@@ -20225,8 +20062,6 @@
20225
20062
  scheduleRemoteFleetTaskFollow();
20226
20063
  }
20227
20064
 
20228
- primeRemoteFleetRenderedFrameSurfaces(bodyView, 'monitor-render');
20229
-
20230
20065
  sendVisibleButton.addEventListener('click', async event => {
20231
20066
  event.preventDefault();
20232
20067
  event.stopPropagation();
@@ -20237,19 +20072,19 @@
20237
20072
  return;
20238
20073
  }
20239
20074
 
20240
- const targetIds = getVisibleEligibleDeviceIds();
20241
- if (targetIds.length === 0) {
20242
- setTaskFeedback('No visible targetable devices.', 'error');
20075
+ const targetId = getSelectedEligibleDeviceId();
20076
+ if (!targetId) {
20077
+ setTaskFeedback('Select an online task-capable agent.', 'error');
20243
20078
  return;
20244
20079
  }
20245
20080
 
20246
20081
  sendVisibleButton.disabled = true;
20247
- setTaskFeedback('Dispatching task to visible devices...');
20082
+ setTaskFeedback('Dispatching task to selected agent...');
20248
20083
  try {
20249
- const result = await invokeDotNetAsync('DispatchRemoteFleetTaskBatchFromJs', nodeId, targetIds, instruction, useAiAssist());
20084
+ const result = await invokeDotNetAsync('DispatchRemoteFleetTaskFromJs', nodeId, targetId, instruction, useAiAssist());
20250
20085
  await syncRemoteFleetNodeStateFromResult(result);
20251
- const mode = useAiAssist() ? 'visible AI task' : 'visible remote task';
20252
- const feedback = formatRemoteFleetDispatchFeedback(result, targetIds.length, mode);
20086
+ const mode = useAiAssist() ? 'selected AI task' : 'selected agent task';
20087
+ const feedback = formatRemoteFleetDispatchFeedback(result, 1, mode);
20253
20088
  setTaskFeedback(feedback.text, feedback.tone);
20254
20089
  startRemoteFleetTaskFollowFromResult(result);
20255
20090
  } finally {
@@ -20373,84 +20208,6 @@
20373
20208
  });
20374
20209
  });
20375
20210
 
20376
- bodyView.querySelectorAll('[data-remote-fleet-action="pin-device"]').forEach(button => {
20377
- button.addEventListener('click', async event => {
20378
- event.preventDefault();
20379
- event.stopPropagation();
20380
- const deviceId = String(button.dataset.deviceId || '').trim();
20381
- if (!deviceId) return;
20382
- button.disabled = true;
20383
- setTaskFeedback('Pinning device to canvas...');
20384
- try {
20385
- const result = await invokeDotNetAsync('AddRemoteFleetDeviceNodeFromJs', nodeId, deviceId);
20386
- await syncRemoteFleetNodeStateFromResult(result);
20387
- if (result?.success) {
20388
- setTaskFeedback('Pinned device node.', 'success');
20389
- } else {
20390
- setTaskFeedback(result?.error || 'Pin failed.', 'error');
20391
- }
20392
- } finally {
20393
- button.disabled = false;
20394
- }
20395
- });
20396
- });
20397
-
20398
- bodyView.querySelectorAll('[data-remote-fleet-action="live-focus"]').forEach(button => {
20399
- button.addEventListener('click', event => {
20400
- event.preventDefault();
20401
- event.stopPropagation();
20402
- const deviceId = String(button.dataset.deviceId || '').trim();
20403
- if (!deviceId) return;
20404
- bodyView.dataset.remoteFleetFocusDeviceId = deviceId;
20405
- renderRemoteFleetMonitor(bodyView, nodeModel);
20406
- });
20407
- });
20408
-
20409
- bodyView.querySelectorAll('[data-remote-fleet-action="live-start"]').forEach(button => {
20410
- button.addEventListener('click', async event => {
20411
- event.preventDefault();
20412
- event.stopPropagation();
20413
- const deviceId = String(button.dataset.deviceId || '').trim();
20414
- if (!deviceId) return;
20415
- bodyView.dataset.remoteFleetFocusDeviceId = deviceId;
20416
- button.disabled = true;
20417
- setTaskFeedback('Starting focused live stream...');
20418
- try {
20419
- const result = await invokeDotNetAsync('StartRemoteFleetLiveStreamFromJs', nodeId, deviceId);
20420
- await syncRemoteFleetNodeStateFromResult(result);
20421
- if (result?.success) {
20422
- setTaskFeedback('Focused live stream started.', 'success');
20423
- } else {
20424
- setTaskFeedback(result?.error || 'Live stream start failed.', 'error');
20425
- }
20426
- } finally {
20427
- button.disabled = false;
20428
- }
20429
- });
20430
- });
20431
-
20432
- bodyView.querySelectorAll('[data-remote-fleet-action="live-stop"]').forEach(button => {
20433
- button.addEventListener('click', async event => {
20434
- event.preventDefault();
20435
- event.stopPropagation();
20436
- const deviceId = String(button.dataset.deviceId || '').trim();
20437
- if (!deviceId) return;
20438
- button.disabled = true;
20439
- setTaskFeedback('Stopping focused live stream...');
20440
- try {
20441
- const result = await invokeDotNetAsync('StopRemoteFleetLiveStreamFromJs', nodeId, deviceId, button.dataset.streamId || '');
20442
- await syncRemoteFleetNodeStateFromResult(result);
20443
- if (result?.success) {
20444
- setTaskFeedback('Focused live stream stopped.', 'success');
20445
- } else {
20446
- setTaskFeedback(result?.error || 'Live stream stop failed.', 'error');
20447
- }
20448
- } finally {
20449
- button.disabled = false;
20450
- }
20451
- });
20452
- });
20453
-
20454
20211
  bodyView.querySelectorAll('[data-remote-fleet-action="ping-device"]').forEach(button => {
20455
20212
  button.addEventListener('click', async event => {
20456
20213
  event.preventDefault();
@@ -20517,65 +20274,13 @@
20517
20274
  }, 250);
20518
20275
  }
20519
20276
 
20520
- const visibleFrameDeviceIds = getVisibleFrameDeviceIds();
20521
- const hasVisibleFrameTarget = visibleFrameDeviceIds.length > 0;
20522
- const hasVisibleLiveTarget = getVisibleLiveFrameDeviceIds().length > 0
20523
- || devices.some(device => isRemoteFleetDeviceConnected(device) && isRemoteFleetLiveCapable(device));
20524
- const shouldUseBinaryFrameSocket = hasVisibleLiveTarget
20525
- || hasActiveLiveStream
20526
- || (autoMonitorState && hasVisibleFrameTarget);
20527
- if (shouldUseBinaryFrameSocket) {
20528
- const atlasSocketStarted = startRemoteFleetAtlasSocket(bodyView, () => {
20529
- const liveIds = getVisibleLiveFrameDeviceIds();
20530
- return liveIds.length > 0 ? liveIds : getVisibleFrameDeviceIds();
20531
- }, {
20532
- fps: REMOTE_FLEET_MONITOR_LIVE_FPS,
20533
- width: 1920,
20534
- height: 1080,
20535
- tileWidth: 320,
20536
- tileHeight: 180
20537
- });
20538
- if (!atlasSocketStarted) {
20539
- window.RuntimeTrace?.emit?.('remote.frame.wsUnavailable', {
20540
- nodeId,
20541
- reason: 'atlas-frame-socket-not-started'
20542
- });
20543
- ensureVisibleRemoteFleetLiveStreams().catch(error => {
20544
- window.RuntimeTrace?.emit?.('remote.live.autoStartFailed', {
20545
- nodeId,
20546
- error: error?.message || String(error || '')
20547
- });
20548
- });
20549
- } else {
20550
- window.RuntimeTrace?.emit?.('remote.live.wsAutoStartRequested', {
20551
- nodeId,
20552
- transport: 'ws-atlas-h264',
20553
- fps: REMOTE_FLEET_MONITOR_LIVE_FPS,
20554
- visibleFrameTargets: visibleFrameDeviceIds.length,
20555
- visibleLiveTargets: getVisibleLiveFrameDeviceIds().length
20556
- });
20557
- }
20558
- bodyView._remoteFleetLiveRefreshTimer = setInterval(async () => {
20559
- if (!document.body.contains(bodyView)) {
20560
- clearRemoteFleetTimers(bodyView);
20561
- return;
20562
- }
20563
-
20564
- try {
20565
- await refreshRemoteFleetNode();
20566
- } catch {
20567
- clearRemoteFleetTimers(bodyView);
20568
- }
20569
- }, REMOTE_FLEET_LIVE_REFRESH_MS);
20570
- } else {
20571
- releaseRemoteFleetBinaryFrameSocket(bodyView);
20572
- releaseRemoteFleetAtlasSocket(bodyView);
20573
- if (autoMonitorState && hasMonitorTargets) {
20574
- startRemoteFleetFrameLoop(bodyView, REMOTE_FLEET_THUMBNAIL_FRAME_REFRESH_MS, () => refreshRemoteFleetVisibleFrames(true));
20575
- startRemoteFleetMonitorRefreshTimer(REMOTE_FLEET_MONITOR_REFRESH_MS, 'visible-devices');
20576
- } else if (autoMonitorState) {
20577
- startRemoteFleetMonitorRefreshTimer(REMOTE_FLEET_EMPTY_MONITOR_REFRESH_MS, 'empty-discovery');
20578
- }
20277
+ releaseRemoteFleetBinaryFrameSocket(bodyView);
20278
+ releaseRemoteFleetAtlasSocket(bodyView);
20279
+ if (autoMonitorState && hasMonitorTargets) {
20280
+ startRemoteFleetFrameLoop(bodyView, REMOTE_FLEET_THUMBNAIL_FRAME_REFRESH_MS, () => refreshRemoteFleetVisibleFrames(true));
20281
+ startRemoteFleetMonitorRefreshTimer(REMOTE_FLEET_MONITOR_REFRESH_MS, 'thumbnail-only');
20282
+ } else if (autoMonitorState) {
20283
+ startRemoteFleetMonitorRefreshTimer(REMOTE_FLEET_EMPTY_MONITOR_REFRESH_MS, 'empty-discovery');
20579
20284
  }
20580
20285
  }
20581
20286