@mindexec/cli 0.2.73 → 0.2.74

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.73",
3
+ "version": "0.2.74",
4
4
  "description": "MindExec local runtime and bridge CLI",
5
5
  "main": "server.js",
6
6
  "type": "module",
@@ -715,6 +715,10 @@ try {
715
715
  assert.ok(bodyChildOrder.endsWith('remoteFleetStatusRail'), bodyChildOrder);
716
716
  assert.ok(statusFooter.style.cssText.includes('flex-direction: row'));
717
717
  assert.ok(statusFooter.style.cssText.includes('justify-content: flex-end'));
718
+ const sizeControls = statusFooter.querySelector('[data-remote-fleet-size-controls="true"]');
719
+ assert.ok(sizeControls);
720
+ assert.equal(sizeControls.querySelector('[data-remote-fleet-action="monitor-size-down"]')?.textContent, '-');
721
+ assert.equal(sizeControls.querySelector('[data-remote-fleet-action="monitor-size-up"]')?.textContent, '+');
718
722
  assert.match(statusFooter.style.cssText, /box-sizing:\s*border-box;/);
719
723
  assert.equal(statusFooter.querySelectorAll('[data-remote-fleet-status-item]').length, 5);
720
724
  assert.ok(statusFooter.querySelector('[data-remote-fleet-status-item="route"]'));
@@ -733,6 +737,14 @@ try {
733
737
  assert.ok(initialDetailPanel?.textContent.includes('Load'));
734
738
  assert.ok(cards[0]?.querySelector('[data-remote-fleet-device-preview="tile"]'));
735
739
  assert.equal(/\b(Seen|Uptime|Mem|Load)\b/.test(cards[0]?.textContent || ''), false);
740
+ assert.match(deviceGrid.style.cssText, /minmax\(132px,\s*1fr\)/);
741
+ sizeControls.querySelector('[data-remote-fleet-action="monitor-size-up"]').dispatchEvent({ type: 'click' });
742
+ assert.equal(bodyView.dataset.remoteFleetDensity, 'large');
743
+ assert.match(bodyView.querySelector('[data-remote-fleet-device-grid="true"]')?.style.cssText || '', /minmax\(168px,\s*1fr\)/);
744
+ bodyView.querySelector('[data-remote-fleet-action="monitor-size-down"]').dispatchEvent({ type: 'click' });
745
+ assert.equal(bodyView.dataset.remoteFleetDensity, 'cards');
746
+ assert.match(bodyView.querySelector('[data-remote-fleet-device-grid="true"]')?.style.cssText || '', /minmax\(132px,\s*1fr\)/);
747
+ cards = bodyView.querySelectorAll('article[data-device-id]');
736
748
  const patchTarget = devices.find(device => device.ThumbnailEnabled === true && device.LiveStreamActive !== true);
737
749
  assert.ok(patchTarget);
738
750
  const patchCard = Array.from(cards).find(card => card.dataset.deviceId === patchTarget.DeviceId);
@@ -3429,6 +3429,12 @@
3429
3429
  const REMOTE_FLEET_MONITOR_TILE_GAP_PX = 8;
3430
3430
  const REMOTE_FLEET_EMPTY_SCREEN_MIN_WIDTH = 132;
3431
3431
  const REMOTE_FLEET_EMPTY_SCREEN_MIN_HEIGHT = 72;
3432
+ const REMOTE_FLEET_MONITOR_SIZE_LEVELS = Object.freeze(['dense', 'cards', 'large']);
3433
+ const REMOTE_FLEET_MONITOR_TILE_METRICS = Object.freeze({
3434
+ dense: Object.freeze({ tileMinWidth: 104, tileMinHeight: 66, emptyMinWidth: 104, emptyMinHeight: 58 }),
3435
+ cards: Object.freeze({ tileMinWidth: 132, tileMinHeight: 84, emptyMinWidth: 132, emptyMinHeight: 72 }),
3436
+ large: Object.freeze({ tileMinWidth: 168, tileMinHeight: 106, emptyMinWidth: 168, emptyMinHeight: 94 })
3437
+ });
3432
3438
  const AUTOMATION_NODE_KIND_METADATA_KEY = 'AutomationNodeKind';
3433
3439
  const AUTOMATION_NODE_LABEL_METADATA_KEY = 'AutomationNodeLabel';
3434
3440
  const AUTOMATION_NODE_DESCRIPTION_METADATA_KEY = 'AutomationNodeDescription';
@@ -12504,7 +12510,72 @@
12504
12510
  return item;
12505
12511
  }
12506
12512
 
12507
- function createRemoteFleetStatusRail(items, errorMessage = '') {
12513
+ function normalizeRemoteFleetMonitorSize(value) {
12514
+ const normalized = String(value || '').trim().toLowerCase();
12515
+ return REMOTE_FLEET_MONITOR_SIZE_LEVELS.includes(normalized)
12516
+ ? normalized
12517
+ : 'cards';
12518
+ }
12519
+
12520
+ function getRemoteFleetMonitorSizeIndex(value) {
12521
+ return Math.max(0, REMOTE_FLEET_MONITOR_SIZE_LEVELS.indexOf(normalizeRemoteFleetMonitorSize(value)));
12522
+ }
12523
+
12524
+ function getRemoteFleetTileMetrics(value) {
12525
+ const size = normalizeRemoteFleetMonitorSize(value);
12526
+ return REMOTE_FLEET_MONITOR_TILE_METRICS[size] || REMOTE_FLEET_MONITOR_TILE_METRICS.cards;
12527
+ }
12528
+
12529
+ function createRemoteFleetMonitorSizeControls(sizeState) {
12530
+ const sizeIndex = getRemoteFleetMonitorSizeIndex(sizeState);
12531
+ const controls = document.createElement('div');
12532
+ controls.dataset.remoteFleetSizeControls = 'true';
12533
+ controls.style.cssText = `
12534
+ flex: 0 0 auto;
12535
+ display: inline-flex;
12536
+ align-items: center;
12537
+ gap: 4px;
12538
+ margin-right: auto;
12539
+ min-width: 0;
12540
+ pointer-events: auto;
12541
+ `;
12542
+
12543
+ const createButton = (label, title, action, disabled) => {
12544
+ const button = document.createElement('button');
12545
+ button.type = 'button';
12546
+ button.dataset.remoteFleetAction = action;
12547
+ button.textContent = label;
12548
+ button.title = title;
12549
+ button.setAttribute('aria-label', title);
12550
+ button.disabled = disabled === true;
12551
+ button.style.cssText = `
12552
+ flex: 0 0 24px;
12553
+ width: 24px;
12554
+ height: 22px;
12555
+ display: inline-flex;
12556
+ align-items: center;
12557
+ justify-content: center;
12558
+ padding: 0;
12559
+ border-radius: 999px;
12560
+ border: 1px solid rgba(148, 163, 184, 0.24);
12561
+ background: ${disabled ? 'rgba(241, 245, 249, 0.70)' : 'rgba(255, 255, 255, 0.92)'};
12562
+ color: ${disabled ? '#94a3b8' : '#0f172a'};
12563
+ font-size: 13px;
12564
+ font-weight: 950;
12565
+ line-height: 1;
12566
+ letter-spacing: 0;
12567
+ cursor: ${disabled ? 'default' : 'pointer'};
12568
+ pointer-events: ${disabled ? 'none' : 'auto'};
12569
+ `;
12570
+ return button;
12571
+ };
12572
+
12573
+ controls.appendChild(createButton('-', 'Smaller screens', 'monitor-size-down', sizeIndex <= 0));
12574
+ controls.appendChild(createButton('+', 'Larger screens', 'monitor-size-up', sizeIndex >= REMOTE_FLEET_MONITOR_SIZE_LEVELS.length - 1));
12575
+ return controls;
12576
+ }
12577
+
12578
+ function createRemoteFleetStatusRail(items, errorMessage = '', leadingControl = null) {
12508
12579
  const rail = document.createElement('aside');
12509
12580
  rail.dataset.remoteFleetStatusRail = 'true';
12510
12581
  rail.style.cssText = `
@@ -12527,6 +12598,10 @@
12527
12598
  background: rgba(255, 255, 255, 0.70);
12528
12599
  `;
12529
12600
 
12601
+ if (leadingControl) {
12602
+ rail.appendChild(leadingControl);
12603
+ }
12604
+
12530
12605
  const normalizedError = String(errorMessage || '').trim();
12531
12606
  if (normalizedError) {
12532
12607
  const error = document.createElement('div');
@@ -12785,17 +12860,19 @@
12785
12860
  return titleActions;
12786
12861
  }
12787
12862
 
12788
- function getRemoteFleetEmptyScreenCount(nodeModel) {
12863
+ function getRemoteFleetEmptyScreenCount(nodeModel, sizeState = 'cards') {
12864
+ const metrics = getRemoteFleetTileMetrics(sizeState);
12789
12865
  const width = Number(nodeModel?.width ?? nodeModel?.Width ?? 960);
12790
12866
  const height = Number(nodeModel?.height ?? nodeModel?.Height ?? 620);
12791
12867
  const usableWidth = Number.isFinite(width) ? Math.max(360, width - 44) : 916;
12792
12868
  const usableHeight = Number.isFinite(height) ? Math.max(260, height - 128) : 492;
12793
- const columns = Math.max(3, Math.floor((usableWidth + REMOTE_FLEET_MONITOR_TILE_GAP_PX) / (REMOTE_FLEET_EMPTY_SCREEN_MIN_WIDTH + REMOTE_FLEET_MONITOR_TILE_GAP_PX)));
12794
- const rows = Math.max(3, Math.ceil((usableHeight + REMOTE_FLEET_MONITOR_TILE_GAP_PX) / (REMOTE_FLEET_EMPTY_SCREEN_MIN_HEIGHT + REMOTE_FLEET_MONITOR_TILE_GAP_PX)));
12869
+ const columns = Math.max(3, Math.floor((usableWidth + REMOTE_FLEET_MONITOR_TILE_GAP_PX) / (metrics.emptyMinWidth + REMOTE_FLEET_MONITOR_TILE_GAP_PX)));
12870
+ const rows = Math.max(3, Math.ceil((usableHeight + REMOTE_FLEET_MONITOR_TILE_GAP_PX) / (metrics.emptyMinHeight + REMOTE_FLEET_MONITOR_TILE_GAP_PX)));
12795
12871
  return Math.max(12, Math.min(80, columns * rows));
12796
12872
  }
12797
12873
 
12798
- function createRemoteFleetEmptyScreens(nodeModel) {
12874
+ function createRemoteFleetEmptyScreens(nodeModel, sizeState = 'cards') {
12875
+ const metrics = getRemoteFleetTileMetrics(sizeState);
12799
12876
  const shell = document.createElement('section');
12800
12877
  shell.dataset.remoteFleetEmptyScreens = 'true';
12801
12878
  shell.style.cssText = `
@@ -12804,7 +12881,7 @@
12804
12881
  overflow-y: auto;
12805
12882
  overflow-x: hidden;
12806
12883
  display: grid;
12807
- grid-template-columns: repeat(auto-fill, minmax(${REMOTE_FLEET_EMPTY_SCREEN_MIN_WIDTH}px, 1fr));
12884
+ grid-template-columns: repeat(auto-fill, minmax(${metrics.emptyMinWidth}px, 1fr));
12808
12885
  grid-auto-rows: max-content;
12809
12886
  align-content: start;
12810
12887
  align-items: start;
@@ -12819,7 +12896,7 @@
12819
12896
  padding: 2px 4px 6px 4px;
12820
12897
  `;
12821
12898
 
12822
- const screenCount = getRemoteFleetEmptyScreenCount(nodeModel);
12899
+ const screenCount = getRemoteFleetEmptyScreenCount(nodeModel, sizeState);
12823
12900
  for (let index = 0; index < screenCount; index += 1) {
12824
12901
  const screen = document.createElement('div');
12825
12902
  screen.dataset.remoteFleetEmptyScreen = 'true';
@@ -12827,7 +12904,7 @@
12827
12904
  width: 100%;
12828
12905
  height: auto;
12829
12906
  aspect-ratio: 16 / 9;
12830
- min-height: ${REMOTE_FLEET_EMPTY_SCREEN_MIN_HEIGHT}px;
12907
+ min-height: ${metrics.emptyMinHeight}px;
12831
12908
  box-sizing: border-box;
12832
12909
  border-radius: 8px;
12833
12910
  border: 1px solid rgba(203, 213, 225, 0.72);
@@ -14921,7 +14998,7 @@
14921
14998
  const filterState = bodyView.dataset.remoteFleetFilter || 'all';
14922
14999
  const sortState = bodyView.dataset.remoteFleetSort || 'status';
14923
15000
  const groupState = bodyView.dataset.remoteFleetGroup || 'none';
14924
- const densityState = bodyView.dataset.remoteFleetDensity || 'cards';
15001
+ const densityState = normalizeRemoteFleetMonitorSize(bodyView.dataset.remoteFleetDensity || 'cards');
14925
15002
  const aiAssistState = bodyView.dataset.remoteFleetAiAssist === 'true';
14926
15003
  const autoMonitorState = bodyView.dataset.remoteFleetAutoMonitor !== 'false';
14927
15004
  const focusState = bodyView.dataset.remoteFleetFocusDeviceId || '';
@@ -14982,6 +15059,7 @@
14982
15059
 
14983
15060
  bodyView.dataset.src = `remote-fleet:${refreshedAt}:${devices.length}:${connected}`;
14984
15061
  bodyView.dataset.remoteFleetHostState = hostTargetState;
15062
+ bodyView.dataset.remoteFleetDensity = densityState;
14985
15063
  bodyView.classList.add('map-node-remote-fleet__body');
14986
15064
  bodyView.innerHTML = '';
14987
15065
  bodyView.style.cssText = `
@@ -15042,7 +15120,7 @@
15042
15120
  tone: routeInfo.tone,
15043
15121
  title: routeInfo.title
15044
15122
  }
15045
- ], lastError);
15123
+ ], lastError, createRemoteFleetMonitorSizeControls(densityState));
15046
15124
 
15047
15125
  const filterRow = document.createElement('div');
15048
15126
  filterRow.style.cssText = `
@@ -15104,8 +15182,9 @@
15104
15182
  ], groupState, 'Device grouping');
15105
15183
 
15106
15184
  const densitySelect = createRemoteFleetSelect([
15185
+ { value: 'dense', label: 'Dense' },
15107
15186
  { value: 'cards', label: 'Cards' },
15108
- { value: 'dense', label: 'Dense' }
15187
+ { value: 'large', label: 'Large' }
15109
15188
  ], densityState, 'Device density');
15110
15189
 
15111
15190
  const matchCount = document.createElement('div');
@@ -15815,8 +15894,9 @@
15815
15894
  return panel;
15816
15895
  };
15817
15896
 
15818
- const tileMinWidth = densityState === 'dense' ? 104 : 132;
15819
- const tileMinHeight = densityState === 'dense' ? 66 : 84;
15897
+ const tileMetrics = getRemoteFleetTileMetrics(densityState);
15898
+ const tileMinWidth = tileMetrics.tileMinWidth;
15899
+ const tileMinHeight = tileMetrics.tileMinHeight;
15820
15900
  const tileGap = REMOTE_FLEET_MONITOR_TILE_GAP_PX;
15821
15901
 
15822
15902
  const monitorWorkspace = document.createElement('div');
@@ -16011,7 +16091,7 @@
16011
16091
  if (devices.length === 0) {
16012
16092
  monitorWorkspace.style.display = 'flex';
16013
16093
  monitorWorkspace.style.flexDirection = 'column';
16014
- monitorWorkspace.appendChild(createRemoteFleetEmptyScreens(nodeModel));
16094
+ monitorWorkspace.appendChild(createRemoteFleetEmptyScreens(nodeModel, densityState));
16015
16095
  } else {
16016
16096
  monitorWorkspace.appendChild(grid);
16017
16097
  monitorWorkspace.appendChild(createSelectedDevicePanel(selectedDevice));
@@ -16423,6 +16503,34 @@
16423
16503
  await setRemoteFleetHostTarget(true);
16424
16504
  });
16425
16505
 
16506
+ const setRemoteFleetMonitorSize = direction => {
16507
+ const currentIndex = getRemoteFleetMonitorSizeIndex(bodyView.dataset.remoteFleetDensity || densityState);
16508
+ const nextIndex = Math.max(
16509
+ 0,
16510
+ Math.min(REMOTE_FLEET_MONITOR_SIZE_LEVELS.length - 1, currentIndex + direction));
16511
+ if (nextIndex === currentIndex) {
16512
+ return;
16513
+ }
16514
+
16515
+ bodyView.dataset.remoteFleetDensity = REMOTE_FLEET_MONITOR_SIZE_LEVELS[nextIndex];
16516
+ renderRemoteFleetMonitor(bodyView, nodeModel);
16517
+ };
16518
+
16519
+ bodyView.querySelectorAll('[data-remote-fleet-action]').forEach(button => {
16520
+ const action = String(button.dataset.remoteFleetAction || '');
16521
+ if (action !== 'monitor-size-down' && action !== 'monitor-size-up') {
16522
+ return;
16523
+ }
16524
+ ['mousedown', 'mouseup', 'click', 'dblclick', 'keydown'].forEach(eventName => {
16525
+ button.addEventListener(eventName, event => event.stopPropagation());
16526
+ });
16527
+ button.addEventListener('click', event => {
16528
+ event.preventDefault();
16529
+ event.stopPropagation();
16530
+ setRemoteFleetMonitorSize(action === 'monitor-size-up' ? 1 : -1);
16531
+ });
16532
+ });
16533
+
16426
16534
  bodyView.querySelectorAll('[data-remote-fleet-action="pin-device"]').forEach(button => {
16427
16535
  button.addEventListener('click', async event => {
16428
16536
  event.preventDefault();
@@ -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-monitor-no-stop-v528" />
11
- <link rel="stylesheet" href="_content/MindExecution.Shared/css/mind-map-overrides.css?v=20260614-remote-monitor-no-stop-v528" />
10
+ <link rel="stylesheet" href="_content/MindExecution.Shared/css/app.css?v=20260614-remote-monitor-size-controls-v529" />
11
+ <link rel="stylesheet" href="_content/MindExecution.Shared/css/mind-map-overrides.css?v=20260614-remote-monitor-size-controls-v529" />
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 = '20260614-remote-monitor-no-stop-v528';
582
+ const scriptVersion = '20260614-remote-monitor-size-controls-v529';
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": "d4LRzdfE",
2
+ "version": "D4Pf0guw",
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-DjKISYGUi+3HQOa9MQJYjRG1GbKw9oubNALH0YjyDzU=",
89
+ "hash": "sha256-hzl6gNvjb9faAA2tUeCfriNvdohhGaDtasnYOCMum7E=",
90
90
  "url": "_content/MindExecution.Shared/js/mind-map-css3d-manager.js"
91
91
  },
92
92
  {
@@ -834,7 +834,7 @@
834
834
  "url": "image-manifest.json"
835
835
  },
836
836
  {
837
- "hash": "sha256-0kYKq5leJEhEiWAGy8flD4R+Ip+L1HNwLTpiz9XKKbc=",
837
+ "hash": "sha256-6okf9Y0Fpz1uWtjB0xMwIlfltrQLSgbPn8PBj3QW/5Y=",
838
838
  "url": "index.html"
839
839
  },
840
840
  {
@@ -1,4 +1,4 @@
1
- /* Manifest version: d4LRzdfE */
1
+ /* Manifest version: D4Pf0guw */
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