@mindexec/cli 0.2.143 → 0.2.145

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@mindexec/cli",
3
- "version": "0.2.143",
3
+ "version": "0.2.145",
4
4
  "description": "MindExec local runtime and bridge CLI",
5
5
  "main": "server.js",
6
6
  "type": "module",
@@ -186,6 +186,16 @@ class MiniElement {
186
186
  return true;
187
187
  }
188
188
 
189
+ focus() {
190
+ this.ownerDocument.activeElement = this;
191
+ }
192
+
193
+ blur() {
194
+ if (this.ownerDocument.activeElement === this) {
195
+ this.ownerDocument.activeElement = null;
196
+ }
197
+ }
198
+
189
199
  getBoundingClientRect() {
190
200
  return {
191
201
  left: 0,
@@ -268,6 +278,7 @@ class MiniDocument {
268
278
  this.body = new MiniElement('body', this);
269
279
  this.head = new MiniElement('head', this);
270
280
  this.canvasDrawCalls = [];
281
+ this.activeElement = null;
271
282
  }
272
283
 
273
284
  createElement(tagName) {
@@ -997,6 +1008,111 @@ try {
997
1008
  assert.equal(rerenderedPatchPreview.dataset.remoteFleetFrameSeq, String(websocketFrameSeq));
998
1009
  assert.equal(rerenderedPatchPreview.querySelector('canvas[data-remote-fleet-frame-canvas="true"]')?.style.display, 'block');
999
1010
 
1011
+ const liveStartCallsBeforeControl = dotNetCalls.filter(call => call.methodName === 'StartRemoteFleetLiveStreamFromJs').length;
1012
+ const sendCountBeforeControl = diagnostics.webSocketSends.length;
1013
+ const drawCountBeforeControl = document.canvasDrawCalls.length;
1014
+ const controlCard = bodyView.querySelector(`article[data-device-id="${patchTarget.DeviceId}"]`);
1015
+ assert.ok(controlCard);
1016
+ controlCard.dispatchEvent({ type: 'dblclick', button: 0 });
1017
+ await wait(30);
1018
+ const controlPopup = document.body.querySelector('[data-remote-fleet-control-popup="true"]');
1019
+ assert.ok(controlPopup, 'double-clicking an MDM tile should open the control popup');
1020
+ const controlShell = controlPopup.querySelector('[data-remote-fleet-control-shell="true"]');
1021
+ const controlStage = controlPopup.querySelector('[data-remote-fleet-control-stage="true"]');
1022
+ const controlCanvas = controlPopup.querySelector('[data-remote-fleet-control-canvas="true"]');
1023
+ assert.ok(controlShell);
1024
+ assert.ok(controlStage);
1025
+ assert.ok(controlCanvas);
1026
+ assert.equal(document.activeElement, controlShell);
1027
+ const controlStartCalls = dotNetCalls
1028
+ .filter(call => call.methodName === 'StartRemoteFleetLiveStreamFromJs')
1029
+ .slice(liveStartCallsBeforeControl);
1030
+ assert.equal(controlStartCalls.length, 1);
1031
+ assert.equal(controlStartCalls[0].args[0], 'remote-fleet-render-smoke');
1032
+ assert.equal(controlStartCalls[0].args[1], patchTarget.DeviceId);
1033
+ assert.equal(controlStartCalls[0].args[2], 20);
1034
+ const controlSubscribe = diagnostics.webSocketSends
1035
+ .slice(sendCountBeforeControl)
1036
+ .map(send => {
1037
+ try {
1038
+ return JSON.parse(send.payload);
1039
+ } catch {
1040
+ return null;
1041
+ }
1042
+ })
1043
+ .find(message =>
1044
+ message
1045
+ && message.type === 'subscribe'
1046
+ && message.nodeId === 'remote-fleet-render-smoke'
1047
+ && message.autoStartLive === true
1048
+ && message.fps === 20
1049
+ && Array.isArray(message.deviceIds)
1050
+ && message.deviceIds.includes(patchTarget.DeviceId));
1051
+ assert.ok(controlSubscribe, 'control popup should reuse the binary frame WebSocket with a 20fps subscription');
1052
+
1053
+ const controlFrameSeq = 20001;
1054
+ liveWs.onmessage?.({
1055
+ data: new Blob([encodeRemoteBinaryFrame({
1056
+ type: 'remote.frame.binary',
1057
+ deviceId: patchTarget.DeviceId,
1058
+ kind: 'live',
1059
+ frameSeq: controlFrameSeq,
1060
+ streamId: 'render-smoke-control-live',
1061
+ contentHash: `render-smoke-control-live-${controlFrameSeq}`,
1062
+ mimeType: 'image/jpeg',
1063
+ width: 64,
1064
+ height: 36,
1065
+ capturedAt: new Date().toISOString(),
1066
+ receivedAt: new Date().toISOString()
1067
+ })])
1068
+ });
1069
+ await wait(40);
1070
+ assert.equal(controlCanvas.style.display, 'block');
1071
+ assert.ok(
1072
+ document.canvasDrawCalls
1073
+ .slice(drawCountBeforeControl)
1074
+ .some(call => call.canvas === controlCanvas && call.op === 'drawImage'),
1075
+ 'control popup should paint binary WebSocket frames directly to its canvas');
1076
+
1077
+ controlStage.dispatchEvent({
1078
+ type: 'pointerdown',
1079
+ button: 0,
1080
+ pointerId: 7,
1081
+ clientX: 160,
1082
+ clientY: 90
1083
+ });
1084
+ controlStage.dispatchEvent({
1085
+ type: 'pointerup',
1086
+ button: 0,
1087
+ pointerId: 7,
1088
+ clientX: 160,
1089
+ clientY: 90
1090
+ });
1091
+ controlShell.dispatchEvent({
1092
+ type: 'keydown',
1093
+ key: 'A',
1094
+ code: 'KeyA',
1095
+ repeat: false
1096
+ });
1097
+ await wait(20);
1098
+ const inputCalls = dotNetCalls.filter(call => call.methodName === 'SendRemoteFleetInputFromJs');
1099
+ assert.ok(inputCalls.length >= 3, 'control popup should send pointer and keyboard input through JS interop');
1100
+ const pointerDown = inputCalls.find(call => call.args[2]?.type === 'pointerDown');
1101
+ const keyDown = inputCalls.find(call => call.args[2]?.type === 'keyDown');
1102
+ assert.ok(pointerDown);
1103
+ assert.ok(keyDown);
1104
+ assert.equal(pointerDown.args[0], 'remote-fleet-render-smoke');
1105
+ assert.equal(pointerDown.args[1], patchTarget.DeviceId);
1106
+ assert.equal(pointerDown.args[2].button, 'left');
1107
+ assert.ok(pointerDown.args[2].controlLeaseId);
1108
+ assert.ok(pointerDown.args[2].normalizedX >= 0 && pointerDown.args[2].normalizedX <= 1);
1109
+ assert.ok(pointerDown.args[2].normalizedY >= 0 && pointerDown.args[2].normalizedY <= 1);
1110
+ assert.equal(keyDown.args[2].key, 'A');
1111
+ assert.equal(keyDown.args[2].code, 'KeyA');
1112
+ manager.closeRemoteFleetControlPopupForTest('render-smoke');
1113
+ await wait(20);
1114
+ assert.equal(document.body.querySelector('[data-remote-fleet-control-popup="true"]'), null);
1115
+
1000
1116
  const alternateDevice = devices.find(device =>
1001
1117
  device.Connected === true
1002
1118
  && device.DeviceId !== focusedDevice.DeviceId);
@@ -1063,7 +1179,9 @@ try {
1063
1179
  assert.equal(resultPanel, null);
1064
1180
  assert.ok(devices.some(device => /^synthetic-response-/.test(device.LatestTaskResultResponseId)));
1065
1181
  await wait(20);
1066
- const liveStartCalls = dotNetCalls.filter(call => call.methodName === 'StartRemoteFleetLiveStreamFromJs');
1182
+ const liveStartCalls = dotNetCalls
1183
+ .filter(call => call.methodName === 'StartRemoteFleetLiveStreamFromJs')
1184
+ .slice(0, liveStartCallsBeforeControl);
1067
1185
  const subscribeMessages = diagnostics.webSocketSends
1068
1186
  .map(send => {
1069
1187
  try {
@@ -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=20260616-mdm-binary-canvas-v579" />
11
- <link rel="stylesheet" href="_content/MindExecution.Shared/css/mind-map-overrides.css?v=20260616-mdm-binary-canvas-v579" />
10
+ <link rel="stylesheet" href="_content/MindExecution.Shared/css/app.css?v=20260617-mdm-ws-rerender-v580" />
11
+ <link rel="stylesheet" href="_content/MindExecution.Shared/css/mind-map-overrides.css?v=20260617-mdm-ws-rerender-v580" />
12
12
  <!-- ?쇄뼹??Font Awesome (local) ?쇄뼹??-->
13
13
  <link rel="stylesheet" href="_content/MindExecution.Shared/lib/font-awesome/css/all.min.css" />
14
14
  <!-- ?꿎뼯??-->
@@ -579,7 +579,7 @@
579
579
  }
580
580
 
581
581
  const base = '_content/MindExecution.Shared/js/';
582
- const scriptVersion = '20260616-mdm-binary-canvas-v579';
582
+ const scriptVersion = '20260617-mdm-ws-rerender-v580';
583
583
  const scriptUrl = (script) => `${base}${script}?v=${scriptVersion}`;
584
584
  console.log(`[Script Loader] Shared JS version: ${scriptVersion}`);
585
585
  const criticalScripts = [
@@ -1,5 +1,5 @@
1
1
  self.assetsManifest = {
2
- "version": "Q3LEcx0Y",
2
+ "version": "caOR4cJE",
3
3
  "assets": [
4
4
  {
5
5
  "hash": "sha256-+CSYMcqLNTsq3VnH11jgYyOCCdxvHzL74CBmo4sCmMU=",
@@ -834,7 +834,7 @@
834
834
  "url": "image-manifest.json"
835
835
  },
836
836
  {
837
- "hash": "sha256-0O54YE8cYfnYOu/2NbpFuJs/cJRKBw/OAc963M3JI6E=",
837
+ "hash": "sha256-zI55TuKnPpHEJMEolp25Zk/P6dkZEOtbMSHObMgR84A=",
838
838
  "url": "index.html"
839
839
  },
840
840
  {
@@ -1,4 +1,4 @@
1
- /* Manifest version: Q3LEcx0Y */
1
+ /* Manifest version: caOR4cJE */
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