@mindexec/cli 0.2.94 → 0.2.96

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.
Files changed (19) hide show
  1. package/package.json +1 -1
  2. package/remote-hub.js +35 -6
  3. package/scripts/remote-http-smoke.mjs +2 -0
  4. package/server.js +186 -8
  5. package/wwwroot/_framework/MindExecution.Core.eyl4o4qxg8.dll +0 -0
  6. package/wwwroot/_framework/{MindExecution.Kernel.55q6x6zeoc.dll → MindExecution.Kernel.hxyapaztgr.dll} +0 -0
  7. package/wwwroot/_framework/{MindExecution.Plugins.Admin.peei1t6ncj.dll → MindExecution.Plugins.Admin.7kemovesa7.dll} +0 -0
  8. package/wwwroot/_framework/{MindExecution.Plugins.Business.04t0oe4t4k.dll → MindExecution.Plugins.Business.t370in2g1b.dll} +0 -0
  9. package/wwwroot/_framework/{MindExecution.Plugins.Concept.f4gpqdzqwj.dll → MindExecution.Plugins.Concept.oqhv1116kb.dll} +0 -0
  10. package/wwwroot/_framework/{MindExecution.Plugins.Directory.az6m63vnll.dll → MindExecution.Plugins.Directory.0v80a0hi9m.dll} +0 -0
  11. package/wwwroot/_framework/{MindExecution.Plugins.PlanMaster.o2xcmf9i46.dll → MindExecution.Plugins.PlanMaster.hn5sfx4z2l.dll} +0 -0
  12. package/wwwroot/_framework/{MindExecution.Plugins.YouTube.xnrrltoofq.dll → MindExecution.Plugins.YouTube.c8sc0tlc6o.dll} +0 -0
  13. package/wwwroot/_framework/{MindExecution.Shared.6qq547u3iu.dll → MindExecution.Shared.osv9nbh3ym.dll} +0 -0
  14. package/wwwroot/_framework/MindExecution.Web.q1jwri2r1p.dll +0 -0
  15. package/wwwroot/_framework/blazor.boot.json +21 -21
  16. package/wwwroot/service-worker-assets.js +22 -22
  17. package/wwwroot/service-worker.js +1 -1
  18. package/wwwroot/_framework/MindExecution.Core.e31e775w23.dll +0 -0
  19. package/wwwroot/_framework/MindExecution.Web.nfbmmsf2rl.dll +0 -0
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@mindexec/cli",
3
- "version": "0.2.94",
3
+ "version": "0.2.96",
4
4
  "description": "MindExec local runtime and bridge CLI",
5
5
  "main": "server.js",
6
6
  "type": "module",
package/remote-hub.js CHANGED
@@ -182,6 +182,19 @@ function getReachableIPv4Address() {
182
182
  return candidates.find(isPrivateIPv4) || candidates[0] || '127.0.0.1';
183
183
  }
184
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
+
185
198
  function parseManagerEndpoint(value) {
186
199
  const endpoint = safeString(value, 256);
187
200
  const match = endpoint.match(/^(\[[^\]]+\]|[^:\s]+):(\d{1,5})$/);
@@ -486,14 +499,26 @@ export function createRemoteHub(options = {}) {
486
499
  }
487
500
 
488
501
  function getAgentEndpointRouteInfo() {
489
- const candidateDetails = getReachableIPv4CandidateEntries();
490
- const candidates = candidateDetails.map(candidate => candidate.address);
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);
491
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);
492
517
  const wildcardWithoutReachableAddress =
493
518
  !publicEndpoint
494
519
  && !publicHost
495
520
  && isWildcardHost(host)
496
- && candidates.length === 0;
521
+ && candidateDetails.length === 0;
497
522
  const reason = getAccountRouteEndpointReason(endpoint, { wildcardWithoutReachableAddress });
498
523
  const parsed = parseManagerEndpoint(endpoint);
499
524
  return {
@@ -502,8 +527,8 @@ export function createRemoteHub(options = {}) {
502
527
  port: parsed?.port || 0,
503
528
  accountRouteReady: reason === 'ok',
504
529
  reason,
505
- candidates,
506
- candidateDetails
530
+ candidates: endpointCandidates,
531
+ candidateDetails: candidateEndpoints
507
532
  };
508
533
  }
509
534
 
@@ -536,6 +561,7 @@ export function createRemoteHub(options = {}) {
536
561
  leaseId: '',
537
562
  hostInstanceId: '',
538
563
  endpoint: '',
564
+ endpointCandidates: [],
539
565
  activatedAt: '',
540
566
  updatedAt: '',
541
567
  expiresAt: ''
@@ -548,6 +574,7 @@ export function createRemoteHub(options = {}) {
548
574
  leaseId: target.leaseId,
549
575
  hostInstanceId: target.hostInstanceId || hostInstanceId,
550
576
  endpoint: target.endpoint,
577
+ endpointCandidates: Array.isArray(target.endpointCandidates) ? [...target.endpointCandidates] : [target.endpoint].filter(Boolean),
551
578
  activatedAt: target.activatedAt,
552
579
  updatedAt: target.updatedAt,
553
580
  expiresAt: target.expiresAt
@@ -609,6 +636,7 @@ export function createRemoteHub(options = {}) {
609
636
  leaseId: activeSameNode && previous?.leaseId ? previous.leaseId : crypto.randomUUID(),
610
637
  hostInstanceId,
611
638
  endpoint: routeInfo.endpoint,
639
+ endpointCandidates: routeInfo.candidates,
612
640
  activatedAt: activeSameNode && previous?.activatedAt ? previous.activatedAt : now.toISOString(),
613
641
  updatedAt: now.toISOString(),
614
642
  expiresAt: new Date(now.getTime() + leaseMs).toISOString()
@@ -621,7 +649,7 @@ export function createRemoteHub(options = {}) {
621
649
  if (!activeSameNode || !routeInfo.accountRouteReady) {
622
650
  logEvent(
623
651
  'remote',
624
- `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}`,
625
653
  'remote');
626
654
  }
627
655
  return {
@@ -665,6 +693,7 @@ export function createRemoteHub(options = {}) {
665
693
  hostTargetLeaseId: activeHostTarget.leaseId,
666
694
  hostTargetHostInstanceId: activeHostTarget.hostInstanceId,
667
695
  hostTargetEndpoint: activeHostTarget.endpoint,
696
+ hostTargetEndpointCandidates: activeHostTarget.endpointCandidates,
668
697
  hostTargetActivatedAt: activeHostTarget.activatedAt,
669
698
  hostTargetUpdatedAt: activeHostTarget.updatedAt,
670
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,25 +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);
3042
+ const managers = normalizeRemoteManagerEndpointList(
3043
+ options.manager || options.managerEndpoint || options.endpoint,
3044
+ options.managerCandidates,
3045
+ options.endpointCandidates,
3046
+ options.candidates);
2955
3047
 
2956
- if (!manager) {
3048
+ if (managers.length === 0) {
2957
3049
  logWarn('remote', 'managed RemoteAgent connect rejected: invalid manager endpoint');
2958
3050
  return { ok: false, error: 'invalid-manager-endpoint', agent: serializeRemoteAgentState() };
2959
3051
  }
2960
3052
 
2961
3053
  if (!pairToken) {
2962
- logWarn('remote', `managed RemoteAgent connect rejected: missing pair token ${formatKeyValue('manager', manager)}`);
3054
+ logWarn('remote', `managed RemoteAgent connect rejected: missing pair token ${formatKeyValue('manager', managers[0])}`);
2963
3055
  return { ok: false, error: 'missing-pair-token', agent: serializeRemoteAgentState() };
2964
3056
  }
2965
3057
 
2966
- const connectionKey = createRemoteAgentConnectionKey(manager, leaseId);
2967
- if (isRemoteAgentProcessRunning() && remoteAgentState.connectionKey === connectionKey) {
3058
+ const activeConnectionKeys = new Set(managers.map(manager => createRemoteAgentConnectionKey(manager, leaseId)));
3059
+ if (isRemoteAgentProcessRunning()
3060
+ && remoteAgentState.ready === true
3061
+ && activeConnectionKeys.has(remoteAgentState.connectionKey)) {
2968
3062
  return { ok: true, alreadyRunning: true, agent: serializeRemoteAgentState() };
2969
3063
  }
2970
3064
 
@@ -2972,6 +3066,66 @@ async function startRemoteAgentConnection(options = {}) {
2972
3066
  await stopRemoteAgentConnection('replaced-by-new-target');
2973
3067
  }
2974
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);
2975
3129
  const launcher = resolveRemoteAgentLauncher();
2976
3130
  const args = [
2977
3131
  ...launcher.argsPrefix,
@@ -2987,12 +3141,15 @@ async function startRemoteAgentConnection(options = {}) {
2987
3141
  remoteAgentState = createRemoteAgentIdleState({
2988
3142
  status: 'starting',
2989
3143
  manager,
3144
+ managerCandidates,
2990
3145
  leaseId,
2991
3146
  nodeId,
2992
3147
  engine,
2993
3148
  source,
2994
3149
  connectionKey,
2995
3150
  startedAt: new Date().toISOString(),
3151
+ ready: false,
3152
+ connectedAt: '',
2996
3153
  launcher: launcher.launcher,
2997
3154
  usingNpx: launcher.usingNpx
2998
3155
  });
@@ -3022,10 +3179,15 @@ async function startRemoteAgentConnection(options = {}) {
3022
3179
  remoteAgentState.pid = Number(child.pid || 0);
3023
3180
  remoteAgentState.status = 'running';
3024
3181
  remoteAgentState.updatedAt = new Date().toISOString();
3182
+ const stateConnectionKey = connectionKey;
3025
3183
 
3026
- child.stdout.on('data', chunk => appendRemoteAgentOutput('stdout', chunk));
3027
- 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));
3028
3186
  child.once('error', err => {
3187
+ if (remoteAgentState.connectionKey !== stateConnectionKey) {
3188
+ return;
3189
+ }
3190
+
3029
3191
  remoteAgentState.status = 'failed';
3030
3192
  remoteAgentState.lastError = err?.message || String(err);
3031
3193
  remoteAgentState.updatedAt = new Date().toISOString();
@@ -3033,6 +3195,10 @@ async function startRemoteAgentConnection(options = {}) {
3033
3195
  emitBridgeEvent('RemoteAgentFailed', serializeRemoteAgentState());
3034
3196
  });
3035
3197
  child.once('exit', (code, signal) => {
3198
+ if (remoteAgentState.connectionKey !== stateConnectionKey) {
3199
+ return;
3200
+ }
3201
+
3036
3202
  remoteAgentState.status = code === 0 ? 'exited' : 'failed';
3037
3203
  remoteAgentState.exitCode = Number.isFinite(code) ? code : null;
3038
3204
  remoteAgentState.signal = signal || '';
@@ -3062,6 +3228,17 @@ async function startRemoteAgentConnection(options = {}) {
3062
3228
  return { ok: false, error, agent: serializeRemoteAgentState() };
3063
3229
  }
3064
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());
3239
+ return { ok: false, error, agent: serializeRemoteAgentState() };
3240
+ }
3241
+
3065
3242
  return { ok: true, alreadyRunning: false, agent: serializeRemoteAgentState() };
3066
3243
  }
3067
3244
 
@@ -7621,6 +7798,7 @@ app.post('/api/remote/agent/connect', async (req, res) => {
7621
7798
  const requestedManager = normalizeRemoteManagerEndpoint(req.body?.manager || req.body?.managerEndpoint);
7622
7799
  const result = await startRemoteAgentConnection({
7623
7800
  manager: requestedManager,
7801
+ managerCandidates: req.body?.managerCandidates || req.body?.endpointCandidates || req.body?.candidates,
7624
7802
  pairToken: req.body?.pairToken || req.body?.pair,
7625
7803
  leaseId: req.body?.leaseId,
7626
7804
  nodeId: req.body?.nodeId,
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "mainAssemblyName": "MindExecution.Web",
3
3
  "resources": {
4
- "hash": "sha256-En37ftP0ESJ05mTVQWmF9DLUneIu5kqMcNkEfGC06KA=",
4
+ "hash": "sha256-S5i7mkxpxBzpYozfgxXvhV6AnfLnexeTJfewiJ8jOtA=",
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.e31e775w23.dll": "MindExecution.Core.dll",
127
- "MindExecution.Kernel.55q6x6zeoc.dll": "MindExecution.Kernel.dll",
128
- "MindExecution.Plugins.Admin.peei1t6ncj.dll": "MindExecution.Plugins.Admin.dll",
129
- "MindExecution.Plugins.Business.04t0oe4t4k.dll": "MindExecution.Plugins.Business.dll",
130
- "MindExecution.Plugins.Concept.f4gpqdzqwj.dll": "MindExecution.Plugins.Concept.dll",
131
- "MindExecution.Plugins.Directory.az6m63vnll.dll": "MindExecution.Plugins.Directory.dll",
132
- "MindExecution.Plugins.PlanMaster.o2xcmf9i46.dll": "MindExecution.Plugins.PlanMaster.dll",
133
- "MindExecution.Plugins.YouTube.xnrrltoofq.dll": "MindExecution.Plugins.YouTube.dll",
134
- "MindExecution.Shared.6qq547u3iu.dll": "MindExecution.Shared.dll",
135
- "MindExecution.Web.nfbmmsf2rl.dll": "MindExecution.Web.dll",
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.q1jwri2r1p.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.e31e775w23.dll": "sha256-CjA5yl5JfpYf6+7TuOwW4XZuBybv5Y6g5sAYXgoaq2M=",
282
- "MindExecution.Kernel.55q6x6zeoc.dll": "sha256-2RLhrX3JMUc5g/mGCTwFB61ND7dgYYPaFFFPUAakdiU=",
283
- "MindExecution.Plugins.Concept.f4gpqdzqwj.dll": "sha256-33uklvsdPqUhPHgnHxyQLPMNbo22Ztttf6r3foxoq7M=",
284
- "MindExecution.Plugins.PlanMaster.o2xcmf9i46.dll": "sha256-kEtfwKXd/IeopHD65TdAZ+8RpdLvnRFJhJ5m2PXozYk=",
285
- "MindExecution.Shared.6qq547u3iu.dll": "sha256-jrYtMJjsdd4gl1VIp/WvUr1j6xPzFcb6KsRP8gVxz9I=",
286
- "MindExecution.Web.nfbmmsf2rl.dll": "sha256-neaU6eYk85SeylghFpeBWqjRvKdscMU7Rfx2aPgn9N4="
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.q1jwri2r1p.dll": "sha256-bovOzmI58+BvUxaKQrGot/z4TEAg+VMmAkhiLkkfg1k="
287
287
  },
288
288
  "lazyAssembly": {
289
- "MindExecution.Plugins.Admin.peei1t6ncj.dll": "sha256-cW6VWE09PF8oNMZ07w2mgGKAKt2tTWuGBvEvhG8ReFI=",
290
- "MindExecution.Plugins.Business.04t0oe4t4k.dll": "sha256-YCPKCRRQ/Mhy8GKyovbWLGa1RV+RAdsX9ZqvTBztSpg=",
291
- "MindExecution.Plugins.Directory.az6m63vnll.dll": "sha256-KtGyNwTSSCOz2ArDDURYQ9FZABwjPuD9Cf47ck0KH10=",
292
- "MindExecution.Plugins.YouTube.xnrrltoofq.dll": "sha256-zQ2pUfGZpcRDKDvxrdKZ8YMSVts3fH2+Lz5j6HaUrTE="
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": "8tpj6Cb7",
2
+ "version": "CHEnV4yd",
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-CjA5yl5JfpYf6+7TuOwW4XZuBybv5Y6g5sAYXgoaq2M=",
414
- "url": "_framework/MindExecution.Core.e31e775w23.dll"
413
+ "hash": "sha256-JtBC04XSxkMOl0cZOA2ZWvyV88yYPyU0nkIbBCF9Jtc=",
414
+ "url": "_framework/MindExecution.Core.eyl4o4qxg8.dll"
415
415
  },
416
416
  {
417
- "hash": "sha256-2RLhrX3JMUc5g/mGCTwFB61ND7dgYYPaFFFPUAakdiU=",
418
- "url": "_framework/MindExecution.Kernel.55q6x6zeoc.dll"
417
+ "hash": "sha256-q59U8/001rTsB1m+pkA4PkI9a9lvf5fijDWKXbN7uQ4=",
418
+ "url": "_framework/MindExecution.Kernel.hxyapaztgr.dll"
419
419
  },
420
420
  {
421
- "hash": "sha256-cW6VWE09PF8oNMZ07w2mgGKAKt2tTWuGBvEvhG8ReFI=",
422
- "url": "_framework/MindExecution.Plugins.Admin.peei1t6ncj.dll"
421
+ "hash": "sha256-N8cYgaOErldVhLpnvnh4R9kf7f7fmt+16KhBWlnfG1I=",
422
+ "url": "_framework/MindExecution.Plugins.Admin.7kemovesa7.dll"
423
423
  },
424
424
  {
425
- "hash": "sha256-YCPKCRRQ/Mhy8GKyovbWLGa1RV+RAdsX9ZqvTBztSpg=",
426
- "url": "_framework/MindExecution.Plugins.Business.04t0oe4t4k.dll"
425
+ "hash": "sha256-B66uDzMZQfzN3fDnRSM1TvWh0uZjD6AVfUvJAyuGMdI=",
426
+ "url": "_framework/MindExecution.Plugins.Business.t370in2g1b.dll"
427
427
  },
428
428
  {
429
- "hash": "sha256-33uklvsdPqUhPHgnHxyQLPMNbo22Ztttf6r3foxoq7M=",
430
- "url": "_framework/MindExecution.Plugins.Concept.f4gpqdzqwj.dll"
429
+ "hash": "sha256-kEAfhSpocd0AdwocZnMU2+v0W2y6HJV7TRiOB6FbmDY=",
430
+ "url": "_framework/MindExecution.Plugins.Concept.oqhv1116kb.dll"
431
431
  },
432
432
  {
433
- "hash": "sha256-KtGyNwTSSCOz2ArDDURYQ9FZABwjPuD9Cf47ck0KH10=",
434
- "url": "_framework/MindExecution.Plugins.Directory.az6m63vnll.dll"
433
+ "hash": "sha256-JPn9UkEDTmb2CO4o/CnuG76R4RgQStGYZ6jH5pzblXk=",
434
+ "url": "_framework/MindExecution.Plugins.Directory.0v80a0hi9m.dll"
435
435
  },
436
436
  {
437
- "hash": "sha256-kEtfwKXd/IeopHD65TdAZ+8RpdLvnRFJhJ5m2PXozYk=",
438
- "url": "_framework/MindExecution.Plugins.PlanMaster.o2xcmf9i46.dll"
437
+ "hash": "sha256-Y2F3UYa2JgW9pCxL/YlCHo6gUohqHjQ4Z59cL/fdDBU=",
438
+ "url": "_framework/MindExecution.Plugins.PlanMaster.hn5sfx4z2l.dll"
439
439
  },
440
440
  {
441
- "hash": "sha256-zQ2pUfGZpcRDKDvxrdKZ8YMSVts3fH2+Lz5j6HaUrTE=",
442
- "url": "_framework/MindExecution.Plugins.YouTube.xnrrltoofq.dll"
441
+ "hash": "sha256-7P2anWE7Z/EXJfm/2CSQ1SWL1qPRtZG+gMwZEeqQaKM=",
442
+ "url": "_framework/MindExecution.Plugins.YouTube.c8sc0tlc6o.dll"
443
443
  },
444
444
  {
445
- "hash": "sha256-jrYtMJjsdd4gl1VIp/WvUr1j6xPzFcb6KsRP8gVxz9I=",
446
- "url": "_framework/MindExecution.Shared.6qq547u3iu.dll"
445
+ "hash": "sha256-yKMhEPXMN1XCDYyFMEbhio9mvn7j2JkPK/upMkWEfOE=",
446
+ "url": "_framework/MindExecution.Shared.osv9nbh3ym.dll"
447
447
  },
448
448
  {
449
- "hash": "sha256-neaU6eYk85SeylghFpeBWqjRvKdscMU7Rfx2aPgn9N4=",
450
- "url": "_framework/MindExecution.Web.nfbmmsf2rl.dll"
449
+ "hash": "sha256-bovOzmI58+BvUxaKQrGot/z4TEAg+VMmAkhiLkkfg1k=",
450
+ "url": "_framework/MindExecution.Web.q1jwri2r1p.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-xRkkZYryfd2M9u7R9q8FWfp9HwacRvKIdqvSNyvTEik=",
773
+ "hash": "sha256-Ep+Ov81XThtcE2HBQd0whA+KI3/0iJDNLBCtGNYC4TI=",
774
774
  "url": "_framework/blazor.boot.json"
775
775
  },
776
776
  {
@@ -1,4 +1,4 @@
1
- /* Manifest version: 8tpj6Cb7 */
1
+ /* Manifest version: CHEnV4yd */
2
2
  // Hosted deployments should prefer the network over stale offline caches.
3
3
  // This service worker immediately clears old Blazor offline caches and unregisters itself.
4
4