brew-tui 0.8.1 → 0.9.1
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/README.md +11 -5
- package/build/{brewbar-installer-DCF37YM3.js → brewbar-installer-V6R7BORH.js} +2 -2
- package/build/{brewfile-manager-6LXONGSA.js → brewfile-manager-G7Q4IOG3.js} +4 -4
- package/build/{chunk-VLREAA5F.js → chunk-BRXZG7ZL.js} +2 -2
- package/build/{chunk-QZZZAAWG.js → chunk-IGDHDXUH.js} +11 -1
- package/build/chunk-IGDHDXUH.js.map +1 -0
- package/build/{chunk-FIPCCYL6.js → chunk-J6HCX7RG.js} +2 -2
- package/build/{chunk-3OIVIQWW.js → chunk-KDKXGXN2.js} +4 -4
- package/build/{chunk-3VDIKVS3.js → chunk-QX5DEW3S.js} +3 -3
- package/build/{chunk-JYHINZVV.js → chunk-VQJBFXZN.js} +2 -2
- package/build/{chunk-OHMNJ3EA.js → chunk-WDRT6G63.js} +23 -9
- package/build/chunk-WDRT6G63.js.map +1 -0
- package/build/compliance-checker-IXZHIMQG.js +12 -0
- package/build/{history-logger-FJ3HZSFU.js → history-logger-SB5UG5BQ.js} +3 -3
- package/build/index.js +1103 -985
- package/build/index.js.map +1 -1
- package/build/{snapshot-JDRSBMG6.js → snapshot-ZOJETCED.js} +3 -3
- package/build/{sync-engine-CIL6C44Z.js → sync-engine-76YMONYH.js} +5 -5
- package/build/{version-check-LEJWNDQK.js → version-check-X3HTR3HM.js} +2 -2
- package/package.json +1 -1
- package/build/chunk-OHMNJ3EA.js.map +0 -1
- package/build/chunk-QZZZAAWG.js.map +0 -1
- package/build/compliance-checker-MAREAFDH.js +0 -12
- /package/build/{brewbar-installer-DCF37YM3.js.map → brewbar-installer-V6R7BORH.js.map} +0 -0
- /package/build/{brewfile-manager-6LXONGSA.js.map → brewfile-manager-G7Q4IOG3.js.map} +0 -0
- /package/build/{chunk-VLREAA5F.js.map → chunk-BRXZG7ZL.js.map} +0 -0
- /package/build/{chunk-FIPCCYL6.js.map → chunk-J6HCX7RG.js.map} +0 -0
- /package/build/{chunk-3OIVIQWW.js.map → chunk-KDKXGXN2.js.map} +0 -0
- /package/build/{chunk-3VDIKVS3.js.map → chunk-QX5DEW3S.js.map} +0 -0
- /package/build/{chunk-JYHINZVV.js.map → chunk-VQJBFXZN.js.map} +0 -0
- /package/build/{compliance-checker-MAREAFDH.js.map → compliance-checker-IXZHIMQG.js.map} +0 -0
- /package/build/{history-logger-FJ3HZSFU.js.map → history-logger-SB5UG5BQ.js.map} +0 -0
- /package/build/{snapshot-JDRSBMG6.js.map → snapshot-ZOJETCED.js.map} +0 -0
- /package/build/{sync-engine-CIL6C44Z.js.map → sync-engine-76YMONYH.js.map} +0 -0
- /package/build/{version-check-LEJWNDQK.js.map → version-check-X3HTR3HM.js.map} +0 -0
package/build/index.js
CHANGED
|
@@ -5,7 +5,7 @@ import {
|
|
|
5
5
|
loadBrewfile,
|
|
6
6
|
reconcile,
|
|
7
7
|
saveBrewfile
|
|
8
|
-
} from "./chunk-
|
|
8
|
+
} from "./chunk-QX5DEW3S.js";
|
|
9
9
|
import {
|
|
10
10
|
activate,
|
|
11
11
|
applyConflictResolutions,
|
|
@@ -19,17 +19,17 @@ import {
|
|
|
19
19
|
readSyncEnvelope,
|
|
20
20
|
revalidate,
|
|
21
21
|
sync
|
|
22
|
-
} from "./chunk-
|
|
22
|
+
} from "./chunk-KDKXGXN2.js";
|
|
23
23
|
import {
|
|
24
24
|
checkCompliance
|
|
25
|
-
} from "./chunk-
|
|
25
|
+
} from "./chunk-J6HCX7RG.js";
|
|
26
26
|
import {
|
|
27
27
|
captureSnapshot,
|
|
28
28
|
execBrew,
|
|
29
29
|
loadSnapshots,
|
|
30
30
|
saveSnapshot,
|
|
31
31
|
streamBrew
|
|
32
|
-
} from "./chunk-
|
|
32
|
+
} from "./chunk-BRXZG7ZL.js";
|
|
33
33
|
import {
|
|
34
34
|
exportReport,
|
|
35
35
|
loadPolicy
|
|
@@ -39,14 +39,15 @@ import {
|
|
|
39
39
|
clearHistory,
|
|
40
40
|
detectAction,
|
|
41
41
|
loadHistory
|
|
42
|
-
} from "./chunk-
|
|
42
|
+
} from "./chunk-VQJBFXZN.js";
|
|
43
43
|
import {
|
|
44
44
|
DATA_DIR,
|
|
45
45
|
ONBOARDING_FLAG_PATH,
|
|
46
46
|
PROFILES_DIR,
|
|
47
47
|
ensureDataDirs,
|
|
48
|
-
getMachineId
|
|
49
|
-
|
|
48
|
+
getMachineId,
|
|
49
|
+
writeLastAction
|
|
50
|
+
} from "./chunk-IGDHDXUH.js";
|
|
50
51
|
import {
|
|
51
52
|
fetchWithRetry,
|
|
52
53
|
fetchWithTimeout,
|
|
@@ -54,7 +55,7 @@ import {
|
|
|
54
55
|
t,
|
|
55
56
|
tp,
|
|
56
57
|
useLocaleStore
|
|
57
|
-
} from "./chunk-
|
|
58
|
+
} from "./chunk-WDRT6G63.js";
|
|
58
59
|
import {
|
|
59
60
|
logger
|
|
60
61
|
} from "./chunk-KDHEUNRI.js";
|
|
@@ -65,23 +66,22 @@ import { rm as rm2 } from "fs/promises";
|
|
|
65
66
|
import { render } from "ink";
|
|
66
67
|
|
|
67
68
|
// src/app.tsx
|
|
68
|
-
import { useEffect as
|
|
69
|
+
import { useEffect as useEffect23, useState as useState20 } from "react";
|
|
69
70
|
import { useApp } from "ink";
|
|
70
71
|
|
|
71
72
|
// src/components/layout/app-layout.tsx
|
|
72
73
|
import { Box as Box3 } from "ink";
|
|
73
74
|
|
|
74
75
|
// src/components/layout/header.tsx
|
|
75
|
-
import { Box, Text as
|
|
76
|
+
import { Box, Text as Text3, useStdout } from "ink";
|
|
76
77
|
|
|
77
78
|
// src/stores/navigation-store.ts
|
|
78
79
|
import { create } from "zustand";
|
|
79
|
-
var
|
|
80
|
+
var MENU_VIEWS = [
|
|
80
81
|
"dashboard",
|
|
81
82
|
"installed",
|
|
82
83
|
"outdated",
|
|
83
84
|
"package-info",
|
|
84
|
-
"search",
|
|
85
85
|
"services",
|
|
86
86
|
"doctor",
|
|
87
87
|
"profiles",
|
|
@@ -99,6 +99,10 @@ var useNavigationStore = create((set, get) => ({
|
|
|
99
99
|
selectedPackage: null,
|
|
100
100
|
selectedPackageType: null,
|
|
101
101
|
viewHistory: [],
|
|
102
|
+
// menuMode starts ON so the side menu owns arrows from the first frame —
|
|
103
|
+
// users can navigate with ↑/↓/↵ without having to press M first.
|
|
104
|
+
menuMode: true,
|
|
105
|
+
menuCursor: 0,
|
|
102
106
|
navigate: (view) => {
|
|
103
107
|
const { currentView, viewHistory } = get();
|
|
104
108
|
if (view === currentView) return;
|
|
@@ -108,7 +112,11 @@ var useNavigationStore = create((set, get) => ({
|
|
|
108
112
|
});
|
|
109
113
|
},
|
|
110
114
|
goBack: () => {
|
|
111
|
-
const { viewHistory } = get();
|
|
115
|
+
const { viewHistory, menuMode } = get();
|
|
116
|
+
if (menuMode) {
|
|
117
|
+
set({ menuMode: false });
|
|
118
|
+
return;
|
|
119
|
+
}
|
|
112
120
|
if (viewHistory.length === 0) return;
|
|
113
121
|
const prev = viewHistory[viewHistory.length - 1];
|
|
114
122
|
set({
|
|
@@ -116,16 +124,37 @@ var useNavigationStore = create((set, get) => ({
|
|
|
116
124
|
viewHistory: viewHistory.slice(0, -1)
|
|
117
125
|
});
|
|
118
126
|
},
|
|
119
|
-
selectPackage: (name, type = null) => set({ selectedPackage: name, selectedPackageType: type })
|
|
127
|
+
selectPackage: (name, type = null) => set({ selectedPackage: name, selectedPackageType: type }),
|
|
128
|
+
enterMenuMode: () => {
|
|
129
|
+
const { currentView } = get();
|
|
130
|
+
const idx = MENU_VIEWS.indexOf(currentView);
|
|
131
|
+
set({ menuMode: true, menuCursor: idx >= 0 ? idx : 0 });
|
|
132
|
+
},
|
|
133
|
+
exitMenuMode: () => set({ menuMode: false }),
|
|
134
|
+
moveMenuCursor: (delta) => {
|
|
135
|
+
const { menuCursor } = get();
|
|
136
|
+
const next = menuCursor + delta;
|
|
137
|
+
if (next < 0 || next >= MENU_VIEWS.length) return;
|
|
138
|
+
set({ menuCursor: next });
|
|
139
|
+
},
|
|
140
|
+
selectMenuItem: () => {
|
|
141
|
+
const { menuCursor, currentView, viewHistory } = get();
|
|
142
|
+
const target = MENU_VIEWS[menuCursor];
|
|
143
|
+
if (!target) {
|
|
144
|
+
set({ menuMode: false });
|
|
145
|
+
return;
|
|
146
|
+
}
|
|
147
|
+
if (target === currentView) {
|
|
148
|
+
set({ menuMode: false });
|
|
149
|
+
return;
|
|
150
|
+
}
|
|
151
|
+
set({
|
|
152
|
+
currentView: target,
|
|
153
|
+
viewHistory: [...viewHistory.slice(-19), currentView],
|
|
154
|
+
menuMode: false
|
|
155
|
+
});
|
|
156
|
+
}
|
|
120
157
|
}));
|
|
121
|
-
function getNextView(current) {
|
|
122
|
-
const idx = VIEWS.indexOf(current);
|
|
123
|
-
return VIEWS[(idx + 1) % VIEWS.length];
|
|
124
|
-
}
|
|
125
|
-
function getPrevView(current) {
|
|
126
|
-
const idx = VIEWS.indexOf(current);
|
|
127
|
-
return VIEWS[(idx - 1 + VIEWS.length) % VIEWS.length];
|
|
128
|
-
}
|
|
129
158
|
|
|
130
159
|
// src/lib/license/feature-gate.ts
|
|
131
160
|
var PRO_VIEWS = /* @__PURE__ */ new Set([
|
|
@@ -266,6 +295,24 @@ var GRADIENTS = {
|
|
|
266
295
|
darkGold: [COLORS.goldDeep, COLORS.goldDark, COLORS.goldDeepest]
|
|
267
296
|
};
|
|
268
297
|
|
|
298
|
+
// src/components/common/blinking-text.tsx
|
|
299
|
+
import { useEffect, useState } from "react";
|
|
300
|
+
import { Text as Text2 } from "ink";
|
|
301
|
+
import { jsx as jsx2 } from "react/jsx-runtime";
|
|
302
|
+
function BlinkingText({
|
|
303
|
+
color,
|
|
304
|
+
intervalMs = 600,
|
|
305
|
+
bold = true,
|
|
306
|
+
children
|
|
307
|
+
}) {
|
|
308
|
+
const [bright, setBright] = useState(true);
|
|
309
|
+
useEffect(() => {
|
|
310
|
+
const id = setInterval(() => setBright((b) => !b), intervalMs);
|
|
311
|
+
return () => clearInterval(id);
|
|
312
|
+
}, [intervalMs]);
|
|
313
|
+
return /* @__PURE__ */ jsx2(Text2, { color, bold, dimColor: !bright, children });
|
|
314
|
+
}
|
|
315
|
+
|
|
269
316
|
// src/utils/spacing.ts
|
|
270
317
|
var SPACING = {
|
|
271
318
|
none: 0,
|
|
@@ -278,7 +325,7 @@ var SPACING = {
|
|
|
278
325
|
};
|
|
279
326
|
|
|
280
327
|
// src/components/layout/header.tsx
|
|
281
|
-
import { jsx as
|
|
328
|
+
import { jsx as jsx3, jsxs } from "react/jsx-runtime";
|
|
282
329
|
var LOGO_BREW = [
|
|
283
330
|
"\u256D\u2501\u2501\u256E\u2571\u256D\u2501\u2501\u2501\u256E\u256D\u2501\u2501\u2501\u256E\u256D\u256E\u256D\u256E\u256D\u256E\u2571\u2571\u2571\u2571\u2571\u2571\u2571",
|
|
284
331
|
"\u2503\u256D\u256E\u2503\u2571\u2503\u256D\u2501\u256E\u2503\u2503\u256D\u2501\u2501\u256F\u2503\u2503\u2503\u2503\u2503\u2503\u2571\u2571\u2571\u2571\u2571\u2571\u2571",
|
|
@@ -313,180 +360,158 @@ var VIEW_LABEL_KEYS = {
|
|
|
313
360
|
compliance: "view_compliance",
|
|
314
361
|
account: "view_account"
|
|
315
362
|
};
|
|
316
|
-
|
|
317
|
-
dashboard: "1",
|
|
318
|
-
installed: "2",
|
|
319
|
-
search: "",
|
|
320
|
-
outdated: "3",
|
|
321
|
-
"package-info": "",
|
|
322
|
-
services: "4",
|
|
323
|
-
doctor: "5",
|
|
324
|
-
profiles: "6",
|
|
325
|
-
"smart-cleanup": "7",
|
|
326
|
-
history: "8",
|
|
327
|
-
"security-audit": "9",
|
|
328
|
-
rollback: "",
|
|
329
|
-
brewfile: "",
|
|
330
|
-
sync: "",
|
|
331
|
-
compliance: "",
|
|
332
|
-
account: "0"
|
|
333
|
-
};
|
|
334
|
-
var TAB_VIEWS = [
|
|
335
|
-
"dashboard",
|
|
336
|
-
"installed",
|
|
337
|
-
"outdated",
|
|
338
|
-
"package-info",
|
|
339
|
-
"services",
|
|
340
|
-
"doctor",
|
|
341
|
-
"profiles",
|
|
342
|
-
"smart-cleanup",
|
|
343
|
-
"history",
|
|
344
|
-
"rollback",
|
|
345
|
-
"brewfile",
|
|
346
|
-
"sync",
|
|
347
|
-
"security-audit",
|
|
348
|
-
"compliance",
|
|
349
|
-
"account"
|
|
350
|
-
];
|
|
351
|
-
function MenuItem({ view, currentView }) {
|
|
352
|
-
const key = VIEW_KEYS[view];
|
|
363
|
+
function MenuItem({ view, currentView, cursorView, menuMode }) {
|
|
353
364
|
const viewLabel = t(VIEW_LABEL_KEYS[view]);
|
|
354
365
|
const isPro = isProView(view) || isTeamView(view);
|
|
355
|
-
const
|
|
366
|
+
const isCurrent = view === currentView;
|
|
367
|
+
const isCursor = menuMode && view === cursorView;
|
|
356
368
|
const isAccount = view === "account";
|
|
357
|
-
const
|
|
369
|
+
const indicatorColor = isCursor ? COLORS.brand : COLORS.success;
|
|
370
|
+
const labelColor = isCursor ? COLORS.brand : isCurrent ? COLORS.success : isAccount ? COLORS.gold : COLORS.textSecondary;
|
|
371
|
+
const showArrow = menuMode ? isCursor : isCurrent;
|
|
358
372
|
return /* @__PURE__ */ jsxs(Box, { children: [
|
|
359
|
-
|
|
373
|
+
showArrow ? /* @__PURE__ */ jsxs(Text3, { color: indicatorColor, bold: true, children: [
|
|
360
374
|
"\u25B6",
|
|
361
375
|
" "
|
|
362
|
-
] }) : /* @__PURE__ */
|
|
363
|
-
/* @__PURE__ */
|
|
364
|
-
/* @__PURE__ */ jsxs(
|
|
365
|
-
" ",
|
|
366
|
-
viewLabel
|
|
367
|
-
] }),
|
|
368
|
-
isPro && /* @__PURE__ */ jsxs(Text2, { color: COLORS.brand, bold: true, children: [
|
|
376
|
+
] }) : /* @__PURE__ */ jsx3(Text3, { children: " " }),
|
|
377
|
+
/* @__PURE__ */ jsx3(Text3, { bold: showArrow, underline: !menuMode && isCurrent, color: labelColor, children: viewLabel }),
|
|
378
|
+
isPro && /* @__PURE__ */ jsxs(Text3, { color: COLORS.brand, bold: true, children: [
|
|
369
379
|
" ",
|
|
370
380
|
t("pro_badge")
|
|
371
381
|
] })
|
|
372
382
|
] });
|
|
373
383
|
}
|
|
374
|
-
var COL1_VIEWS =
|
|
375
|
-
var COL2_VIEWS =
|
|
384
|
+
var COL1_VIEWS = MENU_VIEWS.slice(0, 6);
|
|
385
|
+
var COL2_VIEWS = MENU_VIEWS.slice(6);
|
|
376
386
|
function Header() {
|
|
377
387
|
const currentView = useNavigationStore((s) => s.currentView);
|
|
388
|
+
const menuMode = useNavigationStore((s) => s.menuMode);
|
|
389
|
+
const menuCursor = useNavigationStore((s) => s.menuCursor);
|
|
378
390
|
useLocaleStore((s) => s.locale);
|
|
379
391
|
const { stdout } = useStdout();
|
|
380
392
|
const cols = stdout?.columns ?? 80;
|
|
381
393
|
const isNarrow = cols < 95;
|
|
382
|
-
const
|
|
383
|
-
|
|
384
|
-
/* @__PURE__ */
|
|
394
|
+
const cursorView = menuMode ? MENU_VIEWS[menuCursor] ?? null : null;
|
|
395
|
+
const logoBlock = /* @__PURE__ */ jsx3(Box, { flexDirection: "column", flexShrink: 0, children: LOGO_BREW.map((brew, i) => /* @__PURE__ */ jsxs(Box, { children: [
|
|
396
|
+
/* @__PURE__ */ jsx3(GradientText, { colors: GRADIENTS.gold, children: brew }),
|
|
397
|
+
/* @__PURE__ */ jsx3(GradientText, { colors: GRADIENTS.darkGold, children: LOGO_TUI[i] })
|
|
385
398
|
] }, `logo-${i}`)) });
|
|
386
|
-
const
|
|
399
|
+
const menuBorderColor = menuMode ? COLORS.brand : COLORS.lavender;
|
|
400
|
+
const menuBlock = /* @__PURE__ */ jsxs(Box, { borderStyle: "round", borderColor: menuBorderColor, paddingX: SPACING.xs, flexDirection: "column", alignSelf: isNarrow ? "flex-start" : "center", children: [
|
|
387
401
|
/* @__PURE__ */ jsxs(Box, { flexDirection: "row", children: [
|
|
388
|
-
/* @__PURE__ */
|
|
389
|
-
/* @__PURE__ */
|
|
402
|
+
/* @__PURE__ */ jsx3(Box, { flexDirection: "column", children: COL1_VIEWS.map((view) => /* @__PURE__ */ jsx3(MenuItem, { view, currentView, cursorView, menuMode }, view)) }),
|
|
403
|
+
/* @__PURE__ */ jsx3(Box, { flexDirection: "column", marginLeft: SPACING.sm, children: COL2_VIEWS.map((view) => /* @__PURE__ */ jsx3(MenuItem, { view, currentView, cursorView, menuMode }, view)) })
|
|
390
404
|
] }),
|
|
391
|
-
/* @__PURE__ */
|
|
392
|
-
|
|
393
|
-
/* @__PURE__ */
|
|
394
|
-
|
|
395
|
-
|
|
396
|
-
|
|
397
|
-
|
|
398
|
-
|
|
399
|
-
"\u2503",
|
|
400
|
-
" "
|
|
401
|
-
] }),
|
|
402
|
-
/* @__PURE__ */ jsx2(Text2, { bold: true, color: COLORS.white, children: "L" }),
|
|
403
|
-
/* @__PURE__ */ jsxs(Text2, { color: COLORS.textSecondary, children: [
|
|
404
|
-
" ",
|
|
405
|
-
t("hint_lang")
|
|
406
|
-
] })
|
|
407
|
-
] })
|
|
405
|
+
/* @__PURE__ */ jsx3(Box, { borderStyle: "single", borderTop: true, borderBottom: false, borderLeft: false, borderRight: false, borderColor: menuBorderColor, marginTop: SPACING.none, children: menuMode ? /* @__PURE__ */ jsxs(Text3, { color: COLORS.brand, children: [
|
|
406
|
+
t("hint_menuMode_prefix"),
|
|
407
|
+
/* @__PURE__ */ jsx3(BlinkingText, { color: COLORS.brand, children: "m" }),
|
|
408
|
+
t("hint_menuMode_suffix")
|
|
409
|
+
] }) : /* @__PURE__ */ jsxs(Text3, { color: COLORS.textSecondary, children: [
|
|
410
|
+
/* @__PURE__ */ jsx3(BlinkingText, { color: COLORS.brand, children: "M" }),
|
|
411
|
+
t("hint_menuOpen_suffix")
|
|
412
|
+
] }) })
|
|
408
413
|
] });
|
|
409
414
|
if (isNarrow) {
|
|
410
415
|
return /* @__PURE__ */ jsxs(Box, { flexDirection: "column", paddingX: SPACING.xs, children: [
|
|
411
416
|
logoBlock,
|
|
412
|
-
/* @__PURE__ */
|
|
417
|
+
/* @__PURE__ */ jsx3(Box, { marginTop: SPACING.xs, children: menuBlock })
|
|
413
418
|
] });
|
|
414
419
|
}
|
|
415
420
|
return /* @__PURE__ */ jsxs(Box, { flexDirection: "row", paddingX: SPACING.xs, alignItems: "center", children: [
|
|
416
421
|
logoBlock,
|
|
417
|
-
/* @__PURE__ */
|
|
422
|
+
/* @__PURE__ */ jsx3(Box, { marginLeft: SPACING.sm, children: menuBlock })
|
|
418
423
|
] });
|
|
419
424
|
}
|
|
420
425
|
|
|
421
426
|
// src/components/layout/footer.tsx
|
|
422
|
-
import
|
|
423
|
-
import { Box as Box2, Text as
|
|
424
|
-
import { Fragment as Fragment2, jsx as
|
|
427
|
+
import React3 from "react";
|
|
428
|
+
import { Box as Box2, Text as Text4 } from "ink";
|
|
429
|
+
import { Fragment as Fragment2, jsx as jsx4, jsxs as jsxs2 } from "react/jsx-runtime";
|
|
425
430
|
var VIEW_HINT_DEFS = {
|
|
426
|
-
dashboard: [["1
|
|
427
|
-
installed: [["/", "hint_filter"], ["enter", "hint_info"], ["
|
|
428
|
-
search: [["
|
|
429
|
-
outdated: [["enter", "hint_upgrade"], ["
|
|
430
|
-
"package-info": [["
|
|
431
|
-
services: [["
|
|
432
|
-
doctor: [["
|
|
433
|
-
profiles: [["
|
|
434
|
-
"smart-cleanup": [["enter", "hint_toggle"], ["
|
|
435
|
-
history: [["/", "hint_search"], ["enter", "hint_replay"], ["
|
|
436
|
-
"security-audit": [["
|
|
437
|
-
rollback: [["j/k", "hint_navigate"], ["enter", "hint_select"], ["
|
|
438
|
-
brewfile: [["
|
|
439
|
-
sync: [["
|
|
440
|
-
compliance: [["
|
|
441
|
-
account: [["
|
|
431
|
+
dashboard: [["1", "hint_refresh"]],
|
|
432
|
+
installed: [["/", "hint_filter"], ["enter", "hint_info"], ["1", "hint_uninstall"], ["2", "hint_switchTab"]],
|
|
433
|
+
search: [["enter", "hint_details"], ["1", "hint_install"]],
|
|
434
|
+
outdated: [["enter", "hint_upgrade"], ["1", "hint_upgradeAll"], ["2", "hint_pin"], ["3", "hint_refresh"]],
|
|
435
|
+
"package-info": [["1", "hint_install"], ["2", "hint_uninstall"], ["3", "hint_upgrade"]],
|
|
436
|
+
services: [["1", "hint_start"], ["2", "hint_stop"], ["3", "hint_restart"], ["4", "hint_refresh"]],
|
|
437
|
+
doctor: [["1", "hint_refresh"]],
|
|
438
|
+
profiles: [["enter", "hint_details"], ["1", "hint_new"], ["2", "hint_edit"], ["3", "hint_import"], ["4", "hint_delete"]],
|
|
439
|
+
"smart-cleanup": [["enter", "hint_toggle"], ["1", "hint_all"], ["2", "hint_clean"], ["3", "hint_force"], ["4", "hint_refresh"]],
|
|
440
|
+
history: [["/", "hint_search"], ["enter", "hint_replay"], ["1", "hint_filter"], ["2", "hint_clear"]],
|
|
441
|
+
"security-audit": [["enter", "hint_details"], ["1", "hint_scan"], ["2", "hint_upgrade"]],
|
|
442
|
+
rollback: [["j/k", "hint_navigate"], ["enter", "hint_select"], ["1", "hint_rollback_confirm"]],
|
|
443
|
+
brewfile: [["1", "hint_new"], ["2", "hint_refresh"], ["3", "hint_reconcile"]],
|
|
444
|
+
sync: [["1", "hint_sync"], ["2", "hint_refresh"], ["3", "hint_conflict"], ["4", "hint_useLocal"]],
|
|
445
|
+
compliance: [["1", "hint_scan"], ["2", "hint_import"], ["3", "hint_export"], ["4", "hint_clean"]],
|
|
446
|
+
account: [["1", "hint_promo"], ["2", "hint_deactivate"]]
|
|
442
447
|
};
|
|
448
|
+
function hasNumberedActions(defs) {
|
|
449
|
+
return defs.some(([key]) => /^\d+$/.test(key));
|
|
450
|
+
}
|
|
443
451
|
function HintItem({ def }) {
|
|
444
|
-
if (def.length === 1) return /* @__PURE__ */ jsx3(Text3, { color: COLORS.gold, dimColor: true, children: t(def[0]) });
|
|
445
452
|
return /* @__PURE__ */ jsxs2(Fragment2, { children: [
|
|
446
|
-
/* @__PURE__ */
|
|
447
|
-
/* @__PURE__ */
|
|
448
|
-
/* @__PURE__ */
|
|
453
|
+
/* @__PURE__ */ jsx4(Text4, { color: COLORS.text, bold: true, children: def[0] }),
|
|
454
|
+
/* @__PURE__ */ jsx4(Text4, { color: COLORS.textSecondary, children: ":" }),
|
|
455
|
+
/* @__PURE__ */ jsx4(Text4, { color: COLORS.gold, dimColor: true, children: t(def[1]) })
|
|
449
456
|
] });
|
|
450
457
|
}
|
|
451
458
|
function Footer() {
|
|
452
459
|
const currentView = useNavigationStore((s) => s.currentView);
|
|
460
|
+
const menuMode = useNavigationStore((s) => s.menuMode);
|
|
453
461
|
const locale = useLocaleStore((s) => s.locale);
|
|
454
462
|
const defs = VIEW_HINT_DEFS[currentView] ?? [];
|
|
455
|
-
|
|
456
|
-
|
|
457
|
-
|
|
458
|
-
|
|
459
|
-
|
|
463
|
+
const showChoose = hasNumberedActions(defs) && !menuMode;
|
|
464
|
+
return /* @__PURE__ */ jsxs2(Box2, { flexDirection: "column", children: [
|
|
465
|
+
showChoose && /* @__PURE__ */ jsx4(Box2, { paddingX: SPACING.xs, children: /* @__PURE__ */ jsx4(Text4, { color: COLORS.text, children: t("hint_chooseNumber") }) }),
|
|
466
|
+
/* @__PURE__ */ jsxs2(Box2, { borderStyle: "single", borderTop: true, borderBottom: false, borderLeft: false, borderRight: false, borderColor: COLORS.gold, paddingX: SPACING.xs, flexWrap: "wrap", children: [
|
|
467
|
+
!menuMode && defs.map((def, i) => /* @__PURE__ */ jsxs2(React3.Fragment, { children: [
|
|
468
|
+
i > 0 && /* @__PURE__ */ jsxs2(Text4, { color: COLORS.border, children: [
|
|
460
469
|
" ",
|
|
461
470
|
"\u2502",
|
|
462
471
|
" "
|
|
463
472
|
] }),
|
|
464
|
-
/* @__PURE__ */
|
|
465
|
-
] },
|
|
466
|
-
|
|
467
|
-
|
|
468
|
-
|
|
469
|
-
|
|
470
|
-
|
|
471
|
-
|
|
472
|
-
|
|
473
|
-
|
|
474
|
-
|
|
475
|
-
|
|
476
|
-
|
|
477
|
-
|
|
478
|
-
|
|
473
|
+
/* @__PURE__ */ jsx4(HintItem, { def })
|
|
474
|
+
] }, `${def[0]}:${def[1]}`)),
|
|
475
|
+
!menuMode && defs.length > 0 && /* @__PURE__ */ jsxs2(Text4, { color: COLORS.border, children: [
|
|
476
|
+
" ",
|
|
477
|
+
"\u2502",
|
|
478
|
+
" "
|
|
479
|
+
] }),
|
|
480
|
+
/* @__PURE__ */ jsx4(Text4, { color: COLORS.text, bold: true, children: "esc" }),
|
|
481
|
+
/* @__PURE__ */ jsx4(Text4, { color: COLORS.textSecondary, children: ":" }),
|
|
482
|
+
/* @__PURE__ */ jsx4(Text4, { color: COLORS.gold, dimColor: true, children: t("hint_back") }),
|
|
483
|
+
/* @__PURE__ */ jsxs2(Text4, { color: COLORS.border, children: [
|
|
484
|
+
" ",
|
|
485
|
+
"\u2502",
|
|
486
|
+
" "
|
|
487
|
+
] }),
|
|
488
|
+
/* @__PURE__ */ jsx4(Text4, { color: COLORS.text, bold: true, children: "q" }),
|
|
489
|
+
/* @__PURE__ */ jsx4(Text4, { color: COLORS.textSecondary, children: ":" }),
|
|
490
|
+
/* @__PURE__ */ jsx4(Text4, { color: COLORS.gold, dimColor: true, children: t("hint_quit") }),
|
|
491
|
+
/* @__PURE__ */ jsxs2(Text4, { color: COLORS.lavender, children: [
|
|
492
|
+
" ",
|
|
493
|
+
"\u2503",
|
|
494
|
+
" "
|
|
495
|
+
] }),
|
|
496
|
+
/* @__PURE__ */ jsx4(Text4, { color: COLORS.text, bold: true, children: "L" }),
|
|
497
|
+
/* @__PURE__ */ jsx4(Text4, { color: COLORS.textSecondary, children: ":" }),
|
|
498
|
+
/* @__PURE__ */ jsxs2(Text4, { color: COLORS.gold, dimColor: true, children: [
|
|
499
|
+
t("hint_lang"),
|
|
500
|
+
"(",
|
|
501
|
+
locale,
|
|
502
|
+
")"
|
|
503
|
+
] })
|
|
479
504
|
] })
|
|
480
505
|
] });
|
|
481
506
|
}
|
|
482
507
|
|
|
483
508
|
// src/components/layout/app-layout.tsx
|
|
484
|
-
import { jsx as
|
|
509
|
+
import { jsx as jsx5, jsxs as jsxs3 } from "react/jsx-runtime";
|
|
485
510
|
function AppLayout({ children }) {
|
|
486
511
|
return /* @__PURE__ */ jsxs3(Box3, { flexDirection: "column", width: "100%", children: [
|
|
487
|
-
/* @__PURE__ */
|
|
488
|
-
/* @__PURE__ */
|
|
489
|
-
/* @__PURE__ */
|
|
512
|
+
/* @__PURE__ */ jsx5(Header, {}),
|
|
513
|
+
/* @__PURE__ */ jsx5(Box3, { flexDirection: "column", flexGrow: 1, paddingX: SPACING.sm, paddingY: SPACING.xs, children }),
|
|
514
|
+
/* @__PURE__ */ jsx5(Footer, {})
|
|
490
515
|
] });
|
|
491
516
|
}
|
|
492
517
|
|
|
@@ -629,27 +654,42 @@ var useModalStore = create3((set) => ({
|
|
|
629
654
|
}));
|
|
630
655
|
|
|
631
656
|
// src/hooks/use-keyboard.ts
|
|
632
|
-
var VIEW_KEYS2 = {
|
|
633
|
-
"1": "dashboard",
|
|
634
|
-
"2": "installed",
|
|
635
|
-
"3": "outdated",
|
|
636
|
-
"4": "services",
|
|
637
|
-
"5": "doctor",
|
|
638
|
-
"6": "profiles",
|
|
639
|
-
"7": "smart-cleanup",
|
|
640
|
-
"8": "history",
|
|
641
|
-
"9": "security-audit",
|
|
642
|
-
"0": "account"
|
|
643
|
-
};
|
|
644
657
|
function useGlobalKeyboard(opts) {
|
|
645
658
|
const navigate = useNavigationStore((s) => s.navigate);
|
|
646
|
-
const currentView = useNavigationStore((s) => s.currentView);
|
|
647
659
|
const goBack = useNavigationStore((s) => s.goBack);
|
|
660
|
+
const menuMode = useNavigationStore((s) => s.menuMode);
|
|
661
|
+
const enterMenuMode = useNavigationStore((s) => s.enterMenuMode);
|
|
662
|
+
const exitMenuMode = useNavigationStore((s) => s.exitMenuMode);
|
|
663
|
+
const moveMenuCursor = useNavigationStore((s) => s.moveMenuCursor);
|
|
664
|
+
const selectMenuItem = useNavigationStore((s) => s.selectMenuItem);
|
|
648
665
|
const { locale, setLocale } = useLocaleStore();
|
|
649
666
|
const modalOpen = useModalStore((s) => s.isOpen);
|
|
650
667
|
useInput((input, key) => {
|
|
651
668
|
if (opts?.disabled) return;
|
|
652
669
|
if (modalOpen) return;
|
|
670
|
+
if (menuMode) {
|
|
671
|
+
if (input === "q" || key.ctrl && input === "c") {
|
|
672
|
+
opts?.onQuit?.();
|
|
673
|
+
return;
|
|
674
|
+
}
|
|
675
|
+
if (key.escape || input === "m") {
|
|
676
|
+
exitMenuMode();
|
|
677
|
+
return;
|
|
678
|
+
}
|
|
679
|
+
if (key.upArrow) {
|
|
680
|
+
moveMenuCursor(-1);
|
|
681
|
+
return;
|
|
682
|
+
}
|
|
683
|
+
if (key.downArrow) {
|
|
684
|
+
moveMenuCursor(1);
|
|
685
|
+
return;
|
|
686
|
+
}
|
|
687
|
+
if (key.return) {
|
|
688
|
+
selectMenuItem();
|
|
689
|
+
return;
|
|
690
|
+
}
|
|
691
|
+
return;
|
|
692
|
+
}
|
|
653
693
|
if (input === "q" || key.ctrl && input === "c") {
|
|
654
694
|
opts?.onQuit?.();
|
|
655
695
|
return;
|
|
@@ -658,12 +698,8 @@ function useGlobalKeyboard(opts) {
|
|
|
658
698
|
goBack();
|
|
659
699
|
return;
|
|
660
700
|
}
|
|
661
|
-
if (
|
|
662
|
-
|
|
663
|
-
return;
|
|
664
|
-
}
|
|
665
|
-
if (key.tab) {
|
|
666
|
-
navigate(getNextView(currentView));
|
|
701
|
+
if (input === "m") {
|
|
702
|
+
enterMenuMode();
|
|
667
703
|
return;
|
|
668
704
|
}
|
|
669
705
|
if (input === "S") {
|
|
@@ -674,9 +710,6 @@ function useGlobalKeyboard(opts) {
|
|
|
674
710
|
setLocale(locale === "en" ? "es" : "en");
|
|
675
711
|
return;
|
|
676
712
|
}
|
|
677
|
-
if (input in VIEW_KEYS2) {
|
|
678
|
-
navigate(VIEW_KEYS2[input]);
|
|
679
|
-
}
|
|
680
713
|
}, { isActive: !opts?.disabled });
|
|
681
714
|
}
|
|
682
715
|
|
|
@@ -704,78 +737,88 @@ async function markOnboardingComplete() {
|
|
|
704
737
|
}
|
|
705
738
|
|
|
706
739
|
// src/views/welcome.tsx
|
|
707
|
-
import { useEffect } from "react";
|
|
708
|
-
import { Box as Box4, Text as
|
|
709
|
-
|
|
740
|
+
import { useEffect as useEffect2 } from "react";
|
|
741
|
+
import { Box as Box4, Text as Text5 } from "ink";
|
|
742
|
+
|
|
743
|
+
// src/hooks/use-view-input.ts
|
|
744
|
+
import { useInput as useInput2 } from "ink";
|
|
745
|
+
function useViewInput(handler, opts) {
|
|
746
|
+
const menuMode = useNavigationStore((s) => s.menuMode);
|
|
747
|
+
const baseActive = opts?.isActive ?? true;
|
|
748
|
+
useInput2(handler, { ...opts, isActive: baseActive && !menuMode });
|
|
749
|
+
}
|
|
750
|
+
|
|
751
|
+
// src/views/welcome.tsx
|
|
752
|
+
import { jsx as jsx6, jsxs as jsxs4 } from "react/jsx-runtime";
|
|
710
753
|
function WelcomeView({ onContinue }) {
|
|
711
|
-
|
|
754
|
+
useEffect2(() => {
|
|
712
755
|
return () => {
|
|
713
756
|
};
|
|
714
757
|
}, []);
|
|
715
|
-
|
|
758
|
+
useViewInput((input, key) => {
|
|
716
759
|
if (key.return || input === " " || key.escape) {
|
|
717
760
|
void markOnboardingComplete().finally(onContinue);
|
|
718
761
|
}
|
|
719
762
|
});
|
|
720
763
|
return /* @__PURE__ */ jsxs4(Box4, { flexDirection: "column", paddingY: SPACING.md, paddingX: SPACING.lg, children: [
|
|
721
|
-
/* @__PURE__ */
|
|
722
|
-
/* @__PURE__ */
|
|
764
|
+
/* @__PURE__ */ jsx6(Box4, { children: /* @__PURE__ */ jsx6(GradientText, { colors: GRADIENTS.gold, bold: true, children: t("welcome_title") }) }),
|
|
765
|
+
/* @__PURE__ */ jsx6(Box4, { marginTop: SPACING.sm, children: /* @__PURE__ */ jsx6(Text5, { color: COLORS.text, children: t("welcome_intro") }) }),
|
|
723
766
|
/* @__PURE__ */ jsxs4(Box4, { flexDirection: "column", marginTop: SPACING.sm, children: [
|
|
724
|
-
/* @__PURE__ */
|
|
767
|
+
/* @__PURE__ */ jsx6(Text5, { color: COLORS.muted, children: t("welcome_keysHeader") }),
|
|
725
768
|
/* @__PURE__ */ jsxs4(Box4, { flexDirection: "column", paddingLeft: SPACING.sm, marginTop: SPACING.xs, children: [
|
|
726
|
-
/* @__PURE__ */ jsxs4(
|
|
727
|
-
/* @__PURE__ */
|
|
728
|
-
"
|
|
729
|
-
t("
|
|
730
|
-
] }),
|
|
731
|
-
/* @__PURE__ */ jsxs4(Text4, { children: [
|
|
732
|
-
/* @__PURE__ */ jsx5(Text4, { color: COLORS.gold, bold: true, children: "Tab" }),
|
|
733
|
-
" ",
|
|
734
|
-
t("welcome_keyCycleView")
|
|
769
|
+
/* @__PURE__ */ jsxs4(Text5, { children: [
|
|
770
|
+
/* @__PURE__ */ jsx6(Text5, { color: COLORS.gold, bold: true, children: "m" }),
|
|
771
|
+
" ",
|
|
772
|
+
t("welcome_keyMenu")
|
|
735
773
|
] }),
|
|
736
|
-
/* @__PURE__ */ jsxs4(
|
|
737
|
-
/* @__PURE__ */
|
|
774
|
+
/* @__PURE__ */ jsxs4(Text5, { children: [
|
|
775
|
+
/* @__PURE__ */ jsx6(Text5, { color: COLORS.gold, bold: true, children: "\u2191 \u2193" }),
|
|
738
776
|
" ",
|
|
739
777
|
t("welcome_keyMove")
|
|
740
778
|
] }),
|
|
741
|
-
/* @__PURE__ */ jsxs4(
|
|
742
|
-
/* @__PURE__ */
|
|
743
|
-
"
|
|
744
|
-
t("
|
|
779
|
+
/* @__PURE__ */ jsxs4(Text5, { children: [
|
|
780
|
+
/* @__PURE__ */ jsx6(Text5, { color: COLORS.gold, bold: true, children: "1-9" }),
|
|
781
|
+
" ",
|
|
782
|
+
t("welcome_keyAction")
|
|
745
783
|
] }),
|
|
746
|
-
/* @__PURE__ */ jsxs4(
|
|
747
|
-
/* @__PURE__ */
|
|
784
|
+
/* @__PURE__ */ jsxs4(Text5, { children: [
|
|
785
|
+
/* @__PURE__ */ jsx6(Text5, { color: COLORS.gold, bold: true, children: "Enter" }),
|
|
748
786
|
" ",
|
|
749
787
|
t("welcome_keySelect")
|
|
750
788
|
] }),
|
|
751
|
-
/* @__PURE__ */ jsxs4(
|
|
752
|
-
/* @__PURE__ */
|
|
789
|
+
/* @__PURE__ */ jsxs4(Text5, { children: [
|
|
790
|
+
/* @__PURE__ */ jsx6(Text5, { color: COLORS.gold, bold: true, children: "S" }),
|
|
791
|
+
" ",
|
|
792
|
+
t("welcome_keySearch")
|
|
793
|
+
] }),
|
|
794
|
+
/* @__PURE__ */ jsxs4(Text5, { children: [
|
|
795
|
+
/* @__PURE__ */ jsx6(Text5, { color: COLORS.gold, bold: true, children: "Esc" }),
|
|
753
796
|
" ",
|
|
754
797
|
t("welcome_keyBack")
|
|
755
798
|
] }),
|
|
756
|
-
/* @__PURE__ */ jsxs4(
|
|
757
|
-
/* @__PURE__ */
|
|
799
|
+
/* @__PURE__ */ jsxs4(Text5, { children: [
|
|
800
|
+
/* @__PURE__ */ jsx6(Text5, { color: COLORS.gold, bold: true, children: "L" }),
|
|
758
801
|
" ",
|
|
759
802
|
t("welcome_keyLocale")
|
|
760
803
|
] }),
|
|
761
|
-
/* @__PURE__ */ jsxs4(
|
|
762
|
-
/* @__PURE__ */
|
|
804
|
+
/* @__PURE__ */ jsxs4(Text5, { children: [
|
|
805
|
+
/* @__PURE__ */ jsx6(Text5, { color: COLORS.gold, bold: true, children: "q" }),
|
|
763
806
|
" ",
|
|
764
807
|
t("welcome_keyQuit")
|
|
765
808
|
] })
|
|
766
809
|
] })
|
|
767
810
|
] }),
|
|
768
811
|
/* @__PURE__ */ jsxs4(Box4, { flexDirection: "column", marginTop: SPACING.sm, children: [
|
|
769
|
-
/* @__PURE__ */
|
|
770
|
-
/* @__PURE__ */
|
|
812
|
+
/* @__PURE__ */ jsx6(Text5, { color: COLORS.muted, children: t("welcome_proHeader") }),
|
|
813
|
+
/* @__PURE__ */ jsx6(Box4, { paddingLeft: SPACING.sm, children: /* @__PURE__ */ jsx6(Text5, { color: COLORS.textSecondary, children: t("welcome_proIntro") }) })
|
|
771
814
|
] }),
|
|
772
|
-
/* @__PURE__ */
|
|
815
|
+
/* @__PURE__ */ jsx6(Box4, { marginTop: SPACING.md, children: /* @__PURE__ */ jsx6(Text5, { color: COLORS.success, bold: true, children: t("welcome_continueHint") }) })
|
|
773
816
|
] });
|
|
774
817
|
}
|
|
775
818
|
|
|
776
819
|
// src/components/common/upgrade-prompt.tsx
|
|
777
|
-
import { Box as Box5, Text as
|
|
778
|
-
import { jsx as
|
|
820
|
+
import { Box as Box5, Text as Text6 } from "ink";
|
|
821
|
+
import { jsx as jsx7, jsxs as jsxs5 } from "react/jsx-runtime";
|
|
779
822
|
var FEATURE_KEYS = {
|
|
780
823
|
profiles: { title: "upgrade_profiles", desc: "upgrade_profilesDesc" },
|
|
781
824
|
"smart-cleanup": { title: "upgrade_cleanup", desc: "upgrade_cleanupDesc" },
|
|
@@ -795,7 +838,7 @@ function UpgradePrompt({ viewId }) {
|
|
|
795
838
|
const pricingKey = team ? "upgrade_teamPricing" : "upgrade_pricing";
|
|
796
839
|
const buyUrlKey = team ? "upgrade_buyUrlTeam" : "upgrade_buyUrl";
|
|
797
840
|
const labelKey = team ? "upgrade_teamLabel" : "upgrade_proLabel";
|
|
798
|
-
return /* @__PURE__ */
|
|
841
|
+
return /* @__PURE__ */ jsx7(Box5, { flexDirection: "column", alignItems: "center", paddingY: SPACING.sm, children: /* @__PURE__ */ jsxs5(
|
|
799
842
|
Box5,
|
|
800
843
|
{
|
|
801
844
|
borderStyle: "double",
|
|
@@ -806,30 +849,30 @@ function UpgradePrompt({ viewId }) {
|
|
|
806
849
|
alignItems: "center",
|
|
807
850
|
width: "80%",
|
|
808
851
|
children: [
|
|
809
|
-
/* @__PURE__ */ jsxs5(
|
|
852
|
+
/* @__PURE__ */ jsxs5(Text6, { bold: true, color: COLORS.brand, children: [
|
|
810
853
|
"\u2B50",
|
|
811
854
|
" ",
|
|
812
855
|
t(headerKey, { title })
|
|
813
856
|
] }),
|
|
814
|
-
/* @__PURE__ */
|
|
815
|
-
/* @__PURE__ */
|
|
816
|
-
/* @__PURE__ */
|
|
857
|
+
/* @__PURE__ */ jsx7(Text6, { children: " " }),
|
|
858
|
+
/* @__PURE__ */ jsx7(Text6, { color: COLORS.text, wrap: "wrap", children: t(keys.desc) }),
|
|
859
|
+
/* @__PURE__ */ jsx7(Text6, { children: " " }),
|
|
817
860
|
/* @__PURE__ */ jsxs5(Box5, { flexDirection: "column", alignItems: "center", children: [
|
|
818
|
-
/* @__PURE__ */
|
|
819
|
-
/* @__PURE__ */
|
|
820
|
-
/* @__PURE__ */
|
|
821
|
-
/* @__PURE__ */ jsxs5(
|
|
861
|
+
/* @__PURE__ */ jsx7(Text6, { color: COLORS.info, bold: true, children: t(pricingKey) }),
|
|
862
|
+
/* @__PURE__ */ jsx7(Text6, { children: " " }),
|
|
863
|
+
/* @__PURE__ */ jsx7(Text6, { color: COLORS.muted, children: t("upgrade_buyAt") }),
|
|
864
|
+
/* @__PURE__ */ jsxs5(Text6, { color: COLORS.sky, bold: true, children: [
|
|
822
865
|
" ",
|
|
823
866
|
t(buyUrlKey)
|
|
824
867
|
] }),
|
|
825
|
-
/* @__PURE__ */
|
|
826
|
-
/* @__PURE__ */
|
|
827
|
-
/* @__PURE__ */ jsxs5(
|
|
868
|
+
/* @__PURE__ */ jsx7(Text6, { children: " " }),
|
|
869
|
+
/* @__PURE__ */ jsx7(Text6, { color: COLORS.muted, children: t("upgrade_activateWith") }),
|
|
870
|
+
/* @__PURE__ */ jsxs5(Text6, { color: COLORS.success, bold: true, children: [
|
|
828
871
|
" ",
|
|
829
872
|
t("upgrade_activateCmd")
|
|
830
873
|
] }),
|
|
831
|
-
/* @__PURE__ */
|
|
832
|
-
/* @__PURE__ */
|
|
874
|
+
/* @__PURE__ */ jsx7(Text6, { children: " " }),
|
|
875
|
+
/* @__PURE__ */ jsx7(Text6, { color: COLORS.brand, children: t(labelKey) })
|
|
833
876
|
] })
|
|
834
877
|
]
|
|
835
878
|
}
|
|
@@ -837,8 +880,8 @@ function UpgradePrompt({ viewId }) {
|
|
|
837
880
|
}
|
|
838
881
|
|
|
839
882
|
// src/views/dashboard.tsx
|
|
840
|
-
import { useEffect as
|
|
841
|
-
import { Box as Box9, Text as
|
|
883
|
+
import { useEffect as useEffect3, useMemo as useMemo2 } from "react";
|
|
884
|
+
import { Box as Box9, Text as Text12, useStdout as useStdout3 } from "ink";
|
|
842
885
|
|
|
843
886
|
// src/stores/brew-store.ts
|
|
844
887
|
import { create as create4 } from "zustand";
|
|
@@ -1804,8 +1847,8 @@ var useComplianceStore = create8((set, get) => ({
|
|
|
1804
1847
|
}));
|
|
1805
1848
|
|
|
1806
1849
|
// src/components/common/stat-card.tsx
|
|
1807
|
-
import { Box as Box6, Text as
|
|
1808
|
-
import { jsx as
|
|
1850
|
+
import { Box as Box6, Text as Text7, useStdout as useStdout2 } from "ink";
|
|
1851
|
+
import { jsx as jsx8, jsxs as jsxs6 } from "react/jsx-runtime";
|
|
1809
1852
|
function StatCard({ label, value, color = COLORS.white }) {
|
|
1810
1853
|
const { stdout } = useStdout2();
|
|
1811
1854
|
const cols = stdout?.columns ?? 80;
|
|
@@ -1821,35 +1864,35 @@ function StatCard({ label, value, color = COLORS.white }) {
|
|
|
1821
1864
|
alignItems: "center",
|
|
1822
1865
|
minWidth: minW,
|
|
1823
1866
|
children: [
|
|
1824
|
-
/* @__PURE__ */
|
|
1825
|
-
/* @__PURE__ */
|
|
1867
|
+
/* @__PURE__ */ jsx8(Text7, { bold: true, color, children: value }),
|
|
1868
|
+
/* @__PURE__ */ jsx8(Text7, { color: COLORS.muted, children: label })
|
|
1826
1869
|
]
|
|
1827
1870
|
}
|
|
1828
1871
|
);
|
|
1829
1872
|
}
|
|
1830
1873
|
|
|
1831
1874
|
// src/components/common/loading.tsx
|
|
1832
|
-
import { Box as Box7, Text as
|
|
1875
|
+
import { Box as Box7, Text as Text8 } from "ink";
|
|
1833
1876
|
import { Spinner } from "@inkjs/ui";
|
|
1834
|
-
import { jsx as
|
|
1877
|
+
import { jsx as jsx9, jsxs as jsxs7 } from "react/jsx-runtime";
|
|
1835
1878
|
function Loading({ message }) {
|
|
1836
1879
|
useLocaleStore((s) => s.locale);
|
|
1837
|
-
return /* @__PURE__ */
|
|
1880
|
+
return /* @__PURE__ */ jsx9(Box7, { paddingY: SPACING.xs, children: /* @__PURE__ */ jsx9(Spinner, { label: message ?? t("loading_default") }) });
|
|
1838
1881
|
}
|
|
1839
1882
|
function ErrorMessage({ message }) {
|
|
1840
1883
|
useLocaleStore((s) => s.locale);
|
|
1841
1884
|
return /* @__PURE__ */ jsxs7(Box7, { paddingY: SPACING.xs, children: [
|
|
1842
|
-
/* @__PURE__ */ jsxs7(
|
|
1885
|
+
/* @__PURE__ */ jsxs7(Text8, { color: COLORS.error, bold: true, children: [
|
|
1843
1886
|
"\u2718",
|
|
1844
1887
|
" ",
|
|
1845
1888
|
t("error_prefix")
|
|
1846
1889
|
] }),
|
|
1847
|
-
/* @__PURE__ */
|
|
1890
|
+
/* @__PURE__ */ jsx9(Text8, { color: COLORS.error, children: message })
|
|
1848
1891
|
] });
|
|
1849
1892
|
}
|
|
1850
1893
|
|
|
1851
1894
|
// src/components/common/status-badge.tsx
|
|
1852
|
-
import { Text as
|
|
1895
|
+
import { Text as Text9 } from "ink";
|
|
1853
1896
|
import { jsxs as jsxs8 } from "react/jsx-runtime";
|
|
1854
1897
|
var BADGE_STYLES = {
|
|
1855
1898
|
success: { icon: "\u2714", color: COLORS.success },
|
|
@@ -1860,7 +1903,7 @@ var BADGE_STYLES = {
|
|
|
1860
1903
|
};
|
|
1861
1904
|
function StatusBadge({ label, variant }) {
|
|
1862
1905
|
const { icon, color } = BADGE_STYLES[variant];
|
|
1863
|
-
return /* @__PURE__ */ jsxs8(
|
|
1906
|
+
return /* @__PURE__ */ jsxs8(Text9, { color, children: [
|
|
1864
1907
|
icon,
|
|
1865
1908
|
" ",
|
|
1866
1909
|
label
|
|
@@ -1868,16 +1911,16 @@ function StatusBadge({ label, variant }) {
|
|
|
1868
1911
|
}
|
|
1869
1912
|
|
|
1870
1913
|
// src/components/common/section-header.tsx
|
|
1871
|
-
import { Box as Box8, Text as
|
|
1872
|
-
import { jsx as
|
|
1914
|
+
import { Box as Box8, Text as Text10 } from "ink";
|
|
1915
|
+
import { jsx as jsx10, jsxs as jsxs9 } from "react/jsx-runtime";
|
|
1873
1916
|
function SectionHeader({ emoji, title, color = COLORS.gold, gradient, count }) {
|
|
1874
1917
|
return /* @__PURE__ */ jsxs9(Box8, { gap: SPACING.xs, children: [
|
|
1875
|
-
/* @__PURE__ */ jsxs9(
|
|
1918
|
+
/* @__PURE__ */ jsxs9(Text10, { children: [
|
|
1876
1919
|
emoji,
|
|
1877
1920
|
" "
|
|
1878
1921
|
] }),
|
|
1879
|
-
gradient ? /* @__PURE__ */
|
|
1880
|
-
count !== void 0 && /* @__PURE__ */ jsxs9(
|
|
1922
|
+
gradient ? /* @__PURE__ */ jsx10(GradientText, { colors: gradient, bold: true, children: title }) : /* @__PURE__ */ jsx10(Text10, { bold: true, color, children: title }),
|
|
1923
|
+
count !== void 0 && /* @__PURE__ */ jsxs9(Text10, { color: COLORS.textSecondary, children: [
|
|
1881
1924
|
"(",
|
|
1882
1925
|
count,
|
|
1883
1926
|
")"
|
|
@@ -1886,23 +1929,23 @@ function SectionHeader({ emoji, title, color = COLORS.gold, gradient, count }) {
|
|
|
1886
1929
|
}
|
|
1887
1930
|
|
|
1888
1931
|
// src/components/common/version-arrow.tsx
|
|
1889
|
-
import { Text as
|
|
1890
|
-
import { Fragment as Fragment3, jsx as
|
|
1932
|
+
import { Text as Text11 } from "ink";
|
|
1933
|
+
import { Fragment as Fragment3, jsx as jsx11, jsxs as jsxs10 } from "react/jsx-runtime";
|
|
1891
1934
|
function VersionArrow({ current, latest }) {
|
|
1892
1935
|
return /* @__PURE__ */ jsxs10(Fragment3, { children: [
|
|
1893
|
-
/* @__PURE__ */ jsxs10(
|
|
1936
|
+
/* @__PURE__ */ jsxs10(Text11, { color: COLORS.muted, children: [
|
|
1894
1937
|
t("version_installed"),
|
|
1895
1938
|
" "
|
|
1896
1939
|
] }),
|
|
1897
|
-
/* @__PURE__ */
|
|
1898
|
-
/* @__PURE__ */
|
|
1899
|
-
/* @__PURE__ */
|
|
1900
|
-
/* @__PURE__ */ jsxs10(
|
|
1940
|
+
/* @__PURE__ */ jsx11(Text11, { color: COLORS.error, children: current }),
|
|
1941
|
+
/* @__PURE__ */ jsx11(Text11, { color: COLORS.warning, children: " \u2500\u2500 " }),
|
|
1942
|
+
/* @__PURE__ */ jsx11(Text11, { color: COLORS.gold, children: "\u25B6" }),
|
|
1943
|
+
/* @__PURE__ */ jsxs10(Text11, { color: COLORS.muted, children: [
|
|
1901
1944
|
" ",
|
|
1902
1945
|
t("version_available"),
|
|
1903
1946
|
" "
|
|
1904
1947
|
] }),
|
|
1905
|
-
/* @__PURE__ */
|
|
1948
|
+
/* @__PURE__ */ jsx11(Text11, { color: COLORS.teal, children: latest })
|
|
1906
1949
|
] });
|
|
1907
1950
|
}
|
|
1908
1951
|
|
|
@@ -1934,7 +1977,7 @@ function truncate(str, maxLen) {
|
|
|
1934
1977
|
}
|
|
1935
1978
|
|
|
1936
1979
|
// src/views/dashboard.tsx
|
|
1937
|
-
import { jsx as
|
|
1980
|
+
import { jsx as jsx12, jsxs as jsxs11 } from "react/jsx-runtime";
|
|
1938
1981
|
function ProStatusPanel() {
|
|
1939
1982
|
const security = useSecurityStore((s) => s.summary);
|
|
1940
1983
|
const drift = useBrewfileStore((s) => s.drift);
|
|
@@ -1947,28 +1990,28 @@ function ProStatusPanel() {
|
|
|
1947
1990
|
const syncAgo = lastSync ? formatRelativeTime(new Date(lastSync).getTime() / 1e3) : null;
|
|
1948
1991
|
const violationCount = complianceReport ? complianceReport.violations.length : null;
|
|
1949
1992
|
return /* @__PURE__ */ jsxs11(Box9, { flexDirection: "column", borderStyle: "round", borderColor: COLORS.purple, paddingX: SPACING.sm, paddingY: SPACING.none, marginTop: SPACING.xs, children: [
|
|
1950
|
-
/* @__PURE__ */
|
|
1993
|
+
/* @__PURE__ */ jsx12(Text12, { bold: true, color: COLORS.purple, children: t("dashboard_pro_status") }),
|
|
1951
1994
|
/* @__PURE__ */ jsxs11(Box9, { gap: SPACING.xs, children: [
|
|
1952
|
-
/* @__PURE__ */
|
|
1953
|
-
cveCount === null ? /* @__PURE__ */
|
|
1995
|
+
/* @__PURE__ */ jsx12(Text12, { color: COLORS.muted, children: t("dashboard_security") }),
|
|
1996
|
+
cveCount === null ? /* @__PURE__ */ jsx12(Text12, { color: COLORS.muted, children: "\u2014" }) : cveCount === 0 ? /* @__PURE__ */ jsx12(Text12, { color: COLORS.success, children: t("dashboard_no_cves") }) : /* @__PURE__ */ jsxs11(Text12, { color: COLORS.error, children: [
|
|
1954
1997
|
t("dashboard_cves", { count: String(cveCount) }),
|
|
1955
1998
|
criticalCount && criticalCount > 0 ? ` (${criticalCount} critical)` : ""
|
|
1956
1999
|
] })
|
|
1957
2000
|
] }),
|
|
1958
2001
|
/* @__PURE__ */ jsxs11(Box9, { gap: SPACING.xs, children: [
|
|
1959
|
-
/* @__PURE__ */
|
|
1960
|
-
driftScore === null ? /* @__PURE__ */
|
|
2002
|
+
/* @__PURE__ */ jsx12(Text12, { color: COLORS.muted, children: t("dashboard_brewfile") }),
|
|
2003
|
+
driftScore === null ? /* @__PURE__ */ jsx12(Text12, { color: COLORS.muted, children: "\u2014" }) : /* @__PURE__ */ jsxs11(Text12, { color: driftScore >= 80 ? COLORS.success : COLORS.warning, children: [
|
|
1961
2004
|
driftScore,
|
|
1962
2005
|
"%"
|
|
1963
2006
|
] })
|
|
1964
2007
|
] }),
|
|
1965
2008
|
/* @__PURE__ */ jsxs11(Box9, { gap: SPACING.xs, children: [
|
|
1966
|
-
/* @__PURE__ */
|
|
1967
|
-
syncAgo === null ? /* @__PURE__ */
|
|
2009
|
+
/* @__PURE__ */ jsx12(Text12, { color: COLORS.muted, children: t("dashboard_sync") }),
|
|
2010
|
+
syncAgo === null ? /* @__PURE__ */ jsx12(Text12, { color: COLORS.muted, children: t("dashboard_sync_never") }) : /* @__PURE__ */ jsx12(Text12, { color: COLORS.info, children: t("dashboard_sync_ago", { time: syncAgo }) })
|
|
1968
2011
|
] }),
|
|
1969
2012
|
/* @__PURE__ */ jsxs11(Box9, { gap: SPACING.xs, children: [
|
|
1970
|
-
/* @__PURE__ */
|
|
1971
|
-
violationCount === null ? /* @__PURE__ */
|
|
2013
|
+
/* @__PURE__ */ jsx12(Text12, { color: COLORS.muted, children: t("dashboard_compliance") }),
|
|
2014
|
+
violationCount === null ? /* @__PURE__ */ jsx12(Text12, { color: COLORS.muted, children: "\u2014" }) : violationCount === 0 ? /* @__PURE__ */ jsx12(Text12, { color: COLORS.success, children: t("dashboard_compliance_ok") }) : /* @__PURE__ */ jsx12(Text12, { color: COLORS.warning, children: t("dashboard_compliance_violations", { count: String(violationCount) }) })
|
|
1972
2015
|
] })
|
|
1973
2016
|
] });
|
|
1974
2017
|
}
|
|
@@ -1985,11 +2028,11 @@ function DashboardView() {
|
|
|
1985
2028
|
const isPro = useLicenseStore((s) => s.isPro);
|
|
1986
2029
|
const { stdout } = useStdout3();
|
|
1987
2030
|
const columns = stdout?.columns ?? 80;
|
|
1988
|
-
|
|
2031
|
+
useEffect3(() => {
|
|
1989
2032
|
fetchAll();
|
|
1990
2033
|
}, []);
|
|
1991
|
-
|
|
1992
|
-
if (input === "r" || input === "R") {
|
|
2034
|
+
useViewInput((input) => {
|
|
2035
|
+
if (input === "r" || input === "R" || input === "1") {
|
|
1993
2036
|
void fetchAll();
|
|
1994
2037
|
}
|
|
1995
2038
|
});
|
|
@@ -2010,11 +2053,11 @@ function DashboardView() {
|
|
|
2010
2053
|
const outdatedValue = loading.outdated ? "..." : errors.outdated ? t("dashboard_statError") : outdated.formulae.length + outdated.casks.length;
|
|
2011
2054
|
const servicesValue = loading.services ? "..." : errors.services ? t("dashboard_statError") : `${runningServices}/${services.length}`;
|
|
2012
2055
|
const lastUpdated = lastFetchedAt.installed ? formatRelativeTime(lastFetchedAt.installed / 1e3) : null;
|
|
2013
|
-
if (loading.installed) return /* @__PURE__ */
|
|
2056
|
+
if (loading.installed) return /* @__PURE__ */ jsx12(Loading, { message: t("loading_fetchingBrew") });
|
|
2014
2057
|
if (errors.installed) {
|
|
2015
2058
|
return /* @__PURE__ */ jsxs11(Box9, { flexDirection: "column", children: [
|
|
2016
|
-
/* @__PURE__ */
|
|
2017
|
-
/* @__PURE__ */
|
|
2059
|
+
/* @__PURE__ */ jsx12(ErrorMessage, { message: errors.installed }),
|
|
2060
|
+
/* @__PURE__ */ jsx12(Box9, { marginTop: SPACING.xs, children: /* @__PURE__ */ jsxs11(Text12, { color: COLORS.textSecondary, children: [
|
|
2018
2061
|
"r:",
|
|
2019
2062
|
t("hint_refresh")
|
|
2020
2063
|
] }) })
|
|
@@ -2022,11 +2065,11 @@ function DashboardView() {
|
|
|
2022
2065
|
}
|
|
2023
2066
|
const isNarrow = columns < 60;
|
|
2024
2067
|
return /* @__PURE__ */ jsxs11(Box9, { flexDirection: "column", gap: SPACING.sm, children: [
|
|
2025
|
-
/* @__PURE__ */
|
|
2068
|
+
/* @__PURE__ */ jsx12(SectionHeader, { emoji: "\u{1F4CA}", title: t("dashboard_overview"), gradient: GRADIENTS.gold }),
|
|
2026
2069
|
/* @__PURE__ */ jsxs11(Box9, { gap: SPACING.xs, flexWrap: "wrap", flexDirection: isNarrow ? "column" : "row", children: [
|
|
2027
|
-
/* @__PURE__ */
|
|
2028
|
-
/* @__PURE__ */
|
|
2029
|
-
/* @__PURE__ */
|
|
2070
|
+
/* @__PURE__ */ jsx12(StatCard, { label: t("dashboard_formulae"), value: formulae.length, color: COLORS.info }),
|
|
2071
|
+
/* @__PURE__ */ jsx12(StatCard, { label: t("dashboard_casks"), value: casks.length, color: COLORS.purple }),
|
|
2072
|
+
/* @__PURE__ */ jsx12(
|
|
2030
2073
|
StatCard,
|
|
2031
2074
|
{
|
|
2032
2075
|
label: t("dashboard_outdated"),
|
|
@@ -2034,7 +2077,7 @@ function DashboardView() {
|
|
|
2034
2077
|
color: typeof outdatedValue === "number" && outdatedValue > 0 ? COLORS.warning : errors.outdated ? COLORS.error : COLORS.success
|
|
2035
2078
|
}
|
|
2036
2079
|
),
|
|
2037
|
-
/* @__PURE__ */
|
|
2080
|
+
/* @__PURE__ */ jsx12(
|
|
2038
2081
|
StatCard,
|
|
2039
2082
|
{
|
|
2040
2083
|
label: t("dashboard_services"),
|
|
@@ -2043,66 +2086,66 @@ function DashboardView() {
|
|
|
2043
2086
|
}
|
|
2044
2087
|
)
|
|
2045
2088
|
] }),
|
|
2046
|
-
lastUpdated && /* @__PURE__ */
|
|
2089
|
+
lastUpdated && /* @__PURE__ */ jsx12(Text12, { color: COLORS.muted, children: t("dashboard_lastUpdated", { time: lastUpdated }) }),
|
|
2047
2090
|
partialErrors.length > 0 && /* @__PURE__ */ jsxs11(Box9, { flexDirection: "column", borderStyle: "round", borderColor: COLORS.warning, paddingX: SPACING.sm, paddingY: SPACING.none, children: [
|
|
2048
|
-
/* @__PURE__ */
|
|
2049
|
-
partialErrors.map((item) => /* @__PURE__ */ jsxs11(
|
|
2091
|
+
/* @__PURE__ */ jsx12(Text12, { color: COLORS.warning, bold: true, children: t("dashboard_partialData") }),
|
|
2092
|
+
partialErrors.map((item) => /* @__PURE__ */ jsxs11(Text12, { color: COLORS.muted, children: [
|
|
2050
2093
|
item.label,
|
|
2051
2094
|
": ",
|
|
2052
2095
|
item.message
|
|
2053
2096
|
] }, item.label))
|
|
2054
2097
|
] }),
|
|
2055
2098
|
config && !errors.config && /* @__PURE__ */ jsxs11(Box9, { flexDirection: "column", children: [
|
|
2056
|
-
/* @__PURE__ */
|
|
2099
|
+
/* @__PURE__ */ jsx12(SectionHeader, { emoji: "\u2139\uFE0F", title: t("dashboard_systemInfo"), gradient: [COLORS.text, COLORS.muted] }),
|
|
2057
2100
|
/* @__PURE__ */ jsxs11(Box9, { borderStyle: "round", borderColor: COLORS.blue, paddingX: SPACING.sm, paddingY: SPACING.none, flexDirection: "column", marginTop: SPACING.xs, children: [
|
|
2058
|
-
/* @__PURE__ */ jsxs11(
|
|
2059
|
-
/* @__PURE__ */
|
|
2101
|
+
/* @__PURE__ */ jsxs11(Text12, { children: [
|
|
2102
|
+
/* @__PURE__ */ jsx12(Text12, { color: COLORS.muted, children: t("dashboard_homebrew") }),
|
|
2060
2103
|
" ",
|
|
2061
2104
|
config.HOMEBREW_VERSION
|
|
2062
2105
|
] }),
|
|
2063
|
-
/* @__PURE__ */ jsxs11(
|
|
2064
|
-
/* @__PURE__ */
|
|
2106
|
+
/* @__PURE__ */ jsxs11(Text12, { children: [
|
|
2107
|
+
/* @__PURE__ */ jsx12(Text12, { color: COLORS.muted, children: t("dashboard_prefix") }),
|
|
2065
2108
|
" ",
|
|
2066
2109
|
config.HOMEBREW_PREFIX
|
|
2067
2110
|
] }),
|
|
2068
|
-
/* @__PURE__ */ jsxs11(
|
|
2069
|
-
/* @__PURE__ */
|
|
2111
|
+
/* @__PURE__ */ jsxs11(Text12, { children: [
|
|
2112
|
+
/* @__PURE__ */ jsx12(Text12, { color: COLORS.muted, children: t("dashboard_updated") }),
|
|
2070
2113
|
" ",
|
|
2071
2114
|
config.coreUpdated
|
|
2072
2115
|
] })
|
|
2073
2116
|
] })
|
|
2074
2117
|
] }),
|
|
2075
2118
|
!errors.outdated && outdated.formulae.length > 0 && /* @__PURE__ */ jsxs11(Box9, { flexDirection: "column", marginTop: SPACING.xs, children: [
|
|
2076
|
-
/* @__PURE__ */
|
|
2119
|
+
/* @__PURE__ */ jsx12(SectionHeader, { emoji: "\u{1F4E6}", title: t("dashboard_outdatedPackages"), gradient: GRADIENTS.fire }),
|
|
2077
2120
|
/* @__PURE__ */ jsxs11(Box9, { paddingLeft: SPACING.sm, flexDirection: "column", children: [
|
|
2078
2121
|
outdated.formulae.slice(0, 10).map((pkg) => /* @__PURE__ */ jsxs11(Box9, { gap: SPACING.xs, children: [
|
|
2079
|
-
/* @__PURE__ */
|
|
2080
|
-
/* @__PURE__ */
|
|
2122
|
+
/* @__PURE__ */ jsx12(Text12, { color: COLORS.text, children: pkg.name }),
|
|
2123
|
+
/* @__PURE__ */ jsx12(VersionArrow, { current: pkg.installed_versions[0] ?? "", latest: pkg.current_version })
|
|
2081
2124
|
] }, pkg.name)),
|
|
2082
|
-
outdated.formulae.length > 10 && /* @__PURE__ */
|
|
2125
|
+
outdated.formulae.length > 10 && /* @__PURE__ */ jsx12(Text12, { color: COLORS.textSecondary, italic: true, children: t("common_andMore", { count: outdated.formulae.length - 10 }) })
|
|
2083
2126
|
] })
|
|
2084
2127
|
] }),
|
|
2085
2128
|
!errors.services && errorServices > 0 && /* @__PURE__ */ jsxs11(Box9, { flexDirection: "column", marginTop: SPACING.xs, children: [
|
|
2086
|
-
/* @__PURE__ */
|
|
2087
|
-
/* @__PURE__ */
|
|
2088
|
-
/* @__PURE__ */
|
|
2089
|
-
/* @__PURE__ */
|
|
2090
|
-
s.exit_code != null && /* @__PURE__ */
|
|
2129
|
+
/* @__PURE__ */ jsx12(SectionHeader, { emoji: "\u26A0\uFE0F", title: t("dashboard_serviceErrors"), color: COLORS.error }),
|
|
2130
|
+
/* @__PURE__ */ jsx12(Box9, { paddingLeft: SPACING.sm, flexDirection: "column", children: errorServiceList.map((s) => /* @__PURE__ */ jsxs11(Box9, { gap: SPACING.xs, children: [
|
|
2131
|
+
/* @__PURE__ */ jsx12(StatusBadge, { label: t("badge_error"), variant: "error" }),
|
|
2132
|
+
/* @__PURE__ */ jsx12(Text12, { children: s.name }),
|
|
2133
|
+
s.exit_code != null && /* @__PURE__ */ jsx12(Text12, { color: COLORS.muted, children: t("common_exit", { code: s.exit_code }) })
|
|
2091
2134
|
] }, s.name)) })
|
|
2092
2135
|
] }),
|
|
2093
|
-
isPro() && /* @__PURE__ */
|
|
2136
|
+
isPro() && /* @__PURE__ */ jsx12(ProStatusPanel, {})
|
|
2094
2137
|
] });
|
|
2095
2138
|
}
|
|
2096
2139
|
|
|
2097
2140
|
// src/views/installed.tsx
|
|
2098
|
-
import { useState as
|
|
2099
|
-
import { Box as Box15, Text as
|
|
2141
|
+
import { useState as useState6, useMemo as useMemo3, useEffect as useEffect9, useRef as useRef2 } from "react";
|
|
2142
|
+
import { Box as Box15, Text as Text18 } from "ink";
|
|
2100
2143
|
|
|
2101
2144
|
// src/hooks/use-debounce.ts
|
|
2102
|
-
import { useState, useEffect as
|
|
2145
|
+
import { useState as useState2, useEffect as useEffect4 } from "react";
|
|
2103
2146
|
function useDebounce(value, delayMs) {
|
|
2104
|
-
const [debounced, setDebounced] =
|
|
2105
|
-
|
|
2147
|
+
const [debounced, setDebounced] = useState2(value);
|
|
2148
|
+
useEffect4(() => {
|
|
2106
2149
|
const timer = setTimeout(() => setDebounced(value), delayMs);
|
|
2107
2150
|
return () => clearTimeout(timer);
|
|
2108
2151
|
}, [value, delayMs]);
|
|
@@ -2110,26 +2153,26 @@ function useDebounce(value, delayMs) {
|
|
|
2110
2153
|
}
|
|
2111
2154
|
|
|
2112
2155
|
// src/hooks/use-brew-stream.ts
|
|
2113
|
-
import { useState as
|
|
2156
|
+
import { useState as useState3, useCallback, useRef, useEffect as useEffect5 } from "react";
|
|
2114
2157
|
var MAX_LINES = 100;
|
|
2115
2158
|
async function logToHistory(args, success, error) {
|
|
2116
2159
|
const detected = detectAction(args);
|
|
2117
2160
|
if (!detected) return;
|
|
2118
2161
|
try {
|
|
2119
2162
|
const isPro = useLicenseStore.getState().isPro();
|
|
2120
|
-
const { appendEntry: appendEntry2 } = await import("./history-logger-
|
|
2163
|
+
const { appendEntry: appendEntry2 } = await import("./history-logger-SB5UG5BQ.js");
|
|
2121
2164
|
await appendEntry2(isPro, detected.action, detected.packageName, success, error);
|
|
2122
2165
|
} catch {
|
|
2123
2166
|
}
|
|
2124
2167
|
}
|
|
2125
2168
|
function useBrewStream() {
|
|
2126
|
-
const [lines, setLines] =
|
|
2127
|
-
const [isRunning, setIsRunning] =
|
|
2128
|
-
const [error, setError2] =
|
|
2169
|
+
const [lines, setLines] = useState3([]);
|
|
2170
|
+
const [isRunning, setIsRunning] = useState3(false);
|
|
2171
|
+
const [error, setError2] = useState3(null);
|
|
2129
2172
|
const cancelRef = useRef(false);
|
|
2130
2173
|
const generatorRef = useRef(null);
|
|
2131
2174
|
const mountedRef = useRef(true);
|
|
2132
|
-
|
|
2175
|
+
useEffect5(() => {
|
|
2133
2176
|
mountedRef.current = true;
|
|
2134
2177
|
return () => {
|
|
2135
2178
|
mountedRef.current = false;
|
|
@@ -2169,7 +2212,7 @@ function useBrewStream() {
|
|
|
2169
2212
|
}
|
|
2170
2213
|
const MUTATING_COMMANDS = /* @__PURE__ */ new Set(["install", "uninstall", "upgrade", "pin", "unpin", "tap", "untap"]);
|
|
2171
2214
|
if (!cancelRef.current && MUTATING_COMMANDS.has(args[0] ?? "")) {
|
|
2172
|
-
void import("./snapshot-
|
|
2215
|
+
void import("./snapshot-ZOJETCED.js").then(({ captureSnapshot: captureSnapshot2, saveSnapshot: saveSnapshot2 }) => {
|
|
2173
2216
|
captureSnapshot2().then((s) => saveSnapshot2(s)).catch((err) => logger.warn("snapshot: capture/save failed", { error: String(err) }));
|
|
2174
2217
|
});
|
|
2175
2218
|
}
|
|
@@ -2187,67 +2230,67 @@ function useBrewStream() {
|
|
|
2187
2230
|
}
|
|
2188
2231
|
|
|
2189
2232
|
// src/components/common/search-input.tsx
|
|
2190
|
-
import { Box as Box10, Text as
|
|
2233
|
+
import { Box as Box10, Text as Text13 } from "ink";
|
|
2191
2234
|
import { TextInput } from "@inkjs/ui";
|
|
2192
|
-
import { jsx as
|
|
2235
|
+
import { jsx as jsx13, jsxs as jsxs12 } from "react/jsx-runtime";
|
|
2193
2236
|
function SearchInput({ defaultValue, onChange, placeholder, isActive = true }) {
|
|
2194
2237
|
const resolvedPlaceholder = placeholder ?? t("searchInput_placeholder");
|
|
2195
2238
|
return /* @__PURE__ */ jsxs12(Box10, { children: [
|
|
2196
|
-
/* @__PURE__ */ jsxs12(
|
|
2239
|
+
/* @__PURE__ */ jsxs12(Text13, { color: COLORS.gold, children: [
|
|
2197
2240
|
"\u{1F50D}",
|
|
2198
2241
|
" "
|
|
2199
2242
|
] }),
|
|
2200
|
-
isActive ? /* @__PURE__ */
|
|
2243
|
+
isActive ? /* @__PURE__ */ jsx13(
|
|
2201
2244
|
TextInput,
|
|
2202
2245
|
{
|
|
2203
2246
|
placeholder: resolvedPlaceholder,
|
|
2204
2247
|
defaultValue,
|
|
2205
2248
|
onChange
|
|
2206
2249
|
}
|
|
2207
|
-
) : /* @__PURE__ */
|
|
2250
|
+
) : /* @__PURE__ */ jsx13(Text13, { color: COLORS.textSecondary, children: defaultValue || placeholder })
|
|
2208
2251
|
] });
|
|
2209
2252
|
}
|
|
2210
2253
|
|
|
2211
2254
|
// src/components/common/confirm-dialog.tsx
|
|
2212
|
-
import { useEffect as
|
|
2213
|
-
import { Box as Box11, Text as
|
|
2214
|
-
import { jsx as
|
|
2255
|
+
import { useEffect as useEffect6 } from "react";
|
|
2256
|
+
import { Box as Box11, Text as Text14, useInput as useInput3 } from "ink";
|
|
2257
|
+
import { jsx as jsx14, jsxs as jsxs13 } from "react/jsx-runtime";
|
|
2215
2258
|
function ConfirmDialog({ message, onConfirm, onCancel }) {
|
|
2216
2259
|
const locale = useLocaleStore((s) => s.locale);
|
|
2217
2260
|
const { openModal, closeModal } = useModalStore();
|
|
2218
|
-
|
|
2261
|
+
useEffect6(() => {
|
|
2219
2262
|
openModal();
|
|
2220
2263
|
return () => {
|
|
2221
2264
|
closeModal();
|
|
2222
2265
|
};
|
|
2223
2266
|
}, []);
|
|
2224
|
-
|
|
2267
|
+
useInput3((input, key) => {
|
|
2225
2268
|
if (input === "y" || input === "Y") onConfirm();
|
|
2226
2269
|
else if (locale === "es" && (input === "s" || input === "S")) onConfirm();
|
|
2227
2270
|
else if (input === "n" || input === "N") onCancel();
|
|
2228
2271
|
else if (key.escape) onCancel();
|
|
2229
2272
|
});
|
|
2230
2273
|
return /* @__PURE__ */ jsxs13(Box11, { borderStyle: "double", borderColor: COLORS.purple, paddingX: SPACING.sm, paddingY: SPACING.xs, flexDirection: "column", children: [
|
|
2231
|
-
/* @__PURE__ */
|
|
2274
|
+
/* @__PURE__ */ jsx14(Text14, { bold: true, color: COLORS.text, children: message }),
|
|
2232
2275
|
/* @__PURE__ */ jsxs13(Box11, { marginTop: SPACING.xs, children: [
|
|
2233
|
-
/* @__PURE__ */
|
|
2234
|
-
/* @__PURE__ */
|
|
2235
|
-
/* @__PURE__ */
|
|
2276
|
+
/* @__PURE__ */ jsx14(Text14, { color: COLORS.success, children: t("confirm_yes") }),
|
|
2277
|
+
/* @__PURE__ */ jsx14(Text14, { children: " / " }),
|
|
2278
|
+
/* @__PURE__ */ jsx14(Text14, { color: COLORS.error, children: t("confirm_no") })
|
|
2236
2279
|
] })
|
|
2237
2280
|
] });
|
|
2238
2281
|
}
|
|
2239
2282
|
|
|
2240
2283
|
// src/components/common/progress-log.tsx
|
|
2241
|
-
import { Box as Box12, Text as
|
|
2284
|
+
import { Box as Box12, Text as Text15 } from "ink";
|
|
2242
2285
|
import { Spinner as Spinner2 } from "@inkjs/ui";
|
|
2243
|
-
import { jsx as
|
|
2286
|
+
import { jsx as jsx15, jsxs as jsxs14 } from "react/jsx-runtime";
|
|
2244
2287
|
function ProgressLog({ lines, isRunning, title, maxVisible = 15 }) {
|
|
2245
2288
|
const start = Math.max(0, lines.length - maxVisible);
|
|
2246
2289
|
const visible = lines.slice(start);
|
|
2247
2290
|
return /* @__PURE__ */ jsxs14(Box12, { flexDirection: "column", borderStyle: "round", borderColor: COLORS.sky, paddingX: SPACING.xs, children: [
|
|
2248
2291
|
title && /* @__PURE__ */ jsxs14(Box12, { marginBottom: SPACING.xs, children: [
|
|
2249
|
-
isRunning && /* @__PURE__ */
|
|
2250
|
-
/* @__PURE__ */ jsxs14(
|
|
2292
|
+
isRunning && /* @__PURE__ */ jsx15(Spinner2, { label: "" }),
|
|
2293
|
+
/* @__PURE__ */ jsxs14(Text15, { bold: true, color: COLORS.sky, children: [
|
|
2251
2294
|
" ",
|
|
2252
2295
|
title
|
|
2253
2296
|
] })
|
|
@@ -2256,15 +2299,15 @@ function ProgressLog({ lines, isRunning, title, maxVisible = 15 }) {
|
|
|
2256
2299
|
// UI-006: keys are absolute indices, so a line that scrolls off-screen
|
|
2257
2300
|
// does not change the key of remaining lines. Stable identity prevents
|
|
2258
2301
|
// React from treating the whole list as new on every append.
|
|
2259
|
-
/* @__PURE__ */
|
|
2302
|
+
/* @__PURE__ */ jsx15(Text15, { color: COLORS.muted, wrap: "wrap", children: line }, `log-${start + i}`)
|
|
2260
2303
|
)),
|
|
2261
|
-
lines.length === 0 && !isRunning && /* @__PURE__ */
|
|
2304
|
+
lines.length === 0 && !isRunning && /* @__PURE__ */ jsx15(Text15, { color: COLORS.textSecondary, italic: true, children: t("progress_noOutput") })
|
|
2262
2305
|
] });
|
|
2263
2306
|
}
|
|
2264
2307
|
|
|
2265
2308
|
// src/components/common/result-banner.tsx
|
|
2266
|
-
import { Box as Box13, Text as
|
|
2267
|
-
import { jsx as
|
|
2309
|
+
import { Box as Box13, Text as Text16 } from "ink";
|
|
2310
|
+
import { jsx as jsx16 } from "react/jsx-runtime";
|
|
2268
2311
|
var STATUS_COLORS = {
|
|
2269
2312
|
success: COLORS.success,
|
|
2270
2313
|
error: COLORS.error,
|
|
@@ -2272,21 +2315,64 @@ var STATUS_COLORS = {
|
|
|
2272
2315
|
info: COLORS.info
|
|
2273
2316
|
};
|
|
2274
2317
|
function ResultBanner({ status, message }) {
|
|
2275
|
-
return /* @__PURE__ */
|
|
2318
|
+
return /* @__PURE__ */ jsx16(Box13, { borderStyle: "round", borderColor: STATUS_COLORS[status], paddingX: SPACING.sm, paddingY: SPACING.none, children: /* @__PURE__ */ jsx16(Text16, { color: STATUS_COLORS[status], bold: true, children: message }) });
|
|
2276
2319
|
}
|
|
2277
2320
|
|
|
2278
2321
|
// src/components/common/selectable-row.tsx
|
|
2279
|
-
import { Box as Box14, Text as
|
|
2280
|
-
import { jsx as
|
|
2322
|
+
import { Box as Box14, Text as Text17 } from "ink";
|
|
2323
|
+
import { jsx as jsx17, jsxs as jsxs15 } from "react/jsx-runtime";
|
|
2281
2324
|
function SelectableRow({ isCurrent, children, gap = 1 }) {
|
|
2282
2325
|
return /* @__PURE__ */ jsxs15(Box14, { gap, children: [
|
|
2283
|
-
/* @__PURE__ */
|
|
2326
|
+
/* @__PURE__ */ jsx17(Text17, { color: isCurrent ? COLORS.success : COLORS.muted, children: isCurrent ? "\u25B6" : " " }),
|
|
2284
2327
|
children
|
|
2285
2328
|
] });
|
|
2286
2329
|
}
|
|
2287
2330
|
|
|
2331
|
+
// src/hooks/use-container-size.ts
|
|
2332
|
+
import { useEffect as useEffect8, useState as useState5 } from "react";
|
|
2333
|
+
import { measureElement } from "ink";
|
|
2334
|
+
|
|
2335
|
+
// src/hooks/use-terminal-size.ts
|
|
2336
|
+
import { useEffect as useEffect7, useState as useState4 } from "react";
|
|
2337
|
+
import { useStdout as useStdout4 } from "ink";
|
|
2338
|
+
function useTerminalSize() {
|
|
2339
|
+
const { stdout } = useStdout4();
|
|
2340
|
+
const [size, setSize] = useState4(() => ({
|
|
2341
|
+
columns: stdout?.columns ?? 80,
|
|
2342
|
+
rows: stdout?.rows ?? 24
|
|
2343
|
+
}));
|
|
2344
|
+
useEffect7(() => {
|
|
2345
|
+
if (!stdout) return;
|
|
2346
|
+
const onResize = () => {
|
|
2347
|
+
setSize({
|
|
2348
|
+
columns: stdout.columns ?? 80,
|
|
2349
|
+
rows: stdout.rows ?? 24
|
|
2350
|
+
});
|
|
2351
|
+
};
|
|
2352
|
+
stdout.on("resize", onResize);
|
|
2353
|
+
return () => {
|
|
2354
|
+
stdout.off("resize", onResize);
|
|
2355
|
+
};
|
|
2356
|
+
}, [stdout]);
|
|
2357
|
+
return size;
|
|
2358
|
+
}
|
|
2359
|
+
|
|
2360
|
+
// src/hooks/use-container-size.ts
|
|
2361
|
+
function useContainerSize(ref) {
|
|
2362
|
+
const terminal = useTerminalSize();
|
|
2363
|
+
const [size, setSize] = useState5({ width: 0, height: 0 });
|
|
2364
|
+
useEffect8(() => {
|
|
2365
|
+
if (!ref.current) return;
|
|
2366
|
+
const measured = measureElement(ref.current);
|
|
2367
|
+
setSize(
|
|
2368
|
+
(prev) => prev.width === measured.width && prev.height === measured.height ? prev : measured
|
|
2369
|
+
);
|
|
2370
|
+
}, [ref, terminal.columns, terminal.rows]);
|
|
2371
|
+
return size;
|
|
2372
|
+
}
|
|
2373
|
+
|
|
2288
2374
|
// src/views/installed.tsx
|
|
2289
|
-
import { jsx as
|
|
2375
|
+
import { jsx as jsx18, jsxs as jsxs16 } from "react/jsx-runtime";
|
|
2290
2376
|
function InstalledView() {
|
|
2291
2377
|
const formulae = useBrewStore((s) => s.formulae);
|
|
2292
2378
|
const casks = useBrewStore((s) => s.casks);
|
|
@@ -2295,22 +2381,24 @@ function InstalledView() {
|
|
|
2295
2381
|
const fetchInstalled = useBrewStore((s) => s.fetchInstalled);
|
|
2296
2382
|
const navigate = useNavigationStore((s) => s.navigate);
|
|
2297
2383
|
const selectPackage = useNavigationStore((s) => s.selectPackage);
|
|
2298
|
-
const
|
|
2299
|
-
const
|
|
2300
|
-
const
|
|
2301
|
-
const
|
|
2302
|
-
const
|
|
2384
|
+
const { openModal, closeModal } = useModalStore();
|
|
2385
|
+
const containerRef = useRef2(null);
|
|
2386
|
+
const { width: containerWidth } = useContainerSize(containerRef);
|
|
2387
|
+
const { rows: terminalRows } = useTerminalSize();
|
|
2388
|
+
const columns = containerWidth > 0 ? containerWidth : 80;
|
|
2389
|
+
const nameWidth = Math.floor(columns * 0.35);
|
|
2390
|
+
const versionWidth = Math.floor(columns * 0.15);
|
|
2391
|
+
const [filter, setFilter] = useState6("");
|
|
2392
|
+
const [cursor, setCursor] = useState6(0);
|
|
2393
|
+
const [tab, setTab] = useState6("formulae");
|
|
2394
|
+
const [isSearching, setIsSearching] = useState6(false);
|
|
2395
|
+
const [confirmUninstall, setConfirmUninstall] = useState6(null);
|
|
2303
2396
|
const debouncedFilter = useDebounce(filter, 200);
|
|
2304
2397
|
const stream = useBrewStream();
|
|
2305
|
-
|
|
2306
|
-
const { stdout } = useStdout4();
|
|
2307
|
-
const cols = stdout?.columns ?? 80;
|
|
2308
|
-
const nameWidth = Math.floor(cols * 0.35);
|
|
2309
|
-
const versionWidth = Math.floor(cols * 0.15);
|
|
2310
|
-
useEffect6(() => {
|
|
2398
|
+
useEffect9(() => {
|
|
2311
2399
|
fetchInstalled();
|
|
2312
2400
|
}, []);
|
|
2313
|
-
|
|
2401
|
+
useEffect9(() => {
|
|
2314
2402
|
if (isSearching) {
|
|
2315
2403
|
openModal();
|
|
2316
2404
|
return () => {
|
|
@@ -2327,7 +2415,7 @@ function InstalledView() {
|
|
|
2327
2415
|
(p) => p.name.toLowerCase().includes(lower) || p.desc.toLowerCase().includes(lower)
|
|
2328
2416
|
);
|
|
2329
2417
|
}, [formulae, casks, tab, debouncedFilter]);
|
|
2330
|
-
|
|
2418
|
+
useViewInput((input, key) => {
|
|
2331
2419
|
if (confirmUninstall) return;
|
|
2332
2420
|
if (stream.isRunning) {
|
|
2333
2421
|
if (key.escape) stream.cancel();
|
|
@@ -2351,7 +2439,7 @@ function InstalledView() {
|
|
|
2351
2439
|
setIsSearching(true);
|
|
2352
2440
|
return;
|
|
2353
2441
|
}
|
|
2354
|
-
if (input === "u" && allItems[cursor]) {
|
|
2442
|
+
if ((input === "u" || input === "1") && allItems[cursor]) {
|
|
2355
2443
|
setConfirmUninstall(allItems[cursor].name);
|
|
2356
2444
|
return;
|
|
2357
2445
|
}
|
|
@@ -2366,16 +2454,16 @@ function InstalledView() {
|
|
|
2366
2454
|
} else if (key.return && allItems[cursor]) {
|
|
2367
2455
|
selectPackage(allItems[cursor].name, tab === "formulae" ? "formula" : "cask");
|
|
2368
2456
|
navigate("package-info");
|
|
2369
|
-
} else if (input === "f") {
|
|
2457
|
+
} else if (input === "f" || input === "2") {
|
|
2370
2458
|
setTab((t2) => t2 === "formulae" ? "casks" : "formulae");
|
|
2371
2459
|
setCursor(0);
|
|
2372
2460
|
}
|
|
2373
2461
|
}, { isActive: true });
|
|
2374
|
-
if (loading.installed) return /* @__PURE__ */
|
|
2375
|
-
if (errors.installed) return /* @__PURE__ */
|
|
2462
|
+
if (loading.installed) return /* @__PURE__ */ jsx18(Loading, { message: t("loading_installed") });
|
|
2463
|
+
if (errors.installed) return /* @__PURE__ */ jsx18(ErrorMessage, { message: errors.installed });
|
|
2376
2464
|
if (stream.isRunning || stream.lines.length > 0) {
|
|
2377
2465
|
return /* @__PURE__ */ jsxs16(Box15, { flexDirection: "column", children: [
|
|
2378
|
-
/* @__PURE__ */
|
|
2466
|
+
/* @__PURE__ */ jsx18(
|
|
2379
2467
|
ProgressLog,
|
|
2380
2468
|
{
|
|
2381
2469
|
lines: stream.lines,
|
|
@@ -2383,50 +2471,50 @@ function InstalledView() {
|
|
|
2383
2471
|
title: t("pkgInfo_uninstalling", { name: "..." })
|
|
2384
2472
|
}
|
|
2385
2473
|
),
|
|
2386
|
-
stream.isRunning && /* @__PURE__ */ jsxs16(
|
|
2474
|
+
stream.isRunning && /* @__PURE__ */ jsxs16(Text18, { color: COLORS.textSecondary, children: [
|
|
2387
2475
|
"esc:",
|
|
2388
2476
|
t("hint_cancel")
|
|
2389
2477
|
] }),
|
|
2390
2478
|
!stream.isRunning && /* @__PURE__ */ jsxs16(Box15, { flexDirection: "column", marginTop: SPACING.xs, children: [
|
|
2391
|
-
/* @__PURE__ */
|
|
2479
|
+
/* @__PURE__ */ jsx18(
|
|
2392
2480
|
ResultBanner,
|
|
2393
2481
|
{
|
|
2394
2482
|
status: stream.error ? "error" : "success",
|
|
2395
2483
|
message: stream.error ? `\u2718 ${stream.error}` : `\u2714 ${t("pkgInfo_done")}`
|
|
2396
2484
|
}
|
|
2397
2485
|
),
|
|
2398
|
-
/* @__PURE__ */ jsxs16(
|
|
2486
|
+
/* @__PURE__ */ jsxs16(Text18, { color: COLORS.textSecondary, children: [
|
|
2399
2487
|
"esc:",
|
|
2400
2488
|
t("hint_back")
|
|
2401
2489
|
] })
|
|
2402
2490
|
] })
|
|
2403
2491
|
] });
|
|
2404
2492
|
}
|
|
2405
|
-
const MAX_VISIBLE_ROWS = Math.max(5,
|
|
2493
|
+
const MAX_VISIBLE_ROWS = Math.max(5, terminalRows - 8);
|
|
2406
2494
|
const start = Math.max(0, cursor - Math.floor(MAX_VISIBLE_ROWS / 2));
|
|
2407
2495
|
const visible = allItems.slice(start, start + MAX_VISIBLE_ROWS);
|
|
2408
|
-
return /* @__PURE__ */ jsxs16(Box15, { flexDirection: "column", children: [
|
|
2496
|
+
return /* @__PURE__ */ jsxs16(Box15, { flexDirection: "column", ref: containerRef, children: [
|
|
2409
2497
|
/* @__PURE__ */ jsxs16(Box15, { marginBottom: SPACING.xs, gap: SPACING.xs, children: [
|
|
2410
|
-
/* @__PURE__ */
|
|
2498
|
+
/* @__PURE__ */ jsx18(
|
|
2411
2499
|
Box15,
|
|
2412
2500
|
{
|
|
2413
2501
|
borderStyle: "round",
|
|
2414
2502
|
borderColor: tab === "formulae" ? COLORS.info : COLORS.textSecondary,
|
|
2415
2503
|
paddingX: SPACING.xs,
|
|
2416
|
-
children: /* @__PURE__ */ jsxs16(
|
|
2504
|
+
children: /* @__PURE__ */ jsxs16(Text18, { bold: tab === "formulae", color: tab === "formulae" ? COLORS.info : COLORS.textSecondary, children: [
|
|
2417
2505
|
"\u{1F4E6}",
|
|
2418
2506
|
" ",
|
|
2419
2507
|
t("installed_formulaeCount", { count: formulae.length })
|
|
2420
2508
|
] })
|
|
2421
2509
|
}
|
|
2422
2510
|
),
|
|
2423
|
-
/* @__PURE__ */
|
|
2511
|
+
/* @__PURE__ */ jsx18(
|
|
2424
2512
|
Box15,
|
|
2425
2513
|
{
|
|
2426
2514
|
borderStyle: "round",
|
|
2427
2515
|
borderColor: tab === "casks" ? COLORS.purple : COLORS.textSecondary,
|
|
2428
2516
|
paddingX: SPACING.xs,
|
|
2429
|
-
children: /* @__PURE__ */ jsxs16(
|
|
2517
|
+
children: /* @__PURE__ */ jsxs16(Text18, { bold: tab === "casks", color: tab === "casks" ? COLORS.purple : COLORS.textSecondary, children: [
|
|
2430
2518
|
"\u{1F37A}",
|
|
2431
2519
|
" ",
|
|
2432
2520
|
t("installed_casksCount", { count: casks.length })
|
|
@@ -2434,7 +2522,7 @@ function InstalledView() {
|
|
|
2434
2522
|
}
|
|
2435
2523
|
)
|
|
2436
2524
|
] }),
|
|
2437
|
-
confirmUninstall && /* @__PURE__ */
|
|
2525
|
+
confirmUninstall && /* @__PURE__ */ jsx18(
|
|
2438
2526
|
ConfirmDialog,
|
|
2439
2527
|
{
|
|
2440
2528
|
message: t("installed_confirmUninstall", { name: confirmUninstall }),
|
|
@@ -2448,18 +2536,18 @@ function InstalledView() {
|
|
|
2448
2536
|
onCancel: () => setConfirmUninstall(null)
|
|
2449
2537
|
}
|
|
2450
2538
|
),
|
|
2451
|
-
isSearching && /* @__PURE__ */
|
|
2539
|
+
isSearching && /* @__PURE__ */ jsx18(Box15, { marginBottom: SPACING.xs, borderStyle: "round", borderColor: COLORS.gold, paddingX: SPACING.xs, children: /* @__PURE__ */ jsx18(SearchInput, { defaultValue: filter, onChange: setFilter, isActive: isSearching }) }),
|
|
2452
2540
|
/* @__PURE__ */ jsxs16(Box15, { gap: SPACING.xs, borderStyle: "single", borderBottom: true, borderTop: false, borderLeft: false, borderRight: false, borderColor: COLORS.border, children: [
|
|
2453
|
-
/* @__PURE__ */ jsxs16(
|
|
2541
|
+
/* @__PURE__ */ jsxs16(Text18, { color: COLORS.text, bold: true, children: [
|
|
2454
2542
|
" ",
|
|
2455
2543
|
t("installed_col_package").padEnd(nameWidth)
|
|
2456
2544
|
] }),
|
|
2457
|
-
/* @__PURE__ */
|
|
2458
|
-
/* @__PURE__ */
|
|
2545
|
+
/* @__PURE__ */ jsx18(Text18, { color: COLORS.text, bold: true, children: t("installed_col_version").padEnd(versionWidth) }),
|
|
2546
|
+
/* @__PURE__ */ jsx18(Text18, { color: COLORS.text, bold: true, children: t("installed_col_status") })
|
|
2459
2547
|
] }),
|
|
2460
2548
|
/* @__PURE__ */ jsxs16(Box15, { flexDirection: "column", children: [
|
|
2461
|
-
visible.length === 0 && /* @__PURE__ */
|
|
2462
|
-
start > 0 && /* @__PURE__ */ jsxs16(
|
|
2549
|
+
visible.length === 0 && /* @__PURE__ */ jsx18(Box15, { paddingY: SPACING.xs, justifyContent: "center", children: /* @__PURE__ */ jsx18(Text18, { color: COLORS.textSecondary, italic: true, children: t("installed_noPackages") }) }),
|
|
2550
|
+
start > 0 && /* @__PURE__ */ jsxs16(Text18, { color: COLORS.textSecondary, dimColor: true, children: [
|
|
2463
2551
|
" ",
|
|
2464
2552
|
t("scroll_moreAbove", { count: start })
|
|
2465
2553
|
] }),
|
|
@@ -2467,43 +2555,43 @@ function InstalledView() {
|
|
|
2467
2555
|
const idx = start + i;
|
|
2468
2556
|
const isCurrent = idx === cursor;
|
|
2469
2557
|
return /* @__PURE__ */ jsxs16(SelectableRow, { isCurrent, children: [
|
|
2470
|
-
/* @__PURE__ */
|
|
2471
|
-
/* @__PURE__ */
|
|
2472
|
-
item.outdated && /* @__PURE__ */
|
|
2473
|
-
item.pinned && /* @__PURE__ */
|
|
2474
|
-
item.kegOnly && /* @__PURE__ */
|
|
2475
|
-
item.installedAsDependency && /* @__PURE__ */
|
|
2476
|
-
!item.outdated && !item.pinned && !item.kegOnly && !item.installedAsDependency && /* @__PURE__ */
|
|
2558
|
+
/* @__PURE__ */ jsx18(Text18, { bold: isCurrent, inverse: isCurrent, color: isCurrent ? COLORS.text : COLORS.muted, children: truncate(item.name, nameWidth).padEnd(nameWidth) }),
|
|
2559
|
+
/* @__PURE__ */ jsx18(Text18, { color: COLORS.teal, children: item.version.padEnd(versionWidth) }),
|
|
2560
|
+
item.outdated && /* @__PURE__ */ jsx18(StatusBadge, { label: t("badge_outdated"), variant: "warning" }),
|
|
2561
|
+
item.pinned && /* @__PURE__ */ jsx18(StatusBadge, { label: t("badge_pinned"), variant: "info" }),
|
|
2562
|
+
item.kegOnly && /* @__PURE__ */ jsx18(StatusBadge, { label: t("badge_kegOnly"), variant: "muted" }),
|
|
2563
|
+
item.installedAsDependency && /* @__PURE__ */ jsx18(StatusBadge, { label: t("badge_dep"), variant: "muted" }),
|
|
2564
|
+
!item.outdated && !item.pinned && !item.kegOnly && !item.installedAsDependency && /* @__PURE__ */ jsx18(Text18, { color: COLORS.textSecondary, dimColor: true, children: truncate(item.desc, 30) })
|
|
2477
2565
|
] }, item.name);
|
|
2478
2566
|
}),
|
|
2479
|
-
start + MAX_VISIBLE_ROWS < allItems.length && /* @__PURE__ */ jsxs16(
|
|
2567
|
+
start + MAX_VISIBLE_ROWS < allItems.length && /* @__PURE__ */ jsxs16(Text18, { color: COLORS.textSecondary, dimColor: true, children: [
|
|
2480
2568
|
" ",
|
|
2481
2569
|
t("scroll_moreBelow", { count: allItems.length - start - MAX_VISIBLE_ROWS })
|
|
2482
2570
|
] })
|
|
2483
2571
|
] }),
|
|
2484
|
-
/* @__PURE__ */
|
|
2572
|
+
/* @__PURE__ */ jsx18(Box15, { marginTop: SPACING.xs, children: /* @__PURE__ */ jsx18(Text18, { color: COLORS.text, bold: true, children: allItems.length > 0 ? `${cursor + 1}/${allItems.length}` : "0/0" }) })
|
|
2485
2573
|
] });
|
|
2486
2574
|
}
|
|
2487
2575
|
|
|
2488
2576
|
// src/views/search.tsx
|
|
2489
|
-
import { useState as
|
|
2490
|
-
import { Box as Box16, Text as
|
|
2577
|
+
import { useState as useState7, useCallback as useCallback2, useEffect as useEffect10, useRef as useRef3 } from "react";
|
|
2578
|
+
import { Box as Box16, Text as Text19 } from "ink";
|
|
2491
2579
|
import { TextInput as TextInput2 } from "@inkjs/ui";
|
|
2492
|
-
import { jsx as
|
|
2580
|
+
import { jsx as jsx19, jsxs as jsxs17 } from "react/jsx-runtime";
|
|
2493
2581
|
function SearchView() {
|
|
2494
|
-
const [query, setQuery] =
|
|
2495
|
-
const [results, setResults] =
|
|
2496
|
-
const [searching, setSearching] =
|
|
2497
|
-
const [searchError, setSearchError] =
|
|
2498
|
-
const [cursor, setCursor] =
|
|
2499
|
-
const [confirmInstall, setConfirmInstall] =
|
|
2582
|
+
const [query, setQuery] = useState7("");
|
|
2583
|
+
const [results, setResults] = useState7(null);
|
|
2584
|
+
const [searching, setSearching] = useState7(false);
|
|
2585
|
+
const [searchError, setSearchError] = useState7(null);
|
|
2586
|
+
const [cursor, setCursor] = useState7(0);
|
|
2587
|
+
const [confirmInstall, setConfirmInstall] = useState7(null);
|
|
2500
2588
|
const stream = useBrewStream();
|
|
2501
2589
|
const { openModal, closeModal } = useModalStore();
|
|
2502
2590
|
const navigate = useNavigationStore((s) => s.navigate);
|
|
2503
2591
|
const selectPackage = useNavigationStore((s) => s.selectPackage);
|
|
2504
2592
|
const fetchInstalled = useBrewStore((s) => s.fetchInstalled);
|
|
2505
|
-
const hasRefreshed =
|
|
2506
|
-
|
|
2593
|
+
const hasRefreshed = useRef3(false);
|
|
2594
|
+
useEffect10(() => {
|
|
2507
2595
|
if (results !== null) {
|
|
2508
2596
|
openModal();
|
|
2509
2597
|
return () => {
|
|
@@ -2531,7 +2619,7 @@ function SearchView() {
|
|
|
2531
2619
|
setSearching(false);
|
|
2532
2620
|
}
|
|
2533
2621
|
}, []);
|
|
2534
|
-
|
|
2622
|
+
useEffect10(() => {
|
|
2535
2623
|
if (!stream.isRunning && !stream.error && stream.lines.length > 0 && !hasRefreshed.current) {
|
|
2536
2624
|
hasRefreshed.current = true;
|
|
2537
2625
|
void fetchInstalled();
|
|
@@ -2541,7 +2629,7 @@ function SearchView() {
|
|
|
2541
2629
|
const visibleFormulae = results ? results.formulae.slice(0, MAX_VISIBLE) : [];
|
|
2542
2630
|
const visibleCasks = results ? results.casks.slice(0, MAX_VISIBLE) : [];
|
|
2543
2631
|
const allVisible = [...visibleFormulae, ...visibleCasks];
|
|
2544
|
-
|
|
2632
|
+
useViewInput((input, key) => {
|
|
2545
2633
|
if (stream.isRunning) {
|
|
2546
2634
|
if (key.escape) stream.cancel();
|
|
2547
2635
|
return;
|
|
@@ -2562,7 +2650,7 @@ function SearchView() {
|
|
|
2562
2650
|
navigate("package-info");
|
|
2563
2651
|
return;
|
|
2564
2652
|
}
|
|
2565
|
-
if (input === "i" && allVisible[cursor]) {
|
|
2653
|
+
if ((input === "i" || input === "1") && allVisible[cursor]) {
|
|
2566
2654
|
setConfirmInstall(allVisible[cursor]);
|
|
2567
2655
|
return;
|
|
2568
2656
|
}
|
|
@@ -2577,7 +2665,7 @@ function SearchView() {
|
|
|
2577
2665
|
});
|
|
2578
2666
|
if (stream.isRunning || stream.lines.length > 0) {
|
|
2579
2667
|
return /* @__PURE__ */ jsxs17(Box16, { flexDirection: "column", children: [
|
|
2580
|
-
/* @__PURE__ */
|
|
2668
|
+
/* @__PURE__ */ jsx19(
|
|
2581
2669
|
ProgressLog,
|
|
2582
2670
|
{
|
|
2583
2671
|
lines: stream.lines,
|
|
@@ -2585,19 +2673,19 @@ function SearchView() {
|
|
|
2585
2673
|
title: t("search_installing")
|
|
2586
2674
|
}
|
|
2587
2675
|
),
|
|
2588
|
-
stream.isRunning && /* @__PURE__ */ jsxs17(
|
|
2676
|
+
stream.isRunning && /* @__PURE__ */ jsxs17(Text19, { color: COLORS.textSecondary, children: [
|
|
2589
2677
|
"esc:",
|
|
2590
2678
|
t("hint_cancel")
|
|
2591
2679
|
] }),
|
|
2592
2680
|
!stream.isRunning && /* @__PURE__ */ jsxs17(Box16, { flexDirection: "column", marginTop: SPACING.xs, children: [
|
|
2593
|
-
/* @__PURE__ */
|
|
2681
|
+
/* @__PURE__ */ jsx19(
|
|
2594
2682
|
ResultBanner,
|
|
2595
2683
|
{
|
|
2596
2684
|
status: stream.error ? "error" : "success",
|
|
2597
2685
|
message: stream.error ? `\u2718 ${stream.error}` : `\u2714 ${t("search_installComplete")}`
|
|
2598
2686
|
}
|
|
2599
2687
|
),
|
|
2600
|
-
/* @__PURE__ */ jsxs17(
|
|
2688
|
+
/* @__PURE__ */ jsxs17(Text19, { color: COLORS.textSecondary, children: [
|
|
2601
2689
|
"esc:",
|
|
2602
2690
|
t("hint_clear")
|
|
2603
2691
|
] })
|
|
@@ -2606,11 +2694,11 @@ function SearchView() {
|
|
|
2606
2694
|
}
|
|
2607
2695
|
return /* @__PURE__ */ jsxs17(Box16, { flexDirection: "column", children: [
|
|
2608
2696
|
/* @__PURE__ */ jsxs17(Box16, { marginBottom: SPACING.xs, children: [
|
|
2609
|
-
/* @__PURE__ */ jsxs17(
|
|
2697
|
+
/* @__PURE__ */ jsxs17(Text19, { color: COLORS.gold, children: [
|
|
2610
2698
|
"\u{1F50D}",
|
|
2611
2699
|
" "
|
|
2612
2700
|
] }),
|
|
2613
|
-
!results ? /* @__PURE__ */
|
|
2701
|
+
!results ? /* @__PURE__ */ jsx19(
|
|
2614
2702
|
TextInput2,
|
|
2615
2703
|
{
|
|
2616
2704
|
placeholder: t("search_placeholder"),
|
|
@@ -2618,17 +2706,17 @@ function SearchView() {
|
|
|
2618
2706
|
onChange: setQuery,
|
|
2619
2707
|
onSubmit: () => void doSearch(query)
|
|
2620
2708
|
}
|
|
2621
|
-
) : /* @__PURE__ */ jsxs17(
|
|
2709
|
+
) : /* @__PURE__ */ jsxs17(Text19, { children: [
|
|
2622
2710
|
t("search_resultsFor"),
|
|
2623
2711
|
' "',
|
|
2624
|
-
/* @__PURE__ */
|
|
2712
|
+
/* @__PURE__ */ jsx19(Text19, { bold: true, color: COLORS.text, children: query }),
|
|
2625
2713
|
'" ',
|
|
2626
|
-
/* @__PURE__ */
|
|
2714
|
+
/* @__PURE__ */ jsx19(Text19, { color: COLORS.textSecondary, children: t("search_escToClear") })
|
|
2627
2715
|
] })
|
|
2628
2716
|
] }),
|
|
2629
|
-
searching && /* @__PURE__ */
|
|
2630
|
-
searchError && /* @__PURE__ */
|
|
2631
|
-
confirmInstall && /* @__PURE__ */
|
|
2717
|
+
searching && /* @__PURE__ */ jsx19(Loading, { message: t("loading_searching") }),
|
|
2718
|
+
searchError && /* @__PURE__ */ jsx19(Box16, { marginBottom: SPACING.xs, children: /* @__PURE__ */ jsx19(Text19, { color: COLORS.error, children: searchError }) }),
|
|
2719
|
+
confirmInstall && /* @__PURE__ */ jsx19(
|
|
2632
2720
|
ConfirmDialog,
|
|
2633
2721
|
{
|
|
2634
2722
|
message: t("search_confirmInstall", { name: confirmInstall }),
|
|
@@ -2643,74 +2731,88 @@ function SearchView() {
|
|
|
2643
2731
|
),
|
|
2644
2732
|
results && !searching && !confirmInstall && /* @__PURE__ */ jsxs17(Box16, { flexDirection: "column", children: [
|
|
2645
2733
|
visibleFormulae.length > 0 && /* @__PURE__ */ jsxs17(Box16, { flexDirection: "column", marginBottom: SPACING.xs, children: [
|
|
2646
|
-
/* @__PURE__ */
|
|
2734
|
+
/* @__PURE__ */ jsx19(Text19, { bold: true, color: COLORS.info, children: t("search_formulaeHeader", { count: results.formulae.length }) }),
|
|
2647
2735
|
visibleFormulae.map((name, i) => {
|
|
2648
2736
|
const isCurrent = i === cursor;
|
|
2649
|
-
return /* @__PURE__ */
|
|
2737
|
+
return /* @__PURE__ */ jsx19(SelectableRow, { isCurrent, children: /* @__PURE__ */ jsx19(Text19, { bold: isCurrent, inverse: isCurrent, children: name }) }, name);
|
|
2650
2738
|
}),
|
|
2651
|
-
results.formulae.length > MAX_VISIBLE && /* @__PURE__ */ jsxs17(
|
|
2739
|
+
results.formulae.length > MAX_VISIBLE && /* @__PURE__ */ jsxs17(Text19, { color: COLORS.textSecondary, dimColor: true, children: [
|
|
2652
2740
|
" ",
|
|
2653
2741
|
t("scroll_moreBelow", { count: results.formulae.length - MAX_VISIBLE })
|
|
2654
2742
|
] })
|
|
2655
2743
|
] }),
|
|
2656
2744
|
visibleCasks.length > 0 && /* @__PURE__ */ jsxs17(Box16, { flexDirection: "column", children: [
|
|
2657
|
-
/* @__PURE__ */
|
|
2745
|
+
/* @__PURE__ */ jsx19(Text19, { bold: true, color: COLORS.purple, children: t("search_casksHeader", { count: results.casks.length }) }),
|
|
2658
2746
|
visibleCasks.map((name, i) => {
|
|
2659
2747
|
const idx = visibleFormulae.length + i;
|
|
2660
2748
|
const isCurrent = idx === cursor;
|
|
2661
|
-
return /* @__PURE__ */
|
|
2749
|
+
return /* @__PURE__ */ jsx19(SelectableRow, { isCurrent, children: /* @__PURE__ */ jsx19(Text19, { bold: isCurrent, inverse: isCurrent, children: name }) }, name);
|
|
2662
2750
|
}),
|
|
2663
|
-
results.casks.length > MAX_VISIBLE && /* @__PURE__ */ jsxs17(
|
|
2751
|
+
results.casks.length > MAX_VISIBLE && /* @__PURE__ */ jsxs17(Text19, { color: COLORS.textSecondary, dimColor: true, children: [
|
|
2664
2752
|
" ",
|
|
2665
2753
|
t("scroll_moreBelow", { count: results.casks.length - MAX_VISIBLE })
|
|
2666
2754
|
] })
|
|
2667
2755
|
] }),
|
|
2668
|
-
allVisible.length === 0 && /* @__PURE__ */
|
|
2669
|
-
/* @__PURE__ */
|
|
2756
|
+
allVisible.length === 0 && /* @__PURE__ */ jsx19(Box16, { borderStyle: "round", borderColor: COLORS.textSecondary, paddingX: SPACING.sm, children: /* @__PURE__ */ jsx19(Text19, { color: COLORS.textSecondary, italic: true, children: t("search_noResults") }) }),
|
|
2757
|
+
/* @__PURE__ */ jsx19(Box16, { marginTop: SPACING.xs, children: /* @__PURE__ */ jsx19(Text19, { color: COLORS.text, bold: true, children: allVisible.length > 0 ? `${cursor + 1}/${allVisible.length}` : "" }) })
|
|
2670
2758
|
] })
|
|
2671
2759
|
] });
|
|
2672
2760
|
}
|
|
2673
2761
|
|
|
2674
2762
|
// src/views/outdated.tsx
|
|
2675
|
-
import { useEffect as
|
|
2676
|
-
import { Box as Box17, Text as
|
|
2677
|
-
import { jsx as
|
|
2763
|
+
import { useEffect as useEffect11, useMemo as useMemo4, useRef as useRef4, useState as useState8 } from "react";
|
|
2764
|
+
import { Box as Box17, Text as Text20 } from "ink";
|
|
2765
|
+
import { jsx as jsx20, jsxs as jsxs18 } from "react/jsx-runtime";
|
|
2678
2766
|
function ImpactPanel({ impact }) {
|
|
2679
2767
|
const riskColor = impact.risk === "high" ? COLORS.error : impact.risk === "medium" ? COLORS.warning : COLORS.success;
|
|
2680
2768
|
const riskLabel = impact.risk === "high" ? t("impact_high") : impact.risk === "medium" ? t("impact_medium") : t("impact_low");
|
|
2681
2769
|
const riskIcon = impact.risk === "high" ? "\u26A0" : impact.risk === "medium" ? "~" : "\u2713";
|
|
2682
2770
|
return /* @__PURE__ */ jsxs18(Box17, { flexDirection: "column", marginTop: SPACING.xs, borderStyle: "round", borderColor: riskColor, paddingX: SPACING.sm, paddingY: SPACING.none, children: [
|
|
2683
2771
|
/* @__PURE__ */ jsxs18(Box17, { children: [
|
|
2684
|
-
/* @__PURE__ */ jsxs18(
|
|
2772
|
+
/* @__PURE__ */ jsxs18(Text20, { bold: true, color: riskColor, children: [
|
|
2685
2773
|
riskIcon,
|
|
2686
2774
|
" ",
|
|
2687
2775
|
riskLabel
|
|
2688
2776
|
] }),
|
|
2689
|
-
impact.reverseDeps.length > 0 && /* @__PURE__ */ jsxs18(
|
|
2777
|
+
impact.reverseDeps.length > 0 && /* @__PURE__ */ jsxs18(Text20, { color: COLORS.textSecondary, children: [
|
|
2690
2778
|
" \\u2014 ",
|
|
2691
2779
|
t("impact_affects", { count: impact.reverseDeps.length })
|
|
2692
2780
|
] })
|
|
2693
2781
|
] }),
|
|
2694
|
-
impact.riskReasons.length > 0 && /* @__PURE__ */
|
|
2695
|
-
impact.reverseDeps.length > 0 && impact.reverseDeps.length <= 5 && /* @__PURE__ */
|
|
2696
|
-
impact.risk === "high" && /* @__PURE__ */
|
|
2782
|
+
impact.riskReasons.length > 0 && /* @__PURE__ */ jsx20(Text20, { color: COLORS.textSecondary, children: impact.riskReasons.join(" \xB7 ") }),
|
|
2783
|
+
impact.reverseDeps.length > 0 && impact.reverseDeps.length <= 5 && /* @__PURE__ */ jsx20(Text20, { color: COLORS.muted, dimColor: true, children: t("impact_usedBy", { packages: impact.reverseDeps.join(", ") }) }),
|
|
2784
|
+
impact.risk === "high" && /* @__PURE__ */ jsx20(Text20, { color: COLORS.info, children: t("impact_brewfile_hint") })
|
|
2697
2785
|
] });
|
|
2698
2786
|
}
|
|
2699
2787
|
function OutdatedView() {
|
|
2700
2788
|
const { outdated, loading, errors, fetchOutdated } = useBrewStore();
|
|
2701
2789
|
const stream = useBrewStream();
|
|
2702
|
-
const [cursor, setCursor] =
|
|
2703
|
-
const [confirmAction, setConfirmAction] =
|
|
2704
|
-
const hasRefreshed =
|
|
2705
|
-
const
|
|
2706
|
-
const [
|
|
2707
|
-
|
|
2790
|
+
const [cursor, setCursor] = useState8(0);
|
|
2791
|
+
const [confirmAction, setConfirmAction] = useState8(null);
|
|
2792
|
+
const hasRefreshed = useRef4(false);
|
|
2793
|
+
const pendingUpgradeRef = useRef4(null);
|
|
2794
|
+
const [impact, setImpact] = useState8(null);
|
|
2795
|
+
const [impactLoading, setImpactLoading] = useState8(false);
|
|
2796
|
+
useEffect11(() => {
|
|
2708
2797
|
fetchOutdated();
|
|
2709
2798
|
}, []);
|
|
2710
|
-
|
|
2799
|
+
useEffect11(() => {
|
|
2711
2800
|
if (!stream.isRunning && !stream.error && stream.lines.length > 0 && !hasRefreshed.current) {
|
|
2712
2801
|
hasRefreshed.current = true;
|
|
2713
|
-
void fetchOutdated()
|
|
2802
|
+
void fetchOutdated().then(() => {
|
|
2803
|
+
const pkgs = pendingUpgradeRef.current;
|
|
2804
|
+
if (!pkgs) return;
|
|
2805
|
+
pendingUpgradeRef.current = null;
|
|
2806
|
+
const state = useBrewStore.getState().outdated;
|
|
2807
|
+
const remaining = state.formulae.length + state.casks.length;
|
|
2808
|
+
void writeLastAction({
|
|
2809
|
+
timestamp: (/* @__PURE__ */ new Date()).toISOString(),
|
|
2810
|
+
action: "upgrade",
|
|
2811
|
+
packages: pkgs,
|
|
2812
|
+
remainingOutdated: remaining,
|
|
2813
|
+
source: "brew-tui"
|
|
2814
|
+
}).catch((err) => logger.warn("Failed to write last-action.json", err));
|
|
2815
|
+
});
|
|
2714
2816
|
}
|
|
2715
2817
|
}, [stream.isRunning, stream.error]);
|
|
2716
2818
|
const allOutdated = useMemo4(
|
|
@@ -2721,7 +2823,7 @@ function OutdatedView() {
|
|
|
2721
2823
|
[outdated.formulae, outdated.casks]
|
|
2722
2824
|
);
|
|
2723
2825
|
const debouncedCursor = useDebounce(cursor, 150);
|
|
2724
|
-
|
|
2826
|
+
useEffect11(() => {
|
|
2725
2827
|
const pkg = allOutdated[debouncedCursor];
|
|
2726
2828
|
if (!pkg || stream.isRunning) {
|
|
2727
2829
|
setImpact(null);
|
|
@@ -2745,7 +2847,7 @@ function OutdatedView() {
|
|
|
2745
2847
|
cancelled = true;
|
|
2746
2848
|
};
|
|
2747
2849
|
}, [debouncedCursor, stream.isRunning]);
|
|
2748
|
-
|
|
2850
|
+
useViewInput((input, key) => {
|
|
2749
2851
|
if (stream.isRunning) {
|
|
2750
2852
|
if (key.escape) stream.cancel();
|
|
2751
2853
|
return;
|
|
@@ -2755,7 +2857,7 @@ function OutdatedView() {
|
|
|
2755
2857
|
stream.clear();
|
|
2756
2858
|
return;
|
|
2757
2859
|
}
|
|
2758
|
-
if (input === "r") {
|
|
2860
|
+
if (input === "r" || input === "3") {
|
|
2759
2861
|
stream.clear();
|
|
2760
2862
|
void fetchOutdated();
|
|
2761
2863
|
}
|
|
@@ -2768,25 +2870,25 @@ function OutdatedView() {
|
|
|
2768
2870
|
setCursor((c) => Math.max(c - 1, 0));
|
|
2769
2871
|
} else if (key.return && allOutdated[cursor]) {
|
|
2770
2872
|
setConfirmAction({ type: "single", name: allOutdated[cursor].name });
|
|
2771
|
-
} else if (input === "A" && allOutdated.length > 0) {
|
|
2873
|
+
} else if ((input === "A" || input === "1") && allOutdated.length > 0) {
|
|
2772
2874
|
setConfirmAction({ type: "all" });
|
|
2773
|
-
} else if (input === "p" && allOutdated[cursor]) {
|
|
2875
|
+
} else if ((input === "p" || input === "2") && allOutdated[cursor]) {
|
|
2774
2876
|
const pkg = allOutdated[cursor];
|
|
2775
2877
|
void (pkg.pinned ? unpinPackage(pkg.name) : pinPackage(pkg.name)).then(() => void fetchOutdated());
|
|
2776
2878
|
return;
|
|
2777
|
-
} else if (input === "r") {
|
|
2879
|
+
} else if (input === "r" || input === "3") {
|
|
2778
2880
|
void fetchOutdated();
|
|
2779
2881
|
}
|
|
2780
2882
|
});
|
|
2781
|
-
const {
|
|
2782
|
-
const MAX_VISIBLE_ROWS = Math.max(5,
|
|
2883
|
+
const { rows: terminalRows } = useTerminalSize();
|
|
2884
|
+
const MAX_VISIBLE_ROWS = Math.max(5, terminalRows - 8);
|
|
2783
2885
|
const start = Math.max(0, cursor - Math.floor(MAX_VISIBLE_ROWS / 2));
|
|
2784
2886
|
const visible = allOutdated.slice(start, start + MAX_VISIBLE_ROWS);
|
|
2785
|
-
if (loading.outdated) return /* @__PURE__ */
|
|
2786
|
-
if (errors.outdated) return /* @__PURE__ */
|
|
2887
|
+
if (loading.outdated) return /* @__PURE__ */ jsx20(Loading, { message: t("loading_outdated") });
|
|
2888
|
+
if (errors.outdated) return /* @__PURE__ */ jsx20(ErrorMessage, { message: errors.outdated });
|
|
2787
2889
|
if (stream.isRunning || stream.lines.length > 0) {
|
|
2788
2890
|
return /* @__PURE__ */ jsxs18(Box17, { flexDirection: "column", children: [
|
|
2789
|
-
/* @__PURE__ */
|
|
2891
|
+
/* @__PURE__ */ jsx20(
|
|
2790
2892
|
ProgressLog,
|
|
2791
2893
|
{
|
|
2792
2894
|
lines: stream.lines,
|
|
@@ -2794,19 +2896,19 @@ function OutdatedView() {
|
|
|
2794
2896
|
title: t("outdated_upgrading")
|
|
2795
2897
|
}
|
|
2796
2898
|
),
|
|
2797
|
-
stream.isRunning && /* @__PURE__ */ jsxs18(
|
|
2899
|
+
stream.isRunning && /* @__PURE__ */ jsxs18(Text20, { color: COLORS.textSecondary, children: [
|
|
2798
2900
|
"esc:",
|
|
2799
2901
|
t("hint_cancel")
|
|
2800
2902
|
] }),
|
|
2801
2903
|
!stream.isRunning && /* @__PURE__ */ jsxs18(Box17, { flexDirection: "column", marginTop: SPACING.xs, children: [
|
|
2802
2904
|
/* @__PURE__ */ jsxs18(Box17, { borderStyle: "round", borderColor: stream.error ? COLORS.error : COLORS.success, paddingX: SPACING.sm, paddingY: SPACING.none, children: [
|
|
2803
|
-
/* @__PURE__ */
|
|
2804
|
-
/* @__PURE__ */ jsxs18(
|
|
2905
|
+
/* @__PURE__ */ jsx20(Text20, { color: stream.error ? COLORS.error : COLORS.success, bold: true, children: stream.error ? `\u2718 ${stream.error}` : `\u2714 ${t("outdated_upgradeComplete")}` }),
|
|
2906
|
+
/* @__PURE__ */ jsxs18(Text20, { color: COLORS.muted, children: [
|
|
2805
2907
|
" ",
|
|
2806
2908
|
t("outdated_pressRefresh")
|
|
2807
2909
|
] })
|
|
2808
2910
|
] }),
|
|
2809
|
-
/* @__PURE__ */ jsxs18(
|
|
2911
|
+
/* @__PURE__ */ jsxs18(Text20, { color: COLORS.textSecondary, children: [
|
|
2810
2912
|
"r:",
|
|
2811
2913
|
t("hint_refresh"),
|
|
2812
2914
|
" esc:",
|
|
@@ -2818,16 +2920,18 @@ function OutdatedView() {
|
|
|
2818
2920
|
const upgradeAllMessage = confirmAction?.type === "all" ? `${t("outdated_confirmAll", { count: allOutdated.length })}
|
|
2819
2921
|
${t("outdated_upgradeAllList", { list: allOutdated.map((p) => p.name).join(", ") })}` : "";
|
|
2820
2922
|
return /* @__PURE__ */ jsxs18(Box17, { flexDirection: "column", children: [
|
|
2821
|
-
/* @__PURE__ */
|
|
2822
|
-
confirmAction && /* @__PURE__ */
|
|
2923
|
+
/* @__PURE__ */ jsx20(SectionHeader, { emoji: "\u{1F4E6}", title: t("outdated_title", { count: allOutdated.length }), gradient: GRADIENTS.fire }),
|
|
2924
|
+
confirmAction && /* @__PURE__ */ jsx20(Box17, { marginY: SPACING.xs, children: /* @__PURE__ */ jsx20(
|
|
2823
2925
|
ConfirmDialog,
|
|
2824
2926
|
{
|
|
2825
2927
|
message: confirmAction.type === "all" ? upgradeAllMessage : t("outdated_confirmSingle", { name: confirmAction.type === "single" ? confirmAction.name : "" }),
|
|
2826
2928
|
onConfirm: () => {
|
|
2827
2929
|
hasRefreshed.current = false;
|
|
2828
2930
|
if (confirmAction.type === "all") {
|
|
2931
|
+
pendingUpgradeRef.current = allOutdated.map((p) => p.name);
|
|
2829
2932
|
void stream.run(["upgrade"]);
|
|
2830
2933
|
} else if (confirmAction.name) {
|
|
2934
|
+
pendingUpgradeRef.current = [confirmAction.name];
|
|
2831
2935
|
void stream.run(["upgrade", confirmAction.name]);
|
|
2832
2936
|
}
|
|
2833
2937
|
setConfirmAction(null);
|
|
@@ -2835,9 +2939,9 @@ ${t("outdated_upgradeAllList", { list: allOutdated.map((p) => p.name).join(", ")
|
|
|
2835
2939
|
onCancel: () => setConfirmAction(null)
|
|
2836
2940
|
}
|
|
2837
2941
|
) }),
|
|
2838
|
-
allOutdated.length === 0 && !confirmAction && /* @__PURE__ */
|
|
2942
|
+
allOutdated.length === 0 && !confirmAction && /* @__PURE__ */ jsx20(Box17, { marginTop: SPACING.xs, children: /* @__PURE__ */ jsx20(ResultBanner, { status: "success", message: `\u2714 ${t("outdated_upToDate")}` }) }),
|
|
2839
2943
|
allOutdated.length > 0 && !confirmAction && /* @__PURE__ */ jsxs18(Box17, { flexDirection: "column", marginTop: SPACING.xs, children: [
|
|
2840
|
-
start > 0 && /* @__PURE__ */ jsxs18(
|
|
2944
|
+
start > 0 && /* @__PURE__ */ jsxs18(Text20, { color: COLORS.textSecondary, dimColor: true, children: [
|
|
2841
2945
|
" ",
|
|
2842
2946
|
t("scroll_moreAbove", { count: start })
|
|
2843
2947
|
] }),
|
|
@@ -2845,31 +2949,31 @@ ${t("outdated_upgradeAllList", { list: allOutdated.map((p) => p.name).join(", ")
|
|
|
2845
2949
|
const idx = start + i;
|
|
2846
2950
|
const isCurrent = idx === cursor;
|
|
2847
2951
|
return /* @__PURE__ */ jsxs18(SelectableRow, { isCurrent, children: [
|
|
2848
|
-
/* @__PURE__ */
|
|
2849
|
-
/* @__PURE__ */
|
|
2850
|
-
pkg.pinned && /* @__PURE__ */
|
|
2952
|
+
/* @__PURE__ */ jsx20(Text20, { bold: isCurrent, inverse: isCurrent, color: isCurrent ? COLORS.text : COLORS.muted, children: pkg.name }),
|
|
2953
|
+
/* @__PURE__ */ jsx20(VersionArrow, { current: pkg.installed_versions[0] ?? "", latest: pkg.current_version }),
|
|
2954
|
+
pkg.pinned && /* @__PURE__ */ jsx20(StatusBadge, { label: t("outdated_pinned"), variant: "info" })
|
|
2851
2955
|
] }, pkg.name);
|
|
2852
2956
|
}),
|
|
2853
|
-
start + MAX_VISIBLE_ROWS < allOutdated.length && /* @__PURE__ */ jsxs18(
|
|
2957
|
+
start + MAX_VISIBLE_ROWS < allOutdated.length && /* @__PURE__ */ jsxs18(Text20, { color: COLORS.textSecondary, dimColor: true, children: [
|
|
2854
2958
|
" ",
|
|
2855
2959
|
t("scroll_moreBelow", { count: allOutdated.length - start - MAX_VISIBLE_ROWS })
|
|
2856
2960
|
] }),
|
|
2857
|
-
/* @__PURE__ */
|
|
2961
|
+
/* @__PURE__ */ jsx20(Box17, { marginTop: SPACING.xs, children: /* @__PURE__ */ jsxs18(Text20, { color: COLORS.text, bold: true, children: [
|
|
2858
2962
|
cursor + 1,
|
|
2859
2963
|
"/",
|
|
2860
2964
|
allOutdated.length
|
|
2861
2965
|
] }) }),
|
|
2862
|
-
impact && !stream.isRunning && !confirmAction && /* @__PURE__ */
|
|
2863
|
-
impactLoading && !stream.isRunning && !confirmAction && /* @__PURE__ */
|
|
2864
|
-
/* @__PURE__ */
|
|
2966
|
+
impact && !stream.isRunning && !confirmAction && /* @__PURE__ */ jsx20(ImpactPanel, { impact }),
|
|
2967
|
+
impactLoading && !stream.isRunning && !confirmAction && /* @__PURE__ */ jsx20(Box17, { marginTop: SPACING.xs, children: /* @__PURE__ */ jsx20(Text20, { color: COLORS.textSecondary, children: t("impact_analyzing") }) }),
|
|
2968
|
+
/* @__PURE__ */ jsx20(Box17, { marginTop: SPACING.xs, children: /* @__PURE__ */ jsx20(Text20, { color: COLORS.textSecondary, children: t("impact_hint") }) })
|
|
2865
2969
|
] })
|
|
2866
2970
|
] });
|
|
2867
2971
|
}
|
|
2868
2972
|
|
|
2869
2973
|
// src/views/package-info.tsx
|
|
2870
|
-
import { useEffect as
|
|
2871
|
-
import { Box as Box18, Text as
|
|
2872
|
-
import { Fragment as Fragment4, jsx as
|
|
2974
|
+
import { useEffect as useEffect12, useRef as useRef5, useState as useState9 } from "react";
|
|
2975
|
+
import { Box as Box18, Text as Text21 } from "ink";
|
|
2976
|
+
import { Fragment as Fragment4, jsx as jsx21, jsxs as jsxs19 } from "react/jsx-runtime";
|
|
2873
2977
|
var ACTION_PROGRESS_KEYS = {
|
|
2874
2978
|
install: "pkgInfo_installing",
|
|
2875
2979
|
uninstall: "pkgInfo_uninstalling",
|
|
@@ -2883,21 +2987,21 @@ var ACTION_CONFIRM_KEYS = {
|
|
|
2883
2987
|
function PackageInfoView() {
|
|
2884
2988
|
const packageName = useNavigationStore((s) => s.selectedPackage);
|
|
2885
2989
|
const packageType = useNavigationStore((s) => s.selectedPackageType);
|
|
2886
|
-
const [formula, setFormula] =
|
|
2887
|
-
const [loading, setLoading2] =
|
|
2888
|
-
const [error, setError2] =
|
|
2889
|
-
const [confirmAction, setConfirmAction] =
|
|
2890
|
-
const activeActionRef =
|
|
2891
|
-
const mountedRef =
|
|
2892
|
-
const hasRefreshed =
|
|
2990
|
+
const [formula, setFormula] = useState9(null);
|
|
2991
|
+
const [loading, setLoading2] = useState9(true);
|
|
2992
|
+
const [error, setError2] = useState9(null);
|
|
2993
|
+
const [confirmAction, setConfirmAction] = useState9(null);
|
|
2994
|
+
const activeActionRef = useRef5("install");
|
|
2995
|
+
const mountedRef = useRef5(true);
|
|
2996
|
+
const hasRefreshed = useRef5(false);
|
|
2893
2997
|
const stream = useBrewStream();
|
|
2894
|
-
|
|
2998
|
+
useEffect12(() => {
|
|
2895
2999
|
mountedRef.current = true;
|
|
2896
3000
|
return () => {
|
|
2897
3001
|
mountedRef.current = false;
|
|
2898
3002
|
};
|
|
2899
3003
|
}, []);
|
|
2900
|
-
|
|
3004
|
+
useEffect12(() => {
|
|
2901
3005
|
if (!packageName) return;
|
|
2902
3006
|
setLoading2(true);
|
|
2903
3007
|
const fetchInfo = async () => {
|
|
@@ -2922,7 +3026,7 @@ function PackageInfoView() {
|
|
|
2922
3026
|
}
|
|
2923
3027
|
});
|
|
2924
3028
|
}, [packageName, packageType]);
|
|
2925
|
-
|
|
3029
|
+
useEffect12(() => {
|
|
2926
3030
|
if (!stream.isRunning && !stream.error && stream.lines.length > 0 && !hasRefreshed.current && packageName) {
|
|
2927
3031
|
hasRefreshed.current = true;
|
|
2928
3032
|
const refreshFn = packageType === "cask" ? getCaskInfo(packageName).then((c) => c ? { ...c, installed: c.installed ? [{ version: c.installed }] : [] } : null) : getFormulaInfo(packageName);
|
|
@@ -2932,9 +3036,23 @@ function PackageInfoView() {
|
|
|
2932
3036
|
}
|
|
2933
3037
|
}).catch(() => {
|
|
2934
3038
|
});
|
|
3039
|
+
const action = activeActionRef.current;
|
|
3040
|
+
if (action === "upgrade" || action === "install" || action === "uninstall") {
|
|
3041
|
+
void useBrewStore.getState().fetchOutdated().then(() => {
|
|
3042
|
+
const out = useBrewStore.getState().outdated;
|
|
3043
|
+
const remaining = out.formulae.length + out.casks.length;
|
|
3044
|
+
void writeLastAction({
|
|
3045
|
+
timestamp: (/* @__PURE__ */ new Date()).toISOString(),
|
|
3046
|
+
action,
|
|
3047
|
+
packages: [packageName],
|
|
3048
|
+
remainingOutdated: remaining,
|
|
3049
|
+
source: "brew-tui"
|
|
3050
|
+
}).catch((err) => logger.warn("Failed to write last-action.json", err));
|
|
3051
|
+
});
|
|
3052
|
+
}
|
|
2935
3053
|
}
|
|
2936
3054
|
}, [stream.isRunning, stream.error]);
|
|
2937
|
-
|
|
3055
|
+
useViewInput((input, key) => {
|
|
2938
3056
|
if (stream.isRunning) {
|
|
2939
3057
|
if (key.escape) stream.cancel();
|
|
2940
3058
|
return;
|
|
@@ -2942,30 +3060,30 @@ function PackageInfoView() {
|
|
|
2942
3060
|
if (confirmAction) return;
|
|
2943
3061
|
if (!formula) return;
|
|
2944
3062
|
const isInstalled2 = formula.installed.length > 0;
|
|
2945
|
-
if (input === "i" && !isInstalled2) {
|
|
3063
|
+
if ((input === "i" || input === "1") && !isInstalled2) {
|
|
2946
3064
|
setConfirmAction("install");
|
|
2947
|
-
} else if (input === "u" && isInstalled2) {
|
|
3065
|
+
} else if ((input === "u" || input === "2") && isInstalled2) {
|
|
2948
3066
|
setConfirmAction("uninstall");
|
|
2949
|
-
} else if (input === "U" && isInstalled2 && formula.outdated) {
|
|
3067
|
+
} else if ((input === "U" || input === "3") && isInstalled2 && formula.outdated) {
|
|
2950
3068
|
setConfirmAction("upgrade");
|
|
2951
3069
|
}
|
|
2952
3070
|
});
|
|
2953
3071
|
if (!packageName) {
|
|
2954
|
-
return /* @__PURE__ */
|
|
3072
|
+
return /* @__PURE__ */ jsx21(Text21, { color: COLORS.textSecondary, italic: true, children: t("pkgInfo_noPackage") });
|
|
2955
3073
|
}
|
|
2956
|
-
if (loading) return /* @__PURE__ */
|
|
2957
|
-
if (error) return /* @__PURE__ */
|
|
2958
|
-
if (!formula) return /* @__PURE__ */
|
|
3074
|
+
if (loading) return /* @__PURE__ */ jsx21(Loading, { message: t("loading_package", { name: packageName }) });
|
|
3075
|
+
if (error) return /* @__PURE__ */ jsx21(ErrorMessage, { message: error });
|
|
3076
|
+
if (!formula) return /* @__PURE__ */ jsx21(ErrorMessage, { message: t("pkgInfo_notFound") });
|
|
2959
3077
|
if (stream.isRunning || stream.lines.length > 0) {
|
|
2960
3078
|
return /* @__PURE__ */ jsxs19(Box18, { flexDirection: "column", children: [
|
|
2961
|
-
/* @__PURE__ */
|
|
2962
|
-
stream.isRunning && /* @__PURE__ */ jsxs19(
|
|
3079
|
+
/* @__PURE__ */ jsx21(ProgressLog, { lines: stream.lines, isRunning: stream.isRunning, title: t(ACTION_PROGRESS_KEYS[activeActionRef.current] ?? ACTION_PROGRESS_KEYS["install"], { name: formula.name }) }),
|
|
3080
|
+
stream.isRunning && /* @__PURE__ */ jsxs19(Text21, { color: COLORS.textSecondary, children: [
|
|
2963
3081
|
"esc:",
|
|
2964
3082
|
t("hint_cancel")
|
|
2965
3083
|
] }),
|
|
2966
3084
|
!stream.isRunning && /* @__PURE__ */ jsxs19(Fragment4, { children: [
|
|
2967
|
-
/* @__PURE__ */
|
|
2968
|
-
/* @__PURE__ */ jsxs19(
|
|
3085
|
+
/* @__PURE__ */ jsx21(Text21, { color: stream.error ? COLORS.error : COLORS.success, bold: true, children: stream.error ? `\u2718 ${stream.error}` : `\u2714 ${t("pkgInfo_done")}` }),
|
|
3086
|
+
/* @__PURE__ */ jsxs19(Text21, { color: COLORS.textSecondary, children: [
|
|
2969
3087
|
"esc:",
|
|
2970
3088
|
t("hint_back")
|
|
2971
3089
|
] })
|
|
@@ -2975,7 +3093,7 @@ function PackageInfoView() {
|
|
|
2975
3093
|
const installed = formula.installed[0];
|
|
2976
3094
|
const isInstalled = formula.installed.length > 0;
|
|
2977
3095
|
return /* @__PURE__ */ jsxs19(Box18, { flexDirection: "column", children: [
|
|
2978
|
-
confirmAction && /* @__PURE__ */
|
|
3096
|
+
confirmAction && /* @__PURE__ */ jsx21(
|
|
2979
3097
|
ConfirmDialog,
|
|
2980
3098
|
{
|
|
2981
3099
|
message: t(ACTION_CONFIRM_KEYS[confirmAction], { name: formula.name }),
|
|
@@ -2992,55 +3110,55 @@ function PackageInfoView() {
|
|
|
2992
3110
|
}
|
|
2993
3111
|
),
|
|
2994
3112
|
/* @__PURE__ */ jsxs19(Box18, { gap: SPACING.sm, marginBottom: SPACING.xs, children: [
|
|
2995
|
-
/* @__PURE__ */
|
|
2996
|
-
/* @__PURE__ */
|
|
2997
|
-
isInstalled && /* @__PURE__ */
|
|
2998
|
-
formula.outdated && /* @__PURE__ */
|
|
2999
|
-
formula.pinned && /* @__PURE__ */
|
|
3000
|
-
formula.keg_only && /* @__PURE__ */
|
|
3001
|
-
formula.deprecated && /* @__PURE__ */
|
|
3113
|
+
/* @__PURE__ */ jsx21(GradientText, { colors: GRADIENTS.gold, bold: true, children: formula.name }),
|
|
3114
|
+
/* @__PURE__ */ jsx21(Text21, { color: COLORS.teal, children: installed?.version ?? formula.versions.stable }),
|
|
3115
|
+
isInstalled && /* @__PURE__ */ jsx21(StatusBadge, { label: t("badge_installed"), variant: "success" }),
|
|
3116
|
+
formula.outdated && /* @__PURE__ */ jsx21(StatusBadge, { label: t("badge_outdated"), variant: "warning" }),
|
|
3117
|
+
formula.pinned && /* @__PURE__ */ jsx21(StatusBadge, { label: t("badge_pinned"), variant: "info" }),
|
|
3118
|
+
formula.keg_only && /* @__PURE__ */ jsx21(StatusBadge, { label: t("badge_kegOnly"), variant: "muted" }),
|
|
3119
|
+
formula.deprecated && /* @__PURE__ */ jsx21(StatusBadge, { label: t("badge_deprecated"), variant: "error" })
|
|
3002
3120
|
] }),
|
|
3003
3121
|
/* @__PURE__ */ jsxs19(Box18, { flexDirection: "column", gap: SPACING.xs, children: [
|
|
3004
|
-
/* @__PURE__ */
|
|
3122
|
+
/* @__PURE__ */ jsx21(Text21, { children: formula.desc }),
|
|
3005
3123
|
/* @__PURE__ */ jsxs19(Box18, { flexDirection: "column", children: [
|
|
3006
|
-
/* @__PURE__ */
|
|
3124
|
+
/* @__PURE__ */ jsx21(SectionHeader, { emoji: "\u{1F4CB}", title: t("pkgInfo_details"), gradient: [COLORS.text, COLORS.muted] }),
|
|
3007
3125
|
/* @__PURE__ */ jsxs19(Box18, { borderStyle: "round", borderColor: COLORS.border, paddingX: SPACING.sm, flexDirection: "column", children: [
|
|
3008
|
-
/* @__PURE__ */ jsxs19(
|
|
3009
|
-
/* @__PURE__ */
|
|
3126
|
+
/* @__PURE__ */ jsxs19(Text21, { children: [
|
|
3127
|
+
/* @__PURE__ */ jsx21(Text21, { color: COLORS.muted, children: t("pkgInfo_homepage") }),
|
|
3010
3128
|
" ",
|
|
3011
3129
|
formula.homepage
|
|
3012
3130
|
] }),
|
|
3013
|
-
/* @__PURE__ */ jsxs19(
|
|
3014
|
-
/* @__PURE__ */
|
|
3131
|
+
/* @__PURE__ */ jsxs19(Text21, { children: [
|
|
3132
|
+
/* @__PURE__ */ jsx21(Text21, { color: COLORS.muted, children: t("pkgInfo_license") }),
|
|
3015
3133
|
" ",
|
|
3016
3134
|
formula.license
|
|
3017
3135
|
] }),
|
|
3018
|
-
/* @__PURE__ */ jsxs19(
|
|
3019
|
-
/* @__PURE__ */
|
|
3136
|
+
/* @__PURE__ */ jsxs19(Text21, { children: [
|
|
3137
|
+
/* @__PURE__ */ jsx21(Text21, { color: COLORS.muted, children: t("pkgInfo_tap") }),
|
|
3020
3138
|
" ",
|
|
3021
3139
|
formula.tap
|
|
3022
3140
|
] }),
|
|
3023
|
-
/* @__PURE__ */ jsxs19(
|
|
3024
|
-
/* @__PURE__ */
|
|
3141
|
+
/* @__PURE__ */ jsxs19(Text21, { children: [
|
|
3142
|
+
/* @__PURE__ */ jsx21(Text21, { color: COLORS.muted, children: t("pkgInfo_stable") }),
|
|
3025
3143
|
" ",
|
|
3026
3144
|
formula.versions.stable
|
|
3027
3145
|
] }),
|
|
3028
3146
|
installed && /* @__PURE__ */ jsxs19(Fragment4, { children: [
|
|
3029
|
-
/* @__PURE__ */ jsxs19(
|
|
3030
|
-
/* @__PURE__ */
|
|
3147
|
+
/* @__PURE__ */ jsxs19(Text21, { children: [
|
|
3148
|
+
/* @__PURE__ */ jsx21(Text21, { color: COLORS.muted, children: t("pkgInfo_installed") }),
|
|
3031
3149
|
" ",
|
|
3032
3150
|
installed.version,
|
|
3033
3151
|
" (",
|
|
3034
3152
|
formatRelativeTime(installed.time),
|
|
3035
3153
|
")"
|
|
3036
3154
|
] }),
|
|
3037
|
-
/* @__PURE__ */ jsxs19(
|
|
3038
|
-
/* @__PURE__ */
|
|
3155
|
+
/* @__PURE__ */ jsxs19(Text21, { children: [
|
|
3156
|
+
/* @__PURE__ */ jsx21(Text21, { color: COLORS.muted, children: t("pkgInfo_bottle") }),
|
|
3039
3157
|
" ",
|
|
3040
3158
|
installed.poured_from_bottle ? t("common_yes") : t("common_no")
|
|
3041
3159
|
] }),
|
|
3042
|
-
/* @__PURE__ */ jsxs19(
|
|
3043
|
-
/* @__PURE__ */
|
|
3160
|
+
/* @__PURE__ */ jsxs19(Text21, { children: [
|
|
3161
|
+
/* @__PURE__ */ jsx21(Text21, { color: COLORS.muted, children: t("pkgInfo_onRequest") }),
|
|
3044
3162
|
" ",
|
|
3045
3163
|
installed.installed_on_request ? t("common_yes") : t("pkgInfo_noDependency")
|
|
3046
3164
|
] })
|
|
@@ -3048,15 +3166,15 @@ function PackageInfoView() {
|
|
|
3048
3166
|
] })
|
|
3049
3167
|
] }),
|
|
3050
3168
|
formula.dependencies.length > 0 && /* @__PURE__ */ jsxs19(Box18, { flexDirection: "column", children: [
|
|
3051
|
-
/* @__PURE__ */
|
|
3052
|
-
/* @__PURE__ */
|
|
3169
|
+
/* @__PURE__ */ jsx21(SectionHeader, { emoji: "\u{1F517}", title: t("pkgInfo_dependencies", { count: formula.dependencies.length }), gradient: GRADIENTS.ocean }),
|
|
3170
|
+
/* @__PURE__ */ jsx21(Box18, { paddingLeft: SPACING.sm, flexWrap: "wrap", columnGap: 2, children: formula.dependencies.map((dep) => /* @__PURE__ */ jsx21(Text21, { color: COLORS.muted, children: dep }, dep)) })
|
|
3053
3171
|
] }),
|
|
3054
3172
|
formula.caveats && /* @__PURE__ */ jsxs19(Box18, { flexDirection: "column", children: [
|
|
3055
|
-
/* @__PURE__ */
|
|
3056
|
-
/* @__PURE__ */
|
|
3173
|
+
/* @__PURE__ */ jsx21(SectionHeader, { emoji: "\u26A0\uFE0F", title: t("pkgInfo_caveats"), color: COLORS.warning }),
|
|
3174
|
+
/* @__PURE__ */ jsx21(Box18, { borderStyle: "round", borderColor: COLORS.warning, paddingX: SPACING.sm, children: /* @__PURE__ */ jsx21(Text21, { color: COLORS.warning, children: formula.caveats }) })
|
|
3057
3175
|
] })
|
|
3058
3176
|
] }),
|
|
3059
|
-
/* @__PURE__ */
|
|
3177
|
+
/* @__PURE__ */ jsx21(Box18, { marginTop: SPACING.xs, children: /* @__PURE__ */ jsxs19(Text21, { color: COLORS.textSecondary, children: [
|
|
3060
3178
|
isInstalled ? `u:${t("hint_uninstall")}` : `i:${t("hint_install")}`,
|
|
3061
3179
|
isInstalled && formula.outdated ? ` U:${t("hint_upgrade")}` : "",
|
|
3062
3180
|
` esc:${t("hint_back")}`
|
|
@@ -3065,9 +3183,9 @@ function PackageInfoView() {
|
|
|
3065
3183
|
}
|
|
3066
3184
|
|
|
3067
3185
|
// src/views/services.tsx
|
|
3068
|
-
import { useEffect as
|
|
3069
|
-
import { Box as Box19, Text as
|
|
3070
|
-
import { jsx as
|
|
3186
|
+
import { useEffect as useEffect13, useState as useState10 } from "react";
|
|
3187
|
+
import { Box as Box19, Text as Text22, useStdout as useStdout5 } from "ink";
|
|
3188
|
+
import { jsx as jsx22, jsxs as jsxs20 } from "react/jsx-runtime";
|
|
3071
3189
|
var STATUS_VARIANTS = {
|
|
3072
3190
|
started: "success",
|
|
3073
3191
|
stopped: "muted",
|
|
@@ -3082,19 +3200,19 @@ function humaniseServiceError(message) {
|
|
|
3082
3200
|
}
|
|
3083
3201
|
function ServicesView() {
|
|
3084
3202
|
const { services, loading, errors, fetchServices, serviceAction: serviceAction2 } = useBrewStore();
|
|
3085
|
-
const [cursor, setCursor] =
|
|
3086
|
-
const [actionInProgress, setActionInProgress] =
|
|
3087
|
-
const [confirmAction, setConfirmAction] =
|
|
3088
|
-
const [lastError, setLastError] =
|
|
3089
|
-
const { stdout } =
|
|
3203
|
+
const [cursor, setCursor] = useState10(0);
|
|
3204
|
+
const [actionInProgress, setActionInProgress] = useState10(false);
|
|
3205
|
+
const [confirmAction, setConfirmAction] = useState10(null);
|
|
3206
|
+
const [lastError, setLastError] = useState10(null);
|
|
3207
|
+
const { stdout } = useStdout5();
|
|
3090
3208
|
const cols = stdout?.columns ?? 80;
|
|
3091
3209
|
const svcNameWidth = Math.floor(cols * 0.35);
|
|
3092
3210
|
const svcStatusWidth = Math.floor(cols * 0.15);
|
|
3093
3211
|
const MAX_VISIBLE_ROWS = Math.max(5, (stdout?.rows ?? 24) - 10);
|
|
3094
|
-
|
|
3212
|
+
useEffect13(() => {
|
|
3095
3213
|
fetchServices();
|
|
3096
3214
|
}, []);
|
|
3097
|
-
|
|
3215
|
+
useViewInput((input, key) => {
|
|
3098
3216
|
if (actionInProgress) return;
|
|
3099
3217
|
if (confirmAction) return;
|
|
3100
3218
|
if (lastError) {
|
|
@@ -3104,7 +3222,7 @@ function ServicesView() {
|
|
|
3104
3222
|
setCursor((c) => Math.min(c + 1, Math.max(0, services.length - 1)));
|
|
3105
3223
|
} else if (input === "k" || key.upArrow) {
|
|
3106
3224
|
setCursor((c) => Math.max(c - 1, 0));
|
|
3107
|
-
} else if (input === "r") {
|
|
3225
|
+
} else if (input === "r" || input === "4") {
|
|
3108
3226
|
void fetchServices();
|
|
3109
3227
|
}
|
|
3110
3228
|
const svc = services[cursor];
|
|
@@ -3119,23 +3237,23 @@ function ServicesView() {
|
|
|
3119
3237
|
if (storeError) setLastError(humaniseServiceError(storeError));
|
|
3120
3238
|
});
|
|
3121
3239
|
};
|
|
3122
|
-
if (input === "s") doAction("start");
|
|
3123
|
-
else if (input === "x") setConfirmAction({ type: "stop", name: svc.name });
|
|
3124
|
-
else if (input === "R") setConfirmAction({ type: "restart", name: svc.name });
|
|
3240
|
+
if (input === "s" || input === "1") doAction("start");
|
|
3241
|
+
else if (input === "x" || input === "2") setConfirmAction({ type: "stop", name: svc.name });
|
|
3242
|
+
else if (input === "R" || input === "3") setConfirmAction({ type: "restart", name: svc.name });
|
|
3125
3243
|
});
|
|
3126
|
-
if (loading.services) return /* @__PURE__ */
|
|
3127
|
-
if (errors.services) return /* @__PURE__ */
|
|
3244
|
+
if (loading.services) return /* @__PURE__ */ jsx22(Loading, { message: t("loading_services") });
|
|
3245
|
+
if (errors.services) return /* @__PURE__ */ jsx22(ErrorMessage, { message: errors.services });
|
|
3128
3246
|
if (services.length === 0) {
|
|
3129
3247
|
return /* @__PURE__ */ jsxs20(Box19, { flexDirection: "column", children: [
|
|
3130
|
-
/* @__PURE__ */
|
|
3131
|
-
/* @__PURE__ */
|
|
3248
|
+
/* @__PURE__ */ jsx22(SectionHeader, { emoji: "\u2699\uFE0F", title: t("services_title"), gradient: GRADIENTS.ocean }),
|
|
3249
|
+
/* @__PURE__ */ jsx22(Text22, { color: COLORS.textSecondary, italic: true, children: t("services_noServices") })
|
|
3132
3250
|
] });
|
|
3133
3251
|
}
|
|
3134
3252
|
const start = Math.max(0, cursor - Math.floor(MAX_VISIBLE_ROWS / 2));
|
|
3135
3253
|
const visible = services.slice(start, start + MAX_VISIBLE_ROWS);
|
|
3136
3254
|
return /* @__PURE__ */ jsxs20(Box19, { flexDirection: "column", children: [
|
|
3137
|
-
/* @__PURE__ */
|
|
3138
|
-
confirmAction && /* @__PURE__ */
|
|
3255
|
+
/* @__PURE__ */ jsx22(SectionHeader, { emoji: "\u2699\uFE0F", title: t("services_titleCount", { count: services.length }), gradient: GRADIENTS.ocean }),
|
|
3256
|
+
confirmAction && /* @__PURE__ */ jsx22(Box19, { marginY: SPACING.xs, children: /* @__PURE__ */ jsx22(
|
|
3139
3257
|
ConfirmDialog,
|
|
3140
3258
|
{
|
|
3141
3259
|
message: confirmAction.type === "stop" ? t("services_confirmStop", { name: confirmAction.name }) : t("services_confirmRestart", { name: confirmAction.name }),
|
|
@@ -3156,14 +3274,14 @@ function ServicesView() {
|
|
|
3156
3274
|
) }),
|
|
3157
3275
|
/* @__PURE__ */ jsxs20(Box19, { flexDirection: "column", marginTop: SPACING.xs, children: [
|
|
3158
3276
|
/* @__PURE__ */ jsxs20(Box19, { gap: SPACING.xs, borderStyle: "single", borderBottom: true, borderTop: false, borderLeft: false, borderRight: false, borderColor: COLORS.border, paddingBottom: SPACING.none, children: [
|
|
3159
|
-
/* @__PURE__ */ jsxs20(
|
|
3277
|
+
/* @__PURE__ */ jsxs20(Text22, { bold: true, color: COLORS.text, children: [
|
|
3160
3278
|
" ",
|
|
3161
3279
|
t("services_name").padEnd(svcNameWidth)
|
|
3162
3280
|
] }),
|
|
3163
|
-
/* @__PURE__ */
|
|
3164
|
-
/* @__PURE__ */
|
|
3281
|
+
/* @__PURE__ */ jsx22(Text22, { bold: true, color: COLORS.text, children: t("services_status").padEnd(svcStatusWidth) }),
|
|
3282
|
+
/* @__PURE__ */ jsx22(Text22, { bold: true, color: COLORS.text, children: t("services_user") })
|
|
3165
3283
|
] }),
|
|
3166
|
-
start > 0 && /* @__PURE__ */ jsxs20(
|
|
3284
|
+
start > 0 && /* @__PURE__ */ jsxs20(Text22, { color: COLORS.textSecondary, dimColor: true, children: [
|
|
3167
3285
|
" ",
|
|
3168
3286
|
t("scroll_moreAbove", { count: start })
|
|
3169
3287
|
] }),
|
|
@@ -3171,20 +3289,20 @@ function ServicesView() {
|
|
|
3171
3289
|
const idx = start + i;
|
|
3172
3290
|
const isCurrent = idx === cursor;
|
|
3173
3291
|
return /* @__PURE__ */ jsxs20(SelectableRow, { isCurrent, children: [
|
|
3174
|
-
/* @__PURE__ */
|
|
3175
|
-
/* @__PURE__ */
|
|
3176
|
-
/* @__PURE__ */
|
|
3177
|
-
svc.exit_code != null && svc.exit_code !== 0 && /* @__PURE__ */
|
|
3292
|
+
/* @__PURE__ */ jsx22(Text22, { bold: isCurrent, inverse: isCurrent, color: isCurrent ? COLORS.text : COLORS.muted, children: svc.name.padEnd(svcNameWidth - 2) }),
|
|
3293
|
+
/* @__PURE__ */ jsx22(StatusBadge, { label: svc.status, variant: STATUS_VARIANTS[svc.status] }),
|
|
3294
|
+
/* @__PURE__ */ jsx22(Text22, { color: COLORS.muted, children: svc.user ?? "-" }),
|
|
3295
|
+
svc.exit_code != null && svc.exit_code !== 0 && /* @__PURE__ */ jsx22(Text22, { color: COLORS.error, children: t("common_exit", { code: svc.exit_code }) })
|
|
3178
3296
|
] }, svc.name);
|
|
3179
3297
|
}),
|
|
3180
|
-
start + MAX_VISIBLE_ROWS < services.length && /* @__PURE__ */ jsxs20(
|
|
3298
|
+
start + MAX_VISIBLE_ROWS < services.length && /* @__PURE__ */ jsxs20(Text22, { color: COLORS.textSecondary, dimColor: true, children: [
|
|
3181
3299
|
" ",
|
|
3182
3300
|
t("scroll_moreBelow", { count: services.length - start - MAX_VISIBLE_ROWS })
|
|
3183
3301
|
] })
|
|
3184
3302
|
] }),
|
|
3185
|
-
actionInProgress && /* @__PURE__ */
|
|
3186
|
-
lastError && /* @__PURE__ */
|
|
3187
|
-
/* @__PURE__ */
|
|
3303
|
+
actionInProgress && /* @__PURE__ */ jsx22(Text22, { color: COLORS.sky, children: t("services_processing") }),
|
|
3304
|
+
lastError && /* @__PURE__ */ jsx22(Box19, { marginTop: SPACING.xs, children: /* @__PURE__ */ jsx22(Text22, { color: COLORS.error, children: lastError }) }),
|
|
3305
|
+
/* @__PURE__ */ jsx22(Box19, { marginTop: SPACING.xs, children: /* @__PURE__ */ jsxs20(Text22, { color: COLORS.text, bold: true, children: [
|
|
3188
3306
|
cursor + 1,
|
|
3189
3307
|
"/",
|
|
3190
3308
|
services.length
|
|
@@ -3193,43 +3311,43 @@ function ServicesView() {
|
|
|
3193
3311
|
}
|
|
3194
3312
|
|
|
3195
3313
|
// src/views/doctor.tsx
|
|
3196
|
-
import { useEffect as
|
|
3197
|
-
import { Box as Box20, Text as
|
|
3198
|
-
import { jsx as
|
|
3314
|
+
import { useEffect as useEffect14, useRef as useRef6 } from "react";
|
|
3315
|
+
import { Box as Box20, Text as Text23 } from "ink";
|
|
3316
|
+
import { jsx as jsx23, jsxs as jsxs21 } from "react/jsx-runtime";
|
|
3199
3317
|
function DoctorView() {
|
|
3200
3318
|
const { doctorWarnings, doctorClean, loading, errors, fetchDoctor } = useBrewStore();
|
|
3201
|
-
const mountedRef =
|
|
3202
|
-
|
|
3319
|
+
const mountedRef = useRef6(true);
|
|
3320
|
+
useEffect14(() => {
|
|
3203
3321
|
mountedRef.current = true;
|
|
3204
3322
|
return () => {
|
|
3205
3323
|
mountedRef.current = false;
|
|
3206
3324
|
};
|
|
3207
3325
|
}, []);
|
|
3208
|
-
|
|
3326
|
+
useEffect14(() => {
|
|
3209
3327
|
fetchDoctor();
|
|
3210
3328
|
}, []);
|
|
3211
|
-
|
|
3212
|
-
if (input === "r") void fetchDoctor();
|
|
3329
|
+
useViewInput((input) => {
|
|
3330
|
+
if (input === "r" || input === "1") void fetchDoctor();
|
|
3213
3331
|
});
|
|
3214
|
-
if (loading.doctor) return /* @__PURE__ */
|
|
3215
|
-
if (errors.doctor) return /* @__PURE__ */
|
|
3332
|
+
if (loading.doctor) return /* @__PURE__ */ jsx23(Loading, { message: t("loading_doctor") });
|
|
3333
|
+
if (errors.doctor) return /* @__PURE__ */ jsx23(ErrorMessage, { message: errors.doctor });
|
|
3216
3334
|
return /* @__PURE__ */ jsxs21(Box20, { flexDirection: "column", children: [
|
|
3217
|
-
/* @__PURE__ */
|
|
3335
|
+
/* @__PURE__ */ jsx23(SectionHeader, { emoji: "\u{1FA7A}", title: t("doctor_title"), gradient: GRADIENTS.emerald }),
|
|
3218
3336
|
/* @__PURE__ */ jsxs21(Box20, { flexDirection: "column", marginTop: SPACING.xs, children: [
|
|
3219
|
-
doctorClean && /* @__PURE__ */
|
|
3220
|
-
doctorClean === false && doctorWarnings.length === 0 && /* @__PURE__ */
|
|
3337
|
+
doctorClean && /* @__PURE__ */ jsx23(ResultBanner, { status: "success", message: `\u2714 ${t("doctor_clean")}` }),
|
|
3338
|
+
doctorClean === false && doctorWarnings.length === 0 && /* @__PURE__ */ jsx23(Text23, { color: COLORS.warning, children: t("doctor_warningsNotCaptured") }),
|
|
3221
3339
|
doctorWarnings.map((warning, i) => (
|
|
3222
3340
|
// FE-004: Improved React key
|
|
3223
|
-
/* @__PURE__ */
|
|
3341
|
+
/* @__PURE__ */ jsx23(Box20, { flexDirection: "column", marginBottom: SPACING.xs, borderStyle: "single", borderColor: COLORS.warning, paddingX: SPACING.xs, children: warning.split("\n").map((line, j) => /* @__PURE__ */ jsx23(Text23, { color: j === 0 ? COLORS.warning : COLORS.muted, children: line }, `warning-${i}-${j}-${line.slice(0, 20)}`)) }, `warning-${i}-${warning.slice(0, 20)}`)
|
|
3224
3342
|
))
|
|
3225
3343
|
] }),
|
|
3226
|
-
/* @__PURE__ */
|
|
3344
|
+
/* @__PURE__ */ jsx23(Box20, { marginTop: SPACING.xs, children: /* @__PURE__ */ jsx23(Text23, { color: COLORS.text, bold: true, children: doctorWarnings.length > 0 ? tp("plural_warnings", doctorWarnings.length) : "" }) })
|
|
3227
3345
|
] });
|
|
3228
3346
|
}
|
|
3229
3347
|
|
|
3230
3348
|
// src/views/profiles.tsx
|
|
3231
|
-
import { useEffect as
|
|
3232
|
-
import { Box as Box25
|
|
3349
|
+
import { useEffect as useEffect15, useRef as useRef7, useState as useState11 } from "react";
|
|
3350
|
+
import { Box as Box25 } from "ink";
|
|
3233
3351
|
|
|
3234
3352
|
// src/stores/profile-store.ts
|
|
3235
3353
|
import { create as create9 } from "zustand";
|
|
@@ -3449,13 +3567,13 @@ var useProfileStore = create9((set) => ({
|
|
|
3449
3567
|
}));
|
|
3450
3568
|
|
|
3451
3569
|
// src/views/profiles/profile-list-mode.tsx
|
|
3452
|
-
import { Box as Box21, Text as
|
|
3453
|
-
import { jsx as
|
|
3570
|
+
import { Box as Box21, Text as Text24 } from "ink";
|
|
3571
|
+
import { jsx as jsx24, jsxs as jsxs22 } from "react/jsx-runtime";
|
|
3454
3572
|
function ProfileListMode({ profileNames, cursor, confirmDelete, loadError, onConfirmDelete, onCancelDelete }) {
|
|
3455
3573
|
return /* @__PURE__ */ jsxs22(Box21, { flexDirection: "column", children: [
|
|
3456
|
-
/* @__PURE__ */
|
|
3457
|
-
loadError && /* @__PURE__ */
|
|
3458
|
-
confirmDelete && profileNames[cursor] && /* @__PURE__ */
|
|
3574
|
+
/* @__PURE__ */ jsx24(SectionHeader, { emoji: "\u{1F4C1}", title: t("profiles_title", { count: profileNames.length }), gradient: GRADIENTS.gold }),
|
|
3575
|
+
loadError && /* @__PURE__ */ jsx24(Box21, { marginY: SPACING.xs, children: /* @__PURE__ */ jsx24(Text24, { color: COLORS.error, children: loadError }) }),
|
|
3576
|
+
confirmDelete && profileNames[cursor] && /* @__PURE__ */ jsx24(Box21, { marginY: SPACING.xs, children: /* @__PURE__ */ jsx24(
|
|
3459
3577
|
ConfirmDialog,
|
|
3460
3578
|
{
|
|
3461
3579
|
message: t("profiles_confirmDelete", { name: profileNames[cursor] }),
|
|
@@ -3463,12 +3581,12 @@ function ProfileListMode({ profileNames, cursor, confirmDelete, loadError, onCon
|
|
|
3463
3581
|
onCancel: onCancelDelete
|
|
3464
3582
|
}
|
|
3465
3583
|
) }),
|
|
3466
|
-
profileNames.length === 0 && !confirmDelete && /* @__PURE__ */
|
|
3467
|
-
/* @__PURE__ */
|
|
3468
|
-
/* @__PURE__ */ jsxs22(
|
|
3584
|
+
profileNames.length === 0 && !confirmDelete && /* @__PURE__ */ jsx24(Box21, { marginTop: SPACING.xs, borderStyle: "round", borderColor: COLORS.textSecondary, paddingX: SPACING.sm, paddingY: SPACING.none, children: /* @__PURE__ */ jsxs22(Box21, { flexDirection: "column", children: [
|
|
3585
|
+
/* @__PURE__ */ jsx24(Text24, { color: COLORS.textSecondary, italic: true, children: t("profiles_noProfiles") }),
|
|
3586
|
+
/* @__PURE__ */ jsxs22(Text24, { color: COLORS.muted, children: [
|
|
3469
3587
|
t("profiles_press"),
|
|
3470
3588
|
" ",
|
|
3471
|
-
/* @__PURE__ */
|
|
3589
|
+
/* @__PURE__ */ jsx24(Text24, { color: COLORS.gold, bold: true, children: "n" }),
|
|
3472
3590
|
" ",
|
|
3473
3591
|
t("profiles_exportHint")
|
|
3474
3592
|
] })
|
|
@@ -3476,9 +3594,9 @@ function ProfileListMode({ profileNames, cursor, confirmDelete, loadError, onCon
|
|
|
3476
3594
|
profileNames.length > 0 && !confirmDelete && /* @__PURE__ */ jsxs22(Box21, { flexDirection: "column", marginTop: SPACING.xs, children: [
|
|
3477
3595
|
profileNames.map((name, i) => {
|
|
3478
3596
|
const isCurrent = i === cursor;
|
|
3479
|
-
return /* @__PURE__ */
|
|
3597
|
+
return /* @__PURE__ */ jsx24(SelectableRow, { isCurrent, children: /* @__PURE__ */ jsx24(Text24, { bold: isCurrent, inverse: isCurrent, children: name }) }, name);
|
|
3480
3598
|
}),
|
|
3481
|
-
/* @__PURE__ */
|
|
3599
|
+
/* @__PURE__ */ jsx24(Box21, { marginTop: SPACING.xs, children: /* @__PURE__ */ jsxs22(Text24, { color: COLORS.text, bold: true, children: [
|
|
3482
3600
|
cursor + 1,
|
|
3483
3601
|
"/",
|
|
3484
3602
|
profileNames.length
|
|
@@ -3488,23 +3606,23 @@ function ProfileListMode({ profileNames, cursor, confirmDelete, loadError, onCon
|
|
|
3488
3606
|
}
|
|
3489
3607
|
|
|
3490
3608
|
// src/views/profiles/profile-detail-mode.tsx
|
|
3491
|
-
import { Box as Box22, Text as
|
|
3492
|
-
import { jsx as
|
|
3609
|
+
import { Box as Box22, Text as Text25 } from "ink";
|
|
3610
|
+
import { jsx as jsx25, jsxs as jsxs23 } from "react/jsx-runtime";
|
|
3493
3611
|
function ProfileDetailMode({ profile }) {
|
|
3494
3612
|
return /* @__PURE__ */ jsxs23(Box22, { flexDirection: "column", children: [
|
|
3495
|
-
/* @__PURE__ */
|
|
3496
|
-
/* @__PURE__ */
|
|
3497
|
-
/* @__PURE__ */
|
|
3613
|
+
/* @__PURE__ */ jsx25(Text25, { bold: true, color: COLORS.gold, children: profile.name }),
|
|
3614
|
+
/* @__PURE__ */ jsx25(Text25, { color: COLORS.muted, children: profile.description }),
|
|
3615
|
+
/* @__PURE__ */ jsx25(Text25, { color: COLORS.muted, children: t("profiles_created", { date: formatDate(profile.createdAt) }) }),
|
|
3498
3616
|
/* @__PURE__ */ jsxs23(Box22, { marginTop: SPACING.xs, flexDirection: "column", children: [
|
|
3499
|
-
/* @__PURE__ */
|
|
3617
|
+
/* @__PURE__ */ jsx25(Text25, { bold: true, children: t("profiles_formulaeCount", { count: profile.formulae.length }) }),
|
|
3500
3618
|
/* @__PURE__ */ jsxs23(Box22, { paddingLeft: SPACING.sm, flexDirection: "column", children: [
|
|
3501
|
-
profile.formulae.slice(0, 30).map((f) => /* @__PURE__ */
|
|
3502
|
-
profile.formulae.length > 30 && /* @__PURE__ */
|
|
3619
|
+
profile.formulae.slice(0, 30).map((f) => /* @__PURE__ */ jsx25(Text25, { color: COLORS.muted, children: f }, f)),
|
|
3620
|
+
profile.formulae.length > 30 && /* @__PURE__ */ jsx25(Text25, { color: COLORS.textSecondary, italic: true, children: t("common_andMore", { count: profile.formulae.length - 30 }) })
|
|
3503
3621
|
] }),
|
|
3504
|
-
/* @__PURE__ */
|
|
3505
|
-
/* @__PURE__ */
|
|
3622
|
+
/* @__PURE__ */ jsx25(Text25, { bold: true, children: t("profiles_casksCount", { count: profile.casks.length }) }),
|
|
3623
|
+
/* @__PURE__ */ jsx25(Box22, { paddingLeft: SPACING.sm, flexDirection: "column", children: profile.casks.map((c) => /* @__PURE__ */ jsx25(Text25, { color: COLORS.muted, children: c }, c)) })
|
|
3506
3624
|
] }),
|
|
3507
|
-
/* @__PURE__ */
|
|
3625
|
+
/* @__PURE__ */ jsx25(Box22, { marginTop: SPACING.xs, children: /* @__PURE__ */ jsxs23(Text25, { color: COLORS.textSecondary, children: [
|
|
3508
3626
|
"esc:",
|
|
3509
3627
|
t("hint_back"),
|
|
3510
3628
|
" e:",
|
|
@@ -3516,13 +3634,13 @@ function ProfileDetailMode({ profile }) {
|
|
|
3516
3634
|
}
|
|
3517
3635
|
|
|
3518
3636
|
// src/views/profiles/profile-create-flow.tsx
|
|
3519
|
-
import { Box as Box23, Text as
|
|
3637
|
+
import { Box as Box23, Text as Text26 } from "ink";
|
|
3520
3638
|
import { TextInput as TextInput3 } from "@inkjs/ui";
|
|
3521
|
-
import { jsx as
|
|
3639
|
+
import { jsx as jsx26, jsxs as jsxs24 } from "react/jsx-runtime";
|
|
3522
3640
|
function ProfileCreateName({ onSubmit }) {
|
|
3523
3641
|
return /* @__PURE__ */ jsxs24(Box23, { flexDirection: "column", children: [
|
|
3524
|
-
/* @__PURE__ */
|
|
3525
|
-
/* @__PURE__ */
|
|
3642
|
+
/* @__PURE__ */ jsx26(Text26, { bold: true, children: t("profiles_createName") }),
|
|
3643
|
+
/* @__PURE__ */ jsx26(
|
|
3526
3644
|
TextInput3,
|
|
3527
3645
|
{
|
|
3528
3646
|
placeholder: t("profiles_namePlaceholder"),
|
|
@@ -3533,12 +3651,12 @@ function ProfileCreateName({ onSubmit }) {
|
|
|
3533
3651
|
}
|
|
3534
3652
|
function ProfileCreateDesc({ name, loadError, onSubmit }) {
|
|
3535
3653
|
return /* @__PURE__ */ jsxs24(Box23, { flexDirection: "column", children: [
|
|
3536
|
-
/* @__PURE__ */
|
|
3537
|
-
loadError && /* @__PURE__ */ jsxs24(
|
|
3654
|
+
/* @__PURE__ */ jsx26(Text26, { bold: true, children: t("profiles_createDesc", { name }) }),
|
|
3655
|
+
loadError && /* @__PURE__ */ jsxs24(Text26, { color: COLORS.error, children: [
|
|
3538
3656
|
t("error_prefix"),
|
|
3539
3657
|
loadError
|
|
3540
3658
|
] }),
|
|
3541
|
-
/* @__PURE__ */
|
|
3659
|
+
/* @__PURE__ */ jsx26(
|
|
3542
3660
|
TextInput3,
|
|
3543
3661
|
{
|
|
3544
3662
|
placeholder: t("profiles_descPlaceholder"),
|
|
@@ -3549,13 +3667,13 @@ function ProfileCreateDesc({ name, loadError, onSubmit }) {
|
|
|
3549
3667
|
}
|
|
3550
3668
|
|
|
3551
3669
|
// src/views/profiles/profile-edit-flow.tsx
|
|
3552
|
-
import { Box as Box24, Text as
|
|
3670
|
+
import { Box as Box24, Text as Text27 } from "ink";
|
|
3553
3671
|
import { TextInput as TextInput4 } from "@inkjs/ui";
|
|
3554
|
-
import { jsx as
|
|
3672
|
+
import { jsx as jsx27, jsxs as jsxs25 } from "react/jsx-runtime";
|
|
3555
3673
|
function ProfileEditName({ defaultName, onSubmit }) {
|
|
3556
3674
|
return /* @__PURE__ */ jsxs25(Box24, { flexDirection: "column", children: [
|
|
3557
|
-
/* @__PURE__ */
|
|
3558
|
-
/* @__PURE__ */
|
|
3675
|
+
/* @__PURE__ */ jsx27(Text27, { bold: true, children: t("profiles_editName") }),
|
|
3676
|
+
/* @__PURE__ */ jsx27(
|
|
3559
3677
|
TextInput4,
|
|
3560
3678
|
{
|
|
3561
3679
|
defaultValue: defaultName,
|
|
@@ -3566,12 +3684,12 @@ function ProfileEditName({ defaultName, onSubmit }) {
|
|
|
3566
3684
|
}
|
|
3567
3685
|
function ProfileEditDesc({ name, defaultDesc, loadError, onSubmit }) {
|
|
3568
3686
|
return /* @__PURE__ */ jsxs25(Box24, { flexDirection: "column", children: [
|
|
3569
|
-
/* @__PURE__ */
|
|
3570
|
-
loadError && /* @__PURE__ */ jsxs25(
|
|
3687
|
+
/* @__PURE__ */ jsx27(Text27, { bold: true, children: t("profiles_editDesc", { name }) }),
|
|
3688
|
+
loadError && /* @__PURE__ */ jsxs25(Text27, { color: COLORS.error, children: [
|
|
3571
3689
|
t("error_prefix"),
|
|
3572
3690
|
loadError
|
|
3573
3691
|
] }),
|
|
3574
|
-
/* @__PURE__ */
|
|
3692
|
+
/* @__PURE__ */ jsx27(
|
|
3575
3693
|
TextInput4,
|
|
3576
3694
|
{
|
|
3577
3695
|
defaultValue: defaultDesc,
|
|
@@ -3582,26 +3700,26 @@ function ProfileEditDesc({ name, defaultDesc, loadError, onSubmit }) {
|
|
|
3582
3700
|
}
|
|
3583
3701
|
|
|
3584
3702
|
// src/views/profiles.tsx
|
|
3585
|
-
import { jsx as
|
|
3703
|
+
import { jsx as jsx28, jsxs as jsxs26 } from "react/jsx-runtime";
|
|
3586
3704
|
function ProfilesView() {
|
|
3587
3705
|
const { profileNames, selectedProfile, loading, loadError, fetchProfiles, loadProfile: loadProfile2, exportCurrent, deleteProfile: deleteProfile2, updateProfile: updateProfile2 } = useProfileStore();
|
|
3588
|
-
const [cursor, setCursor] =
|
|
3589
|
-
const [mode, setMode] =
|
|
3590
|
-
const [newName, setNewName] =
|
|
3591
|
-
const [confirmDelete, setConfirmDelete] =
|
|
3592
|
-
const [editName, setEditName] =
|
|
3593
|
-
const [editDesc, setEditDesc] =
|
|
3594
|
-
const [importLines, setImportLines] =
|
|
3595
|
-
const [importRunning, setImportRunning] =
|
|
3596
|
-
const [importHadError, setImportHadError] =
|
|
3597
|
-
const [importProfile2, setImportProfile] =
|
|
3706
|
+
const [cursor, setCursor] = useState11(0);
|
|
3707
|
+
const [mode, setMode] = useState11("list");
|
|
3708
|
+
const [newName, setNewName] = useState11("");
|
|
3709
|
+
const [confirmDelete, setConfirmDelete] = useState11(false);
|
|
3710
|
+
const [editName, setEditName] = useState11("");
|
|
3711
|
+
const [editDesc, setEditDesc] = useState11("");
|
|
3712
|
+
const [importLines, setImportLines] = useState11([]);
|
|
3713
|
+
const [importRunning, setImportRunning] = useState11(false);
|
|
3714
|
+
const [importHadError, setImportHadError] = useState11(false);
|
|
3715
|
+
const [importProfile2, setImportProfile] = useState11(null);
|
|
3598
3716
|
const { openModal, closeModal } = useModalStore();
|
|
3599
|
-
const importGenRef =
|
|
3600
|
-
const mountedRef =
|
|
3601
|
-
|
|
3717
|
+
const importGenRef = useRef7(null);
|
|
3718
|
+
const mountedRef = useRef7(true);
|
|
3719
|
+
useEffect15(() => {
|
|
3602
3720
|
fetchProfiles();
|
|
3603
3721
|
}, []);
|
|
3604
|
-
|
|
3722
|
+
useEffect15(() => {
|
|
3605
3723
|
mountedRef.current = true;
|
|
3606
3724
|
return () => {
|
|
3607
3725
|
mountedRef.current = false;
|
|
@@ -3609,7 +3727,7 @@ function ProfilesView() {
|
|
|
3609
3727
|
importGenRef.current = null;
|
|
3610
3728
|
};
|
|
3611
3729
|
}, []);
|
|
3612
|
-
|
|
3730
|
+
useEffect15(() => {
|
|
3613
3731
|
if (mode !== "list") {
|
|
3614
3732
|
openModal();
|
|
3615
3733
|
return () => {
|
|
@@ -3618,13 +3736,13 @@ function ProfilesView() {
|
|
|
3618
3736
|
}
|
|
3619
3737
|
return void 0;
|
|
3620
3738
|
}, [mode]);
|
|
3621
|
-
|
|
3739
|
+
useViewInput((input, key) => {
|
|
3622
3740
|
if (mode !== "list" || confirmDelete) return;
|
|
3623
|
-
if (input === "n") {
|
|
3741
|
+
if (input === "n" || input === "1") {
|
|
3624
3742
|
setMode("create-name");
|
|
3625
3743
|
return;
|
|
3626
3744
|
}
|
|
3627
|
-
if (input === "d" && profileNames[cursor]) {
|
|
3745
|
+
if ((input === "d" || input === "4") && profileNames[cursor]) {
|
|
3628
3746
|
setConfirmDelete(true);
|
|
3629
3747
|
return;
|
|
3630
3748
|
}
|
|
@@ -3633,25 +3751,25 @@ function ProfilesView() {
|
|
|
3633
3751
|
setMode("detail");
|
|
3634
3752
|
return;
|
|
3635
3753
|
}
|
|
3636
|
-
if (input === "i" && profileNames[cursor]) {
|
|
3754
|
+
if ((input === "i" || input === "3") && profileNames[cursor]) {
|
|
3637
3755
|
void prepareImport(profileNames[cursor]);
|
|
3638
3756
|
return;
|
|
3639
3757
|
}
|
|
3640
3758
|
if (input === "j" || key.downArrow) setCursor((c) => Math.min(c + 1, Math.max(0, profileNames.length - 1)));
|
|
3641
3759
|
else if (input === "k" || key.upArrow) setCursor((c) => Math.max(c - 1, 0));
|
|
3642
3760
|
});
|
|
3643
|
-
|
|
3761
|
+
useViewInput((input, key) => {
|
|
3644
3762
|
if (key.escape || input === "q") {
|
|
3645
3763
|
setMode("list");
|
|
3646
3764
|
return;
|
|
3647
3765
|
}
|
|
3648
|
-
if (input === "e" && selectedProfile) {
|
|
3766
|
+
if ((input === "e" || input === "2") && selectedProfile) {
|
|
3649
3767
|
setEditName(selectedProfile.name);
|
|
3650
3768
|
setEditDesc(selectedProfile.description);
|
|
3651
3769
|
setMode("edit-name");
|
|
3652
3770
|
}
|
|
3653
3771
|
}, { isActive: mode === "detail" });
|
|
3654
|
-
|
|
3772
|
+
useViewInput(() => {
|
|
3655
3773
|
setMode("list");
|
|
3656
3774
|
}, { isActive: mode === "importing" && !importRunning });
|
|
3657
3775
|
const prepareImport = async (name) => {
|
|
@@ -3691,9 +3809,9 @@ function ProfilesView() {
|
|
|
3691
3809
|
}
|
|
3692
3810
|
}
|
|
3693
3811
|
};
|
|
3694
|
-
if (loading) return /* @__PURE__ */
|
|
3812
|
+
if (loading) return /* @__PURE__ */ jsx28(Loading, { message: t("loading_profiles") });
|
|
3695
3813
|
if (mode === "confirm-import" && importProfile2) {
|
|
3696
|
-
return /* @__PURE__ */
|
|
3814
|
+
return /* @__PURE__ */ jsx28(Box25, { flexDirection: "column", children: /* @__PURE__ */ jsx28(
|
|
3697
3815
|
ConfirmDialog,
|
|
3698
3816
|
{
|
|
3699
3817
|
message: t("profiles_importSummary", {
|
|
@@ -3714,18 +3832,18 @@ function ProfilesView() {
|
|
|
3714
3832
|
}
|
|
3715
3833
|
if (mode === "importing") {
|
|
3716
3834
|
return /* @__PURE__ */ jsxs26(Box25, { flexDirection: "column", children: [
|
|
3717
|
-
/* @__PURE__ */
|
|
3718
|
-
!importRunning && /* @__PURE__ */
|
|
3835
|
+
/* @__PURE__ */ jsx28(ProgressLog, { lines: importLines, isRunning: importRunning, title: t("profiles_importTitle") }),
|
|
3836
|
+
!importRunning && /* @__PURE__ */ jsx28(Box25, { marginTop: SPACING.xs, children: /* @__PURE__ */ jsx28(ResultBanner, { status: importHadError ? "error" : "success", message: importHadError ? t("profiles_importPartial") : `\u2714 ${t("profiles_importComplete")}` }) })
|
|
3719
3837
|
] });
|
|
3720
3838
|
}
|
|
3721
3839
|
if (mode === "create-name") {
|
|
3722
|
-
return /* @__PURE__ */
|
|
3840
|
+
return /* @__PURE__ */ jsx28(ProfileCreateName, { onSubmit: (val) => {
|
|
3723
3841
|
setNewName(val);
|
|
3724
3842
|
setMode("create-desc");
|
|
3725
3843
|
} });
|
|
3726
3844
|
}
|
|
3727
3845
|
if (mode === "create-desc") {
|
|
3728
|
-
return /* @__PURE__ */
|
|
3846
|
+
return /* @__PURE__ */ jsx28(
|
|
3729
3847
|
ProfileCreateDesc,
|
|
3730
3848
|
{
|
|
3731
3849
|
name: newName,
|
|
@@ -3742,13 +3860,13 @@ function ProfilesView() {
|
|
|
3742
3860
|
);
|
|
3743
3861
|
}
|
|
3744
3862
|
if (mode === "edit-name") {
|
|
3745
|
-
return /* @__PURE__ */
|
|
3863
|
+
return /* @__PURE__ */ jsx28(ProfileEditName, { defaultName: editName, onSubmit: (val) => {
|
|
3746
3864
|
setEditName(val);
|
|
3747
3865
|
setMode("edit-desc");
|
|
3748
3866
|
} });
|
|
3749
3867
|
}
|
|
3750
3868
|
if (mode === "edit-desc") {
|
|
3751
|
-
return /* @__PURE__ */
|
|
3869
|
+
return /* @__PURE__ */ jsx28(
|
|
3752
3870
|
ProfileEditDesc,
|
|
3753
3871
|
{
|
|
3754
3872
|
name: editName,
|
|
@@ -3766,9 +3884,9 @@ function ProfilesView() {
|
|
|
3766
3884
|
);
|
|
3767
3885
|
}
|
|
3768
3886
|
if (mode === "detail" && selectedProfile) {
|
|
3769
|
-
return /* @__PURE__ */
|
|
3887
|
+
return /* @__PURE__ */ jsx28(ProfileDetailMode, { profile: selectedProfile });
|
|
3770
3888
|
}
|
|
3771
|
-
return /* @__PURE__ */
|
|
3889
|
+
return /* @__PURE__ */ jsx28(
|
|
3772
3890
|
ProfileListMode,
|
|
3773
3891
|
{
|
|
3774
3892
|
profileNames,
|
|
@@ -3785,8 +3903,8 @@ function ProfilesView() {
|
|
|
3785
3903
|
}
|
|
3786
3904
|
|
|
3787
3905
|
// src/views/smart-cleanup.tsx
|
|
3788
|
-
import { useEffect as
|
|
3789
|
-
import { Box as Box26, Text as
|
|
3906
|
+
import { useEffect as useEffect16, useRef as useRef8, useState as useState12 } from "react";
|
|
3907
|
+
import { Box as Box26, Text as Text28 } from "ink";
|
|
3790
3908
|
|
|
3791
3909
|
// src/stores/cleanup-store.ts
|
|
3792
3910
|
import { create as create10 } from "zustand";
|
|
@@ -3906,19 +4024,19 @@ var useCleanupStore = create10((set, get) => ({
|
|
|
3906
4024
|
}));
|
|
3907
4025
|
|
|
3908
4026
|
// src/views/smart-cleanup.tsx
|
|
3909
|
-
import { jsx as
|
|
4027
|
+
import { jsx as jsx29, jsxs as jsxs27 } from "react/jsx-runtime";
|
|
3910
4028
|
function SmartCleanupView() {
|
|
3911
4029
|
const { summary, selected, loading, error, analyze, toggleSelect, selectAll } = useCleanupStore();
|
|
3912
|
-
const [cursor, setCursor] =
|
|
3913
|
-
const [confirmClean, setConfirmClean] =
|
|
3914
|
-
const [confirmForce, setConfirmForce] =
|
|
3915
|
-
const [failedNames, setFailedNames] =
|
|
4030
|
+
const [cursor, setCursor] = useState12(0);
|
|
4031
|
+
const [confirmClean, setConfirmClean] = useState12(false);
|
|
4032
|
+
const [confirmForce, setConfirmForce] = useState12(false);
|
|
4033
|
+
const [failedNames, setFailedNames] = useState12([]);
|
|
3916
4034
|
const stream = useBrewStream();
|
|
3917
|
-
const hasRefreshed =
|
|
3918
|
-
|
|
4035
|
+
const hasRefreshed = useRef8(false);
|
|
4036
|
+
useEffect16(() => {
|
|
3919
4037
|
analyze();
|
|
3920
4038
|
}, []);
|
|
3921
|
-
|
|
4039
|
+
useEffect16(() => {
|
|
3922
4040
|
if (!stream.isRunning && !stream.error && stream.lines.length > 0 && !hasRefreshed.current) {
|
|
3923
4041
|
hasRefreshed.current = true;
|
|
3924
4042
|
void analyze();
|
|
@@ -3926,17 +4044,17 @@ function SmartCleanupView() {
|
|
|
3926
4044
|
}, [stream.isRunning, stream.error]);
|
|
3927
4045
|
const candidates = summary?.candidates ?? [];
|
|
3928
4046
|
const isDependencyError = stream.error != null && stream.lines.some((l) => l.includes("Refusing to uninstall") || l.includes("required by"));
|
|
3929
|
-
|
|
4047
|
+
useViewInput((input, key) => {
|
|
3930
4048
|
if (stream.isRunning) {
|
|
3931
4049
|
if (key.escape) stream.cancel();
|
|
3932
4050
|
return;
|
|
3933
4051
|
}
|
|
3934
4052
|
if (confirmClean || confirmForce) return;
|
|
3935
|
-
if (input === "F" && isDependencyError && failedNames.length > 0) {
|
|
4053
|
+
if ((input === "F" || input === "3") && isDependencyError && failedNames.length > 0) {
|
|
3936
4054
|
setConfirmForce(true);
|
|
3937
4055
|
return;
|
|
3938
4056
|
}
|
|
3939
|
-
if (input === "r") {
|
|
4057
|
+
if (input === "r" || input === "4") {
|
|
3940
4058
|
stream.clear();
|
|
3941
4059
|
setFailedNames([]);
|
|
3942
4060
|
void analyze();
|
|
@@ -3946,37 +4064,37 @@ function SmartCleanupView() {
|
|
|
3946
4064
|
toggleSelect(candidates[cursor].name);
|
|
3947
4065
|
return;
|
|
3948
4066
|
}
|
|
3949
|
-
if (input === "a") {
|
|
4067
|
+
if (input === "a" || input === "1") {
|
|
3950
4068
|
selectAll();
|
|
3951
4069
|
return;
|
|
3952
4070
|
}
|
|
3953
|
-
if (input === "c" && selected.size > 0) {
|
|
4071
|
+
if ((input === "c" || input === "2") && selected.size > 0) {
|
|
3954
4072
|
setConfirmClean(true);
|
|
3955
4073
|
return;
|
|
3956
4074
|
}
|
|
3957
4075
|
if (input === "j" || key.downArrow) setCursor((c) => Math.min(c + 1, Math.max(0, candidates.length - 1)));
|
|
3958
4076
|
else if (input === "k" || key.upArrow) setCursor((c) => Math.max(c - 1, 0));
|
|
3959
4077
|
});
|
|
3960
|
-
if (loading) return /* @__PURE__ */
|
|
3961
|
-
if (error) return /* @__PURE__ */
|
|
4078
|
+
if (loading) return /* @__PURE__ */ jsx29(Loading, { message: t("loading_cleanup") });
|
|
4079
|
+
if (error) return /* @__PURE__ */ jsx29(ErrorMessage, { message: error });
|
|
3962
4080
|
if (stream.isRunning || stream.lines.length > 0) {
|
|
3963
4081
|
return /* @__PURE__ */ jsxs27(Box26, { flexDirection: "column", children: [
|
|
3964
|
-
/* @__PURE__ */
|
|
3965
|
-
stream.isRunning && /* @__PURE__ */ jsxs27(
|
|
4082
|
+
/* @__PURE__ */ jsx29(ProgressLog, { lines: stream.lines, isRunning: stream.isRunning, title: t("cleanup_cleaning") }),
|
|
4083
|
+
stream.isRunning && /* @__PURE__ */ jsxs27(Text28, { color: COLORS.muted, children: [
|
|
3966
4084
|
"esc:",
|
|
3967
4085
|
t("hint_cancel")
|
|
3968
4086
|
] }),
|
|
3969
|
-
!stream.isRunning && !stream.error && /* @__PURE__ */
|
|
4087
|
+
!stream.isRunning && !stream.error && /* @__PURE__ */ jsx29(ResultBanner, { status: "success", message: `\u2714 ${t("cleanup_complete")}` }),
|
|
3970
4088
|
!stream.isRunning && stream.error && /* @__PURE__ */ jsxs27(Box26, { flexDirection: "column", gap: SPACING.xs, children: [
|
|
3971
|
-
/* @__PURE__ */
|
|
3972
|
-
isDependencyError && failedNames.length > 0 && /* @__PURE__ */ jsxs27(
|
|
4089
|
+
/* @__PURE__ */ jsx29(ResultBanner, { status: "error", message: `\u2718 ${t("cleanup_depError")}` }),
|
|
4090
|
+
isDependencyError && failedNames.length > 0 && /* @__PURE__ */ jsxs27(Text28, { color: COLORS.warning, children: [
|
|
3973
4091
|
"F:",
|
|
3974
4092
|
t("hint_force"),
|
|
3975
4093
|
" r:",
|
|
3976
4094
|
t("hint_refresh")
|
|
3977
4095
|
] })
|
|
3978
4096
|
] }),
|
|
3979
|
-
confirmForce && /* @__PURE__ */
|
|
4097
|
+
confirmForce && /* @__PURE__ */ jsx29(Box26, { marginY: SPACING.xs, children: /* @__PURE__ */ jsx29(
|
|
3980
4098
|
ConfirmDialog,
|
|
3981
4099
|
{
|
|
3982
4100
|
message: t("cleanup_confirmForce", { count: failedNames.length }),
|
|
@@ -3992,15 +4110,15 @@ function SmartCleanupView() {
|
|
|
3992
4110
|
] });
|
|
3993
4111
|
}
|
|
3994
4112
|
return /* @__PURE__ */ jsxs27(Box26, { flexDirection: "column", children: [
|
|
3995
|
-
/* @__PURE__ */
|
|
4113
|
+
/* @__PURE__ */ jsx29(SectionHeader, { emoji: "\u{1F9F9}", title: t("cleanup_title"), gradient: GRADIENTS.emerald }),
|
|
3996
4114
|
summary && /* @__PURE__ */ jsxs27(Box26, { gap: SPACING.xs, marginY: SPACING.xs, children: [
|
|
3997
|
-
/* @__PURE__ */
|
|
3998
|
-
/* @__PURE__ */
|
|
3999
|
-
/* @__PURE__ */
|
|
4115
|
+
/* @__PURE__ */ jsx29(StatCard, { label: t("cleanup_orphans"), value: candidates.length, color: candidates.length > 0 ? COLORS.warning : COLORS.success }),
|
|
4116
|
+
/* @__PURE__ */ jsx29(StatCard, { label: t("cleanup_reclaimable"), value: summary.totalReclaimableFormatted, color: COLORS.sky }),
|
|
4117
|
+
/* @__PURE__ */ jsx29(StatCard, { label: t("cleanup_selected"), value: selected.size, color: selected.size > 0 ? COLORS.success : COLORS.muted })
|
|
4000
4118
|
] }),
|
|
4001
4119
|
confirmClean && /* @__PURE__ */ jsxs27(Box26, { flexDirection: "column", marginY: SPACING.xs, gap: SPACING.xs, children: [
|
|
4002
|
-
/* @__PURE__ */
|
|
4003
|
-
/* @__PURE__ */
|
|
4120
|
+
/* @__PURE__ */ jsx29(Box26, { borderStyle: "round", borderColor: COLORS.warning, paddingX: SPACING.sm, paddingY: SPACING.none, children: /* @__PURE__ */ jsx29(Text28, { color: COLORS.warning, children: t("cleanup_warning_system_tools") }) }),
|
|
4121
|
+
/* @__PURE__ */ jsx29(
|
|
4004
4122
|
ConfirmDialog,
|
|
4005
4123
|
{
|
|
4006
4124
|
message: t("cleanup_confirmUninstall", { count: selected.size }),
|
|
@@ -4015,23 +4133,23 @@ function SmartCleanupView() {
|
|
|
4015
4133
|
}
|
|
4016
4134
|
)
|
|
4017
4135
|
] }),
|
|
4018
|
-
candidates.length === 0 && !confirmClean && /* @__PURE__ */
|
|
4136
|
+
candidates.length === 0 && !confirmClean && /* @__PURE__ */ jsx29(ResultBanner, { status: "success", message: `\u2714 ${t("cleanup_systemClean")}` }),
|
|
4019
4137
|
candidates.length > 0 && !confirmClean && /* @__PURE__ */ jsxs27(Box26, { flexDirection: "column", children: [
|
|
4020
4138
|
candidates.map((c, i) => {
|
|
4021
4139
|
const isCurrent = i === cursor;
|
|
4022
4140
|
const isSelected = selected.has(c.name);
|
|
4023
4141
|
return /* @__PURE__ */ jsxs27(SelectableRow, { isCurrent, children: [
|
|
4024
|
-
/* @__PURE__ */
|
|
4025
|
-
/* @__PURE__ */
|
|
4026
|
-
/* @__PURE__ */
|
|
4027
|
-
/* @__PURE__ */ jsxs27(
|
|
4142
|
+
/* @__PURE__ */ jsx29(Text28, { color: isSelected ? COLORS.success : COLORS.muted, children: isSelected ? "\u2611" : "\u2610" }),
|
|
4143
|
+
/* @__PURE__ */ jsx29(Text28, { bold: isCurrent, inverse: isCurrent, color: isCurrent ? COLORS.text : COLORS.muted, children: c.name }),
|
|
4144
|
+
/* @__PURE__ */ jsx29(Text28, { color: COLORS.warning, children: c.diskUsageFormatted }),
|
|
4145
|
+
/* @__PURE__ */ jsxs27(Text28, { color: COLORS.textSecondary, children: [
|
|
4028
4146
|
"[",
|
|
4029
4147
|
c.reason,
|
|
4030
4148
|
"]"
|
|
4031
4149
|
] })
|
|
4032
4150
|
] }, c.name);
|
|
4033
4151
|
}),
|
|
4034
|
-
/* @__PURE__ */
|
|
4152
|
+
/* @__PURE__ */ jsx29(Box26, { marginTop: SPACING.xs, children: /* @__PURE__ */ jsxs27(Text28, { color: COLORS.text, bold: true, children: [
|
|
4035
4153
|
cursor + 1,
|
|
4036
4154
|
"/",
|
|
4037
4155
|
candidates.length
|
|
@@ -4041,8 +4159,8 @@ function SmartCleanupView() {
|
|
|
4041
4159
|
}
|
|
4042
4160
|
|
|
4043
4161
|
// src/views/history.tsx
|
|
4044
|
-
import { useEffect as
|
|
4045
|
-
import { Box as Box27, Text as
|
|
4162
|
+
import { useEffect as useEffect17, useState as useState13, useMemo as useMemo5 } from "react";
|
|
4163
|
+
import { Box as Box27, Text as Text29, useStdout as useStdout6 } from "ink";
|
|
4046
4164
|
|
|
4047
4165
|
// src/stores/history-store.ts
|
|
4048
4166
|
import { create as create11 } from "zustand";
|
|
@@ -4078,7 +4196,7 @@ var useHistoryStore = create11((set) => ({
|
|
|
4078
4196
|
}));
|
|
4079
4197
|
|
|
4080
4198
|
// src/views/history.tsx
|
|
4081
|
-
import { jsx as
|
|
4199
|
+
import { jsx as jsx30, jsxs as jsxs28 } from "react/jsx-runtime";
|
|
4082
4200
|
var ACTION_ICONS = {
|
|
4083
4201
|
install: { icon: "+", color: COLORS.success },
|
|
4084
4202
|
uninstall: { icon: "-", color: COLORS.error },
|
|
@@ -4094,21 +4212,21 @@ var ACTION_LABEL_KEYS = {
|
|
|
4094
4212
|
var FILTERS = ["all", "install", "uninstall", "upgrade", "upgrade-all"];
|
|
4095
4213
|
function HistoryView() {
|
|
4096
4214
|
const { entries, loading, error, fetchHistory, clearHistory: clearHistory2 } = useHistoryStore();
|
|
4097
|
-
const [cursor, setCursor] =
|
|
4098
|
-
const [filter, setFilter] =
|
|
4099
|
-
const [searchQuery, setSearchQuery] =
|
|
4100
|
-
const [isSearching, setIsSearching] =
|
|
4101
|
-
const [confirmClear, setConfirmClear] =
|
|
4102
|
-
const [confirmReplay, setConfirmReplay] =
|
|
4215
|
+
const [cursor, setCursor] = useState13(0);
|
|
4216
|
+
const [filter, setFilter] = useState13("all");
|
|
4217
|
+
const [searchQuery, setSearchQuery] = useState13("");
|
|
4218
|
+
const [isSearching, setIsSearching] = useState13(false);
|
|
4219
|
+
const [confirmClear, setConfirmClear] = useState13(false);
|
|
4220
|
+
const [confirmReplay, setConfirmReplay] = useState13(null);
|
|
4103
4221
|
const stream = useBrewStream();
|
|
4104
4222
|
const debouncedQuery = useDebounce(searchQuery, 200);
|
|
4105
4223
|
const { openModal, closeModal } = useModalStore();
|
|
4106
|
-
const { stdout } =
|
|
4224
|
+
const { stdout } = useStdout6();
|
|
4107
4225
|
const MAX_VISIBLE_ROWS = Math.max(5, (stdout?.rows ?? 24) - 8);
|
|
4108
|
-
|
|
4226
|
+
useEffect17(() => {
|
|
4109
4227
|
fetchHistory();
|
|
4110
4228
|
}, []);
|
|
4111
|
-
|
|
4229
|
+
useEffect17(() => {
|
|
4112
4230
|
if (isSearching) {
|
|
4113
4231
|
openModal();
|
|
4114
4232
|
return () => {
|
|
@@ -4128,7 +4246,7 @@ function HistoryView() {
|
|
|
4128
4246
|
}
|
|
4129
4247
|
return result;
|
|
4130
4248
|
}, [entries, filter, debouncedQuery]);
|
|
4131
|
-
|
|
4249
|
+
useViewInput((input, key) => {
|
|
4132
4250
|
if (confirmClear || confirmReplay || stream.isRunning) return;
|
|
4133
4251
|
if (isSearching) {
|
|
4134
4252
|
if (key.escape) {
|
|
@@ -4141,13 +4259,13 @@ function HistoryView() {
|
|
|
4141
4259
|
setIsSearching(true);
|
|
4142
4260
|
return;
|
|
4143
4261
|
}
|
|
4144
|
-
if (input === "f") {
|
|
4262
|
+
if (input === "f" || input === "1") {
|
|
4145
4263
|
const idx = FILTERS.indexOf(filter);
|
|
4146
4264
|
setFilter(FILTERS[(idx + 1) % FILTERS.length]);
|
|
4147
4265
|
setCursor(0);
|
|
4148
4266
|
return;
|
|
4149
4267
|
}
|
|
4150
|
-
if (input === "c" && entries.length > 0) {
|
|
4268
|
+
if ((input === "c" || input === "2") && entries.length > 0) {
|
|
4151
4269
|
setConfirmClear(true);
|
|
4152
4270
|
return;
|
|
4153
4271
|
}
|
|
@@ -4158,17 +4276,17 @@ function HistoryView() {
|
|
|
4158
4276
|
if (input === "j" || key.downArrow) setCursor((c) => Math.min(c + 1, Math.max(0, filtered.length - 1)));
|
|
4159
4277
|
else if (input === "k" || key.upArrow) setCursor((c) => Math.max(c - 1, 0));
|
|
4160
4278
|
});
|
|
4161
|
-
if (loading) return /* @__PURE__ */
|
|
4162
|
-
if (error) return /* @__PURE__ */
|
|
4279
|
+
if (loading) return /* @__PURE__ */ jsx30(Loading, { message: t("loading_history") });
|
|
4280
|
+
if (error) return /* @__PURE__ */ jsx30(ErrorMessage, { message: error });
|
|
4163
4281
|
const start = Math.max(0, cursor - Math.floor(MAX_VISIBLE_ROWS / 2));
|
|
4164
4282
|
const visible = filtered.slice(start, start + MAX_VISIBLE_ROWS);
|
|
4165
4283
|
return /* @__PURE__ */ jsxs28(Box27, { flexDirection: "column", children: [
|
|
4166
4284
|
/* @__PURE__ */ jsxs28(Box27, { gap: SPACING.sm, marginBottom: SPACING.xs, children: [
|
|
4167
|
-
/* @__PURE__ */
|
|
4168
|
-
/* @__PURE__ */
|
|
4285
|
+
/* @__PURE__ */ jsx30(SectionHeader, { emoji: "\u{1F4DC}", title: t("history_title", { count: filtered.length }), gradient: GRADIENTS.gold }),
|
|
4286
|
+
/* @__PURE__ */ jsx30(Text29, { color: filter === "all" ? COLORS.text : COLORS.gold, children: t("history_filterLabel", { filter }) })
|
|
4169
4287
|
] }),
|
|
4170
|
-
isSearching && /* @__PURE__ */
|
|
4171
|
-
confirmClear && /* @__PURE__ */
|
|
4288
|
+
isSearching && /* @__PURE__ */ jsx30(Box27, { marginBottom: SPACING.xs, children: /* @__PURE__ */ jsx30(SearchInput, { defaultValue: searchQuery, onChange: setSearchQuery, placeholder: t("history_searchPlaceholder"), isActive: true }) }),
|
|
4289
|
+
confirmClear && /* @__PURE__ */ jsx30(
|
|
4172
4290
|
ConfirmDialog,
|
|
4173
4291
|
{
|
|
4174
4292
|
message: t("history_confirmClear", { count: entries.length }),
|
|
@@ -4179,7 +4297,7 @@ function HistoryView() {
|
|
|
4179
4297
|
onCancel: () => setConfirmClear(false)
|
|
4180
4298
|
}
|
|
4181
4299
|
),
|
|
4182
|
-
confirmReplay && /* @__PURE__ */
|
|
4300
|
+
confirmReplay && /* @__PURE__ */ jsx30(
|
|
4183
4301
|
ConfirmDialog,
|
|
4184
4302
|
{
|
|
4185
4303
|
message: confirmReplay.action === "upgrade-all" ? t("history_replayAll") + "\n" + t("upgrade_all_warning") : t("history_confirmReplay", { action: t(ACTION_LABEL_KEYS[confirmReplay.action]), name: confirmReplay.packageName ?? "" }),
|
|
@@ -4207,10 +4325,10 @@ function HistoryView() {
|
|
|
4207
4325
|
onCancel: () => setConfirmReplay(null)
|
|
4208
4326
|
}
|
|
4209
4327
|
),
|
|
4210
|
-
(stream.isRunning || stream.lines.length > 0) && /* @__PURE__ */
|
|
4211
|
-
filtered.length === 0 && !confirmClear && /* @__PURE__ */
|
|
4328
|
+
(stream.isRunning || stream.lines.length > 0) && /* @__PURE__ */ jsx30(Box27, { marginY: SPACING.xs, children: /* @__PURE__ */ jsx30(ProgressLog, { lines: stream.lines, isRunning: stream.isRunning, title: t("hint_replay") }) }),
|
|
4329
|
+
filtered.length === 0 && !confirmClear && /* @__PURE__ */ jsx30(Text29, { color: COLORS.textSecondary, italic: true, children: filter !== "all" ? t("history_noEntriesFor", { filter }) : t("history_noEntries") }),
|
|
4212
4330
|
filtered.length > 0 && !confirmClear && /* @__PURE__ */ jsxs28(Box27, { flexDirection: "column", children: [
|
|
4213
|
-
start > 0 && /* @__PURE__ */ jsxs28(
|
|
4331
|
+
start > 0 && /* @__PURE__ */ jsxs28(Text29, { color: COLORS.textSecondary, dimColor: true, children: [
|
|
4214
4332
|
" ",
|
|
4215
4333
|
t("scroll_moreAbove", { count: start })
|
|
4216
4334
|
] }),
|
|
@@ -4220,18 +4338,18 @@ function HistoryView() {
|
|
|
4220
4338
|
const { icon, color } = ACTION_ICONS[entry.action];
|
|
4221
4339
|
const ts = new Date(entry.timestamp).getTime() / 1e3;
|
|
4222
4340
|
return /* @__PURE__ */ jsxs28(SelectableRow, { isCurrent, children: [
|
|
4223
|
-
/* @__PURE__ */
|
|
4224
|
-
/* @__PURE__ */
|
|
4225
|
-
/* @__PURE__ */
|
|
4226
|
-
entry.success ? /* @__PURE__ */
|
|
4227
|
-
/* @__PURE__ */
|
|
4341
|
+
/* @__PURE__ */ jsx30(Text29, { color, bold: true, children: icon }),
|
|
4342
|
+
/* @__PURE__ */ jsx30(Text29, { bold: isCurrent, inverse: isCurrent, color: isCurrent ? COLORS.text : COLORS.muted, children: t(ACTION_LABEL_KEYS[entry.action]).padEnd(12) }),
|
|
4343
|
+
/* @__PURE__ */ jsx30(Text29, { color: COLORS.text, children: entry.packageName ?? t("history_all") }),
|
|
4344
|
+
entry.success ? /* @__PURE__ */ jsx30(StatusBadge, { label: t("badge_ok"), variant: "success" }) : /* @__PURE__ */ jsx30(StatusBadge, { label: t("badge_fail"), variant: "error" }),
|
|
4345
|
+
/* @__PURE__ */ jsx30(Text29, { color: COLORS.muted, children: formatRelativeTime(ts) })
|
|
4228
4346
|
] }, entry.id);
|
|
4229
4347
|
}),
|
|
4230
|
-
start + MAX_VISIBLE_ROWS < filtered.length && /* @__PURE__ */ jsxs28(
|
|
4348
|
+
start + MAX_VISIBLE_ROWS < filtered.length && /* @__PURE__ */ jsxs28(Text29, { color: COLORS.textSecondary, dimColor: true, children: [
|
|
4231
4349
|
" ",
|
|
4232
4350
|
t("scroll_moreBelow", { count: filtered.length - start - MAX_VISIBLE_ROWS })
|
|
4233
4351
|
] }),
|
|
4234
|
-
/* @__PURE__ */
|
|
4352
|
+
/* @__PURE__ */ jsx30(Box27, { marginTop: SPACING.xs, children: /* @__PURE__ */ jsxs28(Text29, { color: COLORS.text, bold: true, children: [
|
|
4235
4353
|
cursor + 1,
|
|
4236
4354
|
"/",
|
|
4237
4355
|
filtered.length
|
|
@@ -4241,9 +4359,9 @@ function HistoryView() {
|
|
|
4241
4359
|
}
|
|
4242
4360
|
|
|
4243
4361
|
// src/views/security-audit.tsx
|
|
4244
|
-
import { useEffect as
|
|
4245
|
-
import { Box as Box28, Text as
|
|
4246
|
-
import { jsx as
|
|
4362
|
+
import { useEffect as useEffect18, useState as useState14 } from "react";
|
|
4363
|
+
import { Box as Box28, Text as Text30 } from "ink";
|
|
4364
|
+
import { jsx as jsx31, jsxs as jsxs29 } from "react/jsx-runtime";
|
|
4247
4365
|
var SEVERITY_COLORS = {
|
|
4248
4366
|
CRITICAL: COLORS.error,
|
|
4249
4367
|
HIGH: COLORS.error,
|
|
@@ -4264,17 +4382,17 @@ function isNetworkError(msg) {
|
|
|
4264
4382
|
function SecurityAuditView() {
|
|
4265
4383
|
const { summary, loading, error, scan, cachedAt } = useSecurityStore();
|
|
4266
4384
|
const navigate = useNavigationStore((s) => s.navigate);
|
|
4267
|
-
const [cursor, setCursor] =
|
|
4268
|
-
const [expandedPkg, setExpandedPkg] =
|
|
4269
|
-
const [confirmUpgrade, setConfirmUpgrade] =
|
|
4385
|
+
const [cursor, setCursor] = useState14(0);
|
|
4386
|
+
const [expandedPkg, setExpandedPkg] = useState14(null);
|
|
4387
|
+
const [confirmUpgrade, setConfirmUpgrade] = useState14(null);
|
|
4270
4388
|
const stream = useBrewStream();
|
|
4271
|
-
|
|
4389
|
+
useEffect18(() => {
|
|
4272
4390
|
scan();
|
|
4273
4391
|
}, []);
|
|
4274
4392
|
const results = summary?.results ?? [];
|
|
4275
|
-
|
|
4393
|
+
useViewInput((input, key) => {
|
|
4276
4394
|
if (confirmUpgrade || stream.isRunning) return;
|
|
4277
|
-
if (input === "r") {
|
|
4395
|
+
if (input === "r" || input === "1") {
|
|
4278
4396
|
void scan(true);
|
|
4279
4397
|
return;
|
|
4280
4398
|
}
|
|
@@ -4282,7 +4400,7 @@ function SecurityAuditView() {
|
|
|
4282
4400
|
navigate("rollback");
|
|
4283
4401
|
return;
|
|
4284
4402
|
}
|
|
4285
|
-
if (input === "u" && results[cursor]) {
|
|
4403
|
+
if ((input === "u" || input === "2") && results[cursor]) {
|
|
4286
4404
|
setConfirmUpgrade(results[cursor].packageName);
|
|
4287
4405
|
return;
|
|
4288
4406
|
}
|
|
@@ -4292,17 +4410,17 @@ function SecurityAuditView() {
|
|
|
4292
4410
|
setExpandedPkg(expandedPkg === results[cursor].packageName ? null : results[cursor].packageName);
|
|
4293
4411
|
}
|
|
4294
4412
|
});
|
|
4295
|
-
if (loading) return /* @__PURE__ */
|
|
4413
|
+
if (loading) return /* @__PURE__ */ jsx31(Loading, { message: t("loading_security") });
|
|
4296
4414
|
if (error) {
|
|
4297
4415
|
const displayError = isNetworkError(error) ? t("security_networkError") : error;
|
|
4298
|
-
return /* @__PURE__ */
|
|
4416
|
+
return /* @__PURE__ */ jsx31(ErrorMessage, { message: displayError });
|
|
4299
4417
|
}
|
|
4300
4418
|
const cacheAge = cachedAt ? formatRelativeTime(cachedAt / 1e3) : null;
|
|
4301
4419
|
return /* @__PURE__ */ jsxs29(Box28, { flexDirection: "column", children: [
|
|
4302
|
-
/* @__PURE__ */
|
|
4420
|
+
/* @__PURE__ */ jsx31(SectionHeader, { emoji: "\u{1F6E1}\uFE0F", title: t("security_title"), gradient: GRADIENTS.ocean }),
|
|
4303
4421
|
summary && /* @__PURE__ */ jsxs29(Box28, { gap: SPACING.xs, marginY: SPACING.xs, children: [
|
|
4304
|
-
/* @__PURE__ */
|
|
4305
|
-
/* @__PURE__ */
|
|
4422
|
+
/* @__PURE__ */ jsx31(StatCard, { label: t("security_scanned"), value: summary.totalPackages, color: COLORS.info }),
|
|
4423
|
+
/* @__PURE__ */ jsx31(
|
|
4306
4424
|
StatCard,
|
|
4307
4425
|
{
|
|
4308
4426
|
label: t("security_vulnerable"),
|
|
@@ -4310,14 +4428,14 @@ function SecurityAuditView() {
|
|
|
4310
4428
|
color: summary.vulnerablePackages > 0 ? COLORS.error : COLORS.success
|
|
4311
4429
|
}
|
|
4312
4430
|
),
|
|
4313
|
-
summary.criticalCount > 0 && /* @__PURE__ */
|
|
4314
|
-
summary.highCount > 0 && /* @__PURE__ */
|
|
4315
|
-
summary.mediumCount > 0 && /* @__PURE__ */
|
|
4431
|
+
summary.criticalCount > 0 && /* @__PURE__ */ jsx31(StatCard, { label: t("security_critical"), value: summary.criticalCount, color: COLORS.error }),
|
|
4432
|
+
summary.highCount > 0 && /* @__PURE__ */ jsx31(StatCard, { label: t("security_high"), value: summary.highCount, color: COLORS.error }),
|
|
4433
|
+
summary.mediumCount > 0 && /* @__PURE__ */ jsx31(StatCard, { label: t("security_medium"), value: summary.mediumCount, color: COLORS.warning })
|
|
4316
4434
|
] }),
|
|
4317
|
-
cacheAge && /* @__PURE__ */
|
|
4318
|
-
summary && /* @__PURE__ */
|
|
4319
|
-
results.length === 0 && summary && /* @__PURE__ */
|
|
4320
|
-
confirmUpgrade && /* @__PURE__ */
|
|
4435
|
+
cacheAge && /* @__PURE__ */ jsx31(Text30, { color: COLORS.muted, children: t("security_cachedResults", { time: cacheAge }) }),
|
|
4436
|
+
summary && /* @__PURE__ */ jsx31(Box28, { marginTop: SPACING.xs, children: /* @__PURE__ */ jsx31(Text30, { color: COLORS.textSecondary, italic: true, children: t("security_coverage_warning") }) }),
|
|
4437
|
+
results.length === 0 && summary && /* @__PURE__ */ jsx31(Box28, { marginTop: SPACING.xs, children: /* @__PURE__ */ jsx31(ResultBanner, { status: "success", message: `\u2714 ${t("security_noVulns")}` }) }),
|
|
4438
|
+
confirmUpgrade && /* @__PURE__ */ jsx31(Box28, { marginY: SPACING.xs, children: /* @__PURE__ */ jsx31(
|
|
4321
4439
|
ConfirmDialog,
|
|
4322
4440
|
{
|
|
4323
4441
|
message: t("security_confirmUpgrade", { name: confirmUpgrade }),
|
|
@@ -4330,51 +4448,51 @@ function SecurityAuditView() {
|
|
|
4330
4448
|
onCancel: () => setConfirmUpgrade(null)
|
|
4331
4449
|
}
|
|
4332
4450
|
) }),
|
|
4333
|
-
(stream.isRunning || stream.lines.length > 0) && /* @__PURE__ */
|
|
4451
|
+
(stream.isRunning || stream.lines.length > 0) && /* @__PURE__ */ jsx31(Box28, { marginY: SPACING.xs, children: /* @__PURE__ */ jsx31(ProgressLog, { lines: stream.lines, isRunning: stream.isRunning, title: t("hint_upgrade") }) }),
|
|
4334
4452
|
results.length > 0 && /* @__PURE__ */ jsxs29(Box28, { flexDirection: "column", marginTop: SPACING.xs, children: [
|
|
4335
4453
|
results.map((pkg, i) => {
|
|
4336
4454
|
const isCurrent = i === cursor;
|
|
4337
4455
|
const isExpanded = expandedPkg === pkg.packageName;
|
|
4338
4456
|
return /* @__PURE__ */ jsxs29(Box28, { flexDirection: "column", children: [
|
|
4339
4457
|
/* @__PURE__ */ jsxs29(SelectableRow, { isCurrent, children: [
|
|
4340
|
-
/* @__PURE__ */
|
|
4341
|
-
/* @__PURE__ */
|
|
4342
|
-
/* @__PURE__ */
|
|
4343
|
-
/* @__PURE__ */
|
|
4344
|
-
pkg.vulnerabilities.some((v) => v.fixedVersion) && /* @__PURE__ */ jsxs29(
|
|
4458
|
+
/* @__PURE__ */ jsx31(StatusBadge, { label: pkg.maxSeverity, variant: SEVERITY_BADGE[pkg.maxSeverity] }),
|
|
4459
|
+
/* @__PURE__ */ jsx31(Text30, { bold: isCurrent, inverse: isCurrent, color: isCurrent ? COLORS.text : COLORS.muted, children: pkg.packageName }),
|
|
4460
|
+
/* @__PURE__ */ jsx31(Text30, { color: COLORS.muted, children: pkg.installedVersion }),
|
|
4461
|
+
/* @__PURE__ */ jsx31(Text30, { color: COLORS.muted, children: tp("plural_vulns", pkg.vulnerabilities.length) }),
|
|
4462
|
+
pkg.vulnerabilities.some((v) => v.fixedVersion) && /* @__PURE__ */ jsxs29(Text30, { color: COLORS.textSecondary, children: [
|
|
4345
4463
|
"[R:",
|
|
4346
4464
|
t("hint_rollback"),
|
|
4347
4465
|
"]"
|
|
4348
4466
|
] }),
|
|
4349
|
-
/* @__PURE__ */
|
|
4467
|
+
/* @__PURE__ */ jsx31(Text30, { color: COLORS.muted, children: isExpanded ? "\u25BC" : "\u25B6" })
|
|
4350
4468
|
] }),
|
|
4351
|
-
isExpanded && /* @__PURE__ */
|
|
4469
|
+
isExpanded && /* @__PURE__ */ jsx31(Box28, { flexDirection: "column", paddingLeft: SPACING.lg, marginBottom: SPACING.xs, children: pkg.vulnerabilities.map((vuln) => /* @__PURE__ */ jsxs29(Box28, { flexDirection: "column", marginBottom: SPACING.xs, children: [
|
|
4352
4470
|
/* @__PURE__ */ jsxs29(Box28, { gap: SPACING.xs, children: [
|
|
4353
|
-
/* @__PURE__ */
|
|
4354
|
-
/* @__PURE__ */ jsxs29(
|
|
4471
|
+
/* @__PURE__ */ jsx31(Text30, { color: SEVERITY_COLORS[vuln.severity], bold: true, children: vuln.id }),
|
|
4472
|
+
/* @__PURE__ */ jsxs29(Text30, { color: COLORS.muted, children: [
|
|
4355
4473
|
"[",
|
|
4356
4474
|
vuln.severity,
|
|
4357
4475
|
"]"
|
|
4358
4476
|
] })
|
|
4359
4477
|
] }),
|
|
4360
|
-
/* @__PURE__ */
|
|
4361
|
-
vuln.fixedVersion && /* @__PURE__ */
|
|
4478
|
+
/* @__PURE__ */ jsx31(Text30, { color: COLORS.muted, wrap: "wrap", children: vuln.summary }),
|
|
4479
|
+
vuln.fixedVersion && /* @__PURE__ */ jsx31(Text30, { color: COLORS.success, children: t("security_fixedIn", { version: vuln.fixedVersion }) })
|
|
4362
4480
|
] }, vuln.id)) })
|
|
4363
4481
|
] }, pkg.packageName);
|
|
4364
4482
|
}),
|
|
4365
|
-
/* @__PURE__ */
|
|
4483
|
+
/* @__PURE__ */ jsx31(Box28, { marginTop: SPACING.xs, children: /* @__PURE__ */ jsxs29(Text30, { color: COLORS.text, bold: true, children: [
|
|
4366
4484
|
cursor + 1,
|
|
4367
4485
|
"/",
|
|
4368
4486
|
results.length
|
|
4369
4487
|
] }) }),
|
|
4370
|
-
/* @__PURE__ */
|
|
4488
|
+
/* @__PURE__ */ jsx31(Box28, { marginTop: SPACING.xs, children: /* @__PURE__ */ jsx31(Text30, { color: COLORS.textSecondary, children: t("security_rollback_hint") }) })
|
|
4371
4489
|
] })
|
|
4372
4490
|
] });
|
|
4373
4491
|
}
|
|
4374
4492
|
|
|
4375
4493
|
// src/views/account.tsx
|
|
4376
|
-
import { useState as
|
|
4377
|
-
import { Box as Box29, Text as
|
|
4494
|
+
import { useState as useState15 } from "react";
|
|
4495
|
+
import { Box as Box29, Text as Text31 } from "ink";
|
|
4378
4496
|
import { TextInput as TextInput5 } from "@inkjs/ui";
|
|
4379
4497
|
|
|
4380
4498
|
// src/lib/license/promo.ts
|
|
@@ -4452,17 +4570,17 @@ async function redeemPromoCode(code) {
|
|
|
4452
4570
|
}
|
|
4453
4571
|
|
|
4454
4572
|
// src/views/account.tsx
|
|
4455
|
-
import { Fragment as Fragment5, jsx as
|
|
4573
|
+
import { Fragment as Fragment5, jsx as jsx32, jsxs as jsxs30 } from "react/jsx-runtime";
|
|
4456
4574
|
function AccountView() {
|
|
4457
4575
|
const { status, license, deactivate: deactivate2, revalidate: revalidate2, degradation } = useLicenseStore();
|
|
4458
|
-
const [confirmDeactivate, setConfirmDeactivate] =
|
|
4459
|
-
const [deactivating, setDeactivating] =
|
|
4460
|
-
const [deactivateError, setDeactivateError] =
|
|
4461
|
-
const [promoMode, setPromoMode] =
|
|
4462
|
-
const [promoLoading, setPromoLoading] =
|
|
4463
|
-
const [promoResult, setPromoResult] =
|
|
4464
|
-
const [revalidating, setRevalidating] =
|
|
4465
|
-
|
|
4576
|
+
const [confirmDeactivate, setConfirmDeactivate] = useState15(false);
|
|
4577
|
+
const [deactivating, setDeactivating] = useState15(false);
|
|
4578
|
+
const [deactivateError, setDeactivateError] = useState15(null);
|
|
4579
|
+
const [promoMode, setPromoMode] = useState15(false);
|
|
4580
|
+
const [promoLoading, setPromoLoading] = useState15(false);
|
|
4581
|
+
const [promoResult, setPromoResult] = useState15(null);
|
|
4582
|
+
const [revalidating, setRevalidating] = useState15(false);
|
|
4583
|
+
useViewInput((input, key) => {
|
|
4466
4584
|
if (confirmDeactivate || deactivating || promoMode || revalidating) {
|
|
4467
4585
|
if (key.escape && promoMode) {
|
|
4468
4586
|
setPromoMode(false);
|
|
@@ -4470,10 +4588,10 @@ function AccountView() {
|
|
|
4470
4588
|
}
|
|
4471
4589
|
return;
|
|
4472
4590
|
}
|
|
4473
|
-
if (input === "d" && status === "pro") {
|
|
4591
|
+
if ((input === "d" || input === "2") && status === "pro") {
|
|
4474
4592
|
setConfirmDeactivate(true);
|
|
4475
4593
|
}
|
|
4476
|
-
if (input === "p") {
|
|
4594
|
+
if (input === "p" || input === "1") {
|
|
4477
4595
|
setPromoMode(true);
|
|
4478
4596
|
setPromoResult(null);
|
|
4479
4597
|
}
|
|
@@ -4487,11 +4605,11 @@ function AccountView() {
|
|
|
4487
4605
|
return key.slice(0, 4) + "-****-****-" + key.slice(-4);
|
|
4488
4606
|
};
|
|
4489
4607
|
if (status === "validating") {
|
|
4490
|
-
return /* @__PURE__ */
|
|
4608
|
+
return /* @__PURE__ */ jsx32(Loading, { message: t("account_loading") });
|
|
4491
4609
|
}
|
|
4492
4610
|
return /* @__PURE__ */ jsxs30(Box29, { flexDirection: "column", children: [
|
|
4493
|
-
/* @__PURE__ */
|
|
4494
|
-
confirmDeactivate && /* @__PURE__ */
|
|
4611
|
+
/* @__PURE__ */ jsx32(SectionHeader, { emoji: "\u{1F464}", title: t("account_title"), gradient: GRADIENTS.gold }),
|
|
4612
|
+
confirmDeactivate && /* @__PURE__ */ jsx32(Box29, { marginY: SPACING.xs, children: /* @__PURE__ */ jsx32(
|
|
4495
4613
|
ConfirmDialog,
|
|
4496
4614
|
{
|
|
4497
4615
|
message: t("account_confirmDeactivate"),
|
|
@@ -4512,70 +4630,70 @@ function AccountView() {
|
|
|
4512
4630
|
) }),
|
|
4513
4631
|
/* @__PURE__ */ jsxs30(Box29, { flexDirection: "column", marginTop: SPACING.xs, paddingLeft: SPACING.sm, children: [
|
|
4514
4632
|
/* @__PURE__ */ jsxs30(Box29, { gap: SPACING.xs, children: [
|
|
4515
|
-
/* @__PURE__ */
|
|
4516
|
-
status === "pro" && /* @__PURE__ */
|
|
4517
|
-
status === "free" && /* @__PURE__ */
|
|
4518
|
-
status === "expired" && /* @__PURE__ */
|
|
4633
|
+
/* @__PURE__ */ jsx32(Text31, { color: COLORS.muted, children: t("account_statusLabel") }),
|
|
4634
|
+
status === "pro" && /* @__PURE__ */ jsx32(Text31, { color: COLORS.success, bold: true, children: t("account_pro") }),
|
|
4635
|
+
status === "free" && /* @__PURE__ */ jsx32(Text31, { color: COLORS.muted, children: t("account_free") }),
|
|
4636
|
+
status === "expired" && /* @__PURE__ */ jsx32(Text31, { color: COLORS.error, children: t("account_expired") })
|
|
4519
4637
|
] }),
|
|
4520
|
-
(degradation === "warning" || degradation === "limited") && license && /* @__PURE__ */
|
|
4638
|
+
(degradation === "warning" || degradation === "limited") && license && /* @__PURE__ */ jsx32(Box29, { marginTop: SPACING.xs, borderStyle: "round", borderColor: COLORS.warning, paddingX: SPACING.sm, paddingY: SPACING.none, children: /* @__PURE__ */ jsx32(Text31, { color: COLORS.warning, children: t("license_offlineWarning", {
|
|
4521
4639
|
days: Math.floor((Date.now() - new Date(license.lastValidatedAt).getTime()) / (24 * 60 * 60 * 1e3))
|
|
4522
4640
|
}) }) }),
|
|
4523
4641
|
license && /* @__PURE__ */ jsxs30(Fragment5, { children: [
|
|
4524
4642
|
/* @__PURE__ */ jsxs30(Box29, { gap: SPACING.xs, children: [
|
|
4525
|
-
/* @__PURE__ */
|
|
4526
|
-
/* @__PURE__ */
|
|
4643
|
+
/* @__PURE__ */ jsx32(Text31, { color: COLORS.muted, children: t("account_emailLabel") }),
|
|
4644
|
+
/* @__PURE__ */ jsx32(Text31, { children: license.customerEmail })
|
|
4527
4645
|
] }),
|
|
4528
4646
|
/* @__PURE__ */ jsxs30(Box29, { gap: SPACING.xs, children: [
|
|
4529
|
-
/* @__PURE__ */
|
|
4530
|
-
/* @__PURE__ */
|
|
4647
|
+
/* @__PURE__ */ jsx32(Text31, { color: COLORS.muted, children: t("account_nameLabel") }),
|
|
4648
|
+
/* @__PURE__ */ jsx32(Text31, { children: license.customerName })
|
|
4531
4649
|
] }),
|
|
4532
4650
|
/* @__PURE__ */ jsxs30(Box29, { gap: SPACING.xs, children: [
|
|
4533
|
-
/* @__PURE__ */
|
|
4534
|
-
/* @__PURE__ */
|
|
4651
|
+
/* @__PURE__ */ jsx32(Text31, { color: COLORS.muted, children: t("account_planLabel") }),
|
|
4652
|
+
/* @__PURE__ */ jsx32(Text31, { color: COLORS.success, bold: true, children: "Pro" })
|
|
4535
4653
|
] }),
|
|
4536
4654
|
/* @__PURE__ */ jsxs30(Box29, { gap: SPACING.xs, children: [
|
|
4537
|
-
/* @__PURE__ */
|
|
4538
|
-
/* @__PURE__ */
|
|
4655
|
+
/* @__PURE__ */ jsx32(Text31, { color: COLORS.muted, children: t("account_keyLabel") }),
|
|
4656
|
+
/* @__PURE__ */ jsx32(Text31, { children: maskKey(license.key) })
|
|
4539
4657
|
] }),
|
|
4540
4658
|
license.expiresAt && /* @__PURE__ */ jsxs30(Box29, { gap: SPACING.xs, children: [
|
|
4541
|
-
/* @__PURE__ */
|
|
4542
|
-
/* @__PURE__ */
|
|
4659
|
+
/* @__PURE__ */ jsx32(Text31, { color: COLORS.muted, children: t("account_expiresLabel") }),
|
|
4660
|
+
/* @__PURE__ */ jsx32(Text31, { children: formatDate(license.expiresAt) })
|
|
4543
4661
|
] }),
|
|
4544
4662
|
/* @__PURE__ */ jsxs30(Box29, { gap: SPACING.xs, children: [
|
|
4545
|
-
/* @__PURE__ */
|
|
4546
|
-
/* @__PURE__ */
|
|
4663
|
+
/* @__PURE__ */ jsx32(Text31, { color: COLORS.muted, children: t("account_activatedLabel") }),
|
|
4664
|
+
/* @__PURE__ */ jsx32(Text31, { children: formatDate(license.activatedAt) })
|
|
4547
4665
|
] })
|
|
4548
4666
|
] }),
|
|
4549
4667
|
status === "free" && /* @__PURE__ */ jsxs30(Box29, { flexDirection: "column", marginTop: SPACING.sm, borderStyle: "round", borderColor: COLORS.brand, paddingX: SPACING.sm, paddingY: SPACING.xs, children: [
|
|
4550
|
-
/* @__PURE__ */ jsxs30(
|
|
4668
|
+
/* @__PURE__ */ jsxs30(Text31, { bold: true, color: COLORS.brand, children: [
|
|
4551
4669
|
"\u2B50",
|
|
4552
4670
|
" ",
|
|
4553
4671
|
t("account_upgradeTitle")
|
|
4554
4672
|
] }),
|
|
4555
|
-
/* @__PURE__ */
|
|
4556
|
-
/* @__PURE__ */
|
|
4557
|
-
/* @__PURE__ */
|
|
4558
|
-
/* @__PURE__ */
|
|
4559
|
-
/* @__PURE__ */ jsxs30(
|
|
4673
|
+
/* @__PURE__ */ jsx32(Text31, { children: " " }),
|
|
4674
|
+
/* @__PURE__ */ jsx32(Text31, { children: t("account_unlockDesc") }),
|
|
4675
|
+
/* @__PURE__ */ jsx32(Text31, { color: COLORS.info, bold: true, children: t("account_pricing") }),
|
|
4676
|
+
/* @__PURE__ */ jsx32(Text31, { children: " " }),
|
|
4677
|
+
/* @__PURE__ */ jsxs30(Text31, { color: COLORS.muted, children: [
|
|
4560
4678
|
t("upgrade_buyAt"),
|
|
4561
4679
|
" ",
|
|
4562
|
-
/* @__PURE__ */
|
|
4680
|
+
/* @__PURE__ */ jsx32(Text31, { color: COLORS.sky, bold: true, children: t("upgrade_buyUrl") })
|
|
4563
4681
|
] }),
|
|
4564
|
-
/* @__PURE__ */ jsxs30(
|
|
4682
|
+
/* @__PURE__ */ jsxs30(Text31, { color: COLORS.muted, children: [
|
|
4565
4683
|
t("account_runActivate"),
|
|
4566
4684
|
" ",
|
|
4567
|
-
/* @__PURE__ */
|
|
4685
|
+
/* @__PURE__ */ jsx32(Text31, { color: COLORS.success, bold: true, children: t("account_activateCmd") })
|
|
4568
4686
|
] })
|
|
4569
4687
|
] }),
|
|
4570
|
-
status === "expired" && /* @__PURE__ */
|
|
4571
|
-
deactivating && /* @__PURE__ */
|
|
4572
|
-
deactivateError && /* @__PURE__ */
|
|
4688
|
+
status === "expired" && /* @__PURE__ */ jsx32(Box29, { marginTop: SPACING.xs, children: /* @__PURE__ */ jsx32(Box29, { borderStyle: "round", borderColor: COLORS.error, paddingX: SPACING.sm, paddingY: SPACING.none, children: /* @__PURE__ */ jsx32(Text31, { color: COLORS.error, children: t("account_licenseExpired") }) }) }),
|
|
4689
|
+
deactivating && /* @__PURE__ */ jsx32(Text31, { color: COLORS.sky, children: t("account_deactivating") }),
|
|
4690
|
+
deactivateError && /* @__PURE__ */ jsx32(Text31, { color: COLORS.error, children: deactivateError })
|
|
4573
4691
|
] }),
|
|
4574
|
-
/* @__PURE__ */
|
|
4575
|
-
/* @__PURE__ */
|
|
4576
|
-
promoLoading ? /* @__PURE__ */
|
|
4577
|
-
/* @__PURE__ */
|
|
4578
|
-
/* @__PURE__ */
|
|
4692
|
+
/* @__PURE__ */ jsx32(Box29, { flexDirection: "column", marginTop: SPACING.xs, paddingLeft: SPACING.sm, children: promoMode ? /* @__PURE__ */ jsxs30(Box29, { flexDirection: "column", gap: SPACING.xs, children: [
|
|
4693
|
+
/* @__PURE__ */ jsx32(Text31, { bold: true, color: COLORS.gold, children: t("account_promoTitle") }),
|
|
4694
|
+
promoLoading ? /* @__PURE__ */ jsx32(Text31, { color: COLORS.sky, children: t("account_promoValidating") }) : /* @__PURE__ */ jsxs30(Box29, { gap: SPACING.xs, children: [
|
|
4695
|
+
/* @__PURE__ */ jsx32(Text31, { color: COLORS.muted, children: t("account_promoLabel") }),
|
|
4696
|
+
/* @__PURE__ */ jsx32(
|
|
4579
4697
|
TextInput5,
|
|
4580
4698
|
{
|
|
4581
4699
|
defaultValue: "",
|
|
@@ -4599,22 +4717,22 @@ function AccountView() {
|
|
|
4599
4717
|
}
|
|
4600
4718
|
)
|
|
4601
4719
|
] }),
|
|
4602
|
-
promoResult && /* @__PURE__ */
|
|
4603
|
-
/* @__PURE__ */
|
|
4604
|
-
] }) : /* @__PURE__ */
|
|
4605
|
-
/* @__PURE__ */
|
|
4720
|
+
promoResult && /* @__PURE__ */ jsx32(ResultBanner, { status: promoResult.success ? "success" : "error", message: promoResult.message }),
|
|
4721
|
+
/* @__PURE__ */ jsx32(Text31, { color: COLORS.textSecondary, dimColor: true, children: t("account_promoEsc") })
|
|
4722
|
+
] }) : /* @__PURE__ */ jsx32(Text31, { color: COLORS.textSecondary, children: t("account_promoHint") }) }),
|
|
4723
|
+
/* @__PURE__ */ jsx32(Box29, { marginTop: SPACING.xs, children: /* @__PURE__ */ jsxs30(Text31, { color: COLORS.textSecondary, children: [
|
|
4606
4724
|
status === "pro" || status === "team" ? `d ${t("hint_deactivate")} ` : "",
|
|
4607
4725
|
status === "pro" || status === "team" || status === "expired" ? `v ${t("hint_revalidate")} ` : "",
|
|
4608
4726
|
revalidating ? t("account_revalidating") : "",
|
|
4609
4727
|
" ",
|
|
4610
|
-
t("app_version", { version: "0.
|
|
4728
|
+
t("app_version", { version: "0.9.1" })
|
|
4611
4729
|
] }) })
|
|
4612
4730
|
] });
|
|
4613
4731
|
}
|
|
4614
4732
|
|
|
4615
4733
|
// src/views/rollback.tsx
|
|
4616
|
-
import { useCallback as useCallback3, useEffect as
|
|
4617
|
-
import { Box as Box30, Text as
|
|
4734
|
+
import { useCallback as useCallback3, useEffect as useEffect19, useRef as useRef9, useState as useState16 } from "react";
|
|
4735
|
+
import { Box as Box30, Text as Text32 } from "ink";
|
|
4618
4736
|
|
|
4619
4737
|
// src/stores/rollback-store.ts
|
|
4620
4738
|
import { create as create12 } from "zustand";
|
|
@@ -4824,7 +4942,7 @@ var useRollbackStore = create12((set) => ({
|
|
|
4824
4942
|
}));
|
|
4825
4943
|
|
|
4826
4944
|
// src/views/rollback.tsx
|
|
4827
|
-
import { jsx as
|
|
4945
|
+
import { jsx as jsx33, jsxs as jsxs31 } from "react/jsx-runtime";
|
|
4828
4946
|
function strategyLabel(action) {
|
|
4829
4947
|
switch (action.strategy) {
|
|
4830
4948
|
case "versioned-formula":
|
|
@@ -4854,46 +4972,46 @@ function PlanView({ plan }) {
|
|
|
4854
4972
|
const executableCount = plan.actions.filter((a) => a.strategy !== "unavailable" && a.action !== "remove").length;
|
|
4855
4973
|
return /* @__PURE__ */ jsxs31(Box30, { flexDirection: "column", marginTop: SPACING.xs, children: [
|
|
4856
4974
|
/* @__PURE__ */ jsxs31(Box30, { marginBottom: SPACING.xs, children: [
|
|
4857
|
-
/* @__PURE__ */ jsxs31(
|
|
4975
|
+
/* @__PURE__ */ jsxs31(Text32, { color: COLORS.text, bold: true, children: [
|
|
4858
4976
|
plan.snapshotLabel,
|
|
4859
4977
|
" "
|
|
4860
4978
|
] }),
|
|
4861
|
-
/* @__PURE__ */
|
|
4979
|
+
/* @__PURE__ */ jsx33(Text32, { color: COLORS.textSecondary, children: plan.snapshotDate })
|
|
4862
4980
|
] }),
|
|
4863
|
-
plan.actions.length === 0 && /* @__PURE__ */
|
|
4981
|
+
plan.actions.length === 0 && /* @__PURE__ */ jsx33(ResultBanner, { status: "success", message: t("rollback_diff_empty") }),
|
|
4864
4982
|
plan.actions.map((a) => /* @__PURE__ */ jsxs31(Box30, { children: [
|
|
4865
|
-
/* @__PURE__ */ jsxs31(
|
|
4983
|
+
/* @__PURE__ */ jsxs31(Text32, { color: actionColor(a), children: [
|
|
4866
4984
|
actionPrefix(a),
|
|
4867
4985
|
" "
|
|
4868
4986
|
] }),
|
|
4869
|
-
/* @__PURE__ */
|
|
4870
|
-
a.fromVersion !== "" && a.toVersion !== "" && /* @__PURE__ */ jsxs31(
|
|
4987
|
+
/* @__PURE__ */ jsx33(Text32, { color: actionColor(a), bold: true, children: a.packageName }),
|
|
4988
|
+
a.fromVersion !== "" && a.toVersion !== "" && /* @__PURE__ */ jsxs31(Text32, { color: COLORS.textSecondary, children: [
|
|
4871
4989
|
" ",
|
|
4872
4990
|
a.fromVersion,
|
|
4873
4991
|
" \u2192 ",
|
|
4874
4992
|
a.toVersion
|
|
4875
4993
|
] }),
|
|
4876
|
-
a.fromVersion === "" && a.toVersion !== "" && /* @__PURE__ */ jsxs31(
|
|
4994
|
+
a.fromVersion === "" && a.toVersion !== "" && /* @__PURE__ */ jsxs31(Text32, { color: COLORS.textSecondary, children: [
|
|
4877
4995
|
" install ",
|
|
4878
4996
|
a.toVersion
|
|
4879
4997
|
] }),
|
|
4880
|
-
a.fromVersion !== "" && a.toVersion === "" && /* @__PURE__ */
|
|
4881
|
-
/* @__PURE__ */ jsxs31(
|
|
4998
|
+
a.fromVersion !== "" && a.toVersion === "" && /* @__PURE__ */ jsx33(Text32, { color: COLORS.textSecondary, children: " remove" }),
|
|
4999
|
+
/* @__PURE__ */ jsxs31(Text32, { color: COLORS.muted, dimColor: true, children: [
|
|
4882
5000
|
" [",
|
|
4883
5001
|
strategyLabel(a),
|
|
4884
5002
|
"]"
|
|
4885
5003
|
] })
|
|
4886
5004
|
] }, a.packageName + a.action)),
|
|
4887
|
-
plan.warnings.map((w) => /* @__PURE__ */
|
|
5005
|
+
plan.warnings.map((w) => /* @__PURE__ */ jsx33(Box30, { marginTop: SPACING.xs, children: /* @__PURE__ */ jsxs31(Text32, { color: COLORS.warning, children: [
|
|
4888
5006
|
"\u26A0 ",
|
|
4889
5007
|
w
|
|
4890
5008
|
] }) }, w)),
|
|
4891
|
-
/* @__PURE__ */
|
|
5009
|
+
/* @__PURE__ */ jsx33(Box30, { marginTop: SPACING.xs, children: plan.canExecute ? /* @__PURE__ */ jsxs31(Text32, { color: COLORS.textSecondary, children: [
|
|
4892
5010
|
"enter:",
|
|
4893
5011
|
t("rollback_confirm", { count: String(executableCount) }),
|
|
4894
5012
|
" esc:",
|
|
4895
5013
|
t("hint_back")
|
|
4896
|
-
] }) : /* @__PURE__ */ jsxs31(
|
|
5014
|
+
] }) : /* @__PURE__ */ jsxs31(Text32, { color: COLORS.muted, children: [
|
|
4897
5015
|
t("rollback_strategy_unavailable"),
|
|
4898
5016
|
" esc:",
|
|
4899
5017
|
t("hint_back")
|
|
@@ -4903,21 +5021,21 @@ function PlanView({ plan }) {
|
|
|
4903
5021
|
function RollbackView() {
|
|
4904
5022
|
const isPro = useLicenseStore((s) => s.isPro);
|
|
4905
5023
|
const { snapshots, loading, error, plan, planLoading, planError, fetchSnapshots, selectSnapshot, clearPlan } = useRollbackStore();
|
|
4906
|
-
const [cursor, setCursor] =
|
|
4907
|
-
const [phase, setPhase] =
|
|
4908
|
-
const [streamLines, setStreamLines] =
|
|
4909
|
-
const [streamRunning, setStreamRunning] =
|
|
4910
|
-
const [streamError, setStreamError] =
|
|
4911
|
-
const generatorRef =
|
|
4912
|
-
const mountedRef =
|
|
4913
|
-
|
|
5024
|
+
const [cursor, setCursor] = useState16(0);
|
|
5025
|
+
const [phase, setPhase] = useState16("list");
|
|
5026
|
+
const [streamLines, setStreamLines] = useState16([]);
|
|
5027
|
+
const [streamRunning, setStreamRunning] = useState16(false);
|
|
5028
|
+
const [streamError, setStreamError] = useState16(null);
|
|
5029
|
+
const generatorRef = useRef9(null);
|
|
5030
|
+
const mountedRef = useRef9(true);
|
|
5031
|
+
useEffect19(() => {
|
|
4914
5032
|
mountedRef.current = true;
|
|
4915
5033
|
return () => {
|
|
4916
5034
|
mountedRef.current = false;
|
|
4917
5035
|
void generatorRef.current?.return(void 0);
|
|
4918
5036
|
};
|
|
4919
5037
|
}, []);
|
|
4920
|
-
|
|
5038
|
+
useEffect19(() => {
|
|
4921
5039
|
void fetchSnapshots(isPro());
|
|
4922
5040
|
}, []);
|
|
4923
5041
|
const runRollback = useCallback3(async (p) => {
|
|
@@ -4944,7 +5062,7 @@ function RollbackView() {
|
|
|
4944
5062
|
}
|
|
4945
5063
|
}
|
|
4946
5064
|
}, [isPro]);
|
|
4947
|
-
|
|
5065
|
+
useViewInput((input, key) => {
|
|
4948
5066
|
if (phase === "executing") return;
|
|
4949
5067
|
if (phase === "result") {
|
|
4950
5068
|
if (key.escape || input === "r") {
|
|
@@ -4973,25 +5091,25 @@ function RollbackView() {
|
|
|
4973
5091
|
} else if (key.return && snapshots[cursor]) {
|
|
4974
5092
|
void selectSnapshot(snapshots[cursor], isPro());
|
|
4975
5093
|
setPhase("plan");
|
|
4976
|
-
} else if (input === "r") {
|
|
5094
|
+
} else if (input === "r" || input === "1") {
|
|
4977
5095
|
void fetchSnapshots(isPro());
|
|
4978
5096
|
}
|
|
4979
5097
|
});
|
|
4980
|
-
if (loading) return /* @__PURE__ */
|
|
4981
|
-
if (error) return /* @__PURE__ */
|
|
5098
|
+
if (loading) return /* @__PURE__ */ jsx33(Loading, { message: t("rollback_select_snapshot") });
|
|
5099
|
+
if (error) return /* @__PURE__ */ jsx33(ErrorMessage, { message: error });
|
|
4982
5100
|
if (phase === "executing") {
|
|
4983
|
-
return /* @__PURE__ */
|
|
5101
|
+
return /* @__PURE__ */ jsx33(Box30, { flexDirection: "column", children: /* @__PURE__ */ jsx33(ProgressLog, { lines: streamLines, isRunning: streamRunning, title: t("rollback_executing") }) });
|
|
4984
5102
|
}
|
|
4985
5103
|
if (phase === "result") {
|
|
4986
5104
|
return /* @__PURE__ */ jsxs31(Box30, { flexDirection: "column", marginTop: SPACING.xs, children: [
|
|
4987
|
-
/* @__PURE__ */
|
|
5105
|
+
/* @__PURE__ */ jsx33(
|
|
4988
5106
|
ResultBanner,
|
|
4989
5107
|
{
|
|
4990
5108
|
status: streamError ? "error" : "success",
|
|
4991
5109
|
message: streamError ? t("rollback_error", { error: streamError }) : t("rollback_success")
|
|
4992
5110
|
}
|
|
4993
5111
|
),
|
|
4994
|
-
/* @__PURE__ */
|
|
5112
|
+
/* @__PURE__ */ jsx33(Box30, { marginTop: SPACING.xs, children: /* @__PURE__ */ jsxs31(Text32, { color: COLORS.textSecondary, children: [
|
|
4995
5113
|
"r:",
|
|
4996
5114
|
t("hint_refresh"),
|
|
4997
5115
|
" esc:",
|
|
@@ -5000,17 +5118,17 @@ function RollbackView() {
|
|
|
5000
5118
|
] });
|
|
5001
5119
|
}
|
|
5002
5120
|
return /* @__PURE__ */ jsxs31(Box30, { flexDirection: "column", children: [
|
|
5003
|
-
/* @__PURE__ */
|
|
5004
|
-
snapshots.length === 0 && /* @__PURE__ */
|
|
5121
|
+
/* @__PURE__ */ jsx33(SectionHeader, { emoji: "\u23EA", title: t("rollback_title"), gradient: GRADIENTS.gold }),
|
|
5122
|
+
snapshots.length === 0 && /* @__PURE__ */ jsx33(Box30, { marginTop: SPACING.xs, children: /* @__PURE__ */ jsx33(ResultBanner, { status: "info", message: t("rollback_no_snapshots") }) }),
|
|
5005
5123
|
phase === "list" && snapshots.length > 0 && /* @__PURE__ */ jsxs31(Box30, { flexDirection: "column", marginTop: SPACING.xs, children: [
|
|
5006
|
-
/* @__PURE__ */
|
|
5007
|
-
/* @__PURE__ */
|
|
5008
|
-
/* @__PURE__ */
|
|
5009
|
-
/* @__PURE__ */ jsxs31(
|
|
5124
|
+
/* @__PURE__ */ jsx33(Text32, { color: COLORS.textSecondary, dimColor: true, children: t("rollback_select_snapshot") }),
|
|
5125
|
+
/* @__PURE__ */ jsx33(Box30, { flexDirection: "column", marginTop: SPACING.xs, children: snapshots.map((s, i) => /* @__PURE__ */ jsxs31(SelectableRow, { isCurrent: i === cursor, children: [
|
|
5126
|
+
/* @__PURE__ */ jsx33(Text32, { bold: i === cursor, color: i === cursor ? COLORS.text : COLORS.muted, children: s.label ?? t("rollback_snapshot_auto") }),
|
|
5127
|
+
/* @__PURE__ */ jsxs31(Text32, { color: COLORS.textSecondary, children: [
|
|
5010
5128
|
" \u2014 ",
|
|
5011
5129
|
new Date(s.capturedAt).toLocaleString()
|
|
5012
5130
|
] }),
|
|
5013
|
-
/* @__PURE__ */ jsxs31(
|
|
5131
|
+
/* @__PURE__ */ jsxs31(Text32, { color: COLORS.muted, dimColor: true, children: [
|
|
5014
5132
|
" ",
|
|
5015
5133
|
"(",
|
|
5016
5134
|
tp("packages", s.formulae.length + s.casks.length),
|
|
@@ -5019,11 +5137,11 @@ function RollbackView() {
|
|
|
5019
5137
|
] }, s.capturedAt)) })
|
|
5020
5138
|
] }),
|
|
5021
5139
|
phase === "plan" && /* @__PURE__ */ jsxs31(Box30, { flexDirection: "column", children: [
|
|
5022
|
-
planLoading && /* @__PURE__ */
|
|
5023
|
-
planError && /* @__PURE__ */
|
|
5024
|
-
plan && !planLoading && /* @__PURE__ */
|
|
5140
|
+
planLoading && /* @__PURE__ */ jsx33(Loading, { message: t("rollback_capturing") }),
|
|
5141
|
+
planError && /* @__PURE__ */ jsx33(ErrorMessage, { message: planError }),
|
|
5142
|
+
plan && !planLoading && /* @__PURE__ */ jsx33(PlanView, { plan })
|
|
5025
5143
|
] }),
|
|
5026
|
-
phase === "confirm" && plan && /* @__PURE__ */
|
|
5144
|
+
phase === "confirm" && plan && /* @__PURE__ */ jsx33(Box30, { marginTop: SPACING.xs, children: /* @__PURE__ */ jsx33(
|
|
5027
5145
|
ConfirmDialog,
|
|
5028
5146
|
{
|
|
5029
5147
|
message: t("rollback_confirm", {
|
|
@@ -5037,60 +5155,60 @@ function RollbackView() {
|
|
|
5037
5155
|
}
|
|
5038
5156
|
|
|
5039
5157
|
// src/views/brewfile.tsx
|
|
5040
|
-
import { useCallback as useCallback4, useEffect as
|
|
5041
|
-
import { Box as Box31, Text as
|
|
5158
|
+
import { useCallback as useCallback4, useEffect as useEffect20, useRef as useRef10, useState as useState17 } from "react";
|
|
5159
|
+
import { Box as Box31, Text as Text33 } from "ink";
|
|
5042
5160
|
import { TextInput as TextInput6 } from "@inkjs/ui";
|
|
5043
|
-
import { jsx as
|
|
5161
|
+
import { jsx as jsx34, jsxs as jsxs32 } from "react/jsx-runtime";
|
|
5044
5162
|
function DriftScore({ score }) {
|
|
5045
5163
|
const color = score >= 80 ? COLORS.success : score >= 50 ? COLORS.warning : COLORS.error;
|
|
5046
5164
|
const bars = Math.round(score / 10);
|
|
5047
5165
|
const filled = "\u2593".repeat(bars);
|
|
5048
5166
|
const empty = "\u2591".repeat(10 - bars);
|
|
5049
5167
|
return /* @__PURE__ */ jsxs32(Box31, { children: [
|
|
5050
|
-
/* @__PURE__ */ jsxs32(
|
|
5168
|
+
/* @__PURE__ */ jsxs32(Text33, { color, children: [
|
|
5051
5169
|
filled,
|
|
5052
5170
|
empty
|
|
5053
5171
|
] }),
|
|
5054
|
-
/* @__PURE__ */ jsxs32(
|
|
5172
|
+
/* @__PURE__ */ jsxs32(Text33, { color, bold: true, children: [
|
|
5055
5173
|
" ",
|
|
5056
5174
|
score,
|
|
5057
5175
|
"% "
|
|
5058
5176
|
] }),
|
|
5059
|
-
/* @__PURE__ */
|
|
5177
|
+
/* @__PURE__ */ jsx34(Text33, { color: COLORS.textSecondary, children: t("brewfile_compliant") })
|
|
5060
5178
|
] });
|
|
5061
5179
|
}
|
|
5062
5180
|
function DriftSummary({ drift }) {
|
|
5063
5181
|
return /* @__PURE__ */ jsxs32(Box31, { flexDirection: "column", marginTop: SPACING.xs, children: [
|
|
5064
5182
|
drift.missingPackages.length > 0 && /* @__PURE__ */ jsxs32(Box31, { children: [
|
|
5065
|
-
/* @__PURE__ */
|
|
5066
|
-
/* @__PURE__ */
|
|
5067
|
-
/* @__PURE__ */ jsxs32(
|
|
5183
|
+
/* @__PURE__ */ jsx34(Text33, { color: COLORS.error, children: "\u25CF " }),
|
|
5184
|
+
/* @__PURE__ */ jsx34(Text33, { color: COLORS.error, children: t("brewfile_drift_missing", { count: drift.missingPackages.length }) }),
|
|
5185
|
+
/* @__PURE__ */ jsxs32(Text33, { color: COLORS.textSecondary, children: [
|
|
5068
5186
|
": " + drift.missingPackages.slice(0, 3).join(", "),
|
|
5069
5187
|
drift.missingPackages.length > 3 ? "..." : ""
|
|
5070
5188
|
] })
|
|
5071
5189
|
] }),
|
|
5072
5190
|
drift.extraPackages.length > 0 && /* @__PURE__ */ jsxs32(Box31, { children: [
|
|
5073
|
-
/* @__PURE__ */
|
|
5074
|
-
/* @__PURE__ */
|
|
5191
|
+
/* @__PURE__ */ jsx34(Text33, { color: COLORS.warning, children: "\u25CF " }),
|
|
5192
|
+
/* @__PURE__ */ jsx34(Text33, { color: COLORS.warning, children: t("brewfile_drift_extra", { count: drift.extraPackages.length }) })
|
|
5075
5193
|
] }),
|
|
5076
5194
|
drift.wrongVersions.length > 0 && /* @__PURE__ */ jsxs32(Box31, { children: [
|
|
5077
|
-
/* @__PURE__ */
|
|
5078
|
-
/* @__PURE__ */
|
|
5195
|
+
/* @__PURE__ */ jsx34(Text33, { color: COLORS.info, children: "\u25CF " }),
|
|
5196
|
+
/* @__PURE__ */ jsx34(Text33, { color: COLORS.info, children: t("brewfile_drift_wrong", { count: drift.wrongVersions.length }) })
|
|
5079
5197
|
] }),
|
|
5080
|
-
drift.missingPackages.length === 0 && drift.extraPackages.length === 0 && drift.wrongVersions.length === 0 && /* @__PURE__ */
|
|
5198
|
+
drift.missingPackages.length === 0 && drift.extraPackages.length === 0 && drift.wrongVersions.length === 0 && /* @__PURE__ */ jsx34(ResultBanner, { status: "success", message: t("brewfile_in_sync") })
|
|
5081
5199
|
] });
|
|
5082
5200
|
}
|
|
5083
5201
|
function BrewfileView() {
|
|
5084
5202
|
const isPro = useLicenseStore((s) => s.isPro);
|
|
5085
5203
|
const { schema, drift, loading, driftLoading, error, load, createFromCurrent } = useBrewfileStore();
|
|
5086
|
-
const [phase, setPhase] =
|
|
5087
|
-
const [streamLines, setStreamLines] =
|
|
5088
|
-
const [streamRunning, setStreamRunning] =
|
|
5089
|
-
const [streamError, setStreamError] =
|
|
5090
|
-
const [resultMessage, setResultMessage] =
|
|
5091
|
-
const generatorRef =
|
|
5092
|
-
const mountedRef =
|
|
5093
|
-
|
|
5204
|
+
const [phase, setPhase] = useState17("overview");
|
|
5205
|
+
const [streamLines, setStreamLines] = useState17([]);
|
|
5206
|
+
const [streamRunning, setStreamRunning] = useState17(false);
|
|
5207
|
+
const [streamError, setStreamError] = useState17(null);
|
|
5208
|
+
const [resultMessage, setResultMessage] = useState17("");
|
|
5209
|
+
const generatorRef = useRef10(null);
|
|
5210
|
+
const mountedRef = useRef10(true);
|
|
5211
|
+
useEffect20(() => {
|
|
5094
5212
|
mountedRef.current = true;
|
|
5095
5213
|
void load();
|
|
5096
5214
|
return () => {
|
|
@@ -5128,7 +5246,7 @@ function BrewfileView() {
|
|
|
5128
5246
|
}
|
|
5129
5247
|
}
|
|
5130
5248
|
}, [schema, isPro]);
|
|
5131
|
-
|
|
5249
|
+
useViewInput((input, key) => {
|
|
5132
5250
|
if (phase === "reconciling") return;
|
|
5133
5251
|
if (phase === "confirming-reconcile") return;
|
|
5134
5252
|
if (phase === "result") {
|
|
@@ -5139,15 +5257,15 @@ function BrewfileView() {
|
|
|
5139
5257
|
return;
|
|
5140
5258
|
}
|
|
5141
5259
|
if (phase === "creating") return;
|
|
5142
|
-
if (input === "n") {
|
|
5260
|
+
if (input === "n" || input === "1") {
|
|
5143
5261
|
setPhase("creating");
|
|
5144
5262
|
return;
|
|
5145
5263
|
}
|
|
5146
|
-
if (input === "r") {
|
|
5264
|
+
if (input === "r" || input === "2") {
|
|
5147
5265
|
void load();
|
|
5148
5266
|
return;
|
|
5149
5267
|
}
|
|
5150
|
-
if (input === "c") {
|
|
5268
|
+
if (input === "c" || input === "3") {
|
|
5151
5269
|
const needsReconcile = drift && (drift.missingPackages.length > 0 || drift.wrongVersions.length > 0);
|
|
5152
5270
|
if (needsReconcile) {
|
|
5153
5271
|
setPhase("confirming-reconcile");
|
|
@@ -5157,10 +5275,10 @@ function BrewfileView() {
|
|
|
5157
5275
|
if (key.escape) {
|
|
5158
5276
|
}
|
|
5159
5277
|
});
|
|
5160
|
-
if (loading) return /* @__PURE__ */
|
|
5161
|
-
if (error) return /* @__PURE__ */
|
|
5278
|
+
if (loading) return /* @__PURE__ */ jsx34(Loading, { message: t("loading_default") });
|
|
5279
|
+
if (error) return /* @__PURE__ */ jsx34(ErrorMessage, { message: error });
|
|
5162
5280
|
if (phase === "confirming-reconcile" && drift) {
|
|
5163
|
-
return /* @__PURE__ */
|
|
5281
|
+
return /* @__PURE__ */ jsx34(
|
|
5164
5282
|
ConfirmDialog,
|
|
5165
5283
|
{
|
|
5166
5284
|
message: t("confirm_brewfile_reconcile", {
|
|
@@ -5178,13 +5296,13 @@ function BrewfileView() {
|
|
|
5178
5296
|
}
|
|
5179
5297
|
if (phase === "creating") {
|
|
5180
5298
|
return /* @__PURE__ */ jsxs32(Box31, { flexDirection: "column", marginTop: SPACING.xs, children: [
|
|
5181
|
-
/* @__PURE__ */
|
|
5299
|
+
/* @__PURE__ */ jsx34(SectionHeader, { emoji: "\u{1F4E6}", title: t("brewfile_title"), gradient: GRADIENTS.ocean }),
|
|
5182
5300
|
/* @__PURE__ */ jsxs32(Box31, { marginTop: SPACING.xs, children: [
|
|
5183
|
-
/* @__PURE__ */ jsxs32(
|
|
5301
|
+
/* @__PURE__ */ jsxs32(Text33, { color: COLORS.textSecondary, children: [
|
|
5184
5302
|
t("brewfile_create_name"),
|
|
5185
5303
|
" "
|
|
5186
5304
|
] }),
|
|
5187
|
-
/* @__PURE__ */
|
|
5305
|
+
/* @__PURE__ */ jsx34(
|
|
5188
5306
|
TextInput6,
|
|
5189
5307
|
{
|
|
5190
5308
|
defaultValue: "My Environment",
|
|
@@ -5200,7 +5318,7 @@ function BrewfileView() {
|
|
|
5200
5318
|
] });
|
|
5201
5319
|
}
|
|
5202
5320
|
if (phase === "reconciling") {
|
|
5203
|
-
return /* @__PURE__ */
|
|
5321
|
+
return /* @__PURE__ */ jsx34(Box31, { flexDirection: "column", children: /* @__PURE__ */ jsx34(
|
|
5204
5322
|
ProgressLog,
|
|
5205
5323
|
{
|
|
5206
5324
|
lines: streamLines,
|
|
@@ -5211,14 +5329,14 @@ function BrewfileView() {
|
|
|
5211
5329
|
}
|
|
5212
5330
|
if (phase === "result") {
|
|
5213
5331
|
return /* @__PURE__ */ jsxs32(Box31, { flexDirection: "column", marginTop: SPACING.xs, children: [
|
|
5214
|
-
/* @__PURE__ */
|
|
5332
|
+
/* @__PURE__ */ jsx34(
|
|
5215
5333
|
ResultBanner,
|
|
5216
5334
|
{
|
|
5217
5335
|
status: streamError ? "error" : "success",
|
|
5218
5336
|
message: resultMessage
|
|
5219
5337
|
}
|
|
5220
5338
|
),
|
|
5221
|
-
/* @__PURE__ */
|
|
5339
|
+
/* @__PURE__ */ jsx34(Box31, { marginTop: SPACING.xs, children: /* @__PURE__ */ jsxs32(Text33, { color: COLORS.textSecondary, children: [
|
|
5222
5340
|
"r:",
|
|
5223
5341
|
t("hint_refresh"),
|
|
5224
5342
|
" esc:",
|
|
@@ -5227,33 +5345,33 @@ function BrewfileView() {
|
|
|
5227
5345
|
] });
|
|
5228
5346
|
}
|
|
5229
5347
|
return /* @__PURE__ */ jsxs32(Box31, { flexDirection: "column", children: [
|
|
5230
|
-
/* @__PURE__ */
|
|
5348
|
+
/* @__PURE__ */ jsx34(SectionHeader, { emoji: "\u{1F4E6}", title: t("brewfile_title"), gradient: GRADIENTS.ocean }),
|
|
5231
5349
|
schema === null ? /* @__PURE__ */ jsxs32(Box31, { marginTop: SPACING.xs, flexDirection: "column", children: [
|
|
5232
|
-
/* @__PURE__ */
|
|
5233
|
-
/* @__PURE__ */
|
|
5350
|
+
/* @__PURE__ */ jsx34(ResultBanner, { status: "info", message: t("brewfile_no_brewfile") }),
|
|
5351
|
+
/* @__PURE__ */ jsx34(Box31, { marginTop: SPACING.xs, children: /* @__PURE__ */ jsxs32(Text33, { color: COLORS.textSecondary, children: [
|
|
5234
5352
|
"n:",
|
|
5235
5353
|
t("hint_new")
|
|
5236
5354
|
] }) })
|
|
5237
5355
|
] }) : /* @__PURE__ */ jsxs32(Box31, { flexDirection: "column", marginTop: SPACING.xs, children: [
|
|
5238
5356
|
/* @__PURE__ */ jsxs32(Box31, { gap: SPACING.sm, children: [
|
|
5239
|
-
/* @__PURE__ */
|
|
5240
|
-
schema.meta.description && /* @__PURE__ */
|
|
5241
|
-
schema.strictMode && /* @__PURE__ */ jsxs32(
|
|
5357
|
+
/* @__PURE__ */ jsx34(Text33, { color: COLORS.text, bold: true, children: schema.meta.name }),
|
|
5358
|
+
schema.meta.description && /* @__PURE__ */ jsx34(Text33, { color: COLORS.textSecondary, children: schema.meta.description }),
|
|
5359
|
+
schema.strictMode && /* @__PURE__ */ jsxs32(Text33, { color: COLORS.warning, children: [
|
|
5242
5360
|
"[",
|
|
5243
5361
|
t("brewfile_strict_mode"),
|
|
5244
5362
|
"]"
|
|
5245
5363
|
] })
|
|
5246
5364
|
] }),
|
|
5247
5365
|
/* @__PURE__ */ jsxs32(Box31, { gap: SPACING.md, marginTop: SPACING.xs, children: [
|
|
5248
|
-
/* @__PURE__ */
|
|
5249
|
-
/* @__PURE__ */
|
|
5366
|
+
/* @__PURE__ */ jsx34(Text33, { color: COLORS.sky, children: t("brewfile_formulae_count", { count: schema.formulae.length }) }),
|
|
5367
|
+
/* @__PURE__ */ jsx34(Text33, { color: COLORS.teal, children: t("brewfile_casks_count", { count: schema.casks.length }) })
|
|
5250
5368
|
] }),
|
|
5251
|
-
driftLoading && /* @__PURE__ */
|
|
5369
|
+
driftLoading && /* @__PURE__ */ jsx34(Box31, { marginTop: SPACING.xs, children: /* @__PURE__ */ jsx34(Text33, { color: COLORS.muted, children: t("brewfile_computing_drift") }) }),
|
|
5252
5370
|
drift && !driftLoading && /* @__PURE__ */ jsxs32(Box31, { flexDirection: "column", marginTop: SPACING.xs, children: [
|
|
5253
|
-
/* @__PURE__ */
|
|
5254
|
-
/* @__PURE__ */
|
|
5371
|
+
/* @__PURE__ */ jsx34(DriftScore, { score: drift.score }),
|
|
5372
|
+
/* @__PURE__ */ jsx34(DriftSummary, { drift })
|
|
5255
5373
|
] }),
|
|
5256
|
-
/* @__PURE__ */
|
|
5374
|
+
/* @__PURE__ */ jsx34(Box31, { marginTop: SPACING.xs, children: /* @__PURE__ */ jsxs32(Text33, { color: COLORS.textSecondary, children: [
|
|
5257
5375
|
"r:",
|
|
5258
5376
|
t("hint_refresh"),
|
|
5259
5377
|
drift && (drift.missingPackages.length > 0 || drift.wrongVersions.length > 0) ? ` c:${t("hint_reconcile")}` : "",
|
|
@@ -5266,9 +5384,9 @@ function BrewfileView() {
|
|
|
5266
5384
|
}
|
|
5267
5385
|
|
|
5268
5386
|
// src/views/sync.tsx
|
|
5269
|
-
import { useCallback as useCallback5, useEffect as
|
|
5270
|
-
import { Box as Box32, Text as
|
|
5271
|
-
import { Fragment as Fragment6, jsx as
|
|
5387
|
+
import { useCallback as useCallback5, useEffect as useEffect21, useState as useState18 } from "react";
|
|
5388
|
+
import { Box as Box32, Text as Text34 } from "ink";
|
|
5389
|
+
import { Fragment as Fragment6, jsx as jsx35, jsxs as jsxs33 } from "react/jsx-runtime";
|
|
5272
5390
|
function OverviewSection({
|
|
5273
5391
|
config,
|
|
5274
5392
|
lastResult,
|
|
@@ -5280,32 +5398,32 @@ function OverviewSection({
|
|
|
5280
5398
|
const showComplianceHint = !hasConflicts && !!lastResult?.success;
|
|
5281
5399
|
return /* @__PURE__ */ jsxs33(Box32, { flexDirection: "column", marginTop: SPACING.xs, children: [
|
|
5282
5400
|
config ? /* @__PURE__ */ jsxs33(Fragment6, { children: [
|
|
5283
|
-
/* @__PURE__ */
|
|
5284
|
-
config.lastSync && /* @__PURE__ */
|
|
5285
|
-
hasConflicts ? /* @__PURE__ */
|
|
5401
|
+
/* @__PURE__ */ jsx35(Box32, { marginBottom: SPACING.xs, children: /* @__PURE__ */ jsx35(Text34, { color: COLORS.textSecondary, children: t("sync_machine", { name: config.machineName }) }) }),
|
|
5402
|
+
config.lastSync && /* @__PURE__ */ jsx35(Box32, { marginBottom: SPACING.xs, children: /* @__PURE__ */ jsx35(Text34, { color: COLORS.textSecondary, children: t("sync_last_sync", { date: new Date(config.lastSync).toLocaleString() }) }) }),
|
|
5403
|
+
hasConflicts ? /* @__PURE__ */ jsx35(
|
|
5286
5404
|
ResultBanner,
|
|
5287
5405
|
{
|
|
5288
5406
|
status: "error",
|
|
5289
5407
|
message: t("sync_status_conflict", { count: String(conflicts.length) })
|
|
5290
5408
|
}
|
|
5291
|
-
) : lastResult?.success ? /* @__PURE__ */
|
|
5292
|
-
] }) : /* @__PURE__ */
|
|
5293
|
-
/* @__PURE__ */
|
|
5409
|
+
) : lastResult?.success ? /* @__PURE__ */ jsx35(ResultBanner, { status: "success", message: t("sync_status_ok") }) : null
|
|
5410
|
+
] }) : /* @__PURE__ */ jsx35(Box32, { marginBottom: SPACING.xs, children: /* @__PURE__ */ jsx35(Text34, { color: COLORS.textSecondary, children: t("sync_disabled") }) }),
|
|
5411
|
+
/* @__PURE__ */ jsx35(Box32, { marginTop: SPACING.xs, children: /* @__PURE__ */ jsxs33(Text34, { color: COLORS.textSecondary, children: [
|
|
5294
5412
|
"s",
|
|
5295
|
-
/* @__PURE__ */ jsxs33(
|
|
5413
|
+
/* @__PURE__ */ jsxs33(Text34, { color: COLORS.gold, children: [
|
|
5296
5414
|
":",
|
|
5297
5415
|
t("hint_sync")
|
|
5298
5416
|
] }),
|
|
5299
5417
|
hasConflicts && /* @__PURE__ */ jsxs33(Fragment6, { children: [
|
|
5300
5418
|
" c",
|
|
5301
|
-
/* @__PURE__ */ jsxs33(
|
|
5419
|
+
/* @__PURE__ */ jsxs33(Text34, { color: COLORS.gold, children: [
|
|
5302
5420
|
":",
|
|
5303
5421
|
t("hint_conflict")
|
|
5304
5422
|
] })
|
|
5305
5423
|
] }),
|
|
5306
5424
|
showComplianceHint && /* @__PURE__ */ jsxs33(Fragment6, { children: [
|
|
5307
5425
|
" c",
|
|
5308
|
-
/* @__PURE__ */ jsxs33(
|
|
5426
|
+
/* @__PURE__ */ jsxs33(Text34, { color: COLORS.gold, children: [
|
|
5309
5427
|
":",
|
|
5310
5428
|
t("hint_check_compliance")
|
|
5311
5429
|
] })
|
|
@@ -5323,8 +5441,8 @@ function ConflictsList({
|
|
|
5323
5441
|
const isActive = i === cursor;
|
|
5324
5442
|
return /* @__PURE__ */ jsxs33(Box32, { flexDirection: "column", marginBottom: SPACING.xs, children: [
|
|
5325
5443
|
/* @__PURE__ */ jsxs33(SelectableRow, { isCurrent: isActive, children: [
|
|
5326
|
-
/* @__PURE__ */
|
|
5327
|
-
/* @__PURE__ */ jsxs33(
|
|
5444
|
+
/* @__PURE__ */ jsx35(Text34, { bold: true, color: isActive ? COLORS.text : COLORS.textSecondary, children: t("sync_conflict_title", { package: conflict.packageName }) }),
|
|
5445
|
+
/* @__PURE__ */ jsxs33(Text34, { color: COLORS.muted, children: [
|
|
5328
5446
|
" (",
|
|
5329
5447
|
conflict.packageType,
|
|
5330
5448
|
")"
|
|
@@ -5332,7 +5450,7 @@ function ConflictsList({
|
|
|
5332
5450
|
] }),
|
|
5333
5451
|
/* @__PURE__ */ jsxs33(Box32, { marginLeft: SPACING.sm, flexDirection: "column", children: [
|
|
5334
5452
|
/* @__PURE__ */ jsxs33(
|
|
5335
|
-
|
|
5453
|
+
Text34,
|
|
5336
5454
|
{
|
|
5337
5455
|
color: resolution === "use-local" ? COLORS.success : COLORS.textSecondary,
|
|
5338
5456
|
children: [
|
|
@@ -5343,7 +5461,7 @@ function ConflictsList({
|
|
|
5343
5461
|
}
|
|
5344
5462
|
),
|
|
5345
5463
|
/* @__PURE__ */ jsxs33(
|
|
5346
|
-
|
|
5464
|
+
Text34,
|
|
5347
5465
|
{
|
|
5348
5466
|
color: resolution === "use-remote" ? COLORS.success : COLORS.textSecondary,
|
|
5349
5467
|
children: [
|
|
@@ -5356,7 +5474,7 @@ function ConflictsList({
|
|
|
5356
5474
|
] })
|
|
5357
5475
|
] }, `${conflict.packageName}-${conflict.remoteMachine}`);
|
|
5358
5476
|
}),
|
|
5359
|
-
/* @__PURE__ */
|
|
5477
|
+
/* @__PURE__ */ jsx35(Box32, { marginTop: SPACING.xs, children: /* @__PURE__ */ jsxs33(Text34, { color: COLORS.textSecondary, children: [
|
|
5360
5478
|
"j/k:",
|
|
5361
5479
|
t("hint_navigate"),
|
|
5362
5480
|
" l:",
|
|
@@ -5374,14 +5492,14 @@ function SyncView() {
|
|
|
5374
5492
|
const isPro = useLicenseStore((s) => s.isPro);
|
|
5375
5493
|
const navigate = useNavigationStore((s) => s.navigate);
|
|
5376
5494
|
const { config, lastResult, conflicts, loading, error, initialize, syncNow, resolveConflicts } = useSyncStore();
|
|
5377
|
-
const [phase, setPhase] =
|
|
5378
|
-
const [syncError, setSyncError] =
|
|
5379
|
-
const [conflictEntries, setConflictEntries] =
|
|
5380
|
-
const [cursor, setCursor] =
|
|
5381
|
-
|
|
5495
|
+
const [phase, setPhase] = useState18("overview");
|
|
5496
|
+
const [syncError, setSyncError] = useState18(null);
|
|
5497
|
+
const [conflictEntries, setConflictEntries] = useState18([]);
|
|
5498
|
+
const [cursor, setCursor] = useState18(0);
|
|
5499
|
+
useEffect21(() => {
|
|
5382
5500
|
void initialize(isPro());
|
|
5383
5501
|
}, []);
|
|
5384
|
-
|
|
5502
|
+
useEffect21(() => {
|
|
5385
5503
|
if (conflicts.length > 0) {
|
|
5386
5504
|
setConflictEntries(
|
|
5387
5505
|
conflicts.map((c) => ({ conflict: c, resolution: "pending" }))
|
|
@@ -5412,7 +5530,7 @@ function SyncView() {
|
|
|
5412
5530
|
await resolveConflicts(resolutions);
|
|
5413
5531
|
setPhase("result");
|
|
5414
5532
|
}, [conflictEntries, resolveConflicts]);
|
|
5415
|
-
|
|
5533
|
+
useViewInput((input, key) => {
|
|
5416
5534
|
if (phase === "syncing") return;
|
|
5417
5535
|
if (phase === "confirming-sync" || phase === "confirming-apply") return;
|
|
5418
5536
|
if (phase === "result") {
|
|
@@ -5454,26 +5572,26 @@ function SyncView() {
|
|
|
5454
5572
|
return;
|
|
5455
5573
|
}
|
|
5456
5574
|
}
|
|
5457
|
-
if (input === "s") {
|
|
5575
|
+
if (input === "s" || input === "1") {
|
|
5458
5576
|
setPhase("confirming-sync");
|
|
5459
5577
|
return;
|
|
5460
5578
|
}
|
|
5461
|
-
if (input === "c" && conflicts.length > 0) {
|
|
5579
|
+
if ((input === "c" || input === "3") && conflicts.length > 0) {
|
|
5462
5580
|
setCursor(0);
|
|
5463
5581
|
setPhase("conflicts");
|
|
5464
5582
|
return;
|
|
5465
5583
|
}
|
|
5466
|
-
if (input === "c" && lastResult?.success) {
|
|
5584
|
+
if ((input === "c" || input === "3") && lastResult?.success) {
|
|
5467
5585
|
navigate("compliance");
|
|
5468
5586
|
return;
|
|
5469
5587
|
}
|
|
5470
|
-
if (input === "r") {
|
|
5588
|
+
if (input === "r" || input === "2") {
|
|
5471
5589
|
void initialize(isPro());
|
|
5472
5590
|
return;
|
|
5473
5591
|
}
|
|
5474
5592
|
});
|
|
5475
5593
|
if (phase === "confirming-sync") {
|
|
5476
|
-
return /* @__PURE__ */
|
|
5594
|
+
return /* @__PURE__ */ jsx35(
|
|
5477
5595
|
ConfirmDialog,
|
|
5478
5596
|
{
|
|
5479
5597
|
message: t("confirm_sync_now"),
|
|
@@ -5487,7 +5605,7 @@ function SyncView() {
|
|
|
5487
5605
|
);
|
|
5488
5606
|
}
|
|
5489
5607
|
if (phase === "confirming-apply") {
|
|
5490
|
-
return /* @__PURE__ */
|
|
5608
|
+
return /* @__PURE__ */ jsx35(
|
|
5491
5609
|
ConfirmDialog,
|
|
5492
5610
|
{
|
|
5493
5611
|
message: t("confirm_sync_apply", { count: String(conflictEntries.length) }),
|
|
@@ -5501,20 +5619,20 @@ function SyncView() {
|
|
|
5501
5619
|
);
|
|
5502
5620
|
}
|
|
5503
5621
|
if (phase === "syncing" || loading) {
|
|
5504
|
-
return /* @__PURE__ */
|
|
5622
|
+
return /* @__PURE__ */ jsx35(Loading, { message: t("sync_syncing") });
|
|
5505
5623
|
}
|
|
5506
5624
|
if (phase === "result") {
|
|
5507
5625
|
const isError = !!(syncError ?? error);
|
|
5508
5626
|
return /* @__PURE__ */ jsxs33(Box32, { flexDirection: "column", marginTop: SPACING.xs, children: [
|
|
5509
|
-
/* @__PURE__ */
|
|
5510
|
-
/* @__PURE__ */
|
|
5627
|
+
/* @__PURE__ */ jsx35(SectionHeader, { emoji: "\u{1F504}", title: t("sync_title"), gradient: GRADIENTS.gold }),
|
|
5628
|
+
/* @__PURE__ */ jsx35(Box32, { marginTop: SPACING.xs, children: /* @__PURE__ */ jsx35(
|
|
5511
5629
|
ResultBanner,
|
|
5512
5630
|
{
|
|
5513
5631
|
status: isError ? "error" : "success",
|
|
5514
5632
|
message: isError ? t("sync_error", { error: syncError ?? error ?? "" }) : t("sync_success")
|
|
5515
5633
|
}
|
|
5516
5634
|
) }),
|
|
5517
|
-
/* @__PURE__ */
|
|
5635
|
+
/* @__PURE__ */ jsx35(Box32, { marginTop: SPACING.xs, children: /* @__PURE__ */ jsxs33(Text34, { color: COLORS.textSecondary, children: [
|
|
5518
5636
|
"r:",
|
|
5519
5637
|
t("hint_refresh"),
|
|
5520
5638
|
" esc:",
|
|
@@ -5523,9 +5641,9 @@ function SyncView() {
|
|
|
5523
5641
|
] });
|
|
5524
5642
|
}
|
|
5525
5643
|
return /* @__PURE__ */ jsxs33(Box32, { flexDirection: "column", children: [
|
|
5526
|
-
/* @__PURE__ */
|
|
5527
|
-
error && phase === "overview" && /* @__PURE__ */
|
|
5528
|
-
phase === "overview" && /* @__PURE__ */
|
|
5644
|
+
/* @__PURE__ */ jsx35(SectionHeader, { emoji: "\u{1F504}", title: t("sync_title"), gradient: GRADIENTS.gold }),
|
|
5645
|
+
error && phase === "overview" && /* @__PURE__ */ jsx35(Box32, { marginTop: SPACING.xs, children: /* @__PURE__ */ jsx35(ResultBanner, { status: "error", message: t("sync_error", { error }) }) }),
|
|
5646
|
+
phase === "overview" && /* @__PURE__ */ jsx35(
|
|
5529
5647
|
OverviewSection,
|
|
5530
5648
|
{
|
|
5531
5649
|
config,
|
|
@@ -5539,15 +5657,15 @@ function SyncView() {
|
|
|
5539
5657
|
}
|
|
5540
5658
|
),
|
|
5541
5659
|
phase === "conflicts" && /* @__PURE__ */ jsxs33(Box32, { flexDirection: "column", children: [
|
|
5542
|
-
/* @__PURE__ */
|
|
5543
|
-
/* @__PURE__ */
|
|
5660
|
+
/* @__PURE__ */ jsx35(SectionHeader, { emoji: "\u26A0", title: t("sync_status_conflict", { count: String(conflictEntries.length) }), gradient: GRADIENTS.gold }),
|
|
5661
|
+
/* @__PURE__ */ jsx35(ConflictsList, { entries: conflictEntries, cursor })
|
|
5544
5662
|
] })
|
|
5545
5663
|
] });
|
|
5546
5664
|
}
|
|
5547
5665
|
|
|
5548
5666
|
// src/views/compliance.tsx
|
|
5549
|
-
import { useCallback as useCallback6, useEffect as
|
|
5550
|
-
import { Box as Box33, Text as
|
|
5667
|
+
import { useCallback as useCallback6, useEffect as useEffect22, useRef as useRef11, useState as useState19 } from "react";
|
|
5668
|
+
import { Box as Box33, Text as Text35 } from "ink";
|
|
5551
5669
|
import { TextInput as TextInput7 } from "@inkjs/ui";
|
|
5552
5670
|
|
|
5553
5671
|
// src/lib/compliance/compliance-remediator.ts
|
|
@@ -5592,27 +5710,27 @@ async function* remediateViolations(violations, isPro) {
|
|
|
5592
5710
|
|
|
5593
5711
|
// src/views/compliance.tsx
|
|
5594
5712
|
import { join as join4 } from "path";
|
|
5595
|
-
import { jsx as
|
|
5713
|
+
import { jsx as jsx36, jsxs as jsxs34 } from "react/jsx-runtime";
|
|
5596
5714
|
function ComplianceScore({ report }) {
|
|
5597
5715
|
const color = report.score >= 80 ? COLORS.success : report.score >= 50 ? COLORS.warning : COLORS.error;
|
|
5598
5716
|
const bars = Math.round(report.score / 10);
|
|
5599
5717
|
return /* @__PURE__ */ jsxs34(Box33, { flexDirection: "column", marginBottom: SPACING.xs, children: [
|
|
5600
5718
|
/* @__PURE__ */ jsxs34(Box33, { children: [
|
|
5601
|
-
/* @__PURE__ */ jsxs34(
|
|
5719
|
+
/* @__PURE__ */ jsxs34(Text35, { color, children: [
|
|
5602
5720
|
"\u2593".repeat(bars),
|
|
5603
5721
|
"\u2591".repeat(10 - bars)
|
|
5604
5722
|
] }),
|
|
5605
|
-
/* @__PURE__ */ jsxs34(
|
|
5723
|
+
/* @__PURE__ */ jsxs34(Text35, { color, bold: true, children: [
|
|
5606
5724
|
" ",
|
|
5607
5725
|
report.score,
|
|
5608
5726
|
"%"
|
|
5609
5727
|
] }),
|
|
5610
|
-
/* @__PURE__ */ jsxs34(
|
|
5728
|
+
/* @__PURE__ */ jsxs34(Text35, { color: COLORS.textSecondary, children: [
|
|
5611
5729
|
" ",
|
|
5612
5730
|
t("compliance_score", { score: String(report.score) })
|
|
5613
5731
|
] })
|
|
5614
5732
|
] }),
|
|
5615
|
-
/* @__PURE__ */ jsxs34(
|
|
5733
|
+
/* @__PURE__ */ jsxs34(Text35, { color: COLORS.muted, dimColor: true, children: [
|
|
5616
5734
|
t("compliance_policy_name", { name: report.policyName }),
|
|
5617
5735
|
" \xB7 ",
|
|
5618
5736
|
t("compliance_machine", { name: report.machineName })
|
|
@@ -5623,11 +5741,11 @@ function ViolationItem({ violation }) {
|
|
|
5623
5741
|
const color = violation.severity === "error" ? COLORS.error : COLORS.warning;
|
|
5624
5742
|
const prefix = violation.severity === "error" ? "\u2717" : "\u26A0";
|
|
5625
5743
|
return /* @__PURE__ */ jsxs34(Box33, { marginBottom: SPACING.none, children: [
|
|
5626
|
-
/* @__PURE__ */ jsxs34(
|
|
5744
|
+
/* @__PURE__ */ jsxs34(Text35, { color, children: [
|
|
5627
5745
|
prefix,
|
|
5628
5746
|
" "
|
|
5629
5747
|
] }),
|
|
5630
|
-
/* @__PURE__ */
|
|
5748
|
+
/* @__PURE__ */ jsx36(Text35, { color, children: violation.detail })
|
|
5631
5749
|
] });
|
|
5632
5750
|
}
|
|
5633
5751
|
function ViolationList({ violations }) {
|
|
@@ -5635,31 +5753,31 @@ function ViolationList({ violations }) {
|
|
|
5635
5753
|
const warnings = violations.filter((v) => v.severity === "warning");
|
|
5636
5754
|
return /* @__PURE__ */ jsxs34(Box33, { flexDirection: "column", marginTop: SPACING.xs, children: [
|
|
5637
5755
|
errors.length > 0 && /* @__PURE__ */ jsxs34(Box33, { flexDirection: "column", marginBottom: SPACING.xs, children: [
|
|
5638
|
-
/* @__PURE__ */ jsxs34(
|
|
5756
|
+
/* @__PURE__ */ jsxs34(Text35, { color: COLORS.error, bold: true, children: [
|
|
5639
5757
|
t("compliance_violations", { count: String(errors.length) }),
|
|
5640
5758
|
" (errors)"
|
|
5641
5759
|
] }),
|
|
5642
|
-
errors.map((v) => /* @__PURE__ */
|
|
5760
|
+
errors.map((v) => /* @__PURE__ */ jsx36(ViolationItem, { violation: v }, `${v.type}-${v.packageName}`))
|
|
5643
5761
|
] }),
|
|
5644
5762
|
warnings.length > 0 && /* @__PURE__ */ jsxs34(Box33, { flexDirection: "column", children: [
|
|
5645
|
-
/* @__PURE__ */ jsxs34(
|
|
5763
|
+
/* @__PURE__ */ jsxs34(Text35, { color: COLORS.warning, bold: true, children: [
|
|
5646
5764
|
t("compliance_violations", { count: String(warnings.length) }),
|
|
5647
5765
|
" (warnings)"
|
|
5648
5766
|
] }),
|
|
5649
|
-
warnings.map((v) => /* @__PURE__ */
|
|
5767
|
+
warnings.map((v) => /* @__PURE__ */ jsx36(ViolationItem, { violation: v }, `${v.type}-${v.packageName}`))
|
|
5650
5768
|
] })
|
|
5651
5769
|
] });
|
|
5652
5770
|
}
|
|
5653
5771
|
function ComplianceView() {
|
|
5654
5772
|
const isPro = useLicenseStore((s) => s.isPro);
|
|
5655
5773
|
const { policy, report, loading, error, importPolicy, runCheck } = useComplianceStore();
|
|
5656
|
-
const [phase, setPhase] =
|
|
5657
|
-
const [resultMessage, setResultMessage] =
|
|
5658
|
-
const [streamLines, setStreamLines] =
|
|
5659
|
-
const [streamRunning, setStreamRunning] =
|
|
5660
|
-
const generatorRef =
|
|
5661
|
-
const mountedRef =
|
|
5662
|
-
|
|
5774
|
+
const [phase, setPhase] = useState19("overview");
|
|
5775
|
+
const [resultMessage, setResultMessage] = useState19(null);
|
|
5776
|
+
const [streamLines, setStreamLines] = useState19([]);
|
|
5777
|
+
const [streamRunning, setStreamRunning] = useState19(false);
|
|
5778
|
+
const generatorRef = useRef11(null);
|
|
5779
|
+
const mountedRef = useRef11(true);
|
|
5780
|
+
useEffect22(() => {
|
|
5663
5781
|
mountedRef.current = true;
|
|
5664
5782
|
return () => {
|
|
5665
5783
|
mountedRef.current = false;
|
|
@@ -5735,7 +5853,7 @@ function ComplianceView() {
|
|
|
5735
5853
|
}
|
|
5736
5854
|
}
|
|
5737
5855
|
}, [report, isPro, runCheck]);
|
|
5738
|
-
|
|
5856
|
+
useViewInput((input, key) => {
|
|
5739
5857
|
if (phase === "remediating" || phase === "importing") return;
|
|
5740
5858
|
if (phase === "confirming-remediate") return;
|
|
5741
5859
|
if (phase === "result") {
|
|
@@ -5745,19 +5863,19 @@ function ComplianceView() {
|
|
|
5745
5863
|
}
|
|
5746
5864
|
return;
|
|
5747
5865
|
}
|
|
5748
|
-
if (input === "i") {
|
|
5866
|
+
if (input === "i" || input === "2") {
|
|
5749
5867
|
setPhase("importing");
|
|
5750
5868
|
return;
|
|
5751
5869
|
}
|
|
5752
|
-
if (input === "r" && policy) {
|
|
5870
|
+
if ((input === "r" || input === "1") && policy) {
|
|
5753
5871
|
handleRecheck();
|
|
5754
5872
|
return;
|
|
5755
5873
|
}
|
|
5756
|
-
if (input === "e" && report) {
|
|
5874
|
+
if ((input === "e" || input === "3") && report) {
|
|
5757
5875
|
void handleExport();
|
|
5758
5876
|
return;
|
|
5759
5877
|
}
|
|
5760
|
-
if (input === "c" && report) {
|
|
5878
|
+
if ((input === "c" || input === "4") && report) {
|
|
5761
5879
|
const actionable = report.violations.filter(
|
|
5762
5880
|
(v) => v.type === "missing" || v.type === "wrong-version"
|
|
5763
5881
|
);
|
|
@@ -5771,7 +5889,7 @@ function ComplianceView() {
|
|
|
5771
5889
|
const actionable = report.violations.filter(
|
|
5772
5890
|
(v) => v.type === "missing" || v.type === "wrong-version"
|
|
5773
5891
|
);
|
|
5774
|
-
return /* @__PURE__ */
|
|
5892
|
+
return /* @__PURE__ */ jsx36(
|
|
5775
5893
|
ConfirmDialog,
|
|
5776
5894
|
{
|
|
5777
5895
|
message: t("confirm_compliance_remediate", { count: String(actionable.length) }),
|
|
@@ -5787,23 +5905,23 @@ function ComplianceView() {
|
|
|
5787
5905
|
if (phase === "remediating" || loading && phase !== "importing") {
|
|
5788
5906
|
if (phase === "remediating") {
|
|
5789
5907
|
return /* @__PURE__ */ jsxs34(Box33, { flexDirection: "column", children: [
|
|
5790
|
-
/* @__PURE__ */
|
|
5791
|
-
/* @__PURE__ */
|
|
5908
|
+
/* @__PURE__ */ jsx36(SectionHeader, { emoji: "\u{1F50D}", title: t("compliance_title"), gradient: GRADIENTS.gold }),
|
|
5909
|
+
/* @__PURE__ */ jsx36(Box33, { marginTop: SPACING.xs, children: /* @__PURE__ */ jsx36(ProgressLog, { lines: streamLines, isRunning: streamRunning, title: t("compliance_remediating") }) })
|
|
5792
5910
|
] });
|
|
5793
5911
|
}
|
|
5794
|
-
return /* @__PURE__ */
|
|
5912
|
+
return /* @__PURE__ */ jsx36(Loading, { message: t("compliance_title") });
|
|
5795
5913
|
}
|
|
5796
5914
|
if (phase === "result" && resultMessage) {
|
|
5797
5915
|
return /* @__PURE__ */ jsxs34(Box33, { flexDirection: "column", marginTop: SPACING.xs, children: [
|
|
5798
|
-
/* @__PURE__ */
|
|
5799
|
-
/* @__PURE__ */
|
|
5916
|
+
/* @__PURE__ */ jsx36(SectionHeader, { emoji: "\u{1F50D}", title: t("compliance_title"), gradient: GRADIENTS.gold }),
|
|
5917
|
+
/* @__PURE__ */ jsx36(Box33, { marginTop: SPACING.xs, children: /* @__PURE__ */ jsx36(
|
|
5800
5918
|
ResultBanner,
|
|
5801
5919
|
{
|
|
5802
5920
|
status: resultMessage.ok ? "success" : "error",
|
|
5803
5921
|
message: resultMessage.text
|
|
5804
5922
|
}
|
|
5805
5923
|
) }),
|
|
5806
|
-
/* @__PURE__ */
|
|
5924
|
+
/* @__PURE__ */ jsx36(Box33, { marginTop: SPACING.xs, children: /* @__PURE__ */ jsxs34(Text35, { color: COLORS.textSecondary, children: [
|
|
5807
5925
|
"r:",
|
|
5808
5926
|
t("hint_refresh"),
|
|
5809
5927
|
" esc:",
|
|
@@ -5812,11 +5930,11 @@ function ComplianceView() {
|
|
|
5812
5930
|
] });
|
|
5813
5931
|
}
|
|
5814
5932
|
return /* @__PURE__ */ jsxs34(Box33, { flexDirection: "column", children: [
|
|
5815
|
-
/* @__PURE__ */
|
|
5816
|
-
error && /* @__PURE__ */
|
|
5933
|
+
/* @__PURE__ */ jsx36(SectionHeader, { emoji: "\u{1F50D}", title: t("compliance_title"), gradient: GRADIENTS.gold }),
|
|
5934
|
+
error && /* @__PURE__ */ jsx36(Box33, { marginTop: SPACING.xs, children: /* @__PURE__ */ jsx36(ResultBanner, { status: "error", message: t("compliance_import_error", { error }) }) }),
|
|
5817
5935
|
phase === "importing" && /* @__PURE__ */ jsxs34(Box33, { marginTop: SPACING.xs, flexDirection: "column", children: [
|
|
5818
|
-
/* @__PURE__ */
|
|
5819
|
-
/* @__PURE__ */
|
|
5936
|
+
/* @__PURE__ */ jsx36(Text35, { color: COLORS.textSecondary, children: t("compliance_import_prompt") }),
|
|
5937
|
+
/* @__PURE__ */ jsx36(Box33, { marginTop: SPACING.xs, children: /* @__PURE__ */ jsx36(
|
|
5820
5938
|
TextInput7,
|
|
5821
5939
|
{
|
|
5822
5940
|
defaultValue: "",
|
|
@@ -5825,31 +5943,31 @@ function ComplianceView() {
|
|
|
5825
5943
|
}
|
|
5826
5944
|
}
|
|
5827
5945
|
) }),
|
|
5828
|
-
/* @__PURE__ */
|
|
5946
|
+
/* @__PURE__ */ jsx36(Box33, { marginTop: SPACING.xs, children: /* @__PURE__ */ jsxs34(Text35, { color: COLORS.muted, dimColor: true, children: [
|
|
5829
5947
|
"esc:",
|
|
5830
5948
|
t("hint_back")
|
|
5831
5949
|
] }) })
|
|
5832
5950
|
] }),
|
|
5833
5951
|
phase === "overview" && /* @__PURE__ */ jsxs34(Box33, { flexDirection: "column", marginTop: SPACING.xs, children: [
|
|
5834
|
-
!policy ? /* @__PURE__ */
|
|
5835
|
-
/* @__PURE__ */
|
|
5952
|
+
!policy ? /* @__PURE__ */ jsx36(Box33, { flexDirection: "column", children: /* @__PURE__ */ jsx36(Text35, { color: COLORS.textSecondary, children: t("compliance_no_policy") }) }) : /* @__PURE__ */ jsxs34(Box33, { flexDirection: "column", children: [
|
|
5953
|
+
/* @__PURE__ */ jsx36(Text35, { color: COLORS.textSecondary, bold: true, children: t("compliance_policy_by", { maintainer: policy.meta.maintainer }) }),
|
|
5836
5954
|
report ? /* @__PURE__ */ jsxs34(Box33, { flexDirection: "column", marginTop: SPACING.xs, children: [
|
|
5837
|
-
/* @__PURE__ */
|
|
5838
|
-
report.compliant ? /* @__PURE__ */
|
|
5839
|
-
] }) : /* @__PURE__ */
|
|
5955
|
+
/* @__PURE__ */ jsx36(ComplianceScore, { report }),
|
|
5956
|
+
report.compliant ? /* @__PURE__ */ jsx36(ResultBanner, { status: "success", message: t("compliance_ok") }) : /* @__PURE__ */ jsx36(ViolationList, { violations: report.violations })
|
|
5957
|
+
] }) : /* @__PURE__ */ jsx36(Box33, { marginTop: SPACING.xs, children: /* @__PURE__ */ jsx36(Text35, { color: COLORS.muted, dimColor: true, children: t("compliance_press_r_hint") }) })
|
|
5840
5958
|
] }),
|
|
5841
|
-
/* @__PURE__ */
|
|
5959
|
+
/* @__PURE__ */ jsx36(Box33, { marginTop: SPACING.sm, flexWrap: "wrap", children: /* @__PURE__ */ jsxs34(Text35, { color: COLORS.textSecondary, children: [
|
|
5842
5960
|
"i:",
|
|
5843
5961
|
t("hint_import"),
|
|
5844
|
-
policy && /* @__PURE__ */ jsxs34(
|
|
5962
|
+
policy && /* @__PURE__ */ jsxs34(Text35, { children: [
|
|
5845
5963
|
" r:",
|
|
5846
5964
|
t("hint_scan")
|
|
5847
5965
|
] }),
|
|
5848
|
-
report && /* @__PURE__ */ jsxs34(
|
|
5966
|
+
report && /* @__PURE__ */ jsxs34(Text35, { children: [
|
|
5849
5967
|
" e:",
|
|
5850
5968
|
t("hint_export")
|
|
5851
5969
|
] }),
|
|
5852
|
-
report && report.violations.some((v) => v.type === "missing" || v.type === "wrong-version") && /* @__PURE__ */ jsxs34(
|
|
5970
|
+
report && report.violations.some((v) => v.type === "missing" || v.type === "wrong-version") && /* @__PURE__ */ jsxs34(Text35, { children: [
|
|
5853
5971
|
" c:",
|
|
5854
5972
|
t("hint_clean")
|
|
5855
5973
|
] }),
|
|
@@ -5861,10 +5979,10 @@ function ComplianceView() {
|
|
|
5861
5979
|
}
|
|
5862
5980
|
|
|
5863
5981
|
// src/app.tsx
|
|
5864
|
-
import { Fragment as Fragment7, jsx as
|
|
5982
|
+
import { Fragment as Fragment7, jsx as jsx37, jsxs as jsxs35 } from "react/jsx-runtime";
|
|
5865
5983
|
function LicenseInitializer() {
|
|
5866
5984
|
const initLicense = useLicenseStore((s) => s.initialize);
|
|
5867
|
-
|
|
5985
|
+
useEffect23(() => {
|
|
5868
5986
|
initLicense();
|
|
5869
5987
|
}, []);
|
|
5870
5988
|
return null;
|
|
@@ -5873,65 +5991,65 @@ function ViewRouter({ currentView }) {
|
|
|
5873
5991
|
const isPro = useLicenseStore((s) => s.isPro);
|
|
5874
5992
|
const isTeam = useLicenseStore((s) => s.isTeam);
|
|
5875
5993
|
if (isProView(currentView) && !isPro()) {
|
|
5876
|
-
return /* @__PURE__ */
|
|
5994
|
+
return /* @__PURE__ */ jsx37(UpgradePrompt, { viewId: currentView });
|
|
5877
5995
|
}
|
|
5878
5996
|
if (isTeamView(currentView) && !isTeam()) {
|
|
5879
|
-
return /* @__PURE__ */
|
|
5997
|
+
return /* @__PURE__ */ jsx37(UpgradePrompt, { viewId: currentView });
|
|
5880
5998
|
}
|
|
5881
5999
|
switch (currentView) {
|
|
5882
6000
|
case "dashboard":
|
|
5883
|
-
return /* @__PURE__ */
|
|
6001
|
+
return /* @__PURE__ */ jsx37(DashboardView, {});
|
|
5884
6002
|
case "installed":
|
|
5885
|
-
return /* @__PURE__ */
|
|
6003
|
+
return /* @__PURE__ */ jsx37(InstalledView, {});
|
|
5886
6004
|
case "search":
|
|
5887
|
-
return /* @__PURE__ */
|
|
6005
|
+
return /* @__PURE__ */ jsx37(SearchView, {});
|
|
5888
6006
|
case "outdated":
|
|
5889
|
-
return /* @__PURE__ */
|
|
6007
|
+
return /* @__PURE__ */ jsx37(OutdatedView, {});
|
|
5890
6008
|
case "package-info":
|
|
5891
|
-
return /* @__PURE__ */
|
|
6009
|
+
return /* @__PURE__ */ jsx37(PackageInfoView, {});
|
|
5892
6010
|
case "services":
|
|
5893
|
-
return /* @__PURE__ */
|
|
6011
|
+
return /* @__PURE__ */ jsx37(ServicesView, {});
|
|
5894
6012
|
case "doctor":
|
|
5895
|
-
return /* @__PURE__ */
|
|
6013
|
+
return /* @__PURE__ */ jsx37(DoctorView, {});
|
|
5896
6014
|
case "profiles":
|
|
5897
|
-
return /* @__PURE__ */
|
|
6015
|
+
return /* @__PURE__ */ jsx37(ProfilesView, {});
|
|
5898
6016
|
case "smart-cleanup":
|
|
5899
|
-
return /* @__PURE__ */
|
|
6017
|
+
return /* @__PURE__ */ jsx37(SmartCleanupView, {});
|
|
5900
6018
|
case "history":
|
|
5901
|
-
return /* @__PURE__ */
|
|
6019
|
+
return /* @__PURE__ */ jsx37(HistoryView, {});
|
|
5902
6020
|
case "rollback":
|
|
5903
|
-
return /* @__PURE__ */
|
|
6021
|
+
return /* @__PURE__ */ jsx37(RollbackView, {});
|
|
5904
6022
|
case "brewfile":
|
|
5905
|
-
return /* @__PURE__ */
|
|
6023
|
+
return /* @__PURE__ */ jsx37(BrewfileView, {});
|
|
5906
6024
|
case "sync":
|
|
5907
|
-
return /* @__PURE__ */
|
|
6025
|
+
return /* @__PURE__ */ jsx37(SyncView, {});
|
|
5908
6026
|
case "security-audit":
|
|
5909
|
-
return /* @__PURE__ */
|
|
6027
|
+
return /* @__PURE__ */ jsx37(SecurityAuditView, {});
|
|
5910
6028
|
case "compliance":
|
|
5911
|
-
return /* @__PURE__ */
|
|
6029
|
+
return /* @__PURE__ */ jsx37(ComplianceView, {});
|
|
5912
6030
|
case "account":
|
|
5913
|
-
return /* @__PURE__ */
|
|
6031
|
+
return /* @__PURE__ */ jsx37(AccountView, {});
|
|
5914
6032
|
}
|
|
5915
6033
|
}
|
|
5916
6034
|
function App() {
|
|
5917
6035
|
const { exit } = useApp();
|
|
5918
6036
|
const currentView = useNavigationStore((s) => s.currentView);
|
|
5919
6037
|
const isTestEnv = typeof process !== "undefined" && false;
|
|
5920
|
-
const [showWelcome, setShowWelcome] =
|
|
5921
|
-
|
|
6038
|
+
const [showWelcome, setShowWelcome] = useState20(isTestEnv ? false : null);
|
|
6039
|
+
useEffect23(() => {
|
|
5922
6040
|
if (isTestEnv) return;
|
|
5923
6041
|
void hasCompletedOnboarding().then((done) => setShowWelcome(!done));
|
|
5924
6042
|
}, []);
|
|
5925
6043
|
useGlobalKeyboard({ onQuit: exit });
|
|
5926
6044
|
if (showWelcome === null) {
|
|
5927
|
-
return /* @__PURE__ */
|
|
6045
|
+
return /* @__PURE__ */ jsx37(AppLayout, { children: /* @__PURE__ */ jsx37(Fragment7, {}) });
|
|
5928
6046
|
}
|
|
5929
6047
|
if (showWelcome) {
|
|
5930
|
-
return /* @__PURE__ */
|
|
6048
|
+
return /* @__PURE__ */ jsx37(AppLayout, { children: /* @__PURE__ */ jsx37(WelcomeView, { onContinue: () => setShowWelcome(false) }) });
|
|
5931
6049
|
}
|
|
5932
6050
|
return /* @__PURE__ */ jsxs35(AppLayout, { children: [
|
|
5933
|
-
/* @__PURE__ */
|
|
5934
|
-
/* @__PURE__ */
|
|
6051
|
+
/* @__PURE__ */ jsx37(LicenseInitializer, {}),
|
|
6052
|
+
/* @__PURE__ */ jsx37(ViewRouter, { currentView })
|
|
5935
6053
|
] });
|
|
5936
6054
|
}
|
|
5937
6055
|
|
|
@@ -6015,7 +6133,7 @@ async function reportError(err, context = {}) {
|
|
|
6015
6133
|
const config = await resolveConfig();
|
|
6016
6134
|
if (!config.enabled || !config.endpoint) return;
|
|
6017
6135
|
const machineId = await getMachineId();
|
|
6018
|
-
const version = true ? "0.
|
|
6136
|
+
const version = true ? "0.9.1" : "unknown";
|
|
6019
6137
|
await postReport(buildReport("error", err, context, machineId, version), config);
|
|
6020
6138
|
}
|
|
6021
6139
|
async function installCrashReporter() {
|
|
@@ -6024,7 +6142,7 @@ async function installCrashReporter() {
|
|
|
6024
6142
|
if (!config.enabled || !config.endpoint) return;
|
|
6025
6143
|
_installed = true;
|
|
6026
6144
|
const machineId = await getMachineId();
|
|
6027
|
-
const version = true ? "0.
|
|
6145
|
+
const version = true ? "0.9.1" : "unknown";
|
|
6028
6146
|
process.on("uncaughtException", (err) => {
|
|
6029
6147
|
void postReport(buildReport("fatal", err, { kind: "uncaughtException" }, machineId, version), config);
|
|
6030
6148
|
});
|
|
@@ -6035,11 +6153,11 @@ async function installCrashReporter() {
|
|
|
6035
6153
|
}
|
|
6036
6154
|
|
|
6037
6155
|
// src/index.tsx
|
|
6038
|
-
import { jsx as
|
|
6156
|
+
import { jsx as jsx38 } from "react/jsx-runtime";
|
|
6039
6157
|
var [, , command, arg] = process.argv;
|
|
6040
6158
|
async function runCli() {
|
|
6041
6159
|
if (command === "--version" || command === "-v" || command === "version") {
|
|
6042
|
-
process.stdout.write("0.
|
|
6160
|
+
process.stdout.write("0.9.1\n");
|
|
6043
6161
|
return;
|
|
6044
6162
|
}
|
|
6045
6163
|
await ensureDataDirs();
|
|
@@ -6134,7 +6252,7 @@ async function runCli() {
|
|
|
6134
6252
|
}
|
|
6135
6253
|
if (isPro) {
|
|
6136
6254
|
try {
|
|
6137
|
-
const { loadSnapshots: loadSnapshots2 } = await import("./snapshot-
|
|
6255
|
+
const { loadSnapshots: loadSnapshots2 } = await import("./snapshot-ZOJETCED.js");
|
|
6138
6256
|
const snapshots = await loadSnapshots2();
|
|
6139
6257
|
if (snapshots.length > 0) {
|
|
6140
6258
|
const latest = snapshots[0];
|
|
@@ -6146,7 +6264,7 @@ Snapshots: ${snapshots.length} (latest: ${latest ? formatDate(latest.capturedAt)
|
|
|
6146
6264
|
} catch {
|
|
6147
6265
|
}
|
|
6148
6266
|
try {
|
|
6149
|
-
const { loadBrewfile: loadBrewfile2, computeDrift: computeDrift2 } = await import("./brewfile-manager-
|
|
6267
|
+
const { loadBrewfile: loadBrewfile2, computeDrift: computeDrift2 } = await import("./brewfile-manager-G7Q4IOG3.js");
|
|
6150
6268
|
const schema = await loadBrewfile2();
|
|
6151
6269
|
if (schema) {
|
|
6152
6270
|
const drift = await computeDrift2(schema);
|
|
@@ -6155,7 +6273,7 @@ Snapshots: ${snapshots.length} (latest: ${latest ? formatDate(latest.capturedAt)
|
|
|
6155
6273
|
} catch {
|
|
6156
6274
|
}
|
|
6157
6275
|
try {
|
|
6158
|
-
const { loadSyncConfig: loadSyncConfig2 } = await import("./sync-engine-
|
|
6276
|
+
const { loadSyncConfig: loadSyncConfig2 } = await import("./sync-engine-76YMONYH.js");
|
|
6159
6277
|
const syncConfig = await loadSyncConfig2();
|
|
6160
6278
|
if (syncConfig?.lastSync) {
|
|
6161
6279
|
console.log(`Sync: last sync ${formatDate(syncConfig.lastSync)}`);
|
|
@@ -6164,7 +6282,7 @@ Snapshots: ${snapshots.length} (latest: ${latest ? formatDate(latest.capturedAt)
|
|
|
6164
6282
|
}
|
|
6165
6283
|
try {
|
|
6166
6284
|
const { loadPolicy: loadPolicy2 } = await import("./policy-io-EECGRKNA.js");
|
|
6167
|
-
const { checkCompliance: checkCompliance2 } = await import("./compliance-checker-
|
|
6285
|
+
const { checkCompliance: checkCompliance2 } = await import("./compliance-checker-IXZHIMQG.js");
|
|
6168
6286
|
const policy = await loadPolicy2(`${process.env["HOME"] ?? "~"}/.brew-tui/policy.yaml`).catch(() => null);
|
|
6169
6287
|
if (policy) {
|
|
6170
6288
|
const report = await checkCompliance2(policy, true);
|
|
@@ -6178,7 +6296,7 @@ Snapshots: ${snapshots.length} (latest: ${latest ? formatDate(latest.capturedAt)
|
|
|
6178
6296
|
if (command === "install-brewbar") {
|
|
6179
6297
|
await useLicenseStore.getState().initialize();
|
|
6180
6298
|
const isPro = useLicenseStore.getState().isPro();
|
|
6181
|
-
const { installBrewBar } = await import("./brewbar-installer-
|
|
6299
|
+
const { installBrewBar } = await import("./brewbar-installer-V6R7BORH.js");
|
|
6182
6300
|
try {
|
|
6183
6301
|
await installBrewBar(isPro, arg === "--force");
|
|
6184
6302
|
console.log(t("cli_brewbarInstalled"));
|
|
@@ -6189,7 +6307,7 @@ Snapshots: ${snapshots.length} (latest: ${latest ? formatDate(latest.capturedAt)
|
|
|
6189
6307
|
return;
|
|
6190
6308
|
}
|
|
6191
6309
|
if (command === "uninstall-brewbar") {
|
|
6192
|
-
const { uninstallBrewBar } = await import("./brewbar-installer-
|
|
6310
|
+
const { uninstallBrewBar } = await import("./brewbar-installer-V6R7BORH.js");
|
|
6193
6311
|
try {
|
|
6194
6312
|
await uninstallBrewBar();
|
|
6195
6313
|
console.log(t("cli_brewbarUninstalled"));
|
|
@@ -6214,14 +6332,14 @@ Snapshots: ${snapshots.length} (latest: ${latest ? formatDate(latest.capturedAt)
|
|
|
6214
6332
|
await ensureBrewBarRunning();
|
|
6215
6333
|
process.env.BREW_TUI_TUI_MODE = "1";
|
|
6216
6334
|
process.stdout.write("\x1B[2J\x1B[3J\x1B[H");
|
|
6217
|
-
render(/* @__PURE__ */
|
|
6335
|
+
render(/* @__PURE__ */ jsx38(App, {}));
|
|
6218
6336
|
}
|
|
6219
6337
|
async function ensureBrewBarRunning() {
|
|
6220
6338
|
if (process.platform !== "darwin") return;
|
|
6221
6339
|
await useLicenseStore.getState().initialize();
|
|
6222
6340
|
if (!useLicenseStore.getState().isPro()) return;
|
|
6223
|
-
const { isBrewBarInstalled, installBrewBar, launchBrewBar } = await import("./brewbar-installer-
|
|
6224
|
-
const { checkBrewBarVersion } = await import("./version-check-
|
|
6341
|
+
const { isBrewBarInstalled, installBrewBar, launchBrewBar } = await import("./brewbar-installer-V6R7BORH.js");
|
|
6342
|
+
const { checkBrewBarVersion } = await import("./version-check-X3HTR3HM.js");
|
|
6225
6343
|
try {
|
|
6226
6344
|
if (!await isBrewBarInstalled()) {
|
|
6227
6345
|
console.log(t("cli_brewbarInstalling"));
|