@mindexec/cli 0.2.158 → 0.2.159
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
CHANGED
|
@@ -1043,6 +1043,7 @@ try {
|
|
|
1043
1043
|
binaryDrawCalls.some(call => call.op === 'clearRect' || call.op === 'fillRect'),
|
|
1044
1044
|
false,
|
|
1045
1045
|
'binary Blob frame paint must not clear/fill the canvas before drawing');
|
|
1046
|
+
const binaryCanvasBeforeRerender = binaryCanvas;
|
|
1046
1047
|
|
|
1047
1048
|
const liveOverlayCard = document.createElement('div');
|
|
1048
1049
|
liveOverlayCard.dataset.nodeId = 'remote-fleet-render-smoke';
|
|
@@ -1105,7 +1106,12 @@ try {
|
|
|
1105
1106
|
?.querySelector('[data-remote-fleet-device-preview="tile"]');
|
|
1106
1107
|
assert.ok(rerenderedPatchPreview);
|
|
1107
1108
|
assert.equal(rerenderedPatchPreview.dataset.remoteFleetFrameSeq, String(websocketFrameSeq));
|
|
1108
|
-
|
|
1109
|
+
const rerenderedPatchCanvas = rerenderedPatchPreview.querySelector('canvas[data-remote-fleet-frame-canvas="true"]');
|
|
1110
|
+
assert.equal(rerenderedPatchCanvas?.style.display, 'block');
|
|
1111
|
+
assert.equal(
|
|
1112
|
+
rerenderedPatchCanvas,
|
|
1113
|
+
binaryCanvasBeforeRerender,
|
|
1114
|
+
'MDM rerender should reuse the already-painted canvas instead of flashing a blank replacement');
|
|
1109
1115
|
|
|
1110
1116
|
const otherBoardNodeId = 'remote-fleet-render-smoke-other-board';
|
|
1111
1117
|
const { nodeShell: otherBoardShell, bodyView: otherBoardBodyView } =
|
|
@@ -1434,6 +1440,18 @@ try {
|
|
|
1434
1440
|
assert.ok(deviceBody.querySelector('[data-remote-fleet-action="task-device"]'));
|
|
1435
1441
|
assert.ok(deviceBody.textContent.includes('Task timed out waiting for the agent response.'));
|
|
1436
1442
|
assert.ok(deviceBody.textContent.includes(focusedDevice.DeviceId));
|
|
1443
|
+
const controlCanvasBeforeRerender = deviceControlCanvas;
|
|
1444
|
+
manager.renderRemoteFleetDeviceForTest(deviceBody, buildDeviceNode(focusedDevice, hub.getStatus()));
|
|
1445
|
+
await wait(30);
|
|
1446
|
+
const controlCanvasAfterRerender = deviceBody.querySelector('[data-remote-fleet-control-node-canvas="true"]');
|
|
1447
|
+
assert.equal(
|
|
1448
|
+
controlCanvasAfterRerender,
|
|
1449
|
+
controlCanvasBeforeRerender,
|
|
1450
|
+
'RemoteFleetDevice rerender should reuse the already-painted control canvas instead of flashing black');
|
|
1451
|
+
assert.equal(
|
|
1452
|
+
deviceBody.querySelector('[data-remote-fleet-control-node-placeholder="true"]'),
|
|
1453
|
+
null,
|
|
1454
|
+
'RemoteFleetDevice rerender should not cover a restored control canvas with a waiting placeholder');
|
|
1437
1455
|
|
|
1438
1456
|
nodeShell.remove();
|
|
1439
1457
|
emptyShell.remove();
|
|
@@ -14842,6 +14842,104 @@
|
|
|
14842
14842
|
return canvas;
|
|
14843
14843
|
}
|
|
14844
14844
|
|
|
14845
|
+
function collectRemoteFleetPreviewFrameSurfaces(root) {
|
|
14846
|
+
const surfaces = new Map();
|
|
14847
|
+
if (!root?.querySelectorAll) {
|
|
14848
|
+
return surfaces;
|
|
14849
|
+
}
|
|
14850
|
+
|
|
14851
|
+
root.querySelectorAll('[data-remote-fleet-device-preview][data-device-id]').forEach(preview => {
|
|
14852
|
+
const deviceId = String(preview.dataset.deviceId || '').trim();
|
|
14853
|
+
if (!deviceId) {
|
|
14854
|
+
return;
|
|
14855
|
+
}
|
|
14856
|
+
|
|
14857
|
+
const canvas = preview.querySelector('canvas[data-remote-fleet-frame-canvas="true"]');
|
|
14858
|
+
const image = preview.querySelector('img[data-remote-fleet-frame-image="true"]');
|
|
14859
|
+
surfaces.set(deviceId, {
|
|
14860
|
+
canvas,
|
|
14861
|
+
image,
|
|
14862
|
+
kind: String(preview.dataset.remoteFleetFrameKind || canvas?.dataset?.remoteFleetFrameKind || image?.dataset?.remoteFleetFrameKind || '').trim().toLowerCase(),
|
|
14863
|
+
seq: Number(preview.dataset.remoteFleetFrameSeq || canvas?.dataset?.remoteFleetFrameSeq || image?.dataset?.remoteFleetFrameSeq || 0) || 0,
|
|
14864
|
+
url: String(preview.dataset.remoteFleetFrameUrl || canvas?.dataset?.remoteFleetFrameUrl || image?.dataset?.remoteFleetFrameUrl || '').trim()
|
|
14865
|
+
});
|
|
14866
|
+
});
|
|
14867
|
+
|
|
14868
|
+
return surfaces;
|
|
14869
|
+
}
|
|
14870
|
+
|
|
14871
|
+
function restoreRemoteFleetPreviewFrameSurface(preview, surfaces, deviceId) {
|
|
14872
|
+
const id = String(deviceId || preview?.dataset?.deviceId || '').trim();
|
|
14873
|
+
const surface = id && surfaces instanceof Map ? surfaces.get(id) : null;
|
|
14874
|
+
if (!preview || !surface) {
|
|
14875
|
+
return false;
|
|
14876
|
+
}
|
|
14877
|
+
|
|
14878
|
+
const existingSeq = Number(surface.seq || 0) || 0;
|
|
14879
|
+
const nextSeq = Number(preview.dataset.remoteFleetFrameSeq || 0) || 0;
|
|
14880
|
+
if (existingSeq <= 0 || (nextSeq > 0 && existingSeq < nextSeq)) {
|
|
14881
|
+
return false;
|
|
14882
|
+
}
|
|
14883
|
+
|
|
14884
|
+
const currentCanvas = preview.querySelector('canvas[data-remote-fleet-frame-canvas="true"]');
|
|
14885
|
+
if (surface.canvas && surface.canvas !== currentCanvas) {
|
|
14886
|
+
currentCanvas?.remove?.();
|
|
14887
|
+
surface.canvas.dataset.remoteFleetFrameKind = surface.kind || preview.dataset.remoteFleetFrameKind || 'live';
|
|
14888
|
+
surface.canvas.dataset.remoteFleetFrameSeq = String(existingSeq);
|
|
14889
|
+
surface.canvas.dataset.remoteFleetFrameUrl = surface.url || '';
|
|
14890
|
+
surface.canvas.style.display = 'block';
|
|
14891
|
+
if (typeof preview.insertBefore === 'function') {
|
|
14892
|
+
preview.insertBefore(surface.canvas, preview.firstChild || null);
|
|
14893
|
+
} else {
|
|
14894
|
+
preview.appendChild?.(surface.canvas);
|
|
14895
|
+
}
|
|
14896
|
+
}
|
|
14897
|
+
|
|
14898
|
+
const currentImage = preview.querySelector('img[data-remote-fleet-frame-image="true"]');
|
|
14899
|
+
if (surface.canvas) {
|
|
14900
|
+
preview.querySelector('[data-remote-fleet-screen-placeholder="true"]')?.remove?.();
|
|
14901
|
+
if (currentImage && currentImage !== surface.image) {
|
|
14902
|
+
currentImage.style.display = 'none';
|
|
14903
|
+
}
|
|
14904
|
+
if (surface.image && surface.image !== currentImage && surface.image.parentElement === preview) {
|
|
14905
|
+
surface.image.style.display = 'none';
|
|
14906
|
+
}
|
|
14907
|
+
} else if (surface.image && surface.image !== currentImage) {
|
|
14908
|
+
currentImage?.remove?.();
|
|
14909
|
+
surface.image.style.display = 'block';
|
|
14910
|
+
if (typeof preview.insertBefore === 'function') {
|
|
14911
|
+
preview.insertBefore(surface.image, preview.firstChild || null);
|
|
14912
|
+
} else {
|
|
14913
|
+
preview.appendChild?.(surface.image);
|
|
14914
|
+
}
|
|
14915
|
+
}
|
|
14916
|
+
|
|
14917
|
+
preview.dataset.remoteFleetFrameKind = surface.kind || preview.dataset.remoteFleetFrameKind || '';
|
|
14918
|
+
preview.dataset.remoteFleetFrameSeq = String(existingSeq);
|
|
14919
|
+
preview.dataset.remoteFleetFrameUrl = surface.url || '';
|
|
14920
|
+
preview.dataset.remoteFleetRestoredFrame = 'true';
|
|
14921
|
+
return true;
|
|
14922
|
+
}
|
|
14923
|
+
|
|
14924
|
+
function collectRemoteFleetControlNodeSurface(root) {
|
|
14925
|
+
const canvas = root?.querySelector?.('canvas[data-remote-fleet-control-node-canvas="true"]');
|
|
14926
|
+
if (!canvas) {
|
|
14927
|
+
return null;
|
|
14928
|
+
}
|
|
14929
|
+
|
|
14930
|
+
return {
|
|
14931
|
+
canvas,
|
|
14932
|
+
kind: String(canvas.dataset.remoteFleetFrameKind || 'live').trim().toLowerCase(),
|
|
14933
|
+
seq: Number(canvas.dataset.remoteFleetFrameSeq || 0) || 0,
|
|
14934
|
+
contentRect: canvas._remoteFleetContentRect || null
|
|
14935
|
+
};
|
|
14936
|
+
}
|
|
14937
|
+
|
|
14938
|
+
function hasRemoteFleetReusableControlSurface(surface) {
|
|
14939
|
+
return !!surface?.canvas
|
|
14940
|
+
&& (Number(surface.seq || 0) > 0 || !!surface.contentRect);
|
|
14941
|
+
}
|
|
14942
|
+
|
|
14845
14943
|
function syncRemoteFleetFrameCanvasSize(canvas) {
|
|
14846
14944
|
if (!canvas) {
|
|
14847
14945
|
return null;
|
|
@@ -14853,8 +14951,18 @@
|
|
|
14853
14951
|
const cssWidth = Math.max(1, Math.round(rect?.width || canvas.clientWidth || 320));
|
|
14854
14952
|
const cssHeight = Math.max(1, Math.round(rect?.height || canvas.clientHeight || 180));
|
|
14855
14953
|
const dpr = Math.max(1, Math.min(REMOTE_FLEET_FRAME_CANVAS_MAX_DPR, Number(window.devicePixelRatio || 1) || 1));
|
|
14856
|
-
|
|
14857
|
-
|
|
14954
|
+
let nextWidth = Math.max(1, Math.round(cssWidth * dpr));
|
|
14955
|
+
let nextHeight = Math.max(1, Math.round(cssHeight * dpr));
|
|
14956
|
+
const currentWidth = Number(canvas.width || 0) || 0;
|
|
14957
|
+
const currentHeight = Number(canvas.height || 0) || 0;
|
|
14958
|
+
const widthDelta = Math.abs(currentWidth - nextWidth);
|
|
14959
|
+
const heightDelta = Math.abs(currentHeight - nextHeight);
|
|
14960
|
+
if (currentWidth > 0 && widthDelta > 0 && widthDelta <= 2) {
|
|
14961
|
+
nextWidth = currentWidth;
|
|
14962
|
+
}
|
|
14963
|
+
if (currentHeight > 0 && heightDelta > 0 && heightDelta <= 2) {
|
|
14964
|
+
nextHeight = currentHeight;
|
|
14965
|
+
}
|
|
14858
14966
|
if (canvas.width !== nextWidth) {
|
|
14859
14967
|
canvas.width = nextWidth;
|
|
14860
14968
|
}
|
|
@@ -15970,7 +16078,12 @@
|
|
|
15970
16078
|
}
|
|
15971
16079
|
|
|
15972
16080
|
drawRemoteFleetFrameToCanvas(session.canvas, bitmap, 'contain');
|
|
16081
|
+
session.canvas.dataset.remoteFleetFrameKind = String(frame.kind || 'live').toLowerCase();
|
|
16082
|
+
session.canvas.dataset.remoteFleetFrameSeq = String(Number(frame.frameSeq || frame.FrameSeq || 0) || 0);
|
|
16083
|
+
session.canvas.dataset.remoteFleetFrameUrl = String(frame.frameUrl || '');
|
|
15973
16084
|
session.canvas.style.display = 'block';
|
|
16085
|
+
session.lastControlFrameSeq = Number(frame.frameSeq || frame.FrameSeq || session.lastControlFrameSeq || 0) || 0;
|
|
16086
|
+
session.lastControlFrameAt = Date.now();
|
|
15974
16087
|
session.placeholder?.remove?.();
|
|
15975
16088
|
session.placeholder = null;
|
|
15976
16089
|
if (typeof bitmap.close === 'function') {
|
|
@@ -16020,6 +16133,9 @@
|
|
|
16020
16133
|
}
|
|
16021
16134
|
|
|
16022
16135
|
drawRemoteFleetFrameToCanvas(session.canvas, bitmap, 'contain');
|
|
16136
|
+
session.canvas.dataset.remoteFleetFrameKind = String(frame.kind || 'live').toLowerCase();
|
|
16137
|
+
session.canvas.dataset.remoteFleetFrameSeq = String(frameSeq || 0);
|
|
16138
|
+
session.canvas.dataset.remoteFleetFrameUrl = String(frame.frameUrl || '');
|
|
16023
16139
|
session.canvas.style.display = 'block';
|
|
16024
16140
|
session.lastControlFrameAt = Date.now();
|
|
16025
16141
|
session.status.textContent = `Control ${REMOTE_FLEET_CONTROL_LIVE_FPS}fps`;
|
|
@@ -16971,6 +17087,7 @@
|
|
|
16971
17087
|
function renderRemoteFleetDevice(bodyView, nodeModel) {
|
|
16972
17088
|
if (!bodyView) return;
|
|
16973
17089
|
clearRemoteFleetTimers(bodyView, { keepBinaryFrameSocket: true });
|
|
17090
|
+
const preservedControlSurface = collectRemoteFleetControlNodeSurface(bodyView);
|
|
16974
17091
|
|
|
16975
17092
|
const nodeId = String(nodeModel?.id ?? nodeModel?.Id ?? '');
|
|
16976
17093
|
const device = parseRemoteFleetPinnedDevice(nodeModel);
|
|
@@ -17166,7 +17283,7 @@
|
|
|
17166
17283
|
touch-action: none;
|
|
17167
17284
|
outline: none;
|
|
17168
17285
|
`;
|
|
17169
|
-
const controlCanvas = document.createElement('canvas');
|
|
17286
|
+
const controlCanvas = preservedControlSurface?.canvas || document.createElement('canvas');
|
|
17170
17287
|
controlCanvas.dataset.remoteFleetControlNodeCanvas = 'true';
|
|
17171
17288
|
controlCanvas.style.cssText = `
|
|
17172
17289
|
position: absolute;
|
|
@@ -17226,7 +17343,10 @@
|
|
|
17226
17343
|
controlOverlay.appendChild(controlDot);
|
|
17227
17344
|
controlOverlay.appendChild(controlStatus);
|
|
17228
17345
|
controlStage.appendChild(controlCanvas);
|
|
17229
|
-
|
|
17346
|
+
const restoredControlSurface = hasRemoteFleetReusableControlSurface(preservedControlSurface);
|
|
17347
|
+
if (!restoredControlSurface) {
|
|
17348
|
+
controlStage.appendChild(controlPlaceholder);
|
|
17349
|
+
}
|
|
17230
17350
|
controlStage.appendChild(controlOverlay);
|
|
17231
17351
|
bodyView.appendChild(controlStage);
|
|
17232
17352
|
|
|
@@ -17238,7 +17358,17 @@
|
|
|
17238
17358
|
controlStage,
|
|
17239
17359
|
controlCanvas,
|
|
17240
17360
|
controlStatus,
|
|
17241
|
-
controlPlaceholder);
|
|
17361
|
+
restoredControlSurface ? null : controlPlaceholder);
|
|
17362
|
+
if (session && restoredControlSurface) {
|
|
17363
|
+
session.lastControlFrameSeq = Number(preservedControlSurface?.seq || session.lastControlFrameSeq || 0) || 0;
|
|
17364
|
+
session.lastControlFrameAt = Date.now();
|
|
17365
|
+
controlStatus.textContent = `Control ${REMOTE_FLEET_CONTROL_LIVE_FPS}fps`;
|
|
17366
|
+
window.RuntimeTrace?.emit?.('remote.control.surfaceRestored', {
|
|
17367
|
+
nodeId,
|
|
17368
|
+
deviceId,
|
|
17369
|
+
seq: session.lastControlFrameSeq
|
|
17370
|
+
});
|
|
17371
|
+
}
|
|
17242
17372
|
if (session && isRemoteFleetFrameSource(previewSource)) {
|
|
17243
17373
|
paintRemoteFleetControlFrame(session, {
|
|
17244
17374
|
deviceId,
|
|
@@ -17526,6 +17656,7 @@
|
|
|
17526
17656
|
function renderRemoteFleetMonitor(bodyView, nodeModel) {
|
|
17527
17657
|
if (!bodyView) return;
|
|
17528
17658
|
clearRemoteFleetTimers(bodyView, { keepBinaryFrameSocket: true });
|
|
17659
|
+
const preservedFrameSurfaces = collectRemoteFleetPreviewFrameSurfaces(bodyView);
|
|
17529
17660
|
|
|
17530
17661
|
const nodeId = String(nodeModel?.id ?? nodeModel?.Id ?? '');
|
|
17531
17662
|
const searchState = bodyView.dataset.remoteFleetSearch || '';
|
|
@@ -18080,6 +18211,7 @@
|
|
|
18080
18211
|
preview.appendChild(placeholder);
|
|
18081
18212
|
}
|
|
18082
18213
|
|
|
18214
|
+
restoreRemoteFleetPreviewFrameSurface(preview, preservedFrameSurfaces, getRemoteFleetDeviceId(device));
|
|
18083
18215
|
return preview;
|
|
18084
18216
|
};
|
|
18085
18217
|
|
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-
|
|
11
|
-
<link rel="stylesheet" href="_content/MindExecution.Shared/css/mind-map-overrides.css?v=20260617-
|
|
10
|
+
<link rel="stylesheet" href="_content/MindExecution.Shared/css/app.css?v=20260617-remote-frame-no-flash-v592" />
|
|
11
|
+
<link rel="stylesheet" href="_content/MindExecution.Shared/css/mind-map-overrides.css?v=20260617-remote-frame-no-flash-v592" />
|
|
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-
|
|
582
|
+
const scriptVersion = '20260617-remote-frame-no-flash-v592';
|
|
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": "ikaqQxI3",
|
|
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-yUuxzH9Fpd62pPLMU5n0HuYjsJhKvC82LO5X5Uu/1gg=",
|
|
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-8VAYYW89mBjF45WS2vA1+Hssmo6S30PB8AW03niSE2Q=",
|
|
838
838
|
"url": "index.html"
|
|
839
839
|
},
|
|
840
840
|
{
|