brew-tui 0.6.2 → 0.7.0

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.
Files changed (34) hide show
  1. package/build/{brewbar-installer-WJZKSELD.js → brewbar-installer-KJTIZIVU.js} +2 -2
  2. package/build/{brewfile-manager-OITSKEHY.js → brewfile-manager-6LXONGSA.js} +4 -4
  3. package/build/{chunk-KSIAKLE2.js → chunk-3VDIKVS3.js} +3 -3
  4. package/build/{chunk-6NA4INJS.js → chunk-F6EISN54.js} +35 -3
  5. package/build/chunk-F6EISN54.js.map +1 -0
  6. package/build/{chunk-5MYWF5D7.js → chunk-FIPCCYL6.js} +2 -2
  7. package/build/{chunk-QPXROTAP.js → chunk-GWXDXFUC.js} +59 -17
  8. package/build/chunk-GWXDXFUC.js.map +1 -0
  9. package/build/{chunk-Z2VN4VYQ.js → chunk-JYHINZVV.js} +19 -4
  10. package/build/chunk-JYHINZVV.js.map +1 -0
  11. package/build/{chunk-EHIBIFCB.js → chunk-QZZZAAWG.js} +4 -2
  12. package/build/chunk-QZZZAAWG.js.map +1 -0
  13. package/build/{chunk-PVSE6XO7.js → chunk-VLREAA5F.js} +19 -3
  14. package/build/{chunk-PVSE6XO7.js.map → chunk-VLREAA5F.js.map} +1 -1
  15. package/build/compliance-checker-MAREAFDH.js +12 -0
  16. package/build/{history-logger-ZGYRAFON.js → history-logger-FJ3HZSFU.js} +3 -3
  17. package/build/index.js +1048 -849
  18. package/build/index.js.map +1 -1
  19. package/build/{snapshot-YWIOFQ5H.js → snapshot-JDRSBMG6.js} +3 -3
  20. package/build/{sync-engine-DIYXV66P.js → sync-engine-4OA4JNR3.js} +5 -5
  21. package/package.json +1 -1
  22. package/build/chunk-6NA4INJS.js.map +0 -1
  23. package/build/chunk-EHIBIFCB.js.map +0 -1
  24. package/build/chunk-QPXROTAP.js.map +0 -1
  25. package/build/chunk-Z2VN4VYQ.js.map +0 -1
  26. package/build/compliance-checker-7NMFKWTI.js +0 -12
  27. /package/build/{brewbar-installer-WJZKSELD.js.map → brewbar-installer-KJTIZIVU.js.map} +0 -0
  28. /package/build/{brewfile-manager-OITSKEHY.js.map → brewfile-manager-6LXONGSA.js.map} +0 -0
  29. /package/build/{chunk-KSIAKLE2.js.map → chunk-3VDIKVS3.js.map} +0 -0
  30. /package/build/{chunk-5MYWF5D7.js.map → chunk-FIPCCYL6.js.map} +0 -0
  31. /package/build/{compliance-checker-7NMFKWTI.js.map → compliance-checker-MAREAFDH.js.map} +0 -0
  32. /package/build/{history-logger-ZGYRAFON.js.map → history-logger-FJ3HZSFU.js.map} +0 -0
  33. /package/build/{snapshot-YWIOFQ5H.js.map → snapshot-JDRSBMG6.js.map} +0 -0
  34. /package/build/{sync-engine-DIYXV66P.js.map → sync-engine-4OA4JNR3.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-KSIAKLE2.js";
8
+ } from "./chunk-3VDIKVS3.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-QPXROTAP.js";
22
+ } from "./chunk-GWXDXFUC.js";
23
23
  import {
24
24
  checkCompliance
25
- } from "./chunk-5MYWF5D7.js";
25
+ } from "./chunk-FIPCCYL6.js";
26
26
  import {
27
27
  captureSnapshot,
28
28
  execBrew,
29
29
  loadSnapshots,
30
30
  saveSnapshot,
31
31
  streamBrew
32
- } from "./chunk-PVSE6XO7.js";
32
+ } from "./chunk-VLREAA5F.js";
33
33
  import {
34
34
  exportReport,
35
35
  loadPolicy
@@ -39,13 +39,14 @@ import {
39
39
  clearHistory,
40
40
  detectAction,
41
41
  loadHistory
42
- } from "./chunk-Z2VN4VYQ.js";
42
+ } from "./chunk-JYHINZVV.js";
43
43
  import {
44
44
  DATA_DIR,
45
+ ONBOARDING_FLAG_PATH,
45
46
  PROFILES_DIR,
46
47
  ensureDataDirs,
47
48
  getMachineId
48
- } from "./chunk-EHIBIFCB.js";
49
+ } from "./chunk-QZZZAAWG.js";
49
50
  import {
50
51
  fetchWithRetry,
51
52
  fetchWithTimeout,
@@ -53,7 +54,7 @@ import {
53
54
  t,
54
55
  tp,
55
56
  useLocaleStore
56
- } from "./chunk-6NA4INJS.js";
57
+ } from "./chunk-F6EISN54.js";
57
58
  import {
58
59
  logger
59
60
  } from "./chunk-KDHEUNRI.js";
@@ -64,7 +65,7 @@ import { rm as rm2 } from "fs/promises";
64
65
  import { render } from "ink";
65
66
 
66
67
  // src/app.tsx
67
- import { useEffect as useEffect19 } from "react";
68
+ import { useEffect as useEffect20, useState as useState17 } from "react";
68
69
  import { useApp } from "ink";
69
70
 
70
71
  // src/components/layout/app-layout.tsx
@@ -80,6 +81,7 @@ var VIEWS = [
80
81
  "installed",
81
82
  "outdated",
82
83
  "package-info",
84
+ "search",
83
85
  "services",
84
86
  "doctor",
85
87
  "profiles",
@@ -144,7 +146,7 @@ function isTeamView(viewId) {
144
146
  }
145
147
 
146
148
  // src/utils/colors.ts
147
- var PALETTE = {
149
+ var DARK_PALETTE = {
148
150
  success: "#22C55E",
149
151
  error: "#EF4444",
150
152
  warning: "#F59E0B",
@@ -156,17 +158,58 @@ var PALETTE = {
156
158
  teal: "#2DD4BF",
157
159
  sky: "#38BDF8",
158
160
  gold: "#FFD700",
161
+ goldOrange: "#FFA500",
162
+ goldDeep: "#B8860B",
163
+ goldDark: "#8B6914",
164
+ goldDeepest: "#6B4F10",
159
165
  purple: "#A855F7",
160
166
  blue: "#3B82F6",
161
167
  lavender: "#C4B5FD",
162
168
  border: "#4B5563",
163
169
  white: "#FFFFFF"
164
170
  };
171
+ var LIGHT_PALETTE = {
172
+ success: "#15803D",
173
+ error: "#B91C1C",
174
+ warning: "#B45309",
175
+ info: "#0E7490",
176
+ brand: "#C2410C",
177
+ muted: "#4B5563",
178
+ text: "#111827",
179
+ textSecondary: "#374151",
180
+ teal: "#0F766E",
181
+ sky: "#0369A1",
182
+ gold: "#A16207",
183
+ goldOrange: "#9A3412",
184
+ goldDeep: "#7C2D12",
185
+ goldDark: "#5B2509",
186
+ goldDeepest: "#3F1A06",
187
+ purple: "#6B21A8",
188
+ blue: "#1D4ED8",
189
+ lavender: "#6D28D9",
190
+ border: "#D1D5DB",
191
+ white: "#000000"
192
+ // intentional: "white-on-light" reads as black ink
193
+ };
194
+ function detectTheme() {
195
+ const override = process.env["BREW_TUI_THEME"];
196
+ if (override === "dark" || override === "light") return override;
197
+ const cfb = process.env["COLORFGBG"];
198
+ if (cfb) {
199
+ const parts = cfb.split(";");
200
+ const bg = Number(parts[parts.length - 1]);
201
+ if (!isNaN(bg) && bg >= 7) return "light";
202
+ if (!isNaN(bg) && bg <= 6) return "dark";
203
+ }
204
+ return "dark";
205
+ }
206
+ var PALETTE = detectTheme() === "light" ? LIGHT_PALETTE : DARK_PALETTE;
165
207
  function isNoColorRequested() {
166
208
  const v = process.env["NO_COLOR"];
167
209
  return typeof v === "string" && v.length > 0;
168
210
  }
169
211
  var NO_COLOR = isNoColorRequested();
212
+ var THEME = detectTheme();
170
213
  var COLORS = NO_COLOR ? Object.fromEntries(
171
214
  Object.keys(PALETTE).map((k) => [k, ""])
172
215
  ) : PALETTE;
@@ -213,14 +256,14 @@ var GradientText = React.memo(function GradientText2({ children, colors, bold })
213
256
  return /* @__PURE__ */ jsx(Fragment, { children: coloredChars.map(({ char, color, key }) => /* @__PURE__ */ jsx(Text, { color, bold, children: char }, key)) });
214
257
  });
215
258
  var GRADIENTS = {
216
- gold: ["#FFD700", "#FFA500", "#B8860B"],
217
- sunset: ["#FF6B2B", "#FFD700", "#FF6B2B"],
218
- ocean: ["#06B6D4", "#3B82F6", "#A855F7"],
219
- emerald: ["#22C55E", "#2DD4BF", "#06B6D4"],
220
- fire: ["#EF4444", "#F59E0B", "#FFD700"],
221
- version: ["#EF4444", "#9CA3AF", "#2DD4BF"],
222
- pro: ["#FF6B2B", "#FFD700", "#FF6B2B"],
223
- darkGold: ["#B8860B", "#8B6914", "#6B4F10"]
259
+ gold: [COLORS.gold, COLORS.goldOrange, COLORS.goldDeep],
260
+ sunset: [COLORS.brand, COLORS.gold, COLORS.brand],
261
+ ocean: [COLORS.info, COLORS.blue, COLORS.purple],
262
+ emerald: [COLORS.success, COLORS.teal, COLORS.info],
263
+ fire: [COLORS.error, COLORS.warning, COLORS.gold],
264
+ version: [COLORS.error, COLORS.muted, COLORS.teal],
265
+ pro: [COLORS.brand, COLORS.gold, COLORS.brand],
266
+ darkGold: [COLORS.goldDeep, COLORS.goldDark, COLORS.goldDeepest]
224
267
  };
225
268
 
226
269
  // src/utils/spacing.ts
@@ -339,7 +382,7 @@ function Header() {
339
382
  const logoBlock = /* @__PURE__ */ jsx2(Box, { flexDirection: "column", flexShrink: 0, children: LOGO_BREW.map((brew, i) => /* @__PURE__ */ jsxs(Box, { children: [
340
383
  /* @__PURE__ */ jsx2(GradientText, { colors: GRADIENTS.gold, children: brew }),
341
384
  /* @__PURE__ */ jsx2(GradientText, { colors: GRADIENTS.darkGold, children: LOGO_TUI[i] })
342
- ] }, i)) });
385
+ ] }, `logo-${i}`)) });
343
386
  const menuBlock = /* @__PURE__ */ jsxs(Box, { borderStyle: "round", borderColor: COLORS.lavender, paddingX: SPACING.xs, flexDirection: "column", alignSelf: isNarrow ? "flex-start" : "center", children: [
344
387
  /* @__PURE__ */ jsxs(Box, { flexDirection: "row", children: [
345
388
  /* @__PURE__ */ jsx2(Box, { flexDirection: "column", children: COL1_VIEWS.map((view) => /* @__PURE__ */ jsx2(MenuItem, { view, currentView }, view)) }),
@@ -637,9 +680,102 @@ function useGlobalKeyboard(opts) {
637
680
  }, { isActive: !opts?.disabled });
638
681
  }
639
682
 
640
- // src/components/common/upgrade-prompt.tsx
641
- import { Box as Box4, Text as Text4 } from "ink";
683
+ // src/lib/onboarding.ts
684
+ import { access, writeFile, mkdir } from "fs/promises";
685
+ var cached = null;
686
+ async function hasCompletedOnboarding() {
687
+ if (cached !== null) return cached;
688
+ try {
689
+ await access(ONBOARDING_FLAG_PATH);
690
+ cached = true;
691
+ } catch {
692
+ cached = false;
693
+ }
694
+ return cached;
695
+ }
696
+ async function markOnboardingComplete() {
697
+ await ensureDataDirs();
698
+ await mkdir(DATA_DIR, { recursive: true, mode: 448 });
699
+ await writeFile(ONBOARDING_FLAG_PATH, (/* @__PURE__ */ new Date()).toISOString(), {
700
+ encoding: "utf-8",
701
+ mode: 384
702
+ });
703
+ cached = true;
704
+ }
705
+
706
+ // src/views/welcome.tsx
707
+ import { useEffect } from "react";
708
+ import { Box as Box4, Text as Text4, useInput as useInput2 } from "ink";
642
709
  import { jsx as jsx5, jsxs as jsxs4 } from "react/jsx-runtime";
710
+ function WelcomeView({ onContinue }) {
711
+ useEffect(() => {
712
+ return () => {
713
+ };
714
+ }, []);
715
+ useInput2((input, key) => {
716
+ if (key.return || input === " " || key.escape) {
717
+ void markOnboardingComplete().finally(onContinue);
718
+ }
719
+ });
720
+ return /* @__PURE__ */ jsxs4(Box4, { flexDirection: "column", paddingY: SPACING.md, paddingX: SPACING.lg, children: [
721
+ /* @__PURE__ */ jsx5(Box4, { children: /* @__PURE__ */ jsx5(GradientText, { colors: GRADIENTS.gold, bold: true, children: t("welcome_title") }) }),
722
+ /* @__PURE__ */ jsx5(Box4, { marginTop: SPACING.sm, children: /* @__PURE__ */ jsx5(Text4, { color: COLORS.text, children: t("welcome_intro") }) }),
723
+ /* @__PURE__ */ jsxs4(Box4, { flexDirection: "column", marginTop: SPACING.sm, children: [
724
+ /* @__PURE__ */ jsx5(Text4, { color: COLORS.muted, children: t("welcome_keysHeader") }),
725
+ /* @__PURE__ */ jsxs4(Box4, { flexDirection: "column", paddingLeft: SPACING.sm, marginTop: SPACING.xs, children: [
726
+ /* @__PURE__ */ jsxs4(Text4, { children: [
727
+ /* @__PURE__ */ jsx5(Text4, { color: COLORS.gold, bold: true, children: "1-9 0" }),
728
+ " ",
729
+ t("welcome_keyJumpView")
730
+ ] }),
731
+ /* @__PURE__ */ jsxs4(Text4, { children: [
732
+ /* @__PURE__ */ jsx5(Text4, { color: COLORS.gold, bold: true, children: "Tab" }),
733
+ " ",
734
+ t("welcome_keyCycleView")
735
+ ] }),
736
+ /* @__PURE__ */ jsxs4(Text4, { children: [
737
+ /* @__PURE__ */ jsx5(Text4, { color: COLORS.gold, bold: true, children: "j k" }),
738
+ " ",
739
+ t("welcome_keyMove")
740
+ ] }),
741
+ /* @__PURE__ */ jsxs4(Text4, { children: [
742
+ /* @__PURE__ */ jsx5(Text4, { color: COLORS.gold, bold: true, children: "/" }),
743
+ " ",
744
+ t("welcome_keySearch")
745
+ ] }),
746
+ /* @__PURE__ */ jsxs4(Text4, { children: [
747
+ /* @__PURE__ */ jsx5(Text4, { color: COLORS.gold, bold: true, children: "Enter" }),
748
+ " ",
749
+ t("welcome_keySelect")
750
+ ] }),
751
+ /* @__PURE__ */ jsxs4(Text4, { children: [
752
+ /* @__PURE__ */ jsx5(Text4, { color: COLORS.gold, bold: true, children: "Esc" }),
753
+ " ",
754
+ t("welcome_keyBack")
755
+ ] }),
756
+ /* @__PURE__ */ jsxs4(Text4, { children: [
757
+ /* @__PURE__ */ jsx5(Text4, { color: COLORS.gold, bold: true, children: "L" }),
758
+ " ",
759
+ t("welcome_keyLocale")
760
+ ] }),
761
+ /* @__PURE__ */ jsxs4(Text4, { children: [
762
+ /* @__PURE__ */ jsx5(Text4, { color: COLORS.gold, bold: true, children: "q" }),
763
+ " ",
764
+ t("welcome_keyQuit")
765
+ ] })
766
+ ] })
767
+ ] }),
768
+ /* @__PURE__ */ jsxs4(Box4, { flexDirection: "column", marginTop: SPACING.sm, children: [
769
+ /* @__PURE__ */ jsx5(Text4, { color: COLORS.muted, children: t("welcome_proHeader") }),
770
+ /* @__PURE__ */ jsx5(Box4, { paddingLeft: SPACING.sm, children: /* @__PURE__ */ jsx5(Text4, { color: COLORS.textSecondary, children: t("welcome_proIntro") }) })
771
+ ] }),
772
+ /* @__PURE__ */ jsx5(Box4, { marginTop: SPACING.md, children: /* @__PURE__ */ jsx5(Text4, { color: COLORS.success, bold: true, children: t("welcome_continueHint") }) })
773
+ ] });
774
+ }
775
+
776
+ // src/components/common/upgrade-prompt.tsx
777
+ import { Box as Box5, Text as Text5 } from "ink";
778
+ import { jsx as jsx6, jsxs as jsxs5 } from "react/jsx-runtime";
643
779
  var FEATURE_KEYS = {
644
780
  profiles: { title: "upgrade_profiles", desc: "upgrade_profilesDesc" },
645
781
  "smart-cleanup": { title: "upgrade_cleanup", desc: "upgrade_cleanupDesc" },
@@ -659,8 +795,8 @@ function UpgradePrompt({ viewId }) {
659
795
  const pricingKey = team ? "upgrade_teamPricing" : "upgrade_pricing";
660
796
  const buyUrlKey = team ? "upgrade_buyUrlTeam" : "upgrade_buyUrl";
661
797
  const labelKey = team ? "upgrade_teamLabel" : "upgrade_proLabel";
662
- return /* @__PURE__ */ jsx5(Box4, { flexDirection: "column", alignItems: "center", paddingY: SPACING.sm, children: /* @__PURE__ */ jsxs4(
663
- Box4,
798
+ return /* @__PURE__ */ jsx6(Box5, { flexDirection: "column", alignItems: "center", paddingY: SPACING.sm, children: /* @__PURE__ */ jsxs5(
799
+ Box5,
664
800
  {
665
801
  borderStyle: "double",
666
802
  borderColor: COLORS.brand,
@@ -670,30 +806,30 @@ function UpgradePrompt({ viewId }) {
670
806
  alignItems: "center",
671
807
  width: "80%",
672
808
  children: [
673
- /* @__PURE__ */ jsxs4(Text4, { bold: true, color: COLORS.brand, children: [
809
+ /* @__PURE__ */ jsxs5(Text5, { bold: true, color: COLORS.brand, children: [
674
810
  "\u2B50",
675
811
  " ",
676
812
  t(headerKey, { title })
677
813
  ] }),
678
- /* @__PURE__ */ jsx5(Text4, { children: " " }),
679
- /* @__PURE__ */ jsx5(Text4, { color: COLORS.text, wrap: "wrap", children: t(keys.desc) }),
680
- /* @__PURE__ */ jsx5(Text4, { children: " " }),
681
- /* @__PURE__ */ jsxs4(Box4, { flexDirection: "column", alignItems: "center", children: [
682
- /* @__PURE__ */ jsx5(Text4, { color: COLORS.info, bold: true, children: t(pricingKey) }),
683
- /* @__PURE__ */ jsx5(Text4, { children: " " }),
684
- /* @__PURE__ */ jsx5(Text4, { color: COLORS.muted, children: t("upgrade_buyAt") }),
685
- /* @__PURE__ */ jsxs4(Text4, { color: COLORS.sky, bold: true, children: [
814
+ /* @__PURE__ */ jsx6(Text5, { children: " " }),
815
+ /* @__PURE__ */ jsx6(Text5, { color: COLORS.text, wrap: "wrap", children: t(keys.desc) }),
816
+ /* @__PURE__ */ jsx6(Text5, { children: " " }),
817
+ /* @__PURE__ */ jsxs5(Box5, { flexDirection: "column", alignItems: "center", children: [
818
+ /* @__PURE__ */ jsx6(Text5, { color: COLORS.info, bold: true, children: t(pricingKey) }),
819
+ /* @__PURE__ */ jsx6(Text5, { children: " " }),
820
+ /* @__PURE__ */ jsx6(Text5, { color: COLORS.muted, children: t("upgrade_buyAt") }),
821
+ /* @__PURE__ */ jsxs5(Text5, { color: COLORS.sky, bold: true, children: [
686
822
  " ",
687
823
  t(buyUrlKey)
688
824
  ] }),
689
- /* @__PURE__ */ jsx5(Text4, { children: " " }),
690
- /* @__PURE__ */ jsx5(Text4, { color: COLORS.muted, children: t("upgrade_activateWith") }),
691
- /* @__PURE__ */ jsxs4(Text4, { color: COLORS.success, bold: true, children: [
825
+ /* @__PURE__ */ jsx6(Text5, { children: " " }),
826
+ /* @__PURE__ */ jsx6(Text5, { color: COLORS.muted, children: t("upgrade_activateWith") }),
827
+ /* @__PURE__ */ jsxs5(Text5, { color: COLORS.success, bold: true, children: [
692
828
  " ",
693
829
  t("upgrade_activateCmd")
694
830
  ] }),
695
- /* @__PURE__ */ jsx5(Text4, { children: " " }),
696
- /* @__PURE__ */ jsx5(Text4, { color: COLORS.brand, children: t(labelKey) })
831
+ /* @__PURE__ */ jsx6(Text5, { children: " " }),
832
+ /* @__PURE__ */ jsx6(Text5, { color: COLORS.brand, children: t(labelKey) })
697
833
  ] })
698
834
  ]
699
835
  }
@@ -701,8 +837,8 @@ function UpgradePrompt({ viewId }) {
701
837
  }
702
838
 
703
839
  // src/views/dashboard.tsx
704
- import { useEffect, useMemo as useMemo2 } from "react";
705
- import { Box as Box8, Text as Text10, useInput as useInput2, useStdout as useStdout3 } from "ink";
840
+ import { useEffect as useEffect2, useMemo as useMemo2 } from "react";
841
+ import { Box as Box9, Text as Text11, useInput as useInput3, useStdout as useStdout3 } from "ink";
706
842
 
707
843
  // src/stores/brew-store.ts
708
844
  import { create as create4 } from "zustand";
@@ -955,6 +1091,35 @@ async function getCaskInfo(name) {
955
1091
  return null;
956
1092
  }
957
1093
  }
1094
+ function formulaeFromCask(cask) {
1095
+ return {
1096
+ name: cask.token,
1097
+ full_name: cask.full_token,
1098
+ tap: "",
1099
+ desc: cask.desc,
1100
+ license: "",
1101
+ homepage: cask.homepage,
1102
+ versions: { stable: cask.version, head: null, bottle: false },
1103
+ dependencies: [],
1104
+ build_dependencies: [],
1105
+ installed: cask.installed ? [{
1106
+ version: cask.installed,
1107
+ used_options: [],
1108
+ built_as_bottle: false,
1109
+ poured_from_bottle: false,
1110
+ time: cask.installed_time ?? 0,
1111
+ runtime_dependencies: [],
1112
+ installed_as_dependency: false,
1113
+ installed_on_request: true
1114
+ }] : [],
1115
+ linked_keg: null,
1116
+ pinned: false,
1117
+ outdated: cask.outdated,
1118
+ deprecated: false,
1119
+ keg_only: false,
1120
+ caveats: null
1121
+ };
1122
+ }
958
1123
  async function search(term) {
959
1124
  const safeTerm = term.replace(/^-+/, "");
960
1125
  if (!safeTerm) return { formulae: [], casks: [] };
@@ -1010,9 +1175,23 @@ function formulaeToListItems(formulae) {
1010
1175
  };
1011
1176
  });
1012
1177
  }
1178
+ var impactCache = /* @__PURE__ */ new Map();
1179
+ var IMPACT_CACHE_LIMIT = 64;
1180
+ function impactKey(name, from, to, type) {
1181
+ return `${type}::${name}::${from}::${to}`;
1182
+ }
1013
1183
  async function getUpgradeImpact(packageName, fromVersion, toVersion, packageType) {
1014
1184
  validatePackageName(packageName);
1015
- return analyzeUpgradeImpact(packageName, fromVersion, toVersion, packageType);
1185
+ const key = impactKey(packageName, fromVersion, toVersion, packageType);
1186
+ const cached2 = impactCache.get(key);
1187
+ if (cached2) return cached2;
1188
+ const result = await analyzeUpgradeImpact(packageName, fromVersion, toVersion, packageType);
1189
+ if (impactCache.size >= IMPACT_CACHE_LIMIT) {
1190
+ const firstKey = impactCache.keys().next().value;
1191
+ if (firstKey !== void 0) impactCache.delete(firstKey);
1192
+ }
1193
+ impactCache.set(key, result);
1194
+ return result;
1016
1195
  }
1017
1196
  function casksToListItems(casks) {
1018
1197
  return casks.map((c) => ({
@@ -1625,14 +1804,14 @@ var useComplianceStore = create8((set, get) => ({
1625
1804
  }));
1626
1805
 
1627
1806
  // src/components/common/stat-card.tsx
1628
- import { Box as Box5, Text as Text5, useStdout as useStdout2 } from "ink";
1629
- import { jsx as jsx6, jsxs as jsxs5 } from "react/jsx-runtime";
1630
- function StatCard({ label, value, color = "white" }) {
1807
+ import { Box as Box6, Text as Text6, useStdout as useStdout2 } from "ink";
1808
+ import { jsx as jsx7, jsxs as jsxs6 } from "react/jsx-runtime";
1809
+ function StatCard({ label, value, color = COLORS.white }) {
1631
1810
  const { stdout } = useStdout2();
1632
1811
  const cols = stdout?.columns ?? 80;
1633
1812
  const minW = cols < 60 ? 12 : cols < 100 ? 14 : 16;
1634
- return /* @__PURE__ */ jsxs5(
1635
- Box5,
1813
+ return /* @__PURE__ */ jsxs6(
1814
+ Box6,
1636
1815
  {
1637
1816
  borderStyle: "round",
1638
1817
  borderColor: color,
@@ -1642,36 +1821,36 @@ function StatCard({ label, value, color = "white" }) {
1642
1821
  alignItems: "center",
1643
1822
  minWidth: minW,
1644
1823
  children: [
1645
- /* @__PURE__ */ jsx6(Text5, { bold: true, color, children: value }),
1646
- /* @__PURE__ */ jsx6(Text5, { color: COLORS.muted, children: label })
1824
+ /* @__PURE__ */ jsx7(Text6, { bold: true, color, children: value }),
1825
+ /* @__PURE__ */ jsx7(Text6, { color: COLORS.muted, children: label })
1647
1826
  ]
1648
1827
  }
1649
1828
  );
1650
1829
  }
1651
1830
 
1652
1831
  // src/components/common/loading.tsx
1653
- import { Box as Box6, Text as Text6 } from "ink";
1832
+ import { Box as Box7, Text as Text7 } from "ink";
1654
1833
  import { Spinner } from "@inkjs/ui";
1655
- import { jsx as jsx7, jsxs as jsxs6 } from "react/jsx-runtime";
1834
+ import { jsx as jsx8, jsxs as jsxs7 } from "react/jsx-runtime";
1656
1835
  function Loading({ message }) {
1657
1836
  useLocaleStore((s) => s.locale);
1658
- return /* @__PURE__ */ jsx7(Box6, { paddingY: SPACING.xs, children: /* @__PURE__ */ jsx7(Spinner, { label: message ?? t("loading_default") }) });
1837
+ return /* @__PURE__ */ jsx8(Box7, { paddingY: SPACING.xs, children: /* @__PURE__ */ jsx8(Spinner, { label: message ?? t("loading_default") }) });
1659
1838
  }
1660
1839
  function ErrorMessage({ message }) {
1661
1840
  useLocaleStore((s) => s.locale);
1662
- return /* @__PURE__ */ jsxs6(Box6, { paddingY: SPACING.xs, children: [
1663
- /* @__PURE__ */ jsxs6(Text6, { color: COLORS.error, bold: true, children: [
1841
+ return /* @__PURE__ */ jsxs7(Box7, { paddingY: SPACING.xs, children: [
1842
+ /* @__PURE__ */ jsxs7(Text7, { color: COLORS.error, bold: true, children: [
1664
1843
  "\u2718",
1665
1844
  " ",
1666
1845
  t("error_prefix")
1667
1846
  ] }),
1668
- /* @__PURE__ */ jsx7(Text6, { color: COLORS.error, children: message })
1847
+ /* @__PURE__ */ jsx8(Text7, { color: COLORS.error, children: message })
1669
1848
  ] });
1670
1849
  }
1671
1850
 
1672
1851
  // src/components/common/status-badge.tsx
1673
- import { Text as Text7 } from "ink";
1674
- import { jsxs as jsxs7 } from "react/jsx-runtime";
1852
+ import { Text as Text8 } from "ink";
1853
+ import { jsxs as jsxs8 } from "react/jsx-runtime";
1675
1854
  var BADGE_STYLES = {
1676
1855
  success: { icon: "\u2714", color: COLORS.success },
1677
1856
  warning: { icon: "\u25B2", color: COLORS.warning },
@@ -1681,7 +1860,7 @@ var BADGE_STYLES = {
1681
1860
  };
1682
1861
  function StatusBadge({ label, variant }) {
1683
1862
  const { icon, color } = BADGE_STYLES[variant];
1684
- return /* @__PURE__ */ jsxs7(Text7, { color, children: [
1863
+ return /* @__PURE__ */ jsxs8(Text8, { color, children: [
1685
1864
  icon,
1686
1865
  " ",
1687
1866
  label
@@ -1689,16 +1868,16 @@ function StatusBadge({ label, variant }) {
1689
1868
  }
1690
1869
 
1691
1870
  // src/components/common/section-header.tsx
1692
- import { Box as Box7, Text as Text8 } from "ink";
1693
- import { jsx as jsx8, jsxs as jsxs8 } from "react/jsx-runtime";
1871
+ import { Box as Box8, Text as Text9 } from "ink";
1872
+ import { jsx as jsx9, jsxs as jsxs9 } from "react/jsx-runtime";
1694
1873
  function SectionHeader({ emoji, title, color = COLORS.gold, gradient, count }) {
1695
- return /* @__PURE__ */ jsxs8(Box7, { gap: SPACING.xs, children: [
1696
- /* @__PURE__ */ jsxs8(Text8, { children: [
1874
+ return /* @__PURE__ */ jsxs9(Box8, { gap: SPACING.xs, children: [
1875
+ /* @__PURE__ */ jsxs9(Text9, { children: [
1697
1876
  emoji,
1698
1877
  " "
1699
1878
  ] }),
1700
- gradient ? /* @__PURE__ */ jsx8(GradientText, { colors: gradient, bold: true, children: title }) : /* @__PURE__ */ jsx8(Text8, { bold: true, color, children: title }),
1701
- count !== void 0 && /* @__PURE__ */ jsxs8(Text8, { color: COLORS.textSecondary, children: [
1879
+ gradient ? /* @__PURE__ */ jsx9(GradientText, { colors: gradient, bold: true, children: title }) : /* @__PURE__ */ jsx9(Text9, { bold: true, color, children: title }),
1880
+ count !== void 0 && /* @__PURE__ */ jsxs9(Text9, { color: COLORS.textSecondary, children: [
1702
1881
  "(",
1703
1882
  count,
1704
1883
  ")"
@@ -1707,23 +1886,23 @@ function SectionHeader({ emoji, title, color = COLORS.gold, gradient, count }) {
1707
1886
  }
1708
1887
 
1709
1888
  // src/components/common/version-arrow.tsx
1710
- import { Text as Text9 } from "ink";
1711
- import { Fragment as Fragment3, jsx as jsx9, jsxs as jsxs9 } from "react/jsx-runtime";
1889
+ import { Text as Text10 } from "ink";
1890
+ import { Fragment as Fragment3, jsx as jsx10, jsxs as jsxs10 } from "react/jsx-runtime";
1712
1891
  function VersionArrow({ current, latest }) {
1713
- return /* @__PURE__ */ jsxs9(Fragment3, { children: [
1714
- /* @__PURE__ */ jsxs9(Text9, { color: COLORS.muted, children: [
1892
+ return /* @__PURE__ */ jsxs10(Fragment3, { children: [
1893
+ /* @__PURE__ */ jsxs10(Text10, { color: COLORS.muted, children: [
1715
1894
  t("version_installed"),
1716
1895
  " "
1717
1896
  ] }),
1718
- /* @__PURE__ */ jsx9(Text9, { color: COLORS.error, children: current }),
1719
- /* @__PURE__ */ jsx9(Text9, { color: COLORS.warning, children: " \u2500\u2500 " }),
1720
- /* @__PURE__ */ jsx9(Text9, { color: COLORS.gold, children: "\u25B6" }),
1721
- /* @__PURE__ */ jsxs9(Text9, { color: COLORS.muted, children: [
1897
+ /* @__PURE__ */ jsx10(Text10, { color: COLORS.error, children: current }),
1898
+ /* @__PURE__ */ jsx10(Text10, { color: COLORS.warning, children: " \u2500\u2500 " }),
1899
+ /* @__PURE__ */ jsx10(Text10, { color: COLORS.gold, children: "\u25B6" }),
1900
+ /* @__PURE__ */ jsxs10(Text10, { color: COLORS.muted, children: [
1722
1901
  " ",
1723
1902
  t("version_available"),
1724
1903
  " "
1725
1904
  ] }),
1726
- /* @__PURE__ */ jsx9(Text9, { color: COLORS.teal, children: latest })
1905
+ /* @__PURE__ */ jsx10(Text10, { color: COLORS.teal, children: latest })
1727
1906
  ] });
1728
1907
  }
1729
1908
 
@@ -1755,7 +1934,7 @@ function truncate(str, maxLen) {
1755
1934
  }
1756
1935
 
1757
1936
  // src/views/dashboard.tsx
1758
- import { jsx as jsx10, jsxs as jsxs10 } from "react/jsx-runtime";
1937
+ import { jsx as jsx11, jsxs as jsxs11 } from "react/jsx-runtime";
1759
1938
  function ProStatusPanel() {
1760
1939
  const security = useSecurityStore((s) => s.summary);
1761
1940
  const drift = useBrewfileStore((s) => s.drift);
@@ -1767,41 +1946,49 @@ function ProStatusPanel() {
1767
1946
  const lastSync = syncConfig?.lastSync ?? null;
1768
1947
  const syncAgo = lastSync ? formatRelativeTime(new Date(lastSync).getTime() / 1e3) : null;
1769
1948
  const violationCount = complianceReport ? complianceReport.violations.length : null;
1770
- return /* @__PURE__ */ jsxs10(Box8, { flexDirection: "column", borderStyle: "round", borderColor: COLORS.purple, paddingX: SPACING.sm, paddingY: SPACING.none, marginTop: SPACING.xs, children: [
1771
- /* @__PURE__ */ jsx10(Text10, { bold: true, color: COLORS.purple, children: t("dashboard_pro_status") }),
1772
- /* @__PURE__ */ jsxs10(Box8, { gap: SPACING.xs, children: [
1773
- /* @__PURE__ */ jsx10(Text10, { color: COLORS.muted, children: t("dashboard_security") }),
1774
- cveCount === null ? /* @__PURE__ */ jsx10(Text10, { color: COLORS.muted, children: "\u2014" }) : cveCount === 0 ? /* @__PURE__ */ jsx10(Text10, { color: COLORS.success, children: t("dashboard_no_cves") }) : /* @__PURE__ */ jsxs10(Text10, { color: COLORS.error, children: [
1949
+ return /* @__PURE__ */ jsxs11(Box9, { flexDirection: "column", borderStyle: "round", borderColor: COLORS.purple, paddingX: SPACING.sm, paddingY: SPACING.none, marginTop: SPACING.xs, children: [
1950
+ /* @__PURE__ */ jsx11(Text11, { bold: true, color: COLORS.purple, children: t("dashboard_pro_status") }),
1951
+ /* @__PURE__ */ jsxs11(Box9, { gap: SPACING.xs, children: [
1952
+ /* @__PURE__ */ jsx11(Text11, { color: COLORS.muted, children: t("dashboard_security") }),
1953
+ cveCount === null ? /* @__PURE__ */ jsx11(Text11, { color: COLORS.muted, children: "\u2014" }) : cveCount === 0 ? /* @__PURE__ */ jsx11(Text11, { color: COLORS.success, children: t("dashboard_no_cves") }) : /* @__PURE__ */ jsxs11(Text11, { color: COLORS.error, children: [
1775
1954
  t("dashboard_cves", { count: String(cveCount) }),
1776
1955
  criticalCount && criticalCount > 0 ? ` (${criticalCount} critical)` : ""
1777
1956
  ] })
1778
1957
  ] }),
1779
- /* @__PURE__ */ jsxs10(Box8, { gap: SPACING.xs, children: [
1780
- /* @__PURE__ */ jsx10(Text10, { color: COLORS.muted, children: t("dashboard_brewfile") }),
1781
- driftScore === null ? /* @__PURE__ */ jsx10(Text10, { color: COLORS.muted, children: "\u2014" }) : /* @__PURE__ */ jsxs10(Text10, { color: driftScore >= 80 ? COLORS.success : COLORS.warning, children: [
1958
+ /* @__PURE__ */ jsxs11(Box9, { gap: SPACING.xs, children: [
1959
+ /* @__PURE__ */ jsx11(Text11, { color: COLORS.muted, children: t("dashboard_brewfile") }),
1960
+ driftScore === null ? /* @__PURE__ */ jsx11(Text11, { color: COLORS.muted, children: "\u2014" }) : /* @__PURE__ */ jsxs11(Text11, { color: driftScore >= 80 ? COLORS.success : COLORS.warning, children: [
1782
1961
  driftScore,
1783
1962
  "%"
1784
1963
  ] })
1785
1964
  ] }),
1786
- /* @__PURE__ */ jsxs10(Box8, { gap: SPACING.xs, children: [
1787
- /* @__PURE__ */ jsx10(Text10, { color: COLORS.muted, children: t("dashboard_sync") }),
1788
- syncAgo === null ? /* @__PURE__ */ jsx10(Text10, { color: COLORS.muted, children: t("dashboard_sync_never") }) : /* @__PURE__ */ jsx10(Text10, { color: COLORS.info, children: t("dashboard_sync_ago", { time: syncAgo }) })
1965
+ /* @__PURE__ */ jsxs11(Box9, { gap: SPACING.xs, children: [
1966
+ /* @__PURE__ */ jsx11(Text11, { color: COLORS.muted, children: t("dashboard_sync") }),
1967
+ syncAgo === null ? /* @__PURE__ */ jsx11(Text11, { color: COLORS.muted, children: t("dashboard_sync_never") }) : /* @__PURE__ */ jsx11(Text11, { color: COLORS.info, children: t("dashboard_sync_ago", { time: syncAgo }) })
1789
1968
  ] }),
1790
- /* @__PURE__ */ jsxs10(Box8, { gap: SPACING.xs, children: [
1791
- /* @__PURE__ */ jsx10(Text10, { color: COLORS.muted, children: t("dashboard_compliance") }),
1792
- violationCount === null ? /* @__PURE__ */ jsx10(Text10, { color: COLORS.muted, children: "\u2014" }) : violationCount === 0 ? /* @__PURE__ */ jsx10(Text10, { color: COLORS.success, children: t("dashboard_compliance_ok") }) : /* @__PURE__ */ jsx10(Text10, { color: COLORS.warning, children: t("dashboard_compliance_violations", { count: String(violationCount) }) })
1969
+ /* @__PURE__ */ jsxs11(Box9, { gap: SPACING.xs, children: [
1970
+ /* @__PURE__ */ jsx11(Text11, { color: COLORS.muted, children: t("dashboard_compliance") }),
1971
+ violationCount === null ? /* @__PURE__ */ jsx11(Text11, { color: COLORS.muted, children: "\u2014" }) : violationCount === 0 ? /* @__PURE__ */ jsx11(Text11, { color: COLORS.success, children: t("dashboard_compliance_ok") }) : /* @__PURE__ */ jsx11(Text11, { color: COLORS.warning, children: t("dashboard_compliance_violations", { count: String(violationCount) }) })
1793
1972
  ] })
1794
1973
  ] });
1795
1974
  }
1796
1975
  function DashboardView() {
1797
- const { formulae, casks, outdated, services, config, loading, errors, lastFetchedAt, fetchAll } = useBrewStore();
1976
+ const formulae = useBrewStore((s) => s.formulae);
1977
+ const casks = useBrewStore((s) => s.casks);
1978
+ const outdated = useBrewStore((s) => s.outdated);
1979
+ const services = useBrewStore((s) => s.services);
1980
+ const config = useBrewStore((s) => s.config);
1981
+ const loading = useBrewStore((s) => s.loading);
1982
+ const errors = useBrewStore((s) => s.errors);
1983
+ const lastFetchedAt = useBrewStore((s) => s.lastFetchedAt);
1984
+ const fetchAll = useBrewStore((s) => s.fetchAll);
1798
1985
  const isPro = useLicenseStore((s) => s.isPro);
1799
1986
  const { stdout } = useStdout3();
1800
1987
  const columns = stdout?.columns ?? 80;
1801
- useEffect(() => {
1988
+ useEffect2(() => {
1802
1989
  fetchAll();
1803
1990
  }, []);
1804
- useInput2((input) => {
1991
+ useInput3((input) => {
1805
1992
  if (errors.installed && (input === "r" || input === "R")) {
1806
1993
  void fetchAll();
1807
1994
  }
@@ -1823,23 +2010,23 @@ function DashboardView() {
1823
2010
  const outdatedValue = loading.outdated ? "..." : errors.outdated ? t("dashboard_statError") : outdated.formulae.length + outdated.casks.length;
1824
2011
  const servicesValue = loading.services ? "..." : errors.services ? t("dashboard_statError") : `${runningServices}/${services.length}`;
1825
2012
  const lastUpdated = lastFetchedAt.installed ? formatRelativeTime(lastFetchedAt.installed / 1e3) : null;
1826
- if (loading.installed) return /* @__PURE__ */ jsx10(Loading, { message: t("loading_fetchingBrew") });
2013
+ if (loading.installed) return /* @__PURE__ */ jsx11(Loading, { message: t("loading_fetchingBrew") });
1827
2014
  if (errors.installed) {
1828
- return /* @__PURE__ */ jsxs10(Box8, { flexDirection: "column", children: [
1829
- /* @__PURE__ */ jsx10(ErrorMessage, { message: errors.installed }),
1830
- /* @__PURE__ */ jsx10(Box8, { marginTop: SPACING.xs, children: /* @__PURE__ */ jsxs10(Text10, { color: COLORS.textSecondary, children: [
2015
+ return /* @__PURE__ */ jsxs11(Box9, { flexDirection: "column", children: [
2016
+ /* @__PURE__ */ jsx11(ErrorMessage, { message: errors.installed }),
2017
+ /* @__PURE__ */ jsx11(Box9, { marginTop: SPACING.xs, children: /* @__PURE__ */ jsxs11(Text11, { color: COLORS.textSecondary, children: [
1831
2018
  "r:",
1832
2019
  t("hint_refresh")
1833
2020
  ] }) })
1834
2021
  ] });
1835
2022
  }
1836
2023
  const isNarrow = columns < 60;
1837
- return /* @__PURE__ */ jsxs10(Box8, { flexDirection: "column", gap: SPACING.sm, children: [
1838
- /* @__PURE__ */ jsx10(SectionHeader, { emoji: "\u{1F4CA}", title: t("dashboard_overview"), gradient: GRADIENTS.gold }),
1839
- /* @__PURE__ */ jsxs10(Box8, { gap: SPACING.xs, flexWrap: "wrap", flexDirection: isNarrow ? "column" : "row", children: [
1840
- /* @__PURE__ */ jsx10(StatCard, { label: t("dashboard_formulae"), value: formulae.length, color: COLORS.info }),
1841
- /* @__PURE__ */ jsx10(StatCard, { label: t("dashboard_casks"), value: casks.length, color: COLORS.purple }),
1842
- /* @__PURE__ */ jsx10(
2024
+ return /* @__PURE__ */ jsxs11(Box9, { flexDirection: "column", gap: SPACING.sm, children: [
2025
+ /* @__PURE__ */ jsx11(SectionHeader, { emoji: "\u{1F4CA}", title: t("dashboard_overview"), gradient: GRADIENTS.gold }),
2026
+ /* @__PURE__ */ jsxs11(Box9, { gap: SPACING.xs, flexWrap: "wrap", flexDirection: isNarrow ? "column" : "row", children: [
2027
+ /* @__PURE__ */ jsx11(StatCard, { label: t("dashboard_formulae"), value: formulae.length, color: COLORS.info }),
2028
+ /* @__PURE__ */ jsx11(StatCard, { label: t("dashboard_casks"), value: casks.length, color: COLORS.purple }),
2029
+ /* @__PURE__ */ jsx11(
1843
2030
  StatCard,
1844
2031
  {
1845
2032
  label: t("dashboard_outdated"),
@@ -1847,7 +2034,7 @@ function DashboardView() {
1847
2034
  color: typeof outdatedValue === "number" && outdatedValue > 0 ? COLORS.warning : errors.outdated ? COLORS.error : COLORS.success
1848
2035
  }
1849
2036
  ),
1850
- /* @__PURE__ */ jsx10(
2037
+ /* @__PURE__ */ jsx11(
1851
2038
  StatCard,
1852
2039
  {
1853
2040
  label: t("dashboard_services"),
@@ -1856,66 +2043,66 @@ function DashboardView() {
1856
2043
  }
1857
2044
  )
1858
2045
  ] }),
1859
- lastUpdated && /* @__PURE__ */ jsx10(Text10, { color: COLORS.muted, children: t("dashboard_lastUpdated", { time: lastUpdated }) }),
1860
- partialErrors.length > 0 && /* @__PURE__ */ jsxs10(Box8, { flexDirection: "column", borderStyle: "round", borderColor: COLORS.warning, paddingX: SPACING.sm, paddingY: SPACING.none, children: [
1861
- /* @__PURE__ */ jsx10(Text10, { color: COLORS.warning, bold: true, children: t("dashboard_partialData") }),
1862
- partialErrors.map((item) => /* @__PURE__ */ jsxs10(Text10, { color: COLORS.muted, children: [
2046
+ lastUpdated && /* @__PURE__ */ jsx11(Text11, { color: COLORS.muted, children: t("dashboard_lastUpdated", { time: lastUpdated }) }),
2047
+ partialErrors.length > 0 && /* @__PURE__ */ jsxs11(Box9, { flexDirection: "column", borderStyle: "round", borderColor: COLORS.warning, paddingX: SPACING.sm, paddingY: SPACING.none, children: [
2048
+ /* @__PURE__ */ jsx11(Text11, { color: COLORS.warning, bold: true, children: t("dashboard_partialData") }),
2049
+ partialErrors.map((item) => /* @__PURE__ */ jsxs11(Text11, { color: COLORS.muted, children: [
1863
2050
  item.label,
1864
2051
  ": ",
1865
2052
  item.message
1866
2053
  ] }, item.label))
1867
2054
  ] }),
1868
- config && !errors.config && /* @__PURE__ */ jsxs10(Box8, { flexDirection: "column", children: [
1869
- /* @__PURE__ */ jsx10(SectionHeader, { emoji: "\u2139\uFE0F", title: t("dashboard_systemInfo"), gradient: [COLORS.text, COLORS.muted] }),
1870
- /* @__PURE__ */ jsxs10(Box8, { borderStyle: "round", borderColor: COLORS.blue, paddingX: SPACING.sm, paddingY: SPACING.none, flexDirection: "column", marginTop: SPACING.xs, children: [
1871
- /* @__PURE__ */ jsxs10(Text10, { children: [
1872
- /* @__PURE__ */ jsx10(Text10, { color: COLORS.muted, children: t("dashboard_homebrew") }),
2055
+ config && !errors.config && /* @__PURE__ */ jsxs11(Box9, { flexDirection: "column", children: [
2056
+ /* @__PURE__ */ jsx11(SectionHeader, { emoji: "\u2139\uFE0F", title: t("dashboard_systemInfo"), gradient: [COLORS.text, COLORS.muted] }),
2057
+ /* @__PURE__ */ jsxs11(Box9, { borderStyle: "round", borderColor: COLORS.blue, paddingX: SPACING.sm, paddingY: SPACING.none, flexDirection: "column", marginTop: SPACING.xs, children: [
2058
+ /* @__PURE__ */ jsxs11(Text11, { children: [
2059
+ /* @__PURE__ */ jsx11(Text11, { color: COLORS.muted, children: t("dashboard_homebrew") }),
1873
2060
  " ",
1874
2061
  config.HOMEBREW_VERSION
1875
2062
  ] }),
1876
- /* @__PURE__ */ jsxs10(Text10, { children: [
1877
- /* @__PURE__ */ jsx10(Text10, { color: COLORS.muted, children: t("dashboard_prefix") }),
2063
+ /* @__PURE__ */ jsxs11(Text11, { children: [
2064
+ /* @__PURE__ */ jsx11(Text11, { color: COLORS.muted, children: t("dashboard_prefix") }),
1878
2065
  " ",
1879
2066
  config.HOMEBREW_PREFIX
1880
2067
  ] }),
1881
- /* @__PURE__ */ jsxs10(Text10, { children: [
1882
- /* @__PURE__ */ jsx10(Text10, { color: COLORS.muted, children: t("dashboard_updated") }),
2068
+ /* @__PURE__ */ jsxs11(Text11, { children: [
2069
+ /* @__PURE__ */ jsx11(Text11, { color: COLORS.muted, children: t("dashboard_updated") }),
1883
2070
  " ",
1884
2071
  config.coreUpdated
1885
2072
  ] })
1886
2073
  ] })
1887
2074
  ] }),
1888
- !errors.outdated && outdated.formulae.length > 0 && /* @__PURE__ */ jsxs10(Box8, { flexDirection: "column", marginTop: SPACING.xs, children: [
1889
- /* @__PURE__ */ jsx10(SectionHeader, { emoji: "\u{1F4E6}", title: t("dashboard_outdatedPackages"), gradient: GRADIENTS.fire }),
1890
- /* @__PURE__ */ jsxs10(Box8, { paddingLeft: SPACING.sm, flexDirection: "column", children: [
1891
- outdated.formulae.slice(0, 10).map((pkg) => /* @__PURE__ */ jsxs10(Box8, { gap: SPACING.xs, children: [
1892
- /* @__PURE__ */ jsx10(Text10, { color: COLORS.text, children: pkg.name }),
1893
- /* @__PURE__ */ jsx10(VersionArrow, { current: pkg.installed_versions[0] ?? "", latest: pkg.current_version })
2075
+ !errors.outdated && outdated.formulae.length > 0 && /* @__PURE__ */ jsxs11(Box9, { flexDirection: "column", marginTop: SPACING.xs, children: [
2076
+ /* @__PURE__ */ jsx11(SectionHeader, { emoji: "\u{1F4E6}", title: t("dashboard_outdatedPackages"), gradient: GRADIENTS.fire }),
2077
+ /* @__PURE__ */ jsxs11(Box9, { paddingLeft: SPACING.sm, flexDirection: "column", children: [
2078
+ outdated.formulae.slice(0, 10).map((pkg) => /* @__PURE__ */ jsxs11(Box9, { gap: SPACING.xs, children: [
2079
+ /* @__PURE__ */ jsx11(Text11, { color: COLORS.text, children: pkg.name }),
2080
+ /* @__PURE__ */ jsx11(VersionArrow, { current: pkg.installed_versions[0] ?? "", latest: pkg.current_version })
1894
2081
  ] }, pkg.name)),
1895
- outdated.formulae.length > 10 && /* @__PURE__ */ jsx10(Text10, { color: COLORS.textSecondary, italic: true, children: t("common_andMore", { count: outdated.formulae.length - 10 }) })
2082
+ outdated.formulae.length > 10 && /* @__PURE__ */ jsx11(Text11, { color: COLORS.textSecondary, italic: true, children: t("common_andMore", { count: outdated.formulae.length - 10 }) })
1896
2083
  ] })
1897
2084
  ] }),
1898
- !errors.services && errorServices > 0 && /* @__PURE__ */ jsxs10(Box8, { flexDirection: "column", marginTop: SPACING.xs, children: [
1899
- /* @__PURE__ */ jsx10(SectionHeader, { emoji: "\u26A0\uFE0F", title: t("dashboard_serviceErrors"), color: COLORS.error }),
1900
- /* @__PURE__ */ jsx10(Box8, { paddingLeft: SPACING.sm, flexDirection: "column", children: errorServiceList.map((s) => /* @__PURE__ */ jsxs10(Box8, { gap: SPACING.xs, children: [
1901
- /* @__PURE__ */ jsx10(StatusBadge, { label: t("badge_error"), variant: "error" }),
1902
- /* @__PURE__ */ jsx10(Text10, { children: s.name }),
1903
- s.exit_code != null && /* @__PURE__ */ jsx10(Text10, { color: COLORS.muted, children: t("common_exit", { code: s.exit_code }) })
2085
+ !errors.services && errorServices > 0 && /* @__PURE__ */ jsxs11(Box9, { flexDirection: "column", marginTop: SPACING.xs, children: [
2086
+ /* @__PURE__ */ jsx11(SectionHeader, { emoji: "\u26A0\uFE0F", title: t("dashboard_serviceErrors"), color: COLORS.error }),
2087
+ /* @__PURE__ */ jsx11(Box9, { paddingLeft: SPACING.sm, flexDirection: "column", children: errorServiceList.map((s) => /* @__PURE__ */ jsxs11(Box9, { gap: SPACING.xs, children: [
2088
+ /* @__PURE__ */ jsx11(StatusBadge, { label: t("badge_error"), variant: "error" }),
2089
+ /* @__PURE__ */ jsx11(Text11, { children: s.name }),
2090
+ s.exit_code != null && /* @__PURE__ */ jsx11(Text11, { color: COLORS.muted, children: t("common_exit", { code: s.exit_code }) })
1904
2091
  ] }, s.name)) })
1905
2092
  ] }),
1906
- isPro() && /* @__PURE__ */ jsx10(ProStatusPanel, {})
2093
+ isPro() && /* @__PURE__ */ jsx11(ProStatusPanel, {})
1907
2094
  ] });
1908
2095
  }
1909
2096
 
1910
2097
  // src/views/installed.tsx
1911
- import { useState as useState3, useMemo as useMemo3, useEffect as useEffect5 } from "react";
1912
- import { Box as Box14, Text as Text16, useInput as useInput4, useStdout as useStdout4 } from "ink";
2098
+ import { useState as useState3, useMemo as useMemo3, useEffect as useEffect6 } from "react";
2099
+ import { Box as Box15, Text as Text17, useInput as useInput5, useStdout as useStdout4 } from "ink";
1913
2100
 
1914
2101
  // src/hooks/use-debounce.ts
1915
- import { useState, useEffect as useEffect2 } from "react";
2102
+ import { useState, useEffect as useEffect3 } from "react";
1916
2103
  function useDebounce(value, delayMs) {
1917
2104
  const [debounced, setDebounced] = useState(value);
1918
- useEffect2(() => {
2105
+ useEffect3(() => {
1919
2106
  const timer = setTimeout(() => setDebounced(value), delayMs);
1920
2107
  return () => clearTimeout(timer);
1921
2108
  }, [value, delayMs]);
@@ -1923,14 +2110,14 @@ function useDebounce(value, delayMs) {
1923
2110
  }
1924
2111
 
1925
2112
  // src/hooks/use-brew-stream.ts
1926
- import { useState as useState2, useCallback, useRef, useEffect as useEffect3 } from "react";
2113
+ import { useState as useState2, useCallback, useRef, useEffect as useEffect4 } from "react";
1927
2114
  var MAX_LINES = 100;
1928
2115
  async function logToHistory(args, success, error) {
1929
2116
  const detected = detectAction(args);
1930
2117
  if (!detected) return;
1931
2118
  try {
1932
2119
  const isPro = useLicenseStore.getState().isPro();
1933
- const { appendEntry: appendEntry2 } = await import("./history-logger-ZGYRAFON.js");
2120
+ const { appendEntry: appendEntry2 } = await import("./history-logger-FJ3HZSFU.js");
1934
2121
  await appendEntry2(isPro, detected.action, detected.packageName, success, error);
1935
2122
  } catch {
1936
2123
  }
@@ -1942,7 +2129,7 @@ function useBrewStream() {
1942
2129
  const cancelRef = useRef(false);
1943
2130
  const generatorRef = useRef(null);
1944
2131
  const mountedRef = useRef(true);
1945
- useEffect3(() => {
2132
+ useEffect4(() => {
1946
2133
  mountedRef.current = true;
1947
2134
  return () => {
1948
2135
  mountedRef.current = false;
@@ -1982,7 +2169,7 @@ function useBrewStream() {
1982
2169
  }
1983
2170
  const MUTATING_COMMANDS = /* @__PURE__ */ new Set(["install", "uninstall", "upgrade", "pin", "unpin", "tap", "untap"]);
1984
2171
  if (!cancelRef.current && MUTATING_COMMANDS.has(args[0] ?? "")) {
1985
- void import("./snapshot-YWIOFQ5H.js").then(({ captureSnapshot: captureSnapshot2, saveSnapshot: saveSnapshot2 }) => {
2172
+ void import("./snapshot-JDRSBMG6.js").then(({ captureSnapshot: captureSnapshot2, saveSnapshot: saveSnapshot2 }) => {
1986
2173
  captureSnapshot2().then((s) => saveSnapshot2(s)).catch((err) => logger.warn("snapshot: capture/save failed", { error: String(err) }));
1987
2174
  });
1988
2175
  }
@@ -2000,78 +2187,84 @@ function useBrewStream() {
2000
2187
  }
2001
2188
 
2002
2189
  // src/components/common/search-input.tsx
2003
- import { Box as Box9, Text as Text11 } from "ink";
2190
+ import { Box as Box10, Text as Text12 } from "ink";
2004
2191
  import { TextInput } from "@inkjs/ui";
2005
- import { jsx as jsx11, jsxs as jsxs11 } from "react/jsx-runtime";
2192
+ import { jsx as jsx12, jsxs as jsxs12 } from "react/jsx-runtime";
2006
2193
  function SearchInput({ defaultValue, onChange, placeholder, isActive = true }) {
2007
2194
  const resolvedPlaceholder = placeholder ?? t("searchInput_placeholder");
2008
- return /* @__PURE__ */ jsxs11(Box9, { children: [
2009
- /* @__PURE__ */ jsxs11(Text11, { color: COLORS.gold, children: [
2195
+ return /* @__PURE__ */ jsxs12(Box10, { children: [
2196
+ /* @__PURE__ */ jsxs12(Text12, { color: COLORS.gold, children: [
2010
2197
  "\u{1F50D}",
2011
2198
  " "
2012
2199
  ] }),
2013
- isActive ? /* @__PURE__ */ jsx11(
2200
+ isActive ? /* @__PURE__ */ jsx12(
2014
2201
  TextInput,
2015
2202
  {
2016
2203
  placeholder: resolvedPlaceholder,
2017
2204
  defaultValue,
2018
2205
  onChange
2019
2206
  }
2020
- ) : /* @__PURE__ */ jsx11(Text11, { color: COLORS.textSecondary, children: defaultValue || placeholder })
2207
+ ) : /* @__PURE__ */ jsx12(Text12, { color: COLORS.textSecondary, children: defaultValue || placeholder })
2021
2208
  ] });
2022
2209
  }
2023
2210
 
2024
2211
  // src/components/common/confirm-dialog.tsx
2025
- import { useEffect as useEffect4 } from "react";
2026
- import { Box as Box10, Text as Text12, useInput as useInput3 } from "ink";
2027
- import { jsx as jsx12, jsxs as jsxs12 } from "react/jsx-runtime";
2212
+ import { useEffect as useEffect5 } from "react";
2213
+ import { Box as Box11, Text as Text13, useInput as useInput4 } from "ink";
2214
+ import { jsx as jsx13, jsxs as jsxs13 } from "react/jsx-runtime";
2028
2215
  function ConfirmDialog({ message, onConfirm, onCancel }) {
2029
2216
  const locale = useLocaleStore((s) => s.locale);
2030
2217
  const { openModal, closeModal } = useModalStore();
2031
- useEffect4(() => {
2218
+ useEffect5(() => {
2032
2219
  openModal();
2033
2220
  return () => {
2034
2221
  closeModal();
2035
2222
  };
2036
2223
  }, []);
2037
- useInput3((input, key) => {
2224
+ useInput4((input, key) => {
2038
2225
  if (input === "y" || input === "Y") onConfirm();
2039
2226
  else if (locale === "es" && (input === "s" || input === "S")) onConfirm();
2040
2227
  else if (input === "n" || input === "N") onCancel();
2041
2228
  else if (key.escape) onCancel();
2042
2229
  });
2043
- return /* @__PURE__ */ jsxs12(Box10, { borderStyle: "double", borderColor: COLORS.purple, paddingX: SPACING.sm, paddingY: SPACING.xs, flexDirection: "column", children: [
2044
- /* @__PURE__ */ jsx12(Text12, { bold: true, color: COLORS.text, children: message }),
2045
- /* @__PURE__ */ jsxs12(Box10, { marginTop: SPACING.xs, children: [
2046
- /* @__PURE__ */ jsx12(Text12, { color: COLORS.success, children: t("confirm_yes") }),
2047
- /* @__PURE__ */ jsx12(Text12, { children: " / " }),
2048
- /* @__PURE__ */ jsx12(Text12, { color: COLORS.error, children: t("confirm_no") })
2230
+ return /* @__PURE__ */ jsxs13(Box11, { borderStyle: "double", borderColor: COLORS.purple, paddingX: SPACING.sm, paddingY: SPACING.xs, flexDirection: "column", children: [
2231
+ /* @__PURE__ */ jsx13(Text13, { bold: true, color: COLORS.text, children: message }),
2232
+ /* @__PURE__ */ jsxs13(Box11, { marginTop: SPACING.xs, children: [
2233
+ /* @__PURE__ */ jsx13(Text13, { color: COLORS.success, children: t("confirm_yes") }),
2234
+ /* @__PURE__ */ jsx13(Text13, { children: " / " }),
2235
+ /* @__PURE__ */ jsx13(Text13, { color: COLORS.error, children: t("confirm_no") })
2049
2236
  ] })
2050
2237
  ] });
2051
2238
  }
2052
2239
 
2053
2240
  // src/components/common/progress-log.tsx
2054
- import { Box as Box11, Text as Text13 } from "ink";
2241
+ import { Box as Box12, Text as Text14 } from "ink";
2055
2242
  import { Spinner as Spinner2 } from "@inkjs/ui";
2056
- import { jsx as jsx13, jsxs as jsxs13 } from "react/jsx-runtime";
2243
+ import { jsx as jsx14, jsxs as jsxs14 } from "react/jsx-runtime";
2057
2244
  function ProgressLog({ lines, isRunning, title, maxVisible = 15 }) {
2058
- const visible = lines.slice(-maxVisible);
2059
- return /* @__PURE__ */ jsxs13(Box11, { flexDirection: "column", borderStyle: "round", borderColor: COLORS.sky, paddingX: SPACING.xs, children: [
2060
- title && /* @__PURE__ */ jsxs13(Box11, { marginBottom: SPACING.xs, children: [
2061
- isRunning && /* @__PURE__ */ jsx13(Spinner2, { label: "" }),
2062
- /* @__PURE__ */ jsxs13(Text13, { bold: true, color: COLORS.sky, children: [
2245
+ const start = Math.max(0, lines.length - maxVisible);
2246
+ const visible = lines.slice(start);
2247
+ return /* @__PURE__ */ jsxs14(Box12, { flexDirection: "column", borderStyle: "round", borderColor: COLORS.sky, paddingX: SPACING.xs, children: [
2248
+ title && /* @__PURE__ */ jsxs14(Box12, { marginBottom: SPACING.xs, children: [
2249
+ isRunning && /* @__PURE__ */ jsx14(Spinner2, { label: "" }),
2250
+ /* @__PURE__ */ jsxs14(Text14, { bold: true, color: COLORS.sky, children: [
2063
2251
  " ",
2064
2252
  title
2065
2253
  ] })
2066
2254
  ] }),
2067
- visible.map((line, i) => /* @__PURE__ */ jsx13(Text13, { color: COLORS.muted, wrap: "wrap", children: line }, lines.length - visible.length + i)),
2068
- lines.length === 0 && !isRunning && /* @__PURE__ */ jsx13(Text13, { color: COLORS.textSecondary, italic: true, children: t("progress_noOutput") })
2255
+ visible.map((line, i) => (
2256
+ // UI-006: keys are absolute indices, so a line that scrolls off-screen
2257
+ // does not change the key of remaining lines. Stable identity prevents
2258
+ // React from treating the whole list as new on every append.
2259
+ /* @__PURE__ */ jsx14(Text14, { color: COLORS.muted, wrap: "wrap", children: line }, `log-${start + i}`)
2260
+ )),
2261
+ lines.length === 0 && !isRunning && /* @__PURE__ */ jsx14(Text14, { color: COLORS.textSecondary, italic: true, children: t("progress_noOutput") })
2069
2262
  ] });
2070
2263
  }
2071
2264
 
2072
2265
  // src/components/common/result-banner.tsx
2073
- import { Box as Box12, Text as Text14 } from "ink";
2074
- import { jsx as jsx14 } from "react/jsx-runtime";
2266
+ import { Box as Box13, Text as Text15 } from "ink";
2267
+ import { jsx as jsx15 } from "react/jsx-runtime";
2075
2268
  var STATUS_COLORS = {
2076
2269
  success: COLORS.success,
2077
2270
  error: COLORS.error,
@@ -2079,21 +2272,21 @@ var STATUS_COLORS = {
2079
2272
  info: COLORS.info
2080
2273
  };
2081
2274
  function ResultBanner({ status, message }) {
2082
- return /* @__PURE__ */ jsx14(Box12, { borderStyle: "round", borderColor: STATUS_COLORS[status], paddingX: SPACING.sm, paddingY: SPACING.none, children: /* @__PURE__ */ jsx14(Text14, { color: STATUS_COLORS[status], bold: true, children: message }) });
2275
+ return /* @__PURE__ */ jsx15(Box13, { borderStyle: "round", borderColor: STATUS_COLORS[status], paddingX: SPACING.sm, paddingY: SPACING.none, children: /* @__PURE__ */ jsx15(Text15, { color: STATUS_COLORS[status], bold: true, children: message }) });
2083
2276
  }
2084
2277
 
2085
2278
  // src/components/common/selectable-row.tsx
2086
- import { Box as Box13, Text as Text15 } from "ink";
2087
- import { jsx as jsx15, jsxs as jsxs14 } from "react/jsx-runtime";
2279
+ import { Box as Box14, Text as Text16 } from "ink";
2280
+ import { jsx as jsx16, jsxs as jsxs15 } from "react/jsx-runtime";
2088
2281
  function SelectableRow({ isCurrent, children, gap = 1 }) {
2089
- return /* @__PURE__ */ jsxs14(Box13, { gap, children: [
2090
- /* @__PURE__ */ jsx15(Text15, { color: isCurrent ? COLORS.success : COLORS.muted, children: isCurrent ? "\u25B6" : " " }),
2282
+ return /* @__PURE__ */ jsxs15(Box14, { gap, children: [
2283
+ /* @__PURE__ */ jsx16(Text16, { color: isCurrent ? COLORS.success : COLORS.muted, children: isCurrent ? "\u25B6" : " " }),
2091
2284
  children
2092
2285
  ] });
2093
2286
  }
2094
2287
 
2095
2288
  // src/views/installed.tsx
2096
- import { jsx as jsx16, jsxs as jsxs15 } from "react/jsx-runtime";
2289
+ import { jsx as jsx17, jsxs as jsxs16 } from "react/jsx-runtime";
2097
2290
  function InstalledView() {
2098
2291
  const formulae = useBrewStore((s) => s.formulae);
2099
2292
  const casks = useBrewStore((s) => s.casks);
@@ -2114,10 +2307,10 @@ function InstalledView() {
2114
2307
  const cols = stdout?.columns ?? 80;
2115
2308
  const nameWidth = Math.floor(cols * 0.35);
2116
2309
  const versionWidth = Math.floor(cols * 0.15);
2117
- useEffect5(() => {
2310
+ useEffect6(() => {
2118
2311
  fetchInstalled();
2119
2312
  }, []);
2120
- useEffect5(() => {
2313
+ useEffect6(() => {
2121
2314
  if (isSearching) {
2122
2315
  openModal();
2123
2316
  return () => {
@@ -2134,9 +2327,13 @@ function InstalledView() {
2134
2327
  (p) => p.name.toLowerCase().includes(lower) || p.desc.toLowerCase().includes(lower)
2135
2328
  );
2136
2329
  }, [formulae, casks, tab, debouncedFilter]);
2137
- useInput4((input, key) => {
2138
- if (confirmUninstall || stream.isRunning) return;
2139
- if (!stream.isRunning && stream.lines.length > 0) {
2330
+ useInput5((input, key) => {
2331
+ if (confirmUninstall) return;
2332
+ if (stream.isRunning) {
2333
+ if (key.escape) stream.cancel();
2334
+ return;
2335
+ }
2336
+ if (stream.lines.length > 0) {
2140
2337
  if (key.escape) {
2141
2338
  stream.clear();
2142
2339
  void fetchInstalled();
@@ -2174,11 +2371,11 @@ function InstalledView() {
2174
2371
  setCursor(0);
2175
2372
  }
2176
2373
  }, { isActive: true });
2177
- if (loading.installed) return /* @__PURE__ */ jsx16(Loading, { message: t("loading_installed") });
2178
- if (errors.installed) return /* @__PURE__ */ jsx16(ErrorMessage, { message: errors.installed });
2374
+ if (loading.installed) return /* @__PURE__ */ jsx17(Loading, { message: t("loading_installed") });
2375
+ if (errors.installed) return /* @__PURE__ */ jsx17(ErrorMessage, { message: errors.installed });
2179
2376
  if (stream.isRunning || stream.lines.length > 0) {
2180
- return /* @__PURE__ */ jsxs15(Box14, { flexDirection: "column", children: [
2181
- /* @__PURE__ */ jsx16(
2377
+ return /* @__PURE__ */ jsxs16(Box15, { flexDirection: "column", children: [
2378
+ /* @__PURE__ */ jsx17(
2182
2379
  ProgressLog,
2183
2380
  {
2184
2381
  lines: stream.lines,
@@ -2186,19 +2383,19 @@ function InstalledView() {
2186
2383
  title: t("pkgInfo_uninstalling", { name: "..." })
2187
2384
  }
2188
2385
  ),
2189
- stream.isRunning && /* @__PURE__ */ jsxs15(Text16, { color: COLORS.textSecondary, children: [
2386
+ stream.isRunning && /* @__PURE__ */ jsxs16(Text17, { color: COLORS.textSecondary, children: [
2190
2387
  "esc:",
2191
2388
  t("hint_cancel")
2192
2389
  ] }),
2193
- !stream.isRunning && /* @__PURE__ */ jsxs15(Box14, { flexDirection: "column", marginTop: SPACING.xs, children: [
2194
- /* @__PURE__ */ jsx16(
2390
+ !stream.isRunning && /* @__PURE__ */ jsxs16(Box15, { flexDirection: "column", marginTop: SPACING.xs, children: [
2391
+ /* @__PURE__ */ jsx17(
2195
2392
  ResultBanner,
2196
2393
  {
2197
2394
  status: stream.error ? "error" : "success",
2198
2395
  message: stream.error ? `\u2718 ${stream.error}` : `\u2714 ${t("pkgInfo_done")}`
2199
2396
  }
2200
2397
  ),
2201
- /* @__PURE__ */ jsxs15(Text16, { color: COLORS.textSecondary, children: [
2398
+ /* @__PURE__ */ jsxs16(Text17, { color: COLORS.textSecondary, children: [
2202
2399
  "esc:",
2203
2400
  t("hint_back")
2204
2401
  ] })
@@ -2208,28 +2405,28 @@ function InstalledView() {
2208
2405
  const MAX_VISIBLE_ROWS = Math.max(5, (stdout?.rows ?? 24) - 8);
2209
2406
  const start = Math.max(0, cursor - Math.floor(MAX_VISIBLE_ROWS / 2));
2210
2407
  const visible = allItems.slice(start, start + MAX_VISIBLE_ROWS);
2211
- return /* @__PURE__ */ jsxs15(Box14, { flexDirection: "column", children: [
2212
- /* @__PURE__ */ jsxs15(Box14, { marginBottom: SPACING.xs, gap: SPACING.xs, children: [
2213
- /* @__PURE__ */ jsx16(
2214
- Box14,
2408
+ return /* @__PURE__ */ jsxs16(Box15, { flexDirection: "column", children: [
2409
+ /* @__PURE__ */ jsxs16(Box15, { marginBottom: SPACING.xs, gap: SPACING.xs, children: [
2410
+ /* @__PURE__ */ jsx17(
2411
+ Box15,
2215
2412
  {
2216
2413
  borderStyle: "round",
2217
2414
  borderColor: tab === "formulae" ? COLORS.info : COLORS.textSecondary,
2218
2415
  paddingX: SPACING.xs,
2219
- children: /* @__PURE__ */ jsxs15(Text16, { bold: tab === "formulae", color: tab === "formulae" ? COLORS.info : COLORS.textSecondary, children: [
2416
+ children: /* @__PURE__ */ jsxs16(Text17, { bold: tab === "formulae", color: tab === "formulae" ? COLORS.info : COLORS.textSecondary, children: [
2220
2417
  "\u{1F4E6}",
2221
2418
  " ",
2222
2419
  t("installed_formulaeCount", { count: formulae.length })
2223
2420
  ] })
2224
2421
  }
2225
2422
  ),
2226
- /* @__PURE__ */ jsx16(
2227
- Box14,
2423
+ /* @__PURE__ */ jsx17(
2424
+ Box15,
2228
2425
  {
2229
2426
  borderStyle: "round",
2230
2427
  borderColor: tab === "casks" ? COLORS.purple : COLORS.textSecondary,
2231
2428
  paddingX: SPACING.xs,
2232
- children: /* @__PURE__ */ jsxs15(Text16, { bold: tab === "casks", color: tab === "casks" ? COLORS.purple : COLORS.textSecondary, children: [
2429
+ children: /* @__PURE__ */ jsxs16(Text17, { bold: tab === "casks", color: tab === "casks" ? COLORS.purple : COLORS.textSecondary, children: [
2233
2430
  "\u{1F37A}",
2234
2431
  " ",
2235
2432
  t("installed_casksCount", { count: casks.length })
@@ -2237,7 +2434,7 @@ function InstalledView() {
2237
2434
  }
2238
2435
  )
2239
2436
  ] }),
2240
- confirmUninstall && /* @__PURE__ */ jsx16(
2437
+ confirmUninstall && /* @__PURE__ */ jsx17(
2241
2438
  ConfirmDialog,
2242
2439
  {
2243
2440
  message: t("installed_confirmUninstall", { name: confirmUninstall }),
@@ -2251,48 +2448,48 @@ function InstalledView() {
2251
2448
  onCancel: () => setConfirmUninstall(null)
2252
2449
  }
2253
2450
  ),
2254
- isSearching && /* @__PURE__ */ jsx16(Box14, { marginBottom: SPACING.xs, borderStyle: "round", borderColor: COLORS.gold, paddingX: SPACING.xs, children: /* @__PURE__ */ jsx16(SearchInput, { defaultValue: filter, onChange: setFilter, isActive: isSearching }) }),
2255
- /* @__PURE__ */ jsxs15(Box14, { gap: SPACING.xs, borderStyle: "single", borderBottom: true, borderTop: false, borderLeft: false, borderRight: false, borderColor: COLORS.border, children: [
2256
- /* @__PURE__ */ jsxs15(Text16, { color: COLORS.text, bold: true, children: [
2451
+ isSearching && /* @__PURE__ */ jsx17(Box15, { marginBottom: SPACING.xs, borderStyle: "round", borderColor: COLORS.gold, paddingX: SPACING.xs, children: /* @__PURE__ */ jsx17(SearchInput, { defaultValue: filter, onChange: setFilter, isActive: isSearching }) }),
2452
+ /* @__PURE__ */ jsxs16(Box15, { gap: SPACING.xs, borderStyle: "single", borderBottom: true, borderTop: false, borderLeft: false, borderRight: false, borderColor: COLORS.border, children: [
2453
+ /* @__PURE__ */ jsxs16(Text17, { color: COLORS.text, bold: true, children: [
2257
2454
  " ",
2258
2455
  t("installed_col_package").padEnd(nameWidth)
2259
2456
  ] }),
2260
- /* @__PURE__ */ jsx16(Text16, { color: COLORS.text, bold: true, children: t("installed_col_version").padEnd(versionWidth) }),
2261
- /* @__PURE__ */ jsx16(Text16, { color: COLORS.text, bold: true, children: t("installed_col_status") })
2457
+ /* @__PURE__ */ jsx17(Text17, { color: COLORS.text, bold: true, children: t("installed_col_version").padEnd(versionWidth) }),
2458
+ /* @__PURE__ */ jsx17(Text17, { color: COLORS.text, bold: true, children: t("installed_col_status") })
2262
2459
  ] }),
2263
- /* @__PURE__ */ jsxs15(Box14, { flexDirection: "column", children: [
2264
- visible.length === 0 && /* @__PURE__ */ jsx16(Box14, { paddingY: SPACING.xs, justifyContent: "center", children: /* @__PURE__ */ jsx16(Text16, { color: COLORS.textSecondary, italic: true, children: t("installed_noPackages") }) }),
2265
- start > 0 && /* @__PURE__ */ jsxs15(Text16, { color: COLORS.textSecondary, dimColor: true, children: [
2460
+ /* @__PURE__ */ jsxs16(Box15, { flexDirection: "column", children: [
2461
+ visible.length === 0 && /* @__PURE__ */ jsx17(Box15, { paddingY: SPACING.xs, justifyContent: "center", children: /* @__PURE__ */ jsx17(Text17, { color: COLORS.textSecondary, italic: true, children: t("installed_noPackages") }) }),
2462
+ start > 0 && /* @__PURE__ */ jsxs16(Text17, { color: COLORS.textSecondary, dimColor: true, children: [
2266
2463
  " ",
2267
2464
  t("scroll_moreAbove", { count: start })
2268
2465
  ] }),
2269
2466
  visible.map((item, i) => {
2270
2467
  const idx = start + i;
2271
2468
  const isCurrent = idx === cursor;
2272
- return /* @__PURE__ */ jsxs15(SelectableRow, { isCurrent, children: [
2273
- /* @__PURE__ */ jsx16(Text16, { bold: isCurrent, inverse: isCurrent, color: isCurrent ? COLORS.text : COLORS.muted, children: truncate(item.name, nameWidth).padEnd(nameWidth) }),
2274
- /* @__PURE__ */ jsx16(Text16, { color: COLORS.teal, children: item.version.padEnd(versionWidth) }),
2275
- item.outdated && /* @__PURE__ */ jsx16(StatusBadge, { label: t("badge_outdated"), variant: "warning" }),
2276
- item.pinned && /* @__PURE__ */ jsx16(StatusBadge, { label: t("badge_pinned"), variant: "info" }),
2277
- item.kegOnly && /* @__PURE__ */ jsx16(StatusBadge, { label: t("badge_kegOnly"), variant: "muted" }),
2278
- item.installedAsDependency && /* @__PURE__ */ jsx16(StatusBadge, { label: t("badge_dep"), variant: "muted" }),
2279
- !item.outdated && !item.pinned && !item.kegOnly && !item.installedAsDependency && /* @__PURE__ */ jsx16(Text16, { color: COLORS.textSecondary, dimColor: true, children: truncate(item.desc, 30) })
2469
+ return /* @__PURE__ */ jsxs16(SelectableRow, { isCurrent, children: [
2470
+ /* @__PURE__ */ jsx17(Text17, { bold: isCurrent, inverse: isCurrent, color: isCurrent ? COLORS.text : COLORS.muted, children: truncate(item.name, nameWidth).padEnd(nameWidth) }),
2471
+ /* @__PURE__ */ jsx17(Text17, { color: COLORS.teal, children: item.version.padEnd(versionWidth) }),
2472
+ item.outdated && /* @__PURE__ */ jsx17(StatusBadge, { label: t("badge_outdated"), variant: "warning" }),
2473
+ item.pinned && /* @__PURE__ */ jsx17(StatusBadge, { label: t("badge_pinned"), variant: "info" }),
2474
+ item.kegOnly && /* @__PURE__ */ jsx17(StatusBadge, { label: t("badge_kegOnly"), variant: "muted" }),
2475
+ item.installedAsDependency && /* @__PURE__ */ jsx17(StatusBadge, { label: t("badge_dep"), variant: "muted" }),
2476
+ !item.outdated && !item.pinned && !item.kegOnly && !item.installedAsDependency && /* @__PURE__ */ jsx17(Text17, { color: COLORS.textSecondary, dimColor: true, children: truncate(item.desc, 30) })
2280
2477
  ] }, item.name);
2281
2478
  }),
2282
- start + MAX_VISIBLE_ROWS < allItems.length && /* @__PURE__ */ jsxs15(Text16, { color: COLORS.textSecondary, dimColor: true, children: [
2479
+ start + MAX_VISIBLE_ROWS < allItems.length && /* @__PURE__ */ jsxs16(Text17, { color: COLORS.textSecondary, dimColor: true, children: [
2283
2480
  " ",
2284
2481
  t("scroll_moreBelow", { count: allItems.length - start - MAX_VISIBLE_ROWS })
2285
2482
  ] })
2286
2483
  ] }),
2287
- /* @__PURE__ */ jsx16(Box14, { marginTop: SPACING.xs, children: /* @__PURE__ */ jsx16(Text16, { color: COLORS.text, bold: true, children: allItems.length > 0 ? `${cursor + 1}/${allItems.length}` : "0/0" }) })
2484
+ /* @__PURE__ */ jsx17(Box15, { marginTop: SPACING.xs, children: /* @__PURE__ */ jsx17(Text17, { color: COLORS.text, bold: true, children: allItems.length > 0 ? `${cursor + 1}/${allItems.length}` : "0/0" }) })
2288
2485
  ] });
2289
2486
  }
2290
2487
 
2291
2488
  // src/views/search.tsx
2292
- import { useState as useState4, useCallback as useCallback2, useEffect as useEffect6, useRef as useRef2 } from "react";
2293
- import { Box as Box15, Text as Text17, useInput as useInput5 } from "ink";
2489
+ import { useState as useState4, useCallback as useCallback2, useEffect as useEffect7, useRef as useRef2 } from "react";
2490
+ import { Box as Box16, Text as Text18, useInput as useInput6 } from "ink";
2294
2491
  import { TextInput as TextInput2 } from "@inkjs/ui";
2295
- import { jsx as jsx17, jsxs as jsxs16 } from "react/jsx-runtime";
2492
+ import { jsx as jsx18, jsxs as jsxs17 } from "react/jsx-runtime";
2296
2493
  function SearchView() {
2297
2494
  const [query, setQuery] = useState4("");
2298
2495
  const [results, setResults] = useState4(null);
@@ -2306,7 +2503,7 @@ function SearchView() {
2306
2503
  const selectPackage = useNavigationStore((s) => s.selectPackage);
2307
2504
  const fetchInstalled = useBrewStore((s) => s.fetchInstalled);
2308
2505
  const hasRefreshed = useRef2(false);
2309
- useEffect6(() => {
2506
+ useEffect7(() => {
2310
2507
  if (results !== null) {
2311
2508
  openModal();
2312
2509
  return () => {
@@ -2334,7 +2531,7 @@ function SearchView() {
2334
2531
  setSearching(false);
2335
2532
  }
2336
2533
  }, []);
2337
- useEffect6(() => {
2534
+ useEffect7(() => {
2338
2535
  if (!stream.isRunning && !stream.error && stream.lines.length > 0 && !hasRefreshed.current) {
2339
2536
  hasRefreshed.current = true;
2340
2537
  void fetchInstalled();
@@ -2344,7 +2541,7 @@ function SearchView() {
2344
2541
  const visibleFormulae = results ? results.formulae.slice(0, MAX_VISIBLE) : [];
2345
2542
  const visibleCasks = results ? results.casks.slice(0, MAX_VISIBLE) : [];
2346
2543
  const allVisible = [...visibleFormulae, ...visibleCasks];
2347
- useInput5((input, key) => {
2544
+ useInput6((input, key) => {
2348
2545
  if (stream.isRunning) {
2349
2546
  if (key.escape) stream.cancel();
2350
2547
  return;
@@ -2379,8 +2576,8 @@ function SearchView() {
2379
2576
  }
2380
2577
  });
2381
2578
  if (stream.isRunning || stream.lines.length > 0) {
2382
- return /* @__PURE__ */ jsxs16(Box15, { flexDirection: "column", children: [
2383
- /* @__PURE__ */ jsx17(
2579
+ return /* @__PURE__ */ jsxs17(Box16, { flexDirection: "column", children: [
2580
+ /* @__PURE__ */ jsx18(
2384
2581
  ProgressLog,
2385
2582
  {
2386
2583
  lines: stream.lines,
@@ -2388,32 +2585,32 @@ function SearchView() {
2388
2585
  title: t("search_installing")
2389
2586
  }
2390
2587
  ),
2391
- stream.isRunning && /* @__PURE__ */ jsxs16(Text17, { color: COLORS.textSecondary, children: [
2588
+ stream.isRunning && /* @__PURE__ */ jsxs17(Text18, { color: COLORS.textSecondary, children: [
2392
2589
  "esc:",
2393
2590
  t("hint_cancel")
2394
2591
  ] }),
2395
- !stream.isRunning && /* @__PURE__ */ jsxs16(Box15, { flexDirection: "column", marginTop: SPACING.xs, children: [
2396
- /* @__PURE__ */ jsx17(
2592
+ !stream.isRunning && /* @__PURE__ */ jsxs17(Box16, { flexDirection: "column", marginTop: SPACING.xs, children: [
2593
+ /* @__PURE__ */ jsx18(
2397
2594
  ResultBanner,
2398
2595
  {
2399
2596
  status: stream.error ? "error" : "success",
2400
2597
  message: stream.error ? `\u2718 ${stream.error}` : `\u2714 ${t("search_installComplete")}`
2401
2598
  }
2402
2599
  ),
2403
- /* @__PURE__ */ jsxs16(Text17, { color: COLORS.textSecondary, children: [
2600
+ /* @__PURE__ */ jsxs17(Text18, { color: COLORS.textSecondary, children: [
2404
2601
  "esc:",
2405
2602
  t("hint_clear")
2406
2603
  ] })
2407
2604
  ] })
2408
2605
  ] });
2409
2606
  }
2410
- return /* @__PURE__ */ jsxs16(Box15, { flexDirection: "column", children: [
2411
- /* @__PURE__ */ jsxs16(Box15, { marginBottom: SPACING.xs, children: [
2412
- /* @__PURE__ */ jsxs16(Text17, { color: COLORS.gold, children: [
2607
+ return /* @__PURE__ */ jsxs17(Box16, { flexDirection: "column", children: [
2608
+ /* @__PURE__ */ jsxs17(Box16, { marginBottom: SPACING.xs, children: [
2609
+ /* @__PURE__ */ jsxs17(Text18, { color: COLORS.gold, children: [
2413
2610
  "\u{1F50D}",
2414
2611
  " "
2415
2612
  ] }),
2416
- !results ? /* @__PURE__ */ jsx17(
2613
+ !results ? /* @__PURE__ */ jsx18(
2417
2614
  TextInput2,
2418
2615
  {
2419
2616
  placeholder: t("search_placeholder"),
@@ -2421,17 +2618,17 @@ function SearchView() {
2421
2618
  onChange: setQuery,
2422
2619
  onSubmit: () => void doSearch(query)
2423
2620
  }
2424
- ) : /* @__PURE__ */ jsxs16(Text17, { children: [
2621
+ ) : /* @__PURE__ */ jsxs17(Text18, { children: [
2425
2622
  t("search_resultsFor"),
2426
2623
  ' "',
2427
- /* @__PURE__ */ jsx17(Text17, { bold: true, color: COLORS.text, children: query }),
2624
+ /* @__PURE__ */ jsx18(Text18, { bold: true, color: COLORS.text, children: query }),
2428
2625
  '" ',
2429
- /* @__PURE__ */ jsx17(Text17, { color: COLORS.textSecondary, children: t("search_escToClear") })
2626
+ /* @__PURE__ */ jsx18(Text18, { color: COLORS.textSecondary, children: t("search_escToClear") })
2430
2627
  ] })
2431
2628
  ] }),
2432
- searching && /* @__PURE__ */ jsx17(Loading, { message: t("loading_searching") }),
2433
- searchError && /* @__PURE__ */ jsx17(Box15, { marginBottom: SPACING.xs, children: /* @__PURE__ */ jsx17(Text17, { color: COLORS.error, children: searchError }) }),
2434
- confirmInstall && /* @__PURE__ */ jsx17(
2629
+ searching && /* @__PURE__ */ jsx18(Loading, { message: t("loading_searching") }),
2630
+ searchError && /* @__PURE__ */ jsx18(Box16, { marginBottom: SPACING.xs, children: /* @__PURE__ */ jsx18(Text18, { color: COLORS.error, children: searchError }) }),
2631
+ confirmInstall && /* @__PURE__ */ jsx18(
2435
2632
  ConfirmDialog,
2436
2633
  {
2437
2634
  message: t("search_confirmInstall", { name: confirmInstall }),
@@ -2444,59 +2641,59 @@ function SearchView() {
2444
2641
  onCancel: () => setConfirmInstall(null)
2445
2642
  }
2446
2643
  ),
2447
- results && !searching && !confirmInstall && /* @__PURE__ */ jsxs16(Box15, { flexDirection: "column", children: [
2448
- visibleFormulae.length > 0 && /* @__PURE__ */ jsxs16(Box15, { flexDirection: "column", marginBottom: SPACING.xs, children: [
2449
- /* @__PURE__ */ jsx17(Text17, { bold: true, color: COLORS.info, children: t("search_formulaeHeader", { count: results.formulae.length }) }),
2644
+ results && !searching && !confirmInstall && /* @__PURE__ */ jsxs17(Box16, { flexDirection: "column", children: [
2645
+ visibleFormulae.length > 0 && /* @__PURE__ */ jsxs17(Box16, { flexDirection: "column", marginBottom: SPACING.xs, children: [
2646
+ /* @__PURE__ */ jsx18(Text18, { bold: true, color: COLORS.info, children: t("search_formulaeHeader", { count: results.formulae.length }) }),
2450
2647
  visibleFormulae.map((name, i) => {
2451
2648
  const isCurrent = i === cursor;
2452
- return /* @__PURE__ */ jsx17(SelectableRow, { isCurrent, children: /* @__PURE__ */ jsx17(Text17, { bold: isCurrent, inverse: isCurrent, children: name }) }, name);
2649
+ return /* @__PURE__ */ jsx18(SelectableRow, { isCurrent, children: /* @__PURE__ */ jsx18(Text18, { bold: isCurrent, inverse: isCurrent, children: name }) }, name);
2453
2650
  }),
2454
- results.formulae.length > MAX_VISIBLE && /* @__PURE__ */ jsxs16(Text17, { color: COLORS.textSecondary, dimColor: true, children: [
2651
+ results.formulae.length > MAX_VISIBLE && /* @__PURE__ */ jsxs17(Text18, { color: COLORS.textSecondary, dimColor: true, children: [
2455
2652
  " ",
2456
2653
  t("scroll_moreBelow", { count: results.formulae.length - MAX_VISIBLE })
2457
2654
  ] })
2458
2655
  ] }),
2459
- visibleCasks.length > 0 && /* @__PURE__ */ jsxs16(Box15, { flexDirection: "column", children: [
2460
- /* @__PURE__ */ jsx17(Text17, { bold: true, color: COLORS.purple, children: t("search_casksHeader", { count: results.casks.length }) }),
2656
+ visibleCasks.length > 0 && /* @__PURE__ */ jsxs17(Box16, { flexDirection: "column", children: [
2657
+ /* @__PURE__ */ jsx18(Text18, { bold: true, color: COLORS.purple, children: t("search_casksHeader", { count: results.casks.length }) }),
2461
2658
  visibleCasks.map((name, i) => {
2462
2659
  const idx = visibleFormulae.length + i;
2463
2660
  const isCurrent = idx === cursor;
2464
- return /* @__PURE__ */ jsx17(SelectableRow, { isCurrent, children: /* @__PURE__ */ jsx17(Text17, { bold: isCurrent, inverse: isCurrent, children: name }) }, name);
2661
+ return /* @__PURE__ */ jsx18(SelectableRow, { isCurrent, children: /* @__PURE__ */ jsx18(Text18, { bold: isCurrent, inverse: isCurrent, children: name }) }, name);
2465
2662
  }),
2466
- results.casks.length > MAX_VISIBLE && /* @__PURE__ */ jsxs16(Text17, { color: COLORS.textSecondary, dimColor: true, children: [
2663
+ results.casks.length > MAX_VISIBLE && /* @__PURE__ */ jsxs17(Text18, { color: COLORS.textSecondary, dimColor: true, children: [
2467
2664
  " ",
2468
2665
  t("scroll_moreBelow", { count: results.casks.length - MAX_VISIBLE })
2469
2666
  ] })
2470
2667
  ] }),
2471
- allVisible.length === 0 && /* @__PURE__ */ jsx17(Box15, { borderStyle: "round", borderColor: COLORS.textSecondary, paddingX: SPACING.sm, children: /* @__PURE__ */ jsx17(Text17, { color: COLORS.textSecondary, italic: true, children: t("search_noResults") }) }),
2472
- /* @__PURE__ */ jsx17(Box15, { marginTop: SPACING.xs, children: /* @__PURE__ */ jsx17(Text17, { color: COLORS.text, bold: true, children: allVisible.length > 0 ? `${cursor + 1}/${allVisible.length}` : "" }) })
2668
+ allVisible.length === 0 && /* @__PURE__ */ jsx18(Box16, { borderStyle: "round", borderColor: COLORS.textSecondary, paddingX: SPACING.sm, children: /* @__PURE__ */ jsx18(Text18, { color: COLORS.textSecondary, italic: true, children: t("search_noResults") }) }),
2669
+ /* @__PURE__ */ jsx18(Box16, { marginTop: SPACING.xs, children: /* @__PURE__ */ jsx18(Text18, { color: COLORS.text, bold: true, children: allVisible.length > 0 ? `${cursor + 1}/${allVisible.length}` : "" }) })
2473
2670
  ] })
2474
2671
  ] });
2475
2672
  }
2476
2673
 
2477
2674
  // src/views/outdated.tsx
2478
- import { useEffect as useEffect7, useMemo as useMemo4, useRef as useRef3, useState as useState5 } from "react";
2479
- import { Box as Box16, Text as Text18, useInput as useInput6, useStdout as useStdout5 } from "ink";
2480
- import { jsx as jsx18, jsxs as jsxs17 } from "react/jsx-runtime";
2675
+ import { useEffect as useEffect8, useMemo as useMemo4, useRef as useRef3, useState as useState5 } from "react";
2676
+ import { Box as Box17, Text as Text19, useInput as useInput7, useStdout as useStdout5 } from "ink";
2677
+ import { jsx as jsx19, jsxs as jsxs18 } from "react/jsx-runtime";
2481
2678
  function ImpactPanel({ impact }) {
2482
2679
  const riskColor = impact.risk === "high" ? COLORS.error : impact.risk === "medium" ? COLORS.warning : COLORS.success;
2483
2680
  const riskLabel = impact.risk === "high" ? t("impact_high") : impact.risk === "medium" ? t("impact_medium") : t("impact_low");
2484
2681
  const riskIcon = impact.risk === "high" ? "\u26A0" : impact.risk === "medium" ? "~" : "\u2713";
2485
- return /* @__PURE__ */ jsxs17(Box16, { flexDirection: "column", marginTop: SPACING.xs, borderStyle: "round", borderColor: riskColor, paddingX: SPACING.sm, paddingY: SPACING.none, children: [
2486
- /* @__PURE__ */ jsxs17(Box16, { children: [
2487
- /* @__PURE__ */ jsxs17(Text18, { bold: true, color: riskColor, children: [
2682
+ return /* @__PURE__ */ jsxs18(Box17, { flexDirection: "column", marginTop: SPACING.xs, borderStyle: "round", borderColor: riskColor, paddingX: SPACING.sm, paddingY: SPACING.none, children: [
2683
+ /* @__PURE__ */ jsxs18(Box17, { children: [
2684
+ /* @__PURE__ */ jsxs18(Text19, { bold: true, color: riskColor, children: [
2488
2685
  riskIcon,
2489
2686
  " ",
2490
2687
  riskLabel
2491
2688
  ] }),
2492
- impact.reverseDeps.length > 0 && /* @__PURE__ */ jsxs17(Text18, { color: COLORS.textSecondary, children: [
2689
+ impact.reverseDeps.length > 0 && /* @__PURE__ */ jsxs18(Text19, { color: COLORS.textSecondary, children: [
2493
2690
  " \\u2014 ",
2494
2691
  t("impact_affects", { count: impact.reverseDeps.length })
2495
2692
  ] })
2496
2693
  ] }),
2497
- impact.riskReasons.length > 0 && /* @__PURE__ */ jsx18(Text18, { color: COLORS.textSecondary, children: impact.riskReasons.join(" \xB7 ") }),
2498
- impact.reverseDeps.length > 0 && impact.reverseDeps.length <= 5 && /* @__PURE__ */ jsx18(Text18, { color: COLORS.muted, dimColor: true, children: t("impact_usedBy", { packages: impact.reverseDeps.join(", ") }) }),
2499
- impact.risk === "high" && /* @__PURE__ */ jsx18(Text18, { color: COLORS.info, children: t("impact_brewfile_hint") })
2694
+ impact.riskReasons.length > 0 && /* @__PURE__ */ jsx19(Text19, { color: COLORS.textSecondary, children: impact.riskReasons.join(" \xB7 ") }),
2695
+ impact.reverseDeps.length > 0 && impact.reverseDeps.length <= 5 && /* @__PURE__ */ jsx19(Text19, { color: COLORS.muted, dimColor: true, children: t("impact_usedBy", { packages: impact.reverseDeps.join(", ") }) }),
2696
+ impact.risk === "high" && /* @__PURE__ */ jsx19(Text19, { color: COLORS.info, children: t("impact_brewfile_hint") })
2500
2697
  ] });
2501
2698
  }
2502
2699
  function OutdatedView() {
@@ -2507,10 +2704,10 @@ function OutdatedView() {
2507
2704
  const hasRefreshed = useRef3(false);
2508
2705
  const [impact, setImpact] = useState5(null);
2509
2706
  const [impactLoading, setImpactLoading] = useState5(false);
2510
- useEffect7(() => {
2707
+ useEffect8(() => {
2511
2708
  fetchOutdated();
2512
2709
  }, []);
2513
- useEffect7(() => {
2710
+ useEffect8(() => {
2514
2711
  if (!stream.isRunning && !stream.error && stream.lines.length > 0 && !hasRefreshed.current) {
2515
2712
  hasRefreshed.current = true;
2516
2713
  void fetchOutdated();
@@ -2524,21 +2721,31 @@ function OutdatedView() {
2524
2721
  [outdated.formulae, outdated.casks]
2525
2722
  );
2526
2723
  const debouncedCursor = useDebounce(cursor, 150);
2527
- useEffect7(() => {
2724
+ useEffect8(() => {
2528
2725
  const pkg = allOutdated[debouncedCursor];
2529
2726
  if (!pkg || stream.isRunning) {
2530
2727
  setImpact(null);
2531
2728
  return;
2532
2729
  }
2730
+ let cancelled = false;
2533
2731
  setImpactLoading(true);
2534
2732
  void getUpgradeImpact(
2535
2733
  pkg.name,
2536
2734
  pkg.installed_versions[0] ?? "",
2537
2735
  pkg.current_version,
2538
2736
  pkg.type
2539
- ).then(setImpact).catch(() => setImpact(null)).finally(() => setImpactLoading(false));
2737
+ ).then((result) => {
2738
+ if (!cancelled) setImpact(result);
2739
+ }).catch(() => {
2740
+ if (!cancelled) setImpact(null);
2741
+ }).finally(() => {
2742
+ if (!cancelled) setImpactLoading(false);
2743
+ });
2744
+ return () => {
2745
+ cancelled = true;
2746
+ };
2540
2747
  }, [debouncedCursor, stream.isRunning]);
2541
- useInput6((input, key) => {
2748
+ useInput7((input, key) => {
2542
2749
  if (stream.isRunning) {
2543
2750
  if (key.escape) stream.cancel();
2544
2751
  return;
@@ -2575,11 +2782,11 @@ function OutdatedView() {
2575
2782
  const MAX_VISIBLE_ROWS = Math.max(5, (stdout?.rows ?? 24) - 8);
2576
2783
  const start = Math.max(0, cursor - Math.floor(MAX_VISIBLE_ROWS / 2));
2577
2784
  const visible = allOutdated.slice(start, start + MAX_VISIBLE_ROWS);
2578
- if (loading.outdated) return /* @__PURE__ */ jsx18(Loading, { message: t("loading_outdated") });
2579
- if (errors.outdated) return /* @__PURE__ */ jsx18(ErrorMessage, { message: errors.outdated });
2785
+ if (loading.outdated) return /* @__PURE__ */ jsx19(Loading, { message: t("loading_outdated") });
2786
+ if (errors.outdated) return /* @__PURE__ */ jsx19(ErrorMessage, { message: errors.outdated });
2580
2787
  if (stream.isRunning || stream.lines.length > 0) {
2581
- return /* @__PURE__ */ jsxs17(Box16, { flexDirection: "column", children: [
2582
- /* @__PURE__ */ jsx18(
2788
+ return /* @__PURE__ */ jsxs18(Box17, { flexDirection: "column", children: [
2789
+ /* @__PURE__ */ jsx19(
2583
2790
  ProgressLog,
2584
2791
  {
2585
2792
  lines: stream.lines,
@@ -2587,19 +2794,19 @@ function OutdatedView() {
2587
2794
  title: t("outdated_upgrading")
2588
2795
  }
2589
2796
  ),
2590
- stream.isRunning && /* @__PURE__ */ jsxs17(Text18, { color: COLORS.textSecondary, children: [
2797
+ stream.isRunning && /* @__PURE__ */ jsxs18(Text19, { color: COLORS.textSecondary, children: [
2591
2798
  "esc:",
2592
2799
  t("hint_cancel")
2593
2800
  ] }),
2594
- !stream.isRunning && /* @__PURE__ */ jsxs17(Box16, { flexDirection: "column", marginTop: SPACING.xs, children: [
2595
- /* @__PURE__ */ jsxs17(Box16, { borderStyle: "round", borderColor: stream.error ? COLORS.error : COLORS.success, paddingX: SPACING.sm, paddingY: SPACING.none, children: [
2596
- /* @__PURE__ */ jsx18(Text18, { color: stream.error ? COLORS.error : COLORS.success, bold: true, children: stream.error ? `\u2718 ${stream.error}` : `\u2714 ${t("outdated_upgradeComplete")}` }),
2597
- /* @__PURE__ */ jsxs17(Text18, { color: COLORS.muted, children: [
2801
+ !stream.isRunning && /* @__PURE__ */ jsxs18(Box17, { flexDirection: "column", marginTop: SPACING.xs, children: [
2802
+ /* @__PURE__ */ jsxs18(Box17, { borderStyle: "round", borderColor: stream.error ? COLORS.error : COLORS.success, paddingX: SPACING.sm, paddingY: SPACING.none, children: [
2803
+ /* @__PURE__ */ jsx19(Text19, { color: stream.error ? COLORS.error : COLORS.success, bold: true, children: stream.error ? `\u2718 ${stream.error}` : `\u2714 ${t("outdated_upgradeComplete")}` }),
2804
+ /* @__PURE__ */ jsxs18(Text19, { color: COLORS.muted, children: [
2598
2805
  " ",
2599
2806
  t("outdated_pressRefresh")
2600
2807
  ] })
2601
2808
  ] }),
2602
- /* @__PURE__ */ jsxs17(Text18, { color: COLORS.textSecondary, children: [
2809
+ /* @__PURE__ */ jsxs18(Text19, { color: COLORS.textSecondary, children: [
2603
2810
  "r:",
2604
2811
  t("hint_refresh"),
2605
2812
  " esc:",
@@ -2610,9 +2817,9 @@ function OutdatedView() {
2610
2817
  }
2611
2818
  const upgradeAllMessage = confirmAction?.type === "all" ? `${t("outdated_confirmAll", { count: allOutdated.length })}
2612
2819
  ${t("outdated_upgradeAllList", { list: allOutdated.map((p) => p.name).join(", ") })}` : "";
2613
- return /* @__PURE__ */ jsxs17(Box16, { flexDirection: "column", children: [
2614
- /* @__PURE__ */ jsx18(SectionHeader, { emoji: "\u{1F4E6}", title: t("outdated_title", { count: allOutdated.length }), gradient: GRADIENTS.fire }),
2615
- confirmAction && /* @__PURE__ */ jsx18(Box16, { marginY: SPACING.xs, children: /* @__PURE__ */ jsx18(
2820
+ return /* @__PURE__ */ jsxs18(Box17, { flexDirection: "column", children: [
2821
+ /* @__PURE__ */ jsx19(SectionHeader, { emoji: "\u{1F4E6}", title: t("outdated_title", { count: allOutdated.length }), gradient: GRADIENTS.fire }),
2822
+ confirmAction && /* @__PURE__ */ jsx19(Box17, { marginY: SPACING.xs, children: /* @__PURE__ */ jsx19(
2616
2823
  ConfirmDialog,
2617
2824
  {
2618
2825
  message: confirmAction.type === "all" ? upgradeAllMessage : t("outdated_confirmSingle", { name: confirmAction.type === "single" ? confirmAction.name : "" }),
@@ -2628,41 +2835,41 @@ ${t("outdated_upgradeAllList", { list: allOutdated.map((p) => p.name).join(", ")
2628
2835
  onCancel: () => setConfirmAction(null)
2629
2836
  }
2630
2837
  ) }),
2631
- allOutdated.length === 0 && !confirmAction && /* @__PURE__ */ jsx18(Box16, { marginTop: SPACING.xs, children: /* @__PURE__ */ jsx18(ResultBanner, { status: "success", message: `\u2714 ${t("outdated_upToDate")}` }) }),
2632
- allOutdated.length > 0 && !confirmAction && /* @__PURE__ */ jsxs17(Box16, { flexDirection: "column", marginTop: SPACING.xs, children: [
2633
- start > 0 && /* @__PURE__ */ jsxs17(Text18, { color: COLORS.textSecondary, dimColor: true, children: [
2838
+ allOutdated.length === 0 && !confirmAction && /* @__PURE__ */ jsx19(Box17, { marginTop: SPACING.xs, children: /* @__PURE__ */ jsx19(ResultBanner, { status: "success", message: `\u2714 ${t("outdated_upToDate")}` }) }),
2839
+ allOutdated.length > 0 && !confirmAction && /* @__PURE__ */ jsxs18(Box17, { flexDirection: "column", marginTop: SPACING.xs, children: [
2840
+ start > 0 && /* @__PURE__ */ jsxs18(Text19, { color: COLORS.textSecondary, dimColor: true, children: [
2634
2841
  " ",
2635
2842
  t("scroll_moreAbove", { count: start })
2636
2843
  ] }),
2637
2844
  visible.map((pkg, i) => {
2638
2845
  const idx = start + i;
2639
2846
  const isCurrent = idx === cursor;
2640
- return /* @__PURE__ */ jsxs17(SelectableRow, { isCurrent, children: [
2641
- /* @__PURE__ */ jsx18(Text18, { bold: isCurrent, inverse: isCurrent, color: isCurrent ? COLORS.text : COLORS.muted, children: pkg.name }),
2642
- /* @__PURE__ */ jsx18(VersionArrow, { current: pkg.installed_versions[0] ?? "", latest: pkg.current_version }),
2643
- pkg.pinned && /* @__PURE__ */ jsx18(StatusBadge, { label: t("outdated_pinned"), variant: "info" })
2847
+ return /* @__PURE__ */ jsxs18(SelectableRow, { isCurrent, children: [
2848
+ /* @__PURE__ */ jsx19(Text19, { bold: isCurrent, inverse: isCurrent, color: isCurrent ? COLORS.text : COLORS.muted, children: pkg.name }),
2849
+ /* @__PURE__ */ jsx19(VersionArrow, { current: pkg.installed_versions[0] ?? "", latest: pkg.current_version }),
2850
+ pkg.pinned && /* @__PURE__ */ jsx19(StatusBadge, { label: t("outdated_pinned"), variant: "info" })
2644
2851
  ] }, pkg.name);
2645
2852
  }),
2646
- start + MAX_VISIBLE_ROWS < allOutdated.length && /* @__PURE__ */ jsxs17(Text18, { color: COLORS.textSecondary, dimColor: true, children: [
2853
+ start + MAX_VISIBLE_ROWS < allOutdated.length && /* @__PURE__ */ jsxs18(Text19, { color: COLORS.textSecondary, dimColor: true, children: [
2647
2854
  " ",
2648
2855
  t("scroll_moreBelow", { count: allOutdated.length - start - MAX_VISIBLE_ROWS })
2649
2856
  ] }),
2650
- /* @__PURE__ */ jsx18(Box16, { marginTop: SPACING.xs, children: /* @__PURE__ */ jsxs17(Text18, { color: COLORS.text, bold: true, children: [
2857
+ /* @__PURE__ */ jsx19(Box17, { marginTop: SPACING.xs, children: /* @__PURE__ */ jsxs18(Text19, { color: COLORS.text, bold: true, children: [
2651
2858
  cursor + 1,
2652
2859
  "/",
2653
2860
  allOutdated.length
2654
2861
  ] }) }),
2655
- impact && !stream.isRunning && !confirmAction && /* @__PURE__ */ jsx18(ImpactPanel, { impact }),
2656
- impactLoading && !stream.isRunning && !confirmAction && /* @__PURE__ */ jsx18(Box16, { marginTop: SPACING.xs, children: /* @__PURE__ */ jsx18(Text18, { color: COLORS.textSecondary, children: t("impact_analyzing") }) }),
2657
- /* @__PURE__ */ jsx18(Box16, { marginTop: SPACING.xs, children: /* @__PURE__ */ jsx18(Text18, { color: COLORS.textSecondary, children: t("impact_hint") }) })
2862
+ impact && !stream.isRunning && !confirmAction && /* @__PURE__ */ jsx19(ImpactPanel, { impact }),
2863
+ impactLoading && !stream.isRunning && !confirmAction && /* @__PURE__ */ jsx19(Box17, { marginTop: SPACING.xs, children: /* @__PURE__ */ jsx19(Text19, { color: COLORS.textSecondary, children: t("impact_analyzing") }) }),
2864
+ /* @__PURE__ */ jsx19(Box17, { marginTop: SPACING.xs, children: /* @__PURE__ */ jsx19(Text19, { color: COLORS.textSecondary, children: t("impact_hint") }) })
2658
2865
  ] })
2659
2866
  ] });
2660
2867
  }
2661
2868
 
2662
2869
  // src/views/package-info.tsx
2663
- import { useEffect as useEffect8, useRef as useRef4, useState as useState6 } from "react";
2664
- import { Box as Box17, Text as Text19, useInput as useInput7 } from "ink";
2665
- import { Fragment as Fragment4, jsx as jsx19, jsxs as jsxs18 } from "react/jsx-runtime";
2870
+ import { useEffect as useEffect9, useRef as useRef4, useState as useState6 } from "react";
2871
+ import { Box as Box18, Text as Text20, useInput as useInput8 } from "ink";
2872
+ import { Fragment as Fragment4, jsx as jsx20, jsxs as jsxs19 } from "react/jsx-runtime";
2666
2873
  var ACTION_PROGRESS_KEYS = {
2667
2874
  install: "pkgInfo_installing",
2668
2875
  uninstall: "pkgInfo_uninstalling",
@@ -2684,47 +2891,20 @@ function PackageInfoView() {
2684
2891
  const mountedRef = useRef4(true);
2685
2892
  const hasRefreshed = useRef4(false);
2686
2893
  const stream = useBrewStream();
2687
- useEffect8(() => {
2894
+ useEffect9(() => {
2688
2895
  mountedRef.current = true;
2689
2896
  return () => {
2690
2897
  mountedRef.current = false;
2691
2898
  };
2692
2899
  }, []);
2693
- useEffect8(() => {
2900
+ useEffect9(() => {
2694
2901
  if (!packageName) return;
2695
2902
  setLoading2(true);
2696
2903
  const fetchInfo = async () => {
2697
2904
  if (packageType === "cask") {
2698
2905
  const caskInfo = await getCaskInfo(packageName);
2699
2906
  if (caskInfo && mountedRef.current) {
2700
- const formulaLike = {
2701
- name: caskInfo.token,
2702
- full_name: caskInfo.full_token,
2703
- tap: "",
2704
- desc: caskInfo.desc,
2705
- license: "",
2706
- homepage: caskInfo.homepage,
2707
- versions: { stable: caskInfo.version, head: null, bottle: false },
2708
- dependencies: [],
2709
- build_dependencies: [],
2710
- installed: caskInfo.installed ? [{
2711
- version: caskInfo.installed,
2712
- used_options: [],
2713
- built_as_bottle: false,
2714
- poured_from_bottle: false,
2715
- time: caskInfo.installed_time ?? 0,
2716
- runtime_dependencies: [],
2717
- installed_as_dependency: false,
2718
- installed_on_request: true
2719
- }] : [],
2720
- linked_keg: null,
2721
- pinned: false,
2722
- outdated: caskInfo.outdated,
2723
- deprecated: false,
2724
- keg_only: false,
2725
- caveats: null
2726
- };
2727
- setFormula(formulaLike);
2907
+ setFormula(formulaeFromCask(caskInfo));
2728
2908
  setLoading2(false);
2729
2909
  return;
2730
2910
  }
@@ -2742,7 +2922,7 @@ function PackageInfoView() {
2742
2922
  }
2743
2923
  });
2744
2924
  }, [packageName, packageType]);
2745
- useEffect8(() => {
2925
+ useEffect9(() => {
2746
2926
  if (!stream.isRunning && !stream.error && stream.lines.length > 0 && !hasRefreshed.current && packageName) {
2747
2927
  hasRefreshed.current = true;
2748
2928
  const refreshFn = packageType === "cask" ? getCaskInfo(packageName).then((c) => c ? { ...c, installed: c.installed ? [{ version: c.installed }] : [] } : null) : getFormulaInfo(packageName);
@@ -2754,7 +2934,7 @@ function PackageInfoView() {
2754
2934
  });
2755
2935
  }
2756
2936
  }, [stream.isRunning, stream.error]);
2757
- useInput7((input, key) => {
2937
+ useInput8((input, key) => {
2758
2938
  if (stream.isRunning) {
2759
2939
  if (key.escape) stream.cancel();
2760
2940
  return;
@@ -2771,21 +2951,21 @@ function PackageInfoView() {
2771
2951
  }
2772
2952
  });
2773
2953
  if (!packageName) {
2774
- return /* @__PURE__ */ jsx19(Text19, { color: COLORS.textSecondary, italic: true, children: t("pkgInfo_noPackage") });
2954
+ return /* @__PURE__ */ jsx20(Text20, { color: COLORS.textSecondary, italic: true, children: t("pkgInfo_noPackage") });
2775
2955
  }
2776
- if (loading) return /* @__PURE__ */ jsx19(Loading, { message: t("loading_package", { name: packageName }) });
2777
- if (error) return /* @__PURE__ */ jsx19(ErrorMessage, { message: error });
2778
- if (!formula) return /* @__PURE__ */ jsx19(ErrorMessage, { message: t("pkgInfo_notFound") });
2956
+ if (loading) return /* @__PURE__ */ jsx20(Loading, { message: t("loading_package", { name: packageName }) });
2957
+ if (error) return /* @__PURE__ */ jsx20(ErrorMessage, { message: error });
2958
+ if (!formula) return /* @__PURE__ */ jsx20(ErrorMessage, { message: t("pkgInfo_notFound") });
2779
2959
  if (stream.isRunning || stream.lines.length > 0) {
2780
- return /* @__PURE__ */ jsxs18(Box17, { flexDirection: "column", children: [
2781
- /* @__PURE__ */ jsx19(ProgressLog, { lines: stream.lines, isRunning: stream.isRunning, title: t(ACTION_PROGRESS_KEYS[activeActionRef.current] ?? ACTION_PROGRESS_KEYS["install"], { name: formula.name }) }),
2782
- stream.isRunning && /* @__PURE__ */ jsxs18(Text19, { color: COLORS.textSecondary, children: [
2960
+ return /* @__PURE__ */ jsxs19(Box18, { flexDirection: "column", children: [
2961
+ /* @__PURE__ */ jsx20(ProgressLog, { lines: stream.lines, isRunning: stream.isRunning, title: t(ACTION_PROGRESS_KEYS[activeActionRef.current] ?? ACTION_PROGRESS_KEYS["install"], { name: formula.name }) }),
2962
+ stream.isRunning && /* @__PURE__ */ jsxs19(Text20, { color: COLORS.textSecondary, children: [
2783
2963
  "esc:",
2784
2964
  t("hint_cancel")
2785
2965
  ] }),
2786
- !stream.isRunning && /* @__PURE__ */ jsxs18(Fragment4, { children: [
2787
- /* @__PURE__ */ jsx19(Text19, { color: stream.error ? COLORS.error : COLORS.success, bold: true, children: stream.error ? `\u2718 ${stream.error}` : `\u2714 ${t("pkgInfo_done")}` }),
2788
- /* @__PURE__ */ jsxs18(Text19, { color: COLORS.textSecondary, children: [
2966
+ !stream.isRunning && /* @__PURE__ */ jsxs19(Fragment4, { children: [
2967
+ /* @__PURE__ */ jsx20(Text20, { color: stream.error ? COLORS.error : COLORS.success, bold: true, children: stream.error ? `\u2718 ${stream.error}` : `\u2714 ${t("pkgInfo_done")}` }),
2968
+ /* @__PURE__ */ jsxs19(Text20, { color: COLORS.textSecondary, children: [
2789
2969
  "esc:",
2790
2970
  t("hint_back")
2791
2971
  ] })
@@ -2794,8 +2974,8 @@ function PackageInfoView() {
2794
2974
  }
2795
2975
  const installed = formula.installed[0];
2796
2976
  const isInstalled = formula.installed.length > 0;
2797
- return /* @__PURE__ */ jsxs18(Box17, { flexDirection: "column", children: [
2798
- confirmAction && /* @__PURE__ */ jsx19(
2977
+ return /* @__PURE__ */ jsxs19(Box18, { flexDirection: "column", children: [
2978
+ confirmAction && /* @__PURE__ */ jsx20(
2799
2979
  ConfirmDialog,
2800
2980
  {
2801
2981
  message: t(ACTION_CONFIRM_KEYS[confirmAction], { name: formula.name }),
@@ -2811,72 +2991,72 @@ function PackageInfoView() {
2811
2991
  onCancel: () => setConfirmAction(null)
2812
2992
  }
2813
2993
  ),
2814
- /* @__PURE__ */ jsxs18(Box17, { gap: SPACING.sm, marginBottom: SPACING.xs, children: [
2815
- /* @__PURE__ */ jsx19(GradientText, { colors: GRADIENTS.gold, bold: true, children: formula.name }),
2816
- /* @__PURE__ */ jsx19(Text19, { color: COLORS.teal, children: installed?.version ?? formula.versions.stable }),
2817
- isInstalled && /* @__PURE__ */ jsx19(StatusBadge, { label: t("badge_installed"), variant: "success" }),
2818
- formula.outdated && /* @__PURE__ */ jsx19(StatusBadge, { label: t("badge_outdated"), variant: "warning" }),
2819
- formula.pinned && /* @__PURE__ */ jsx19(StatusBadge, { label: t("badge_pinned"), variant: "info" }),
2820
- formula.keg_only && /* @__PURE__ */ jsx19(StatusBadge, { label: t("badge_kegOnly"), variant: "muted" }),
2821
- formula.deprecated && /* @__PURE__ */ jsx19(StatusBadge, { label: t("badge_deprecated"), variant: "error" })
2994
+ /* @__PURE__ */ jsxs19(Box18, { gap: SPACING.sm, marginBottom: SPACING.xs, children: [
2995
+ /* @__PURE__ */ jsx20(GradientText, { colors: GRADIENTS.gold, bold: true, children: formula.name }),
2996
+ /* @__PURE__ */ jsx20(Text20, { color: COLORS.teal, children: installed?.version ?? formula.versions.stable }),
2997
+ isInstalled && /* @__PURE__ */ jsx20(StatusBadge, { label: t("badge_installed"), variant: "success" }),
2998
+ formula.outdated && /* @__PURE__ */ jsx20(StatusBadge, { label: t("badge_outdated"), variant: "warning" }),
2999
+ formula.pinned && /* @__PURE__ */ jsx20(StatusBadge, { label: t("badge_pinned"), variant: "info" }),
3000
+ formula.keg_only && /* @__PURE__ */ jsx20(StatusBadge, { label: t("badge_kegOnly"), variant: "muted" }),
3001
+ formula.deprecated && /* @__PURE__ */ jsx20(StatusBadge, { label: t("badge_deprecated"), variant: "error" })
2822
3002
  ] }),
2823
- /* @__PURE__ */ jsxs18(Box17, { flexDirection: "column", gap: SPACING.xs, children: [
2824
- /* @__PURE__ */ jsx19(Text19, { children: formula.desc }),
2825
- /* @__PURE__ */ jsxs18(Box17, { flexDirection: "column", children: [
2826
- /* @__PURE__ */ jsx19(SectionHeader, { emoji: "\u{1F4CB}", title: t("pkgInfo_details"), gradient: [COLORS.text, COLORS.muted] }),
2827
- /* @__PURE__ */ jsxs18(Box17, { borderStyle: "round", borderColor: COLORS.border, paddingX: SPACING.sm, flexDirection: "column", children: [
2828
- /* @__PURE__ */ jsxs18(Text19, { children: [
2829
- /* @__PURE__ */ jsx19(Text19, { color: COLORS.muted, children: t("pkgInfo_homepage") }),
3003
+ /* @__PURE__ */ jsxs19(Box18, { flexDirection: "column", gap: SPACING.xs, children: [
3004
+ /* @__PURE__ */ jsx20(Text20, { children: formula.desc }),
3005
+ /* @__PURE__ */ jsxs19(Box18, { flexDirection: "column", children: [
3006
+ /* @__PURE__ */ jsx20(SectionHeader, { emoji: "\u{1F4CB}", title: t("pkgInfo_details"), gradient: [COLORS.text, COLORS.muted] }),
3007
+ /* @__PURE__ */ jsxs19(Box18, { borderStyle: "round", borderColor: COLORS.border, paddingX: SPACING.sm, flexDirection: "column", children: [
3008
+ /* @__PURE__ */ jsxs19(Text20, { children: [
3009
+ /* @__PURE__ */ jsx20(Text20, { color: COLORS.muted, children: t("pkgInfo_homepage") }),
2830
3010
  " ",
2831
3011
  formula.homepage
2832
3012
  ] }),
2833
- /* @__PURE__ */ jsxs18(Text19, { children: [
2834
- /* @__PURE__ */ jsx19(Text19, { color: COLORS.muted, children: t("pkgInfo_license") }),
3013
+ /* @__PURE__ */ jsxs19(Text20, { children: [
3014
+ /* @__PURE__ */ jsx20(Text20, { color: COLORS.muted, children: t("pkgInfo_license") }),
2835
3015
  " ",
2836
3016
  formula.license
2837
3017
  ] }),
2838
- /* @__PURE__ */ jsxs18(Text19, { children: [
2839
- /* @__PURE__ */ jsx19(Text19, { color: COLORS.muted, children: t("pkgInfo_tap") }),
3018
+ /* @__PURE__ */ jsxs19(Text20, { children: [
3019
+ /* @__PURE__ */ jsx20(Text20, { color: COLORS.muted, children: t("pkgInfo_tap") }),
2840
3020
  " ",
2841
3021
  formula.tap
2842
3022
  ] }),
2843
- /* @__PURE__ */ jsxs18(Text19, { children: [
2844
- /* @__PURE__ */ jsx19(Text19, { color: COLORS.muted, children: t("pkgInfo_stable") }),
3023
+ /* @__PURE__ */ jsxs19(Text20, { children: [
3024
+ /* @__PURE__ */ jsx20(Text20, { color: COLORS.muted, children: t("pkgInfo_stable") }),
2845
3025
  " ",
2846
3026
  formula.versions.stable
2847
3027
  ] }),
2848
- installed && /* @__PURE__ */ jsxs18(Fragment4, { children: [
2849
- /* @__PURE__ */ jsxs18(Text19, { children: [
2850
- /* @__PURE__ */ jsx19(Text19, { color: COLORS.muted, children: t("pkgInfo_installed") }),
3028
+ installed && /* @__PURE__ */ jsxs19(Fragment4, { children: [
3029
+ /* @__PURE__ */ jsxs19(Text20, { children: [
3030
+ /* @__PURE__ */ jsx20(Text20, { color: COLORS.muted, children: t("pkgInfo_installed") }),
2851
3031
  " ",
2852
3032
  installed.version,
2853
3033
  " (",
2854
3034
  formatRelativeTime(installed.time),
2855
3035
  ")"
2856
3036
  ] }),
2857
- /* @__PURE__ */ jsxs18(Text19, { children: [
2858
- /* @__PURE__ */ jsx19(Text19, { color: COLORS.muted, children: t("pkgInfo_bottle") }),
3037
+ /* @__PURE__ */ jsxs19(Text20, { children: [
3038
+ /* @__PURE__ */ jsx20(Text20, { color: COLORS.muted, children: t("pkgInfo_bottle") }),
2859
3039
  " ",
2860
3040
  installed.poured_from_bottle ? t("common_yes") : t("common_no")
2861
3041
  ] }),
2862
- /* @__PURE__ */ jsxs18(Text19, { children: [
2863
- /* @__PURE__ */ jsx19(Text19, { color: COLORS.muted, children: t("pkgInfo_onRequest") }),
3042
+ /* @__PURE__ */ jsxs19(Text20, { children: [
3043
+ /* @__PURE__ */ jsx20(Text20, { color: COLORS.muted, children: t("pkgInfo_onRequest") }),
2864
3044
  " ",
2865
3045
  installed.installed_on_request ? t("common_yes") : t("pkgInfo_noDependency")
2866
3046
  ] })
2867
3047
  ] })
2868
3048
  ] })
2869
3049
  ] }),
2870
- formula.dependencies.length > 0 && /* @__PURE__ */ jsxs18(Box17, { flexDirection: "column", children: [
2871
- /* @__PURE__ */ jsx19(SectionHeader, { emoji: "\u{1F517}", title: t("pkgInfo_dependencies", { count: formula.dependencies.length }), gradient: GRADIENTS.ocean }),
2872
- /* @__PURE__ */ jsx19(Box17, { paddingLeft: SPACING.sm, flexWrap: "wrap", columnGap: 2, children: formula.dependencies.map((dep) => /* @__PURE__ */ jsx19(Text19, { color: COLORS.muted, children: dep }, dep)) })
3050
+ formula.dependencies.length > 0 && /* @__PURE__ */ jsxs19(Box18, { flexDirection: "column", children: [
3051
+ /* @__PURE__ */ jsx20(SectionHeader, { emoji: "\u{1F517}", title: t("pkgInfo_dependencies", { count: formula.dependencies.length }), gradient: GRADIENTS.ocean }),
3052
+ /* @__PURE__ */ jsx20(Box18, { paddingLeft: SPACING.sm, flexWrap: "wrap", columnGap: 2, children: formula.dependencies.map((dep) => /* @__PURE__ */ jsx20(Text20, { color: COLORS.muted, children: dep }, dep)) })
2873
3053
  ] }),
2874
- formula.caveats && /* @__PURE__ */ jsxs18(Box17, { flexDirection: "column", children: [
2875
- /* @__PURE__ */ jsx19(SectionHeader, { emoji: "\u26A0\uFE0F", title: t("pkgInfo_caveats"), color: COLORS.warning }),
2876
- /* @__PURE__ */ jsx19(Box17, { borderStyle: "round", borderColor: COLORS.warning, paddingX: SPACING.sm, children: /* @__PURE__ */ jsx19(Text19, { color: COLORS.warning, children: formula.caveats }) })
3054
+ formula.caveats && /* @__PURE__ */ jsxs19(Box18, { flexDirection: "column", children: [
3055
+ /* @__PURE__ */ jsx20(SectionHeader, { emoji: "\u26A0\uFE0F", title: t("pkgInfo_caveats"), color: COLORS.warning }),
3056
+ /* @__PURE__ */ jsx20(Box18, { borderStyle: "round", borderColor: COLORS.warning, paddingX: SPACING.sm, children: /* @__PURE__ */ jsx20(Text20, { color: COLORS.warning, children: formula.caveats }) })
2877
3057
  ] })
2878
3058
  ] }),
2879
- /* @__PURE__ */ jsx19(Box17, { marginTop: SPACING.xs, children: /* @__PURE__ */ jsxs18(Text19, { color: COLORS.textSecondary, children: [
3059
+ /* @__PURE__ */ jsx20(Box18, { marginTop: SPACING.xs, children: /* @__PURE__ */ jsxs19(Text20, { color: COLORS.textSecondary, children: [
2880
3060
  isInstalled ? `u:${t("hint_uninstall")}` : `i:${t("hint_install")}`,
2881
3061
  isInstalled && formula.outdated ? ` U:${t("hint_upgrade")}` : "",
2882
3062
  ` esc:${t("hint_back")}`
@@ -2885,15 +3065,21 @@ function PackageInfoView() {
2885
3065
  }
2886
3066
 
2887
3067
  // src/views/services.tsx
2888
- import { useEffect as useEffect9, useState as useState7 } from "react";
2889
- import { Box as Box18, Text as Text20, useInput as useInput8, useStdout as useStdout6 } from "ink";
2890
- import { jsx as jsx20, jsxs as jsxs19 } from "react/jsx-runtime";
3068
+ import { useEffect as useEffect10, useState as useState7 } from "react";
3069
+ import { Box as Box19, Text as Text21, useInput as useInput9, useStdout as useStdout6 } from "ink";
3070
+ import { jsx as jsx21, jsxs as jsxs20 } from "react/jsx-runtime";
2891
3071
  var STATUS_VARIANTS = {
2892
3072
  started: "success",
2893
3073
  stopped: "muted",
2894
3074
  error: "error",
2895
3075
  none: "muted"
2896
3076
  };
3077
+ function humaniseServiceError(message) {
3078
+ if (/EACCES|operation not permitted|permission denied|sudo/i.test(message)) {
3079
+ return t("services_errorPermission");
3080
+ }
3081
+ return message;
3082
+ }
2897
3083
  function ServicesView() {
2898
3084
  const { services, loading, errors, fetchServices, serviceAction: serviceAction2 } = useBrewStore();
2899
3085
  const [cursor, setCursor] = useState7(0);
@@ -2905,10 +3091,10 @@ function ServicesView() {
2905
3091
  const svcNameWidth = Math.floor(cols * 0.35);
2906
3092
  const svcStatusWidth = Math.floor(cols * 0.15);
2907
3093
  const MAX_VISIBLE_ROWS = Math.max(5, (stdout?.rows ?? 24) - 10);
2908
- useEffect9(() => {
3094
+ useEffect10(() => {
2909
3095
  fetchServices();
2910
3096
  }, []);
2911
- useInput8((input, key) => {
3097
+ useInput9((input, key) => {
2912
3098
  if (actionInProgress) return;
2913
3099
  if (confirmAction) return;
2914
3100
  if (lastError) {
@@ -2926,30 +3112,30 @@ function ServicesView() {
2926
3112
  const doAction = (action) => {
2927
3113
  setActionInProgress(true);
2928
3114
  void serviceAction2(svc.name, action).catch((err) => {
2929
- setLastError(err instanceof Error ? err.message : String(err));
3115
+ setLastError(humaniseServiceError(err instanceof Error ? err.message : String(err)));
2930
3116
  }).finally(() => {
2931
3117
  setActionInProgress(false);
2932
3118
  const storeError = useBrewStore.getState().errors["service-action"];
2933
- if (storeError) setLastError(storeError);
3119
+ if (storeError) setLastError(humaniseServiceError(storeError));
2934
3120
  });
2935
3121
  };
2936
3122
  if (input === "s") doAction("start");
2937
3123
  else if (input === "x") setConfirmAction({ type: "stop", name: svc.name });
2938
3124
  else if (input === "R") setConfirmAction({ type: "restart", name: svc.name });
2939
3125
  });
2940
- if (loading.services) return /* @__PURE__ */ jsx20(Loading, { message: t("loading_services") });
2941
- if (errors.services) return /* @__PURE__ */ jsx20(ErrorMessage, { message: errors.services });
3126
+ if (loading.services) return /* @__PURE__ */ jsx21(Loading, { message: t("loading_services") });
3127
+ if (errors.services) return /* @__PURE__ */ jsx21(ErrorMessage, { message: errors.services });
2942
3128
  if (services.length === 0) {
2943
- return /* @__PURE__ */ jsxs19(Box18, { flexDirection: "column", children: [
2944
- /* @__PURE__ */ jsx20(SectionHeader, { emoji: "\u2699\uFE0F", title: t("services_title"), gradient: GRADIENTS.ocean }),
2945
- /* @__PURE__ */ jsx20(Text20, { color: COLORS.textSecondary, italic: true, children: t("services_noServices") })
3129
+ return /* @__PURE__ */ jsxs20(Box19, { flexDirection: "column", children: [
3130
+ /* @__PURE__ */ jsx21(SectionHeader, { emoji: "\u2699\uFE0F", title: t("services_title"), gradient: GRADIENTS.ocean }),
3131
+ /* @__PURE__ */ jsx21(Text21, { color: COLORS.textSecondary, italic: true, children: t("services_noServices") })
2946
3132
  ] });
2947
3133
  }
2948
3134
  const start = Math.max(0, cursor - Math.floor(MAX_VISIBLE_ROWS / 2));
2949
3135
  const visible = services.slice(start, start + MAX_VISIBLE_ROWS);
2950
- return /* @__PURE__ */ jsxs19(Box18, { flexDirection: "column", children: [
2951
- /* @__PURE__ */ jsx20(SectionHeader, { emoji: "\u2699\uFE0F", title: t("services_titleCount", { count: services.length }), gradient: GRADIENTS.ocean }),
2952
- confirmAction && /* @__PURE__ */ jsx20(Box18, { marginY: SPACING.xs, children: /* @__PURE__ */ jsx20(
3136
+ return /* @__PURE__ */ jsxs20(Box19, { flexDirection: "column", children: [
3137
+ /* @__PURE__ */ jsx21(SectionHeader, { emoji: "\u2699\uFE0F", title: t("services_titleCount", { count: services.length }), gradient: GRADIENTS.ocean }),
3138
+ confirmAction && /* @__PURE__ */ jsx21(Box19, { marginY: SPACING.xs, children: /* @__PURE__ */ jsx21(
2953
3139
  ConfirmDialog,
2954
3140
  {
2955
3141
  message: confirmAction.type === "stop" ? t("services_confirmStop", { name: confirmAction.name }) : t("services_confirmRestart", { name: confirmAction.name }),
@@ -2968,37 +3154,37 @@ function ServicesView() {
2968
3154
  onCancel: () => setConfirmAction(null)
2969
3155
  }
2970
3156
  ) }),
2971
- /* @__PURE__ */ jsxs19(Box18, { flexDirection: "column", marginTop: SPACING.xs, children: [
2972
- /* @__PURE__ */ jsxs19(Box18, { gap: SPACING.xs, borderStyle: "single", borderBottom: true, borderTop: false, borderLeft: false, borderRight: false, borderColor: COLORS.border, paddingBottom: SPACING.none, children: [
2973
- /* @__PURE__ */ jsxs19(Text20, { bold: true, color: COLORS.text, children: [
3157
+ /* @__PURE__ */ jsxs20(Box19, { flexDirection: "column", marginTop: SPACING.xs, children: [
3158
+ /* @__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(Text21, { bold: true, color: COLORS.text, children: [
2974
3160
  " ",
2975
3161
  t("services_name").padEnd(svcNameWidth)
2976
3162
  ] }),
2977
- /* @__PURE__ */ jsx20(Text20, { bold: true, color: COLORS.text, children: t("services_status").padEnd(svcStatusWidth) }),
2978
- /* @__PURE__ */ jsx20(Text20, { bold: true, color: COLORS.text, children: t("services_user") })
3163
+ /* @__PURE__ */ jsx21(Text21, { bold: true, color: COLORS.text, children: t("services_status").padEnd(svcStatusWidth) }),
3164
+ /* @__PURE__ */ jsx21(Text21, { bold: true, color: COLORS.text, children: t("services_user") })
2979
3165
  ] }),
2980
- start > 0 && /* @__PURE__ */ jsxs19(Text20, { color: COLORS.textSecondary, dimColor: true, children: [
3166
+ start > 0 && /* @__PURE__ */ jsxs20(Text21, { color: COLORS.textSecondary, dimColor: true, children: [
2981
3167
  " ",
2982
3168
  t("scroll_moreAbove", { count: start })
2983
3169
  ] }),
2984
3170
  visible.map((svc, i) => {
2985
3171
  const idx = start + i;
2986
3172
  const isCurrent = idx === cursor;
2987
- return /* @__PURE__ */ jsxs19(SelectableRow, { isCurrent, children: [
2988
- /* @__PURE__ */ jsx20(Text20, { bold: isCurrent, inverse: isCurrent, color: isCurrent ? COLORS.text : COLORS.muted, children: svc.name.padEnd(svcNameWidth - 2) }),
2989
- /* @__PURE__ */ jsx20(StatusBadge, { label: svc.status, variant: STATUS_VARIANTS[svc.status] }),
2990
- /* @__PURE__ */ jsx20(Text20, { color: COLORS.muted, children: svc.user ?? "-" }),
2991
- svc.exit_code != null && svc.exit_code !== 0 && /* @__PURE__ */ jsx20(Text20, { color: COLORS.error, children: t("common_exit", { code: svc.exit_code }) })
3173
+ return /* @__PURE__ */ jsxs20(SelectableRow, { isCurrent, children: [
3174
+ /* @__PURE__ */ jsx21(Text21, { bold: isCurrent, inverse: isCurrent, color: isCurrent ? COLORS.text : COLORS.muted, children: svc.name.padEnd(svcNameWidth - 2) }),
3175
+ /* @__PURE__ */ jsx21(StatusBadge, { label: svc.status, variant: STATUS_VARIANTS[svc.status] }),
3176
+ /* @__PURE__ */ jsx21(Text21, { color: COLORS.muted, children: svc.user ?? "-" }),
3177
+ svc.exit_code != null && svc.exit_code !== 0 && /* @__PURE__ */ jsx21(Text21, { color: COLORS.error, children: t("common_exit", { code: svc.exit_code }) })
2992
3178
  ] }, svc.name);
2993
3179
  }),
2994
- start + MAX_VISIBLE_ROWS < services.length && /* @__PURE__ */ jsxs19(Text20, { color: COLORS.textSecondary, dimColor: true, children: [
3180
+ start + MAX_VISIBLE_ROWS < services.length && /* @__PURE__ */ jsxs20(Text21, { color: COLORS.textSecondary, dimColor: true, children: [
2995
3181
  " ",
2996
3182
  t("scroll_moreBelow", { count: services.length - start - MAX_VISIBLE_ROWS })
2997
3183
  ] })
2998
3184
  ] }),
2999
- actionInProgress && /* @__PURE__ */ jsx20(Text20, { color: COLORS.sky, children: t("services_processing") }),
3000
- lastError && /* @__PURE__ */ jsx20(Box18, { marginTop: SPACING.xs, children: /* @__PURE__ */ jsx20(Text20, { color: COLORS.error, children: lastError }) }),
3001
- /* @__PURE__ */ jsx20(Box18, { marginTop: SPACING.xs, children: /* @__PURE__ */ jsxs19(Text20, { color: COLORS.text, bold: true, children: [
3185
+ actionInProgress && /* @__PURE__ */ jsx21(Text21, { color: COLORS.sky, children: t("services_processing") }),
3186
+ lastError && /* @__PURE__ */ jsx21(Box19, { marginTop: SPACING.xs, children: /* @__PURE__ */ jsx21(Text21, { color: COLORS.error, children: lastError }) }),
3187
+ /* @__PURE__ */ jsx21(Box19, { marginTop: SPACING.xs, children: /* @__PURE__ */ jsxs20(Text21, { color: COLORS.text, bold: true, children: [
3002
3188
  cursor + 1,
3003
3189
  "/",
3004
3190
  services.length
@@ -3007,49 +3193,49 @@ function ServicesView() {
3007
3193
  }
3008
3194
 
3009
3195
  // src/views/doctor.tsx
3010
- import { useEffect as useEffect10, useRef as useRef5 } from "react";
3011
- import { Box as Box19, Text as Text21, useInput as useInput9 } from "ink";
3012
- import { jsx as jsx21, jsxs as jsxs20 } from "react/jsx-runtime";
3196
+ import { useEffect as useEffect11, useRef as useRef5 } from "react";
3197
+ import { Box as Box20, Text as Text22, useInput as useInput10 } from "ink";
3198
+ import { jsx as jsx22, jsxs as jsxs21 } from "react/jsx-runtime";
3013
3199
  function DoctorView() {
3014
3200
  const { doctorWarnings, doctorClean, loading, errors, fetchDoctor } = useBrewStore();
3015
3201
  const mountedRef = useRef5(true);
3016
- useEffect10(() => {
3202
+ useEffect11(() => {
3017
3203
  mountedRef.current = true;
3018
3204
  return () => {
3019
3205
  mountedRef.current = false;
3020
3206
  };
3021
3207
  }, []);
3022
- useEffect10(() => {
3208
+ useEffect11(() => {
3023
3209
  fetchDoctor();
3024
3210
  }, []);
3025
- useInput9((input) => {
3211
+ useInput10((input) => {
3026
3212
  if (input === "r") void fetchDoctor();
3027
3213
  });
3028
- if (loading.doctor) return /* @__PURE__ */ jsx21(Loading, { message: t("loading_doctor") });
3029
- if (errors.doctor) return /* @__PURE__ */ jsx21(ErrorMessage, { message: errors.doctor });
3030
- return /* @__PURE__ */ jsxs20(Box19, { flexDirection: "column", children: [
3031
- /* @__PURE__ */ jsx21(SectionHeader, { emoji: "\u{1FA7A}", title: t("doctor_title"), gradient: GRADIENTS.emerald }),
3032
- /* @__PURE__ */ jsxs20(Box19, { flexDirection: "column", marginTop: SPACING.xs, children: [
3033
- doctorClean && /* @__PURE__ */ jsx21(ResultBanner, { status: "success", message: `\u2714 ${t("doctor_clean")}` }),
3034
- doctorClean === false && doctorWarnings.length === 0 && /* @__PURE__ */ jsx21(Text21, { color: COLORS.warning, children: t("doctor_warningsNotCaptured") }),
3214
+ if (loading.doctor) return /* @__PURE__ */ jsx22(Loading, { message: t("loading_doctor") });
3215
+ if (errors.doctor) return /* @__PURE__ */ jsx22(ErrorMessage, { message: errors.doctor });
3216
+ return /* @__PURE__ */ jsxs21(Box20, { flexDirection: "column", children: [
3217
+ /* @__PURE__ */ jsx22(SectionHeader, { emoji: "\u{1FA7A}", title: t("doctor_title"), gradient: GRADIENTS.emerald }),
3218
+ /* @__PURE__ */ jsxs21(Box20, { flexDirection: "column", marginTop: SPACING.xs, children: [
3219
+ doctorClean && /* @__PURE__ */ jsx22(ResultBanner, { status: "success", message: `\u2714 ${t("doctor_clean")}` }),
3220
+ doctorClean === false && doctorWarnings.length === 0 && /* @__PURE__ */ jsx22(Text22, { color: COLORS.warning, children: t("doctor_warningsNotCaptured") }),
3035
3221
  doctorWarnings.map((warning, i) => (
3036
3222
  // FE-004: Improved React key
3037
- /* @__PURE__ */ jsx21(Box19, { flexDirection: "column", marginBottom: SPACING.xs, borderStyle: "single", borderColor: COLORS.warning, paddingX: SPACING.xs, children: warning.split("\n").map((line, j) => /* @__PURE__ */ jsx21(Text21, { color: j === 0 ? COLORS.warning : COLORS.muted, children: line }, `warning-${i}-${j}-${line.slice(0, 20)}`)) }, `warning-${i}-${warning.slice(0, 20)}`)
3223
+ /* @__PURE__ */ jsx22(Box20, { flexDirection: "column", marginBottom: SPACING.xs, borderStyle: "single", borderColor: COLORS.warning, paddingX: SPACING.xs, children: warning.split("\n").map((line, j) => /* @__PURE__ */ jsx22(Text22, { color: j === 0 ? COLORS.warning : COLORS.muted, children: line }, `warning-${i}-${j}-${line.slice(0, 20)}`)) }, `warning-${i}-${warning.slice(0, 20)}`)
3038
3224
  ))
3039
3225
  ] }),
3040
- /* @__PURE__ */ jsx21(Box19, { marginTop: SPACING.xs, children: /* @__PURE__ */ jsx21(Text21, { color: COLORS.text, bold: true, children: doctorWarnings.length > 0 ? tp("plural_warnings", doctorWarnings.length) : "" }) })
3226
+ /* @__PURE__ */ jsx22(Box20, { marginTop: SPACING.xs, children: /* @__PURE__ */ jsx22(Text22, { color: COLORS.text, bold: true, children: doctorWarnings.length > 0 ? tp("plural_warnings", doctorWarnings.length) : "" }) })
3041
3227
  ] });
3042
3228
  }
3043
3229
 
3044
3230
  // src/views/profiles.tsx
3045
- import { useEffect as useEffect11, useRef as useRef6, useState as useState8 } from "react";
3046
- import { Box as Box24, useInput as useInput10 } from "ink";
3231
+ import { useEffect as useEffect12, useRef as useRef6, useState as useState8 } from "react";
3232
+ import { Box as Box25, useInput as useInput11 } from "ink";
3047
3233
 
3048
3234
  // src/stores/profile-store.ts
3049
3235
  import { create as create9 } from "zustand";
3050
3236
 
3051
3237
  // src/lib/profiles/profile-manager.ts
3052
- import { readFile, writeFile, readdir, rm, rename } from "fs/promises";
3238
+ import { readFile, writeFile as writeFile2, readdir, rm, rename } from "fs/promises";
3053
3239
  import { join, basename } from "path";
3054
3240
 
3055
3241
  // src/lib/license/watermark.ts
@@ -3112,7 +3298,7 @@ async function saveProfile(isPro, profile) {
3112
3298
  const filePath = profilePath(profile.name);
3113
3299
  const tmpPath = filePath + ".tmp";
3114
3300
  const file = { version: 1, profile };
3115
- await writeFile(tmpPath, JSON.stringify(file, null, 2), { encoding: "utf-8", mode: 384 });
3301
+ await writeFile2(tmpPath, JSON.stringify(file, null, 2), { encoding: "utf-8", mode: 384 });
3116
3302
  await rename(tmpPath, filePath);
3117
3303
  }
3118
3304
  async function deleteProfile(isPro, name) {
@@ -3263,13 +3449,13 @@ var useProfileStore = create9((set) => ({
3263
3449
  }));
3264
3450
 
3265
3451
  // src/views/profiles/profile-list-mode.tsx
3266
- import { Box as Box20, Text as Text22 } from "ink";
3267
- import { jsx as jsx22, jsxs as jsxs21 } from "react/jsx-runtime";
3452
+ import { Box as Box21, Text as Text23 } from "ink";
3453
+ import { jsx as jsx23, jsxs as jsxs22 } from "react/jsx-runtime";
3268
3454
  function ProfileListMode({ profileNames, cursor, confirmDelete, loadError, onConfirmDelete, onCancelDelete }) {
3269
- return /* @__PURE__ */ jsxs21(Box20, { flexDirection: "column", children: [
3270
- /* @__PURE__ */ jsx22(SectionHeader, { emoji: "\u{1F4C1}", title: t("profiles_title", { count: profileNames.length }), gradient: GRADIENTS.gold }),
3271
- loadError && /* @__PURE__ */ jsx22(Box20, { marginY: SPACING.xs, children: /* @__PURE__ */ jsx22(Text22, { color: COLORS.error, children: loadError }) }),
3272
- confirmDelete && profileNames[cursor] && /* @__PURE__ */ jsx22(Box20, { marginY: SPACING.xs, children: /* @__PURE__ */ jsx22(
3455
+ return /* @__PURE__ */ jsxs22(Box21, { flexDirection: "column", children: [
3456
+ /* @__PURE__ */ jsx23(SectionHeader, { emoji: "\u{1F4C1}", title: t("profiles_title", { count: profileNames.length }), gradient: GRADIENTS.gold }),
3457
+ loadError && /* @__PURE__ */ jsx23(Box21, { marginY: SPACING.xs, children: /* @__PURE__ */ jsx23(Text23, { color: COLORS.error, children: loadError }) }),
3458
+ confirmDelete && profileNames[cursor] && /* @__PURE__ */ jsx23(Box21, { marginY: SPACING.xs, children: /* @__PURE__ */ jsx23(
3273
3459
  ConfirmDialog,
3274
3460
  {
3275
3461
  message: t("profiles_confirmDelete", { name: profileNames[cursor] }),
@@ -3277,22 +3463,22 @@ function ProfileListMode({ profileNames, cursor, confirmDelete, loadError, onCon
3277
3463
  onCancel: onCancelDelete
3278
3464
  }
3279
3465
  ) }),
3280
- profileNames.length === 0 && !confirmDelete && /* @__PURE__ */ jsx22(Box20, { marginTop: SPACING.xs, borderStyle: "round", borderColor: COLORS.textSecondary, paddingX: SPACING.sm, paddingY: SPACING.none, children: /* @__PURE__ */ jsxs21(Box20, { flexDirection: "column", children: [
3281
- /* @__PURE__ */ jsx22(Text22, { color: COLORS.textSecondary, italic: true, children: t("profiles_noProfiles") }),
3282
- /* @__PURE__ */ jsxs21(Text22, { color: COLORS.muted, children: [
3466
+ profileNames.length === 0 && !confirmDelete && /* @__PURE__ */ jsx23(Box21, { marginTop: SPACING.xs, borderStyle: "round", borderColor: COLORS.textSecondary, paddingX: SPACING.sm, paddingY: SPACING.none, children: /* @__PURE__ */ jsxs22(Box21, { flexDirection: "column", children: [
3467
+ /* @__PURE__ */ jsx23(Text23, { color: COLORS.textSecondary, italic: true, children: t("profiles_noProfiles") }),
3468
+ /* @__PURE__ */ jsxs22(Text23, { color: COLORS.muted, children: [
3283
3469
  t("profiles_press"),
3284
3470
  " ",
3285
- /* @__PURE__ */ jsx22(Text22, { color: COLORS.gold, bold: true, children: "n" }),
3471
+ /* @__PURE__ */ jsx23(Text23, { color: COLORS.gold, bold: true, children: "n" }),
3286
3472
  " ",
3287
3473
  t("profiles_exportHint")
3288
3474
  ] })
3289
3475
  ] }) }),
3290
- profileNames.length > 0 && !confirmDelete && /* @__PURE__ */ jsxs21(Box20, { flexDirection: "column", marginTop: SPACING.xs, children: [
3476
+ profileNames.length > 0 && !confirmDelete && /* @__PURE__ */ jsxs22(Box21, { flexDirection: "column", marginTop: SPACING.xs, children: [
3291
3477
  profileNames.map((name, i) => {
3292
3478
  const isCurrent = i === cursor;
3293
- return /* @__PURE__ */ jsx22(SelectableRow, { isCurrent, children: /* @__PURE__ */ jsx22(Text22, { bold: isCurrent, inverse: isCurrent, children: name }) }, name);
3479
+ return /* @__PURE__ */ jsx23(SelectableRow, { isCurrent, children: /* @__PURE__ */ jsx23(Text23, { bold: isCurrent, inverse: isCurrent, children: name }) }, name);
3294
3480
  }),
3295
- /* @__PURE__ */ jsx22(Box20, { marginTop: SPACING.xs, children: /* @__PURE__ */ jsxs21(Text22, { color: COLORS.text, bold: true, children: [
3481
+ /* @__PURE__ */ jsx23(Box21, { marginTop: SPACING.xs, children: /* @__PURE__ */ jsxs22(Text23, { color: COLORS.text, bold: true, children: [
3296
3482
  cursor + 1,
3297
3483
  "/",
3298
3484
  profileNames.length
@@ -3302,23 +3488,23 @@ function ProfileListMode({ profileNames, cursor, confirmDelete, loadError, onCon
3302
3488
  }
3303
3489
 
3304
3490
  // src/views/profiles/profile-detail-mode.tsx
3305
- import { Box as Box21, Text as Text23 } from "ink";
3306
- import { jsx as jsx23, jsxs as jsxs22 } from "react/jsx-runtime";
3491
+ import { Box as Box22, Text as Text24 } from "ink";
3492
+ import { jsx as jsx24, jsxs as jsxs23 } from "react/jsx-runtime";
3307
3493
  function ProfileDetailMode({ profile }) {
3308
- return /* @__PURE__ */ jsxs22(Box21, { flexDirection: "column", children: [
3309
- /* @__PURE__ */ jsx23(Text23, { bold: true, color: COLORS.gold, children: profile.name }),
3310
- /* @__PURE__ */ jsx23(Text23, { color: COLORS.muted, children: profile.description }),
3311
- /* @__PURE__ */ jsx23(Text23, { color: COLORS.muted, children: t("profiles_created", { date: formatDate(profile.createdAt) }) }),
3312
- /* @__PURE__ */ jsxs22(Box21, { marginTop: SPACING.xs, flexDirection: "column", children: [
3313
- /* @__PURE__ */ jsx23(Text23, { bold: true, children: t("profiles_formulaeCount", { count: profile.formulae.length }) }),
3314
- /* @__PURE__ */ jsxs22(Box21, { paddingLeft: SPACING.sm, flexDirection: "column", children: [
3315
- profile.formulae.slice(0, 30).map((f) => /* @__PURE__ */ jsx23(Text23, { color: COLORS.muted, children: f }, f)),
3316
- profile.formulae.length > 30 && /* @__PURE__ */ jsx23(Text23, { color: COLORS.textSecondary, italic: true, children: t("common_andMore", { count: profile.formulae.length - 30 }) })
3494
+ return /* @__PURE__ */ jsxs23(Box22, { flexDirection: "column", children: [
3495
+ /* @__PURE__ */ jsx24(Text24, { bold: true, color: COLORS.gold, children: profile.name }),
3496
+ /* @__PURE__ */ jsx24(Text24, { color: COLORS.muted, children: profile.description }),
3497
+ /* @__PURE__ */ jsx24(Text24, { color: COLORS.muted, children: t("profiles_created", { date: formatDate(profile.createdAt) }) }),
3498
+ /* @__PURE__ */ jsxs23(Box22, { marginTop: SPACING.xs, flexDirection: "column", children: [
3499
+ /* @__PURE__ */ jsx24(Text24, { bold: true, children: t("profiles_formulaeCount", { count: profile.formulae.length }) }),
3500
+ /* @__PURE__ */ jsxs23(Box22, { paddingLeft: SPACING.sm, flexDirection: "column", children: [
3501
+ profile.formulae.slice(0, 30).map((f) => /* @__PURE__ */ jsx24(Text24, { color: COLORS.muted, children: f }, f)),
3502
+ profile.formulae.length > 30 && /* @__PURE__ */ jsx24(Text24, { color: COLORS.textSecondary, italic: true, children: t("common_andMore", { count: profile.formulae.length - 30 }) })
3317
3503
  ] }),
3318
- /* @__PURE__ */ jsx23(Text23, { bold: true, children: t("profiles_casksCount", { count: profile.casks.length }) }),
3319
- /* @__PURE__ */ jsx23(Box21, { paddingLeft: SPACING.sm, flexDirection: "column", children: profile.casks.map((c) => /* @__PURE__ */ jsx23(Text23, { color: COLORS.muted, children: c }, c)) })
3504
+ /* @__PURE__ */ jsx24(Text24, { bold: true, children: t("profiles_casksCount", { count: profile.casks.length }) }),
3505
+ /* @__PURE__ */ jsx24(Box22, { paddingLeft: SPACING.sm, flexDirection: "column", children: profile.casks.map((c) => /* @__PURE__ */ jsx24(Text24, { color: COLORS.muted, children: c }, c)) })
3320
3506
  ] }),
3321
- /* @__PURE__ */ jsx23(Box21, { marginTop: SPACING.xs, children: /* @__PURE__ */ jsxs22(Text23, { color: COLORS.textSecondary, children: [
3507
+ /* @__PURE__ */ jsx24(Box22, { marginTop: SPACING.xs, children: /* @__PURE__ */ jsxs23(Text24, { color: COLORS.textSecondary, children: [
3322
3508
  "esc:",
3323
3509
  t("hint_back"),
3324
3510
  " e:",
@@ -3330,13 +3516,13 @@ function ProfileDetailMode({ profile }) {
3330
3516
  }
3331
3517
 
3332
3518
  // src/views/profiles/profile-create-flow.tsx
3333
- import { Box as Box22, Text as Text24 } from "ink";
3519
+ import { Box as Box23, Text as Text25 } from "ink";
3334
3520
  import { TextInput as TextInput3 } from "@inkjs/ui";
3335
- import { jsx as jsx24, jsxs as jsxs23 } from "react/jsx-runtime";
3521
+ import { jsx as jsx25, jsxs as jsxs24 } from "react/jsx-runtime";
3336
3522
  function ProfileCreateName({ onSubmit }) {
3337
- return /* @__PURE__ */ jsxs23(Box22, { flexDirection: "column", children: [
3338
- /* @__PURE__ */ jsx24(Text24, { bold: true, children: t("profiles_createName") }),
3339
- /* @__PURE__ */ jsx24(
3523
+ return /* @__PURE__ */ jsxs24(Box23, { flexDirection: "column", children: [
3524
+ /* @__PURE__ */ jsx25(Text25, { bold: true, children: t("profiles_createName") }),
3525
+ /* @__PURE__ */ jsx25(
3340
3526
  TextInput3,
3341
3527
  {
3342
3528
  placeholder: t("profiles_namePlaceholder"),
@@ -3346,13 +3532,13 @@ function ProfileCreateName({ onSubmit }) {
3346
3532
  ] });
3347
3533
  }
3348
3534
  function ProfileCreateDesc({ name, loadError, onSubmit }) {
3349
- return /* @__PURE__ */ jsxs23(Box22, { flexDirection: "column", children: [
3350
- /* @__PURE__ */ jsx24(Text24, { bold: true, children: t("profiles_createDesc", { name }) }),
3351
- loadError && /* @__PURE__ */ jsxs23(Text24, { color: COLORS.error, children: [
3535
+ return /* @__PURE__ */ jsxs24(Box23, { flexDirection: "column", children: [
3536
+ /* @__PURE__ */ jsx25(Text25, { bold: true, children: t("profiles_createDesc", { name }) }),
3537
+ loadError && /* @__PURE__ */ jsxs24(Text25, { color: COLORS.error, children: [
3352
3538
  t("error_prefix"),
3353
3539
  loadError
3354
3540
  ] }),
3355
- /* @__PURE__ */ jsx24(
3541
+ /* @__PURE__ */ jsx25(
3356
3542
  TextInput3,
3357
3543
  {
3358
3544
  placeholder: t("profiles_descPlaceholder"),
@@ -3363,13 +3549,13 @@ function ProfileCreateDesc({ name, loadError, onSubmit }) {
3363
3549
  }
3364
3550
 
3365
3551
  // src/views/profiles/profile-edit-flow.tsx
3366
- import { Box as Box23, Text as Text25 } from "ink";
3552
+ import { Box as Box24, Text as Text26 } from "ink";
3367
3553
  import { TextInput as TextInput4 } from "@inkjs/ui";
3368
- import { jsx as jsx25, jsxs as jsxs24 } from "react/jsx-runtime";
3554
+ import { jsx as jsx26, jsxs as jsxs25 } from "react/jsx-runtime";
3369
3555
  function ProfileEditName({ defaultName, onSubmit }) {
3370
- return /* @__PURE__ */ jsxs24(Box23, { flexDirection: "column", children: [
3371
- /* @__PURE__ */ jsx25(Text25, { bold: true, children: t("profiles_editName") }),
3372
- /* @__PURE__ */ jsx25(
3556
+ return /* @__PURE__ */ jsxs25(Box24, { flexDirection: "column", children: [
3557
+ /* @__PURE__ */ jsx26(Text26, { bold: true, children: t("profiles_editName") }),
3558
+ /* @__PURE__ */ jsx26(
3373
3559
  TextInput4,
3374
3560
  {
3375
3561
  defaultValue: defaultName,
@@ -3379,13 +3565,13 @@ function ProfileEditName({ defaultName, onSubmit }) {
3379
3565
  ] });
3380
3566
  }
3381
3567
  function ProfileEditDesc({ name, defaultDesc, loadError, onSubmit }) {
3382
- return /* @__PURE__ */ jsxs24(Box23, { flexDirection: "column", children: [
3383
- /* @__PURE__ */ jsx25(Text25, { bold: true, children: t("profiles_editDesc", { name }) }),
3384
- loadError && /* @__PURE__ */ jsxs24(Text25, { color: COLORS.error, children: [
3568
+ return /* @__PURE__ */ jsxs25(Box24, { flexDirection: "column", children: [
3569
+ /* @__PURE__ */ jsx26(Text26, { bold: true, children: t("profiles_editDesc", { name }) }),
3570
+ loadError && /* @__PURE__ */ jsxs25(Text26, { color: COLORS.error, children: [
3385
3571
  t("error_prefix"),
3386
3572
  loadError
3387
3573
  ] }),
3388
- /* @__PURE__ */ jsx25(
3574
+ /* @__PURE__ */ jsx26(
3389
3575
  TextInput4,
3390
3576
  {
3391
3577
  defaultValue: defaultDesc,
@@ -3396,7 +3582,7 @@ function ProfileEditDesc({ name, defaultDesc, loadError, onSubmit }) {
3396
3582
  }
3397
3583
 
3398
3584
  // src/views/profiles.tsx
3399
- import { jsx as jsx26, jsxs as jsxs25 } from "react/jsx-runtime";
3585
+ import { jsx as jsx27, jsxs as jsxs26 } from "react/jsx-runtime";
3400
3586
  function ProfilesView() {
3401
3587
  const { profileNames, selectedProfile, loading, loadError, fetchProfiles, loadProfile: loadProfile2, exportCurrent, deleteProfile: deleteProfile2, updateProfile: updateProfile2 } = useProfileStore();
3402
3588
  const [cursor, setCursor] = useState8(0);
@@ -3412,10 +3598,10 @@ function ProfilesView() {
3412
3598
  const { openModal, closeModal } = useModalStore();
3413
3599
  const importGenRef = useRef6(null);
3414
3600
  const mountedRef = useRef6(true);
3415
- useEffect11(() => {
3601
+ useEffect12(() => {
3416
3602
  fetchProfiles();
3417
3603
  }, []);
3418
- useEffect11(() => {
3604
+ useEffect12(() => {
3419
3605
  mountedRef.current = true;
3420
3606
  return () => {
3421
3607
  mountedRef.current = false;
@@ -3423,7 +3609,7 @@ function ProfilesView() {
3423
3609
  importGenRef.current = null;
3424
3610
  };
3425
3611
  }, []);
3426
- useEffect11(() => {
3612
+ useEffect12(() => {
3427
3613
  if (mode !== "list") {
3428
3614
  openModal();
3429
3615
  return () => {
@@ -3432,7 +3618,7 @@ function ProfilesView() {
3432
3618
  }
3433
3619
  return void 0;
3434
3620
  }, [mode]);
3435
- useInput10((input, key) => {
3621
+ useInput11((input, key) => {
3436
3622
  if (mode !== "list" || confirmDelete) return;
3437
3623
  if (input === "n") {
3438
3624
  setMode("create-name");
@@ -3454,7 +3640,7 @@ function ProfilesView() {
3454
3640
  if (input === "j" || key.downArrow) setCursor((c) => Math.min(c + 1, Math.max(0, profileNames.length - 1)));
3455
3641
  else if (input === "k" || key.upArrow) setCursor((c) => Math.max(c - 1, 0));
3456
3642
  });
3457
- useInput10((input, key) => {
3643
+ useInput11((input, key) => {
3458
3644
  if (key.escape || input === "q") {
3459
3645
  setMode("list");
3460
3646
  return;
@@ -3465,7 +3651,7 @@ function ProfilesView() {
3465
3651
  setMode("edit-name");
3466
3652
  }
3467
3653
  }, { isActive: mode === "detail" });
3468
- useInput10(() => {
3654
+ useInput11(() => {
3469
3655
  setMode("list");
3470
3656
  }, { isActive: mode === "importing" && !importRunning });
3471
3657
  const prepareImport = async (name) => {
@@ -3505,9 +3691,9 @@ function ProfilesView() {
3505
3691
  }
3506
3692
  }
3507
3693
  };
3508
- if (loading) return /* @__PURE__ */ jsx26(Loading, { message: t("loading_profiles") });
3694
+ if (loading) return /* @__PURE__ */ jsx27(Loading, { message: t("loading_profiles") });
3509
3695
  if (mode === "confirm-import" && importProfile2) {
3510
- return /* @__PURE__ */ jsx26(Box24, { flexDirection: "column", children: /* @__PURE__ */ jsx26(
3696
+ return /* @__PURE__ */ jsx27(Box25, { flexDirection: "column", children: /* @__PURE__ */ jsx27(
3511
3697
  ConfirmDialog,
3512
3698
  {
3513
3699
  message: t("profiles_importSummary", {
@@ -3527,19 +3713,19 @@ function ProfilesView() {
3527
3713
  ) });
3528
3714
  }
3529
3715
  if (mode === "importing") {
3530
- return /* @__PURE__ */ jsxs25(Box24, { flexDirection: "column", children: [
3531
- /* @__PURE__ */ jsx26(ProgressLog, { lines: importLines, isRunning: importRunning, title: t("profiles_importTitle") }),
3532
- !importRunning && /* @__PURE__ */ jsx26(Box24, { marginTop: SPACING.xs, children: /* @__PURE__ */ jsx26(ResultBanner, { status: importHadError ? "error" : "success", message: importHadError ? t("profiles_importPartial") : `\u2714 ${t("profiles_importComplete")}` }) })
3716
+ return /* @__PURE__ */ jsxs26(Box25, { flexDirection: "column", children: [
3717
+ /* @__PURE__ */ jsx27(ProgressLog, { lines: importLines, isRunning: importRunning, title: t("profiles_importTitle") }),
3718
+ !importRunning && /* @__PURE__ */ jsx27(Box25, { marginTop: SPACING.xs, children: /* @__PURE__ */ jsx27(ResultBanner, { status: importHadError ? "error" : "success", message: importHadError ? t("profiles_importPartial") : `\u2714 ${t("profiles_importComplete")}` }) })
3533
3719
  ] });
3534
3720
  }
3535
3721
  if (mode === "create-name") {
3536
- return /* @__PURE__ */ jsx26(ProfileCreateName, { onSubmit: (val) => {
3722
+ return /* @__PURE__ */ jsx27(ProfileCreateName, { onSubmit: (val) => {
3537
3723
  setNewName(val);
3538
3724
  setMode("create-desc");
3539
3725
  } });
3540
3726
  }
3541
3727
  if (mode === "create-desc") {
3542
- return /* @__PURE__ */ jsx26(
3728
+ return /* @__PURE__ */ jsx27(
3543
3729
  ProfileCreateDesc,
3544
3730
  {
3545
3731
  name: newName,
@@ -3556,13 +3742,13 @@ function ProfilesView() {
3556
3742
  );
3557
3743
  }
3558
3744
  if (mode === "edit-name") {
3559
- return /* @__PURE__ */ jsx26(ProfileEditName, { defaultName: editName, onSubmit: (val) => {
3745
+ return /* @__PURE__ */ jsx27(ProfileEditName, { defaultName: editName, onSubmit: (val) => {
3560
3746
  setEditName(val);
3561
3747
  setMode("edit-desc");
3562
3748
  } });
3563
3749
  }
3564
3750
  if (mode === "edit-desc") {
3565
- return /* @__PURE__ */ jsx26(
3751
+ return /* @__PURE__ */ jsx27(
3566
3752
  ProfileEditDesc,
3567
3753
  {
3568
3754
  name: editName,
@@ -3580,9 +3766,9 @@ function ProfilesView() {
3580
3766
  );
3581
3767
  }
3582
3768
  if (mode === "detail" && selectedProfile) {
3583
- return /* @__PURE__ */ jsx26(ProfileDetailMode, { profile: selectedProfile });
3769
+ return /* @__PURE__ */ jsx27(ProfileDetailMode, { profile: selectedProfile });
3584
3770
  }
3585
- return /* @__PURE__ */ jsx26(
3771
+ return /* @__PURE__ */ jsx27(
3586
3772
  ProfileListMode,
3587
3773
  {
3588
3774
  profileNames,
@@ -3599,8 +3785,8 @@ function ProfilesView() {
3599
3785
  }
3600
3786
 
3601
3787
  // src/views/smart-cleanup.tsx
3602
- import { useEffect as useEffect12, useRef as useRef7, useState as useState9 } from "react";
3603
- import { Box as Box25, Text as Text26, useInput as useInput11 } from "ink";
3788
+ import { useEffect as useEffect13, useRef as useRef7, useState as useState9 } from "react";
3789
+ import { Box as Box26, Text as Text27, useInput as useInput12 } from "ink";
3604
3790
 
3605
3791
  // src/stores/cleanup-store.ts
3606
3792
  import { create as create10 } from "zustand";
@@ -3720,7 +3906,7 @@ var useCleanupStore = create10((set, get) => ({
3720
3906
  }));
3721
3907
 
3722
3908
  // src/views/smart-cleanup.tsx
3723
- import { jsx as jsx27, jsxs as jsxs26 } from "react/jsx-runtime";
3909
+ import { jsx as jsx28, jsxs as jsxs27 } from "react/jsx-runtime";
3724
3910
  function SmartCleanupView() {
3725
3911
  const { summary, selected, loading, error, analyze, toggleSelect, selectAll } = useCleanupStore();
3726
3912
  const [cursor, setCursor] = useState9(0);
@@ -3729,10 +3915,10 @@ function SmartCleanupView() {
3729
3915
  const [failedNames, setFailedNames] = useState9([]);
3730
3916
  const stream = useBrewStream();
3731
3917
  const hasRefreshed = useRef7(false);
3732
- useEffect12(() => {
3918
+ useEffect13(() => {
3733
3919
  analyze();
3734
3920
  }, []);
3735
- useEffect12(() => {
3921
+ useEffect13(() => {
3736
3922
  if (!stream.isRunning && !stream.error && stream.lines.length > 0 && !hasRefreshed.current) {
3737
3923
  hasRefreshed.current = true;
3738
3924
  void analyze();
@@ -3740,7 +3926,7 @@ function SmartCleanupView() {
3740
3926
  }, [stream.isRunning, stream.error]);
3741
3927
  const candidates = summary?.candidates ?? [];
3742
3928
  const isDependencyError = stream.error != null && stream.lines.some((l) => l.includes("Refusing to uninstall") || l.includes("required by"));
3743
- useInput11((input, key) => {
3929
+ useInput12((input, key) => {
3744
3930
  if (stream.isRunning) {
3745
3931
  if (key.escape) stream.cancel();
3746
3932
  return;
@@ -3771,26 +3957,26 @@ function SmartCleanupView() {
3771
3957
  if (input === "j" || key.downArrow) setCursor((c) => Math.min(c + 1, Math.max(0, candidates.length - 1)));
3772
3958
  else if (input === "k" || key.upArrow) setCursor((c) => Math.max(c - 1, 0));
3773
3959
  });
3774
- if (loading) return /* @__PURE__ */ jsx27(Loading, { message: t("loading_cleanup") });
3775
- if (error) return /* @__PURE__ */ jsx27(ErrorMessage, { message: error });
3960
+ if (loading) return /* @__PURE__ */ jsx28(Loading, { message: t("loading_cleanup") });
3961
+ if (error) return /* @__PURE__ */ jsx28(ErrorMessage, { message: error });
3776
3962
  if (stream.isRunning || stream.lines.length > 0) {
3777
- return /* @__PURE__ */ jsxs26(Box25, { flexDirection: "column", children: [
3778
- /* @__PURE__ */ jsx27(ProgressLog, { lines: stream.lines, isRunning: stream.isRunning, title: t("cleanup_cleaning") }),
3779
- stream.isRunning && /* @__PURE__ */ jsxs26(Text26, { color: COLORS.muted, children: [
3963
+ return /* @__PURE__ */ jsxs27(Box26, { flexDirection: "column", children: [
3964
+ /* @__PURE__ */ jsx28(ProgressLog, { lines: stream.lines, isRunning: stream.isRunning, title: t("cleanup_cleaning") }),
3965
+ stream.isRunning && /* @__PURE__ */ jsxs27(Text27, { color: COLORS.muted, children: [
3780
3966
  "esc:",
3781
3967
  t("hint_cancel")
3782
3968
  ] }),
3783
- !stream.isRunning && !stream.error && /* @__PURE__ */ jsx27(ResultBanner, { status: "success", message: `\u2714 ${t("cleanup_complete")}` }),
3784
- !stream.isRunning && stream.error && /* @__PURE__ */ jsxs26(Box25, { flexDirection: "column", gap: SPACING.xs, children: [
3785
- /* @__PURE__ */ jsx27(ResultBanner, { status: "error", message: `\u2718 ${t("cleanup_depError")}` }),
3786
- isDependencyError && failedNames.length > 0 && /* @__PURE__ */ jsxs26(Text26, { color: COLORS.warning, children: [
3969
+ !stream.isRunning && !stream.error && /* @__PURE__ */ jsx28(ResultBanner, { status: "success", message: `\u2714 ${t("cleanup_complete")}` }),
3970
+ !stream.isRunning && stream.error && /* @__PURE__ */ jsxs27(Box26, { flexDirection: "column", gap: SPACING.xs, children: [
3971
+ /* @__PURE__ */ jsx28(ResultBanner, { status: "error", message: `\u2718 ${t("cleanup_depError")}` }),
3972
+ isDependencyError && failedNames.length > 0 && /* @__PURE__ */ jsxs27(Text27, { color: COLORS.warning, children: [
3787
3973
  "F:",
3788
3974
  t("hint_force"),
3789
3975
  " r:",
3790
3976
  t("hint_refresh")
3791
3977
  ] })
3792
3978
  ] }),
3793
- confirmForce && /* @__PURE__ */ jsx27(Box25, { marginY: SPACING.xs, children: /* @__PURE__ */ jsx27(
3979
+ confirmForce && /* @__PURE__ */ jsx28(Box26, { marginY: SPACING.xs, children: /* @__PURE__ */ jsx28(
3794
3980
  ConfirmDialog,
3795
3981
  {
3796
3982
  message: t("cleanup_confirmForce", { count: failedNames.length }),
@@ -3805,16 +3991,16 @@ function SmartCleanupView() {
3805
3991
  ) })
3806
3992
  ] });
3807
3993
  }
3808
- return /* @__PURE__ */ jsxs26(Box25, { flexDirection: "column", children: [
3809
- /* @__PURE__ */ jsx27(SectionHeader, { emoji: "\u{1F9F9}", title: t("cleanup_title"), gradient: GRADIENTS.emerald }),
3810
- summary && /* @__PURE__ */ jsxs26(Box25, { gap: SPACING.xs, marginY: SPACING.xs, children: [
3811
- /* @__PURE__ */ jsx27(StatCard, { label: t("cleanup_orphans"), value: candidates.length, color: candidates.length > 0 ? COLORS.warning : COLORS.success }),
3812
- /* @__PURE__ */ jsx27(StatCard, { label: t("cleanup_reclaimable"), value: summary.totalReclaimableFormatted, color: COLORS.sky }),
3813
- /* @__PURE__ */ jsx27(StatCard, { label: t("cleanup_selected"), value: selected.size, color: selected.size > 0 ? COLORS.success : COLORS.muted })
3994
+ return /* @__PURE__ */ jsxs27(Box26, { flexDirection: "column", children: [
3995
+ /* @__PURE__ */ jsx28(SectionHeader, { emoji: "\u{1F9F9}", title: t("cleanup_title"), gradient: GRADIENTS.emerald }),
3996
+ summary && /* @__PURE__ */ jsxs27(Box26, { gap: SPACING.xs, marginY: SPACING.xs, children: [
3997
+ /* @__PURE__ */ jsx28(StatCard, { label: t("cleanup_orphans"), value: candidates.length, color: candidates.length > 0 ? COLORS.warning : COLORS.success }),
3998
+ /* @__PURE__ */ jsx28(StatCard, { label: t("cleanup_reclaimable"), value: summary.totalReclaimableFormatted, color: COLORS.sky }),
3999
+ /* @__PURE__ */ jsx28(StatCard, { label: t("cleanup_selected"), value: selected.size, color: selected.size > 0 ? COLORS.success : COLORS.muted })
3814
4000
  ] }),
3815
- confirmClean && /* @__PURE__ */ jsxs26(Box25, { flexDirection: "column", marginY: SPACING.xs, gap: SPACING.xs, children: [
3816
- /* @__PURE__ */ jsx27(Box25, { borderStyle: "round", borderColor: COLORS.warning, paddingX: SPACING.sm, paddingY: SPACING.none, children: /* @__PURE__ */ jsx27(Text26, { color: COLORS.warning, children: t("cleanup_warning_system_tools") }) }),
3817
- /* @__PURE__ */ jsx27(
4001
+ confirmClean && /* @__PURE__ */ jsxs27(Box26, { flexDirection: "column", marginY: SPACING.xs, gap: SPACING.xs, children: [
4002
+ /* @__PURE__ */ jsx28(Box26, { borderStyle: "round", borderColor: COLORS.warning, paddingX: SPACING.sm, paddingY: SPACING.none, children: /* @__PURE__ */ jsx28(Text27, { color: COLORS.warning, children: t("cleanup_warning_system_tools") }) }),
4003
+ /* @__PURE__ */ jsx28(
3818
4004
  ConfirmDialog,
3819
4005
  {
3820
4006
  message: t("cleanup_confirmUninstall", { count: selected.size }),
@@ -3829,23 +4015,23 @@ function SmartCleanupView() {
3829
4015
  }
3830
4016
  )
3831
4017
  ] }),
3832
- candidates.length === 0 && !confirmClean && /* @__PURE__ */ jsx27(ResultBanner, { status: "success", message: `\u2714 ${t("cleanup_systemClean")}` }),
3833
- candidates.length > 0 && !confirmClean && /* @__PURE__ */ jsxs26(Box25, { flexDirection: "column", children: [
4018
+ candidates.length === 0 && !confirmClean && /* @__PURE__ */ jsx28(ResultBanner, { status: "success", message: `\u2714 ${t("cleanup_systemClean")}` }),
4019
+ candidates.length > 0 && !confirmClean && /* @__PURE__ */ jsxs27(Box26, { flexDirection: "column", children: [
3834
4020
  candidates.map((c, i) => {
3835
4021
  const isCurrent = i === cursor;
3836
4022
  const isSelected = selected.has(c.name);
3837
- return /* @__PURE__ */ jsxs26(SelectableRow, { isCurrent, children: [
3838
- /* @__PURE__ */ jsx27(Text26, { color: isSelected ? COLORS.success : COLORS.muted, children: isSelected ? "\u2611" : "\u2610" }),
3839
- /* @__PURE__ */ jsx27(Text26, { bold: isCurrent, inverse: isCurrent, color: isCurrent ? COLORS.text : COLORS.muted, children: c.name }),
3840
- /* @__PURE__ */ jsx27(Text26, { color: COLORS.warning, children: c.diskUsageFormatted }),
3841
- /* @__PURE__ */ jsxs26(Text26, { color: COLORS.textSecondary, children: [
4023
+ return /* @__PURE__ */ jsxs27(SelectableRow, { isCurrent, children: [
4024
+ /* @__PURE__ */ jsx28(Text27, { color: isSelected ? COLORS.success : COLORS.muted, children: isSelected ? "\u2611" : "\u2610" }),
4025
+ /* @__PURE__ */ jsx28(Text27, { bold: isCurrent, inverse: isCurrent, color: isCurrent ? COLORS.text : COLORS.muted, children: c.name }),
4026
+ /* @__PURE__ */ jsx28(Text27, { color: COLORS.warning, children: c.diskUsageFormatted }),
4027
+ /* @__PURE__ */ jsxs27(Text27, { color: COLORS.textSecondary, children: [
3842
4028
  "[",
3843
4029
  c.reason,
3844
4030
  "]"
3845
4031
  ] })
3846
4032
  ] }, c.name);
3847
4033
  }),
3848
- /* @__PURE__ */ jsx27(Box25, { marginTop: SPACING.xs, children: /* @__PURE__ */ jsxs26(Text26, { color: COLORS.text, bold: true, children: [
4034
+ /* @__PURE__ */ jsx28(Box26, { marginTop: SPACING.xs, children: /* @__PURE__ */ jsxs27(Text27, { color: COLORS.text, bold: true, children: [
3849
4035
  cursor + 1,
3850
4036
  "/",
3851
4037
  candidates.length
@@ -3855,8 +4041,8 @@ function SmartCleanupView() {
3855
4041
  }
3856
4042
 
3857
4043
  // src/views/history.tsx
3858
- import { useEffect as useEffect13, useState as useState10, useMemo as useMemo5 } from "react";
3859
- import { Box as Box26, Text as Text27, useInput as useInput12, useStdout as useStdout7 } from "ink";
4044
+ import { useEffect as useEffect14, useState as useState10, useMemo as useMemo5 } from "react";
4045
+ import { Box as Box27, Text as Text28, useInput as useInput13, useStdout as useStdout7 } from "ink";
3860
4046
 
3861
4047
  // src/stores/history-store.ts
3862
4048
  import { create as create11 } from "zustand";
@@ -3892,7 +4078,7 @@ var useHistoryStore = create11((set) => ({
3892
4078
  }));
3893
4079
 
3894
4080
  // src/views/history.tsx
3895
- import { jsx as jsx28, jsxs as jsxs27 } from "react/jsx-runtime";
4081
+ import { jsx as jsx29, jsxs as jsxs28 } from "react/jsx-runtime";
3896
4082
  var ACTION_ICONS = {
3897
4083
  install: { icon: "+", color: COLORS.success },
3898
4084
  uninstall: { icon: "-", color: COLORS.error },
@@ -3917,10 +4103,12 @@ function HistoryView() {
3917
4103
  const stream = useBrewStream();
3918
4104
  const debouncedQuery = useDebounce(searchQuery, 200);
3919
4105
  const { openModal, closeModal } = useModalStore();
3920
- useEffect13(() => {
4106
+ const { stdout } = useStdout7();
4107
+ const MAX_VISIBLE_ROWS = Math.max(5, (stdout?.rows ?? 24) - 8);
4108
+ useEffect14(() => {
3921
4109
  fetchHistory();
3922
4110
  }, []);
3923
- useEffect13(() => {
4111
+ useEffect14(() => {
3924
4112
  if (isSearching) {
3925
4113
  openModal();
3926
4114
  return () => {
@@ -3940,7 +4128,7 @@ function HistoryView() {
3940
4128
  }
3941
4129
  return result;
3942
4130
  }, [entries, filter, debouncedQuery]);
3943
- useInput12((input, key) => {
4131
+ useInput13((input, key) => {
3944
4132
  if (confirmClear || confirmReplay || stream.isRunning) return;
3945
4133
  if (isSearching) {
3946
4134
  if (key.escape) {
@@ -3970,19 +4158,17 @@ function HistoryView() {
3970
4158
  if (input === "j" || key.downArrow) setCursor((c) => Math.min(c + 1, Math.max(0, filtered.length - 1)));
3971
4159
  else if (input === "k" || key.upArrow) setCursor((c) => Math.max(c - 1, 0));
3972
4160
  });
3973
- if (loading) return /* @__PURE__ */ jsx28(Loading, { message: t("loading_history") });
3974
- if (error) return /* @__PURE__ */ jsx28(ErrorMessage, { message: error });
3975
- const { stdout } = useStdout7();
3976
- const MAX_VISIBLE_ROWS = Math.max(5, (stdout?.rows ?? 24) - 8);
4161
+ if (loading) return /* @__PURE__ */ jsx29(Loading, { message: t("loading_history") });
4162
+ if (error) return /* @__PURE__ */ jsx29(ErrorMessage, { message: error });
3977
4163
  const start = Math.max(0, cursor - Math.floor(MAX_VISIBLE_ROWS / 2));
3978
4164
  const visible = filtered.slice(start, start + MAX_VISIBLE_ROWS);
3979
- return /* @__PURE__ */ jsxs27(Box26, { flexDirection: "column", children: [
3980
- /* @__PURE__ */ jsxs27(Box26, { gap: SPACING.sm, marginBottom: SPACING.xs, children: [
3981
- /* @__PURE__ */ jsx28(SectionHeader, { emoji: "\u{1F4DC}", title: t("history_title", { count: filtered.length }), gradient: GRADIENTS.gold }),
3982
- /* @__PURE__ */ jsx28(Text27, { color: filter === "all" ? COLORS.text : COLORS.gold, children: t("history_filterLabel", { filter }) })
4165
+ return /* @__PURE__ */ jsxs28(Box27, { flexDirection: "column", children: [
4166
+ /* @__PURE__ */ jsxs28(Box27, { gap: SPACING.sm, marginBottom: SPACING.xs, children: [
4167
+ /* @__PURE__ */ jsx29(SectionHeader, { emoji: "\u{1F4DC}", title: t("history_title", { count: filtered.length }), gradient: GRADIENTS.gold }),
4168
+ /* @__PURE__ */ jsx29(Text28, { color: filter === "all" ? COLORS.text : COLORS.gold, children: t("history_filterLabel", { filter }) })
3983
4169
  ] }),
3984
- isSearching && /* @__PURE__ */ jsx28(Box26, { marginBottom: SPACING.xs, children: /* @__PURE__ */ jsx28(SearchInput, { defaultValue: searchQuery, onChange: setSearchQuery, placeholder: t("history_searchPlaceholder"), isActive: true }) }),
3985
- confirmClear && /* @__PURE__ */ jsx28(
4170
+ isSearching && /* @__PURE__ */ jsx29(Box27, { marginBottom: SPACING.xs, children: /* @__PURE__ */ jsx29(SearchInput, { defaultValue: searchQuery, onChange: setSearchQuery, placeholder: t("history_searchPlaceholder"), isActive: true }) }),
4171
+ confirmClear && /* @__PURE__ */ jsx29(
3986
4172
  ConfirmDialog,
3987
4173
  {
3988
4174
  message: t("history_confirmClear", { count: entries.length }),
@@ -3993,7 +4179,7 @@ function HistoryView() {
3993
4179
  onCancel: () => setConfirmClear(false)
3994
4180
  }
3995
4181
  ),
3996
- confirmReplay && /* @__PURE__ */ jsx28(
4182
+ confirmReplay && /* @__PURE__ */ jsx29(
3997
4183
  ConfirmDialog,
3998
4184
  {
3999
4185
  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 ?? "" }),
@@ -4021,10 +4207,10 @@ function HistoryView() {
4021
4207
  onCancel: () => setConfirmReplay(null)
4022
4208
  }
4023
4209
  ),
4024
- (stream.isRunning || stream.lines.length > 0) && /* @__PURE__ */ jsx28(Box26, { marginY: SPACING.xs, children: /* @__PURE__ */ jsx28(ProgressLog, { lines: stream.lines, isRunning: stream.isRunning, title: t("hint_replay") }) }),
4025
- filtered.length === 0 && !confirmClear && /* @__PURE__ */ jsx28(Text27, { color: COLORS.textSecondary, italic: true, children: filter !== "all" ? t("history_noEntriesFor", { filter }) : t("history_noEntries") }),
4026
- filtered.length > 0 && !confirmClear && /* @__PURE__ */ jsxs27(Box26, { flexDirection: "column", children: [
4027
- start > 0 && /* @__PURE__ */ jsxs27(Text27, { color: COLORS.textSecondary, dimColor: true, children: [
4210
+ (stream.isRunning || stream.lines.length > 0) && /* @__PURE__ */ jsx29(Box27, { marginY: SPACING.xs, children: /* @__PURE__ */ jsx29(ProgressLog, { lines: stream.lines, isRunning: stream.isRunning, title: t("hint_replay") }) }),
4211
+ filtered.length === 0 && !confirmClear && /* @__PURE__ */ jsx29(Text28, { color: COLORS.textSecondary, italic: true, children: filter !== "all" ? t("history_noEntriesFor", { filter }) : t("history_noEntries") }),
4212
+ filtered.length > 0 && !confirmClear && /* @__PURE__ */ jsxs28(Box27, { flexDirection: "column", children: [
4213
+ start > 0 && /* @__PURE__ */ jsxs28(Text28, { color: COLORS.textSecondary, dimColor: true, children: [
4028
4214
  " ",
4029
4215
  t("scroll_moreAbove", { count: start })
4030
4216
  ] }),
@@ -4033,19 +4219,19 @@ function HistoryView() {
4033
4219
  const isCurrent = idx === cursor;
4034
4220
  const { icon, color } = ACTION_ICONS[entry.action];
4035
4221
  const ts = new Date(entry.timestamp).getTime() / 1e3;
4036
- return /* @__PURE__ */ jsxs27(SelectableRow, { isCurrent, children: [
4037
- /* @__PURE__ */ jsx28(Text27, { color, bold: true, children: icon }),
4038
- /* @__PURE__ */ jsx28(Text27, { bold: isCurrent, inverse: isCurrent, color: isCurrent ? COLORS.text : COLORS.muted, children: t(ACTION_LABEL_KEYS[entry.action]).padEnd(12) }),
4039
- /* @__PURE__ */ jsx28(Text27, { color: COLORS.text, children: entry.packageName ?? t("history_all") }),
4040
- entry.success ? /* @__PURE__ */ jsx28(StatusBadge, { label: t("badge_ok"), variant: "success" }) : /* @__PURE__ */ jsx28(StatusBadge, { label: t("badge_fail"), variant: "error" }),
4041
- /* @__PURE__ */ jsx28(Text27, { color: COLORS.muted, children: formatRelativeTime(ts) })
4222
+ return /* @__PURE__ */ jsxs28(SelectableRow, { isCurrent, children: [
4223
+ /* @__PURE__ */ jsx29(Text28, { color, bold: true, children: icon }),
4224
+ /* @__PURE__ */ jsx29(Text28, { bold: isCurrent, inverse: isCurrent, color: isCurrent ? COLORS.text : COLORS.muted, children: t(ACTION_LABEL_KEYS[entry.action]).padEnd(12) }),
4225
+ /* @__PURE__ */ jsx29(Text28, { color: COLORS.text, children: entry.packageName ?? t("history_all") }),
4226
+ entry.success ? /* @__PURE__ */ jsx29(StatusBadge, { label: t("badge_ok"), variant: "success" }) : /* @__PURE__ */ jsx29(StatusBadge, { label: t("badge_fail"), variant: "error" }),
4227
+ /* @__PURE__ */ jsx29(Text28, { color: COLORS.muted, children: formatRelativeTime(ts) })
4042
4228
  ] }, entry.id);
4043
4229
  }),
4044
- start + MAX_VISIBLE_ROWS < filtered.length && /* @__PURE__ */ jsxs27(Text27, { color: COLORS.textSecondary, dimColor: true, children: [
4230
+ start + MAX_VISIBLE_ROWS < filtered.length && /* @__PURE__ */ jsxs28(Text28, { color: COLORS.textSecondary, dimColor: true, children: [
4045
4231
  " ",
4046
4232
  t("scroll_moreBelow", { count: filtered.length - start - MAX_VISIBLE_ROWS })
4047
4233
  ] }),
4048
- /* @__PURE__ */ jsx28(Box26, { marginTop: SPACING.xs, children: /* @__PURE__ */ jsxs27(Text27, { color: COLORS.text, bold: true, children: [
4234
+ /* @__PURE__ */ jsx29(Box27, { marginTop: SPACING.xs, children: /* @__PURE__ */ jsxs28(Text28, { color: COLORS.text, bold: true, children: [
4049
4235
  cursor + 1,
4050
4236
  "/",
4051
4237
  filtered.length
@@ -4055,9 +4241,9 @@ function HistoryView() {
4055
4241
  }
4056
4242
 
4057
4243
  // src/views/security-audit.tsx
4058
- import { useEffect as useEffect14, useState as useState11 } from "react";
4059
- import { Box as Box27, Text as Text28, useInput as useInput13 } from "ink";
4060
- import { jsx as jsx29, jsxs as jsxs28 } from "react/jsx-runtime";
4244
+ import { useEffect as useEffect15, useState as useState11 } from "react";
4245
+ import { Box as Box28, Text as Text29, useInput as useInput14 } from "ink";
4246
+ import { jsx as jsx30, jsxs as jsxs29 } from "react/jsx-runtime";
4061
4247
  var SEVERITY_COLORS = {
4062
4248
  CRITICAL: COLORS.error,
4063
4249
  HIGH: COLORS.error,
@@ -4082,11 +4268,11 @@ function SecurityAuditView() {
4082
4268
  const [expandedPkg, setExpandedPkg] = useState11(null);
4083
4269
  const [confirmUpgrade, setConfirmUpgrade] = useState11(null);
4084
4270
  const stream = useBrewStream();
4085
- useEffect14(() => {
4271
+ useEffect15(() => {
4086
4272
  scan();
4087
4273
  }, []);
4088
4274
  const results = summary?.results ?? [];
4089
- useInput13((input, key) => {
4275
+ useInput14((input, key) => {
4090
4276
  if (confirmUpgrade || stream.isRunning) return;
4091
4277
  if (input === "r") {
4092
4278
  void scan(true);
@@ -4106,17 +4292,17 @@ function SecurityAuditView() {
4106
4292
  setExpandedPkg(expandedPkg === results[cursor].packageName ? null : results[cursor].packageName);
4107
4293
  }
4108
4294
  });
4109
- if (loading) return /* @__PURE__ */ jsx29(Loading, { message: t("loading_security") });
4295
+ if (loading) return /* @__PURE__ */ jsx30(Loading, { message: t("loading_security") });
4110
4296
  if (error) {
4111
4297
  const displayError = isNetworkError(error) ? t("security_networkError") : error;
4112
- return /* @__PURE__ */ jsx29(ErrorMessage, { message: displayError });
4298
+ return /* @__PURE__ */ jsx30(ErrorMessage, { message: displayError });
4113
4299
  }
4114
4300
  const cacheAge = cachedAt ? formatRelativeTime(cachedAt / 1e3) : null;
4115
- return /* @__PURE__ */ jsxs28(Box27, { flexDirection: "column", children: [
4116
- /* @__PURE__ */ jsx29(SectionHeader, { emoji: "\u{1F6E1}\uFE0F", title: t("security_title"), gradient: GRADIENTS.ocean }),
4117
- summary && /* @__PURE__ */ jsxs28(Box27, { gap: SPACING.xs, marginY: SPACING.xs, children: [
4118
- /* @__PURE__ */ jsx29(StatCard, { label: t("security_scanned"), value: summary.totalPackages, color: COLORS.info }),
4119
- /* @__PURE__ */ jsx29(
4301
+ return /* @__PURE__ */ jsxs29(Box28, { flexDirection: "column", children: [
4302
+ /* @__PURE__ */ jsx30(SectionHeader, { emoji: "\u{1F6E1}\uFE0F", title: t("security_title"), gradient: GRADIENTS.ocean }),
4303
+ summary && /* @__PURE__ */ jsxs29(Box28, { gap: SPACING.xs, marginY: SPACING.xs, children: [
4304
+ /* @__PURE__ */ jsx30(StatCard, { label: t("security_scanned"), value: summary.totalPackages, color: COLORS.info }),
4305
+ /* @__PURE__ */ jsx30(
4120
4306
  StatCard,
4121
4307
  {
4122
4308
  label: t("security_vulnerable"),
@@ -4124,13 +4310,14 @@ function SecurityAuditView() {
4124
4310
  color: summary.vulnerablePackages > 0 ? COLORS.error : COLORS.success
4125
4311
  }
4126
4312
  ),
4127
- summary.criticalCount > 0 && /* @__PURE__ */ jsx29(StatCard, { label: t("security_critical"), value: summary.criticalCount, color: COLORS.error }),
4128
- summary.highCount > 0 && /* @__PURE__ */ jsx29(StatCard, { label: t("security_high"), value: summary.highCount, color: COLORS.error }),
4129
- summary.mediumCount > 0 && /* @__PURE__ */ jsx29(StatCard, { label: t("security_medium"), value: summary.mediumCount, color: COLORS.warning })
4313
+ summary.criticalCount > 0 && /* @__PURE__ */ jsx30(StatCard, { label: t("security_critical"), value: summary.criticalCount, color: COLORS.error }),
4314
+ summary.highCount > 0 && /* @__PURE__ */ jsx30(StatCard, { label: t("security_high"), value: summary.highCount, color: COLORS.error }),
4315
+ summary.mediumCount > 0 && /* @__PURE__ */ jsx30(StatCard, { label: t("security_medium"), value: summary.mediumCount, color: COLORS.warning })
4130
4316
  ] }),
4131
- cacheAge && /* @__PURE__ */ jsx29(Text28, { color: COLORS.muted, children: t("security_cachedResults", { time: cacheAge }) }),
4132
- results.length === 0 && summary && /* @__PURE__ */ jsx29(Box27, { marginTop: SPACING.xs, children: /* @__PURE__ */ jsx29(ResultBanner, { status: "success", message: `\u2714 ${t("security_noVulns")}` }) }),
4133
- confirmUpgrade && /* @__PURE__ */ jsx29(Box27, { marginY: SPACING.xs, children: /* @__PURE__ */ jsx29(
4317
+ cacheAge && /* @__PURE__ */ jsx30(Text29, { color: COLORS.muted, children: t("security_cachedResults", { time: cacheAge }) }),
4318
+ summary && /* @__PURE__ */ jsx30(Box28, { marginTop: SPACING.xs, children: /* @__PURE__ */ jsx30(Text29, { color: COLORS.textSecondary, italic: true, children: t("security_coverage_warning") }) }),
4319
+ results.length === 0 && summary && /* @__PURE__ */ jsx30(Box28, { marginTop: SPACING.xs, children: /* @__PURE__ */ jsx30(ResultBanner, { status: "success", message: `\u2714 ${t("security_noVulns")}` }) }),
4320
+ confirmUpgrade && /* @__PURE__ */ jsx30(Box28, { marginY: SPACING.xs, children: /* @__PURE__ */ jsx30(
4134
4321
  ConfirmDialog,
4135
4322
  {
4136
4323
  message: t("security_confirmUpgrade", { name: confirmUpgrade }),
@@ -4143,55 +4330,55 @@ function SecurityAuditView() {
4143
4330
  onCancel: () => setConfirmUpgrade(null)
4144
4331
  }
4145
4332
  ) }),
4146
- (stream.isRunning || stream.lines.length > 0) && /* @__PURE__ */ jsx29(Box27, { marginY: SPACING.xs, children: /* @__PURE__ */ jsx29(ProgressLog, { lines: stream.lines, isRunning: stream.isRunning, title: t("hint_upgrade") }) }),
4147
- results.length > 0 && /* @__PURE__ */ jsxs28(Box27, { flexDirection: "column", marginTop: SPACING.xs, children: [
4333
+ (stream.isRunning || stream.lines.length > 0) && /* @__PURE__ */ jsx30(Box28, { marginY: SPACING.xs, children: /* @__PURE__ */ jsx30(ProgressLog, { lines: stream.lines, isRunning: stream.isRunning, title: t("hint_upgrade") }) }),
4334
+ results.length > 0 && /* @__PURE__ */ jsxs29(Box28, { flexDirection: "column", marginTop: SPACING.xs, children: [
4148
4335
  results.map((pkg, i) => {
4149
4336
  const isCurrent = i === cursor;
4150
4337
  const isExpanded = expandedPkg === pkg.packageName;
4151
- return /* @__PURE__ */ jsxs28(Box27, { flexDirection: "column", children: [
4152
- /* @__PURE__ */ jsxs28(SelectableRow, { isCurrent, children: [
4153
- /* @__PURE__ */ jsx29(StatusBadge, { label: pkg.maxSeverity, variant: SEVERITY_BADGE[pkg.maxSeverity] }),
4154
- /* @__PURE__ */ jsx29(Text28, { bold: isCurrent, inverse: isCurrent, color: isCurrent ? COLORS.text : COLORS.muted, children: pkg.packageName }),
4155
- /* @__PURE__ */ jsx29(Text28, { color: COLORS.muted, children: pkg.installedVersion }),
4156
- /* @__PURE__ */ jsx29(Text28, { color: COLORS.muted, children: tp("plural_vulns", pkg.vulnerabilities.length) }),
4157
- pkg.vulnerabilities.some((v) => v.fixedVersion) && /* @__PURE__ */ jsxs28(Text28, { color: COLORS.textSecondary, children: [
4338
+ return /* @__PURE__ */ jsxs29(Box28, { flexDirection: "column", children: [
4339
+ /* @__PURE__ */ jsxs29(SelectableRow, { isCurrent, children: [
4340
+ /* @__PURE__ */ jsx30(StatusBadge, { label: pkg.maxSeverity, variant: SEVERITY_BADGE[pkg.maxSeverity] }),
4341
+ /* @__PURE__ */ jsx30(Text29, { bold: isCurrent, inverse: isCurrent, color: isCurrent ? COLORS.text : COLORS.muted, children: pkg.packageName }),
4342
+ /* @__PURE__ */ jsx30(Text29, { color: COLORS.muted, children: pkg.installedVersion }),
4343
+ /* @__PURE__ */ jsx30(Text29, { color: COLORS.muted, children: tp("plural_vulns", pkg.vulnerabilities.length) }),
4344
+ pkg.vulnerabilities.some((v) => v.fixedVersion) && /* @__PURE__ */ jsxs29(Text29, { color: COLORS.textSecondary, children: [
4158
4345
  "[R:",
4159
4346
  t("hint_rollback"),
4160
4347
  "]"
4161
4348
  ] }),
4162
- /* @__PURE__ */ jsx29(Text28, { color: COLORS.muted, children: isExpanded ? "\u25BC" : "\u25B6" })
4349
+ /* @__PURE__ */ jsx30(Text29, { color: COLORS.muted, children: isExpanded ? "\u25BC" : "\u25B6" })
4163
4350
  ] }),
4164
- isExpanded && /* @__PURE__ */ jsx29(Box27, { flexDirection: "column", paddingLeft: SPACING.lg, marginBottom: SPACING.xs, children: pkg.vulnerabilities.map((vuln) => /* @__PURE__ */ jsxs28(Box27, { flexDirection: "column", marginBottom: SPACING.xs, children: [
4165
- /* @__PURE__ */ jsxs28(Box27, { gap: SPACING.xs, children: [
4166
- /* @__PURE__ */ jsx29(Text28, { color: SEVERITY_COLORS[vuln.severity], bold: true, children: vuln.id }),
4167
- /* @__PURE__ */ jsxs28(Text28, { color: COLORS.muted, children: [
4351
+ isExpanded && /* @__PURE__ */ jsx30(Box28, { flexDirection: "column", paddingLeft: SPACING.lg, marginBottom: SPACING.xs, children: pkg.vulnerabilities.map((vuln) => /* @__PURE__ */ jsxs29(Box28, { flexDirection: "column", marginBottom: SPACING.xs, children: [
4352
+ /* @__PURE__ */ jsxs29(Box28, { gap: SPACING.xs, children: [
4353
+ /* @__PURE__ */ jsx30(Text29, { color: SEVERITY_COLORS[vuln.severity], bold: true, children: vuln.id }),
4354
+ /* @__PURE__ */ jsxs29(Text29, { color: COLORS.muted, children: [
4168
4355
  "[",
4169
4356
  vuln.severity,
4170
4357
  "]"
4171
4358
  ] })
4172
4359
  ] }),
4173
- /* @__PURE__ */ jsx29(Text28, { color: COLORS.muted, wrap: "wrap", children: vuln.summary }),
4174
- vuln.fixedVersion && /* @__PURE__ */ jsx29(Text28, { color: COLORS.success, children: t("security_fixedIn", { version: vuln.fixedVersion }) })
4360
+ /* @__PURE__ */ jsx30(Text29, { color: COLORS.muted, wrap: "wrap", children: vuln.summary }),
4361
+ vuln.fixedVersion && /* @__PURE__ */ jsx30(Text29, { color: COLORS.success, children: t("security_fixedIn", { version: vuln.fixedVersion }) })
4175
4362
  ] }, vuln.id)) })
4176
4363
  ] }, pkg.packageName);
4177
4364
  }),
4178
- /* @__PURE__ */ jsx29(Box27, { marginTop: SPACING.xs, children: /* @__PURE__ */ jsxs28(Text28, { color: COLORS.text, bold: true, children: [
4365
+ /* @__PURE__ */ jsx30(Box28, { marginTop: SPACING.xs, children: /* @__PURE__ */ jsxs29(Text29, { color: COLORS.text, bold: true, children: [
4179
4366
  cursor + 1,
4180
4367
  "/",
4181
4368
  results.length
4182
4369
  ] }) }),
4183
- /* @__PURE__ */ jsx29(Box27, { marginTop: SPACING.xs, children: /* @__PURE__ */ jsx29(Text28, { color: COLORS.textSecondary, children: t("security_rollback_hint") }) })
4370
+ /* @__PURE__ */ jsx30(Box28, { marginTop: SPACING.xs, children: /* @__PURE__ */ jsx30(Text29, { color: COLORS.textSecondary, children: t("security_rollback_hint") }) })
4184
4371
  ] })
4185
4372
  ] });
4186
4373
  }
4187
4374
 
4188
4375
  // src/views/account.tsx
4189
4376
  import { useState as useState12 } from "react";
4190
- import { Box as Box28, Text as Text29, useInput as useInput14 } from "ink";
4377
+ import { Box as Box29, Text as Text30, useInput as useInput15 } from "ink";
4191
4378
  import { TextInput as TextInput5 } from "@inkjs/ui";
4192
4379
 
4193
4380
  // src/lib/license/promo.ts
4194
- import { readFile as readFile2, writeFile as writeFile2, rename as rename2 } from "fs/promises";
4381
+ import { readFile as readFile2, writeFile as writeFile3, rename as rename2 } from "fs/promises";
4195
4382
  import { randomBytes, randomUUID } from "crypto";
4196
4383
  import { join as join2 } from "path";
4197
4384
  var PROMO_PATH = join2(DATA_DIR, "promo.json");
@@ -4259,13 +4446,13 @@ async function redeemPromoCode(code) {
4259
4446
  }
4260
4447
  file.redemptions.push(redemption);
4261
4448
  const tmpPath = PROMO_PATH + ".tmp";
4262
- await writeFile2(tmpPath, JSON.stringify(file, null, 2), { encoding: "utf-8", mode: 384 });
4449
+ await writeFile3(tmpPath, JSON.stringify(file, null, 2), { encoding: "utf-8", mode: 384 });
4263
4450
  await rename2(tmpPath, PROMO_PATH);
4264
4451
  return { success: true, expiresAt: redemption.expiresAt };
4265
4452
  }
4266
4453
 
4267
4454
  // src/views/account.tsx
4268
- import { Fragment as Fragment5, jsx as jsx30, jsxs as jsxs29 } from "react/jsx-runtime";
4455
+ import { Fragment as Fragment5, jsx as jsx31, jsxs as jsxs30 } from "react/jsx-runtime";
4269
4456
  function AccountView() {
4270
4457
  const { status, license, deactivate: deactivate2, revalidate: revalidate2, degradation } = useLicenseStore();
4271
4458
  const [confirmDeactivate, setConfirmDeactivate] = useState12(false);
@@ -4275,7 +4462,7 @@ function AccountView() {
4275
4462
  const [promoLoading, setPromoLoading] = useState12(false);
4276
4463
  const [promoResult, setPromoResult] = useState12(null);
4277
4464
  const [revalidating, setRevalidating] = useState12(false);
4278
- useInput14((input, key) => {
4465
+ useInput15((input, key) => {
4279
4466
  if (confirmDeactivate || deactivating || promoMode || revalidating) {
4280
4467
  if (key.escape && promoMode) {
4281
4468
  setPromoMode(false);
@@ -4300,11 +4487,11 @@ function AccountView() {
4300
4487
  return key.slice(0, 4) + "-****-****-" + key.slice(-4);
4301
4488
  };
4302
4489
  if (status === "validating") {
4303
- return /* @__PURE__ */ jsx30(Loading, { message: t("account_loading") });
4490
+ return /* @__PURE__ */ jsx31(Loading, { message: t("account_loading") });
4304
4491
  }
4305
- return /* @__PURE__ */ jsxs29(Box28, { flexDirection: "column", children: [
4306
- /* @__PURE__ */ jsx30(SectionHeader, { emoji: "\u{1F464}", title: t("account_title"), gradient: GRADIENTS.gold }),
4307
- confirmDeactivate && /* @__PURE__ */ jsx30(Box28, { marginY: SPACING.xs, children: /* @__PURE__ */ jsx30(
4492
+ return /* @__PURE__ */ jsxs30(Box29, { flexDirection: "column", children: [
4493
+ /* @__PURE__ */ jsx31(SectionHeader, { emoji: "\u{1F464}", title: t("account_title"), gradient: GRADIENTS.gold }),
4494
+ confirmDeactivate && /* @__PURE__ */ jsx31(Box29, { marginY: SPACING.xs, children: /* @__PURE__ */ jsx31(
4308
4495
  ConfirmDialog,
4309
4496
  {
4310
4497
  message: t("account_confirmDeactivate"),
@@ -4323,72 +4510,72 @@ function AccountView() {
4323
4510
  onCancel: () => setConfirmDeactivate(false)
4324
4511
  }
4325
4512
  ) }),
4326
- /* @__PURE__ */ jsxs29(Box28, { flexDirection: "column", marginTop: SPACING.xs, paddingLeft: SPACING.sm, children: [
4327
- /* @__PURE__ */ jsxs29(Box28, { gap: SPACING.xs, children: [
4328
- /* @__PURE__ */ jsx30(Text29, { color: COLORS.muted, children: t("account_statusLabel") }),
4329
- status === "pro" && /* @__PURE__ */ jsx30(Text29, { color: COLORS.success, bold: true, children: t("account_pro") }),
4330
- status === "free" && /* @__PURE__ */ jsx30(Text29, { color: COLORS.muted, children: t("account_free") }),
4331
- status === "expired" && /* @__PURE__ */ jsx30(Text29, { color: COLORS.error, children: t("account_expired") })
4513
+ /* @__PURE__ */ jsxs30(Box29, { flexDirection: "column", marginTop: SPACING.xs, paddingLeft: SPACING.sm, children: [
4514
+ /* @__PURE__ */ jsxs30(Box29, { gap: SPACING.xs, children: [
4515
+ /* @__PURE__ */ jsx31(Text30, { color: COLORS.muted, children: t("account_statusLabel") }),
4516
+ status === "pro" && /* @__PURE__ */ jsx31(Text30, { color: COLORS.success, bold: true, children: t("account_pro") }),
4517
+ status === "free" && /* @__PURE__ */ jsx31(Text30, { color: COLORS.muted, children: t("account_free") }),
4518
+ status === "expired" && /* @__PURE__ */ jsx31(Text30, { color: COLORS.error, children: t("account_expired") })
4332
4519
  ] }),
4333
- (degradation === "warning" || degradation === "limited") && license && /* @__PURE__ */ jsx30(Box28, { marginTop: SPACING.xs, borderStyle: "round", borderColor: COLORS.warning, paddingX: SPACING.sm, paddingY: SPACING.none, children: /* @__PURE__ */ jsx30(Text29, { color: COLORS.warning, children: t("license_offlineWarning", {
4520
+ (degradation === "warning" || degradation === "limited") && license && /* @__PURE__ */ jsx31(Box29, { marginTop: SPACING.xs, borderStyle: "round", borderColor: COLORS.warning, paddingX: SPACING.sm, paddingY: SPACING.none, children: /* @__PURE__ */ jsx31(Text30, { color: COLORS.warning, children: t("license_offlineWarning", {
4334
4521
  days: Math.floor((Date.now() - new Date(license.lastValidatedAt).getTime()) / (24 * 60 * 60 * 1e3))
4335
4522
  }) }) }),
4336
- license && /* @__PURE__ */ jsxs29(Fragment5, { children: [
4337
- /* @__PURE__ */ jsxs29(Box28, { gap: SPACING.xs, children: [
4338
- /* @__PURE__ */ jsx30(Text29, { color: COLORS.muted, children: t("account_emailLabel") }),
4339
- /* @__PURE__ */ jsx30(Text29, { children: license.customerEmail })
4523
+ license && /* @__PURE__ */ jsxs30(Fragment5, { children: [
4524
+ /* @__PURE__ */ jsxs30(Box29, { gap: SPACING.xs, children: [
4525
+ /* @__PURE__ */ jsx31(Text30, { color: COLORS.muted, children: t("account_emailLabel") }),
4526
+ /* @__PURE__ */ jsx31(Text30, { children: license.customerEmail })
4340
4527
  ] }),
4341
- /* @__PURE__ */ jsxs29(Box28, { gap: SPACING.xs, children: [
4342
- /* @__PURE__ */ jsx30(Text29, { color: COLORS.muted, children: t("account_nameLabel") }),
4343
- /* @__PURE__ */ jsx30(Text29, { children: license.customerName })
4528
+ /* @__PURE__ */ jsxs30(Box29, { gap: SPACING.xs, children: [
4529
+ /* @__PURE__ */ jsx31(Text30, { color: COLORS.muted, children: t("account_nameLabel") }),
4530
+ /* @__PURE__ */ jsx31(Text30, { children: license.customerName })
4344
4531
  ] }),
4345
- /* @__PURE__ */ jsxs29(Box28, { gap: SPACING.xs, children: [
4346
- /* @__PURE__ */ jsx30(Text29, { color: COLORS.muted, children: t("account_planLabel") }),
4347
- /* @__PURE__ */ jsx30(Text29, { color: COLORS.success, bold: true, children: "Pro" })
4532
+ /* @__PURE__ */ jsxs30(Box29, { gap: SPACING.xs, children: [
4533
+ /* @__PURE__ */ jsx31(Text30, { color: COLORS.muted, children: t("account_planLabel") }),
4534
+ /* @__PURE__ */ jsx31(Text30, { color: COLORS.success, bold: true, children: "Pro" })
4348
4535
  ] }),
4349
- /* @__PURE__ */ jsxs29(Box28, { gap: SPACING.xs, children: [
4350
- /* @__PURE__ */ jsx30(Text29, { color: COLORS.muted, children: t("account_keyLabel") }),
4351
- /* @__PURE__ */ jsx30(Text29, { children: maskKey(license.key) })
4536
+ /* @__PURE__ */ jsxs30(Box29, { gap: SPACING.xs, children: [
4537
+ /* @__PURE__ */ jsx31(Text30, { color: COLORS.muted, children: t("account_keyLabel") }),
4538
+ /* @__PURE__ */ jsx31(Text30, { children: maskKey(license.key) })
4352
4539
  ] }),
4353
- license.expiresAt && /* @__PURE__ */ jsxs29(Box28, { gap: SPACING.xs, children: [
4354
- /* @__PURE__ */ jsx30(Text29, { color: COLORS.muted, children: t("account_expiresLabel") }),
4355
- /* @__PURE__ */ jsx30(Text29, { children: formatDate(license.expiresAt) })
4540
+ license.expiresAt && /* @__PURE__ */ jsxs30(Box29, { gap: SPACING.xs, children: [
4541
+ /* @__PURE__ */ jsx31(Text30, { color: COLORS.muted, children: t("account_expiresLabel") }),
4542
+ /* @__PURE__ */ jsx31(Text30, { children: formatDate(license.expiresAt) })
4356
4543
  ] }),
4357
- /* @__PURE__ */ jsxs29(Box28, { gap: SPACING.xs, children: [
4358
- /* @__PURE__ */ jsx30(Text29, { color: COLORS.muted, children: t("account_activatedLabel") }),
4359
- /* @__PURE__ */ jsx30(Text29, { children: formatDate(license.activatedAt) })
4544
+ /* @__PURE__ */ jsxs30(Box29, { gap: SPACING.xs, children: [
4545
+ /* @__PURE__ */ jsx31(Text30, { color: COLORS.muted, children: t("account_activatedLabel") }),
4546
+ /* @__PURE__ */ jsx31(Text30, { children: formatDate(license.activatedAt) })
4360
4547
  ] })
4361
4548
  ] }),
4362
- status === "free" && /* @__PURE__ */ jsxs29(Box28, { flexDirection: "column", marginTop: SPACING.sm, borderStyle: "round", borderColor: COLORS.brand, paddingX: SPACING.sm, paddingY: SPACING.xs, children: [
4363
- /* @__PURE__ */ jsxs29(Text29, { bold: true, color: COLORS.brand, children: [
4549
+ 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(Text30, { bold: true, color: COLORS.brand, children: [
4364
4551
  "\u2B50",
4365
4552
  " ",
4366
4553
  t("account_upgradeTitle")
4367
4554
  ] }),
4368
- /* @__PURE__ */ jsx30(Text29, { children: " " }),
4369
- /* @__PURE__ */ jsx30(Text29, { children: t("account_unlockDesc") }),
4370
- /* @__PURE__ */ jsx30(Text29, { color: COLORS.info, bold: true, children: t("account_pricing") }),
4371
- /* @__PURE__ */ jsx30(Text29, { children: " " }),
4372
- /* @__PURE__ */ jsxs29(Text29, { color: COLORS.muted, children: [
4555
+ /* @__PURE__ */ jsx31(Text30, { children: " " }),
4556
+ /* @__PURE__ */ jsx31(Text30, { children: t("account_unlockDesc") }),
4557
+ /* @__PURE__ */ jsx31(Text30, { color: COLORS.info, bold: true, children: t("account_pricing") }),
4558
+ /* @__PURE__ */ jsx31(Text30, { children: " " }),
4559
+ /* @__PURE__ */ jsxs30(Text30, { color: COLORS.muted, children: [
4373
4560
  t("upgrade_buyAt"),
4374
4561
  " ",
4375
- /* @__PURE__ */ jsx30(Text29, { color: COLORS.sky, bold: true, children: t("upgrade_buyUrl") })
4562
+ /* @__PURE__ */ jsx31(Text30, { color: COLORS.sky, bold: true, children: t("upgrade_buyUrl") })
4376
4563
  ] }),
4377
- /* @__PURE__ */ jsxs29(Text29, { color: COLORS.muted, children: [
4564
+ /* @__PURE__ */ jsxs30(Text30, { color: COLORS.muted, children: [
4378
4565
  t("account_runActivate"),
4379
4566
  " ",
4380
- /* @__PURE__ */ jsx30(Text29, { color: COLORS.success, bold: true, children: t("account_activateCmd") })
4567
+ /* @__PURE__ */ jsx31(Text30, { color: COLORS.success, bold: true, children: t("account_activateCmd") })
4381
4568
  ] })
4382
4569
  ] }),
4383
- status === "expired" && /* @__PURE__ */ jsx30(Box28, { marginTop: SPACING.xs, children: /* @__PURE__ */ jsx30(Box28, { borderStyle: "round", borderColor: COLORS.error, paddingX: SPACING.sm, paddingY: SPACING.none, children: /* @__PURE__ */ jsx30(Text29, { color: COLORS.error, children: t("account_licenseExpired") }) }) }),
4384
- deactivating && /* @__PURE__ */ jsx30(Text29, { color: COLORS.sky, children: t("account_deactivating") }),
4385
- deactivateError && /* @__PURE__ */ jsx30(Text29, { color: COLORS.error, children: deactivateError })
4570
+ status === "expired" && /* @__PURE__ */ jsx31(Box29, { marginTop: SPACING.xs, children: /* @__PURE__ */ jsx31(Box29, { borderStyle: "round", borderColor: COLORS.error, paddingX: SPACING.sm, paddingY: SPACING.none, children: /* @__PURE__ */ jsx31(Text30, { color: COLORS.error, children: t("account_licenseExpired") }) }) }),
4571
+ deactivating && /* @__PURE__ */ jsx31(Text30, { color: COLORS.sky, children: t("account_deactivating") }),
4572
+ deactivateError && /* @__PURE__ */ jsx31(Text30, { color: COLORS.error, children: deactivateError })
4386
4573
  ] }),
4387
- /* @__PURE__ */ jsx30(Box28, { flexDirection: "column", marginTop: SPACING.xs, paddingLeft: SPACING.sm, children: promoMode ? /* @__PURE__ */ jsxs29(Box28, { flexDirection: "column", gap: SPACING.xs, children: [
4388
- /* @__PURE__ */ jsx30(Text29, { bold: true, color: COLORS.gold, children: t("account_promoTitle") }),
4389
- promoLoading ? /* @__PURE__ */ jsx30(Text29, { color: COLORS.sky, children: t("account_promoValidating") }) : /* @__PURE__ */ jsxs29(Box28, { gap: SPACING.xs, children: [
4390
- /* @__PURE__ */ jsx30(Text29, { color: COLORS.muted, children: t("account_promoLabel") }),
4391
- /* @__PURE__ */ jsx30(
4574
+ /* @__PURE__ */ jsx31(Box29, { flexDirection: "column", marginTop: SPACING.xs, paddingLeft: SPACING.sm, children: promoMode ? /* @__PURE__ */ jsxs30(Box29, { flexDirection: "column", gap: SPACING.xs, children: [
4575
+ /* @__PURE__ */ jsx31(Text30, { bold: true, color: COLORS.gold, children: t("account_promoTitle") }),
4576
+ promoLoading ? /* @__PURE__ */ jsx31(Text30, { color: COLORS.sky, children: t("account_promoValidating") }) : /* @__PURE__ */ jsxs30(Box29, { gap: SPACING.xs, children: [
4577
+ /* @__PURE__ */ jsx31(Text30, { color: COLORS.muted, children: t("account_promoLabel") }),
4578
+ /* @__PURE__ */ jsx31(
4392
4579
  TextInput5,
4393
4580
  {
4394
4581
  defaultValue: "",
@@ -4412,22 +4599,22 @@ function AccountView() {
4412
4599
  }
4413
4600
  )
4414
4601
  ] }),
4415
- promoResult && /* @__PURE__ */ jsx30(ResultBanner, { status: promoResult.success ? "success" : "error", message: promoResult.message }),
4416
- /* @__PURE__ */ jsx30(Text29, { color: COLORS.textSecondary, dimColor: true, children: t("account_promoEsc") })
4417
- ] }) : /* @__PURE__ */ jsx30(Text29, { color: COLORS.textSecondary, children: t("account_promoHint") }) }),
4418
- /* @__PURE__ */ jsx30(Box28, { marginTop: SPACING.xs, children: /* @__PURE__ */ jsxs29(Text29, { color: COLORS.textSecondary, children: [
4602
+ promoResult && /* @__PURE__ */ jsx31(ResultBanner, { status: promoResult.success ? "success" : "error", message: promoResult.message }),
4603
+ /* @__PURE__ */ jsx31(Text30, { color: COLORS.textSecondary, dimColor: true, children: t("account_promoEsc") })
4604
+ ] }) : /* @__PURE__ */ jsx31(Text30, { color: COLORS.textSecondary, children: t("account_promoHint") }) }),
4605
+ /* @__PURE__ */ jsx31(Box29, { marginTop: SPACING.xs, children: /* @__PURE__ */ jsxs30(Text30, { color: COLORS.textSecondary, children: [
4419
4606
  status === "pro" || status === "team" ? `d ${t("hint_deactivate")} ` : "",
4420
4607
  status === "pro" || status === "team" || status === "expired" ? `v ${t("hint_revalidate")} ` : "",
4421
4608
  revalidating ? t("account_revalidating") : "",
4422
4609
  " ",
4423
- t("app_version", { version: "0.6.2" })
4610
+ t("app_version", { version: "0.7.0" })
4424
4611
  ] }) })
4425
4612
  ] });
4426
4613
  }
4427
4614
 
4428
4615
  // src/views/rollback.tsx
4429
- import { useCallback as useCallback3, useEffect as useEffect15, useRef as useRef8, useState as useState13 } from "react";
4430
- import { Box as Box29, Text as Text30, useInput as useInput15 } from "ink";
4616
+ import { useCallback as useCallback3, useEffect as useEffect16, useRef as useRef8, useState as useState13 } from "react";
4617
+ import { Box as Box30, Text as Text31, useInput as useInput16 } from "ink";
4431
4618
 
4432
4619
  // src/stores/rollback-store.ts
4433
4620
  import { create as create12 } from "zustand";
@@ -4637,7 +4824,7 @@ var useRollbackStore = create12((set) => ({
4637
4824
  }));
4638
4825
 
4639
4826
  // src/views/rollback.tsx
4640
- import { jsx as jsx31, jsxs as jsxs30 } from "react/jsx-runtime";
4827
+ import { jsx as jsx32, jsxs as jsxs31 } from "react/jsx-runtime";
4641
4828
  function strategyLabel(action) {
4642
4829
  switch (action.strategy) {
4643
4830
  case "versioned-formula":
@@ -4665,48 +4852,48 @@ function actionPrefix(action) {
4665
4852
  }
4666
4853
  function PlanView({ plan }) {
4667
4854
  const executableCount = plan.actions.filter((a) => a.strategy !== "unavailable" && a.action !== "remove").length;
4668
- return /* @__PURE__ */ jsxs30(Box29, { flexDirection: "column", marginTop: SPACING.xs, children: [
4669
- /* @__PURE__ */ jsxs30(Box29, { marginBottom: SPACING.xs, children: [
4670
- /* @__PURE__ */ jsxs30(Text30, { color: COLORS.text, bold: true, children: [
4855
+ return /* @__PURE__ */ jsxs31(Box30, { flexDirection: "column", marginTop: SPACING.xs, children: [
4856
+ /* @__PURE__ */ jsxs31(Box30, { marginBottom: SPACING.xs, children: [
4857
+ /* @__PURE__ */ jsxs31(Text31, { color: COLORS.text, bold: true, children: [
4671
4858
  plan.snapshotLabel,
4672
4859
  " "
4673
4860
  ] }),
4674
- /* @__PURE__ */ jsx31(Text30, { color: COLORS.textSecondary, children: plan.snapshotDate })
4861
+ /* @__PURE__ */ jsx32(Text31, { color: COLORS.textSecondary, children: plan.snapshotDate })
4675
4862
  ] }),
4676
- plan.actions.length === 0 && /* @__PURE__ */ jsx31(ResultBanner, { status: "success", message: t("rollback_diff_empty") }),
4677
- plan.actions.map((a) => /* @__PURE__ */ jsxs30(Box29, { children: [
4678
- /* @__PURE__ */ jsxs30(Text30, { color: actionColor(a), children: [
4863
+ plan.actions.length === 0 && /* @__PURE__ */ jsx32(ResultBanner, { status: "success", message: t("rollback_diff_empty") }),
4864
+ plan.actions.map((a) => /* @__PURE__ */ jsxs31(Box30, { children: [
4865
+ /* @__PURE__ */ jsxs31(Text31, { color: actionColor(a), children: [
4679
4866
  actionPrefix(a),
4680
4867
  " "
4681
4868
  ] }),
4682
- /* @__PURE__ */ jsx31(Text30, { color: actionColor(a), bold: true, children: a.packageName }),
4683
- a.fromVersion !== "" && a.toVersion !== "" && /* @__PURE__ */ jsxs30(Text30, { color: COLORS.textSecondary, children: [
4869
+ /* @__PURE__ */ jsx32(Text31, { color: actionColor(a), bold: true, children: a.packageName }),
4870
+ a.fromVersion !== "" && a.toVersion !== "" && /* @__PURE__ */ jsxs31(Text31, { color: COLORS.textSecondary, children: [
4684
4871
  " ",
4685
4872
  a.fromVersion,
4686
4873
  " \u2192 ",
4687
4874
  a.toVersion
4688
4875
  ] }),
4689
- a.fromVersion === "" && a.toVersion !== "" && /* @__PURE__ */ jsxs30(Text30, { color: COLORS.textSecondary, children: [
4876
+ a.fromVersion === "" && a.toVersion !== "" && /* @__PURE__ */ jsxs31(Text31, { color: COLORS.textSecondary, children: [
4690
4877
  " install ",
4691
4878
  a.toVersion
4692
4879
  ] }),
4693
- a.fromVersion !== "" && a.toVersion === "" && /* @__PURE__ */ jsx31(Text30, { color: COLORS.textSecondary, children: " remove" }),
4694
- /* @__PURE__ */ jsxs30(Text30, { color: COLORS.muted, dimColor: true, children: [
4880
+ a.fromVersion !== "" && a.toVersion === "" && /* @__PURE__ */ jsx32(Text31, { color: COLORS.textSecondary, children: " remove" }),
4881
+ /* @__PURE__ */ jsxs31(Text31, { color: COLORS.muted, dimColor: true, children: [
4695
4882
  " [",
4696
4883
  strategyLabel(a),
4697
4884
  "]"
4698
4885
  ] })
4699
4886
  ] }, a.packageName + a.action)),
4700
- plan.warnings.map((w) => /* @__PURE__ */ jsx31(Box29, { marginTop: SPACING.xs, children: /* @__PURE__ */ jsxs30(Text30, { color: COLORS.warning, children: [
4887
+ plan.warnings.map((w) => /* @__PURE__ */ jsx32(Box30, { marginTop: SPACING.xs, children: /* @__PURE__ */ jsxs31(Text31, { color: COLORS.warning, children: [
4701
4888
  "\u26A0 ",
4702
4889
  w
4703
4890
  ] }) }, w)),
4704
- /* @__PURE__ */ jsx31(Box29, { marginTop: SPACING.xs, children: plan.canExecute ? /* @__PURE__ */ jsxs30(Text30, { color: COLORS.textSecondary, children: [
4891
+ /* @__PURE__ */ jsx32(Box30, { marginTop: SPACING.xs, children: plan.canExecute ? /* @__PURE__ */ jsxs31(Text31, { color: COLORS.textSecondary, children: [
4705
4892
  "enter:",
4706
4893
  t("rollback_confirm", { count: String(executableCount) }),
4707
4894
  " esc:",
4708
4895
  t("hint_back")
4709
- ] }) : /* @__PURE__ */ jsxs30(Text30, { color: COLORS.muted, children: [
4896
+ ] }) : /* @__PURE__ */ jsxs31(Text31, { color: COLORS.muted, children: [
4710
4897
  t("rollback_strategy_unavailable"),
4711
4898
  " esc:",
4712
4899
  t("hint_back")
@@ -4723,14 +4910,14 @@ function RollbackView() {
4723
4910
  const [streamError, setStreamError] = useState13(null);
4724
4911
  const generatorRef = useRef8(null);
4725
4912
  const mountedRef = useRef8(true);
4726
- useEffect15(() => {
4913
+ useEffect16(() => {
4727
4914
  mountedRef.current = true;
4728
4915
  return () => {
4729
4916
  mountedRef.current = false;
4730
4917
  void generatorRef.current?.return(void 0);
4731
4918
  };
4732
4919
  }, []);
4733
- useEffect15(() => {
4920
+ useEffect16(() => {
4734
4921
  void fetchSnapshots(isPro());
4735
4922
  }, []);
4736
4923
  const runRollback = useCallback3(async (p) => {
@@ -4757,7 +4944,7 @@ function RollbackView() {
4757
4944
  }
4758
4945
  }
4759
4946
  }, [isPro]);
4760
- useInput15((input, key) => {
4947
+ useInput16((input, key) => {
4761
4948
  if (phase === "executing") return;
4762
4949
  if (phase === "result") {
4763
4950
  if (key.escape || input === "r") {
@@ -4790,21 +4977,21 @@ function RollbackView() {
4790
4977
  void fetchSnapshots(isPro());
4791
4978
  }
4792
4979
  });
4793
- if (loading) return /* @__PURE__ */ jsx31(Loading, { message: t("rollback_select_snapshot") });
4794
- if (error) return /* @__PURE__ */ jsx31(ErrorMessage, { message: error });
4980
+ if (loading) return /* @__PURE__ */ jsx32(Loading, { message: t("rollback_select_snapshot") });
4981
+ if (error) return /* @__PURE__ */ jsx32(ErrorMessage, { message: error });
4795
4982
  if (phase === "executing") {
4796
- return /* @__PURE__ */ jsx31(Box29, { flexDirection: "column", children: /* @__PURE__ */ jsx31(ProgressLog, { lines: streamLines, isRunning: streamRunning, title: t("rollback_executing") }) });
4983
+ return /* @__PURE__ */ jsx32(Box30, { flexDirection: "column", children: /* @__PURE__ */ jsx32(ProgressLog, { lines: streamLines, isRunning: streamRunning, title: t("rollback_executing") }) });
4797
4984
  }
4798
4985
  if (phase === "result") {
4799
- return /* @__PURE__ */ jsxs30(Box29, { flexDirection: "column", marginTop: SPACING.xs, children: [
4800
- /* @__PURE__ */ jsx31(
4986
+ return /* @__PURE__ */ jsxs31(Box30, { flexDirection: "column", marginTop: SPACING.xs, children: [
4987
+ /* @__PURE__ */ jsx32(
4801
4988
  ResultBanner,
4802
4989
  {
4803
4990
  status: streamError ? "error" : "success",
4804
4991
  message: streamError ? t("rollback_error", { error: streamError }) : t("rollback_success")
4805
4992
  }
4806
4993
  ),
4807
- /* @__PURE__ */ jsx31(Box29, { marginTop: SPACING.xs, children: /* @__PURE__ */ jsxs30(Text30, { color: COLORS.textSecondary, children: [
4994
+ /* @__PURE__ */ jsx32(Box30, { marginTop: SPACING.xs, children: /* @__PURE__ */ jsxs31(Text31, { color: COLORS.textSecondary, children: [
4808
4995
  "r:",
4809
4996
  t("hint_refresh"),
4810
4997
  " esc:",
@@ -4812,18 +4999,18 @@ function RollbackView() {
4812
4999
  ] }) })
4813
5000
  ] });
4814
5001
  }
4815
- return /* @__PURE__ */ jsxs30(Box29, { flexDirection: "column", children: [
4816
- /* @__PURE__ */ jsx31(SectionHeader, { emoji: "\u23EA", title: t("rollback_title"), gradient: GRADIENTS.gold }),
4817
- snapshots.length === 0 && /* @__PURE__ */ jsx31(Box29, { marginTop: SPACING.xs, children: /* @__PURE__ */ jsx31(ResultBanner, { status: "info", message: t("rollback_no_snapshots") }) }),
4818
- phase === "list" && snapshots.length > 0 && /* @__PURE__ */ jsxs30(Box29, { flexDirection: "column", marginTop: SPACING.xs, children: [
4819
- /* @__PURE__ */ jsx31(Text30, { color: COLORS.textSecondary, dimColor: true, children: t("rollback_select_snapshot") }),
4820
- /* @__PURE__ */ jsx31(Box29, { flexDirection: "column", marginTop: SPACING.xs, children: snapshots.map((s, i) => /* @__PURE__ */ jsxs30(SelectableRow, { isCurrent: i === cursor, children: [
4821
- /* @__PURE__ */ jsx31(Text30, { bold: i === cursor, color: i === cursor ? COLORS.text : COLORS.muted, children: s.label ?? t("rollback_snapshot_auto") }),
4822
- /* @__PURE__ */ jsxs30(Text30, { color: COLORS.textSecondary, children: [
5002
+ return /* @__PURE__ */ jsxs31(Box30, { flexDirection: "column", children: [
5003
+ /* @__PURE__ */ jsx32(SectionHeader, { emoji: "\u23EA", title: t("rollback_title"), gradient: GRADIENTS.gold }),
5004
+ snapshots.length === 0 && /* @__PURE__ */ jsx32(Box30, { marginTop: SPACING.xs, children: /* @__PURE__ */ jsx32(ResultBanner, { status: "info", message: t("rollback_no_snapshots") }) }),
5005
+ phase === "list" && snapshots.length > 0 && /* @__PURE__ */ jsxs31(Box30, { flexDirection: "column", marginTop: SPACING.xs, children: [
5006
+ /* @__PURE__ */ jsx32(Text31, { color: COLORS.textSecondary, dimColor: true, children: t("rollback_select_snapshot") }),
5007
+ /* @__PURE__ */ jsx32(Box30, { flexDirection: "column", marginTop: SPACING.xs, children: snapshots.map((s, i) => /* @__PURE__ */ jsxs31(SelectableRow, { isCurrent: i === cursor, children: [
5008
+ /* @__PURE__ */ jsx32(Text31, { bold: i === cursor, color: i === cursor ? COLORS.text : COLORS.muted, children: s.label ?? t("rollback_snapshot_auto") }),
5009
+ /* @__PURE__ */ jsxs31(Text31, { color: COLORS.textSecondary, children: [
4823
5010
  " \u2014 ",
4824
5011
  new Date(s.capturedAt).toLocaleString()
4825
5012
  ] }),
4826
- /* @__PURE__ */ jsxs30(Text30, { color: COLORS.muted, dimColor: true, children: [
5013
+ /* @__PURE__ */ jsxs31(Text31, { color: COLORS.muted, dimColor: true, children: [
4827
5014
  " ",
4828
5015
  "(",
4829
5016
  tp("packages", s.formulae.length + s.casks.length),
@@ -4831,12 +5018,12 @@ function RollbackView() {
4831
5018
  ] })
4832
5019
  ] }, s.capturedAt)) })
4833
5020
  ] }),
4834
- phase === "plan" && /* @__PURE__ */ jsxs30(Box29, { flexDirection: "column", children: [
4835
- planLoading && /* @__PURE__ */ jsx31(Loading, { message: t("rollback_capturing") }),
4836
- planError && /* @__PURE__ */ jsx31(ErrorMessage, { message: planError }),
4837
- plan && !planLoading && /* @__PURE__ */ jsx31(PlanView, { plan })
5021
+ phase === "plan" && /* @__PURE__ */ jsxs31(Box30, { flexDirection: "column", children: [
5022
+ planLoading && /* @__PURE__ */ jsx32(Loading, { message: t("rollback_capturing") }),
5023
+ planError && /* @__PURE__ */ jsx32(ErrorMessage, { message: planError }),
5024
+ plan && !planLoading && /* @__PURE__ */ jsx32(PlanView, { plan })
4838
5025
  ] }),
4839
- phase === "confirm" && plan && /* @__PURE__ */ jsx31(Box29, { marginTop: SPACING.xs, children: /* @__PURE__ */ jsx31(
5026
+ phase === "confirm" && plan && /* @__PURE__ */ jsx32(Box30, { marginTop: SPACING.xs, children: /* @__PURE__ */ jsx32(
4840
5027
  ConfirmDialog,
4841
5028
  {
4842
5029
  message: t("rollback_confirm", {
@@ -4850,47 +5037,47 @@ function RollbackView() {
4850
5037
  }
4851
5038
 
4852
5039
  // src/views/brewfile.tsx
4853
- import { useCallback as useCallback4, useEffect as useEffect16, useRef as useRef9, useState as useState14 } from "react";
4854
- import { Box as Box30, Text as Text31, useInput as useInput16 } from "ink";
5040
+ import { useCallback as useCallback4, useEffect as useEffect17, useRef as useRef9, useState as useState14 } from "react";
5041
+ import { Box as Box31, Text as Text32, useInput as useInput17 } from "ink";
4855
5042
  import { TextInput as TextInput6 } from "@inkjs/ui";
4856
- import { jsx as jsx32, jsxs as jsxs31 } from "react/jsx-runtime";
5043
+ import { jsx as jsx33, jsxs as jsxs32 } from "react/jsx-runtime";
4857
5044
  function DriftScore({ score }) {
4858
5045
  const color = score >= 80 ? COLORS.success : score >= 50 ? COLORS.warning : COLORS.error;
4859
5046
  const bars = Math.round(score / 10);
4860
5047
  const filled = "\u2593".repeat(bars);
4861
5048
  const empty = "\u2591".repeat(10 - bars);
4862
- return /* @__PURE__ */ jsxs31(Box30, { children: [
4863
- /* @__PURE__ */ jsxs31(Text31, { color, children: [
5049
+ return /* @__PURE__ */ jsxs32(Box31, { children: [
5050
+ /* @__PURE__ */ jsxs32(Text32, { color, children: [
4864
5051
  filled,
4865
5052
  empty
4866
5053
  ] }),
4867
- /* @__PURE__ */ jsxs31(Text31, { color, bold: true, children: [
5054
+ /* @__PURE__ */ jsxs32(Text32, { color, bold: true, children: [
4868
5055
  " ",
4869
5056
  score,
4870
5057
  "% "
4871
5058
  ] }),
4872
- /* @__PURE__ */ jsx32(Text31, { color: COLORS.textSecondary, children: t("brewfile_compliant") })
5059
+ /* @__PURE__ */ jsx33(Text32, { color: COLORS.textSecondary, children: t("brewfile_compliant") })
4873
5060
  ] });
4874
5061
  }
4875
5062
  function DriftSummary({ drift }) {
4876
- return /* @__PURE__ */ jsxs31(Box30, { flexDirection: "column", marginTop: SPACING.xs, children: [
4877
- drift.missingPackages.length > 0 && /* @__PURE__ */ jsxs31(Box30, { children: [
4878
- /* @__PURE__ */ jsx32(Text31, { color: COLORS.error, children: "\u25CF " }),
4879
- /* @__PURE__ */ jsx32(Text31, { color: COLORS.error, children: t("brewfile_drift_missing", { count: drift.missingPackages.length }) }),
4880
- /* @__PURE__ */ jsxs31(Text31, { color: COLORS.textSecondary, children: [
5063
+ return /* @__PURE__ */ jsxs32(Box31, { flexDirection: "column", marginTop: SPACING.xs, children: [
5064
+ drift.missingPackages.length > 0 && /* @__PURE__ */ jsxs32(Box31, { children: [
5065
+ /* @__PURE__ */ jsx33(Text32, { color: COLORS.error, children: "\u25CF " }),
5066
+ /* @__PURE__ */ jsx33(Text32, { color: COLORS.error, children: t("brewfile_drift_missing", { count: drift.missingPackages.length }) }),
5067
+ /* @__PURE__ */ jsxs32(Text32, { color: COLORS.textSecondary, children: [
4881
5068
  ": " + drift.missingPackages.slice(0, 3).join(", "),
4882
5069
  drift.missingPackages.length > 3 ? "..." : ""
4883
5070
  ] })
4884
5071
  ] }),
4885
- drift.extraPackages.length > 0 && /* @__PURE__ */ jsxs31(Box30, { children: [
4886
- /* @__PURE__ */ jsx32(Text31, { color: COLORS.warning, children: "\u25CF " }),
4887
- /* @__PURE__ */ jsx32(Text31, { color: COLORS.warning, children: t("brewfile_drift_extra", { count: drift.extraPackages.length }) })
5072
+ drift.extraPackages.length > 0 && /* @__PURE__ */ jsxs32(Box31, { children: [
5073
+ /* @__PURE__ */ jsx33(Text32, { color: COLORS.warning, children: "\u25CF " }),
5074
+ /* @__PURE__ */ jsx33(Text32, { color: COLORS.warning, children: t("brewfile_drift_extra", { count: drift.extraPackages.length }) })
4888
5075
  ] }),
4889
- drift.wrongVersions.length > 0 && /* @__PURE__ */ jsxs31(Box30, { children: [
4890
- /* @__PURE__ */ jsx32(Text31, { color: COLORS.info, children: "\u25CF " }),
4891
- /* @__PURE__ */ jsx32(Text31, { color: COLORS.info, children: t("brewfile_drift_wrong", { count: drift.wrongVersions.length }) })
5076
+ drift.wrongVersions.length > 0 && /* @__PURE__ */ jsxs32(Box31, { children: [
5077
+ /* @__PURE__ */ jsx33(Text32, { color: COLORS.info, children: "\u25CF " }),
5078
+ /* @__PURE__ */ jsx33(Text32, { color: COLORS.info, children: t("brewfile_drift_wrong", { count: drift.wrongVersions.length }) })
4892
5079
  ] }),
4893
- drift.missingPackages.length === 0 && drift.extraPackages.length === 0 && drift.wrongVersions.length === 0 && /* @__PURE__ */ jsx32(ResultBanner, { status: "success", message: t("brewfile_in_sync") })
5080
+ drift.missingPackages.length === 0 && drift.extraPackages.length === 0 && drift.wrongVersions.length === 0 && /* @__PURE__ */ jsx33(ResultBanner, { status: "success", message: t("brewfile_in_sync") })
4894
5081
  ] });
4895
5082
  }
4896
5083
  function BrewfileView() {
@@ -4903,7 +5090,7 @@ function BrewfileView() {
4903
5090
  const [resultMessage, setResultMessage] = useState14("");
4904
5091
  const generatorRef = useRef9(null);
4905
5092
  const mountedRef = useRef9(true);
4906
- useEffect16(() => {
5093
+ useEffect17(() => {
4907
5094
  mountedRef.current = true;
4908
5095
  void load();
4909
5096
  return () => {
@@ -4941,7 +5128,7 @@ function BrewfileView() {
4941
5128
  }
4942
5129
  }
4943
5130
  }, [schema, isPro]);
4944
- useInput16((input, key) => {
5131
+ useInput17((input, key) => {
4945
5132
  if (phase === "reconciling") return;
4946
5133
  if (phase === "confirming-reconcile") return;
4947
5134
  if (phase === "result") {
@@ -4970,10 +5157,10 @@ function BrewfileView() {
4970
5157
  if (key.escape) {
4971
5158
  }
4972
5159
  });
4973
- if (loading) return /* @__PURE__ */ jsx32(Loading, { message: t("loading_default") });
4974
- if (error) return /* @__PURE__ */ jsx32(ErrorMessage, { message: error });
5160
+ if (loading) return /* @__PURE__ */ jsx33(Loading, { message: t("loading_default") });
5161
+ if (error) return /* @__PURE__ */ jsx33(ErrorMessage, { message: error });
4975
5162
  if (phase === "confirming-reconcile" && drift) {
4976
- return /* @__PURE__ */ jsx32(
5163
+ return /* @__PURE__ */ jsx33(
4977
5164
  ConfirmDialog,
4978
5165
  {
4979
5166
  message: t("confirm_brewfile_reconcile", {
@@ -4990,14 +5177,14 @@ function BrewfileView() {
4990
5177
  );
4991
5178
  }
4992
5179
  if (phase === "creating") {
4993
- return /* @__PURE__ */ jsxs31(Box30, { flexDirection: "column", marginTop: SPACING.xs, children: [
4994
- /* @__PURE__ */ jsx32(SectionHeader, { emoji: "\u{1F4E6}", title: t("brewfile_title"), gradient: GRADIENTS.ocean }),
4995
- /* @__PURE__ */ jsxs31(Box30, { marginTop: SPACING.xs, children: [
4996
- /* @__PURE__ */ jsxs31(Text31, { color: COLORS.textSecondary, children: [
5180
+ return /* @__PURE__ */ jsxs32(Box31, { flexDirection: "column", marginTop: SPACING.xs, children: [
5181
+ /* @__PURE__ */ jsx33(SectionHeader, { emoji: "\u{1F4E6}", title: t("brewfile_title"), gradient: GRADIENTS.ocean }),
5182
+ /* @__PURE__ */ jsxs32(Box31, { marginTop: SPACING.xs, children: [
5183
+ /* @__PURE__ */ jsxs32(Text32, { color: COLORS.textSecondary, children: [
4997
5184
  t("brewfile_create_name"),
4998
5185
  " "
4999
5186
  ] }),
5000
- /* @__PURE__ */ jsx32(
5187
+ /* @__PURE__ */ jsx33(
5001
5188
  TextInput6,
5002
5189
  {
5003
5190
  defaultValue: "My Environment",
@@ -5013,7 +5200,7 @@ function BrewfileView() {
5013
5200
  ] });
5014
5201
  }
5015
5202
  if (phase === "reconciling") {
5016
- return /* @__PURE__ */ jsx32(Box30, { flexDirection: "column", children: /* @__PURE__ */ jsx32(
5203
+ return /* @__PURE__ */ jsx33(Box31, { flexDirection: "column", children: /* @__PURE__ */ jsx33(
5017
5204
  ProgressLog,
5018
5205
  {
5019
5206
  lines: streamLines,
@@ -5023,15 +5210,15 @@ function BrewfileView() {
5023
5210
  ) });
5024
5211
  }
5025
5212
  if (phase === "result") {
5026
- return /* @__PURE__ */ jsxs31(Box30, { flexDirection: "column", marginTop: SPACING.xs, children: [
5027
- /* @__PURE__ */ jsx32(
5213
+ return /* @__PURE__ */ jsxs32(Box31, { flexDirection: "column", marginTop: SPACING.xs, children: [
5214
+ /* @__PURE__ */ jsx33(
5028
5215
  ResultBanner,
5029
5216
  {
5030
5217
  status: streamError ? "error" : "success",
5031
5218
  message: resultMessage
5032
5219
  }
5033
5220
  ),
5034
- /* @__PURE__ */ jsx32(Box30, { marginTop: SPACING.xs, children: /* @__PURE__ */ jsxs31(Text31, { color: COLORS.textSecondary, children: [
5221
+ /* @__PURE__ */ jsx33(Box31, { marginTop: SPACING.xs, children: /* @__PURE__ */ jsxs32(Text32, { color: COLORS.textSecondary, children: [
5035
5222
  "r:",
5036
5223
  t("hint_refresh"),
5037
5224
  " esc:",
@@ -5039,34 +5226,34 @@ function BrewfileView() {
5039
5226
  ] }) })
5040
5227
  ] });
5041
5228
  }
5042
- return /* @__PURE__ */ jsxs31(Box30, { flexDirection: "column", children: [
5043
- /* @__PURE__ */ jsx32(SectionHeader, { emoji: "\u{1F4E6}", title: t("brewfile_title"), gradient: GRADIENTS.ocean }),
5044
- schema === null ? /* @__PURE__ */ jsxs31(Box30, { marginTop: SPACING.xs, flexDirection: "column", children: [
5045
- /* @__PURE__ */ jsx32(ResultBanner, { status: "info", message: t("brewfile_no_brewfile") }),
5046
- /* @__PURE__ */ jsx32(Box30, { marginTop: SPACING.xs, children: /* @__PURE__ */ jsxs31(Text31, { color: COLORS.textSecondary, children: [
5229
+ return /* @__PURE__ */ jsxs32(Box31, { flexDirection: "column", children: [
5230
+ /* @__PURE__ */ jsx33(SectionHeader, { emoji: "\u{1F4E6}", title: t("brewfile_title"), gradient: GRADIENTS.ocean }),
5231
+ schema === null ? /* @__PURE__ */ jsxs32(Box31, { marginTop: SPACING.xs, flexDirection: "column", children: [
5232
+ /* @__PURE__ */ jsx33(ResultBanner, { status: "info", message: t("brewfile_no_brewfile") }),
5233
+ /* @__PURE__ */ jsx33(Box31, { marginTop: SPACING.xs, children: /* @__PURE__ */ jsxs32(Text32, { color: COLORS.textSecondary, children: [
5047
5234
  "n:",
5048
5235
  t("hint_new")
5049
5236
  ] }) })
5050
- ] }) : /* @__PURE__ */ jsxs31(Box30, { flexDirection: "column", marginTop: SPACING.xs, children: [
5051
- /* @__PURE__ */ jsxs31(Box30, { gap: SPACING.sm, children: [
5052
- /* @__PURE__ */ jsx32(Text31, { color: COLORS.text, bold: true, children: schema.meta.name }),
5053
- schema.meta.description && /* @__PURE__ */ jsx32(Text31, { color: COLORS.textSecondary, children: schema.meta.description }),
5054
- schema.strictMode && /* @__PURE__ */ jsxs31(Text31, { color: COLORS.warning, children: [
5237
+ ] }) : /* @__PURE__ */ jsxs32(Box31, { flexDirection: "column", marginTop: SPACING.xs, children: [
5238
+ /* @__PURE__ */ jsxs32(Box31, { gap: SPACING.sm, children: [
5239
+ /* @__PURE__ */ jsx33(Text32, { color: COLORS.text, bold: true, children: schema.meta.name }),
5240
+ schema.meta.description && /* @__PURE__ */ jsx33(Text32, { color: COLORS.textSecondary, children: schema.meta.description }),
5241
+ schema.strictMode && /* @__PURE__ */ jsxs32(Text32, { color: COLORS.warning, children: [
5055
5242
  "[",
5056
5243
  t("brewfile_strict_mode"),
5057
5244
  "]"
5058
5245
  ] })
5059
5246
  ] }),
5060
- /* @__PURE__ */ jsxs31(Box30, { gap: SPACING.md, marginTop: SPACING.xs, children: [
5061
- /* @__PURE__ */ jsx32(Text31, { color: COLORS.sky, children: t("brewfile_formulae_count", { count: schema.formulae.length }) }),
5062
- /* @__PURE__ */ jsx32(Text31, { color: COLORS.teal, children: t("brewfile_casks_count", { count: schema.casks.length }) })
5247
+ /* @__PURE__ */ jsxs32(Box31, { gap: SPACING.md, marginTop: SPACING.xs, children: [
5248
+ /* @__PURE__ */ jsx33(Text32, { color: COLORS.sky, children: t("brewfile_formulae_count", { count: schema.formulae.length }) }),
5249
+ /* @__PURE__ */ jsx33(Text32, { color: COLORS.teal, children: t("brewfile_casks_count", { count: schema.casks.length }) })
5063
5250
  ] }),
5064
- driftLoading && /* @__PURE__ */ jsx32(Box30, { marginTop: SPACING.xs, children: /* @__PURE__ */ jsx32(Text31, { color: COLORS.muted, children: t("brewfile_computing_drift") }) }),
5065
- drift && !driftLoading && /* @__PURE__ */ jsxs31(Box30, { flexDirection: "column", marginTop: SPACING.xs, children: [
5066
- /* @__PURE__ */ jsx32(DriftScore, { score: drift.score }),
5067
- /* @__PURE__ */ jsx32(DriftSummary, { drift })
5251
+ driftLoading && /* @__PURE__ */ jsx33(Box31, { marginTop: SPACING.xs, children: /* @__PURE__ */ jsx33(Text32, { color: COLORS.muted, children: t("brewfile_computing_drift") }) }),
5252
+ drift && !driftLoading && /* @__PURE__ */ jsxs32(Box31, { flexDirection: "column", marginTop: SPACING.xs, children: [
5253
+ /* @__PURE__ */ jsx33(DriftScore, { score: drift.score }),
5254
+ /* @__PURE__ */ jsx33(DriftSummary, { drift })
5068
5255
  ] }),
5069
- /* @__PURE__ */ jsx32(Box30, { marginTop: SPACING.xs, children: /* @__PURE__ */ jsxs31(Text31, { color: COLORS.textSecondary, children: [
5256
+ /* @__PURE__ */ jsx33(Box31, { marginTop: SPACING.xs, children: /* @__PURE__ */ jsxs32(Text32, { color: COLORS.textSecondary, children: [
5070
5257
  "r:",
5071
5258
  t("hint_refresh"),
5072
5259
  drift && (drift.missingPackages.length > 0 || drift.wrongVersions.length > 0) ? ` c:${t("hint_reconcile")}` : "",
@@ -5079,9 +5266,9 @@ function BrewfileView() {
5079
5266
  }
5080
5267
 
5081
5268
  // src/views/sync.tsx
5082
- import { useCallback as useCallback5, useEffect as useEffect17, useState as useState15 } from "react";
5083
- import { Box as Box31, Text as Text32, useInput as useInput17 } from "ink";
5084
- import { Fragment as Fragment6, jsx as jsx33, jsxs as jsxs32 } from "react/jsx-runtime";
5269
+ import { useCallback as useCallback5, useEffect as useEffect18, useState as useState15 } from "react";
5270
+ import { Box as Box32, Text as Text33, useInput as useInput18 } from "ink";
5271
+ import { Fragment as Fragment6, jsx as jsx34, jsxs as jsxs33 } from "react/jsx-runtime";
5085
5272
  function OverviewSection({
5086
5273
  config,
5087
5274
  lastResult,
@@ -5091,34 +5278,34 @@ function OverviewSection({
5091
5278
  }) {
5092
5279
  const hasConflicts = conflicts.length > 0;
5093
5280
  const showComplianceHint = !hasConflicts && !!lastResult?.success;
5094
- return /* @__PURE__ */ jsxs32(Box31, { flexDirection: "column", marginTop: SPACING.xs, children: [
5095
- config ? /* @__PURE__ */ jsxs32(Fragment6, { children: [
5096
- /* @__PURE__ */ jsx33(Box31, { marginBottom: SPACING.xs, children: /* @__PURE__ */ jsx33(Text32, { color: COLORS.textSecondary, children: t("sync_machine", { name: config.machineName }) }) }),
5097
- config.lastSync && /* @__PURE__ */ jsx33(Box31, { marginBottom: SPACING.xs, children: /* @__PURE__ */ jsx33(Text32, { color: COLORS.textSecondary, children: t("sync_last_sync", { date: new Date(config.lastSync).toLocaleString() }) }) }),
5098
- hasConflicts ? /* @__PURE__ */ jsx33(
5281
+ return /* @__PURE__ */ jsxs33(Box32, { flexDirection: "column", marginTop: SPACING.xs, children: [
5282
+ config ? /* @__PURE__ */ jsxs33(Fragment6, { children: [
5283
+ /* @__PURE__ */ jsx34(Box32, { marginBottom: SPACING.xs, children: /* @__PURE__ */ jsx34(Text33, { color: COLORS.textSecondary, children: t("sync_machine", { name: config.machineName }) }) }),
5284
+ config.lastSync && /* @__PURE__ */ jsx34(Box32, { marginBottom: SPACING.xs, children: /* @__PURE__ */ jsx34(Text33, { color: COLORS.textSecondary, children: t("sync_last_sync", { date: new Date(config.lastSync).toLocaleString() }) }) }),
5285
+ hasConflicts ? /* @__PURE__ */ jsx34(
5099
5286
  ResultBanner,
5100
5287
  {
5101
5288
  status: "error",
5102
5289
  message: t("sync_status_conflict", { count: String(conflicts.length) })
5103
5290
  }
5104
- ) : lastResult?.success ? /* @__PURE__ */ jsx33(ResultBanner, { status: "success", message: t("sync_status_ok") }) : null
5105
- ] }) : /* @__PURE__ */ jsx33(Box31, { marginBottom: SPACING.xs, children: /* @__PURE__ */ jsx33(Text32, { color: COLORS.textSecondary, children: t("sync_disabled") }) }),
5106
- /* @__PURE__ */ jsx33(Box31, { marginTop: SPACING.xs, children: /* @__PURE__ */ jsxs32(Text32, { color: COLORS.textSecondary, children: [
5291
+ ) : lastResult?.success ? /* @__PURE__ */ jsx34(ResultBanner, { status: "success", message: t("sync_status_ok") }) : null
5292
+ ] }) : /* @__PURE__ */ jsx34(Box32, { marginBottom: SPACING.xs, children: /* @__PURE__ */ jsx34(Text33, { color: COLORS.textSecondary, children: t("sync_disabled") }) }),
5293
+ /* @__PURE__ */ jsx34(Box32, { marginTop: SPACING.xs, children: /* @__PURE__ */ jsxs33(Text33, { color: COLORS.textSecondary, children: [
5107
5294
  "s",
5108
- /* @__PURE__ */ jsxs32(Text32, { color: COLORS.gold, children: [
5295
+ /* @__PURE__ */ jsxs33(Text33, { color: COLORS.gold, children: [
5109
5296
  ":",
5110
5297
  t("hint_sync")
5111
5298
  ] }),
5112
- hasConflicts && /* @__PURE__ */ jsxs32(Fragment6, { children: [
5299
+ hasConflicts && /* @__PURE__ */ jsxs33(Fragment6, { children: [
5113
5300
  " c",
5114
- /* @__PURE__ */ jsxs32(Text32, { color: COLORS.gold, children: [
5301
+ /* @__PURE__ */ jsxs33(Text33, { color: COLORS.gold, children: [
5115
5302
  ":",
5116
5303
  t("hint_conflict")
5117
5304
  ] })
5118
5305
  ] }),
5119
- showComplianceHint && /* @__PURE__ */ jsxs32(Fragment6, { children: [
5306
+ showComplianceHint && /* @__PURE__ */ jsxs33(Fragment6, { children: [
5120
5307
  " c",
5121
- /* @__PURE__ */ jsxs32(Text32, { color: COLORS.gold, children: [
5308
+ /* @__PURE__ */ jsxs33(Text33, { color: COLORS.gold, children: [
5122
5309
  ":",
5123
5310
  t("hint_check_compliance")
5124
5311
  ] })
@@ -5130,22 +5317,22 @@ function ConflictsList({
5130
5317
  entries,
5131
5318
  cursor
5132
5319
  }) {
5133
- return /* @__PURE__ */ jsxs32(Box31, { flexDirection: "column", marginTop: SPACING.xs, children: [
5320
+ return /* @__PURE__ */ jsxs33(Box32, { flexDirection: "column", marginTop: SPACING.xs, children: [
5134
5321
  entries.map((entry, i) => {
5135
5322
  const { conflict, resolution } = entry;
5136
5323
  const isActive = i === cursor;
5137
- return /* @__PURE__ */ jsxs32(Box31, { flexDirection: "column", marginBottom: SPACING.xs, children: [
5138
- /* @__PURE__ */ jsxs32(SelectableRow, { isCurrent: isActive, children: [
5139
- /* @__PURE__ */ jsx33(Text32, { bold: true, color: isActive ? COLORS.text : COLORS.textSecondary, children: t("sync_conflict_title", { package: conflict.packageName }) }),
5140
- /* @__PURE__ */ jsxs32(Text32, { color: COLORS.muted, children: [
5324
+ return /* @__PURE__ */ jsxs33(Box32, { flexDirection: "column", marginBottom: SPACING.xs, children: [
5325
+ /* @__PURE__ */ jsxs33(SelectableRow, { isCurrent: isActive, children: [
5326
+ /* @__PURE__ */ jsx34(Text33, { bold: true, color: isActive ? COLORS.text : COLORS.textSecondary, children: t("sync_conflict_title", { package: conflict.packageName }) }),
5327
+ /* @__PURE__ */ jsxs33(Text33, { color: COLORS.muted, children: [
5141
5328
  " (",
5142
5329
  conflict.packageType,
5143
5330
  ")"
5144
5331
  ] })
5145
5332
  ] }),
5146
- /* @__PURE__ */ jsxs32(Box31, { marginLeft: SPACING.sm, flexDirection: "column", children: [
5147
- /* @__PURE__ */ jsxs32(
5148
- Text32,
5333
+ /* @__PURE__ */ jsxs33(Box32, { marginLeft: SPACING.sm, flexDirection: "column", children: [
5334
+ /* @__PURE__ */ jsxs33(
5335
+ Text33,
5149
5336
  {
5150
5337
  color: resolution === "use-local" ? COLORS.success : COLORS.textSecondary,
5151
5338
  children: [
@@ -5155,8 +5342,8 @@ function ConflictsList({
5155
5342
  ]
5156
5343
  }
5157
5344
  ),
5158
- /* @__PURE__ */ jsxs32(
5159
- Text32,
5345
+ /* @__PURE__ */ jsxs33(
5346
+ Text33,
5160
5347
  {
5161
5348
  color: resolution === "use-remote" ? COLORS.success : COLORS.textSecondary,
5162
5349
  children: [
@@ -5169,7 +5356,7 @@ function ConflictsList({
5169
5356
  ] })
5170
5357
  ] }, `${conflict.packageName}-${conflict.remoteMachine}`);
5171
5358
  }),
5172
- /* @__PURE__ */ jsx33(Box31, { marginTop: SPACING.xs, children: /* @__PURE__ */ jsxs32(Text32, { color: COLORS.textSecondary, children: [
5359
+ /* @__PURE__ */ jsx34(Box32, { marginTop: SPACING.xs, children: /* @__PURE__ */ jsxs33(Text33, { color: COLORS.textSecondary, children: [
5173
5360
  "j/k:",
5174
5361
  t("hint_navigate"),
5175
5362
  " l:",
@@ -5191,10 +5378,10 @@ function SyncView() {
5191
5378
  const [syncError, setSyncError] = useState15(null);
5192
5379
  const [conflictEntries, setConflictEntries] = useState15([]);
5193
5380
  const [cursor, setCursor] = useState15(0);
5194
- useEffect17(() => {
5381
+ useEffect18(() => {
5195
5382
  void initialize(isPro());
5196
5383
  }, []);
5197
- useEffect17(() => {
5384
+ useEffect18(() => {
5198
5385
  if (conflicts.length > 0) {
5199
5386
  setConflictEntries(
5200
5387
  conflicts.map((c) => ({ conflict: c, resolution: "pending" }))
@@ -5225,7 +5412,7 @@ function SyncView() {
5225
5412
  await resolveConflicts(resolutions);
5226
5413
  setPhase("result");
5227
5414
  }, [conflictEntries, resolveConflicts]);
5228
- useInput17((input, key) => {
5415
+ useInput18((input, key) => {
5229
5416
  if (phase === "syncing") return;
5230
5417
  if (phase === "confirming-sync" || phase === "confirming-apply") return;
5231
5418
  if (phase === "result") {
@@ -5286,7 +5473,7 @@ function SyncView() {
5286
5473
  }
5287
5474
  });
5288
5475
  if (phase === "confirming-sync") {
5289
- return /* @__PURE__ */ jsx33(
5476
+ return /* @__PURE__ */ jsx34(
5290
5477
  ConfirmDialog,
5291
5478
  {
5292
5479
  message: t("confirm_sync_now"),
@@ -5300,7 +5487,7 @@ function SyncView() {
5300
5487
  );
5301
5488
  }
5302
5489
  if (phase === "confirming-apply") {
5303
- return /* @__PURE__ */ jsx33(
5490
+ return /* @__PURE__ */ jsx34(
5304
5491
  ConfirmDialog,
5305
5492
  {
5306
5493
  message: t("confirm_sync_apply", { count: String(conflictEntries.length) }),
@@ -5314,20 +5501,20 @@ function SyncView() {
5314
5501
  );
5315
5502
  }
5316
5503
  if (phase === "syncing" || loading) {
5317
- return /* @__PURE__ */ jsx33(Loading, { message: t("sync_syncing") });
5504
+ return /* @__PURE__ */ jsx34(Loading, { message: t("sync_syncing") });
5318
5505
  }
5319
5506
  if (phase === "result") {
5320
5507
  const isError = !!(syncError ?? error);
5321
- return /* @__PURE__ */ jsxs32(Box31, { flexDirection: "column", marginTop: SPACING.xs, children: [
5322
- /* @__PURE__ */ jsx33(SectionHeader, { emoji: "\u{1F504}", title: t("sync_title"), gradient: GRADIENTS.gold }),
5323
- /* @__PURE__ */ jsx33(Box31, { marginTop: SPACING.xs, children: /* @__PURE__ */ jsx33(
5508
+ return /* @__PURE__ */ jsxs33(Box32, { flexDirection: "column", marginTop: SPACING.xs, children: [
5509
+ /* @__PURE__ */ jsx34(SectionHeader, { emoji: "\u{1F504}", title: t("sync_title"), gradient: GRADIENTS.gold }),
5510
+ /* @__PURE__ */ jsx34(Box32, { marginTop: SPACING.xs, children: /* @__PURE__ */ jsx34(
5324
5511
  ResultBanner,
5325
5512
  {
5326
5513
  status: isError ? "error" : "success",
5327
5514
  message: isError ? t("sync_error", { error: syncError ?? error ?? "" }) : t("sync_success")
5328
5515
  }
5329
5516
  ) }),
5330
- /* @__PURE__ */ jsx33(Box31, { marginTop: SPACING.xs, children: /* @__PURE__ */ jsxs32(Text32, { color: COLORS.textSecondary, children: [
5517
+ /* @__PURE__ */ jsx34(Box32, { marginTop: SPACING.xs, children: /* @__PURE__ */ jsxs33(Text33, { color: COLORS.textSecondary, children: [
5331
5518
  "r:",
5332
5519
  t("hint_refresh"),
5333
5520
  " esc:",
@@ -5335,10 +5522,10 @@ function SyncView() {
5335
5522
  ] }) })
5336
5523
  ] });
5337
5524
  }
5338
- return /* @__PURE__ */ jsxs32(Box31, { flexDirection: "column", children: [
5339
- /* @__PURE__ */ jsx33(SectionHeader, { emoji: "\u{1F504}", title: t("sync_title"), gradient: GRADIENTS.gold }),
5340
- error && phase === "overview" && /* @__PURE__ */ jsx33(Box31, { marginTop: SPACING.xs, children: /* @__PURE__ */ jsx33(ResultBanner, { status: "error", message: t("sync_error", { error }) }) }),
5341
- phase === "overview" && /* @__PURE__ */ jsx33(
5525
+ return /* @__PURE__ */ jsxs33(Box32, { flexDirection: "column", children: [
5526
+ /* @__PURE__ */ jsx34(SectionHeader, { emoji: "\u{1F504}", title: t("sync_title"), gradient: GRADIENTS.gold }),
5527
+ error && phase === "overview" && /* @__PURE__ */ jsx34(Box32, { marginTop: SPACING.xs, children: /* @__PURE__ */ jsx34(ResultBanner, { status: "error", message: t("sync_error", { error }) }) }),
5528
+ phase === "overview" && /* @__PURE__ */ jsx34(
5342
5529
  OverviewSection,
5343
5530
  {
5344
5531
  config,
@@ -5351,16 +5538,16 @@ function SyncView() {
5351
5538
  }
5352
5539
  }
5353
5540
  ),
5354
- phase === "conflicts" && /* @__PURE__ */ jsxs32(Box31, { flexDirection: "column", children: [
5355
- /* @__PURE__ */ jsx33(SectionHeader, { emoji: "\u26A0", title: t("sync_status_conflict", { count: String(conflictEntries.length) }), gradient: GRADIENTS.gold }),
5356
- /* @__PURE__ */ jsx33(ConflictsList, { entries: conflictEntries, cursor })
5541
+ phase === "conflicts" && /* @__PURE__ */ jsxs33(Box32, { flexDirection: "column", children: [
5542
+ /* @__PURE__ */ jsx34(SectionHeader, { emoji: "\u26A0", title: t("sync_status_conflict", { count: String(conflictEntries.length) }), gradient: GRADIENTS.gold }),
5543
+ /* @__PURE__ */ jsx34(ConflictsList, { entries: conflictEntries, cursor })
5357
5544
  ] })
5358
5545
  ] });
5359
5546
  }
5360
5547
 
5361
5548
  // src/views/compliance.tsx
5362
- import { useCallback as useCallback6, useEffect as useEffect18, useRef as useRef10, useState as useState16 } from "react";
5363
- import { Box as Box32, Text as Text33, useInput as useInput18 } from "ink";
5549
+ import { useCallback as useCallback6, useEffect as useEffect19, useRef as useRef10, useState as useState16 } from "react";
5550
+ import { Box as Box33, Text as Text34, useInput as useInput19 } from "ink";
5364
5551
  import { TextInput as TextInput7 } from "@inkjs/ui";
5365
5552
 
5366
5553
  // src/lib/compliance/compliance-remediator.ts
@@ -5405,27 +5592,27 @@ async function* remediateViolations(violations, isPro) {
5405
5592
 
5406
5593
  // src/views/compliance.tsx
5407
5594
  import { join as join4 } from "path";
5408
- import { jsx as jsx34, jsxs as jsxs33 } from "react/jsx-runtime";
5595
+ import { jsx as jsx35, jsxs as jsxs34 } from "react/jsx-runtime";
5409
5596
  function ComplianceScore({ report }) {
5410
5597
  const color = report.score >= 80 ? COLORS.success : report.score >= 50 ? COLORS.warning : COLORS.error;
5411
5598
  const bars = Math.round(report.score / 10);
5412
- return /* @__PURE__ */ jsxs33(Box32, { flexDirection: "column", marginBottom: SPACING.xs, children: [
5413
- /* @__PURE__ */ jsxs33(Box32, { children: [
5414
- /* @__PURE__ */ jsxs33(Text33, { color, children: [
5599
+ return /* @__PURE__ */ jsxs34(Box33, { flexDirection: "column", marginBottom: SPACING.xs, children: [
5600
+ /* @__PURE__ */ jsxs34(Box33, { children: [
5601
+ /* @__PURE__ */ jsxs34(Text34, { color, children: [
5415
5602
  "\u2593".repeat(bars),
5416
5603
  "\u2591".repeat(10 - bars)
5417
5604
  ] }),
5418
- /* @__PURE__ */ jsxs33(Text33, { color, bold: true, children: [
5605
+ /* @__PURE__ */ jsxs34(Text34, { color, bold: true, children: [
5419
5606
  " ",
5420
5607
  report.score,
5421
5608
  "%"
5422
5609
  ] }),
5423
- /* @__PURE__ */ jsxs33(Text33, { color: COLORS.textSecondary, children: [
5610
+ /* @__PURE__ */ jsxs34(Text34, { color: COLORS.textSecondary, children: [
5424
5611
  " ",
5425
5612
  t("compliance_score", { score: String(report.score) })
5426
5613
  ] })
5427
5614
  ] }),
5428
- /* @__PURE__ */ jsxs33(Text33, { color: COLORS.muted, dimColor: true, children: [
5615
+ /* @__PURE__ */ jsxs34(Text34, { color: COLORS.muted, dimColor: true, children: [
5429
5616
  t("compliance_policy_name", { name: report.policyName }),
5430
5617
  " \xB7 ",
5431
5618
  t("compliance_machine", { name: report.machineName })
@@ -5435,31 +5622,31 @@ function ComplianceScore({ report }) {
5435
5622
  function ViolationItem({ violation }) {
5436
5623
  const color = violation.severity === "error" ? COLORS.error : COLORS.warning;
5437
5624
  const prefix = violation.severity === "error" ? "\u2717" : "\u26A0";
5438
- return /* @__PURE__ */ jsxs33(Box32, { marginBottom: SPACING.none, children: [
5439
- /* @__PURE__ */ jsxs33(Text33, { color, children: [
5625
+ return /* @__PURE__ */ jsxs34(Box33, { marginBottom: SPACING.none, children: [
5626
+ /* @__PURE__ */ jsxs34(Text34, { color, children: [
5440
5627
  prefix,
5441
5628
  " "
5442
5629
  ] }),
5443
- /* @__PURE__ */ jsx34(Text33, { color, children: violation.detail })
5630
+ /* @__PURE__ */ jsx35(Text34, { color, children: violation.detail })
5444
5631
  ] });
5445
5632
  }
5446
5633
  function ViolationList({ violations }) {
5447
5634
  const errors = violations.filter((v) => v.severity === "error");
5448
5635
  const warnings = violations.filter((v) => v.severity === "warning");
5449
- return /* @__PURE__ */ jsxs33(Box32, { flexDirection: "column", marginTop: SPACING.xs, children: [
5450
- errors.length > 0 && /* @__PURE__ */ jsxs33(Box32, { flexDirection: "column", marginBottom: SPACING.xs, children: [
5451
- /* @__PURE__ */ jsxs33(Text33, { color: COLORS.error, bold: true, children: [
5636
+ return /* @__PURE__ */ jsxs34(Box33, { flexDirection: "column", marginTop: SPACING.xs, children: [
5637
+ errors.length > 0 && /* @__PURE__ */ jsxs34(Box33, { flexDirection: "column", marginBottom: SPACING.xs, children: [
5638
+ /* @__PURE__ */ jsxs34(Text34, { color: COLORS.error, bold: true, children: [
5452
5639
  t("compliance_violations", { count: String(errors.length) }),
5453
5640
  " (errors)"
5454
5641
  ] }),
5455
- errors.map((v) => /* @__PURE__ */ jsx34(ViolationItem, { violation: v }, `${v.type}-${v.packageName}`))
5642
+ errors.map((v) => /* @__PURE__ */ jsx35(ViolationItem, { violation: v }, `${v.type}-${v.packageName}`))
5456
5643
  ] }),
5457
- warnings.length > 0 && /* @__PURE__ */ jsxs33(Box32, { flexDirection: "column", children: [
5458
- /* @__PURE__ */ jsxs33(Text33, { color: COLORS.warning, bold: true, children: [
5644
+ warnings.length > 0 && /* @__PURE__ */ jsxs34(Box33, { flexDirection: "column", children: [
5645
+ /* @__PURE__ */ jsxs34(Text34, { color: COLORS.warning, bold: true, children: [
5459
5646
  t("compliance_violations", { count: String(warnings.length) }),
5460
5647
  " (warnings)"
5461
5648
  ] }),
5462
- warnings.map((v) => /* @__PURE__ */ jsx34(ViolationItem, { violation: v }, `${v.type}-${v.packageName}`))
5649
+ warnings.map((v) => /* @__PURE__ */ jsx35(ViolationItem, { violation: v }, `${v.type}-${v.packageName}`))
5463
5650
  ] })
5464
5651
  ] });
5465
5652
  }
@@ -5472,7 +5659,7 @@ function ComplianceView() {
5472
5659
  const [streamRunning, setStreamRunning] = useState16(false);
5473
5660
  const generatorRef = useRef10(null);
5474
5661
  const mountedRef = useRef10(true);
5475
- useEffect18(() => {
5662
+ useEffect19(() => {
5476
5663
  mountedRef.current = true;
5477
5664
  return () => {
5478
5665
  mountedRef.current = false;
@@ -5548,7 +5735,7 @@ function ComplianceView() {
5548
5735
  }
5549
5736
  }
5550
5737
  }, [report, isPro, runCheck]);
5551
- useInput18((input, key) => {
5738
+ useInput19((input, key) => {
5552
5739
  if (phase === "remediating" || phase === "importing") return;
5553
5740
  if (phase === "confirming-remediate") return;
5554
5741
  if (phase === "result") {
@@ -5584,7 +5771,7 @@ function ComplianceView() {
5584
5771
  const actionable = report.violations.filter(
5585
5772
  (v) => v.type === "missing" || v.type === "wrong-version"
5586
5773
  );
5587
- return /* @__PURE__ */ jsx34(
5774
+ return /* @__PURE__ */ jsx35(
5588
5775
  ConfirmDialog,
5589
5776
  {
5590
5777
  message: t("confirm_compliance_remediate", { count: String(actionable.length) }),
@@ -5599,24 +5786,24 @@ function ComplianceView() {
5599
5786
  }
5600
5787
  if (phase === "remediating" || loading && phase !== "importing") {
5601
5788
  if (phase === "remediating") {
5602
- return /* @__PURE__ */ jsxs33(Box32, { flexDirection: "column", children: [
5603
- /* @__PURE__ */ jsx34(SectionHeader, { emoji: "\u{1F50D}", title: t("compliance_title"), gradient: GRADIENTS.gold }),
5604
- /* @__PURE__ */ jsx34(Box32, { marginTop: SPACING.xs, children: /* @__PURE__ */ jsx34(ProgressLog, { lines: streamLines, isRunning: streamRunning, title: t("compliance_remediating") }) })
5789
+ return /* @__PURE__ */ jsxs34(Box33, { flexDirection: "column", children: [
5790
+ /* @__PURE__ */ jsx35(SectionHeader, { emoji: "\u{1F50D}", title: t("compliance_title"), gradient: GRADIENTS.gold }),
5791
+ /* @__PURE__ */ jsx35(Box33, { marginTop: SPACING.xs, children: /* @__PURE__ */ jsx35(ProgressLog, { lines: streamLines, isRunning: streamRunning, title: t("compliance_remediating") }) })
5605
5792
  ] });
5606
5793
  }
5607
- return /* @__PURE__ */ jsx34(Loading, { message: t("compliance_title") });
5794
+ return /* @__PURE__ */ jsx35(Loading, { message: t("compliance_title") });
5608
5795
  }
5609
5796
  if (phase === "result" && resultMessage) {
5610
- return /* @__PURE__ */ jsxs33(Box32, { flexDirection: "column", marginTop: SPACING.xs, children: [
5611
- /* @__PURE__ */ jsx34(SectionHeader, { emoji: "\u{1F50D}", title: t("compliance_title"), gradient: GRADIENTS.gold }),
5612
- /* @__PURE__ */ jsx34(Box32, { marginTop: SPACING.xs, children: /* @__PURE__ */ jsx34(
5797
+ return /* @__PURE__ */ jsxs34(Box33, { flexDirection: "column", marginTop: SPACING.xs, children: [
5798
+ /* @__PURE__ */ jsx35(SectionHeader, { emoji: "\u{1F50D}", title: t("compliance_title"), gradient: GRADIENTS.gold }),
5799
+ /* @__PURE__ */ jsx35(Box33, { marginTop: SPACING.xs, children: /* @__PURE__ */ jsx35(
5613
5800
  ResultBanner,
5614
5801
  {
5615
5802
  status: resultMessage.ok ? "success" : "error",
5616
5803
  message: resultMessage.text
5617
5804
  }
5618
5805
  ) }),
5619
- /* @__PURE__ */ jsx34(Box32, { marginTop: SPACING.xs, children: /* @__PURE__ */ jsxs33(Text33, { color: COLORS.textSecondary, children: [
5806
+ /* @__PURE__ */ jsx35(Box33, { marginTop: SPACING.xs, children: /* @__PURE__ */ jsxs34(Text34, { color: COLORS.textSecondary, children: [
5620
5807
  "r:",
5621
5808
  t("hint_refresh"),
5622
5809
  " esc:",
@@ -5624,12 +5811,12 @@ function ComplianceView() {
5624
5811
  ] }) })
5625
5812
  ] });
5626
5813
  }
5627
- return /* @__PURE__ */ jsxs33(Box32, { flexDirection: "column", children: [
5628
- /* @__PURE__ */ jsx34(SectionHeader, { emoji: "\u{1F50D}", title: t("compliance_title"), gradient: GRADIENTS.gold }),
5629
- error && /* @__PURE__ */ jsx34(Box32, { marginTop: SPACING.xs, children: /* @__PURE__ */ jsx34(ResultBanner, { status: "error", message: t("compliance_import_error", { error }) }) }),
5630
- phase === "importing" && /* @__PURE__ */ jsxs33(Box32, { marginTop: SPACING.xs, flexDirection: "column", children: [
5631
- /* @__PURE__ */ jsx34(Text33, { color: COLORS.textSecondary, children: t("compliance_import_prompt") }),
5632
- /* @__PURE__ */ jsx34(Box32, { marginTop: SPACING.xs, children: /* @__PURE__ */ jsx34(
5814
+ return /* @__PURE__ */ jsxs34(Box33, { flexDirection: "column", children: [
5815
+ /* @__PURE__ */ jsx35(SectionHeader, { emoji: "\u{1F50D}", title: t("compliance_title"), gradient: GRADIENTS.gold }),
5816
+ error && /* @__PURE__ */ jsx35(Box33, { marginTop: SPACING.xs, children: /* @__PURE__ */ jsx35(ResultBanner, { status: "error", message: t("compliance_import_error", { error }) }) }),
5817
+ phase === "importing" && /* @__PURE__ */ jsxs34(Box33, { marginTop: SPACING.xs, flexDirection: "column", children: [
5818
+ /* @__PURE__ */ jsx35(Text34, { color: COLORS.textSecondary, children: t("compliance_import_prompt") }),
5819
+ /* @__PURE__ */ jsx35(Box33, { marginTop: SPACING.xs, children: /* @__PURE__ */ jsx35(
5633
5820
  TextInput7,
5634
5821
  {
5635
5822
  defaultValue: "",
@@ -5638,31 +5825,31 @@ function ComplianceView() {
5638
5825
  }
5639
5826
  }
5640
5827
  ) }),
5641
- /* @__PURE__ */ jsx34(Box32, { marginTop: SPACING.xs, children: /* @__PURE__ */ jsxs33(Text33, { color: COLORS.muted, dimColor: true, children: [
5828
+ /* @__PURE__ */ jsx35(Box33, { marginTop: SPACING.xs, children: /* @__PURE__ */ jsxs34(Text34, { color: COLORS.muted, dimColor: true, children: [
5642
5829
  "esc:",
5643
5830
  t("hint_back")
5644
5831
  ] }) })
5645
5832
  ] }),
5646
- phase === "overview" && /* @__PURE__ */ jsxs33(Box32, { flexDirection: "column", marginTop: SPACING.xs, children: [
5647
- !policy ? /* @__PURE__ */ jsx34(Box32, { flexDirection: "column", children: /* @__PURE__ */ jsx34(Text33, { color: COLORS.textSecondary, children: t("compliance_no_policy") }) }) : /* @__PURE__ */ jsxs33(Box32, { flexDirection: "column", children: [
5648
- /* @__PURE__ */ jsx34(Text33, { color: COLORS.textSecondary, bold: true, children: t("compliance_policy_by", { maintainer: policy.meta.maintainer }) }),
5649
- report ? /* @__PURE__ */ jsxs33(Box32, { flexDirection: "column", marginTop: SPACING.xs, children: [
5650
- /* @__PURE__ */ jsx34(ComplianceScore, { report }),
5651
- report.compliant ? /* @__PURE__ */ jsx34(ResultBanner, { status: "success", message: t("compliance_ok") }) : /* @__PURE__ */ jsx34(ViolationList, { violations: report.violations })
5652
- ] }) : /* @__PURE__ */ jsx34(Box32, { marginTop: SPACING.xs, children: /* @__PURE__ */ jsx34(Text33, { color: COLORS.muted, dimColor: true, children: t("compliance_press_r_hint") }) })
5833
+ phase === "overview" && /* @__PURE__ */ jsxs34(Box33, { flexDirection: "column", marginTop: SPACING.xs, children: [
5834
+ !policy ? /* @__PURE__ */ jsx35(Box33, { flexDirection: "column", children: /* @__PURE__ */ jsx35(Text34, { color: COLORS.textSecondary, children: t("compliance_no_policy") }) }) : /* @__PURE__ */ jsxs34(Box33, { flexDirection: "column", children: [
5835
+ /* @__PURE__ */ jsx35(Text34, { color: COLORS.textSecondary, bold: true, children: t("compliance_policy_by", { maintainer: policy.meta.maintainer }) }),
5836
+ report ? /* @__PURE__ */ jsxs34(Box33, { flexDirection: "column", marginTop: SPACING.xs, children: [
5837
+ /* @__PURE__ */ jsx35(ComplianceScore, { report }),
5838
+ report.compliant ? /* @__PURE__ */ jsx35(ResultBanner, { status: "success", message: t("compliance_ok") }) : /* @__PURE__ */ jsx35(ViolationList, { violations: report.violations })
5839
+ ] }) : /* @__PURE__ */ jsx35(Box33, { marginTop: SPACING.xs, children: /* @__PURE__ */ jsx35(Text34, { color: COLORS.muted, dimColor: true, children: t("compliance_press_r_hint") }) })
5653
5840
  ] }),
5654
- /* @__PURE__ */ jsx34(Box32, { marginTop: SPACING.sm, flexWrap: "wrap", children: /* @__PURE__ */ jsxs33(Text33, { color: COLORS.textSecondary, children: [
5841
+ /* @__PURE__ */ jsx35(Box33, { marginTop: SPACING.sm, flexWrap: "wrap", children: /* @__PURE__ */ jsxs34(Text34, { color: COLORS.textSecondary, children: [
5655
5842
  "i:",
5656
5843
  t("hint_import"),
5657
- policy && /* @__PURE__ */ jsxs33(Text33, { children: [
5844
+ policy && /* @__PURE__ */ jsxs34(Text34, { children: [
5658
5845
  " r:",
5659
5846
  t("hint_scan")
5660
5847
  ] }),
5661
- report && /* @__PURE__ */ jsxs33(Text33, { children: [
5848
+ report && /* @__PURE__ */ jsxs34(Text34, { children: [
5662
5849
  " e:",
5663
5850
  t("hint_export")
5664
5851
  ] }),
5665
- report && report.violations.some((v) => v.type === "missing" || v.type === "wrong-version") && /* @__PURE__ */ jsxs33(Text33, { children: [
5852
+ report && report.violations.some((v) => v.type === "missing" || v.type === "wrong-version") && /* @__PURE__ */ jsxs34(Text34, { children: [
5666
5853
  " c:",
5667
5854
  t("hint_clean")
5668
5855
  ] }),
@@ -5674,10 +5861,10 @@ function ComplianceView() {
5674
5861
  }
5675
5862
 
5676
5863
  // src/app.tsx
5677
- import { jsx as jsx35, jsxs as jsxs34 } from "react/jsx-runtime";
5864
+ import { Fragment as Fragment7, jsx as jsx36, jsxs as jsxs35 } from "react/jsx-runtime";
5678
5865
  function LicenseInitializer() {
5679
5866
  const initLicense = useLicenseStore((s) => s.initialize);
5680
- useEffect19(() => {
5867
+ useEffect20(() => {
5681
5868
  initLicense();
5682
5869
  }, []);
5683
5870
  return null;
@@ -5686,53 +5873,65 @@ function ViewRouter({ currentView }) {
5686
5873
  const isPro = useLicenseStore((s) => s.isPro);
5687
5874
  const isTeam = useLicenseStore((s) => s.isTeam);
5688
5875
  if (isProView(currentView) && !isPro()) {
5689
- return /* @__PURE__ */ jsx35(UpgradePrompt, { viewId: currentView });
5876
+ return /* @__PURE__ */ jsx36(UpgradePrompt, { viewId: currentView });
5690
5877
  }
5691
5878
  if (isTeamView(currentView) && !isTeam()) {
5692
- return /* @__PURE__ */ jsx35(UpgradePrompt, { viewId: currentView });
5879
+ return /* @__PURE__ */ jsx36(UpgradePrompt, { viewId: currentView });
5693
5880
  }
5694
5881
  switch (currentView) {
5695
5882
  case "dashboard":
5696
- return /* @__PURE__ */ jsx35(DashboardView, {});
5883
+ return /* @__PURE__ */ jsx36(DashboardView, {});
5697
5884
  case "installed":
5698
- return /* @__PURE__ */ jsx35(InstalledView, {});
5885
+ return /* @__PURE__ */ jsx36(InstalledView, {});
5699
5886
  case "search":
5700
- return /* @__PURE__ */ jsx35(SearchView, {});
5887
+ return /* @__PURE__ */ jsx36(SearchView, {});
5701
5888
  case "outdated":
5702
- return /* @__PURE__ */ jsx35(OutdatedView, {});
5889
+ return /* @__PURE__ */ jsx36(OutdatedView, {});
5703
5890
  case "package-info":
5704
- return /* @__PURE__ */ jsx35(PackageInfoView, {});
5891
+ return /* @__PURE__ */ jsx36(PackageInfoView, {});
5705
5892
  case "services":
5706
- return /* @__PURE__ */ jsx35(ServicesView, {});
5893
+ return /* @__PURE__ */ jsx36(ServicesView, {});
5707
5894
  case "doctor":
5708
- return /* @__PURE__ */ jsx35(DoctorView, {});
5895
+ return /* @__PURE__ */ jsx36(DoctorView, {});
5709
5896
  case "profiles":
5710
- return /* @__PURE__ */ jsx35(ProfilesView, {});
5897
+ return /* @__PURE__ */ jsx36(ProfilesView, {});
5711
5898
  case "smart-cleanup":
5712
- return /* @__PURE__ */ jsx35(SmartCleanupView, {});
5899
+ return /* @__PURE__ */ jsx36(SmartCleanupView, {});
5713
5900
  case "history":
5714
- return /* @__PURE__ */ jsx35(HistoryView, {});
5901
+ return /* @__PURE__ */ jsx36(HistoryView, {});
5715
5902
  case "rollback":
5716
- return /* @__PURE__ */ jsx35(RollbackView, {});
5903
+ return /* @__PURE__ */ jsx36(RollbackView, {});
5717
5904
  case "brewfile":
5718
- return /* @__PURE__ */ jsx35(BrewfileView, {});
5905
+ return /* @__PURE__ */ jsx36(BrewfileView, {});
5719
5906
  case "sync":
5720
- return /* @__PURE__ */ jsx35(SyncView, {});
5907
+ return /* @__PURE__ */ jsx36(SyncView, {});
5721
5908
  case "security-audit":
5722
- return /* @__PURE__ */ jsx35(SecurityAuditView, {});
5909
+ return /* @__PURE__ */ jsx36(SecurityAuditView, {});
5723
5910
  case "compliance":
5724
- return /* @__PURE__ */ jsx35(ComplianceView, {});
5911
+ return /* @__PURE__ */ jsx36(ComplianceView, {});
5725
5912
  case "account":
5726
- return /* @__PURE__ */ jsx35(AccountView, {});
5913
+ return /* @__PURE__ */ jsx36(AccountView, {});
5727
5914
  }
5728
5915
  }
5729
5916
  function App() {
5730
5917
  const { exit } = useApp();
5731
5918
  const currentView = useNavigationStore((s) => s.currentView);
5919
+ const isTestEnv = typeof process !== "undefined" && false;
5920
+ const [showWelcome, setShowWelcome] = useState17(isTestEnv ? false : null);
5921
+ useEffect20(() => {
5922
+ if (isTestEnv) return;
5923
+ void hasCompletedOnboarding().then((done) => setShowWelcome(!done));
5924
+ }, []);
5732
5925
  useGlobalKeyboard({ onQuit: exit });
5733
- return /* @__PURE__ */ jsxs34(AppLayout, { children: [
5734
- /* @__PURE__ */ jsx35(LicenseInitializer, {}),
5735
- /* @__PURE__ */ jsx35(ViewRouter, { currentView })
5926
+ if (showWelcome === null) {
5927
+ return /* @__PURE__ */ jsx36(AppLayout, { children: /* @__PURE__ */ jsx36(Fragment7, {}) });
5928
+ }
5929
+ if (showWelcome) {
5930
+ return /* @__PURE__ */ jsx36(AppLayout, { children: /* @__PURE__ */ jsx36(WelcomeView, { onContinue: () => setShowWelcome(false) }) });
5931
+ }
5932
+ return /* @__PURE__ */ jsxs35(AppLayout, { children: [
5933
+ /* @__PURE__ */ jsx36(LicenseInitializer, {}),
5934
+ /* @__PURE__ */ jsx36(ViewRouter, { currentView })
5736
5935
  ] });
5737
5936
  }
5738
5937
 
@@ -5816,7 +6015,7 @@ async function reportError(err, context = {}) {
5816
6015
  const config = await resolveConfig();
5817
6016
  if (!config.enabled || !config.endpoint) return;
5818
6017
  const machineId = await getMachineId();
5819
- const version = true ? "0.6.2" : "unknown";
6018
+ const version = true ? "0.7.0" : "unknown";
5820
6019
  await postReport(buildReport("error", err, context, machineId, version), config);
5821
6020
  }
5822
6021
  async function installCrashReporter() {
@@ -5825,7 +6024,7 @@ async function installCrashReporter() {
5825
6024
  if (!config.enabled || !config.endpoint) return;
5826
6025
  _installed = true;
5827
6026
  const machineId = await getMachineId();
5828
- const version = true ? "0.6.2" : "unknown";
6027
+ const version = true ? "0.7.0" : "unknown";
5829
6028
  process.on("uncaughtException", (err) => {
5830
6029
  void postReport(buildReport("fatal", err, { kind: "uncaughtException" }, machineId, version), config);
5831
6030
  });
@@ -5836,7 +6035,7 @@ async function installCrashReporter() {
5836
6035
  }
5837
6036
 
5838
6037
  // src/index.tsx
5839
- import { jsx as jsx36 } from "react/jsx-runtime";
6038
+ import { jsx as jsx37 } from "react/jsx-runtime";
5840
6039
  var [, , command, arg] = process.argv;
5841
6040
  async function runCli() {
5842
6041
  await ensureDataDirs();
@@ -5931,7 +6130,7 @@ async function runCli() {
5931
6130
  }
5932
6131
  if (isPro) {
5933
6132
  try {
5934
- const { loadSnapshots: loadSnapshots2 } = await import("./snapshot-YWIOFQ5H.js");
6133
+ const { loadSnapshots: loadSnapshots2 } = await import("./snapshot-JDRSBMG6.js");
5935
6134
  const snapshots = await loadSnapshots2();
5936
6135
  if (snapshots.length > 0) {
5937
6136
  const latest = snapshots[0];
@@ -5943,7 +6142,7 @@ Snapshots: ${snapshots.length} (latest: ${latest ? formatDate(latest.capturedAt)
5943
6142
  } catch {
5944
6143
  }
5945
6144
  try {
5946
- const { loadBrewfile: loadBrewfile2, computeDrift: computeDrift2 } = await import("./brewfile-manager-OITSKEHY.js");
6145
+ const { loadBrewfile: loadBrewfile2, computeDrift: computeDrift2 } = await import("./brewfile-manager-6LXONGSA.js");
5947
6146
  const schema = await loadBrewfile2();
5948
6147
  if (schema) {
5949
6148
  const drift = await computeDrift2(schema);
@@ -5952,7 +6151,7 @@ Snapshots: ${snapshots.length} (latest: ${latest ? formatDate(latest.capturedAt)
5952
6151
  } catch {
5953
6152
  }
5954
6153
  try {
5955
- const { loadSyncConfig: loadSyncConfig2 } = await import("./sync-engine-DIYXV66P.js");
6154
+ const { loadSyncConfig: loadSyncConfig2 } = await import("./sync-engine-4OA4JNR3.js");
5956
6155
  const syncConfig = await loadSyncConfig2();
5957
6156
  if (syncConfig?.lastSync) {
5958
6157
  console.log(`Sync: last sync ${formatDate(syncConfig.lastSync)}`);
@@ -5961,7 +6160,7 @@ Snapshots: ${snapshots.length} (latest: ${latest ? formatDate(latest.capturedAt)
5961
6160
  }
5962
6161
  try {
5963
6162
  const { loadPolicy: loadPolicy2 } = await import("./policy-io-EECGRKNA.js");
5964
- const { checkCompliance: checkCompliance2 } = await import("./compliance-checker-7NMFKWTI.js");
6163
+ const { checkCompliance: checkCompliance2 } = await import("./compliance-checker-MAREAFDH.js");
5965
6164
  const policy = await loadPolicy2(`${process.env["HOME"] ?? "~"}/.brew-tui/policy.yaml`).catch(() => null);
5966
6165
  if (policy) {
5967
6166
  const report = await checkCompliance2(policy, true);
@@ -5975,7 +6174,7 @@ Snapshots: ${snapshots.length} (latest: ${latest ? formatDate(latest.capturedAt)
5975
6174
  if (command === "install-brewbar") {
5976
6175
  await useLicenseStore.getState().initialize();
5977
6176
  const isPro = useLicenseStore.getState().isPro();
5978
- const { installBrewBar } = await import("./brewbar-installer-WJZKSELD.js");
6177
+ const { installBrewBar } = await import("./brewbar-installer-KJTIZIVU.js");
5979
6178
  try {
5980
6179
  await installBrewBar(isPro, arg === "--force");
5981
6180
  console.log(t("cli_brewbarInstalled"));
@@ -5986,7 +6185,7 @@ Snapshots: ${snapshots.length} (latest: ${latest ? formatDate(latest.capturedAt)
5986
6185
  return;
5987
6186
  }
5988
6187
  if (command === "uninstall-brewbar") {
5989
- const { uninstallBrewBar } = await import("./brewbar-installer-WJZKSELD.js");
6188
+ const { uninstallBrewBar } = await import("./brewbar-installer-KJTIZIVU.js");
5990
6189
  try {
5991
6190
  await uninstallBrewBar();
5992
6191
  console.log(t("cli_brewbarUninstalled"));
@@ -6011,13 +6210,13 @@ Snapshots: ${snapshots.length} (latest: ${latest ? formatDate(latest.capturedAt)
6011
6210
  await ensureBrewBarRunning();
6012
6211
  process.env.BREW_TUI_TUI_MODE = "1";
6013
6212
  process.stdout.write("\x1B[2J\x1B[3J\x1B[H");
6014
- render(/* @__PURE__ */ jsx36(App, {}));
6213
+ render(/* @__PURE__ */ jsx37(App, {}));
6015
6214
  }
6016
6215
  async function ensureBrewBarRunning() {
6017
6216
  if (process.platform !== "darwin") return;
6018
6217
  await useLicenseStore.getState().initialize();
6019
6218
  if (!useLicenseStore.getState().isPro()) return;
6020
- const { isBrewBarInstalled, installBrewBar, launchBrewBar } = await import("./brewbar-installer-WJZKSELD.js");
6219
+ const { isBrewBarInstalled, installBrewBar, launchBrewBar } = await import("./brewbar-installer-KJTIZIVU.js");
6021
6220
  try {
6022
6221
  if (!await isBrewBarInstalled()) {
6023
6222
  console.log(t("cli_brewbarInstalling"));