pudu-ai 0.2.11 → 0.2.13

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 +233 -177
  2. package/package.json +1 -1
package/dist/cli/index.js CHANGED
@@ -1985,11 +1985,11 @@ function setLogLevel(next) {
1985
1985
  import { render } from "ink";
1986
1986
 
1987
1987
  // src/tui/App.tsx
1988
- import { Box as Box10, useApp as useApp2, useInput as useInput4 } from "ink";
1989
- import { useMemo as useMemo2, useRef as useRef2, useState as useState4 } from "react";
1988
+ import { Box as Box11, useApp as useApp2, useInput as useInput4 } from "ink";
1989
+ import { useMemo as useMemo2, useRef as useRef2, useState as useState5 } from "react";
1990
1990
 
1991
1991
  // src/tui/views/Dashboard.tsx
1992
- import { Box, Text } from "ink";
1992
+ import { Box, Text as Text2 } from "ink";
1993
1993
 
1994
1994
  // src/shared/format.ts
1995
1995
  function formatNumber(value, digits = 1) {
@@ -2035,6 +2035,39 @@ function sparkline(values, width = 24) {
2035
2035
  return slice.map((v) => glyphs[Math.min(glyphs.length - 1, Math.floor(v / max * (glyphs.length - 1)))]).join("").padStart(width, glyphs[0]);
2036
2036
  }
2037
2037
 
2038
+ // src/tui/Typewriter.tsx
2039
+ import { Text } from "ink";
2040
+ import { useEffect, useState } from "react";
2041
+ import { jsx, jsxs } from "react/jsx-runtime";
2042
+ var finished = /* @__PURE__ */ new Set();
2043
+ function Typewriter(props) {
2044
+ const start = props.once && finished.has(props.text) ? props.text.length : 0;
2045
+ const [n, setN] = useState(start);
2046
+ useEffect(() => {
2047
+ if (props.once && finished.has(props.text)) {
2048
+ setN(props.text.length);
2049
+ return;
2050
+ }
2051
+ setN(0);
2052
+ }, [props.text, props.once]);
2053
+ useEffect(() => {
2054
+ if (n >= props.text.length) return;
2055
+ const timer = setTimeout(() => {
2056
+ setN((v) => {
2057
+ const next = v + 1;
2058
+ if (props.once && next >= props.text.length) finished.add(props.text);
2059
+ return next;
2060
+ });
2061
+ }, props.ms ?? 16);
2062
+ return () => clearTimeout(timer);
2063
+ }, [n, props.text, props.ms, props.once]);
2064
+ const done = n >= props.text.length;
2065
+ return /* @__PURE__ */ jsxs(Text, { color: props.color, dimColor: props.dimColor, bold: props.bold, children: [
2066
+ props.text.slice(0, n),
2067
+ done ? null : /* @__PURE__ */ jsx(Text, { color: "cyan", bold: true, children: "\u258D" })
2068
+ ] });
2069
+ }
2070
+
2038
2071
  // src/tui/width.ts
2039
2072
  import { useStdout } from "ink";
2040
2073
  function useCols() {
@@ -2049,7 +2082,7 @@ function fit(text, width) {
2049
2082
  }
2050
2083
 
2051
2084
  // src/tui/views/Dashboard.tsx
2052
- import { jsx, jsxs } from "react/jsx-runtime";
2085
+ import { jsx as jsx2, jsxs as jsxs2 } from "react/jsx-runtime";
2053
2086
  function Dashboard({ session }) {
2054
2087
  const cols = useCols();
2055
2088
  const h = session.hardware;
@@ -2057,41 +2090,41 @@ function Dashboard({ session }) {
2057
2090
  `${h.machineModel ?? t("unknownMachine")} \xB7 ${h.cpu.name ?? t("cpuNa")} \xB7 ${formatBytes(h.memory.totalBytes, 0)} ${memoryLabel(h)}`,
2058
2091
  cols
2059
2092
  );
2060
- return /* @__PURE__ */ jsxs(Box, { flexDirection: "column", width: cols, children: [
2061
- /* @__PURE__ */ jsx(Text, { bold: true, color: "cyan", children: t("machine") }),
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: [
2093
+ return /* @__PURE__ */ jsxs2(Box, { flexDirection: "column", width: cols, children: [
2094
+ /* @__PURE__ */ jsx2(Text2, { bold: true, color: "cyan", children: t("machine") }),
2095
+ /* @__PURE__ */ jsx2(Text2, { children: line }),
2096
+ /* @__PURE__ */ jsx2(Text2, { children: session.runtimes.map((r, i) => /* @__PURE__ */ jsxs2(Text2, { color: r.detected ? "green" : "gray", children: [
2064
2097
  i ? " " : "",
2065
2098
  r.detected ? "\u2713" : "\u25CB",
2066
2099
  r.label
2067
2100
  ] }, 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: [
2101
+ /* @__PURE__ */ jsx2(Text2, { bold: true, color: "cyan", children: t("installedModels") }),
2102
+ session.rows.length === 0 && /* @__PURE__ */ jsx2(Text2, { dimColor: true, children: t("noModels") }),
2103
+ session.rows.slice(0, 6).map((row) => /* @__PURE__ */ jsxs2(Text2, { children: [
2104
+ /* @__PURE__ */ jsx2(Text2, { color: "green", children: fit(row.local.name, 18) }),
2105
+ /* @__PURE__ */ jsx2(Text2, { children: " " }),
2106
+ /* @__PURE__ */ jsx2(Text2, { color: gradeColor(row.compatibility?.grade), children: row.compatibility?.grade ?? "\u2014" }),
2107
+ /* @__PURE__ */ jsxs2(Text2, { dimColor: true, children: [
2075
2108
  " ",
2076
2109
  row.lastBenchmark?.benchmark.generationTokensPerSecond ? formatTokensPerSec(row.lastBenchmark.benchmark.generationTokensPerSecond) : t("notTested")
2077
2110
  ] })
2078
2111
  ] }, 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: [
2112
+ /* @__PURE__ */ jsx2(Text2, { bold: true, color: "cyan", children: t("recommended") }),
2113
+ session.recommendations.slice(0, 4).map((rec) => /* @__PURE__ */ jsxs2(Text2, { children: [
2114
+ /* @__PURE__ */ jsx2(Text2, { color: "magenta", children: fit(rec.useCase, 10) }),
2115
+ /* @__PURE__ */ jsxs2(Text2, { children: [
2083
2116
  " ",
2084
2117
  fit(rec.model.name, 22),
2085
2118
  " "
2086
2119
  ] }),
2087
- /* @__PURE__ */ jsx(Text, { color: gradeColor(rec.grade), children: rec.grade })
2120
+ /* @__PURE__ */ jsx2(Text2, { color: gradeColor(rec.grade), children: rec.grade })
2088
2121
  ] }, `${rec.useCase}-${rec.model.id}`)),
2089
- /* @__PURE__ */ jsx(Text, { color: "yellow", children: fit(t("setupCta"), cols) })
2122
+ /* @__PURE__ */ jsx2(Typewriter, { text: fit(t("setupCta"), cols), ms: 18, color: "yellow" })
2090
2123
  ] });
2091
2124
  }
2092
2125
 
2093
2126
  // src/tui/views/Models.tsx
2094
- import { Box as Box2, Text as Text2 } from "ink";
2127
+ import { Box as Box2, Text as Text3 } from "ink";
2095
2128
 
2096
2129
  // src/compatibility/types.ts
2097
2130
  var GRADE_MEANING = {
@@ -2295,28 +2328,57 @@ function resultText(record, assessment) {
2295
2328
  }
2296
2329
 
2297
2330
  // src/tui/views/Models.tsx
2298
- import { jsx as jsx2, jsxs as jsxs2 } from "react/jsx-runtime";
2331
+ import { jsx as jsx3, jsxs as jsxs3 } from "react/jsx-runtime";
2299
2332
  function ModelsView({ session }) {
2300
- return /* @__PURE__ */ jsxs2(Box2, { flexDirection: "column", children: [
2301
- /* @__PURE__ */ jsx2(Text2, { children: modelsText(session) }),
2302
- /* @__PURE__ */ jsx2(Text2, { color: "yellow", children: t("modelsHint") })
2333
+ return /* @__PURE__ */ jsxs3(Box2, { flexDirection: "column", children: [
2334
+ /* @__PURE__ */ jsx3(Text3, { children: modelsText(session) }),
2335
+ /* @__PURE__ */ jsx3(Text3, { color: "yellow", children: t("modelsHint") })
2303
2336
  ] });
2304
2337
  }
2305
2338
 
2306
2339
  // src/tui/views/Hardware.tsx
2307
- import { Box as Box3, Text as Text3 } from "ink";
2308
- import { jsx as jsx3, jsxs as jsxs3 } from "react/jsx-runtime";
2340
+ import { Box as Box3, Text as Text4 } from "ink";
2341
+ import { jsx as jsx4, jsxs as jsxs4 } from "react/jsx-runtime";
2309
2342
  function HardwareView({ session }) {
2310
- return /* @__PURE__ */ jsxs3(Box3, { flexDirection: "column", children: [
2311
- /* @__PURE__ */ jsx3(Text3, { children: hardwareText(session) }),
2312
- /* @__PURE__ */ jsx3(Text3, { children: runtimesText(session) }),
2313
- /* @__PURE__ */ jsx3(Text3, { color: "yellow", children: t("hardwareHint") })
2343
+ return /* @__PURE__ */ jsxs4(Box3, { flexDirection: "column", children: [
2344
+ /* @__PURE__ */ jsx4(Text4, { children: hardwareText(session) }),
2345
+ /* @__PURE__ */ jsx4(Text4, { children: runtimesText(session) }),
2346
+ /* @__PURE__ */ jsx4(Text4, { color: "yellow", children: t("hardwareHint") })
2314
2347
  ] });
2315
2348
  }
2316
2349
 
2317
2350
  // src/tui/views/Recommend.tsx
2318
- import { Box as Box4, Text as Text4, useApp, useInput } from "ink";
2319
- import { useState } from "react";
2351
+ import { Box as Box4, Text as Text5 } from "ink";
2352
+ import { jsx as jsx5, jsxs as jsxs5 } from "react/jsx-runtime";
2353
+ function RecommendView({ session }) {
2354
+ const cols = useCols();
2355
+ return /* @__PURE__ */ jsxs5(Box4, { flexDirection: "column", width: cols, children: [
2356
+ /* @__PURE__ */ jsx5(Text5, { bold: true, color: "magenta", children: t("recommended") }),
2357
+ /* @__PURE__ */ jsx5(Typewriter, { text: fit(t("aboutRecommend"), cols), ms: 12, dimColor: true }),
2358
+ session.recommendations.map((rec) => /* @__PURE__ */ jsxs5(Text5, { children: [
2359
+ /* @__PURE__ */ jsx5(Text5, { color: "magenta", children: fit(rec.useCase, 10) }),
2360
+ /* @__PURE__ */ jsxs5(Text5, { children: [
2361
+ " ",
2362
+ fit(rec.model.name, 22),
2363
+ " "
2364
+ ] }),
2365
+ /* @__PURE__ */ jsx5(Text5, { color: gradeColor(rec.grade), children: rec.grade }),
2366
+ /* @__PURE__ */ jsxs5(Text5, { children: [
2367
+ " ",
2368
+ GRADE_MEANING[rec.grade]
2369
+ ] }),
2370
+ /* @__PURE__ */ jsxs5(Text5, { dimColor: true, children: [
2371
+ " ",
2372
+ resolveOllamaTag(rec.model.id, rec.model.name) ?? "\u2014"
2373
+ ] })
2374
+ ] }, `${rec.useCase}-${rec.model.id}`)),
2375
+ /* @__PURE__ */ jsx5(Text5, { color: "yellow", children: fit(t("setupCta"), cols) })
2376
+ ] });
2377
+ }
2378
+
2379
+ // src/tui/views/Setup.tsx
2380
+ import { Box as Box5, Text as Text6, useApp, useInput } from "ink";
2381
+ import { useState as useState2 } from "react";
2320
2382
 
2321
2383
  // src/integrations/catalog.ts
2322
2384
  var INTEGRATIONS = {
@@ -2505,19 +2567,19 @@ async function pullOllamaModel(modelId, extraName) {
2505
2567
  return { ok: true, log: t("modelPulled", { model: tag }), tag };
2506
2568
  }
2507
2569
 
2508
- // src/tui/views/Recommend.tsx
2509
- import { jsx as jsx4, jsxs as jsxs4 } from "react/jsx-runtime";
2570
+ // src/tui/views/Setup.tsx
2571
+ import { jsx as jsx6, jsxs as jsxs6 } from "react/jsx-runtime";
2510
2572
  var TOOLS = [
2511
2573
  { key: "1", id: "opencode", label: "OpenCode" },
2512
2574
  { key: "2", id: "hermes", label: "Hermes" },
2513
2575
  { key: "3", id: "openclaw", label: "OpenClaw" }
2514
2576
  ];
2515
- function RecommendView({ session }) {
2577
+ function SetupView({ session }) {
2516
2578
  const cols = useCols();
2517
2579
  const { exit } = useApp();
2518
- const [cursor, setCursor] = useState(0);
2519
- const [log, setLog] = useState("");
2520
- const [busy, setBusy] = useState(false);
2580
+ const [cursor, setCursor] = useState2(0);
2581
+ const [log, setLog] = useState2("");
2582
+ const [busy, setBusy] = useState2(false);
2521
2583
  const recs = session.recommendations;
2522
2584
  const rec = recs[cursor];
2523
2585
  useInput((input, key) => {
@@ -2553,19 +2615,19 @@ function RecommendView({ session }) {
2553
2615
  }
2554
2616
  });
2555
2617
  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) }),
2558
- recs.map((item, i) => /* @__PURE__ */ jsxs4(Text4, { color: i === cursor ? "cyan" : void 0, children: [
2618
+ return /* @__PURE__ */ jsxs6(Box5, { flexDirection: "column", width: cols, children: [
2619
+ /* @__PURE__ */ jsx6(Text6, { bold: true, color: "yellow", children: fit(t("setupTitle"), cols) }),
2620
+ recs.map((item, i) => /* @__PURE__ */ jsxs6(Text6, { color: i === cursor ? "cyan" : void 0, children: [
2559
2621
  i === cursor ? "\u276F " : " ",
2560
2622
  fit(item.model.name, 20),
2561
2623
  " ",
2562
- /* @__PURE__ */ jsx4(Text4, { color: gradeColor(item.grade), children: item.grade }),
2563
- /* @__PURE__ */ jsxs4(Text4, { dimColor: true, children: [
2624
+ /* @__PURE__ */ jsx6(Text6, { color: gradeColor(item.grade), children: item.grade }),
2625
+ /* @__PURE__ */ jsxs6(Text6, { dimColor: true, children: [
2564
2626
  " ",
2565
2627
  resolveOllamaTag(item.model.id, item.model.name) ?? "\u2014"
2566
2628
  ] })
2567
2629
  ] }, `${item.useCase}-${item.model.id}`)),
2568
- /* @__PURE__ */ jsx4(Text4, { children: session.agents.map((agent, index) => /* @__PURE__ */ jsxs4(Text4, { color: agent.detected ? "green" : "gray", children: [
2630
+ /* @__PURE__ */ jsx6(Text6, { children: session.agents.map((agent, index) => /* @__PURE__ */ jsxs6(Text6, { color: agent.detected ? "green" : "gray", children: [
2569
2631
  index ? " " : "",
2570
2632
  "[",
2571
2633
  index + 1,
@@ -2573,28 +2635,28 @@ function RecommendView({ session }) {
2573
2635
  agent.detected ? "\u2713" : "\u25CB",
2574
2636
  agent.label
2575
2637
  ] }, 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
2638
+ /* @__PURE__ */ jsx6(Typewriter, { text: fit(`Enter=pull ${tag ?? ""} 1/2/3=agent Esc=back`, cols), ms: 14, dimColor: true }),
2639
+ log ? /* @__PURE__ */ jsx6(Text6, { color: "green", children: fit(log, cols) }) : null
2578
2640
  ] });
2579
2641
  }
2580
2642
 
2581
2643
  // src/tui/views/Compare.tsx
2582
- import { Box as Box5, Text as Text5 } from "ink";
2583
- import { jsx as jsx5 } from "react/jsx-runtime";
2644
+ import { Box as Box6, Text as Text7 } from "ink";
2645
+ import { jsx as jsx7 } from "react/jsx-runtime";
2584
2646
  function CompareView({ session }) {
2585
- return /* @__PURE__ */ jsx5(Box5, { flexDirection: "column", children: /* @__PURE__ */ jsx5(Text5, { children: compareText(session.history) }) });
2647
+ return /* @__PURE__ */ jsx7(Box6, { flexDirection: "column", children: /* @__PURE__ */ jsx7(Text7, { children: compareText(session.history) }) });
2586
2648
  }
2587
2649
 
2588
2650
  // src/tui/views/Benchmark.tsx
2589
- import { Box as Box6, Text as Text6, useInput as useInput2 } from "ink";
2590
- import { useEffect, useRef, useState as useState2 } from "react";
2591
- import { jsx as jsx6, jsxs as jsxs5 } from "react/jsx-runtime";
2651
+ import { Box as Box7, Text as Text8, useInput as useInput2 } from "ink";
2652
+ import { useEffect as useEffect2, useRef, useState as useState3 } from "react";
2653
+ import { jsx as jsx8, jsxs as jsxs7 } from "react/jsx-runtime";
2592
2654
  function BenchmarkView(props) {
2593
- const [phase, setPhase] = useState2(props.models.length ? "select" : "error");
2594
- const [sample, setSample] = useState2();
2595
- const [elapsed, setElapsed] = useState2(0);
2596
- const [result, setResult] = useState2();
2597
- const [error, setError] = useState2(props.models.length ? "" : t("noGguf"));
2655
+ const [phase, setPhase] = useState3(props.models.length ? "select" : "error");
2656
+ const [sample, setSample] = useState3();
2657
+ const [elapsed, setElapsed] = useState3(0);
2658
+ const [result, setResult] = useState3();
2659
+ const [error, setError] = useState3(props.models.length ? "" : t("noGguf"));
2598
2660
  const cpuHist = useRef([]);
2599
2661
  const memHist = useRef([]);
2600
2662
  const abortRef = useRef(void 0);
@@ -2610,7 +2672,7 @@ function BenchmarkView(props) {
2610
2672
  props.onBack();
2611
2673
  }
2612
2674
  });
2613
- useEffect(() => {
2675
+ useEffect2(() => {
2614
2676
  if (phase !== "running") return;
2615
2677
  const model2 = props.models[props.selected];
2616
2678
  if (!model2) return;
@@ -2648,19 +2710,19 @@ function BenchmarkView(props) {
2648
2710
  const h = props.session.hardware;
2649
2711
  const model = props.models[props.selected];
2650
2712
  if (phase === "select") {
2651
- return /* @__PURE__ */ jsxs5(Box6, { flexDirection: "column", children: [
2652
- /* @__PURE__ */ jsx6(Text6, { bold: true, children: t("selectBenchmark") }),
2653
- props.models.map((m, i) => /* @__PURE__ */ jsxs5(Text6, { color: i === props.selected ? "cyan" : void 0, children: [
2713
+ return /* @__PURE__ */ jsxs7(Box7, { flexDirection: "column", children: [
2714
+ /* @__PURE__ */ jsx8(Text8, { bold: true, children: t("selectBenchmark") }),
2715
+ props.models.map((m, i) => /* @__PURE__ */ jsxs7(Text8, { color: i === props.selected ? "cyan" : void 0, children: [
2654
2716
  i === props.selected ? "\u276F " : " ",
2655
2717
  m.name
2656
2718
  ] }, m.id)),
2657
- /* @__PURE__ */ jsx6(Text6, { dimColor: true, children: t("enterToRun") })
2719
+ /* @__PURE__ */ jsx8(Text8, { dimColor: true, children: t("enterToRun") })
2658
2720
  ] });
2659
2721
  }
2660
2722
  if (phase === "done" && result) {
2661
- return /* @__PURE__ */ jsxs5(Box6, { flexDirection: "column", children: [
2662
- /* @__PURE__ */ jsx6(Text6, { children: resultText(result.record, result.assessment) }),
2663
- /* @__PURE__ */ jsxs5(Text6, { dimColor: true, children: [
2723
+ return /* @__PURE__ */ jsxs7(Box7, { flexDirection: "column", children: [
2724
+ /* @__PURE__ */ jsx8(Text8, { children: resultText(result.record, result.assessment) }),
2725
+ /* @__PURE__ */ jsxs7(Text8, { dimColor: true, children: [
2664
2726
  t("saved"),
2665
2727
  " ",
2666
2728
  result.path
@@ -2668,17 +2730,17 @@ function BenchmarkView(props) {
2668
2730
  ] });
2669
2731
  }
2670
2732
  if (phase === "error") {
2671
- return /* @__PURE__ */ jsx6(Box6, { flexDirection: "column", children: /* @__PURE__ */ jsx6(Text6, { color: "red", children: error }) });
2733
+ return /* @__PURE__ */ jsx8(Box7, { flexDirection: "column", children: /* @__PURE__ */ jsx8(Text8, { color: "red", children: error }) });
2672
2734
  }
2673
2735
  const cpu = sample?.cpu?.utilizationPercent;
2674
2736
  const gpu = sample?.gpu?.utilizationPercent;
2675
2737
  const memUsed = sample?.memory.usedBytes;
2676
2738
  const memTotal = h.memory.totalBytes;
2677
- return /* @__PURE__ */ jsxs5(Box6, { flexDirection: "column", children: [
2678
- /* @__PURE__ */ jsxs5(Box6, { borderStyle: "round", borderColor: "cyan", flexDirection: "column", paddingX: 1, children: [
2679
- /* @__PURE__ */ jsx6(Text6, { bold: true, children: t("benchmarkTitle") }),
2680
- /* @__PURE__ */ jsx6(Text6, { children: model?.name }),
2681
- /* @__PURE__ */ jsxs5(Text6, { dimColor: true, children: [
2739
+ return /* @__PURE__ */ jsxs7(Box7, { flexDirection: "column", children: [
2740
+ /* @__PURE__ */ jsxs7(Box7, { borderStyle: "round", borderColor: "cyan", flexDirection: "column", paddingX: 1, children: [
2741
+ /* @__PURE__ */ jsx8(Text8, { bold: true, children: t("benchmarkTitle") }),
2742
+ /* @__PURE__ */ jsx8(Text8, { children: model?.name }),
2743
+ /* @__PURE__ */ jsxs7(Text8, { dimColor: true, children: [
2682
2744
  h.cpu.name,
2683
2745
  " \xB7 ",
2684
2746
  formatBytes(h.memory.totalBytes, 0),
@@ -2686,31 +2748,31 @@ function BenchmarkView(props) {
2686
2748
  memoryLabel(h)
2687
2749
  ] })
2688
2750
  ] }),
2689
- /* @__PURE__ */ jsxs5(Box6, { marginTop: 1, flexDirection: "column", children: [
2690
- /* @__PURE__ */ jsx6(Text6, { bold: true, color: "cyan", children: t("performance") }),
2691
- /* @__PURE__ */ jsxs5(Text6, { children: [
2751
+ /* @__PURE__ */ jsxs7(Box7, { marginTop: 1, flexDirection: "column", children: [
2752
+ /* @__PURE__ */ jsx8(Text8, { bold: true, color: "cyan", children: t("performance") }),
2753
+ /* @__PURE__ */ jsxs7(Text8, { children: [
2692
2754
  t("elapsed"),
2693
2755
  " ",
2694
2756
  elapsed.toFixed(1),
2695
2757
  " s"
2696
2758
  ] }),
2697
- /* @__PURE__ */ jsx6(Text6, { dimColor: true, children: t("measuredAfter") })
2759
+ /* @__PURE__ */ jsx8(Text8, { dimColor: true, children: t("measuredAfter") })
2698
2760
  ] }),
2699
- /* @__PURE__ */ jsxs5(Box6, { marginTop: 1, flexDirection: "column", children: [
2700
- /* @__PURE__ */ jsx6(Text6, { bold: true, color: "cyan", children: t("system") }),
2701
- /* @__PURE__ */ jsxs5(Text6, { children: [
2761
+ /* @__PURE__ */ jsxs7(Box7, { marginTop: 1, flexDirection: "column", children: [
2762
+ /* @__PURE__ */ jsx8(Text8, { bold: true, color: "cyan", children: t("system") }),
2763
+ /* @__PURE__ */ jsxs7(Text8, { children: [
2702
2764
  "CPU ",
2703
2765
  bar(cpu),
2704
2766
  " ",
2705
2767
  formatPercent(cpu)
2706
2768
  ] }),
2707
- /* @__PURE__ */ jsxs5(Text6, { children: [
2769
+ /* @__PURE__ */ jsxs7(Text8, { children: [
2708
2770
  "GPU ",
2709
2771
  bar(gpu),
2710
2772
  " ",
2711
2773
  formatPercent(gpu)
2712
2774
  ] }),
2713
- /* @__PURE__ */ jsxs5(Text6, { children: [
2775
+ /* @__PURE__ */ jsxs7(Text8, { children: [
2714
2776
  "Memory ",
2715
2777
  bar(memUsed && memTotal ? memUsed / memTotal * 100 : void 0),
2716
2778
  " ",
@@ -2718,56 +2780,56 @@ function BenchmarkView(props) {
2718
2780
  " / ",
2719
2781
  formatBytes(memTotal, 0)
2720
2782
  ] }),
2721
- /* @__PURE__ */ jsxs5(Text6, { children: [
2783
+ /* @__PURE__ */ jsxs7(Text8, { children: [
2722
2784
  "Swap ",
2723
2785
  bar(0),
2724
2786
  " ",
2725
2787
  sample ? formatBytes(sample.memory.swapUsedBytes) : "N/A"
2726
2788
  ] })
2727
2789
  ] }),
2728
- /* @__PURE__ */ jsxs5(Box6, { marginTop: 1, flexDirection: "column", children: [
2729
- /* @__PURE__ */ jsx6(Text6, { bold: true, color: "cyan", children: t("powerThermals") }),
2730
- /* @__PURE__ */ jsxs5(Text6, { children: [
2790
+ /* @__PURE__ */ jsxs7(Box7, { marginTop: 1, flexDirection: "column", children: [
2791
+ /* @__PURE__ */ jsx8(Text8, { bold: true, color: "cyan", children: t("powerThermals") }),
2792
+ /* @__PURE__ */ jsxs7(Text8, { children: [
2731
2793
  "Package ",
2732
2794
  sample?.packagePowerWatts ?? "N/A",
2733
2795
  " W"
2734
2796
  ] }),
2735
- /* @__PURE__ */ jsxs5(Text6, { children: [
2797
+ /* @__PURE__ */ jsxs7(Text8, { children: [
2736
2798
  "Temperature ",
2737
2799
  sample?.thermal?.temperatureC ?? "N/A",
2738
2800
  " \xB0C"
2739
2801
  ] }),
2740
- /* @__PURE__ */ jsxs5(Text6, { children: [
2802
+ /* @__PURE__ */ jsxs7(Text8, { children: [
2741
2803
  "Thermal Pressure ",
2742
2804
  sample?.thermal?.pressure ?? "N/A"
2743
2805
  ] }),
2744
- /* @__PURE__ */ jsx6(Text6, { dimColor: true, children: t("permissionsHint") })
2806
+ /* @__PURE__ */ jsx8(Text8, { dimColor: true, children: t("permissionsHint") })
2745
2807
  ] }),
2746
- /* @__PURE__ */ jsxs5(Text6, { children: [
2808
+ /* @__PURE__ */ jsxs7(Text8, { children: [
2747
2809
  sparkline(cpuHist.current),
2748
2810
  " CPU"
2749
2811
  ] }),
2750
- /* @__PURE__ */ jsxs5(Text6, { children: [
2812
+ /* @__PURE__ */ jsxs7(Text8, { children: [
2751
2813
  sparkline(memHist.current.map((v) => v / 1024 ** 3)),
2752
2814
  " Memory"
2753
2815
  ] }),
2754
- /* @__PURE__ */ jsx6(Text6, { dimColor: true, children: t("cancelHint") })
2816
+ /* @__PURE__ */ jsx8(Text8, { dimColor: true, children: t("cancelHint") })
2755
2817
  ] });
2756
2818
  }
2757
2819
 
2758
2820
  // src/tui/views/History.tsx
2759
- import { Box as Box7, Text as Text7 } from "ink";
2760
- import { jsx as jsx7, jsxs as jsxs6 } from "react/jsx-runtime";
2821
+ import { Box as Box8, Text as Text9 } from "ink";
2822
+ import { jsx as jsx9, jsxs as jsxs8 } from "react/jsx-runtime";
2761
2823
  function HistoryView({ session }) {
2762
- return /* @__PURE__ */ jsxs6(Box7, { flexDirection: "column", children: [
2763
- /* @__PURE__ */ jsx7(Text7, { bold: true, color: "cyan", children: t("measured") }),
2764
- /* @__PURE__ */ jsx7(Text7, { children: historyText(session.history) })
2824
+ return /* @__PURE__ */ jsxs8(Box8, { flexDirection: "column", children: [
2825
+ /* @__PURE__ */ jsx9(Text9, { bold: true, color: "cyan", children: t("measured") }),
2826
+ /* @__PURE__ */ jsx9(Text9, { children: historyText(session.history) })
2765
2827
  ] });
2766
2828
  }
2767
2829
 
2768
2830
  // src/tui/views/Tasks.tsx
2769
- import { Box as Box8, Text as Text8, useInput as useInput3 } from "ink";
2770
- import { useMemo, useState as useState3 } from "react";
2831
+ import { Box as Box9, Text as Text10, useInput as useInput3 } from "ink";
2832
+ import { useMemo, useState as useState4 } from "react";
2771
2833
 
2772
2834
  // src/tasks/catalog.ts
2773
2835
  var TASK_CATALOG = [
@@ -2962,7 +3024,7 @@ function tasksText(plans, answers) {
2962
3024
  }
2963
3025
 
2964
3026
  // src/tui/views/Tasks.tsx
2965
- import { Fragment, jsx as jsx8, jsxs as jsxs7 } from "react/jsx-runtime";
3027
+ import { Fragment, jsx as jsx10, jsxs as jsxs9 } from "react/jsx-runtime";
2966
3028
  var KIND_LABEL = {
2967
3029
  code: "tasksOptCode",
2968
3030
  video: "tasksOptVideo",
@@ -2971,11 +3033,11 @@ var KIND_LABEL = {
2971
3033
  chat: "tasksOptChat"
2972
3034
  };
2973
3035
  function TasksView({ session }) {
2974
- const [step, setStep] = useState3(0);
2975
- const [cursor, setCursor] = useState3(0);
2976
- const [kinds, setKinds] = useState3(["code", "chat"]);
2977
- const [scope, setScope] = useState3("installed");
2978
- const [priority, setPriority] = useState3("balanced");
3036
+ const [step, setStep] = useState4(0);
3037
+ const [cursor, setCursor] = useState4(0);
3038
+ const [kinds, setKinds] = useState4(["code", "chat"]);
3039
+ const [scope, setScope] = useState4("installed");
3040
+ const [priority, setPriority] = useState4("balanced");
2979
3041
  const plans = useMemo(
2980
3042
  () => planTasks(session, { kinds, scope, priority }),
2981
3043
  [session, kinds, scope, priority]
@@ -3003,13 +3065,13 @@ function TasksView({ session }) {
3003
3065
  }
3004
3066
  });
3005
3067
  if (step === 3) {
3006
- return /* @__PURE__ */ jsx8(Box8, { flexDirection: "column", children: /* @__PURE__ */ jsx8(Text8, { children: tasksText(plans, { kinds, scope, priority }) }) });
3068
+ return /* @__PURE__ */ jsx10(Box9, { flexDirection: "column", children: /* @__PURE__ */ jsx10(Text10, { children: tasksText(plans, { kinds, scope, priority }) }) });
3007
3069
  }
3008
- return /* @__PURE__ */ jsxs7(Box8, { flexDirection: "column", children: [
3009
- /* @__PURE__ */ jsx8(Text8, { bold: true, color: "cyan", children: t("tasksTitle") }),
3010
- step === 0 && /* @__PURE__ */ jsxs7(Fragment, { children: [
3011
- /* @__PURE__ */ jsx8(Text8, { children: t("tasksQ1") }),
3012
- WORK_KINDS.map((kind, i) => /* @__PURE__ */ jsxs7(Text8, { color: i === cursor ? "cyan" : void 0, children: [
3070
+ return /* @__PURE__ */ jsxs9(Box9, { flexDirection: "column", children: [
3071
+ /* @__PURE__ */ jsx10(Text10, { bold: true, color: "cyan", children: t("tasksTitle") }),
3072
+ step === 0 && /* @__PURE__ */ jsxs9(Fragment, { children: [
3073
+ /* @__PURE__ */ jsx10(Text10, { children: t("tasksQ1") }),
3074
+ WORK_KINDS.map((kind, i) => /* @__PURE__ */ jsxs9(Text10, { color: i === cursor ? "cyan" : void 0, children: [
3013
3075
  i === cursor ? "\u276F " : " ",
3014
3076
  "[",
3015
3077
  kinds.includes(kind) ? "x" : " ",
@@ -3017,20 +3079,20 @@ function TasksView({ session }) {
3017
3079
  t(KIND_LABEL[kind])
3018
3080
  ] }, kind))
3019
3081
  ] }),
3020
- step === 1 && /* @__PURE__ */ jsxs7(Fragment, { children: [
3021
- /* @__PURE__ */ jsx8(Text8, { children: t("tasksQ2") }),
3022
- /* @__PURE__ */ jsxs7(Text8, { color: scope === "installed" ? "cyan" : void 0, children: [
3082
+ step === 1 && /* @__PURE__ */ jsxs9(Fragment, { children: [
3083
+ /* @__PURE__ */ jsx10(Text10, { children: t("tasksQ2") }),
3084
+ /* @__PURE__ */ jsxs9(Text10, { color: scope === "installed" ? "cyan" : void 0, children: [
3023
3085
  scope === "installed" ? "\u276F " : " ",
3024
3086
  t("tasksOptInstalled")
3025
3087
  ] }),
3026
- /* @__PURE__ */ jsxs7(Text8, { color: scope === "all" ? "cyan" : void 0, children: [
3088
+ /* @__PURE__ */ jsxs9(Text10, { color: scope === "all" ? "cyan" : void 0, children: [
3027
3089
  scope === "all" ? "\u276F " : " ",
3028
3090
  t("tasksOptAll")
3029
3091
  ] })
3030
3092
  ] }),
3031
- step === 2 && /* @__PURE__ */ jsxs7(Fragment, { children: [
3032
- /* @__PURE__ */ jsx8(Text8, { children: t("tasksQ3") }),
3033
- ["speed", "balanced", "quality"].map((item) => /* @__PURE__ */ jsxs7(Text8, { color: priority === item ? "cyan" : void 0, children: [
3093
+ step === 2 && /* @__PURE__ */ jsxs9(Fragment, { children: [
3094
+ /* @__PURE__ */ jsx10(Text10, { children: t("tasksQ3") }),
3095
+ ["speed", "balanced", "quality"].map((item) => /* @__PURE__ */ jsxs9(Text10, { color: priority === item ? "cyan" : void 0, children: [
3034
3096
  priority === item ? "\u276F " : " ",
3035
3097
  item === "speed" ? t("tasksOptSpeed") : item === "quality" ? t("tasksOptQuality") : t("tasksOptBalanced")
3036
3098
  ] }, item))
@@ -3047,7 +3109,7 @@ function globalNav(letter) {
3047
3109
  if (letter === "c") return { type: "screen", screen: "compare" };
3048
3110
  if (letter === "l") return { type: "screen", screen: "history" };
3049
3111
  if (letter === "t") return { type: "screen", screen: "tasks" };
3050
- if (letter === "s") return { type: "screen", screen: "recommend" };
3112
+ if (letter === "s") return { type: "screen", screen: "setup" };
3051
3113
  return void 0;
3052
3114
  }
3053
3115
  function handleAppKey(screen, input, key) {
@@ -3055,72 +3117,65 @@ function handleAppKey(screen, input, key) {
3055
3117
  if (screen === "benchmark") return { type: "ignore" };
3056
3118
  if (letter === "q") return { type: "quit" };
3057
3119
  if (key.escape) return screen === "home" ? { type: "quit" } : { type: "home" };
3058
- if (screen === "recommend") {
3120
+ if (screen === "setup") {
3059
3121
  if (letter === "i" || letter === "1" || letter === "2" || letter === "3") return { type: "ignore" };
3060
3122
  }
3061
3123
  const nav = globalNav(letter);
3062
3124
  if (nav) return nav;
3063
- if (letter === "i" && screen === "home") return { type: "screen", screen: "recommend" };
3125
+ if (letter === "i" && screen === "home") return { type: "screen", screen: "setup" };
3064
3126
  if (key.return && screen === "home") return { type: "screen", screen: "benchmark" };
3065
3127
  return { type: "ignore" };
3066
3128
  }
3067
3129
 
3068
3130
  // src/tui/Welcome.tsx
3069
- import { Box as Box9, Text as Text9 } from "ink";
3070
- import { Fragment as Fragment2, jsx as jsx9, jsxs as jsxs8 } from "react/jsx-runtime";
3131
+ import { Box as Box10, Text as Text11 } from "ink";
3132
+ import { Fragment as Fragment2, jsx as jsx11, jsxs as jsxs10 } from "react/jsx-runtime";
3071
3133
  function Chrome() {
3072
3134
  const cols = useCols();
3073
3135
  const wide = cols >= 72;
3074
- return /* @__PURE__ */ jsxs8(Box9, { flexDirection: "column", width: cols, marginBottom: 1, children: [
3075
- /* @__PURE__ */ jsxs8(Text9, { children: [
3076
- /* @__PURE__ */ jsx9(Text9, { bold: true, color: "cyan", children: t("appTitle") }),
3077
- /* @__PURE__ */ jsx9(Text9, { color: "gray", children: " \xB7 " }),
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
3083
- ] }),
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]" })
3136
+ const brand = `${t("appTitle")} ${t("byline")}`;
3137
+ return /* @__PURE__ */ jsxs10(Box10, { flexDirection: "column", width: cols, marginBottom: 1, children: [
3138
+ /* @__PURE__ */ jsx11(Typewriter, { text: brand, ms: 28, color: "cyan", bold: true, once: true }),
3139
+ /* @__PURE__ */ jsx11(Text11, { children: wide ? /* @__PURE__ */ jsxs10(Fragment2, { children: [
3140
+ /* @__PURE__ */ jsx11(Text11, { color: "yellow", children: "[S] Setup" }),
3141
+ /* @__PURE__ */ jsx11(Text11, { children: " " }),
3142
+ /* @__PURE__ */ jsx11(Text11, { color: "green", children: "[B] Bench" }),
3143
+ /* @__PURE__ */ jsx11(Text11, { children: " " }),
3144
+ /* @__PURE__ */ jsx11(Text11, { color: "cyan", children: "[M] Models" }),
3145
+ /* @__PURE__ */ jsx11(Text11, { children: " " }),
3146
+ /* @__PURE__ */ jsx11(Text11, { color: "magenta", children: "[R] Rec" }),
3147
+ /* @__PURE__ */ jsx11(Text11, { children: " " }),
3148
+ /* @__PURE__ */ jsx11(Text11, { color: "blue", children: "[T] Tasks" }),
3149
+ /* @__PURE__ */ jsx11(Text11, { children: " " }),
3150
+ /* @__PURE__ */ jsx11(Text11, { children: "[H] HW" }),
3151
+ /* @__PURE__ */ jsx11(Text11, { children: " " }),
3152
+ /* @__PURE__ */ jsx11(Text11, { color: "green", children: "[C] Cmp" }),
3153
+ /* @__PURE__ */ jsx11(Text11, { children: " " }),
3154
+ /* @__PURE__ */ jsx11(Text11, { color: "cyan", children: "[L] Log" }),
3155
+ /* @__PURE__ */ jsx11(Text11, { children: " " }),
3156
+ /* @__PURE__ */ jsx11(Text11, { color: "red", children: "[Q] Quit" })
3157
+ ] }) : /* @__PURE__ */ jsxs10(Fragment2, { children: [
3158
+ /* @__PURE__ */ jsx11(Text11, { color: "yellow", children: "[S]" }),
3159
+ /* @__PURE__ */ jsx11(Text11, { color: "green", children: "[B]" }),
3160
+ /* @__PURE__ */ jsx11(Text11, { color: "cyan", children: "[M]" }),
3161
+ /* @__PURE__ */ jsx11(Text11, { color: "magenta", children: "[R]" }),
3162
+ /* @__PURE__ */ jsx11(Text11, { color: "blue", children: "[T]" }),
3163
+ /* @__PURE__ */ jsx11(Text11, { children: "[H]" }),
3164
+ /* @__PURE__ */ jsx11(Text11, { color: "green", children: "[C]" }),
3165
+ /* @__PURE__ */ jsx11(Text11, { color: "cyan", children: "[L]" }),
3166
+ /* @__PURE__ */ jsx11(Text11, { color: "red", children: "[Q]" })
3112
3167
  ] }) })
3113
3168
  ] });
3114
3169
  }
3115
3170
 
3116
3171
  // src/tui/App.tsx
3117
- import { jsx as jsx10, jsxs as jsxs9 } from "react/jsx-runtime";
3172
+ import { jsx as jsx12, jsxs as jsxs11 } from "react/jsx-runtime";
3118
3173
  function App(props) {
3119
3174
  const { exit } = useApp2();
3120
- const [screen, setScreen] = useState4(props.start ?? "home");
3175
+ const [screen, setScreen] = useState5(props.start ?? "home");
3121
3176
  const screenRef = useRef2(screen);
3122
3177
  screenRef.current = screen;
3123
- const [selected, setSelected] = useState4(0);
3178
+ const [selected, setSelected] = useState5(0);
3124
3179
  const benchable = useMemo2(
3125
3180
  () => props.session.models.filter((m) => Boolean(m.artifactPath)),
3126
3181
  [props.session.models]
@@ -3131,16 +3186,17 @@ function App(props) {
3131
3186
  if (result.type === "home") setScreen("home");
3132
3187
  if (result.type === "screen") setScreen(result.screen);
3133
3188
  });
3134
- return /* @__PURE__ */ jsxs9(Box10, { flexDirection: "column", paddingX: 1, children: [
3135
- screen !== "benchmark" && /* @__PURE__ */ jsx10(Chrome, {}),
3136
- screen === "home" && /* @__PURE__ */ jsx10(Dashboard, { session: props.session }),
3137
- screen === "models" && /* @__PURE__ */ jsx10(ModelsView, { session: props.session }),
3138
- screen === "hardware" && /* @__PURE__ */ jsx10(HardwareView, { session: props.session }),
3139
- screen === "recommend" && /* @__PURE__ */ jsx10(RecommendView, { session: props.session }),
3140
- screen === "compare" && /* @__PURE__ */ jsx10(CompareView, { session: props.session }),
3141
- screen === "history" && /* @__PURE__ */ jsx10(HistoryView, { session: props.session }),
3142
- screen === "tasks" && /* @__PURE__ */ jsx10(TasksView, { session: props.session }),
3143
- screen === "benchmark" && /* @__PURE__ */ jsx10(
3189
+ return /* @__PURE__ */ jsxs11(Box11, { flexDirection: "column", paddingX: 1, children: [
3190
+ screen !== "benchmark" && /* @__PURE__ */ jsx12(Chrome, {}),
3191
+ screen === "home" && /* @__PURE__ */ jsx12(Dashboard, { session: props.session }),
3192
+ screen === "models" && /* @__PURE__ */ jsx12(ModelsView, { session: props.session }),
3193
+ screen === "hardware" && /* @__PURE__ */ jsx12(HardwareView, { session: props.session }),
3194
+ screen === "recommend" && /* @__PURE__ */ jsx12(RecommendView, { session: props.session }),
3195
+ screen === "setup" && /* @__PURE__ */ jsx12(SetupView, { session: props.session }),
3196
+ screen === "compare" && /* @__PURE__ */ jsx12(CompareView, { session: props.session }),
3197
+ screen === "history" && /* @__PURE__ */ jsx12(HistoryView, { session: props.session }),
3198
+ screen === "tasks" && /* @__PURE__ */ jsx12(TasksView, { session: props.session }),
3199
+ screen === "benchmark" && /* @__PURE__ */ jsx12(
3144
3200
  BenchmarkView,
3145
3201
  {
3146
3202
  session: props.session,
@@ -3155,9 +3211,9 @@ function App(props) {
3155
3211
  }
3156
3212
 
3157
3213
  // src/tui/render.tsx
3158
- import { jsx as jsx11 } from "react/jsx-runtime";
3214
+ import { jsx as jsx13 } from "react/jsx-runtime";
3159
3215
  async function renderDashboard(session, preset, start) {
3160
- const instance = render(/* @__PURE__ */ jsx11(App, { session, preset, start }));
3216
+ const instance = render(/* @__PURE__ */ jsx13(App, { session, preset, start }));
3161
3217
  await instance.waitUntilExit();
3162
3218
  }
3163
3219
 
@@ -3224,7 +3280,7 @@ ${runtimesText(session)}`),
3224
3280
  print({ recommendations: session.recommendations, agents: session.agents }, true);
3225
3281
  return 0;
3226
3282
  }
3227
- await renderDashboard(session, args2.preset, "recommend");
3283
+ await renderDashboard(session, args2.preset, "setup");
3228
3284
  return 0;
3229
3285
  case "recommend": {
3230
3286
  if (args2.install && args2.yes) {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "pudu-ai",
3
- "version": "0.2.11",
3
+ "version": "0.2.13",
4
4
  "description": "Pudu-AI — local AI hardware & benchmark lab for the terminal",
5
5
  "keywords": [
6
6
  "ai",