@qodalis/react-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.js +232 -2
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +232 -2
- package/dist/index.mjs.map +1 -1
- package/dist/package.json +1 -1
- package/package.json +3 -3
package/dist/index.mjs
CHANGED
|
@@ -207,7 +207,7 @@ var CliPanel = React3.forwardRef(
|
|
|
207
207
|
function CliPanel2(props, ref) {
|
|
208
208
|
const { options: optionsProp, modules: modulesProp, processors: processorsProp, services: servicesProp, onClose, style, className } = props;
|
|
209
209
|
const config = useCliConfig();
|
|
210
|
-
const options = optionsProp
|
|
210
|
+
const options = optionsProp ? { ...config.options, ...optionsProp } : config.options;
|
|
211
211
|
const modules = modulesProp ?? config.modules;
|
|
212
212
|
const processors = processorsProp ?? config.processors;
|
|
213
213
|
const services = servicesProp ?? config.services;
|
|
@@ -282,6 +282,18 @@ var CliPanel = React3.forwardRef(
|
|
|
282
282
|
const panelResizeRef = useRef3({ startY: 0, startHeight: 0, startX: 0, startWidth: 0 });
|
|
283
283
|
const prevHeightRef = useRef3(600);
|
|
284
284
|
const prevWidthRef = useRef3(400);
|
|
285
|
+
const [statusExecutionState, setStatusExecutionState] = useState2("idle");
|
|
286
|
+
const [statusLastCommand, setStatusLastCommand] = useState2(null);
|
|
287
|
+
const [statusServiceCount, setStatusServiceCount] = useState2({ running: 0, total: 0 });
|
|
288
|
+
const [statusServiceDetails, setStatusServiceDetails] = useState2([]);
|
|
289
|
+
const [statusServerState, setStatusServerState] = useState2("none");
|
|
290
|
+
const [statusServerDetails, setStatusServerDetails] = useState2([]);
|
|
291
|
+
const [statusUptime, setStatusUptime] = useState2(0);
|
|
292
|
+
const [statusText, setStatusText] = useState2(null);
|
|
293
|
+
const [servicesDropdownOpen, setServicesDropdownOpen] = useState2(false);
|
|
294
|
+
const [serversDropdownOpen, setServersDropdownOpen] = useState2(false);
|
|
295
|
+
const servicesDropdownRef = useRef3(null);
|
|
296
|
+
const serversDropdownRef = useRef3(null);
|
|
285
297
|
const normalizePanes = useCallback((panes) => {
|
|
286
298
|
const total = panes.reduce((s, p) => s + p.widthPercent, 0);
|
|
287
299
|
if (total === 0) return;
|
|
@@ -364,6 +376,10 @@ var CliPanel = React3.forwardRef(
|
|
|
364
376
|
setTabs((prev) => prev.map((t) => {
|
|
365
377
|
if (t.id !== targetTabId) return t;
|
|
366
378
|
const newPanes = [...t.panes.map((p) => ({ ...p })), { id: paneId, widthPercent: 0 }];
|
|
379
|
+
const evenWidth = 100 / newPanes.length;
|
|
380
|
+
newPanes.forEach((p) => {
|
|
381
|
+
p.widthPercent = evenWidth;
|
|
382
|
+
});
|
|
367
383
|
normalizePanes(newPanes);
|
|
368
384
|
return { ...t, panes: newPanes };
|
|
369
385
|
}));
|
|
@@ -513,6 +529,81 @@ var CliPanel = React3.forwardRef(
|
|
|
513
529
|
}, 200);
|
|
514
530
|
return () => clearTimeout(timer);
|
|
515
531
|
}, [syncTheme, initialized]);
|
|
532
|
+
useEffect3(() => {
|
|
533
|
+
if (!initialized) return;
|
|
534
|
+
const pollExec = setInterval(() => {
|
|
535
|
+
const tab = tabs.find((t) => t.id === activeTabIdRef.current);
|
|
536
|
+
if (!tab) return;
|
|
537
|
+
const engine = engineMapRef.current.get(tab.panes[0]?.id);
|
|
538
|
+
if (!engine) return;
|
|
539
|
+
const context = engine.getContext();
|
|
540
|
+
if (!context) return;
|
|
541
|
+
const running = !!context.isExecuting || !!context.contextProcessor;
|
|
542
|
+
setStatusExecutionState(running ? "running" : "idle");
|
|
543
|
+
const result = context.lastCommandResult;
|
|
544
|
+
setStatusLastCommand(result ? { name: result.command, success: result.success } : null);
|
|
545
|
+
const text = context.getStatusText?.();
|
|
546
|
+
setStatusText(text || null);
|
|
547
|
+
}, 300);
|
|
548
|
+
const pollGlobal = setInterval(() => {
|
|
549
|
+
const tab = tabs.find((t) => t.id === activeTabIdRef.current);
|
|
550
|
+
if (!tab) return;
|
|
551
|
+
const engine = engineMapRef.current.get(tab.panes[0]?.id);
|
|
552
|
+
if (!engine) return;
|
|
553
|
+
const context = engine.getContext();
|
|
554
|
+
if (!context) return;
|
|
555
|
+
try {
|
|
556
|
+
const services2 = context.backgroundServices?.list() ?? [];
|
|
557
|
+
setStatusServiceCount({ running: services2.filter((s) => s.status === "running").length, total: services2.length });
|
|
558
|
+
setStatusServiceDetails(services2.map((s) => ({ name: s.name, status: s.status, description: s.description })));
|
|
559
|
+
} catch {
|
|
560
|
+
}
|
|
561
|
+
try {
|
|
562
|
+
let serverManager;
|
|
563
|
+
try {
|
|
564
|
+
serverManager = context.services?.get?.("cli-server-manager");
|
|
565
|
+
} catch {
|
|
566
|
+
}
|
|
567
|
+
const details = [];
|
|
568
|
+
if (serverManager?.connections?.size > 0) {
|
|
569
|
+
let anyConnected = false;
|
|
570
|
+
for (const [name, conn] of serverManager.connections) {
|
|
571
|
+
if (conn.connected) anyConnected = true;
|
|
572
|
+
details.push({
|
|
573
|
+
name,
|
|
574
|
+
url: conn.config?.url ?? "",
|
|
575
|
+
connected: !!conn.connected,
|
|
576
|
+
apiVersion: conn.connected ? conn.apiVersion : void 0,
|
|
577
|
+
commandCount: conn.connected ? conn.commands?.length : void 0
|
|
578
|
+
});
|
|
579
|
+
}
|
|
580
|
+
setStatusServerState(anyConnected ? "connected" : "disconnected");
|
|
581
|
+
} else {
|
|
582
|
+
const configuredServers = engine.options?.servers;
|
|
583
|
+
if (Array.isArray(configuredServers) && configuredServers.length > 0) {
|
|
584
|
+
for (const srv of configuredServers) {
|
|
585
|
+
if (srv.enabled === false) continue;
|
|
586
|
+
details.push({
|
|
587
|
+
name: srv.name,
|
|
588
|
+
url: srv.url ?? "",
|
|
589
|
+
connected: false
|
|
590
|
+
});
|
|
591
|
+
}
|
|
592
|
+
setStatusServerState("disconnected");
|
|
593
|
+
} else {
|
|
594
|
+
setStatusServerState("none");
|
|
595
|
+
}
|
|
596
|
+
}
|
|
597
|
+
setStatusServerDetails(details);
|
|
598
|
+
} catch {
|
|
599
|
+
}
|
|
600
|
+
setStatusUptime(engine.startedAt ? Date.now() - engine.startedAt : 0);
|
|
601
|
+
}, 2e3);
|
|
602
|
+
return () => {
|
|
603
|
+
clearInterval(pollExec);
|
|
604
|
+
clearInterval(pollGlobal);
|
|
605
|
+
};
|
|
606
|
+
}, [initialized, tabs]);
|
|
516
607
|
const toggleMaximize = useCallback(() => {
|
|
517
608
|
const nextMaximized = !maximized;
|
|
518
609
|
if (nextMaximized) {
|
|
@@ -551,6 +642,15 @@ var CliPanel = React3.forwardRef(
|
|
|
551
642
|
document.addEventListener("click", closePositionDropdown);
|
|
552
643
|
return () => document.removeEventListener("click", closePositionDropdown);
|
|
553
644
|
}, [positionDropdownOpen, closePositionDropdown]);
|
|
645
|
+
useEffect3(() => {
|
|
646
|
+
if (!servicesDropdownOpen && !serversDropdownOpen) return;
|
|
647
|
+
const handler = () => {
|
|
648
|
+
setServicesDropdownOpen(false);
|
|
649
|
+
setServersDropdownOpen(false);
|
|
650
|
+
};
|
|
651
|
+
document.addEventListener("click", handler);
|
|
652
|
+
return () => document.removeEventListener("click", handler);
|
|
653
|
+
}, [servicesDropdownOpen, serversDropdownOpen]);
|
|
554
654
|
const handlePositionButtonClick = useCallback((e) => {
|
|
555
655
|
e.stopPropagation();
|
|
556
656
|
setPositionDropdownOpen((prev) => !prev);
|
|
@@ -661,6 +761,12 @@ var CliPanel = React3.forwardRef(
|
|
|
661
761
|
getEngine,
|
|
662
762
|
getState
|
|
663
763
|
]);
|
|
764
|
+
const formattedUptime = (() => {
|
|
765
|
+
const mins = Math.floor(statusUptime / 6e4);
|
|
766
|
+
if (mins < 60) return `${mins}m`;
|
|
767
|
+
const hrs = Math.floor(mins / 60);
|
|
768
|
+
return `${hrs}h${mins % 60}m`;
|
|
769
|
+
})();
|
|
664
770
|
if (!visible) return null;
|
|
665
771
|
const wrapperStyle = {
|
|
666
772
|
...isHorizontal ? { width: `${panelWidth}px` } : { height: `${panelHeight}px` },
|
|
@@ -706,6 +812,63 @@ var CliPanel = React3.forwardRef(
|
|
|
706
812
|
/* @__PURE__ */ jsx3("span", { className: "cli-panel-title-icon", children: /* @__PURE__ */ jsx3(TerminalIcon, {}) }),
|
|
707
813
|
"CLI"
|
|
708
814
|
] }),
|
|
815
|
+
(position === "bottom" || position === "top") && /* @__PURE__ */ jsxs("div", { className: "cli-panel-status-indicators", children: [
|
|
816
|
+
/* @__PURE__ */ jsxs("span", { className: `cli-panel-status-item${statusExecutionState === "running" ? " status-running" : ""}`, children: [
|
|
817
|
+
/* @__PURE__ */ jsx3("span", { className: `cli-panel-status-dot ${statusExecutionState === "running" ? "dot-running" : "dot-idle"}` }),
|
|
818
|
+
/* @__PURE__ */ jsx3("span", { className: "cli-panel-status-label", children: statusExecutionState })
|
|
819
|
+
] }),
|
|
820
|
+
statusServiceCount.total > 0 && /* @__PURE__ */ jsxs(
|
|
821
|
+
"span",
|
|
822
|
+
{
|
|
823
|
+
ref: servicesDropdownRef,
|
|
824
|
+
className: "cli-panel-status-item status-clickable",
|
|
825
|
+
onClick: (e) => {
|
|
826
|
+
e.stopPropagation();
|
|
827
|
+
setServicesDropdownOpen((prev) => !prev);
|
|
828
|
+
setServersDropdownOpen(false);
|
|
829
|
+
},
|
|
830
|
+
children: [
|
|
831
|
+
/* @__PURE__ */ jsx3("span", { className: "cli-panel-status-icon", children: "\u2699" }),
|
|
832
|
+
/* @__PURE__ */ jsxs("span", { className: "cli-panel-status-label", children: [
|
|
833
|
+
statusServiceCount.running,
|
|
834
|
+
"/",
|
|
835
|
+
statusServiceCount.total,
|
|
836
|
+
" services"
|
|
837
|
+
] })
|
|
838
|
+
]
|
|
839
|
+
}
|
|
840
|
+
),
|
|
841
|
+
statusLastCommand && /* @__PURE__ */ jsxs("span", { className: "cli-panel-status-item", children: [
|
|
842
|
+
/* @__PURE__ */ jsx3("span", { className: `cli-panel-status-icon ${statusLastCommand.success ? "status-success" : "status-error"}`, children: statusLastCommand.success ? "\u2713" : "\u2717" }),
|
|
843
|
+
/* @__PURE__ */ jsx3("span", { className: "cli-panel-status-label", children: statusLastCommand.name })
|
|
844
|
+
] }),
|
|
845
|
+
statusServerState !== "none" && /* @__PURE__ */ jsxs(
|
|
846
|
+
"span",
|
|
847
|
+
{
|
|
848
|
+
ref: serversDropdownRef,
|
|
849
|
+
className: "cli-panel-status-item status-clickable",
|
|
850
|
+
onClick: (e) => {
|
|
851
|
+
e.stopPropagation();
|
|
852
|
+
setServersDropdownOpen((prev) => !prev);
|
|
853
|
+
setServicesDropdownOpen(false);
|
|
854
|
+
},
|
|
855
|
+
children: [
|
|
856
|
+
/* @__PURE__ */ jsx3("span", { className: `cli-panel-status-dot ${statusServerState === "connected" ? "dot-idle" : "dot-error"}` }),
|
|
857
|
+
/* @__PURE__ */ jsxs("span", { className: "cli-panel-status-label", children: [
|
|
858
|
+
statusServerDetails.filter((s) => s.connected).length,
|
|
859
|
+
"/",
|
|
860
|
+
statusServerDetails.length,
|
|
861
|
+
" servers"
|
|
862
|
+
] })
|
|
863
|
+
]
|
|
864
|
+
}
|
|
865
|
+
),
|
|
866
|
+
statusUptime > 0 && /* @__PURE__ */ jsxs("span", { className: "cli-panel-status-item status-muted", children: [
|
|
867
|
+
/* @__PURE__ */ jsx3("span", { className: "cli-panel-status-icon", children: "\u2191" }),
|
|
868
|
+
/* @__PURE__ */ jsx3("span", { className: "cli-panel-status-label", children: formattedUptime })
|
|
869
|
+
] }),
|
|
870
|
+
statusText && /* @__PURE__ */ jsx3("span", { className: "cli-panel-status-item status-text", children: /* @__PURE__ */ jsx3("span", { className: "cli-panel-status-label", children: statusText }) })
|
|
871
|
+
] }),
|
|
709
872
|
/* @__PURE__ */ jsxs("div", { className: "cli-panel-action-buttons", children: [
|
|
710
873
|
/* @__PURE__ */ jsxs("div", { className: "cli-panel-btn-position-wrapper", onClick: (e) => e.stopPropagation(), children: [
|
|
711
874
|
/* @__PURE__ */ jsx3("button", { className: "cli-panel-btn cli-panel-btn-position", title: "Move panel", onClick: handlePositionButtonClick, children: /* @__PURE__ */ jsx3(PositionIcon, { position }) }),
|
|
@@ -727,7 +890,8 @@ var CliPanel = React3.forwardRef(
|
|
|
727
890
|
/* @__PURE__ */ jsx3("button", { className: "cli-panel-btn", title: collapsed ? "Expand" : "Collapse", onClick: toggle, children: /* @__PURE__ */ jsx3(CollapseChevron, { position, isCollapsed: collapsed }) }),
|
|
728
891
|
closable && /* @__PURE__ */ jsx3("button", { className: "cli-panel-btn cli-panel-btn-close", title: "Close", onClick: handleClose, children: /* @__PURE__ */ jsx3(CloseIcon, {}) })
|
|
729
892
|
] })
|
|
730
|
-
] })
|
|
893
|
+
] }),
|
|
894
|
+
/* @__PURE__ */ jsx3("div", { className: `cli-panel-glow-line${statusExecutionState === "running" ? " glow-active" : ""}` })
|
|
731
895
|
] }),
|
|
732
896
|
initialized && /* @__PURE__ */ jsxs("div", { className: "cli-panel-content", style: collapsed ? { display: "none" } : void 0, children: [
|
|
733
897
|
/* @__PURE__ */ jsxs("div", { className: "cli-panel-tabs", children: [
|
|
@@ -758,6 +922,12 @@ var CliPanel = React3.forwardRef(
|
|
|
758
922
|
onDoubleClick: (e) => e.stopPropagation()
|
|
759
923
|
}
|
|
760
924
|
) : /* @__PURE__ */ jsxs(Fragment2, { children: [
|
|
925
|
+
/* @__PURE__ */ jsx3("span", { className: `cli-panel-tab-dot ${(() => {
|
|
926
|
+
if (tab.id !== activeTabId) return "dot-idle";
|
|
927
|
+
if (statusExecutionState === "running") return "dot-running";
|
|
928
|
+
if (statusLastCommand && !statusLastCommand.success) return "dot-error";
|
|
929
|
+
return "dot-idle";
|
|
930
|
+
})()}` }),
|
|
761
931
|
/* @__PURE__ */ jsx3("span", { className: "cli-panel-tab-title", children: tab.title }),
|
|
762
932
|
/* @__PURE__ */ jsx3(
|
|
763
933
|
"button",
|
|
@@ -883,6 +1053,66 @@ var CliPanel = React3.forwardRef(
|
|
|
883
1053
|
}, children: "Close All" })
|
|
884
1054
|
]
|
|
885
1055
|
}
|
|
1056
|
+
),
|
|
1057
|
+
servicesDropdownOpen && statusServiceCount.total > 0 && /* @__PURE__ */ jsxs(
|
|
1058
|
+
"div",
|
|
1059
|
+
{
|
|
1060
|
+
className: "cli-panel-services-dropdown",
|
|
1061
|
+
style: (() => {
|
|
1062
|
+
const el = servicesDropdownRef.current;
|
|
1063
|
+
if (!el) return {};
|
|
1064
|
+
const rect = el.getBoundingClientRect();
|
|
1065
|
+
return position === "top" ? { position: "fixed", top: rect.bottom + 4, left: rect.left, zIndex: 1100 } : { position: "fixed", bottom: window.innerHeight - rect.top + 4, left: rect.left, zIndex: 1100 };
|
|
1066
|
+
})(),
|
|
1067
|
+
onClick: (e) => e.stopPropagation(),
|
|
1068
|
+
children: [
|
|
1069
|
+
/* @__PURE__ */ jsx3("div", { className: "cli-panel-services-dropdown-header", children: "Background Services" }),
|
|
1070
|
+
/* @__PURE__ */ jsx3("div", { className: "cli-panel-services-dropdown-list", children: statusServiceDetails.map((svc, i) => /* @__PURE__ */ jsxs("div", { className: "cli-panel-services-dropdown-item", children: [
|
|
1071
|
+
/* @__PURE__ */ jsx3("span", { className: `cli-panel-svc-dot ${svc.status === "running" ? "svc-running" : "svc-stopped"}` }),
|
|
1072
|
+
/* @__PURE__ */ jsxs("div", { className: "cli-panel-svc-info", children: [
|
|
1073
|
+
/* @__PURE__ */ jsx3("span", { className: "cli-panel-svc-name", children: svc.name }),
|
|
1074
|
+
svc.description && /* @__PURE__ */ jsx3("span", { className: "cli-panel-svc-desc", children: svc.description })
|
|
1075
|
+
] }),
|
|
1076
|
+
/* @__PURE__ */ jsx3("span", { className: "cli-panel-svc-status", children: svc.status })
|
|
1077
|
+
] }, i)) }),
|
|
1078
|
+
statusServiceDetails.length === 0 && /* @__PURE__ */ jsx3("div", { className: "cli-panel-services-dropdown-empty", children: "No services registered" })
|
|
1079
|
+
]
|
|
1080
|
+
}
|
|
1081
|
+
),
|
|
1082
|
+
serversDropdownOpen && statusServerState !== "none" && /* @__PURE__ */ jsxs(
|
|
1083
|
+
"div",
|
|
1084
|
+
{
|
|
1085
|
+
className: "cli-panel-services-dropdown",
|
|
1086
|
+
style: (() => {
|
|
1087
|
+
const el = serversDropdownRef.current;
|
|
1088
|
+
if (!el) return {};
|
|
1089
|
+
const rect = el.getBoundingClientRect();
|
|
1090
|
+
return position === "top" ? { position: "fixed", top: rect.bottom + 4, left: rect.left, zIndex: 1100 } : { position: "fixed", bottom: window.innerHeight - rect.top + 4, left: rect.left, zIndex: 1100 };
|
|
1091
|
+
})(),
|
|
1092
|
+
onClick: (e) => e.stopPropagation(),
|
|
1093
|
+
children: [
|
|
1094
|
+
/* @__PURE__ */ jsx3("div", { className: "cli-panel-services-dropdown-header", children: "Server Connections" }),
|
|
1095
|
+
/* @__PURE__ */ jsx3("div", { className: "cli-panel-services-dropdown-list", children: statusServerDetails.map((srv, i) => /* @__PURE__ */ jsxs("div", { className: "cli-panel-services-dropdown-item", children: [
|
|
1096
|
+
/* @__PURE__ */ jsx3("span", { className: `cli-panel-svc-dot ${srv.connected ? "svc-running" : "svc-stopped"}` }),
|
|
1097
|
+
/* @__PURE__ */ jsxs("div", { className: "cli-panel-svc-info", children: [
|
|
1098
|
+
/* @__PURE__ */ jsx3("span", { className: "cli-panel-svc-name", children: srv.name }),
|
|
1099
|
+
srv.url && /* @__PURE__ */ jsx3("span", { className: "cli-panel-svc-desc", children: srv.url })
|
|
1100
|
+
] }),
|
|
1101
|
+
/* @__PURE__ */ jsxs("div", { className: "cli-panel-srv-meta", children: [
|
|
1102
|
+
/* @__PURE__ */ jsx3("span", { className: "cli-panel-svc-status", children: srv.connected ? "connected" : "disconnected" }),
|
|
1103
|
+
srv.apiVersion && /* @__PURE__ */ jsxs("span", { className: "cli-panel-svc-desc", children: [
|
|
1104
|
+
"v",
|
|
1105
|
+
srv.apiVersion
|
|
1106
|
+
] }),
|
|
1107
|
+
srv.commandCount && /* @__PURE__ */ jsxs("span", { className: "cli-panel-svc-desc", children: [
|
|
1108
|
+
srv.commandCount,
|
|
1109
|
+
" cmds"
|
|
1110
|
+
] })
|
|
1111
|
+
] })
|
|
1112
|
+
] }, i)) }),
|
|
1113
|
+
statusServerDetails.length === 0 && /* @__PURE__ */ jsx3("div", { className: "cli-panel-services-dropdown-empty", children: "No servers configured" })
|
|
1114
|
+
]
|
|
1115
|
+
}
|
|
886
1116
|
)
|
|
887
1117
|
] });
|
|
888
1118
|
}
|