pudu-ai 0.2.9 → 0.2.11

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 (2) hide show
  1. package/dist/cli/index.js +126 -170
  2. package/package.json +1 -1
package/dist/cli/index.js CHANGED
@@ -851,7 +851,7 @@ var en = {
851
851
  setupLinkNow: "installed \u2192 press 1/2/3 to link this model",
852
852
  setupInstallAgent: "not installed \u2192 press 1/2/3 to install via ollama launch (if eligible)",
853
853
  setupKeys: "Enter/I = pull model 1 OpenCode 2 Hermes 3 OpenClaw Esc = back",
854
- setupCta: "\u2192 Press [S] or [I] to INSTALL a recommended model and link OpenCode / Hermes / OpenClaw",
854
+ setupCta: "[S] Setup: install model + OpenCode / Hermes / OpenClaw",
855
855
  machine: "MACHINE",
856
856
  runtimes: "LOCAL AI RUNTIMES",
857
857
  installedModels: "INSTALLED MODELS",
@@ -1036,7 +1036,7 @@ var es = {
1036
1036
  setupLinkNow: "instalado \u2192 pulsa 1/2/3 para vincular este modelo",
1037
1037
  setupInstallAgent: "no instalado \u2192 pulsa 1/2/3 para instalar con ollama launch (si es elegible)",
1038
1038
  setupKeys: "Enter/I = descargar modelo 1 OpenCode 2 Hermes 3 OpenClaw Esc = atr\xE1s",
1039
- setupCta: "\u2192 Pulsa [S] o [I] para INSTALAR un modelo recomendado y vincular OpenCode / Hermes / OpenClaw",
1039
+ setupCta: "[S] Setup: instalar modelo + OpenCode / Hermes / OpenClaw",
1040
1040
  machine: "EQUIPO",
1041
1041
  runtimes: "RUNTIMES DE IA LOCAL",
1042
1042
  installedModels: "MODELOS INSTALADOS",
@@ -2014,16 +2014,6 @@ function memoryLabel(profile) {
2014
2014
  return profile.memory.unified ? "Unified Memory" : "RAM";
2015
2015
  }
2016
2016
 
2017
- // src/compatibility/types.ts
2018
- var GRADE_MEANING = {
2019
- S: "Excellent",
2020
- A: "Recommended",
2021
- B: "Good",
2022
- C: "Tight",
2023
- D: "CPU/offload",
2024
- F: "Not recommended"
2025
- };
2026
-
2027
2017
  // src/tui/theme.ts
2028
2018
  function gradeColor(grade) {
2029
2019
  if (grade === "S" || grade === "A") return "green";
@@ -2045,83 +2035,74 @@ function sparkline(values, width = 24) {
2045
2035
  return slice.map((v) => glyphs[Math.min(glyphs.length - 1, Math.floor(v / max * (glyphs.length - 1)))]).join("").padStart(width, glyphs[0]);
2046
2036
  }
2047
2037
 
2038
+ // src/tui/width.ts
2039
+ import { useStdout } from "ink";
2040
+ function useCols() {
2041
+ const { stdout } = useStdout();
2042
+ const cols = stdout?.columns ?? 80;
2043
+ return Math.max(40, Math.min(cols - 2, 100));
2044
+ }
2045
+ function fit(text, width) {
2046
+ if (text.length <= width) return text;
2047
+ if (width <= 1) return "\u2026";
2048
+ return `${text.slice(0, width - 1)}\u2026`;
2049
+ }
2050
+
2048
2051
  // src/tui/views/Dashboard.tsx
2049
2052
  import { jsx, jsxs } from "react/jsx-runtime";
2050
2053
  function Dashboard({ session }) {
2054
+ const cols = useCols();
2051
2055
  const h = session.hardware;
2052
- return /* @__PURE__ */ jsxs(Box, { flexDirection: "column", children: [
2053
- /* @__PURE__ */ jsx(Text, { dimColor: true, children: t("aboutDashboard") }),
2056
+ const line = fit(
2057
+ `${h.machineModel ?? t("unknownMachine")} \xB7 ${h.cpu.name ?? t("cpuNa")} \xB7 ${formatBytes(h.memory.totalBytes, 0)} ${memoryLabel(h)}`,
2058
+ cols
2059
+ );
2060
+ return /* @__PURE__ */ jsxs(Box, { flexDirection: "column", width: cols, children: [
2054
2061
  /* @__PURE__ */ jsx(Text, { bold: true, color: "cyan", children: t("machine") }),
2055
- /* @__PURE__ */ jsx(Text, { children: h.machineModel ?? t("unknownMachine") }),
2056
- /* @__PURE__ */ jsx(Text, { children: h.cpu.name ?? t("cpuNa") }),
2057
- /* @__PURE__ */ jsxs(Text, { children: [
2058
- "CPU ",
2059
- h.cpu.physicalCores ?? "N/A",
2060
- " cores",
2061
- h.cpu.performanceCores ? ` (${h.cpu.performanceCores}P/${h.cpu.efficiencyCores ?? "?"}E)` : ""
2062
- ] }),
2063
- /* @__PURE__ */ jsxs(Text, { children: [
2064
- "GPU ",
2065
- h.gpu.name ?? "N/A"
2066
- ] }),
2067
- /* @__PURE__ */ jsxs(Text, { children: [
2068
- memoryLabel(h).padEnd(13),
2069
- " ",
2070
- formatBytes(h.memory.totalBytes, 0)
2071
- ] }),
2072
- /* @__PURE__ */ jsxs(Text, { children: [
2073
- "Available ",
2074
- h.memory.availableBytes ? formatBytes(h.memory.availableBytes) : "N/A"
2075
- ] }),
2076
- /* @__PURE__ */ jsxs(Text, { children: [
2077
- h.os,
2078
- " ",
2079
- h.osVersion ?? h.arch
2080
- ] }),
2081
- /* @__PURE__ */ jsxs(Box, { marginTop: 1, flexDirection: "column", children: [
2082
- /* @__PURE__ */ jsx(Text, { bold: true, color: "cyan", children: t("runtimes") }),
2083
- session.runtimes.map((r) => /* @__PURE__ */ jsxs(Text, { color: r.detected ? "green" : "gray", children: [
2084
- r.detected ? "\u2713" : "\u25CB",
2085
- " ",
2086
- r.label.padEnd(14),
2087
- " ",
2088
- r.detected ? r.version ?? t("detected") : t("notDetected")
2089
- ] }, r.id))
2090
- ] }),
2091
- /* @__PURE__ */ jsxs(Box, { marginTop: 1, flexDirection: "column", children: [
2092
- /* @__PURE__ */ jsx(Text, { bold: true, color: "cyan", children: t("installedModels") }),
2093
- session.rows.length === 0 && /* @__PURE__ */ jsx(Text, { dimColor: true, children: t("noModels") }),
2094
- session.rows.map((row) => /* @__PURE__ */ jsxs(Text, { children: [
2095
- /* @__PURE__ */ jsx(Text, { color: "green", children: row.local.name.padEnd(20) }),
2096
- " ",
2097
- row.local.sizeBytes ? formatBytes(row.local.sizeBytes) : "N/A",
2098
- " ",
2099
- /* @__PURE__ */ jsx(Text, { color: gradeColor(row.compatibility?.grade), bold: true, children: row.compatibility?.grade ?? "\u2014" }),
2062
+ /* @__PURE__ */ jsx(Text, { children: line }),
2063
+ /* @__PURE__ */ jsx(Text, { children: session.runtimes.map((r, i) => /* @__PURE__ */ jsxs(Text, { color: r.detected ? "green" : "gray", children: [
2064
+ i ? " " : "",
2065
+ r.detected ? "\u2713" : "\u25CB",
2066
+ r.label
2067
+ ] }, r.id)) }),
2068
+ /* @__PURE__ */ jsx(Text, { bold: true, color: "cyan", children: t("installedModels") }),
2069
+ session.rows.length === 0 && /* @__PURE__ */ jsx(Text, { dimColor: true, children: t("noModels") }),
2070
+ session.rows.slice(0, 6).map((row) => /* @__PURE__ */ jsxs(Text, { children: [
2071
+ /* @__PURE__ */ jsx(Text, { color: "green", children: fit(row.local.name, 18) }),
2072
+ /* @__PURE__ */ jsx(Text, { children: " " }),
2073
+ /* @__PURE__ */ jsx(Text, { color: gradeColor(row.compatibility?.grade), children: row.compatibility?.grade ?? "\u2014" }),
2074
+ /* @__PURE__ */ jsxs(Text, { dimColor: true, children: [
2100
2075
  " ",
2101
2076
  row.lastBenchmark?.benchmark.generationTokensPerSecond ? formatTokensPerSec(row.lastBenchmark.benchmark.generationTokensPerSecond) : t("notTested")
2102
- ] }, row.local.id))
2103
- ] }),
2104
- /* @__PURE__ */ jsxs(Box, { marginTop: 1, flexDirection: "column", children: [
2105
- /* @__PURE__ */ jsx(Text, { bold: true, color: "cyan", children: t("recommended") }),
2106
- /* @__PURE__ */ jsx(Text, { dimColor: true, children: t("recommendedHint") }),
2107
- session.recommendations.map((rec) => /* @__PURE__ */ jsxs(Text, { children: [
2108
- /* @__PURE__ */ jsx(Text, { color: "magenta", children: rec.useCase.padEnd(12) }),
2109
- " ",
2110
- rec.model.name.padEnd(22),
2111
- " ",
2112
- /* @__PURE__ */ jsx(Text, { color: gradeColor(rec.grade), bold: true, children: rec.grade }),
2077
+ ] })
2078
+ ] }, row.local.id)),
2079
+ /* @__PURE__ */ jsx(Text, { bold: true, color: "cyan", children: t("recommended") }),
2080
+ session.recommendations.slice(0, 4).map((rec) => /* @__PURE__ */ jsxs(Text, { children: [
2081
+ /* @__PURE__ */ jsx(Text, { color: "magenta", children: fit(rec.useCase, 10) }),
2082
+ /* @__PURE__ */ jsxs(Text, { children: [
2113
2083
  " ",
2114
- GRADE_MEANING[rec.grade]
2115
- ] }, `${rec.useCase}-${rec.model.id}`)),
2116
- /* @__PURE__ */ jsx(Text, { dimColor: true, children: t("credits") }),
2117
- /* @__PURE__ */ jsx(Text, { bold: true, color: "yellow", children: t("setupCta") })
2118
- ] })
2084
+ fit(rec.model.name, 22),
2085
+ " "
2086
+ ] }),
2087
+ /* @__PURE__ */ jsx(Text, { color: gradeColor(rec.grade), children: rec.grade })
2088
+ ] }, `${rec.useCase}-${rec.model.id}`)),
2089
+ /* @__PURE__ */ jsx(Text, { color: "yellow", children: fit(t("setupCta"), cols) })
2119
2090
  ] });
2120
2091
  }
2121
2092
 
2122
2093
  // src/tui/views/Models.tsx
2123
2094
  import { Box as Box2, Text as Text2 } from "ink";
2124
2095
 
2096
+ // src/compatibility/types.ts
2097
+ var GRADE_MEANING = {
2098
+ S: "Excellent",
2099
+ A: "Recommended",
2100
+ B: "Good",
2101
+ C: "Tight",
2102
+ D: "CPU/offload",
2103
+ F: "Not recommended"
2104
+ };
2105
+
2125
2106
  // src/cli/color.ts
2126
2107
  var enabled = () => !process.env.NO_COLOR && process.stdout.isTTY;
2127
2108
  var wrap = (open, close = 39) => (text) => enabled() ? `\x1B[${open}m${text}\x1B[${close}m` : text;
@@ -2169,11 +2150,11 @@ function runtimesText(session) {
2169
2150
  function modelsText(session) {
2170
2151
  const lines = [bold(cyan(t("installedModels"))), dim("MODEL INSTALLED FIT EST. SPEED MEASURED")];
2171
2152
  for (const row of session.rows) {
2172
- const fit = row.compatibility?.grade ?? "\u2014";
2153
+ const fit2 = row.compatibility?.grade ?? "\u2014";
2173
2154
  const est = row.compatibility?.estimatedTokensPerSecond ? `~${formatNumber(row.compatibility.estimatedTokensPerSecond)} t/s` : "\u2014";
2174
2155
  const measured = row.lastBenchmark?.benchmark.generationTokensPerSecond ? formatTokensPerSec(row.lastBenchmark.benchmark.generationTokensPerSecond) : t("notTested");
2175
2156
  lines.push(
2176
- `${green(row.local.name.padEnd(22))} \u2713 ${gradeAnsi(fit).padEnd(9)} ${est.padEnd(14)} ${measured}`
2157
+ `${green(row.local.name.padEnd(22))} \u2713 ${gradeAnsi(fit2).padEnd(9)} ${est.padEnd(14)} ${measured}`
2177
2158
  );
2178
2159
  }
2179
2160
  lines.push("", t("compatible"));
@@ -2406,8 +2387,8 @@ function decideLaunch(session, id) {
2406
2387
  if (!candidates.length) {
2407
2388
  for (const model of session.catalog) {
2408
2389
  if (!useCaseOk(model.useCase, def.useCases)) continue;
2409
- const fit = localCompatibility(session.hardware, model);
2410
- if (!def.allowedGrades.includes(fit.grade)) continue;
2390
+ const fit2 = localCompatibility(session.hardware, model);
2391
+ if (!def.allowedGrades.includes(fit2.grade)) continue;
2411
2392
  const tag = resolveOllamaTag(model.id, model.name);
2412
2393
  if (!tag) continue;
2413
2394
  candidates.push({
@@ -2415,7 +2396,7 @@ function decideLaunch(session, id) {
2415
2396
  ollamaTag: tag,
2416
2397
  installed: false,
2417
2398
  origin: "estimated",
2418
- grade: fit.grade
2399
+ grade: fit2.grade
2419
2400
  });
2420
2401
  }
2421
2402
  }
@@ -2532,6 +2513,7 @@ var TOOLS = [
2532
2513
  { key: "3", id: "openclaw", label: "OpenClaw" }
2533
2514
  ];
2534
2515
  function RecommendView({ session }) {
2516
+ const cols = useCols();
2535
2517
  const { exit } = useApp();
2536
2518
  const [cursor, setCursor] = useState(0);
2537
2519
  const [log, setLog] = useState("");
@@ -2570,43 +2552,29 @@ function RecommendView({ session }) {
2570
2552
  });
2571
2553
  }
2572
2554
  });
2573
- return /* @__PURE__ */ jsxs4(Box4, { flexDirection: "column", children: [
2574
- /* @__PURE__ */ jsxs4(Box4, { borderStyle: "round", borderColor: "yellow", flexDirection: "column", paddingX: 1, marginBottom: 1, children: [
2575
- /* @__PURE__ */ jsx4(Text4, { bold: true, color: "yellow", children: t("setupTitle") }),
2576
- /* @__PURE__ */ jsx4(Text4, { children: t("setupIntro") })
2577
- ] }),
2578
- /* @__PURE__ */ jsx4(Text4, { bold: true, color: "cyan", children: t("setupStep1") }),
2579
- recs.length === 0 && /* @__PURE__ */ jsx4(Text4, { dimColor: true, children: t("installNone") }),
2555
+ const tag = rec ? resolveOllamaTag(rec.model.id, rec.model.name) : void 0;
2556
+ return /* @__PURE__ */ jsxs4(Box4, { flexDirection: "column", width: cols, children: [
2557
+ /* @__PURE__ */ jsx4(Text4, { bold: true, color: "yellow", children: fit(t("setupTitle"), cols) }),
2580
2558
  recs.map((item, i) => /* @__PURE__ */ jsxs4(Text4, { color: i === cursor ? "cyan" : void 0, children: [
2581
2559
  i === cursor ? "\u276F " : " ",
2582
- /* @__PURE__ */ jsx4(Text4, { color: "magenta", children: item.useCase.padEnd(12) }),
2583
- item.model.name.padEnd(22),
2584
- " ",
2585
- /* @__PURE__ */ jsx4(Text4, { color: gradeColor(item.grade), bold: true, children: item.grade }),
2560
+ fit(item.model.name, 20),
2586
2561
  " ",
2587
- GRADE_MEANING[item.grade],
2588
- " ",
2589
- /* @__PURE__ */ jsx4(Text4, { dimColor: true, children: resolveOllamaTag(item.model.id, item.model.name) ?? t("noOllamaTag", { model: item.model.name }) })
2590
- ] }, `${item.useCase}-${item.model.id}`)),
2591
- /* @__PURE__ */ jsxs4(Box4, { marginTop: 1, flexDirection: "column", children: [
2592
- /* @__PURE__ */ jsx4(Text4, { bold: true, color: "green", children: t("setupStep2") }),
2593
- /* @__PURE__ */ jsx4(Text4, { color: "green", children: t("setupInstallModel") })
2594
- ] }),
2595
- /* @__PURE__ */ jsxs4(Box4, { marginTop: 1, flexDirection: "column", children: [
2596
- /* @__PURE__ */ jsx4(Text4, { bold: true, color: "yellow", children: t("setupStep3") }),
2597
- session.agents.map((agent, index) => /* @__PURE__ */ jsxs4(Text4, { color: agent.detected ? "green" : "yellow", children: [
2598
- "[",
2599
- index + 1,
2600
- "] ",
2601
- agent.detected ? "\u2713" : "\u25CB",
2562
+ /* @__PURE__ */ jsx4(Text4, { color: gradeColor(item.grade), children: item.grade }),
2563
+ /* @__PURE__ */ jsxs4(Text4, { dimColor: true, children: [
2602
2564
  " ",
2603
- agent.label.padEnd(12),
2604
- " ",
2605
- agent.detected ? t("setupLinkNow") : t("setupInstallAgent")
2606
- ] }, agent.id))
2607
- ] }),
2608
- /* @__PURE__ */ jsx4(Box4, { marginTop: 1, children: /* @__PURE__ */ jsx4(Text4, { dimColor: true, children: t("setupKeys") }) }),
2609
- log ? /* @__PURE__ */ jsx4(Text4, { color: "green", children: log }) : null
2565
+ resolveOllamaTag(item.model.id, item.model.name) ?? "\u2014"
2566
+ ] })
2567
+ ] }, `${item.useCase}-${item.model.id}`)),
2568
+ /* @__PURE__ */ jsx4(Text4, { children: session.agents.map((agent, index) => /* @__PURE__ */ jsxs4(Text4, { color: agent.detected ? "green" : "gray", children: [
2569
+ index ? " " : "",
2570
+ "[",
2571
+ index + 1,
2572
+ "]",
2573
+ agent.detected ? "\u2713" : "\u25CB",
2574
+ agent.label
2575
+ ] }, agent.id)) }),
2576
+ /* @__PURE__ */ jsx4(Text4, { dimColor: true, children: fit(`Enter=pull ${tag ?? ""} 1/2/3=agent Esc=back`, cols) }),
2577
+ log ? /* @__PURE__ */ jsx4(Text4, { color: "green", children: fit(log, cols) }) : null
2610
2578
  ] });
2611
2579
  }
2612
2580
 
@@ -2929,13 +2897,13 @@ function planTasks(session, answers) {
2929
2897
  const catalogExtras = answers.scope === "all" ? session.catalog.filter((model) => !session.rows.some((row) => idsLikelyMatch(row.local.id, model.id))).map((model) => {
2930
2898
  const useCases = model.useCase ?? [];
2931
2899
  const kinds = answers.kinds.filter((kind) => kindMatches(kind, useCases));
2932
- const fit = localCompatibility(session.hardware, model);
2900
+ const fit2 = localCompatibility(session.hardware, model);
2933
2901
  return {
2934
2902
  modelId: model.id,
2935
2903
  modelName: model.name,
2936
2904
  installed: false,
2937
2905
  origin: "estimated",
2938
- grade: fit.grade,
2906
+ grade: fit2.grade,
2939
2907
  useCases,
2940
2908
  kinds
2941
2909
  };
@@ -3099,63 +3067,54 @@ function handleAppKey(screen, input, key) {
3099
3067
 
3100
3068
  // src/tui/Welcome.tsx
3101
3069
  import { Box as Box9, Text as Text9 } from "ink";
3102
- import { jsx as jsx9, jsxs as jsxs8 } from "react/jsx-runtime";
3103
- function Welcome({ compact = false }) {
3104
- if (compact) {
3105
- return /* @__PURE__ */ jsxs8(Box9, { marginBottom: 1, borderStyle: "round", borderColor: "cyan", paddingX: 1, children: [
3070
+ import { Fragment as Fragment2, jsx as jsx9, jsxs as jsxs8 } from "react/jsx-runtime";
3071
+ function Chrome() {
3072
+ const cols = useCols();
3073
+ const wide = cols >= 72;
3074
+ return /* @__PURE__ */ jsxs8(Box9, { flexDirection: "column", width: cols, marginBottom: 1, children: [
3075
+ /* @__PURE__ */ jsxs8(Text9, { children: [
3106
3076
  /* @__PURE__ */ jsx9(Text9, { bold: true, color: "cyan", children: t("appTitle") }),
3107
3077
  /* @__PURE__ */ jsx9(Text9, { color: "gray", children: " \xB7 " }),
3108
- /* @__PURE__ */ jsx9(Text9, { color: "magenta", children: t("byline") })
3109
- ] });
3110
- }
3111
- return /* @__PURE__ */ jsxs8(Box9, { flexDirection: "row", marginBottom: 1, children: [
3112
- /* @__PURE__ */ jsxs8(Box9, { flexDirection: "column", marginRight: 2, children: [
3113
- /* @__PURE__ */ jsx9(Text9, { color: "yellow", children: " \u2572" }),
3114
- /* @__PURE__ */ jsxs8(Text9, { children: [
3115
- /* @__PURE__ */ jsx9(Text9, { color: "cyan", children: " \u256D\u2500" }),
3116
- /* @__PURE__ */ jsx9(Text9, { color: "white", children: "\u25CF \u25CF" }),
3117
- /* @__PURE__ */ jsx9(Text9, { color: "cyan", children: "\u2500\u256E" })
3118
- ] }),
3119
- /* @__PURE__ */ jsxs8(Text9, { children: [
3120
- /* @__PURE__ */ jsx9(Text9, { color: "cyan", children: " \u2502 " }),
3121
- /* @__PURE__ */ jsx9(Text9, { color: "yellow", children: "\u25BD" }),
3122
- /* @__PURE__ */ jsx9(Text9, { color: "cyan", children: " \u2502" })
3123
- ] }),
3124
- /* @__PURE__ */ jsx9(Text9, { color: "cyan", children: " \u2570\u252C\u2500\u2500\u2500\u252C\u256F" }),
3125
- /* @__PURE__ */ jsx9(Text9, { color: "green", children: " uu uu" })
3078
+ /* @__PURE__ */ jsx9(Text9, { color: "magenta", children: t("byline") }),
3079
+ wide ? /* @__PURE__ */ jsxs8(Text9, { color: "gray", children: [
3080
+ " \xB7 ",
3081
+ fit(t("appSubtitle"), cols - 28)
3082
+ ] }) : null
3126
3083
  ] }),
3127
- /* @__PURE__ */ jsxs8(Box9, { flexDirection: "column", justifyContent: "center", children: [
3128
- /* @__PURE__ */ jsx9(Text9, { bold: true, color: "cyan", children: t("appTitle") }),
3129
- /* @__PURE__ */ jsx9(Text9, { color: "white", children: t("appSubtitle") }),
3130
- /* @__PURE__ */ jsx9(Text9, { color: "magenta", children: t("byline") })
3131
- ] })
3084
+ /* @__PURE__ */ jsx9(Text9, { children: wide ? /* @__PURE__ */ jsxs8(Fragment2, { children: [
3085
+ /* @__PURE__ */ jsx9(Text9, { color: "yellow", children: "[S] Setup" }),
3086
+ /* @__PURE__ */ jsx9(Text9, { children: " " }),
3087
+ /* @__PURE__ */ jsx9(Text9, { color: "green", children: "[B] Bench" }),
3088
+ /* @__PURE__ */ jsx9(Text9, { children: " " }),
3089
+ /* @__PURE__ */ jsx9(Text9, { color: "cyan", children: "[M] Models" }),
3090
+ /* @__PURE__ */ jsx9(Text9, { children: " " }),
3091
+ /* @__PURE__ */ jsx9(Text9, { color: "magenta", children: "[R] Rec" }),
3092
+ /* @__PURE__ */ jsx9(Text9, { children: " " }),
3093
+ /* @__PURE__ */ jsx9(Text9, { color: "blue", children: "[T] Tasks" }),
3094
+ /* @__PURE__ */ jsx9(Text9, { children: " " }),
3095
+ /* @__PURE__ */ jsx9(Text9, { children: "[H] HW" }),
3096
+ /* @__PURE__ */ jsx9(Text9, { children: " " }),
3097
+ /* @__PURE__ */ jsx9(Text9, { color: "green", children: "[C] Cmp" }),
3098
+ /* @__PURE__ */ jsx9(Text9, { children: " " }),
3099
+ /* @__PURE__ */ jsx9(Text9, { color: "cyan", children: "[L] Log" }),
3100
+ /* @__PURE__ */ jsx9(Text9, { children: " " }),
3101
+ /* @__PURE__ */ jsx9(Text9, { color: "red", children: "[Q] Quit" })
3102
+ ] }) : /* @__PURE__ */ jsxs8(Fragment2, { children: [
3103
+ /* @__PURE__ */ jsx9(Text9, { color: "yellow", children: "[S]" }),
3104
+ /* @__PURE__ */ jsx9(Text9, { color: "green", children: "[B]" }),
3105
+ /* @__PURE__ */ jsx9(Text9, { color: "cyan", children: "[M]" }),
3106
+ /* @__PURE__ */ jsx9(Text9, { color: "magenta", children: "[R]" }),
3107
+ /* @__PURE__ */ jsx9(Text9, { color: "blue", children: "[T]" }),
3108
+ /* @__PURE__ */ jsx9(Text9, { children: "[H]" }),
3109
+ /* @__PURE__ */ jsx9(Text9, { color: "green", children: "[C]" }),
3110
+ /* @__PURE__ */ jsx9(Text9, { color: "cyan", children: "[L]" }),
3111
+ /* @__PURE__ */ jsx9(Text9, { color: "red", children: "[Q]" })
3112
+ ] }) })
3132
3113
  ] });
3133
3114
  }
3134
- function ColorNav() {
3135
- return /* @__PURE__ */ jsx9(Box9, { marginTop: 1, borderStyle: "single", borderColor: "gray", paddingX: 1, children: /* @__PURE__ */ jsxs8(Text9, { children: [
3136
- /* @__PURE__ */ jsx9(Text9, { color: "yellow", bold: true, children: "[S]" }),
3137
- /* @__PURE__ */ jsx9(Text9, { color: "yellow", children: " Setup " }),
3138
- /* @__PURE__ */ jsx9(Text9, { color: "green", bold: true, children: "[B]" }),
3139
- /* @__PURE__ */ jsx9(Text9, { color: "green", children: " Bench " }),
3140
- /* @__PURE__ */ jsx9(Text9, { color: "cyan", bold: true, children: "[M]" }),
3141
- /* @__PURE__ */ jsx9(Text9, { color: "cyan", children: " Models " }),
3142
- /* @__PURE__ */ jsx9(Text9, { color: "magenta", bold: true, children: "[R]" }),
3143
- /* @__PURE__ */ jsx9(Text9, { color: "magenta", children: " Rec " }),
3144
- /* @__PURE__ */ jsx9(Text9, { color: "blue", bold: true, children: "[T]" }),
3145
- /* @__PURE__ */ jsx9(Text9, { color: "blue", children: " Tasks " }),
3146
- /* @__PURE__ */ jsx9(Text9, { color: "white", bold: true, children: "[H]" }),
3147
- /* @__PURE__ */ jsx9(Text9, { children: " HW " }),
3148
- /* @__PURE__ */ jsx9(Text9, { color: "green", bold: true, children: "[C]" }),
3149
- /* @__PURE__ */ jsx9(Text9, { color: "green", children: " Cmp " }),
3150
- /* @__PURE__ */ jsx9(Text9, { color: "cyan", bold: true, children: "[L]" }),
3151
- /* @__PURE__ */ jsx9(Text9, { color: "cyan", children: " Log " }),
3152
- /* @__PURE__ */ jsx9(Text9, { color: "red", bold: true, children: "[Q]" }),
3153
- /* @__PURE__ */ jsx9(Text9, { color: "red", children: " Quit" })
3154
- ] }) });
3155
- }
3156
3115
 
3157
3116
  // src/tui/App.tsx
3158
- import { Fragment as Fragment2, jsx as jsx10, jsxs as jsxs9 } from "react/jsx-runtime";
3117
+ import { jsx as jsx10, jsxs as jsxs9 } from "react/jsx-runtime";
3159
3118
  function App(props) {
3160
3119
  const { exit } = useApp2();
3161
3120
  const [screen, setScreen] = useState4(props.start ?? "home");
@@ -3172,11 +3131,8 @@ function App(props) {
3172
3131
  if (result.type === "home") setScreen("home");
3173
3132
  if (result.type === "screen") setScreen(result.screen);
3174
3133
  });
3175
- return /* @__PURE__ */ jsxs9(Box10, { flexDirection: "column", paddingX: 1, paddingTop: 0, paddingBottom: 1, children: [
3176
- screen !== "benchmark" && /* @__PURE__ */ jsxs9(Fragment2, { children: [
3177
- /* @__PURE__ */ jsx10(ColorNav, {}),
3178
- /* @__PURE__ */ jsx10(Welcome, { compact: true })
3179
- ] }),
3134
+ return /* @__PURE__ */ jsxs9(Box10, { flexDirection: "column", paddingX: 1, children: [
3135
+ screen !== "benchmark" && /* @__PURE__ */ jsx10(Chrome, {}),
3180
3136
  screen === "home" && /* @__PURE__ */ jsx10(Dashboard, { session: props.session }),
3181
3137
  screen === "models" && /* @__PURE__ */ jsx10(ModelsView, { session: props.session }),
3182
3138
  screen === "hardware" && /* @__PURE__ */ jsx10(HardwareView, { session: props.session }),
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "pudu-ai",
3
- "version": "0.2.9",
3
+ "version": "0.2.11",
4
4
  "description": "Pudu-AI — local AI hardware & benchmark lab for the terminal",
5
5
  "keywords": [
6
6
  "ai",