brew-tui 0.8.1 → 0.9.1

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