@mindexec/cli 0.2.51 → 0.2.53
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-hub.js +35 -0
- package/scripts/remote-http-smoke.mjs +34 -0
- package/server.js +22 -3
- package/wwwroot/_content/MindExecution.Shared/js/mind-map-css3d-manager.js +302 -4
- package/wwwroot/_framework/MindExecution.Core.fu1rl67yt3.dll +0 -0
- package/wwwroot/_framework/{MindExecution.Kernel.necgouk2lu.dll → MindExecution.Kernel.cqcbagjpqb.dll} +0 -0
- package/wwwroot/_framework/{MindExecution.Plugins.Admin.i1bsxgnkwb.dll → MindExecution.Plugins.Admin.tsn0j478un.dll} +0 -0
- package/wwwroot/_framework/{MindExecution.Plugins.Business.opnf5esnox.dll → MindExecution.Plugins.Business.xg74dmn0vz.dll} +0 -0
- package/wwwroot/_framework/{MindExecution.Plugins.Concept.3c5vvjh1ax.dll → MindExecution.Plugins.Concept.j0zntvuecv.dll} +0 -0
- package/wwwroot/_framework/{MindExecution.Plugins.Directory.mcs5ilkrby.dll → MindExecution.Plugins.Directory.9i4bd043ia.dll} +0 -0
- package/wwwroot/_framework/{MindExecution.Plugins.PlanMaster.ofkqkx5csm.dll → MindExecution.Plugins.PlanMaster.vml3qie2ji.dll} +0 -0
- package/wwwroot/_framework/{MindExecution.Plugins.YouTube.si9ylbnkqo.dll → MindExecution.Plugins.YouTube.0gfbwq1jfg.dll} +0 -0
- package/wwwroot/_framework/{MindExecution.Shared.w5v05uuccd.dll → MindExecution.Shared.f3bclzo6k4.dll} +0 -0
- package/wwwroot/_framework/MindExecution.Web.4jhsxoiqgz.dll +0 -0
- package/wwwroot/_framework/blazor.boot.json +21 -21
- package/wwwroot/index.html +3 -3
- package/wwwroot/service-worker-assets.js +24 -24
- package/wwwroot/service-worker.js +1 -1
- package/wwwroot/_framework/MindExecution.Core.fv9epd367q.dll +0 -0
- package/wwwroot/_framework/MindExecution.Web.y71txqhdir.dll +0 -0
package/package.json
CHANGED
package/remote-hub.js
CHANGED
|
@@ -304,6 +304,7 @@ export function createRemoteHub(options = {}) {
|
|
|
304
304
|
DEFAULT_AGENT_TASK_TIMEOUT_MS);
|
|
305
305
|
const managerPackage = safeString(options.managerPackage ?? env.MINDEXEC_MANAGER_PACKAGE ?? '@mindexec/cli', 128);
|
|
306
306
|
const managerVersion = safeString(options.managerVersion ?? env.MINDEXEC_MANAGER_VERSION ?? '', 64);
|
|
307
|
+
const hostInstanceId = safeString(options.hostInstanceId ?? env.MINDEXEC_BRIDGE_INSTANCE_ID ?? crypto.randomUUID(), 128) || crypto.randomUUID();
|
|
307
308
|
const publicEndpoint = safeString(env.MINDEXEC_REMOTE_PUBLIC_ENDPOINT || env.REMOTE_HUB_PUBLIC_ENDPOINT, 256);
|
|
308
309
|
const publicHost = safeString(env.MINDEXEC_REMOTE_PUBLIC_HOST || env.REMOTE_HUB_PUBLIC_HOST, 128);
|
|
309
310
|
const pairToken = safeString(
|
|
@@ -367,6 +368,7 @@ export function createRemoteHub(options = {}) {
|
|
|
367
368
|
active: false,
|
|
368
369
|
nodeId: '',
|
|
369
370
|
leaseId: '',
|
|
371
|
+
hostInstanceId: '',
|
|
370
372
|
endpoint: '',
|
|
371
373
|
activatedAt: '',
|
|
372
374
|
updatedAt: '',
|
|
@@ -378,6 +380,7 @@ export function createRemoteHub(options = {}) {
|
|
|
378
380
|
active: true,
|
|
379
381
|
nodeId: target.nodeId,
|
|
380
382
|
leaseId: target.leaseId,
|
|
383
|
+
hostInstanceId: target.hostInstanceId || hostInstanceId,
|
|
381
384
|
endpoint: target.endpoint,
|
|
382
385
|
activatedAt: target.activatedAt,
|
|
383
386
|
updatedAt: target.updatedAt,
|
|
@@ -437,6 +440,7 @@ export function createRemoteHub(options = {}) {
|
|
|
437
440
|
hostTarget = {
|
|
438
441
|
nodeId,
|
|
439
442
|
leaseId: activeSameNode && previous?.leaseId ? previous.leaseId : crypto.randomUUID(),
|
|
443
|
+
hostInstanceId,
|
|
440
444
|
endpoint: getAgentEndpoint(),
|
|
441
445
|
activatedAt: activeSameNode && previous?.activatedAt ? previous.activatedAt : now.toISOString(),
|
|
442
446
|
updatedAt: now.toISOString(),
|
|
@@ -469,6 +473,7 @@ export function createRemoteHub(options = {}) {
|
|
|
469
473
|
taskTimeoutMs,
|
|
470
474
|
managerPackage,
|
|
471
475
|
managerVersion,
|
|
476
|
+
hostInstanceId,
|
|
472
477
|
agentPackage: '@mindexec/remote',
|
|
473
478
|
agentEndpoint: getAgentEndpoint(),
|
|
474
479
|
pairToken: includeSecrets ? pairToken : undefined,
|
|
@@ -480,6 +485,7 @@ export function createRemoteHub(options = {}) {
|
|
|
480
485
|
hostTargetActive: activeHostTarget.active,
|
|
481
486
|
hostTargetNodeId: activeHostTarget.nodeId,
|
|
482
487
|
hostTargetLeaseId: activeHostTarget.leaseId,
|
|
488
|
+
hostTargetHostInstanceId: activeHostTarget.hostInstanceId,
|
|
483
489
|
hostTargetEndpoint: activeHostTarget.endpoint,
|
|
484
490
|
hostTargetActivatedAt: activeHostTarget.activatedAt,
|
|
485
491
|
hostTargetUpdatedAt: activeHostTarget.updatedAt,
|
|
@@ -506,6 +512,34 @@ export function createRemoteHub(options = {}) {
|
|
|
506
512
|
});
|
|
507
513
|
}
|
|
508
514
|
|
|
515
|
+
function listDeviceFrames(options = {}) {
|
|
516
|
+
const ids = Array.isArray(options.deviceIds)
|
|
517
|
+
? options.deviceIds.map(value => safeString(value, 160)).filter(Boolean)
|
|
518
|
+
: [];
|
|
519
|
+
const idSet = ids.length > 0 ? new Set(ids) : null;
|
|
520
|
+
const includeThumbnail = options.includeThumbnail !== false;
|
|
521
|
+
const includeLive = options.includeLive !== false;
|
|
522
|
+
|
|
523
|
+
return [...devices.values()]
|
|
524
|
+
.filter(device => !idSet || idSet.has(device.deviceId))
|
|
525
|
+
.map(device => ({
|
|
526
|
+
deviceId: device.deviceId,
|
|
527
|
+
connected: device.connected === true,
|
|
528
|
+
thumbnailEnabled: readCapabilityFlag(device.capabilities, 'thumbnail'),
|
|
529
|
+
liveStreamActive: device.activeLiveStream?.active === true,
|
|
530
|
+
liveStreamId: device.activeLiveStream?.streamId || '',
|
|
531
|
+
liveStreamFps: Number(device.activeLiveStream?.fps || 0),
|
|
532
|
+
liveStreamLastFrameAt: device.activeLiveStream?.lastFrameAt || '',
|
|
533
|
+
thumbnail: includeThumbnail
|
|
534
|
+
? serializeRemoteFrame(device.latestThumbnail, device.deviceId, 'thumbnail', { includeDataUrl: false })
|
|
535
|
+
: null,
|
|
536
|
+
live: includeLive
|
|
537
|
+
? serializeRemoteFrame(device.latestLiveFrame, device.deviceId, 'live', { includeDataUrl: false })
|
|
538
|
+
: null
|
|
539
|
+
}))
|
|
540
|
+
.sort((a, b) => String(a.deviceId).localeCompare(String(b.deviceId)));
|
|
541
|
+
}
|
|
542
|
+
|
|
509
543
|
function listTaskBatches() {
|
|
510
544
|
return [...taskBatches.values()]
|
|
511
545
|
.map(serializeTaskBatch)
|
|
@@ -2094,6 +2128,7 @@ export function createRemoteHub(options = {}) {
|
|
|
2094
2128
|
listDevices,
|
|
2095
2129
|
listTaskBatches,
|
|
2096
2130
|
getLatestTaskBatch,
|
|
2131
|
+
listDeviceFrames,
|
|
2097
2132
|
disconnectDevice,
|
|
2098
2133
|
sendCommand,
|
|
2099
2134
|
requestAgentTask,
|
|
@@ -377,6 +377,23 @@ async function runSyntheticEnabledSmoke() {
|
|
|
377
377
|
assert.ok(urlOnlyThumbnailDevice?.latestThumbnail?.framePath);
|
|
378
378
|
assert.ok(!('dataUrl' in urlOnlyThumbnailDevice.latestThumbnail));
|
|
379
379
|
|
|
380
|
+
const thumbnailFramesOnly = await fetchJson(`${baseUrl}/api/remote/frames`, {
|
|
381
|
+
method: 'POST',
|
|
382
|
+
token: BRIDGE_TOKEN,
|
|
383
|
+
body: JSON.stringify({
|
|
384
|
+
deviceIds: [thumbnailTarget.deviceId],
|
|
385
|
+
includeThumbnail: true,
|
|
386
|
+
includeLive: true
|
|
387
|
+
})
|
|
388
|
+
});
|
|
389
|
+
assert.equal(thumbnailFramesOnly.ok, true, JSON.stringify(thumbnailFramesOnly.payload));
|
|
390
|
+
assert.equal(thumbnailFramesOnly.payload?.ok, true);
|
|
391
|
+
assert.equal(thumbnailFramesOnly.payload?.frames?.length, 1);
|
|
392
|
+
assert.equal(thumbnailFramesOnly.payload.frames[0].deviceId, thumbnailTarget.deviceId);
|
|
393
|
+
assert.equal(thumbnailFramesOnly.payload.frames[0].thumbnailEnabled, true);
|
|
394
|
+
assert.ok(String(thumbnailFramesOnly.payload.frames[0].thumbnail?.framePath || '').includes(`/api/remote/devices/${encodeURIComponent(thumbnailTarget.deviceId)}/thumbnail?`));
|
|
395
|
+
assert.ok(!('dataUrl' in thumbnailFramesOnly.payload.frames[0].thumbnail));
|
|
396
|
+
|
|
380
397
|
const liveTarget = devicesResult.payload.devices.find(device =>
|
|
381
398
|
device.connected && device.capabilities?.liveStream);
|
|
382
399
|
assert.ok(liveTarget);
|
|
@@ -419,6 +436,23 @@ async function runSyntheticEnabledSmoke() {
|
|
|
419
436
|
const badLiveSeq = await fetchBinary(`${baseUrl}${liveFrame.payload.frame.framePath.replace(/seq=\d+/, 'seq=999999')}`);
|
|
420
437
|
assert.equal(badLiveSeq.status, 401);
|
|
421
438
|
|
|
439
|
+
const liveFramesOnly = await fetchJson(`${baseUrl}/api/remote/frames`, {
|
|
440
|
+
method: 'POST',
|
|
441
|
+
token: BRIDGE_TOKEN,
|
|
442
|
+
body: JSON.stringify({
|
|
443
|
+
deviceIds: [liveTarget.deviceId],
|
|
444
|
+
includeThumbnail: true,
|
|
445
|
+
includeLive: true
|
|
446
|
+
})
|
|
447
|
+
});
|
|
448
|
+
assert.equal(liveFramesOnly.ok, true, JSON.stringify(liveFramesOnly.payload));
|
|
449
|
+
assert.equal(liveFramesOnly.payload?.ok, true);
|
|
450
|
+
assert.equal(liveFramesOnly.payload?.frames?.length, 1);
|
|
451
|
+
assert.equal(liveFramesOnly.payload.frames[0].deviceId, liveTarget.deviceId);
|
|
452
|
+
assert.equal(liveFramesOnly.payload.frames[0].liveStreamActive, true);
|
|
453
|
+
assert.ok(String(liveFramesOnly.payload.frames[0].live?.framePath || '').includes(`/api/remote/devices/${encodeURIComponent(liveTarget.deviceId)}/live/frame?`));
|
|
454
|
+
assert.ok(!('dataUrl' in liveFramesOnly.payload.frames[0].live));
|
|
455
|
+
|
|
422
456
|
const liveStop = await fetchJson(`${baseUrl}/api/remote/devices/${encodeURIComponent(liveTarget.deviceId)}/live/stop`, {
|
|
423
457
|
method: 'POST',
|
|
424
458
|
token: BRIDGE_TOKEN,
|
package/server.js
CHANGED
|
@@ -33,8 +33,9 @@ const app = express();
|
|
|
33
33
|
const PORT = normalizePort(process.env.BRIDGE_PORT);
|
|
34
34
|
const BRIDGE_ROOT = path.dirname(fileURLToPath(import.meta.url));
|
|
35
35
|
const PACKAGE_INFO = JSON.parse(readFileSync(path.join(BRIDGE_ROOT, 'package.json'), 'utf8'));
|
|
36
|
-
const BRIDGE_PACKAGE_NAME = String(PACKAGE_INFO.name || '@mindexec/cli');
|
|
37
|
-
const BRIDGE_VERSION = String(PACKAGE_INFO.version || '0.1.0');
|
|
36
|
+
const BRIDGE_PACKAGE_NAME = String(PACKAGE_INFO.name || '@mindexec/cli');
|
|
37
|
+
const BRIDGE_VERSION = String(PACKAGE_INFO.version || '0.1.0');
|
|
38
|
+
const BRIDGE_INSTANCE_ID = String(process.env.MINDEXEC_BRIDGE_INSTANCE_ID || crypto.randomUUID()).trim() || crypto.randomUUID();
|
|
38
39
|
const TREE_SITTER_GRAMMAR_DIR = path.join(BRIDGE_ROOT, 'tree-sitter-grammars');
|
|
39
40
|
const VERBOSE_CODEX_TRACE = /^(1|true|yes|on)$/i.test(String(process.env.BRIDGE_VERBOSE_CODEX || ''));
|
|
40
41
|
const COLOR_LOGS_ENABLED = Boolean(process.stdout.isTTY) && !process.env.NO_COLOR;
|
|
@@ -2515,7 +2516,8 @@ const remoteHub = createRemoteHub({
|
|
|
2515
2516
|
logError,
|
|
2516
2517
|
emitEvent: emitBridgeEvent,
|
|
2517
2518
|
managerPackage: BRIDGE_PACKAGE_NAME,
|
|
2518
|
-
managerVersion: BRIDGE_VERSION
|
|
2519
|
+
managerVersion: BRIDGE_VERSION,
|
|
2520
|
+
hostInstanceId: BRIDGE_INSTANCE_ID
|
|
2519
2521
|
});
|
|
2520
2522
|
|
|
2521
2523
|
const REMOTE_AGENT_STDIO_TAIL_CHARS = 12000;
|
|
@@ -7282,6 +7284,23 @@ app.get('/api/remote/devices', (req, res) => {
|
|
|
7282
7284
|
});
|
|
7283
7285
|
});
|
|
7284
7286
|
|
|
7287
|
+
app.post('/api/remote/frames', (req, res) => {
|
|
7288
|
+
res.setHeader('Cache-Control', 'no-store');
|
|
7289
|
+
const deviceIds = Array.isArray(req.body?.deviceIds)
|
|
7290
|
+
? req.body.deviceIds.map(value => String(value || '').trim()).filter(Boolean).slice(0, 120)
|
|
7291
|
+
: [];
|
|
7292
|
+
const frames = remoteHub.listDeviceFrames({
|
|
7293
|
+
deviceIds,
|
|
7294
|
+
includeThumbnail: req.body?.includeThumbnail !== false,
|
|
7295
|
+
includeLive: req.body?.includeLive !== false
|
|
7296
|
+
});
|
|
7297
|
+
res.json({
|
|
7298
|
+
ok: true,
|
|
7299
|
+
total: frames.length,
|
|
7300
|
+
frames
|
|
7301
|
+
});
|
|
7302
|
+
});
|
|
7303
|
+
|
|
7285
7304
|
app.post('/api/remote/host-target', (req, res) => {
|
|
7286
7305
|
res.setHeader('Cache-Control', 'no-store');
|
|
7287
7306
|
res.json(remoteHub.setHostTarget({
|
|
@@ -12765,8 +12765,10 @@
|
|
|
12765
12765
|
return select;
|
|
12766
12766
|
}
|
|
12767
12767
|
|
|
12768
|
-
const REMOTE_FLEET_MONITOR_REFRESH_MS =
|
|
12769
|
-
const REMOTE_FLEET_LIVE_REFRESH_MS =
|
|
12768
|
+
const REMOTE_FLEET_MONITOR_REFRESH_MS = 10000;
|
|
12769
|
+
const REMOTE_FLEET_LIVE_REFRESH_MS = 5000;
|
|
12770
|
+
const REMOTE_FLEET_LIVE_FRAME_REFRESH_MS = 50;
|
|
12771
|
+
const REMOTE_FLEET_THUMBNAIL_FRAME_REFRESH_MS = 2000;
|
|
12770
12772
|
const REMOTE_FLEET_TASK_FOLLOW_INITIAL_MS = 250;
|
|
12771
12773
|
const REMOTE_FLEET_TASK_FOLLOW_REFRESH_MS = 2000;
|
|
12772
12774
|
const REMOTE_FLEET_TASK_FOLLOW_MAX_TICKS = 60;
|
|
@@ -12917,6 +12919,12 @@
|
|
|
12917
12919
|
clearInterval(bodyView._remoteFleetMonitorRefreshTimer);
|
|
12918
12920
|
bodyView._remoteFleetMonitorRefreshTimer = null;
|
|
12919
12921
|
}
|
|
12922
|
+
if (bodyView._remoteFleetFrameLoopRaf) {
|
|
12923
|
+
cancelRemoteFleetFrameLoopFrame(bodyView._remoteFleetFrameLoopRaf);
|
|
12924
|
+
bodyView._remoteFleetFrameLoopRaf = null;
|
|
12925
|
+
}
|
|
12926
|
+
bodyView._remoteFleetFrameLoopActive = false;
|
|
12927
|
+
bodyView._remoteFleetFrameRefreshInFlight = false;
|
|
12920
12928
|
if (bodyView._remoteFleetTaskFollowTimer) {
|
|
12921
12929
|
clearTimeout(bodyView._remoteFleetTaskFollowTimer);
|
|
12922
12930
|
bodyView._remoteFleetTaskFollowTimer = null;
|
|
@@ -12927,6 +12935,38 @@
|
|
|
12927
12935
|
}
|
|
12928
12936
|
}
|
|
12929
12937
|
|
|
12938
|
+
function requestRemoteFleetFrameLoopFrame(callback) {
|
|
12939
|
+
if (typeof requestAnimationFrame === 'function') {
|
|
12940
|
+
return {
|
|
12941
|
+
kind: 'raf',
|
|
12942
|
+
id: requestAnimationFrame(callback)
|
|
12943
|
+
};
|
|
12944
|
+
}
|
|
12945
|
+
|
|
12946
|
+
return {
|
|
12947
|
+
kind: 'timeout',
|
|
12948
|
+
id: setTimeout(
|
|
12949
|
+
() => callback(typeof performance !== 'undefined' ? performance.now() : Date.now()),
|
|
12950
|
+
33
|
|
12951
|
+
)
|
|
12952
|
+
};
|
|
12953
|
+
}
|
|
12954
|
+
|
|
12955
|
+
function cancelRemoteFleetFrameLoopFrame(handle) {
|
|
12956
|
+
if (!handle) {
|
|
12957
|
+
return;
|
|
12958
|
+
}
|
|
12959
|
+
|
|
12960
|
+
if (handle.kind === 'timeout') {
|
|
12961
|
+
clearTimeout(handle.id);
|
|
12962
|
+
return;
|
|
12963
|
+
}
|
|
12964
|
+
|
|
12965
|
+
if (typeof cancelAnimationFrame === 'function') {
|
|
12966
|
+
cancelAnimationFrame(handle.id);
|
|
12967
|
+
}
|
|
12968
|
+
}
|
|
12969
|
+
|
|
12930
12970
|
function getRemoteFleetDeviceField(device, camelKey, pascalKey, fallback = '') {
|
|
12931
12971
|
const value = device?.[camelKey] ?? device?.[pascalKey] ?? fallback;
|
|
12932
12972
|
return value === undefined || value === null ? fallback : value;
|
|
@@ -12983,6 +13023,200 @@
|
|
|
12983
13023
|
|| getRemoteFleetDeviceField(device, 'thumbnailDataUrl', 'ThumbnailDataUrl', ''));
|
|
12984
13024
|
}
|
|
12985
13025
|
|
|
13026
|
+
function getRemoteFleetFrameSeq(device, frameKind) {
|
|
13027
|
+
const raw = frameKind === 'live'
|
|
13028
|
+
? getRemoteFleetDeviceField(device, 'liveFrameSeq', 'LiveFrameSeq', 0)
|
|
13029
|
+
: getRemoteFleetDeviceField(device, 'thumbnailFrameSeq', 'ThumbnailFrameSeq', 0);
|
|
13030
|
+
const seq = Number(raw);
|
|
13031
|
+
return Number.isFinite(seq) ? Math.floor(seq) : 0;
|
|
13032
|
+
}
|
|
13033
|
+
|
|
13034
|
+
function normalizeRemoteFleetFramePayload(payload, fallbackKind = 'thumbnail') {
|
|
13035
|
+
if (!payload || typeof payload !== 'object') {
|
|
13036
|
+
return null;
|
|
13037
|
+
}
|
|
13038
|
+
|
|
13039
|
+
const frame = payload.frame || payload.Frame || payload;
|
|
13040
|
+
if (!frame || typeof frame !== 'object') {
|
|
13041
|
+
return null;
|
|
13042
|
+
}
|
|
13043
|
+
|
|
13044
|
+
const source = String(
|
|
13045
|
+
readRemoteFleetObjectField(frame, 'frameUrl', 'FrameUrl', '')
|
|
13046
|
+
|| readRemoteFleetObjectField(frame, 'framePath', 'FramePath', '')
|
|
13047
|
+
|| readRemoteFleetObjectField(frame, 'dataUrl', 'DataUrl', '')).trim();
|
|
13048
|
+
if (!isRemoteFleetFrameSource(source)) {
|
|
13049
|
+
return null;
|
|
13050
|
+
}
|
|
13051
|
+
|
|
13052
|
+
const seq = Number(readRemoteFleetObjectField(frame, 'frameSeq', 'FrameSeq', 0));
|
|
13053
|
+
return {
|
|
13054
|
+
deviceId: String(readRemoteFleetObjectField(frame, 'deviceId', 'DeviceId', '')).trim(),
|
|
13055
|
+
kind: String(readRemoteFleetObjectField(frame, 'kind', 'Kind', fallbackKind) || fallbackKind).trim().toLowerCase(),
|
|
13056
|
+
frameSeq: Number.isFinite(seq) ? Math.floor(seq) : 0,
|
|
13057
|
+
frameUrl: source,
|
|
13058
|
+
receivedAt: String(readRemoteFleetObjectField(frame, 'receivedAt', 'ReceivedAt', '') || '').trim(),
|
|
13059
|
+
capturedAt: String(readRemoteFleetObjectField(frame, 'capturedAt', 'CapturedAt', '') || '').trim(),
|
|
13060
|
+
streamId: String(readRemoteFleetObjectField(frame, 'streamId', 'StreamId', '') || '').trim()
|
|
13061
|
+
};
|
|
13062
|
+
}
|
|
13063
|
+
|
|
13064
|
+
function normalizeRemoteFleetDeviceFramePatches(result) {
|
|
13065
|
+
const rows = result?.frames || result?.Frames || [];
|
|
13066
|
+
if (!Array.isArray(rows)) {
|
|
13067
|
+
return [];
|
|
13068
|
+
}
|
|
13069
|
+
|
|
13070
|
+
const patches = [];
|
|
13071
|
+
rows.forEach(row => {
|
|
13072
|
+
const deviceId = String(readRemoteFleetObjectField(row, 'deviceId', 'DeviceId', '') || '').trim();
|
|
13073
|
+
const live = normalizeRemoteFleetFramePayload(row?.live || row?.Live, 'live');
|
|
13074
|
+
const thumbnail = normalizeRemoteFleetFramePayload(row?.thumbnail || row?.Thumbnail, 'thumbnail');
|
|
13075
|
+
[thumbnail, live].forEach(frame => {
|
|
13076
|
+
if (!frame) return;
|
|
13077
|
+
frame.deviceId = frame.deviceId || deviceId;
|
|
13078
|
+
patches.push(frame);
|
|
13079
|
+
});
|
|
13080
|
+
});
|
|
13081
|
+
return patches;
|
|
13082
|
+
}
|
|
13083
|
+
|
|
13084
|
+
function ensureRemoteFleetFrameImage(preview, frame) {
|
|
13085
|
+
let image = preview?.querySelector?.('img[data-remote-fleet-frame-image="true"]');
|
|
13086
|
+
if (image) {
|
|
13087
|
+
return image;
|
|
13088
|
+
}
|
|
13089
|
+
|
|
13090
|
+
image = document.createElement('img');
|
|
13091
|
+
image.dataset.remoteFleetFrameImage = 'true';
|
|
13092
|
+
image.alt = frame.kind === 'live' ? 'Live screen' : 'Remote screen';
|
|
13093
|
+
image.loading = frame.kind === 'thumbnail' ? 'lazy' : 'eager';
|
|
13094
|
+
image.decoding = 'async';
|
|
13095
|
+
image.style.cssText = 'width:100%;height:100%;object-fit:cover;display:block;';
|
|
13096
|
+
const placeholder = preview?.querySelector?.('[data-remote-fleet-screen-placeholder="true"]');
|
|
13097
|
+
if (placeholder) {
|
|
13098
|
+
placeholder.remove();
|
|
13099
|
+
}
|
|
13100
|
+
preview?.insertBefore?.(image, preview.firstChild || null);
|
|
13101
|
+
return image;
|
|
13102
|
+
}
|
|
13103
|
+
|
|
13104
|
+
function applyRemoteFleetFramePatchToPreview(preview, frame) {
|
|
13105
|
+
if (!preview || !frame || !isRemoteFleetFrameSource(frame.frameUrl)) {
|
|
13106
|
+
return false;
|
|
13107
|
+
}
|
|
13108
|
+
|
|
13109
|
+
const currentSeq = Number(preview.dataset.remoteFleetFrameSeq || '0');
|
|
13110
|
+
const nextSeq = Number(frame.frameSeq || 0);
|
|
13111
|
+
const currentKind = String(preview.dataset.remoteFleetFrameKind || '').toLowerCase();
|
|
13112
|
+
const isNewer = frame.kind === 'live' && currentKind !== 'live'
|
|
13113
|
+
|| !Number.isFinite(currentSeq)
|
|
13114
|
+
|| nextSeq <= 0
|
|
13115
|
+
|| nextSeq > currentSeq
|
|
13116
|
+
|| String(preview.dataset.remoteFleetFrameUrl || '') !== frame.frameUrl;
|
|
13117
|
+
if (!isNewer) {
|
|
13118
|
+
return false;
|
|
13119
|
+
}
|
|
13120
|
+
|
|
13121
|
+
const image = ensureRemoteFleetFrameImage(preview, frame);
|
|
13122
|
+
if (!image) {
|
|
13123
|
+
return false;
|
|
13124
|
+
}
|
|
13125
|
+
|
|
13126
|
+
image.dataset.remoteFleetFrameKind = frame.kind;
|
|
13127
|
+
image.dataset.remoteFleetFrameSeq = String(nextSeq || 0);
|
|
13128
|
+
image.dataset.remoteFleetFrameUrl = frame.frameUrl;
|
|
13129
|
+
image.loading = frame.kind === 'thumbnail' ? 'lazy' : 'eager';
|
|
13130
|
+
if (image.src !== frame.frameUrl) {
|
|
13131
|
+
image.src = frame.frameUrl;
|
|
13132
|
+
}
|
|
13133
|
+
|
|
13134
|
+
preview.dataset.remoteFleetFrameKind = frame.kind;
|
|
13135
|
+
preview.dataset.remoteFleetFrameSeq = String(nextSeq || 0);
|
|
13136
|
+
preview.dataset.remoteFleetFrameUrl = frame.frameUrl;
|
|
13137
|
+
preview.dataset.remoteFleetFrameAt = frame.receivedAt || frame.capturedAt || '';
|
|
13138
|
+
|
|
13139
|
+
const badge = preview.querySelector('[data-remote-fleet-frame-badge="true"]');
|
|
13140
|
+
if (badge) {
|
|
13141
|
+
const at = frame.receivedAt || frame.capturedAt || '';
|
|
13142
|
+
badge.textContent = frame.kind === 'live'
|
|
13143
|
+
? `LIVE ${at ? formatRemoteFleetAge(at) : ''}`.trim()
|
|
13144
|
+
: (at ? formatRemoteFleetAge(at) : 'Screen');
|
|
13145
|
+
badge.style.display = 'inline-flex';
|
|
13146
|
+
badge.style.background = frame.kind === 'live'
|
|
13147
|
+
? 'rgba(220, 38, 38, 0.84)'
|
|
13148
|
+
: 'rgba(15, 23, 42, 0.72)';
|
|
13149
|
+
}
|
|
13150
|
+
|
|
13151
|
+
return true;
|
|
13152
|
+
}
|
|
13153
|
+
|
|
13154
|
+
function applyRemoteFleetFramePatches(bodyView, patches) {
|
|
13155
|
+
if (!bodyView || !Array.isArray(patches) || patches.length === 0) {
|
|
13156
|
+
return 0;
|
|
13157
|
+
}
|
|
13158
|
+
|
|
13159
|
+
let applied = 0;
|
|
13160
|
+
patches.forEach(frame => {
|
|
13161
|
+
const deviceId = String(frame?.deviceId || '').trim();
|
|
13162
|
+
if (!deviceId) return;
|
|
13163
|
+
|
|
13164
|
+
bodyView.querySelectorAll('[data-remote-fleet-device-preview][data-device-id]').forEach(preview => {
|
|
13165
|
+
if (String(preview.dataset.deviceId || '').trim() !== deviceId) return;
|
|
13166
|
+
const currentKind = String(preview.dataset.remoteFleetFrameKind || '').toLowerCase();
|
|
13167
|
+
if (currentKind === 'live' && frame.kind !== 'live') return;
|
|
13168
|
+
if (applyRemoteFleetFramePatchToPreview(preview, frame)) {
|
|
13169
|
+
applied += 1;
|
|
13170
|
+
}
|
|
13171
|
+
});
|
|
13172
|
+
|
|
13173
|
+
bodyView.querySelectorAll(`article[data-device-id]`).forEach(card => {
|
|
13174
|
+
if (String(card.dataset.deviceId || '').trim() === deviceId && frame.kind) {
|
|
13175
|
+
card.dataset.remoteFleetHasFrame = 'true';
|
|
13176
|
+
}
|
|
13177
|
+
});
|
|
13178
|
+
});
|
|
13179
|
+
|
|
13180
|
+
if (applied > 0) {
|
|
13181
|
+
window.RuntimeTrace?.emit?.('remote.frame.uiPatched', {
|
|
13182
|
+
count: applied
|
|
13183
|
+
});
|
|
13184
|
+
}
|
|
13185
|
+
|
|
13186
|
+
return applied;
|
|
13187
|
+
}
|
|
13188
|
+
|
|
13189
|
+
function startRemoteFleetFrameLoop(bodyView, intervalMs, refreshCallback) {
|
|
13190
|
+
if (!bodyView || typeof refreshCallback !== 'function') {
|
|
13191
|
+
return;
|
|
13192
|
+
}
|
|
13193
|
+
|
|
13194
|
+
bodyView._remoteFleetFrameLoopActive = true;
|
|
13195
|
+
let lastTick = 0;
|
|
13196
|
+
const loop = timestamp => {
|
|
13197
|
+
if (!bodyView._remoteFleetFrameLoopActive || !document.body.contains(bodyView)) {
|
|
13198
|
+
clearRemoteFleetTimers(bodyView);
|
|
13199
|
+
return;
|
|
13200
|
+
}
|
|
13201
|
+
|
|
13202
|
+
if (timestamp - lastTick >= intervalMs && bodyView._remoteFleetFrameRefreshInFlight !== true) {
|
|
13203
|
+
lastTick = timestamp;
|
|
13204
|
+
bodyView._remoteFleetFrameRefreshInFlight = true;
|
|
13205
|
+
Promise.resolve(refreshCallback())
|
|
13206
|
+
.catch(() => {
|
|
13207
|
+
clearRemoteFleetTimers(bodyView);
|
|
13208
|
+
})
|
|
13209
|
+
.finally(() => {
|
|
13210
|
+
bodyView._remoteFleetFrameRefreshInFlight = false;
|
|
13211
|
+
});
|
|
13212
|
+
}
|
|
13213
|
+
|
|
13214
|
+
bodyView._remoteFleetFrameLoopRaf = requestRemoteFleetFrameLoopFrame(loop);
|
|
13215
|
+
};
|
|
13216
|
+
|
|
13217
|
+
bodyView._remoteFleetFrameLoopRaf = requestRemoteFleetFrameLoopFrame(loop);
|
|
13218
|
+
}
|
|
13219
|
+
|
|
12986
13220
|
function isRemoteFleetLiveActive(device) {
|
|
12987
13221
|
return getRemoteFleetDeviceField(device, 'liveStreamActive', 'LiveStreamActive', false) === true;
|
|
12988
13222
|
}
|
|
@@ -13215,6 +13449,15 @@
|
|
|
13215
13449
|
bodyView._remoteFleetRefreshInFlight = false;
|
|
13216
13450
|
}
|
|
13217
13451
|
};
|
|
13452
|
+
const refreshRemoteDeviceFrame = async (kind = 'live') => {
|
|
13453
|
+
const result = await invokeDotNetAsync('GetRemoteFleetFrameFromJs', nodeId, deviceId, kind);
|
|
13454
|
+
const frame = normalizeRemoteFleetFramePayload(result?.frame || result?.Frame, kind);
|
|
13455
|
+
if (frame) {
|
|
13456
|
+
frame.deviceId = frame.deviceId || deviceId;
|
|
13457
|
+
applyRemoteFleetFramePatches(bodyView, [frame]);
|
|
13458
|
+
}
|
|
13459
|
+
return result;
|
|
13460
|
+
};
|
|
13218
13461
|
|
|
13219
13462
|
if (!device || !deviceId) {
|
|
13220
13463
|
const empty = document.createElement('div');
|
|
@@ -13314,6 +13557,12 @@
|
|
|
13314
13557
|
bodyView.appendChild(header);
|
|
13315
13558
|
|
|
13316
13559
|
const preview = document.createElement('div');
|
|
13560
|
+
preview.dataset.remoteFleetDevicePreview = 'pinned';
|
|
13561
|
+
preview.dataset.deviceId = deviceId;
|
|
13562
|
+
preview.dataset.remoteFleetFrameKind = hasLiveFrame ? 'live' : (hasThumbnail ? 'thumbnail' : '');
|
|
13563
|
+
preview.dataset.remoteFleetFrameSeq = String(hasLiveFrame
|
|
13564
|
+
? getRemoteFleetDeviceField(device, 'liveFrameSeq', 'LiveFrameSeq', 0)
|
|
13565
|
+
: getRemoteFleetDeviceField(device, 'thumbnailFrameSeq', 'ThumbnailFrameSeq', 0));
|
|
13317
13566
|
preview.style.cssText = `
|
|
13318
13567
|
position: relative;
|
|
13319
13568
|
flex: 0 0 auto;
|
|
@@ -13326,6 +13575,9 @@
|
|
|
13326
13575
|
`;
|
|
13327
13576
|
if (hasLiveFrame || hasThumbnail) {
|
|
13328
13577
|
const image = document.createElement('img');
|
|
13578
|
+
image.dataset.remoteFleetFrameImage = 'true';
|
|
13579
|
+
image.dataset.remoteFleetFrameKind = hasLiveFrame ? 'live' : 'thumbnail';
|
|
13580
|
+
image.dataset.remoteFleetFrameSeq = preview.dataset.remoteFleetFrameSeq;
|
|
13329
13581
|
image.src = previewSource;
|
|
13330
13582
|
image.alt = `${name} screen`;
|
|
13331
13583
|
image.loading = 'lazy';
|
|
@@ -13334,6 +13586,7 @@
|
|
|
13334
13586
|
preview.appendChild(image);
|
|
13335
13587
|
} else {
|
|
13336
13588
|
const placeholder = document.createElement('div');
|
|
13589
|
+
placeholder.dataset.remoteFleetScreenPlaceholder = 'true';
|
|
13337
13590
|
placeholder.textContent = thumbnailEnabled ? 'No frame yet' : 'Status only';
|
|
13338
13591
|
placeholder.style.cssText = `
|
|
13339
13592
|
position: absolute;
|
|
@@ -13349,6 +13602,7 @@
|
|
|
13349
13602
|
preview.appendChild(placeholder);
|
|
13350
13603
|
}
|
|
13351
13604
|
const previewBadge = document.createElement('span');
|
|
13605
|
+
previewBadge.dataset.remoteFleetFrameBadge = 'true';
|
|
13352
13606
|
previewBadge.textContent = hasLiveFrame
|
|
13353
13607
|
? `LIVE ${previewAt ? formatRemoteFleetAge(previewAt) : ''}`.trim()
|
|
13354
13608
|
: (previewAt ? formatRemoteFleetAge(previewAt) : (hubStatus === 'online' ? 'Pinned' : 'Hub offline'));
|
|
@@ -13627,6 +13881,7 @@
|
|
|
13627
13881
|
});
|
|
13628
13882
|
|
|
13629
13883
|
if (liveActive) {
|
|
13884
|
+
startRemoteFleetFrameLoop(bodyView, REMOTE_FLEET_LIVE_FRAME_REFRESH_MS, () => refreshRemoteDeviceFrame('live'));
|
|
13630
13885
|
bodyView._remoteFleetLiveRefreshTimer = setInterval(async () => {
|
|
13631
13886
|
if (!document.body.contains(bodyView)) {
|
|
13632
13887
|
clearRemoteFleetTimers(bodyView);
|
|
@@ -14141,6 +14396,10 @@
|
|
|
14141
14396
|
`;
|
|
14142
14397
|
|
|
14143
14398
|
const livePreview = document.createElement('div');
|
|
14399
|
+
livePreview.dataset.remoteFleetDevicePreview = 'focused-live';
|
|
14400
|
+
livePreview.dataset.deviceId = focusedId;
|
|
14401
|
+
livePreview.dataset.remoteFleetFrameKind = hasLiveFrame ? 'live' : '';
|
|
14402
|
+
livePreview.dataset.remoteFleetFrameSeq = String(getRemoteFleetDeviceField(focusedDevice, 'liveFrameSeq', 'LiveFrameSeq', 0));
|
|
14144
14403
|
livePreview.style.cssText = `
|
|
14145
14404
|
position: relative;
|
|
14146
14405
|
min-width: 0;
|
|
@@ -14152,6 +14411,9 @@
|
|
|
14152
14411
|
`;
|
|
14153
14412
|
if (hasLiveFrame) {
|
|
14154
14413
|
const image = document.createElement('img');
|
|
14414
|
+
image.dataset.remoteFleetFrameImage = 'true';
|
|
14415
|
+
image.dataset.remoteFleetFrameKind = 'live';
|
|
14416
|
+
image.dataset.remoteFleetFrameSeq = livePreview.dataset.remoteFleetFrameSeq;
|
|
14155
14417
|
image.src = liveFrameSource;
|
|
14156
14418
|
image.alt = `${focusedName} live screen`;
|
|
14157
14419
|
image.decoding = 'async';
|
|
@@ -14164,6 +14426,7 @@
|
|
|
14164
14426
|
livePreview.appendChild(image);
|
|
14165
14427
|
} else {
|
|
14166
14428
|
const placeholder = document.createElement('div');
|
|
14429
|
+
placeholder.dataset.remoteFleetScreenPlaceholder = 'true';
|
|
14167
14430
|
placeholder.textContent = liveActive ? 'Waiting for live frame' : 'Live view idle';
|
|
14168
14431
|
placeholder.style.cssText = `
|
|
14169
14432
|
position: absolute;
|
|
@@ -14179,6 +14442,7 @@
|
|
|
14179
14442
|
livePreview.appendChild(placeholder);
|
|
14180
14443
|
}
|
|
14181
14444
|
const liveBadge = document.createElement('span');
|
|
14445
|
+
liveBadge.dataset.remoteFleetFrameBadge = 'true';
|
|
14182
14446
|
liveBadge.textContent = liveActive
|
|
14183
14447
|
? `LIVE ${liveFrameAt ? formatRemoteFleetAge(liveFrameAt) : ''}`.trim()
|
|
14184
14448
|
: 'FOCUS';
|
|
@@ -14267,6 +14531,11 @@
|
|
|
14267
14531
|
|
|
14268
14532
|
const preview = document.createElement('div');
|
|
14269
14533
|
preview.dataset.remoteFleetDevicePreview = mode;
|
|
14534
|
+
preview.dataset.deviceId = getRemoteFleetDeviceId(device);
|
|
14535
|
+
preview.dataset.remoteFleetFrameKind = hasLiveFrame ? 'live' : (hasThumbnail ? 'thumbnail' : '');
|
|
14536
|
+
preview.dataset.remoteFleetFrameSeq = String(hasLiveFrame
|
|
14537
|
+
? getRemoteFleetDeviceField(device, 'liveFrameSeq', 'LiveFrameSeq', 0)
|
|
14538
|
+
: getRemoteFleetDeviceField(device, 'thumbnailFrameSeq', 'ThumbnailFrameSeq', 0));
|
|
14270
14539
|
preview.style.cssText = `
|
|
14271
14540
|
position: relative;
|
|
14272
14541
|
width: 100%;
|
|
@@ -14279,6 +14548,9 @@
|
|
|
14279
14548
|
|
|
14280
14549
|
if (hasLiveFrame || hasThumbnail) {
|
|
14281
14550
|
const image = document.createElement('img');
|
|
14551
|
+
image.dataset.remoteFleetFrameImage = 'true';
|
|
14552
|
+
image.dataset.remoteFleetFrameKind = hasLiveFrame ? 'live' : 'thumbnail';
|
|
14553
|
+
image.dataset.remoteFleetFrameSeq = preview.dataset.remoteFleetFrameSeq;
|
|
14282
14554
|
image.src = previewSource;
|
|
14283
14555
|
image.alt = hasLiveFrame ? `${name} live frame` : `${name} thumbnail`;
|
|
14284
14556
|
image.loading = 'lazy';
|
|
@@ -14316,6 +14588,7 @@
|
|
|
14316
14588
|
|
|
14317
14589
|
if (hasLiveFrame || (isDetail && previewAt)) {
|
|
14318
14590
|
const badge = document.createElement('span');
|
|
14591
|
+
badge.dataset.remoteFleetFrameBadge = 'true';
|
|
14319
14592
|
badge.textContent = hasLiveFrame
|
|
14320
14593
|
? (isDetail && previewAt ? `LIVE ${formatRemoteFleetAge(previewAt)}` : 'LIVE')
|
|
14321
14594
|
: formatRemoteFleetAge(previewAt);
|
|
@@ -14738,6 +15011,19 @@
|
|
|
14738
15011
|
const readTaskInstruction = () => String(taskInput.value || '').trim();
|
|
14739
15012
|
const useAiAssist = () => aiToggle.checked === true;
|
|
14740
15013
|
const getDeviceCards = () => Array.from(grid.querySelectorAll('article[data-device-id]'));
|
|
15014
|
+
const getVisibleFrameDeviceIds = () => {
|
|
15015
|
+
const ids = getDeviceCards()
|
|
15016
|
+
.filter(card => card.style.display !== 'none')
|
|
15017
|
+
.map(card => String(card.dataset.deviceId || '').trim())
|
|
15018
|
+
.filter(Boolean);
|
|
15019
|
+
if (focusedDevice) {
|
|
15020
|
+
const focusedId = getRemoteFleetDeviceId(focusedDevice);
|
|
15021
|
+
if (focusedId) {
|
|
15022
|
+
ids.unshift(focusedId);
|
|
15023
|
+
}
|
|
15024
|
+
}
|
|
15025
|
+
return Array.from(new Set(ids)).slice(0, 120);
|
|
15026
|
+
};
|
|
14741
15027
|
const refreshRemoteFleetNode = async () => {
|
|
14742
15028
|
if (bodyView._remoteFleetRefreshInFlight === true) {
|
|
14743
15029
|
return null;
|
|
@@ -14752,6 +15038,11 @@
|
|
|
14752
15038
|
bodyView._remoteFleetRefreshInFlight = false;
|
|
14753
15039
|
}
|
|
14754
15040
|
};
|
|
15041
|
+
const refreshRemoteFleetVisibleFrames = async (requestThumbnails = false) => {
|
|
15042
|
+
const result = await invokeDotNetAsync('RefreshRemoteFleetFramesFromJs', nodeId, getVisibleFrameDeviceIds(), requestThumbnails === true);
|
|
15043
|
+
applyRemoteFleetFramePatches(bodyView, normalizeRemoteFleetDeviceFramePatches(result));
|
|
15044
|
+
return result;
|
|
15045
|
+
};
|
|
14755
15046
|
const prepareRemoteFleetTaskFollow = batch => {
|
|
14756
15047
|
if (!isRemoteFleetTaskBatchActive(batch)) {
|
|
14757
15048
|
bodyView.dataset.remoteFleetTaskFollowActive = 'false';
|
|
@@ -15023,6 +15314,7 @@
|
|
|
15023
15314
|
|
|
15024
15315
|
const setRemoteFleetHostTarget = async (enabled, options = {}) => {
|
|
15025
15316
|
const quiet = options?.quiet === true;
|
|
15317
|
+
const renew = options?.renew === true || quiet;
|
|
15026
15318
|
const activeButton = enabled ? hostButton : stopHostButton;
|
|
15027
15319
|
if (!quiet && activeButton) {
|
|
15028
15320
|
activeButton.disabled = true;
|
|
@@ -15032,10 +15324,11 @@
|
|
|
15032
15324
|
setTaskFeedback(enabled ? 'Setting host target...' : 'Stopping host target...');
|
|
15033
15325
|
}
|
|
15034
15326
|
try {
|
|
15035
|
-
const result = await invokeDotNetAsync('SetRemoteFleetHostFromJs', nodeId, enabled === true);
|
|
15327
|
+
const result = await invokeDotNetAsync('SetRemoteFleetHostFromJs', nodeId, enabled === true, renew === true);
|
|
15036
15328
|
window.RuntimeTrace?.emit?.('remote.hostTarget.result', {
|
|
15037
15329
|
nodeId,
|
|
15038
15330
|
enabled: enabled === true,
|
|
15331
|
+
renew: renew === true,
|
|
15039
15332
|
success: isRemoteFleetResultSuccess(result),
|
|
15040
15333
|
active: isRemoteFleetResultActive(result),
|
|
15041
15334
|
error: result?.error || result?.Error || ''
|
|
@@ -15043,6 +15336,9 @@
|
|
|
15043
15336
|
rememberRemoteFleetLocalHostTarget(nodeId, enabled === true, result);
|
|
15044
15337
|
await syncRemoteFleetNodeStateFromResult(result);
|
|
15045
15338
|
if (quiet) {
|
|
15339
|
+
if (!isRemoteFleetResultSuccess(result) || !isRemoteFleetResultActive(result)) {
|
|
15340
|
+
stopRemoteFleetHostLeaseTimer(nodeId);
|
|
15341
|
+
}
|
|
15046
15342
|
return result;
|
|
15047
15343
|
}
|
|
15048
15344
|
if (isRemoteFleetResultSuccess(result) && enabled !== true) {
|
|
@@ -15205,10 +15501,11 @@
|
|
|
15205
15501
|
});
|
|
15206
15502
|
|
|
15207
15503
|
if (isHostingTarget) {
|
|
15208
|
-
startRemoteFleetHostLeaseTimer(nodeId, () => setRemoteFleetHostTarget(true, { quiet: true }));
|
|
15504
|
+
startRemoteFleetHostLeaseTimer(nodeId, () => setRemoteFleetHostTarget(true, { quiet: true, renew: true }));
|
|
15209
15505
|
}
|
|
15210
15506
|
|
|
15211
15507
|
if (hasActiveLiveStream) {
|
|
15508
|
+
startRemoteFleetFrameLoop(bodyView, REMOTE_FLEET_LIVE_FRAME_REFRESH_MS, () => refreshRemoteFleetVisibleFrames(false));
|
|
15212
15509
|
bodyView._remoteFleetLiveRefreshTimer = setInterval(async () => {
|
|
15213
15510
|
if (!document.body.contains(bodyView)) {
|
|
15214
15511
|
clearRemoteFleetTimers(bodyView);
|
|
@@ -15222,6 +15519,7 @@
|
|
|
15222
15519
|
}
|
|
15223
15520
|
}, REMOTE_FLEET_LIVE_REFRESH_MS);
|
|
15224
15521
|
} else if (autoMonitorState && hasMonitorTargets) {
|
|
15522
|
+
startRemoteFleetFrameLoop(bodyView, REMOTE_FLEET_THUMBNAIL_FRAME_REFRESH_MS, () => refreshRemoteFleetVisibleFrames(true));
|
|
15225
15523
|
bodyView._remoteFleetMonitorRefreshTimer = setInterval(async () => {
|
|
15226
15524
|
if (!document.body.contains(bodyView)) {
|
|
15227
15525
|
clearRemoteFleetTimers(bodyView);
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"mainAssemblyName": "MindExecution.Web",
|
|
3
3
|
"resources": {
|
|
4
|
-
"hash": "sha256-
|
|
4
|
+
"hash": "sha256-FI1aVvJXZHMtJ4l634osWbTe8sQ5rfdCKfSBgDnqQ70=",
|
|
5
5
|
"fingerprinting": {
|
|
6
6
|
"Google.Protobuf.9h59ukbel7.dll": "Google.Protobuf.dll",
|
|
7
7
|
"Markdig.d1j7v41cl1.dll": "Markdig.dll",
|
|
@@ -123,16 +123,16 @@
|
|
|
123
123
|
"System.brmz7yk5qh.dll": "System.dll",
|
|
124
124
|
"netstandard.yvr3prsx0x.dll": "netstandard.dll",
|
|
125
125
|
"System.Private.CoreLib.ns29bor93l.dll": "System.Private.CoreLib.dll",
|
|
126
|
-
"MindExecution.Core.
|
|
127
|
-
"MindExecution.Kernel.
|
|
128
|
-
"MindExecution.Plugins.Admin.
|
|
129
|
-
"MindExecution.Plugins.Business.
|
|
130
|
-
"MindExecution.Plugins.Concept.
|
|
131
|
-
"MindExecution.Plugins.Directory.
|
|
132
|
-
"MindExecution.Plugins.PlanMaster.
|
|
133
|
-
"MindExecution.Plugins.YouTube.
|
|
134
|
-
"MindExecution.Shared.
|
|
135
|
-
"MindExecution.Web.
|
|
126
|
+
"MindExecution.Core.fu1rl67yt3.dll": "MindExecution.Core.dll",
|
|
127
|
+
"MindExecution.Kernel.cqcbagjpqb.dll": "MindExecution.Kernel.dll",
|
|
128
|
+
"MindExecution.Plugins.Admin.tsn0j478un.dll": "MindExecution.Plugins.Admin.dll",
|
|
129
|
+
"MindExecution.Plugins.Business.xg74dmn0vz.dll": "MindExecution.Plugins.Business.dll",
|
|
130
|
+
"MindExecution.Plugins.Concept.j0zntvuecv.dll": "MindExecution.Plugins.Concept.dll",
|
|
131
|
+
"MindExecution.Plugins.Directory.9i4bd043ia.dll": "MindExecution.Plugins.Directory.dll",
|
|
132
|
+
"MindExecution.Plugins.PlanMaster.vml3qie2ji.dll": "MindExecution.Plugins.PlanMaster.dll",
|
|
133
|
+
"MindExecution.Plugins.YouTube.0gfbwq1jfg.dll": "MindExecution.Plugins.YouTube.dll",
|
|
134
|
+
"MindExecution.Shared.f3bclzo6k4.dll": "MindExecution.Shared.dll",
|
|
135
|
+
"MindExecution.Web.4jhsxoiqgz.dll": "MindExecution.Web.dll",
|
|
136
136
|
"dotnet.js": "dotnet.js",
|
|
137
137
|
"dotnet.native.qc8g39g30v.js": "dotnet.native.js",
|
|
138
138
|
"dotnet.native.boem75ye5i.wasm": "dotnet.native.wasm",
|
|
@@ -278,18 +278,18 @@
|
|
|
278
278
|
"System.Xml.XDocument.sn51jas17n.dll": "sha256-GNI2kFgFmPTwzuzwUn8gxK+AzGLUWRJFdg9JzIbrybQ=",
|
|
279
279
|
"System.brmz7yk5qh.dll": "sha256-CfM2miyj1KHApFmqMdLYWio3S/jrdON2pW9Xr2nTwlo=",
|
|
280
280
|
"netstandard.yvr3prsx0x.dll": "sha256-EksNn8Luo4bOWqJ6X7dIe9qG9oOqwOVzjH2xYyMNi+E=",
|
|
281
|
-
"MindExecution.Core.
|
|
282
|
-
"MindExecution.Kernel.
|
|
283
|
-
"MindExecution.Plugins.Concept.
|
|
284
|
-
"MindExecution.Plugins.PlanMaster.
|
|
285
|
-
"MindExecution.Shared.
|
|
286
|
-
"MindExecution.Web.
|
|
281
|
+
"MindExecution.Core.fu1rl67yt3.dll": "sha256-6cDbehKdjX71zeL9Ro5GNupn7wqRYfb7yLW2w3Wp05g=",
|
|
282
|
+
"MindExecution.Kernel.cqcbagjpqb.dll": "sha256-zPB0tmwi/UKdJ//g0xMH1Y02ahDX5ii6ZKdB3yiQQz4=",
|
|
283
|
+
"MindExecution.Plugins.Concept.j0zntvuecv.dll": "sha256-/XUaopvgQk71o+jBdb3ljhCAQkXrda6XxCzS0242pIo=",
|
|
284
|
+
"MindExecution.Plugins.PlanMaster.vml3qie2ji.dll": "sha256-uS3p/j4Kq171sz/xkiEn08DZni3X6HLbq2OHsYcxIjg=",
|
|
285
|
+
"MindExecution.Shared.f3bclzo6k4.dll": "sha256-1ZuF0eTN8dm8o0BzDJX+lyuKB1Wlc8MO2+kPJx/TYec=",
|
|
286
|
+
"MindExecution.Web.4jhsxoiqgz.dll": "sha256-QPegscpX6rm9Fp7lPqHdeKDVUFshfip6frFo62NWuss="
|
|
287
287
|
},
|
|
288
288
|
"lazyAssembly": {
|
|
289
|
-
"MindExecution.Plugins.Admin.
|
|
290
|
-
"MindExecution.Plugins.Business.
|
|
291
|
-
"MindExecution.Plugins.Directory.
|
|
292
|
-
"MindExecution.Plugins.YouTube.
|
|
289
|
+
"MindExecution.Plugins.Admin.tsn0j478un.dll": "sha256-g5Q4Ihy2PJKx6EFB6k78dIszLgK4hZ3Xintjvso/zmw=",
|
|
290
|
+
"MindExecution.Plugins.Business.xg74dmn0vz.dll": "sha256-0bP/QgMyXSk9IlQVun63rnWvkwqqZmJcRe90QoPC6jw=",
|
|
291
|
+
"MindExecution.Plugins.Directory.9i4bd043ia.dll": "sha256-b+fpVz2RkQC8uL4dIvN6wMWWefoII84Jyfe85EU/URk=",
|
|
292
|
+
"MindExecution.Plugins.YouTube.0gfbwq1jfg.dll": "sha256-EEXiqTRw/mDzke0TaI/QAlp2DRCQCfL4lzGSH0pRZ4c="
|
|
293
293
|
}
|
|
294
294
|
},
|
|
295
295
|
"cacheBootResources": true,
|
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=20260614-remote-
|
|
11
|
-
<link rel="stylesheet" href="_content/MindExecution.Shared/css/mind-map-overrides.css?v=20260614-remote-
|
|
10
|
+
<link rel="stylesheet" href="_content/MindExecution.Shared/css/app.css?v=20260614-remote-frame-meta-v513" />
|
|
11
|
+
<link rel="stylesheet" href="_content/MindExecution.Shared/css/mind-map-overrides.css?v=20260614-remote-frame-meta-v513" />
|
|
12
12
|
<!-- ?쇄뼹??Font Awesome (local) ?쇄뼹??-->
|
|
13
13
|
<link rel="stylesheet" href="_content/MindExecution.Shared/lib/font-awesome/css/all.min.css" />
|
|
14
14
|
<!-- ?꿎뼯??-->
|
|
@@ -558,7 +558,7 @@
|
|
|
558
558
|
}
|
|
559
559
|
|
|
560
560
|
const base = '_content/MindExecution.Shared/js/';
|
|
561
|
-
const scriptVersion = '20260614-remote-
|
|
561
|
+
const scriptVersion = '20260614-remote-frame-meta-v513';
|
|
562
562
|
const scriptUrl = (script) => `${base}${script}?v=${scriptVersion}`;
|
|
563
563
|
console.log(`[Script Loader] Shared JS version: ${scriptVersion}`);
|
|
564
564
|
const criticalScripts = [
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
self.assetsManifest = {
|
|
2
|
-
"version": "
|
|
2
|
+
"version": "3rReX/U0",
|
|
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-U5R3dUgCFR7qo8wM4p3MlIDxa9ZCd686fnrWvQFfSfs=",
|
|
90
90
|
"url": "_content/MindExecution.Shared/js/mind-map-css3d-manager.js"
|
|
91
91
|
},
|
|
92
92
|
{
|
|
@@ -410,44 +410,44 @@
|
|
|
410
410
|
"url": "_framework/MimeMapping.og9ys58ylm.dll"
|
|
411
411
|
},
|
|
412
412
|
{
|
|
413
|
-
"hash": "sha256-
|
|
414
|
-
"url": "_framework/MindExecution.Core.
|
|
413
|
+
"hash": "sha256-6cDbehKdjX71zeL9Ro5GNupn7wqRYfb7yLW2w3Wp05g=",
|
|
414
|
+
"url": "_framework/MindExecution.Core.fu1rl67yt3.dll"
|
|
415
415
|
},
|
|
416
416
|
{
|
|
417
|
-
"hash": "sha256-
|
|
418
|
-
"url": "_framework/MindExecution.Kernel.
|
|
417
|
+
"hash": "sha256-zPB0tmwi/UKdJ//g0xMH1Y02ahDX5ii6ZKdB3yiQQz4=",
|
|
418
|
+
"url": "_framework/MindExecution.Kernel.cqcbagjpqb.dll"
|
|
419
419
|
},
|
|
420
420
|
{
|
|
421
|
-
"hash": "sha256-
|
|
422
|
-
"url": "_framework/MindExecution.Plugins.Admin.
|
|
421
|
+
"hash": "sha256-g5Q4Ihy2PJKx6EFB6k78dIszLgK4hZ3Xintjvso/zmw=",
|
|
422
|
+
"url": "_framework/MindExecution.Plugins.Admin.tsn0j478un.dll"
|
|
423
423
|
},
|
|
424
424
|
{
|
|
425
|
-
"hash": "sha256-
|
|
426
|
-
"url": "_framework/MindExecution.Plugins.Business.
|
|
425
|
+
"hash": "sha256-0bP/QgMyXSk9IlQVun63rnWvkwqqZmJcRe90QoPC6jw=",
|
|
426
|
+
"url": "_framework/MindExecution.Plugins.Business.xg74dmn0vz.dll"
|
|
427
427
|
},
|
|
428
428
|
{
|
|
429
|
-
"hash": "sha256
|
|
430
|
-
"url": "_framework/MindExecution.Plugins.Concept.
|
|
429
|
+
"hash": "sha256-/XUaopvgQk71o+jBdb3ljhCAQkXrda6XxCzS0242pIo=",
|
|
430
|
+
"url": "_framework/MindExecution.Plugins.Concept.j0zntvuecv.dll"
|
|
431
431
|
},
|
|
432
432
|
{
|
|
433
|
-
"hash": "sha256-
|
|
434
|
-
"url": "_framework/MindExecution.Plugins.Directory.
|
|
433
|
+
"hash": "sha256-b+fpVz2RkQC8uL4dIvN6wMWWefoII84Jyfe85EU/URk=",
|
|
434
|
+
"url": "_framework/MindExecution.Plugins.Directory.9i4bd043ia.dll"
|
|
435
435
|
},
|
|
436
436
|
{
|
|
437
|
-
"hash": "sha256-
|
|
438
|
-
"url": "_framework/MindExecution.Plugins.PlanMaster.
|
|
437
|
+
"hash": "sha256-uS3p/j4Kq171sz/xkiEn08DZni3X6HLbq2OHsYcxIjg=",
|
|
438
|
+
"url": "_framework/MindExecution.Plugins.PlanMaster.vml3qie2ji.dll"
|
|
439
439
|
},
|
|
440
440
|
{
|
|
441
|
-
"hash": "sha256-
|
|
442
|
-
"url": "_framework/MindExecution.Plugins.YouTube.
|
|
441
|
+
"hash": "sha256-EEXiqTRw/mDzke0TaI/QAlp2DRCQCfL4lzGSH0pRZ4c=",
|
|
442
|
+
"url": "_framework/MindExecution.Plugins.YouTube.0gfbwq1jfg.dll"
|
|
443
443
|
},
|
|
444
444
|
{
|
|
445
|
-
"hash": "sha256-
|
|
446
|
-
"url": "_framework/MindExecution.Shared.
|
|
445
|
+
"hash": "sha256-1ZuF0eTN8dm8o0BzDJX+lyuKB1Wlc8MO2+kPJx/TYec=",
|
|
446
|
+
"url": "_framework/MindExecution.Shared.f3bclzo6k4.dll"
|
|
447
447
|
},
|
|
448
448
|
{
|
|
449
|
-
"hash": "sha256-
|
|
450
|
-
"url": "_framework/MindExecution.Web.
|
|
449
|
+
"hash": "sha256-QPegscpX6rm9Fp7lPqHdeKDVUFshfip6frFo62NWuss=",
|
|
450
|
+
"url": "_framework/MindExecution.Web.4jhsxoiqgz.dll"
|
|
451
451
|
},
|
|
452
452
|
{
|
|
453
453
|
"hash": "sha256-IsZJ91/OW+fHzNqIgEc7Y072ns8z9dGritiSyvR9Wgc=",
|
|
@@ -770,7 +770,7 @@
|
|
|
770
770
|
"url": "_framework/Websocket.Client.vapounvmnl.dll"
|
|
771
771
|
},
|
|
772
772
|
{
|
|
773
|
-
"hash": "sha256-
|
|
773
|
+
"hash": "sha256-XdUGtIDw1SDDWXPLtg2RaeuvCW6T6yjMxok5H9KUFaE=",
|
|
774
774
|
"url": "_framework/blazor.boot.json"
|
|
775
775
|
},
|
|
776
776
|
{
|
|
@@ -834,7 +834,7 @@
|
|
|
834
834
|
"url": "image-manifest.json"
|
|
835
835
|
},
|
|
836
836
|
{
|
|
837
|
-
"hash": "sha256-
|
|
837
|
+
"hash": "sha256-KqDHFUlmca/5qM/MGimpiIQKNxh1Udxo7/O1bDIsk+s=",
|
|
838
838
|
"url": "index.html"
|
|
839
839
|
},
|
|
840
840
|
{
|
|
Binary file
|
|
Binary file
|