brew-tui 1.2.0 → 1.2.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/build/{brewbar-installer-GWJ76J6G.js → brewbar-installer-BKE6Z7OI.js} +5 -3
- package/build/{brewbar-installer-GWJ76J6G.js.map → brewbar-installer-BKE6Z7OI.js.map} +1 -1
- package/build/{brewfile-manager-G7Q4IOG3.js → brewfile-manager-CPVXIVZC.js} +4 -3
- package/build/{chunk-KN4GCMIE.js → chunk-5PJWI4XS.js} +20 -1
- package/build/chunk-5PJWI4XS.js.map +1 -0
- package/build/{chunk-BRXZG7ZL.js → chunk-CMIC4N74.js} +11 -3
- package/build/chunk-CMIC4N74.js.map +1 -0
- package/build/{chunk-KDKXGXN2.js → chunk-EDQPT5EF.js} +15 -8
- package/build/chunk-EDQPT5EF.js.map +1 -0
- package/build/{chunk-J6HCX7RG.js → chunk-JNEIP2LJ.js} +2 -2
- package/build/chunk-NRRQECXA.js +63 -0
- package/build/chunk-NRRQECXA.js.map +1 -0
- package/build/{chunk-WDRT6G63.js → chunk-WX7MPVPH.js} +6 -46
- package/build/chunk-WX7MPVPH.js.map +1 -0
- package/build/{chunk-QX5DEW3S.js → chunk-XI743B6D.js} +408 -2
- package/build/chunk-XI743B6D.js.map +1 -0
- package/build/{compliance-checker-IXZHIMQG.js → compliance-checker-3FDEX4OI.js} +3 -3
- package/build/index.js +299 -566
- package/build/index.js.map +1 -1
- package/build/{policy-io-EECGRKNA.js → policy-io-P5YIH6C7.js} +2 -2
- package/build/{snapshot-ZOJETCED.js → snapshot-RQ444U5L.js} +2 -2
- package/build/{sync-engine-76YMONYH.js → sync-engine-Q4B2PPQS.js} +5 -4
- package/build/{version-check-MJZDQG73.js → version-check-FKY5HGSI.js} +2 -2
- package/package.json +1 -1
- package/build/chunk-BRXZG7ZL.js.map +0 -1
- package/build/chunk-KDKXGXN2.js.map +0 -1
- package/build/chunk-KN4GCMIE.js.map +0 -1
- package/build/chunk-QX5DEW3S.js.map +0 -1
- package/build/chunk-WDRT6G63.js.map +0 -1
- /package/build/{brewfile-manager-G7Q4IOG3.js.map → brewfile-manager-CPVXIVZC.js.map} +0 -0
- /package/build/{chunk-J6HCX7RG.js.map → chunk-JNEIP2LJ.js.map} +0 -0
- /package/build/{compliance-checker-IXZHIMQG.js.map → compliance-checker-3FDEX4OI.js.map} +0 -0
- /package/build/{policy-io-EECGRKNA.js.map → policy-io-P5YIH6C7.js.map} +0 -0
- /package/build/{snapshot-ZOJETCED.js.map → snapshot-RQ444U5L.js.map} +0 -0
- /package/build/{sync-engine-76YMONYH.js.map → sync-engine-Q4B2PPQS.js.map} +0 -0
- /package/build/{version-check-MJZDQG73.js.map → version-check-FKY5HGSI.js.map} +0 -0
package/build/index.js
CHANGED
|
@@ -1,11 +1,30 @@
|
|
|
1
1
|
import {
|
|
2
|
+
brewUpdate,
|
|
3
|
+
casksToListItems,
|
|
2
4
|
computeDrift,
|
|
3
5
|
createDefaultBrewfile,
|
|
4
6
|
diffSnapshots,
|
|
7
|
+
formulaeFromCask,
|
|
8
|
+
formulaeToListItems,
|
|
9
|
+
getCaskInfo,
|
|
10
|
+
getConfig,
|
|
11
|
+
getDoctor,
|
|
12
|
+
getFormulaInfo,
|
|
13
|
+
getInstalled,
|
|
14
|
+
getLeaves,
|
|
15
|
+
getOutdated,
|
|
16
|
+
getServices,
|
|
17
|
+
getUpgradeImpact,
|
|
5
18
|
loadBrewfile,
|
|
19
|
+
pinPackage,
|
|
6
20
|
reconcile,
|
|
7
|
-
saveBrewfile
|
|
8
|
-
|
|
21
|
+
saveBrewfile,
|
|
22
|
+
search,
|
|
23
|
+
serviceAction,
|
|
24
|
+
uninstallPackage,
|
|
25
|
+
unpinPackage,
|
|
26
|
+
validatePackageName
|
|
27
|
+
} from "./chunk-XI743B6D.js";
|
|
9
28
|
import {
|
|
10
29
|
activate,
|
|
11
30
|
applyConflictResolutions,
|
|
@@ -19,21 +38,21 @@ import {
|
|
|
19
38
|
readSyncEnvelope,
|
|
20
39
|
revalidate,
|
|
21
40
|
sync
|
|
22
|
-
} from "./chunk-
|
|
41
|
+
} from "./chunk-EDQPT5EF.js";
|
|
23
42
|
import {
|
|
24
43
|
checkCompliance
|
|
25
|
-
} from "./chunk-
|
|
44
|
+
} from "./chunk-JNEIP2LJ.js";
|
|
26
45
|
import {
|
|
27
46
|
captureSnapshot,
|
|
28
47
|
execBrew,
|
|
29
48
|
loadSnapshots,
|
|
30
49
|
saveSnapshot,
|
|
31
50
|
streamBrew
|
|
32
|
-
} from "./chunk-
|
|
51
|
+
} from "./chunk-CMIC4N74.js";
|
|
33
52
|
import {
|
|
34
53
|
exportReport,
|
|
35
54
|
loadPolicy
|
|
36
|
-
} from "./chunk-
|
|
55
|
+
} from "./chunk-5PJWI4XS.js";
|
|
37
56
|
import {
|
|
38
57
|
appendEntry,
|
|
39
58
|
clearHistory,
|
|
@@ -49,13 +68,14 @@ import {
|
|
|
49
68
|
writeLastAction
|
|
50
69
|
} from "./chunk-IGDHDXUH.js";
|
|
51
70
|
import {
|
|
52
|
-
fetchWithRetry
|
|
53
|
-
|
|
71
|
+
fetchWithRetry
|
|
72
|
+
} from "./chunk-NRRQECXA.js";
|
|
73
|
+
import {
|
|
54
74
|
getLocale,
|
|
55
75
|
t,
|
|
56
76
|
tp,
|
|
57
77
|
useLocaleStore
|
|
58
|
-
} from "./chunk-
|
|
78
|
+
} from "./chunk-WX7MPVPH.js";
|
|
59
79
|
import {
|
|
60
80
|
logger
|
|
61
81
|
} from "./chunk-KDHEUNRI.js";
|
|
@@ -66,7 +86,7 @@ import { rm as rm2 } from "fs/promises";
|
|
|
66
86
|
import { render } from "ink";
|
|
67
87
|
|
|
68
88
|
// src/app.tsx
|
|
69
|
-
import { useEffect as
|
|
89
|
+
import { useEffect as useEffect22, useState as useState20 } from "react";
|
|
70
90
|
import { useApp } from "ink";
|
|
71
91
|
|
|
72
92
|
// src/components/layout/app-layout.tsx
|
|
@@ -77,28 +97,46 @@ import { Box as Box3 } from "ink";
|
|
|
77
97
|
import { Box, Text as Text3 } from "ink";
|
|
78
98
|
|
|
79
99
|
// src/hooks/use-terminal-size.ts
|
|
80
|
-
import {
|
|
100
|
+
import { useSyncExternalStore } from "react";
|
|
81
101
|
import { useStdout } from "ink";
|
|
102
|
+
var FALLBACK = { columns: 80, rows: 24 };
|
|
103
|
+
var cache = /* @__PURE__ */ new WeakMap();
|
|
104
|
+
function snapshot(stdout) {
|
|
105
|
+
return {
|
|
106
|
+
columns: stdout.columns ?? FALLBACK.columns,
|
|
107
|
+
rows: stdout.rows ?? FALLBACK.rows
|
|
108
|
+
};
|
|
109
|
+
}
|
|
110
|
+
function getCache(stdout) {
|
|
111
|
+
const existing = cache.get(stdout);
|
|
112
|
+
if (existing) return existing;
|
|
113
|
+
const entry = {
|
|
114
|
+
current: snapshot(stdout),
|
|
115
|
+
subscribers: /* @__PURE__ */ new Set()
|
|
116
|
+
};
|
|
117
|
+
cache.set(stdout, entry);
|
|
118
|
+
stdout.on("resize", () => {
|
|
119
|
+
entry.current = snapshot(stdout);
|
|
120
|
+
entry.subscribers.forEach((cb) => cb());
|
|
121
|
+
});
|
|
122
|
+
return entry;
|
|
123
|
+
}
|
|
82
124
|
function useTerminalSize() {
|
|
83
125
|
const { stdout } = useStdout();
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
stdout.off("resize", onResize);
|
|
99
|
-
};
|
|
100
|
-
}, [stdout]);
|
|
101
|
-
return size;
|
|
126
|
+
return useSyncExternalStore(
|
|
127
|
+
(cb) => {
|
|
128
|
+
if (!stdout) return () => {
|
|
129
|
+
};
|
|
130
|
+
const entry = getCache(stdout);
|
|
131
|
+
entry.subscribers.add(cb);
|
|
132
|
+
return () => {
|
|
133
|
+
entry.subscribers.delete(cb);
|
|
134
|
+
};
|
|
135
|
+
},
|
|
136
|
+
() => stdout ? getCache(stdout).current : FALLBACK,
|
|
137
|
+
// Server snapshot — not used in CLI, but useSyncExternalStore requires it.
|
|
138
|
+
() => FALLBACK
|
|
139
|
+
);
|
|
102
140
|
}
|
|
103
141
|
|
|
104
142
|
// src/stores/navigation-store.ts
|
|
@@ -322,21 +360,26 @@ var GRADIENTS = {
|
|
|
322
360
|
};
|
|
323
361
|
|
|
324
362
|
// src/components/common/blinking-text.tsx
|
|
325
|
-
import { useEffect
|
|
363
|
+
import { useEffect, useState } from "react";
|
|
326
364
|
import { Text as Text2 } from "ink";
|
|
327
365
|
import { jsx as jsx2 } from "react/jsx-runtime";
|
|
366
|
+
function shouldDisableBlink() {
|
|
367
|
+
return Boolean(process.env.NO_COLOR) || process.env.REDUCE_MOTION === "1" || process.env.ACCESSIBILITY_REDUCE_MOTION === "1";
|
|
368
|
+
}
|
|
328
369
|
function BlinkingText({
|
|
329
370
|
color,
|
|
330
371
|
intervalMs = 600,
|
|
331
372
|
bold = true,
|
|
332
373
|
children
|
|
333
374
|
}) {
|
|
334
|
-
const
|
|
335
|
-
|
|
375
|
+
const blinkDisabled = shouldDisableBlink();
|
|
376
|
+
const [bright, setBright] = useState(true);
|
|
377
|
+
useEffect(() => {
|
|
378
|
+
if (blinkDisabled) return;
|
|
336
379
|
const id = setInterval(() => setBright((b) => !b), intervalMs);
|
|
337
380
|
return () => clearInterval(id);
|
|
338
|
-
}, [intervalMs]);
|
|
339
|
-
return /* @__PURE__ */ jsx2(Text2, { color, bold, dimColor: !bright, children });
|
|
381
|
+
}, [intervalMs, blinkDisabled]);
|
|
382
|
+
return /* @__PURE__ */ jsx2(Text2, { color, bold, dimColor: !bright && !blinkDisabled, children });
|
|
340
383
|
}
|
|
341
384
|
|
|
342
385
|
// src/utils/spacing.ts
|
|
@@ -567,12 +610,12 @@ function Footer() {
|
|
|
567
610
|
}
|
|
568
611
|
|
|
569
612
|
// src/hooks/use-container-size.ts
|
|
570
|
-
import { useEffect as
|
|
613
|
+
import { useEffect as useEffect2, useState as useState2 } from "react";
|
|
571
614
|
import { measureElement } from "ink";
|
|
572
615
|
function useContainerSize(ref) {
|
|
573
616
|
const terminal = useTerminalSize();
|
|
574
|
-
const [size, setSize] =
|
|
575
|
-
|
|
617
|
+
const [size, setSize] = useState2({ width: 0, height: 0 });
|
|
618
|
+
useEffect2(() => {
|
|
576
619
|
if (!ref.current) return;
|
|
577
620
|
const measured = measureElement(ref.current);
|
|
578
621
|
setSize(
|
|
@@ -849,7 +892,7 @@ async function markOnboardingComplete() {
|
|
|
849
892
|
}
|
|
850
893
|
|
|
851
894
|
// src/views/welcome.tsx
|
|
852
|
-
import { useEffect as
|
|
895
|
+
import { useEffect as useEffect3 } from "react";
|
|
853
896
|
import { Box as Box4, Text as Text5 } from "ink";
|
|
854
897
|
|
|
855
898
|
// src/hooks/use-view-input.ts
|
|
@@ -863,7 +906,7 @@ function useViewInput(handler, opts) {
|
|
|
863
906
|
// src/views/welcome.tsx
|
|
864
907
|
import { jsx as jsx7, jsxs as jsxs4 } from "react/jsx-runtime";
|
|
865
908
|
function WelcomeView({ onContinue }) {
|
|
866
|
-
|
|
909
|
+
useEffect3(() => {
|
|
867
910
|
return () => {
|
|
868
911
|
};
|
|
869
912
|
}, []);
|
|
@@ -982,7 +1025,7 @@ function UpgradePrompt({ viewId }) {
|
|
|
982
1025
|
}
|
|
983
1026
|
|
|
984
1027
|
// src/views/dashboard.tsx
|
|
985
|
-
import { useEffect as
|
|
1028
|
+
import { useEffect as useEffect4, useMemo as useMemo2 } from "react";
|
|
986
1029
|
import { Box as Box9, Text as Text12 } from "ink";
|
|
987
1030
|
|
|
988
1031
|
// src/hooks/use-visible-rows.ts
|
|
@@ -999,372 +1042,6 @@ function useVisibleRows({
|
|
|
999
1042
|
|
|
1000
1043
|
// src/stores/brew-store.ts
|
|
1001
1044
|
import { create as create4 } from "zustand";
|
|
1002
|
-
|
|
1003
|
-
// src/lib/brew-api.ts
|
|
1004
|
-
import { spawn } from "child_process";
|
|
1005
|
-
|
|
1006
|
-
// src/lib/parsers/json-parser.ts
|
|
1007
|
-
function safeParse(raw, context) {
|
|
1008
|
-
try {
|
|
1009
|
-
const result = JSON.parse(raw);
|
|
1010
|
-
if (result === null || result === void 0) {
|
|
1011
|
-
throw new Error(`${context} returned null or empty response`);
|
|
1012
|
-
}
|
|
1013
|
-
return result;
|
|
1014
|
-
} catch (err) {
|
|
1015
|
-
throw new Error(`Failed to parse ${context} JSON: ${err instanceof Error ? err.message : String(err)}`, { cause: err });
|
|
1016
|
-
}
|
|
1017
|
-
}
|
|
1018
|
-
function parseInstalledJson(raw) {
|
|
1019
|
-
const data = safeParse(raw, "brew info --installed");
|
|
1020
|
-
return {
|
|
1021
|
-
formulae: Array.isArray(data.formulae) ? data.formulae : [],
|
|
1022
|
-
casks: Array.isArray(data.casks) ? data.casks : []
|
|
1023
|
-
};
|
|
1024
|
-
}
|
|
1025
|
-
function parseOutdatedJson(raw) {
|
|
1026
|
-
const data = safeParse(raw, "brew outdated");
|
|
1027
|
-
return {
|
|
1028
|
-
formulae: Array.isArray(data.formulae) ? data.formulae : [],
|
|
1029
|
-
casks: Array.isArray(data.casks) ? data.casks : []
|
|
1030
|
-
};
|
|
1031
|
-
}
|
|
1032
|
-
function parseServicesJson(raw) {
|
|
1033
|
-
const data = safeParse(raw, "brew services list");
|
|
1034
|
-
if (!Array.isArray(data)) return [];
|
|
1035
|
-
return data.map((s) => ({
|
|
1036
|
-
name: s.name,
|
|
1037
|
-
status: s.status ?? "none",
|
|
1038
|
-
user: s.user ?? null,
|
|
1039
|
-
file: s.file ?? null,
|
|
1040
|
-
exit_code: s.exit_code ?? null
|
|
1041
|
-
}));
|
|
1042
|
-
}
|
|
1043
|
-
function parseFormulaInfoJson(raw) {
|
|
1044
|
-
const data = safeParse(raw, "brew info");
|
|
1045
|
-
return data.formulae?.[0] ?? null;
|
|
1046
|
-
}
|
|
1047
|
-
|
|
1048
|
-
// src/lib/parsers/text-parser.ts
|
|
1049
|
-
function parseSearchResults(raw) {
|
|
1050
|
-
const lines = raw.split("\n").map((l) => l.trim()).filter(Boolean);
|
|
1051
|
-
const formulae = [];
|
|
1052
|
-
const casks = [];
|
|
1053
|
-
let section = "formulae";
|
|
1054
|
-
for (const line of lines) {
|
|
1055
|
-
if (line.startsWith("==> Formulae")) {
|
|
1056
|
-
section = "formulae";
|
|
1057
|
-
continue;
|
|
1058
|
-
}
|
|
1059
|
-
if (line.startsWith("==> Casks")) {
|
|
1060
|
-
section = "casks";
|
|
1061
|
-
continue;
|
|
1062
|
-
}
|
|
1063
|
-
if (line.startsWith("==>")) continue;
|
|
1064
|
-
if (section === "formulae") formulae.push(line);
|
|
1065
|
-
else casks.push(line);
|
|
1066
|
-
}
|
|
1067
|
-
return { formulae, casks };
|
|
1068
|
-
}
|
|
1069
|
-
function parseDoctorOutput(raw) {
|
|
1070
|
-
const cleaned = raw.trim();
|
|
1071
|
-
if (cleaned.includes("Your system is ready to brew")) {
|
|
1072
|
-
return { warnings: [], isClean: true };
|
|
1073
|
-
}
|
|
1074
|
-
const warnings = [];
|
|
1075
|
-
let current = "";
|
|
1076
|
-
for (const line of cleaned.split("\n")) {
|
|
1077
|
-
if (line.startsWith("Warning:")) {
|
|
1078
|
-
if (current) warnings.push(current.trim());
|
|
1079
|
-
current = line;
|
|
1080
|
-
} else if (current) {
|
|
1081
|
-
current += "\n" + line;
|
|
1082
|
-
}
|
|
1083
|
-
}
|
|
1084
|
-
if (current) warnings.push(current.trim());
|
|
1085
|
-
return { warnings, isClean: false };
|
|
1086
|
-
}
|
|
1087
|
-
function parseBrewConfig(raw) {
|
|
1088
|
-
const lines = raw.split("\n");
|
|
1089
|
-
const get = (key) => {
|
|
1090
|
-
const line = lines.find((l) => l.startsWith(key));
|
|
1091
|
-
return line?.split(":").slice(1).join(":").trim() ?? "";
|
|
1092
|
-
};
|
|
1093
|
-
return {
|
|
1094
|
-
HOMEBREW_VERSION: get("HOMEBREW_VERSION"),
|
|
1095
|
-
HOMEBREW_PREFIX: get("HOMEBREW_PREFIX"),
|
|
1096
|
-
coreUpdated: get("Core tap last commit") || get("Core tap JSON")
|
|
1097
|
-
};
|
|
1098
|
-
}
|
|
1099
|
-
function parseLeavesOutput(raw) {
|
|
1100
|
-
return raw.split("\n").map((l) => l.trim()).filter(Boolean);
|
|
1101
|
-
}
|
|
1102
|
-
|
|
1103
|
-
// src/lib/impact/impact-analyzer.ts
|
|
1104
|
-
var HIGH_RISK_PACKAGES = /* @__PURE__ */ new Set([
|
|
1105
|
-
"openssl",
|
|
1106
|
-
"openssl@3",
|
|
1107
|
-
"openssl@1.1",
|
|
1108
|
-
"python",
|
|
1109
|
-
"python@3",
|
|
1110
|
-
"python@3.11",
|
|
1111
|
-
"python@3.12",
|
|
1112
|
-
"python@3.13",
|
|
1113
|
-
"node",
|
|
1114
|
-
"node@18",
|
|
1115
|
-
"node@20",
|
|
1116
|
-
"ruby",
|
|
1117
|
-
"ruby@3",
|
|
1118
|
-
"sqlite",
|
|
1119
|
-
"sqlite3",
|
|
1120
|
-
"libpq",
|
|
1121
|
-
"postgresql",
|
|
1122
|
-
"postgresql@16",
|
|
1123
|
-
"glibc",
|
|
1124
|
-
"gcc",
|
|
1125
|
-
"llvm"
|
|
1126
|
-
]);
|
|
1127
|
-
function isMajorVersionBump(from, to) {
|
|
1128
|
-
const fromMajor = parseInt(from.split(".")[0] ?? "0", 10);
|
|
1129
|
-
const toMajor = parseInt(to.split(".")[0] ?? "0", 10);
|
|
1130
|
-
return !isNaN(fromMajor) && !isNaN(toMajor) && toMajor > fromMajor;
|
|
1131
|
-
}
|
|
1132
|
-
function calculateRisk(name, reverseDeps, fromVersion, toVersion) {
|
|
1133
|
-
const reasons = [];
|
|
1134
|
-
if (HIGH_RISK_PACKAGES.has(name)) {
|
|
1135
|
-
reasons.push(t("impact_reason_critical_package"));
|
|
1136
|
-
return { risk: "high", reasons };
|
|
1137
|
-
}
|
|
1138
|
-
if (reverseDeps.length > 10) {
|
|
1139
|
-
reasons.push(t("impact_reason_many_deps", { count: reverseDeps.length }));
|
|
1140
|
-
return { risk: "high", reasons };
|
|
1141
|
-
}
|
|
1142
|
-
let factorCount = 0;
|
|
1143
|
-
if (reverseDeps.length >= 3) {
|
|
1144
|
-
factorCount++;
|
|
1145
|
-
reasons.push(t("impact_reason_many_deps", { count: reverseDeps.length }));
|
|
1146
|
-
}
|
|
1147
|
-
if (isMajorVersionBump(fromVersion, toVersion)) {
|
|
1148
|
-
factorCount++;
|
|
1149
|
-
reasons.push(t("impact_reason_major_bump"));
|
|
1150
|
-
}
|
|
1151
|
-
const risk = factorCount >= 2 ? "high" : factorCount === 1 ? "medium" : "low";
|
|
1152
|
-
return { risk, reasons };
|
|
1153
|
-
}
|
|
1154
|
-
async function analyzeUpgradeImpact(packageName, fromVersion, toVersion, packageType) {
|
|
1155
|
-
if (packageType === "cask") {
|
|
1156
|
-
return {
|
|
1157
|
-
packageName,
|
|
1158
|
-
fromVersion,
|
|
1159
|
-
toVersion,
|
|
1160
|
-
packageType,
|
|
1161
|
-
directDeps: [],
|
|
1162
|
-
reverseDeps: [],
|
|
1163
|
-
risk: "low",
|
|
1164
|
-
riskReasons: []
|
|
1165
|
-
};
|
|
1166
|
-
}
|
|
1167
|
-
let directDeps = [];
|
|
1168
|
-
let reverseDeps = [];
|
|
1169
|
-
try {
|
|
1170
|
-
const depsOutput = await execBrew(["deps", "--1", packageName]);
|
|
1171
|
-
directDeps = depsOutput.split("\n").filter((l) => l.trim() !== "");
|
|
1172
|
-
} catch (err) {
|
|
1173
|
-
logger.warn(`impact-analyzer: deps failed for ${packageName}: ${err instanceof Error ? err.message : String(err)}`);
|
|
1174
|
-
}
|
|
1175
|
-
try {
|
|
1176
|
-
const usesOutput = await execBrew(["uses", "--installed", packageName]);
|
|
1177
|
-
reverseDeps = usesOutput.split("\n").filter((l) => l.trim() !== "");
|
|
1178
|
-
} catch (err) {
|
|
1179
|
-
logger.warn(`impact-analyzer: uses failed for ${packageName}: ${err instanceof Error ? err.message : String(err)}`);
|
|
1180
|
-
}
|
|
1181
|
-
const { risk, reasons } = calculateRisk(packageName, reverseDeps, fromVersion, toVersion);
|
|
1182
|
-
return {
|
|
1183
|
-
packageName,
|
|
1184
|
-
fromVersion,
|
|
1185
|
-
toVersion,
|
|
1186
|
-
packageType,
|
|
1187
|
-
directDeps,
|
|
1188
|
-
reverseDeps,
|
|
1189
|
-
risk,
|
|
1190
|
-
riskReasons: reasons
|
|
1191
|
-
};
|
|
1192
|
-
}
|
|
1193
|
-
|
|
1194
|
-
// src/lib/brew-api.ts
|
|
1195
|
-
var PKG_PATTERN = /^[\w@./+-]+$/;
|
|
1196
|
-
function validatePackageName(name) {
|
|
1197
|
-
if (!PKG_PATTERN.test(name)) throw new Error("Invalid package name: " + name);
|
|
1198
|
-
}
|
|
1199
|
-
async function brewUpdate() {
|
|
1200
|
-
return new Promise((resolve, reject) => {
|
|
1201
|
-
const proc = spawn("brew", ["update"], { stdio: "ignore" });
|
|
1202
|
-
let settled = false;
|
|
1203
|
-
const timeout = setTimeout(() => {
|
|
1204
|
-
if (settled) return;
|
|
1205
|
-
settled = true;
|
|
1206
|
-
proc.kill("SIGTERM");
|
|
1207
|
-
reject(new Error("brew update timed out after 120s"));
|
|
1208
|
-
}, 12e4);
|
|
1209
|
-
proc.on("close", (code) => {
|
|
1210
|
-
if (settled) return;
|
|
1211
|
-
settled = true;
|
|
1212
|
-
clearTimeout(timeout);
|
|
1213
|
-
if (code === 0) resolve();
|
|
1214
|
-
else reject(new Error(`brew update exited with code ${code}`));
|
|
1215
|
-
});
|
|
1216
|
-
proc.on("error", (err) => {
|
|
1217
|
-
if (settled) return;
|
|
1218
|
-
settled = true;
|
|
1219
|
-
clearTimeout(timeout);
|
|
1220
|
-
reject(err);
|
|
1221
|
-
});
|
|
1222
|
-
});
|
|
1223
|
-
}
|
|
1224
|
-
async function getInstalled() {
|
|
1225
|
-
const raw = await execBrew(["info", "--json=v2", "--installed"]);
|
|
1226
|
-
return parseInstalledJson(raw);
|
|
1227
|
-
}
|
|
1228
|
-
async function getOutdated() {
|
|
1229
|
-
const raw = await execBrew(["outdated", "--json=v2"]);
|
|
1230
|
-
return parseOutdatedJson(raw);
|
|
1231
|
-
}
|
|
1232
|
-
async function getServices() {
|
|
1233
|
-
const raw = await execBrew(["services", "list", "--json"]);
|
|
1234
|
-
return parseServicesJson(raw);
|
|
1235
|
-
}
|
|
1236
|
-
async function getFormulaInfo(name) {
|
|
1237
|
-
validatePackageName(name);
|
|
1238
|
-
const raw = await execBrew(["info", "--json=v2", name]);
|
|
1239
|
-
return parseFormulaInfoJson(raw);
|
|
1240
|
-
}
|
|
1241
|
-
async function getCaskInfo(name) {
|
|
1242
|
-
validatePackageName(name);
|
|
1243
|
-
try {
|
|
1244
|
-
const raw = await execBrew(["info", "--json=v2", "--cask", name]);
|
|
1245
|
-
const data = JSON.parse(raw);
|
|
1246
|
-
return data.casks?.[0] ?? null;
|
|
1247
|
-
} catch {
|
|
1248
|
-
return null;
|
|
1249
|
-
}
|
|
1250
|
-
}
|
|
1251
|
-
function formulaeFromCask(cask) {
|
|
1252
|
-
return {
|
|
1253
|
-
name: cask.token,
|
|
1254
|
-
full_name: cask.full_token,
|
|
1255
|
-
tap: "",
|
|
1256
|
-
desc: cask.desc,
|
|
1257
|
-
license: "",
|
|
1258
|
-
homepage: cask.homepage,
|
|
1259
|
-
versions: { stable: cask.version, head: null, bottle: false },
|
|
1260
|
-
dependencies: [],
|
|
1261
|
-
build_dependencies: [],
|
|
1262
|
-
installed: cask.installed ? [{
|
|
1263
|
-
version: cask.installed,
|
|
1264
|
-
used_options: [],
|
|
1265
|
-
built_as_bottle: false,
|
|
1266
|
-
poured_from_bottle: false,
|
|
1267
|
-
time: cask.installed_time ?? 0,
|
|
1268
|
-
runtime_dependencies: [],
|
|
1269
|
-
installed_as_dependency: false,
|
|
1270
|
-
installed_on_request: true
|
|
1271
|
-
}] : [],
|
|
1272
|
-
linked_keg: null,
|
|
1273
|
-
pinned: false,
|
|
1274
|
-
outdated: cask.outdated,
|
|
1275
|
-
deprecated: false,
|
|
1276
|
-
keg_only: false,
|
|
1277
|
-
caveats: null
|
|
1278
|
-
};
|
|
1279
|
-
}
|
|
1280
|
-
async function search(term) {
|
|
1281
|
-
const safeTerm = term.replace(/^-+/, "");
|
|
1282
|
-
if (!safeTerm) return { formulae: [], casks: [] };
|
|
1283
|
-
const raw = await execBrew(["search", safeTerm]);
|
|
1284
|
-
return parseSearchResults(raw);
|
|
1285
|
-
}
|
|
1286
|
-
async function getDoctor() {
|
|
1287
|
-
try {
|
|
1288
|
-
const raw = await execBrew(["doctor"]);
|
|
1289
|
-
return parseDoctorOutput(raw);
|
|
1290
|
-
} catch (err) {
|
|
1291
|
-
const msg = err instanceof Error ? err.message : String(err);
|
|
1292
|
-
return parseDoctorOutput(msg);
|
|
1293
|
-
}
|
|
1294
|
-
}
|
|
1295
|
-
async function getConfig() {
|
|
1296
|
-
const raw = await execBrew(["config"]);
|
|
1297
|
-
return parseBrewConfig(raw);
|
|
1298
|
-
}
|
|
1299
|
-
async function getLeaves() {
|
|
1300
|
-
const raw = await execBrew(["leaves"]);
|
|
1301
|
-
return parseLeavesOutput(raw);
|
|
1302
|
-
}
|
|
1303
|
-
async function uninstallPackage(name) {
|
|
1304
|
-
validatePackageName(name);
|
|
1305
|
-
return execBrew(["uninstall", name]);
|
|
1306
|
-
}
|
|
1307
|
-
async function serviceAction(name, action) {
|
|
1308
|
-
validatePackageName(name);
|
|
1309
|
-
return execBrew(["services", action, name]);
|
|
1310
|
-
}
|
|
1311
|
-
async function pinPackage(name) {
|
|
1312
|
-
validatePackageName(name);
|
|
1313
|
-
return execBrew(["pin", name]);
|
|
1314
|
-
}
|
|
1315
|
-
async function unpinPackage(name) {
|
|
1316
|
-
validatePackageName(name);
|
|
1317
|
-
return execBrew(["unpin", name]);
|
|
1318
|
-
}
|
|
1319
|
-
function formulaeToListItems(formulae) {
|
|
1320
|
-
return formulae.map((f) => {
|
|
1321
|
-
const installed = f.installed[0];
|
|
1322
|
-
return {
|
|
1323
|
-
name: f.name,
|
|
1324
|
-
version: installed?.version ?? f.versions.stable,
|
|
1325
|
-
desc: f.desc,
|
|
1326
|
-
type: "formula",
|
|
1327
|
-
outdated: f.outdated,
|
|
1328
|
-
pinned: f.pinned,
|
|
1329
|
-
kegOnly: f.keg_only,
|
|
1330
|
-
installedAsDependency: installed?.installed_as_dependency ?? false,
|
|
1331
|
-
installedTime: installed?.time ?? null
|
|
1332
|
-
};
|
|
1333
|
-
});
|
|
1334
|
-
}
|
|
1335
|
-
var impactCache = /* @__PURE__ */ new Map();
|
|
1336
|
-
var IMPACT_CACHE_LIMIT = 64;
|
|
1337
|
-
function impactKey(name, from, to, type) {
|
|
1338
|
-
return `${type}::${name}::${from}::${to}`;
|
|
1339
|
-
}
|
|
1340
|
-
async function getUpgradeImpact(packageName, fromVersion, toVersion, packageType) {
|
|
1341
|
-
validatePackageName(packageName);
|
|
1342
|
-
const key = impactKey(packageName, fromVersion, toVersion, packageType);
|
|
1343
|
-
const cached2 = impactCache.get(key);
|
|
1344
|
-
if (cached2) return cached2;
|
|
1345
|
-
const result = await analyzeUpgradeImpact(packageName, fromVersion, toVersion, packageType);
|
|
1346
|
-
if (impactCache.size >= IMPACT_CACHE_LIMIT) {
|
|
1347
|
-
const firstKey = impactCache.keys().next().value;
|
|
1348
|
-
if (firstKey !== void 0) impactCache.delete(firstKey);
|
|
1349
|
-
}
|
|
1350
|
-
impactCache.set(key, result);
|
|
1351
|
-
return result;
|
|
1352
|
-
}
|
|
1353
|
-
function casksToListItems(casks) {
|
|
1354
|
-
return casks.map((c) => ({
|
|
1355
|
-
name: c.token,
|
|
1356
|
-
version: c.installed ?? c.version,
|
|
1357
|
-
desc: c.desc,
|
|
1358
|
-
type: "cask",
|
|
1359
|
-
outdated: c.outdated,
|
|
1360
|
-
pinned: false,
|
|
1361
|
-
kegOnly: false,
|
|
1362
|
-
installedAsDependency: false,
|
|
1363
|
-
installedTime: c.installed_time ?? null
|
|
1364
|
-
}));
|
|
1365
|
-
}
|
|
1366
|
-
|
|
1367
|
-
// src/stores/brew-store.ts
|
|
1368
1045
|
var BREW_UPDATE_COOLDOWN_MS = 5 * 60 * 1e3;
|
|
1369
1046
|
var fetchAllInFlight = null;
|
|
1370
1047
|
var brewUpdateInFlight = null;
|
|
@@ -2143,7 +1820,7 @@ function DashboardView() {
|
|
|
2143
1820
|
minRows: 2
|
|
2144
1821
|
});
|
|
2145
1822
|
const halfRows = Math.max(1, Math.floor(splitRows / 2));
|
|
2146
|
-
|
|
1823
|
+
useEffect4(() => {
|
|
2147
1824
|
fetchAll();
|
|
2148
1825
|
}, []);
|
|
2149
1826
|
useViewInput((input) => {
|
|
@@ -2256,14 +1933,14 @@ function DashboardView() {
|
|
|
2256
1933
|
}
|
|
2257
1934
|
|
|
2258
1935
|
// src/views/installed.tsx
|
|
2259
|
-
import { useState as
|
|
1936
|
+
import { useState as useState5, useMemo as useMemo3, useEffect as useEffect8, useRef as useRef3 } from "react";
|
|
2260
1937
|
import { Box as Box15, Text as Text18 } from "ink";
|
|
2261
1938
|
|
|
2262
1939
|
// src/hooks/use-debounce.ts
|
|
2263
|
-
import { useState as
|
|
1940
|
+
import { useState as useState3, useEffect as useEffect5 } from "react";
|
|
2264
1941
|
function useDebounce(value, delayMs) {
|
|
2265
|
-
const [debounced, setDebounced] =
|
|
2266
|
-
|
|
1942
|
+
const [debounced, setDebounced] = useState3(value);
|
|
1943
|
+
useEffect5(() => {
|
|
2267
1944
|
const timer = setTimeout(() => setDebounced(value), delayMs);
|
|
2268
1945
|
return () => clearTimeout(timer);
|
|
2269
1946
|
}, [value, delayMs]);
|
|
@@ -2271,7 +1948,7 @@ function useDebounce(value, delayMs) {
|
|
|
2271
1948
|
}
|
|
2272
1949
|
|
|
2273
1950
|
// src/hooks/use-brew-stream.ts
|
|
2274
|
-
import { useState as
|
|
1951
|
+
import { useState as useState4, useCallback, useRef as useRef2, useEffect as useEffect6 } from "react";
|
|
2275
1952
|
var MAX_LINES = 100;
|
|
2276
1953
|
async function logToHistory(args, success, error) {
|
|
2277
1954
|
const detected = detectAction(args);
|
|
@@ -2284,13 +1961,13 @@ async function logToHistory(args, success, error) {
|
|
|
2284
1961
|
}
|
|
2285
1962
|
}
|
|
2286
1963
|
function useBrewStream() {
|
|
2287
|
-
const [lines, setLines] =
|
|
2288
|
-
const [isRunning, setIsRunning] =
|
|
2289
|
-
const [error, setError2] =
|
|
1964
|
+
const [lines, setLines] = useState4([]);
|
|
1965
|
+
const [isRunning, setIsRunning] = useState4(false);
|
|
1966
|
+
const [error, setError2] = useState4(null);
|
|
2290
1967
|
const cancelRef = useRef2(false);
|
|
2291
1968
|
const generatorRef = useRef2(null);
|
|
2292
1969
|
const mountedRef = useRef2(true);
|
|
2293
|
-
|
|
1970
|
+
useEffect6(() => {
|
|
2294
1971
|
mountedRef.current = true;
|
|
2295
1972
|
return () => {
|
|
2296
1973
|
mountedRef.current = false;
|
|
@@ -2330,7 +2007,7 @@ function useBrewStream() {
|
|
|
2330
2007
|
}
|
|
2331
2008
|
const MUTATING_COMMANDS = /* @__PURE__ */ new Set(["install", "uninstall", "upgrade", "pin", "unpin", "tap", "untap"]);
|
|
2332
2009
|
if (!cancelRef.current && MUTATING_COMMANDS.has(args[0] ?? "")) {
|
|
2333
|
-
void import("./snapshot-
|
|
2010
|
+
void import("./snapshot-RQ444U5L.js").then(({ captureSnapshot: captureSnapshot2, saveSnapshot: saveSnapshot2 }) => {
|
|
2334
2011
|
captureSnapshot2().then((s) => saveSnapshot2(s)).catch((err) => logger.warn("snapshot: capture/save failed", { error: String(err) }));
|
|
2335
2012
|
});
|
|
2336
2013
|
}
|
|
@@ -2370,13 +2047,13 @@ function SearchInput({ defaultValue, onChange, placeholder, isActive = true }) {
|
|
|
2370
2047
|
}
|
|
2371
2048
|
|
|
2372
2049
|
// src/components/common/confirm-dialog.tsx
|
|
2373
|
-
import { useEffect as
|
|
2050
|
+
import { useEffect as useEffect7 } from "react";
|
|
2374
2051
|
import { Box as Box11, Text as Text14, useInput as useInput3 } from "ink";
|
|
2375
2052
|
import { jsx as jsx15, jsxs as jsxs13 } from "react/jsx-runtime";
|
|
2376
2053
|
function ConfirmDialog({ message, onConfirm, onCancel }) {
|
|
2377
2054
|
const locale = useLocaleStore((s) => s.locale);
|
|
2378
2055
|
const { openModal, closeModal } = useModalStore();
|
|
2379
|
-
|
|
2056
|
+
useEffect7(() => {
|
|
2380
2057
|
openModal();
|
|
2381
2058
|
return () => {
|
|
2382
2059
|
closeModal();
|
|
@@ -2467,11 +2144,11 @@ function InstalledView() {
|
|
|
2467
2144
|
/* cursor + gap */
|
|
2468
2145
|
) : Math.max(12, Math.floor(columns * 0.35));
|
|
2469
2146
|
const versionWidth = Math.max(8, Math.floor(columns * 0.15));
|
|
2470
|
-
const [filter, setFilter] =
|
|
2471
|
-
const [cursor, setCursor] =
|
|
2472
|
-
const [tab, setTab] =
|
|
2473
|
-
const [isSearching, setIsSearching] =
|
|
2474
|
-
const [confirmUninstall, setConfirmUninstall] =
|
|
2147
|
+
const [filter, setFilter] = useState5("");
|
|
2148
|
+
const [cursor, setCursor] = useState5(0);
|
|
2149
|
+
const [tab, setTab] = useState5("formulae");
|
|
2150
|
+
const [isSearching, setIsSearching] = useState5(false);
|
|
2151
|
+
const [confirmUninstall, setConfirmUninstall] = useState5(null);
|
|
2475
2152
|
const debouncedFilter = useDebounce(filter, 200);
|
|
2476
2153
|
const stream = useBrewStream();
|
|
2477
2154
|
const listRows = useVisibleRows({
|
|
@@ -2484,10 +2161,10 @@ function InstalledView() {
|
|
|
2484
2161
|
fallbackReservedRows: 14,
|
|
2485
2162
|
minRows: 1
|
|
2486
2163
|
});
|
|
2487
|
-
|
|
2164
|
+
useEffect8(() => {
|
|
2488
2165
|
fetchInstalled();
|
|
2489
2166
|
}, []);
|
|
2490
|
-
|
|
2167
|
+
useEffect8(() => {
|
|
2491
2168
|
if (isSearching) {
|
|
2492
2169
|
openModal();
|
|
2493
2170
|
return () => {
|
|
@@ -2621,6 +2298,13 @@ function InstalledView() {
|
|
|
2621
2298
|
setConfirmUninstall(null);
|
|
2622
2299
|
void stream.run(["uninstall", name]).then(() => {
|
|
2623
2300
|
fetchInstalled();
|
|
2301
|
+
void writeLastAction({
|
|
2302
|
+
timestamp: (/* @__PURE__ */ new Date()).toISOString(),
|
|
2303
|
+
action: "uninstall",
|
|
2304
|
+
packages: [name],
|
|
2305
|
+
remainingOutdated: 0,
|
|
2306
|
+
source: "brew-tui"
|
|
2307
|
+
});
|
|
2624
2308
|
});
|
|
2625
2309
|
},
|
|
2626
2310
|
onCancel: () => setConfirmUninstall(null)
|
|
@@ -2673,23 +2357,24 @@ function InstalledView() {
|
|
|
2673
2357
|
}
|
|
2674
2358
|
|
|
2675
2359
|
// src/views/search.tsx
|
|
2676
|
-
import { useState as
|
|
2360
|
+
import { useState as useState6, useCallback as useCallback2, useEffect as useEffect9, useRef as useRef4 } from "react";
|
|
2677
2361
|
import { Box as Box16, Text as Text19 } from "ink";
|
|
2678
2362
|
import { TextInput as TextInput2 } from "@inkjs/ui";
|
|
2679
2363
|
import { jsx as jsx20, jsxs as jsxs17 } from "react/jsx-runtime";
|
|
2680
2364
|
function SearchView() {
|
|
2681
|
-
const [query, setQuery] =
|
|
2682
|
-
const [results, setResults] =
|
|
2683
|
-
const [searching, setSearching] =
|
|
2684
|
-
const [searchError, setSearchError] =
|
|
2685
|
-
const [cursor, setCursor] =
|
|
2686
|
-
const [confirmInstall, setConfirmInstall] =
|
|
2365
|
+
const [query, setQuery] = useState6("");
|
|
2366
|
+
const [results, setResults] = useState6(null);
|
|
2367
|
+
const [searching, setSearching] = useState6(false);
|
|
2368
|
+
const [searchError, setSearchError] = useState6(null);
|
|
2369
|
+
const [cursor, setCursor] = useState6(0);
|
|
2370
|
+
const [confirmInstall, setConfirmInstall] = useState6(null);
|
|
2687
2371
|
const stream = useBrewStream();
|
|
2688
2372
|
const { openModal, closeModal } = useModalStore();
|
|
2689
2373
|
const navigate = useNavigationStore((s) => s.navigate);
|
|
2690
2374
|
const selectPackage = useNavigationStore((s) => s.selectPackage);
|
|
2691
2375
|
const fetchInstalled = useBrewStore((s) => s.fetchInstalled);
|
|
2692
2376
|
const hasRefreshed = useRef4(false);
|
|
2377
|
+
const pendingInstallRef = useRef4(null);
|
|
2693
2378
|
const resultRows = useVisibleRows({
|
|
2694
2379
|
reservedRows: searchError ? 8 : 6,
|
|
2695
2380
|
fallbackReservedRows: searchError ? 18 : 16,
|
|
@@ -2700,7 +2385,7 @@ function SearchView() {
|
|
|
2700
2385
|
fallbackReservedRows: 14,
|
|
2701
2386
|
minRows: 1
|
|
2702
2387
|
});
|
|
2703
|
-
|
|
2388
|
+
useEffect9(() => {
|
|
2704
2389
|
if (results !== null) {
|
|
2705
2390
|
openModal();
|
|
2706
2391
|
return () => {
|
|
@@ -2728,10 +2413,21 @@ function SearchView() {
|
|
|
2728
2413
|
setSearching(false);
|
|
2729
2414
|
}
|
|
2730
2415
|
}, []);
|
|
2731
|
-
|
|
2416
|
+
useEffect9(() => {
|
|
2732
2417
|
if (!stream.isRunning && !stream.error && stream.lines.length > 0 && !hasRefreshed.current) {
|
|
2733
2418
|
hasRefreshed.current = true;
|
|
2734
2419
|
void fetchInstalled();
|
|
2420
|
+
const installed = pendingInstallRef.current;
|
|
2421
|
+
if (installed) {
|
|
2422
|
+
pendingInstallRef.current = null;
|
|
2423
|
+
void writeLastAction({
|
|
2424
|
+
timestamp: (/* @__PURE__ */ new Date()).toISOString(),
|
|
2425
|
+
action: "install",
|
|
2426
|
+
packages: [installed],
|
|
2427
|
+
remainingOutdated: 0,
|
|
2428
|
+
source: "brew-tui"
|
|
2429
|
+
});
|
|
2430
|
+
}
|
|
2735
2431
|
}
|
|
2736
2432
|
}, [stream.isRunning, stream.error]);
|
|
2737
2433
|
const allResults = results ? [
|
|
@@ -2743,7 +2439,7 @@ function SearchView() {
|
|
|
2743
2439
|
Math.max(0, allResults.length - resultRows)
|
|
2744
2440
|
);
|
|
2745
2441
|
const visibleResults = allResults.slice(start, start + resultRows);
|
|
2746
|
-
|
|
2442
|
+
useEffect9(() => {
|
|
2747
2443
|
setCursor((current) => Math.min(current, Math.max(0, allResults.length - 1)));
|
|
2748
2444
|
}, [allResults.length]);
|
|
2749
2445
|
useViewInput((input, key) => {
|
|
@@ -2842,6 +2538,7 @@ function SearchView() {
|
|
|
2842
2538
|
onConfirm: () => {
|
|
2843
2539
|
const name = confirmInstall;
|
|
2844
2540
|
hasRefreshed.current = false;
|
|
2541
|
+
pendingInstallRef.current = name;
|
|
2845
2542
|
setConfirmInstall(null);
|
|
2846
2543
|
void stream.run(["install", name]);
|
|
2847
2544
|
},
|
|
@@ -2885,7 +2582,7 @@ function SearchView() {
|
|
|
2885
2582
|
}
|
|
2886
2583
|
|
|
2887
2584
|
// src/views/outdated.tsx
|
|
2888
|
-
import { useEffect as
|
|
2585
|
+
import { useEffect as useEffect10, useMemo as useMemo4, useRef as useRef5, useState as useState7 } from "react";
|
|
2889
2586
|
import { Box as Box17, Text as Text20 } from "ink";
|
|
2890
2587
|
import { jsx as jsx21, jsxs as jsxs18 } from "react/jsx-runtime";
|
|
2891
2588
|
function ImpactPanel({ impact }) {
|
|
@@ -2910,14 +2607,17 @@ function ImpactPanel({ impact }) {
|
|
|
2910
2607
|
] });
|
|
2911
2608
|
}
|
|
2912
2609
|
function OutdatedView() {
|
|
2913
|
-
const
|
|
2610
|
+
const outdated = useBrewStore((s) => s.outdated);
|
|
2611
|
+
const loading = useBrewStore((s) => s.loading);
|
|
2612
|
+
const errors = useBrewStore((s) => s.errors);
|
|
2613
|
+
const fetchOutdated = useBrewStore((s) => s.fetchOutdated);
|
|
2914
2614
|
const stream = useBrewStream();
|
|
2915
|
-
const [cursor, setCursor] =
|
|
2916
|
-
const [confirmAction, setConfirmAction] =
|
|
2615
|
+
const [cursor, setCursor] = useState7(0);
|
|
2616
|
+
const [confirmAction, setConfirmAction] = useState7(null);
|
|
2917
2617
|
const hasRefreshed = useRef5(false);
|
|
2918
2618
|
const pendingUpgradeRef = useRef5(null);
|
|
2919
|
-
const [impact, setImpact] =
|
|
2920
|
-
const [impactLoading, setImpactLoading] =
|
|
2619
|
+
const [impact, setImpact] = useState7(null);
|
|
2620
|
+
const [impactLoading, setImpactLoading] = useState7(false);
|
|
2921
2621
|
const listRows = useVisibleRows({
|
|
2922
2622
|
reservedRows: impact || impactLoading ? 11 : 7,
|
|
2923
2623
|
fallbackReservedRows: impact || impactLoading ? 18 : 14,
|
|
@@ -2928,10 +2628,10 @@ function OutdatedView() {
|
|
|
2928
2628
|
fallbackReservedRows: 14,
|
|
2929
2629
|
minRows: 1
|
|
2930
2630
|
});
|
|
2931
|
-
|
|
2631
|
+
useEffect10(() => {
|
|
2932
2632
|
fetchOutdated();
|
|
2933
2633
|
}, []);
|
|
2934
|
-
|
|
2634
|
+
useEffect10(() => {
|
|
2935
2635
|
if (!stream.isRunning && !stream.error && stream.lines.length > 0 && !hasRefreshed.current) {
|
|
2936
2636
|
hasRefreshed.current = true;
|
|
2937
2637
|
void fetchOutdated().then(() => {
|
|
@@ -2958,7 +2658,7 @@ function OutdatedView() {
|
|
|
2958
2658
|
[outdated.formulae, outdated.casks]
|
|
2959
2659
|
);
|
|
2960
2660
|
const debouncedCursor = useDebounce(cursor, 150);
|
|
2961
|
-
|
|
2661
|
+
useEffect10(() => {
|
|
2962
2662
|
const pkg = allOutdated[debouncedCursor];
|
|
2963
2663
|
if (!pkg || stream.isRunning) {
|
|
2964
2664
|
setImpact(null);
|
|
@@ -3115,7 +2815,7 @@ ${t("outdated_upgradeAllList", { list: allOutdated.map((p) => p.name).join(", ")
|
|
|
3115
2815
|
}
|
|
3116
2816
|
|
|
3117
2817
|
// src/views/package-info.tsx
|
|
3118
|
-
import { useEffect as
|
|
2818
|
+
import { useEffect as useEffect11, useRef as useRef6, useState as useState8 } from "react";
|
|
3119
2819
|
import { Box as Box18, Text as Text21 } from "ink";
|
|
3120
2820
|
import { Fragment as Fragment4, jsx as jsx22, jsxs as jsxs19 } from "react/jsx-runtime";
|
|
3121
2821
|
var ACTION_PROGRESS_KEYS = {
|
|
@@ -3131,21 +2831,21 @@ var ACTION_CONFIRM_KEYS = {
|
|
|
3131
2831
|
function PackageInfoView() {
|
|
3132
2832
|
const packageName = useNavigationStore((s) => s.selectedPackage);
|
|
3133
2833
|
const packageType = useNavigationStore((s) => s.selectedPackageType);
|
|
3134
|
-
const [formula, setFormula] =
|
|
3135
|
-
const [loading, setLoading2] =
|
|
3136
|
-
const [error, setError2] =
|
|
3137
|
-
const [confirmAction, setConfirmAction] =
|
|
2834
|
+
const [formula, setFormula] = useState8(null);
|
|
2835
|
+
const [loading, setLoading2] = useState8(true);
|
|
2836
|
+
const [error, setError2] = useState8(null);
|
|
2837
|
+
const [confirmAction, setConfirmAction] = useState8(null);
|
|
3138
2838
|
const activeActionRef = useRef6("install");
|
|
3139
2839
|
const mountedRef = useRef6(true);
|
|
3140
2840
|
const hasRefreshed = useRef6(false);
|
|
3141
2841
|
const stream = useBrewStream();
|
|
3142
|
-
|
|
2842
|
+
useEffect11(() => {
|
|
3143
2843
|
mountedRef.current = true;
|
|
3144
2844
|
return () => {
|
|
3145
2845
|
mountedRef.current = false;
|
|
3146
2846
|
};
|
|
3147
2847
|
}, []);
|
|
3148
|
-
|
|
2848
|
+
useEffect11(() => {
|
|
3149
2849
|
if (!packageName) return;
|
|
3150
2850
|
setLoading2(true);
|
|
3151
2851
|
const fetchInfo = async () => {
|
|
@@ -3170,7 +2870,7 @@ function PackageInfoView() {
|
|
|
3170
2870
|
}
|
|
3171
2871
|
});
|
|
3172
2872
|
}, [packageName, packageType]);
|
|
3173
|
-
|
|
2873
|
+
useEffect11(() => {
|
|
3174
2874
|
if (!stream.isRunning && !stream.error && stream.lines.length > 0 && !hasRefreshed.current && packageName) {
|
|
3175
2875
|
hasRefreshed.current = true;
|
|
3176
2876
|
const refreshFn = packageType === "cask" ? getCaskInfo(packageName).then((c) => c ? { ...c, installed: c.installed ? [{ version: c.installed }] : [] } : null) : getFormulaInfo(packageName);
|
|
@@ -3330,7 +3030,7 @@ function PackageInfoView() {
|
|
|
3330
3030
|
}
|
|
3331
3031
|
|
|
3332
3032
|
// src/views/services.tsx
|
|
3333
|
-
import { useEffect as
|
|
3033
|
+
import { useEffect as useEffect12, useRef as useRef7, useState as useState9 } from "react";
|
|
3334
3034
|
import { Box as Box19, Text as Text22 } from "ink";
|
|
3335
3035
|
import { jsx as jsx23, jsxs as jsxs20 } from "react/jsx-runtime";
|
|
3336
3036
|
var STATUS_VARIANTS = {
|
|
@@ -3346,11 +3046,15 @@ function humaniseServiceError(message) {
|
|
|
3346
3046
|
return message;
|
|
3347
3047
|
}
|
|
3348
3048
|
function ServicesView() {
|
|
3349
|
-
const
|
|
3350
|
-
const
|
|
3351
|
-
const
|
|
3352
|
-
const
|
|
3353
|
-
const
|
|
3049
|
+
const services = useBrewStore((s) => s.services);
|
|
3050
|
+
const loading = useBrewStore((s) => s.loading);
|
|
3051
|
+
const errors = useBrewStore((s) => s.errors);
|
|
3052
|
+
const fetchServices = useBrewStore((s) => s.fetchServices);
|
|
3053
|
+
const serviceAction2 = useBrewStore((s) => s.serviceAction);
|
|
3054
|
+
const [cursor, setCursor] = useState9(0);
|
|
3055
|
+
const [actionInProgress, setActionInProgress] = useState9(false);
|
|
3056
|
+
const [confirmAction, setConfirmAction] = useState9(null);
|
|
3057
|
+
const [lastError, setLastError] = useState9(null);
|
|
3354
3058
|
const containerRef = useRef7(null);
|
|
3355
3059
|
const { width: containerWidth } = useContainerSize(containerRef);
|
|
3356
3060
|
const cols = containerWidth > 0 ? containerWidth : 80;
|
|
@@ -3366,7 +3070,7 @@ function ServicesView() {
|
|
|
3366
3070
|
fallbackReservedRows: lastError || actionInProgress ? 16 : 14,
|
|
3367
3071
|
minRows: 1
|
|
3368
3072
|
});
|
|
3369
|
-
|
|
3073
|
+
useEffect12(() => {
|
|
3370
3074
|
fetchServices();
|
|
3371
3075
|
}, []);
|
|
3372
3076
|
useViewInput((input, key) => {
|
|
@@ -3477,25 +3181,29 @@ function ServicesView() {
|
|
|
3477
3181
|
}
|
|
3478
3182
|
|
|
3479
3183
|
// src/views/doctor.tsx
|
|
3480
|
-
import { useEffect as
|
|
3184
|
+
import { useEffect as useEffect13, useRef as useRef8, useState as useState10 } from "react";
|
|
3481
3185
|
import { Box as Box20, Text as Text23 } from "ink";
|
|
3482
3186
|
import { jsx as jsx24, jsxs as jsxs21 } from "react/jsx-runtime";
|
|
3483
3187
|
function DoctorView() {
|
|
3484
|
-
const
|
|
3485
|
-
const
|
|
3188
|
+
const doctorWarnings = useBrewStore((s) => s.doctorWarnings);
|
|
3189
|
+
const doctorClean = useBrewStore((s) => s.doctorClean);
|
|
3190
|
+
const loading = useBrewStore((s) => s.loading);
|
|
3191
|
+
const errors = useBrewStore((s) => s.errors);
|
|
3192
|
+
const fetchDoctor = useBrewStore((s) => s.fetchDoctor);
|
|
3193
|
+
const [cursor, setCursor] = useState10(0);
|
|
3486
3194
|
const visibleWarnings = useVisibleRows({
|
|
3487
3195
|
reservedRows: 6,
|
|
3488
3196
|
fallbackReservedRows: 14,
|
|
3489
3197
|
minRows: 1
|
|
3490
3198
|
});
|
|
3491
3199
|
const mountedRef = useRef8(true);
|
|
3492
|
-
|
|
3200
|
+
useEffect13(() => {
|
|
3493
3201
|
mountedRef.current = true;
|
|
3494
3202
|
return () => {
|
|
3495
3203
|
mountedRef.current = false;
|
|
3496
3204
|
};
|
|
3497
3205
|
}, []);
|
|
3498
|
-
|
|
3206
|
+
useEffect13(() => {
|
|
3499
3207
|
fetchDoctor();
|
|
3500
3208
|
}, []);
|
|
3501
3209
|
useViewInput((input, key) => {
|
|
@@ -3533,7 +3241,7 @@ function DoctorView() {
|
|
|
3533
3241
|
}
|
|
3534
3242
|
|
|
3535
3243
|
// src/views/profiles.tsx
|
|
3536
|
-
import { useEffect as
|
|
3244
|
+
import { useEffect as useEffect14, useRef as useRef9, useState as useState11 } from "react";
|
|
3537
3245
|
import { Box as Box25 } from "ink";
|
|
3538
3246
|
|
|
3539
3247
|
// src/stores/profile-store.ts
|
|
@@ -3656,7 +3364,7 @@ async function updateProfile(isPro, oldName, newName, newDescription) {
|
|
|
3656
3364
|
await saveProfile(isPro, updated);
|
|
3657
3365
|
}
|
|
3658
3366
|
var TAP_PATTERN = /^[a-z0-9][-a-z0-9]*\/[a-z0-9][-a-z0-9]*$/;
|
|
3659
|
-
var
|
|
3367
|
+
var PKG_PATTERN = /^[a-z0-9][-a-z0-9_.@+]*$/;
|
|
3660
3368
|
async function* importProfile(isPro, profile) {
|
|
3661
3369
|
proCheck(isPro);
|
|
3662
3370
|
const installed = await getInstalled();
|
|
@@ -3675,7 +3383,7 @@ async function* importProfile(isPro, profile) {
|
|
|
3675
3383
|
}
|
|
3676
3384
|
const missingFormulae = profile.formulae.filter((f) => !installedFormulae.has(f));
|
|
3677
3385
|
for (const name of missingFormulae) {
|
|
3678
|
-
if (!
|
|
3386
|
+
if (!PKG_PATTERN.test(name)) {
|
|
3679
3387
|
yield `Skipping invalid formula name: ${name}`;
|
|
3680
3388
|
continue;
|
|
3681
3389
|
}
|
|
@@ -3686,7 +3394,7 @@ async function* importProfile(isPro, profile) {
|
|
|
3686
3394
|
}
|
|
3687
3395
|
const missingCasks = profile.casks.filter((c) => !installedCasks.has(c));
|
|
3688
3396
|
for (const name of missingCasks) {
|
|
3689
|
-
if (!
|
|
3397
|
+
if (!PKG_PATTERN.test(name)) {
|
|
3690
3398
|
yield `Skipping invalid cask name: ${name}`;
|
|
3691
3399
|
continue;
|
|
3692
3400
|
}
|
|
@@ -3905,23 +3613,23 @@ function ProfileEditDesc({ name, defaultDesc, loadError, onSubmit }) {
|
|
|
3905
3613
|
import { jsx as jsx29, jsxs as jsxs26 } from "react/jsx-runtime";
|
|
3906
3614
|
function ProfilesView() {
|
|
3907
3615
|
const { profileNames, selectedProfile, loading, loadError, fetchProfiles, loadProfile: loadProfile2, exportCurrent, deleteProfile: deleteProfile2, updateProfile: updateProfile2 } = useProfileStore();
|
|
3908
|
-
const [cursor, setCursor] =
|
|
3909
|
-
const [mode, setMode] =
|
|
3910
|
-
const [newName, setNewName] =
|
|
3911
|
-
const [confirmDelete, setConfirmDelete] =
|
|
3912
|
-
const [editName, setEditName] =
|
|
3913
|
-
const [editDesc, setEditDesc] =
|
|
3914
|
-
const [importLines, setImportLines] =
|
|
3915
|
-
const [importRunning, setImportRunning] =
|
|
3916
|
-
const [importHadError, setImportHadError] =
|
|
3917
|
-
const [importProfile2, setImportProfile] =
|
|
3616
|
+
const [cursor, setCursor] = useState11(0);
|
|
3617
|
+
const [mode, setMode] = useState11("list");
|
|
3618
|
+
const [newName, setNewName] = useState11("");
|
|
3619
|
+
const [confirmDelete, setConfirmDelete] = useState11(false);
|
|
3620
|
+
const [editName, setEditName] = useState11("");
|
|
3621
|
+
const [editDesc, setEditDesc] = useState11("");
|
|
3622
|
+
const [importLines, setImportLines] = useState11([]);
|
|
3623
|
+
const [importRunning, setImportRunning] = useState11(false);
|
|
3624
|
+
const [importHadError, setImportHadError] = useState11(false);
|
|
3625
|
+
const [importProfile2, setImportProfile] = useState11(null);
|
|
3918
3626
|
const { openModal, closeModal } = useModalStore();
|
|
3919
3627
|
const importGenRef = useRef9(null);
|
|
3920
3628
|
const mountedRef = useRef9(true);
|
|
3921
|
-
|
|
3629
|
+
useEffect14(() => {
|
|
3922
3630
|
fetchProfiles();
|
|
3923
3631
|
}, []);
|
|
3924
|
-
|
|
3632
|
+
useEffect14(() => {
|
|
3925
3633
|
mountedRef.current = true;
|
|
3926
3634
|
return () => {
|
|
3927
3635
|
mountedRef.current = false;
|
|
@@ -3929,7 +3637,7 @@ function ProfilesView() {
|
|
|
3929
3637
|
importGenRef.current = null;
|
|
3930
3638
|
};
|
|
3931
3639
|
}, []);
|
|
3932
|
-
|
|
3640
|
+
useEffect14(() => {
|
|
3933
3641
|
if (mode !== "list") {
|
|
3934
3642
|
openModal();
|
|
3935
3643
|
return () => {
|
|
@@ -4105,7 +3813,7 @@ function ProfilesView() {
|
|
|
4105
3813
|
}
|
|
4106
3814
|
|
|
4107
3815
|
// src/views/smart-cleanup.tsx
|
|
4108
|
-
import { useEffect as
|
|
3816
|
+
import { useEffect as useEffect15, useRef as useRef10, useState as useState12 } from "react";
|
|
4109
3817
|
import { Box as Box26, Text as Text28 } from "ink";
|
|
4110
3818
|
|
|
4111
3819
|
// src/stores/cleanup-store.ts
|
|
@@ -4229,10 +3937,10 @@ var useCleanupStore = create10((set, get) => ({
|
|
|
4229
3937
|
import { jsx as jsx30, jsxs as jsxs27 } from "react/jsx-runtime";
|
|
4230
3938
|
function SmartCleanupView() {
|
|
4231
3939
|
const { summary, selected, loading, error, analyze, toggleSelect, selectAll } = useCleanupStore();
|
|
4232
|
-
const [cursor, setCursor] =
|
|
4233
|
-
const [confirmClean, setConfirmClean] =
|
|
4234
|
-
const [confirmForce, setConfirmForce] =
|
|
4235
|
-
const [failedNames, setFailedNames] =
|
|
3940
|
+
const [cursor, setCursor] = useState12(0);
|
|
3941
|
+
const [confirmClean, setConfirmClean] = useState12(false);
|
|
3942
|
+
const [confirmForce, setConfirmForce] = useState12(false);
|
|
3943
|
+
const [failedNames, setFailedNames] = useState12([]);
|
|
4236
3944
|
const stream = useBrewStream();
|
|
4237
3945
|
const hasRefreshed = useRef10(false);
|
|
4238
3946
|
const listRows = useVisibleRows({
|
|
@@ -4240,10 +3948,10 @@ function SmartCleanupView() {
|
|
|
4240
3948
|
fallbackReservedRows: confirmClean || confirmForce ? 18 : 14,
|
|
4241
3949
|
minRows: 1
|
|
4242
3950
|
});
|
|
4243
|
-
|
|
3951
|
+
useEffect15(() => {
|
|
4244
3952
|
analyze();
|
|
4245
3953
|
}, []);
|
|
4246
|
-
|
|
3954
|
+
useEffect15(() => {
|
|
4247
3955
|
if (!stream.isRunning && !stream.error && stream.lines.length > 0 && !hasRefreshed.current) {
|
|
4248
3956
|
hasRefreshed.current = true;
|
|
4249
3957
|
void analyze();
|
|
@@ -4379,7 +4087,7 @@ function SmartCleanupView() {
|
|
|
4379
4087
|
}
|
|
4380
4088
|
|
|
4381
4089
|
// src/views/history.tsx
|
|
4382
|
-
import { useEffect as
|
|
4090
|
+
import { useEffect as useEffect16, useState as useState13, useMemo as useMemo5 } from "react";
|
|
4383
4091
|
import { Box as Box27, Text as Text29 } from "ink";
|
|
4384
4092
|
|
|
4385
4093
|
// src/stores/history-store.ts
|
|
@@ -4432,12 +4140,12 @@ var ACTION_LABEL_KEYS = {
|
|
|
4432
4140
|
var FILTERS = ["all", "install", "uninstall", "upgrade", "upgrade-all"];
|
|
4433
4141
|
function HistoryView() {
|
|
4434
4142
|
const { entries, loading, error, fetchHistory, clearHistory: clearHistory2 } = useHistoryStore();
|
|
4435
|
-
const [cursor, setCursor] =
|
|
4436
|
-
const [filter, setFilter] =
|
|
4437
|
-
const [searchQuery, setSearchQuery] =
|
|
4438
|
-
const [isSearching, setIsSearching] =
|
|
4439
|
-
const [confirmClear, setConfirmClear] =
|
|
4440
|
-
const [confirmReplay, setConfirmReplay] =
|
|
4143
|
+
const [cursor, setCursor] = useState13(0);
|
|
4144
|
+
const [filter, setFilter] = useState13("all");
|
|
4145
|
+
const [searchQuery, setSearchQuery] = useState13("");
|
|
4146
|
+
const [isSearching, setIsSearching] = useState13(false);
|
|
4147
|
+
const [confirmClear, setConfirmClear] = useState13(false);
|
|
4148
|
+
const [confirmReplay, setConfirmReplay] = useState13(null);
|
|
4441
4149
|
const stream = useBrewStream();
|
|
4442
4150
|
const debouncedQuery = useDebounce(searchQuery, 200);
|
|
4443
4151
|
const { openModal, closeModal } = useModalStore();
|
|
@@ -4451,10 +4159,10 @@ function HistoryView() {
|
|
|
4451
4159
|
fallbackReservedRows: 16,
|
|
4452
4160
|
minRows: 1
|
|
4453
4161
|
});
|
|
4454
|
-
|
|
4162
|
+
useEffect16(() => {
|
|
4455
4163
|
fetchHistory();
|
|
4456
4164
|
}, []);
|
|
4457
|
-
|
|
4165
|
+
useEffect16(() => {
|
|
4458
4166
|
if (isSearching) {
|
|
4459
4167
|
openModal();
|
|
4460
4168
|
return () => {
|
|
@@ -4595,7 +4303,7 @@ function HistoryView() {
|
|
|
4595
4303
|
}
|
|
4596
4304
|
|
|
4597
4305
|
// src/views/security-audit.tsx
|
|
4598
|
-
import { useEffect as
|
|
4306
|
+
import { useEffect as useEffect17, useState as useState14 } from "react";
|
|
4599
4307
|
import { Box as Box28, Text as Text30 } from "ink";
|
|
4600
4308
|
import { jsx as jsx32, jsxs as jsxs29 } from "react/jsx-runtime";
|
|
4601
4309
|
var SEVERITY_COLORS = {
|
|
@@ -4618,11 +4326,11 @@ function isNetworkError(msg) {
|
|
|
4618
4326
|
function SecurityAuditView() {
|
|
4619
4327
|
const { summary, loading, error, scan, cachedAt } = useSecurityStore();
|
|
4620
4328
|
const navigate = useNavigationStore((s) => s.navigate);
|
|
4621
|
-
const [cursor, setCursor] =
|
|
4622
|
-
const [expandedPkg, setExpandedPkg] =
|
|
4623
|
-
const [confirmUpgrade, setConfirmUpgrade] =
|
|
4329
|
+
const [cursor, setCursor] = useState14(0);
|
|
4330
|
+
const [expandedPkg, setExpandedPkg] = useState14(null);
|
|
4331
|
+
const [confirmUpgrade, setConfirmUpgrade] = useState14(null);
|
|
4624
4332
|
const stream = useBrewStream();
|
|
4625
|
-
|
|
4333
|
+
useEffect17(() => {
|
|
4626
4334
|
scan();
|
|
4627
4335
|
}, []);
|
|
4628
4336
|
const results = summary?.results ?? [];
|
|
@@ -4727,7 +4435,7 @@ function SecurityAuditView() {
|
|
|
4727
4435
|
}
|
|
4728
4436
|
|
|
4729
4437
|
// src/views/account.tsx
|
|
4730
|
-
import { useState as
|
|
4438
|
+
import { useState as useState15 } from "react";
|
|
4731
4439
|
import { Box as Box29, Text as Text31 } from "ink";
|
|
4732
4440
|
import { TextInput as TextInput5 } from "@inkjs/ui";
|
|
4733
4441
|
|
|
@@ -4754,7 +4462,7 @@ async function redeemPromoCode(code) {
|
|
|
4754
4462
|
let serverType;
|
|
4755
4463
|
const idempotencyKey = randomUUID();
|
|
4756
4464
|
try {
|
|
4757
|
-
const res = await
|
|
4465
|
+
const res = await fetchWithRetry(`${PROMO_API_URL}/redeem`, {
|
|
4758
4466
|
method: "POST",
|
|
4759
4467
|
headers: {
|
|
4760
4468
|
"Content-Type": "application/json",
|
|
@@ -4809,13 +4517,13 @@ async function redeemPromoCode(code) {
|
|
|
4809
4517
|
import { Fragment as Fragment5, jsx as jsx33, jsxs as jsxs30 } from "react/jsx-runtime";
|
|
4810
4518
|
function AccountView() {
|
|
4811
4519
|
const { status, license, deactivate: deactivate2, revalidate: revalidate2, degradation } = useLicenseStore();
|
|
4812
|
-
const [confirmDeactivate, setConfirmDeactivate] =
|
|
4813
|
-
const [deactivating, setDeactivating] =
|
|
4814
|
-
const [deactivateError, setDeactivateError] =
|
|
4815
|
-
const [promoMode, setPromoMode] =
|
|
4816
|
-
const [promoLoading, setPromoLoading] =
|
|
4817
|
-
const [promoResult, setPromoResult] =
|
|
4818
|
-
const [revalidating, setRevalidating] =
|
|
4520
|
+
const [confirmDeactivate, setConfirmDeactivate] = useState15(false);
|
|
4521
|
+
const [deactivating, setDeactivating] = useState15(false);
|
|
4522
|
+
const [deactivateError, setDeactivateError] = useState15(null);
|
|
4523
|
+
const [promoMode, setPromoMode] = useState15(false);
|
|
4524
|
+
const [promoLoading, setPromoLoading] = useState15(false);
|
|
4525
|
+
const [promoResult, setPromoResult] = useState15(null);
|
|
4526
|
+
const [revalidating, setRevalidating] = useState15(false);
|
|
4819
4527
|
useViewInput((input, key) => {
|
|
4820
4528
|
if (confirmDeactivate || deactivating || promoMode || revalidating) {
|
|
4821
4529
|
if (key.escape && promoMode) {
|
|
@@ -4824,7 +4532,7 @@ function AccountView() {
|
|
|
4824
4532
|
}
|
|
4825
4533
|
return;
|
|
4826
4534
|
}
|
|
4827
|
-
if ((input === "d" || input === "2") && status === "pro") {
|
|
4535
|
+
if ((input === "d" || input === "2") && (status === "pro" || status === "team")) {
|
|
4828
4536
|
setConfirmDeactivate(true);
|
|
4829
4537
|
}
|
|
4830
4538
|
if (input === "p" || input === "1") {
|
|
@@ -4868,6 +4576,7 @@ function AccountView() {
|
|
|
4868
4576
|
/* @__PURE__ */ jsxs30(Box29, { gap: SPACING.xs, children: [
|
|
4869
4577
|
/* @__PURE__ */ jsx33(Text31, { color: COLORS.muted, children: t("account_statusLabel") }),
|
|
4870
4578
|
status === "pro" && /* @__PURE__ */ jsx33(Text31, { color: COLORS.success, bold: true, children: t("account_pro") }),
|
|
4579
|
+
status === "team" && /* @__PURE__ */ jsx33(Text31, { color: COLORS.success, bold: true, children: t("account_team") }),
|
|
4871
4580
|
status === "free" && /* @__PURE__ */ jsx33(Text31, { color: COLORS.muted, children: t("account_free") }),
|
|
4872
4581
|
status === "expired" && /* @__PURE__ */ jsx33(Text31, { color: COLORS.error, children: t("account_expired") })
|
|
4873
4582
|
] }),
|
|
@@ -4959,13 +4668,13 @@ function AccountView() {
|
|
|
4959
4668
|
status === "pro" || status === "team" || status === "expired" ? `v ${t("hint_revalidate")} ` : "",
|
|
4960
4669
|
revalidating ? t("account_revalidating") : "",
|
|
4961
4670
|
" ",
|
|
4962
|
-
t("app_version", { version: "1.2.
|
|
4671
|
+
t("app_version", { version: "1.2.2" })
|
|
4963
4672
|
] }) })
|
|
4964
4673
|
] });
|
|
4965
4674
|
}
|
|
4966
4675
|
|
|
4967
4676
|
// src/views/rollback.tsx
|
|
4968
|
-
import { useCallback as useCallback3, useEffect as
|
|
4677
|
+
import { useCallback as useCallback3, useEffect as useEffect18, useRef as useRef11, useState as useState16 } from "react";
|
|
4969
4678
|
import { Box as Box30, Text as Text32 } from "ink";
|
|
4970
4679
|
|
|
4971
4680
|
// src/stores/rollback-store.ts
|
|
@@ -5001,10 +4710,10 @@ async function detectStrategy(name, targetVersion, packageType) {
|
|
|
5001
4710
|
}
|
|
5002
4711
|
return { strategy: "pin-only" };
|
|
5003
4712
|
}
|
|
5004
|
-
async function buildRollbackPlan(
|
|
4713
|
+
async function buildRollbackPlan(snapshot2, isPro) {
|
|
5005
4714
|
if (!isPro) throw new Error("Pro license required");
|
|
5006
4715
|
const current = await captureSnapshot();
|
|
5007
|
-
const diff = diffSnapshots(
|
|
4716
|
+
const diff = diffSnapshots(snapshot2, current);
|
|
5008
4717
|
const actions = [];
|
|
5009
4718
|
const warnings = [];
|
|
5010
4719
|
for (const entry of diff.upgraded) {
|
|
@@ -5070,8 +4779,8 @@ async function buildRollbackPlan(snapshot, isPro) {
|
|
|
5070
4779
|
warnings.push(`${caskPinCount} cask(s) will be pinned only (version restoration not supported)`);
|
|
5071
4780
|
}
|
|
5072
4781
|
const canExecute = actions.some((a) => a.strategy !== "unavailable");
|
|
5073
|
-
const snapshotLabel =
|
|
5074
|
-
const snapshotDate = new Date(
|
|
4782
|
+
const snapshotLabel = snapshot2.label ?? "Auto";
|
|
4783
|
+
const snapshotDate = new Date(snapshot2.capturedAt).toLocaleString();
|
|
5075
4784
|
logger.debug("Built rollback plan", { actionCount: actions.length, canExecute });
|
|
5076
4785
|
return {
|
|
5077
4786
|
snapshotLabel,
|
|
@@ -5092,6 +4801,13 @@ async function* executeRollbackPlan(plan, isPro) {
|
|
|
5092
4801
|
yield `[skip] ${action.packageName}: removal skipped for safety \u2014 remove manually if needed`;
|
|
5093
4802
|
continue;
|
|
5094
4803
|
}
|
|
4804
|
+
try {
|
|
4805
|
+
validatePackageName(action.packageName);
|
|
4806
|
+
if (action.versionedFormula) validatePackageName(action.versionedFormula);
|
|
4807
|
+
} catch (err) {
|
|
4808
|
+
yield `[reject] ${action.packageName}: ${err instanceof Error ? err.message : String(err)}`;
|
|
4809
|
+
continue;
|
|
4810
|
+
}
|
|
5095
4811
|
if (action.action === "install") {
|
|
5096
4812
|
if (action.strategy === "pin-only") {
|
|
5097
4813
|
yield `[warn] ${action.packageName}: cannot install specific version \u2014 skipping`;
|
|
@@ -5159,14 +4875,14 @@ var useRollbackStore = create12((set) => ({
|
|
|
5159
4875
|
set({ error: err instanceof Error ? err.message : String(err), loading: false });
|
|
5160
4876
|
}
|
|
5161
4877
|
},
|
|
5162
|
-
selectSnapshot: async (
|
|
5163
|
-
if (!
|
|
4878
|
+
selectSnapshot: async (snapshot2, isPro) => {
|
|
4879
|
+
if (!snapshot2) {
|
|
5164
4880
|
set({ selectedSnapshot: null, plan: null, planError: null });
|
|
5165
4881
|
return;
|
|
5166
4882
|
}
|
|
5167
|
-
set({ selectedSnapshot:
|
|
4883
|
+
set({ selectedSnapshot: snapshot2, plan: null, planLoading: true, planError: null });
|
|
5168
4884
|
try {
|
|
5169
|
-
const plan = await buildRollbackPlan(
|
|
4885
|
+
const plan = await buildRollbackPlan(snapshot2, isPro);
|
|
5170
4886
|
set({ plan, planLoading: false });
|
|
5171
4887
|
} catch (err) {
|
|
5172
4888
|
set({ planError: err instanceof Error ? err.message : String(err), planLoading: false });
|
|
@@ -5271,11 +4987,11 @@ function PlanView({ plan }) {
|
|
|
5271
4987
|
function RollbackView() {
|
|
5272
4988
|
const isPro = useLicenseStore((s) => s.isPro);
|
|
5273
4989
|
const { snapshots, loading, error, plan, planLoading, planError, fetchSnapshots, selectSnapshot, clearPlan } = useRollbackStore();
|
|
5274
|
-
const [cursor, setCursor] =
|
|
5275
|
-
const [phase, setPhase] =
|
|
5276
|
-
const [streamLines, setStreamLines] =
|
|
5277
|
-
const [streamRunning, setStreamRunning] =
|
|
5278
|
-
const [streamError, setStreamError] =
|
|
4990
|
+
const [cursor, setCursor] = useState16(0);
|
|
4991
|
+
const [phase, setPhase] = useState16("list");
|
|
4992
|
+
const [streamLines, setStreamLines] = useState16([]);
|
|
4993
|
+
const [streamRunning, setStreamRunning] = useState16(false);
|
|
4994
|
+
const [streamError, setStreamError] = useState16(null);
|
|
5279
4995
|
const generatorRef = useRef11(null);
|
|
5280
4996
|
const mountedRef = useRef11(true);
|
|
5281
4997
|
const snapshotRows = useVisibleRows({
|
|
@@ -5283,14 +4999,14 @@ function RollbackView() {
|
|
|
5283
4999
|
fallbackReservedRows: 14,
|
|
5284
5000
|
minRows: 1
|
|
5285
5001
|
});
|
|
5286
|
-
|
|
5002
|
+
useEffect18(() => {
|
|
5287
5003
|
mountedRef.current = true;
|
|
5288
5004
|
return () => {
|
|
5289
5005
|
mountedRef.current = false;
|
|
5290
5006
|
void generatorRef.current?.return(void 0);
|
|
5291
5007
|
};
|
|
5292
5008
|
}, []);
|
|
5293
|
-
|
|
5009
|
+
useEffect18(() => {
|
|
5294
5010
|
void fetchSnapshots(isPro());
|
|
5295
5011
|
}, []);
|
|
5296
5012
|
const runRollback = useCallback3(async (p) => {
|
|
@@ -5353,7 +5069,10 @@ function RollbackView() {
|
|
|
5353
5069
|
if (loading) return /* @__PURE__ */ jsx34(Loading, { message: t("rollback_select_snapshot") });
|
|
5354
5070
|
if (error) return /* @__PURE__ */ jsx34(ErrorMessage, { message: error });
|
|
5355
5071
|
if (phase === "executing") {
|
|
5356
|
-
return /* @__PURE__ */
|
|
5072
|
+
return /* @__PURE__ */ jsxs31(Box30, { flexDirection: "column", children: [
|
|
5073
|
+
/* @__PURE__ */ jsx34(ProgressLog, { lines: streamLines, isRunning: streamRunning, title: t("rollback_executing") }),
|
|
5074
|
+
/* @__PURE__ */ jsx34(Box30, { marginTop: SPACING.xs, children: /* @__PURE__ */ jsx34(Text32, { color: COLORS.warning, children: t("rollback_executing_no_cancel") }) })
|
|
5075
|
+
] });
|
|
5357
5076
|
}
|
|
5358
5077
|
if (phase === "result") {
|
|
5359
5078
|
return /* @__PURE__ */ jsxs31(Box30, { flexDirection: "column", marginTop: SPACING.xs, children: [
|
|
@@ -5427,7 +5146,7 @@ function RollbackView() {
|
|
|
5427
5146
|
}
|
|
5428
5147
|
|
|
5429
5148
|
// src/views/brewfile.tsx
|
|
5430
|
-
import { useCallback as useCallback4, useEffect as
|
|
5149
|
+
import { useCallback as useCallback4, useEffect as useEffect19, useRef as useRef12, useState as useState17 } from "react";
|
|
5431
5150
|
import { Box as Box31, Text as Text33 } from "ink";
|
|
5432
5151
|
import { TextInput as TextInput6 } from "@inkjs/ui";
|
|
5433
5152
|
import { jsx as jsx35, jsxs as jsxs32 } from "react/jsx-runtime";
|
|
@@ -5473,14 +5192,14 @@ function DriftSummary({ drift }) {
|
|
|
5473
5192
|
function BrewfileView() {
|
|
5474
5193
|
const isPro = useLicenseStore((s) => s.isPro);
|
|
5475
5194
|
const { schema, drift, loading, driftLoading, error, load, createFromCurrent } = useBrewfileStore();
|
|
5476
|
-
const [phase, setPhase] =
|
|
5477
|
-
const [streamLines, setStreamLines] =
|
|
5478
|
-
const [streamRunning, setStreamRunning] =
|
|
5479
|
-
const [streamError, setStreamError] =
|
|
5480
|
-
const [resultMessage, setResultMessage] =
|
|
5195
|
+
const [phase, setPhase] = useState17("overview");
|
|
5196
|
+
const [streamLines, setStreamLines] = useState17([]);
|
|
5197
|
+
const [streamRunning, setStreamRunning] = useState17(false);
|
|
5198
|
+
const [streamError, setStreamError] = useState17(null);
|
|
5199
|
+
const [resultMessage, setResultMessage] = useState17("");
|
|
5481
5200
|
const generatorRef = useRef12(null);
|
|
5482
5201
|
const mountedRef = useRef12(true);
|
|
5483
|
-
|
|
5202
|
+
useEffect19(() => {
|
|
5484
5203
|
mountedRef.current = true;
|
|
5485
5204
|
void load();
|
|
5486
5205
|
return () => {
|
|
@@ -5656,7 +5375,7 @@ function BrewfileView() {
|
|
|
5656
5375
|
}
|
|
5657
5376
|
|
|
5658
5377
|
// src/views/sync.tsx
|
|
5659
|
-
import { useCallback as useCallback5, useEffect as
|
|
5378
|
+
import { useCallback as useCallback5, useEffect as useEffect20, useState as useState18 } from "react";
|
|
5660
5379
|
import { Box as Box32, Text as Text34 } from "ink";
|
|
5661
5380
|
import { Fragment as Fragment6, jsx as jsx36, jsxs as jsxs33 } from "react/jsx-runtime";
|
|
5662
5381
|
function OverviewSection({
|
|
@@ -5782,14 +5501,14 @@ function SyncView() {
|
|
|
5782
5501
|
const isPro = useLicenseStore((s) => s.isPro);
|
|
5783
5502
|
const navigate = useNavigationStore((s) => s.navigate);
|
|
5784
5503
|
const { config, lastResult, conflicts, loading, error, initialize, syncNow, resolveConflicts } = useSyncStore();
|
|
5785
|
-
const [phase, setPhase] =
|
|
5786
|
-
const [syncError, setSyncError] =
|
|
5787
|
-
const [conflictEntries, setConflictEntries] =
|
|
5788
|
-
const [cursor, setCursor] =
|
|
5789
|
-
|
|
5504
|
+
const [phase, setPhase] = useState18("overview");
|
|
5505
|
+
const [syncError, setSyncError] = useState18(null);
|
|
5506
|
+
const [conflictEntries, setConflictEntries] = useState18([]);
|
|
5507
|
+
const [cursor, setCursor] = useState18(0);
|
|
5508
|
+
useEffect20(() => {
|
|
5790
5509
|
void initialize(isPro());
|
|
5791
5510
|
}, []);
|
|
5792
|
-
|
|
5511
|
+
useEffect20(() => {
|
|
5793
5512
|
if (conflicts.length > 0) {
|
|
5794
5513
|
setConflictEntries(
|
|
5795
5514
|
conflicts.map((c) => ({ conflict: c, resolution: "pending" }))
|
|
@@ -5954,7 +5673,7 @@ function SyncView() {
|
|
|
5954
5673
|
}
|
|
5955
5674
|
|
|
5956
5675
|
// src/views/compliance.tsx
|
|
5957
|
-
import { useCallback as useCallback6, useEffect as
|
|
5676
|
+
import { useCallback as useCallback6, useEffect as useEffect21, useRef as useRef13, useState as useState19 } from "react";
|
|
5958
5677
|
import { Box as Box33, Text as Text35 } from "ink";
|
|
5959
5678
|
import { TextInput as TextInput7 } from "@inkjs/ui";
|
|
5960
5679
|
|
|
@@ -5966,6 +5685,13 @@ async function* remediateViolations(violations, isPro) {
|
|
|
5966
5685
|
let skipped = 0;
|
|
5967
5686
|
for (const v of violations) {
|
|
5968
5687
|
if (v.type === "missing") {
|
|
5688
|
+
try {
|
|
5689
|
+
validatePackageName(v.packageName);
|
|
5690
|
+
} catch (err) {
|
|
5691
|
+
yield ` \u2717 Rejected ${v.packageName}: ${err instanceof Error ? err.message : String(err)}`;
|
|
5692
|
+
skipped++;
|
|
5693
|
+
continue;
|
|
5694
|
+
}
|
|
5969
5695
|
yield `Installing ${v.packageName}...`;
|
|
5970
5696
|
try {
|
|
5971
5697
|
for await (const line of streamBrew(["install", v.packageName])) {
|
|
@@ -5977,6 +5703,13 @@ async function* remediateViolations(violations, isPro) {
|
|
|
5977
5703
|
skipped++;
|
|
5978
5704
|
}
|
|
5979
5705
|
} else if (v.type === "wrong-version") {
|
|
5706
|
+
try {
|
|
5707
|
+
validatePackageName(v.packageName);
|
|
5708
|
+
} catch (err) {
|
|
5709
|
+
yield ` \u2717 Rejected ${v.packageName}: ${err instanceof Error ? err.message : String(err)}`;
|
|
5710
|
+
skipped++;
|
|
5711
|
+
continue;
|
|
5712
|
+
}
|
|
5980
5713
|
yield `Upgrading ${v.packageName}${v.required ? ` to ${v.required}+` : ""}...`;
|
|
5981
5714
|
try {
|
|
5982
5715
|
for await (const line of streamBrew(["upgrade", v.packageName])) {
|
|
@@ -6081,13 +5814,13 @@ function ViolationList({ violations }) {
|
|
|
6081
5814
|
function ComplianceView() {
|
|
6082
5815
|
const isPro = useLicenseStore((s) => s.isPro);
|
|
6083
5816
|
const { policy, report, loading, error, importPolicy, runCheck } = useComplianceStore();
|
|
6084
|
-
const [phase, setPhase] =
|
|
6085
|
-
const [resultMessage, setResultMessage] =
|
|
6086
|
-
const [streamLines, setStreamLines] =
|
|
6087
|
-
const [streamRunning, setStreamRunning] =
|
|
5817
|
+
const [phase, setPhase] = useState19("overview");
|
|
5818
|
+
const [resultMessage, setResultMessage] = useState19(null);
|
|
5819
|
+
const [streamLines, setStreamLines] = useState19([]);
|
|
5820
|
+
const [streamRunning, setStreamRunning] = useState19(false);
|
|
6088
5821
|
const generatorRef = useRef13(null);
|
|
6089
5822
|
const mountedRef = useRef13(true);
|
|
6090
|
-
|
|
5823
|
+
useEffect21(() => {
|
|
6091
5824
|
mountedRef.current = true;
|
|
6092
5825
|
return () => {
|
|
6093
5826
|
mountedRef.current = false;
|
|
@@ -6292,7 +6025,7 @@ function ComplianceView() {
|
|
|
6292
6025
|
import { Fragment as Fragment7, jsx as jsx38, jsxs as jsxs35 } from "react/jsx-runtime";
|
|
6293
6026
|
function LicenseInitializer() {
|
|
6294
6027
|
const initLicense = useLicenseStore((s) => s.initialize);
|
|
6295
|
-
|
|
6028
|
+
useEffect22(() => {
|
|
6296
6029
|
initLicense();
|
|
6297
6030
|
}, []);
|
|
6298
6031
|
return null;
|
|
@@ -6345,8 +6078,8 @@ function App() {
|
|
|
6345
6078
|
const { exit } = useApp();
|
|
6346
6079
|
const currentView = useNavigationStore((s) => s.currentView);
|
|
6347
6080
|
const isTestEnv = typeof process !== "undefined" && false;
|
|
6348
|
-
const [showWelcome, setShowWelcome] =
|
|
6349
|
-
|
|
6081
|
+
const [showWelcome, setShowWelcome] = useState20(isTestEnv ? false : null);
|
|
6082
|
+
useEffect22(() => {
|
|
6350
6083
|
if (isTestEnv) return;
|
|
6351
6084
|
void hasCompletedOnboarding().then((done) => setShowWelcome(!done));
|
|
6352
6085
|
}, []);
|
|
@@ -6443,7 +6176,7 @@ async function reportError(err, context = {}) {
|
|
|
6443
6176
|
const config = await resolveConfig();
|
|
6444
6177
|
if (!config.enabled || !config.endpoint) return;
|
|
6445
6178
|
const machineId = await getMachineId();
|
|
6446
|
-
const version = true ? "1.2.
|
|
6179
|
+
const version = true ? "1.2.2" : "unknown";
|
|
6447
6180
|
await postReport(buildReport("error", err, context, machineId, version), config);
|
|
6448
6181
|
}
|
|
6449
6182
|
async function installCrashReporter() {
|
|
@@ -6452,7 +6185,7 @@ async function installCrashReporter() {
|
|
|
6452
6185
|
if (!config.enabled || !config.endpoint) return;
|
|
6453
6186
|
_installed = true;
|
|
6454
6187
|
const machineId = await getMachineId();
|
|
6455
|
-
const version = true ? "1.2.
|
|
6188
|
+
const version = true ? "1.2.2" : "unknown";
|
|
6456
6189
|
process.on("uncaughtException", (err) => {
|
|
6457
6190
|
void postReport(buildReport("fatal", err, { kind: "uncaughtException" }, machineId, version), config);
|
|
6458
6191
|
});
|
|
@@ -6467,7 +6200,7 @@ import { jsx as jsx39 } from "react/jsx-runtime";
|
|
|
6467
6200
|
var [, , command, arg] = process.argv;
|
|
6468
6201
|
async function runCli() {
|
|
6469
6202
|
if (command === "--version" || command === "-v" || command === "version") {
|
|
6470
|
-
process.stdout.write("1.2.
|
|
6203
|
+
process.stdout.write("1.2.2\n");
|
|
6471
6204
|
return;
|
|
6472
6205
|
}
|
|
6473
6206
|
await ensureDataDirs();
|
|
@@ -6562,7 +6295,7 @@ async function runCli() {
|
|
|
6562
6295
|
}
|
|
6563
6296
|
if (isPro) {
|
|
6564
6297
|
try {
|
|
6565
|
-
const { loadSnapshots: loadSnapshots2 } = await import("./snapshot-
|
|
6298
|
+
const { loadSnapshots: loadSnapshots2 } = await import("./snapshot-RQ444U5L.js");
|
|
6566
6299
|
const snapshots = await loadSnapshots2();
|
|
6567
6300
|
if (snapshots.length > 0) {
|
|
6568
6301
|
const latest = snapshots[0];
|
|
@@ -6574,7 +6307,7 @@ Snapshots: ${snapshots.length} (latest: ${latest ? formatDate(latest.capturedAt)
|
|
|
6574
6307
|
} catch {
|
|
6575
6308
|
}
|
|
6576
6309
|
try {
|
|
6577
|
-
const { loadBrewfile: loadBrewfile2, computeDrift: computeDrift2 } = await import("./brewfile-manager-
|
|
6310
|
+
const { loadBrewfile: loadBrewfile2, computeDrift: computeDrift2 } = await import("./brewfile-manager-CPVXIVZC.js");
|
|
6578
6311
|
const schema = await loadBrewfile2();
|
|
6579
6312
|
if (schema) {
|
|
6580
6313
|
const drift = await computeDrift2(schema);
|
|
@@ -6583,7 +6316,7 @@ Snapshots: ${snapshots.length} (latest: ${latest ? formatDate(latest.capturedAt)
|
|
|
6583
6316
|
} catch {
|
|
6584
6317
|
}
|
|
6585
6318
|
try {
|
|
6586
|
-
const { loadSyncConfig: loadSyncConfig2 } = await import("./sync-engine-
|
|
6319
|
+
const { loadSyncConfig: loadSyncConfig2 } = await import("./sync-engine-Q4B2PPQS.js");
|
|
6587
6320
|
const syncConfig = await loadSyncConfig2();
|
|
6588
6321
|
if (syncConfig?.lastSync) {
|
|
6589
6322
|
console.log(`Sync: last sync ${formatDate(syncConfig.lastSync)}`);
|
|
@@ -6591,8 +6324,8 @@ Snapshots: ${snapshots.length} (latest: ${latest ? formatDate(latest.capturedAt)
|
|
|
6591
6324
|
} catch {
|
|
6592
6325
|
}
|
|
6593
6326
|
try {
|
|
6594
|
-
const { loadPolicy: loadPolicy2 } = await import("./policy-io-
|
|
6595
|
-
const { checkCompliance: checkCompliance2 } = await import("./compliance-checker-
|
|
6327
|
+
const { loadPolicy: loadPolicy2 } = await import("./policy-io-P5YIH6C7.js");
|
|
6328
|
+
const { checkCompliance: checkCompliance2 } = await import("./compliance-checker-3FDEX4OI.js");
|
|
6596
6329
|
const policy = await loadPolicy2(`${process.env["HOME"] ?? "~"}/.brew-tui/policy.yaml`).catch(() => null);
|
|
6597
6330
|
if (policy) {
|
|
6598
6331
|
const report = await checkCompliance2(policy, true);
|
|
@@ -6606,7 +6339,7 @@ Snapshots: ${snapshots.length} (latest: ${latest ? formatDate(latest.capturedAt)
|
|
|
6606
6339
|
if (command === "install-brewbar") {
|
|
6607
6340
|
await useLicenseStore.getState().initialize();
|
|
6608
6341
|
const isPro = useLicenseStore.getState().isPro();
|
|
6609
|
-
const { installBrewBar } = await import("./brewbar-installer-
|
|
6342
|
+
const { installBrewBar } = await import("./brewbar-installer-BKE6Z7OI.js");
|
|
6610
6343
|
try {
|
|
6611
6344
|
console.log(t("cli_brewbarInstalling"));
|
|
6612
6345
|
await installBrewBar(isPro, arg === "--force");
|
|
@@ -6618,7 +6351,7 @@ Snapshots: ${snapshots.length} (latest: ${latest ? formatDate(latest.capturedAt)
|
|
|
6618
6351
|
return;
|
|
6619
6352
|
}
|
|
6620
6353
|
if (command === "uninstall-brewbar") {
|
|
6621
|
-
const { uninstallBrewBar } = await import("./brewbar-installer-
|
|
6354
|
+
const { uninstallBrewBar } = await import("./brewbar-installer-BKE6Z7OI.js");
|
|
6622
6355
|
try {
|
|
6623
6356
|
await uninstallBrewBar();
|
|
6624
6357
|
console.log(t("cli_brewbarUninstalled"));
|
|
@@ -6649,8 +6382,8 @@ async function ensureBrewBarRunning() {
|
|
|
6649
6382
|
if (process.platform !== "darwin") return;
|
|
6650
6383
|
await useLicenseStore.getState().initialize();
|
|
6651
6384
|
if (!useLicenseStore.getState().isPro()) return;
|
|
6652
|
-
const { isBrewBarInstalled, installBrewBar, launchBrewBar } = await import("./brewbar-installer-
|
|
6653
|
-
const { checkBrewBarVersion } = await import("./version-check-
|
|
6385
|
+
const { isBrewBarInstalled, installBrewBar, launchBrewBar } = await import("./brewbar-installer-BKE6Z7OI.js");
|
|
6386
|
+
const { checkBrewBarVersion } = await import("./version-check-FKY5HGSI.js");
|
|
6654
6387
|
try {
|
|
6655
6388
|
if (!await isBrewBarInstalled()) {
|
|
6656
6389
|
console.log(t("cli_brewbarInstalling"));
|