@mindexec/cli 0.2.145 → 0.2.147
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/package.json +1 -1
- package/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/remote-fleet-render-smoke.mjs +76 -3
- package/wwwroot/_content/MindExecution.Shared/js/mind-map-css3d-manager.js +231 -22
- package/wwwroot/index.html +3 -3
- package/wwwroot/service-worker-assets.js +3 -3
- package/wwwroot/service-worker.js +1 -1
package/package.json
CHANGED
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
@@ -856,12 +856,41 @@ try {
|
|
|
856
856
|
return { success: true };
|
|
857
857
|
}
|
|
858
858
|
};
|
|
859
|
-
|
|
859
|
+
const moduleRef = {
|
|
860
|
+
dotNetHelper,
|
|
861
|
+
nodeObjectsById: new Map(),
|
|
862
|
+
_visibleIds: new Set(['remote-fleet-render-smoke']),
|
|
863
|
+
_prevVisibleIds: new Set(['remote-fleet-render-smoke']),
|
|
864
|
+
_forceUpdateFrames: 0,
|
|
865
|
+
_textOverlayV2State: {
|
|
866
|
+
cards: new Map(),
|
|
867
|
+
passiveCandidateIds: new Set(['remote-fleet-render-smoke']),
|
|
868
|
+
layer: document.createElement('div')
|
|
869
|
+
},
|
|
870
|
+
requestAnimationWake(reason) {
|
|
871
|
+
this._lastAnimationWakeReason = reason;
|
|
872
|
+
this._animationWakeCount = Number(this._animationWakeCount || 0) + 1;
|
|
873
|
+
},
|
|
874
|
+
isAnimationLoopActive() {
|
|
875
|
+
return true;
|
|
876
|
+
}
|
|
877
|
+
};
|
|
878
|
+
manager.setModuleForTest(moduleRef);
|
|
860
879
|
|
|
861
880
|
const { nodeShell, bodyView } = createRemoteFleetTemplateShell(document, focusedDevice.DeviceId);
|
|
862
881
|
document.body.appendChild(nodeShell);
|
|
882
|
+
const monitorNode = buildMonitorNode(devices, hub.getStatus({ includeSecrets: true }), latestTaskBatch, recentTaskBatches);
|
|
883
|
+
moduleRef.nodeObjectsById.set('remote-fleet-render-smoke', {
|
|
884
|
+
model: monitorNode,
|
|
885
|
+
currentType: 'CSS',
|
|
886
|
+
cssObject: {
|
|
887
|
+
visible: true,
|
|
888
|
+
element: nodeShell
|
|
889
|
+
}
|
|
890
|
+
});
|
|
891
|
+
document.body.appendChild(moduleRef._textOverlayV2State.layer);
|
|
863
892
|
|
|
864
|
-
manager.renderRemoteFleetMonitorForTest(bodyView,
|
|
893
|
+
manager.renderRemoteFleetMonitorForTest(bodyView, monitorNode);
|
|
865
894
|
|
|
866
895
|
let cards = bodyView.querySelectorAll('article[data-device-id]');
|
|
867
896
|
assert.equal(cards.length, connectedCount);
|
|
@@ -894,7 +923,13 @@ try {
|
|
|
894
923
|
assert.equal(bodyView.querySelectorAll('[data-remote-fleet-action="task-device"]').length, 0);
|
|
895
924
|
assert.equal(bodyView.querySelectorAll('[data-remote-fleet-action="thumbnail-device"]').length, 0);
|
|
896
925
|
assert.equal(bodyView.querySelectorAll('[data-remote-fleet-frame-badge="true"]').length, 0);
|
|
897
|
-
|
|
926
|
+
const firstPreview = cards[0]?.querySelector('[data-remote-fleet-device-preview="tile"]');
|
|
927
|
+
assert.ok(firstPreview);
|
|
928
|
+
assert.match(cards[0]?.style.cssText || '', /border-radius:\s*0/);
|
|
929
|
+
assert.match(firstPreview.style.cssText, /border-radius:\s*0/);
|
|
930
|
+
assert.match(cards[0]?.title || '', /Status:\s*(Connected|Offline)/);
|
|
931
|
+
assert.match(cards[0]?.title || '', /Seen:/);
|
|
932
|
+
assert.match(cards[0]?.title || '', /Uptime:/);
|
|
898
933
|
assert.equal(/\b(Seen|Uptime|Mem|Load)\b/.test(cards[0]?.textContent || ''), false);
|
|
899
934
|
assert.match(deviceGrid.style.cssText, /minmax\(132px,\s*1fr\)/);
|
|
900
935
|
sizeControls.querySelector('[data-remote-fleet-action="monitor-size-up"]').dispatchEvent({ type: 'click' });
|
|
@@ -963,6 +998,16 @@ try {
|
|
|
963
998
|
false,
|
|
964
999
|
'binary Blob frame paint must not clear/fill the canvas before drawing');
|
|
965
1000
|
|
|
1001
|
+
const liveOverlayCard = document.createElement('div');
|
|
1002
|
+
liveOverlayCard.dataset.nodeId = 'remote-fleet-render-smoke';
|
|
1003
|
+
liveOverlayCard.dataset.sourceKind = 'live';
|
|
1004
|
+
liveOverlayCard.dataset.liveInteractive = 'true';
|
|
1005
|
+
liveOverlayCard.style.display = 'block';
|
|
1006
|
+
moduleRef._textOverlayV2State.cards.set('selection:remote-fleet-render-smoke', liveOverlayCard);
|
|
1007
|
+
moduleRef._forceUpdateFrames = 0;
|
|
1008
|
+
moduleRef._animationWakeCount = 0;
|
|
1009
|
+
moduleRef._lastAnimationWakeReason = '';
|
|
1010
|
+
|
|
966
1011
|
await wait(20);
|
|
967
1012
|
const liveWs = diagnostics.webSocketConnections[0];
|
|
968
1013
|
assert.ok(liveWs, 'expected MDM render to open the binary frame WebSocket');
|
|
@@ -990,6 +1035,14 @@ try {
|
|
|
990
1035
|
patchPreview.dataset.remoteFleetFrameSeq,
|
|
991
1036
|
String(websocketFrameSeq),
|
|
992
1037
|
JSON.stringify(diagnostics.runtimeTrace.slice(-12)));
|
|
1038
|
+
await wait(10);
|
|
1039
|
+
assert.ok(
|
|
1040
|
+
Number(moduleRef._forceUpdateFrames || 0) >= 2,
|
|
1041
|
+
'binary live frame commits must wake the passive MDM overlay frame loop');
|
|
1042
|
+
assert.equal(moduleRef._lastAnimationWakeReason, 'remote-live-overlay-frame');
|
|
1043
|
+
assert.ok(
|
|
1044
|
+
diagnostics.runtimeTrace.some(event => event.type === 'remote.frame.overlayWake'),
|
|
1045
|
+
'binary live frame commits must trace the MDM overlay wake path');
|
|
993
1046
|
|
|
994
1047
|
manager.renderRemoteFleetMonitorForTest(bodyView, buildMonitorNode(devices, hub.getStatus({ includeSecrets: true }), latestTaskBatch, recentTaskBatches));
|
|
995
1048
|
await wait(30);
|
|
@@ -1227,6 +1280,7 @@ try {
|
|
|
1227
1280
|
const emptyScreens = emptyBody.querySelectorAll('[data-remote-fleet-empty-screen="true"]');
|
|
1228
1281
|
assert.ok(emptyScreens.length >= 24, `expected empty monitor to fill space, got ${emptyScreens.length}`);
|
|
1229
1282
|
assert.notEqual(emptyScreens.length, 6);
|
|
1283
|
+
assert.match(emptyScreens[0].style.cssText, /border-radius:\s*0/);
|
|
1230
1284
|
assert.ok(Array.from(emptyBody.children).map(child =>
|
|
1231
1285
|
Object.keys(child.dataset || {}).join(',') || child.tagName).join('|').endsWith('remoteFleetStatusRail'));
|
|
1232
1286
|
assert.equal(emptyBody.textContent.includes('No devices connected yet.'), false);
|
|
@@ -1234,6 +1288,24 @@ try {
|
|
|
1234
1288
|
assert.equal(emptyBody.textContent.includes('No screen'), false);
|
|
1235
1289
|
assert.equal(emptyBody.textContent.includes('Endpoint 127.0.0.1'), false);
|
|
1236
1290
|
|
|
1291
|
+
const oneDevice = devices.find(device => device.Connected === true);
|
|
1292
|
+
assert.ok(oneDevice);
|
|
1293
|
+
const { nodeShell: oneShell, bodyView: oneBody } = createRemoteFleetTemplateShell(document);
|
|
1294
|
+
document.body.appendChild(oneShell);
|
|
1295
|
+
manager.renderRemoteFleetMonitorForTest(oneBody, buildMonitorNode([oneDevice], hub.getStatus({ includeSecrets: true })));
|
|
1296
|
+
const oneCards = oneBody.querySelectorAll('article[data-device-id]');
|
|
1297
|
+
assert.equal(oneCards.length, 1);
|
|
1298
|
+
const onePreview = oneCards[0]?.querySelector('[data-remote-fleet-device-preview="tile"]');
|
|
1299
|
+
assert.ok(onePreview);
|
|
1300
|
+
assert.match(oneCards[0]?.style.cssText || '', /border-radius:\s*0/);
|
|
1301
|
+
assert.match(onePreview.style.cssText, /border-radius:\s*0/);
|
|
1302
|
+
assert.match(oneCards[0]?.title || '', /Status:\s*Connected/);
|
|
1303
|
+
assert.match(oneCards[0]?.title || '', /Seen:/);
|
|
1304
|
+
assert.match(oneCards[0]?.title || '', /Uptime:/);
|
|
1305
|
+
const oneFillers = oneBody.querySelectorAll('[data-remote-fleet-empty-screen="true"]');
|
|
1306
|
+
assert.ok(oneFillers.length > 0, 'single connected monitor wall should keep blank screen placeholders');
|
|
1307
|
+
assert.match(oneFillers[0].style.cssText, /border-radius:\s*0/);
|
|
1308
|
+
|
|
1237
1309
|
const { nodeShell: errorShell, bodyView: errorBody } = createRemoteFleetTemplateShell(document);
|
|
1238
1310
|
document.body.appendChild(errorShell);
|
|
1239
1311
|
manager.renderRemoteFleetMonitorForTest(errorBody, buildMonitorNode([], hub.getStatus({ includeSecrets: true }), null, [], 'RemoteHub is unavailable. Start LocalBridge and retry.'));
|
|
@@ -1258,6 +1330,7 @@ try {
|
|
|
1258
1330
|
|
|
1259
1331
|
nodeShell.remove();
|
|
1260
1332
|
emptyShell.remove();
|
|
1333
|
+
oneShell.remove();
|
|
1261
1334
|
errorShell.remove();
|
|
1262
1335
|
deviceBody.remove();
|
|
1263
1336
|
await wait(2200);
|
|
@@ -13374,6 +13374,33 @@
|
|
|
13374
13374
|
return Math.max(12, Math.min(80, columns * rows));
|
|
13375
13375
|
}
|
|
13376
13376
|
|
|
13377
|
+
function createRemoteFleetEmptyScreenElement(metrics) {
|
|
13378
|
+
const screen = document.createElement('div');
|
|
13379
|
+
screen.dataset.remoteFleetEmptyScreen = 'true';
|
|
13380
|
+
screen.style.cssText = `
|
|
13381
|
+
width: 100%;
|
|
13382
|
+
height: auto;
|
|
13383
|
+
aspect-ratio: 16 / 9;
|
|
13384
|
+
min-height: ${metrics.emptyMinHeight}px;
|
|
13385
|
+
box-sizing: border-box;
|
|
13386
|
+
border-radius: 0;
|
|
13387
|
+
border: 1px solid rgba(203, 213, 225, 0.66);
|
|
13388
|
+
background: #ffffff;
|
|
13389
|
+
box-shadow: none;
|
|
13390
|
+
`;
|
|
13391
|
+
return screen;
|
|
13392
|
+
}
|
|
13393
|
+
|
|
13394
|
+
function appendRemoteFleetEmptyScreens(container, nodeModel, sizeState = 'cards', occupiedScreens = 0) {
|
|
13395
|
+
const metrics = getRemoteFleetTileMetrics(sizeState);
|
|
13396
|
+
const targetScreenCount = getRemoteFleetEmptyScreenCount(nodeModel, sizeState);
|
|
13397
|
+
const screenCount = Math.max(0, targetScreenCount - Math.max(0, Number(occupiedScreens) || 0));
|
|
13398
|
+
for (let index = 0; index < screenCount; index += 1) {
|
|
13399
|
+
container.appendChild(createRemoteFleetEmptyScreenElement(metrics));
|
|
13400
|
+
}
|
|
13401
|
+
return screenCount;
|
|
13402
|
+
}
|
|
13403
|
+
|
|
13377
13404
|
function createRemoteFleetEmptyScreens(nodeModel, sizeState = 'cards') {
|
|
13378
13405
|
const metrics = getRemoteFleetTileMetrics(sizeState);
|
|
13379
13406
|
const shell = document.createElement('section');
|
|
@@ -13399,23 +13426,7 @@
|
|
|
13399
13426
|
padding: 2px 4px 6px 4px;
|
|
13400
13427
|
`;
|
|
13401
13428
|
|
|
13402
|
-
|
|
13403
|
-
for (let index = 0; index < screenCount; index += 1) {
|
|
13404
|
-
const screen = document.createElement('div');
|
|
13405
|
-
screen.dataset.remoteFleetEmptyScreen = 'true';
|
|
13406
|
-
screen.style.cssText = `
|
|
13407
|
-
width: 100%;
|
|
13408
|
-
height: auto;
|
|
13409
|
-
aspect-ratio: 16 / 9;
|
|
13410
|
-
min-height: ${metrics.emptyMinHeight}px;
|
|
13411
|
-
box-sizing: border-box;
|
|
13412
|
-
border-radius: 8px;
|
|
13413
|
-
border: 1px solid rgba(203, 213, 225, 0.66);
|
|
13414
|
-
background: #ffffff;
|
|
13415
|
-
box-shadow: none;
|
|
13416
|
-
`;
|
|
13417
|
-
shell.appendChild(screen);
|
|
13418
|
-
}
|
|
13429
|
+
appendRemoteFleetEmptyScreens(shell, nodeModel, sizeState, 0);
|
|
13419
13430
|
|
|
13420
13431
|
return shell;
|
|
13421
13432
|
}
|
|
@@ -13877,6 +13888,145 @@
|
|
|
13877
13888
|
: 0;
|
|
13878
13889
|
}
|
|
13879
13890
|
|
|
13891
|
+
function getRemoteFleetBodyNodeId(bodyView) {
|
|
13892
|
+
return String(
|
|
13893
|
+
bodyView?.dataset?.nodeId
|
|
13894
|
+
|| bodyView?.dataset?.remoteFleetMonitorNodeId
|
|
13895
|
+
|| bodyView?.closest?.('.map-node-remote-fleet__body[data-node-id]')?.dataset?.nodeId
|
|
13896
|
+
|| bodyView?.closest?.('[data-node-id]')?.dataset?.nodeId
|
|
13897
|
+
|| ''
|
|
13898
|
+
).trim();
|
|
13899
|
+
}
|
|
13900
|
+
|
|
13901
|
+
function getRemoteFleetBodyFromPreview(preview) {
|
|
13902
|
+
if (!preview) {
|
|
13903
|
+
return null;
|
|
13904
|
+
}
|
|
13905
|
+
|
|
13906
|
+
return preview.closest?.('.map-node-remote-fleet__body[data-node-id]')
|
|
13907
|
+
|| preview.closest?.('.map-node-remote-fleet__body[data-remote-fleet-monitor-node-id]')
|
|
13908
|
+
|| null;
|
|
13909
|
+
}
|
|
13910
|
+
|
|
13911
|
+
function wakeRemoteFleetModuleAnimation(module, reason) {
|
|
13912
|
+
if (!module) {
|
|
13913
|
+
return;
|
|
13914
|
+
}
|
|
13915
|
+
|
|
13916
|
+
if (typeof module.requestAnimationWake === 'function') {
|
|
13917
|
+
module.requestAnimationWake(reason);
|
|
13918
|
+
}
|
|
13919
|
+
|
|
13920
|
+
if (typeof module.isAnimationLoopActive === 'function'
|
|
13921
|
+
&& module.isAnimationLoopActive() !== true
|
|
13922
|
+
&& typeof module.animate === 'function') {
|
|
13923
|
+
module.animate();
|
|
13924
|
+
}
|
|
13925
|
+
}
|
|
13926
|
+
|
|
13927
|
+
function flushRemoteFleetLiveOverlayWake(module) {
|
|
13928
|
+
const state = module?._remoteFleetLiveOverlayWakeState || null;
|
|
13929
|
+
if (!module || !state || !(state.nodeIds instanceof Set)) {
|
|
13930
|
+
return;
|
|
13931
|
+
}
|
|
13932
|
+
|
|
13933
|
+
state.raf = 0;
|
|
13934
|
+
let woke = false;
|
|
13935
|
+
const overlayState = module._textOverlayV2State || null;
|
|
13936
|
+
state.nodeIds.forEach(nodeId => {
|
|
13937
|
+
const normalizedNodeId = String(nodeId || '').trim();
|
|
13938
|
+
if (!normalizedNodeId) {
|
|
13939
|
+
return;
|
|
13940
|
+
}
|
|
13941
|
+
|
|
13942
|
+
const entry = module.nodeObjectsById?.get?.(normalizedNodeId) || null;
|
|
13943
|
+
if (!entry?.model || !isRemoteFleetMonitorNode(entry.model)) {
|
|
13944
|
+
return;
|
|
13945
|
+
}
|
|
13946
|
+
|
|
13947
|
+
const card = overlayState?.cards?.get?.(`selection:${normalizedNodeId}`) || null;
|
|
13948
|
+
const hasLiveOverlayCard =
|
|
13949
|
+
!!card &&
|
|
13950
|
+
card.style?.display !== 'none' &&
|
|
13951
|
+
card.dataset?.sourceKind === 'live' &&
|
|
13952
|
+
card.dataset?.liveInteractive === 'true';
|
|
13953
|
+
const mayCreatePassiveOverlay =
|
|
13954
|
+
window.MindMapTextOverlayV2?.shouldRenderPassiveDomOverlays?.(module) === true &&
|
|
13955
|
+
(
|
|
13956
|
+
overlayState?.passiveCandidateIds?.has?.(normalizedNodeId) === true ||
|
|
13957
|
+
module._visibleIds?.has?.(normalizedNodeId) === true ||
|
|
13958
|
+
module._prevVisibleIds?.has?.(normalizedNodeId) === true ||
|
|
13959
|
+
String(module.selectedNodeIdJs || '').trim() === normalizedNodeId
|
|
13960
|
+
);
|
|
13961
|
+
|
|
13962
|
+
if (!hasLiveOverlayCard && !mayCreatePassiveOverlay) {
|
|
13963
|
+
return;
|
|
13964
|
+
}
|
|
13965
|
+
|
|
13966
|
+
if (hasLiveOverlayCard) {
|
|
13967
|
+
if (overlayState?.layer?.style && module._suppressPassiveDomOverlayDuringZoom !== true) {
|
|
13968
|
+
overlayState.layer.style.display = '';
|
|
13969
|
+
}
|
|
13970
|
+
card.style.display = 'block';
|
|
13971
|
+
} else {
|
|
13972
|
+
window.MindMapTextOverlayV2?.invalidateNode?.(module, normalizedNodeId, 'remote-live-frame');
|
|
13973
|
+
module._overlayDirty = true;
|
|
13974
|
+
module._lastOverlayKey = '';
|
|
13975
|
+
}
|
|
13976
|
+
|
|
13977
|
+
woke = true;
|
|
13978
|
+
});
|
|
13979
|
+
state.nodeIds.clear();
|
|
13980
|
+
|
|
13981
|
+
if (!woke) {
|
|
13982
|
+
return;
|
|
13983
|
+
}
|
|
13984
|
+
|
|
13985
|
+
module._forceUpdateFrames = Math.max(Number(module._forceUpdateFrames || 0), 2);
|
|
13986
|
+
module._css3dVisualChangedThisFrame = true;
|
|
13987
|
+
module._css3dVisualChangedSinceLastRender = true;
|
|
13988
|
+
wakeRemoteFleetModuleAnimation(module, 'remote-live-overlay-frame');
|
|
13989
|
+
|
|
13990
|
+
const now = getRemoteFleetFrameNow();
|
|
13991
|
+
if (now - Number(module._remoteFleetLiveOverlayWakeLastTraceAt || 0) >= 1000) {
|
|
13992
|
+
module._remoteFleetLiveOverlayWakeLastTraceAt = now;
|
|
13993
|
+
window.RuntimeTrace?.emit?.('remote.frame.overlayWake', {
|
|
13994
|
+
nodes: state.lastWakeCount || 0
|
|
13995
|
+
});
|
|
13996
|
+
}
|
|
13997
|
+
}
|
|
13998
|
+
|
|
13999
|
+
function requestRemoteFleetLiveOverlayWake(bodyView, frame) {
|
|
14000
|
+
if (!_module || !bodyView || String(frame?.kind || '').toLowerCase() !== 'live') {
|
|
14001
|
+
return false;
|
|
14002
|
+
}
|
|
14003
|
+
|
|
14004
|
+
const nodeId = getRemoteFleetBodyNodeId(bodyView);
|
|
14005
|
+
if (!nodeId) {
|
|
14006
|
+
return false;
|
|
14007
|
+
}
|
|
14008
|
+
|
|
14009
|
+
const state = _module._remoteFleetLiveOverlayWakeState || {
|
|
14010
|
+
nodeIds: new Set(),
|
|
14011
|
+
raf: 0,
|
|
14012
|
+
lastWakeCount: 0
|
|
14013
|
+
};
|
|
14014
|
+
_module._remoteFleetLiveOverlayWakeState = state;
|
|
14015
|
+
state.nodeIds.add(nodeId);
|
|
14016
|
+
state.lastWakeCount = state.nodeIds.size;
|
|
14017
|
+
|
|
14018
|
+
if (!state.raf) {
|
|
14019
|
+
state.raf = requestRemoteFleetFrameLoopFrame(() => flushRemoteFleetLiveOverlayWake(_module));
|
|
14020
|
+
}
|
|
14021
|
+
|
|
14022
|
+
return true;
|
|
14023
|
+
}
|
|
14024
|
+
|
|
14025
|
+
function requestRemoteFleetLiveOverlayWakeFromPreview(preview, frame) {
|
|
14026
|
+
const bodyView = getRemoteFleetBodyFromPreview(preview);
|
|
14027
|
+
return requestRemoteFleetLiveOverlayWake(bodyView, frame);
|
|
14028
|
+
}
|
|
14029
|
+
|
|
13880
14030
|
function refreshRemoteFleetBinaryFrameSubscription(session, force = false) {
|
|
13881
14031
|
if (!session?.ws || session.ws.readyState !== WebSocket.OPEN) {
|
|
13882
14032
|
return false;
|
|
@@ -14181,6 +14331,54 @@
|
|
|
14181
14331
|
|| 'device');
|
|
14182
14332
|
}
|
|
14183
14333
|
|
|
14334
|
+
function getRemoteFleetDeviceTooltip(device) {
|
|
14335
|
+
const name = getRemoteFleetDeviceName(device);
|
|
14336
|
+
const deviceId = getRemoteFleetDeviceId(device);
|
|
14337
|
+
const hostname = String(getRemoteFleetDeviceField(device, 'hostname', 'Hostname', '') || '').trim();
|
|
14338
|
+
const connected = isRemoteFleetDeviceConnected(device);
|
|
14339
|
+
const platform = [
|
|
14340
|
+
getRemoteFleetDeviceField(device, 'platform', 'Platform', ''),
|
|
14341
|
+
getRemoteFleetDeviceField(device, 'release', 'Release', ''),
|
|
14342
|
+
getRemoteFleetDeviceField(device, 'arch', 'Arch', '')
|
|
14343
|
+
].map(value => String(value || '').trim()).filter(Boolean).join(' ');
|
|
14344
|
+
const agentVersion = String(getRemoteFleetDeviceField(device, 'agentVersion', 'AgentVersion', '') || '').trim();
|
|
14345
|
+
const remoteAddress = String(getRemoteFleetDeviceField(device, 'remoteAddress', 'RemoteAddress', '') || '').trim();
|
|
14346
|
+
const remotePort = Number(getRemoteFleetDeviceField(device, 'remotePort', 'RemotePort', 0)) || 0;
|
|
14347
|
+
const remoteEndpoint = remoteAddress ? `${remoteAddress}${remotePort > 0 ? `:${remotePort}` : ''}` : '';
|
|
14348
|
+
const liveSeq = getRemoteFleetFrameSeq(device, 'live');
|
|
14349
|
+
const thumbnailSeq = getRemoteFleetFrameSeq(device, 'thumbnail');
|
|
14350
|
+
const liveReceivedAt = String(getRemoteFleetDeviceField(device, 'liveFrameReceivedAt', 'LiveFrameReceivedAt', '') || '').trim();
|
|
14351
|
+
const thumbnailReceivedAt = String(getRemoteFleetDeviceField(device, 'thumbnailReceivedAt', 'ThumbnailReceivedAt', '') || '').trim();
|
|
14352
|
+
const latestTaskStatus = String(getRemoteFleetDeviceField(device, 'latestTaskStatus', 'LatestTaskStatus', '') || '').trim();
|
|
14353
|
+
const latestTaskTitle = String(getRemoteFleetDeviceField(device, 'latestTaskTitle', 'LatestTaskTitle', '') || '').trim();
|
|
14354
|
+
const latestTaskError = String(getRemoteFleetDeviceField(device, 'latestTaskError', 'LatestTaskError', '') || '').trim();
|
|
14355
|
+
const capabilityText = [
|
|
14356
|
+
isRemoteFleetLiveCapable(device) ? 'live' : '',
|
|
14357
|
+
isRemoteFleetThumbnailCapable(device) ? 'thumbnail' : '',
|
|
14358
|
+
isRemoteFleetDeviceTaskCapable(device) ? 'task' : '',
|
|
14359
|
+
isRemoteFleetDeviceAiCapable(device) ? 'ai' : ''
|
|
14360
|
+
].filter(Boolean).join(', ');
|
|
14361
|
+
|
|
14362
|
+
return [
|
|
14363
|
+
name,
|
|
14364
|
+
deviceId ? `ID: ${deviceId}` : '',
|
|
14365
|
+
hostname && hostname !== name ? `Host: ${hostname}` : '',
|
|
14366
|
+
`Status: ${connected ? 'Connected' : 'Offline'}`,
|
|
14367
|
+
platform ? `OS: ${platform}` : '',
|
|
14368
|
+
agentVersion ? `Agent: ${agentVersion}` : '',
|
|
14369
|
+
remoteEndpoint ? `Remote: ${remoteEndpoint}` : '',
|
|
14370
|
+
`Seen: ${formatRemoteFleetAge(getRemoteFleetDeviceField(device, 'lastSeenAt', 'LastSeenAt', ''))}`,
|
|
14371
|
+
`Uptime: ${formatRemoteFleetDuration(getRemoteFleetDeviceField(device, 'uptimeSec', 'UptimeSec', Number.NaN))}`,
|
|
14372
|
+
`Memory: ${formatRemoteFleetPercent(getRemoteFleetDeviceField(device, 'usedMemRatio', 'UsedMemRatio', Number.NaN))}`,
|
|
14373
|
+
`Load: ${formatRemoteFleetNumber(getRemoteFleetDeviceField(device, 'load1', 'Load1', Number.NaN), 2)}`,
|
|
14374
|
+
liveSeq > 0 ? `Live frame: #${liveSeq}${liveReceivedAt ? ` (${formatRemoteFleetAge(liveReceivedAt)})` : ''}` : '',
|
|
14375
|
+
thumbnailSeq > 0 ? `Thumbnail: #${thumbnailSeq}${thumbnailReceivedAt ? ` (${formatRemoteFleetAge(thumbnailReceivedAt)})` : ''}` : '',
|
|
14376
|
+
capabilityText ? `Capabilities: ${capabilityText}` : '',
|
|
14377
|
+
latestTaskStatus ? `Task: ${latestTaskStatus}${latestTaskTitle ? ` - ${latestTaskTitle}` : ''}` : '',
|
|
14378
|
+
latestTaskError ? `Task error: ${formatRemoteFleetTaskError(latestTaskError)}` : ''
|
|
14379
|
+
].filter(Boolean).join('\n');
|
|
14380
|
+
}
|
|
14381
|
+
|
|
14184
14382
|
function isRemoteFleetDeviceConnected(device) {
|
|
14185
14383
|
return getRemoteFleetDeviceField(device, 'connected', 'Connected', false) === true;
|
|
14186
14384
|
}
|
|
@@ -14701,7 +14899,11 @@
|
|
|
14701
14899
|
canvas.style.display = 'none';
|
|
14702
14900
|
}
|
|
14703
14901
|
|
|
14704
|
-
|
|
14902
|
+
const committed = commitRemoteFleetFrameMetadata(preview, frame);
|
|
14903
|
+
if (committed) {
|
|
14904
|
+
requestRemoteFleetLiveOverlayWakeFromPreview(preview, frame);
|
|
14905
|
+
}
|
|
14906
|
+
return committed;
|
|
14705
14907
|
}
|
|
14706
14908
|
|
|
14707
14909
|
function commitRemoteFleetFrameToCanvas(preview, canvas, image, bitmap, frame) {
|
|
@@ -14722,7 +14924,11 @@
|
|
|
14722
14924
|
image.style.display = 'none';
|
|
14723
14925
|
}
|
|
14724
14926
|
|
|
14725
|
-
|
|
14927
|
+
const committed = commitRemoteFleetFrameMetadata(preview, frame);
|
|
14928
|
+
if (committed) {
|
|
14929
|
+
requestRemoteFleetLiveOverlayWakeFromPreview(preview, frame);
|
|
14930
|
+
}
|
|
14931
|
+
return committed;
|
|
14726
14932
|
}
|
|
14727
14933
|
|
|
14728
14934
|
function clearRemoteFleetPendingFrameDataset(preview, frame) {
|
|
@@ -17122,12 +17328,13 @@
|
|
|
17122
17328
|
preview.dataset.remoteFleetFrameSeq = String(hasLiveFrame
|
|
17123
17329
|
? getRemoteFleetDeviceField(device, 'liveFrameSeq', 'LiveFrameSeq', 0)
|
|
17124
17330
|
: getRemoteFleetDeviceField(device, 'thumbnailFrameSeq', 'ThumbnailFrameSeq', 0));
|
|
17331
|
+
preview.title = getRemoteFleetDeviceTooltip(device);
|
|
17125
17332
|
preview.style.cssText = `
|
|
17126
17333
|
position: relative;
|
|
17127
17334
|
width: 100%;
|
|
17128
17335
|
aspect-ratio: 16 / 9;
|
|
17129
17336
|
overflow: hidden;
|
|
17130
|
-
border-radius:
|
|
17337
|
+
border-radius: 0;
|
|
17131
17338
|
background: ${(hasLiveFrame || hasThumbnail) ? 'linear-gradient(135deg, #0f172a 0%, #1e293b 100%)' : '#ffffff'};
|
|
17132
17339
|
border: 1px solid rgba(148, 163, 184, ${isDetail ? '0.34' : '0.24'});
|
|
17133
17340
|
box-shadow: none;
|
|
@@ -17288,7 +17495,7 @@
|
|
|
17288
17495
|
card.setAttribute('aria-pressed', isSelected ? 'true' : 'false');
|
|
17289
17496
|
card.setAttribute('aria-label', `Open remote control for ${name}`);
|
|
17290
17497
|
card.tabIndex = 0;
|
|
17291
|
-
card.title =
|
|
17498
|
+
card.title = getRemoteFleetDeviceTooltip(device);
|
|
17292
17499
|
card.style.cssText = `
|
|
17293
17500
|
position: relative;
|
|
17294
17501
|
display: flex;
|
|
@@ -17301,7 +17508,7 @@
|
|
|
17301
17508
|
box-sizing: border-box;
|
|
17302
17509
|
overflow: hidden;
|
|
17303
17510
|
padding: 0;
|
|
17304
|
-
border-radius:
|
|
17511
|
+
border-radius: 0;
|
|
17305
17512
|
background: transparent;
|
|
17306
17513
|
border: 0;
|
|
17307
17514
|
box-shadow: none;
|
|
@@ -17319,6 +17526,8 @@
|
|
|
17319
17526
|
grid.appendChild(card);
|
|
17320
17527
|
});
|
|
17321
17528
|
|
|
17529
|
+
appendRemoteFleetEmptyScreens(grid, nodeModel, densityState, devices.length);
|
|
17530
|
+
|
|
17322
17531
|
const noMatch = document.createElement('div');
|
|
17323
17532
|
noMatch.dataset.remoteFleetNoMatch = 'true';
|
|
17324
17533
|
noMatch.textContent = 'No matching devices.';
|
package/wwwroot/index.html
CHANGED
|
@@ -7,8 +7,8 @@
|
|
|
7
7
|
<title>MindExec | Run your ideas as AI task graphs</title>
|
|
8
8
|
<meta name="description" content="MindExec is an AI execution canvas for solo builders, researchers, developers, and creators. Start with free browser tools, then move serious work into saved MindCanvas projects." />
|
|
9
9
|
<base href="/" />
|
|
10
|
-
<link rel="stylesheet" href="_content/MindExecution.Shared/css/app.css?v=20260617-mdm-
|
|
11
|
-
<link rel="stylesheet" href="_content/MindExecution.Shared/css/mind-map-overrides.css?v=20260617-mdm-
|
|
10
|
+
<link rel="stylesheet" href="_content/MindExecution.Shared/css/app.css?v=20260617-mdm-monitor-wall-v582" />
|
|
11
|
+
<link rel="stylesheet" href="_content/MindExecution.Shared/css/mind-map-overrides.css?v=20260617-mdm-monitor-wall-v582" />
|
|
12
12
|
<!-- ?쇄뼹??Font Awesome (local) ?쇄뼹??-->
|
|
13
13
|
<link rel="stylesheet" href="_content/MindExecution.Shared/lib/font-awesome/css/all.min.css" />
|
|
14
14
|
<!-- ?꿎뼯??-->
|
|
@@ -579,7 +579,7 @@
|
|
|
579
579
|
}
|
|
580
580
|
|
|
581
581
|
const base = '_content/MindExecution.Shared/js/';
|
|
582
|
-
const scriptVersion = '20260617-mdm-
|
|
582
|
+
const scriptVersion = '20260617-mdm-monitor-wall-v582';
|
|
583
583
|
const scriptUrl = (script) => `${base}${script}?v=${scriptVersion}`;
|
|
584
584
|
console.log(`[Script Loader] Shared JS version: ${scriptVersion}`);
|
|
585
585
|
const criticalScripts = [
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
self.assetsManifest = {
|
|
2
|
-
"version": "
|
|
2
|
+
"version": "7b1rjf6s",
|
|
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-
|
|
89
|
+
"hash": "sha256-N0yX4cRkRJsZGixBtFAt5IkDeSMDDcKAmNtERmwuC+0=",
|
|
90
90
|
"url": "_content/MindExecution.Shared/js/mind-map-css3d-manager.js"
|
|
91
91
|
},
|
|
92
92
|
{
|
|
@@ -834,7 +834,7 @@
|
|
|
834
834
|
"url": "image-manifest.json"
|
|
835
835
|
},
|
|
836
836
|
{
|
|
837
|
-
"hash": "sha256-
|
|
837
|
+
"hash": "sha256-OtihK34SGInpkBV5g69QHYb9Mt/yUTsekpGz4Jl29L0=",
|
|
838
838
|
"url": "index.html"
|
|
839
839
|
},
|
|
840
840
|
{
|