@hoox-sh/hoox-tui 0.3.0 → 0.3.2
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/main.js +597 -327
- package/package.json +3 -5
- package/src/app.tsx +7 -9
- package/src/components/ui/dialog-state.ts +15 -0
- package/src/components/ui/dialog.tsx +447 -172
- package/src/components/ui/select.tsx +10 -158
- package/src/components/ui/toast.tsx +44 -92
- package/src/components/views/service-manager.test.tsx +8 -27
- package/src/hooks/shell-overlay.ts +3 -2
- package/src/main.tsx +5 -14
package/dist/main.js
CHANGED
|
@@ -4312,14 +4312,12 @@ var init_src = __esm(() => {
|
|
|
4312
4312
|
// src/main.tsx
|
|
4313
4313
|
import { createCliRenderer } from "@opentui/core";
|
|
4314
4314
|
import { createRoot } from "@opentui/react";
|
|
4315
|
-
import { ToasterRenderable } from "@opentui-ui/toast";
|
|
4316
4315
|
|
|
4317
4316
|
// src/app.tsx
|
|
4318
4317
|
init_src();
|
|
4319
4318
|
init_src();
|
|
4320
|
-
import { useState as useState23, useEffect as
|
|
4321
|
-
import { useKeyboard as
|
|
4322
|
-
import { DialogProvider, useDialog } from "@opentui-ui/dialog/react";
|
|
4319
|
+
import { useState as useState23, useEffect as useEffect25, useCallback as useCallback18 } from "react";
|
|
4320
|
+
import { useKeyboard as useKeyboard8 } from "@opentui/react";
|
|
4323
4321
|
|
|
4324
4322
|
// src/services/cli-bridge/index.ts
|
|
4325
4323
|
init_src();
|
|
@@ -5760,41 +5758,19 @@ function getSettingsConnectionSnapshot(env = process.env, config = {}) {
|
|
|
5760
5758
|
|
|
5761
5759
|
// src/components/ui/toast.tsx
|
|
5762
5760
|
init_src();
|
|
5763
|
-
|
|
5764
|
-
|
|
5765
|
-
|
|
5766
|
-
|
|
5767
|
-
borderColor: Colors.border,
|
|
5768
|
-
paddingX: 1,
|
|
5769
|
-
paddingY: 0
|
|
5770
|
-
};
|
|
5771
|
-
var hooxTypeStyles = {
|
|
5772
|
-
success: { borderColor: Colors.success },
|
|
5773
|
-
error: { borderColor: Colors.error },
|
|
5774
|
-
warning: { borderColor: Colors.warning },
|
|
5775
|
-
info: { borderColor: Colors.highlight },
|
|
5776
|
-
loading: { borderColor: Colors.dim }
|
|
5777
|
-
};
|
|
5778
|
-
function toastSuccess(message, options) {
|
|
5779
|
-
return toast.success(message, {
|
|
5780
|
-
...options,
|
|
5781
|
-
style: { ...baseStyle, ...hooxTypeStyles.success },
|
|
5782
|
-
duration: options?.duration ?? TOAST_DURATION.SHORT
|
|
5783
|
-
});
|
|
5761
|
+
var toastSeq = 0;
|
|
5762
|
+
function nextId() {
|
|
5763
|
+
toastSeq += 1;
|
|
5764
|
+
return `toast-noop-${toastSeq}`;
|
|
5784
5765
|
}
|
|
5785
|
-
function
|
|
5786
|
-
return
|
|
5787
|
-
...options,
|
|
5788
|
-
style: { ...baseStyle, ...hooxTypeStyles.error },
|
|
5789
|
-
duration: options?.duration ?? TOAST_DURATION.LONG
|
|
5790
|
-
});
|
|
5766
|
+
function toastSuccess(_message, _options) {
|
|
5767
|
+
return nextId();
|
|
5791
5768
|
}
|
|
5792
|
-
function
|
|
5793
|
-
return
|
|
5794
|
-
|
|
5795
|
-
|
|
5796
|
-
|
|
5797
|
-
});
|
|
5769
|
+
function toastError(_message, _options) {
|
|
5770
|
+
return nextId();
|
|
5771
|
+
}
|
|
5772
|
+
function toastWarning(_message, _options) {
|
|
5773
|
+
return nextId();
|
|
5798
5774
|
}
|
|
5799
5775
|
var COPY_PREVIEW_MAX = 48;
|
|
5800
5776
|
function messageCopiedToClipboard(text) {
|
|
@@ -5911,9 +5887,20 @@ init_src();
|
|
|
5911
5887
|
// src/hooks/shell-overlay.ts
|
|
5912
5888
|
init_src();
|
|
5913
5889
|
import { useKeyboard } from "@opentui/react";
|
|
5890
|
+
|
|
5891
|
+
// src/components/ui/dialog-state.ts
|
|
5892
|
+
var openDialogCount = 0;
|
|
5893
|
+
function setOpenDialogCount(n) {
|
|
5894
|
+
openDialogCount = Math.max(0, n);
|
|
5895
|
+
}
|
|
5896
|
+
function isHooxDialogOpen() {
|
|
5897
|
+
return openDialogCount > 0;
|
|
5898
|
+
}
|
|
5899
|
+
|
|
5900
|
+
// src/hooks/shell-overlay.ts
|
|
5914
5901
|
function isShellOverlayOpen() {
|
|
5915
5902
|
const s = useUIStore.getState();
|
|
5916
|
-
return Boolean(s.commandPaletteOpen || s.modal);
|
|
5903
|
+
return Boolean(s.commandPaletteOpen || s.modal || isHooxDialogOpen());
|
|
5917
5904
|
}
|
|
5918
5905
|
function useViewKeyboard(handler) {
|
|
5919
5906
|
useKeyboard((key) => {
|
|
@@ -5922,15 +5909,365 @@ function useViewKeyboard(handler) {
|
|
|
5922
5909
|
handler(key);
|
|
5923
5910
|
});
|
|
5924
5911
|
}
|
|
5912
|
+
// src/components/ui/dialog.tsx
|
|
5913
|
+
init_src();
|
|
5914
|
+
import {
|
|
5915
|
+
createContext,
|
|
5916
|
+
useCallback,
|
|
5917
|
+
useContext,
|
|
5918
|
+
useEffect as useEffect3,
|
|
5919
|
+
useMemo,
|
|
5920
|
+
useState
|
|
5921
|
+
} from "react";
|
|
5922
|
+
import { useKeyboard as useKeyboard3 } from "@opentui/react";
|
|
5923
|
+
import { jsxDEV } from "@opentui/react/jsx-dev-runtime";
|
|
5924
|
+
var nextId2 = 1;
|
|
5925
|
+
var DialogCtx = createContext(null);
|
|
5926
|
+
function ConfirmOverlay({
|
|
5927
|
+
entry,
|
|
5928
|
+
onResolve
|
|
5929
|
+
}) {
|
|
5930
|
+
useKeyboard3((key) => {
|
|
5931
|
+
const name = String(key.name ?? "").toLowerCase();
|
|
5932
|
+
if (name === "return" || name === "enter" || name === "y") {
|
|
5933
|
+
onResolve(true);
|
|
5934
|
+
return;
|
|
5935
|
+
}
|
|
5936
|
+
if (name === "escape" || name === "n") {
|
|
5937
|
+
onResolve(false);
|
|
5938
|
+
}
|
|
5939
|
+
});
|
|
5940
|
+
return /* @__PURE__ */ jsxDEV("box", {
|
|
5941
|
+
position: "absolute",
|
|
5942
|
+
left: 0,
|
|
5943
|
+
top: 0,
|
|
5944
|
+
width: "100%",
|
|
5945
|
+
height: "100%",
|
|
5946
|
+
justifyContent: "center",
|
|
5947
|
+
alignItems: "center",
|
|
5948
|
+
backgroundColor: Colors.backdrop,
|
|
5949
|
+
onMouseUp: entry.closeOnClickOutside ? () => onResolve(false) : undefined,
|
|
5950
|
+
children: /* @__PURE__ */ jsxDEV("box", {
|
|
5951
|
+
flexDirection: "column",
|
|
5952
|
+
gap: 1,
|
|
5953
|
+
padding: 2,
|
|
5954
|
+
border: true,
|
|
5955
|
+
borderStyle: "double",
|
|
5956
|
+
borderColor: Colors.accent,
|
|
5957
|
+
backgroundColor: Colors.card,
|
|
5958
|
+
minWidth: 44,
|
|
5959
|
+
onMouseUp: (e) => {
|
|
5960
|
+
e?.stopPropagation?.();
|
|
5961
|
+
},
|
|
5962
|
+
children: [
|
|
5963
|
+
/* @__PURE__ */ jsxDEV("text", {
|
|
5964
|
+
fg: Colors.accent,
|
|
5965
|
+
bold: true,
|
|
5966
|
+
children: entry.title
|
|
5967
|
+
}, undefined, false, undefined, this),
|
|
5968
|
+
/* @__PURE__ */ jsxDEV("text", {
|
|
5969
|
+
fg: Colors.foreground,
|
|
5970
|
+
children: entry.message
|
|
5971
|
+
}, undefined, false, undefined, this),
|
|
5972
|
+
/* @__PURE__ */ jsxDEV("box", {
|
|
5973
|
+
flexDirection: "row",
|
|
5974
|
+
gap: 2,
|
|
5975
|
+
paddingTop: 1,
|
|
5976
|
+
children: [
|
|
5977
|
+
/* @__PURE__ */ jsxDEV("text", {
|
|
5978
|
+
fg: Colors.accent,
|
|
5979
|
+
bg: Colors.card,
|
|
5980
|
+
bold: true,
|
|
5981
|
+
onMouseUp: () => onResolve(true),
|
|
5982
|
+
children: ` [Y/Enter] ${entry.confirmLabel} `
|
|
5983
|
+
}, undefined, false, undefined, this),
|
|
5984
|
+
/* @__PURE__ */ jsxDEV("text", {
|
|
5985
|
+
fg: Colors.muted,
|
|
5986
|
+
onMouseUp: () => onResolve(false),
|
|
5987
|
+
children: ` [N/Esc] ${entry.cancelLabel} `
|
|
5988
|
+
}, undefined, false, undefined, this)
|
|
5989
|
+
]
|
|
5990
|
+
}, undefined, true, undefined, this)
|
|
5991
|
+
]
|
|
5992
|
+
}, undefined, true, undefined, this)
|
|
5993
|
+
}, undefined, false, undefined, this);
|
|
5994
|
+
}
|
|
5995
|
+
function ChoiceOverlay({
|
|
5996
|
+
entry,
|
|
5997
|
+
onResolve
|
|
5998
|
+
}) {
|
|
5999
|
+
const [selectedIndex, setSelectedIndex] = useState(0);
|
|
6000
|
+
useKeyboard3((key) => {
|
|
6001
|
+
const name = String(key.name ?? "").toLowerCase();
|
|
6002
|
+
if (name === "down" || name === "j") {
|
|
6003
|
+
setSelectedIndex((prev) => prev < entry.choices.length - 1 ? prev + 1 : 0);
|
|
6004
|
+
return;
|
|
6005
|
+
}
|
|
6006
|
+
if (name === "up" || name === "k") {
|
|
6007
|
+
setSelectedIndex((prev) => prev > 0 ? prev - 1 : entry.choices.length - 1);
|
|
6008
|
+
return;
|
|
6009
|
+
}
|
|
6010
|
+
if (name === "return" || name === "enter") {
|
|
6011
|
+
const choice = entry.choices[selectedIndex];
|
|
6012
|
+
if (choice)
|
|
6013
|
+
onResolve(choice.key);
|
|
6014
|
+
return;
|
|
6015
|
+
}
|
|
6016
|
+
if (name === "escape") {
|
|
6017
|
+
onResolve(entry.fallback);
|
|
6018
|
+
}
|
|
6019
|
+
});
|
|
6020
|
+
return /* @__PURE__ */ jsxDEV("box", {
|
|
6021
|
+
position: "absolute",
|
|
6022
|
+
left: 0,
|
|
6023
|
+
top: 0,
|
|
6024
|
+
width: "100%",
|
|
6025
|
+
height: "100%",
|
|
6026
|
+
justifyContent: "center",
|
|
6027
|
+
alignItems: "center",
|
|
6028
|
+
backgroundColor: Colors.backdrop,
|
|
6029
|
+
onMouseUp: entry.closeOnClickOutside ? () => onResolve(entry.fallback) : undefined,
|
|
6030
|
+
children: /* @__PURE__ */ jsxDEV("box", {
|
|
6031
|
+
flexDirection: "column",
|
|
6032
|
+
gap: 1,
|
|
6033
|
+
padding: 2,
|
|
6034
|
+
border: true,
|
|
6035
|
+
borderStyle: "double",
|
|
6036
|
+
borderColor: Colors.accent,
|
|
6037
|
+
backgroundColor: Colors.card,
|
|
6038
|
+
minWidth: 48,
|
|
6039
|
+
children: [
|
|
6040
|
+
/* @__PURE__ */ jsxDEV("text", {
|
|
6041
|
+
fg: Colors.accent,
|
|
6042
|
+
bold: true,
|
|
6043
|
+
children: entry.title
|
|
6044
|
+
}, undefined, false, undefined, this),
|
|
6045
|
+
/* @__PURE__ */ jsxDEV("text", {
|
|
6046
|
+
dim: true,
|
|
6047
|
+
fg: Colors.muted,
|
|
6048
|
+
children: "Use \u2191\u2193 to navigate, Enter to select, Esc to cancel"
|
|
6049
|
+
}, undefined, false, undefined, this),
|
|
6050
|
+
/* @__PURE__ */ jsxDEV("box", {
|
|
6051
|
+
flexDirection: "column",
|
|
6052
|
+
gap: 0,
|
|
6053
|
+
paddingTop: 1,
|
|
6054
|
+
children: entry.choices.map((choice, idx) => /* @__PURE__ */ jsxDEV("box", {
|
|
6055
|
+
flexDirection: "row",
|
|
6056
|
+
gap: 2,
|
|
6057
|
+
paddingLeft: 1,
|
|
6058
|
+
paddingRight: 1,
|
|
6059
|
+
children: [
|
|
6060
|
+
/* @__PURE__ */ jsxDEV("text", {
|
|
6061
|
+
fg: idx === selectedIndex ? Colors.accent : Colors.muted,
|
|
6062
|
+
children: idx === selectedIndex ? "\u25B6" : " "
|
|
6063
|
+
}, undefined, false, undefined, this),
|
|
6064
|
+
/* @__PURE__ */ jsxDEV("text", {
|
|
6065
|
+
fg: idx === selectedIndex ? Colors.foreground : Colors.muted,
|
|
6066
|
+
bg: idx === selectedIndex ? Colors.card : undefined,
|
|
6067
|
+
onMouseUp: () => onResolve(choice.key),
|
|
6068
|
+
children: choice.label
|
|
6069
|
+
}, undefined, false, undefined, this),
|
|
6070
|
+
choice.description ? /* @__PURE__ */ jsxDEV("text", {
|
|
6071
|
+
dim: true,
|
|
6072
|
+
fg: Colors.muted,
|
|
6073
|
+
children: [
|
|
6074
|
+
"\u2014 ",
|
|
6075
|
+
choice.description
|
|
6076
|
+
]
|
|
6077
|
+
}, undefined, true, undefined, this) : null
|
|
6078
|
+
]
|
|
6079
|
+
}, choice.key, true, undefined, this))
|
|
6080
|
+
}, undefined, false, undefined, this),
|
|
6081
|
+
/* @__PURE__ */ jsxDEV("box", {
|
|
6082
|
+
flexDirection: "row",
|
|
6083
|
+
justifyContent: "flex-end",
|
|
6084
|
+
paddingTop: 1,
|
|
6085
|
+
children: /* @__PURE__ */ jsxDEV("text", {
|
|
6086
|
+
fg: Colors.muted,
|
|
6087
|
+
onMouseUp: () => onResolve(entry.fallback),
|
|
6088
|
+
children: " Cancel "
|
|
6089
|
+
}, undefined, false, undefined, this)
|
|
6090
|
+
}, undefined, false, undefined, this)
|
|
6091
|
+
]
|
|
6092
|
+
}, undefined, true, undefined, this)
|
|
6093
|
+
}, undefined, false, undefined, this);
|
|
6094
|
+
}
|
|
6095
|
+
function LoadingOverlay({ message }) {
|
|
6096
|
+
return /* @__PURE__ */ jsxDEV("box", {
|
|
6097
|
+
position: "absolute",
|
|
6098
|
+
left: 0,
|
|
6099
|
+
top: 0,
|
|
6100
|
+
width: "100%",
|
|
6101
|
+
height: "100%",
|
|
6102
|
+
justifyContent: "center",
|
|
6103
|
+
alignItems: "center",
|
|
6104
|
+
backgroundColor: Colors.backdrop,
|
|
6105
|
+
children: /* @__PURE__ */ jsxDEV("box", {
|
|
6106
|
+
flexDirection: "column",
|
|
6107
|
+
padding: 2,
|
|
6108
|
+
gap: 1,
|
|
6109
|
+
border: true,
|
|
6110
|
+
borderStyle: "single",
|
|
6111
|
+
borderColor: Colors.border,
|
|
6112
|
+
backgroundColor: Colors.card,
|
|
6113
|
+
justifyContent: "center",
|
|
6114
|
+
alignItems: "center",
|
|
6115
|
+
children: [
|
|
6116
|
+
/* @__PURE__ */ jsxDEV("text", {
|
|
6117
|
+
fg: Colors.accent,
|
|
6118
|
+
children: message
|
|
6119
|
+
}, undefined, false, undefined, this),
|
|
6120
|
+
/* @__PURE__ */ jsxDEV("text", {
|
|
6121
|
+
dim: true,
|
|
6122
|
+
fg: Colors.muted,
|
|
6123
|
+
children: "Please wait..."
|
|
6124
|
+
}, undefined, false, undefined, this)
|
|
6125
|
+
]
|
|
6126
|
+
}, undefined, true, undefined, this)
|
|
6127
|
+
}, undefined, false, undefined, this);
|
|
6128
|
+
}
|
|
6129
|
+
function DialogProvider({ children }) {
|
|
6130
|
+
const [stack, setStack] = useState([]);
|
|
6131
|
+
useEffect3(() => {
|
|
6132
|
+
setOpenDialogCount(stack.length);
|
|
6133
|
+
return () => setOpenDialogCount(0);
|
|
6134
|
+
}, [stack.length]);
|
|
6135
|
+
const popId = useCallback((id) => {
|
|
6136
|
+
setStack((s) => s.filter((e) => e.id !== id));
|
|
6137
|
+
}, []);
|
|
6138
|
+
const handle = useMemo(() => {
|
|
6139
|
+
const confirmSimple = (options) => new Promise((resolve3) => {
|
|
6140
|
+
const id = nextId2++;
|
|
6141
|
+
setStack((s) => [
|
|
6142
|
+
...s,
|
|
6143
|
+
{
|
|
6144
|
+
kind: "confirm",
|
|
6145
|
+
id,
|
|
6146
|
+
title: options.title,
|
|
6147
|
+
message: options.message,
|
|
6148
|
+
confirmLabel: options.confirmLabel ?? "Confirm",
|
|
6149
|
+
cancelLabel: options.cancelLabel ?? "Cancel",
|
|
6150
|
+
closeOnClickOutside: options.closeOnClickOutside ?? true,
|
|
6151
|
+
resolve: (value) => {
|
|
6152
|
+
popId(id);
|
|
6153
|
+
resolve3(value);
|
|
6154
|
+
}
|
|
6155
|
+
}
|
|
6156
|
+
]);
|
|
6157
|
+
});
|
|
6158
|
+
const choiceSimple = (options) => new Promise((resolve3) => {
|
|
6159
|
+
const id = nextId2++;
|
|
6160
|
+
setStack((s) => [
|
|
6161
|
+
...s,
|
|
6162
|
+
{
|
|
6163
|
+
kind: "choice",
|
|
6164
|
+
id,
|
|
6165
|
+
title: options.title,
|
|
6166
|
+
choices: options.choices,
|
|
6167
|
+
fallback: options.fallback,
|
|
6168
|
+
closeOnClickOutside: options.closeOnClickOutside ?? true,
|
|
6169
|
+
resolve: (value) => {
|
|
6170
|
+
popId(id);
|
|
6171
|
+
resolve3(value);
|
|
6172
|
+
}
|
|
6173
|
+
}
|
|
6174
|
+
]);
|
|
6175
|
+
});
|
|
6176
|
+
return {
|
|
6177
|
+
confirmSimple,
|
|
6178
|
+
choiceSimple,
|
|
6179
|
+
confirm: (options) => {
|
|
6180
|
+
const title = options.title ?? (typeof options.content === "function" ? "Confirm" : "Confirm");
|
|
6181
|
+
const message = options.message ?? "Continue?";
|
|
6182
|
+
return confirmSimple({
|
|
6183
|
+
title,
|
|
6184
|
+
message,
|
|
6185
|
+
confirmLabel: options.confirmLabel,
|
|
6186
|
+
cancelLabel: options.cancelLabel,
|
|
6187
|
+
closeOnClickOutside: options.closeOnClickOutside
|
|
6188
|
+
});
|
|
6189
|
+
},
|
|
6190
|
+
choice: (options) => {
|
|
6191
|
+
return choiceSimple({
|
|
6192
|
+
title: options.title ?? "Select",
|
|
6193
|
+
choices: options.choices ?? [],
|
|
6194
|
+
fallback: options.fallback,
|
|
6195
|
+
closeOnClickOutside: options.closeOnClickOutside
|
|
6196
|
+
});
|
|
6197
|
+
},
|
|
6198
|
+
show: (options) => {
|
|
6199
|
+
const id = nextId2++;
|
|
6200
|
+
setStack((s) => [
|
|
6201
|
+
...s,
|
|
6202
|
+
{
|
|
6203
|
+
kind: "loading",
|
|
6204
|
+
id,
|
|
6205
|
+
message: options.message ?? "Loading\u2026"
|
|
6206
|
+
}
|
|
6207
|
+
]);
|
|
6208
|
+
return id;
|
|
6209
|
+
},
|
|
6210
|
+
close: (id) => {
|
|
6211
|
+
if (id == null) {
|
|
6212
|
+
setStack([]);
|
|
6213
|
+
return;
|
|
6214
|
+
}
|
|
6215
|
+
popId(Number(id));
|
|
6216
|
+
}
|
|
6217
|
+
};
|
|
6218
|
+
}, [popId]);
|
|
6219
|
+
const top = stack[stack.length - 1] ?? null;
|
|
6220
|
+
return /* @__PURE__ */ jsxDEV(DialogCtx.Provider, {
|
|
6221
|
+
value: handle,
|
|
6222
|
+
children: [
|
|
6223
|
+
children,
|
|
6224
|
+
top?.kind === "confirm" ? /* @__PURE__ */ jsxDEV(ConfirmOverlay, {
|
|
6225
|
+
entry: top,
|
|
6226
|
+
onResolve: (v) => {
|
|
6227
|
+
top.resolve(v);
|
|
6228
|
+
}
|
|
6229
|
+
}, undefined, false, undefined, this) : null,
|
|
6230
|
+
top?.kind === "choice" ? /* @__PURE__ */ jsxDEV(ChoiceOverlay, {
|
|
6231
|
+
entry: top,
|
|
6232
|
+
onResolve: (v) => {
|
|
6233
|
+
top.resolve(v);
|
|
6234
|
+
}
|
|
6235
|
+
}, undefined, false, undefined, this) : null,
|
|
6236
|
+
top?.kind === "loading" ? /* @__PURE__ */ jsxDEV(LoadingOverlay, {
|
|
6237
|
+
message: top.message
|
|
6238
|
+
}, undefined, false, undefined, this) : null
|
|
6239
|
+
]
|
|
6240
|
+
}, undefined, true, undefined, this);
|
|
6241
|
+
}
|
|
6242
|
+
function useDialog() {
|
|
6243
|
+
const ctx = useContext(DialogCtx);
|
|
6244
|
+
if (!ctx) {
|
|
6245
|
+
throw new Error("useDialog must be used within <DialogProvider>");
|
|
6246
|
+
}
|
|
6247
|
+
return ctx;
|
|
6248
|
+
}
|
|
6249
|
+
async function showConfirm(dialog, options) {
|
|
6250
|
+
if (typeof dialog.confirmSimple === "function") {
|
|
6251
|
+
return dialog.confirmSimple(options);
|
|
6252
|
+
}
|
|
6253
|
+
return dialog.confirm({
|
|
6254
|
+
title: options.title,
|
|
6255
|
+
message: options.message,
|
|
6256
|
+
confirmLabel: options.confirmLabel,
|
|
6257
|
+
cancelLabel: options.cancelLabel,
|
|
6258
|
+
closeOnClickOutside: options.closeOnClickOutside
|
|
6259
|
+
});
|
|
6260
|
+
}
|
|
6261
|
+
|
|
5925
6262
|
// src/components/views/dashboard.tsx
|
|
5926
6263
|
init_src();
|
|
5927
|
-
import { useEffect as
|
|
6264
|
+
import { useEffect as useEffect8, useMemo as useMemo4, useState as useState6, useCallback as useCallback3, useRef as useRef3 } from "react";
|
|
5928
6265
|
|
|
5929
6266
|
// src/components/shared/error-boundary.tsx
|
|
5930
6267
|
init_src();
|
|
5931
6268
|
import { Component } from "react";
|
|
5932
|
-
import { useKeyboard as
|
|
5933
|
-
import { jsxDEV } from "@opentui/react/jsx-dev-runtime";
|
|
6269
|
+
import { useKeyboard as useKeyboard4 } from "@opentui/react";
|
|
6270
|
+
import { jsxDEV as jsxDEV2 } from "@opentui/react/jsx-dev-runtime";
|
|
5934
6271
|
function formatBoundaryErrorMessage(error, maxLen = 160) {
|
|
5935
6272
|
const first = (error.message || "Unknown error").split(`
|
|
5936
6273
|
`)[0] ?? "";
|
|
@@ -5942,13 +6279,13 @@ function ErrorRecoveryPanel({
|
|
|
5942
6279
|
message,
|
|
5943
6280
|
onRetry
|
|
5944
6281
|
}) {
|
|
5945
|
-
|
|
6282
|
+
useKeyboard4((key) => {
|
|
5946
6283
|
const name = String(key.name ?? "").toLowerCase();
|
|
5947
6284
|
if (name === "return" || name === "enter" || name === "r") {
|
|
5948
6285
|
onRetry();
|
|
5949
6286
|
}
|
|
5950
6287
|
});
|
|
5951
|
-
return /* @__PURE__ */
|
|
6288
|
+
return /* @__PURE__ */ jsxDEV2("box", {
|
|
5952
6289
|
flexDirection: "column",
|
|
5953
6290
|
padding: 2,
|
|
5954
6291
|
gap: 1,
|
|
@@ -5957,16 +6294,16 @@ function ErrorRecoveryPanel({
|
|
|
5957
6294
|
borderColor: Colors.border,
|
|
5958
6295
|
backgroundColor: Colors.card,
|
|
5959
6296
|
children: [
|
|
5960
|
-
/* @__PURE__ */
|
|
6297
|
+
/* @__PURE__ */ jsxDEV2("box", {
|
|
5961
6298
|
flexDirection: "row",
|
|
5962
6299
|
gap: 1,
|
|
5963
6300
|
children: [
|
|
5964
|
-
/* @__PURE__ */
|
|
6301
|
+
/* @__PURE__ */ jsxDEV2("text", {
|
|
5965
6302
|
fg: Colors.error,
|
|
5966
6303
|
bold: true,
|
|
5967
6304
|
children: "\u26A0"
|
|
5968
6305
|
}, undefined, false, undefined, this),
|
|
5969
|
-
/* @__PURE__ */
|
|
6306
|
+
/* @__PURE__ */ jsxDEV2("text", {
|
|
5970
6307
|
fg: Colors.error,
|
|
5971
6308
|
bold: true,
|
|
5972
6309
|
children: [
|
|
@@ -5976,22 +6313,22 @@ function ErrorRecoveryPanel({
|
|
|
5976
6313
|
}, undefined, true, undefined, this)
|
|
5977
6314
|
]
|
|
5978
6315
|
}, undefined, true, undefined, this),
|
|
5979
|
-
/* @__PURE__ */
|
|
6316
|
+
/* @__PURE__ */ jsxDEV2("text", {
|
|
5980
6317
|
fg: Colors.muted,
|
|
5981
6318
|
children: message
|
|
5982
6319
|
}, undefined, false, undefined, this),
|
|
5983
|
-
/* @__PURE__ */
|
|
6320
|
+
/* @__PURE__ */ jsxDEV2("box", {
|
|
5984
6321
|
paddingTop: 1,
|
|
5985
6322
|
flexDirection: "row",
|
|
5986
6323
|
gap: 2,
|
|
5987
6324
|
children: [
|
|
5988
|
-
/* @__PURE__ */
|
|
6325
|
+
/* @__PURE__ */ jsxDEV2("text", {
|
|
5989
6326
|
fg: Colors.accent,
|
|
5990
6327
|
bg: Colors.card,
|
|
5991
6328
|
onMouseUp: onRetry,
|
|
5992
6329
|
children: " [Retry] "
|
|
5993
6330
|
}, undefined, false, undefined, this),
|
|
5994
|
-
/* @__PURE__ */
|
|
6331
|
+
/* @__PURE__ */ jsxDEV2("text", {
|
|
5995
6332
|
fg: Colors.dim,
|
|
5996
6333
|
dim: true,
|
|
5997
6334
|
children: "Enter / R"
|
|
@@ -6013,7 +6350,7 @@ class ErrorBoundary extends Component {
|
|
|
6013
6350
|
render() {
|
|
6014
6351
|
if (this.state.error) {
|
|
6015
6352
|
const message = formatBoundaryErrorMessage(this.state.error);
|
|
6016
|
-
return /* @__PURE__ */
|
|
6353
|
+
return /* @__PURE__ */ jsxDEV2(ErrorRecoveryPanel, {
|
|
6017
6354
|
viewName: this.props.viewName,
|
|
6018
6355
|
message,
|
|
6019
6356
|
onRetry: this.handleRetry
|
|
@@ -6025,7 +6362,7 @@ class ErrorBoundary extends Component {
|
|
|
6025
6362
|
|
|
6026
6363
|
// src/components/shared/status-dot.tsx
|
|
6027
6364
|
init_src();
|
|
6028
|
-
import { jsxDEV as
|
|
6365
|
+
import { jsxDEV as jsxDEV3 } from "@opentui/react/jsx-dev-runtime";
|
|
6029
6366
|
var DOT_CHAR = {
|
|
6030
6367
|
operational: "\u2588",
|
|
6031
6368
|
degraded: "\u258C",
|
|
@@ -6037,7 +6374,7 @@ function StatusDot({ status, pulse = false }) {
|
|
|
6037
6374
|
const color = DOT_COLOR[status];
|
|
6038
6375
|
const isDown = status === "down";
|
|
6039
6376
|
const shouldBlink = pulse && status === "operational";
|
|
6040
|
-
return /* @__PURE__ */
|
|
6377
|
+
return /* @__PURE__ */ jsxDEV3("text", {
|
|
6041
6378
|
fg: color,
|
|
6042
6379
|
bold: !isDown,
|
|
6043
6380
|
dim: isDown,
|
|
@@ -6051,24 +6388,24 @@ init_src();
|
|
|
6051
6388
|
|
|
6052
6389
|
// src/components/shared/cool-brackets.tsx
|
|
6053
6390
|
init_src();
|
|
6054
|
-
import { jsxDEV as
|
|
6391
|
+
import { jsxDEV as jsxDEV4 } from "@opentui/react/jsx-dev-runtime";
|
|
6055
6392
|
function CoolBrackets({
|
|
6056
6393
|
children,
|
|
6057
6394
|
open = "\u250C",
|
|
6058
6395
|
close = "\u2510",
|
|
6059
6396
|
gap = 1
|
|
6060
6397
|
}) {
|
|
6061
|
-
return /* @__PURE__ */
|
|
6398
|
+
return /* @__PURE__ */ jsxDEV4("box", {
|
|
6062
6399
|
flexDirection: "row",
|
|
6063
6400
|
gap,
|
|
6064
6401
|
alignItems: "center",
|
|
6065
6402
|
children: [
|
|
6066
|
-
/* @__PURE__ */
|
|
6403
|
+
/* @__PURE__ */ jsxDEV4("text", {
|
|
6067
6404
|
fg: Colors.accent,
|
|
6068
6405
|
children: open
|
|
6069
6406
|
}, undefined, false, undefined, this),
|
|
6070
6407
|
children ?? null,
|
|
6071
|
-
/* @__PURE__ */
|
|
6408
|
+
/* @__PURE__ */ jsxDEV4("text", {
|
|
6072
6409
|
fg: Colors.accent,
|
|
6073
6410
|
children: close
|
|
6074
6411
|
}, undefined, false, undefined, this)
|
|
@@ -6078,20 +6415,20 @@ function CoolBrackets({
|
|
|
6078
6415
|
function CoolGlyph({
|
|
6079
6416
|
char
|
|
6080
6417
|
}) {
|
|
6081
|
-
return /* @__PURE__ */
|
|
6418
|
+
return /* @__PURE__ */ jsxDEV4("text", {
|
|
6082
6419
|
fg: Colors.accent,
|
|
6083
6420
|
children: char
|
|
6084
6421
|
}, undefined, false, undefined, this);
|
|
6085
6422
|
}
|
|
6086
6423
|
|
|
6087
6424
|
// src/components/shared/view-header.tsx
|
|
6088
|
-
import { jsxDEV as
|
|
6425
|
+
import { jsxDEV as jsxDEV5 } from "@opentui/react/jsx-dev-runtime";
|
|
6089
6426
|
function ViewHeader({
|
|
6090
6427
|
title,
|
|
6091
6428
|
meta,
|
|
6092
6429
|
showDivider = true
|
|
6093
6430
|
}) {
|
|
6094
|
-
return /* @__PURE__ */
|
|
6431
|
+
return /* @__PURE__ */ jsxDEV5("box", {
|
|
6095
6432
|
flexDirection: "row",
|
|
6096
6433
|
gap: 2,
|
|
6097
6434
|
paddingBottom: showDivider ? 1 : 0,
|
|
@@ -6101,17 +6438,17 @@ function ViewHeader({
|
|
|
6101
6438
|
justifyContent: "space-between",
|
|
6102
6439
|
width: "100%",
|
|
6103
6440
|
children: [
|
|
6104
|
-
/* @__PURE__ */
|
|
6441
|
+
/* @__PURE__ */ jsxDEV5(CoolBrackets, {
|
|
6105
6442
|
open: "\u250C",
|
|
6106
6443
|
close: "\u2510",
|
|
6107
6444
|
gap: 1,
|
|
6108
|
-
children: /* @__PURE__ */
|
|
6445
|
+
children: /* @__PURE__ */ jsxDEV5("text", {
|
|
6109
6446
|
fg: Colors.accent,
|
|
6110
6447
|
bold: true,
|
|
6111
6448
|
children: title
|
|
6112
6449
|
}, undefined, false, undefined, this)
|
|
6113
6450
|
}, undefined, false, undefined, this),
|
|
6114
|
-
meta ? /* @__PURE__ */
|
|
6451
|
+
meta ? /* @__PURE__ */ jsxDEV5("box", {
|
|
6115
6452
|
flexDirection: "row",
|
|
6116
6453
|
gap: 1,
|
|
6117
6454
|
children: meta
|
|
@@ -6120,65 +6457,9 @@ function ViewHeader({
|
|
|
6120
6457
|
}, undefined, true, undefined, this);
|
|
6121
6458
|
}
|
|
6122
6459
|
|
|
6123
|
-
// src/components/ui/dialog.tsx
|
|
6124
|
-
init_src();
|
|
6125
|
-
import { useState } from "react";
|
|
6126
|
-
import {
|
|
6127
|
-
useDialogKeyboard
|
|
6128
|
-
} from "@opentui-ui/dialog/react";
|
|
6129
|
-
import { jsxDEV as jsxDEV5 } from "@opentui/react/jsx-dev-runtime";
|
|
6130
|
-
async function showConfirm(dialog, options) {
|
|
6131
|
-
return dialog.confirm({
|
|
6132
|
-
content: (ctx) => /* @__PURE__ */ jsxDEV5("box", {
|
|
6133
|
-
flexDirection: "column",
|
|
6134
|
-
padding: 1,
|
|
6135
|
-
gap: 1,
|
|
6136
|
-
children: [
|
|
6137
|
-
/* @__PURE__ */ jsxDEV5("text", {
|
|
6138
|
-
fg: Colors.accent,
|
|
6139
|
-
children: /* @__PURE__ */ jsxDEV5("b", {
|
|
6140
|
-
children: options.title
|
|
6141
|
-
}, undefined, false, undefined, this)
|
|
6142
|
-
}, undefined, false, undefined, this),
|
|
6143
|
-
/* @__PURE__ */ jsxDEV5("text", {
|
|
6144
|
-
fg: Colors.muted,
|
|
6145
|
-
children: options.message
|
|
6146
|
-
}, undefined, false, undefined, this),
|
|
6147
|
-
/* @__PURE__ */ jsxDEV5("box", {
|
|
6148
|
-
flexDirection: "row",
|
|
6149
|
-
gap: 2,
|
|
6150
|
-
justifyContent: "flex-end",
|
|
6151
|
-
children: [
|
|
6152
|
-
/* @__PURE__ */ jsxDEV5("text", {
|
|
6153
|
-
fg: Colors.muted,
|
|
6154
|
-
onMouseUp: () => ctx.resolve(false),
|
|
6155
|
-
children: [
|
|
6156
|
-
" ",
|
|
6157
|
-
options.cancelLabel ?? "Cancel",
|
|
6158
|
-
" "
|
|
6159
|
-
]
|
|
6160
|
-
}, undefined, true, undefined, this),
|
|
6161
|
-
/* @__PURE__ */ jsxDEV5("text", {
|
|
6162
|
-
fg: Colors.accent,
|
|
6163
|
-
bg: Colors.card,
|
|
6164
|
-
onMouseUp: () => ctx.resolve(true),
|
|
6165
|
-
children: [
|
|
6166
|
-
" ",
|
|
6167
|
-
options.confirmLabel ?? "Confirm",
|
|
6168
|
-
" "
|
|
6169
|
-
]
|
|
6170
|
-
}, undefined, true, undefined, this)
|
|
6171
|
-
]
|
|
6172
|
-
}, undefined, true, undefined, this)
|
|
6173
|
-
]
|
|
6174
|
-
}, undefined, true, undefined, this),
|
|
6175
|
-
closeOnClickOutside: options.closeOnClickOutside ?? true
|
|
6176
|
-
});
|
|
6177
|
-
}
|
|
6178
|
-
|
|
6179
6460
|
// src/components/shared/spinner.tsx
|
|
6180
6461
|
init_src();
|
|
6181
|
-
import { useState as useState2, useEffect as
|
|
6462
|
+
import { useState as useState2, useEffect as useEffect4 } from "react";
|
|
6182
6463
|
import { jsxDEV as jsxDEV6 } from "@opentui/react/jsx-dev-runtime";
|
|
6183
6464
|
var SPINNER_FRAMES = ["\u280B", "\u2819", "\u2839", "\u2838", "\u283C", "\u2834", "\u2826", "\u2827", "\u2807", "\u280F"];
|
|
6184
6465
|
function Spinner({
|
|
@@ -6186,7 +6467,7 @@ function Spinner({
|
|
|
6186
6467
|
color = Colors.highlight
|
|
6187
6468
|
}) {
|
|
6188
6469
|
const [frame, setFrame] = useState2(0);
|
|
6189
|
-
|
|
6470
|
+
useEffect4(() => {
|
|
6190
6471
|
if (globalThis.IS_REACT_ACT_ENVIRONMENT === true) {
|
|
6191
6472
|
return;
|
|
6192
6473
|
}
|
|
@@ -6245,7 +6526,7 @@ function EmptyState({
|
|
|
6245
6526
|
|
|
6246
6527
|
// src/components/views/dashboard/auto-repair-panel.tsx
|
|
6247
6528
|
init_src();
|
|
6248
|
-
import { useMemo } from "react";
|
|
6529
|
+
import { useMemo as useMemo2 } from "react";
|
|
6249
6530
|
import { jsxDEV as jsxDEV7, Fragment } from "@opentui/react/jsx-dev-runtime";
|
|
6250
6531
|
function RepairStatusBadge({
|
|
6251
6532
|
status
|
|
@@ -6275,7 +6556,7 @@ function AutoRepairPanel({
|
|
|
6275
6556
|
onDismiss,
|
|
6276
6557
|
onRerun
|
|
6277
6558
|
}) {
|
|
6278
|
-
const resultCounts =
|
|
6559
|
+
const resultCounts = useMemo2(() => {
|
|
6279
6560
|
if (state.kind !== "results")
|
|
6280
6561
|
return { applied: 0, failed: 0 };
|
|
6281
6562
|
let applied = 0;
|
|
@@ -6443,7 +6724,7 @@ function AutoRepairPanel({
|
|
|
6443
6724
|
|
|
6444
6725
|
// src/components/views/dashboard/model-health-section.tsx
|
|
6445
6726
|
init_src();
|
|
6446
|
-
import { useState as useState3, useCallback, useEffect as
|
|
6727
|
+
import { useState as useState3, useCallback as useCallback2, useEffect as useEffect5 } from "react";
|
|
6447
6728
|
import { jsxDEV as jsxDEV8 } from "@opentui/react/jsx-dev-runtime";
|
|
6448
6729
|
var MODEL_HEALTH_POLL_MS = 30000;
|
|
6449
6730
|
function modelStatusToDot(status) {
|
|
@@ -6551,7 +6832,7 @@ function ModelHealthSection() {
|
|
|
6551
6832
|
const [loading, setLoading] = useState3(true);
|
|
6552
6833
|
const [error, setError] = useState3(null);
|
|
6553
6834
|
const [lastRefresh, setLastRefresh] = useState3(null);
|
|
6554
|
-
|
|
6835
|
+
useEffect5(() => {
|
|
6555
6836
|
let cancelled = false;
|
|
6556
6837
|
let generation = 0;
|
|
6557
6838
|
let inFlight = false;
|
|
@@ -6590,7 +6871,7 @@ function ModelHealthSection() {
|
|
|
6590
6871
|
clearInterval(interval);
|
|
6591
6872
|
};
|
|
6592
6873
|
}, []);
|
|
6593
|
-
const toggleExpand =
|
|
6874
|
+
const toggleExpand = useCallback2((index) => {
|
|
6594
6875
|
setExpandedIndex((prev) => prev === index ? null : index);
|
|
6595
6876
|
}, []);
|
|
6596
6877
|
if (loading && providers.length === 0) {
|
|
@@ -6708,7 +6989,7 @@ function ModelHealthSection() {
|
|
|
6708
6989
|
|
|
6709
6990
|
// src/components/views/dashboard/pyne-health-section.tsx
|
|
6710
6991
|
init_src();
|
|
6711
|
-
import { useState as useState4, useEffect as
|
|
6992
|
+
import { useState as useState4, useEffect as useEffect6 } from "react";
|
|
6712
6993
|
import { jsxDEV as jsxDEV9 } from "@opentui/react/jsx-dev-runtime";
|
|
6713
6994
|
var POLL_MS = 30000;
|
|
6714
6995
|
function statusToDot(status) {
|
|
@@ -6721,7 +7002,7 @@ function statusToDot(status) {
|
|
|
6721
7002
|
function PyneHealthSection() {
|
|
6722
7003
|
const [result, setResult] = useState4(null);
|
|
6723
7004
|
const [loading, setLoading] = useState4(true);
|
|
6724
|
-
|
|
7005
|
+
useEffect6(() => {
|
|
6725
7006
|
let cancelled = false;
|
|
6726
7007
|
let generation = 0;
|
|
6727
7008
|
let inFlight = false;
|
|
@@ -6821,7 +7102,7 @@ function PyneHealthSection() {
|
|
|
6821
7102
|
|
|
6822
7103
|
// src/components/views/dashboard/alerts-panel.tsx
|
|
6823
7104
|
init_src();
|
|
6824
|
-
import { useState as useState5, useMemo as
|
|
7105
|
+
import { useState as useState5, useMemo as useMemo3, useEffect as useEffect7 } from "react";
|
|
6825
7106
|
import { jsxDEV as jsxDEV10 } from "@opentui/react/jsx-dev-runtime";
|
|
6826
7107
|
var SEVERITY_LABEL = {
|
|
6827
7108
|
info: "INFO",
|
|
@@ -6843,10 +7124,10 @@ function AlertsPanel() {
|
|
|
6843
7124
|
const activeView = useUIStore((s) => s.activeView);
|
|
6844
7125
|
const isActive = activeView === "dashboard";
|
|
6845
7126
|
const [scrollOffset, setScrollOffset] = useState5(0);
|
|
6846
|
-
const sortedAlerts =
|
|
7127
|
+
const sortedAlerts = useMemo3(() => {
|
|
6847
7128
|
return [...alerts].sort((a, b) => b.timestamp - a.timestamp).slice(0, MAX_VISIBLE_ALERTS);
|
|
6848
7129
|
}, [alerts]);
|
|
6849
|
-
|
|
7130
|
+
useEffect7(() => {
|
|
6850
7131
|
setScrollOffset((o) => Math.min(o, Math.max(0, sortedAlerts.length - 1)));
|
|
6851
7132
|
}, [sortedAlerts.length]);
|
|
6852
7133
|
useViewKeyboard((key) => {
|
|
@@ -6982,7 +7263,7 @@ function formatStatNumber(value, isPnl = false) {
|
|
|
6982
7263
|
var KILL_SWITCH_POLL_MS = 15000;
|
|
6983
7264
|
function KillSwitchStatusBadge() {
|
|
6984
7265
|
const [state, setState] = useState6("unknown");
|
|
6985
|
-
|
|
7266
|
+
useEffect8(() => {
|
|
6986
7267
|
let cancelled = false;
|
|
6987
7268
|
const refresh = async () => {
|
|
6988
7269
|
try {
|
|
@@ -7083,12 +7364,12 @@ function ServiceHealthGrid() {
|
|
|
7083
7364
|
const activeView = useUIStore((s) => s.activeView);
|
|
7084
7365
|
const isActive = activeView === "dashboard";
|
|
7085
7366
|
const [focusIndex, setFocusIndex] = useState6(0);
|
|
7086
|
-
const visibleWorkers =
|
|
7087
|
-
const emptySlots =
|
|
7088
|
-
|
|
7367
|
+
const visibleWorkers = useMemo4(() => workers.slice(0, 10), [workers]);
|
|
7368
|
+
const emptySlots = useMemo4(() => visibleWorkers.length < 10 ? Array.from({ length: 10 - visibleWorkers.length }, (_, i) => i) : [], [visibleWorkers.length]);
|
|
7369
|
+
useEffect8(() => {
|
|
7089
7370
|
setFocusIndex((i) => visibleWorkers.length === 0 ? 0 : Math.min(i, visibleWorkers.length - 1));
|
|
7090
7371
|
}, [visibleWorkers.length]);
|
|
7091
|
-
const openWorker =
|
|
7372
|
+
const openWorker = useCallback3((workerId) => {
|
|
7092
7373
|
useServiceStore.getState().selectWorker(workerId);
|
|
7093
7374
|
useUIStore.getState().setView("worker-detail");
|
|
7094
7375
|
}, []);
|
|
@@ -7326,13 +7607,13 @@ function DashboardView({ dialog } = {}) {
|
|
|
7326
7607
|
const mountedRef = useRef3(true);
|
|
7327
7608
|
const refreshGenRef = useRef3(0);
|
|
7328
7609
|
const repairRunningRef = useRef3(false);
|
|
7329
|
-
|
|
7610
|
+
useEffect8(() => {
|
|
7330
7611
|
mountedRef.current = true;
|
|
7331
7612
|
return () => {
|
|
7332
7613
|
mountedRef.current = false;
|
|
7333
7614
|
};
|
|
7334
7615
|
}, []);
|
|
7335
|
-
const handleRefresh =
|
|
7616
|
+
const handleRefresh = useCallback3(async () => {
|
|
7336
7617
|
const gen = ++refreshGenRef.current;
|
|
7337
7618
|
try {
|
|
7338
7619
|
const result = await cliBridge.monitorStatus();
|
|
@@ -7344,7 +7625,7 @@ function DashboardView({ dialog } = {}) {
|
|
|
7344
7625
|
}
|
|
7345
7626
|
} catch {}
|
|
7346
7627
|
}, []);
|
|
7347
|
-
const handleRunAutoRepair =
|
|
7628
|
+
const handleRunAutoRepair = useCallback3(async () => {
|
|
7348
7629
|
if (!dialog) {
|
|
7349
7630
|
useServiceStore.getState().addAlert({
|
|
7350
7631
|
id: `repair-noconfirm-${Date.now()}`,
|
|
@@ -7431,10 +7712,10 @@ function DashboardView({ dialog } = {}) {
|
|
|
7431
7712
|
repairRunningRef.current = false;
|
|
7432
7713
|
}
|
|
7433
7714
|
}, [dialog]);
|
|
7434
|
-
const dismissRepairPanel =
|
|
7715
|
+
const dismissRepairPanel = useCallback3(() => {
|
|
7435
7716
|
setRepairState({ kind: "idle" });
|
|
7436
7717
|
}, []);
|
|
7437
|
-
const rerunRepair =
|
|
7718
|
+
const rerunRepair = useCallback3(() => {
|
|
7438
7719
|
handleRunAutoRepair();
|
|
7439
7720
|
}, [handleRunAutoRepair]);
|
|
7440
7721
|
useViewKeyboard((key) => {
|
|
@@ -7442,7 +7723,7 @@ function DashboardView({ dialog } = {}) {
|
|
|
7442
7723
|
dismissRepairPanel();
|
|
7443
7724
|
}
|
|
7444
7725
|
});
|
|
7445
|
-
|
|
7726
|
+
useEffect8(() => {
|
|
7446
7727
|
let cancelled = false;
|
|
7447
7728
|
const runHealthCheck = async () => {
|
|
7448
7729
|
try {
|
|
@@ -7519,7 +7800,7 @@ function DashboardView({ dialog } = {}) {
|
|
|
7519
7800
|
init_src();
|
|
7520
7801
|
init_src();
|
|
7521
7802
|
init_src();
|
|
7522
|
-
import { useState as useState7, useMemo as
|
|
7803
|
+
import { useState as useState7, useMemo as useMemo5, useCallback as useCallback4, useEffect as useEffect9, useRef as useRef4 } from "react";
|
|
7523
7804
|
|
|
7524
7805
|
// src/components/shared/panel.tsx
|
|
7525
7806
|
init_src();
|
|
@@ -7751,7 +8032,7 @@ function WorkersOverview({ dialog } = {}) {
|
|
|
7751
8032
|
const [deployProgress, setDeployProgress] = useState7("");
|
|
7752
8033
|
const mountedRef = useRef4(true);
|
|
7753
8034
|
const deployingRef = useRef4(false);
|
|
7754
|
-
|
|
8035
|
+
useEffect9(() => {
|
|
7755
8036
|
mountedRef.current = true;
|
|
7756
8037
|
return () => {
|
|
7757
8038
|
mountedRef.current = false;
|
|
@@ -7763,7 +8044,7 @@ function WorkersOverview({ dialog } = {}) {
|
|
|
7763
8044
|
const setView = useUIStore((s) => s.setView);
|
|
7764
8045
|
const [cliFallbackTried, setCliFallbackTried] = useState7(false);
|
|
7765
8046
|
const [cliFallbackError, setCliFallbackError] = useState7(null);
|
|
7766
|
-
|
|
8047
|
+
useEffect9(() => {
|
|
7767
8048
|
if (workers.length > 0) {
|
|
7768
8049
|
setCliFallbackTried(false);
|
|
7769
8050
|
setCliFallbackError(null);
|
|
@@ -7834,7 +8115,7 @@ function WorkersOverview({ dialog } = {}) {
|
|
|
7834
8115
|
};
|
|
7835
8116
|
}, [workers.length, cliFallbackTried]);
|
|
7836
8117
|
const maxIndex = Math.max(0, workers.length - 1);
|
|
7837
|
-
const rows =
|
|
8118
|
+
const rows = useMemo5(() => {
|
|
7838
8119
|
const result = [];
|
|
7839
8120
|
for (let i = 0;i < workers.length; i += COLS) {
|
|
7840
8121
|
result.push(workers.slice(i, i + COLS));
|
|
@@ -7842,7 +8123,7 @@ function WorkersOverview({ dialog } = {}) {
|
|
|
7842
8123
|
return result;
|
|
7843
8124
|
}, [workers]);
|
|
7844
8125
|
const safeIndex = Math.min(focusedIndex, maxIndex);
|
|
7845
|
-
|
|
8126
|
+
useEffect9(() => {
|
|
7846
8127
|
setFocusedIndex((i) => Math.min(i, maxIndex));
|
|
7847
8128
|
}, [maxIndex]);
|
|
7848
8129
|
useViewKeyboard((key) => {
|
|
@@ -7869,11 +8150,11 @@ function WorkersOverview({ dialog } = {}) {
|
|
|
7869
8150
|
}
|
|
7870
8151
|
}
|
|
7871
8152
|
});
|
|
7872
|
-
const onProgress =
|
|
8153
|
+
const onProgress = useCallback4((chunk) => {
|
|
7873
8154
|
const safe = redactSecretsInText(chunk);
|
|
7874
8155
|
setDeployProgress((prev) => (prev + safe).slice(-2000));
|
|
7875
8156
|
}, []);
|
|
7876
|
-
const handleLogs =
|
|
8157
|
+
const handleLogs = useCallback4(async (worker) => {
|
|
7877
8158
|
if (deployingRef.current)
|
|
7878
8159
|
return;
|
|
7879
8160
|
const store = useServiceStore.getState();
|
|
@@ -7920,7 +8201,7 @@ function WorkersOverview({ dialog } = {}) {
|
|
|
7920
8201
|
});
|
|
7921
8202
|
}
|
|
7922
8203
|
}, []);
|
|
7923
|
-
const handleDeploy =
|
|
8204
|
+
const handleDeploy = useCallback4(async (worker) => {
|
|
7924
8205
|
if (deployingRef.current)
|
|
7925
8206
|
return;
|
|
7926
8207
|
if (!dialog) {
|
|
@@ -7978,7 +8259,7 @@ function WorkersOverview({ dialog } = {}) {
|
|
|
7978
8259
|
setDeployingWorker(null);
|
|
7979
8260
|
}
|
|
7980
8261
|
}, [onProgress, dialog]);
|
|
7981
|
-
const handleRestart =
|
|
8262
|
+
const handleRestart = useCallback4(async (worker) => {
|
|
7982
8263
|
if (deployingRef.current)
|
|
7983
8264
|
return;
|
|
7984
8265
|
if (!dialog) {
|
|
@@ -8202,7 +8483,7 @@ function WorkersOverview({ dialog } = {}) {
|
|
|
8202
8483
|
|
|
8203
8484
|
// src/components/views/worker-detail.tsx
|
|
8204
8485
|
init_src();
|
|
8205
|
-
import { useState as useState8, useMemo as
|
|
8486
|
+
import { useState as useState8, useMemo as useMemo6, useEffect as useEffect10, useCallback as useCallback5, useRef as useRef5 } from "react";
|
|
8206
8487
|
import { jsxDEV as jsxDEV14 } from "@opentui/react/jsx-dev-runtime";
|
|
8207
8488
|
var PANE_COUNT = 4;
|
|
8208
8489
|
var PANE_NAMES = [
|
|
@@ -8312,10 +8593,10 @@ function LogsPane({
|
|
|
8312
8593
|
focused
|
|
8313
8594
|
}) {
|
|
8314
8595
|
const allLogs = useServiceStore((s) => s.logs);
|
|
8315
|
-
const workerLogs =
|
|
8596
|
+
const workerLogs = useMemo6(() => allLogs.filter((l) => l.workerId === workerId), [allLogs, workerId]);
|
|
8316
8597
|
const [paused, setPaused] = useState8(false);
|
|
8317
8598
|
const [, setAutoScroll] = useState8(true);
|
|
8318
|
-
|
|
8599
|
+
useEffect10(() => {
|
|
8319
8600
|
if (!paused) {
|
|
8320
8601
|
setAutoScroll(true);
|
|
8321
8602
|
}
|
|
@@ -8327,7 +8608,7 @@ function LogsPane({
|
|
|
8327
8608
|
setPaused((p) => !p);
|
|
8328
8609
|
}
|
|
8329
8610
|
});
|
|
8330
|
-
const displayedLogs =
|
|
8611
|
+
const displayedLogs = useMemo6(() => {
|
|
8331
8612
|
const source = paused ? workerLogs : workerLogs.slice(-50);
|
|
8332
8613
|
return source;
|
|
8333
8614
|
}, [workerLogs, paused]);
|
|
@@ -8469,7 +8750,7 @@ function ConfigPreviewPane({
|
|
|
8469
8750
|
entries,
|
|
8470
8751
|
loading
|
|
8471
8752
|
}) {
|
|
8472
|
-
const displayEntries =
|
|
8753
|
+
const displayEntries = useMemo6(() => {
|
|
8473
8754
|
if (entries && entries.length > 0)
|
|
8474
8755
|
return entries;
|
|
8475
8756
|
return [
|
|
@@ -8551,7 +8832,7 @@ function WorkerDetail() {
|
|
|
8551
8832
|
const mountedRef = useRef5(true);
|
|
8552
8833
|
const configGenRef = useRef5(0);
|
|
8553
8834
|
const logsGenRef = useRef5(0);
|
|
8554
|
-
|
|
8835
|
+
useEffect10(() => {
|
|
8555
8836
|
mountedRef.current = true;
|
|
8556
8837
|
return () => {
|
|
8557
8838
|
mountedRef.current = false;
|
|
@@ -8561,8 +8842,8 @@ function WorkerDetail() {
|
|
|
8561
8842
|
const workers = useServiceStore((s) => s.workers);
|
|
8562
8843
|
const connectionStatus = useServiceStore((s) => s.connectionStatus);
|
|
8563
8844
|
const goBack = useUIStore((s) => s.goBack);
|
|
8564
|
-
const worker =
|
|
8565
|
-
const fetchConfig =
|
|
8845
|
+
const worker = useMemo6(() => workers.find((w) => w.id === selectedWorkerId) ?? null, [workers, selectedWorkerId]);
|
|
8846
|
+
const fetchConfig = useCallback5(async () => {
|
|
8566
8847
|
if (!worker)
|
|
8567
8848
|
return;
|
|
8568
8849
|
const gen = ++configGenRef.current;
|
|
@@ -8602,7 +8883,7 @@ function WorkerDetail() {
|
|
|
8602
8883
|
}
|
|
8603
8884
|
}
|
|
8604
8885
|
}, [worker]);
|
|
8605
|
-
const fetchLogs =
|
|
8886
|
+
const fetchLogs = useCallback5(async () => {
|
|
8606
8887
|
if (!worker)
|
|
8607
8888
|
return;
|
|
8608
8889
|
const gen = ++logsGenRef.current;
|
|
@@ -8646,10 +8927,10 @@ function WorkerDetail() {
|
|
|
8646
8927
|
}
|
|
8647
8928
|
}
|
|
8648
8929
|
}, [worker]);
|
|
8649
|
-
|
|
8930
|
+
useEffect10(() => {
|
|
8650
8931
|
fetchConfig();
|
|
8651
8932
|
}, [fetchConfig]);
|
|
8652
|
-
|
|
8933
|
+
useEffect10(() => {
|
|
8653
8934
|
if (connectionStatus !== "connected") {
|
|
8654
8935
|
fetchLogs();
|
|
8655
8936
|
return;
|
|
@@ -8659,7 +8940,7 @@ function WorkerDetail() {
|
|
|
8659
8940
|
fetchLogs();
|
|
8660
8941
|
}
|
|
8661
8942
|
}, [connectionStatus, fetchLogs, worker]);
|
|
8662
|
-
const handleRefresh =
|
|
8943
|
+
const handleRefresh = useCallback5(() => {
|
|
8663
8944
|
fetchConfig();
|
|
8664
8945
|
fetchLogs();
|
|
8665
8946
|
}, [fetchConfig, fetchLogs]);
|
|
@@ -8814,7 +9095,7 @@ function WorkerDetail() {
|
|
|
8814
9095
|
|
|
8815
9096
|
// src/components/views/trade-monitor.tsx
|
|
8816
9097
|
init_src();
|
|
8817
|
-
import { useState as useState9, useMemo as
|
|
9098
|
+
import { useState as useState9, useMemo as useMemo7, useRef as useRef6, useEffect as useEffect11 } from "react";
|
|
8818
9099
|
import { jsxDEV as jsxDEV15, Fragment as Fragment2 } from "@opentui/react/jsx-dev-runtime";
|
|
8819
9100
|
var MAX_VISIBLE_TRADES = 120;
|
|
8820
9101
|
var SIDE_COLOR = {
|
|
@@ -8937,7 +9218,7 @@ function LiveTradeFeed({
|
|
|
8937
9218
|
const [selectedIndex, setSelectedIndex] = useState9(0);
|
|
8938
9219
|
const frozenRef = useRef6([]);
|
|
8939
9220
|
const [frozenStream, setFrozenStream] = useState9(null);
|
|
8940
|
-
|
|
9221
|
+
useEffect11(() => {
|
|
8941
9222
|
if (paused) {
|
|
8942
9223
|
frozenRef.current = [...tradeStream];
|
|
8943
9224
|
setFrozenStream(frozenRef.current);
|
|
@@ -8947,9 +9228,9 @@ function LiveTradeFeed({
|
|
|
8947
9228
|
}
|
|
8948
9229
|
}, [paused]);
|
|
8949
9230
|
const effectiveStream = paused ? frozenStream ?? frozenRef.current : tradeStream;
|
|
8950
|
-
const sortedTrades =
|
|
9231
|
+
const sortedTrades = useMemo7(() => selectVisibleTrades(effectiveStream, MAX_VISIBLE_TRADES), [effectiveStream]);
|
|
8951
9232
|
const maxIndex = Math.max(0, sortedTrades.length - 1);
|
|
8952
|
-
|
|
9233
|
+
useEffect11(() => {
|
|
8953
9234
|
setSelectedIndex((i) => Math.min(i, maxIndex));
|
|
8954
9235
|
}, [maxIndex]);
|
|
8955
9236
|
const safeIndex = Math.min(selectedIndex, maxIndex);
|
|
@@ -9102,7 +9383,7 @@ function LiveTradeFeed({
|
|
|
9102
9383
|
}
|
|
9103
9384
|
function OpenPositions() {
|
|
9104
9385
|
const tradeStream = useServiceStore((s) => s.tradeStream);
|
|
9105
|
-
const positions =
|
|
9386
|
+
const positions = useMemo7(() => {
|
|
9106
9387
|
const map = new Map;
|
|
9107
9388
|
for (const trade of tradeStream) {
|
|
9108
9389
|
const existing = map.get(trade.symbol);
|
|
@@ -9227,7 +9508,7 @@ function OpenPositions() {
|
|
|
9227
9508
|
function PerformanceSummary() {
|
|
9228
9509
|
const tradeStream = useServiceStore((s) => s.tradeStream);
|
|
9229
9510
|
const metrics = useServiceStore((s) => s.metrics);
|
|
9230
|
-
const perf =
|
|
9511
|
+
const perf = useMemo7(() => {
|
|
9231
9512
|
const todayStart = startOfToday();
|
|
9232
9513
|
const weekStart = startOfDaysAgo(7);
|
|
9233
9514
|
const monthStart = startOfDaysAgo(30);
|
|
@@ -9436,7 +9717,7 @@ function TradeMonitor() {
|
|
|
9436
9717
|
|
|
9437
9718
|
// src/components/views/logs-viewer.tsx
|
|
9438
9719
|
init_src();
|
|
9439
|
-
import { useState as useState10, useMemo as
|
|
9720
|
+
import { useState as useState10, useMemo as useMemo8, useCallback as useCallback6, useEffect as useEffect12, useRef as useRef7 } from "react";
|
|
9440
9721
|
import { jsxDEV as jsxDEV16 } from "@opentui/react/jsx-dev-runtime";
|
|
9441
9722
|
var LEVEL_LABEL = {
|
|
9442
9723
|
error: "ERR",
|
|
@@ -9727,7 +10008,7 @@ function LogsViewer() {
|
|
|
9727
10008
|
const activeView = useUIStore((s) => s.activeView);
|
|
9728
10009
|
const isActive = activeView === "logs-viewer";
|
|
9729
10010
|
const sseConnected = connectionStatus === "connected";
|
|
9730
|
-
|
|
10011
|
+
useEffect12(() => {
|
|
9731
10012
|
if (searchTimerRef.current)
|
|
9732
10013
|
clearTimeout(searchTimerRef.current);
|
|
9733
10014
|
searchTimerRef.current = setTimeout(() => {
|
|
@@ -9741,11 +10022,11 @@ function LogsViewer() {
|
|
|
9741
10022
|
}
|
|
9742
10023
|
};
|
|
9743
10024
|
}, [searchText]);
|
|
9744
|
-
const workerNames =
|
|
9745
|
-
const toggleAll =
|
|
10025
|
+
const workerNames = useMemo8(() => workers.map((w) => w.name), [workers]);
|
|
10026
|
+
const toggleAll = useCallback6(() => {
|
|
9746
10027
|
setAllLevels((prev) => !prev);
|
|
9747
10028
|
}, []);
|
|
9748
|
-
const toggleLevel =
|
|
10029
|
+
const toggleLevel = useCallback6((lvl) => {
|
|
9749
10030
|
setLevels((prev) => {
|
|
9750
10031
|
const next = new Set(prev);
|
|
9751
10032
|
if (next.has(lvl))
|
|
@@ -9755,7 +10036,7 @@ function LogsViewer() {
|
|
|
9755
10036
|
return next;
|
|
9756
10037
|
});
|
|
9757
10038
|
}, []);
|
|
9758
|
-
const toggleWorker =
|
|
10039
|
+
const toggleWorker = useCallback6((name) => {
|
|
9759
10040
|
setSelectedWorkers((prev) => {
|
|
9760
10041
|
const next = new Set(prev);
|
|
9761
10042
|
if (next.has(name))
|
|
@@ -9765,7 +10046,7 @@ function LogsViewer() {
|
|
|
9765
10046
|
return next;
|
|
9766
10047
|
});
|
|
9767
10048
|
}, []);
|
|
9768
|
-
const handleExport =
|
|
10049
|
+
const handleExport = useCallback6(async () => {
|
|
9769
10050
|
const ts = Date.now();
|
|
9770
10051
|
try {
|
|
9771
10052
|
const result = await cliBridge.exec(["logs", "all"], {
|
|
@@ -9805,7 +10086,7 @@ function LogsViewer() {
|
|
|
9805
10086
|
}, []);
|
|
9806
10087
|
const [clearArmed, setClearArmed] = useState10(false);
|
|
9807
10088
|
const clearArmTimer = useRef7(null);
|
|
9808
|
-
const handleClear =
|
|
10089
|
+
const handleClear = useCallback6(() => {
|
|
9809
10090
|
if (!clearArmed) {
|
|
9810
10091
|
setClearArmed(true);
|
|
9811
10092
|
if (clearArmTimer.current)
|
|
@@ -9837,7 +10118,7 @@ function LogsViewer() {
|
|
|
9837
10118
|
acknowledged: false
|
|
9838
10119
|
});
|
|
9839
10120
|
}, [clearArmed]);
|
|
9840
|
-
const handleFetch =
|
|
10121
|
+
const handleFetch = useCallback6(async () => {
|
|
9841
10122
|
const ts = Date.now();
|
|
9842
10123
|
let fetchedCount = 0;
|
|
9843
10124
|
const names = useServiceStore.getState().workers.map((w) => w.name);
|
|
@@ -9866,20 +10147,20 @@ function LogsViewer() {
|
|
|
9866
10147
|
};
|
|
9867
10148
|
useServiceStore.getState().addAlert(alert);
|
|
9868
10149
|
}, []);
|
|
9869
|
-
const filteredLogs =
|
|
10150
|
+
const filteredLogs = useMemo8(() => applyLogFilters(allLogs, {
|
|
9870
10151
|
allLevels,
|
|
9871
10152
|
levels,
|
|
9872
10153
|
selectedWorkers,
|
|
9873
10154
|
searchText: debouncedSearch,
|
|
9874
10155
|
workers
|
|
9875
10156
|
}), [allLogs, allLevels, levels, selectedWorkers, debouncedSearch, workers]);
|
|
9876
|
-
const displayed =
|
|
10157
|
+
const displayed = useMemo8(() => {
|
|
9877
10158
|
const newestFirst = filteredLogs.slice().reverse();
|
|
9878
10159
|
return newestFirst.slice(0, MAX_VISIBLE_LOGS);
|
|
9879
10160
|
}, [filteredLogs]);
|
|
9880
10161
|
const [frozen, setFrozen] = useState10(null);
|
|
9881
10162
|
const visible = paused && frozen !== null ? frozen : displayed;
|
|
9882
|
-
|
|
10163
|
+
useEffect12(() => {
|
|
9883
10164
|
if (paused && frozen === null) {
|
|
9884
10165
|
setFrozen(displayed);
|
|
9885
10166
|
}
|
|
@@ -9994,7 +10275,7 @@ function LogsViewer() {
|
|
|
9994
10275
|
// src/components/views/service-manager.tsx
|
|
9995
10276
|
init_service_store();
|
|
9996
10277
|
init_src();
|
|
9997
|
-
import { useState as useState11, useCallback as
|
|
10278
|
+
import { useState as useState11, useCallback as useCallback7, useEffect as useEffect13, useMemo as useMemo9, useRef as useRef8 } from "react";
|
|
9998
10279
|
import { jsxDEV as jsxDEV17 } from "@opentui/react/jsx-dev-runtime";
|
|
9999
10280
|
var EDGE_LOCATIONS = [
|
|
10000
10281
|
{ code: "SFO", city: "San Francisco", x: 4, y: 3, latency: 2 },
|
|
@@ -10025,7 +10306,7 @@ var EDGE_LOCATION_BY_CELL = (() => {
|
|
|
10025
10306
|
})();
|
|
10026
10307
|
function EdgeMap() {
|
|
10027
10308
|
const [selectedCode, setSelectedCode] = useState11(null);
|
|
10028
|
-
const selectedLocation =
|
|
10309
|
+
const selectedLocation = useMemo9(() => EDGE_LOCATIONS.find((l) => l.code === selectedCode) ?? null, [selectedCode]);
|
|
10029
10310
|
return /* @__PURE__ */ jsxDEV17("box", {
|
|
10030
10311
|
flexDirection: "column",
|
|
10031
10312
|
flexGrow: 1,
|
|
@@ -10354,13 +10635,13 @@ function KillSwitchSection({ dialog, onAlert }) {
|
|
|
10354
10635
|
const loadingRef = useRef8(false);
|
|
10355
10636
|
const activeView = useUIStore((s) => s.activeView);
|
|
10356
10637
|
const isActive = activeView === "service-manager";
|
|
10357
|
-
|
|
10638
|
+
useEffect13(() => {
|
|
10358
10639
|
mountedRef.current = true;
|
|
10359
10640
|
return () => {
|
|
10360
10641
|
mountedRef.current = false;
|
|
10361
10642
|
};
|
|
10362
10643
|
}, []);
|
|
10363
|
-
const refresh =
|
|
10644
|
+
const refresh = useCallback7(async () => {
|
|
10364
10645
|
if (loadingRef.current)
|
|
10365
10646
|
return;
|
|
10366
10647
|
loadingRef.current = true;
|
|
@@ -10386,10 +10667,10 @@ function KillSwitchSection({ dialog, onAlert }) {
|
|
|
10386
10667
|
setLoading(false);
|
|
10387
10668
|
}
|
|
10388
10669
|
}, []);
|
|
10389
|
-
|
|
10670
|
+
useEffect13(() => {
|
|
10390
10671
|
refresh();
|
|
10391
10672
|
}, [refresh]);
|
|
10392
|
-
const setEngaged =
|
|
10673
|
+
const setEngaged = useCallback7(async (engaged2) => {
|
|
10393
10674
|
if (!dialog) {
|
|
10394
10675
|
useServiceStore.getState().addAlert({
|
|
10395
10676
|
id: `killswitch-noconfirm-${Date.now()}`,
|
|
@@ -10563,23 +10844,23 @@ function ServiceManager({ dialog }) {
|
|
|
10563
10844
|
const [selectedIndex, setSelectedIndex] = useState11(0);
|
|
10564
10845
|
const mountedRef = useRef8(true);
|
|
10565
10846
|
const deployingRef = useRef8(false);
|
|
10566
|
-
|
|
10847
|
+
useEffect13(() => {
|
|
10567
10848
|
mountedRef.current = true;
|
|
10568
10849
|
return () => {
|
|
10569
10850
|
mountedRef.current = false;
|
|
10570
10851
|
};
|
|
10571
10852
|
}, []);
|
|
10572
|
-
|
|
10853
|
+
useEffect13(() => {
|
|
10573
10854
|
setSelectedIndex((i) => workers.length === 0 ? 0 : Math.min(i, workers.length - 1));
|
|
10574
10855
|
}, [workers.length]);
|
|
10575
|
-
const totalEdgeCount =
|
|
10856
|
+
const totalEdgeCount = useMemo9(() => workers.reduce((sum, w) => sum + (w.edgeCount ?? 0), 0), [workers]);
|
|
10576
10857
|
const displayEdgeCount = totalEdgeCount;
|
|
10577
10858
|
const showPlus = false;
|
|
10578
|
-
const onProgress =
|
|
10859
|
+
const onProgress = useCallback7((chunk) => {
|
|
10579
10860
|
const safe = redactSecretsInText(chunk);
|
|
10580
10861
|
setDeployProgress((prev) => (prev + safe).slice(-2000));
|
|
10581
10862
|
}, []);
|
|
10582
|
-
const addResultAlert =
|
|
10863
|
+
const addResultAlert = useCallback7((id, type, result, successMsg, failMsg) => {
|
|
10583
10864
|
const store = useServiceStore.getState();
|
|
10584
10865
|
store.addAlert({
|
|
10585
10866
|
id,
|
|
@@ -10590,7 +10871,7 @@ function ServiceManager({ dialog }) {
|
|
|
10590
10871
|
acknowledged: false
|
|
10591
10872
|
});
|
|
10592
10873
|
}, []);
|
|
10593
|
-
const blockWithoutDialog =
|
|
10874
|
+
const blockWithoutDialog = useCallback7((action, target) => {
|
|
10594
10875
|
useServiceStore.getState().addAlert({
|
|
10595
10876
|
id: `${action}-noconfirm-${Date.now()}`,
|
|
10596
10877
|
type: action,
|
|
@@ -10600,7 +10881,7 @@ function ServiceManager({ dialog }) {
|
|
|
10600
10881
|
acknowledged: false
|
|
10601
10882
|
});
|
|
10602
10883
|
}, []);
|
|
10603
|
-
const handleDeploy =
|
|
10884
|
+
const handleDeploy = useCallback7(async (worker) => {
|
|
10604
10885
|
if (deployingRef.current)
|
|
10605
10886
|
return;
|
|
10606
10887
|
if (!dialog) {
|
|
@@ -10642,7 +10923,7 @@ function ServiceManager({ dialog }) {
|
|
|
10642
10923
|
setDeployingWorker(null);
|
|
10643
10924
|
}
|
|
10644
10925
|
}, [dialog, onProgress, addResultAlert, blockWithoutDialog]);
|
|
10645
|
-
const handleRestart =
|
|
10926
|
+
const handleRestart = useCallback7(async (worker) => {
|
|
10646
10927
|
if (deployingRef.current)
|
|
10647
10928
|
return;
|
|
10648
10929
|
if (!dialog) {
|
|
@@ -10684,7 +10965,7 @@ function ServiceManager({ dialog }) {
|
|
|
10684
10965
|
setDeployingWorker(null);
|
|
10685
10966
|
}
|
|
10686
10967
|
}, [dialog, onProgress, addResultAlert, blockWithoutDialog]);
|
|
10687
|
-
const handleDeployAll =
|
|
10968
|
+
const handleDeployAll = useCallback7(async () => {
|
|
10688
10969
|
if (deployingRef.current)
|
|
10689
10970
|
return;
|
|
10690
10971
|
if (!dialog) {
|
|
@@ -10726,7 +11007,7 @@ function ServiceManager({ dialog }) {
|
|
|
10726
11007
|
setDeployingWorker(null);
|
|
10727
11008
|
}
|
|
10728
11009
|
}, [dialog, workers.length, onProgress, addResultAlert, blockWithoutDialog]);
|
|
10729
|
-
const handleRestartAll =
|
|
11010
|
+
const handleRestartAll = useCallback7(async () => {
|
|
10730
11011
|
if (deployingRef.current)
|
|
10731
11012
|
return;
|
|
10732
11013
|
if (!dialog) {
|
|
@@ -10907,11 +11188,11 @@ function ServiceManager({ dialog }) {
|
|
|
10907
11188
|
init_src();
|
|
10908
11189
|
import { existsSync as existsSync5 } from "fs";
|
|
10909
11190
|
import { isAbsolute, relative, resolve as pathResolve } from "path";
|
|
10910
|
-
import { useState as useState12, useCallback as
|
|
11191
|
+
import { useState as useState12, useCallback as useCallback8, useMemo as useMemo12, useRef as useRef9, useEffect as useEffect14 } from "react";
|
|
10911
11192
|
|
|
10912
11193
|
// src/components/views/config-editor/file-tree.tsx
|
|
10913
11194
|
init_src();
|
|
10914
|
-
import { useMemo as
|
|
11195
|
+
import { useMemo as useMemo10 } from "react";
|
|
10915
11196
|
import { jsxDEV as jsxDEV18 } from "@opentui/react/jsx-dev-runtime";
|
|
10916
11197
|
function flattenTree(nodes, level = 0) {
|
|
10917
11198
|
const result = [];
|
|
@@ -10930,7 +11211,7 @@ function FileTree({
|
|
|
10930
11211
|
focusedPath,
|
|
10931
11212
|
onSelectFile
|
|
10932
11213
|
}) {
|
|
10933
|
-
const flatNodes =
|
|
11214
|
+
const flatNodes = useMemo10(() => flattenTree(nodes), [nodes]);
|
|
10934
11215
|
return /* @__PURE__ */ jsxDEV18("box", {
|
|
10935
11216
|
flexDirection: "column",
|
|
10936
11217
|
flexGrow: 1,
|
|
@@ -10986,7 +11267,7 @@ function FileTree({
|
|
|
10986
11267
|
|
|
10987
11268
|
// src/components/views/config-editor/code-editor.tsx
|
|
10988
11269
|
init_src();
|
|
10989
|
-
import { useMemo as
|
|
11270
|
+
import { useMemo as useMemo11 } from "react";
|
|
10990
11271
|
import { parse as parseToml, TomlError } from "smol-toml";
|
|
10991
11272
|
import { jsxDEV as jsxDEV19, Fragment as Fragment3 } from "@opentui/react/jsx-dev-runtime";
|
|
10992
11273
|
var TOML_COLORS = {
|
|
@@ -11298,11 +11579,11 @@ function CodeEditor({
|
|
|
11298
11579
|
scrollOffset: _scrollOffset,
|
|
11299
11580
|
maxDisplayLines = 5000
|
|
11300
11581
|
}) {
|
|
11301
|
-
const lines =
|
|
11582
|
+
const lines = useMemo11(() => content.split(`
|
|
11302
11583
|
`), [content]);
|
|
11303
11584
|
const truncated = lines.length > maxDisplayLines;
|
|
11304
|
-
const visibleLines =
|
|
11305
|
-
const errorLineSet =
|
|
11585
|
+
const visibleLines = useMemo11(() => truncated ? lines.slice(0, maxDisplayLines) : lines, [lines, maxDisplayLines, truncated]);
|
|
11586
|
+
const errorLineSet = useMemo11(() => {
|
|
11306
11587
|
const set = new Set;
|
|
11307
11588
|
for (const err of syntaxErrors)
|
|
11308
11589
|
set.add(err.line);
|
|
@@ -11725,8 +12006,8 @@ function ConfigEditor() {
|
|
|
11725
12006
|
const [validationError, setValidationError] = useState12(null);
|
|
11726
12007
|
const [undoStack, setUndoStack] = useState12([]);
|
|
11727
12008
|
const [redoStack, setRedoStack] = useState12([]);
|
|
11728
|
-
const fileTree =
|
|
11729
|
-
const flatFiles =
|
|
12009
|
+
const fileTree = useMemo12(() => CONFIG_TREE_BLUEPRINT, []);
|
|
12010
|
+
const flatFiles = useMemo12(() => {
|
|
11730
12011
|
const files = [];
|
|
11731
12012
|
function walk(nodes) {
|
|
11732
12013
|
for (const n of nodes) {
|
|
@@ -11744,7 +12025,7 @@ function ConfigEditor() {
|
|
|
11744
12025
|
const unsavedCount = unsavedPaths.size;
|
|
11745
12026
|
const safeFocusedIdx = Math.max(0, Math.min(focusedTreeIdx, flatFiles.length - 1));
|
|
11746
12027
|
const focusedFilePath = flatFiles[safeFocusedIdx]?.path ?? null;
|
|
11747
|
-
const selectFile =
|
|
12028
|
+
const selectFile = useCallback8(async (path2) => {
|
|
11748
12029
|
if (fileContents.has(path2)) {
|
|
11749
12030
|
setSelectedFile(path2);
|
|
11750
12031
|
setActivePane("editor");
|
|
@@ -11761,7 +12042,7 @@ function ConfigEditor() {
|
|
|
11761
12042
|
setStatusMessage(`Loaded: ${path2}`);
|
|
11762
12043
|
}, [fileContents]);
|
|
11763
12044
|
const prevContentRef = useRef9(currentContent);
|
|
11764
|
-
|
|
12045
|
+
useEffect14(() => {
|
|
11765
12046
|
if (!selectedFile || !currentContent)
|
|
11766
12047
|
return;
|
|
11767
12048
|
if (prevContentRef.current !== currentContent && prevContentRef.current !== "") {
|
|
@@ -11773,7 +12054,7 @@ function ConfigEditor() {
|
|
|
11773
12054
|
}
|
|
11774
12055
|
prevContentRef.current = currentContent;
|
|
11775
12056
|
}, [currentContent, selectedFile]);
|
|
11776
|
-
const handleSave =
|
|
12057
|
+
const handleSave = useCallback8(async () => {
|
|
11777
12058
|
if (!selectedFile)
|
|
11778
12059
|
return;
|
|
11779
12060
|
try {
|
|
@@ -11809,7 +12090,7 @@ function ConfigEditor() {
|
|
|
11809
12090
|
setStatusMessage(`Failed to save: ${msg}`);
|
|
11810
12091
|
}
|
|
11811
12092
|
}, [selectedFile, currentContent, fileType]);
|
|
11812
|
-
const handleValidate =
|
|
12093
|
+
const handleValidate = useCallback8(async () => {
|
|
11813
12094
|
if (!selectedFile)
|
|
11814
12095
|
return;
|
|
11815
12096
|
const errors = validateSyntax(currentContent, fileType);
|
|
@@ -11829,7 +12110,7 @@ function ConfigEditor() {
|
|
|
11829
12110
|
setStatusMessage("Validation passed \u2014 Config is valid");
|
|
11830
12111
|
}
|
|
11831
12112
|
}, [selectedFile, currentContent, fileType]);
|
|
11832
|
-
const handleDiff =
|
|
12113
|
+
const handleDiff = useCallback8(() => {
|
|
11833
12114
|
const original = selectedFile ? originalContents.get(selectedFile) ?? "" : "";
|
|
11834
12115
|
const origLines = original.split(`
|
|
11835
12116
|
`).length;
|
|
@@ -11842,7 +12123,7 @@ function ConfigEditor() {
|
|
|
11842
12123
|
setStatusMessage(`Diff: ${origLines} \u2192 ${currLines} lines (${diff > 0 ? "+" : ""}${diff})`);
|
|
11843
12124
|
}
|
|
11844
12125
|
}, [selectedFile, originalContents, currentContent]);
|
|
11845
|
-
const handleFormat =
|
|
12126
|
+
const handleFormat = useCallback8(() => {
|
|
11846
12127
|
if (!selectedFile)
|
|
11847
12128
|
return;
|
|
11848
12129
|
const formatted = formatContent(currentContent, fileType);
|
|
@@ -11852,7 +12133,7 @@ function ConfigEditor() {
|
|
|
11852
12133
|
}
|
|
11853
12134
|
setStatusMessage(`Formatted: ${selectedFile}`);
|
|
11854
12135
|
}, [selectedFile, currentContent, fileType]);
|
|
11855
|
-
const handleUndo =
|
|
12136
|
+
const handleUndo = useCallback8(() => {
|
|
11856
12137
|
if (undoStack.length === 0 || !selectedFile)
|
|
11857
12138
|
return;
|
|
11858
12139
|
const prev = undoStack[undoStack.length - 1];
|
|
@@ -11862,7 +12143,7 @@ function ConfigEditor() {
|
|
|
11862
12143
|
setUnsavedPaths((paths) => new Set(paths).add(selectedFile));
|
|
11863
12144
|
setStatusMessage("Undo");
|
|
11864
12145
|
}, [undoStack, currentContent, selectedFile]);
|
|
11865
|
-
const handleRedo =
|
|
12146
|
+
const handleRedo = useCallback8(() => {
|
|
11866
12147
|
if (redoStack.length === 0 || !selectedFile)
|
|
11867
12148
|
return;
|
|
11868
12149
|
const next = redoStack[redoStack.length - 1];
|
|
@@ -11874,7 +12155,7 @@ function ConfigEditor() {
|
|
|
11874
12155
|
}, [redoStack, currentContent, selectedFile]);
|
|
11875
12156
|
const [findMode, setFindMode] = useState12(false);
|
|
11876
12157
|
const [findQuery, setFindQuery] = useState12("");
|
|
11877
|
-
const handleFind =
|
|
12158
|
+
const handleFind = useCallback8(() => {
|
|
11878
12159
|
setFindMode((p) => !p);
|
|
11879
12160
|
if (!findMode) {
|
|
11880
12161
|
setFindQuery("");
|
|
@@ -12074,7 +12355,7 @@ function ConfigEditor() {
|
|
|
12074
12355
|
init_src();
|
|
12075
12356
|
init_src();
|
|
12076
12357
|
init_src();
|
|
12077
|
-
import { useState as useState13, useEffect as
|
|
12358
|
+
import { useState as useState13, useEffect as useEffect15, useCallback as useCallback9, useRef as useRef10 } from "react";
|
|
12078
12359
|
import { jsxDEV as jsxDEV22, Fragment as Fragment4 } from "@opentui/react/jsx-dev-runtime";
|
|
12079
12360
|
async function spawnVersion(cmd, flag) {
|
|
12080
12361
|
try {
|
|
@@ -12355,7 +12636,7 @@ function SetupWizard({ dialog }) {
|
|
|
12355
12636
|
const isActive = activeView === "setup-wizard";
|
|
12356
12637
|
const addAlert = useServiceStore((s) => s.addAlert);
|
|
12357
12638
|
const loadedRef = useRef10(false);
|
|
12358
|
-
const runChecks =
|
|
12639
|
+
const runChecks = useCallback9(async () => {
|
|
12359
12640
|
setPrereqsRunning(true);
|
|
12360
12641
|
setPrereqs([
|
|
12361
12642
|
{ label: "RUNTIME", checks: [await checkBun(), await checkGit()] },
|
|
@@ -12368,10 +12649,10 @@ function SetupWizard({ dialog }) {
|
|
|
12368
12649
|
]);
|
|
12369
12650
|
setPrereqsRunning(false);
|
|
12370
12651
|
}, []);
|
|
12371
|
-
|
|
12652
|
+
useEffect15(() => {
|
|
12372
12653
|
runChecks();
|
|
12373
12654
|
}, [runChecks]);
|
|
12374
|
-
|
|
12655
|
+
useEffect15(() => {
|
|
12375
12656
|
(async () => {
|
|
12376
12657
|
try {
|
|
12377
12658
|
const file = Bun.file("wrangler.jsonc");
|
|
@@ -12391,7 +12672,7 @@ function SetupWizard({ dialog }) {
|
|
|
12391
12672
|
} catch {}
|
|
12392
12673
|
})();
|
|
12393
12674
|
}, []);
|
|
12394
|
-
|
|
12675
|
+
useEffect15(() => {
|
|
12395
12676
|
(async () => {
|
|
12396
12677
|
try {
|
|
12397
12678
|
const f = Bun.file(WIZARD_SESSION_PATH);
|
|
@@ -13406,7 +13687,7 @@ Deploy error: ${err.message}
|
|
|
13406
13687
|
|
|
13407
13688
|
// src/components/views/settings.tsx
|
|
13408
13689
|
init_src();
|
|
13409
|
-
import { useMemo as
|
|
13690
|
+
import { useMemo as useMemo13, useState as useState14, useCallback as useCallback10, useEffect as useEffect16 } from "react";
|
|
13410
13691
|
import * as path2 from "path";
|
|
13411
13692
|
import * as os from "os";
|
|
13412
13693
|
import { jsxDEV as jsxDEV23, Fragment as Fragment5 } from "@opentui/react/jsx-dev-runtime";
|
|
@@ -13556,7 +13837,7 @@ function ThemePanel({
|
|
|
13556
13837
|
}) {
|
|
13557
13838
|
const refreshIntervalMs = useConfigStore((s) => s.refreshIntervalMs);
|
|
13558
13839
|
const defaultView = useConfigStore((s) => s.defaultView);
|
|
13559
|
-
const connection =
|
|
13840
|
+
const connection = useMemo13(() => {
|
|
13560
13841
|
let configFallback = {};
|
|
13561
13842
|
try {
|
|
13562
13843
|
const cfg = readConfigSync();
|
|
@@ -14098,12 +14379,12 @@ function SettingsView({ dialog } = {}) {
|
|
|
14098
14379
|
const resetDefaults = useConfigStore((s) => s.resetDefaults);
|
|
14099
14380
|
const toggleNotification = useConfigStore((s) => s.toggleNotification);
|
|
14100
14381
|
const soundEnabled = useConfigStore((s) => s.soundEnabled);
|
|
14101
|
-
|
|
14382
|
+
useEffect16(() => {
|
|
14102
14383
|
if (theme === "light") {
|
|
14103
14384
|
updateConfig({ theme: "dark" });
|
|
14104
14385
|
}
|
|
14105
14386
|
}, [theme, updateConfig]);
|
|
14106
|
-
const confirmAction =
|
|
14387
|
+
const confirmAction = useCallback10(async (title, message, confirmLabel) => {
|
|
14107
14388
|
if (!dialog) {
|
|
14108
14389
|
useServiceStore.getState().addAlert({
|
|
14109
14390
|
id: `settings-noconfirm-${Date.now()}`,
|
|
@@ -14122,7 +14403,7 @@ function SettingsView({ dialog } = {}) {
|
|
|
14122
14403
|
cancelLabel: "Cancel"
|
|
14123
14404
|
});
|
|
14124
14405
|
}, [dialog]);
|
|
14125
|
-
const handleClearCache =
|
|
14406
|
+
const handleClearCache = useCallback10(async () => {
|
|
14126
14407
|
const ok = await confirmAction("Clear Cache?", "Delete ~/.hoox/cache? This cannot be undone.", "Clear Cache");
|
|
14127
14408
|
if (!ok)
|
|
14128
14409
|
return;
|
|
@@ -14149,7 +14430,7 @@ function SettingsView({ dialog } = {}) {
|
|
|
14149
14430
|
});
|
|
14150
14431
|
}
|
|
14151
14432
|
}, [confirmAction]);
|
|
14152
|
-
const handleExportData =
|
|
14433
|
+
const handleExportData = useCallback10(async () => {
|
|
14153
14434
|
try {
|
|
14154
14435
|
const result = await cliBridge2().configShow();
|
|
14155
14436
|
if (!result.success) {
|
|
@@ -14185,11 +14466,11 @@ function SettingsView({ dialog } = {}) {
|
|
|
14185
14466
|
});
|
|
14186
14467
|
}
|
|
14187
14468
|
}, []);
|
|
14188
|
-
const handleImportData =
|
|
14469
|
+
const handleImportData = useCallback10(async () => {
|
|
14189
14470
|
setImporting(true);
|
|
14190
14471
|
setImportPath("");
|
|
14191
14472
|
}, []);
|
|
14192
|
-
const handleImportConfirm =
|
|
14473
|
+
const handleImportConfirm = useCallback10(async () => {
|
|
14193
14474
|
if (!importPath.trim())
|
|
14194
14475
|
return;
|
|
14195
14476
|
if (!dialog) {
|
|
@@ -14277,7 +14558,7 @@ function SettingsView({ dialog } = {}) {
|
|
|
14277
14558
|
setImporting(false);
|
|
14278
14559
|
setImportPath("");
|
|
14279
14560
|
}, [importPath, updateConfig, dialog]);
|
|
14280
|
-
const handleCheckSetup =
|
|
14561
|
+
const handleCheckSetup = useCallback10(async () => {
|
|
14281
14562
|
setSetupCheck({ kind: "running" });
|
|
14282
14563
|
try {
|
|
14283
14564
|
const result = await cliBridge2().checkSetup();
|
|
@@ -14340,10 +14621,10 @@ function SettingsView({ dialog } = {}) {
|
|
|
14340
14621
|
});
|
|
14341
14622
|
}
|
|
14342
14623
|
}, []);
|
|
14343
|
-
const dismissCheckSetup =
|
|
14624
|
+
const dismissCheckSetup = useCallback10(() => {
|
|
14344
14625
|
setSetupCheck({ kind: "idle" });
|
|
14345
14626
|
}, []);
|
|
14346
|
-
const handleRunAutoRepair =
|
|
14627
|
+
const handleRunAutoRepair = useCallback10(async () => {
|
|
14347
14628
|
const ok = await confirmAction("Run Auto-Repair?", "Apply non-destructive config fixes (placeholders, flags, worker configs). Continue?", "Run Repair");
|
|
14348
14629
|
if (!ok)
|
|
14349
14630
|
return;
|
|
@@ -14394,7 +14675,7 @@ function SettingsView({ dialog } = {}) {
|
|
|
14394
14675
|
});
|
|
14395
14676
|
}
|
|
14396
14677
|
}, [confirmAction]);
|
|
14397
|
-
const handleResetDefaults =
|
|
14678
|
+
const handleResetDefaults = useCallback10(async () => {
|
|
14398
14679
|
const ok = await confirmAction("Reset Defaults?", "Reset theme, refresh rate, default view, and notification preferences to factory defaults?", "Reset");
|
|
14399
14680
|
if (!ok)
|
|
14400
14681
|
return;
|
|
@@ -14408,13 +14689,13 @@ function SettingsView({ dialog } = {}) {
|
|
|
14408
14689
|
acknowledged: false
|
|
14409
14690
|
});
|
|
14410
14691
|
}, [confirmAction, resetDefaults]);
|
|
14411
|
-
|
|
14692
|
+
useEffect16(() => {
|
|
14412
14693
|
const g = globalThis;
|
|
14413
14694
|
if (g.__hooxTestAutoCheckSetup) {
|
|
14414
14695
|
handleCheckSetup();
|
|
14415
14696
|
}
|
|
14416
14697
|
}, []);
|
|
14417
|
-
const maxItemsPerPanel =
|
|
14698
|
+
const maxItemsPerPanel = useMemo13(() => {
|
|
14418
14699
|
return {
|
|
14419
14700
|
0: THEME_ITEM_COUNT,
|
|
14420
14701
|
1: NOTIF_ITEM_COUNT,
|
|
@@ -14642,7 +14923,7 @@ function SettingsView({ dialog } = {}) {
|
|
|
14642
14923
|
|
|
14643
14924
|
// src/components/views/queue-depth.tsx
|
|
14644
14925
|
init_src();
|
|
14645
|
-
import { useCallback as
|
|
14926
|
+
import { useCallback as useCallback11, useEffect as useEffect17, useMemo as useMemo14, useRef as useRef11, useState as useState15 } from "react";
|
|
14646
14927
|
import { jsxDEV as jsxDEV24 } from "@opentui/react/jsx-dev-runtime";
|
|
14647
14928
|
var REFRESH_INTERVAL_MS = 5000;
|
|
14648
14929
|
var STATUS_RANK = {
|
|
@@ -14825,7 +15106,7 @@ function QueueDepthView() {
|
|
|
14825
15106
|
const [error, setError] = useState15(null);
|
|
14826
15107
|
const [lastSampledAt, setLastSampledAt] = useState15(null);
|
|
14827
15108
|
const fetchGenRef = useRef11(0);
|
|
14828
|
-
const refresh =
|
|
15109
|
+
const refresh = useCallback11(async (opts) => {
|
|
14829
15110
|
const soft = opts?.soft === true;
|
|
14830
15111
|
const gen = ++fetchGenRef.current;
|
|
14831
15112
|
if (!soft)
|
|
@@ -14843,13 +15124,13 @@ function QueueDepthView() {
|
|
|
14843
15124
|
if (!soft || gen === fetchGenRef.current)
|
|
14844
15125
|
setLoading(false);
|
|
14845
15126
|
}, []);
|
|
14846
|
-
|
|
15127
|
+
useEffect17(() => {
|
|
14847
15128
|
refresh({ soft: false });
|
|
14848
15129
|
return () => {
|
|
14849
15130
|
fetchGenRef.current += 1;
|
|
14850
15131
|
};
|
|
14851
15132
|
}, [refresh]);
|
|
14852
|
-
|
|
15133
|
+
useEffect17(() => {
|
|
14853
15134
|
if (!isActive)
|
|
14854
15135
|
return;
|
|
14855
15136
|
const handle = setInterval(() => {
|
|
@@ -14864,7 +15145,7 @@ function QueueDepthView() {
|
|
|
14864
15145
|
refresh({ soft: false });
|
|
14865
15146
|
}
|
|
14866
15147
|
});
|
|
14867
|
-
const sortedQueues =
|
|
15148
|
+
const sortedQueues = useMemo14(() => sortQueuesByPressure(queues), [queues]);
|
|
14868
15149
|
return /* @__PURE__ */ jsxDEV24(ErrorBoundary, {
|
|
14869
15150
|
viewName: "Queue Depth",
|
|
14870
15151
|
children: /* @__PURE__ */ jsxDEV24("box", {
|
|
@@ -15011,7 +15292,7 @@ function QueueDepthView() {
|
|
|
15011
15292
|
|
|
15012
15293
|
// src/components/views/kv-viewer.tsx
|
|
15013
15294
|
init_src();
|
|
15014
|
-
import { useCallback as
|
|
15295
|
+
import { useCallback as useCallback12, useEffect as useEffect18, useMemo as useMemo15, useRef as useRef12, useState as useState16 } from "react";
|
|
15015
15296
|
import { jsxDEV as jsxDEV25 } from "@opentui/react/jsx-dev-runtime";
|
|
15016
15297
|
var REFRESH_INTERVAL_MS2 = 5000;
|
|
15017
15298
|
var MAX_VISIBLE_KEYS = 200;
|
|
@@ -15311,7 +15592,7 @@ function KvViewer() {
|
|
|
15311
15592
|
const [valueError, setValueError] = useState16(null);
|
|
15312
15593
|
const listGenRef = useRef12(0);
|
|
15313
15594
|
const revealGenRef = useRef12(0);
|
|
15314
|
-
|
|
15595
|
+
useEffect18(() => {
|
|
15315
15596
|
if (searchTimerRef.current)
|
|
15316
15597
|
clearTimeout(searchTimerRef.current);
|
|
15317
15598
|
searchTimerRef.current = setTimeout(() => {
|
|
@@ -15325,7 +15606,7 @@ function KvViewer() {
|
|
|
15325
15606
|
}
|
|
15326
15607
|
};
|
|
15327
15608
|
}, [search]);
|
|
15328
|
-
const refresh =
|
|
15609
|
+
const refresh = useCallback12(async (opts) => {
|
|
15329
15610
|
const soft = opts?.soft === true;
|
|
15330
15611
|
const gen = ++listGenRef.current;
|
|
15331
15612
|
if (!soft)
|
|
@@ -15341,14 +15622,14 @@ function KvViewer() {
|
|
|
15341
15622
|
}
|
|
15342
15623
|
setLoading(false);
|
|
15343
15624
|
}, []);
|
|
15344
|
-
|
|
15625
|
+
useEffect18(() => {
|
|
15345
15626
|
refresh({ soft: false });
|
|
15346
15627
|
return () => {
|
|
15347
15628
|
listGenRef.current += 1;
|
|
15348
15629
|
revealGenRef.current += 1;
|
|
15349
15630
|
};
|
|
15350
15631
|
}, [refresh]);
|
|
15351
|
-
|
|
15632
|
+
useEffect18(() => {
|
|
15352
15633
|
if (!isActive)
|
|
15353
15634
|
return;
|
|
15354
15635
|
const handle = setInterval(() => {
|
|
@@ -15357,22 +15638,22 @@ function KvViewer() {
|
|
|
15357
15638
|
return () => clearInterval(handle);
|
|
15358
15639
|
}, [isActive, refresh]);
|
|
15359
15640
|
const allKeys = snapshot?.keys ?? [];
|
|
15360
|
-
const filteredKeys =
|
|
15361
|
-
const visibleKeys =
|
|
15362
|
-
const secretCount =
|
|
15363
|
-
const selectedKey =
|
|
15641
|
+
const filteredKeys = useMemo15(() => filterKvKeys(allKeys, debouncedSearch), [allKeys, debouncedSearch]);
|
|
15642
|
+
const visibleKeys = useMemo15(() => filteredKeys.slice(0, MAX_VISIBLE_KEYS), [filteredKeys]);
|
|
15643
|
+
const secretCount = useMemo15(() => allKeys.filter((k) => k.isSecret).length, [allKeys]);
|
|
15644
|
+
const selectedKey = useMemo15(() => {
|
|
15364
15645
|
if (!selectedKeyName)
|
|
15365
15646
|
return null;
|
|
15366
15647
|
return allKeys.find((k) => k.name === selectedKeyName) ?? null;
|
|
15367
15648
|
}, [allKeys, selectedKeyName]);
|
|
15368
|
-
|
|
15649
|
+
useEffect18(() => {
|
|
15369
15650
|
revealGenRef.current += 1;
|
|
15370
15651
|
setRevealed(false);
|
|
15371
15652
|
setValue(null);
|
|
15372
15653
|
setValueError(null);
|
|
15373
15654
|
setValueLoading(false);
|
|
15374
15655
|
}, [selectedKeyName]);
|
|
15375
|
-
const handleReveal =
|
|
15656
|
+
const handleReveal = useCallback12(async () => {
|
|
15376
15657
|
if (!selectedKey)
|
|
15377
15658
|
return;
|
|
15378
15659
|
const gen = ++revealGenRef.current;
|
|
@@ -15389,7 +15670,7 @@ function KvViewer() {
|
|
|
15389
15670
|
}
|
|
15390
15671
|
setValueLoading(false);
|
|
15391
15672
|
}, [selectedKey]);
|
|
15392
|
-
const handleHide =
|
|
15673
|
+
const handleHide = useCallback12(() => {
|
|
15393
15674
|
revealGenRef.current += 1;
|
|
15394
15675
|
setRevealed(false);
|
|
15395
15676
|
setValue(null);
|
|
@@ -15675,7 +15956,7 @@ function KvViewer() {
|
|
|
15675
15956
|
|
|
15676
15957
|
// src/components/views/secrets-viewer.tsx
|
|
15677
15958
|
init_src();
|
|
15678
|
-
import { useCallback as
|
|
15959
|
+
import { useCallback as useCallback13, useEffect as useEffect19, useMemo as useMemo16, useRef as useRef13, useState as useState17 } from "react";
|
|
15679
15960
|
import { jsxDEV as jsxDEV26 } from "@opentui/react/jsx-dev-runtime";
|
|
15680
15961
|
var REFRESH_INTERVAL_MS3 = 5000;
|
|
15681
15962
|
var MAX_VISIBLE_SECRETS = 200;
|
|
@@ -15787,7 +16068,7 @@ function SecretsViewer() {
|
|
|
15787
16068
|
const searchTimerRef = useRef13(null);
|
|
15788
16069
|
const listGenRef = useRef13(0);
|
|
15789
16070
|
const [selectedSecretName, setSelectedSecretName] = useState17(null);
|
|
15790
|
-
|
|
16071
|
+
useEffect19(() => {
|
|
15791
16072
|
if (searchTimerRef.current)
|
|
15792
16073
|
clearTimeout(searchTimerRef.current);
|
|
15793
16074
|
searchTimerRef.current = setTimeout(() => {
|
|
@@ -15801,7 +16082,7 @@ function SecretsViewer() {
|
|
|
15801
16082
|
}
|
|
15802
16083
|
};
|
|
15803
16084
|
}, [search]);
|
|
15804
|
-
const refresh =
|
|
16085
|
+
const refresh = useCallback13(async (opts) => {
|
|
15805
16086
|
const soft = opts?.soft === true;
|
|
15806
16087
|
const gen = ++listGenRef.current;
|
|
15807
16088
|
if (!soft)
|
|
@@ -15817,13 +16098,13 @@ function SecretsViewer() {
|
|
|
15817
16098
|
}
|
|
15818
16099
|
setLoading(false);
|
|
15819
16100
|
}, []);
|
|
15820
|
-
|
|
16101
|
+
useEffect19(() => {
|
|
15821
16102
|
refresh({ soft: false });
|
|
15822
16103
|
return () => {
|
|
15823
16104
|
listGenRef.current += 1;
|
|
15824
16105
|
};
|
|
15825
16106
|
}, [refresh]);
|
|
15826
|
-
|
|
16107
|
+
useEffect19(() => {
|
|
15827
16108
|
if (!isActive)
|
|
15828
16109
|
return;
|
|
15829
16110
|
const handle = setInterval(() => {
|
|
@@ -15832,9 +16113,9 @@ function SecretsViewer() {
|
|
|
15832
16113
|
return () => clearInterval(handle);
|
|
15833
16114
|
}, [isActive, refresh]);
|
|
15834
16115
|
const allSecrets = snapshot?.secrets ?? [];
|
|
15835
|
-
const filteredSecrets =
|
|
15836
|
-
const visibleSecrets =
|
|
15837
|
-
const selectedSecret =
|
|
16116
|
+
const filteredSecrets = useMemo16(() => filterSecrets(allSecrets, debouncedSearch), [allSecrets, debouncedSearch]);
|
|
16117
|
+
const visibleSecrets = useMemo16(() => filteredSecrets.slice(0, MAX_VISIBLE_SECRETS), [filteredSecrets]);
|
|
16118
|
+
const selectedSecret = useMemo16(() => {
|
|
15838
16119
|
if (!selectedSecretName)
|
|
15839
16120
|
return null;
|
|
15840
16121
|
return allSecrets.find((s) => s.name === selectedSecretName) ?? null;
|
|
@@ -16202,7 +16483,7 @@ function SecretsViewer() {
|
|
|
16202
16483
|
|
|
16203
16484
|
// src/components/views/ai-chat.tsx
|
|
16204
16485
|
init_src();
|
|
16205
|
-
import { useCallback as
|
|
16486
|
+
import { useCallback as useCallback14, useEffect as useEffect20, useRef as useRef14, useState as useState18 } from "react";
|
|
16206
16487
|
|
|
16207
16488
|
// src/services/tui-storage.ts
|
|
16208
16489
|
import { rename, unlink } from "fs/promises";
|
|
@@ -16389,7 +16670,7 @@ function AiChatView() {
|
|
|
16389
16670
|
const currentStreamRef = useRef14(null);
|
|
16390
16671
|
const scrollRef = useRef14(null);
|
|
16391
16672
|
const [confirmClear, setConfirmClear] = useState18(false);
|
|
16392
|
-
|
|
16673
|
+
useEffect20(() => {
|
|
16393
16674
|
let cancelled = false;
|
|
16394
16675
|
(async () => {
|
|
16395
16676
|
const stored = await readJsonState(TuiStateFiles.chatHistory, []);
|
|
@@ -16404,13 +16685,13 @@ function AiChatView() {
|
|
|
16404
16685
|
cancelled = true;
|
|
16405
16686
|
};
|
|
16406
16687
|
}, []);
|
|
16407
|
-
|
|
16688
|
+
useEffect20(() => {
|
|
16408
16689
|
if (!historyReady)
|
|
16409
16690
|
return;
|
|
16410
16691
|
const trimmed = sanitizeChatHistory(messages);
|
|
16411
16692
|
writeJsonState(TuiStateFiles.chatHistory, trimmed);
|
|
16412
16693
|
}, [messages, historyReady]);
|
|
16413
|
-
|
|
16694
|
+
useEffect20(() => {
|
|
16414
16695
|
if (!isActive && currentStreamRef.current) {
|
|
16415
16696
|
currentStreamRef.current.abort();
|
|
16416
16697
|
currentStreamRef.current = null;
|
|
@@ -16418,7 +16699,7 @@ function AiChatView() {
|
|
|
16418
16699
|
setStreamingContent("");
|
|
16419
16700
|
}
|
|
16420
16701
|
}, [isActive]);
|
|
16421
|
-
|
|
16702
|
+
useEffect20(() => {
|
|
16422
16703
|
return () => {
|
|
16423
16704
|
if (currentStreamRef.current) {
|
|
16424
16705
|
currentStreamRef.current.abort();
|
|
@@ -16430,15 +16711,15 @@ function AiChatView() {
|
|
|
16430
16711
|
}
|
|
16431
16712
|
};
|
|
16432
16713
|
}, []);
|
|
16433
|
-
const scheduleScroll =
|
|
16714
|
+
const scheduleScroll = useCallback14(() => {
|
|
16434
16715
|
if (scrollRef.current)
|
|
16435
16716
|
clearTimeout(scrollRef.current);
|
|
16436
16717
|
scrollRef.current = setTimeout(() => {}, 50);
|
|
16437
16718
|
}, []);
|
|
16438
|
-
|
|
16719
|
+
useEffect20(() => {
|
|
16439
16720
|
scheduleScroll();
|
|
16440
16721
|
}, [messages, streamingContent, scheduleScroll]);
|
|
16441
|
-
const sendMessage =
|
|
16722
|
+
const sendMessage = useCallback14(async () => {
|
|
16442
16723
|
const trimmed = inputText.trim();
|
|
16443
16724
|
if (!trimmed || isStreaming)
|
|
16444
16725
|
return;
|
|
@@ -16494,13 +16775,13 @@ function AiChatView() {
|
|
|
16494
16775
|
currentStreamRef.current = null;
|
|
16495
16776
|
}
|
|
16496
16777
|
}, [inputText, isStreaming, messages, selectedModel]);
|
|
16497
|
-
const handleInputKeyDown =
|
|
16778
|
+
const handleInputKeyDown = useCallback14((event) => {
|
|
16498
16779
|
if (event.key === "Enter" && !event.shiftKey) {
|
|
16499
16780
|
event.preventDefault();
|
|
16500
16781
|
sendMessage();
|
|
16501
16782
|
}
|
|
16502
16783
|
}, [sendMessage]);
|
|
16503
|
-
|
|
16784
|
+
useEffect20(() => {
|
|
16504
16785
|
if (isActive) {}
|
|
16505
16786
|
}, [isActive]);
|
|
16506
16787
|
const statusColor2 = streamStatus === "connected" ? ConnectionStatusColor.connected : streamStatus === "reconnecting" ? ConnectionStatusColor.reconnecting : streamStatus === "disconnected" ? ConnectionStatusColor.offline : Colors.muted;
|
|
@@ -16648,7 +16929,7 @@ function AiChatView() {
|
|
|
16648
16929
|
|
|
16649
16930
|
// src/components/views/db-query.tsx
|
|
16650
16931
|
init_src();
|
|
16651
|
-
import { useCallback as
|
|
16932
|
+
import { useCallback as useCallback15, useEffect as useEffect21, useMemo as useMemo17, useRef as useRef15, useState as useState19 } from "react";
|
|
16652
16933
|
import { jsxDEV as jsxDEV28, Fragment as Fragment6 } from "@opentui/react/jsx-dev-runtime";
|
|
16653
16934
|
var MAX_HISTORY = 20;
|
|
16654
16935
|
var MAX_VISIBLE_ROWS = 200;
|
|
@@ -16966,7 +17247,7 @@ function DbQueryView() {
|
|
|
16966
17247
|
const [sortDir, setSortDir] = useState19("asc");
|
|
16967
17248
|
const [selectedRow, setSelectedRow] = useState19(0);
|
|
16968
17249
|
const queryGenRef = useRef15(0);
|
|
16969
|
-
|
|
17250
|
+
useEffect21(() => {
|
|
16970
17251
|
let cancelled = false;
|
|
16971
17252
|
(async () => {
|
|
16972
17253
|
const stored = await readJsonState(TuiStateFiles.dbQueryHistory, []);
|
|
@@ -16982,12 +17263,12 @@ function DbQueryView() {
|
|
|
16982
17263
|
queryGenRef.current += 1;
|
|
16983
17264
|
};
|
|
16984
17265
|
}, []);
|
|
16985
|
-
|
|
17266
|
+
useEffect21(() => {
|
|
16986
17267
|
if (!historyReady)
|
|
16987
17268
|
return;
|
|
16988
17269
|
writeJsonState(TuiStateFiles.dbQueryHistory, history);
|
|
16989
17270
|
}, [history, historyReady]);
|
|
16990
|
-
const executeQuery =
|
|
17271
|
+
const executeQuery = useCallback15(async (query) => {
|
|
16991
17272
|
const trimmed = query.trim();
|
|
16992
17273
|
if (trimmed.length === 0)
|
|
16993
17274
|
return;
|
|
@@ -17020,7 +17301,7 @@ function DbQueryView() {
|
|
|
17020
17301
|
}
|
|
17021
17302
|
setLoading(false);
|
|
17022
17303
|
}, []);
|
|
17023
|
-
|
|
17304
|
+
useEffect21(() => {
|
|
17024
17305
|
if (sql.trim().length === 0) {
|
|
17025
17306
|
setValidation(null);
|
|
17026
17307
|
return;
|
|
@@ -17028,13 +17309,13 @@ function DbQueryView() {
|
|
|
17028
17309
|
const v = validateReadOnlySql(sql.trim());
|
|
17029
17310
|
setValidation(v);
|
|
17030
17311
|
}, [sql]);
|
|
17031
|
-
const handleActivateInput =
|
|
17312
|
+
const handleActivateInput = useCallback15(() => {
|
|
17032
17313
|
setInputActive(true);
|
|
17033
17314
|
}, []);
|
|
17034
|
-
const handleDeactivateInput =
|
|
17315
|
+
const handleDeactivateInput = useCallback15(() => {
|
|
17035
17316
|
setInputActive(false);
|
|
17036
17317
|
}, []);
|
|
17037
|
-
const handleSort =
|
|
17318
|
+
const handleSort = useCallback15((col) => {
|
|
17038
17319
|
setSortCol((prev) => {
|
|
17039
17320
|
if (prev === col) {
|
|
17040
17321
|
setSortDir((d) => d === "asc" ? "desc" : "asc");
|
|
@@ -17044,7 +17325,7 @@ function DbQueryView() {
|
|
|
17044
17325
|
return col;
|
|
17045
17326
|
});
|
|
17046
17327
|
}, []);
|
|
17047
|
-
const handleHistoryUp =
|
|
17328
|
+
const handleHistoryUp = useCallback15(() => {
|
|
17048
17329
|
if (history.length === 0)
|
|
17049
17330
|
return;
|
|
17050
17331
|
const next = Math.min(historyIdx + 1, history.length - 1);
|
|
@@ -17052,7 +17333,7 @@ function DbQueryView() {
|
|
|
17052
17333
|
setSql(history[next] ?? "");
|
|
17053
17334
|
setValidation(null);
|
|
17054
17335
|
}, [history, historyIdx]);
|
|
17055
|
-
const handleHistoryDown =
|
|
17336
|
+
const handleHistoryDown = useCallback15(() => {
|
|
17056
17337
|
if (historyIdx <= 0) {
|
|
17057
17338
|
setHistoryIdx(-1);
|
|
17058
17339
|
setSql("");
|
|
@@ -17114,13 +17395,13 @@ function DbQueryView() {
|
|
|
17114
17395
|
});
|
|
17115
17396
|
const columns = result?.columns ?? [];
|
|
17116
17397
|
const rows = result?.rows ?? [];
|
|
17117
|
-
const sortedRows =
|
|
17398
|
+
const sortedRows = useMemo17(() => {
|
|
17118
17399
|
if (!sortCol || rows.length === 0)
|
|
17119
17400
|
return rows;
|
|
17120
17401
|
return [...rows].sort((a, b) => compareCells(a[sortCol], b[sortCol], sortDir));
|
|
17121
17402
|
}, [rows, sortCol, sortDir]);
|
|
17122
|
-
const visibleRows =
|
|
17123
|
-
const columnWidths =
|
|
17403
|
+
const visibleRows = useMemo17(() => sortedRows.slice(0, MAX_VISIBLE_ROWS), [sortedRows]);
|
|
17404
|
+
const columnWidths = useMemo17(() => computeColumnWidths(columns, visibleRows), [columns, visibleRows]);
|
|
17124
17405
|
const totalWidth = columns.reduce((acc, col) => acc + (columnWidths.get(col) ?? COLUMN_WIDTH_STRATEGY.fallback) + 1, 0);
|
|
17125
17406
|
return /* @__PURE__ */ jsxDEV28(ErrorBoundary, {
|
|
17126
17407
|
viewName: "DB Query",
|
|
@@ -17332,7 +17613,7 @@ function DbQueryView() {
|
|
|
17332
17613
|
|
|
17333
17614
|
// src/components/views/edge-topology.tsx
|
|
17334
17615
|
init_src();
|
|
17335
|
-
import { useState as useState20, useEffect as
|
|
17616
|
+
import { useState as useState20, useEffect as useEffect22, useMemo as useMemo18 } from "react";
|
|
17336
17617
|
import * as fs from "fs";
|
|
17337
17618
|
import * as path3 from "path";
|
|
17338
17619
|
import { jsxDEV as jsxDEV29, Fragment as Fragment7 } from "@opentui/react/jsx-dev-runtime";
|
|
@@ -17381,7 +17662,7 @@ function EdgeTopologyInner() {
|
|
|
17381
17662
|
const [selectedNode, setSelectedNode] = useState20(null);
|
|
17382
17663
|
const [activeCommunity, setActiveCommunity] = useState20(null);
|
|
17383
17664
|
const [focusedIndex, setFocusedIndex] = useState20(0);
|
|
17384
|
-
|
|
17665
|
+
useEffect22(() => {
|
|
17385
17666
|
let cancelled = false;
|
|
17386
17667
|
try {
|
|
17387
17668
|
const graphPath = resolveGraphMetadataPath();
|
|
@@ -17407,7 +17688,7 @@ function EdgeTopologyInner() {
|
|
|
17407
17688
|
const workers = metadata ? Object.entries(metadata.workers) : [];
|
|
17408
17689
|
const infra = metadata ? Object.entries(metadata.infrastructure) : [];
|
|
17409
17690
|
const communities = metadata ? metadata.communities : [];
|
|
17410
|
-
const selectableItems =
|
|
17691
|
+
const selectableItems = useMemo18(() => {
|
|
17411
17692
|
if (!metadata)
|
|
17412
17693
|
return [];
|
|
17413
17694
|
const visibleWorkers = activeCommunity ? workers.filter(([id]) => communities.find((c) => c.id === activeCommunity)?.nodeIds.includes(`workspace:${id}`)) : workers;
|
|
@@ -17423,7 +17704,7 @@ function EdgeTopologyInner() {
|
|
|
17423
17704
|
...visibleInfra.map(([id]) => ({ type: "infra", id }))
|
|
17424
17705
|
];
|
|
17425
17706
|
}, [metadata, activeCommunity, workers, infra, communities]);
|
|
17426
|
-
|
|
17707
|
+
useEffect22(() => {
|
|
17427
17708
|
if (selectableItems.length === 0) {
|
|
17428
17709
|
setFocusedIndex(0);
|
|
17429
17710
|
return;
|
|
@@ -17862,7 +18143,7 @@ function EdgeTopologyInner() {
|
|
|
17862
18143
|
|
|
17863
18144
|
// src/components/views/worker-settings.tsx
|
|
17864
18145
|
init_src();
|
|
17865
|
-
import { useCallback as
|
|
18146
|
+
import { useCallback as useCallback16, useEffect as useEffect23, useMemo as useMemo19, useRef as useRef16, useState as useState21 } from "react";
|
|
17866
18147
|
|
|
17867
18148
|
// src/services/dashboard-settings-loader.ts
|
|
17868
18149
|
init_src();
|
|
@@ -17920,7 +18201,7 @@ function WorkerSettingsView() {
|
|
|
17920
18201
|
const [pendingDangerousKey, setPendingDangerousKey] = useState21(null);
|
|
17921
18202
|
const loadGeneration = useRef16(0);
|
|
17922
18203
|
const selected = manifests2[workerIndex] ?? null;
|
|
17923
|
-
const flatFields =
|
|
18204
|
+
const flatFields = useMemo19(() => {
|
|
17924
18205
|
if (!selected)
|
|
17925
18206
|
return [];
|
|
17926
18207
|
const out = [];
|
|
@@ -17938,7 +18219,7 @@ function WorkerSettingsView() {
|
|
|
17938
18219
|
}
|
|
17939
18220
|
return out;
|
|
17940
18221
|
}, [selected]);
|
|
17941
|
-
const loadValues =
|
|
18222
|
+
const loadValues = useCallback16(async (manifest) => {
|
|
17942
18223
|
const gen = ++loadGeneration.current;
|
|
17943
18224
|
const fields = [];
|
|
17944
18225
|
for (const section of manifest.sections) {
|
|
@@ -17975,7 +18256,7 @@ function WorkerSettingsView() {
|
|
|
17975
18256
|
next[k] = v;
|
|
17976
18257
|
setValues(next);
|
|
17977
18258
|
}, []);
|
|
17978
|
-
const refresh =
|
|
18259
|
+
const refresh = useCallback16(async () => {
|
|
17979
18260
|
setLoading(true);
|
|
17980
18261
|
setError(null);
|
|
17981
18262
|
try {
|
|
@@ -17995,12 +18276,12 @@ function WorkerSettingsView() {
|
|
|
17995
18276
|
setLoading(false);
|
|
17996
18277
|
}
|
|
17997
18278
|
}, [loadValues, workerIndex]);
|
|
17998
|
-
|
|
18279
|
+
useEffect23(() => {
|
|
17999
18280
|
if (!isActive)
|
|
18000
18281
|
return;
|
|
18001
18282
|
refresh();
|
|
18002
18283
|
}, [isActive]);
|
|
18003
|
-
const selectWorker =
|
|
18284
|
+
const selectWorker = useCallback16(async (idx) => {
|
|
18004
18285
|
if (idx < 0 || idx >= manifests2.length)
|
|
18005
18286
|
return;
|
|
18006
18287
|
setWorkerIndex(idx);
|
|
@@ -18014,7 +18295,7 @@ function WorkerSettingsView() {
|
|
|
18014
18295
|
setLoading(false);
|
|
18015
18296
|
}
|
|
18016
18297
|
}, [manifests2, loadValues]);
|
|
18017
|
-
const cycleFieldValue =
|
|
18298
|
+
const cycleFieldValue = useCallback16((delta) => {
|
|
18018
18299
|
const row = flatFields[fieldIndex];
|
|
18019
18300
|
if (!row || row.field.kind === "secret")
|
|
18020
18301
|
return;
|
|
@@ -18047,7 +18328,7 @@ function WorkerSettingsView() {
|
|
|
18047
18328
|
}));
|
|
18048
18329
|
}
|
|
18049
18330
|
}, [flatFields, fieldIndex, values]);
|
|
18050
|
-
const saveCurrent =
|
|
18331
|
+
const saveCurrent = useCallback16(async () => {
|
|
18051
18332
|
const row = flatFields[fieldIndex];
|
|
18052
18333
|
if (!row || !selected)
|
|
18053
18334
|
return;
|
|
@@ -18626,7 +18907,7 @@ var ALL_PALETTE_COMMANDS = [
|
|
|
18626
18907
|
|
|
18627
18908
|
// src/components/shared/crash-screen.tsx
|
|
18628
18909
|
init_src();
|
|
18629
|
-
import { useKeyboard as
|
|
18910
|
+
import { useKeyboard as useKeyboard5 } from "@opentui/react";
|
|
18630
18911
|
import { jsxDEV as jsxDEV32 } from "@opentui/react/jsx-dev-runtime";
|
|
18631
18912
|
function formatCrashMessage(error, maxLen = 120) {
|
|
18632
18913
|
const first = (error.message || "Unknown error").split(`
|
|
@@ -18644,7 +18925,7 @@ function CrashScreen({
|
|
|
18644
18925
|
`) ? error.message.split(`
|
|
18645
18926
|
`)[1] : undefined;
|
|
18646
18927
|
const secondLine = secondRaw ? redactSecretsInText(secondRaw).slice(0, 80) : undefined;
|
|
18647
|
-
|
|
18928
|
+
useKeyboard5((key) => {
|
|
18648
18929
|
const name = String(key.name ?? "").toLowerCase();
|
|
18649
18930
|
if (name === "r" || name === "1") {
|
|
18650
18931
|
onAction("restart");
|
|
@@ -18773,8 +19054,8 @@ function CrashScreen({
|
|
|
18773
19054
|
|
|
18774
19055
|
// src/components/shared/command-palette.tsx
|
|
18775
19056
|
init_src();
|
|
18776
|
-
import { useState as useState22, useMemo as
|
|
18777
|
-
import { useKeyboard as
|
|
19057
|
+
import { useState as useState22, useMemo as useMemo20, useEffect as useEffect24 } from "react";
|
|
19058
|
+
import { useKeyboard as useKeyboard6 } from "@opentui/react";
|
|
18778
19059
|
import { jsxDEV as jsxDEV33 } from "@opentui/react/jsx-dev-runtime";
|
|
18779
19060
|
var CATEGORY_BADGE = {
|
|
18780
19061
|
view: { label: "view", color: Colors.info },
|
|
@@ -18827,20 +19108,20 @@ function CommandPalette({
|
|
|
18827
19108
|
}) {
|
|
18828
19109
|
const [query, setQuery] = useState22("");
|
|
18829
19110
|
const [selectedIndex, setSelectedIndex] = useState22(0);
|
|
18830
|
-
const filtered =
|
|
19111
|
+
const filtered = useMemo20(() => filterCommands(commands, query), [commands, query]);
|
|
18831
19112
|
const safeIndex = filtered.length === 0 ? 0 : Math.min(selectedIndex, filtered.length - 1);
|
|
18832
|
-
|
|
19113
|
+
useEffect24(() => {
|
|
18833
19114
|
if (!visible) {
|
|
18834
19115
|
setQuery("");
|
|
18835
19116
|
setSelectedIndex(0);
|
|
18836
19117
|
}
|
|
18837
19118
|
}, [visible]);
|
|
18838
|
-
|
|
19119
|
+
useEffect24(() => {
|
|
18839
19120
|
if (selectedIndex !== safeIndex) {
|
|
18840
19121
|
setSelectedIndex(safeIndex);
|
|
18841
19122
|
}
|
|
18842
19123
|
}, [safeIndex, selectedIndex]);
|
|
18843
|
-
|
|
19124
|
+
useKeyboard6((key) => {
|
|
18844
19125
|
if (!visible)
|
|
18845
19126
|
return;
|
|
18846
19127
|
if (key.name === "escape") {
|
|
@@ -19075,8 +19356,8 @@ function QuitModal({
|
|
|
19075
19356
|
|
|
19076
19357
|
// src/components/layout/statusbar.tsx
|
|
19077
19358
|
init_src();
|
|
19078
|
-
import { useCallback as
|
|
19079
|
-
import { useKeyboard as
|
|
19359
|
+
import { useCallback as useCallback17, memo } from "react";
|
|
19360
|
+
import { useKeyboard as useKeyboard7 } from "@opentui/react";
|
|
19080
19361
|
import { jsxDEV as jsxDEV35 } from "@opentui/react/jsx-dev-runtime";
|
|
19081
19362
|
var ERROR_TYPE_LABELS = {
|
|
19082
19363
|
"binary-not-found": "CLI binary not found",
|
|
@@ -19289,10 +19570,10 @@ function StatusBar() {
|
|
|
19289
19570
|
const authReady = conn.hasAuth;
|
|
19290
19571
|
const errorKind = classifyConnectionError(lastError);
|
|
19291
19572
|
const showAuthHint = tuiMode === "remote" && (!authReady || errorKind === "auth" || Boolean(lastError?.includes("401")));
|
|
19292
|
-
const toggleError =
|
|
19573
|
+
const toggleError = useCallback17(() => {
|
|
19293
19574
|
toggleStatusErrorExpanded();
|
|
19294
19575
|
}, [toggleStatusErrorExpanded]);
|
|
19295
|
-
|
|
19576
|
+
useKeyboard7((key) => {
|
|
19296
19577
|
if (isShellOverlayOpen())
|
|
19297
19578
|
return;
|
|
19298
19579
|
const name = String(key.name ?? "").toLowerCase();
|
|
@@ -19484,9 +19765,6 @@ function quitApp() {
|
|
|
19484
19765
|
}
|
|
19485
19766
|
function AppRoot({ safeMode = false }) {
|
|
19486
19767
|
return /* @__PURE__ */ jsxDEV37(DialogProvider, {
|
|
19487
|
-
size: "medium",
|
|
19488
|
-
backdropColor: Colors.backdrop,
|
|
19489
|
-
backdropOpacity: 0.35,
|
|
19490
19768
|
children: /* @__PURE__ */ jsxDEV37(AppRootInner, {
|
|
19491
19769
|
safeMode
|
|
19492
19770
|
}, undefined, false, undefined, this)
|
|
@@ -19504,7 +19782,7 @@ function AppRootInner({ safeMode = false }) {
|
|
|
19504
19782
|
const closePalette = useUIStore((s) => s.closePalette);
|
|
19505
19783
|
const showModal = useUIStore((s) => s.showModal);
|
|
19506
19784
|
const dismissModal = useUIStore((s) => s.dismissModal);
|
|
19507
|
-
const requestQuit =
|
|
19785
|
+
const requestQuit = useCallback18(() => {
|
|
19508
19786
|
closePalette();
|
|
19509
19787
|
showModal({
|
|
19510
19788
|
type: "confirm",
|
|
@@ -19514,7 +19792,7 @@ function AppRootInner({ safeMode = false }) {
|
|
|
19514
19792
|
onCancel: () => dismissModal()
|
|
19515
19793
|
});
|
|
19516
19794
|
}, [closePalette, showModal, dismissModal]);
|
|
19517
|
-
|
|
19795
|
+
useEffect25(() => {
|
|
19518
19796
|
let cancelled = false;
|
|
19519
19797
|
(async () => {
|
|
19520
19798
|
const session = await restoreSession();
|
|
@@ -19534,7 +19812,7 @@ function AppRootInner({ safeMode = false }) {
|
|
|
19534
19812
|
cancelled = true;
|
|
19535
19813
|
};
|
|
19536
19814
|
}, [setView, toggleSidebar]);
|
|
19537
|
-
|
|
19815
|
+
useEffect25(() => {
|
|
19538
19816
|
if (restoring)
|
|
19539
19817
|
return;
|
|
19540
19818
|
if (safeMode) {
|
|
@@ -19663,7 +19941,7 @@ function AppRootInner({ safeMode = false }) {
|
|
|
19663
19941
|
useServiceStore.getState().stopStreams();
|
|
19664
19942
|
};
|
|
19665
19943
|
}, [restoring, safeMode]);
|
|
19666
|
-
|
|
19944
|
+
useEffect25(() => {
|
|
19667
19945
|
if (restoring)
|
|
19668
19946
|
return;
|
|
19669
19947
|
const conn = resolveTuiConnectionEnv();
|
|
@@ -19692,19 +19970,19 @@ function AppRootInner({ safeMode = false }) {
|
|
|
19692
19970
|
});
|
|
19693
19971
|
return unsub;
|
|
19694
19972
|
}, [restoring]);
|
|
19695
|
-
|
|
19973
|
+
useEffect25(() => {
|
|
19696
19974
|
return () => {
|
|
19697
19975
|
const lastUpdated = useServiceStore.getState().lastUpdated;
|
|
19698
19976
|
saveSession(useUIStore.getState().activeView, useUIStore.getState().sidebarExpanded, { cols: 80, rows: 24 }, lastUpdated).catch(() => {});
|
|
19699
19977
|
};
|
|
19700
19978
|
}, []);
|
|
19701
|
-
|
|
19979
|
+
useEffect25(() => {
|
|
19702
19980
|
const unsubscribe = cliBridge.onError((details) => {
|
|
19703
19981
|
useServiceStore.getState().setLastErrorDetails(details);
|
|
19704
19982
|
});
|
|
19705
19983
|
return unsubscribe;
|
|
19706
19984
|
}, []);
|
|
19707
|
-
const onGlobalKey =
|
|
19985
|
+
const onGlobalKey = useCallback18((key) => {
|
|
19708
19986
|
const name = String(key.name ?? "").toLowerCase();
|
|
19709
19987
|
if (modal?.type === "confirm" && modal.title === "Quit HOOX?") {
|
|
19710
19988
|
if (name === "return" || name === "enter" || name === "y") {
|
|
@@ -19789,7 +20067,7 @@ function AppRootInner({ safeMode = false }) {
|
|
|
19789
20067
|
requestQuit,
|
|
19790
20068
|
safeMode
|
|
19791
20069
|
]);
|
|
19792
|
-
|
|
20070
|
+
useKeyboard8(onGlobalKey);
|
|
19793
20071
|
if (restoring) {
|
|
19794
20072
|
return /* @__PURE__ */ jsxDEV37("box", {
|
|
19795
20073
|
flexDirection: "column",
|
|
@@ -19899,7 +20177,7 @@ function AppRootInner({ safeMode = false }) {
|
|
|
19899
20177
|
function CrashRecoveryApp() {
|
|
19900
20178
|
const [crash, setCrash] = useState23(null);
|
|
19901
20179
|
const [safeMode, setSafeMode] = useState23(false);
|
|
19902
|
-
const handleCrashAction =
|
|
20180
|
+
const handleCrashAction = useCallback18((action) => {
|
|
19903
20181
|
switch (action) {
|
|
19904
20182
|
case "restart":
|
|
19905
20183
|
setCrash(null);
|
|
@@ -19927,7 +20205,7 @@ function CrashRecoveryApp() {
|
|
|
19927
20205
|
break;
|
|
19928
20206
|
}
|
|
19929
20207
|
}, [crash, safeMode]);
|
|
19930
|
-
|
|
20208
|
+
useEffect25(() => {
|
|
19931
20209
|
if (typeof process === "undefined")
|
|
19932
20210
|
return;
|
|
19933
20211
|
const onUncaught = (error) => {
|
|
@@ -20103,14 +20381,6 @@ async function main() {
|
|
|
20103
20381
|
});
|
|
20104
20382
|
renderer.on("resize", (_width, _height) => {});
|
|
20105
20383
|
setRendererRef(renderer);
|
|
20106
|
-
try {
|
|
20107
|
-
const root = renderer.root;
|
|
20108
|
-
root.add(new ToasterRenderable(renderer));
|
|
20109
|
-
} catch (err) {
|
|
20110
|
-
await tuiDevLog.warn("startup", "Toaster mount failed \u2014 toasts may no-op", {
|
|
20111
|
-
error: err instanceof Error ? err.message : String(err)
|
|
20112
|
-
});
|
|
20113
|
-
}
|
|
20114
20384
|
enableAutoCopyOnSelection(renderer);
|
|
20115
20385
|
createRoot(renderer).render(/* @__PURE__ */ jsxDEV38(CrashRecoveryApp, {}, undefined, false, undefined, this));
|
|
20116
20386
|
renderer.start();
|