ai-speedometer 2.1.7 → 2.2.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (2) hide show
  1. package/dist/ai-speedometer +1597 -773
  2. package/package.json +1 -1
@@ -390,9 +390,11 @@ var init_models_dev = __esm(() => {
390
390
  // ../core/src/ai-config.ts
391
391
  var exports_ai_config = {};
392
392
  __export(exports_ai_config, {
393
+ writeThemeToConfig: () => writeThemeToConfig,
393
394
  writeAIConfig: () => writeAIConfig,
394
395
  removeVerifiedProvider: () => removeVerifiedProvider,
395
396
  removeCustomProvider: () => removeCustomProvider,
397
+ readThemeFromConfig: () => readThemeFromConfig,
396
398
  readAIConfig: () => readAIConfig,
397
399
  getVerifiedProvidersFromConfig: () => getVerifiedProvidersFromConfig,
398
400
  getRecentModels: () => getRecentModels,
@@ -433,6 +435,12 @@ var getAIConfigPaths = () => {
433
435
  console.warn("Warning: Could not read ai-benchmark-config.json:", error.message);
434
436
  return { verifiedProviders: {}, customProviders: [] };
435
437
  }
438
+ }, readThemeFromConfig = async () => {
439
+ const config = await readAIConfig();
440
+ return config.theme ?? "tokyonight";
441
+ }, writeThemeToConfig = async (theme) => {
442
+ const config = await readAIConfig();
443
+ await writeAIConfig({ ...config, theme });
436
444
  }, writeAIConfig = async (config) => {
437
445
  const { configJson } = getAIConfigPaths();
438
446
  try {
@@ -1821,16 +1829,17 @@ async function benchmarkSingleModelRest(model, logger) {
1821
1829
  continue;
1822
1830
  try {
1823
1831
  if (model.providerType === "anthropic") {
1824
- if (trimmedLine.startsWith("data: ")) {
1825
- const jsonStr = trimmedLine.slice(6);
1832
+ const anthropicDataPrefix = trimmedLine.startsWith("data: ") ? 6 : trimmedLine.startsWith("data:") ? 5 : -1;
1833
+ if (anthropicDataPrefix !== -1) {
1834
+ const jsonStr = trimmedLine.slice(anthropicDataPrefix);
1826
1835
  if (jsonStr === "[DONE]")
1827
1836
  continue;
1828
1837
  const chunk = JSON.parse(jsonStr);
1829
1838
  const chunkTyped = chunk;
1830
- if (chunkTyped.type === "content_block_delta" && chunkTyped.delta?.text) {
1839
+ if (chunkTyped.type === "content_block_delta" && (chunkTyped.delta?.text || chunkTyped.delta?.thinking)) {
1831
1840
  if (!firstParsedTokenTime)
1832
1841
  firstParsedTokenTime = Date.now();
1833
- streamedText += chunkTyped.delta.text;
1842
+ streamedText += chunkTyped.delta?.text || chunkTyped.delta?.thinking || "";
1834
1843
  } else if (chunkTyped.type === "message_start" && chunkTyped.message?.usage) {
1835
1844
  inputTokens = chunkTyped.message.usage.input_tokens || 0;
1836
1845
  } else if (chunkTyped.type === "message_delta") {
@@ -1843,10 +1852,10 @@ async function benchmarkSingleModelRest(model, logger) {
1843
1852
  continue;
1844
1853
  } else {
1845
1854
  const chunk = JSON.parse(trimmedLine);
1846
- if (chunk.type === "content_block_delta" && chunk.delta?.text) {
1855
+ if (chunk.type === "content_block_delta" && (chunk.delta?.text || chunk.delta?.thinking)) {
1847
1856
  if (!firstParsedTokenTime)
1848
1857
  firstParsedTokenTime = Date.now();
1849
- streamedText += chunk.delta.text;
1858
+ streamedText += chunk.delta?.text || chunk.delta?.thinking || "";
1850
1859
  } else if (chunk.type === "message_start" && chunk.message?.usage) {
1851
1860
  inputTokens = chunk.message.usage.input_tokens || 0;
1852
1861
  } else if (chunk.type === "message_delta") {
@@ -1868,24 +1877,42 @@ async function benchmarkSingleModelRest(model, logger) {
1868
1877
  if (chunk.usageMetadata?.candidatesTokenCount)
1869
1878
  outputTokens = chunk.usageMetadata.candidatesTokenCount;
1870
1879
  } else {
1871
- if (trimmedLine.startsWith("data: ")) {
1872
- const jsonStr = trimmedLine.slice(6);
1873
- if (jsonStr === "[DONE]")
1874
- continue;
1875
- const chunk = JSON.parse(jsonStr);
1876
- if (chunk.choices?.[0]?.delta?.content) {
1877
- if (!firstParsedTokenTime)
1878
- firstParsedTokenTime = Date.now();
1879
- streamedText += chunk.choices[0].delta.content;
1880
- } else if (chunk.choices?.[0]?.delta?.reasoning) {
1881
- if (!firstParsedTokenTime)
1882
- firstParsedTokenTime = Date.now();
1883
- streamedText += chunk.choices[0].delta.reasoning;
1884
- }
1885
- if (chunk.usage?.prompt_tokens)
1886
- inputTokens = chunk.usage.prompt_tokens;
1887
- if (chunk.usage?.completion_tokens)
1888
- outputTokens = chunk.usage.completion_tokens;
1880
+ const dataPrefix = trimmedLine.startsWith("data: ") ? 6 : trimmedLine.startsWith("data:") ? 5 : -1;
1881
+ if (dataPrefix === -1)
1882
+ continue;
1883
+ const jsonStr = trimmedLine.slice(dataPrefix);
1884
+ if (jsonStr === "[DONE]")
1885
+ continue;
1886
+ const chunk = JSON.parse(jsonStr);
1887
+ if (chunk.choices?.[0]?.delta?.content) {
1888
+ if (!firstParsedTokenTime)
1889
+ firstParsedTokenTime = Date.now();
1890
+ streamedText += chunk.choices[0].delta.content;
1891
+ } else if (chunk.choices?.[0]?.delta?.reasoning) {
1892
+ if (!firstParsedTokenTime)
1893
+ firstParsedTokenTime = Date.now();
1894
+ streamedText += chunk.choices[0].delta.reasoning;
1895
+ } else if (chunk.choices?.[0]?.delta?.reasoning_content) {
1896
+ if (!firstParsedTokenTime)
1897
+ firstParsedTokenTime = Date.now();
1898
+ streamedText += chunk.choices[0].delta.reasoning_content;
1899
+ } else if (chunk.type === "content_block_delta" && chunk.delta?.text) {
1900
+ if (!firstParsedTokenTime)
1901
+ firstParsedTokenTime = Date.now();
1902
+ streamedText += chunk.delta.text;
1903
+ } else if (chunk.type === "content_block_delta" && chunk.delta?.thinking) {
1904
+ if (!firstParsedTokenTime)
1905
+ firstParsedTokenTime = Date.now();
1906
+ streamedText += chunk.delta.thinking;
1907
+ }
1908
+ if (chunk.usage?.prompt_tokens)
1909
+ inputTokens = chunk.usage.prompt_tokens;
1910
+ if (chunk.usage?.completion_tokens)
1911
+ outputTokens = chunk.usage.completion_tokens;
1912
+ if (chunk.type === "message_start" && chunk.message?.usage?.input_tokens)
1913
+ inputTokens = chunk.message.usage.input_tokens;
1914
+ if (chunk.type === "message_delta" && chunk.usage?.output_tokens) {
1915
+ outputTokens = chunk.usage.output_tokens;
1889
1916
  }
1890
1917
  }
1891
1918
  } catch {
@@ -2264,12 +2291,727 @@ var init_AppContext = __esm(() => {
2264
2291
  AppContext = createContext(null);
2265
2292
  });
2266
2293
 
2294
+ // src/tui/theme/themes.ts
2295
+ function getTheme(name) {
2296
+ return THEMES[name] ?? THEMES[DEFAULT_THEME];
2297
+ }
2298
+ var THEMES, DEFAULT_THEME = "tokyonight", THEME_NAMES;
2299
+ var init_themes = __esm(() => {
2300
+ THEMES = {
2301
+ tokyonight: {
2302
+ background: "#1a1b26",
2303
+ surface: "#1e2030",
2304
+ border: "#292e42",
2305
+ dim: "#565f89",
2306
+ text: "#c0caf5",
2307
+ primary: "#7aa2f7",
2308
+ accent: "#7dcfff",
2309
+ secondary: "#bb9af7",
2310
+ success: "#9ece6a",
2311
+ error: "#f7768e",
2312
+ warning: "#ff9e64"
2313
+ },
2314
+ dracula: {
2315
+ background: "#282a36",
2316
+ surface: "#21222c",
2317
+ border: "#44475a",
2318
+ dim: "#6272a4",
2319
+ text: "#f8f8f2",
2320
+ primary: "#bd93f9",
2321
+ accent: "#8be9fd",
2322
+ secondary: "#ff79c6",
2323
+ success: "#50fa7b",
2324
+ error: "#ff5555",
2325
+ warning: "#f1fa8c"
2326
+ },
2327
+ catppuccin: {
2328
+ background: "#1e1e2e",
2329
+ surface: "#181825",
2330
+ border: "#313244",
2331
+ dim: "#585b70",
2332
+ text: "#cdd6f4",
2333
+ primary: "#89b4fa",
2334
+ accent: "#89dceb",
2335
+ secondary: "#cba6f7",
2336
+ success: "#a6e3a1",
2337
+ error: "#f38ba8",
2338
+ warning: "#fab387"
2339
+ },
2340
+ "catppuccin-frappe": {
2341
+ background: "#303446",
2342
+ surface: "#292c3c",
2343
+ border: "#414559",
2344
+ dim: "#b5bfe2",
2345
+ text: "#c6d0f5",
2346
+ primary: "#8da4e2",
2347
+ accent: "#f4b8e4",
2348
+ secondary: "#ca9ee6",
2349
+ success: "#a6d189",
2350
+ error: "#e78284",
2351
+ warning: "#e5c890"
2352
+ },
2353
+ "catppuccin-macchiato": {
2354
+ background: "#24273a",
2355
+ surface: "#1e2030",
2356
+ border: "#363a4f",
2357
+ dim: "#b8c0e0",
2358
+ text: "#cad3f5",
2359
+ primary: "#8aadf4",
2360
+ accent: "#f5bde6",
2361
+ secondary: "#c6a0f6",
2362
+ success: "#a6da95",
2363
+ error: "#ed8796",
2364
+ warning: "#eed49f"
2365
+ },
2366
+ kanagawa: {
2367
+ background: "#1F1F28",
2368
+ surface: "#2A2A37",
2369
+ border: "#54546D",
2370
+ dim: "#727169",
2371
+ text: "#DCD7BA",
2372
+ primary: "#7E9CD8",
2373
+ accent: "#7FB4CA",
2374
+ secondary: "#957FB8",
2375
+ success: "#98BB6C",
2376
+ error: "#E82424",
2377
+ warning: "#D7A657"
2378
+ },
2379
+ rosepine: {
2380
+ background: "#191724",
2381
+ surface: "#1f1d2e",
2382
+ border: "#403d52",
2383
+ dim: "#6e6a86",
2384
+ text: "#e0def4",
2385
+ primary: "#9ccfd8",
2386
+ accent: "#ebbcba",
2387
+ secondary: "#c4a7e7",
2388
+ success: "#31748f",
2389
+ error: "#eb6f92",
2390
+ warning: "#f6c177"
2391
+ },
2392
+ nord: {
2393
+ background: "#2E3440",
2394
+ surface: "#3B4252",
2395
+ border: "#434C5E",
2396
+ dim: "#8B95A7",
2397
+ text: "#ECEFF4",
2398
+ primary: "#88C0D0",
2399
+ accent: "#8FBCBB",
2400
+ secondary: "#81A1C1",
2401
+ success: "#A3BE8C",
2402
+ error: "#BF616A",
2403
+ warning: "#D08770"
2404
+ },
2405
+ aura: {
2406
+ background: "#0f0f0f",
2407
+ surface: "#15141b",
2408
+ border: "#2d2d2d",
2409
+ dim: "#6d6d6d",
2410
+ text: "#edecee",
2411
+ primary: "#a277ff",
2412
+ accent: "#a277ff",
2413
+ secondary: "#f694ff",
2414
+ success: "#61ffca",
2415
+ error: "#ff6767",
2416
+ warning: "#ffca85"
2417
+ },
2418
+ ayu: {
2419
+ background: "#0B0E14",
2420
+ surface: "#0F131A",
2421
+ border: "#6C7380",
2422
+ dim: "#565B66",
2423
+ text: "#BFBDB6",
2424
+ primary: "#59C2FF",
2425
+ accent: "#E6B450",
2426
+ secondary: "#D2A6FF",
2427
+ success: "#7FD962",
2428
+ error: "#D95757",
2429
+ warning: "#E6B673"
2430
+ },
2431
+ carbonfox: {
2432
+ background: "#161616",
2433
+ surface: "#1a1a1a",
2434
+ border: "#303030",
2435
+ dim: "#7d848f",
2436
+ text: "#f2f4f8",
2437
+ primary: "#33b1ff",
2438
+ accent: "#ff7eb6",
2439
+ secondary: "#78a9ff",
2440
+ success: "#25be6a",
2441
+ error: "#ee5396",
2442
+ warning: "#f1c21b"
2443
+ },
2444
+ cobalt2: {
2445
+ background: "#193549",
2446
+ surface: "#122738",
2447
+ border: "#1f4662",
2448
+ dim: "#adb7c9",
2449
+ text: "#ffffff",
2450
+ primary: "#0088ff",
2451
+ accent: "#2affdf",
2452
+ secondary: "#9a5feb",
2453
+ success: "#9eff80",
2454
+ error: "#ff0088",
2455
+ warning: "#ffc600"
2456
+ },
2457
+ cursor: {
2458
+ background: "#181818",
2459
+ surface: "#141414",
2460
+ border: "#333333",
2461
+ dim: "#666666",
2462
+ text: "#e4e4e4",
2463
+ primary: "#88c0d0",
2464
+ accent: "#88c0d0",
2465
+ secondary: "#81a1c1",
2466
+ success: "#3fa266",
2467
+ error: "#e34671",
2468
+ warning: "#f1b467"
2469
+ },
2470
+ gruvbox: {
2471
+ background: "#282828",
2472
+ surface: "#3c3836",
2473
+ border: "#665c54",
2474
+ dim: "#928374",
2475
+ text: "#ebdbb2",
2476
+ primary: "#83a598",
2477
+ accent: "#8ec07c",
2478
+ secondary: "#d3869b",
2479
+ success: "#b8bb26",
2480
+ error: "#fb4934",
2481
+ warning: "#fe8019"
2482
+ },
2483
+ material: {
2484
+ background: "#263238",
2485
+ surface: "#1e272c",
2486
+ border: "#37474f",
2487
+ dim: "#546e7a",
2488
+ text: "#eeffff",
2489
+ primary: "#82aaff",
2490
+ accent: "#89ddff",
2491
+ secondary: "#c792ea",
2492
+ success: "#c3e88d",
2493
+ error: "#f07178",
2494
+ warning: "#ffcb6b"
2495
+ },
2496
+ matrix: {
2497
+ background: "#0a0e0a",
2498
+ surface: "#0e130d",
2499
+ border: "#1e2a1b",
2500
+ dim: "#8ca391",
2501
+ text: "#62ff94",
2502
+ primary: "#2eff6a",
2503
+ accent: "#c770ff",
2504
+ secondary: "#00efff",
2505
+ success: "#62ff94",
2506
+ error: "#ff4b4b",
2507
+ warning: "#e6ff57"
2508
+ },
2509
+ monokai: {
2510
+ background: "#272822",
2511
+ surface: "#1e1f1c",
2512
+ border: "#3e3d32",
2513
+ dim: "#75715e",
2514
+ text: "#f8f8f2",
2515
+ primary: "#66d9ef",
2516
+ accent: "#a6e22e",
2517
+ secondary: "#ae81ff",
2518
+ success: "#a6e22e",
2519
+ error: "#f92672",
2520
+ warning: "#e6db74"
2521
+ },
2522
+ nightowl: {
2523
+ background: "#011627",
2524
+ surface: "#0b253a",
2525
+ border: "#5f7e97",
2526
+ dim: "#5f7e97",
2527
+ text: "#d6deeb",
2528
+ primary: "#82AAFF",
2529
+ accent: "#c792ea",
2530
+ secondary: "#7fdbca",
2531
+ success: "#c5e478",
2532
+ error: "#EF5350",
2533
+ warning: "#ecc48d"
2534
+ },
2535
+ "one-dark": {
2536
+ background: "#282c34",
2537
+ surface: "#21252b",
2538
+ border: "#393f4a",
2539
+ dim: "#5c6370",
2540
+ text: "#abb2bf",
2541
+ primary: "#61afef",
2542
+ accent: "#56b6c2",
2543
+ secondary: "#c678dd",
2544
+ success: "#98c379",
2545
+ error: "#e06c75",
2546
+ warning: "#e5c07b"
2547
+ },
2548
+ opencode: {
2549
+ background: "#0a0a0a",
2550
+ surface: "#141414",
2551
+ border: "#484848",
2552
+ dim: "#808080",
2553
+ text: "#eeeeee",
2554
+ primary: "#fab283",
2555
+ accent: "#9d7cd8",
2556
+ secondary: "#5c9cf5",
2557
+ success: "#7fd88f",
2558
+ error: "#e06c75",
2559
+ warning: "#f5a742"
2560
+ },
2561
+ "osaka-jade": {
2562
+ background: "#111c18",
2563
+ surface: "#1a2520",
2564
+ border: "#3d4a44",
2565
+ dim: "#53685B",
2566
+ text: "#C1C497",
2567
+ primary: "#2DD5B7",
2568
+ accent: "#549e6a",
2569
+ secondary: "#D2689C",
2570
+ success: "#549e6a",
2571
+ error: "#FF5345",
2572
+ warning: "#E5C736"
2573
+ },
2574
+ palenight: {
2575
+ background: "#292d3e",
2576
+ surface: "#1e2132",
2577
+ border: "#32364a",
2578
+ dim: "#676e95",
2579
+ text: "#a6accd",
2580
+ primary: "#82aaff",
2581
+ accent: "#89ddff",
2582
+ secondary: "#c792ea",
2583
+ success: "#c3e88d",
2584
+ error: "#f07178",
2585
+ warning: "#ffcb6b"
2586
+ },
2587
+ synthwave84: {
2588
+ background: "#262335",
2589
+ surface: "#1e1a29",
2590
+ border: "#495495",
2591
+ dim: "#848bbd",
2592
+ text: "#ffffff",
2593
+ primary: "#36f9f6",
2594
+ accent: "#b084eb",
2595
+ secondary: "#ff7edb",
2596
+ success: "#72f1b8",
2597
+ error: "#fe4450",
2598
+ warning: "#fede5d"
2599
+ },
2600
+ vesper: {
2601
+ background: "#101010",
2602
+ surface: "#181818",
2603
+ border: "#282828",
2604
+ dim: "#A0A0A0",
2605
+ text: "#ffffff",
2606
+ primary: "#FFC799",
2607
+ accent: "#FFC799",
2608
+ secondary: "#99FFE4",
2609
+ success: "#99FFE4",
2610
+ error: "#FF8080",
2611
+ warning: "#FFC799"
2612
+ },
2613
+ zenburn: {
2614
+ background: "#3f3f3f",
2615
+ surface: "#4f4f4f",
2616
+ border: "#5f5f5f",
2617
+ dim: "#9f9f9f",
2618
+ text: "#dcdccc",
2619
+ primary: "#8cd0d3",
2620
+ accent: "#93e0e3",
2621
+ secondary: "#dc8cc3",
2622
+ success: "#7f9f7f",
2623
+ error: "#cc9393",
2624
+ warning: "#f0dfaf"
2625
+ },
2626
+ orng: {
2627
+ background: "#0a0a0a",
2628
+ surface: "#141414",
2629
+ border: "#EC5B2B",
2630
+ dim: "#808080",
2631
+ text: "#eeeeee",
2632
+ primary: "#EC5B2B",
2633
+ accent: "#FFF7F1",
2634
+ secondary: "#EE7948",
2635
+ success: "#6ba1e6",
2636
+ error: "#e06c75",
2637
+ warning: "#EC5B2B"
2638
+ },
2639
+ "lucent-orng": {
2640
+ background: "#000000",
2641
+ surface: "#0a0a0a",
2642
+ border: "#EC5B2B",
2643
+ dim: "#808080",
2644
+ text: "#eeeeee",
2645
+ primary: "#EC5B2B",
2646
+ accent: "#FFF7F1",
2647
+ secondary: "#EE7948",
2648
+ success: "#6ba1e6",
2649
+ error: "#e06c75",
2650
+ warning: "#EC5B2B"
2651
+ },
2652
+ github: {
2653
+ background: "#ffffff",
2654
+ surface: "#f6f8fa",
2655
+ border: "#d0d7de",
2656
+ dim: "#57606a",
2657
+ text: "#24292f",
2658
+ primary: "#0969da",
2659
+ accent: "#1b7c83",
2660
+ secondary: "#8250df",
2661
+ success: "#1a7f37",
2662
+ error: "#cf222e",
2663
+ warning: "#9a6700"
2664
+ },
2665
+ everforest: {
2666
+ background: "#fdf6e3",
2667
+ surface: "#efebd4",
2668
+ border: "#939f91",
2669
+ dim: "#a6b0a0",
2670
+ text: "#5c6a72",
2671
+ primary: "#8da101",
2672
+ accent: "#3a94c5",
2673
+ secondary: "#df69ba",
2674
+ success: "#8da101",
2675
+ error: "#f85552",
2676
+ warning: "#f57d26"
2677
+ },
2678
+ solarized: {
2679
+ background: "#fdf6e3",
2680
+ surface: "#eee8d5",
2681
+ border: "#cdc8b1",
2682
+ dim: "#93a1a1",
2683
+ text: "#657b83",
2684
+ primary: "#268bd2",
2685
+ accent: "#2aa198",
2686
+ secondary: "#6c71c4",
2687
+ success: "#859900",
2688
+ error: "#dc322f",
2689
+ warning: "#b58900"
2690
+ },
2691
+ flexoki: {
2692
+ background: "#FFFCF0",
2693
+ surface: "#F2F0E5",
2694
+ border: "#B7B5AC",
2695
+ dim: "#6F6E69",
2696
+ text: "#100F0F",
2697
+ primary: "#205EA6",
2698
+ accent: "#BC5215",
2699
+ secondary: "#5E409D",
2700
+ success: "#66800B",
2701
+ error: "#AF3029",
2702
+ warning: "#BC5215"
2703
+ },
2704
+ mercury: {
2705
+ background: "#ffffff",
2706
+ surface: "#fbfcfd",
2707
+ border: "#e0e0e8",
2708
+ dim: "#70707d",
2709
+ text: "#363644",
2710
+ primary: "#5266eb",
2711
+ accent: "#8da4f5",
2712
+ secondary: "#465bd1",
2713
+ success: "#036e43",
2714
+ error: "#b0175f",
2715
+ warning: "#a44200"
2716
+ },
2717
+ vercel: {
2718
+ background: "#FFFFFF",
2719
+ surface: "#FAFAFA",
2720
+ border: "#EAEAEA",
2721
+ dim: "#666666",
2722
+ text: "#171717",
2723
+ primary: "#0070F3",
2724
+ accent: "#8E4EC6",
2725
+ secondary: "#0062D1",
2726
+ success: "#388E3C",
2727
+ error: "#DC3545",
2728
+ warning: "#FF9500"
2729
+ }
2730
+ };
2731
+ THEME_NAMES = Object.keys(THEMES);
2732
+ });
2733
+
2734
+ // src/tui/theme/ThemeContext.tsx
2735
+ import { createContext as createContext2, useContext as useContext2, useState, useCallback } from "react";
2736
+ import { jsxDEV as jsxDEV2 } from "@opentui/react/jsx-dev-runtime";
2737
+ function ThemeProvider({ name, children }) {
2738
+ const [themeName, setThemeName] = useState(name);
2739
+ const setTheme = useCallback(async (next) => {
2740
+ setThemeName(next);
2741
+ try {
2742
+ const { writeThemeToConfig: writeThemeToConfig2 } = await Promise.resolve().then(() => (init_ai_config(), exports_ai_config));
2743
+ await writeThemeToConfig2(next);
2744
+ } catch {}
2745
+ }, []);
2746
+ return /* @__PURE__ */ jsxDEV2(ThemeContext.Provider, {
2747
+ value: { theme: getTheme(themeName), themeName, setTheme },
2748
+ children
2749
+ }, undefined, false, undefined, this);
2750
+ }
2751
+ function useTheme() {
2752
+ return useContext2(ThemeContext).theme;
2753
+ }
2754
+ function useThemeCtx() {
2755
+ return useContext2(ThemeContext);
2756
+ }
2757
+ var ThemeContext;
2758
+ var init_ThemeContext = __esm(() => {
2759
+ init_themes();
2760
+ ThemeContext = createContext2({
2761
+ theme: getTheme(DEFAULT_THEME),
2762
+ themeName: DEFAULT_THEME,
2763
+ setTheme: () => {}
2764
+ });
2765
+ });
2766
+
2767
+ // src/tui/context/ModalContext.tsx
2768
+ import { createContext as createContext3, useContext as useContext3, useState as useState2 } from "react";
2769
+ import { jsxDEV as jsxDEV3 } from "@opentui/react/jsx-dev-runtime";
2770
+ function ModalProvider({ children }) {
2771
+ const [modalOpen, setModalOpen] = useState2(false);
2772
+ return /* @__PURE__ */ jsxDEV3(ModalContext.Provider, {
2773
+ value: { modalOpen, setModalOpen },
2774
+ children
2775
+ }, undefined, false, undefined, this);
2776
+ }
2777
+ function useModal() {
2778
+ return useContext3(ModalContext);
2779
+ }
2780
+ var ModalContext;
2781
+ var init_ModalContext = __esm(() => {
2782
+ ModalContext = createContext3({ modalOpen: false, setModalOpen: () => {} });
2783
+ });
2784
+
2785
+ // src/tui/components/ThemePicker.tsx
2786
+ import { useState as useState3, useEffect as useEffect2, useRef } from "react";
2787
+ import { useKeyboard } from "@opentui/react";
2788
+ import { jsxDEV as jsxDEV4 } from "@opentui/react/jsx-dev-runtime";
2789
+ function ThemePicker({ onClose }) {
2790
+ const { theme, themeName, setTheme } = useThemeCtx();
2791
+ const [query, setQuery] = useState3("");
2792
+ const [cursor, setCursor] = useState3(0);
2793
+ const scrollRef = useRef(null);
2794
+ const filtered = THEME_NAMES.filter((n) => n.includes(query.toLowerCase()));
2795
+ useEffect2(() => {
2796
+ setCursor(0);
2797
+ const name = filtered[0];
2798
+ if (name)
2799
+ setTheme(name);
2800
+ }, [query]);
2801
+ useEffect2(() => {
2802
+ const sb = scrollRef.current;
2803
+ if (!sb)
2804
+ return;
2805
+ if (cursor < sb.scrollTop)
2806
+ sb.scrollTo(cursor);
2807
+ else if (cursor >= sb.scrollTop + LIST_H)
2808
+ sb.scrollTo(cursor - LIST_H + 1);
2809
+ }, [cursor]);
2810
+ useEffect2(() => {
2811
+ const idx = filtered.indexOf(themeName);
2812
+ if (idx >= 0)
2813
+ setCursor(idx);
2814
+ }, []);
2815
+ useKeyboard((key) => {
2816
+ if (key.name === "escape" || !key.ctrl && key.sequence === "T") {
2817
+ onClose();
2818
+ return;
2819
+ }
2820
+ if (key.name === "up") {
2821
+ const n = Math.max(0, cursor - 1);
2822
+ setCursor(n);
2823
+ const name = filtered[n];
2824
+ if (name)
2825
+ setTheme(name);
2826
+ return;
2827
+ }
2828
+ if (key.name === "down") {
2829
+ const n = Math.min(filtered.length - 1, cursor + 1);
2830
+ setCursor(n);
2831
+ const name = filtered[n];
2832
+ if (name)
2833
+ setTheme(name);
2834
+ return;
2835
+ }
2836
+ if (key.name === "return" || key.name === "enter") {
2837
+ onClose();
2838
+ return;
2839
+ }
2840
+ if (key.name === "backspace" || key.name === "delete") {
2841
+ setQuery((q) => q.slice(0, -1));
2842
+ return;
2843
+ }
2844
+ if (key.sequence && key.sequence.length === 1 && !key.ctrl && !key.meta && key.sequence >= " ") {
2845
+ setQuery((q) => q + key.sequence);
2846
+ }
2847
+ });
2848
+ const W = 32;
2849
+ const LIST_H = 9;
2850
+ return /* @__PURE__ */ jsxDEV4("box", {
2851
+ position: "absolute",
2852
+ top: 3,
2853
+ right: 3,
2854
+ width: W,
2855
+ flexDirection: "column",
2856
+ border: true,
2857
+ borderStyle: "rounded",
2858
+ borderColor: theme.primary,
2859
+ backgroundColor: theme.surface,
2860
+ zIndex: 100,
2861
+ children: [
2862
+ /* @__PURE__ */ jsxDEV4("box", {
2863
+ height: 1,
2864
+ flexDirection: "row",
2865
+ paddingLeft: 2,
2866
+ paddingRight: 2,
2867
+ paddingTop: 1,
2868
+ children: [
2869
+ /* @__PURE__ */ jsxDEV4("text", {
2870
+ fg: theme.primary,
2871
+ children: "\uDB80\uDFD8 "
2872
+ }, undefined, false, undefined, this),
2873
+ /* @__PURE__ */ jsxDEV4("text", {
2874
+ fg: theme.text,
2875
+ children: "Themes"
2876
+ }, undefined, false, undefined, this),
2877
+ /* @__PURE__ */ jsxDEV4("text", {
2878
+ fg: theme.dim,
2879
+ children: [
2880
+ " ",
2881
+ themeName
2882
+ ]
2883
+ }, undefined, true, undefined, this)
2884
+ ]
2885
+ }, undefined, true, undefined, this),
2886
+ /* @__PURE__ */ jsxDEV4("box", {
2887
+ height: 1,
2888
+ backgroundColor: theme.border
2889
+ }, undefined, false, undefined, this),
2890
+ /* @__PURE__ */ jsxDEV4("box", {
2891
+ height: 1,
2892
+ flexDirection: "row",
2893
+ paddingLeft: 2,
2894
+ paddingRight: 2,
2895
+ paddingTop: 1,
2896
+ paddingBottom: 1,
2897
+ children: [
2898
+ /* @__PURE__ */ jsxDEV4("text", {
2899
+ fg: theme.dim,
2900
+ children: " "
2901
+ }, undefined, false, undefined, this),
2902
+ /* @__PURE__ */ jsxDEV4("text", {
2903
+ fg: query ? theme.text : theme.dim,
2904
+ children: query || "search..."
2905
+ }, undefined, false, undefined, this),
2906
+ query.length > 0 && /* @__PURE__ */ jsxDEV4("text", {
2907
+ fg: theme.accent,
2908
+ children: "_"
2909
+ }, undefined, false, undefined, this)
2910
+ ]
2911
+ }, undefined, true, undefined, this),
2912
+ /* @__PURE__ */ jsxDEV4("box", {
2913
+ height: 1,
2914
+ backgroundColor: theme.border
2915
+ }, undefined, false, undefined, this),
2916
+ /* @__PURE__ */ jsxDEV4("scrollbox", {
2917
+ ref: scrollRef,
2918
+ height: LIST_H,
2919
+ focused: false,
2920
+ children: filtered.length === 0 ? /* @__PURE__ */ jsxDEV4("box", {
2921
+ height: 1,
2922
+ paddingLeft: 3,
2923
+ children: /* @__PURE__ */ jsxDEV4("text", {
2924
+ fg: theme.dim,
2925
+ children: "no match"
2926
+ }, undefined, false, undefined, this)
2927
+ }, undefined, false, undefined, this) : filtered.map((name, i) => {
2928
+ const isActive = i === cursor;
2929
+ const isCurrent = name === themeName;
2930
+ const isDark = !LIGHT_THEMES.has(name);
2931
+ const tag = isDark ? "\u25C6" : "\u25C7";
2932
+ const tagColor = isDark ? theme.secondary : theme.accent;
2933
+ return /* @__PURE__ */ jsxDEV4("box", {
2934
+ height: 1,
2935
+ flexDirection: "row",
2936
+ backgroundColor: isActive ? theme.border : "transparent",
2937
+ paddingLeft: 2,
2938
+ paddingRight: 2,
2939
+ children: [
2940
+ /* @__PURE__ */ jsxDEV4("text", {
2941
+ fg: isCurrent ? theme.success : theme.dim,
2942
+ width: 2,
2943
+ children: isCurrent ? "\u2713" : " "
2944
+ }, undefined, false, undefined, this),
2945
+ /* @__PURE__ */ jsxDEV4("text", {
2946
+ fg: tagColor,
2947
+ width: 2,
2948
+ children: tag
2949
+ }, undefined, false, undefined, this),
2950
+ /* @__PURE__ */ jsxDEV4("text", {
2951
+ fg: isActive ? theme.text : theme.dim,
2952
+ children: [
2953
+ " ",
2954
+ name
2955
+ ]
2956
+ }, undefined, true, undefined, this),
2957
+ isActive && /* @__PURE__ */ jsxDEV4("text", {
2958
+ fg: theme.primary,
2959
+ children: " \u203A"
2960
+ }, undefined, false, undefined, this)
2961
+ ]
2962
+ }, name, true, undefined, this);
2963
+ })
2964
+ }, undefined, false, undefined, this),
2965
+ /* @__PURE__ */ jsxDEV4("box", {
2966
+ height: 1,
2967
+ backgroundColor: theme.border
2968
+ }, undefined, false, undefined, this),
2969
+ /* @__PURE__ */ jsxDEV4("box", {
2970
+ height: 1,
2971
+ flexDirection: "row",
2972
+ paddingLeft: 2,
2973
+ paddingRight: 2,
2974
+ paddingTop: 1,
2975
+ paddingBottom: 1,
2976
+ children: [
2977
+ /* @__PURE__ */ jsxDEV4("text", {
2978
+ fg: theme.secondary,
2979
+ children: "\u25C6"
2980
+ }, undefined, false, undefined, this),
2981
+ /* @__PURE__ */ jsxDEV4("text", {
2982
+ fg: theme.dim,
2983
+ children: " dark "
2984
+ }, undefined, false, undefined, this),
2985
+ /* @__PURE__ */ jsxDEV4("text", {
2986
+ fg: theme.accent,
2987
+ children: "\u25C7"
2988
+ }, undefined, false, undefined, this),
2989
+ /* @__PURE__ */ jsxDEV4("text", {
2990
+ fg: theme.dim,
2991
+ children: " light "
2992
+ }, undefined, false, undefined, this),
2993
+ /* @__PURE__ */ jsxDEV4("text", {
2994
+ fg: theme.dim,
2995
+ children: " [\u2191\u2193] [Esc]"
2996
+ }, undefined, false, undefined, this)
2997
+ ]
2998
+ }, undefined, true, undefined, this)
2999
+ ]
3000
+ }, undefined, true, undefined, this);
3001
+ }
3002
+ var LIGHT_THEMES;
3003
+ var init_ThemePicker = __esm(() => {
3004
+ init_ThemeContext();
3005
+ init_themes();
3006
+ LIGHT_THEMES = new Set(["github", "everforest", "solarized", "flexoki", "mercury", "vercel"]);
3007
+ });
3008
+
2267
3009
  // package.json
2268
3010
  var package_default;
2269
3011
  var init_package = __esm(() => {
2270
3012
  package_default = {
2271
3013
  name: "ai-speedometer",
2272
- version: "2.1.7",
3014
+ version: "2.2.1",
2273
3015
  description: "A comprehensive CLI tool for benchmarking AI models across multiple providers with parallel execution and professional metrics",
2274
3016
  bin: {
2275
3017
  "ai-speedometer": "dist/ai-speedometer",
@@ -2330,27 +3072,28 @@ var init_package = __esm(() => {
2330
3072
  });
2331
3073
 
2332
3074
  // src/tui/components/Header.tsx
2333
- import { jsxDEV as jsxDEV2 } from "@opentui/react/jsx-dev-runtime";
3075
+ import { jsxDEV as jsxDEV5 } from "@opentui/react/jsx-dev-runtime";
2334
3076
  function Header({ screen }) {
3077
+ const theme = useTheme();
2335
3078
  if (screen === "main-menu")
2336
3079
  return null;
2337
- return /* @__PURE__ */ jsxDEV2("box", {
3080
+ return /* @__PURE__ */ jsxDEV5("box", {
2338
3081
  height: 1,
2339
3082
  flexDirection: "row",
2340
3083
  alignItems: "center",
2341
3084
  paddingLeft: 2,
2342
- backgroundColor: "#16161e",
3085
+ backgroundColor: theme.background,
2343
3086
  children: [
2344
- /* @__PURE__ */ jsxDEV2("text", {
2345
- fg: "#7aa2f7",
3087
+ /* @__PURE__ */ jsxDEV5("text", {
3088
+ fg: theme.primary,
2346
3089
  children: "AI-SPEEDOMETER"
2347
3090
  }, undefined, false, undefined, this),
2348
- /* @__PURE__ */ jsxDEV2("text", {
2349
- fg: "#292e42",
3091
+ /* @__PURE__ */ jsxDEV5("text", {
3092
+ fg: theme.border,
2350
3093
  children: " \xB7 "
2351
3094
  }, undefined, false, undefined, this),
2352
- /* @__PURE__ */ jsxDEV2("text", {
2353
- fg: "#565f89",
3095
+ /* @__PURE__ */ jsxDEV5("text", {
3096
+ fg: theme.dim,
2354
3097
  children: [
2355
3098
  "v",
2356
3099
  package_default.version
@@ -2361,37 +3104,60 @@ function Header({ screen }) {
2361
3104
  }
2362
3105
  var init_Header = __esm(() => {
2363
3106
  init_package();
3107
+ init_ThemeContext();
2364
3108
  });
2365
3109
 
2366
3110
  // src/tui/components/Footer.tsx
2367
- import { jsxDEV as jsxDEV3 } from "@opentui/react/jsx-dev-runtime";
3111
+ import { jsxDEV as jsxDEV6 } from "@opentui/react/jsx-dev-runtime";
2368
3112
  function Footer({ hints }) {
3113
+ const theme = useTheme();
2369
3114
  const joined = hints.join(" \xB7 ");
2370
- return /* @__PURE__ */ jsxDEV3("box", {
3115
+ return /* @__PURE__ */ jsxDEV6("box", {
2371
3116
  height: 1,
2372
3117
  flexDirection: "row",
2373
3118
  alignItems: "center",
2374
3119
  paddingLeft: 1,
2375
3120
  paddingRight: 1,
2376
- backgroundColor: "#16161e",
2377
- children: /* @__PURE__ */ jsxDEV3("text", {
2378
- fg: "#565f89",
3121
+ backgroundColor: theme.background,
3122
+ children: /* @__PURE__ */ jsxDEV6("text", {
3123
+ fg: theme.dim,
2379
3124
  children: joined
2380
3125
  }, undefined, false, undefined, this)
2381
3126
  }, undefined, false, undefined, this);
2382
3127
  }
2383
- var init_Footer = () => {};
3128
+ var init_Footer = __esm(() => {
3129
+ init_ThemeContext();
3130
+ });
3131
+
3132
+ // src/tui/hooks/useAppKeyboard.ts
3133
+ import { useKeyboard as useKeyboard2 } from "@opentui/react";
3134
+ function useAppKeyboard(handler) {
3135
+ const { modalOpen } = useModal();
3136
+ useKeyboard2((key) => {
3137
+ if (modalOpen)
3138
+ return;
3139
+ handler(key);
3140
+ });
3141
+ }
3142
+ var init_useAppKeyboard = __esm(() => {
3143
+ init_ModalContext();
3144
+ });
2384
3145
 
2385
3146
  // src/tui/screens/MainMenuScreen.tsx
2386
- import { useState } from "react";
3147
+ import { useState as useState4 } from "react";
2387
3148
  import { useRenderer } from "@opentui/react";
2388
- import { useKeyboard } from "@opentui/react";
2389
- import { jsxDEV as jsxDEV4 } from "@opentui/react/jsx-dev-runtime";
3149
+ import { jsxDEV as jsxDEV7 } from "@opentui/react/jsx-dev-runtime";
2390
3150
  function MainMenuScreen() {
2391
3151
  const navigate = useNavigate();
2392
3152
  const renderer = useRenderer();
2393
- const [cursor, setCursor] = useState(0);
2394
- useKeyboard((key) => {
3153
+ const theme = useTheme();
3154
+ const [cursor, setCursor] = useState4(0);
3155
+ const ITEMS = [
3156
+ { label: "\u26A1 Run Benchmark", desc: "test model speed & throughput", color: theme.accent },
3157
+ { label: "\u2699 Manage Models", desc: "add providers and configure", color: theme.secondary },
3158
+ { label: "\u2715 Exit", desc: "quit the application", color: theme.error }
3159
+ ];
3160
+ useAppKeyboard((key) => {
2395
3161
  if (key.name === "up") {
2396
3162
  setCursor((i) => (i - 1 + ITEMS.length) % ITEMS.length);
2397
3163
  } else if (key.name === "down") {
@@ -2405,24 +3171,24 @@ function MainMenuScreen() {
2405
3171
  renderer.destroy();
2406
3172
  }
2407
3173
  });
2408
- return /* @__PURE__ */ jsxDEV4("box", {
3174
+ return /* @__PURE__ */ jsxDEV7("box", {
2409
3175
  flexDirection: "column",
2410
3176
  flexGrow: 1,
2411
3177
  alignItems: "center",
2412
3178
  justifyContent: "center",
2413
3179
  children: [
2414
- /* @__PURE__ */ jsxDEV4("box", {
3180
+ /* @__PURE__ */ jsxDEV7("box", {
2415
3181
  flexDirection: "column",
2416
3182
  alignItems: "center",
2417
3183
  marginBottom: 2,
2418
3184
  children: [
2419
- /* @__PURE__ */ jsxDEV4("ascii-font", {
3185
+ /* @__PURE__ */ jsxDEV7("ascii-font", {
2420
3186
  text: "AI-SPEEDOMETER",
2421
3187
  font: "tiny",
2422
- color: "#7aa2f7"
3188
+ color: theme.primary
2423
3189
  }, undefined, false, undefined, this),
2424
- /* @__PURE__ */ jsxDEV4("text", {
2425
- fg: "#565f89",
3190
+ /* @__PURE__ */ jsxDEV7("text", {
3191
+ fg: theme.dim,
2426
3192
  children: [
2427
3193
  "v",
2428
3194
  package_default.version
@@ -2430,39 +3196,39 @@ function MainMenuScreen() {
2430
3196
  }, undefined, true, undefined, this)
2431
3197
  ]
2432
3198
  }, undefined, true, undefined, this),
2433
- /* @__PURE__ */ jsxDEV4("box", {
3199
+ /* @__PURE__ */ jsxDEV7("box", {
2434
3200
  flexDirection: "column",
2435
3201
  border: true,
2436
3202
  borderStyle: "rounded",
2437
- borderColor: "#292e42",
2438
- backgroundColor: "#16161e",
3203
+ borderColor: theme.border,
3204
+ backgroundColor: theme.background,
2439
3205
  width: 46,
2440
3206
  children: ITEMS.map((item, i) => {
2441
3207
  const active = i === cursor;
2442
- return /* @__PURE__ */ jsxDEV4("box", {
3208
+ return /* @__PURE__ */ jsxDEV7("box", {
2443
3209
  flexDirection: "row",
2444
3210
  alignItems: "center",
2445
- backgroundColor: active ? "#292e42" : "transparent",
3211
+ backgroundColor: active ? theme.border : "transparent",
2446
3212
  paddingLeft: 2,
2447
3213
  paddingRight: 2,
2448
3214
  paddingTop: 1,
2449
3215
  paddingBottom: 1,
2450
3216
  children: [
2451
- /* @__PURE__ */ jsxDEV4("box", {
3217
+ /* @__PURE__ */ jsxDEV7("box", {
2452
3218
  flexDirection: "column",
2453
3219
  flexGrow: 1,
2454
3220
  children: [
2455
- /* @__PURE__ */ jsxDEV4("text", {
2456
- fg: active ? item.color : "#565f89",
3221
+ /* @__PURE__ */ jsxDEV7("text", {
3222
+ fg: active ? item.color : theme.dim,
2457
3223
  children: item.label
2458
3224
  }, undefined, false, undefined, this),
2459
- /* @__PURE__ */ jsxDEV4("text", {
2460
- fg: active ? "#565f89" : "#292e42",
3225
+ /* @__PURE__ */ jsxDEV7("text", {
3226
+ fg: active ? theme.dim : theme.border,
2461
3227
  children: item.desc
2462
3228
  }, undefined, false, undefined, this)
2463
3229
  ]
2464
3230
  }, undefined, true, undefined, this),
2465
- active && /* @__PURE__ */ jsxDEV4("text", {
3231
+ active && /* @__PURE__ */ jsxDEV7("text", {
2466
3232
  fg: item.color,
2467
3233
  children: "\u203A"
2468
3234
  }, undefined, false, undefined, this)
@@ -2473,24 +3239,20 @@ function MainMenuScreen() {
2473
3239
  ]
2474
3240
  }, undefined, true, undefined, this);
2475
3241
  }
2476
- var ITEMS;
2477
3242
  var init_MainMenuScreen = __esm(() => {
3243
+ init_useAppKeyboard();
2478
3244
  init_AppContext();
3245
+ init_ThemeContext();
2479
3246
  init_package();
2480
- ITEMS = [
2481
- { label: "\u26A1 Run Benchmark", desc: "test model speed & throughput", color: "#7dcfff" },
2482
- { label: "\u2699 Manage Models", desc: "add providers and configure", color: "#bb9af7" },
2483
- { label: "\u2715 Exit", desc: "quit the application", color: "#f7768e" }
2484
- ];
2485
3247
  });
2486
3248
 
2487
3249
  // src/tui/components/MenuList.tsx
2488
- import { useState as useState2 } from "react";
2489
- import { useKeyboard as useKeyboard2 } from "@opentui/react";
2490
- import { jsxDEV as jsxDEV5 } from "@opentui/react/jsx-dev-runtime";
3250
+ import { useState as useState5 } from "react";
3251
+ import { jsxDEV as jsxDEV8 } from "@opentui/react/jsx-dev-runtime";
2491
3252
  function MenuList({ items, selectedIndex: initialIndex = 0, onSelect, onNavigate }) {
2492
- const [cursor, setCursor] = useState2(initialIndex);
2493
- useKeyboard2((key) => {
3253
+ const theme = useTheme();
3254
+ const [cursor, setCursor] = useState5(initialIndex);
3255
+ useAppKeyboard((key) => {
2494
3256
  if (key.name === "up") {
2495
3257
  const next = (cursor - 1 + items.length) % items.length;
2496
3258
  setCursor(next);
@@ -2503,33 +3265,33 @@ function MenuList({ items, selectedIndex: initialIndex = 0, onSelect, onNavigate
2503
3265
  onSelect(cursor);
2504
3266
  }
2505
3267
  });
2506
- return /* @__PURE__ */ jsxDEV5("box", {
3268
+ return /* @__PURE__ */ jsxDEV8("box", {
2507
3269
  flexDirection: "column",
2508
3270
  children: items.map((item, i) => {
2509
3271
  const isSelected = i === cursor;
2510
- return /* @__PURE__ */ jsxDEV5("box", {
3272
+ return /* @__PURE__ */ jsxDEV8("box", {
2511
3273
  flexDirection: "row",
2512
3274
  alignItems: "center",
2513
- backgroundColor: isSelected ? "#292e42" : "transparent",
3275
+ backgroundColor: isSelected ? theme.border : "transparent",
2514
3276
  paddingLeft: 1,
2515
3277
  paddingRight: 1,
2516
3278
  children: [
2517
- /* @__PURE__ */ jsxDEV5("box", {
3279
+ /* @__PURE__ */ jsxDEV8("box", {
2518
3280
  flexDirection: "column",
2519
3281
  flexGrow: 1,
2520
3282
  children: [
2521
- /* @__PURE__ */ jsxDEV5("text", {
2522
- fg: isSelected ? "#c0caf5" : "#565f89",
3283
+ /* @__PURE__ */ jsxDEV8("text", {
3284
+ fg: isSelected ? theme.text : theme.dim,
2523
3285
  children: item.label
2524
3286
  }, undefined, false, undefined, this),
2525
- item.description ? /* @__PURE__ */ jsxDEV5("text", {
2526
- fg: isSelected ? "#565f89" : "#292e42",
3287
+ item.description ? /* @__PURE__ */ jsxDEV8("text", {
3288
+ fg: isSelected ? theme.dim : theme.border,
2527
3289
  children: item.description
2528
3290
  }, undefined, false, undefined, this) : null
2529
3291
  ]
2530
3292
  }, undefined, true, undefined, this),
2531
- isSelected && /* @__PURE__ */ jsxDEV5("text", {
2532
- fg: "#7aa2f7",
3293
+ isSelected && /* @__PURE__ */ jsxDEV8("text", {
3294
+ fg: theme.primary,
2533
3295
  children: "\u203A"
2534
3296
  }, undefined, false, undefined, this)
2535
3297
  ]
@@ -2537,14 +3299,17 @@ function MenuList({ items, selectedIndex: initialIndex = 0, onSelect, onNavigate
2537
3299
  })
2538
3300
  }, undefined, false, undefined, this);
2539
3301
  }
2540
- var init_MenuList = () => {};
3302
+ var init_MenuList = __esm(() => {
3303
+ init_useAppKeyboard();
3304
+ init_ThemeContext();
3305
+ });
2541
3306
 
2542
3307
  // src/tui/screens/ModelMenuScreen.tsx
2543
- import { useKeyboard as useKeyboard3 } from "@opentui/react";
2544
- import { jsxDEV as jsxDEV6 } from "@opentui/react/jsx-dev-runtime";
3308
+ import { jsxDEV as jsxDEV9 } from "@opentui/react/jsx-dev-runtime";
2545
3309
  function ModelMenuScreen() {
2546
3310
  const navigate = useNavigate();
2547
- useKeyboard3((key) => {
3311
+ const theme = useTheme();
3312
+ useAppKeyboard((key) => {
2548
3313
  if (key.name === "escape" || key.name === "q") {
2549
3314
  navigate("main-menu");
2550
3315
  }
@@ -2561,30 +3326,32 @@ function ModelMenuScreen() {
2561
3326
  else if (index === 4)
2562
3327
  navigate("main-menu");
2563
3328
  }
2564
- return /* @__PURE__ */ jsxDEV6("box", {
3329
+ return /* @__PURE__ */ jsxDEV9("box", {
2565
3330
  flexDirection: "column",
2566
3331
  flexGrow: 1,
2567
3332
  padding: 1,
2568
3333
  children: [
2569
- /* @__PURE__ */ jsxDEV6("text", {
2570
- fg: "#7aa2f7",
3334
+ /* @__PURE__ */ jsxDEV9("text", {
3335
+ fg: theme.primary,
2571
3336
  children: "Model Management"
2572
3337
  }, undefined, false, undefined, this),
2573
- /* @__PURE__ */ jsxDEV6("box", {
3338
+ /* @__PURE__ */ jsxDEV9("box", {
2574
3339
  marginTop: 1,
2575
- children: /* @__PURE__ */ jsxDEV6(MenuList, {
2576
- items: ITEMS2,
3340
+ children: /* @__PURE__ */ jsxDEV9(MenuList, {
3341
+ items: ITEMS,
2577
3342
  onSelect: handleSelect
2578
3343
  }, undefined, false, undefined, this)
2579
3344
  }, undefined, false, undefined, this)
2580
3345
  ]
2581
3346
  }, undefined, true, undefined, this);
2582
3347
  }
2583
- var ITEMS2;
3348
+ var ITEMS;
2584
3349
  var init_ModelMenuScreen = __esm(() => {
3350
+ init_useAppKeyboard();
2585
3351
  init_AppContext();
3352
+ init_ThemeContext();
2586
3353
  init_MenuList();
2587
- ITEMS2 = [
3354
+ ITEMS = [
2588
3355
  { label: "Add Verified Provider" },
2589
3356
  { label: "Add Custom Provider" },
2590
3357
  { label: "Add Models to Provider" },
@@ -2594,13 +3361,13 @@ var init_ModelMenuScreen = __esm(() => {
2594
3361
  });
2595
3362
 
2596
3363
  // src/tui/hooks/usePaste.ts
2597
- import { useEffect as useEffect2, useRef } from "react";
3364
+ import { useEffect as useEffect3, useRef as useRef2 } from "react";
2598
3365
  import { useRenderer as useRenderer2 } from "@opentui/react";
2599
3366
  function usePaste(onPaste) {
2600
3367
  const renderer = useRenderer2();
2601
- const callbackRef = useRef(onPaste);
3368
+ const callbackRef = useRef2(onPaste);
2602
3369
  callbackRef.current = onPaste;
2603
- useEffect2(() => {
3370
+ useEffect3(() => {
2604
3371
  const handler = (event) => callbackRef.current(event.text);
2605
3372
  renderer.keyInput.on("paste", handler);
2606
3373
  return () => {
@@ -2611,36 +3378,29 @@ function usePaste(onPaste) {
2611
3378
  var init_usePaste = () => {};
2612
3379
 
2613
3380
  // src/tui/screens/ModelSelectScreen.tsx
2614
- import { useState as useState3, useEffect as useEffect3, useCallback, useRef as useRef2 } from "react";
2615
- import { useKeyboard as useKeyboard4, useTerminalDimensions } from "@opentui/react";
2616
- import { jsxDEV as jsxDEV7 } from "@opentui/react/jsx-dev-runtime";
3381
+ import { useState as useState6, useEffect as useEffect4, useCallback as useCallback2, useRef as useRef3 } from "react";
3382
+ import { useTerminalDimensions } from "@opentui/react";
3383
+ import { jsxDEV as jsxDEV10 } from "@opentui/react/jsx-dev-runtime";
2617
3384
  function ModelSelectScreen() {
2618
3385
  const { state, dispatch } = useAppContext();
2619
3386
  const navigate = useNavigate();
3387
+ const theme = useTheme();
2620
3388
  const { height, width } = useTerminalDimensions();
2621
- const [searchQuery, setSearchQuery] = useState3("");
2622
- const [cursor, setCursor] = useState3(0);
2623
- const [selected, setSelected] = useState3(new Set);
2624
- const [allModels, setAllModels] = useState3([]);
2625
- const [recentKeys, setRecentKeys] = useState3(new Set);
2626
- const [debouncedQuery, setDebouncedQuery] = useState3("");
2627
- const scrollboxRef = useRef2(null);
3389
+ const [searchQuery, setSearchQuery] = useState6("");
3390
+ const [cursor, setCursor] = useState6(0);
3391
+ const [selected, setSelected] = useState6(new Set);
3392
+ const [allModels, setAllModels] = useState6([]);
3393
+ const [recentKeys, setRecentKeys] = useState6(new Set);
3394
+ const [debouncedQuery, setDebouncedQuery] = useState6("");
3395
+ const scrollboxRef = useRef3(null);
2628
3396
  const PAGE_SIZE = Math.max(3, height - 14);
2629
3397
  const CARD_W = Math.min(60, width - 4);
2630
- useEffect3(() => {
3398
+ useEffect4(() => {
2631
3399
  const providers = state.config?.providers ?? [];
2632
3400
  const models = [];
2633
3401
  for (const provider of providers) {
2634
3402
  for (const m of provider.models) {
2635
- models.push({
2636
- id: m.id,
2637
- name: m.name || m.id,
2638
- providerName: provider.name,
2639
- providerType: provider.type,
2640
- providerId: provider.id,
2641
- providerConfig: { baseUrl: provider.baseUrl, apiKey: provider.apiKey },
2642
- key: `${provider.id}::${m.id}`
2643
- });
3403
+ models.push({ id: m.id, name: m.name || m.id, providerName: provider.name, providerType: provider.type, providerId: provider.id, providerConfig: { baseUrl: provider.baseUrl, apiKey: provider.apiKey }, key: `${provider.id}::${m.id}` });
2644
3404
  }
2645
3405
  }
2646
3406
  setAllModels(models);
@@ -2662,11 +3422,11 @@ function ModelSelectScreen() {
2662
3422
  }
2663
3423
  loadRecents();
2664
3424
  }, [state.config]);
2665
- useEffect3(() => {
3425
+ useEffect4(() => {
2666
3426
  const t = setTimeout(() => setDebouncedQuery(searchQuery), DEBOUNCE_MS);
2667
3427
  return () => clearTimeout(t);
2668
3428
  }, [searchQuery]);
2669
- useEffect3(() => {
3429
+ useEffect4(() => {
2670
3430
  setCursor(0);
2671
3431
  }, [debouncedQuery]);
2672
3432
  function isRecent(m) {
@@ -2674,14 +3434,13 @@ function ModelSelectScreen() {
2674
3434
  }
2675
3435
  const orderedModels = (() => {
2676
3436
  if (!debouncedQuery) {
2677
- const recents = allModels.filter((m) => isRecent(m));
2678
- const rest = allModels.filter((m) => !isRecent(m));
2679
- return [...recents, ...rest];
3437
+ const r = allModels.filter((m) => isRecent(m));
3438
+ return [...r, ...allModels.filter((m) => !isRecent(m))];
2680
3439
  }
2681
3440
  const words = debouncedQuery.toLowerCase().split(/\s+/).filter((w) => w.length > 0);
2682
3441
  return allModels.filter((m) => {
2683
- const haystack = `${m.name} ${m.providerName} ${m.providerId} ${m.id}`.toLowerCase();
2684
- return words.every((w) => haystack.includes(w));
3442
+ const h = `${m.name} ${m.providerName} ${m.providerId} ${m.id}`.toLowerCase();
3443
+ return words.every((w) => h.includes(w));
2685
3444
  });
2686
3445
  })();
2687
3446
  const recentCount = !debouncedQuery ? orderedModels.filter((m) => isRecent(m)).length : 0;
@@ -2693,11 +3452,10 @@ function ModelSelectScreen() {
2693
3452
  const mIsRecent = isRecent(m);
2694
3453
  const prevIsRecent = i > 0 ? isRecent(orderedModels[i - 1]) : false;
2695
3454
  if (!debouncedQuery && recentCount > 0) {
2696
- if (i === 0 && mIsRecent) {
3455
+ if (i === 0 && mIsRecent)
2697
3456
  rows.push({ kind: "separator", label: "\u2500\u2500 recent \u2500\u2500" });
2698
- } else if (!mIsRecent && prevIsRecent) {
3457
+ else if (!mIsRecent && prevIsRecent)
2699
3458
  rows.push({ kind: "separator", label: "\u2500\u2500 all models \u2500\u2500" });
2700
- }
2701
3459
  }
2702
3460
  rows.push({ kind: "model", model: m, idx: modelIdx++ });
2703
3461
  }
@@ -2705,26 +3463,25 @@ function ModelSelectScreen() {
2705
3463
  })();
2706
3464
  const allModelRows = allRows.filter((r) => r.kind === "model");
2707
3465
  const cursorModel = allModelRows[cursor]?.model;
2708
- useEffect3(() => {
3466
+ useEffect4(() => {
2709
3467
  const sb = scrollboxRef.current;
2710
3468
  if (!sb)
2711
3469
  return;
2712
3470
  const top = sb.scrollTop;
2713
3471
  const visible = PAGE_SIZE;
2714
- if (cursor < top) {
3472
+ if (cursor < top)
2715
3473
  sb.scrollTo(cursor);
2716
- } else if (cursor >= top + visible) {
3474
+ else if (cursor >= top + visible)
2717
3475
  sb.scrollTo(cursor - visible + 1);
2718
- }
2719
3476
  }, [cursor, PAGE_SIZE]);
2720
- const launchBench = useCallback((models) => {
3477
+ const launchBench = useCallback2((models) => {
2721
3478
  dispatch({ type: "BENCH_START", models });
2722
3479
  navigate("benchmark");
2723
3480
  }, [dispatch, navigate]);
2724
3481
  usePaste((text) => {
2725
3482
  setSearchQuery((q) => q + text.replace(/[\r\n]/g, ""));
2726
3483
  });
2727
- useKeyboard4((key) => {
3484
+ useAppKeyboard((key) => {
2728
3485
  if (key.name === "escape") {
2729
3486
  navigate("main-menu");
2730
3487
  return;
@@ -2759,11 +3516,10 @@ function ModelSelectScreen() {
2759
3516
  return;
2760
3517
  }
2761
3518
  if (key.name === "return" || key.name === "enter") {
2762
- if (selected.size > 0) {
3519
+ if (selected.size > 0)
2763
3520
  launchBench(allModels.filter((m) => selected.has(m.key)));
2764
- } else if (cursorModel) {
3521
+ else if (cursorModel)
2765
3522
  launchBench([cursorModel]);
2766
- }
2767
3523
  return;
2768
3524
  }
2769
3525
  if (!searchQuery && key.sequence === "A") {
@@ -2782,50 +3538,49 @@ function ModelSelectScreen() {
2782
3538
  setSearchQuery((q) => q.slice(0, -1));
2783
3539
  return;
2784
3540
  }
2785
- if (key.sequence && key.sequence.length === 1 && !key.ctrl && !key.meta && key.sequence >= " ") {
3541
+ if (key.sequence && key.sequence.length === 1 && !key.ctrl && !key.meta && key.sequence >= " ")
2786
3542
  setSearchQuery((q) => q + key.sequence);
2787
- }
2788
3543
  });
2789
3544
  if (state.isLoadingConfig) {
2790
- return /* @__PURE__ */ jsxDEV7("box", {
3545
+ return /* @__PURE__ */ jsxDEV10("box", {
2791
3546
  flexDirection: "column",
2792
3547
  flexGrow: 1,
2793
3548
  alignItems: "center",
2794
3549
  justifyContent: "center",
2795
- children: /* @__PURE__ */ jsxDEV7("text", {
2796
- fg: "#565f89",
3550
+ children: /* @__PURE__ */ jsxDEV10("text", {
3551
+ fg: theme.dim,
2797
3552
  children: "Loading config..."
2798
3553
  }, undefined, false, undefined, this)
2799
3554
  }, undefined, false, undefined, this);
2800
3555
  }
2801
3556
  const nameW = Math.floor((CARD_W - 10) / 2);
2802
3557
  const provW = CARD_W - nameW - 10;
2803
- return /* @__PURE__ */ jsxDEV7("box", {
3558
+ return /* @__PURE__ */ jsxDEV10("box", {
2804
3559
  flexDirection: "column",
2805
3560
  flexGrow: 1,
2806
3561
  alignItems: "center",
2807
3562
  justifyContent: "center",
2808
- children: /* @__PURE__ */ jsxDEV7("box", {
3563
+ children: /* @__PURE__ */ jsxDEV10("box", {
2809
3564
  flexDirection: "column",
2810
3565
  border: true,
2811
3566
  borderStyle: "rounded",
2812
- borderColor: "#292e42",
2813
- backgroundColor: "#16161e",
3567
+ borderColor: theme.border,
3568
+ backgroundColor: theme.background,
2814
3569
  width: CARD_W,
2815
3570
  children: [
2816
- /* @__PURE__ */ jsxDEV7("box", {
3571
+ /* @__PURE__ */ jsxDEV10("box", {
2817
3572
  flexDirection: "row",
2818
3573
  paddingLeft: 2,
2819
3574
  paddingRight: 2,
2820
3575
  paddingTop: 1,
2821
3576
  paddingBottom: 1,
2822
3577
  children: [
2823
- /* @__PURE__ */ jsxDEV7("text", {
2824
- fg: "#7dcfff",
3578
+ /* @__PURE__ */ jsxDEV10("text", {
3579
+ fg: theme.accent,
2825
3580
  children: "Search: "
2826
3581
  }, undefined, false, undefined, this),
2827
- /* @__PURE__ */ jsxDEV7("text", {
2828
- fg: "#c0caf5",
3582
+ /* @__PURE__ */ jsxDEV10("text", {
3583
+ fg: theme.text,
2829
3584
  children: [
2830
3585
  searchQuery,
2831
3586
  "_"
@@ -2833,74 +3588,73 @@ function ModelSelectScreen() {
2833
3588
  }, undefined, true, undefined, this)
2834
3589
  ]
2835
3590
  }, undefined, true, undefined, this),
2836
- /* @__PURE__ */ jsxDEV7("box", {
3591
+ /* @__PURE__ */ jsxDEV10("box", {
2837
3592
  height: 1,
2838
- backgroundColor: "#292e42"
3593
+ backgroundColor: theme.border
2839
3594
  }, undefined, false, undefined, this),
2840
- /* @__PURE__ */ jsxDEV7("scrollbox", {
3595
+ /* @__PURE__ */ jsxDEV10("scrollbox", {
2841
3596
  ref: scrollboxRef,
2842
3597
  height: PAGE_SIZE,
2843
- style: { scrollbarOptions: { showArrows: true, trackOptions: { foregroundColor: "#7aa2f7", backgroundColor: "#292e42" } } },
3598
+ style: { scrollbarOptions: { showArrows: true, trackOptions: { foregroundColor: theme.primary, backgroundColor: theme.border } } },
2844
3599
  children: [
2845
- allRows.length === 0 && /* @__PURE__ */ jsxDEV7("box", {
3600
+ allRows.length === 0 && /* @__PURE__ */ jsxDEV10("box", {
2846
3601
  height: 1,
2847
3602
  paddingLeft: 2,
2848
- children: /* @__PURE__ */ jsxDEV7("text", {
2849
- fg: "#565f89",
3603
+ children: /* @__PURE__ */ jsxDEV10("text", {
3604
+ fg: theme.dim,
2850
3605
  children: "No models found"
2851
3606
  }, undefined, false, undefined, this)
2852
3607
  }, undefined, false, undefined, this),
2853
3608
  (() => {
2854
3609
  let modelCursor = 0;
2855
3610
  return allRows.map((row, i) => {
2856
- if (row.kind === "separator") {
2857
- return /* @__PURE__ */ jsxDEV7("box", {
3611
+ if (row.kind === "separator")
3612
+ return /* @__PURE__ */ jsxDEV10("box", {
2858
3613
  height: 1,
2859
3614
  paddingLeft: 2,
2860
- children: /* @__PURE__ */ jsxDEV7("text", {
2861
- fg: "#565f89",
3615
+ children: /* @__PURE__ */ jsxDEV10("text", {
3616
+ fg: theme.dim,
2862
3617
  children: row.label
2863
3618
  }, undefined, false, undefined, this)
2864
3619
  }, `sep-${i}`, false, undefined, this);
2865
- }
2866
3620
  const localCursor = modelCursor++;
2867
3621
  const isActive = localCursor === cursor;
2868
3622
  const isSel = selected.has(row.model.key);
2869
- let nameFg = "#565f89";
3623
+ let nameFg = theme.dim;
2870
3624
  if (isActive && isSel)
2871
- nameFg = "#7dcfff";
3625
+ nameFg = theme.accent;
2872
3626
  else if (isActive)
2873
- nameFg = "#c0caf5";
3627
+ nameFg = theme.text;
2874
3628
  else if (isSel)
2875
- nameFg = "#9ece6a";
2876
- return /* @__PURE__ */ jsxDEV7("box", {
3629
+ nameFg = theme.success;
3630
+ return /* @__PURE__ */ jsxDEV10("box", {
2877
3631
  height: 1,
2878
3632
  width: "100%",
2879
3633
  flexDirection: "row",
2880
- backgroundColor: isActive ? "#292e42" : "transparent",
3634
+ backgroundColor: isActive ? theme.border : "transparent",
2881
3635
  children: [
2882
- /* @__PURE__ */ jsxDEV7("text", {
2883
- fg: "#565f89",
3636
+ /* @__PURE__ */ jsxDEV10("text", {
3637
+ fg: theme.dim,
2884
3638
  width: 2,
2885
3639
  children: " "
2886
3640
  }, undefined, false, undefined, this),
2887
- /* @__PURE__ */ jsxDEV7("text", {
3641
+ /* @__PURE__ */ jsxDEV10("text", {
2888
3642
  fg: nameFg,
2889
3643
  width: nameW,
2890
3644
  children: row.model.name
2891
3645
  }, undefined, false, undefined, this),
2892
- /* @__PURE__ */ jsxDEV7("text", {
2893
- fg: isActive ? "#7aa2f7" : "#565f89",
3646
+ /* @__PURE__ */ jsxDEV10("text", {
3647
+ fg: isActive ? theme.primary : theme.dim,
2894
3648
  width: provW,
2895
3649
  children: row.model.providerName
2896
3650
  }, undefined, false, undefined, this),
2897
- /* @__PURE__ */ jsxDEV7("text", {
2898
- fg: "#9ece6a",
3651
+ /* @__PURE__ */ jsxDEV10("text", {
3652
+ fg: theme.success,
2899
3653
  width: 2,
2900
3654
  children: isSel ? "\u2713" : " "
2901
3655
  }, undefined, false, undefined, this),
2902
- /* @__PURE__ */ jsxDEV7("text", {
2903
- fg: "#7dcfff",
3656
+ /* @__PURE__ */ jsxDEV10("text", {
3657
+ fg: theme.accent,
2904
3658
  width: 2,
2905
3659
  children: isActive ? "\u203A" : " "
2906
3660
  }, undefined, false, undefined, this)
@@ -2910,19 +3664,19 @@ function ModelSelectScreen() {
2910
3664
  })()
2911
3665
  ]
2912
3666
  }, undefined, true, undefined, this),
2913
- /* @__PURE__ */ jsxDEV7("box", {
3667
+ /* @__PURE__ */ jsxDEV10("box", {
2914
3668
  height: 1,
2915
- backgroundColor: "#292e42"
3669
+ backgroundColor: theme.border
2916
3670
  }, undefined, false, undefined, this),
2917
- /* @__PURE__ */ jsxDEV7("box", {
3671
+ /* @__PURE__ */ jsxDEV10("box", {
2918
3672
  flexDirection: "row",
2919
3673
  paddingLeft: 2,
2920
3674
  paddingRight: 2,
2921
3675
  paddingTop: 1,
2922
3676
  paddingBottom: 1,
2923
3677
  children: [
2924
- /* @__PURE__ */ jsxDEV7("text", {
2925
- fg: "#bb9af7",
3678
+ /* @__PURE__ */ jsxDEV10("text", {
3679
+ fg: theme.secondary,
2926
3680
  children: [
2927
3681
  "Selected: ",
2928
3682
  selected.size,
@@ -2930,16 +3684,16 @@ function ModelSelectScreen() {
2930
3684
  selected.size !== 1 ? "s" : ""
2931
3685
  ]
2932
3686
  }, undefined, true, undefined, this),
2933
- recentCount > 0 && /* @__PURE__ */ jsxDEV7("text", {
2934
- fg: "#565f89",
3687
+ recentCount > 0 && /* @__PURE__ */ jsxDEV10("text", {
3688
+ fg: theme.dim,
2935
3689
  children: [
2936
3690
  " [R] recent (",
2937
3691
  recentCount,
2938
3692
  ")"
2939
3693
  ]
2940
3694
  }, undefined, true, undefined, this),
2941
- /* @__PURE__ */ jsxDEV7("text", {
2942
- fg: "#565f89",
3695
+ /* @__PURE__ */ jsxDEV10("text", {
3696
+ fg: theme.dim,
2943
3697
  children: " [\u2191\u2193/PgUp/PgDn/wheel] scroll"
2944
3698
  }, undefined, false, undefined, this)
2945
3699
  ]
@@ -2950,25 +3704,107 @@ function ModelSelectScreen() {
2950
3704
  }
2951
3705
  var DEBOUNCE_MS = 50;
2952
3706
  var init_ModelSelectScreen = __esm(() => {
3707
+ init_useAppKeyboard();
2953
3708
  init_AppContext();
3709
+ init_ThemeContext();
2954
3710
  init_usePaste();
2955
3711
  });
2956
3712
 
2957
3713
  // src/tui/components/BarChart.tsx
2958
- import { jsxDEV as jsxDEV8 } from "@opentui/react/jsx-dev-runtime";
3714
+ import { jsxDEV as jsxDEV11 } from "@opentui/react/jsx-dev-runtime";
2959
3715
  function BarChart({ value, max, width, color }) {
2960
3716
  const filled = max === 0 ? 0 : Math.round(value / max * width);
2961
3717
  const empty = width - filled;
2962
3718
  const bar = "\u2588".repeat(filled) + "\u2591".repeat(empty);
2963
- return /* @__PURE__ */ jsxDEV8("text", {
3719
+ return /* @__PURE__ */ jsxDEV11("text", {
2964
3720
  fg: color,
2965
3721
  children: bar
2966
3722
  }, undefined, false, undefined, this);
2967
3723
  }
2968
3724
  var init_BarChart = () => {};
2969
3725
 
3726
+ // src/tui/components/GlowBar.tsx
3727
+ import { useState as useState7, useEffect as useEffect5 } from "react";
3728
+ import { engine, Timeline } from "@opentui/core";
3729
+ import { jsxDEV as jsxDEV12 } from "@opentui/react/jsx-dev-runtime";
3730
+ function blendHex(hex, toward, t) {
3731
+ const parse3 = (h) => [
3732
+ parseInt(h.slice(1, 3), 16),
3733
+ parseInt(h.slice(3, 5), 16),
3734
+ parseInt(h.slice(5, 7), 16)
3735
+ ];
3736
+ const [r1, g1, b1] = parse3(hex.length === 7 ? hex : "#ffffff");
3737
+ const [r2, g2, b2] = parse3(toward.length === 7 ? toward : "#ffffff");
3738
+ const r = Math.round(r1 + (r2 - r1) * t);
3739
+ const g = Math.round(g1 + (g2 - g1) * t);
3740
+ const b = Math.round(b1 + (b2 - b1) * t);
3741
+ return `#${r.toString(16).padStart(2, "0")}${g.toString(16).padStart(2, "0")}${b.toString(16).padStart(2, "0")}`;
3742
+ }
3743
+ function GlowBar({ done, total, running }) {
3744
+ const theme = useTheme();
3745
+ const [pos, setPos] = useState7(0);
3746
+ useEffect5(() => {
3747
+ const tl = new Timeline({ loop: true, duration: 2200 });
3748
+ const target = { pos: 0 };
3749
+ tl.add(target, { pos: 1, duration: 2200, ease: "linear", onUpdate: (anim) => {
3750
+ setPos(anim.targets[0].pos);
3751
+ } }, 0);
3752
+ tl.play();
3753
+ engine.register(tl);
3754
+ return () => {
3755
+ tl.pause();
3756
+ engine.unregister(tl);
3757
+ };
3758
+ }, []);
3759
+ const filled = Math.round(done / (total || 1) * BAR_W);
3760
+ const barChars = Array.from({ length: BAR_W }, (_, i) => {
3761
+ if (i >= filled)
3762
+ return { ch: "\u2591", fg: theme.border };
3763
+ const phase = pos - i / BAR_W;
3764
+ const intensity = Math.sin(Math.PI * phase * 1.5);
3765
+ const fg = intensity >= 0 ? blendHex(theme.accent, "#ffffff", intensity * 0.55) : blendHex(theme.accent, theme.background, Math.abs(intensity) * 0.5);
3766
+ return { ch: "\u2588", fg };
3767
+ });
3768
+ return /* @__PURE__ */ jsxDEV12("box", {
3769
+ height: 1,
3770
+ flexDirection: "row",
3771
+ paddingLeft: 2,
3772
+ children: [
3773
+ /* @__PURE__ */ jsxDEV12("text", {
3774
+ fg: theme.dim,
3775
+ children: "Benchmarking "
3776
+ }, undefined, false, undefined, this),
3777
+ /* @__PURE__ */ jsxDEV12("text", {
3778
+ fg: theme.accent,
3779
+ children: [
3780
+ done,
3781
+ "/",
3782
+ total,
3783
+ " "
3784
+ ]
3785
+ }, undefined, true, undefined, this),
3786
+ barChars.map((b, i) => /* @__PURE__ */ jsxDEV12("text", {
3787
+ fg: b.fg,
3788
+ children: b.ch
3789
+ }, i, false, undefined, this)),
3790
+ /* @__PURE__ */ jsxDEV12("text", {
3791
+ fg: theme.warning,
3792
+ children: [
3793
+ " ",
3794
+ running,
3795
+ " running..."
3796
+ ]
3797
+ }, undefined, true, undefined, this)
3798
+ ]
3799
+ }, undefined, true, undefined, this);
3800
+ }
3801
+ var BAR_W = 25;
3802
+ var init_GlowBar = __esm(() => {
3803
+ init_ThemeContext();
3804
+ });
3805
+
2970
3806
  // src/tui/components/ResultsTable.tsx
2971
- import { jsxDEV as jsxDEV9 } from "@opentui/react/jsx-dev-runtime";
3807
+ import { jsxDEV as jsxDEV13 } from "@opentui/react/jsx-dev-runtime";
2972
3808
  function lpad(s, w) {
2973
3809
  return s.length >= w ? s.slice(0, w) : " ".repeat(w - s.length) + s;
2974
3810
  }
@@ -2979,6 +3815,7 @@ function trunc(s, w) {
2979
3815
  return s.length > w ? s.slice(0, w - 1) + "\u2026" : s;
2980
3816
  }
2981
3817
  function ResultsTable({ results, pendingCount }) {
3818
+ const theme = useTheme();
2982
3819
  const sorted = [...results].sort((a, b) => b.tokensPerSecond - a.tokensPerSecond);
2983
3820
  const C = { rank: 4, model: 18, prov: 12, time: 10, ttft: 8, tps: 11, out: 8, inp: 8, tot: 8 };
2984
3821
  const totalW = C.rank + C.model + C.prov + C.time + C.ttft + C.tps + C.out + C.inp + C.tot + 9;
@@ -2987,22 +3824,22 @@ function ResultsTable({ results, pendingCount }) {
2987
3824
  return lpad(rank, C.rank) + " \u2502 " + rpad(model, C.model) + " \u2502 " + rpad(prov, C.prov) + " \u2502 " + lpad(time, C.time) + " \u2502 " + lpad(ttft, C.ttft) + " \u2502 " + lpad(tps, C.tps) + " \u2502 " + lpad(out, C.out) + " \u2502 " + lpad(inp, C.inp) + " \u2502 " + lpad(tot, C.tot);
2988
3825
  }
2989
3826
  const header = row("#", "Model", "Provider", "Time(s)", "TTFT(s)", "Tokens/Sec", "Out", "In", "Total");
2990
- return /* @__PURE__ */ jsxDEV9("box", {
3827
+ return /* @__PURE__ */ jsxDEV13("box", {
2991
3828
  flexDirection: "column",
2992
3829
  paddingLeft: 1,
2993
3830
  paddingRight: 1,
2994
3831
  children: [
2995
- /* @__PURE__ */ jsxDEV9("box", {
3832
+ /* @__PURE__ */ jsxDEV13("box", {
2996
3833
  height: 1,
2997
- children: /* @__PURE__ */ jsxDEV9("text", {
2998
- fg: "#7dcfff",
3834
+ children: /* @__PURE__ */ jsxDEV13("text", {
3835
+ fg: theme.accent,
2999
3836
  children: header
3000
3837
  }, undefined, false, undefined, this)
3001
3838
  }, undefined, false, undefined, this),
3002
- /* @__PURE__ */ jsxDEV9("box", {
3839
+ /* @__PURE__ */ jsxDEV13("box", {
3003
3840
  height: 1,
3004
- children: /* @__PURE__ */ jsxDEV9("text", {
3005
- fg: "#292e42",
3841
+ children: /* @__PURE__ */ jsxDEV13("text", {
3842
+ fg: theme.border,
3006
3843
  children: sep
3007
3844
  }, undefined, false, undefined, this)
3008
3845
  }, undefined, false, undefined, this),
@@ -3016,32 +3853,32 @@ function ResultsTable({ results, pendingCount }) {
3016
3853
  const totTok = r.totalTokens.toString() + (r.usedEstimateForOutput || r.usedEstimateForInput ? "[e]" : "");
3017
3854
  const hasEst = r.usedEstimateForOutput || r.usedEstimateForInput;
3018
3855
  const line = row(rank, trunc(r.model, C.model), trunc(r.provider, C.prov), timeSec, ttftSec, tps, outTok, inTok, totTok);
3019
- return /* @__PURE__ */ jsxDEV9("box", {
3856
+ return /* @__PURE__ */ jsxDEV13("box", {
3020
3857
  height: 1,
3021
3858
  flexDirection: "row",
3022
3859
  children: [
3023
- /* @__PURE__ */ jsxDEV9("text", {
3024
- fg: "#c0caf5",
3860
+ /* @__PURE__ */ jsxDEV13("text", {
3861
+ fg: theme.text,
3025
3862
  children: line
3026
3863
  }, undefined, false, undefined, this),
3027
- hasEst && /* @__PURE__ */ jsxDEV9("text", {
3028
- fg: "#ff9e64",
3864
+ hasEst && /* @__PURE__ */ jsxDEV13("text", {
3865
+ fg: theme.warning,
3029
3866
  children: " [est]"
3030
3867
  }, undefined, false, undefined, this)
3031
3868
  ]
3032
3869
  }, `${r.model}-${r.provider}-${i}`, true, undefined, this);
3033
3870
  }),
3034
- /* @__PURE__ */ jsxDEV9("box", {
3871
+ /* @__PURE__ */ jsxDEV13("box", {
3035
3872
  height: 1,
3036
- children: /* @__PURE__ */ jsxDEV9("text", {
3037
- fg: "#292e42",
3873
+ children: /* @__PURE__ */ jsxDEV13("text", {
3874
+ fg: theme.border,
3038
3875
  children: sep
3039
3876
  }, undefined, false, undefined, this)
3040
3877
  }, undefined, false, undefined, this),
3041
- pendingCount > 0 && /* @__PURE__ */ jsxDEV9("box", {
3878
+ pendingCount > 0 && /* @__PURE__ */ jsxDEV13("box", {
3042
3879
  height: 1,
3043
- children: /* @__PURE__ */ jsxDEV9("text", {
3044
- fg: "#565f89",
3880
+ children: /* @__PURE__ */ jsxDEV13("text", {
3881
+ fg: theme.dim,
3045
3882
  children: [
3046
3883
  " Waiting for ",
3047
3884
  pendingCount,
@@ -3054,12 +3891,13 @@ function ResultsTable({ results, pendingCount }) {
3054
3891
  ]
3055
3892
  }, undefined, true, undefined, this);
3056
3893
  }
3057
- var init_ResultsTable = () => {};
3894
+ var init_ResultsTable = __esm(() => {
3895
+ init_ThemeContext();
3896
+ });
3058
3897
 
3059
3898
  // src/tui/screens/BenchmarkScreen.tsx
3060
- import { useState as useState4, useEffect as useEffect4, useRef as useRef3, useMemo } from "react";
3061
- import { useKeyboard as useKeyboard5 } from "@opentui/react";
3062
- import { jsxDEV as jsxDEV10 } from "@opentui/react/jsx-dev-runtime";
3899
+ import { useState as useState8, useEffect as useEffect6, useRef as useRef4, useMemo } from "react";
3900
+ import { jsxDEV as jsxDEV14 } from "@opentui/react/jsx-dev-runtime";
3063
3901
  function rankBadge(rank) {
3064
3902
  if (rank === 1)
3065
3903
  return "1st";
@@ -3069,21 +3907,16 @@ function rankBadge(rank) {
3069
3907
  return "3rd";
3070
3908
  return `${rank}th`;
3071
3909
  }
3072
- function Divider() {
3073
- return /* @__PURE__ */ jsxDEV10("box", {
3074
- height: 1,
3075
- backgroundColor: "#292e42"
3076
- }, undefined, false, undefined, this);
3077
- }
3078
3910
  function BenchmarkScreen() {
3079
3911
  const { state, dispatch } = useAppContext();
3080
3912
  const navigate = useNavigate();
3081
- const [modelStates, setModelStates] = useState4([]);
3082
- const [spinnerFrame, setSpinnerFrame] = useState4(0);
3083
- const [allDone, setAllDone] = useState4(false);
3084
- const spinnerRef = useRef3(null);
3085
- const startedRef = useRef3(false);
3086
- useEffect4(() => {
3913
+ const theme = useTheme();
3914
+ const [modelStates, setModelStates] = useState8([]);
3915
+ const [spinnerFrame, setSpinnerFrame] = useState8(0);
3916
+ const [allDone, setAllDone] = useState8(false);
3917
+ const spinnerRef = useRef4(null);
3918
+ const startedRef = useRef4(false);
3919
+ useEffect6(() => {
3087
3920
  if (startedRef.current)
3088
3921
  return;
3089
3922
  startedRef.current = true;
@@ -3148,72 +3981,38 @@ function BenchmarkScreen() {
3148
3981
  const allRows = useMemo(() => {
3149
3982
  const rows = [];
3150
3983
  if (!allDone) {
3151
- const total = modelStates.length || 1;
3152
- const filled = Math.round((done.length + errors.length) / total * BAR_W);
3153
- const empty = BAR_W - filled;
3154
- rows.push(/* @__PURE__ */ jsxDEV10("box", {
3155
- height: 1,
3156
- flexDirection: "row",
3157
- paddingLeft: 2,
3158
- children: [
3159
- /* @__PURE__ */ jsxDEV10("text", {
3160
- fg: "#565f89",
3161
- children: "Benchmarking "
3162
- }, undefined, false, undefined, this),
3163
- /* @__PURE__ */ jsxDEV10("text", {
3164
- fg: "#7dcfff",
3165
- children: [
3166
- done.length + errors.length,
3167
- "/",
3168
- modelStates.length,
3169
- " "
3170
- ]
3171
- }, undefined, true, undefined, this),
3172
- /* @__PURE__ */ jsxDEV10("text", {
3173
- fg: "#7dcfff",
3174
- children: "\u2588".repeat(filled)
3175
- }, undefined, false, undefined, this),
3176
- /* @__PURE__ */ jsxDEV10("text", {
3177
- fg: "#292e42",
3178
- children: "\u2591".repeat(empty)
3179
- }, undefined, false, undefined, this),
3180
- /* @__PURE__ */ jsxDEV10("text", {
3181
- fg: "#ff9e64",
3182
- children: [
3183
- " ",
3184
- running.length,
3185
- " running..."
3186
- ]
3187
- }, undefined, true, undefined, this)
3188
- ]
3189
- }, "progress-bar", true, undefined, this));
3984
+ rows.push(/* @__PURE__ */ jsxDEV14(GlowBar, {
3985
+ done: done.length + errors.length,
3986
+ total: modelStates.length,
3987
+ running: running.length
3988
+ }, "progress-bar", false, undefined, this));
3190
3989
  for (const s of modelStates.filter((s2) => s2.status === "done" || s2.status === "error")) {
3191
3990
  if (s.status === "done") {
3192
- rows.push(/* @__PURE__ */ jsxDEV10("box", {
3991
+ rows.push(/* @__PURE__ */ jsxDEV14("box", {
3193
3992
  height: 1,
3194
3993
  flexDirection: "row",
3195
3994
  paddingLeft: 2,
3196
3995
  children: [
3197
- /* @__PURE__ */ jsxDEV10("text", {
3198
- fg: "#9ece6a",
3996
+ /* @__PURE__ */ jsxDEV14("text", {
3997
+ fg: theme.success,
3199
3998
  children: " \u2713 "
3200
3999
  }, undefined, false, undefined, this),
3201
- /* @__PURE__ */ jsxDEV10("text", {
3202
- fg: "#c0caf5",
4000
+ /* @__PURE__ */ jsxDEV14("text", {
4001
+ fg: theme.text,
3203
4002
  children: [
3204
4003
  s.model.name,
3205
4004
  " "
3206
4005
  ]
3207
4006
  }, undefined, true, undefined, this),
3208
- /* @__PURE__ */ jsxDEV10("text", {
3209
- fg: "#7dcfff",
4007
+ /* @__PURE__ */ jsxDEV14("text", {
4008
+ fg: theme.accent,
3210
4009
  children: [
3211
4010
  (s.result?.tokensPerSecond ?? 0).toFixed(1),
3212
4011
  " tok/s "
3213
4012
  ]
3214
4013
  }, undefined, true, undefined, this),
3215
- /* @__PURE__ */ jsxDEV10("text", {
3216
- fg: "#bb9af7",
4014
+ /* @__PURE__ */ jsxDEV14("text", {
4015
+ fg: theme.secondary,
3217
4016
  children: [
3218
4017
  ((s.result?.timeToFirstToken ?? 0) / 1000).toFixed(2),
3219
4018
  "s TTFT"
@@ -3222,213 +4021,213 @@ function BenchmarkScreen() {
3222
4021
  ]
3223
4022
  }, `prog-${s.model.id}-${s.model.providerId}`, true, undefined, this));
3224
4023
  } else {
3225
- rows.push(/* @__PURE__ */ jsxDEV10("box", {
4024
+ rows.push(/* @__PURE__ */ jsxDEV14("box", {
3226
4025
  height: 1,
3227
4026
  flexDirection: "row",
3228
4027
  paddingLeft: 2,
3229
4028
  children: [
3230
- /* @__PURE__ */ jsxDEV10("text", {
3231
- fg: "#f7768e",
4029
+ /* @__PURE__ */ jsxDEV14("text", {
4030
+ fg: theme.error,
3232
4031
  children: " \u2717 "
3233
4032
  }, undefined, false, undefined, this),
3234
- /* @__PURE__ */ jsxDEV10("text", {
3235
- fg: "#c0caf5",
4033
+ /* @__PURE__ */ jsxDEV14("text", {
4034
+ fg: theme.text,
3236
4035
  children: [
3237
4036
  s.model.name,
3238
4037
  " "
3239
4038
  ]
3240
4039
  }, undefined, true, undefined, this),
3241
- /* @__PURE__ */ jsxDEV10("text", {
3242
- fg: "#f7768e",
4040
+ /* @__PURE__ */ jsxDEV14("text", {
4041
+ fg: theme.error,
3243
4042
  children: s.error ?? "error"
3244
4043
  }, undefined, false, undefined, this)
3245
4044
  ]
3246
4045
  }, `prog-${s.model.id}-${s.model.providerId}`, true, undefined, this));
3247
4046
  }
3248
4047
  }
3249
- rows.push(/* @__PURE__ */ jsxDEV10("box", {
4048
+ rows.push(/* @__PURE__ */ jsxDEV14("box", {
3250
4049
  height: 1
3251
4050
  }, "prog-spacer", false, undefined, this));
3252
4051
  }
3253
4052
  if (tpsRanked.length > 0) {
3254
- rows.push(/* @__PURE__ */ jsxDEV10("box", {
4053
+ rows.push(/* @__PURE__ */ jsxDEV14("box", {
3255
4054
  height: 1,
3256
- backgroundColor: "#292e42"
4055
+ backgroundColor: theme.border
3257
4056
  }, "div-tps", false, undefined, this));
3258
- rows.push(/* @__PURE__ */ jsxDEV10("box", {
4057
+ rows.push(/* @__PURE__ */ jsxDEV14("box", {
3259
4058
  height: 1,
3260
4059
  flexDirection: "row",
3261
4060
  paddingLeft: 1,
3262
- children: /* @__PURE__ */ jsxDEV10("text", {
3263
- fg: "#7aa2f7",
4061
+ children: /* @__PURE__ */ jsxDEV14("text", {
4062
+ fg: theme.primary,
3264
4063
  children: " TOKENS/SEC RANKING (higher is better) "
3265
4064
  }, undefined, false, undefined, this)
3266
4065
  }, "hdr-tps", false, undefined, this));
3267
4066
  for (const [i, s] of tpsRanked.entries()) {
3268
4067
  const rank = i + 1;
3269
- const rankFg = rank === 1 ? "#7dcfff" : rank === 2 ? "#bb9af7" : "#565f89";
4068
+ const rankFg = rank === 1 ? theme.accent : rank === 2 ? theme.secondary : theme.dim;
3270
4069
  const tps = s.result?.tokensPerSecond ?? 0;
3271
4070
  const timeSec = (s.result?.totalTime ?? 0) / 1000;
3272
4071
  const badge = rankBadge(rank).padStart(3);
3273
4072
  const modelCol = s.model.name.padEnd(18).slice(0, 18);
3274
4073
  const provCol = s.model.providerName.padEnd(12).slice(0, 12);
3275
- rows.push(/* @__PURE__ */ jsxDEV10("box", {
4074
+ rows.push(/* @__PURE__ */ jsxDEV14("box", {
3276
4075
  height: 1,
3277
4076
  flexDirection: "row",
3278
4077
  paddingLeft: 2,
3279
4078
  children: [
3280
- /* @__PURE__ */ jsxDEV10("text", {
4079
+ /* @__PURE__ */ jsxDEV14("text", {
3281
4080
  fg: rankFg,
3282
4081
  children: [
3283
4082
  badge,
3284
4083
  " "
3285
4084
  ]
3286
4085
  }, undefined, true, undefined, this),
3287
- /* @__PURE__ */ jsxDEV10("text", {
3288
- fg: "#565f89",
4086
+ /* @__PURE__ */ jsxDEV14("text", {
4087
+ fg: theme.dim,
3289
4088
  children: " \u2502 "
3290
4089
  }, undefined, false, undefined, this),
3291
- /* @__PURE__ */ jsxDEV10("text", {
3292
- fg: "#7dcfff",
4090
+ /* @__PURE__ */ jsxDEV14("text", {
4091
+ fg: theme.accent,
3293
4092
  children: [
3294
4093
  tps.toFixed(1).padStart(8),
3295
4094
  " tok/s "
3296
4095
  ]
3297
4096
  }, undefined, true, undefined, this),
3298
- /* @__PURE__ */ jsxDEV10("text", {
3299
- fg: "#565f89",
4097
+ /* @__PURE__ */ jsxDEV14("text", {
4098
+ fg: theme.dim,
3300
4099
  children: " \u2502 "
3301
4100
  }, undefined, false, undefined, this),
3302
- /* @__PURE__ */ jsxDEV10("text", {
3303
- fg: "#bb9af7",
4101
+ /* @__PURE__ */ jsxDEV14("text", {
4102
+ fg: theme.secondary,
3304
4103
  children: [
3305
4104
  timeSec.toFixed(2).padStart(6),
3306
4105
  "s "
3307
4106
  ]
3308
4107
  }, undefined, true, undefined, this),
3309
- /* @__PURE__ */ jsxDEV10("text", {
3310
- fg: "#565f89",
4108
+ /* @__PURE__ */ jsxDEV14("text", {
4109
+ fg: theme.dim,
3311
4110
  children: " \u2502 "
3312
4111
  }, undefined, false, undefined, this),
3313
- /* @__PURE__ */ jsxDEV10("text", {
3314
- fg: "#c0caf5",
4112
+ /* @__PURE__ */ jsxDEV14("text", {
4113
+ fg: theme.text,
3315
4114
  children: [
3316
4115
  modelCol,
3317
4116
  " "
3318
4117
  ]
3319
4118
  }, undefined, true, undefined, this),
3320
- /* @__PURE__ */ jsxDEV10("text", {
3321
- fg: "#565f89",
4119
+ /* @__PURE__ */ jsxDEV14("text", {
4120
+ fg: theme.dim,
3322
4121
  children: [
3323
4122
  provCol,
3324
4123
  " \u2502 "
3325
4124
  ]
3326
4125
  }, undefined, true, undefined, this),
3327
- /* @__PURE__ */ jsxDEV10(BarChart, {
4126
+ /* @__PURE__ */ jsxDEV14(BarChart, {
3328
4127
  value: tps,
3329
4128
  max: maxTps,
3330
- width: BAR_W,
3331
- color: "#7dcfff"
4129
+ width: BAR_W2,
4130
+ color: theme.accent
3332
4131
  }, undefined, false, undefined, this)
3333
4132
  ]
3334
4133
  }, `tps-${s.model.id}-${s.model.providerId}`, true, undefined, this));
3335
4134
  }
3336
4135
  }
3337
4136
  if (ttftRanked.length > 0) {
3338
- rows.push(/* @__PURE__ */ jsxDEV10("box", {
4137
+ rows.push(/* @__PURE__ */ jsxDEV14("box", {
3339
4138
  height: 1,
3340
- backgroundColor: "#292e42"
4139
+ backgroundColor: theme.border
3341
4140
  }, "div-ttft", false, undefined, this));
3342
- rows.push(/* @__PURE__ */ jsxDEV10("box", {
4141
+ rows.push(/* @__PURE__ */ jsxDEV14("box", {
3343
4142
  height: 1,
3344
4143
  flexDirection: "row",
3345
4144
  paddingLeft: 1,
3346
- children: /* @__PURE__ */ jsxDEV10("text", {
3347
- fg: "#7aa2f7",
4145
+ children: /* @__PURE__ */ jsxDEV14("text", {
4146
+ fg: theme.primary,
3348
4147
  children: " TIME TO FIRST TOKEN RANKING (lower is better) "
3349
4148
  }, undefined, false, undefined, this)
3350
4149
  }, "hdr-ttft", false, undefined, this));
3351
4150
  for (const [i, s] of ttftRanked.entries()) {
3352
4151
  const rank = i + 1;
3353
- const rankFg = rank === 1 ? "#7dcfff" : rank === 2 ? "#bb9af7" : "#565f89";
4152
+ const rankFg = rank === 1 ? theme.accent : rank === 2 ? theme.secondary : theme.dim;
3354
4153
  const ttft = (s.result?.timeToFirstToken ?? 0) / 1000;
3355
4154
  const tps = s.result?.tokensPerSecond ?? 0;
3356
4155
  const badge = rankBadge(rank).padStart(3);
3357
4156
  const modelCol = s.model.name.padEnd(18).slice(0, 18);
3358
4157
  const provCol = s.model.providerName.padEnd(12).slice(0, 12);
3359
- rows.push(/* @__PURE__ */ jsxDEV10("box", {
4158
+ rows.push(/* @__PURE__ */ jsxDEV14("box", {
3360
4159
  height: 1,
3361
4160
  flexDirection: "row",
3362
4161
  paddingLeft: 2,
3363
4162
  children: [
3364
- /* @__PURE__ */ jsxDEV10("text", {
4163
+ /* @__PURE__ */ jsxDEV14("text", {
3365
4164
  fg: rankFg,
3366
4165
  children: [
3367
4166
  badge,
3368
4167
  " "
3369
4168
  ]
3370
4169
  }, undefined, true, undefined, this),
3371
- /* @__PURE__ */ jsxDEV10("text", {
3372
- fg: "#565f89",
4170
+ /* @__PURE__ */ jsxDEV14("text", {
4171
+ fg: theme.dim,
3373
4172
  children: " \u2502 "
3374
4173
  }, undefined, false, undefined, this),
3375
- /* @__PURE__ */ jsxDEV10("text", {
3376
- fg: "#bb9af7",
4174
+ /* @__PURE__ */ jsxDEV14("text", {
4175
+ fg: theme.secondary,
3377
4176
  children: [
3378
4177
  ttft.toFixed(2).padStart(7),
3379
4178
  "s "
3380
4179
  ]
3381
4180
  }, undefined, true, undefined, this),
3382
- /* @__PURE__ */ jsxDEV10("text", {
3383
- fg: "#565f89",
4181
+ /* @__PURE__ */ jsxDEV14("text", {
4182
+ fg: theme.dim,
3384
4183
  children: " \u2502 "
3385
4184
  }, undefined, false, undefined, this),
3386
- /* @__PURE__ */ jsxDEV10("text", {
3387
- fg: "#7dcfff",
4185
+ /* @__PURE__ */ jsxDEV14("text", {
4186
+ fg: theme.accent,
3388
4187
  children: [
3389
4188
  tps.toFixed(1).padStart(8),
3390
4189
  " tok/s "
3391
4190
  ]
3392
4191
  }, undefined, true, undefined, this),
3393
- /* @__PURE__ */ jsxDEV10("text", {
3394
- fg: "#565f89",
4192
+ /* @__PURE__ */ jsxDEV14("text", {
4193
+ fg: theme.dim,
3395
4194
  children: " \u2502 "
3396
4195
  }, undefined, false, undefined, this),
3397
- /* @__PURE__ */ jsxDEV10("text", {
3398
- fg: "#c0caf5",
4196
+ /* @__PURE__ */ jsxDEV14("text", {
4197
+ fg: theme.text,
3399
4198
  children: [
3400
4199
  modelCol,
3401
4200
  " "
3402
4201
  ]
3403
4202
  }, undefined, true, undefined, this),
3404
- /* @__PURE__ */ jsxDEV10("text", {
3405
- fg: "#565f89",
4203
+ /* @__PURE__ */ jsxDEV14("text", {
4204
+ fg: theme.dim,
3406
4205
  children: [
3407
4206
  provCol,
3408
4207
  " \u2502 "
3409
4208
  ]
3410
4209
  }, undefined, true, undefined, this),
3411
- /* @__PURE__ */ jsxDEV10(BarChart, {
4210
+ /* @__PURE__ */ jsxDEV14(BarChart, {
3412
4211
  value: ttft,
3413
4212
  max: maxTtftForBar,
3414
- width: BAR_W,
3415
- color: "#bb9af7"
4213
+ width: BAR_W2,
4214
+ color: theme.secondary
3416
4215
  }, undefined, false, undefined, this)
3417
4216
  ]
3418
4217
  }, `ttft-${s.model.id}-${s.model.providerId}`, true, undefined, this));
3419
4218
  }
3420
4219
  }
3421
4220
  if (allDone && errors.length > 0) {
3422
- rows.push(/* @__PURE__ */ jsxDEV10("box", {
4221
+ rows.push(/* @__PURE__ */ jsxDEV14("box", {
3423
4222
  height: 1,
3424
- backgroundColor: "#292e42"
4223
+ backgroundColor: theme.border
3425
4224
  }, "div-errors", false, undefined, this));
3426
- rows.push(/* @__PURE__ */ jsxDEV10("box", {
4225
+ rows.push(/* @__PURE__ */ jsxDEV14("box", {
3427
4226
  height: 1,
3428
4227
  flexDirection: "row",
3429
4228
  paddingLeft: 1,
3430
- children: /* @__PURE__ */ jsxDEV10("text", {
3431
- fg: "#f7768e",
4229
+ children: /* @__PURE__ */ jsxDEV14("text", {
4230
+ fg: theme.error,
3432
4231
  children: [
3433
4232
  " FAILED (",
3434
4233
  errors.length,
@@ -3437,29 +4236,29 @@ function BenchmarkScreen() {
3437
4236
  }, undefined, true, undefined, this)
3438
4237
  }, "hdr-errors", false, undefined, this));
3439
4238
  for (const s of errors) {
3440
- rows.push(/* @__PURE__ */ jsxDEV10("box", {
4239
+ rows.push(/* @__PURE__ */ jsxDEV14("box", {
3441
4240
  flexDirection: "column",
3442
4241
  paddingLeft: 2,
3443
4242
  paddingTop: 1,
3444
4243
  paddingBottom: 1,
3445
4244
  children: [
3446
- /* @__PURE__ */ jsxDEV10("box", {
4245
+ /* @__PURE__ */ jsxDEV14("box", {
3447
4246
  height: 1,
3448
4247
  flexDirection: "row",
3449
4248
  children: [
3450
- /* @__PURE__ */ jsxDEV10("text", {
3451
- fg: "#f7768e",
4249
+ /* @__PURE__ */ jsxDEV14("text", {
4250
+ fg: theme.error,
3452
4251
  children: "\u2717 "
3453
4252
  }, undefined, false, undefined, this),
3454
- /* @__PURE__ */ jsxDEV10("text", {
3455
- fg: "#c0caf5",
4253
+ /* @__PURE__ */ jsxDEV14("text", {
4254
+ fg: theme.text,
3456
4255
  children: [
3457
4256
  s.model.name,
3458
4257
  " "
3459
4258
  ]
3460
4259
  }, undefined, true, undefined, this),
3461
- /* @__PURE__ */ jsxDEV10("text", {
3462
- fg: "#565f89",
4260
+ /* @__PURE__ */ jsxDEV14("text", {
4261
+ fg: theme.dim,
3463
4262
  children: [
3464
4263
  "(",
3465
4264
  s.model.providerName,
@@ -3468,11 +4267,11 @@ function BenchmarkScreen() {
3468
4267
  }, undefined, true, undefined, this)
3469
4268
  ]
3470
4269
  }, undefined, true, undefined, this),
3471
- /* @__PURE__ */ jsxDEV10("box", {
4270
+ /* @__PURE__ */ jsxDEV14("box", {
3472
4271
  height: 1,
3473
4272
  paddingLeft: 3,
3474
- children: /* @__PURE__ */ jsxDEV10("text", {
3475
- fg: "#f7768e",
4273
+ children: /* @__PURE__ */ jsxDEV14("text", {
4274
+ fg: theme.error,
3476
4275
  children: s.error ?? "Unknown error"
3477
4276
  }, undefined, false, undefined, this)
3478
4277
  }, undefined, false, undefined, this)
@@ -3480,40 +4279,40 @@ function BenchmarkScreen() {
3480
4279
  }, `err-${s.model.id}-${s.model.providerId}`, true, undefined, this));
3481
4280
  }
3482
4281
  }
3483
- rows.push(/* @__PURE__ */ jsxDEV10("box", {
4282
+ rows.push(/* @__PURE__ */ jsxDEV14("box", {
3484
4283
  height: 1,
3485
- backgroundColor: "#292e42"
4284
+ backgroundColor: theme.border
3486
4285
  }, "div-results", false, undefined, this));
3487
- rows.push(/* @__PURE__ */ jsxDEV10("box", {
4286
+ rows.push(/* @__PURE__ */ jsxDEV14("box", {
3488
4287
  height: 1,
3489
4288
  flexDirection: "row",
3490
4289
  paddingLeft: 1,
3491
- children: /* @__PURE__ */ jsxDEV10("text", {
3492
- fg: "#7aa2f7",
4290
+ children: /* @__PURE__ */ jsxDEV14("text", {
4291
+ fg: theme.primary,
3493
4292
  children: " RESULTS "
3494
4293
  }, undefined, false, undefined, this)
3495
4294
  }, "hdr-results", false, undefined, this));
3496
4295
  if (doneResults.length > 0) {
3497
- rows.push(/* @__PURE__ */ jsxDEV10("box", {
4296
+ rows.push(/* @__PURE__ */ jsxDEV14("box", {
3498
4297
  flexDirection: "column",
3499
- children: /* @__PURE__ */ jsxDEV10(ResultsTable, {
4298
+ children: /* @__PURE__ */ jsxDEV14(ResultsTable, {
3500
4299
  results: doneResults,
3501
4300
  pendingCount
3502
4301
  }, undefined, false, undefined, this)
3503
4302
  }, "results-table", false, undefined, this));
3504
4303
  } else {
3505
- rows.push(/* @__PURE__ */ jsxDEV10("box", {
4304
+ rows.push(/* @__PURE__ */ jsxDEV14("box", {
3506
4305
  paddingLeft: 2,
3507
4306
  paddingBottom: 1,
3508
- children: /* @__PURE__ */ jsxDEV10("text", {
3509
- fg: "#565f89",
4307
+ children: /* @__PURE__ */ jsxDEV14("text", {
4308
+ fg: theme.dim,
3510
4309
  children: "No results yet..."
3511
4310
  }, undefined, false, undefined, this)
3512
4311
  }, "results-empty", false, undefined, this));
3513
4312
  }
3514
4313
  return rows;
3515
- }, [modelStates, allDone, tpsRanked, ttftRanked, doneResults, pendingCount, maxTps, maxTtftForBar]);
3516
- useKeyboard5((key) => {
4314
+ }, [modelStates, allDone, tpsRanked, ttftRanked, doneResults, pendingCount, maxTps, maxTtftForBar, theme]);
4315
+ useAppKeyboard((key) => {
3517
4316
  if (!allDone)
3518
4317
  return;
3519
4318
  if (key.name === "q" || key.name === "return" || key.name === "enter") {
@@ -3521,94 +4320,97 @@ function BenchmarkScreen() {
3521
4320
  navigate("main-menu");
3522
4321
  }
3523
4322
  });
3524
- const statusLine = allDone ? /* @__PURE__ */ jsxDEV10("box", {
4323
+ const statusLine = allDone ? /* @__PURE__ */ jsxDEV14("box", {
3525
4324
  flexDirection: "row",
3526
4325
  children: [
3527
- /* @__PURE__ */ jsxDEV10("text", {
3528
- fg: "#9ece6a",
4326
+ /* @__PURE__ */ jsxDEV14("text", {
4327
+ fg: theme.success,
3529
4328
  children: "All done! [Enter]/[Q] return [\u2191\u2193/PgUp/PgDn/wheel] scroll"
3530
4329
  }, undefined, false, undefined, this),
3531
- state.logMode && state.logPath && /* @__PURE__ */ jsxDEV10("text", {
3532
- fg: "#565f89",
4330
+ state.logMode && state.logPath && /* @__PURE__ */ jsxDEV14("text", {
4331
+ fg: theme.dim,
3533
4332
  children: [
3534
4333
  " log: ",
3535
4334
  state.logPath
3536
4335
  ]
3537
4336
  }, undefined, true, undefined, this)
3538
4337
  ]
3539
- }, undefined, true, undefined, this) : /* @__PURE__ */ jsxDEV10("box", {
4338
+ }, undefined, true, undefined, this) : /* @__PURE__ */ jsxDEV14("box", {
3540
4339
  flexDirection: "row",
3541
4340
  children: [
3542
- running.length > 0 && /* @__PURE__ */ jsxDEV10("text", {
3543
- fg: "#ff9e64",
4341
+ running.length > 0 && /* @__PURE__ */ jsxDEV14("text", {
4342
+ fg: theme.warning,
3544
4343
  children: [
3545
4344
  running.length,
3546
4345
  " running "
3547
4346
  ]
3548
4347
  }, undefined, true, undefined, this),
3549
- done.length > 0 && /* @__PURE__ */ jsxDEV10("text", {
3550
- fg: "#9ece6a",
4348
+ done.length > 0 && /* @__PURE__ */ jsxDEV14("text", {
4349
+ fg: theme.success,
3551
4350
  children: [
3552
4351
  done.length,
3553
4352
  " done "
3554
4353
  ]
3555
4354
  }, undefined, true, undefined, this),
3556
- errors.length > 0 && /* @__PURE__ */ jsxDEV10("text", {
3557
- fg: "#f7768e",
4355
+ errors.length > 0 && /* @__PURE__ */ jsxDEV14("text", {
4356
+ fg: theme.error,
3558
4357
  children: [
3559
4358
  errors.length,
3560
4359
  " errors "
3561
4360
  ]
3562
4361
  }, undefined, true, undefined, this),
3563
- /* @__PURE__ */ jsxDEV10("text", {
3564
- fg: "#565f89",
4362
+ /* @__PURE__ */ jsxDEV14("text", {
4363
+ fg: theme.dim,
3565
4364
  children: "[\u2191\u2193/wheel] scroll"
3566
4365
  }, undefined, false, undefined, this)
3567
4366
  ]
3568
4367
  }, undefined, true, undefined, this);
3569
- return /* @__PURE__ */ jsxDEV10("box", {
4368
+ return /* @__PURE__ */ jsxDEV14("box", {
3570
4369
  flexDirection: "column",
3571
4370
  flexGrow: 1,
3572
4371
  padding: 1,
3573
4372
  children: [
3574
- /* @__PURE__ */ jsxDEV10("box", {
4373
+ /* @__PURE__ */ jsxDEV14("box", {
3575
4374
  alignItems: "center",
3576
4375
  justifyContent: "center",
3577
4376
  marginBottom: 1,
3578
- children: /* @__PURE__ */ jsxDEV10("ascii-font", {
4377
+ children: /* @__PURE__ */ jsxDEV14("ascii-font", {
3579
4378
  text: "AI-SPEEDOMETER",
3580
4379
  font: "tiny",
3581
- color: "#7aa2f7"
4380
+ color: theme.primary
3582
4381
  }, undefined, false, undefined, this)
3583
4382
  }, undefined, false, undefined, this),
3584
- /* @__PURE__ */ jsxDEV10("box", {
4383
+ /* @__PURE__ */ jsxDEV14("box", {
3585
4384
  flexDirection: "column",
3586
4385
  border: true,
3587
4386
  borderStyle: "rounded",
3588
- borderColor: "#292e42",
3589
- backgroundColor: "#16161e",
4387
+ borderColor: theme.border,
4388
+ backgroundColor: theme.background,
3590
4389
  flexGrow: 1,
3591
4390
  children: [
3592
- /* @__PURE__ */ jsxDEV10("box", {
4391
+ /* @__PURE__ */ jsxDEV14("box", {
3593
4392
  height: 1,
3594
4393
  paddingLeft: 2,
3595
4394
  paddingRight: 2,
3596
4395
  flexDirection: "row",
3597
4396
  children: [
3598
- /* @__PURE__ */ jsxDEV10("text", {
3599
- fg: "#7dcfff",
4397
+ /* @__PURE__ */ jsxDEV14("text", {
4398
+ fg: theme.accent,
3600
4399
  children: "LIVE BENCHMARK "
3601
4400
  }, undefined, false, undefined, this),
3602
4401
  statusLine
3603
4402
  ]
3604
4403
  }, undefined, true, undefined, this),
3605
- /* @__PURE__ */ jsxDEV10(Divider, {}, undefined, false, undefined, this),
3606
- /* @__PURE__ */ jsxDEV10("scrollbox", {
4404
+ /* @__PURE__ */ jsxDEV14("box", {
4405
+ height: 1,
4406
+ backgroundColor: theme.border
4407
+ }, undefined, false, undefined, this),
4408
+ /* @__PURE__ */ jsxDEV14("scrollbox", {
3607
4409
  focused: true,
3608
4410
  flexGrow: 1,
3609
4411
  stickyScroll: true,
3610
4412
  stickyStart: "bottom",
3611
- style: { scrollbarOptions: { showArrows: true, trackOptions: { foregroundColor: "#7aa2f7", backgroundColor: "#292e42" } } },
4413
+ style: { scrollbarOptions: { showArrows: true, trackOptions: { foregroundColor: theme.primary, backgroundColor: theme.border } } },
3612
4414
  children: allRows
3613
4415
  }, undefined, false, undefined, this)
3614
4416
  ]
@@ -3616,36 +4418,40 @@ function BenchmarkScreen() {
3616
4418
  ]
3617
4419
  }, undefined, true, undefined, this);
3618
4420
  }
3619
- var BAR_W = 25;
4421
+ var BAR_W2 = 25;
3620
4422
  var init_BenchmarkScreen = __esm(() => {
4423
+ init_useAppKeyboard();
3621
4424
  init_AppContext();
4425
+ init_ThemeContext();
3622
4426
  init_BarChart();
4427
+ init_GlowBar();
3623
4428
  init_ResultsTable();
3624
4429
  });
3625
4430
 
3626
4431
  // src/tui/screens/AddVerifiedScreen.tsx
3627
- import { useState as useState5, useEffect as useEffect5, useRef as useRef4 } from "react";
3628
- import { useKeyboard as useKeyboard6, useTerminalDimensions as useTerminalDimensions2 } from "@opentui/react";
3629
- import { jsxDEV as jsxDEV11 } from "@opentui/react/jsx-dev-runtime";
4432
+ import { useState as useState9, useEffect as useEffect7, useRef as useRef5 } from "react";
4433
+ import { useTerminalDimensions as useTerminalDimensions2 } from "@opentui/react";
4434
+ import { jsxDEV as jsxDEV15 } from "@opentui/react/jsx-dev-runtime";
3630
4435
  function AddVerifiedScreen() {
3631
4436
  const { dispatch } = useAppContext();
3632
4437
  const navigate = useNavigate();
4438
+ const theme = useTheme();
3633
4439
  const { height, width } = useTerminalDimensions2();
3634
4440
  const PAGE_SIZE = Math.max(3, height - 16);
3635
4441
  const CARD_W = Math.min(62, width - 4);
3636
- const [step, setStep] = useState5("browse");
3637
- const [allProviders, setAllProviders] = useState5([]);
3638
- const [filtered, setFiltered] = useState5([]);
3639
- const [cursor, setCursor] = useState5(0);
3640
- const [searchQuery, setSearchQuery] = useState5("");
3641
- const scrollboxRef = useRef4(null);
3642
- const [selectedProvider, setSelectedProvider] = useState5(null);
3643
- const [apiKey, setApiKey] = useState5("");
3644
- const [saving, setSaving] = useState5(false);
3645
- const [saveError, setSaveError] = useState5("");
3646
- const [saveSuccess, setSaveSuccess] = useState5(false);
3647
- const [loadError, setLoadError] = useState5("");
3648
- useEffect5(() => {
4442
+ const [step, setStep] = useState9("browse");
4443
+ const [allProviders, setAllProviders] = useState9([]);
4444
+ const [filtered, setFiltered] = useState9([]);
4445
+ const [cursor, setCursor] = useState9(0);
4446
+ const [searchQuery, setSearchQuery] = useState9("");
4447
+ const scrollboxRef = useRef5(null);
4448
+ const [selectedProvider, setSelectedProvider] = useState9(null);
4449
+ const [apiKey, setApiKey] = useState9("");
4450
+ const [saving, setSaving] = useState9(false);
4451
+ const [saveError, setSaveError] = useState9("");
4452
+ const [saveSuccess, setSaveSuccess] = useState9(false);
4453
+ const [loadError, setLoadError] = useState9("");
4454
+ useEffect7(() => {
3649
4455
  async function load() {
3650
4456
  try {
3651
4457
  const { getAllProviders: getAllProviders2 } = await Promise.resolve().then(() => (init_models_dev(), exports_models_dev));
@@ -3658,7 +4464,7 @@ function AddVerifiedScreen() {
3658
4464
  }
3659
4465
  load();
3660
4466
  }, []);
3661
- useEffect5(() => {
4467
+ useEffect7(() => {
3662
4468
  if (!searchQuery) {
3663
4469
  setFiltered(allProviders);
3664
4470
  } else {
@@ -3667,7 +4473,7 @@ function AddVerifiedScreen() {
3667
4473
  }
3668
4474
  setCursor(0);
3669
4475
  }, [searchQuery, allProviders]);
3670
- useEffect5(() => {
4476
+ useEffect7(() => {
3671
4477
  const sb = scrollboxRef.current;
3672
4478
  if (!sb)
3673
4479
  return;
@@ -3686,7 +4492,7 @@ function AddVerifiedScreen() {
3686
4492
  setSaveError("");
3687
4493
  try {
3688
4494
  const { addApiKey: addApiKey2 } = await Promise.resolve().then(() => (init_opencode_integration(), exports_opencode_integration));
3689
- const { addVerifiedProvider: addVerifiedProvider2, getVerifiedProvidersFromConfig: getVerifiedProvidersFromConfig2 } = await Promise.resolve().then(() => (init_ai_config(), exports_ai_config));
4495
+ const { addVerifiedProvider: addVerifiedProvider2 } = await Promise.resolve().then(() => (init_ai_config(), exports_ai_config));
3690
4496
  await addApiKey2(selectedProvider.id, apiKey.trim());
3691
4497
  await addVerifiedProvider2(selectedProvider.id, apiKey.trim());
3692
4498
  const { getAllAvailableProviders: getAllAvailableProviders2 } = await Promise.resolve().then(() => (init_opencode_integration(), exports_opencode_integration));
@@ -3706,7 +4512,7 @@ function AddVerifiedScreen() {
3706
4512
  else if (step === "confirm")
3707
4513
  setApiKey((k) => k + clean);
3708
4514
  });
3709
- useKeyboard6((key) => {
4515
+ useAppKeyboard((key) => {
3710
4516
  if (step === "browse") {
3711
4517
  if (key.name === "escape" || key.sequence === "q" || key.sequence === "Q") {
3712
4518
  navigate("model-menu");
@@ -3750,9 +4556,8 @@ function AddVerifiedScreen() {
3750
4556
  }
3751
4557
  if (step === "confirm") {
3752
4558
  if (saveSuccess) {
3753
- if (key.name === "return" || key.name === "enter") {
4559
+ if (key.name === "return" || key.name === "enter")
3754
4560
  navigate("model-menu");
3755
- }
3756
4561
  return;
3757
4562
  }
3758
4563
  if (saving)
@@ -3775,91 +4580,91 @@ function AddVerifiedScreen() {
3775
4580
  }
3776
4581
  });
3777
4582
  if (step === "confirm" && selectedProvider) {
3778
- return /* @__PURE__ */ jsxDEV11("box", {
4583
+ return /* @__PURE__ */ jsxDEV15("box", {
3779
4584
  flexDirection: "column",
3780
4585
  flexGrow: 1,
3781
4586
  alignItems: "center",
3782
4587
  justifyContent: "center",
3783
- children: /* @__PURE__ */ jsxDEV11("box", {
4588
+ children: /* @__PURE__ */ jsxDEV15("box", {
3784
4589
  flexDirection: "column",
3785
4590
  border: true,
3786
4591
  borderStyle: "rounded",
3787
- borderColor: "#292e42",
3788
- backgroundColor: "#16161e",
4592
+ borderColor: theme.border,
4593
+ backgroundColor: theme.background,
3789
4594
  width: CARD_W,
3790
4595
  children: [
3791
- /* @__PURE__ */ jsxDEV11("box", {
4596
+ /* @__PURE__ */ jsxDEV15("box", {
3792
4597
  height: 1,
3793
4598
  paddingLeft: 2,
3794
4599
  paddingTop: 1,
3795
- children: /* @__PURE__ */ jsxDEV11("text", {
3796
- fg: "#7dcfff",
4600
+ children: /* @__PURE__ */ jsxDEV15("text", {
4601
+ fg: theme.accent,
3797
4602
  children: "Add Verified Provider"
3798
4603
  }, undefined, false, undefined, this)
3799
4604
  }, undefined, false, undefined, this),
3800
- /* @__PURE__ */ jsxDEV11("box", {
4605
+ /* @__PURE__ */ jsxDEV15("box", {
3801
4606
  height: 1,
3802
- backgroundColor: "#292e42"
4607
+ backgroundColor: theme.border
3803
4608
  }, undefined, false, undefined, this),
3804
- /* @__PURE__ */ jsxDEV11("box", {
4609
+ /* @__PURE__ */ jsxDEV15("box", {
3805
4610
  flexDirection: "column",
3806
4611
  paddingLeft: 2,
3807
4612
  paddingRight: 2,
3808
4613
  paddingTop: 1,
3809
4614
  paddingBottom: 1,
3810
4615
  children: [
3811
- /* @__PURE__ */ jsxDEV11("box", {
4616
+ /* @__PURE__ */ jsxDEV15("box", {
3812
4617
  height: 1,
3813
4618
  flexDirection: "row",
3814
4619
  children: [
3815
- /* @__PURE__ */ jsxDEV11("text", {
3816
- fg: "#7aa2f7",
4620
+ /* @__PURE__ */ jsxDEV15("text", {
4621
+ fg: theme.primary,
3817
4622
  children: "Provider: "
3818
4623
  }, undefined, false, undefined, this),
3819
- /* @__PURE__ */ jsxDEV11("text", {
3820
- fg: "#c0caf5",
4624
+ /* @__PURE__ */ jsxDEV15("text", {
4625
+ fg: theme.text,
3821
4626
  children: selectedProvider.name
3822
4627
  }, undefined, false, undefined, this)
3823
4628
  ]
3824
4629
  }, undefined, true, undefined, this),
3825
- /* @__PURE__ */ jsxDEV11("box", {
4630
+ /* @__PURE__ */ jsxDEV15("box", {
3826
4631
  height: 1,
3827
4632
  flexDirection: "row",
3828
4633
  children: [
3829
- /* @__PURE__ */ jsxDEV11("text", {
3830
- fg: "#565f89",
4634
+ /* @__PURE__ */ jsxDEV15("text", {
4635
+ fg: theme.dim,
3831
4636
  children: "Type: "
3832
4637
  }, undefined, false, undefined, this),
3833
- /* @__PURE__ */ jsxDEV11("text", {
3834
- fg: "#565f89",
4638
+ /* @__PURE__ */ jsxDEV15("text", {
4639
+ fg: theme.dim,
3835
4640
  children: selectedProvider.type
3836
4641
  }, undefined, false, undefined, this)
3837
4642
  ]
3838
4643
  }, undefined, true, undefined, this),
3839
- /* @__PURE__ */ jsxDEV11("box", {
4644
+ /* @__PURE__ */ jsxDEV15("box", {
3840
4645
  height: 1,
3841
4646
  flexDirection: "row",
3842
4647
  children: [
3843
- /* @__PURE__ */ jsxDEV11("text", {
3844
- fg: "#565f89",
4648
+ /* @__PURE__ */ jsxDEV15("text", {
4649
+ fg: theme.dim,
3845
4650
  children: "URL: "
3846
4651
  }, undefined, false, undefined, this),
3847
- /* @__PURE__ */ jsxDEV11("text", {
3848
- fg: "#565f89",
4652
+ /* @__PURE__ */ jsxDEV15("text", {
4653
+ fg: theme.dim,
3849
4654
  children: selectedProvider.baseUrl
3850
4655
  }, undefined, false, undefined, this)
3851
4656
  ]
3852
4657
  }, undefined, true, undefined, this),
3853
- /* @__PURE__ */ jsxDEV11("box", {
4658
+ /* @__PURE__ */ jsxDEV15("box", {
3854
4659
  height: 1,
3855
4660
  flexDirection: "row",
3856
4661
  children: [
3857
- /* @__PURE__ */ jsxDEV11("text", {
3858
- fg: "#565f89",
4662
+ /* @__PURE__ */ jsxDEV15("text", {
4663
+ fg: theme.dim,
3859
4664
  children: "Models: "
3860
4665
  }, undefined, false, undefined, this),
3861
- /* @__PURE__ */ jsxDEV11("text", {
3862
- fg: "#565f89",
4666
+ /* @__PURE__ */ jsxDEV15("text", {
4667
+ fg: theme.dim,
3863
4668
  children: [
3864
4669
  selectedProvider.models.length,
3865
4670
  " available"
@@ -3869,21 +4674,21 @@ function AddVerifiedScreen() {
3869
4674
  }, undefined, true, undefined, this)
3870
4675
  ]
3871
4676
  }, undefined, true, undefined, this),
3872
- /* @__PURE__ */ jsxDEV11("box", {
4677
+ /* @__PURE__ */ jsxDEV15("box", {
3873
4678
  height: 1,
3874
- backgroundColor: "#292e42"
4679
+ backgroundColor: theme.border
3875
4680
  }, undefined, false, undefined, this),
3876
- saveSuccess ? /* @__PURE__ */ jsxDEV11("box", {
4681
+ saveSuccess ? /* @__PURE__ */ jsxDEV15("box", {
3877
4682
  flexDirection: "column",
3878
4683
  paddingLeft: 2,
3879
4684
  paddingRight: 2,
3880
4685
  paddingTop: 1,
3881
4686
  paddingBottom: 1,
3882
4687
  children: [
3883
- /* @__PURE__ */ jsxDEV11("box", {
4688
+ /* @__PURE__ */ jsxDEV15("box", {
3884
4689
  height: 1,
3885
- children: /* @__PURE__ */ jsxDEV11("text", {
3886
- fg: "#9ece6a",
4690
+ children: /* @__PURE__ */ jsxDEV15("text", {
4691
+ fg: theme.success,
3887
4692
  children: [
3888
4693
  "Provider added! ",
3889
4694
  selectedProvider.models.length,
@@ -3891,31 +4696,31 @@ function AddVerifiedScreen() {
3891
4696
  ]
3892
4697
  }, undefined, true, undefined, this)
3893
4698
  }, undefined, false, undefined, this),
3894
- /* @__PURE__ */ jsxDEV11("box", {
4699
+ /* @__PURE__ */ jsxDEV15("box", {
3895
4700
  height: 1,
3896
- children: /* @__PURE__ */ jsxDEV11("text", {
3897
- fg: "#565f89",
4701
+ children: /* @__PURE__ */ jsxDEV15("text", {
4702
+ fg: theme.dim,
3898
4703
  children: "Press [Enter] to return"
3899
4704
  }, undefined, false, undefined, this)
3900
4705
  }, undefined, false, undefined, this)
3901
4706
  ]
3902
- }, undefined, true, undefined, this) : /* @__PURE__ */ jsxDEV11("box", {
4707
+ }, undefined, true, undefined, this) : /* @__PURE__ */ jsxDEV15("box", {
3903
4708
  flexDirection: "column",
3904
4709
  paddingLeft: 2,
3905
4710
  paddingRight: 2,
3906
4711
  paddingTop: 1,
3907
4712
  paddingBottom: 1,
3908
4713
  children: [
3909
- /* @__PURE__ */ jsxDEV11("box", {
4714
+ /* @__PURE__ */ jsxDEV15("box", {
3910
4715
  height: 1,
3911
4716
  flexDirection: "row",
3912
4717
  children: [
3913
- /* @__PURE__ */ jsxDEV11("text", {
3914
- fg: "#7dcfff",
4718
+ /* @__PURE__ */ jsxDEV15("text", {
4719
+ fg: theme.accent,
3915
4720
  children: "API Key: "
3916
4721
  }, undefined, false, undefined, this),
3917
- /* @__PURE__ */ jsxDEV11("text", {
3918
- fg: "#c0caf5",
4722
+ /* @__PURE__ */ jsxDEV15("text", {
4723
+ fg: theme.text,
3919
4724
  children: [
3920
4725
  apiKey,
3921
4726
  "_"
@@ -3923,26 +4728,26 @@ function AddVerifiedScreen() {
3923
4728
  }, undefined, true, undefined, this)
3924
4729
  ]
3925
4730
  }, undefined, true, undefined, this),
3926
- saveError ? /* @__PURE__ */ jsxDEV11("box", {
4731
+ saveError ? /* @__PURE__ */ jsxDEV15("box", {
3927
4732
  height: 1,
3928
- children: /* @__PURE__ */ jsxDEV11("text", {
3929
- fg: "#f7768e",
4733
+ children: /* @__PURE__ */ jsxDEV15("text", {
4734
+ fg: theme.error,
3930
4735
  children: [
3931
4736
  "Error: ",
3932
4737
  saveError
3933
4738
  ]
3934
4739
  }, undefined, true, undefined, this)
3935
4740
  }, undefined, false, undefined, this) : null,
3936
- saving ? /* @__PURE__ */ jsxDEV11("box", {
4741
+ saving ? /* @__PURE__ */ jsxDEV15("box", {
3937
4742
  height: 1,
3938
- children: /* @__PURE__ */ jsxDEV11("text", {
3939
- fg: "#ff9e64",
4743
+ children: /* @__PURE__ */ jsxDEV15("text", {
4744
+ fg: theme.warning,
3940
4745
  children: "Saving..."
3941
4746
  }, undefined, false, undefined, this)
3942
- }, undefined, false, undefined, this) : /* @__PURE__ */ jsxDEV11("box", {
4747
+ }, undefined, false, undefined, this) : /* @__PURE__ */ jsxDEV15("box", {
3943
4748
  height: 1,
3944
- children: /* @__PURE__ */ jsxDEV11("text", {
3945
- fg: "#565f89",
4749
+ children: /* @__PURE__ */ jsxDEV15("text", {
4750
+ fg: theme.dim,
3946
4751
  children: "[Enter] save [Esc] back to list"
3947
4752
  }, undefined, false, undefined, this)
3948
4753
  }, undefined, false, undefined, this)
@@ -3952,32 +4757,32 @@ function AddVerifiedScreen() {
3952
4757
  }, undefined, true, undefined, this)
3953
4758
  }, undefined, false, undefined, this);
3954
4759
  }
3955
- return /* @__PURE__ */ jsxDEV11("box", {
4760
+ return /* @__PURE__ */ jsxDEV15("box", {
3956
4761
  flexDirection: "column",
3957
4762
  flexGrow: 1,
3958
4763
  alignItems: "center",
3959
4764
  justifyContent: "center",
3960
- children: /* @__PURE__ */ jsxDEV11("box", {
4765
+ children: /* @__PURE__ */ jsxDEV15("box", {
3961
4766
  flexDirection: "column",
3962
4767
  border: true,
3963
4768
  borderStyle: "rounded",
3964
- borderColor: "#292e42",
3965
- backgroundColor: "#16161e",
4769
+ borderColor: theme.border,
4770
+ backgroundColor: theme.background,
3966
4771
  width: CARD_W,
3967
4772
  children: [
3968
- /* @__PURE__ */ jsxDEV11("box", {
4773
+ /* @__PURE__ */ jsxDEV15("box", {
3969
4774
  flexDirection: "row",
3970
4775
  paddingLeft: 2,
3971
4776
  paddingRight: 2,
3972
4777
  paddingTop: 1,
3973
4778
  paddingBottom: 1,
3974
4779
  children: [
3975
- /* @__PURE__ */ jsxDEV11("text", {
3976
- fg: "#7dcfff",
4780
+ /* @__PURE__ */ jsxDEV15("text", {
4781
+ fg: theme.accent,
3977
4782
  children: "Search: "
3978
4783
  }, undefined, false, undefined, this),
3979
- /* @__PURE__ */ jsxDEV11("text", {
3980
- fg: "#c0caf5",
4784
+ /* @__PURE__ */ jsxDEV15("text", {
4785
+ fg: theme.text,
3981
4786
  children: [
3982
4787
  searchQuery,
3983
4788
  "_"
@@ -3985,59 +4790,59 @@ function AddVerifiedScreen() {
3985
4790
  }, undefined, true, undefined, this)
3986
4791
  ]
3987
4792
  }, undefined, true, undefined, this),
3988
- /* @__PURE__ */ jsxDEV11("box", {
4793
+ /* @__PURE__ */ jsxDEV15("box", {
3989
4794
  height: 1,
3990
- backgroundColor: "#292e42"
4795
+ backgroundColor: theme.border
3991
4796
  }, undefined, false, undefined, this),
3992
- /* @__PURE__ */ jsxDEV11("scrollbox", {
4797
+ /* @__PURE__ */ jsxDEV15("scrollbox", {
3993
4798
  ref: scrollboxRef,
3994
4799
  height: PAGE_SIZE,
3995
- style: { scrollbarOptions: { showArrows: true, trackOptions: { foregroundColor: "#7aa2f7", backgroundColor: "#292e42" } } },
4800
+ style: { scrollbarOptions: { showArrows: true, trackOptions: { foregroundColor: theme.primary, backgroundColor: theme.border } } },
3996
4801
  children: [
3997
- loadError && /* @__PURE__ */ jsxDEV11("box", {
4802
+ loadError && /* @__PURE__ */ jsxDEV15("box", {
3998
4803
  height: 1,
3999
4804
  paddingLeft: 2,
4000
- children: /* @__PURE__ */ jsxDEV11("text", {
4001
- fg: "#f7768e",
4805
+ children: /* @__PURE__ */ jsxDEV15("text", {
4806
+ fg: theme.error,
4002
4807
  children: [
4003
4808
  "Error loading providers: ",
4004
4809
  loadError
4005
4810
  ]
4006
4811
  }, undefined, true, undefined, this)
4007
4812
  }, undefined, false, undefined, this),
4008
- !loadError && filtered.length === 0 && /* @__PURE__ */ jsxDEV11("box", {
4813
+ !loadError && filtered.length === 0 && /* @__PURE__ */ jsxDEV15("box", {
4009
4814
  height: 1,
4010
4815
  paddingLeft: 2,
4011
- children: /* @__PURE__ */ jsxDEV11("text", {
4012
- fg: "#565f89",
4816
+ children: /* @__PURE__ */ jsxDEV15("text", {
4817
+ fg: theme.dim,
4013
4818
  children: allProviders.length === 0 ? "Loading..." : "No providers found"
4014
4819
  }, undefined, false, undefined, this)
4015
4820
  }, undefined, false, undefined, this),
4016
4821
  filtered.map((prov, i) => {
4017
4822
  const isActive = i === cursor;
4018
- return /* @__PURE__ */ jsxDEV11("box", {
4823
+ return /* @__PURE__ */ jsxDEV15("box", {
4019
4824
  height: 1,
4020
4825
  width: "100%",
4021
4826
  flexDirection: "row",
4022
- backgroundColor: isActive ? "#292e42" : "transparent",
4827
+ backgroundColor: isActive ? theme.border : "transparent",
4023
4828
  children: [
4024
- /* @__PURE__ */ jsxDEV11("text", {
4025
- fg: "#565f89",
4829
+ /* @__PURE__ */ jsxDEV15("text", {
4830
+ fg: theme.dim,
4026
4831
  width: 2,
4027
4832
  children: " "
4028
4833
  }, undefined, false, undefined, this),
4029
- /* @__PURE__ */ jsxDEV11("text", {
4030
- fg: isActive ? "#c0caf5" : "#565f89",
4834
+ /* @__PURE__ */ jsxDEV15("text", {
4835
+ fg: isActive ? theme.text : theme.dim,
4031
4836
  width: Math.floor((CARD_W - 10) / 2),
4032
4837
  children: prov.name
4033
4838
  }, undefined, false, undefined, this),
4034
- /* @__PURE__ */ jsxDEV11("text", {
4035
- fg: isActive ? "#7aa2f7" : "#292e42",
4839
+ /* @__PURE__ */ jsxDEV15("text", {
4840
+ fg: isActive ? theme.primary : theme.border,
4036
4841
  width: Math.floor((CARD_W - 10) / 2),
4037
4842
  children: prov.type
4038
4843
  }, undefined, false, undefined, this),
4039
- /* @__PURE__ */ jsxDEV11("text", {
4040
- fg: "#7dcfff",
4844
+ /* @__PURE__ */ jsxDEV15("text", {
4845
+ fg: theme.accent,
4041
4846
  width: 2,
4042
4847
  children: isActive ? "\u203A" : " "
4043
4848
  }, undefined, false, undefined, this)
@@ -4046,26 +4851,26 @@ function AddVerifiedScreen() {
4046
4851
  })
4047
4852
  ]
4048
4853
  }, undefined, true, undefined, this),
4049
- /* @__PURE__ */ jsxDEV11("box", {
4854
+ /* @__PURE__ */ jsxDEV15("box", {
4050
4855
  height: 1,
4051
- backgroundColor: "#292e42"
4856
+ backgroundColor: theme.border
4052
4857
  }, undefined, false, undefined, this),
4053
- /* @__PURE__ */ jsxDEV11("box", {
4858
+ /* @__PURE__ */ jsxDEV15("box", {
4054
4859
  flexDirection: "row",
4055
4860
  paddingLeft: 2,
4056
4861
  paddingRight: 2,
4057
4862
  paddingTop: 1,
4058
4863
  paddingBottom: 1,
4059
4864
  children: [
4060
- /* @__PURE__ */ jsxDEV11("text", {
4061
- fg: "#565f89",
4865
+ /* @__PURE__ */ jsxDEV15("text", {
4866
+ fg: theme.dim,
4062
4867
  children: [
4063
4868
  filtered.length,
4064
4869
  " providers"
4065
4870
  ]
4066
4871
  }, undefined, true, undefined, this),
4067
- /* @__PURE__ */ jsxDEV11("text", {
4068
- fg: "#565f89",
4872
+ /* @__PURE__ */ jsxDEV15("text", {
4873
+ fg: theme.dim,
4069
4874
  children: " [\u2191\u2193/PgUp/PgDn/wheel] scroll"
4070
4875
  }, undefined, false, undefined, this)
4071
4876
  ]
@@ -4075,34 +4880,37 @@ function AddVerifiedScreen() {
4075
4880
  }, undefined, false, undefined, this);
4076
4881
  }
4077
4882
  var init_AddVerifiedScreen = __esm(() => {
4883
+ init_useAppKeyboard();
4078
4884
  init_AppContext();
4885
+ init_ThemeContext();
4079
4886
  init_usePaste();
4080
4887
  });
4081
4888
 
4082
4889
  // src/tui/screens/AddCustomScreen.tsx
4083
- import { useState as useState6 } from "react";
4084
- import { useKeyboard as useKeyboard7, useTerminalDimensions as useTerminalDimensions3 } from "@opentui/react";
4085
- import { jsxDEV as jsxDEV12 } from "@opentui/react/jsx-dev-runtime";
4890
+ import { useState as useState10 } from "react";
4891
+ import { useTerminalDimensions as useTerminalDimensions3 } from "@opentui/react";
4892
+ import { jsxDEV as jsxDEV16 } from "@opentui/react/jsx-dev-runtime";
4086
4893
  function stepIndex(s) {
4087
4894
  return STEPS.indexOf(s);
4088
4895
  }
4089
4896
  function AddCustomScreen() {
4090
4897
  const { dispatch } = useAppContext();
4091
4898
  const navigate = useNavigate();
4899
+ const theme = useTheme();
4092
4900
  const { width } = useTerminalDimensions3();
4093
4901
  const CARD_W = Math.min(60, width - 4);
4094
- const [step, setStep] = useState6("type");
4095
- const [providerType, setProviderType] = useState6("openai-compatible");
4096
- const [typeCursor, setTypeCursor] = useState6(0);
4097
- const [providerId, setProviderId] = useState6("");
4098
- const [providerName, setProviderName] = useState6("");
4099
- const [baseUrl, setBaseUrl] = useState6("");
4100
- const [apiKey, setApiKey] = useState6("");
4101
- const [modelInput, setModelInput] = useState6("");
4102
- const [models, setModels] = useState6([]);
4103
- const [saveError, setSaveError] = useState6("");
4104
- const [savedModelCount, setSavedModelCount] = useState6(0);
4105
- const [inputError, setInputError] = useState6("");
4902
+ const [step, setStep] = useState10("type");
4903
+ const [providerType, setProviderType] = useState10("openai-compatible");
4904
+ const [typeCursor, setTypeCursor] = useState10(0);
4905
+ const [providerId, setProviderId] = useState10("");
4906
+ const [providerName, setProviderName] = useState10("");
4907
+ const [baseUrl, setBaseUrl] = useState10("");
4908
+ const [apiKey, setApiKey] = useState10("");
4909
+ const [modelInput, setModelInput] = useState10("");
4910
+ const [models, setModels] = useState10([]);
4911
+ const [saveError, setSaveError] = useState10("");
4912
+ const [savedModelCount, setSavedModelCount] = useState10(0);
4913
+ const [inputError, setInputError] = useState10("");
4106
4914
  const typeItems = ["OpenAI Compatible", "Anthropic", "Back"];
4107
4915
  async function doSave() {
4108
4916
  setStep("saving");
@@ -4115,10 +4923,7 @@ function AddCustomScreen() {
4115
4923
  type: providerType,
4116
4924
  baseUrl: baseUrl.trim(),
4117
4925
  apiKey: apiKey.trim(),
4118
- models: models.map((m) => ({
4119
- id: m,
4120
- name: m
4121
- }))
4926
+ models: models.map((m) => ({ id: m, name: m }))
4122
4927
  });
4123
4928
  const { getAllAvailableProviders: getAllAvailableProviders2 } = await Promise.resolve().then(() => (init_opencode_integration(), exports_opencode_integration));
4124
4929
  const providers = await getAllAvailableProviders2(false);
@@ -4143,7 +4948,7 @@ function AddCustomScreen() {
4143
4948
  else if (step === "models")
4144
4949
  setModelInput((v) => v + clean);
4145
4950
  });
4146
- useKeyboard7((key) => {
4951
+ useAppKeyboard((key) => {
4147
4952
  if (step === "done") {
4148
4953
  if (key.name === "return" || key.name === "enter")
4149
4954
  navigate("model-menu");
@@ -4198,9 +5003,8 @@ function AddCustomScreen() {
4198
5003
  setProviderId((v) => v.slice(0, -1));
4199
5004
  return;
4200
5005
  }
4201
- if (key.sequence && key.sequence.length === 1 && !key.ctrl && !key.meta && key.sequence >= " ") {
5006
+ if (key.sequence && key.sequence.length === 1 && !key.ctrl && !key.meta && key.sequence >= " ")
4202
5007
  setProviderId((v) => v + key.sequence);
4203
- }
4204
5008
  return;
4205
5009
  }
4206
5010
  if (step === "name") {
@@ -4215,9 +5019,8 @@ function AddCustomScreen() {
4215
5019
  setProviderName((v) => v.slice(0, -1));
4216
5020
  return;
4217
5021
  }
4218
- if (key.sequence && key.sequence.length === 1 && !key.ctrl && !key.meta && key.sequence >= " ") {
5022
+ if (key.sequence && key.sequence.length === 1 && !key.ctrl && !key.meta && key.sequence >= " ")
4219
5023
  setProviderName((v) => v + key.sequence);
4220
- }
4221
5024
  return;
4222
5025
  }
4223
5026
  if (step === "url") {
@@ -4238,9 +5041,8 @@ function AddCustomScreen() {
4238
5041
  setBaseUrl((v) => v.slice(0, -1));
4239
5042
  return;
4240
5043
  }
4241
- if (key.sequence && key.sequence.length === 1 && !key.ctrl && !key.meta && key.sequence >= " ") {
5044
+ if (key.sequence && key.sequence.length === 1 && !key.ctrl && !key.meta && key.sequence >= " ")
4242
5045
  setBaseUrl((v) => v + key.sequence);
4243
- }
4244
5046
  return;
4245
5047
  }
4246
5048
  if (step === "key") {
@@ -4253,9 +5055,8 @@ function AddCustomScreen() {
4253
5055
  setApiKey((v) => v.slice(0, -1));
4254
5056
  return;
4255
5057
  }
4256
- if (key.sequence && key.sequence.length === 1 && !key.ctrl && !key.meta && key.sequence >= " ") {
5058
+ if (key.sequence && key.sequence.length === 1 && !key.ctrl && !key.meta && key.sequence >= " ")
4257
5059
  setApiKey((v) => v + key.sequence);
4258
- }
4259
5060
  return;
4260
5061
  }
4261
5062
  if (step === "models") {
@@ -4277,31 +5078,30 @@ function AddCustomScreen() {
4277
5078
  setModelInput((v) => v.slice(0, -1));
4278
5079
  return;
4279
5080
  }
4280
- if (key.sequence && key.sequence.length === 1 && !key.ctrl && !key.meta && key.sequence >= " ") {
5081
+ if (key.sequence && key.sequence.length === 1 && !key.ctrl && !key.meta && key.sequence >= " ")
4281
5082
  setModelInput((v) => v + key.sequence);
4282
- }
4283
5083
  }
4284
5084
  });
4285
5085
  const curStepIdx = stepIndex(step);
4286
5086
  function ProgressBar() {
4287
- return /* @__PURE__ */ jsxDEV12("box", {
5087
+ return /* @__PURE__ */ jsxDEV16("box", {
4288
5088
  height: 1,
4289
5089
  paddingLeft: 2,
4290
5090
  paddingRight: 2,
4291
5091
  flexDirection: "row",
4292
- children: STEPS.map((s, i) => /* @__PURE__ */ jsxDEV12("box", {
5092
+ children: STEPS.map((s, i) => /* @__PURE__ */ jsxDEV16("box", {
4293
5093
  flexDirection: "row",
4294
5094
  children: [
4295
- /* @__PURE__ */ jsxDEV12("text", {
4296
- fg: i < curStepIdx ? "#9ece6a" : i === curStepIdx ? "#7dcfff" : "#292e42",
5095
+ /* @__PURE__ */ jsxDEV16("text", {
5096
+ fg: i < curStepIdx ? theme.success : i === curStepIdx ? theme.accent : theme.border,
4297
5097
  children: [
4298
5098
  STEP_NUM[i],
4299
5099
  " ",
4300
5100
  STEP_LABELS[i]
4301
5101
  ]
4302
5102
  }, undefined, true, undefined, this),
4303
- i < STEPS.length - 1 && /* @__PURE__ */ jsxDEV12("text", {
4304
- fg: "#292e42",
5103
+ i < STEPS.length - 1 && /* @__PURE__ */ jsxDEV16("text", {
5104
+ fg: theme.border,
4305
5105
  children: " "
4306
5106
  }, undefined, false, undefined, this)
4307
5107
  ]
@@ -4309,29 +5109,29 @@ function AddCustomScreen() {
4309
5109
  }, undefined, false, undefined, this);
4310
5110
  }
4311
5111
  if (step === "done") {
4312
- return /* @__PURE__ */ jsxDEV12("box", {
5112
+ return /* @__PURE__ */ jsxDEV16("box", {
4313
5113
  flexDirection: "column",
4314
5114
  flexGrow: 1,
4315
5115
  alignItems: "center",
4316
5116
  justifyContent: "center",
4317
- children: /* @__PURE__ */ jsxDEV12("box", {
5117
+ children: /* @__PURE__ */ jsxDEV16("box", {
4318
5118
  flexDirection: "column",
4319
5119
  border: true,
4320
5120
  borderStyle: "rounded",
4321
- borderColor: "#292e42",
4322
- backgroundColor: "#16161e",
5121
+ borderColor: theme.border,
5122
+ backgroundColor: theme.background,
4323
5123
  width: CARD_W,
4324
- children: /* @__PURE__ */ jsxDEV12("box", {
5124
+ children: /* @__PURE__ */ jsxDEV16("box", {
4325
5125
  flexDirection: "column",
4326
5126
  paddingLeft: 2,
4327
5127
  paddingRight: 2,
4328
5128
  paddingTop: 1,
4329
5129
  paddingBottom: 1,
4330
5130
  children: [
4331
- /* @__PURE__ */ jsxDEV12("box", {
5131
+ /* @__PURE__ */ jsxDEV16("box", {
4332
5132
  height: 1,
4333
- children: /* @__PURE__ */ jsxDEV12("text", {
4334
- fg: "#9ece6a",
5133
+ children: /* @__PURE__ */ jsxDEV16("text", {
5134
+ fg: theme.success,
4335
5135
  children: [
4336
5136
  "Custom provider added! ",
4337
5137
  savedModelCount,
@@ -4341,10 +5141,10 @@ function AddCustomScreen() {
4341
5141
  ]
4342
5142
  }, undefined, true, undefined, this)
4343
5143
  }, undefined, false, undefined, this),
4344
- /* @__PURE__ */ jsxDEV12("box", {
5144
+ /* @__PURE__ */ jsxDEV16("box", {
4345
5145
  height: 1,
4346
- children: /* @__PURE__ */ jsxDEV12("text", {
4347
- fg: "#565f89",
5146
+ children: /* @__PURE__ */ jsxDEV16("text", {
5147
+ fg: theme.dim,
4348
5148
  children: "Press [Enter] to return"
4349
5149
  }, undefined, false, undefined, this)
4350
5150
  }, undefined, false, undefined, this)
@@ -4354,107 +5154,107 @@ function AddCustomScreen() {
4354
5154
  }, undefined, false, undefined, this);
4355
5155
  }
4356
5156
  if (step === "saving") {
4357
- return /* @__PURE__ */ jsxDEV12("box", {
5157
+ return /* @__PURE__ */ jsxDEV16("box", {
4358
5158
  flexDirection: "column",
4359
5159
  flexGrow: 1,
4360
5160
  alignItems: "center",
4361
5161
  justifyContent: "center",
4362
- children: /* @__PURE__ */ jsxDEV12("box", {
5162
+ children: /* @__PURE__ */ jsxDEV16("box", {
4363
5163
  flexDirection: "column",
4364
5164
  border: true,
4365
5165
  borderStyle: "rounded",
4366
- borderColor: "#292e42",
4367
- backgroundColor: "#16161e",
5166
+ borderColor: theme.border,
5167
+ backgroundColor: theme.background,
4368
5168
  width: CARD_W,
4369
- children: /* @__PURE__ */ jsxDEV12("box", {
5169
+ children: /* @__PURE__ */ jsxDEV16("box", {
4370
5170
  paddingLeft: 2,
4371
5171
  paddingTop: 1,
4372
5172
  paddingBottom: 1,
4373
- children: /* @__PURE__ */ jsxDEV12("text", {
4374
- fg: "#ff9e64",
5173
+ children: /* @__PURE__ */ jsxDEV16("text", {
5174
+ fg: theme.warning,
4375
5175
  children: "\u2839 Saving..."
4376
5176
  }, undefined, false, undefined, this)
4377
5177
  }, undefined, false, undefined, this)
4378
5178
  }, undefined, false, undefined, this)
4379
5179
  }, undefined, false, undefined, this);
4380
5180
  }
4381
- return /* @__PURE__ */ jsxDEV12("box", {
5181
+ return /* @__PURE__ */ jsxDEV16("box", {
4382
5182
  flexDirection: "column",
4383
5183
  flexGrow: 1,
4384
5184
  alignItems: "center",
4385
5185
  justifyContent: "center",
4386
- children: /* @__PURE__ */ jsxDEV12("box", {
5186
+ children: /* @__PURE__ */ jsxDEV16("box", {
4387
5187
  flexDirection: "column",
4388
5188
  border: true,
4389
5189
  borderStyle: "rounded",
4390
- borderColor: "#292e42",
4391
- backgroundColor: "#16161e",
5190
+ borderColor: theme.border,
5191
+ backgroundColor: theme.background,
4392
5192
  width: CARD_W,
4393
5193
  children: [
4394
- /* @__PURE__ */ jsxDEV12("box", {
5194
+ /* @__PURE__ */ jsxDEV16("box", {
4395
5195
  height: 1,
4396
5196
  paddingLeft: 2,
4397
5197
  paddingTop: 1,
4398
- children: /* @__PURE__ */ jsxDEV12("text", {
4399
- fg: "#7dcfff",
5198
+ children: /* @__PURE__ */ jsxDEV16("text", {
5199
+ fg: theme.accent,
4400
5200
  children: "Add Custom Provider"
4401
5201
  }, undefined, false, undefined, this)
4402
5202
  }, undefined, false, undefined, this),
4403
- /* @__PURE__ */ jsxDEV12("box", {
5203
+ /* @__PURE__ */ jsxDEV16("box", {
4404
5204
  height: 1,
4405
- backgroundColor: "#292e42"
5205
+ backgroundColor: theme.border
4406
5206
  }, undefined, false, undefined, this),
4407
- /* @__PURE__ */ jsxDEV12("box", {
5207
+ /* @__PURE__ */ jsxDEV16("box", {
4408
5208
  paddingTop: 1,
4409
5209
  paddingBottom: 1,
4410
- children: /* @__PURE__ */ jsxDEV12(ProgressBar, {}, undefined, false, undefined, this)
5210
+ children: /* @__PURE__ */ jsxDEV16(ProgressBar, {}, undefined, false, undefined, this)
4411
5211
  }, undefined, false, undefined, this),
4412
- /* @__PURE__ */ jsxDEV12("box", {
5212
+ /* @__PURE__ */ jsxDEV16("box", {
4413
5213
  height: 1,
4414
- backgroundColor: "#292e42"
5214
+ backgroundColor: theme.border
4415
5215
  }, undefined, false, undefined, this),
4416
- /* @__PURE__ */ jsxDEV12("box", {
5216
+ /* @__PURE__ */ jsxDEV16("box", {
4417
5217
  flexDirection: "column",
4418
5218
  paddingLeft: 2,
4419
5219
  paddingRight: 2,
4420
5220
  paddingTop: 1,
4421
5221
  paddingBottom: 1,
4422
5222
  children: [
4423
- step === "type" && /* @__PURE__ */ jsxDEV12("box", {
5223
+ step === "type" && /* @__PURE__ */ jsxDEV16("box", {
4424
5224
  flexDirection: "column",
4425
- children: typeItems.map((item, i) => /* @__PURE__ */ jsxDEV12("box", {
5225
+ children: typeItems.map((item, i) => /* @__PURE__ */ jsxDEV16("box", {
4426
5226
  height: 1,
4427
5227
  width: "100%",
4428
5228
  flexDirection: "row",
4429
- backgroundColor: i === typeCursor ? "#292e42" : "transparent",
5229
+ backgroundColor: i === typeCursor ? theme.border : "transparent",
4430
5230
  children: [
4431
- /* @__PURE__ */ jsxDEV12("text", {
4432
- fg: i === typeCursor ? "#c0caf5" : "#565f89",
5231
+ /* @__PURE__ */ jsxDEV16("text", {
5232
+ fg: i === typeCursor ? theme.text : theme.dim,
4433
5233
  children: [
4434
5234
  " ",
4435
5235
  item
4436
5236
  ]
4437
5237
  }, undefined, true, undefined, this),
4438
- i === typeCursor && /* @__PURE__ */ jsxDEV12("text", {
4439
- fg: "#7dcfff",
5238
+ i === typeCursor && /* @__PURE__ */ jsxDEV16("text", {
5239
+ fg: theme.accent,
4440
5240
  children: " \u203A"
4441
5241
  }, undefined, false, undefined, this)
4442
5242
  ]
4443
5243
  }, item, true, undefined, this))
4444
5244
  }, undefined, false, undefined, this),
4445
- step === "id" && /* @__PURE__ */ jsxDEV12("box", {
5245
+ step === "id" && /* @__PURE__ */ jsxDEV16("box", {
4446
5246
  flexDirection: "column",
4447
5247
  children: [
4448
- /* @__PURE__ */ jsxDEV12("box", {
5248
+ /* @__PURE__ */ jsxDEV16("box", {
4449
5249
  height: 1,
4450
5250
  flexDirection: "row",
4451
5251
  children: [
4452
- /* @__PURE__ */ jsxDEV12("text", {
4453
- fg: "#7aa2f7",
5252
+ /* @__PURE__ */ jsxDEV16("text", {
5253
+ fg: theme.primary,
4454
5254
  children: "Provider ID: "
4455
5255
  }, undefined, false, undefined, this),
4456
- /* @__PURE__ */ jsxDEV12("text", {
4457
- fg: "#c0caf5",
5256
+ /* @__PURE__ */ jsxDEV16("text", {
5257
+ fg: theme.text,
4458
5258
  children: [
4459
5259
  providerId,
4460
5260
  "_"
@@ -4462,28 +5262,28 @@ function AddCustomScreen() {
4462
5262
  }, undefined, true, undefined, this)
4463
5263
  ]
4464
5264
  }, undefined, true, undefined, this),
4465
- /* @__PURE__ */ jsxDEV12("box", {
5265
+ /* @__PURE__ */ jsxDEV16("box", {
4466
5266
  height: 1,
4467
- children: /* @__PURE__ */ jsxDEV12("text", {
4468
- fg: "#565f89",
5267
+ children: /* @__PURE__ */ jsxDEV16("text", {
5268
+ fg: theme.dim,
4469
5269
  children: "e.g. my-openai"
4470
5270
  }, undefined, false, undefined, this)
4471
5271
  }, undefined, false, undefined, this)
4472
5272
  ]
4473
5273
  }, undefined, true, undefined, this),
4474
- step === "name" && /* @__PURE__ */ jsxDEV12("box", {
5274
+ step === "name" && /* @__PURE__ */ jsxDEV16("box", {
4475
5275
  flexDirection: "column",
4476
5276
  children: [
4477
- /* @__PURE__ */ jsxDEV12("box", {
5277
+ /* @__PURE__ */ jsxDEV16("box", {
4478
5278
  height: 1,
4479
5279
  flexDirection: "row",
4480
5280
  children: [
4481
- /* @__PURE__ */ jsxDEV12("text", {
4482
- fg: "#7aa2f7",
5281
+ /* @__PURE__ */ jsxDEV16("text", {
5282
+ fg: theme.primary,
4483
5283
  children: "Display Name: "
4484
5284
  }, undefined, false, undefined, this),
4485
- /* @__PURE__ */ jsxDEV12("text", {
4486
- fg: "#c0caf5",
5285
+ /* @__PURE__ */ jsxDEV16("text", {
5286
+ fg: theme.text,
4487
5287
  children: [
4488
5288
  providerName,
4489
5289
  "_"
@@ -4491,10 +5291,10 @@ function AddCustomScreen() {
4491
5291
  }, undefined, true, undefined, this)
4492
5292
  ]
4493
5293
  }, undefined, true, undefined, this),
4494
- /* @__PURE__ */ jsxDEV12("box", {
5294
+ /* @__PURE__ */ jsxDEV16("box", {
4495
5295
  height: 1,
4496
- children: /* @__PURE__ */ jsxDEV12("text", {
4497
- fg: "#565f89",
5296
+ children: /* @__PURE__ */ jsxDEV16("text", {
5297
+ fg: theme.dim,
4498
5298
  children: [
4499
5299
  'e.g. My OpenAI (Enter to use "',
4500
5300
  providerId,
@@ -4504,19 +5304,19 @@ function AddCustomScreen() {
4504
5304
  }, undefined, false, undefined, this)
4505
5305
  ]
4506
5306
  }, undefined, true, undefined, this),
4507
- step === "url" && /* @__PURE__ */ jsxDEV12("box", {
5307
+ step === "url" && /* @__PURE__ */ jsxDEV16("box", {
4508
5308
  flexDirection: "column",
4509
5309
  children: [
4510
- /* @__PURE__ */ jsxDEV12("box", {
5310
+ /* @__PURE__ */ jsxDEV16("box", {
4511
5311
  height: 1,
4512
5312
  flexDirection: "row",
4513
5313
  children: [
4514
- /* @__PURE__ */ jsxDEV12("text", {
4515
- fg: "#7aa2f7",
5314
+ /* @__PURE__ */ jsxDEV16("text", {
5315
+ fg: theme.primary,
4516
5316
  children: "Base URL: "
4517
5317
  }, undefined, false, undefined, this),
4518
- /* @__PURE__ */ jsxDEV12("text", {
4519
- fg: "#c0caf5",
5318
+ /* @__PURE__ */ jsxDEV16("text", {
5319
+ fg: theme.text,
4520
5320
  children: [
4521
5321
  baseUrl,
4522
5322
  "_"
@@ -4524,28 +5324,28 @@ function AddCustomScreen() {
4524
5324
  }, undefined, true, undefined, this)
4525
5325
  ]
4526
5326
  }, undefined, true, undefined, this),
4527
- /* @__PURE__ */ jsxDEV12("box", {
5327
+ /* @__PURE__ */ jsxDEV16("box", {
4528
5328
  height: 1,
4529
- children: /* @__PURE__ */ jsxDEV12("text", {
4530
- fg: "#565f89",
5329
+ children: /* @__PURE__ */ jsxDEV16("text", {
5330
+ fg: theme.dim,
4531
5331
  children: "e.g. https://api.example.com/v1"
4532
5332
  }, undefined, false, undefined, this)
4533
5333
  }, undefined, false, undefined, this)
4534
5334
  ]
4535
5335
  }, undefined, true, undefined, this),
4536
- step === "key" && /* @__PURE__ */ jsxDEV12("box", {
5336
+ step === "key" && /* @__PURE__ */ jsxDEV16("box", {
4537
5337
  flexDirection: "column",
4538
5338
  children: [
4539
- /* @__PURE__ */ jsxDEV12("box", {
5339
+ /* @__PURE__ */ jsxDEV16("box", {
4540
5340
  height: 1,
4541
5341
  flexDirection: "row",
4542
5342
  children: [
4543
- /* @__PURE__ */ jsxDEV12("text", {
4544
- fg: "#7aa2f7",
5343
+ /* @__PURE__ */ jsxDEV16("text", {
5344
+ fg: theme.primary,
4545
5345
  children: "API Key: "
4546
5346
  }, undefined, false, undefined, this),
4547
- /* @__PURE__ */ jsxDEV12("text", {
4548
- fg: "#c0caf5",
5347
+ /* @__PURE__ */ jsxDEV16("text", {
5348
+ fg: theme.text,
4549
5349
  children: [
4550
5350
  apiKey,
4551
5351
  "_"
@@ -4553,24 +5353,24 @@ function AddCustomScreen() {
4553
5353
  }, undefined, true, undefined, this)
4554
5354
  ]
4555
5355
  }, undefined, true, undefined, this),
4556
- /* @__PURE__ */ jsxDEV12("box", {
5356
+ /* @__PURE__ */ jsxDEV16("box", {
4557
5357
  height: 1,
4558
- children: /* @__PURE__ */ jsxDEV12("text", {
4559
- fg: "#565f89",
5358
+ children: /* @__PURE__ */ jsxDEV16("text", {
5359
+ fg: theme.dim,
4560
5360
  children: "sk-... (leave empty if not needed)"
4561
5361
  }, undefined, false, undefined, this)
4562
5362
  }, undefined, false, undefined, this)
4563
5363
  ]
4564
5364
  }, undefined, true, undefined, this),
4565
- step === "models" && /* @__PURE__ */ jsxDEV12("box", {
5365
+ step === "models" && /* @__PURE__ */ jsxDEV16("box", {
4566
5366
  flexDirection: "column",
4567
5367
  children: [
4568
- models.length > 0 && /* @__PURE__ */ jsxDEV12("box", {
5368
+ models.length > 0 && /* @__PURE__ */ jsxDEV16("box", {
4569
5369
  flexDirection: "column",
4570
- children: models.map((m) => /* @__PURE__ */ jsxDEV12("box", {
5370
+ children: models.map((m) => /* @__PURE__ */ jsxDEV16("box", {
4571
5371
  height: 1,
4572
- children: /* @__PURE__ */ jsxDEV12("text", {
4573
- fg: "#565f89",
5372
+ children: /* @__PURE__ */ jsxDEV16("text", {
5373
+ fg: theme.dim,
4574
5374
  children: [
4575
5375
  " \xB7 ",
4576
5376
  m
@@ -4578,16 +5378,16 @@ function AddCustomScreen() {
4578
5378
  }, undefined, true, undefined, this)
4579
5379
  }, m, false, undefined, this))
4580
5380
  }, undefined, false, undefined, this),
4581
- /* @__PURE__ */ jsxDEV12("box", {
5381
+ /* @__PURE__ */ jsxDEV16("box", {
4582
5382
  height: 1,
4583
5383
  flexDirection: "row",
4584
5384
  children: [
4585
- /* @__PURE__ */ jsxDEV12("text", {
4586
- fg: "#7aa2f7",
5385
+ /* @__PURE__ */ jsxDEV16("text", {
5386
+ fg: theme.primary,
4587
5387
  children: "Model name: "
4588
5388
  }, undefined, false, undefined, this),
4589
- /* @__PURE__ */ jsxDEV12("text", {
4590
- fg: "#c0caf5",
5389
+ /* @__PURE__ */ jsxDEV16("text", {
5390
+ fg: theme.text,
4591
5391
  children: [
4592
5392
  modelInput,
4593
5393
  "_"
@@ -4595,10 +5395,10 @@ function AddCustomScreen() {
4595
5395
  }, undefined, true, undefined, this)
4596
5396
  ]
4597
5397
  }, undefined, true, undefined, this),
4598
- models.length > 0 && /* @__PURE__ */ jsxDEV12("box", {
5398
+ models.length > 0 && /* @__PURE__ */ jsxDEV16("box", {
4599
5399
  height: 1,
4600
- children: /* @__PURE__ */ jsxDEV12("text", {
4601
- fg: "#9ece6a",
5400
+ children: /* @__PURE__ */ jsxDEV16("text", {
5401
+ fg: theme.success,
4602
5402
  children: [
4603
5403
  " ",
4604
5404
  models.length,
@@ -4608,10 +5408,10 @@ function AddCustomScreen() {
4608
5408
  ]
4609
5409
  }, undefined, true, undefined, this)
4610
5410
  }, undefined, false, undefined, this),
4611
- saveError && /* @__PURE__ */ jsxDEV12("box", {
5411
+ saveError && /* @__PURE__ */ jsxDEV16("box", {
4612
5412
  height: 1,
4613
- children: /* @__PURE__ */ jsxDEV12("text", {
4614
- fg: "#f7768e",
5413
+ children: /* @__PURE__ */ jsxDEV16("text", {
5414
+ fg: theme.error,
4615
5415
  children: [
4616
5416
  "Error: ",
4617
5417
  saveError
@@ -4620,10 +5420,10 @@ function AddCustomScreen() {
4620
5420
  }, undefined, false, undefined, this)
4621
5421
  ]
4622
5422
  }, undefined, true, undefined, this),
4623
- inputError ? /* @__PURE__ */ jsxDEV12("box", {
5423
+ inputError ? /* @__PURE__ */ jsxDEV16("box", {
4624
5424
  height: 1,
4625
- children: /* @__PURE__ */ jsxDEV12("text", {
4626
- fg: "#f7768e",
5425
+ children: /* @__PURE__ */ jsxDEV16("text", {
5426
+ fg: theme.error,
4627
5427
  children: inputError
4628
5428
  }, undefined, false, undefined, this)
4629
5429
  }, undefined, false, undefined, this) : null
@@ -4635,7 +5435,9 @@ function AddCustomScreen() {
4635
5435
  }
4636
5436
  var STEPS, STEP_LABELS, STEP_NUM;
4637
5437
  var init_AddCustomScreen = __esm(() => {
5438
+ init_useAppKeyboard();
4638
5439
  init_AppContext();
5440
+ init_ThemeContext();
4639
5441
  init_usePaste();
4640
5442
  STEPS = ["type", "id", "name", "url", "key", "models"];
4641
5443
  STEP_LABELS = ["Type", "ID", "Name", "URL", "Key", "Models"];
@@ -4643,25 +5445,26 @@ var init_AddCustomScreen = __esm(() => {
4643
5445
  });
4644
5446
 
4645
5447
  // src/tui/screens/AddModelsScreen.tsx
4646
- import { useState as useState7, useEffect as useEffect6 } from "react";
4647
- import { useKeyboard as useKeyboard8, useTerminalDimensions as useTerminalDimensions4 } from "@opentui/react";
4648
- import { jsxDEV as jsxDEV13 } from "@opentui/react/jsx-dev-runtime";
5448
+ import { useState as useState11, useEffect as useEffect8 } from "react";
5449
+ import { useTerminalDimensions as useTerminalDimensions4 } from "@opentui/react";
5450
+ import { jsxDEV as jsxDEV17 } from "@opentui/react/jsx-dev-runtime";
4649
5451
  function AddModelsScreen() {
4650
5452
  const { dispatch } = useAppContext();
4651
5453
  const navigate = useNavigate();
5454
+ const theme = useTheme();
4652
5455
  const { width } = useTerminalDimensions4();
4653
5456
  const CARD_W = Math.min(60, width - 4);
4654
- const [step, setStep] = useState7("pick");
4655
- const [providers, setProviders] = useState7([]);
4656
- const [cursor, setCursor] = useState7(0);
4657
- const [selectedProvider, setSelectedProvider] = useState7(null);
4658
- const [modelInput, setModelInput] = useState7("");
4659
- const [addedModels, setAddedModels] = useState7([]);
4660
- const [loadError, setLoadError] = useState7("");
4661
- const [saveError, setSaveError] = useState7("");
4662
- const [inputError, setInputError] = useState7("");
4663
- const [done, setDone] = useState7(false);
4664
- useEffect6(() => {
5457
+ const [step, setStep] = useState11("pick");
5458
+ const [providers, setProviders] = useState11([]);
5459
+ const [cursor, setCursor] = useState11(0);
5460
+ const [selectedProvider, setSelectedProvider] = useState11(null);
5461
+ const [modelInput, setModelInput] = useState11("");
5462
+ const [addedModels, setAddedModels] = useState11([]);
5463
+ const [loadError, setLoadError] = useState11("");
5464
+ const [saveError, setSaveError] = useState11("");
5465
+ const [inputError, setInputError] = useState11("");
5466
+ const [done, setDone] = useState11(false);
5467
+ useEffect8(() => {
4665
5468
  async function load() {
4666
5469
  try {
4667
5470
  const { getCustomProvidersFromConfig: getCustomProvidersFromConfig2 } = await Promise.resolve().then(() => (init_ai_config(), exports_ai_config));
@@ -4678,7 +5481,7 @@ function AddModelsScreen() {
4678
5481
  if (step === "add")
4679
5482
  setModelInput((v) => v + clean);
4680
5483
  });
4681
- useKeyboard8((key) => {
5484
+ useAppKeyboard((key) => {
4682
5485
  if (done) {
4683
5486
  if (key.name === "return" || key.name === "enter")
4684
5487
  navigate("model-menu");
@@ -4731,9 +5534,8 @@ function AddModelsScreen() {
4731
5534
  setModelInput((v) => v.slice(0, -1));
4732
5535
  return;
4733
5536
  }
4734
- if (key.sequence && key.sequence.length === 1 && !key.ctrl && !key.meta && key.sequence >= " ") {
5537
+ if (key.sequence && key.sequence.length === 1 && !key.ctrl && !key.meta && key.sequence >= " ")
4735
5538
  setModelInput((v) => v + key.sequence);
4736
- }
4737
5539
  }
4738
5540
  });
4739
5541
  async function addModel() {
@@ -4744,10 +5546,7 @@ function AddModelsScreen() {
4744
5546
  const name = modelInput.trim();
4745
5547
  try {
4746
5548
  const { addModelToCustomProvider: addModelToCustomProvider2 } = await Promise.resolve().then(() => (init_ai_config(), exports_ai_config));
4747
- await addModelToCustomProvider2(selectedProvider.id, {
4748
- id: name.toLowerCase().replace(/[^a-z0-9-]/g, "-"),
4749
- name
4750
- });
5549
+ await addModelToCustomProvider2(selectedProvider.id, { id: name.toLowerCase().replace(/[^a-z0-9-]/g, "-"), name });
4751
5550
  setAddedModels((ms) => [...ms, name]);
4752
5551
  setModelInput("");
4753
5552
  } catch (e) {
@@ -4761,29 +5560,29 @@ function AddModelsScreen() {
4761
5560
  setDone(true);
4762
5561
  }
4763
5562
  if (done) {
4764
- return /* @__PURE__ */ jsxDEV13("box", {
5563
+ return /* @__PURE__ */ jsxDEV17("box", {
4765
5564
  flexDirection: "column",
4766
5565
  flexGrow: 1,
4767
5566
  alignItems: "center",
4768
5567
  justifyContent: "center",
4769
- children: /* @__PURE__ */ jsxDEV13("box", {
5568
+ children: /* @__PURE__ */ jsxDEV17("box", {
4770
5569
  flexDirection: "column",
4771
5570
  border: true,
4772
5571
  borderStyle: "rounded",
4773
- borderColor: "#292e42",
4774
- backgroundColor: "#16161e",
5572
+ borderColor: theme.border,
5573
+ backgroundColor: theme.background,
4775
5574
  width: CARD_W,
4776
- children: /* @__PURE__ */ jsxDEV13("box", {
5575
+ children: /* @__PURE__ */ jsxDEV17("box", {
4777
5576
  flexDirection: "column",
4778
5577
  paddingLeft: 2,
4779
5578
  paddingRight: 2,
4780
5579
  paddingTop: 1,
4781
5580
  paddingBottom: 1,
4782
5581
  children: [
4783
- /* @__PURE__ */ jsxDEV13("box", {
5582
+ /* @__PURE__ */ jsxDEV17("box", {
4784
5583
  height: 1,
4785
- children: /* @__PURE__ */ jsxDEV13("text", {
4786
- fg: "#9ece6a",
5584
+ children: /* @__PURE__ */ jsxDEV17("text", {
5585
+ fg: theme.success,
4787
5586
  children: [
4788
5587
  "Done! Added ",
4789
5588
  addedModels.length,
@@ -4795,10 +5594,10 @@ function AddModelsScreen() {
4795
5594
  ]
4796
5595
  }, undefined, true, undefined, this)
4797
5596
  }, undefined, false, undefined, this),
4798
- /* @__PURE__ */ jsxDEV13("box", {
5597
+ /* @__PURE__ */ jsxDEV17("box", {
4799
5598
  height: 1,
4800
- children: /* @__PURE__ */ jsxDEV13("text", {
4801
- fg: "#565f89",
5599
+ children: /* @__PURE__ */ jsxDEV17("text", {
5600
+ fg: theme.dim,
4802
5601
  children: "Press [Enter] to return"
4803
5602
  }, undefined, false, undefined, this)
4804
5603
  }, undefined, false, undefined, this)
@@ -4808,70 +5607,70 @@ function AddModelsScreen() {
4808
5607
  }, undefined, false, undefined, this);
4809
5608
  }
4810
5609
  if (step === "add" && selectedProvider) {
4811
- return /* @__PURE__ */ jsxDEV13("box", {
5610
+ return /* @__PURE__ */ jsxDEV17("box", {
4812
5611
  flexDirection: "column",
4813
5612
  flexGrow: 1,
4814
5613
  alignItems: "center",
4815
5614
  justifyContent: "center",
4816
- children: /* @__PURE__ */ jsxDEV13("box", {
5615
+ children: /* @__PURE__ */ jsxDEV17("box", {
4817
5616
  flexDirection: "column",
4818
5617
  border: true,
4819
5618
  borderStyle: "rounded",
4820
- borderColor: "#292e42",
4821
- backgroundColor: "#16161e",
5619
+ borderColor: theme.border,
5620
+ backgroundColor: theme.background,
4822
5621
  width: CARD_W,
4823
5622
  children: [
4824
- /* @__PURE__ */ jsxDEV13("box", {
5623
+ /* @__PURE__ */ jsxDEV17("box", {
4825
5624
  height: 1,
4826
5625
  paddingLeft: 2,
4827
5626
  paddingTop: 1,
4828
5627
  flexDirection: "row",
4829
5628
  children: [
4830
- /* @__PURE__ */ jsxDEV13("text", {
4831
- fg: "#7dcfff",
5629
+ /* @__PURE__ */ jsxDEV17("text", {
5630
+ fg: theme.accent,
4832
5631
  children: "Add Models to: "
4833
5632
  }, undefined, false, undefined, this),
4834
- /* @__PURE__ */ jsxDEV13("text", {
4835
- fg: "#c0caf5",
5633
+ /* @__PURE__ */ jsxDEV17("text", {
5634
+ fg: theme.text,
4836
5635
  children: selectedProvider.name
4837
5636
  }, undefined, false, undefined, this)
4838
5637
  ]
4839
5638
  }, undefined, true, undefined, this),
4840
- /* @__PURE__ */ jsxDEV13("box", {
5639
+ /* @__PURE__ */ jsxDEV17("box", {
4841
5640
  height: 1,
4842
- backgroundColor: "#292e42"
5641
+ backgroundColor: theme.border
4843
5642
  }, undefined, false, undefined, this),
4844
- /* @__PURE__ */ jsxDEV13("box", {
5643
+ /* @__PURE__ */ jsxDEV17("box", {
4845
5644
  flexDirection: "column",
4846
5645
  paddingLeft: 2,
4847
5646
  paddingRight: 2,
4848
5647
  paddingTop: 1,
4849
5648
  paddingBottom: 1,
4850
5649
  children: [
4851
- (selectedProvider.models.length > 0 || addedModels.length > 0) && /* @__PURE__ */ jsxDEV13("box", {
5650
+ (selectedProvider.models.length > 0 || addedModels.length > 0) && /* @__PURE__ */ jsxDEV17("box", {
4852
5651
  flexDirection: "column",
4853
5652
  children: [
4854
- /* @__PURE__ */ jsxDEV13("box", {
5653
+ /* @__PURE__ */ jsxDEV17("box", {
4855
5654
  height: 1,
4856
- children: /* @__PURE__ */ jsxDEV13("text", {
4857
- fg: "#7aa2f7",
5655
+ children: /* @__PURE__ */ jsxDEV17("text", {
5656
+ fg: theme.primary,
4858
5657
  children: "Current models:"
4859
5658
  }, undefined, false, undefined, this)
4860
5659
  }, undefined, false, undefined, this),
4861
- selectedProvider.models.map((m) => /* @__PURE__ */ jsxDEV13("box", {
5660
+ selectedProvider.models.map((m) => /* @__PURE__ */ jsxDEV17("box", {
4862
5661
  height: 1,
4863
- children: /* @__PURE__ */ jsxDEV13("text", {
4864
- fg: "#565f89",
5662
+ children: /* @__PURE__ */ jsxDEV17("text", {
5663
+ fg: theme.dim,
4865
5664
  children: [
4866
5665
  " \xB7 ",
4867
5666
  m.name || m.id
4868
5667
  ]
4869
5668
  }, undefined, true, undefined, this)
4870
5669
  }, m.id, false, undefined, this)),
4871
- addedModels.map((m) => /* @__PURE__ */ jsxDEV13("box", {
5670
+ addedModels.map((m) => /* @__PURE__ */ jsxDEV17("box", {
4872
5671
  height: 1,
4873
- children: /* @__PURE__ */ jsxDEV13("text", {
4874
- fg: "#9ece6a",
5672
+ children: /* @__PURE__ */ jsxDEV17("text", {
5673
+ fg: theme.success,
4875
5674
  children: [
4876
5675
  " \xB7 ",
4877
5676
  m,
@@ -4881,16 +5680,16 @@ function AddModelsScreen() {
4881
5680
  }, m, false, undefined, this))
4882
5681
  ]
4883
5682
  }, undefined, true, undefined, this),
4884
- /* @__PURE__ */ jsxDEV13("box", {
5683
+ /* @__PURE__ */ jsxDEV17("box", {
4885
5684
  height: 1,
4886
5685
  flexDirection: "row",
4887
5686
  children: [
4888
- /* @__PURE__ */ jsxDEV13("text", {
4889
- fg: "#7aa2f7",
5687
+ /* @__PURE__ */ jsxDEV17("text", {
5688
+ fg: theme.primary,
4890
5689
  children: "Model name: "
4891
5690
  }, undefined, false, undefined, this),
4892
- /* @__PURE__ */ jsxDEV13("text", {
4893
- fg: "#c0caf5",
5691
+ /* @__PURE__ */ jsxDEV17("text", {
5692
+ fg: theme.text,
4894
5693
  children: [
4895
5694
  modelInput,
4896
5695
  "_"
@@ -4898,10 +5697,10 @@ function AddModelsScreen() {
4898
5697
  }, undefined, true, undefined, this)
4899
5698
  ]
4900
5699
  }, undefined, true, undefined, this),
4901
- addedModels.length > 0 && /* @__PURE__ */ jsxDEV13("box", {
5700
+ addedModels.length > 0 && /* @__PURE__ */ jsxDEV17("box", {
4902
5701
  height: 1,
4903
- children: /* @__PURE__ */ jsxDEV13("text", {
4904
- fg: "#9ece6a",
5702
+ children: /* @__PURE__ */ jsxDEV17("text", {
5703
+ fg: theme.success,
4905
5704
  children: [
4906
5705
  "Added ",
4907
5706
  addedModels.length,
@@ -4911,20 +5710,20 @@ function AddModelsScreen() {
4911
5710
  ]
4912
5711
  }, undefined, true, undefined, this)
4913
5712
  }, undefined, false, undefined, this),
4914
- saveError && /* @__PURE__ */ jsxDEV13("box", {
5713
+ saveError && /* @__PURE__ */ jsxDEV17("box", {
4915
5714
  height: 1,
4916
- children: /* @__PURE__ */ jsxDEV13("text", {
4917
- fg: "#f7768e",
5715
+ children: /* @__PURE__ */ jsxDEV17("text", {
5716
+ fg: theme.error,
4918
5717
  children: [
4919
5718
  "Error: ",
4920
5719
  saveError
4921
5720
  ]
4922
5721
  }, undefined, true, undefined, this)
4923
5722
  }, undefined, false, undefined, this),
4924
- inputError && /* @__PURE__ */ jsxDEV13("box", {
5723
+ inputError && /* @__PURE__ */ jsxDEV17("box", {
4925
5724
  height: 1,
4926
- children: /* @__PURE__ */ jsxDEV13("text", {
4927
- fg: "#f7768e",
5725
+ children: /* @__PURE__ */ jsxDEV17("text", {
5726
+ fg: theme.error,
4928
5727
  children: inputError
4929
5728
  }, undefined, false, undefined, this)
4930
5729
  }, undefined, false, undefined, this)
@@ -4934,84 +5733,84 @@ function AddModelsScreen() {
4934
5733
  }, undefined, true, undefined, this)
4935
5734
  }, undefined, false, undefined, this);
4936
5735
  }
4937
- return /* @__PURE__ */ jsxDEV13("box", {
5736
+ return /* @__PURE__ */ jsxDEV17("box", {
4938
5737
  flexDirection: "column",
4939
5738
  flexGrow: 1,
4940
5739
  alignItems: "center",
4941
5740
  justifyContent: "center",
4942
- children: /* @__PURE__ */ jsxDEV13("box", {
5741
+ children: /* @__PURE__ */ jsxDEV17("box", {
4943
5742
  flexDirection: "column",
4944
5743
  border: true,
4945
5744
  borderStyle: "rounded",
4946
- borderColor: "#292e42",
4947
- backgroundColor: "#16161e",
5745
+ borderColor: theme.border,
5746
+ backgroundColor: theme.background,
4948
5747
  width: CARD_W,
4949
5748
  children: [
4950
- /* @__PURE__ */ jsxDEV13("box", {
5749
+ /* @__PURE__ */ jsxDEV17("box", {
4951
5750
  height: 1,
4952
5751
  paddingLeft: 2,
4953
5752
  paddingTop: 1,
4954
- children: /* @__PURE__ */ jsxDEV13("text", {
4955
- fg: "#7dcfff",
5753
+ children: /* @__PURE__ */ jsxDEV17("text", {
5754
+ fg: theme.accent,
4956
5755
  children: "Add Models to Provider"
4957
5756
  }, undefined, false, undefined, this)
4958
5757
  }, undefined, false, undefined, this),
4959
- /* @__PURE__ */ jsxDEV13("box", {
5758
+ /* @__PURE__ */ jsxDEV17("box", {
4960
5759
  height: 1,
4961
- backgroundColor: "#292e42"
5760
+ backgroundColor: theme.border
4962
5761
  }, undefined, false, undefined, this),
4963
- /* @__PURE__ */ jsxDEV13("box", {
5762
+ /* @__PURE__ */ jsxDEV17("box", {
4964
5763
  flexDirection: "column",
4965
5764
  paddingLeft: 2,
4966
5765
  paddingRight: 2,
4967
5766
  paddingTop: 1,
4968
5767
  paddingBottom: 1,
4969
5768
  children: [
4970
- loadError && /* @__PURE__ */ jsxDEV13("box", {
5769
+ loadError && /* @__PURE__ */ jsxDEV17("box", {
4971
5770
  height: 1,
4972
- children: /* @__PURE__ */ jsxDEV13("text", {
4973
- fg: "#f7768e",
5771
+ children: /* @__PURE__ */ jsxDEV17("text", {
5772
+ fg: theme.error,
4974
5773
  children: [
4975
5774
  "Error: ",
4976
5775
  loadError
4977
5776
  ]
4978
5777
  }, undefined, true, undefined, this)
4979
5778
  }, undefined, false, undefined, this),
4980
- !loadError && providers.length === 0 && /* @__PURE__ */ jsxDEV13("box", {
5779
+ !loadError && providers.length === 0 && /* @__PURE__ */ jsxDEV17("box", {
4981
5780
  height: 1,
4982
- children: /* @__PURE__ */ jsxDEV13("text", {
4983
- fg: "#ff9e64",
5781
+ children: /* @__PURE__ */ jsxDEV17("text", {
5782
+ fg: theme.warning,
4984
5783
  children: "No custom providers yet. Add one first."
4985
5784
  }, undefined, false, undefined, this)
4986
5785
  }, undefined, false, undefined, this),
4987
5786
  providers.map((prov, i) => {
4988
5787
  const isActive = i === cursor;
4989
- return /* @__PURE__ */ jsxDEV13("box", {
5788
+ return /* @__PURE__ */ jsxDEV17("box", {
4990
5789
  height: 1,
4991
5790
  width: "100%",
4992
5791
  flexDirection: "row",
4993
- backgroundColor: isActive ? "#292e42" : "transparent",
5792
+ backgroundColor: isActive ? theme.border : "transparent",
4994
5793
  children: [
4995
- /* @__PURE__ */ jsxDEV13("text", {
4996
- fg: "#565f89",
5794
+ /* @__PURE__ */ jsxDEV17("text", {
5795
+ fg: theme.dim,
4997
5796
  width: 2,
4998
5797
  children: " "
4999
5798
  }, undefined, false, undefined, this),
5000
- /* @__PURE__ */ jsxDEV13("text", {
5001
- fg: isActive ? "#c0caf5" : "#565f89",
5799
+ /* @__PURE__ */ jsxDEV17("text", {
5800
+ fg: isActive ? theme.text : theme.dim,
5002
5801
  width: Math.floor((CARD_W - 8) * 0.6),
5003
5802
  children: prov.name
5004
5803
  }, undefined, false, undefined, this),
5005
- /* @__PURE__ */ jsxDEV13("text", {
5006
- fg: isActive ? "#7aa2f7" : "#292e42",
5804
+ /* @__PURE__ */ jsxDEV17("text", {
5805
+ fg: isActive ? theme.primary : theme.border,
5007
5806
  width: Math.floor((CARD_W - 8) * 0.3),
5008
5807
  children: [
5009
5808
  prov.models.length,
5010
5809
  " models"
5011
5810
  ]
5012
5811
  }, undefined, true, undefined, this),
5013
- /* @__PURE__ */ jsxDEV13("text", {
5014
- fg: "#7dcfff",
5812
+ /* @__PURE__ */ jsxDEV17("text", {
5813
+ fg: theme.accent,
5015
5814
  width: 2,
5016
5815
  children: isActive ? "\u203A" : " "
5017
5816
  }, undefined, false, undefined, this)
@@ -5025,84 +5824,87 @@ function AddModelsScreen() {
5025
5824
  }, undefined, false, undefined, this);
5026
5825
  }
5027
5826
  var init_AddModelsScreen = __esm(() => {
5827
+ init_useAppKeyboard();
5028
5828
  init_AppContext();
5829
+ init_ThemeContext();
5029
5830
  init_usePaste();
5030
5831
  });
5031
5832
 
5032
5833
  // src/tui/screens/ListProvidersScreen.tsx
5033
- import { useKeyboard as useKeyboard9 } from "@opentui/react";
5034
- import { jsxDEV as jsxDEV14 } from "@opentui/react/jsx-dev-runtime";
5834
+ import { jsxDEV as jsxDEV18 } from "@opentui/react/jsx-dev-runtime";
5035
5835
  function ListProvidersScreen() {
5036
5836
  const { state } = useAppContext();
5037
5837
  const navigate = useNavigate();
5038
- useKeyboard9((key) => {
5838
+ const theme = useTheme();
5839
+ useAppKeyboard((key) => {
5039
5840
  if (key.name === "escape" || key.name === "q") {
5040
5841
  navigate("model-menu");
5041
5842
  }
5042
5843
  });
5043
5844
  if (state.isLoadingConfig) {
5044
- return /* @__PURE__ */ jsxDEV14("box", {
5845
+ return /* @__PURE__ */ jsxDEV18("box", {
5045
5846
  flexDirection: "column",
5046
5847
  flexGrow: 1,
5047
5848
  padding: 1,
5048
- children: /* @__PURE__ */ jsxDEV14("text", {
5849
+ children: /* @__PURE__ */ jsxDEV18("text", {
5850
+ fg: theme.dim,
5049
5851
  children: "Loading providers..."
5050
5852
  }, undefined, false, undefined, this)
5051
5853
  }, undefined, false, undefined, this);
5052
5854
  }
5053
5855
  const providers = state.config?.providers ?? [];
5054
5856
  if (providers.length === 0) {
5055
- return /* @__PURE__ */ jsxDEV14("box", {
5857
+ return /* @__PURE__ */ jsxDEV18("box", {
5056
5858
  flexDirection: "column",
5057
5859
  flexGrow: 1,
5058
5860
  padding: 1,
5059
5861
  children: [
5060
- /* @__PURE__ */ jsxDEV14("text", {
5061
- fg: "#7aa2f7",
5862
+ /* @__PURE__ */ jsxDEV18("text", {
5863
+ fg: theme.primary,
5062
5864
  children: "Configured Providers"
5063
5865
  }, undefined, false, undefined, this),
5064
- /* @__PURE__ */ jsxDEV14("box", {
5866
+ /* @__PURE__ */ jsxDEV18("box", {
5065
5867
  marginTop: 1,
5066
- children: /* @__PURE__ */ jsxDEV14("text", {
5067
- fg: "#ff9e64",
5868
+ children: /* @__PURE__ */ jsxDEV18("text", {
5869
+ fg: theme.warning,
5068
5870
  children: "No providers configured yet."
5069
5871
  }, undefined, false, undefined, this)
5070
5872
  }, undefined, false, undefined, this)
5071
5873
  ]
5072
5874
  }, undefined, true, undefined, this);
5073
5875
  }
5074
- return /* @__PURE__ */ jsxDEV14("box", {
5876
+ return /* @__PURE__ */ jsxDEV18("box", {
5075
5877
  flexDirection: "column",
5076
5878
  flexGrow: 1,
5077
5879
  padding: 1,
5078
5880
  children: [
5079
- /* @__PURE__ */ jsxDEV14("text", {
5080
- fg: "#7aa2f7",
5881
+ /* @__PURE__ */ jsxDEV18("text", {
5882
+ fg: theme.primary,
5081
5883
  children: "Configured Providers"
5082
5884
  }, undefined, false, undefined, this),
5083
- /* @__PURE__ */ jsxDEV14("box", {
5885
+ /* @__PURE__ */ jsxDEV18("box", {
5084
5886
  marginTop: 1,
5085
5887
  flexGrow: 1,
5086
- children: /* @__PURE__ */ jsxDEV14("scrollbox", {
5888
+ children: /* @__PURE__ */ jsxDEV18("scrollbox", {
5087
5889
  focused: true,
5088
- children: providers.map((provider, i) => /* @__PURE__ */ jsxDEV14("box", {
5890
+ children: providers.map((provider, i) => /* @__PURE__ */ jsxDEV18("box", {
5089
5891
  flexDirection: "column",
5090
5892
  border: true,
5091
5893
  borderStyle: "rounded",
5092
- borderColor: "#292e42",
5093
- backgroundColor: "#16161e",
5894
+ borderColor: theme.border,
5895
+ backgroundColor: theme.background,
5094
5896
  marginBottom: 1,
5095
5897
  padding: 1,
5096
5898
  children: [
5097
- /* @__PURE__ */ jsxDEV14("box", {
5899
+ /* @__PURE__ */ jsxDEV18("box", {
5098
5900
  flexDirection: "row",
5099
5901
  children: [
5100
- /* @__PURE__ */ jsxDEV14("text", {
5101
- fg: "#7dcfff",
5902
+ /* @__PURE__ */ jsxDEV18("text", {
5903
+ fg: theme.accent,
5102
5904
  children: provider.name
5103
5905
  }, undefined, false, undefined, this),
5104
- /* @__PURE__ */ jsxDEV14("text", {
5105
- fg: "#565f89",
5906
+ /* @__PURE__ */ jsxDEV18("text", {
5907
+ fg: theme.dim,
5106
5908
  children: [
5107
5909
  " [",
5108
5910
  provider.type,
@@ -5111,8 +5913,8 @@ function ListProvidersScreen() {
5111
5913
  }, undefined, true, undefined, this)
5112
5914
  ]
5113
5915
  }, undefined, true, undefined, this),
5114
- provider.models.map((model, j) => /* @__PURE__ */ jsxDEV14("text", {
5115
- fg: "#565f89",
5916
+ provider.models.map((model, j) => /* @__PURE__ */ jsxDEV18("text", {
5917
+ fg: theme.dim,
5116
5918
  children: [
5117
5919
  " \xB7 ",
5118
5920
  model.name || model.id
@@ -5126,16 +5928,18 @@ function ListProvidersScreen() {
5126
5928
  }, undefined, true, undefined, this);
5127
5929
  }
5128
5930
  var init_ListProvidersScreen = __esm(() => {
5931
+ init_useAppKeyboard();
5129
5932
  init_AppContext();
5933
+ init_ThemeContext();
5130
5934
  });
5131
5935
 
5132
5936
  // src/tui/App.tsx
5133
- import { useKeyboard as useKeyboard10, useRenderer as useRenderer3 } from "@opentui/react";
5134
- import { jsxDEV as jsxDEV15 } from "@opentui/react/jsx-dev-runtime";
5937
+ import { useKeyboard as useKeyboard3, useRenderer as useRenderer3 } from "@opentui/react";
5938
+ import { jsxDEV as jsxDEV19 } from "@opentui/react/jsx-dev-runtime";
5135
5939
  function getHints(screen, benchResults) {
5136
5940
  switch (screen) {
5137
5941
  case "main-menu":
5138
- return ["[\u2191\u2193] navigate", "[Enter] select", "[Ctrl+C] quit"];
5942
+ return ["[\u2191\u2193] navigate", "[Enter] select", "[T] theme", "[Ctrl+C] quit"];
5139
5943
  case "model-menu":
5140
5944
  return ["[\u2191\u2193] navigate", "[Enter] select", "[Q] back"];
5141
5945
  case "model-select":
@@ -5160,59 +5964,76 @@ function ActiveScreen() {
5160
5964
  const { state } = useAppContext();
5161
5965
  switch (state.screen) {
5162
5966
  case "main-menu":
5163
- return /* @__PURE__ */ jsxDEV15(MainMenuScreen, {}, undefined, false, undefined, this);
5967
+ return /* @__PURE__ */ jsxDEV19(MainMenuScreen, {}, undefined, false, undefined, this);
5164
5968
  case "model-menu":
5165
- return /* @__PURE__ */ jsxDEV15(ModelMenuScreen, {}, undefined, false, undefined, this);
5969
+ return /* @__PURE__ */ jsxDEV19(ModelMenuScreen, {}, undefined, false, undefined, this);
5166
5970
  case "model-select":
5167
- return /* @__PURE__ */ jsxDEV15(ModelSelectScreen, {}, undefined, false, undefined, this);
5971
+ return /* @__PURE__ */ jsxDEV19(ModelSelectScreen, {}, undefined, false, undefined, this);
5168
5972
  case "benchmark":
5169
- return /* @__PURE__ */ jsxDEV15(BenchmarkScreen, {}, undefined, false, undefined, this);
5973
+ return /* @__PURE__ */ jsxDEV19(BenchmarkScreen, {}, undefined, false, undefined, this);
5170
5974
  case "add-verified":
5171
- return /* @__PURE__ */ jsxDEV15(AddVerifiedScreen, {}, undefined, false, undefined, this);
5975
+ return /* @__PURE__ */ jsxDEV19(AddVerifiedScreen, {}, undefined, false, undefined, this);
5172
5976
  case "add-custom":
5173
- return /* @__PURE__ */ jsxDEV15(AddCustomScreen, {}, undefined, false, undefined, this);
5977
+ return /* @__PURE__ */ jsxDEV19(AddCustomScreen, {}, undefined, false, undefined, this);
5174
5978
  case "add-models":
5175
- return /* @__PURE__ */ jsxDEV15(AddModelsScreen, {}, undefined, false, undefined, this);
5979
+ return /* @__PURE__ */ jsxDEV19(AddModelsScreen, {}, undefined, false, undefined, this);
5176
5980
  case "list-providers":
5177
- return /* @__PURE__ */ jsxDEV15(ListProvidersScreen, {}, undefined, false, undefined, this);
5981
+ return /* @__PURE__ */ jsxDEV19(ListProvidersScreen, {}, undefined, false, undefined, this);
5178
5982
  }
5179
5983
  }
5180
5984
  function Shell() {
5181
5985
  const renderer = useRenderer3();
5182
5986
  const { state } = useAppContext();
5183
- useKeyboard10((key) => {
5987
+ const theme = useTheme();
5988
+ const { modalOpen, setModalOpen } = useModal();
5989
+ useKeyboard3((key) => {
5184
5990
  if (key.ctrl && key.name === "c") {
5185
5991
  renderer.destroy();
5992
+ return;
5993
+ }
5994
+ if (!key.ctrl && !key.meta && key.sequence === "T") {
5995
+ setModalOpen(!modalOpen);
5186
5996
  }
5187
5997
  });
5188
- return /* @__PURE__ */ jsxDEV15("box", {
5998
+ return /* @__PURE__ */ jsxDEV19("box", {
5189
5999
  flexDirection: "column",
5190
6000
  height: "100%",
5191
6001
  width: "100%",
5192
- backgroundColor: "#1a1b26",
6002
+ backgroundColor: theme.background,
5193
6003
  children: [
5194
- /* @__PURE__ */ jsxDEV15(Header, {
6004
+ /* @__PURE__ */ jsxDEV19(Header, {
5195
6005
  screen: state.screen
5196
6006
  }, undefined, false, undefined, this),
5197
- /* @__PURE__ */ jsxDEV15("box", {
6007
+ /* @__PURE__ */ jsxDEV19("box", {
5198
6008
  flexGrow: 1,
5199
6009
  flexDirection: "column",
5200
- children: /* @__PURE__ */ jsxDEV15(ActiveScreen, {}, undefined, false, undefined, this)
6010
+ children: /* @__PURE__ */ jsxDEV19(ActiveScreen, {}, undefined, false, undefined, this)
5201
6011
  }, undefined, false, undefined, this),
5202
- /* @__PURE__ */ jsxDEV15(Footer, {
6012
+ /* @__PURE__ */ jsxDEV19(Footer, {
5203
6013
  hints: getHints(state.screen, state.benchResults)
6014
+ }, undefined, false, undefined, this),
6015
+ modalOpen && /* @__PURE__ */ jsxDEV19(ThemePicker, {
6016
+ onClose: () => setModalOpen(false)
5204
6017
  }, undefined, false, undefined, this)
5205
6018
  ]
5206
6019
  }, undefined, true, undefined, this);
5207
6020
  }
5208
- function App({ logMode = false }) {
5209
- return /* @__PURE__ */ jsxDEV15(AppProvider, {
5210
- logMode,
5211
- children: /* @__PURE__ */ jsxDEV15(Shell, {}, undefined, false, undefined, this)
6021
+ function App({ logMode = false, theme = "tokyonight" }) {
6022
+ return /* @__PURE__ */ jsxDEV19(ThemeProvider, {
6023
+ name: theme,
6024
+ children: /* @__PURE__ */ jsxDEV19(ModalProvider, {
6025
+ children: /* @__PURE__ */ jsxDEV19(AppProvider, {
6026
+ logMode,
6027
+ children: /* @__PURE__ */ jsxDEV19(Shell, {}, undefined, false, undefined, this)
6028
+ }, undefined, false, undefined, this)
6029
+ }, undefined, false, undefined, this)
5212
6030
  }, undefined, false, undefined, this);
5213
6031
  }
5214
6032
  var init_App = __esm(() => {
5215
6033
  init_AppContext();
6034
+ init_ThemeContext();
6035
+ init_ModalContext();
6036
+ init_ThemePicker();
5216
6037
  init_Header();
5217
6038
  init_Footer();
5218
6039
  init_MainMenuScreen();
@@ -5232,8 +6053,10 @@ __export(exports_tui, {
5232
6053
  });
5233
6054
  import { createCliRenderer } from "@opentui/core";
5234
6055
  import { createRoot } from "@opentui/react";
5235
- import { jsxDEV as jsxDEV16 } from "@opentui/react/jsx-dev-runtime";
6056
+ import { jsxDEV as jsxDEV20 } from "@opentui/react/jsx-dev-runtime";
5236
6057
  async function startTui(logMode = false) {
6058
+ const { readThemeFromConfig: readThemeFromConfig2 } = await Promise.resolve().then(() => (init_ai_config(), exports_ai_config));
6059
+ const theme = await readThemeFromConfig2();
5237
6060
  const renderer = await createCliRenderer({
5238
6061
  exitOnCtrlC: false
5239
6062
  });
@@ -5247,8 +6070,9 @@ async function startTui(logMode = false) {
5247
6070
  renderer.destroy();
5248
6071
  process.exit(0);
5249
6072
  });
5250
- createRoot(renderer).render(/* @__PURE__ */ jsxDEV16(App, {
5251
- logMode
6073
+ createRoot(renderer).render(/* @__PURE__ */ jsxDEV20(App, {
6074
+ logMode,
6075
+ theme
5252
6076
  }, undefined, false, undefined, this));
5253
6077
  }
5254
6078
  var ENABLE_BRACKETED_PASTE = "\x1B[?2004h", DISABLE_BRACKETED_PASTE = "\x1B[?2004l";