@mindexec/cli 0.2.93 → 0.2.95
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 +118 -9
- package/scripts/remote-http-smoke.mjs +2 -0
- package/server.js +194 -9
- package/wwwroot/_framework/MindExecution.Core.eyl4o4qxg8.dll +0 -0
- package/wwwroot/_framework/{MindExecution.Kernel.55q6x6zeoc.dll → MindExecution.Kernel.hxyapaztgr.dll} +0 -0
- package/wwwroot/_framework/{MindExecution.Plugins.Admin.peei1t6ncj.dll → MindExecution.Plugins.Admin.7kemovesa7.dll} +0 -0
- package/wwwroot/_framework/{MindExecution.Plugins.Business.04t0oe4t4k.dll → MindExecution.Plugins.Business.t370in2g1b.dll} +0 -0
- package/wwwroot/_framework/{MindExecution.Plugins.Concept.f4gpqdzqwj.dll → MindExecution.Plugins.Concept.oqhv1116kb.dll} +0 -0
- package/wwwroot/_framework/{MindExecution.Plugins.Directory.az6m63vnll.dll → MindExecution.Plugins.Directory.0v80a0hi9m.dll} +0 -0
- package/wwwroot/_framework/{MindExecution.Plugins.PlanMaster.o2xcmf9i46.dll → MindExecution.Plugins.PlanMaster.hn5sfx4z2l.dll} +0 -0
- package/wwwroot/_framework/{MindExecution.Plugins.YouTube.xnrrltoofq.dll → MindExecution.Plugins.YouTube.c8sc0tlc6o.dll} +0 -0
- package/wwwroot/_framework/{MindExecution.Shared.6qq547u3iu.dll → MindExecution.Shared.osv9nbh3ym.dll} +0 -0
- package/wwwroot/_framework/MindExecution.Web.cdu22y82zq.dll +0 -0
- package/wwwroot/_framework/blazor.boot.json +21 -21
- package/wwwroot/service-worker-assets.js +22 -22
- package/wwwroot/service-worker.js +1 -1
- package/wwwroot/_framework/MindExecution.Core.e31e775w23.dll +0 -0
- package/wwwroot/_framework/MindExecution.Web.nfbmmsf2rl.dll +0 -0
package/package.json
CHANGED
package/remote-hub.js
CHANGED
|
@@ -77,10 +77,72 @@ function isPrivateIPv4(value) {
|
|
|
77
77
|
|| (parts[0] === 192 && parts[1] === 168);
|
|
78
78
|
}
|
|
79
79
|
|
|
80
|
-
function
|
|
80
|
+
function isPreferredPhysicalInterfaceName(value) {
|
|
81
|
+
const name = String(value || '').toLowerCase();
|
|
82
|
+
return /(^|[\s_\-()])((wi[\s_\-]?fi)|wifi|wireless|wlan|ethernet|lan|이더넷|en\d+|eth\d+)(?=$|[\s_\-()])/i.test(name);
|
|
83
|
+
}
|
|
84
|
+
|
|
85
|
+
function isVirtualInterfaceName(value) {
|
|
86
|
+
const name = String(value || '').toLowerCase();
|
|
87
|
+
return /virtual|vethernet|hyper-v|hyperv|vmware|virtualbox|vbox|docker|wsl|container|bluetooth|loopback|npcap|isatap|teredo/i.test(name);
|
|
88
|
+
}
|
|
89
|
+
|
|
90
|
+
function getIPv4LastOctet(value) {
|
|
91
|
+
const parts = String(value || '').split('.').map(part => Number(part));
|
|
92
|
+
if (parts.length !== 4 || parts.some(part => !Number.isInteger(part))) {
|
|
93
|
+
return -1;
|
|
94
|
+
}
|
|
95
|
+
|
|
96
|
+
return parts[3];
|
|
97
|
+
}
|
|
98
|
+
|
|
99
|
+
function scoreReachableIPv4Candidate(candidate) {
|
|
100
|
+
const address = String(candidate?.address || '');
|
|
101
|
+
const name = String(candidate?.name || '');
|
|
102
|
+
let score = 0;
|
|
103
|
+
|
|
104
|
+
if (isPrivateIPv4(address)) {
|
|
105
|
+
score += 1000;
|
|
106
|
+
}
|
|
107
|
+
|
|
108
|
+
if (/^192\.168\./.test(address)) {
|
|
109
|
+
score += 90;
|
|
110
|
+
} else if (/^10\./.test(address)) {
|
|
111
|
+
score += 80;
|
|
112
|
+
} else if (/^172\.(1[6-9]|2\d|3[0-1])\./.test(address)) {
|
|
113
|
+
score += 70;
|
|
114
|
+
}
|
|
115
|
+
|
|
116
|
+
if (isPreferredPhysicalInterfaceName(name)) {
|
|
117
|
+
score += 500;
|
|
118
|
+
}
|
|
119
|
+
|
|
120
|
+
if (isVirtualInterfaceName(name)) {
|
|
121
|
+
score -= 1200;
|
|
122
|
+
}
|
|
123
|
+
|
|
124
|
+
if (/^169\.254\./.test(address)) {
|
|
125
|
+
score -= 2000;
|
|
126
|
+
}
|
|
127
|
+
|
|
128
|
+
const lastOctet = getIPv4LastOctet(address);
|
|
129
|
+
if (lastOctet === 1) {
|
|
130
|
+
score -= 60;
|
|
131
|
+
} else if (lastOctet === 0 || lastOctet === 255) {
|
|
132
|
+
score -= 100;
|
|
133
|
+
}
|
|
134
|
+
|
|
135
|
+
if (candidate?.mac && candidate.mac === '00:00:00:00:00:00') {
|
|
136
|
+
score -= 50;
|
|
137
|
+
}
|
|
138
|
+
|
|
139
|
+
return score;
|
|
140
|
+
}
|
|
141
|
+
|
|
142
|
+
function getReachableIPv4CandidateEntries() {
|
|
81
143
|
const candidates = [];
|
|
82
144
|
const interfaces = os.networkInterfaces();
|
|
83
|
-
for (const entries of Object.
|
|
145
|
+
for (const [name, entries] of Object.entries(interfaces)) {
|
|
84
146
|
for (const entry of entries || []) {
|
|
85
147
|
if (entry?.family !== 'IPv4' || entry.internal) {
|
|
86
148
|
continue;
|
|
@@ -91,13 +153,28 @@ function getReachableIPv4Candidates() {
|
|
|
91
153
|
continue;
|
|
92
154
|
}
|
|
93
155
|
|
|
94
|
-
candidates.push(
|
|
156
|
+
candidates.push({
|
|
157
|
+
address,
|
|
158
|
+
name: safeString(name, 128),
|
|
159
|
+
mac: safeString(entry.mac, 32),
|
|
160
|
+
score: 0,
|
|
161
|
+
virtual: isVirtualInterfaceName(name),
|
|
162
|
+
preferred: isPreferredPhysicalInterfaceName(name)
|
|
163
|
+
});
|
|
95
164
|
}
|
|
96
165
|
}
|
|
97
166
|
|
|
98
167
|
return candidates
|
|
99
|
-
.
|
|
100
|
-
|
|
168
|
+
.map(candidate => ({
|
|
169
|
+
...candidate,
|
|
170
|
+
score: scoreReachableIPv4Candidate(candidate)
|
|
171
|
+
}))
|
|
172
|
+
.sort((left, right) => right.score - left.score || left.address.localeCompare(right.address))
|
|
173
|
+
.filter((candidate, index, all) => all.findIndex(item => item.address === candidate.address) === index);
|
|
174
|
+
}
|
|
175
|
+
|
|
176
|
+
function getReachableIPv4Candidates() {
|
|
177
|
+
return getReachableIPv4CandidateEntries().map(candidate => candidate.address);
|
|
101
178
|
}
|
|
102
179
|
|
|
103
180
|
function getReachableIPv4Address() {
|
|
@@ -105,6 +182,19 @@ function getReachableIPv4Address() {
|
|
|
105
182
|
return candidates.find(isPrivateIPv4) || candidates[0] || '127.0.0.1';
|
|
106
183
|
}
|
|
107
184
|
|
|
185
|
+
function buildEndpoint(hostValue, portValue) {
|
|
186
|
+
const hostText = safeString(hostValue, 128);
|
|
187
|
+
const port = normalizePort(portValue);
|
|
188
|
+
if (!hostText || !port) {
|
|
189
|
+
return '';
|
|
190
|
+
}
|
|
191
|
+
|
|
192
|
+
const hostPart = hostText.includes(':') && !hostText.startsWith('[')
|
|
193
|
+
? `[${hostText}]`
|
|
194
|
+
: hostText;
|
|
195
|
+
return `${hostPart}:${port}`;
|
|
196
|
+
}
|
|
197
|
+
|
|
108
198
|
function parseManagerEndpoint(value) {
|
|
109
199
|
const endpoint = safeString(value, 256);
|
|
110
200
|
const match = endpoint.match(/^(\[[^\]]+\]|[^:\s]+):(\d{1,5})$/);
|
|
@@ -409,13 +499,26 @@ export function createRemoteHub(options = {}) {
|
|
|
409
499
|
}
|
|
410
500
|
|
|
411
501
|
function getAgentEndpointRouteInfo() {
|
|
412
|
-
const
|
|
502
|
+
const includeInterfaceCandidates = !publicEndpoint && isWildcardHost(host);
|
|
503
|
+
const candidateDetails = includeInterfaceCandidates
|
|
504
|
+
? getReachableIPv4CandidateEntries()
|
|
505
|
+
: [];
|
|
506
|
+
const candidateEndpoints = candidateDetails
|
|
507
|
+
.map(candidate => ({
|
|
508
|
+
...candidate,
|
|
509
|
+
endpoint: buildEndpoint(candidate.address, boundPort || requestedPort)
|
|
510
|
+
}))
|
|
511
|
+
.filter(candidate => candidate.endpoint);
|
|
413
512
|
const endpoint = getAgentEndpoint();
|
|
513
|
+
const endpointCandidates = [
|
|
514
|
+
endpoint,
|
|
515
|
+
...candidateEndpoints.map(candidate => candidate.endpoint)
|
|
516
|
+
].filter((value, index, all) => value && all.indexOf(value) === index);
|
|
414
517
|
const wildcardWithoutReachableAddress =
|
|
415
518
|
!publicEndpoint
|
|
416
519
|
&& !publicHost
|
|
417
520
|
&& isWildcardHost(host)
|
|
418
|
-
&&
|
|
521
|
+
&& candidateDetails.length === 0;
|
|
419
522
|
const reason = getAccountRouteEndpointReason(endpoint, { wildcardWithoutReachableAddress });
|
|
420
523
|
const parsed = parseManagerEndpoint(endpoint);
|
|
421
524
|
return {
|
|
@@ -424,7 +527,8 @@ export function createRemoteHub(options = {}) {
|
|
|
424
527
|
port: parsed?.port || 0,
|
|
425
528
|
accountRouteReady: reason === 'ok',
|
|
426
529
|
reason,
|
|
427
|
-
candidates
|
|
530
|
+
candidates: endpointCandidates,
|
|
531
|
+
candidateDetails: candidateEndpoints
|
|
428
532
|
};
|
|
429
533
|
}
|
|
430
534
|
|
|
@@ -457,6 +561,7 @@ export function createRemoteHub(options = {}) {
|
|
|
457
561
|
leaseId: '',
|
|
458
562
|
hostInstanceId: '',
|
|
459
563
|
endpoint: '',
|
|
564
|
+
endpointCandidates: [],
|
|
460
565
|
activatedAt: '',
|
|
461
566
|
updatedAt: '',
|
|
462
567
|
expiresAt: ''
|
|
@@ -469,6 +574,7 @@ export function createRemoteHub(options = {}) {
|
|
|
469
574
|
leaseId: target.leaseId,
|
|
470
575
|
hostInstanceId: target.hostInstanceId || hostInstanceId,
|
|
471
576
|
endpoint: target.endpoint,
|
|
577
|
+
endpointCandidates: Array.isArray(target.endpointCandidates) ? [...target.endpointCandidates] : [target.endpoint].filter(Boolean),
|
|
472
578
|
activatedAt: target.activatedAt,
|
|
473
579
|
updatedAt: target.updatedAt,
|
|
474
580
|
expiresAt: target.expiresAt
|
|
@@ -530,6 +636,7 @@ export function createRemoteHub(options = {}) {
|
|
|
530
636
|
leaseId: activeSameNode && previous?.leaseId ? previous.leaseId : crypto.randomUUID(),
|
|
531
637
|
hostInstanceId,
|
|
532
638
|
endpoint: routeInfo.endpoint,
|
|
639
|
+
endpointCandidates: routeInfo.candidates,
|
|
533
640
|
activatedAt: activeSameNode && previous?.activatedAt ? previous.activatedAt : now.toISOString(),
|
|
534
641
|
updatedAt: now.toISOString(),
|
|
535
642
|
expiresAt: new Date(now.getTime() + leaseMs).toISOString()
|
|
@@ -542,7 +649,7 @@ export function createRemoteHub(options = {}) {
|
|
|
542
649
|
if (!activeSameNode || !routeInfo.accountRouteReady) {
|
|
543
650
|
logEvent(
|
|
544
651
|
'remote',
|
|
545
|
-
`host target ${routeInfo.accountRouteReady ? 'account-ready' : 'local-only'} endpoint=${routeInfo.endpoint} reason=${routeInfo.reason}`,
|
|
652
|
+
`host target ${routeInfo.accountRouteReady ? 'account-ready' : 'local-only'} endpoint=${routeInfo.endpoint} candidates=${routeInfo.candidates.length} reason=${routeInfo.reason}`,
|
|
546
653
|
'remote');
|
|
547
654
|
}
|
|
548
655
|
return {
|
|
@@ -574,6 +681,7 @@ export function createRemoteHub(options = {}) {
|
|
|
574
681
|
agentEndpointAccountRouteReady: routeInfo.accountRouteReady,
|
|
575
682
|
agentEndpointRouteReason: routeInfo.reason,
|
|
576
683
|
agentEndpointCandidates: routeInfo.candidates,
|
|
684
|
+
agentEndpointCandidateDetails: routeInfo.candidateDetails,
|
|
577
685
|
pairToken: includeSecrets ? pairToken : undefined,
|
|
578
686
|
pairTokenPreview: maskToken(pairToken),
|
|
579
687
|
deviceCount: devices.size,
|
|
@@ -585,6 +693,7 @@ export function createRemoteHub(options = {}) {
|
|
|
585
693
|
hostTargetLeaseId: activeHostTarget.leaseId,
|
|
586
694
|
hostTargetHostInstanceId: activeHostTarget.hostInstanceId,
|
|
587
695
|
hostTargetEndpoint: activeHostTarget.endpoint,
|
|
696
|
+
hostTargetEndpointCandidates: activeHostTarget.endpointCandidates,
|
|
588
697
|
hostTargetActivatedAt: activeHostTarget.activatedAt,
|
|
589
698
|
hostTargetUpdatedAt: activeHostTarget.updatedAt,
|
|
590
699
|
hostTargetExpiresAt: activeHostTarget.expiresAt,
|
|
@@ -217,12 +217,14 @@ async function runSyntheticEnabledSmoke() {
|
|
|
217
217
|
assert.equal(setHost.payload?.active, true);
|
|
218
218
|
assert.equal(setHost.payload?.hostTarget?.nodeId, 'remote-fleet-monitor-a');
|
|
219
219
|
assert.equal(setHost.payload?.hostTarget?.endpoint, `127.0.0.1:${remoteHubPort}`);
|
|
220
|
+
assert.deepEqual(setHost.payload?.hostTarget?.endpointCandidates, [`127.0.0.1:${remoteHubPort}`]);
|
|
220
221
|
|
|
221
222
|
const hostStatus = await fetchJson(`${baseUrl}/api/remote/status`, { token: BRIDGE_TOKEN });
|
|
222
223
|
assert.equal(hostStatus.ok, true, JSON.stringify(hostStatus.payload));
|
|
223
224
|
assert.equal(hostStatus.payload?.hostTargetActive, true);
|
|
224
225
|
assert.equal(hostStatus.payload?.hostTargetNodeId, 'remote-fleet-monitor-a');
|
|
225
226
|
assert.equal(hostStatus.payload?.hostTargetEndpoint, `127.0.0.1:${remoteHubPort}`);
|
|
227
|
+
assert.deepEqual(hostStatus.payload?.hostTargetEndpointCandidates, [`127.0.0.1:${remoteHubPort}`]);
|
|
226
228
|
|
|
227
229
|
const clearHostMismatch = await fetchJson(`${baseUrl}/api/remote/host-target`, {
|
|
228
230
|
method: 'DELETE',
|
package/server.js
CHANGED
|
@@ -2733,6 +2733,7 @@ const remoteHub = createRemoteHub({
|
|
|
2733
2733
|
|
|
2734
2734
|
const REMOTE_AGENT_STDIO_TAIL_CHARS = 12000;
|
|
2735
2735
|
const REMOTE_AGENT_EARLY_EXIT_MS = 1200;
|
|
2736
|
+
const REMOTE_AGENT_READY_TIMEOUT_MS = 5000;
|
|
2736
2737
|
const REMOTE_AGENT_DEFAULT_ENGINE = 'auto';
|
|
2737
2738
|
let remoteAgentState = createRemoteAgentIdleState();
|
|
2738
2739
|
|
|
@@ -2740,6 +2741,7 @@ function createRemoteAgentIdleState(overrides = {}) {
|
|
|
2740
2741
|
return {
|
|
2741
2742
|
status: 'idle',
|
|
2742
2743
|
manager: '',
|
|
2744
|
+
managerCandidates: [],
|
|
2743
2745
|
leaseId: '',
|
|
2744
2746
|
nodeId: '',
|
|
2745
2747
|
engine: REMOTE_AGENT_DEFAULT_ENGINE,
|
|
@@ -2748,6 +2750,8 @@ function createRemoteAgentIdleState(overrides = {}) {
|
|
|
2748
2750
|
pid: 0,
|
|
2749
2751
|
startedAt: '',
|
|
2750
2752
|
updatedAt: new Date().toISOString(),
|
|
2753
|
+
ready: false,
|
|
2754
|
+
connectedAt: '',
|
|
2751
2755
|
exitedAt: '',
|
|
2752
2756
|
exitCode: null,
|
|
2753
2757
|
signal: '',
|
|
@@ -2772,10 +2776,18 @@ function serializeRemoteAgentState() {
|
|
|
2772
2776
|
};
|
|
2773
2777
|
}
|
|
2774
2778
|
|
|
2775
|
-
function appendRemoteAgentOutput(stream, chunk) {
|
|
2779
|
+
function appendRemoteAgentOutput(stream, chunk, stateConnectionKey = '') {
|
|
2780
|
+
if (stateConnectionKey && remoteAgentState.connectionKey !== stateConnectionKey) {
|
|
2781
|
+
return;
|
|
2782
|
+
}
|
|
2783
|
+
|
|
2776
2784
|
const text = chunk.toString();
|
|
2777
2785
|
const key = stream === 'stderr' ? 'stderrTail' : 'stdoutTail';
|
|
2778
2786
|
remoteAgentState[key] = String((remoteAgentState[key] || '') + text).slice(-REMOTE_AGENT_STDIO_TAIL_CHARS);
|
|
2787
|
+
if (/Connected to RemoteHub/i.test(text)) {
|
|
2788
|
+
remoteAgentState.ready = true;
|
|
2789
|
+
remoteAgentState.connectedAt = new Date().toISOString();
|
|
2790
|
+
}
|
|
2779
2791
|
remoteAgentState.updatedAt = new Date().toISOString();
|
|
2780
2792
|
}
|
|
2781
2793
|
|
|
@@ -2844,6 +2856,53 @@ function waitForRemoteAgentEarlyExit(child, settleMs = REMOTE_AGENT_EARLY_EXIT_M
|
|
|
2844
2856
|
});
|
|
2845
2857
|
}
|
|
2846
2858
|
|
|
2859
|
+
function waitForRemoteAgentReady(child, timeoutMs = REMOTE_AGENT_READY_TIMEOUT_MS) {
|
|
2860
|
+
return new Promise(resolve => {
|
|
2861
|
+
if (!child || child.exitCode !== null || child.killed) {
|
|
2862
|
+
resolve(false);
|
|
2863
|
+
return;
|
|
2864
|
+
}
|
|
2865
|
+
|
|
2866
|
+
if (remoteAgentState.ready === true) {
|
|
2867
|
+
resolve(true);
|
|
2868
|
+
return;
|
|
2869
|
+
}
|
|
2870
|
+
|
|
2871
|
+
let settled = false;
|
|
2872
|
+
let timer = null;
|
|
2873
|
+
let poller = null;
|
|
2874
|
+
const cleanup = () => {
|
|
2875
|
+
if (timer) {
|
|
2876
|
+
clearTimeout(timer);
|
|
2877
|
+
}
|
|
2878
|
+
if (poller) {
|
|
2879
|
+
clearInterval(poller);
|
|
2880
|
+
}
|
|
2881
|
+
child.off('exit', onExit);
|
|
2882
|
+
child.off('error', onError);
|
|
2883
|
+
};
|
|
2884
|
+
const finish = value => {
|
|
2885
|
+
if (settled) {
|
|
2886
|
+
return;
|
|
2887
|
+
}
|
|
2888
|
+
settled = true;
|
|
2889
|
+
cleanup();
|
|
2890
|
+
resolve(value);
|
|
2891
|
+
};
|
|
2892
|
+
const onExit = () => finish(false);
|
|
2893
|
+
const onError = () => finish(false);
|
|
2894
|
+
|
|
2895
|
+
child.once('exit', onExit);
|
|
2896
|
+
child.once('error', onError);
|
|
2897
|
+
poller = setInterval(() => {
|
|
2898
|
+
if (remoteAgentState.ready === true) {
|
|
2899
|
+
finish(true);
|
|
2900
|
+
}
|
|
2901
|
+
}, 100);
|
|
2902
|
+
timer = setTimeout(() => finish(remoteAgentState.ready === true), timeoutMs);
|
|
2903
|
+
});
|
|
2904
|
+
}
|
|
2905
|
+
|
|
2847
2906
|
function normalizeRemoteAgentEngine(value) {
|
|
2848
2907
|
const engine = String(value || REMOTE_AGENT_DEFAULT_ENGINE).trim().toLowerCase();
|
|
2849
2908
|
if (engine === 'fast' || engine === 'csharp' || engine === 'c#') {
|
|
@@ -2871,6 +2930,34 @@ function normalizeRemoteManagerEndpoint(value) {
|
|
|
2871
2930
|
return `${match[1]}:${port}`;
|
|
2872
2931
|
}
|
|
2873
2932
|
|
|
2933
|
+
function normalizeRemoteManagerEndpointList(...values) {
|
|
2934
|
+
const rawValues = [];
|
|
2935
|
+
for (const value of values) {
|
|
2936
|
+
if (Array.isArray(value)) {
|
|
2937
|
+
rawValues.push(...value);
|
|
2938
|
+
} else if (value && typeof value[Symbol.iterator] === 'function' && typeof value !== 'string') {
|
|
2939
|
+
rawValues.push(...value);
|
|
2940
|
+
} else {
|
|
2941
|
+
rawValues.push(value);
|
|
2942
|
+
}
|
|
2943
|
+
}
|
|
2944
|
+
|
|
2945
|
+
const endpoints = [];
|
|
2946
|
+
const seen = new Set();
|
|
2947
|
+
for (const value of rawValues) {
|
|
2948
|
+
const endpoint = normalizeRemoteManagerEndpoint(value);
|
|
2949
|
+
const key = endpoint.toLowerCase();
|
|
2950
|
+
if (!endpoint || seen.has(key)) {
|
|
2951
|
+
continue;
|
|
2952
|
+
}
|
|
2953
|
+
|
|
2954
|
+
seen.add(key);
|
|
2955
|
+
endpoints.push(endpoint);
|
|
2956
|
+
}
|
|
2957
|
+
|
|
2958
|
+
return endpoints;
|
|
2959
|
+
}
|
|
2960
|
+
|
|
2874
2961
|
function safeRemoteAgentField(value, maxLength = 128) {
|
|
2875
2962
|
return String(value || '').replace(/[\r\n\t]/g, ' ').trim().slice(0, maxLength);
|
|
2876
2963
|
}
|
|
@@ -2928,6 +3015,7 @@ async function stopRemoteAgentConnection(reason = 'stopped') {
|
|
|
2928
3015
|
remoteAgentState = createRemoteAgentIdleState({
|
|
2929
3016
|
status: 'stopped',
|
|
2930
3017
|
manager: previous.manager,
|
|
3018
|
+
managerCandidates: previous.managerCandidates,
|
|
2931
3019
|
leaseId: previous.leaseId,
|
|
2932
3020
|
nodeId: previous.nodeId,
|
|
2933
3021
|
engine: previous.engine,
|
|
@@ -2946,23 +3034,31 @@ async function stopRemoteAgentConnection(reason = 'stopped') {
|
|
|
2946
3034
|
}
|
|
2947
3035
|
|
|
2948
3036
|
async function startRemoteAgentConnection(options = {}) {
|
|
2949
|
-
const manager = normalizeRemoteManagerEndpoint(options.manager || options.managerEndpoint || options.endpoint);
|
|
2950
3037
|
const pairToken = safeRemoteAgentField(options.pairToken || options.pair, 512);
|
|
2951
3038
|
const leaseId = safeRemoteAgentField(options.leaseId, 128);
|
|
2952
3039
|
const nodeId = safeRemoteAgentField(options.nodeId, 128);
|
|
2953
3040
|
const source = safeRemoteAgentField(options.source || 'registry', 64);
|
|
2954
3041
|
const engine = normalizeRemoteAgentEngine(options.engine);
|
|
2955
|
-
|
|
2956
|
-
|
|
3042
|
+
const managers = normalizeRemoteManagerEndpointList(
|
|
3043
|
+
options.manager || options.managerEndpoint || options.endpoint,
|
|
3044
|
+
options.managerCandidates,
|
|
3045
|
+
options.endpointCandidates,
|
|
3046
|
+
options.candidates);
|
|
3047
|
+
|
|
3048
|
+
if (managers.length === 0) {
|
|
3049
|
+
logWarn('remote', 'managed RemoteAgent connect rejected: invalid manager endpoint');
|
|
2957
3050
|
return { ok: false, error: 'invalid-manager-endpoint', agent: serializeRemoteAgentState() };
|
|
2958
3051
|
}
|
|
2959
3052
|
|
|
2960
3053
|
if (!pairToken) {
|
|
3054
|
+
logWarn('remote', `managed RemoteAgent connect rejected: missing pair token ${formatKeyValue('manager', managers[0])}`);
|
|
2961
3055
|
return { ok: false, error: 'missing-pair-token', agent: serializeRemoteAgentState() };
|
|
2962
3056
|
}
|
|
2963
3057
|
|
|
2964
|
-
const
|
|
2965
|
-
if (isRemoteAgentProcessRunning()
|
|
3058
|
+
const activeConnectionKeys = new Set(managers.map(manager => createRemoteAgentConnectionKey(manager, leaseId)));
|
|
3059
|
+
if (isRemoteAgentProcessRunning()
|
|
3060
|
+
&& remoteAgentState.ready === true
|
|
3061
|
+
&& activeConnectionKeys.has(remoteAgentState.connectionKey)) {
|
|
2966
3062
|
return { ok: true, alreadyRunning: true, agent: serializeRemoteAgentState() };
|
|
2967
3063
|
}
|
|
2968
3064
|
|
|
@@ -2970,6 +3066,66 @@ async function startRemoteAgentConnection(options = {}) {
|
|
|
2970
3066
|
await stopRemoteAgentConnection('replaced-by-new-target');
|
|
2971
3067
|
}
|
|
2972
3068
|
|
|
3069
|
+
let lastResult = null;
|
|
3070
|
+
for (let index = 0; index < managers.length; index += 1) {
|
|
3071
|
+
const manager = managers[index];
|
|
3072
|
+
if (managers.length > 1) {
|
|
3073
|
+
logEvent(
|
|
3074
|
+
'remote',
|
|
3075
|
+
`managed RemoteAgent candidate ${index + 1}/${managers.length} ${formatKeyValue('manager', manager)}`,
|
|
3076
|
+
'remote');
|
|
3077
|
+
}
|
|
3078
|
+
|
|
3079
|
+
const result = await startRemoteAgentConnectionAttempt({
|
|
3080
|
+
manager,
|
|
3081
|
+
managerCandidates: managers,
|
|
3082
|
+
pairToken,
|
|
3083
|
+
leaseId,
|
|
3084
|
+
nodeId,
|
|
3085
|
+
source,
|
|
3086
|
+
engine
|
|
3087
|
+
});
|
|
3088
|
+
if (result?.ok === true) {
|
|
3089
|
+
return result;
|
|
3090
|
+
}
|
|
3091
|
+
|
|
3092
|
+
lastResult = result;
|
|
3093
|
+
if (isRemoteAgentProcessRunning()) {
|
|
3094
|
+
await stopRemoteAgentConnection(`candidate-failed:${manager}`);
|
|
3095
|
+
}
|
|
3096
|
+
|
|
3097
|
+
if (index + 1 < managers.length) {
|
|
3098
|
+
logWarn(
|
|
3099
|
+
'remote',
|
|
3100
|
+
`managed RemoteAgent candidate failed; trying next ${formatKeyValue('manager', manager)} ${formatKeyValue('error', result?.error || 'unknown')}`);
|
|
3101
|
+
}
|
|
3102
|
+
}
|
|
3103
|
+
|
|
3104
|
+
return {
|
|
3105
|
+
ok: false,
|
|
3106
|
+
error: lastResult?.error || 'all-manager-candidates-failed',
|
|
3107
|
+
agent: lastResult?.agent || serializeRemoteAgentState()
|
|
3108
|
+
};
|
|
3109
|
+
}
|
|
3110
|
+
|
|
3111
|
+
async function startRemoteAgentConnectionAttempt(options = {}) {
|
|
3112
|
+
const manager = normalizeRemoteManagerEndpoint(options.manager || options.managerEndpoint || options.endpoint);
|
|
3113
|
+
const pairToken = safeRemoteAgentField(options.pairToken || options.pair, 512);
|
|
3114
|
+
const leaseId = safeRemoteAgentField(options.leaseId, 128);
|
|
3115
|
+
const nodeId = safeRemoteAgentField(options.nodeId, 128);
|
|
3116
|
+
const source = safeRemoteAgentField(options.source || 'registry', 64);
|
|
3117
|
+
const engine = normalizeRemoteAgentEngine(options.engine);
|
|
3118
|
+
const managerCandidates = normalizeRemoteManagerEndpointList(options.managerCandidates, manager);
|
|
3119
|
+
|
|
3120
|
+
if (!manager) {
|
|
3121
|
+
return { ok: false, error: 'invalid-manager-endpoint', agent: serializeRemoteAgentState() };
|
|
3122
|
+
}
|
|
3123
|
+
|
|
3124
|
+
if (!pairToken) {
|
|
3125
|
+
return { ok: false, error: 'missing-pair-token', agent: serializeRemoteAgentState() };
|
|
3126
|
+
}
|
|
3127
|
+
|
|
3128
|
+
const connectionKey = createRemoteAgentConnectionKey(manager, leaseId);
|
|
2973
3129
|
const launcher = resolveRemoteAgentLauncher();
|
|
2974
3130
|
const args = [
|
|
2975
3131
|
...launcher.argsPrefix,
|
|
@@ -2985,12 +3141,15 @@ async function startRemoteAgentConnection(options = {}) {
|
|
|
2985
3141
|
remoteAgentState = createRemoteAgentIdleState({
|
|
2986
3142
|
status: 'starting',
|
|
2987
3143
|
manager,
|
|
3144
|
+
managerCandidates,
|
|
2988
3145
|
leaseId,
|
|
2989
3146
|
nodeId,
|
|
2990
3147
|
engine,
|
|
2991
3148
|
source,
|
|
2992
3149
|
connectionKey,
|
|
2993
3150
|
startedAt: new Date().toISOString(),
|
|
3151
|
+
ready: false,
|
|
3152
|
+
connectedAt: '',
|
|
2994
3153
|
launcher: launcher.launcher,
|
|
2995
3154
|
usingNpx: launcher.usingNpx
|
|
2996
3155
|
});
|
|
@@ -3020,10 +3179,15 @@ async function startRemoteAgentConnection(options = {}) {
|
|
|
3020
3179
|
remoteAgentState.pid = Number(child.pid || 0);
|
|
3021
3180
|
remoteAgentState.status = 'running';
|
|
3022
3181
|
remoteAgentState.updatedAt = new Date().toISOString();
|
|
3182
|
+
const stateConnectionKey = connectionKey;
|
|
3023
3183
|
|
|
3024
|
-
child.stdout.on('data', chunk => appendRemoteAgentOutput('stdout', chunk));
|
|
3025
|
-
child.stderr.on('data', chunk => appendRemoteAgentOutput('stderr', chunk));
|
|
3184
|
+
child.stdout.on('data', chunk => appendRemoteAgentOutput('stdout', chunk, stateConnectionKey));
|
|
3185
|
+
child.stderr.on('data', chunk => appendRemoteAgentOutput('stderr', chunk, stateConnectionKey));
|
|
3026
3186
|
child.once('error', err => {
|
|
3187
|
+
if (remoteAgentState.connectionKey !== stateConnectionKey) {
|
|
3188
|
+
return;
|
|
3189
|
+
}
|
|
3190
|
+
|
|
3027
3191
|
remoteAgentState.status = 'failed';
|
|
3028
3192
|
remoteAgentState.lastError = err?.message || String(err);
|
|
3029
3193
|
remoteAgentState.updatedAt = new Date().toISOString();
|
|
@@ -3031,6 +3195,10 @@ async function startRemoteAgentConnection(options = {}) {
|
|
|
3031
3195
|
emitBridgeEvent('RemoteAgentFailed', serializeRemoteAgentState());
|
|
3032
3196
|
});
|
|
3033
3197
|
child.once('exit', (code, signal) => {
|
|
3198
|
+
if (remoteAgentState.connectionKey !== stateConnectionKey) {
|
|
3199
|
+
return;
|
|
3200
|
+
}
|
|
3201
|
+
|
|
3034
3202
|
remoteAgentState.status = code === 0 ? 'exited' : 'failed';
|
|
3035
3203
|
remoteAgentState.exitCode = Number.isFinite(code) ? code : null;
|
|
3036
3204
|
remoteAgentState.signal = signal || '';
|
|
@@ -3056,6 +3224,18 @@ async function startRemoteAgentConnection(options = {}) {
|
|
|
3056
3224
|
const exitedEarly = await waitForRemoteAgentEarlyExit(child);
|
|
3057
3225
|
if (exitedEarly) {
|
|
3058
3226
|
const error = formatRemoteAgentFailureSummary();
|
|
3227
|
+
logWarn('remote', `managed RemoteAgent exited during startup ${formatKeyValue('manager', manager)} ${formatKeyValue('error', error)}`);
|
|
3228
|
+
return { ok: false, error, agent: serializeRemoteAgentState() };
|
|
3229
|
+
}
|
|
3230
|
+
|
|
3231
|
+
const ready = await waitForRemoteAgentReady(child);
|
|
3232
|
+
if (!ready) {
|
|
3233
|
+
const error = `remote-agent-not-ready:${manager}`;
|
|
3234
|
+
remoteAgentState.status = 'failed';
|
|
3235
|
+
remoteAgentState.lastError = error;
|
|
3236
|
+
remoteAgentState.updatedAt = new Date().toISOString();
|
|
3237
|
+
logWarn('remote', `managed RemoteAgent startup did not connect ${formatKeyValue('manager', manager)} ${formatKeyValue('error', formatRemoteAgentFailureSummary())}`);
|
|
3238
|
+
emitBridgeEvent('RemoteAgentFailed', serializeRemoteAgentState());
|
|
3059
3239
|
return { ok: false, error, agent: serializeRemoteAgentState() };
|
|
3060
3240
|
}
|
|
3061
3241
|
|
|
@@ -7615,14 +7795,19 @@ app.get('/api/remote/agent/status', (req, res) => {
|
|
|
7615
7795
|
app.post('/api/remote/agent/connect', async (req, res) => {
|
|
7616
7796
|
res.setHeader('Cache-Control', 'no-store');
|
|
7617
7797
|
try {
|
|
7798
|
+
const requestedManager = normalizeRemoteManagerEndpoint(req.body?.manager || req.body?.managerEndpoint);
|
|
7618
7799
|
const result = await startRemoteAgentConnection({
|
|
7619
|
-
manager:
|
|
7800
|
+
manager: requestedManager,
|
|
7801
|
+
managerCandidates: req.body?.managerCandidates || req.body?.endpointCandidates || req.body?.candidates,
|
|
7620
7802
|
pairToken: req.body?.pairToken || req.body?.pair,
|
|
7621
7803
|
leaseId: req.body?.leaseId,
|
|
7622
7804
|
nodeId: req.body?.nodeId,
|
|
7623
7805
|
engine: req.body?.engine,
|
|
7624
7806
|
source: req.body?.source || 'registry'
|
|
7625
7807
|
});
|
|
7808
|
+
if (!result.ok) {
|
|
7809
|
+
logWarn('remote', `managed RemoteAgent connect failed ${formatKeyValue('manager', requestedManager || 'invalid')} ${formatKeyValue('error', result.error || 'unknown')}`);
|
|
7810
|
+
}
|
|
7626
7811
|
res.status(result.ok ? 200 : 400).json(result);
|
|
7627
7812
|
} catch (err) {
|
|
7628
7813
|
logError('remote', 'managed RemoteAgent connect failed.', err);
|
|
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-5gnfR4WvV/8ivk6zDF09/vNhA5Ptgr7fb/UhdwOAmHM=",
|
|
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.c1dbswx1b2.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.eyl4o4qxg8.dll": "MindExecution.Core.dll",
|
|
127
|
+
"MindExecution.Kernel.hxyapaztgr.dll": "MindExecution.Kernel.dll",
|
|
128
|
+
"MindExecution.Plugins.Admin.7kemovesa7.dll": "MindExecution.Plugins.Admin.dll",
|
|
129
|
+
"MindExecution.Plugins.Business.t370in2g1b.dll": "MindExecution.Plugins.Business.dll",
|
|
130
|
+
"MindExecution.Plugins.Concept.oqhv1116kb.dll": "MindExecution.Plugins.Concept.dll",
|
|
131
|
+
"MindExecution.Plugins.Directory.0v80a0hi9m.dll": "MindExecution.Plugins.Directory.dll",
|
|
132
|
+
"MindExecution.Plugins.PlanMaster.hn5sfx4z2l.dll": "MindExecution.Plugins.PlanMaster.dll",
|
|
133
|
+
"MindExecution.Plugins.YouTube.c8sc0tlc6o.dll": "MindExecution.Plugins.YouTube.dll",
|
|
134
|
+
"MindExecution.Shared.osv9nbh3ym.dll": "MindExecution.Shared.dll",
|
|
135
|
+
"MindExecution.Web.cdu22y82zq.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.eyl4o4qxg8.dll": "sha256-JtBC04XSxkMOl0cZOA2ZWvyV88yYPyU0nkIbBCF9Jtc=",
|
|
282
|
+
"MindExecution.Kernel.hxyapaztgr.dll": "sha256-q59U8/001rTsB1m+pkA4PkI9a9lvf5fijDWKXbN7uQ4=",
|
|
283
|
+
"MindExecution.Plugins.Concept.oqhv1116kb.dll": "sha256-kEAfhSpocd0AdwocZnMU2+v0W2y6HJV7TRiOB6FbmDY=",
|
|
284
|
+
"MindExecution.Plugins.PlanMaster.hn5sfx4z2l.dll": "sha256-Y2F3UYa2JgW9pCxL/YlCHo6gUohqHjQ4Z59cL/fdDBU=",
|
|
285
|
+
"MindExecution.Shared.osv9nbh3ym.dll": "sha256-yKMhEPXMN1XCDYyFMEbhio9mvn7j2JkPK/upMkWEfOE=",
|
|
286
|
+
"MindExecution.Web.cdu22y82zq.dll": "sha256-wO+wguSU+8uumbvn/I2fjxrD0N3+xXvJZZWTmE2EjKg="
|
|
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.7kemovesa7.dll": "sha256-N8cYgaOErldVhLpnvnh4R9kf7f7fmt+16KhBWlnfG1I=",
|
|
290
|
+
"MindExecution.Plugins.Business.t370in2g1b.dll": "sha256-B66uDzMZQfzN3fDnRSM1TvWh0uZjD6AVfUvJAyuGMdI=",
|
|
291
|
+
"MindExecution.Plugins.Directory.0v80a0hi9m.dll": "sha256-JPn9UkEDTmb2CO4o/CnuG76R4RgQStGYZ6jH5pzblXk=",
|
|
292
|
+
"MindExecution.Plugins.YouTube.c8sc0tlc6o.dll": "sha256-7P2anWE7Z/EXJfm/2CSQ1SWL1qPRtZG+gMwZEeqQaKM="
|
|
293
293
|
}
|
|
294
294
|
},
|
|
295
295
|
"cacheBootResources": true,
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
self.assetsManifest = {
|
|
2
|
-
"version": "
|
|
2
|
+
"version": "Gwzavwgq",
|
|
3
3
|
"assets": [
|
|
4
4
|
{
|
|
5
5
|
"hash": "sha256-+CSYMcqLNTsq3VnH11jgYyOCCdxvHzL74CBmo4sCmMU=",
|
|
@@ -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-JtBC04XSxkMOl0cZOA2ZWvyV88yYPyU0nkIbBCF9Jtc=",
|
|
414
|
+
"url": "_framework/MindExecution.Core.eyl4o4qxg8.dll"
|
|
415
415
|
},
|
|
416
416
|
{
|
|
417
|
-
"hash": "sha256-
|
|
418
|
-
"url": "_framework/MindExecution.Kernel.
|
|
417
|
+
"hash": "sha256-q59U8/001rTsB1m+pkA4PkI9a9lvf5fijDWKXbN7uQ4=",
|
|
418
|
+
"url": "_framework/MindExecution.Kernel.hxyapaztgr.dll"
|
|
419
419
|
},
|
|
420
420
|
{
|
|
421
|
-
"hash": "sha256-
|
|
422
|
-
"url": "_framework/MindExecution.Plugins.Admin.
|
|
421
|
+
"hash": "sha256-N8cYgaOErldVhLpnvnh4R9kf7f7fmt+16KhBWlnfG1I=",
|
|
422
|
+
"url": "_framework/MindExecution.Plugins.Admin.7kemovesa7.dll"
|
|
423
423
|
},
|
|
424
424
|
{
|
|
425
|
-
"hash": "sha256-
|
|
426
|
-
"url": "_framework/MindExecution.Plugins.Business.
|
|
425
|
+
"hash": "sha256-B66uDzMZQfzN3fDnRSM1TvWh0uZjD6AVfUvJAyuGMdI=",
|
|
426
|
+
"url": "_framework/MindExecution.Plugins.Business.t370in2g1b.dll"
|
|
427
427
|
},
|
|
428
428
|
{
|
|
429
|
-
"hash": "sha256-
|
|
430
|
-
"url": "_framework/MindExecution.Plugins.Concept.
|
|
429
|
+
"hash": "sha256-kEAfhSpocd0AdwocZnMU2+v0W2y6HJV7TRiOB6FbmDY=",
|
|
430
|
+
"url": "_framework/MindExecution.Plugins.Concept.oqhv1116kb.dll"
|
|
431
431
|
},
|
|
432
432
|
{
|
|
433
|
-
"hash": "sha256-
|
|
434
|
-
"url": "_framework/MindExecution.Plugins.Directory.
|
|
433
|
+
"hash": "sha256-JPn9UkEDTmb2CO4o/CnuG76R4RgQStGYZ6jH5pzblXk=",
|
|
434
|
+
"url": "_framework/MindExecution.Plugins.Directory.0v80a0hi9m.dll"
|
|
435
435
|
},
|
|
436
436
|
{
|
|
437
|
-
"hash": "sha256-
|
|
438
|
-
"url": "_framework/MindExecution.Plugins.PlanMaster.
|
|
437
|
+
"hash": "sha256-Y2F3UYa2JgW9pCxL/YlCHo6gUohqHjQ4Z59cL/fdDBU=",
|
|
438
|
+
"url": "_framework/MindExecution.Plugins.PlanMaster.hn5sfx4z2l.dll"
|
|
439
439
|
},
|
|
440
440
|
{
|
|
441
|
-
"hash": "sha256-
|
|
442
|
-
"url": "_framework/MindExecution.Plugins.YouTube.
|
|
441
|
+
"hash": "sha256-7P2anWE7Z/EXJfm/2CSQ1SWL1qPRtZG+gMwZEeqQaKM=",
|
|
442
|
+
"url": "_framework/MindExecution.Plugins.YouTube.c8sc0tlc6o.dll"
|
|
443
443
|
},
|
|
444
444
|
{
|
|
445
|
-
"hash": "sha256-
|
|
446
|
-
"url": "_framework/MindExecution.Shared.
|
|
445
|
+
"hash": "sha256-yKMhEPXMN1XCDYyFMEbhio9mvn7j2JkPK/upMkWEfOE=",
|
|
446
|
+
"url": "_framework/MindExecution.Shared.osv9nbh3ym.dll"
|
|
447
447
|
},
|
|
448
448
|
{
|
|
449
|
-
"hash": "sha256-
|
|
450
|
-
"url": "_framework/MindExecution.Web.
|
|
449
|
+
"hash": "sha256-wO+wguSU+8uumbvn/I2fjxrD0N3+xXvJZZWTmE2EjKg=",
|
|
450
|
+
"url": "_framework/MindExecution.Web.cdu22y82zq.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-IDuQS33M39C51AcKlK3xYrMwyKOYKfuVq1o1JIS4wkw=",
|
|
774
774
|
"url": "_framework/blazor.boot.json"
|
|
775
775
|
},
|
|
776
776
|
{
|
|
Binary file
|
|
Binary file
|