@qodalis/vue-cli 2.0.0-beta.11 → 2.0.0-beta.12

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/dist/index.mjs CHANGED
@@ -129,6 +129,7 @@ import {
129
129
  ref as ref2,
130
130
  computed,
131
131
  inject as inject2,
132
+ watch,
132
133
  h as h2,
133
134
  onMounted as onMounted2,
134
135
  onBeforeUnmount as onBeforeUnmount2
@@ -285,7 +286,7 @@ var CliPanel = defineComponent3({
285
286
  ],
286
287
  setup(props, { expose, emit }) {
287
288
  const config = inject2(CliConfigKey, null);
288
- const mergedOptions = computed(() => props.options ?? config?.options);
289
+ const mergedOptions = computed(() => props.options ? { ...config?.options, ...props.options } : config?.options);
289
290
  const mergedModules = computed(() => props.modules ?? config?.modules);
290
291
  const mergedProcessors = computed(() => props.processors ?? config?.processors);
291
292
  const mergedServices = computed(() => props.services ?? config?.services);
@@ -367,6 +368,107 @@ var CliPanel = defineComponent3({
367
368
  };
368
369
  const panelResizing = ref2(false);
369
370
  let panelResizeState = { startY: 0, startHeight: 0, startX: 0, startWidth: 0 };
371
+ const statusExecutionState = ref2("idle");
372
+ const statusLastCommand = ref2(null);
373
+ const statusServiceCount = ref2({ running: 0, total: 0 });
374
+ const statusServiceDetails = ref2([]);
375
+ const statusServerState = ref2("none");
376
+ const statusServerDetails = ref2([]);
377
+ const statusUptime = ref2(0);
378
+ const statusText = ref2(null);
379
+ const servicesDropdownOpen = ref2(false);
380
+ const serversDropdownOpen = ref2(false);
381
+ const servicesDropdownTriggerRect = ref2(null);
382
+ const serversDropdownTriggerRect = ref2(null);
383
+ const formattedUptime = computed(() => {
384
+ const mins = Math.floor(statusUptime.value / 6e4);
385
+ if (mins < 60) return `${mins}m`;
386
+ const hrs = Math.floor(mins / 60);
387
+ return `${hrs}h${mins % 60}m`;
388
+ });
389
+ let execPollTimer;
390
+ let globalPollTimer;
391
+ function startStatusPolling() {
392
+ stopStatusPolling();
393
+ execPollTimer = setInterval(() => {
394
+ const tab = tabs.value.find((t) => t.id === resolvedActiveTabId.value);
395
+ if (!tab) return;
396
+ const engine = engineMap.get(tab.panes[0]?.id);
397
+ if (!engine) return;
398
+ const context = engine.getContext();
399
+ if (!context) return;
400
+ const running = !!context.isExecuting || !!context.contextProcessor;
401
+ statusExecutionState.value = running ? "running" : "idle";
402
+ const result = context.lastCommandResult;
403
+ statusLastCommand.value = result ? { name: result.command, success: result.success } : null;
404
+ const text = context.getStatusText?.();
405
+ statusText.value = text || null;
406
+ }, 300);
407
+ globalPollTimer = setInterval(() => {
408
+ const tab = tabs.value.find((t) => t.id === resolvedActiveTabId.value);
409
+ if (!tab) return;
410
+ const engine = engineMap.get(tab.panes[0]?.id);
411
+ if (!engine) return;
412
+ const context = engine.getContext();
413
+ if (!context) return;
414
+ try {
415
+ const services = context.backgroundServices?.list() ?? [];
416
+ statusServiceCount.value = { running: services.filter((s) => s.status === "running").length, total: services.length };
417
+ statusServiceDetails.value = services.map((s) => ({ name: s.name, status: s.status, description: s.description }));
418
+ } catch {
419
+ }
420
+ try {
421
+ const serverManager = context.services?.get?.("cli-server-manager");
422
+ const details = [];
423
+ if (serverManager?.connections?.size > 0) {
424
+ let anyConnected = false;
425
+ for (const [name, conn] of serverManager.connections) {
426
+ if (conn.connected) anyConnected = true;
427
+ details.push({
428
+ name,
429
+ url: conn.config?.url ?? "",
430
+ connected: !!conn.connected,
431
+ apiVersion: conn.connected ? conn.apiVersion : void 0,
432
+ commandCount: conn.connected ? conn.commands?.length : void 0
433
+ });
434
+ }
435
+ statusServerState.value = anyConnected ? "connected" : "disconnected";
436
+ } else {
437
+ const configuredServers = engine.options?.servers;
438
+ if (Array.isArray(configuredServers) && configuredServers.length > 0) {
439
+ for (const srv of configuredServers) {
440
+ if (srv.enabled === false) continue;
441
+ details.push({
442
+ name: srv.name,
443
+ url: srv.url ?? "",
444
+ connected: false
445
+ });
446
+ }
447
+ statusServerState.value = "disconnected";
448
+ } else {
449
+ statusServerState.value = "none";
450
+ }
451
+ }
452
+ statusServerDetails.value = details;
453
+ } catch {
454
+ }
455
+ statusUptime.value = engine.startedAt ? Date.now() - engine.startedAt : 0;
456
+ }, 2e3);
457
+ }
458
+ function stopStatusPolling() {
459
+ if (execPollTimer) {
460
+ clearInterval(execPollTimer);
461
+ execPollTimer = void 0;
462
+ }
463
+ if (globalPollTimer) {
464
+ clearInterval(globalPollTimer);
465
+ globalPollTimer = void 0;
466
+ }
467
+ }
468
+ watch(initialized, (val) => {
469
+ if (val) startStatusPolling();
470
+ else stopStatusPolling();
471
+ });
370
472
  function addTab(title) {
371
473
  const tabId = nextTabId++;
372
474
  const paneId = nextPaneId++;
@@ -443,6 +545,10 @@ var CliPanel = defineComponent3({
443
545
  tabs.value = tabs.value.map((t) => {
444
546
  if (t.id !== targetTabId) return t;
445
547
  const newPanes = [...t.panes, { id: paneId, widthPercent: 0 }];
548
+ const evenWidth = 100 / newPanes.length;
549
+ newPanes.forEach((p) => {
550
+ p.widthPercent = evenWidth;
551
+ });
446
552
  normalizePanes(newPanes);
447
553
  return { ...t, panes: newPanes };
448
554
  });
@@ -585,6 +691,7 @@ var CliPanel = defineComponent3({
585
691
  onBeforeUnmount2(() => {
586
692
  document.removeEventListener("mousemove", onPaneResizeMove);
587
693
  document.removeEventListener("mouseup", onPaneResizeEnd);
694
+ stopStatusPolling();
588
695
  });
589
696
  function toggleMaximize() {
590
697
  if (!resolvedMaximized.value) {
@@ -620,6 +727,8 @@ var CliPanel = defineComponent3({
620
727
  const positionDropdownOpen = ref2(false);
621
728
  function closePositionDropdown() {
622
729
  positionDropdownOpen.value = false;
730
+ servicesDropdownOpen.value = false;
731
+ serversDropdownOpen.value = false;
623
732
  }
624
733
  function togglePositionDropdown(e) {
625
734
  e.stopPropagation();
@@ -746,6 +855,54 @@ var CliPanel = defineComponent3({
746
855
  ]),
747
856
  "CLI"
748
857
  ]),
858
+ // Status indicators (bottom/top only)
859
+ resolvedPosition.value === "bottom" || resolvedPosition.value === "top" ? h2("div", { class: "cli-panel-status-indicators" }, [
860
+ // Execution state
861
+ h2("span", { class: ["cli-panel-status-item", statusExecutionState.value === "running" ? "status-running" : ""].filter(Boolean).join(" ") }, [
862
+ h2("span", { class: ["cli-panel-status-dot", statusExecutionState.value === "running" ? "dot-running" : "dot-idle"].join(" ") }),
863
+ h2("span", { class: "cli-panel-status-label" }, statusExecutionState.value)
864
+ ]),
865
+ // Background services
866
+ statusServiceCount.value.total > 0 ? h2("span", {
867
+ class: "cli-panel-status-item status-clickable",
868
+ onClick: (e) => {
869
+ e.stopPropagation();
870
+ servicesDropdownTriggerRect.value = e.currentTarget.getBoundingClientRect();
871
+ servicesDropdownOpen.value = !servicesDropdownOpen.value;
872
+ serversDropdownOpen.value = false;
873
+ }
874
+ }, [
875
+ h2("span", { class: "cli-panel-status-icon", innerHTML: "&#9881;" }),
876
+ h2("span", { class: "cli-panel-status-label" }, `${statusServiceCount.value.running}/${statusServiceCount.value.total} services`)
877
+ ]) : null,
878
+ // Last command
879
+ statusLastCommand.value ? h2("span", { class: "cli-panel-status-item" }, [
880
+ h2("span", { class: ["cli-panel-status-icon", statusLastCommand.value.success ? "status-success" : "status-error"].join(" "), innerHTML: statusLastCommand.value.success ? "&#10003;" : "&#10005;" }),
881
+ h2("span", { class: "cli-panel-status-label" }, statusLastCommand.value.name)
882
+ ]) : null,
883
+ // Server connection
884
+ statusServerState.value !== "none" ? h2("span", {
885
+ class: "cli-panel-status-item status-clickable",
886
+ onClick: (e) => {
887
+ e.stopPropagation();
888
+ serversDropdownTriggerRect.value = e.currentTarget.getBoundingClientRect();
889
+ serversDropdownOpen.value = !serversDropdownOpen.value;
890
+ servicesDropdownOpen.value = false;
891
+ }
892
+ }, [
893
+ h2("span", { class: ["cli-panel-status-dot", statusServerState.value === "connected" ? "dot-idle" : "dot-error"].join(" ") }),
894
+ h2("span", { class: "cli-panel-status-label" }, `${statusServerDetails.value.filter((s) => s.connected).length}/${statusServerDetails.value.length} servers`)
895
+ ]) : null,
896
+ // Uptime
897
+ statusUptime.value > 0 ? h2("span", { class: "cli-panel-status-item status-muted" }, [
898
+ h2("span", { class: "cli-panel-status-icon", innerHTML: "&uarr;" }),
899
+ h2("span", { class: "cli-panel-status-label" }, formattedUptime.value)
900
+ ]) : null,
901
+ // Custom status text
902
+ statusText.value ? h2("span", { class: "cli-panel-status-item status-text" }, [
903
+ h2("span", { class: "cli-panel-status-label" }, statusText.value)
904
+ ]) : null
905
+ ].filter(Boolean)) : null,
749
906
  h2("div", { class: "cli-panel-action-buttons" }, [
750
907
  h2("div", {
751
908
  class: "cli-panel-btn-position-wrapper",
@@ -804,7 +961,8 @@ var CliPanel = defineComponent3({
804
961
  [closeIcon()]
805
962
  ) : null
806
963
  ])
807
- ])
964
+ ]),
965
+ h2("div", { class: ["cli-panel-glow-line", statusExecutionState.value === "running" ? "glow-active" : ""].filter(Boolean).join(" ") })
808
966
  ]);
809
967
  const contentEl = initialized.value ? h2("div", { class: "cli-panel-content", style: resolvedCollapsed.value ? { display: "none" } : void 0 }, [
810
968
  // Tab bar
@@ -857,6 +1015,12 @@ var CliPanel = defineComponent3({
857
1015
  onDblclick: (e) => e.stopPropagation()
858
1016
  })
859
1017
  ] : [
1018
+ h2("span", { class: ["cli-panel-tab-dot", (() => {
1019
+ if (tab.id !== resolvedActiveTabId.value) return "dot-idle";
1020
+ if (statusExecutionState.value === "running") return "dot-running";
1021
+ if (statusLastCommand.value && !statusLastCommand.value.success) return "dot-error";
1022
+ return "dot-idle";
1023
+ })()].join(" ") }),
860
1024
  h2(
861
1025
  "span",
862
1026
  {
@@ -887,7 +1051,7 @@ var CliPanel = defineComponent3({
887
1051
  {
888
1052
  class: "cli-panel-add-tab",
889
1053
  title: "New terminal",
890
- onClick: addTab
1054
+ onClick: () => addTab()
891
1055
  },
892
1056
  "+"
893
1057
  )
@@ -1138,6 +1302,62 @@ var CliPanel = defineComponent3({
1138
1302
  h2("span", { class: "cli-panel-hide-tab-label" }, "CLI"),
1139
1303
  hideTabChevron(resolvedPosition.value)
1140
1304
  ]) : null;
1305
+ const servicesDropdownEl = servicesDropdownOpen.value && statusServiceCount.value.total > 0 ? h2("div", {
1306
+ class: "cli-panel-services-dropdown",
1307
+ style: (() => {
1308
+ const rect = servicesDropdownTriggerRect.value;
1309
+ if (!rect) return {};
1310
+ return resolvedPosition.value === "top" ? { position: "fixed", top: `${rect.bottom + 4}px`, left: `${rect.left}px`, zIndex: 1100 } : { position: "fixed", bottom: `${window.innerHeight - rect.top + 4}px`, left: `${rect.left}px`, zIndex: 1100 };
1311
+ })(),
1312
+ onClick: (e) => e.stopPropagation()
1313
+ }, [
1314
+ h2("div", { class: "cli-panel-services-dropdown-header" }, "Background Services"),
1315
+ h2(
1316
+ "div",
1317
+ { class: "cli-panel-services-dropdown-list" },
1318
+ statusServiceDetails.value.map(
1319
+ (svc, i) => h2("div", { key: i, class: "cli-panel-services-dropdown-item" }, [
1320
+ h2("span", { class: ["cli-panel-svc-dot", svc.status === "running" ? "svc-running" : "svc-stopped"].join(" ") }),
1321
+ h2("div", { class: "cli-panel-svc-info" }, [
1322
+ h2("span", { class: "cli-panel-svc-name" }, svc.name),
1323
+ svc.description ? h2("span", { class: "cli-panel-svc-desc" }, svc.description) : null
1324
+ ].filter(Boolean)),
1325
+ h2("span", { class: "cli-panel-svc-status" }, svc.status)
1326
+ ])
1327
+ )
1328
+ ),
1329
+ statusServiceDetails.value.length === 0 ? h2("div", { class: "cli-panel-services-dropdown-empty" }, "No services registered") : null
1330
+ ].filter(Boolean)) : null;
1331
+ const serversDropdownEl = serversDropdownOpen.value && statusServerState.value !== "none" ? h2("div", {
1332
+ class: "cli-panel-services-dropdown",
1333
+ style: (() => {
1334
+ const rect = serversDropdownTriggerRect.value;
1335
+ if (!rect) return {};
1336
+ return resolvedPosition.value === "top" ? { position: "fixed", top: `${rect.bottom + 4}px`, left: `${rect.left}px`, zIndex: 1100 } : { position: "fixed", bottom: `${window.innerHeight - rect.top + 4}px`, left: `${rect.left}px`, zIndex: 1100 };
1337
+ })(),
1338
+ onClick: (e) => e.stopPropagation()
1339
+ }, [
1340
+ h2("div", { class: "cli-panel-services-dropdown-header" }, "Server Connections"),
1341
+ h2(
1342
+ "div",
1343
+ { class: "cli-panel-services-dropdown-list" },
1344
+ statusServerDetails.value.map(
1345
+ (srv, i) => h2("div", { key: i, class: "cli-panel-services-dropdown-item" }, [
1346
+ h2("span", { class: ["cli-panel-svc-dot", srv.connected ? "svc-running" : "svc-stopped"].join(" ") }),
1347
+ h2("div", { class: "cli-panel-svc-info" }, [
1348
+ h2("span", { class: "cli-panel-svc-name" }, srv.name),
1349
+ srv.url ? h2("span", { class: "cli-panel-svc-desc" }, srv.url) : null
1350
+ ].filter(Boolean)),
1351
+ h2("div", { class: "cli-panel-srv-meta" }, [
1352
+ h2("span", { class: "cli-panel-svc-status" }, srv.connected ? "connected" : "disconnected"),
1353
+ srv.apiVersion ? h2("span", { class: "cli-panel-svc-desc" }, `v${srv.apiVersion}`) : null,
1354
+ srv.commandCount ? h2("span", { class: "cli-panel-svc-desc" }, `${srv.commandCount} cmds`) : null
1355
+ ].filter(Boolean))
1356
+ ])
1357
+ )
1358
+ ),
1359
+ statusServerDetails.value.length === 0 ? h2("div", { class: "cli-panel-services-dropdown-empty" }, "No servers configured") : null
1360
+ ].filter(Boolean)) : null;
1141
1361
  return h2("div", {}, [
1142
1362
  hideTabEl,
1143
1363
  h2(
@@ -1152,7 +1372,9 @@ var CliPanel = defineComponent3({
1152
1372
  },
1153
1373
  [headerEl, contentEl]
1154
1374
  ),
1155
- contextMenuEl
1375
+ contextMenuEl,
1376
+ servicesDropdownEl,
1377
+ serversDropdownEl
1156
1378
  ]);
1157
1379
  };
1158
1380
  }