@mindexec/cli 0.2.457 → 0.2.459
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/desktop-workspace-state.cjs +120 -0
- package/electron/main.cjs +17 -6
- package/electron/source-smoke.mjs +21 -0
- package/electron/windows-package-smoke.mjs +8 -2
- package/package.json +6 -5
- package/remote-fast/osx-arm64/mindexec-remote-fast.dll +0 -0
- package/remote-fast/osx-x64/mindexec-remote-fast.dll +0 -0
- package/remote-fast/win-x64/mindexec-remote-fast.dll +0 -0
- package/scripts/desktop-workspace-state-smoke.mjs +81 -0
- package/scripts/remote-fleet-render-smoke.mjs +29 -186
- package/server.js +36 -16
- package/wwwroot/_content/MindExecution.Shared/js/mind-map-animated-image-preview.js +270 -0
- package/wwwroot/_content/MindExecution.Shared/js/mind-map-core.js +57 -53
- package/wwwroot/_content/MindExecution.Shared/js/mind-map-css3d-manager.js +51 -346
- package/wwwroot/_content/MindExecution.Shared/js/mind-map-interactions.js +30 -26
- package/wwwroot/_content/MindExecution.Shared/js/mind-map-lod-renderer.js +94 -124
- package/wwwroot/_content/MindExecution.Shared/js/mind-map-menu-manager.js +43 -21
- package/wwwroot/_content/MindExecution.Shared/js/mind-map-nodes.js +45 -13
- package/wwwroot/_content/MindExecution.Shared/js/mind-map-render-plan.js +117 -1
- package/wwwroot/_content/MindExecution.Shared/js/mind-map-texture-factory.js +4 -1
- package/wwwroot/_framework/{MindExecution.Core.speado072l.dll → MindExecution.Core.b973f5f64y.dll} +0 -0
- package/wwwroot/_framework/{MindExecution.Kernel.mjy31ssdac.dll → MindExecution.Kernel.k4h9fvi9wb.dll} +0 -0
- package/wwwroot/_framework/{MindExecution.Plugins.Admin.vbjjmdaao2.dll → MindExecution.Plugins.Admin.u2emae8cb5.dll} +0 -0
- package/wwwroot/_framework/{MindExecution.Plugins.Business.0cr5jc6wqe.dll → MindExecution.Plugins.Business.cysw4qtyke.dll} +0 -0
- package/wwwroot/_framework/{MindExecution.Plugins.Concept.m7p666e0jd.dll → MindExecution.Plugins.Concept.8iehgvzjio.dll} +0 -0
- package/wwwroot/_framework/{MindExecution.Plugins.Directory.kmdtirnljl.dll → MindExecution.Plugins.Directory.t621fsxq2i.dll} +0 -0
- package/wwwroot/_framework/{MindExecution.Plugins.PlanMaster.m1pfeozacj.dll → MindExecution.Plugins.PlanMaster.ft631uc7ki.dll} +0 -0
- package/wwwroot/_framework/{MindExecution.Plugins.YouTube.nvsc9q4s6b.dll → MindExecution.Plugins.YouTube.arivgu92h1.dll} +0 -0
- package/wwwroot/_framework/{MindExecution.Shared.9jaznballd.dll → MindExecution.Shared.wm997st9eb.dll} +0 -0
- package/wwwroot/_framework/{MindExecution.Web.k5jxwawryl.dll → MindExecution.Web.osdbdrue4h.dll} +0 -0
- package/wwwroot/_framework/blazor.boot.json +21 -21
- package/wwwroot/app-icon-1024.png +0 -0
- package/wwwroot/apple-touch-icon.png +0 -0
- package/wwwroot/appsettings.json +81 -81
- package/wwwroot/favicon-32x32.png +0 -0
- package/wwwroot/favicon.ico +0 -0
- package/wwwroot/icon-192.png +0 -0
- package/wwwroot/icon-512.png +0 -0
- package/wwwroot/index.html +750 -726
- package/wwwroot/manifest.webmanifest +4 -4
- package/wwwroot/mindexec-favicon-v3.png +0 -0
- package/wwwroot/service-worker-assets.js +888 -880
- 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
|
|
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
|
|
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: '
|
|
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
|
|
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
|
|
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 =
|
|
19493
|
-
preview.dataset.remoteFleetFrameSeq = String(
|
|
19494
|
-
|
|
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 (
|
|
19491
|
+
if (hasThumbnail && hasPreviewSource) {
|
|
19512
19492
|
const image = document.createElement('img');
|
|
19513
19493
|
image.dataset.remoteFleetFrameImage = 'true';
|
|
19514
|
-
image.dataset.remoteFleetFrameKind =
|
|
19494
|
+
image.dataset.remoteFleetFrameKind = 'thumbnail';
|
|
19515
19495
|
image.dataset.remoteFleetFrameSeq = preview.dataset.remoteFleetFrameSeq;
|
|
19516
19496
|
image.src = previewSource;
|
|
19517
|
-
image.alt =
|
|
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 =
|
|
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', `
|
|
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
|
|
19774
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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
|
|
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
|
|
20009
|
-
|
|
20010
|
-
|
|
20011
|
-
|
|
20012
|
-
|
|
20013
|
-
|
|
20014
|
-
|
|
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
|
-
|
|
20068
|
-
sendVisibleButton.
|
|
20069
|
-
|
|
20070
|
-
|
|
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
|
|
20241
|
-
if (
|
|
20242
|
-
setTaskFeedback('
|
|
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
|
|
20082
|
+
setTaskFeedback('Dispatching task to selected agent...');
|
|
20248
20083
|
try {
|
|
20249
|
-
const result = await invokeDotNetAsync('
|
|
20084
|
+
const result = await invokeDotNetAsync('DispatchRemoteFleetTaskFromJs', nodeId, targetId, instruction, useAiAssist());
|
|
20250
20085
|
await syncRemoteFleetNodeStateFromResult(result);
|
|
20251
|
-
const mode = useAiAssist() ? '
|
|
20252
|
-
const feedback = formatRemoteFleetDispatchFeedback(result,
|
|
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
|
-
|
|
20521
|
-
|
|
20522
|
-
|
|
20523
|
-
|
|
20524
|
-
|
|
20525
|
-
|
|
20526
|
-
|
|
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
|
|
|
@@ -682,13 +682,32 @@ window.MindMapInteractions = (function () {
|
|
|
682
682
|
module._lastNativePasteEventAt = performance.now();
|
|
683
683
|
module._pendingClipboardPasteFallbackToken = null;
|
|
684
684
|
console.log('[MindMap] Ctrl+V fallback read clipboard text. Creating node through PasteTextFromClipboard.');
|
|
685
|
-
await module.dotNetHelper.invokeMethodAsync('PasteTextFromClipboard', text, cursorX, cursorY);
|
|
685
|
+
const createdNode = await module.dotNetHelper.invokeMethodAsync('PasteTextFromClipboard', text, cursorX, cursorY);
|
|
686
|
+
completePastedTextNode(module, createdNode);
|
|
686
687
|
} catch (error) {
|
|
687
688
|
console.warn('[MindMap] Ctrl+V fallback clipboard read failed:', error);
|
|
688
689
|
}
|
|
689
690
|
}, 120);
|
|
690
691
|
}
|
|
691
692
|
|
|
693
|
+
function completePastedTextNode(module, createdNode) {
|
|
694
|
+
const nodeId = String(createdNode?.nodeId ?? createdNode?.NodeId ?? '').trim();
|
|
695
|
+
const nodeEntry = nodeId ? module?.nodeObjectsById?.get?.(nodeId) : null;
|
|
696
|
+
if (!nodeEntry) return false;
|
|
697
|
+
|
|
698
|
+
finalizeSingleSelection(module, nodeId, { notifyBlazor: true, bringToFront: true, showMenu: true });
|
|
699
|
+
module.pendingSelectedActivationNodeIds?.clear?.();
|
|
700
|
+
module.pendingSelectedActivationNodeIds?.add?.(nodeId);
|
|
701
|
+
MindMapNodes.moveCursorAfterNodePlacement?.(
|
|
702
|
+
module,
|
|
703
|
+
nodeEntry.model,
|
|
704
|
+
nodeEntry.model?.width,
|
|
705
|
+
nodeEntry.model?.height,
|
|
706
|
+
{ moveCamera: false }
|
|
707
|
+
);
|
|
708
|
+
return true;
|
|
709
|
+
}
|
|
710
|
+
|
|
692
711
|
function copyTextMetricsFromElement(target, source) {
|
|
693
712
|
if (!target || !source || typeof window === 'undefined' || typeof window.getComputedStyle !== 'function') {
|
|
694
713
|
return;
|
|
@@ -2791,30 +2810,14 @@ window.MindMapInteractions = (function () {
|
|
|
2791
2810
|
if (newNodeIds.length === 1) {
|
|
2792
2811
|
module.selectedNodeIdJs = newNodeIds[0];
|
|
2793
2812
|
|
|
2794
|
-
|
|
2795
|
-
|
|
2796
|
-
|
|
2797
|
-
|
|
2798
|
-
|
|
2799
|
-
|
|
2800
|
-
|
|
2801
|
-
|
|
2802
|
-
|
|
2803
|
-
let nextCursorX, nextCursorY;
|
|
2804
|
-
if (direction === 'vertical') {
|
|
2805
|
-
// Move down (node height + padding)
|
|
2806
|
-
nextCursorX = nodeX;
|
|
2807
|
-
nextCursorY = nodeY - height - PADDING;
|
|
2808
|
-
} else {
|
|
2809
|
-
// Move right (node width + padding)
|
|
2810
|
-
nextCursorX = nodeX + width + PADDING;
|
|
2811
|
-
nextCursorY = nodeY;
|
|
2812
|
-
}
|
|
2813
|
-
|
|
2814
|
-
if (typeof module.updateCursorPosition === 'function') {
|
|
2815
|
-
module.updateCursorPosition(nextCursorX, nextCursorY, false);
|
|
2816
|
-
console.log(`[MindMap] 📍 Cursor moved to (${nextCursorX.toFixed(0)}, ${nextCursorY.toFixed(0)}) after paste`);
|
|
2817
|
-
}
|
|
2813
|
+
const pastedEntry = module.nodeObjectsById?.get?.(newNodeIds[0]);
|
|
2814
|
+
MindMapNodes.moveCursorAfterNodePlacement?.(
|
|
2815
|
+
module,
|
|
2816
|
+
pastedEntry?.model || nodesToPaste[0],
|
|
2817
|
+
pastedEntry?.model?.width || nodesToPaste[0].Width,
|
|
2818
|
+
pastedEntry?.model?.height || nodesToPaste[0].Height,
|
|
2819
|
+
{ moveCamera: false }
|
|
2820
|
+
);
|
|
2818
2821
|
}
|
|
2819
2822
|
if (module.pendingSelectedActivationNodeIds instanceof Set) {
|
|
2820
2823
|
module.pendingSelectedActivationNodeIds.clear();
|
|
@@ -2857,7 +2860,8 @@ window.MindMapInteractions = (function () {
|
|
|
2857
2860
|
if (module.dotNetHelper) {
|
|
2858
2861
|
const cursorX = module.cursorPosition?.x ?? 0;
|
|
2859
2862
|
const cursorY = module.cursorPosition?.y ?? 0;
|
|
2860
|
-
module.dotNetHelper.invokeMethodAsync('PasteTextFromClipboard', finalText, cursorX, cursorY);
|
|
2863
|
+
const createdNode = await module.dotNetHelper.invokeMethodAsync('PasteTextFromClipboard', finalText, cursorX, cursorY);
|
|
2864
|
+
completePastedTextNode(module, createdNode);
|
|
2861
2865
|
}
|
|
2862
2866
|
}
|
|
2863
2867
|
}
|