brew-tui 0.3.5 → 0.4.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/build/index.js CHANGED
@@ -30,15 +30,13 @@ import { useApp } from "ink";
30
30
  import { Box as Box3 } from "ink";
31
31
 
32
32
  // src/components/layout/header.tsx
33
- import React2 from "react";
34
- import { Box, Text as Text2 } from "ink";
33
+ import { Box, Text as Text2, useStdout } from "ink";
35
34
 
36
35
  // src/stores/navigation-store.ts
37
36
  import { create } from "zustand";
38
37
  var VIEWS = [
39
38
  "dashboard",
40
39
  "installed",
41
- "search",
42
40
  "outdated",
43
41
  "package-info",
44
42
  "services",
@@ -108,6 +106,7 @@ var COLORS = {
108
106
  gold: "#FFD700",
109
107
  purple: "#A855F7",
110
108
  blue: "#3B82F6",
109
+ lavender: "#C4B5FD",
111
110
  border: "#4B5563"
112
111
  };
113
112
 
@@ -160,7 +159,7 @@ var GRADIENTS = {
160
159
  };
161
160
 
162
161
  // src/components/layout/header.tsx
163
- import { Fragment as Fragment2, jsx as jsx2, jsxs } from "react/jsx-runtime";
162
+ import { jsx as jsx2, jsxs } from "react/jsx-runtime";
164
163
  var LOGO_BREW = [
165
164
  "\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",
166
165
  "\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",
@@ -194,21 +193,20 @@ var VIEW_LABEL_KEYS = {
194
193
  var VIEW_KEYS = {
195
194
  dashboard: "1",
196
195
  installed: "2",
197
- search: "3",
198
- outdated: "4",
196
+ search: "",
197
+ outdated: "3",
199
198
  "package-info": "",
200
- services: "5",
201
- doctor: "6",
202
- profiles: "7",
203
- "smart-cleanup": "8",
204
- history: "9",
205
- "security-audit": "0",
206
- account: ""
199
+ services: "4",
200
+ doctor: "5",
201
+ profiles: "6",
202
+ "smart-cleanup": "7",
203
+ history: "8",
204
+ "security-audit": "9",
205
+ account: "0"
207
206
  };
208
207
  var TAB_VIEWS = [
209
208
  "dashboard",
210
209
  "installed",
211
- "search",
212
210
  "outdated",
213
211
  "package-info",
214
212
  "services",
@@ -219,68 +217,97 @@ var TAB_VIEWS = [
219
217
  "security-audit",
220
218
  "account"
221
219
  ];
220
+ function MenuItem({ view, currentView }) {
221
+ const key = VIEW_KEYS[view];
222
+ const viewLabel = t(VIEW_LABEL_KEYS[view]);
223
+ const isPro = isProView(view);
224
+ const isActive = view === currentView;
225
+ const isAccount = view === "account";
226
+ const indicator = key || (view === "package-info" ? "\u21B2" : " ");
227
+ return /* @__PURE__ */ jsxs(Box, { children: [
228
+ isActive ? /* @__PURE__ */ jsxs(Text2, { color: COLORS.success, bold: true, children: [
229
+ "\u25B6",
230
+ " "
231
+ ] }) : /* @__PURE__ */ jsx2(Text2, { children: " " }),
232
+ /* @__PURE__ */ jsx2(Text2, { bold: true, color: key ? "#FFFFFF" : COLORS.textSecondary, children: indicator }),
233
+ /* @__PURE__ */ jsxs(Text2, { bold: isActive, underline: isActive, color: isActive ? COLORS.success : isAccount ? COLORS.gold : COLORS.textSecondary, children: [
234
+ " ",
235
+ viewLabel
236
+ ] }),
237
+ isPro && /* @__PURE__ */ jsxs(Text2, { color: COLORS.brand, bold: true, children: [
238
+ " ",
239
+ t("pro_badge")
240
+ ] })
241
+ ] });
242
+ }
243
+ var COL1_VIEWS = TAB_VIEWS.slice(0, 6);
244
+ var COL2_VIEWS = TAB_VIEWS.slice(6);
222
245
  function Header() {
223
246
  const currentView = useNavigationStore((s) => s.currentView);
224
247
  useLocaleStore((s) => s.locale);
225
- return /* @__PURE__ */ jsxs(Box, { flexDirection: "column", children: [
226
- /* @__PURE__ */ jsx2(Box, { flexDirection: "column", paddingX: 1, children: LOGO_BREW.map((brew, i) => /* @__PURE__ */ jsxs(Box, { children: [
227
- /* @__PURE__ */ jsx2(GradientText, { colors: GRADIENTS.gold, children: brew }),
228
- /* @__PURE__ */ jsx2(GradientText, { colors: ["#B8860B", "#8B6914", "#6B4F10"], children: LOGO_TUI[i] })
229
- ] }, i)) }),
230
- /* @__PURE__ */ jsx2(Text2, { children: " " }),
231
- /* @__PURE__ */ jsx2(Box, { borderStyle: "single", borderBottom: true, borderLeft: false, borderRight: false, borderTop: false, borderColor: COLORS.gold, paddingX: 1, flexWrap: "wrap", children: TAB_VIEWS.map((view, i) => {
232
- const key = VIEW_KEYS[view];
233
- const viewLabel = t(VIEW_LABEL_KEYS[view]);
234
- const isPro = isProView(view);
235
- const isActive = view === currentView;
236
- const isAccount = view === "account";
237
- return /* @__PURE__ */ jsxs(React2.Fragment, { children: [
238
- i > 0 && /* @__PURE__ */ jsxs(Text2, { color: COLORS.border, children: [
239
- " ",
240
- "\u2502",
241
- " "
242
- ] }),
243
- isActive && /* @__PURE__ */ jsxs(Text2, { color: COLORS.sky, children: [
244
- "\u25CF",
245
- " "
246
- ] }),
247
- key ? /* @__PURE__ */ jsxs(Fragment2, { children: [
248
- /* @__PURE__ */ jsx2(Text2, { bold: true, color: "#FFFFFF", children: key }),
249
- /* @__PURE__ */ jsxs(Text2, { bold: isActive, underline: isActive, color: isActive ? COLORS.success : isAccount ? COLORS.gold : COLORS.textSecondary, children: [
250
- " ",
251
- viewLabel
252
- ] })
253
- ] }) : /* @__PURE__ */ jsx2(Text2, { bold: isActive, underline: isActive, color: isActive ? COLORS.success : isAccount ? COLORS.gold : COLORS.textSecondary, children: viewLabel }),
254
- isPro && /* @__PURE__ */ jsxs(Text2, { color: COLORS.brand, bold: true, children: [
255
- " ",
256
- t("pro_badge")
257
- ] })
258
- ] }, view);
259
- }) })
248
+ const { stdout } = useStdout();
249
+ const cols = stdout?.columns ?? 80;
250
+ const isNarrow = cols < 95;
251
+ const logoBlock = /* @__PURE__ */ jsx2(Box, { flexDirection: "column", flexShrink: 0, children: LOGO_BREW.map((brew, i) => /* @__PURE__ */ jsxs(Box, { children: [
252
+ /* @__PURE__ */ jsx2(GradientText, { colors: GRADIENTS.gold, children: brew }),
253
+ /* @__PURE__ */ jsx2(GradientText, { colors: ["#B8860B", "#8B6914", "#6B4F10"], children: LOGO_TUI[i] })
254
+ ] }, i)) });
255
+ const menuBlock = /* @__PURE__ */ jsxs(Box, { borderStyle: "round", borderColor: COLORS.lavender, paddingX: 1, flexDirection: "column", alignSelf: isNarrow ? "flex-start" : "center", children: [
256
+ /* @__PURE__ */ jsxs(Box, { flexDirection: "row", children: [
257
+ /* @__PURE__ */ jsx2(Box, { flexDirection: "column", children: COL1_VIEWS.map((view) => /* @__PURE__ */ jsx2(MenuItem, { view, currentView }, view)) }),
258
+ /* @__PURE__ */ jsx2(Box, { flexDirection: "column", marginLeft: 2, children: COL2_VIEWS.map((view) => /* @__PURE__ */ jsx2(MenuItem, { view, currentView }, view)) })
259
+ ] }),
260
+ /* @__PURE__ */ jsxs(Box, { borderStyle: "single", borderTop: true, borderBottom: false, borderLeft: false, borderRight: false, borderColor: COLORS.lavender, marginTop: 0, children: [
261
+ /* @__PURE__ */ jsx2(Text2, { bold: true, color: "#FFFFFF", children: "S" }),
262
+ /* @__PURE__ */ jsxs(Text2, { color: COLORS.textSecondary, children: [
263
+ " ",
264
+ t("hint_search")
265
+ ] }),
266
+ /* @__PURE__ */ jsxs(Text2, { color: COLORS.lavender, children: [
267
+ " ",
268
+ "\u2503",
269
+ " "
270
+ ] }),
271
+ /* @__PURE__ */ jsx2(Text2, { bold: true, color: "#FFFFFF", children: "L" }),
272
+ /* @__PURE__ */ jsxs(Text2, { color: COLORS.textSecondary, children: [
273
+ " ",
274
+ t("hint_lang")
275
+ ] })
276
+ ] })
277
+ ] });
278
+ if (isNarrow) {
279
+ return /* @__PURE__ */ jsxs(Box, { flexDirection: "column", paddingX: 1, children: [
280
+ logoBlock,
281
+ /* @__PURE__ */ jsx2(Box, { marginTop: 1, children: menuBlock })
282
+ ] });
283
+ }
284
+ return /* @__PURE__ */ jsxs(Box, { flexDirection: "row", paddingX: 1, alignItems: "center", children: [
285
+ logoBlock,
286
+ /* @__PURE__ */ jsx2(Box, { marginLeft: 2, children: menuBlock })
260
287
  ] });
261
288
  }
262
289
 
263
290
  // src/components/layout/footer.tsx
264
- import React3 from "react";
291
+ import React2 from "react";
265
292
  import { Box as Box2, Text as Text3 } from "ink";
266
- import { Fragment as Fragment3, jsx as jsx3, jsxs as jsxs2 } from "react/jsx-runtime";
293
+ import { Fragment as Fragment2, jsx as jsx3, jsxs as jsxs2 } from "react/jsx-runtime";
267
294
  var VIEW_HINT_DEFS = {
268
- dashboard: [["1-0", "hint_navigate"], ["tab", "hint_next"], ["q", "hint_quit"]],
269
- installed: [["/", "hint_filter"], ["enter", "hint_info"], ["u", "hint_uninstall"], ["f", "hint_toggle"], ["tab", "hint_next"], ["q", "hint_quit"]],
295
+ dashboard: [["1-9,0", "hint_navigate"], ["S", "hint_search"], ["tab", "hint_next"], ["q", "hint_quit"]],
296
+ installed: [["/", "hint_filter"], ["enter", "hint_info"], ["u", "hint_uninstall"], ["S", "hint_search"], ["q", "hint_quit"]],
270
297
  search: [["hint_typeToSearch"], ["enter", "hint_details"], ["i", "hint_install"], ["esc", "hint_back"], ["q", "hint_quit"]],
271
- outdated: [["enter", "hint_upgrade"], ["A", "hint_upgradeAll"], ["p", "hint_pin"], ["tab", "hint_next"], ["q", "hint_quit"]],
298
+ outdated: [["enter", "hint_upgrade"], ["A", "hint_upgradeAll"], ["p", "hint_pin"], ["S", "hint_search"], ["q", "hint_quit"]],
272
299
  "package-info": [["i", "hint_install"], ["u", "hint_uninstall"], ["U", "hint_upgrade"], ["esc", "hint_back"], ["q", "hint_quit"]],
273
- services: [["s", "hint_start"], ["S", "hint_stop"], ["R", "hint_restart"], ["r", "hint_refresh"], ["tab", "hint_next"], ["q", "hint_quit"]],
274
- doctor: [["r", "hint_refresh"], ["tab", "hint_next"], ["q", "hint_quit"]],
300
+ services: [["s", "hint_start"], ["x", "hint_stop"], ["R", "hint_restart"], ["r", "hint_refresh"], ["S", "hint_search"], ["q", "hint_quit"]],
301
+ doctor: [["r", "hint_refresh"], ["S", "hint_search"], ["tab", "hint_next"], ["q", "hint_quit"]],
275
302
  profiles: [["n", "hint_new"], ["enter", "hint_details"], ["e", "hint_edit"], ["i", "hint_import"], ["d", "hint_delete"], ["q", "hint_quit"]],
276
- "smart-cleanup": [["enter", "hint_toggle"], ["c", "hint_clean"], ["r", "hint_refresh"], ["q", "hint_quit"]],
303
+ "smart-cleanup": [["enter", "hint_toggle"], ["c", "hint_clean"], ["r", "hint_refresh"], ["S", "hint_search"], ["q", "hint_quit"]],
277
304
  history: [["/", "hint_search"], ["enter", "hint_replay"], ["f", "hint_filter"], ["c", "hint_clear"], ["q", "hint_quit"]],
278
- "security-audit": [["r", "hint_scan"], ["enter", "hint_details"], ["u", "hint_upgrade"], ["q", "hint_quit"]],
279
- account: [["p", "hint_promo"], ["d", "hint_deactivate"], ["q", "hint_quit"]]
305
+ "security-audit": [["r", "hint_scan"], ["enter", "hint_details"], ["u", "hint_upgrade"], ["S", "hint_search"], ["q", "hint_quit"]],
306
+ account: [["p", "hint_promo"], ["d", "hint_deactivate"], ["S", "hint_search"], ["q", "hint_quit"]]
280
307
  };
281
308
  function HintItem({ def }) {
282
309
  if (def.length === 1) return /* @__PURE__ */ jsx3(Text3, { color: COLORS.gold, dimColor: true, children: t(def[0]) });
283
- return /* @__PURE__ */ jsxs2(Fragment3, { children: [
310
+ return /* @__PURE__ */ jsxs2(Fragment2, { children: [
284
311
  /* @__PURE__ */ jsx3(Text3, { color: COLORS.text, bold: true, children: def[0] }),
285
312
  /* @__PURE__ */ jsx3(Text3, { color: COLORS.textSecondary, children: ":" }),
286
313
  /* @__PURE__ */ jsx3(Text3, { color: COLORS.gold, dimColor: true, children: t(def[1]) })
@@ -293,7 +320,7 @@ function Footer() {
293
320
  return /* @__PURE__ */ jsxs2(Box2, { borderStyle: "single", borderTop: true, borderBottom: false, borderLeft: false, borderRight: false, borderColor: COLORS.gold, paddingX: 1, flexWrap: "wrap", children: [
294
321
  defs.map((def, i) => {
295
322
  const key = def.length === 1 ? def[0] : `${def[0]}:${def[1]}`;
296
- return /* @__PURE__ */ jsxs2(React3.Fragment, { children: [
323
+ return /* @__PURE__ */ jsxs2(React2.Fragment, { children: [
297
324
  i > 0 && /* @__PURE__ */ jsxs2(Text3, { color: COLORS.border, children: [
298
325
  " ",
299
326
  "\u2502",
@@ -302,9 +329,9 @@ function Footer() {
302
329
  /* @__PURE__ */ jsx3(HintItem, { def })
303
330
  ] }, key);
304
331
  }),
305
- /* @__PURE__ */ jsxs2(Text3, { color: COLORS.border, children: [
332
+ /* @__PURE__ */ jsxs2(Text3, { color: COLORS.lavender, children: [
306
333
  " ",
307
- "\u2502",
334
+ "\u2503",
308
335
  " "
309
336
  ] }),
310
337
  /* @__PURE__ */ jsx3(Text3, { color: COLORS.text, bold: true, children: "L" }),
@@ -823,14 +850,14 @@ var useModalStore = create3((set) => ({
823
850
  var VIEW_KEYS2 = {
824
851
  "1": "dashboard",
825
852
  "2": "installed",
826
- "3": "search",
827
- "4": "outdated",
828
- "5": "services",
829
- "6": "doctor",
830
- "7": "profiles",
831
- "8": "smart-cleanup",
832
- "9": "history",
833
- "0": "security-audit"
853
+ "3": "outdated",
854
+ "4": "services",
855
+ "5": "doctor",
856
+ "6": "profiles",
857
+ "7": "smart-cleanup",
858
+ "8": "history",
859
+ "9": "security-audit",
860
+ "0": "account"
834
861
  };
835
862
  function useGlobalKeyboard(opts) {
836
863
  const navigate = useNavigationStore((s) => s.navigate);
@@ -857,6 +884,10 @@ function useGlobalKeyboard(opts) {
857
884
  navigate(getNextView(currentView));
858
885
  return;
859
886
  }
887
+ if (input === "S") {
888
+ navigate("search");
889
+ return;
890
+ }
860
891
  if (input === "L") {
861
892
  setLocale(locale === "en" ? "es" : "en");
862
893
  return;
@@ -923,7 +954,7 @@ function UpgradePrompt({ viewId }) {
923
954
 
924
955
  // src/views/dashboard.tsx
925
956
  import { useEffect, useMemo as useMemo2 } from "react";
926
- import { Box as Box8, Text as Text10, useStdout } from "ink";
957
+ import { Box as Box8, Text as Text10, useStdout as useStdout3 } from "ink";
927
958
 
928
959
  // src/stores/brew-store.ts
929
960
  import { create as create4 } from "zustand";
@@ -1385,19 +1416,22 @@ var useBrewStore = create4((set, get) => ({
1385
1416
  }));
1386
1417
 
1387
1418
  // src/components/common/stat-card.tsx
1388
- import { Box as Box5, Text as Text5 } from "ink";
1419
+ import { Box as Box5, Text as Text5, useStdout as useStdout2 } from "ink";
1389
1420
  import { jsx as jsx6, jsxs as jsxs5 } from "react/jsx-runtime";
1390
1421
  function StatCard({ label, value, color = "white" }) {
1422
+ const { stdout } = useStdout2();
1423
+ const cols = stdout?.columns ?? 80;
1424
+ const minW = cols < 60 ? 12 : cols < 100 ? 14 : 16;
1391
1425
  return /* @__PURE__ */ jsxs5(
1392
1426
  Box5,
1393
1427
  {
1394
1428
  borderStyle: "round",
1395
1429
  borderColor: color,
1396
1430
  paddingX: 2,
1397
- paddingY: 1,
1431
+ paddingY: 0,
1398
1432
  flexDirection: "column",
1399
1433
  alignItems: "center",
1400
- minWidth: 16,
1434
+ minWidth: minW,
1401
1435
  children: [
1402
1436
  /* @__PURE__ */ jsx6(Text5, { bold: true, color, children: value }),
1403
1437
  /* @__PURE__ */ jsx6(Text5, { color: COLORS.muted, children: label })
@@ -1431,7 +1465,7 @@ import { Text as Text7 } from "ink";
1431
1465
  import { jsxs as jsxs7 } from "react/jsx-runtime";
1432
1466
  var BADGE_STYLES = {
1433
1467
  success: { icon: "\u2714", color: COLORS.success },
1434
- warning: { icon: "\u25CF", color: COLORS.warning },
1468
+ warning: { icon: "\u25B2", color: COLORS.warning },
1435
1469
  error: { icon: "\u2718", color: COLORS.error },
1436
1470
  info: { icon: "\u25C6", color: COLORS.blue },
1437
1471
  muted: { icon: "\u25CB", color: COLORS.textSecondary }
@@ -1465,9 +1499,9 @@ function SectionHeader({ emoji, title, color = COLORS.gold, gradient, count }) {
1465
1499
 
1466
1500
  // src/components/common/version-arrow.tsx
1467
1501
  import { Text as Text9 } from "ink";
1468
- import { Fragment as Fragment4, jsx as jsx9, jsxs as jsxs9 } from "react/jsx-runtime";
1502
+ import { Fragment as Fragment3, jsx as jsx9, jsxs as jsxs9 } from "react/jsx-runtime";
1469
1503
  function VersionArrow({ current, latest }) {
1470
- return /* @__PURE__ */ jsxs9(Fragment4, { children: [
1504
+ return /* @__PURE__ */ jsxs9(Fragment3, { children: [
1471
1505
  /* @__PURE__ */ jsxs9(Text9, { color: COLORS.muted, children: [
1472
1506
  t("version_installed"),
1473
1507
  " "
@@ -1515,7 +1549,7 @@ function truncate(str, maxLen) {
1515
1549
  import { jsx as jsx10, jsxs as jsxs10 } from "react/jsx-runtime";
1516
1550
  function DashboardView() {
1517
1551
  const { formulae, casks, outdated, services, config, loading, errors, lastFetchedAt, fetchAll } = useBrewStore();
1518
- const { stdout } = useStdout();
1552
+ const { stdout } = useStdout3();
1519
1553
  const columns = stdout?.columns ?? 80;
1520
1554
  useEffect(() => {
1521
1555
  fetchAll();
@@ -1614,7 +1648,7 @@ function DashboardView() {
1614
1648
 
1615
1649
  // src/views/installed.tsx
1616
1650
  import { useState as useState3, useMemo as useMemo3, useEffect as useEffect5 } from "react";
1617
- import { Box as Box14, Text as Text16, useInput as useInput3, useStdout as useStdout2 } from "ink";
1651
+ import { Box as Box14, Text as Text16, useInput as useInput3, useStdout as useStdout4 } from "ink";
1618
1652
 
1619
1653
  // src/hooks/use-debounce.ts
1620
1654
  import { useState, useEffect as useEffect2 } from "react";
@@ -1805,7 +1839,7 @@ function InstalledView() {
1805
1839
  const debouncedFilter = useDebounce(filter, 200);
1806
1840
  const stream = useBrewStream();
1807
1841
  const { openModal, closeModal } = useModalStore();
1808
- const { stdout } = useStdout2();
1842
+ const { stdout } = useStdout4();
1809
1843
  const cols = stdout?.columns ?? 80;
1810
1844
  const nameWidth = Math.floor(cols * 0.35);
1811
1845
  const versionWidth = Math.floor(cols * 0.15);
@@ -2171,7 +2205,7 @@ function SearchView() {
2171
2205
 
2172
2206
  // src/views/outdated.tsx
2173
2207
  import { useEffect as useEffect7, useRef as useRef3, useState as useState5 } from "react";
2174
- import { Box as Box16, Text as Text18, useInput as useInput5, useStdout as useStdout3 } from "ink";
2208
+ import { Box as Box16, Text as Text18, useInput as useInput5, useStdout as useStdout5 } from "ink";
2175
2209
  import { jsx as jsx18, jsxs as jsxs17 } from "react/jsx-runtime";
2176
2210
  function OutdatedView() {
2177
2211
  const { outdated, loading, errors, fetchOutdated } = useBrewStore();
@@ -2222,7 +2256,7 @@ function OutdatedView() {
2222
2256
  void fetchOutdated();
2223
2257
  }
2224
2258
  });
2225
- const { stdout } = useStdout3();
2259
+ const { stdout } = useStdout5();
2226
2260
  const MAX_VISIBLE_ROWS = Math.max(5, (stdout?.rows ?? 24) - 8);
2227
2261
  const start = Math.max(0, cursor - Math.floor(MAX_VISIBLE_ROWS / 2));
2228
2262
  const visible = allOutdated.slice(start, start + MAX_VISIBLE_ROWS);
@@ -2310,7 +2344,7 @@ ${t("outdated_upgradeAllList", { list: allOutdated.map((p) => p.name).join(", ")
2310
2344
  // src/views/package-info.tsx
2311
2345
  import { useEffect as useEffect8, useRef as useRef4, useState as useState6 } from "react";
2312
2346
  import { Box as Box17, Text as Text19, useInput as useInput6 } from "ink";
2313
- import { Fragment as Fragment5, jsx as jsx19, jsxs as jsxs18 } from "react/jsx-runtime";
2347
+ import { Fragment as Fragment4, jsx as jsx19, jsxs as jsxs18 } from "react/jsx-runtime";
2314
2348
  var ACTION_PROGRESS_KEYS = {
2315
2349
  install: "pkgInfo_installing",
2316
2350
  uninstall: "pkgInfo_uninstalling",
@@ -2431,7 +2465,7 @@ function PackageInfoView() {
2431
2465
  "esc:",
2432
2466
  t("hint_cancel")
2433
2467
  ] }),
2434
- !stream.isRunning && /* @__PURE__ */ jsxs18(Fragment5, { children: [
2468
+ !stream.isRunning && /* @__PURE__ */ jsxs18(Fragment4, { children: [
2435
2469
  /* @__PURE__ */ jsx19(Text19, { color: stream.error ? COLORS.error : COLORS.success, bold: true, children: stream.error ? `\u2718 ${stream.error}` : `\u2714 ${t("pkgInfo_done")}` }),
2436
2470
  /* @__PURE__ */ jsxs18(Text19, { color: COLORS.textSecondary, children: [
2437
2471
  "esc:",
@@ -2493,7 +2527,7 @@ function PackageInfoView() {
2493
2527
  " ",
2494
2528
  formula.versions.stable
2495
2529
  ] }),
2496
- installed && /* @__PURE__ */ jsxs18(Fragment5, { children: [
2530
+ installed && /* @__PURE__ */ jsxs18(Fragment4, { children: [
2497
2531
  /* @__PURE__ */ jsxs18(Text19, { children: [
2498
2532
  /* @__PURE__ */ jsx19(Text19, { color: COLORS.muted, children: t("pkgInfo_installed") }),
2499
2533
  " ",
@@ -2534,7 +2568,7 @@ function PackageInfoView() {
2534
2568
 
2535
2569
  // src/views/services.tsx
2536
2570
  import { useEffect as useEffect9, useState as useState7 } from "react";
2537
- import { Box as Box18, Text as Text20, useInput as useInput7, useStdout as useStdout4 } from "ink";
2571
+ import { Box as Box18, Text as Text20, useInput as useInput7, useStdout as useStdout6 } from "ink";
2538
2572
  import { jsx as jsx20, jsxs as jsxs19 } from "react/jsx-runtime";
2539
2573
  var STATUS_VARIANTS = {
2540
2574
  started: "success",
@@ -2548,7 +2582,7 @@ function ServicesView() {
2548
2582
  const [actionInProgress, setActionInProgress] = useState7(false);
2549
2583
  const [confirmAction, setConfirmAction] = useState7(null);
2550
2584
  const [lastError, setLastError] = useState7(null);
2551
- const { stdout } = useStdout4();
2585
+ const { stdout } = useStdout6();
2552
2586
  const cols = stdout?.columns ?? 80;
2553
2587
  const svcNameWidth = Math.floor(cols * 0.35);
2554
2588
  const svcStatusWidth = Math.floor(cols * 0.15);
@@ -2582,7 +2616,7 @@ function ServicesView() {
2582
2616
  });
2583
2617
  };
2584
2618
  if (input === "s") doAction("start");
2585
- else if (input === "S") setConfirmAction({ type: "stop", name: svc.name });
2619
+ else if (input === "x") setConfirmAction({ type: "stop", name: svc.name });
2586
2620
  else if (input === "R") setConfirmAction({ type: "restart", name: svc.name });
2587
2621
  });
2588
2622
  if (loading.services) return /* @__PURE__ */ jsx20(Loading, { message: t("loading_services") });
@@ -3502,7 +3536,7 @@ function SmartCleanupView() {
3502
3536
 
3503
3537
  // src/views/history.tsx
3504
3538
  import { useEffect as useEffect13, useState as useState10, useMemo as useMemo4 } from "react";
3505
- import { Box as Box26, Text as Text27, useInput as useInput11, useStdout as useStdout5 } from "ink";
3539
+ import { Box as Box26, Text as Text27, useInput as useInput11, useStdout as useStdout7 } from "ink";
3506
3540
 
3507
3541
  // src/stores/history-store.ts
3508
3542
  import { create as create7 } from "zustand";
@@ -3614,7 +3648,7 @@ function HistoryView() {
3614
3648
  });
3615
3649
  if (loading) return /* @__PURE__ */ jsx28(Loading, { message: t("loading_history") });
3616
3650
  if (error) return /* @__PURE__ */ jsx28(ErrorMessage, { message: error });
3617
- const { stdout } = useStdout5();
3651
+ const { stdout } = useStdout7();
3618
3652
  const MAX_VISIBLE_ROWS = Math.max(5, (stdout?.rows ?? 24) - 8);
3619
3653
  const start = Math.max(0, cursor - Math.floor(MAX_VISIBLE_ROWS / 2));
3620
3654
  const visible = filtered.slice(start, start + MAX_VISIBLE_ROWS);
@@ -4097,7 +4131,7 @@ async function redeemPromoCode(code) {
4097
4131
  }
4098
4132
 
4099
4133
  // src/views/account.tsx
4100
- import { Fragment as Fragment6, jsx as jsx30, jsxs as jsxs29 } from "react/jsx-runtime";
4134
+ import { Fragment as Fragment5, jsx as jsx30, jsxs as jsxs29 } from "react/jsx-runtime";
4101
4135
  function AccountView() {
4102
4136
  const { status, license, deactivate: deactivate2, degradation } = useLicenseStore();
4103
4137
  const [confirmDeactivate, setConfirmDeactivate] = useState12(false);
@@ -4160,7 +4194,7 @@ function AccountView() {
4160
4194
  (degradation === "warning" || degradation === "limited") && license && /* @__PURE__ */ jsx30(Box28, { marginTop: 1, borderStyle: "round", borderColor: COLORS.warning, paddingX: 2, paddingY: 0, children: /* @__PURE__ */ jsx30(Text29, { color: COLORS.warning, children: t("license_offlineWarning", {
4161
4195
  days: Math.floor((Date.now() - new Date(license.lastValidatedAt).getTime()) / (24 * 60 * 60 * 1e3))
4162
4196
  }) }) }),
4163
- license && /* @__PURE__ */ jsxs29(Fragment6, { children: [
4197
+ license && /* @__PURE__ */ jsxs29(Fragment5, { children: [
4164
4198
  /* @__PURE__ */ jsxs29(Box28, { gap: 1, children: [
4165
4199
  /* @__PURE__ */ jsx30(Text29, { color: COLORS.muted, children: t("account_emailLabel") }),
4166
4200
  /* @__PURE__ */ jsx30(Text29, { children: license.customerEmail })
@@ -4245,7 +4279,7 @@ function AccountView() {
4245
4279
  /* @__PURE__ */ jsx30(Box28, { marginTop: 1, children: /* @__PURE__ */ jsxs29(Text29, { color: COLORS.textSecondary, children: [
4246
4280
  status === "pro" ? `d ${t("hint_deactivate")}` : "",
4247
4281
  " ",
4248
- t("app_version", { version: "0.3.5" })
4282
+ t("app_version", { version: "0.4.0" })
4249
4283
  ] }) })
4250
4284
  ] });
4251
4285
  }