pudu-ai 0.2.12 → 0.2.14
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/dist/cli/index.js +263 -191
- package/package.json +1 -1
package/dist/cli/index.js
CHANGED
|
@@ -836,6 +836,10 @@ var en = {
|
|
|
836
836
|
aboutTasks: "Asks what you want (code, video, image, transcription, chat) and returns small OpenCode-style harnesses per model, in this language. Use it to try a model on one concrete job.",
|
|
837
837
|
aboutBenchmark: "Runs llama-bench on a local GGUF and records measured t/s plus system telemetry. Use it when you need real numbers, not estimates.",
|
|
838
838
|
aboutCompare: "Compares saved measured runs (speed, memory, power). Quality is never inferred from speed. Use it after two or more benchmarks.",
|
|
839
|
+
compareHow: "[C] Compare needs two measured llama-bench runs of different models. Press [B], pick a model, wait; repeat with another; then [C]. Quality is not a speed score.",
|
|
840
|
+
compareNeedBench: "Need 2+ measured models. Press [B] to benchmark first.",
|
|
841
|
+
reqOllama: "install: https://ollama.com/download or brew install ollama",
|
|
842
|
+
reqLmStudio: "install: https://lmstudio.ai",
|
|
839
843
|
aboutHistory: "Shows local benchmark files in ~/.pudu-ai/benchmarks. Use it to replay what this machine actually did.",
|
|
840
844
|
aboutDoctor: "Checks Node, Apple Silicon/Metal, Ollama, llama-bench, and the CanIRun API. Use it to see what is missing before a bench or launch.",
|
|
841
845
|
aboutReport: "Writes the latest measured run as Markdown. Use it to paste results into GitHub or notes.",
|
|
@@ -1021,6 +1025,10 @@ var es = {
|
|
|
1021
1025
|
aboutTasks: "Pregunta qu\xE9 quieres (c\xF3digo, v\xEDdeo, imagen, transcripci\xF3n, chat) y devuelve harnesses peque\xF1os estilo OpenCode por modelo, en este idioma. Sirve para probar un modelo en una tarea concreta.",
|
|
1022
1026
|
aboutBenchmark: "Ejecuta llama-bench sobre un GGUF local y guarda t/s medidos m\xE1s telemetr\xEDa. Sirve cuando necesitas n\xFAmeros reales, no estimaciones.",
|
|
1023
1027
|
aboutCompare: "Compara corridas medidas (velocidad, memoria, potencia). La calidad no se infiere de la velocidad. Sirve despu\xE9s de dos o m\xE1s benchmarks.",
|
|
1028
|
+
compareHow: "[C] Comparar necesita dos corridas medidas de llama-bench en modelos distintos. Pulsa [B], elige un modelo, espera; repite con otro; luego [C]. La calidad no es un score de velocidad.",
|
|
1029
|
+
compareNeedBench: "Hacen falta 2+ modelos medidos. Pulsa [B] para hacer un benchmark primero.",
|
|
1030
|
+
reqOllama: "instalar: https://ollama.com/download o brew install ollama",
|
|
1031
|
+
reqLmStudio: "instalar: https://lmstudio.ai",
|
|
1024
1032
|
aboutHistory: "Muestra los JSON locales en ~/.pudu-ai/benchmarks. Sirve para ver qu\xE9 hizo realmente esta m\xE1quina.",
|
|
1025
1033
|
aboutDoctor: "Revisa Node, Apple Silicon/Metal, Ollama, llama-bench y la API de CanIRun. Sirve para ver qu\xE9 falta antes de un bench o un launch.",
|
|
1026
1034
|
aboutReport: "Exporta la \xFAltima corrida medida en Markdown. Sirve para pegar resultados en GitHub o notas.",
|
|
@@ -1441,9 +1449,27 @@ async function listBenchmarks() {
|
|
|
1441
1449
|
|
|
1442
1450
|
// src/integrations/agents.ts
|
|
1443
1451
|
var AGENTS = [
|
|
1444
|
-
{
|
|
1445
|
-
|
|
1446
|
-
|
|
1452
|
+
{
|
|
1453
|
+
id: "opencode",
|
|
1454
|
+
label: "OpenCode",
|
|
1455
|
+
bin: "opencode",
|
|
1456
|
+
launch: "ollama launch opencode",
|
|
1457
|
+
docs: "https://docs.ollama.com/integrations/opencode"
|
|
1458
|
+
},
|
|
1459
|
+
{
|
|
1460
|
+
id: "hermes",
|
|
1461
|
+
label: "Hermes",
|
|
1462
|
+
bin: "hermes",
|
|
1463
|
+
launch: "ollama launch hermes",
|
|
1464
|
+
docs: "https://docs.ollama.com/integrations/hermes"
|
|
1465
|
+
},
|
|
1466
|
+
{
|
|
1467
|
+
id: "openclaw",
|
|
1468
|
+
label: "OpenClaw",
|
|
1469
|
+
bin: "openclaw",
|
|
1470
|
+
launch: "ollama launch openclaw",
|
|
1471
|
+
docs: "https://docs.ollama.com/integrations/openclaw"
|
|
1472
|
+
}
|
|
1447
1473
|
];
|
|
1448
1474
|
async function detectAgents() {
|
|
1449
1475
|
const out = [];
|
|
@@ -1986,10 +2012,10 @@ import { render } from "ink";
|
|
|
1986
2012
|
|
|
1987
2013
|
// src/tui/App.tsx
|
|
1988
2014
|
import { Box as Box11, useApp as useApp2, useInput as useInput4 } from "ink";
|
|
1989
|
-
import { useMemo as useMemo2, useRef as useRef2, useState as
|
|
2015
|
+
import { useMemo as useMemo2, useRef as useRef2, useState as useState5 } from "react";
|
|
1990
2016
|
|
|
1991
2017
|
// src/tui/views/Dashboard.tsx
|
|
1992
|
-
import { Box, Text } from "ink";
|
|
2018
|
+
import { Box, Text as Text2 } from "ink";
|
|
1993
2019
|
|
|
1994
2020
|
// src/shared/format.ts
|
|
1995
2021
|
function formatNumber(value, digits = 1) {
|
|
@@ -2035,6 +2061,39 @@ function sparkline(values, width = 24) {
|
|
|
2035
2061
|
return slice.map((v) => glyphs[Math.min(glyphs.length - 1, Math.floor(v / max * (glyphs.length - 1)))]).join("").padStart(width, glyphs[0]);
|
|
2036
2062
|
}
|
|
2037
2063
|
|
|
2064
|
+
// src/tui/Typewriter.tsx
|
|
2065
|
+
import { Text } from "ink";
|
|
2066
|
+
import { useEffect, useState } from "react";
|
|
2067
|
+
import { jsx, jsxs } from "react/jsx-runtime";
|
|
2068
|
+
var finished = /* @__PURE__ */ new Set();
|
|
2069
|
+
function Typewriter(props) {
|
|
2070
|
+
const start = props.once && finished.has(props.text) ? props.text.length : 0;
|
|
2071
|
+
const [n, setN] = useState(start);
|
|
2072
|
+
useEffect(() => {
|
|
2073
|
+
if (props.once && finished.has(props.text)) {
|
|
2074
|
+
setN(props.text.length);
|
|
2075
|
+
return;
|
|
2076
|
+
}
|
|
2077
|
+
setN(0);
|
|
2078
|
+
}, [props.text, props.once]);
|
|
2079
|
+
useEffect(() => {
|
|
2080
|
+
if (n >= props.text.length) return;
|
|
2081
|
+
const timer = setTimeout(() => {
|
|
2082
|
+
setN((v) => {
|
|
2083
|
+
const next = v + 1;
|
|
2084
|
+
if (props.once && next >= props.text.length) finished.add(props.text);
|
|
2085
|
+
return next;
|
|
2086
|
+
});
|
|
2087
|
+
}, props.ms ?? 16);
|
|
2088
|
+
return () => clearTimeout(timer);
|
|
2089
|
+
}, [n, props.text, props.ms, props.once]);
|
|
2090
|
+
const done = n >= props.text.length;
|
|
2091
|
+
return /* @__PURE__ */ jsxs(Text, { color: props.color, dimColor: props.dimColor, bold: props.bold, children: [
|
|
2092
|
+
props.text.slice(0, n),
|
|
2093
|
+
done ? null : /* @__PURE__ */ jsx(Text, { color: "cyan", bold: true, children: "\u258D" })
|
|
2094
|
+
] });
|
|
2095
|
+
}
|
|
2096
|
+
|
|
2038
2097
|
// src/tui/width.ts
|
|
2039
2098
|
import { useStdout } from "ink";
|
|
2040
2099
|
function useCols() {
|
|
@@ -2049,7 +2108,7 @@ function fit(text, width) {
|
|
|
2049
2108
|
}
|
|
2050
2109
|
|
|
2051
2110
|
// src/tui/views/Dashboard.tsx
|
|
2052
|
-
import { jsx, jsxs } from "react/jsx-runtime";
|
|
2111
|
+
import { jsx as jsx2, jsxs as jsxs2 } from "react/jsx-runtime";
|
|
2053
2112
|
function Dashboard({ session }) {
|
|
2054
2113
|
const cols = useCols();
|
|
2055
2114
|
const h = session.hardware;
|
|
@@ -2057,41 +2116,46 @@ function Dashboard({ session }) {
|
|
|
2057
2116
|
`${h.machineModel ?? t("unknownMachine")} \xB7 ${h.cpu.name ?? t("cpuNa")} \xB7 ${formatBytes(h.memory.totalBytes, 0)} ${memoryLabel(h)}`,
|
|
2058
2117
|
cols
|
|
2059
2118
|
);
|
|
2060
|
-
return /* @__PURE__ */
|
|
2061
|
-
/* @__PURE__ */
|
|
2062
|
-
/* @__PURE__ */
|
|
2063
|
-
/* @__PURE__ */
|
|
2119
|
+
return /* @__PURE__ */ jsxs2(Box, { flexDirection: "column", width: cols, children: [
|
|
2120
|
+
/* @__PURE__ */ jsx2(Text2, { bold: true, color: "cyan", children: t("machine") }),
|
|
2121
|
+
/* @__PURE__ */ jsx2(Text2, { children: line }),
|
|
2122
|
+
/* @__PURE__ */ jsx2(Text2, { children: session.runtimes.map((r, i) => /* @__PURE__ */ jsxs2(Text2, { color: r.detected ? "green" : "gray", children: [
|
|
2064
2123
|
i ? " " : "",
|
|
2065
2124
|
r.detected ? "\u2713" : "\u25CB",
|
|
2066
2125
|
r.label
|
|
2067
2126
|
] }, r.id)) }),
|
|
2068
|
-
/* @__PURE__ */
|
|
2069
|
-
session.rows.length === 0 && /* @__PURE__ */
|
|
2070
|
-
session.rows.slice(0, 6).map((row) => /* @__PURE__ */
|
|
2071
|
-
/* @__PURE__ */
|
|
2072
|
-
/* @__PURE__ */
|
|
2073
|
-
/* @__PURE__ */
|
|
2074
|
-
/* @__PURE__ */
|
|
2127
|
+
/* @__PURE__ */ jsx2(Text2, { bold: true, color: "cyan", children: t("installedModels") }),
|
|
2128
|
+
session.rows.length === 0 && /* @__PURE__ */ jsx2(Text2, { dimColor: true, children: t("noModels") }),
|
|
2129
|
+
session.rows.slice(0, 6).map((row) => /* @__PURE__ */ jsxs2(Text2, { children: [
|
|
2130
|
+
/* @__PURE__ */ jsx2(Text2, { color: "green", children: fit(row.local.name, 18) }),
|
|
2131
|
+
/* @__PURE__ */ jsx2(Text2, { children: " " }),
|
|
2132
|
+
/* @__PURE__ */ jsx2(Text2, { color: gradeColor(row.compatibility?.grade), children: row.compatibility?.grade ?? "\u2014" }),
|
|
2133
|
+
/* @__PURE__ */ jsxs2(Text2, { dimColor: true, children: [
|
|
2075
2134
|
" ",
|
|
2076
2135
|
row.lastBenchmark?.benchmark.generationTokensPerSecond ? formatTokensPerSec(row.lastBenchmark.benchmark.generationTokensPerSecond) : t("notTested")
|
|
2077
2136
|
] })
|
|
2078
2137
|
] }, row.local.id)),
|
|
2079
|
-
/* @__PURE__ */
|
|
2080
|
-
session.recommendations.slice(0, 4).map((rec) => /* @__PURE__ */
|
|
2081
|
-
/* @__PURE__ */
|
|
2082
|
-
/* @__PURE__ */
|
|
2138
|
+
/* @__PURE__ */ jsx2(Text2, { bold: true, color: "cyan", children: t("recommended") }),
|
|
2139
|
+
session.recommendations.slice(0, 4).map((rec) => /* @__PURE__ */ jsxs2(Text2, { children: [
|
|
2140
|
+
/* @__PURE__ */ jsx2(Text2, { color: "magenta", children: fit(rec.useCase, 10) }),
|
|
2141
|
+
/* @__PURE__ */ jsxs2(Text2, { children: [
|
|
2083
2142
|
" ",
|
|
2084
2143
|
fit(rec.model.name, 22),
|
|
2085
2144
|
" "
|
|
2086
2145
|
] }),
|
|
2087
|
-
/* @__PURE__ */
|
|
2146
|
+
/* @__PURE__ */ jsx2(Text2, { color: gradeColor(rec.grade), children: rec.grade })
|
|
2088
2147
|
] }, `${rec.useCase}-${rec.model.id}`)),
|
|
2089
|
-
/* @__PURE__ */
|
|
2148
|
+
/* @__PURE__ */ jsxs2(Text2, { children: [
|
|
2149
|
+
/* @__PURE__ */ jsx2(Text2, { color: session.runtimes.find((r) => r.id === "ollama")?.detected ? "green" : "yellow", children: session.runtimes.find((r) => r.id === "ollama")?.detected ? "\u2713 Ollama" : `\u25CB Ollama ${t("reqOllama")}` }),
|
|
2150
|
+
/* @__PURE__ */ jsx2(Text2, { children: " " }),
|
|
2151
|
+
/* @__PURE__ */ jsx2(Text2, { color: session.runtimes.find((r) => r.id === "lmstudio")?.detected ? "green" : "gray", children: session.runtimes.find((r) => r.id === "lmstudio")?.detected ? "\u2713 LM Studio" : `\u25CB LM Studio ${t("reqLmStudio")}` })
|
|
2152
|
+
] }),
|
|
2153
|
+
/* @__PURE__ */ jsx2(Typewriter, { text: fit(t("setupCta"), cols), ms: 18, color: "yellow" })
|
|
2090
2154
|
] });
|
|
2091
2155
|
}
|
|
2092
2156
|
|
|
2093
2157
|
// src/tui/views/Models.tsx
|
|
2094
|
-
import { Box as Box2, Text as
|
|
2158
|
+
import { Box as Box2, Text as Text3 } from "ink";
|
|
2095
2159
|
|
|
2096
2160
|
// src/compatibility/types.ts
|
|
2097
2161
|
var GRADE_MEANING = {
|
|
@@ -2214,7 +2278,11 @@ function doctorText(session) {
|
|
|
2214
2278
|
`${session.hardware.gpu.metal ? "\u2713" : "\u25CB"} Metal`,
|
|
2215
2279
|
...session.runtimes.map((r) => `${r.detected ? "\u2713" : "\u25CB"} ${r.label.padEnd(14)} ${r.version ?? ""}`.trimEnd()),
|
|
2216
2280
|
`${session.networkUsed ? "\u2713" : "\u25CB"} CanIRun.ai (midudev)`,
|
|
2217
|
-
...session.agents.map(
|
|
2281
|
+
...session.agents.map(
|
|
2282
|
+
(a) => `${a.detected ? "\u2713" : "\u25CB"} ${a.label.padEnd(14)} ${a.detected ? t("detected") : a.launch}`
|
|
2283
|
+
),
|
|
2284
|
+
...session.runtimes.find((r) => r.id === "ollama")?.detected ? [] : [`\u25CB Ollama ${t("reqOllama")}`],
|
|
2285
|
+
...session.runtimes.find((r) => r.id === "lmstudio")?.detected ? [] : [`\u25CB LM Studio ${t("reqLmStudio")}`],
|
|
2218
2286
|
"",
|
|
2219
2287
|
session.llamaBench ? t("doctorReady", { count: session.models.filter((m) => m.artifactPath).length }) : t("doctorNoBench")
|
|
2220
2288
|
];
|
|
@@ -2295,57 +2363,57 @@ function resultText(record, assessment) {
|
|
|
2295
2363
|
}
|
|
2296
2364
|
|
|
2297
2365
|
// src/tui/views/Models.tsx
|
|
2298
|
-
import { jsx as
|
|
2366
|
+
import { jsx as jsx3, jsxs as jsxs3 } from "react/jsx-runtime";
|
|
2299
2367
|
function ModelsView({ session }) {
|
|
2300
|
-
return /* @__PURE__ */
|
|
2301
|
-
/* @__PURE__ */
|
|
2302
|
-
/* @__PURE__ */
|
|
2368
|
+
return /* @__PURE__ */ jsxs3(Box2, { flexDirection: "column", children: [
|
|
2369
|
+
/* @__PURE__ */ jsx3(Text3, { children: modelsText(session) }),
|
|
2370
|
+
/* @__PURE__ */ jsx3(Text3, { color: "yellow", children: t("modelsHint") })
|
|
2303
2371
|
] });
|
|
2304
2372
|
}
|
|
2305
2373
|
|
|
2306
2374
|
// src/tui/views/Hardware.tsx
|
|
2307
|
-
import { Box as Box3, Text as
|
|
2308
|
-
import { jsx as
|
|
2375
|
+
import { Box as Box3, Text as Text4 } from "ink";
|
|
2376
|
+
import { jsx as jsx4, jsxs as jsxs4 } from "react/jsx-runtime";
|
|
2309
2377
|
function HardwareView({ session }) {
|
|
2310
|
-
return /* @__PURE__ */
|
|
2311
|
-
/* @__PURE__ */
|
|
2312
|
-
/* @__PURE__ */
|
|
2313
|
-
/* @__PURE__ */
|
|
2378
|
+
return /* @__PURE__ */ jsxs4(Box3, { flexDirection: "column", children: [
|
|
2379
|
+
/* @__PURE__ */ jsx4(Text4, { children: hardwareText(session) }),
|
|
2380
|
+
/* @__PURE__ */ jsx4(Text4, { children: runtimesText(session) }),
|
|
2381
|
+
/* @__PURE__ */ jsx4(Text4, { color: "yellow", children: t("hardwareHint") })
|
|
2314
2382
|
] });
|
|
2315
2383
|
}
|
|
2316
2384
|
|
|
2317
2385
|
// src/tui/views/Recommend.tsx
|
|
2318
|
-
import { Box as Box4, Text as
|
|
2319
|
-
import { jsx as
|
|
2386
|
+
import { Box as Box4, Text as Text5 } from "ink";
|
|
2387
|
+
import { jsx as jsx5, jsxs as jsxs5 } from "react/jsx-runtime";
|
|
2320
2388
|
function RecommendView({ session }) {
|
|
2321
2389
|
const cols = useCols();
|
|
2322
|
-
return /* @__PURE__ */
|
|
2323
|
-
/* @__PURE__ */
|
|
2324
|
-
/* @__PURE__ */
|
|
2325
|
-
session.recommendations.map((rec) => /* @__PURE__ */
|
|
2326
|
-
/* @__PURE__ */
|
|
2327
|
-
/* @__PURE__ */
|
|
2390
|
+
return /* @__PURE__ */ jsxs5(Box4, { flexDirection: "column", width: cols, children: [
|
|
2391
|
+
/* @__PURE__ */ jsx5(Text5, { bold: true, color: "magenta", children: t("recommended") }),
|
|
2392
|
+
/* @__PURE__ */ jsx5(Typewriter, { text: fit(t("aboutRecommend"), cols), ms: 12, dimColor: true }),
|
|
2393
|
+
session.recommendations.map((rec) => /* @__PURE__ */ jsxs5(Text5, { children: [
|
|
2394
|
+
/* @__PURE__ */ jsx5(Text5, { color: "magenta", children: fit(rec.useCase, 10) }),
|
|
2395
|
+
/* @__PURE__ */ jsxs5(Text5, { children: [
|
|
2328
2396
|
" ",
|
|
2329
2397
|
fit(rec.model.name, 22),
|
|
2330
2398
|
" "
|
|
2331
2399
|
] }),
|
|
2332
|
-
/* @__PURE__ */
|
|
2333
|
-
/* @__PURE__ */
|
|
2400
|
+
/* @__PURE__ */ jsx5(Text5, { color: gradeColor(rec.grade), children: rec.grade }),
|
|
2401
|
+
/* @__PURE__ */ jsxs5(Text5, { children: [
|
|
2334
2402
|
" ",
|
|
2335
2403
|
GRADE_MEANING[rec.grade]
|
|
2336
2404
|
] }),
|
|
2337
|
-
/* @__PURE__ */
|
|
2405
|
+
/* @__PURE__ */ jsxs5(Text5, { dimColor: true, children: [
|
|
2338
2406
|
" ",
|
|
2339
2407
|
resolveOllamaTag(rec.model.id, rec.model.name) ?? "\u2014"
|
|
2340
2408
|
] })
|
|
2341
2409
|
] }, `${rec.useCase}-${rec.model.id}`)),
|
|
2342
|
-
/* @__PURE__ */
|
|
2410
|
+
/* @__PURE__ */ jsx5(Text5, { color: "yellow", children: fit(t("setupCta"), cols) })
|
|
2343
2411
|
] });
|
|
2344
2412
|
}
|
|
2345
2413
|
|
|
2346
2414
|
// src/tui/views/Setup.tsx
|
|
2347
|
-
import { Box as Box5, Text as
|
|
2348
|
-
import { useState } from "react";
|
|
2415
|
+
import { Box as Box5, Text as Text6, useApp, useInput } from "ink";
|
|
2416
|
+
import { useState as useState2 } from "react";
|
|
2349
2417
|
|
|
2350
2418
|
// src/integrations/catalog.ts
|
|
2351
2419
|
var INTEGRATIONS = {
|
|
@@ -2535,7 +2603,7 @@ async function pullOllamaModel(modelId, extraName) {
|
|
|
2535
2603
|
}
|
|
2536
2604
|
|
|
2537
2605
|
// src/tui/views/Setup.tsx
|
|
2538
|
-
import { jsx as
|
|
2606
|
+
import { jsx as jsx6, jsxs as jsxs6 } from "react/jsx-runtime";
|
|
2539
2607
|
var TOOLS = [
|
|
2540
2608
|
{ key: "1", id: "opencode", label: "OpenCode" },
|
|
2541
2609
|
{ key: "2", id: "hermes", label: "Hermes" },
|
|
@@ -2544,9 +2612,9 @@ var TOOLS = [
|
|
|
2544
2612
|
function SetupView({ session }) {
|
|
2545
2613
|
const cols = useCols();
|
|
2546
2614
|
const { exit } = useApp();
|
|
2547
|
-
const [cursor, setCursor] =
|
|
2548
|
-
const [log, setLog] =
|
|
2549
|
-
const [busy, setBusy] =
|
|
2615
|
+
const [cursor, setCursor] = useState2(0);
|
|
2616
|
+
const [log, setLog] = useState2("");
|
|
2617
|
+
const [busy, setBusy] = useState2(false);
|
|
2550
2618
|
const recs = session.recommendations;
|
|
2551
2619
|
const rec = recs[cursor];
|
|
2552
2620
|
useInput((input, key) => {
|
|
@@ -2582,48 +2650,59 @@ function SetupView({ session }) {
|
|
|
2582
2650
|
}
|
|
2583
2651
|
});
|
|
2584
2652
|
const tag = rec ? resolveOllamaTag(rec.model.id, rec.model.name) : void 0;
|
|
2585
|
-
return /* @__PURE__ */
|
|
2586
|
-
/* @__PURE__ */
|
|
2587
|
-
recs.map((item, i) => /* @__PURE__ */
|
|
2653
|
+
return /* @__PURE__ */ jsxs6(Box5, { flexDirection: "column", width: cols, children: [
|
|
2654
|
+
/* @__PURE__ */ jsx6(Text6, { bold: true, color: "yellow", children: fit(t("setupTitle"), cols) }),
|
|
2655
|
+
recs.map((item, i) => /* @__PURE__ */ jsxs6(Text6, { color: i === cursor ? "cyan" : void 0, children: [
|
|
2588
2656
|
i === cursor ? "\u276F " : " ",
|
|
2589
2657
|
fit(item.model.name, 20),
|
|
2590
2658
|
" ",
|
|
2591
|
-
/* @__PURE__ */
|
|
2592
|
-
/* @__PURE__ */
|
|
2659
|
+
/* @__PURE__ */ jsx6(Text6, { color: gradeColor(item.grade), children: item.grade }),
|
|
2660
|
+
/* @__PURE__ */ jsxs6(Text6, { dimColor: true, children: [
|
|
2593
2661
|
" ",
|
|
2594
2662
|
resolveOllamaTag(item.model.id, item.model.name) ?? "\u2014"
|
|
2595
2663
|
] })
|
|
2596
2664
|
] }, `${item.useCase}-${item.model.id}`)),
|
|
2597
|
-
|
|
2598
|
-
index ? " " : "",
|
|
2665
|
+
session.agents.map((agent, index) => /* @__PURE__ */ jsxs6(Text6, { color: agent.detected ? "green" : "yellow", children: [
|
|
2599
2666
|
"[",
|
|
2600
2667
|
index + 1,
|
|
2601
|
-
"]",
|
|
2668
|
+
"] ",
|
|
2602
2669
|
agent.detected ? "\u2713" : "\u25CB",
|
|
2603
|
-
|
|
2604
|
-
|
|
2605
|
-
|
|
2606
|
-
|
|
2670
|
+
" ",
|
|
2671
|
+
agent.label,
|
|
2672
|
+
agent.detected ? "" : ` \u2192 ${agent.launch}`
|
|
2673
|
+
] }, agent.id)),
|
|
2674
|
+
/* @__PURE__ */ jsx6(Text6, { dimColor: true, children: fit(
|
|
2675
|
+
`Ollama: ${session.runtimes.find((r) => r.id === "ollama")?.detected ? "\u2713" : t("reqOllama")} LM Studio: ${session.runtimes.find((r) => r.id === "lmstudio")?.detected ? "\u2713" : t("reqLmStudio")}`,
|
|
2676
|
+
cols
|
|
2677
|
+
) }),
|
|
2678
|
+
/* @__PURE__ */ jsx6(Typewriter, { text: fit(`Enter=pull ${tag ?? ""} 1/2/3=agent Esc=back`, cols), ms: 14, dimColor: true }),
|
|
2679
|
+
log ? /* @__PURE__ */ jsx6(Text6, { color: "green", children: fit(log, cols) }) : null
|
|
2607
2680
|
] });
|
|
2608
2681
|
}
|
|
2609
2682
|
|
|
2610
2683
|
// src/tui/views/Compare.tsx
|
|
2611
|
-
import { Box as Box6, Text as
|
|
2612
|
-
import { jsx as
|
|
2684
|
+
import { Box as Box6, Text as Text7 } from "ink";
|
|
2685
|
+
import { jsx as jsx7, jsxs as jsxs7 } from "react/jsx-runtime";
|
|
2613
2686
|
function CompareView({ session }) {
|
|
2614
|
-
|
|
2687
|
+
const cols = useCols();
|
|
2688
|
+
const n = new Set(session.history.map((h) => h.model.id)).size;
|
|
2689
|
+
return /* @__PURE__ */ jsxs7(Box6, { flexDirection: "column", width: cols, children: [
|
|
2690
|
+
/* @__PURE__ */ jsx7(Text7, { bold: true, color: "green", children: t("compareTitle") }),
|
|
2691
|
+
/* @__PURE__ */ jsx7(Typewriter, { text: fit(t("compareHow"), cols), ms: 12, dimColor: true }),
|
|
2692
|
+
n < 2 ? /* @__PURE__ */ jsx7(Text7, { color: "yellow", children: fit(t("compareNeedBench"), cols) }) : /* @__PURE__ */ jsx7(Text7, { children: compareText(session.history) })
|
|
2693
|
+
] });
|
|
2615
2694
|
}
|
|
2616
2695
|
|
|
2617
2696
|
// src/tui/views/Benchmark.tsx
|
|
2618
|
-
import { Box as Box7, Text as
|
|
2619
|
-
import { useEffect, useRef, useState as
|
|
2620
|
-
import { jsx as
|
|
2697
|
+
import { Box as Box7, Text as Text8, useInput as useInput2 } from "ink";
|
|
2698
|
+
import { useEffect as useEffect2, useRef, useState as useState3 } from "react";
|
|
2699
|
+
import { jsx as jsx8, jsxs as jsxs8 } from "react/jsx-runtime";
|
|
2621
2700
|
function BenchmarkView(props) {
|
|
2622
|
-
const [phase, setPhase] =
|
|
2623
|
-
const [sample, setSample] =
|
|
2624
|
-
const [elapsed, setElapsed] =
|
|
2625
|
-
const [result, setResult] =
|
|
2626
|
-
const [error, setError] =
|
|
2701
|
+
const [phase, setPhase] = useState3(props.models.length ? "select" : "error");
|
|
2702
|
+
const [sample, setSample] = useState3();
|
|
2703
|
+
const [elapsed, setElapsed] = useState3(0);
|
|
2704
|
+
const [result, setResult] = useState3();
|
|
2705
|
+
const [error, setError] = useState3(props.models.length ? "" : t("noGguf"));
|
|
2627
2706
|
const cpuHist = useRef([]);
|
|
2628
2707
|
const memHist = useRef([]);
|
|
2629
2708
|
const abortRef = useRef(void 0);
|
|
@@ -2639,7 +2718,7 @@ function BenchmarkView(props) {
|
|
|
2639
2718
|
props.onBack();
|
|
2640
2719
|
}
|
|
2641
2720
|
});
|
|
2642
|
-
|
|
2721
|
+
useEffect2(() => {
|
|
2643
2722
|
if (phase !== "running") return;
|
|
2644
2723
|
const model2 = props.models[props.selected];
|
|
2645
2724
|
if (!model2) return;
|
|
@@ -2677,19 +2756,19 @@ function BenchmarkView(props) {
|
|
|
2677
2756
|
const h = props.session.hardware;
|
|
2678
2757
|
const model = props.models[props.selected];
|
|
2679
2758
|
if (phase === "select") {
|
|
2680
|
-
return /* @__PURE__ */
|
|
2681
|
-
/* @__PURE__ */
|
|
2682
|
-
props.models.map((m, i) => /* @__PURE__ */
|
|
2759
|
+
return /* @__PURE__ */ jsxs8(Box7, { flexDirection: "column", children: [
|
|
2760
|
+
/* @__PURE__ */ jsx8(Text8, { bold: true, children: t("selectBenchmark") }),
|
|
2761
|
+
props.models.map((m, i) => /* @__PURE__ */ jsxs8(Text8, { color: i === props.selected ? "cyan" : void 0, children: [
|
|
2683
2762
|
i === props.selected ? "\u276F " : " ",
|
|
2684
2763
|
m.name
|
|
2685
2764
|
] }, m.id)),
|
|
2686
|
-
/* @__PURE__ */
|
|
2765
|
+
/* @__PURE__ */ jsx8(Text8, { dimColor: true, children: t("enterToRun") })
|
|
2687
2766
|
] });
|
|
2688
2767
|
}
|
|
2689
2768
|
if (phase === "done" && result) {
|
|
2690
|
-
return /* @__PURE__ */
|
|
2691
|
-
/* @__PURE__ */
|
|
2692
|
-
/* @__PURE__ */
|
|
2769
|
+
return /* @__PURE__ */ jsxs8(Box7, { flexDirection: "column", children: [
|
|
2770
|
+
/* @__PURE__ */ jsx8(Text8, { children: resultText(result.record, result.assessment) }),
|
|
2771
|
+
/* @__PURE__ */ jsxs8(Text8, { dimColor: true, children: [
|
|
2693
2772
|
t("saved"),
|
|
2694
2773
|
" ",
|
|
2695
2774
|
result.path
|
|
@@ -2697,17 +2776,17 @@ function BenchmarkView(props) {
|
|
|
2697
2776
|
] });
|
|
2698
2777
|
}
|
|
2699
2778
|
if (phase === "error") {
|
|
2700
|
-
return /* @__PURE__ */
|
|
2779
|
+
return /* @__PURE__ */ jsx8(Box7, { flexDirection: "column", children: /* @__PURE__ */ jsx8(Text8, { color: "red", children: error }) });
|
|
2701
2780
|
}
|
|
2702
2781
|
const cpu = sample?.cpu?.utilizationPercent;
|
|
2703
2782
|
const gpu = sample?.gpu?.utilizationPercent;
|
|
2704
2783
|
const memUsed = sample?.memory.usedBytes;
|
|
2705
2784
|
const memTotal = h.memory.totalBytes;
|
|
2706
|
-
return /* @__PURE__ */
|
|
2707
|
-
/* @__PURE__ */
|
|
2708
|
-
/* @__PURE__ */
|
|
2709
|
-
/* @__PURE__ */
|
|
2710
|
-
/* @__PURE__ */
|
|
2785
|
+
return /* @__PURE__ */ jsxs8(Box7, { flexDirection: "column", children: [
|
|
2786
|
+
/* @__PURE__ */ jsxs8(Box7, { borderStyle: "round", borderColor: "cyan", flexDirection: "column", paddingX: 1, children: [
|
|
2787
|
+
/* @__PURE__ */ jsx8(Text8, { bold: true, children: t("benchmarkTitle") }),
|
|
2788
|
+
/* @__PURE__ */ jsx8(Text8, { children: model?.name }),
|
|
2789
|
+
/* @__PURE__ */ jsxs8(Text8, { dimColor: true, children: [
|
|
2711
2790
|
h.cpu.name,
|
|
2712
2791
|
" \xB7 ",
|
|
2713
2792
|
formatBytes(h.memory.totalBytes, 0),
|
|
@@ -2715,31 +2794,31 @@ function BenchmarkView(props) {
|
|
|
2715
2794
|
memoryLabel(h)
|
|
2716
2795
|
] })
|
|
2717
2796
|
] }),
|
|
2718
|
-
/* @__PURE__ */
|
|
2719
|
-
/* @__PURE__ */
|
|
2720
|
-
/* @__PURE__ */
|
|
2797
|
+
/* @__PURE__ */ jsxs8(Box7, { marginTop: 1, flexDirection: "column", children: [
|
|
2798
|
+
/* @__PURE__ */ jsx8(Text8, { bold: true, color: "cyan", children: t("performance") }),
|
|
2799
|
+
/* @__PURE__ */ jsxs8(Text8, { children: [
|
|
2721
2800
|
t("elapsed"),
|
|
2722
2801
|
" ",
|
|
2723
2802
|
elapsed.toFixed(1),
|
|
2724
2803
|
" s"
|
|
2725
2804
|
] }),
|
|
2726
|
-
/* @__PURE__ */
|
|
2805
|
+
/* @__PURE__ */ jsx8(Text8, { dimColor: true, children: t("measuredAfter") })
|
|
2727
2806
|
] }),
|
|
2728
|
-
/* @__PURE__ */
|
|
2729
|
-
/* @__PURE__ */
|
|
2730
|
-
/* @__PURE__ */
|
|
2807
|
+
/* @__PURE__ */ jsxs8(Box7, { marginTop: 1, flexDirection: "column", children: [
|
|
2808
|
+
/* @__PURE__ */ jsx8(Text8, { bold: true, color: "cyan", children: t("system") }),
|
|
2809
|
+
/* @__PURE__ */ jsxs8(Text8, { children: [
|
|
2731
2810
|
"CPU ",
|
|
2732
2811
|
bar(cpu),
|
|
2733
2812
|
" ",
|
|
2734
2813
|
formatPercent(cpu)
|
|
2735
2814
|
] }),
|
|
2736
|
-
/* @__PURE__ */
|
|
2815
|
+
/* @__PURE__ */ jsxs8(Text8, { children: [
|
|
2737
2816
|
"GPU ",
|
|
2738
2817
|
bar(gpu),
|
|
2739
2818
|
" ",
|
|
2740
2819
|
formatPercent(gpu)
|
|
2741
2820
|
] }),
|
|
2742
|
-
/* @__PURE__ */
|
|
2821
|
+
/* @__PURE__ */ jsxs8(Text8, { children: [
|
|
2743
2822
|
"Memory ",
|
|
2744
2823
|
bar(memUsed && memTotal ? memUsed / memTotal * 100 : void 0),
|
|
2745
2824
|
" ",
|
|
@@ -2747,56 +2826,56 @@ function BenchmarkView(props) {
|
|
|
2747
2826
|
" / ",
|
|
2748
2827
|
formatBytes(memTotal, 0)
|
|
2749
2828
|
] }),
|
|
2750
|
-
/* @__PURE__ */
|
|
2829
|
+
/* @__PURE__ */ jsxs8(Text8, { children: [
|
|
2751
2830
|
"Swap ",
|
|
2752
2831
|
bar(0),
|
|
2753
2832
|
" ",
|
|
2754
2833
|
sample ? formatBytes(sample.memory.swapUsedBytes) : "N/A"
|
|
2755
2834
|
] })
|
|
2756
2835
|
] }),
|
|
2757
|
-
/* @__PURE__ */
|
|
2758
|
-
/* @__PURE__ */
|
|
2759
|
-
/* @__PURE__ */
|
|
2836
|
+
/* @__PURE__ */ jsxs8(Box7, { marginTop: 1, flexDirection: "column", children: [
|
|
2837
|
+
/* @__PURE__ */ jsx8(Text8, { bold: true, color: "cyan", children: t("powerThermals") }),
|
|
2838
|
+
/* @__PURE__ */ jsxs8(Text8, { children: [
|
|
2760
2839
|
"Package ",
|
|
2761
2840
|
sample?.packagePowerWatts ?? "N/A",
|
|
2762
2841
|
" W"
|
|
2763
2842
|
] }),
|
|
2764
|
-
/* @__PURE__ */
|
|
2843
|
+
/* @__PURE__ */ jsxs8(Text8, { children: [
|
|
2765
2844
|
"Temperature ",
|
|
2766
2845
|
sample?.thermal?.temperatureC ?? "N/A",
|
|
2767
2846
|
" \xB0C"
|
|
2768
2847
|
] }),
|
|
2769
|
-
/* @__PURE__ */
|
|
2848
|
+
/* @__PURE__ */ jsxs8(Text8, { children: [
|
|
2770
2849
|
"Thermal Pressure ",
|
|
2771
2850
|
sample?.thermal?.pressure ?? "N/A"
|
|
2772
2851
|
] }),
|
|
2773
|
-
/* @__PURE__ */
|
|
2852
|
+
/* @__PURE__ */ jsx8(Text8, { dimColor: true, children: t("permissionsHint") })
|
|
2774
2853
|
] }),
|
|
2775
|
-
/* @__PURE__ */
|
|
2854
|
+
/* @__PURE__ */ jsxs8(Text8, { children: [
|
|
2776
2855
|
sparkline(cpuHist.current),
|
|
2777
2856
|
" CPU"
|
|
2778
2857
|
] }),
|
|
2779
|
-
/* @__PURE__ */
|
|
2858
|
+
/* @__PURE__ */ jsxs8(Text8, { children: [
|
|
2780
2859
|
sparkline(memHist.current.map((v) => v / 1024 ** 3)),
|
|
2781
2860
|
" Memory"
|
|
2782
2861
|
] }),
|
|
2783
|
-
/* @__PURE__ */
|
|
2862
|
+
/* @__PURE__ */ jsx8(Text8, { dimColor: true, children: t("cancelHint") })
|
|
2784
2863
|
] });
|
|
2785
2864
|
}
|
|
2786
2865
|
|
|
2787
2866
|
// src/tui/views/History.tsx
|
|
2788
|
-
import { Box as Box8, Text as
|
|
2789
|
-
import { jsx as
|
|
2867
|
+
import { Box as Box8, Text as Text9 } from "ink";
|
|
2868
|
+
import { jsx as jsx9, jsxs as jsxs9 } from "react/jsx-runtime";
|
|
2790
2869
|
function HistoryView({ session }) {
|
|
2791
|
-
return /* @__PURE__ */
|
|
2792
|
-
/* @__PURE__ */
|
|
2793
|
-
/* @__PURE__ */
|
|
2870
|
+
return /* @__PURE__ */ jsxs9(Box8, { flexDirection: "column", children: [
|
|
2871
|
+
/* @__PURE__ */ jsx9(Text9, { bold: true, color: "cyan", children: t("measured") }),
|
|
2872
|
+
/* @__PURE__ */ jsx9(Text9, { children: historyText(session.history) })
|
|
2794
2873
|
] });
|
|
2795
2874
|
}
|
|
2796
2875
|
|
|
2797
2876
|
// src/tui/views/Tasks.tsx
|
|
2798
|
-
import { Box as Box9, Text as
|
|
2799
|
-
import { useMemo, useState as
|
|
2877
|
+
import { Box as Box9, Text as Text10, useInput as useInput3 } from "ink";
|
|
2878
|
+
import { useMemo, useState as useState4 } from "react";
|
|
2800
2879
|
|
|
2801
2880
|
// src/tasks/catalog.ts
|
|
2802
2881
|
var TASK_CATALOG = [
|
|
@@ -2991,7 +3070,7 @@ function tasksText(plans, answers) {
|
|
|
2991
3070
|
}
|
|
2992
3071
|
|
|
2993
3072
|
// src/tui/views/Tasks.tsx
|
|
2994
|
-
import { Fragment, jsx as
|
|
3073
|
+
import { Fragment, jsx as jsx10, jsxs as jsxs10 } from "react/jsx-runtime";
|
|
2995
3074
|
var KIND_LABEL = {
|
|
2996
3075
|
code: "tasksOptCode",
|
|
2997
3076
|
video: "tasksOptVideo",
|
|
@@ -3000,11 +3079,11 @@ var KIND_LABEL = {
|
|
|
3000
3079
|
chat: "tasksOptChat"
|
|
3001
3080
|
};
|
|
3002
3081
|
function TasksView({ session }) {
|
|
3003
|
-
const [step, setStep] =
|
|
3004
|
-
const [cursor, setCursor] =
|
|
3005
|
-
const [kinds, setKinds] =
|
|
3006
|
-
const [scope, setScope] =
|
|
3007
|
-
const [priority, setPriority] =
|
|
3082
|
+
const [step, setStep] = useState4(0);
|
|
3083
|
+
const [cursor, setCursor] = useState4(0);
|
|
3084
|
+
const [kinds, setKinds] = useState4(["code", "chat"]);
|
|
3085
|
+
const [scope, setScope] = useState4("installed");
|
|
3086
|
+
const [priority, setPriority] = useState4("balanced");
|
|
3008
3087
|
const plans = useMemo(
|
|
3009
3088
|
() => planTasks(session, { kinds, scope, priority }),
|
|
3010
3089
|
[session, kinds, scope, priority]
|
|
@@ -3032,13 +3111,13 @@ function TasksView({ session }) {
|
|
|
3032
3111
|
}
|
|
3033
3112
|
});
|
|
3034
3113
|
if (step === 3) {
|
|
3035
|
-
return /* @__PURE__ */
|
|
3114
|
+
return /* @__PURE__ */ jsx10(Box9, { flexDirection: "column", children: /* @__PURE__ */ jsx10(Text10, { children: tasksText(plans, { kinds, scope, priority }) }) });
|
|
3036
3115
|
}
|
|
3037
|
-
return /* @__PURE__ */
|
|
3038
|
-
/* @__PURE__ */
|
|
3039
|
-
step === 0 && /* @__PURE__ */
|
|
3040
|
-
/* @__PURE__ */
|
|
3041
|
-
WORK_KINDS.map((kind, i) => /* @__PURE__ */
|
|
3116
|
+
return /* @__PURE__ */ jsxs10(Box9, { flexDirection: "column", children: [
|
|
3117
|
+
/* @__PURE__ */ jsx10(Text10, { bold: true, color: "cyan", children: t("tasksTitle") }),
|
|
3118
|
+
step === 0 && /* @__PURE__ */ jsxs10(Fragment, { children: [
|
|
3119
|
+
/* @__PURE__ */ jsx10(Text10, { children: t("tasksQ1") }),
|
|
3120
|
+
WORK_KINDS.map((kind, i) => /* @__PURE__ */ jsxs10(Text10, { color: i === cursor ? "cyan" : void 0, children: [
|
|
3042
3121
|
i === cursor ? "\u276F " : " ",
|
|
3043
3122
|
"[",
|
|
3044
3123
|
kinds.includes(kind) ? "x" : " ",
|
|
@@ -3046,20 +3125,20 @@ function TasksView({ session }) {
|
|
|
3046
3125
|
t(KIND_LABEL[kind])
|
|
3047
3126
|
] }, kind))
|
|
3048
3127
|
] }),
|
|
3049
|
-
step === 1 && /* @__PURE__ */
|
|
3050
|
-
/* @__PURE__ */
|
|
3051
|
-
/* @__PURE__ */
|
|
3128
|
+
step === 1 && /* @__PURE__ */ jsxs10(Fragment, { children: [
|
|
3129
|
+
/* @__PURE__ */ jsx10(Text10, { children: t("tasksQ2") }),
|
|
3130
|
+
/* @__PURE__ */ jsxs10(Text10, { color: scope === "installed" ? "cyan" : void 0, children: [
|
|
3052
3131
|
scope === "installed" ? "\u276F " : " ",
|
|
3053
3132
|
t("tasksOptInstalled")
|
|
3054
3133
|
] }),
|
|
3055
|
-
/* @__PURE__ */
|
|
3134
|
+
/* @__PURE__ */ jsxs10(Text10, { color: scope === "all" ? "cyan" : void 0, children: [
|
|
3056
3135
|
scope === "all" ? "\u276F " : " ",
|
|
3057
3136
|
t("tasksOptAll")
|
|
3058
3137
|
] })
|
|
3059
3138
|
] }),
|
|
3060
|
-
step === 2 && /* @__PURE__ */
|
|
3061
|
-
/* @__PURE__ */
|
|
3062
|
-
["speed", "balanced", "quality"].map((item) => /* @__PURE__ */
|
|
3139
|
+
step === 2 && /* @__PURE__ */ jsxs10(Fragment, { children: [
|
|
3140
|
+
/* @__PURE__ */ jsx10(Text10, { children: t("tasksQ3") }),
|
|
3141
|
+
["speed", "balanced", "quality"].map((item) => /* @__PURE__ */ jsxs10(Text10, { color: priority === item ? "cyan" : void 0, children: [
|
|
3063
3142
|
priority === item ? "\u276F " : " ",
|
|
3064
3143
|
item === "speed" ? t("tasksOptSpeed") : item === "quality" ? t("tasksOptQuality") : t("tasksOptBalanced")
|
|
3065
3144
|
] }, item))
|
|
@@ -3095,61 +3174,54 @@ function handleAppKey(screen, input, key) {
|
|
|
3095
3174
|
}
|
|
3096
3175
|
|
|
3097
3176
|
// src/tui/Welcome.tsx
|
|
3098
|
-
import { Box as Box10, Text as
|
|
3099
|
-
import { Fragment as Fragment2, jsx as
|
|
3177
|
+
import { Box as Box10, Text as Text11 } from "ink";
|
|
3178
|
+
import { Fragment as Fragment2, jsx as jsx11, jsxs as jsxs11 } from "react/jsx-runtime";
|
|
3100
3179
|
function Chrome() {
|
|
3101
3180
|
const cols = useCols();
|
|
3102
3181
|
const wide = cols >= 72;
|
|
3103
|
-
|
|
3104
|
-
|
|
3105
|
-
|
|
3106
|
-
|
|
3107
|
-
/* @__PURE__ */
|
|
3108
|
-
|
|
3109
|
-
|
|
3110
|
-
|
|
3111
|
-
] })
|
|
3112
|
-
|
|
3113
|
-
|
|
3114
|
-
/* @__PURE__ */
|
|
3115
|
-
/* @__PURE__ */
|
|
3116
|
-
/* @__PURE__ */
|
|
3117
|
-
/* @__PURE__ */
|
|
3118
|
-
/* @__PURE__ */
|
|
3119
|
-
/* @__PURE__ */
|
|
3120
|
-
/* @__PURE__ */
|
|
3121
|
-
/* @__PURE__ */
|
|
3122
|
-
/* @__PURE__ */
|
|
3123
|
-
/* @__PURE__ */
|
|
3124
|
-
|
|
3125
|
-
/* @__PURE__ */
|
|
3126
|
-
/* @__PURE__ */
|
|
3127
|
-
/* @__PURE__ */
|
|
3128
|
-
/* @__PURE__ */
|
|
3129
|
-
/* @__PURE__ */
|
|
3130
|
-
/* @__PURE__ */
|
|
3131
|
-
|
|
3132
|
-
/* @__PURE__ */
|
|
3133
|
-
/* @__PURE__ */
|
|
3134
|
-
/* @__PURE__ */ jsx10(Text10, { color: "cyan", children: "[M]" }),
|
|
3135
|
-
/* @__PURE__ */ jsx10(Text10, { color: "magenta", children: "[R]" }),
|
|
3136
|
-
/* @__PURE__ */ jsx10(Text10, { color: "blue", children: "[T]" }),
|
|
3137
|
-
/* @__PURE__ */ jsx10(Text10, { children: "[H]" }),
|
|
3138
|
-
/* @__PURE__ */ jsx10(Text10, { color: "green", children: "[C]" }),
|
|
3139
|
-
/* @__PURE__ */ jsx10(Text10, { color: "cyan", children: "[L]" }),
|
|
3140
|
-
/* @__PURE__ */ jsx10(Text10, { color: "red", children: "[Q]" })
|
|
3182
|
+
const brand = `${t("appTitle")} ${t("byline")}`;
|
|
3183
|
+
return /* @__PURE__ */ jsxs11(Box10, { flexDirection: "column", width: cols, marginBottom: 1, children: [
|
|
3184
|
+
/* @__PURE__ */ jsx11(Typewriter, { text: brand, ms: 28, color: "cyan", bold: true, once: true }),
|
|
3185
|
+
/* @__PURE__ */ jsx11(Text11, { children: wide ? /* @__PURE__ */ jsxs11(Fragment2, { children: [
|
|
3186
|
+
/* @__PURE__ */ jsx11(Text11, { color: "yellow", children: "[S] Setup" }),
|
|
3187
|
+
/* @__PURE__ */ jsx11(Text11, { children: " " }),
|
|
3188
|
+
/* @__PURE__ */ jsx11(Text11, { color: "green", children: "[B] Bench" }),
|
|
3189
|
+
/* @__PURE__ */ jsx11(Text11, { children: " " }),
|
|
3190
|
+
/* @__PURE__ */ jsx11(Text11, { color: "cyan", children: "[M] Models" }),
|
|
3191
|
+
/* @__PURE__ */ jsx11(Text11, { children: " " }),
|
|
3192
|
+
/* @__PURE__ */ jsx11(Text11, { color: "magenta", children: "[R] Rec" }),
|
|
3193
|
+
/* @__PURE__ */ jsx11(Text11, { children: " " }),
|
|
3194
|
+
/* @__PURE__ */ jsx11(Text11, { color: "blue", children: "[T] Tasks" }),
|
|
3195
|
+
/* @__PURE__ */ jsx11(Text11, { children: " " }),
|
|
3196
|
+
/* @__PURE__ */ jsx11(Text11, { children: "[H] HW" }),
|
|
3197
|
+
/* @__PURE__ */ jsx11(Text11, { children: " " }),
|
|
3198
|
+
/* @__PURE__ */ jsx11(Text11, { color: "green", children: "[C] Cmp" }),
|
|
3199
|
+
/* @__PURE__ */ jsx11(Text11, { children: " " }),
|
|
3200
|
+
/* @__PURE__ */ jsx11(Text11, { color: "cyan", children: "[L] Log" }),
|
|
3201
|
+
/* @__PURE__ */ jsx11(Text11, { children: " " }),
|
|
3202
|
+
/* @__PURE__ */ jsx11(Text11, { color: "red", children: "[Q] Quit" })
|
|
3203
|
+
] }) : /* @__PURE__ */ jsxs11(Fragment2, { children: [
|
|
3204
|
+
/* @__PURE__ */ jsx11(Text11, { color: "yellow", children: "[S]" }),
|
|
3205
|
+
/* @__PURE__ */ jsx11(Text11, { color: "green", children: "[B]" }),
|
|
3206
|
+
/* @__PURE__ */ jsx11(Text11, { color: "cyan", children: "[M]" }),
|
|
3207
|
+
/* @__PURE__ */ jsx11(Text11, { color: "magenta", children: "[R]" }),
|
|
3208
|
+
/* @__PURE__ */ jsx11(Text11, { color: "blue", children: "[T]" }),
|
|
3209
|
+
/* @__PURE__ */ jsx11(Text11, { children: "[H]" }),
|
|
3210
|
+
/* @__PURE__ */ jsx11(Text11, { color: "green", children: "[C]" }),
|
|
3211
|
+
/* @__PURE__ */ jsx11(Text11, { color: "cyan", children: "[L]" }),
|
|
3212
|
+
/* @__PURE__ */ jsx11(Text11, { color: "red", children: "[Q]" })
|
|
3141
3213
|
] }) })
|
|
3142
3214
|
] });
|
|
3143
3215
|
}
|
|
3144
3216
|
|
|
3145
3217
|
// src/tui/App.tsx
|
|
3146
|
-
import { jsx as
|
|
3218
|
+
import { jsx as jsx12, jsxs as jsxs12 } from "react/jsx-runtime";
|
|
3147
3219
|
function App(props) {
|
|
3148
3220
|
const { exit } = useApp2();
|
|
3149
|
-
const [screen, setScreen] =
|
|
3221
|
+
const [screen, setScreen] = useState5(props.start ?? "home");
|
|
3150
3222
|
const screenRef = useRef2(screen);
|
|
3151
3223
|
screenRef.current = screen;
|
|
3152
|
-
const [selected, setSelected] =
|
|
3224
|
+
const [selected, setSelected] = useState5(0);
|
|
3153
3225
|
const benchable = useMemo2(
|
|
3154
3226
|
() => props.session.models.filter((m) => Boolean(m.artifactPath)),
|
|
3155
3227
|
[props.session.models]
|
|
@@ -3160,17 +3232,17 @@ function App(props) {
|
|
|
3160
3232
|
if (result.type === "home") setScreen("home");
|
|
3161
3233
|
if (result.type === "screen") setScreen(result.screen);
|
|
3162
3234
|
});
|
|
3163
|
-
return /* @__PURE__ */
|
|
3164
|
-
screen !== "benchmark" && /* @__PURE__ */
|
|
3165
|
-
screen === "home" && /* @__PURE__ */
|
|
3166
|
-
screen === "models" && /* @__PURE__ */
|
|
3167
|
-
screen === "hardware" && /* @__PURE__ */
|
|
3168
|
-
screen === "recommend" && /* @__PURE__ */
|
|
3169
|
-
screen === "setup" && /* @__PURE__ */
|
|
3170
|
-
screen === "compare" && /* @__PURE__ */
|
|
3171
|
-
screen === "history" && /* @__PURE__ */
|
|
3172
|
-
screen === "tasks" && /* @__PURE__ */
|
|
3173
|
-
screen === "benchmark" && /* @__PURE__ */
|
|
3235
|
+
return /* @__PURE__ */ jsxs12(Box11, { flexDirection: "column", paddingX: 1, children: [
|
|
3236
|
+
screen !== "benchmark" && /* @__PURE__ */ jsx12(Chrome, {}),
|
|
3237
|
+
screen === "home" && /* @__PURE__ */ jsx12(Dashboard, { session: props.session }),
|
|
3238
|
+
screen === "models" && /* @__PURE__ */ jsx12(ModelsView, { session: props.session }),
|
|
3239
|
+
screen === "hardware" && /* @__PURE__ */ jsx12(HardwareView, { session: props.session }),
|
|
3240
|
+
screen === "recommend" && /* @__PURE__ */ jsx12(RecommendView, { session: props.session }),
|
|
3241
|
+
screen === "setup" && /* @__PURE__ */ jsx12(SetupView, { session: props.session }),
|
|
3242
|
+
screen === "compare" && /* @__PURE__ */ jsx12(CompareView, { session: props.session }),
|
|
3243
|
+
screen === "history" && /* @__PURE__ */ jsx12(HistoryView, { session: props.session }),
|
|
3244
|
+
screen === "tasks" && /* @__PURE__ */ jsx12(TasksView, { session: props.session }),
|
|
3245
|
+
screen === "benchmark" && /* @__PURE__ */ jsx12(
|
|
3174
3246
|
BenchmarkView,
|
|
3175
3247
|
{
|
|
3176
3248
|
session: props.session,
|
|
@@ -3185,9 +3257,9 @@ function App(props) {
|
|
|
3185
3257
|
}
|
|
3186
3258
|
|
|
3187
3259
|
// src/tui/render.tsx
|
|
3188
|
-
import { jsx as
|
|
3260
|
+
import { jsx as jsx13 } from "react/jsx-runtime";
|
|
3189
3261
|
async function renderDashboard(session, preset, start) {
|
|
3190
|
-
const instance = render(/* @__PURE__ */
|
|
3262
|
+
const instance = render(/* @__PURE__ */ jsx13(App, { session, preset, start }));
|
|
3191
3263
|
await instance.waitUntilExit();
|
|
3192
3264
|
}
|
|
3193
3265
|
|