claudish 7.2.0 → 7.4.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (2) hide show
  1. package/dist/index.js +2058 -367
  2. package/package.json +5 -5
package/dist/index.js CHANGED
@@ -27840,6 +27840,9 @@ class NativeHandler {
27840
27840
  if (originalHeaders["x-api-key"]) {
27841
27841
  headers["x-api-key"] = originalHeaders["x-api-key"];
27842
27842
  }
27843
+ if (!originalHeaders["authorization"] && !originalHeaders["x-api-key"] && this.apiKey) {
27844
+ headers["x-api-key"] = this.apiKey;
27845
+ }
27843
27846
  if (originalHeaders["anthropic-beta"]) {
27844
27847
  const incomingBeta = originalHeaders["anthropic-beta"];
27845
27848
  if (advisorSwapped) {
@@ -33157,7 +33160,7 @@ var init_vision_proxy = __esm(() => {
33157
33160
  });
33158
33161
 
33159
33162
  // src/version.ts
33160
- var VERSION = "7.2.0";
33163
+ var VERSION = "7.4.0";
33161
33164
 
33162
33165
  // src/telemetry.ts
33163
33166
  var exports_telemetry = {};
@@ -54328,23 +54331,34 @@ async function probeLink(proxyUrl, link, timeoutMs) {
54328
54331
  signal: AbortSignal.timeout(timeoutMs)
54329
54332
  });
54330
54333
  } catch (e) {
54331
- const latencyMs2 = Date.now() - startedAt;
54334
+ const latencyMs = Date.now() - startedAt;
54332
54335
  const name = e?.name || "";
54333
54336
  const msg = String(e?.message || e);
54334
54337
  if (name === "TimeoutError" || name === "AbortError" || /timeout/i.test(msg)) {
54335
- return { state: "timeout", latencyMs: latencyMs2, errorMessage: msg };
54338
+ return { state: "timeout", latencyMs, errorMessage: msg };
54336
54339
  }
54337
- return { state: "network-error", latencyMs: latencyMs2, errorMessage: msg };
54340
+ return { state: "network-error", latencyMs, errorMessage: msg };
54338
54341
  }
54339
- const latencyMs = Date.now() - startedAt;
54342
+ const ttfbMs = Date.now() - startedAt;
54340
54343
  if (!response.ok) {
54341
54344
  const body = await safeReadBody(response);
54342
- return annotateOAuthHint(classifyHttpError(response.status, body, latencyMs), link.provider, isOAuth);
54343
- }
54344
- const streamResult = await consumeProbeStream(response, timeoutMs);
54345
+ return annotateOAuthHint(classifyHttpError(response.status, body, ttfbMs), link.provider, isOAuth);
54346
+ }
54347
+ const streamResult = await consumeProbeStream(response, timeoutMs, startedAt);
54348
+ const totalMs = Date.now() - startedAt;
54349
+ let timing;
54350
+ if (streamResult.state === "live" && streamResult.ttftMs !== undefined && !streamResult.truncated) {
54351
+ const ttftMs = streamResult.ttftMs;
54352
+ const tokens = streamResult.tokens ?? 0;
54353
+ const streamMs = Math.max(STREAM_MS_FLOOR, totalMs - ttftMs);
54354
+ const tokensPerSec = tokens > 0 ? tokens / streamMs * 1000 : 0;
54355
+ timing = { ttfbMs, ttftMs, totalMs, tokens, tokensPerSec };
54356
+ }
54357
+ const { ttftMs: _ttft, tokens: _tok, truncated: _trunc, ...rest } = streamResult;
54345
54358
  return annotateOAuthHint({
54346
- ...streamResult,
54347
- latencyMs: Date.now() - startedAt
54359
+ ...rest,
54360
+ latencyMs: totalMs,
54361
+ timing
54348
54362
  }, link.provider, isOAuth);
54349
54363
  }
54350
54364
  function annotateOAuthHint(result, provider, isOAuth) {
@@ -54428,7 +54442,7 @@ function extractErrorMessage(body) {
54428
54442
  return;
54429
54443
  return trimmed.length > 160 ? `${trimmed.slice(0, 157)}...` : trimmed;
54430
54444
  }
54431
- async function consumeProbeStream(response, timeoutMs) {
54445
+ async function consumeProbeStream(response, timeoutMs, startedAt) {
54432
54446
  const body = response.body;
54433
54447
  if (!body) {
54434
54448
  return { state: "error", errorMessage: "empty response body" };
@@ -54437,11 +54451,19 @@ async function consumeProbeStream(response, timeoutMs) {
54437
54451
  const decoder = new TextDecoder;
54438
54452
  let buffered = "";
54439
54453
  const deadline = Date.now() + timeoutMs;
54454
+ let ttftMs;
54455
+ let sawContent = false;
54456
+ let textChars = 0;
54457
+ let reportedTokens;
54458
+ let errorVerdict = null;
54459
+ let completed = false;
54440
54460
  try {
54441
54461
  while (Date.now() < deadline) {
54442
54462
  const { value, done } = await reader.read();
54443
- if (done)
54463
+ if (done) {
54464
+ completed = true;
54444
54465
  break;
54466
+ }
54445
54467
  buffered += decoder.decode(value, { stream: true });
54446
54468
  const events = buffered.split(`
54447
54469
 
@@ -54449,29 +54471,71 @@ async function consumeProbeStream(response, timeoutMs) {
54449
54471
  buffered = events.pop() ?? "";
54450
54472
  for (const event of events) {
54451
54473
  const verdict = interpretSseEvent(event);
54452
- if (verdict === "live") {
54453
- try {
54454
- await reader.cancel();
54455
- } catch {}
54456
- return { state: "live" };
54474
+ if (verdict && typeof verdict === "object" && verdict.state !== "live") {
54475
+ errorVerdict = verdict;
54476
+ break;
54457
54477
  }
54458
- if (verdict && verdict.state !== "live") {
54459
- try {
54460
- await reader.cancel();
54461
- } catch {}
54462
- return verdict;
54478
+ const acct = accountStreamEvent(event);
54479
+ if (acct.contentDelta) {
54480
+ if (ttftMs === undefined)
54481
+ ttftMs = Date.now() - startedAt;
54482
+ sawContent = true;
54463
54483
  }
54484
+ if (acct.textChars)
54485
+ textChars += acct.textChars;
54486
+ if (acct.outputTokens !== undefined)
54487
+ reportedTokens = acct.outputTokens;
54464
54488
  }
54489
+ if (errorVerdict)
54490
+ break;
54465
54491
  }
54466
54492
  } catch (e) {
54467
- return {
54468
- state: "network-error",
54469
- errorMessage: String(e?.message || e)
54470
- };
54493
+ if (!sawContent) {
54494
+ return { state: "network-error", errorMessage: String(e?.message || e) };
54495
+ }
54496
+ } finally {
54497
+ try {
54498
+ await reader.cancel();
54499
+ } catch {}
54500
+ }
54501
+ if (errorVerdict)
54502
+ return errorVerdict;
54503
+ if (sawContent) {
54504
+ const tokens = reportedTokens ?? Math.max(1, Math.round(textChars / 4));
54505
+ return { state: "live", ttftMs, tokens, truncated: !completed };
54471
54506
  }
54507
+ return { state: "error", errorMessage: "stream ended without content" };
54508
+ }
54509
+ function accountStreamEvent(rawEvent) {
54510
+ let dataPayload = "";
54511
+ for (const line of rawEvent.split(`
54512
+ `)) {
54513
+ if (line.startsWith("data:"))
54514
+ dataPayload += line.slice(5).trim();
54515
+ }
54516
+ if (!dataPayload || dataPayload === "[DONE]") {
54517
+ return { contentDelta: false, textChars: 0 };
54518
+ }
54519
+ let parsed;
54520
+ try {
54521
+ parsed = JSON.parse(dataPayload);
54522
+ } catch {
54523
+ return { contentDelta: false, textChars: 0 };
54524
+ }
54525
+ let textChars = 0;
54526
+ let contentDelta = false;
54527
+ const text = parsed?.delta?.text ?? (Array.isArray(parsed?.choices) ? parsed.choices[0]?.delta?.content : undefined);
54528
+ if (typeof text === "string" && text.length > 0) {
54529
+ contentDelta = true;
54530
+ textChars = text.length;
54531
+ } else if (parsed?.type === "content_block_delta" || parsed?.type === "content_block_start") {
54532
+ contentDelta = true;
54533
+ }
54534
+ const outputTokens = parsed?.usage?.output_tokens ?? parsed?.message?.usage?.output_tokens ?? parsed?.usage?.completion_tokens;
54472
54535
  return {
54473
- state: "error",
54474
- errorMessage: "stream ended without content"
54536
+ contentDelta,
54537
+ textChars,
54538
+ outputTokens: typeof outputTokens === "number" ? outputTokens : undefined
54475
54539
  };
54476
54540
  }
54477
54541
  function interpretSseEvent(rawEvent) {
@@ -54562,13 +54626,15 @@ function isReadyState(state) {
54562
54626
  function isFailureState(state) {
54563
54627
  return state === "auth-failed" || state === "model-not-found" || state === "rate-limited" || state === "server-error" || state === "timeout" || state === "network-error" || state === "error";
54564
54628
  }
54565
- var OAUTH_PROVIDERS2, PROBE_PROMPT = "ping", PROBE_MAX_TOKENS = 1;
54629
+ var STREAM_MS_FLOOR = 50, OAUTH_PROVIDERS2, PROBE_PROMPT = "Count from one to twenty in words, one per line.", PROBE_MAX_TOKENS = 64;
54566
54630
  var init_probe_live = __esm(() => {
54567
54631
  OAUTH_PROVIDERS2 = new Set(["vertex", "gemini-codeassist"]);
54568
54632
  });
54569
54633
 
54570
54634
  // src/providers/probe-runner.ts
54571
54635
  function pinProbeModelSpec(link) {
54636
+ if (link.provider === "native-anthropic")
54637
+ return link.modelSpec;
54572
54638
  return link.modelSpec.includes("@") ? link.modelSpec : `${link.provider}@${link.modelSpec}`;
54573
54639
  }
54574
54640
  function probeProviderRoute(proxyUrl, link, timeoutMs) {
@@ -54583,7 +54649,108 @@ var init_probe_runner = __esm(() => {
54583
54649
 
54584
54650
  // src/tui/theme.ts
54585
54651
  import { createTextAttributes } from "@opentui/core";
54586
- var C, bold, A;
54652
+ function latencyBucket(ms) {
54653
+ const v = Math.max(0, ms);
54654
+ for (const b of LATENCY_BUCKETS) {
54655
+ if (v < b.maxMs)
54656
+ return b;
54657
+ }
54658
+ return LATENCY_BUCKETS[LATENCY_BUCKETS.length - 1];
54659
+ }
54660
+ function formatLatency(ms) {
54661
+ if (ms < 1000)
54662
+ return `${Math.round(ms)}ms`;
54663
+ return `${(ms / 1000).toFixed(2)}s`;
54664
+ }
54665
+ function latencyBg(ms) {
54666
+ return latencyBucket(ms).hex;
54667
+ }
54668
+ function latencyBgAnsi(ms) {
54669
+ const hex3 = latencyBucket(ms).hex;
54670
+ const r = parseInt(hex3.slice(1, 3), 16);
54671
+ const g = parseInt(hex3.slice(3, 5), 16);
54672
+ const b = parseInt(hex3.slice(5, 7), 16);
54673
+ return `\x1B[48;2;${r};${g};${b}m`;
54674
+ }
54675
+ function hexToAnsiBg(hex3) {
54676
+ const r = parseInt(hex3.slice(1, 3), 16);
54677
+ const g = parseInt(hex3.slice(3, 5), 16);
54678
+ const b = parseInt(hex3.slice(5, 7), 16);
54679
+ return `\x1B[48;2;${r};${g};${b}m`;
54680
+ }
54681
+ function hexToAnsiFg(hex3) {
54682
+ const r = parseInt(hex3.slice(1, 3), 16);
54683
+ const g = parseInt(hex3.slice(3, 5), 16);
54684
+ const b = parseInt(hex3.slice(5, 7), 16);
54685
+ return `\x1B[38;2;${r};${g};${b}m`;
54686
+ }
54687
+ function throughputFg(tokensPerSec) {
54688
+ if (tokensPerSec >= 100)
54689
+ return C.brightGreen;
54690
+ if (tokensPerSec >= 40)
54691
+ return C.orange;
54692
+ return "#9e2b2b";
54693
+ }
54694
+ function timelineBarCells(totalMs, maxTotalMs, barWidth) {
54695
+ if (barWidth <= 0)
54696
+ return 0;
54697
+ const denom = maxTotalMs > 0 ? maxTotalMs : 1;
54698
+ const raw2 = Math.round(barWidth * Math.max(0, totalMs) / denom);
54699
+ return Math.min(barWidth, Math.max(1, raw2));
54700
+ }
54701
+ function splitStageCells(ttfbMs, ttftMs, totalMs, barCells) {
54702
+ const net = Math.max(0, ttfbMs);
54703
+ const srv = Math.max(0, ttftMs - ttfbMs);
54704
+ const str = Math.max(0, totalMs - ttftMs);
54705
+ const durations = [net, srv, str];
54706
+ const sum = net + srv + str;
54707
+ if (barCells <= 0)
54708
+ return { network: 0, server: 0, streaming: 0 };
54709
+ if (sum <= 0) {
54710
+ return { network: barCells, server: 0, streaming: 0 };
54711
+ }
54712
+ const exact = durations.map((d) => barCells * d / sum);
54713
+ const floors = exact.map((e) => Math.floor(e));
54714
+ let used = floors[0] + floors[1] + floors[2];
54715
+ let leftover = barCells - used;
54716
+ const remainders = exact.map((e, i) => ({ i, rem: e - Math.floor(e) })).sort((a, b) => b.rem - a.rem);
54717
+ for (let k = 0;k < leftover; k++) {
54718
+ floors[remainders[k % 3].i] += 1;
54719
+ }
54720
+ if (barCells >= 3) {
54721
+ for (let i = 0;i < 3; i++) {
54722
+ if (durations[i] > 0 && floors[i] === 0) {
54723
+ let donor = 0;
54724
+ for (let j = 1;j < 3; j++) {
54725
+ if (floors[j] > floors[donor])
54726
+ donor = j;
54727
+ }
54728
+ if (floors[donor] > 1) {
54729
+ floors[donor] -= 1;
54730
+ floors[i] += 1;
54731
+ }
54732
+ }
54733
+ }
54734
+ }
54735
+ used = floors[0] + floors[1] + floors[2];
54736
+ leftover = barCells - used;
54737
+ if (leftover !== 0) {
54738
+ let big = 0;
54739
+ for (let j = 1;j < 3; j++)
54740
+ if (durations[j] > durations[big])
54741
+ big = j;
54742
+ floors[big] = Math.max(0, floors[big] + leftover);
54743
+ }
54744
+ return { network: floors[0], server: floors[1], streaming: floors[2] };
54745
+ }
54746
+ function tokBarCells(tokensPerSec, maxTokPerSec, tokWidth) {
54747
+ if (tokWidth <= 0)
54748
+ return 0;
54749
+ const denom = maxTokPerSec > 0 ? maxTokPerSec : 1;
54750
+ const raw2 = Math.round(tokWidth * Math.max(0, tokensPerSec) / denom);
54751
+ return Math.min(tokWidth, Math.max(0, raw2));
54752
+ }
54753
+ var C, bold, A, LATENCY_BUCKETS, latencyFg = "#ffffff", LATENCY_FG_ANSI = "\x1B[38;2;255;255;255m", ANSI_RESET = "\x1B[0m", STAGE_BG, STAGE_FG, STAGE_BG_ANSI;
54587
54754
  var init_theme2 = __esm(() => {
54588
54755
  C = {
54589
54756
  bg: "#000000",
@@ -54610,17 +54777,42 @@ var init_theme2 = __esm(() => {
54610
54777
  tabActiveFg: "#ffffff",
54611
54778
  tabInactiveFg: "#0088ff",
54612
54779
  pillKeyBg: "#2d6e3e",
54613
- pillOauthBg: "#1f6d75"
54780
+ pillOauthBg: "#1f6d75",
54781
+ chipKeyBg: "#3a3a3a",
54782
+ chipLabelBg: "#222222"
54614
54783
  };
54615
54784
  bold = createTextAttributes({ bold: true });
54616
54785
  A = {
54617
54786
  bold,
54618
54787
  boldIf: (enabled) => enabled ? bold : undefined
54619
54788
  };
54789
+ LATENCY_BUCKETS = [
54790
+ { maxMs: 500, hex: "#1f8f3b" },
54791
+ { maxMs: 1000, hex: "#2d6e3e" },
54792
+ { maxMs: 3000, hex: "#8a7d1e" },
54793
+ { maxMs: 6000, hex: "#b5651d" },
54794
+ { maxMs: Infinity, hex: "#9e2b2b" }
54795
+ ];
54796
+ STAGE_BG = {
54797
+ network: "#00b3c4",
54798
+ server: "#2563ff",
54799
+ streaming: "#ffcc00"
54800
+ };
54801
+ STAGE_FG = {
54802
+ network: C.cyan,
54803
+ server: C.blue,
54804
+ streaming: C.yellow
54805
+ };
54806
+ STAGE_BG_ANSI = {
54807
+ network: hexToAnsiBg(STAGE_BG.network),
54808
+ server: hexToAnsiBg(STAGE_BG.server),
54809
+ streaming: hexToAnsiBg(STAGE_BG.streaming)
54810
+ };
54620
54811
  });
54621
54812
 
54622
54813
  // src/probe/probe-tui-app.tsx
54623
- import { useEffect as useEffect2, useState as useState2 } from "react";
54814
+ import { useEffect as useEffect2, useRef as useRef2, useState as useState2 } from "react";
54815
+ import { useKeyboard, useTerminalDimensions } from "@opentui/react";
54624
54816
  import { jsxDEV, Fragment } from "@opentui/react/jsx-dev-runtime";
54625
54817
 
54626
54818
  class ProbeStore {
@@ -54637,6 +54829,12 @@ class ProbeStore {
54637
54829
  for (const fn of this.listeners)
54638
54830
  fn();
54639
54831
  }
54832
+ setResults(results) {
54833
+ this.setState((prev) => ({ ...prev, results, phase: "done" }));
54834
+ }
54835
+ setActiveTab(tab) {
54836
+ this.setState((prev) => ({ ...prev, activeTab: tab }));
54837
+ }
54640
54838
  subscribe(fn) {
54641
54839
  this.listeners.add(fn);
54642
54840
  return () => {
@@ -54659,6 +54857,61 @@ function useAnimationFrame(active) {
54659
54857
  }, [active]);
54660
54858
  return frame;
54661
54859
  }
54860
+ function deriveLayout(width) {
54861
+ if (width < 60) {
54862
+ return { barWidth: 0, tokWidth: 0, showBreakdown: false, pillFallback: true };
54863
+ }
54864
+ if (width < 80) {
54865
+ return {
54866
+ barWidth: TIMELINE_BAR_NARROW,
54867
+ tokWidth: 0,
54868
+ showBreakdown: false,
54869
+ pillFallback: false
54870
+ };
54871
+ }
54872
+ if (width < 100) {
54873
+ return {
54874
+ barWidth: TIMELINE_BAR_FULL,
54875
+ tokWidth: 0,
54876
+ showBreakdown: true,
54877
+ pillFallback: false
54878
+ };
54879
+ }
54880
+ return {
54881
+ barWidth: TIMELINE_BAR_FULL,
54882
+ tokWidth: TOK_BAR_FULL,
54883
+ showBreakdown: true,
54884
+ pillFallback: false
54885
+ };
54886
+ }
54887
+ function computeRowWidth(layout, maxNameLen) {
54888
+ let w = 4 + 5 + 2 + maxNameLen + 2;
54889
+ if (layout.pillFallback) {
54890
+ w += TOTAL_COL + 2 + 25;
54891
+ return w;
54892
+ }
54893
+ w += layout.barWidth + 2 + TOTAL_COL;
54894
+ if (layout.showBreakdown) {
54895
+ w += BREAKDOWN_COL;
54896
+ } else {
54897
+ w += 2;
54898
+ }
54899
+ if (layout.tokWidth > 0) {
54900
+ w += layout.tokWidth + 1;
54901
+ }
54902
+ w += TOK_VALUE_COL;
54903
+ return w;
54904
+ }
54905
+ function padStartSafe(s, n) {
54906
+ if (s.length >= n)
54907
+ return s.slice(s.length - n);
54908
+ return " ".repeat(n - s.length) + s;
54909
+ }
54910
+ function breakdownNum(ms) {
54911
+ if (ms >= 1000)
54912
+ return formatLatency(ms);
54913
+ return `${Math.round(Math.max(0, ms))}`;
54914
+ }
54662
54915
  function formatElapsed(ms) {
54663
54916
  const seconds = Math.floor(ms / 1000);
54664
54917
  const mins = Math.floor(seconds / 60);
@@ -54743,7 +54996,7 @@ function Banner() {
54743
54996
  ]
54744
54997
  }, undefined, true, undefined, this);
54745
54998
  }
54746
- function StepIndicator({ step }) {
54999
+ function StepLine({ steps }) {
54747
55000
  const iconMap = {
54748
55001
  pending: "\u25CB",
54749
55002
  running: "\u25CC",
@@ -54756,103 +55009,267 @@ function StepIndicator({ step }) {
54756
55009
  done: C.green,
54757
55010
  error: C.red
54758
55011
  };
55012
+ if (steps.length === 0)
55013
+ return /* @__PURE__ */ jsxDEV("text", {
55014
+ children: " "
55015
+ }, undefined, false, undefined, this);
55016
+ const active = steps.find((s) => s.status === "running" || s.status === "error") ?? steps[steps.length - 1];
54759
55017
  return /* @__PURE__ */ jsxDEV("text", {
54760
55018
  children: [
54761
55019
  /* @__PURE__ */ jsxDEV("span", {
54762
55020
  children: " "
54763
55021
  }, undefined, false, undefined, this),
54764
- /* @__PURE__ */ jsxDEV("span", {
54765
- fg: colorMap[step.status],
55022
+ steps.map((s, i) => /* @__PURE__ */ jsxDEV("span", {
55023
+ fg: colorMap[s.status],
54766
55024
  children: [
54767
- iconMap[step.status],
54768
- " ",
54769
- step.name
55025
+ iconMap[s.status],
55026
+ i < steps.length - 1 ? " " : ""
54770
55027
  ]
54771
- }, undefined, true, undefined, this)
55028
+ }, `${s.name}-${i}`, true, undefined, this)),
55029
+ /* @__PURE__ */ jsxDEV("span", {
55030
+ fg: C.dim,
55031
+ children: " "
55032
+ }, undefined, false, undefined, this),
55033
+ /* @__PURE__ */ jsxDEV("span", {
55034
+ fg: colorMap[active.status],
55035
+ children: active.name
55036
+ }, undefined, false, undefined, this)
54772
55037
  ]
54773
55038
  }, undefined, true, undefined, this);
54774
55039
  }
54775
55040
  function ProgressBar({
54776
55041
  link,
54777
55042
  animFrame,
54778
- maxNameLen
55043
+ maxNameLen,
55044
+ layout,
55045
+ maxTotalMs,
55046
+ maxTokPerSec,
55047
+ isRunFastest
54779
55048
  }) {
54780
55049
  const elapsedMs = link.status === "waiting" ? 0 : link.startTime ? (link.endTime ?? Date.now()) - link.startTime : 0;
54781
55050
  const elapsed = formatElapsed(elapsedMs);
54782
- let bar;
54783
- let barColor;
54784
- let statusText;
54785
- let statusColor;
54786
- switch (link.status) {
54787
- case "waiting":
54788
- bar = "\u2591".repeat(BAR_WIDTH);
54789
- barColor = C.dim;
54790
- statusText = "\u23F3 waiting...";
54791
- statusColor = C.dim;
54792
- break;
54793
- case "probing": {
54794
- let animated = "";
54795
- for (let i = 0;i < BAR_WIDTH; i++) {
54796
- animated += ANIM_FRAMES[(animFrame + i) % ANIM_FRAMES.length];
54797
- }
54798
- bar = animated;
54799
- barColor = C.cyan;
54800
- statusText = "probing...";
54801
- statusColor = C.cyan;
54802
- break;
54803
- }
54804
- case "live": {
54805
- const latency = link.endTime && link.startTime ? link.endTime - link.startTime : 0;
54806
- bar = "\u2588".repeat(BAR_WIDTH);
54807
- barColor = C.green;
54808
- statusText = `\u2713 live \xB7 ${latency}ms`;
54809
- statusColor = C.green;
54810
- break;
54811
- }
54812
- case "failed":
54813
- bar = "\u2717".repeat(BAR_WIDTH);
54814
- barColor = C.red;
54815
- statusText = `\u2717 ${stripAnsi2(link.error || "failed")}`;
54816
- statusColor = C.red;
54817
- break;
54818
- }
54819
55051
  const displayName = padEndSafe(link.displayName, maxNameLen);
54820
- return /* @__PURE__ */ jsxDEV("text", {
55052
+ const prefix = /* @__PURE__ */ jsxDEV(Fragment, {
54821
55053
  children: [
54822
55054
  /* @__PURE__ */ jsxDEV("span", {
54823
55055
  fg: C.dim,
54824
55056
  children: ` ${elapsed} `
54825
55057
  }, undefined, false, undefined, this),
54826
55058
  /* @__PURE__ */ jsxDEV("span", {
54827
- fg: barColor,
54828
- children: bar
55059
+ fg: C.fg,
55060
+ children: displayName
54829
55061
  }, undefined, false, undefined, this),
54830
55062
  /* @__PURE__ */ jsxDEV("span", {
54831
55063
  fg: C.dim,
54832
55064
  children: " "
55065
+ }, undefined, false, undefined, this)
55066
+ ]
55067
+ }, undefined, true, undefined, this);
55068
+ if (layout.pillFallback) {
55069
+ if (link.status === "live") {
55070
+ const latency = link.timing?.totalMs ?? elapsedMs;
55071
+ return /* @__PURE__ */ jsxDEV("text", {
55072
+ children: [
55073
+ prefix,
55074
+ /* @__PURE__ */ jsxDEV("span", {
55075
+ fg: C.green,
55076
+ children: "\u2713 live \xB7 "
55077
+ }, undefined, false, undefined, this),
55078
+ /* @__PURE__ */ jsxDEV("span", {
55079
+ fg: latencyFg,
55080
+ bg: latencyBg(latency),
55081
+ children: ` ${formatLatency(latency)} `
55082
+ }, undefined, false, undefined, this)
55083
+ ]
55084
+ }, undefined, true, undefined, this);
55085
+ }
55086
+ return /* @__PURE__ */ jsxDEV("text", {
55087
+ children: [
55088
+ prefix,
55089
+ renderNonLiveStatus(link, false)
55090
+ ]
55091
+ }, undefined, true, undefined, this);
55092
+ }
55093
+ if (link.status !== "live" || !link.timing) {
55094
+ return /* @__PURE__ */ jsxDEV("text", {
55095
+ children: [
55096
+ prefix,
55097
+ renderTimelineSlot(link, animFrame, layout.barWidth),
55098
+ /* @__PURE__ */ jsxDEV("span", {
55099
+ fg: C.dim,
55100
+ children: " "
55101
+ }, undefined, false, undefined, this),
55102
+ renderNonLiveStatus(link, true)
55103
+ ]
55104
+ }, undefined, true, undefined, this);
55105
+ }
55106
+ const t = link.timing;
55107
+ const barCells = timelineBarCells(t.totalMs, maxTotalMs, layout.barWidth);
55108
+ const stages = splitStageCells(t.ttfbMs, t.ttftMs, t.totalMs, barCells);
55109
+ const trackCells = Math.max(0, layout.barWidth - barCells);
55110
+ const netMs = Math.max(0, t.ttfbMs);
55111
+ const srvMs = Math.max(0, t.ttftMs - t.ttfbMs);
55112
+ const strMs = Math.max(0, t.totalMs - t.ttftMs);
55113
+ const tokColor = throughputFg(t.tokensPerSec);
55114
+ const tokCells = layout.tokWidth > 0 ? tokBarCells(t.tokensPerSec, maxTokPerSec, layout.tokWidth) : 0;
55115
+ const tokTrack = Math.max(0, layout.tokWidth - tokCells);
55116
+ const tokValue = padStartSafe(`${Math.round(t.tokensPerSec)} t/s`, TOK_VALUE_COL);
55117
+ const netStr = padStartSafe(breakdownNum(netMs), STAGE_NUM_W);
55118
+ const srvStr = padStartSafe(breakdownNum(srvMs), STAGE_NUM_W);
55119
+ const strStr = padStartSafe(breakdownNum(strMs), STAGE_NUM_W);
55120
+ return /* @__PURE__ */ jsxDEV("text", {
55121
+ children: [
55122
+ prefix,
55123
+ stages.network > 0 && /* @__PURE__ */ jsxDEV("span", {
55124
+ bg: STAGE_BG.network,
55125
+ children: " ".repeat(stages.network)
55126
+ }, undefined, false, undefined, this),
55127
+ stages.server > 0 && /* @__PURE__ */ jsxDEV("span", {
55128
+ bg: STAGE_BG.server,
55129
+ children: " ".repeat(stages.server)
55130
+ }, undefined, false, undefined, this),
55131
+ stages.streaming > 0 && /* @__PURE__ */ jsxDEV("span", {
55132
+ bg: STAGE_BG.streaming,
55133
+ children: " ".repeat(stages.streaming)
55134
+ }, undefined, false, undefined, this),
55135
+ trackCells > 0 && /* @__PURE__ */ jsxDEV("span", {
55136
+ fg: C.dim,
55137
+ children: TRACK_CHAR.repeat(trackCells)
54833
55138
  }, undefined, false, undefined, this),
54834
55139
  /* @__PURE__ */ jsxDEV("span", {
54835
- fg: C.fg,
54836
- children: displayName
55140
+ fg: C.dim,
55141
+ children: " "
54837
55142
  }, undefined, false, undefined, this),
54838
55143
  /* @__PURE__ */ jsxDEV("span", {
55144
+ fg: C.white,
55145
+ children: padStartSafe(formatLatency(t.totalMs), TOTAL_COL)
55146
+ }, undefined, false, undefined, this),
55147
+ layout.showBreakdown && /* @__PURE__ */ jsxDEV(Fragment, {
55148
+ children: [
55149
+ /* @__PURE__ */ jsxDEV("span", {
55150
+ fg: C.dim,
55151
+ children: " net "
55152
+ }, undefined, false, undefined, this),
55153
+ /* @__PURE__ */ jsxDEV("span", {
55154
+ fg: STAGE_FG.network,
55155
+ children: netStr
55156
+ }, undefined, false, undefined, this),
55157
+ /* @__PURE__ */ jsxDEV("span", {
55158
+ fg: C.dim,
55159
+ children: " srv "
55160
+ }, undefined, false, undefined, this),
55161
+ /* @__PURE__ */ jsxDEV("span", {
55162
+ fg: STAGE_FG.server,
55163
+ children: srvStr
55164
+ }, undefined, false, undefined, this),
55165
+ /* @__PURE__ */ jsxDEV("span", {
55166
+ fg: C.dim,
55167
+ children: " str "
55168
+ }, undefined, false, undefined, this),
55169
+ /* @__PURE__ */ jsxDEV("span", {
55170
+ fg: STAGE_FG.streaming,
55171
+ children: strStr
55172
+ }, undefined, false, undefined, this)
55173
+ ]
55174
+ }, undefined, true, undefined, this),
55175
+ layout.tokWidth > 0 && /* @__PURE__ */ jsxDEV(Fragment, {
55176
+ children: [
55177
+ /* @__PURE__ */ jsxDEV("span", {
55178
+ fg: C.dim,
55179
+ children: " "
55180
+ }, undefined, false, undefined, this),
55181
+ tokCells > 0 && /* @__PURE__ */ jsxDEV("span", {
55182
+ fg: tokColor,
55183
+ children: BAR_FILL.repeat(tokCells)
55184
+ }, undefined, false, undefined, this),
55185
+ tokTrack > 0 && /* @__PURE__ */ jsxDEV("span", {
55186
+ fg: C.dim,
55187
+ children: TRACK_CHAR.repeat(tokTrack)
55188
+ }, undefined, false, undefined, this),
55189
+ /* @__PURE__ */ jsxDEV("span", {
55190
+ fg: C.dim,
55191
+ children: " "
55192
+ }, undefined, false, undefined, this)
55193
+ ]
55194
+ }, undefined, true, undefined, this),
55195
+ layout.tokWidth === 0 && /* @__PURE__ */ jsxDEV("span", {
54839
55196
  fg: C.dim,
54840
55197
  children: " "
54841
55198
  }, undefined, false, undefined, this),
54842
55199
  /* @__PURE__ */ jsxDEV("span", {
54843
- fg: statusColor,
54844
- children: statusText
55200
+ fg: tokColor,
55201
+ children: tokValue
55202
+ }, undefined, false, undefined, this),
55203
+ isRunFastest && /* @__PURE__ */ jsxDEV("span", {
55204
+ fg: C.brightGreen,
55205
+ children: " \u25CF"
54845
55206
  }, undefined, false, undefined, this)
54846
55207
  ]
54847
55208
  }, undefined, true, undefined, this);
54848
55209
  }
55210
+ function renderTimelineSlot(link, animFrame, barWidth) {
55211
+ if (barWidth <= 0)
55212
+ return null;
55213
+ switch (link.status) {
55214
+ case "probing": {
55215
+ let animated = "";
55216
+ for (let i = 0;i < barWidth; i++) {
55217
+ animated += ANIM_FRAMES[(animFrame + i) % ANIM_FRAMES.length];
55218
+ }
55219
+ return /* @__PURE__ */ jsxDEV("span", {
55220
+ fg: C.cyan,
55221
+ children: animated
55222
+ }, undefined, false, undefined, this);
55223
+ }
55224
+ case "failed":
55225
+ return /* @__PURE__ */ jsxDEV("span", {
55226
+ fg: C.red,
55227
+ children: padEndSafe(`\u2717 ${stripAnsi2(link.error || "failed")}`, barWidth)
55228
+ }, undefined, false, undefined, this);
55229
+ case "waiting":
55230
+ default:
55231
+ return /* @__PURE__ */ jsxDEV("span", {
55232
+ fg: C.dim,
55233
+ children: "\u2591".repeat(barWidth)
55234
+ }, undefined, false, undefined, this);
55235
+ }
55236
+ }
55237
+ function renderNonLiveStatus(link, hasSlot) {
55238
+ switch (link.status) {
55239
+ case "probing": {
55240
+ const elapsedMs = link.startTime ? Date.now() - link.startTime : 0;
55241
+ return /* @__PURE__ */ jsxDEV("span", {
55242
+ fg: C.cyan,
55243
+ children: `\u23F3 probing ${formatElapsed(elapsedMs)}`
55244
+ }, undefined, false, undefined, this);
55245
+ }
55246
+ case "failed":
55247
+ return hasSlot ? /* @__PURE__ */ jsxDEV("span", {
55248
+ fg: C.red,
55249
+ children: "\u2717"
55250
+ }, undefined, false, undefined, this) : /* @__PURE__ */ jsxDEV("span", {
55251
+ fg: C.red,
55252
+ children: `\u2717 ${stripAnsi2(link.error || "failed")}`
55253
+ }, undefined, false, undefined, this);
55254
+ case "waiting":
55255
+ default:
55256
+ return /* @__PURE__ */ jsxDEV("span", {
55257
+ fg: C.dim,
55258
+ children: "\u23F3 waiting\u2026"
55259
+ }, undefined, false, undefined, this);
55260
+ }
55261
+ }
54849
55262
  function ModelGroup({
54850
55263
  model,
54851
55264
  links,
54852
55265
  animFrame,
54853
55266
  maxNameLen,
54854
55267
  rowWidth,
54855
- isLast
55268
+ isLast,
55269
+ layout,
55270
+ maxTotalMs,
55271
+ maxTokPerSec,
55272
+ fastestLinkId
54856
55273
  }) {
54857
55274
  const headerWidth = rowWidth - 2;
54858
55275
  const totalPad = Math.max(0, headerWidth - model.length);
@@ -54884,14 +55301,798 @@ function ModelGroup({
54884
55301
  links.map((link) => /* @__PURE__ */ jsxDEV(ProgressBar, {
54885
55302
  link,
54886
55303
  animFrame,
54887
- maxNameLen
55304
+ maxNameLen,
55305
+ layout,
55306
+ maxTotalMs,
55307
+ maxTokPerSec,
55308
+ isRunFastest: fastestLinkId === link.id
54888
55309
  }, link.id, false, undefined, this))
54889
55310
  ]
54890
55311
  }, undefined, true, undefined, this);
54891
55312
  }
54892
- function ProbeApp({ store }) {
55313
+ function TabBar({ activeTab }) {
55314
+ const tab = (label, active) => /* @__PURE__ */ jsxDEV("span", {
55315
+ bg: active ? C.tabActiveBg : C.tabInactiveBg,
55316
+ fg: active ? C.tabActiveFg : C.tabInactiveFg,
55317
+ attributes: active ? A.bold : undefined,
55318
+ children: ` ${label} `
55319
+ }, undefined, false, undefined, this);
55320
+ return /* @__PURE__ */ jsxDEV("box", {
55321
+ flexDirection: "column",
55322
+ paddingTop: 1,
55323
+ paddingBottom: 1,
55324
+ children: /* @__PURE__ */ jsxDEV("text", {
55325
+ children: [
55326
+ /* @__PURE__ */ jsxDEV("span", {
55327
+ fg: C.dim,
55328
+ children: " "
55329
+ }, undefined, false, undefined, this),
55330
+ tab("1 Summary", activeTab === "summary"),
55331
+ /* @__PURE__ */ jsxDEV("span", {
55332
+ children: " "
55333
+ }, undefined, false, undefined, this),
55334
+ tab("2 Leaderboard", activeTab === "leaderboard"),
55335
+ /* @__PURE__ */ jsxDEV("span", {
55336
+ children: " "
55337
+ }, undefined, false, undefined, this),
55338
+ tab("3 Details", activeTab === "details")
55339
+ ]
55340
+ }, undefined, true, undefined, this)
55341
+ }, undefined, false, undefined, this);
55342
+ }
55343
+ function Legend({ rowWidth }) {
55344
+ const ruleWidth = Math.max(1, Math.min(rowWidth, 120));
55345
+ return /* @__PURE__ */ jsxDEV("box", {
55346
+ flexDirection: "column",
55347
+ children: [
55348
+ /* @__PURE__ */ jsxDEV("text", {
55349
+ children: [
55350
+ /* @__PURE__ */ jsxDEV("span", {
55351
+ bg: STAGE_BG.network,
55352
+ children: " "
55353
+ }, undefined, false, undefined, this),
55354
+ /* @__PURE__ */ jsxDEV("span", {
55355
+ fg: STAGE_FG.network,
55356
+ children: " net "
55357
+ }, undefined, false, undefined, this),
55358
+ /* @__PURE__ */ jsxDEV("span", {
55359
+ bg: STAGE_BG.server,
55360
+ children: " "
55361
+ }, undefined, false, undefined, this),
55362
+ /* @__PURE__ */ jsxDEV("span", {
55363
+ fg: STAGE_FG.server,
55364
+ children: " srv "
55365
+ }, undefined, false, undefined, this),
55366
+ /* @__PURE__ */ jsxDEV("span", {
55367
+ bg: STAGE_BG.streaming,
55368
+ children: " "
55369
+ }, undefined, false, undefined, this),
55370
+ /* @__PURE__ */ jsxDEV("span", {
55371
+ fg: STAGE_FG.streaming,
55372
+ children: " str "
55373
+ }, undefined, false, undefined, this),
55374
+ /* @__PURE__ */ jsxDEV("span", {
55375
+ fg: C.dim,
55376
+ children: "\xB7\xB7 idle \xB7 bar = total time (shared scale) \xB7 tok/s color = absolute"
55377
+ }, undefined, false, undefined, this)
55378
+ ]
55379
+ }, undefined, true, undefined, this),
55380
+ /* @__PURE__ */ jsxDEV("text", {
55381
+ children: /* @__PURE__ */ jsxDEV("span", {
55382
+ fg: C.dim,
55383
+ children: " " + "\u2500".repeat(ruleWidth)
55384
+ }, undefined, false, undefined, this)
55385
+ }, undefined, false, undefined, this)
55386
+ ]
55387
+ }, undefined, true, undefined, this);
55388
+ }
55389
+ function formatContextWindow(ctx) {
55390
+ if (ctx <= 0)
55391
+ return "0";
55392
+ if (ctx >= 1e6)
55393
+ return `${(ctx / 1e6).toFixed(1)}M`;
55394
+ return `${Math.round(ctx / 1000)}K`;
55395
+ }
55396
+ function ruleKeyForModel(model) {
55397
+ const at = model.indexOf("@");
55398
+ return at >= 0 ? model.slice(at + 1) : model;
55399
+ }
55400
+ function detailRowWidth(provW, layout) {
55401
+ let w = 2 + 1 + 1 + provW + 2 + 1 + 2;
55402
+ w += layout.barWidth + 2 + TOTAL_COL;
55403
+ if (layout.showBreakdown)
55404
+ w += BREAKDOWN_COL;
55405
+ else
55406
+ w += 2;
55407
+ if (layout.tokWidth > 0)
55408
+ w += layout.tokWidth + 1;
55409
+ w += TOK_VALUE_COL;
55410
+ return w;
55411
+ }
55412
+ function shortFailureReason(probe, hasCreds) {
55413
+ if (!probe)
55414
+ return hasCreds ? "not probed" : "key missing";
55415
+ if (probe.state === "key-missing")
55416
+ return "key missing";
55417
+ return stripAnsi2(describeProbeState(probe));
55418
+ }
55419
+ function DetailLinkRow({
55420
+ link,
55421
+ isWinner,
55422
+ provW,
55423
+ layout,
55424
+ maxTotalMs,
55425
+ maxTokPerSec
55426
+ }) {
55427
+ const probe = link.probe;
55428
+ const isLive = probe?.state === "live" && !!probe.timing;
55429
+ const winnerMark = isWinner ? /* @__PURE__ */ jsxDEV("span", {
55430
+ fg: C.brightGreen,
55431
+ children: "\u25CF"
55432
+ }, undefined, false, undefined, this) : /* @__PURE__ */ jsxDEV("span", {
55433
+ children: " "
55434
+ }, undefined, false, undefined, this);
55435
+ const provider = /* @__PURE__ */ jsxDEV("span", {
55436
+ fg: C.fg,
55437
+ children: padEndSafe(link.displayName, provW)
55438
+ }, undefined, false, undefined, this);
55439
+ const lead = /* @__PURE__ */ jsxDEV(Fragment, {
55440
+ children: [
55441
+ /* @__PURE__ */ jsxDEV("span", {
55442
+ fg: C.dim,
55443
+ children: " "
55444
+ }, undefined, false, undefined, this),
55445
+ winnerMark,
55446
+ /* @__PURE__ */ jsxDEV("span", {
55447
+ children: " "
55448
+ }, undefined, false, undefined, this),
55449
+ provider,
55450
+ /* @__PURE__ */ jsxDEV("span", {
55451
+ children: " "
55452
+ }, undefined, false, undefined, this)
55453
+ ]
55454
+ }, undefined, true, undefined, this);
55455
+ if (!isLive || !probe?.timing) {
55456
+ return /* @__PURE__ */ jsxDEV("text", {
55457
+ children: [
55458
+ lead,
55459
+ /* @__PURE__ */ jsxDEV("span", {
55460
+ fg: C.red,
55461
+ children: "\u2717 "
55462
+ }, undefined, false, undefined, this),
55463
+ /* @__PURE__ */ jsxDEV("span", {
55464
+ fg: C.red,
55465
+ children: shortFailureReason(probe, link.hasCredentials)
55466
+ }, undefined, false, undefined, this)
55467
+ ]
55468
+ }, undefined, true, undefined, this);
55469
+ }
55470
+ const t = probe.timing;
55471
+ const barCells = timelineBarCells(t.totalMs, maxTotalMs, layout.barWidth);
55472
+ const stages = splitStageCells(t.ttfbMs, t.ttftMs, t.totalMs, barCells);
55473
+ const trackCells = Math.max(0, layout.barWidth - barCells);
55474
+ const netMs = Math.max(0, t.ttfbMs);
55475
+ const srvMs = Math.max(0, t.ttftMs - t.ttfbMs);
55476
+ const strMs = Math.max(0, t.totalMs - t.ttftMs);
55477
+ const netStr = padStartSafe(breakdownNum(netMs), STAGE_NUM_W);
55478
+ const srvStr = padStartSafe(breakdownNum(srvMs), STAGE_NUM_W);
55479
+ const strStr = padStartSafe(breakdownNum(strMs), STAGE_NUM_W);
55480
+ const tokColor = throughputFg(t.tokensPerSec);
55481
+ const tokCells = layout.tokWidth > 0 ? tokBarCells(t.tokensPerSec, maxTokPerSec, layout.tokWidth) : 0;
55482
+ const tokTrack = Math.max(0, layout.tokWidth - tokCells);
55483
+ const tokValue = padStartSafe(`${Math.round(t.tokensPerSec)} t/s`, TOK_VALUE_COL);
55484
+ return /* @__PURE__ */ jsxDEV("text", {
55485
+ children: [
55486
+ lead,
55487
+ /* @__PURE__ */ jsxDEV("span", {
55488
+ fg: C.green,
55489
+ children: "\u2713 "
55490
+ }, undefined, false, undefined, this),
55491
+ stages.network > 0 && /* @__PURE__ */ jsxDEV("span", {
55492
+ bg: STAGE_BG.network,
55493
+ children: " ".repeat(stages.network)
55494
+ }, undefined, false, undefined, this),
55495
+ stages.server > 0 && /* @__PURE__ */ jsxDEV("span", {
55496
+ bg: STAGE_BG.server,
55497
+ children: " ".repeat(stages.server)
55498
+ }, undefined, false, undefined, this),
55499
+ stages.streaming > 0 && /* @__PURE__ */ jsxDEV("span", {
55500
+ bg: STAGE_BG.streaming,
55501
+ children: " ".repeat(stages.streaming)
55502
+ }, undefined, false, undefined, this),
55503
+ trackCells > 0 && /* @__PURE__ */ jsxDEV("span", {
55504
+ fg: C.dim,
55505
+ children: TRACK_CHAR.repeat(trackCells)
55506
+ }, undefined, false, undefined, this),
55507
+ /* @__PURE__ */ jsxDEV("span", {
55508
+ fg: C.dim,
55509
+ children: " "
55510
+ }, undefined, false, undefined, this),
55511
+ /* @__PURE__ */ jsxDEV("span", {
55512
+ fg: C.white,
55513
+ children: padStartSafe(formatLatency(t.totalMs), TOTAL_COL)
55514
+ }, undefined, false, undefined, this),
55515
+ layout.showBreakdown && /* @__PURE__ */ jsxDEV(Fragment, {
55516
+ children: [
55517
+ /* @__PURE__ */ jsxDEV("span", {
55518
+ fg: C.dim,
55519
+ children: " net "
55520
+ }, undefined, false, undefined, this),
55521
+ /* @__PURE__ */ jsxDEV("span", {
55522
+ fg: STAGE_FG.network,
55523
+ children: netStr
55524
+ }, undefined, false, undefined, this),
55525
+ /* @__PURE__ */ jsxDEV("span", {
55526
+ fg: C.dim,
55527
+ children: " srv "
55528
+ }, undefined, false, undefined, this),
55529
+ /* @__PURE__ */ jsxDEV("span", {
55530
+ fg: STAGE_FG.server,
55531
+ children: srvStr
55532
+ }, undefined, false, undefined, this),
55533
+ /* @__PURE__ */ jsxDEV("span", {
55534
+ fg: C.dim,
55535
+ children: " str "
55536
+ }, undefined, false, undefined, this),
55537
+ /* @__PURE__ */ jsxDEV("span", {
55538
+ fg: STAGE_FG.streaming,
55539
+ children: strStr
55540
+ }, undefined, false, undefined, this)
55541
+ ]
55542
+ }, undefined, true, undefined, this),
55543
+ layout.tokWidth > 0 && /* @__PURE__ */ jsxDEV(Fragment, {
55544
+ children: [
55545
+ /* @__PURE__ */ jsxDEV("span", {
55546
+ fg: C.dim,
55547
+ children: " "
55548
+ }, undefined, false, undefined, this),
55549
+ tokCells > 0 && /* @__PURE__ */ jsxDEV("span", {
55550
+ fg: tokColor,
55551
+ children: BAR_FILL.repeat(tokCells)
55552
+ }, undefined, false, undefined, this),
55553
+ tokTrack > 0 && /* @__PURE__ */ jsxDEV("span", {
55554
+ fg: C.dim,
55555
+ children: TRACK_CHAR.repeat(tokTrack)
55556
+ }, undefined, false, undefined, this),
55557
+ /* @__PURE__ */ jsxDEV("span", {
55558
+ fg: C.dim,
55559
+ children: " "
55560
+ }, undefined, false, undefined, this)
55561
+ ]
55562
+ }, undefined, true, undefined, this),
55563
+ layout.tokWidth === 0 && /* @__PURE__ */ jsxDEV("span", {
55564
+ fg: C.dim,
55565
+ children: " "
55566
+ }, undefined, false, undefined, this),
55567
+ /* @__PURE__ */ jsxDEV("span", {
55568
+ fg: tokColor,
55569
+ children: tokValue
55570
+ }, undefined, false, undefined, this)
55571
+ ]
55572
+ }, undefined, true, undefined, this);
55573
+ }
55574
+ function DetailModel({
55575
+ result,
55576
+ provW,
55577
+ headerW,
55578
+ layout,
55579
+ maxTotalMs,
55580
+ maxTokPerSec,
55581
+ isLast
55582
+ }) {
55583
+ const winnerIdx = result.links.findIndex((l) => l.probe?.state === "live" && !!l.probe.timing);
55584
+ const winner = winnerIdx >= 0 ? result.links[winnerIdx] : undefined;
55585
+ const gap = Math.max(2, headerW - result.model.length - result.routingExplanation.length - 2);
55586
+ const wiring = result.wiring;
55587
+ const wireLine = winner && wiring ? `wire (${winner.displayName}): ${wiring.effectiveStreamFormat} \xB7 ${wiring.modelTranslator} \xB7 ${formatContextWindow(wiring.contextWindow)} ctx` : "wire: \u2014";
55588
+ const routeChain = result.links.map((l) => l.displayName).join(" \u2192 ");
55589
+ const liveLinks = result.links.filter((l) => l.probe?.state === "live" && !!l.probe.timing);
55590
+ let fastestByLatency;
55591
+ let fastestByTput;
55592
+ for (const l of liveLinks) {
55593
+ const t = l.probe.timing;
55594
+ if (!fastestByLatency || t.totalMs < fastestByLatency.probe.timing.totalMs) {
55595
+ fastestByLatency = l;
55596
+ }
55597
+ if (!fastestByTput || t.tokensPerSec > fastestByTput.probe.timing.tokensPerSec) {
55598
+ fastestByTput = l;
55599
+ }
55600
+ }
55601
+ const winnerT = winner?.probe?.timing;
55602
+ const candidates = [];
55603
+ if (winner && winnerT) {
55604
+ if (fastestByLatency && fastestByLatency !== winner && fastestByLatency.probe.timing.totalMs < winnerT.totalMs) {
55605
+ candidates.push({
55606
+ link: fastestByLatency,
55607
+ factor: winnerT.totalMs / Math.max(1, fastestByLatency.probe.timing.totalMs),
55608
+ axis: "latency"
55609
+ });
55610
+ }
55611
+ if (fastestByTput && fastestByTput !== winner && fastestByTput.probe.timing.tokensPerSec > winnerT.tokensPerSec && winnerT.tokensPerSec > 0) {
55612
+ candidates.push({
55613
+ link: fastestByTput,
55614
+ factor: fastestByTput.probe.timing.tokensPerSec / winnerT.tokensPerSec,
55615
+ axis: "throughput"
55616
+ });
55617
+ }
55618
+ }
55619
+ const suggestion = candidates.sort((a, b) => b.factor - a.factor)[0];
55620
+ const showSuggestion = !!suggestion;
55621
+ const ruleKey = ruleKeyForModel(result.model);
55622
+ return /* @__PURE__ */ jsxDEV("box", {
55623
+ flexDirection: "column",
55624
+ marginBottom: isLast ? 0 : 1,
55625
+ children: [
55626
+ /* @__PURE__ */ jsxDEV("text", {
55627
+ children: [
55628
+ /* @__PURE__ */ jsxDEV("span", {
55629
+ fg: C.dim,
55630
+ children: " "
55631
+ }, undefined, false, undefined, this),
55632
+ /* @__PURE__ */ jsxDEV("span", {
55633
+ fg: C.cyan,
55634
+ attributes: A.bold,
55635
+ children: result.model
55636
+ }, undefined, false, undefined, this),
55637
+ /* @__PURE__ */ jsxDEV("span", {
55638
+ fg: C.dim,
55639
+ children: " ".repeat(gap)
55640
+ }, undefined, false, undefined, this),
55641
+ /* @__PURE__ */ jsxDEV("span", {
55642
+ fg: C.dim,
55643
+ children: result.routingExplanation
55644
+ }, undefined, false, undefined, this)
55645
+ ]
55646
+ }, undefined, true, undefined, this),
55647
+ result.links.map((link, i) => /* @__PURE__ */ jsxDEV(DetailLinkRow, {
55648
+ link,
55649
+ isWinner: i === winnerIdx,
55650
+ provW,
55651
+ layout,
55652
+ maxTotalMs,
55653
+ maxTokPerSec
55654
+ }, `${result.model}:${link.provider}:${i}`, false, undefined, this)),
55655
+ /* @__PURE__ */ jsxDEV("text", {
55656
+ children: /* @__PURE__ */ jsxDEV("span", {
55657
+ fg: C.dim,
55658
+ children: ` ${wireLine}`
55659
+ }, undefined, false, undefined, this)
55660
+ }, undefined, false, undefined, this),
55661
+ /* @__PURE__ */ jsxDEV("text", {
55662
+ children: [
55663
+ /* @__PURE__ */ jsxDEV("span", {
55664
+ fg: C.dim,
55665
+ children: " route: "
55666
+ }, undefined, false, undefined, this),
55667
+ /* @__PURE__ */ jsxDEV("span", {
55668
+ fg: C.fgMuted,
55669
+ children: routeChain || "\u2014"
55670
+ }, undefined, false, undefined, this),
55671
+ winner && /* @__PURE__ */ jsxDEV(Fragment, {
55672
+ children: [
55673
+ /* @__PURE__ */ jsxDEV("span", {
55674
+ fg: C.dim,
55675
+ children: " \xB7 uses "
55676
+ }, undefined, false, undefined, this),
55677
+ /* @__PURE__ */ jsxDEV("span", {
55678
+ fg: C.green,
55679
+ children: winner.displayName
55680
+ }, undefined, false, undefined, this),
55681
+ /* @__PURE__ */ jsxDEV("span", {
55682
+ fg: C.dim,
55683
+ children: " (first credentialed live link)"
55684
+ }, undefined, false, undefined, this)
55685
+ ]
55686
+ }, undefined, true, undefined, this)
55687
+ ]
55688
+ }, undefined, true, undefined, this),
55689
+ showSuggestion && /* @__PURE__ */ jsxDEV("text", {
55690
+ children: [
55691
+ /* @__PURE__ */ jsxDEV("span", {
55692
+ fg: C.yellow,
55693
+ attributes: A.bold,
55694
+ children: " \u26A1 "
55695
+ }, undefined, false, undefined, this),
55696
+ /* @__PURE__ */ jsxDEV("span", {
55697
+ fg: C.fg,
55698
+ children: suggestion.link.displayName
55699
+ }, undefined, false, undefined, this),
55700
+ /* @__PURE__ */ jsxDEV("span", {
55701
+ fg: C.green,
55702
+ children: ` is ${suggestion.factor.toFixed(1)}\xD7 faster ${suggestion.axis === "latency" ? "end-to-end" : "throughput"}`
55703
+ }, undefined, false, undefined, this),
55704
+ /* @__PURE__ */ jsxDEV("span", {
55705
+ fg: C.dim,
55706
+ children: suggestion.axis === "latency" ? ` (${formatLatency(suggestion.link.probe.timing.totalMs)} vs ${formatLatency(winnerT.totalMs)})` : ` (${Math.round(suggestion.link.probe.timing.tokensPerSec)} vs ${Math.round(winnerT.tokensPerSec)} t/s)`
55707
+ }, undefined, false, undefined, this),
55708
+ /* @__PURE__ */ jsxDEV("span", {
55709
+ fg: C.dim,
55710
+ children: ` \u2014 add routing: `
55711
+ }, undefined, false, undefined, this),
55712
+ /* @__PURE__ */ jsxDEV("span", {
55713
+ fg: C.cyan,
55714
+ children: `"${ruleKey}": ["${suggestion.link.provider}"]`
55715
+ }, undefined, false, undefined, this)
55716
+ ]
55717
+ }, undefined, true, undefined, this)
55718
+ ]
55719
+ }, undefined, true, undefined, this);
55720
+ }
55721
+ function DetailsView({
55722
+ results,
55723
+ layout,
55724
+ termWidth,
55725
+ maxTotalMs,
55726
+ maxTokPerSec
55727
+ }) {
55728
+ const provW = Math.min(22, Math.max(8, ...results.flatMap((r) => r.links.map((l) => l.displayName.length))));
55729
+ const headerW = Math.max(24, Math.min(detailRowWidth(provW, layout), (termWidth || 100) - 3));
55730
+ return /* @__PURE__ */ jsxDEV("box", {
55731
+ flexDirection: "column",
55732
+ children: results.map((r, idx) => /* @__PURE__ */ jsxDEV(DetailModel, {
55733
+ result: r,
55734
+ provW,
55735
+ headerW,
55736
+ layout,
55737
+ maxTotalMs,
55738
+ maxTokPerSec,
55739
+ isLast: idx === results.length - 1
55740
+ }, r.model, false, undefined, this))
55741
+ }, undefined, false, undefined, this);
55742
+ }
55743
+ function pickRepresentativeLink(result) {
55744
+ for (const link of result.links) {
55745
+ if (link.probe?.state === "live" && link.probe.timing) {
55746
+ return { model: result.model, provider: link.displayName, timing: link.probe.timing };
55747
+ }
55748
+ }
55749
+ return { model: result.model, provider: result.nativeProvider };
55750
+ }
55751
+ function LeaderLiveRow({
55752
+ row,
55753
+ rank,
55754
+ isFastest,
55755
+ rankW,
55756
+ nameW,
55757
+ provW,
55758
+ layout,
55759
+ maxTotalMs,
55760
+ maxTokPerSec
55761
+ }) {
55762
+ const t = row.timing;
55763
+ const barCells = timelineBarCells(t.totalMs, maxTotalMs, layout.barWidth);
55764
+ const stages = splitStageCells(t.ttfbMs, t.ttftMs, t.totalMs, barCells);
55765
+ const trackCells = Math.max(0, layout.barWidth - barCells);
55766
+ const netMs = Math.max(0, t.ttfbMs);
55767
+ const srvMs = Math.max(0, t.ttftMs - t.ttfbMs);
55768
+ const strMs = Math.max(0, t.totalMs - t.ttftMs);
55769
+ const netStr = padStartSafe(breakdownNum(netMs), STAGE_NUM_W);
55770
+ const srvStr = padStartSafe(breakdownNum(srvMs), STAGE_NUM_W);
55771
+ const strStr = padStartSafe(breakdownNum(strMs), STAGE_NUM_W);
55772
+ const tokColor = throughputFg(t.tokensPerSec);
55773
+ const tokCells = layout.tokWidth > 0 ? tokBarCells(t.tokensPerSec, maxTokPerSec, layout.tokWidth) : 0;
55774
+ const tokTrack = Math.max(0, layout.tokWidth - tokCells);
55775
+ const tokValue = padStartSafe(`${Math.round(t.tokensPerSec)} t/s`, TOK_VALUE_COL);
55776
+ const lead = /* @__PURE__ */ jsxDEV(Fragment, {
55777
+ children: [
55778
+ /* @__PURE__ */ jsxDEV("span", {
55779
+ fg: C.dim,
55780
+ children: " "
55781
+ }, undefined, false, undefined, this),
55782
+ /* @__PURE__ */ jsxDEV("span", {
55783
+ fg: C.dim,
55784
+ children: padStartSafe(String(rank), rankW)
55785
+ }, undefined, false, undefined, this),
55786
+ /* @__PURE__ */ jsxDEV("span", {
55787
+ children: " "
55788
+ }, undefined, false, undefined, this),
55789
+ isFastest ? /* @__PURE__ */ jsxDEV("span", {
55790
+ fg: C.brightGreen,
55791
+ children: "\u25CF"
55792
+ }, undefined, false, undefined, this) : /* @__PURE__ */ jsxDEV("span", {
55793
+ children: " "
55794
+ }, undefined, false, undefined, this),
55795
+ /* @__PURE__ */ jsxDEV("span", {
55796
+ children: " "
55797
+ }, undefined, false, undefined, this),
55798
+ /* @__PURE__ */ jsxDEV("span", {
55799
+ fg: C.fg,
55800
+ attributes: A.bold,
55801
+ children: padEndSafe(row.model, nameW)
55802
+ }, undefined, false, undefined, this),
55803
+ /* @__PURE__ */ jsxDEV("span", {
55804
+ children: " "
55805
+ }, undefined, false, undefined, this),
55806
+ /* @__PURE__ */ jsxDEV("span", {
55807
+ fg: C.dim,
55808
+ children: padEndSafe(row.provider, provW)
55809
+ }, undefined, false, undefined, this),
55810
+ /* @__PURE__ */ jsxDEV("span", {
55811
+ children: " "
55812
+ }, undefined, false, undefined, this)
55813
+ ]
55814
+ }, undefined, true, undefined, this);
55815
+ if (layout.barWidth <= 0) {
55816
+ return /* @__PURE__ */ jsxDEV("text", {
55817
+ children: [
55818
+ lead,
55819
+ /* @__PURE__ */ jsxDEV("span", {
55820
+ fg: C.white,
55821
+ children: padStartSafe(formatLatency(t.totalMs), TOTAL_COL)
55822
+ }, undefined, false, undefined, this)
55823
+ ]
55824
+ }, undefined, true, undefined, this);
55825
+ }
55826
+ return /* @__PURE__ */ jsxDEV("text", {
55827
+ children: [
55828
+ lead,
55829
+ stages.network > 0 && /* @__PURE__ */ jsxDEV("span", {
55830
+ bg: STAGE_BG.network,
55831
+ children: " ".repeat(stages.network)
55832
+ }, undefined, false, undefined, this),
55833
+ stages.server > 0 && /* @__PURE__ */ jsxDEV("span", {
55834
+ bg: STAGE_BG.server,
55835
+ children: " ".repeat(stages.server)
55836
+ }, undefined, false, undefined, this),
55837
+ stages.streaming > 0 && /* @__PURE__ */ jsxDEV("span", {
55838
+ bg: STAGE_BG.streaming,
55839
+ children: " ".repeat(stages.streaming)
55840
+ }, undefined, false, undefined, this),
55841
+ trackCells > 0 && /* @__PURE__ */ jsxDEV("span", {
55842
+ fg: C.dim,
55843
+ children: TRACK_CHAR.repeat(trackCells)
55844
+ }, undefined, false, undefined, this),
55845
+ /* @__PURE__ */ jsxDEV("span", {
55846
+ fg: C.dim,
55847
+ children: " "
55848
+ }, undefined, false, undefined, this),
55849
+ /* @__PURE__ */ jsxDEV("span", {
55850
+ fg: C.white,
55851
+ children: padStartSafe(formatLatency(t.totalMs), TOTAL_COL)
55852
+ }, undefined, false, undefined, this),
55853
+ layout.showBreakdown && /* @__PURE__ */ jsxDEV(Fragment, {
55854
+ children: [
55855
+ /* @__PURE__ */ jsxDEV("span", {
55856
+ fg: C.dim,
55857
+ children: " "
55858
+ }, undefined, false, undefined, this),
55859
+ /* @__PURE__ */ jsxDEV("span", {
55860
+ fg: STAGE_FG.network,
55861
+ children: netStr
55862
+ }, undefined, false, undefined, this),
55863
+ /* @__PURE__ */ jsxDEV("span", {
55864
+ fg: C.dim,
55865
+ children: " "
55866
+ }, undefined, false, undefined, this),
55867
+ /* @__PURE__ */ jsxDEV("span", {
55868
+ fg: STAGE_FG.server,
55869
+ children: srvStr
55870
+ }, undefined, false, undefined, this),
55871
+ /* @__PURE__ */ jsxDEV("span", {
55872
+ fg: C.dim,
55873
+ children: " "
55874
+ }, undefined, false, undefined, this),
55875
+ /* @__PURE__ */ jsxDEV("span", {
55876
+ fg: STAGE_FG.streaming,
55877
+ children: strStr
55878
+ }, undefined, false, undefined, this)
55879
+ ]
55880
+ }, undefined, true, undefined, this),
55881
+ layout.tokWidth > 0 && /* @__PURE__ */ jsxDEV(Fragment, {
55882
+ children: [
55883
+ /* @__PURE__ */ jsxDEV("span", {
55884
+ fg: C.dim,
55885
+ children: " "
55886
+ }, undefined, false, undefined, this),
55887
+ tokCells > 0 && /* @__PURE__ */ jsxDEV("span", {
55888
+ fg: tokColor,
55889
+ children: BAR_FILL.repeat(tokCells)
55890
+ }, undefined, false, undefined, this),
55891
+ tokTrack > 0 && /* @__PURE__ */ jsxDEV("span", {
55892
+ fg: C.dim,
55893
+ children: TRACK_CHAR.repeat(tokTrack)
55894
+ }, undefined, false, undefined, this),
55895
+ /* @__PURE__ */ jsxDEV("span", {
55896
+ fg: C.dim,
55897
+ children: " "
55898
+ }, undefined, false, undefined, this)
55899
+ ]
55900
+ }, undefined, true, undefined, this),
55901
+ layout.tokWidth === 0 && /* @__PURE__ */ jsxDEV("span", {
55902
+ fg: C.dim,
55903
+ children: " "
55904
+ }, undefined, false, undefined, this),
55905
+ /* @__PURE__ */ jsxDEV("span", {
55906
+ fg: tokColor,
55907
+ children: tokValue
55908
+ }, undefined, false, undefined, this)
55909
+ ]
55910
+ }, undefined, true, undefined, this);
55911
+ }
55912
+ function LeaderboardView({
55913
+ results,
55914
+ layout,
55915
+ maxTotalMs,
55916
+ maxTokPerSec
55917
+ }) {
55918
+ const reps = results.map(pickRepresentativeLink);
55919
+ const live = reps.filter((r) => r.timing).sort((a, b) => a.timing.totalMs - b.timing.totalMs);
55920
+ const unavailable = reps.filter((r) => !r.timing);
55921
+ const nameW = Math.min(28, Math.max(5, ...reps.map((r) => r.model.length)));
55922
+ const provW = Math.min(18, Math.max(8, ...reps.map((r) => r.provider.length)));
55923
+ const rankW = Math.max(1, String(Math.max(1, live.length)).length);
55924
+ const rankHdr = " ".repeat(rankW) + " ";
55925
+ return /* @__PURE__ */ jsxDEV("box", {
55926
+ flexDirection: "column",
55927
+ children: [
55928
+ /* @__PURE__ */ jsxDEV("text", {
55929
+ children: [
55930
+ /* @__PURE__ */ jsxDEV("span", {
55931
+ fg: C.dim,
55932
+ children: " "
55933
+ }, undefined, false, undefined, this),
55934
+ /* @__PURE__ */ jsxDEV("span", {
55935
+ fg: C.cyan,
55936
+ attributes: A.bold,
55937
+ children: "Leaderboard"
55938
+ }, undefined, false, undefined, this),
55939
+ /* @__PURE__ */ jsxDEV("span", {
55940
+ fg: C.dim,
55941
+ children: " \u2014 fastest first"
55942
+ }, undefined, false, undefined, this)
55943
+ ]
55944
+ }, undefined, true, undefined, this),
55945
+ /* @__PURE__ */ jsxDEV("text", {
55946
+ children: [
55947
+ /* @__PURE__ */ jsxDEV("span", {
55948
+ fg: C.dim,
55949
+ children: " " + rankHdr
55950
+ }, undefined, false, undefined, this),
55951
+ /* @__PURE__ */ jsxDEV("span", {
55952
+ fg: C.dim,
55953
+ children: padEndSafe("MODEL", nameW)
55954
+ }, undefined, false, undefined, this),
55955
+ /* @__PURE__ */ jsxDEV("span", {
55956
+ fg: C.dim,
55957
+ children: " "
55958
+ }, undefined, false, undefined, this),
55959
+ /* @__PURE__ */ jsxDEV("span", {
55960
+ fg: C.dim,
55961
+ children: padEndSafe("PROVIDER", provW)
55962
+ }, undefined, false, undefined, this),
55963
+ /* @__PURE__ */ jsxDEV("span", {
55964
+ fg: C.dim,
55965
+ children: " "
55966
+ }, undefined, false, undefined, this),
55967
+ layout.barWidth > 0 && /* @__PURE__ */ jsxDEV("span", {
55968
+ fg: C.dim,
55969
+ children: padEndSafe("TIMELINE", layout.barWidth)
55970
+ }, undefined, false, undefined, this),
55971
+ /* @__PURE__ */ jsxDEV("span", {
55972
+ fg: C.dim,
55973
+ children: " "
55974
+ }, undefined, false, undefined, this),
55975
+ /* @__PURE__ */ jsxDEV("span", {
55976
+ fg: C.dim,
55977
+ children: padStartSafe("TOTAL", TOTAL_COL)
55978
+ }, undefined, false, undefined, this),
55979
+ layout.showBreakdown && /* @__PURE__ */ jsxDEV("span", {
55980
+ fg: C.dim,
55981
+ children: " " + padEndSafe("net", STAGE_NUM_W) + " " + padEndSafe("srv", STAGE_NUM_W) + " " + padEndSafe("str", STAGE_NUM_W)
55982
+ }, undefined, false, undefined, this),
55983
+ layout.tokWidth > 0 ? /* @__PURE__ */ jsxDEV("span", {
55984
+ fg: C.dim,
55985
+ children: " " + " ".repeat(layout.tokWidth + 1) + padStartSafe("tok/s", TOK_VALUE_COL)
55986
+ }, undefined, false, undefined, this) : /* @__PURE__ */ jsxDEV("span", {
55987
+ fg: C.dim,
55988
+ children: " " + padStartSafe("tok/s", TOK_VALUE_COL)
55989
+ }, undefined, false, undefined, this)
55990
+ ]
55991
+ }, undefined, true, undefined, this),
55992
+ live.map((row, idx) => /* @__PURE__ */ jsxDEV(LeaderLiveRow, {
55993
+ row,
55994
+ rank: idx + 1,
55995
+ isFastest: idx === 0,
55996
+ rankW,
55997
+ nameW,
55998
+ provW,
55999
+ layout,
56000
+ maxTotalMs,
56001
+ maxTokPerSec
56002
+ }, `lb:${row.model}`, false, undefined, this)),
56003
+ unavailable.map((row) => /* @__PURE__ */ jsxDEV("text", {
56004
+ children: [
56005
+ /* @__PURE__ */ jsxDEV("span", {
56006
+ fg: C.dim,
56007
+ children: " " + " ".repeat(rankW) + " "
56008
+ }, undefined, false, undefined, this),
56009
+ /* @__PURE__ */ jsxDEV("span", {
56010
+ fg: C.dim,
56011
+ children: padEndSafe(row.model, nameW)
56012
+ }, undefined, false, undefined, this),
56013
+ /* @__PURE__ */ jsxDEV("span", {
56014
+ fg: C.dim,
56015
+ children: " "
56016
+ }, undefined, false, undefined, this),
56017
+ /* @__PURE__ */ jsxDEV("span", {
56018
+ fg: C.dim,
56019
+ children: padEndSafe(row.provider, provW)
56020
+ }, undefined, false, undefined, this),
56021
+ /* @__PURE__ */ jsxDEV("span", {
56022
+ fg: C.dim,
56023
+ children: " \u2014 no live route"
56024
+ }, undefined, false, undefined, this)
56025
+ ]
56026
+ }, `lb-na:${row.model}`, true, undefined, this))
56027
+ ]
56028
+ }, undefined, true, undefined, this);
56029
+ }
56030
+ function ProbeApp({
56031
+ store,
56032
+ onQuit
56033
+ }) {
54893
56034
  const state = useProbeStore(store);
54894
- const animFrame = useAnimationFrame(true);
56035
+ const animFrame = useAnimationFrame(state.phase === "live");
56036
+ const { height: termHeight, width: termWidth } = useTerminalDimensions();
56037
+ const isDone = state.phase === "done";
56038
+ const listScrollRef = useRef2(null);
56039
+ useKeyboard((key) => {
56040
+ if (isDone) {
56041
+ if (key.name === "q" || key.name === "escape") {
56042
+ onQuit?.();
56043
+ return;
56044
+ }
56045
+ if (key.name === "tab") {
56046
+ const order = ["summary", "leaderboard", "details"];
56047
+ const cur = order.indexOf(store.getState().activeTab);
56048
+ const next = key.shift ? (cur - 1 + order.length) % order.length : (cur + 1) % order.length;
56049
+ store.setActiveTab(order[next]);
56050
+ return;
56051
+ }
56052
+ if (key.name === "1") {
56053
+ store.setActiveTab("summary");
56054
+ return;
56055
+ }
56056
+ if (key.name === "2") {
56057
+ store.setActiveTab("leaderboard");
56058
+ return;
56059
+ }
56060
+ if (key.name === "3") {
56061
+ store.setActiveTab("details");
56062
+ return;
56063
+ }
56064
+ }
56065
+ const sb = listScrollRef.current;
56066
+ if (!sb)
56067
+ return;
56068
+ const page = Math.max(1, sb.viewport.height - 1);
56069
+ switch (key.name) {
56070
+ case "up":
56071
+ case "k":
56072
+ sb.scrollBy(-1);
56073
+ break;
56074
+ case "down":
56075
+ case "j":
56076
+ sb.scrollBy(1);
56077
+ break;
56078
+ case "pageup":
56079
+ sb.scrollBy(-page);
56080
+ break;
56081
+ case "pagedown":
56082
+ case "space":
56083
+ sb.scrollBy(page);
56084
+ break;
56085
+ case "home":
56086
+ sb.scrollTo(0);
56087
+ break;
56088
+ case "end":
56089
+ sb.scrollTo(sb.content.height);
56090
+ break;
56091
+ case "g":
56092
+ sb.scrollTo(key.shift ? sb.content.height : 0);
56093
+ break;
56094
+ }
56095
+ });
54895
56096
  const groups = [];
54896
56097
  for (const link of state.links) {
54897
56098
  let group = groups.find((g) => g.model === link.model);
@@ -54902,36 +56103,112 @@ function ProbeApp({ store }) {
54902
56103
  group.links.push(link);
54903
56104
  }
54904
56105
  const maxNameLen = Math.min(25, Math.max(...state.links.map((l) => l.displayName.length), 12));
54905
- const rowWidth = 4 + 5 + 2 + BAR_WIDTH + 2 + maxNameLen + 2 + 25;
56106
+ const layout = deriveLayout(termWidth || 100);
56107
+ const rowWidth = computeRowWidth(layout, maxNameLen);
56108
+ let maxTotalMs = 1;
56109
+ let maxTokPerSec = 1;
56110
+ let fastestLinkId = null;
56111
+ let fastestTokPerSec = -Infinity;
56112
+ for (const link of state.links) {
56113
+ if (link.status !== "live" || !link.timing)
56114
+ continue;
56115
+ const t = link.timing;
56116
+ if (t.totalMs > maxTotalMs)
56117
+ maxTotalMs = t.totalMs;
56118
+ const streamMs = Math.max(STREAM_MS_FLOOR, t.totalMs - t.ttftMs);
56119
+ const scaledTps = t.tokens > 0 ? t.tokens / streamMs * 1000 : 0;
56120
+ if (scaledTps > maxTokPerSec)
56121
+ maxTokPerSec = scaledTps;
56122
+ if (t.tokensPerSec > fastestTokPerSec) {
56123
+ fastestTokPerSec = t.tokensPerSec;
56124
+ fastestLinkId = link.id;
56125
+ }
56126
+ }
56127
+ if (fastestTokPerSec <= 0)
56128
+ fastestLinkId = null;
56129
+ const showDetails = isDone && state.activeTab === "details";
56130
+ const showLeaderboard = isDone && state.activeTab === "leaderboard";
56131
+ const showSummary = !showDetails && !showLeaderboard;
56132
+ const stepsRows = isDone ? 0 : state.steps.length > 0 ? 1 : 0;
56133
+ const tabBarRows = isDone ? TAB_BAR_ROWS : 0;
56134
+ const legendRows = showSummary ? LEGEND_ROWS : 0;
56135
+ const listH = Math.max(MIN_LIST_H, termHeight - BANNER_ROWS - stepsRows - tabBarRows - legendRows - SCROLL_HINT_ROWS);
56136
+ const sbForHint = listScrollRef.current;
56137
+ const overflow = sbForHint ? sbForHint.content.height > sbForHint.viewport.height : true;
56138
+ const scrollKeys = "\u2191\u2193 scroll \xB7 PgUp/PgDn page \xB7 g/G top/bottom";
56139
+ const footerHint = isDone ? " " + (overflow ? scrollKeys + " \xB7 " : "") + "Tab/1/2/3 switch \xB7 q quit" : " " + (overflow ? scrollKeys : "");
54906
56140
  return /* @__PURE__ */ jsxDEV("box", {
54907
56141
  flexDirection: "column",
54908
56142
  children: [
54909
- /* @__PURE__ */ jsxDEV(Banner, {}, undefined, false, undefined, this),
54910
56143
  /* @__PURE__ */ jsxDEV("box", {
54911
56144
  flexDirection: "column",
54912
- paddingY: 1,
54913
- children: state.steps.map((step, i) => /* @__PURE__ */ jsxDEV(StepIndicator, {
54914
- step
54915
- }, `${step.name}-${i}`, false, undefined, this))
56145
+ height: BANNER_ROWS,
56146
+ children: /* @__PURE__ */ jsxDEV(Banner, {}, undefined, false, undefined, this)
54916
56147
  }, undefined, false, undefined, this),
54917
- groups.length > 0 ? /* @__PURE__ */ jsxDEV("box", {
56148
+ isDone ? /* @__PURE__ */ jsxDEV(TabBar, {
56149
+ activeTab: state.activeTab
56150
+ }, undefined, false, undefined, this) : /* @__PURE__ */ jsxDEV("box", {
54918
56151
  flexDirection: "column",
54919
- children: groups.map((g, idx) => /* @__PURE__ */ jsxDEV(ModelGroup, {
54920
- model: g.model,
54921
- links: g.links,
54922
- animFrame,
54923
- maxNameLen,
54924
- rowWidth,
54925
- isLast: idx === groups.length - 1
54926
- }, g.model, false, undefined, this))
54927
- }, undefined, false, undefined, this) : null
56152
+ children: /* @__PURE__ */ jsxDEV(StepLine, {
56153
+ steps: state.steps
56154
+ }, undefined, false, undefined, this)
56155
+ }, undefined, false, undefined, this),
56156
+ groups.length > 0 ? /* @__PURE__ */ jsxDEV(Fragment, {
56157
+ children: [
56158
+ showSummary && /* @__PURE__ */ jsxDEV("box", {
56159
+ flexDirection: "column",
56160
+ height: LEGEND_ROWS,
56161
+ children: /* @__PURE__ */ jsxDEV(Legend, {
56162
+ rowWidth
56163
+ }, undefined, false, undefined, this)
56164
+ }, undefined, false, undefined, this),
56165
+ /* @__PURE__ */ jsxDEV("scrollbox", {
56166
+ ref: listScrollRef,
56167
+ scrollX: false,
56168
+ scrollY: true,
56169
+ focused: true,
56170
+ style: { height: listH },
56171
+ children: showDetails ? /* @__PURE__ */ jsxDEV(DetailsView, {
56172
+ results: state.results,
56173
+ layout,
56174
+ termWidth,
56175
+ maxTotalMs,
56176
+ maxTokPerSec
56177
+ }, undefined, false, undefined, this) : showLeaderboard ? /* @__PURE__ */ jsxDEV(LeaderboardView, {
56178
+ results: state.results,
56179
+ layout,
56180
+ maxTotalMs,
56181
+ maxTokPerSec
56182
+ }, undefined, false, undefined, this) : groups.map((g, idx) => /* @__PURE__ */ jsxDEV(ModelGroup, {
56183
+ model: g.model,
56184
+ links: g.links,
56185
+ animFrame,
56186
+ maxNameLen,
56187
+ rowWidth,
56188
+ isLast: idx === groups.length - 1,
56189
+ layout,
56190
+ maxTotalMs,
56191
+ maxTokPerSec,
56192
+ fastestLinkId
56193
+ }, g.model, false, undefined, this))
56194
+ }, undefined, false, undefined, this),
56195
+ /* @__PURE__ */ jsxDEV("text", {
56196
+ children: /* @__PURE__ */ jsxDEV("span", {
56197
+ fg: C.dim,
56198
+ children: footerHint
56199
+ }, undefined, false, undefined, this)
56200
+ }, undefined, false, undefined, this)
56201
+ ]
56202
+ }, undefined, true, undefined, this) : null
54928
56203
  ]
54929
- }, undefined, true, undefined, this);
56204
+ }, state.phase, true, undefined, this);
54930
56205
  }
54931
- var ANIM_FRAMES, BAR_WIDTH = 20;
56206
+ var ANIM_FRAMES, TIMELINE_BAR_FULL = 24, TIMELINE_BAR_NARROW = 12, TOK_BAR_FULL = 14, TOTAL_COL = 7, STAGE_NUM_W = 6, BREAKDOWN_COL, TOK_VALUE_COL = 7, TRACK_CHAR = "\xB7", BAR_FILL = "\u2588", BANNER_ROWS = 7, SCROLL_HINT_ROWS = 1, LEGEND_ROWS = 2, MIN_LIST_H = 4, TAB_BAR_ROWS = 2;
54932
56207
  var init_probe_tui_app = __esm(() => {
54933
56208
  init_theme2();
56209
+ init_probe_live();
54934
56210
  ANIM_FRAMES = ["\u2593", "\u2592", "\u2591", "\u2592"];
56211
+ BREAKDOWN_COL = 16 + 3 * STAGE_NUM_W;
54935
56212
  });
54936
56213
 
54937
56214
  // src/probe/probe-tui-runtime.tsx
@@ -54942,13 +56219,25 @@ async function startProbeTui(initial) {
54942
56219
  const renderer = await createCliRenderer({
54943
56220
  stdout: process.stderr,
54944
56221
  useAlternateScreen: false,
54945
- useMouse: false,
56222
+ useMouse: true,
54946
56223
  exitOnCtrlC: true
54947
56224
  });
54948
56225
  const store = new ProbeStore(initial);
56226
+ let resolveQuit;
56227
+ const quitPromise = new Promise((resolve3) => {
56228
+ resolveQuit = resolve3;
56229
+ });
56230
+ let quit = false;
56231
+ const onQuit = () => {
56232
+ if (quit)
56233
+ return;
56234
+ quit = true;
56235
+ resolveQuit();
56236
+ };
54949
56237
  const root = createRoot(renderer);
54950
56238
  root.render(/* @__PURE__ */ jsxDEV2(ProbeApp, {
54951
- store
56239
+ store,
56240
+ onQuit
54952
56241
  }, undefined, false, undefined, this));
54953
56242
  let destroyed = false;
54954
56243
  const shutdown = async () => {
@@ -54962,7 +56251,7 @@ async function startProbeTui(initial) {
54962
56251
  renderer.destroy();
54963
56252
  } catch {}
54964
56253
  };
54965
- return { store, shutdown };
56254
+ return { store, waitForQuit: () => quitPromise, shutdown };
54966
56255
  }
54967
56256
  var init_probe_tui_runtime = __esm(() => {
54968
56257
  init_probe_tui_app();
@@ -55024,6 +56313,104 @@ function wordWrap(text, maxWidth) {
55024
56313
  lines.push(current);
55025
56314
  return lines;
55026
56315
  }
56316
+ function computeBarScales(results) {
56317
+ let maxTokPerSec = 1;
56318
+ const liveTotals = [];
56319
+ const consider = (probe) => {
56320
+ if (!probe || probe.state !== "live" || !probe.timing)
56321
+ return;
56322
+ const t = probe.timing;
56323
+ liveTotals.push(t.totalMs);
56324
+ const streamMs = Math.max(STREAM_MS_FLOOR, t.totalMs - t.ttftMs);
56325
+ const scaledTps = t.tokens > 0 ? t.tokens / streamMs * 1000 : 0;
56326
+ if (scaledTps > maxTokPerSec)
56327
+ maxTokPerSec = scaledTps;
56328
+ };
56329
+ for (const r of results) {
56330
+ consider(r.directProbe);
56331
+ for (const c of r.chain ?? [])
56332
+ consider(c.probe);
56333
+ }
56334
+ let maxTotalMs = 1;
56335
+ if (liveTotals.length > 0) {
56336
+ const sorted = [...liveTotals].sort((a, b) => a - b);
56337
+ const rawMax = sorted[sorted.length - 1];
56338
+ maxTotalMs = Math.max(1, rawMax);
56339
+ if (sorted.length >= 3) {
56340
+ const median = sorted[Math.floor((sorted.length - 1) / 2)];
56341
+ const secondSlowest = sorted[sorted.length - 2];
56342
+ const cap = Math.max(secondSlowest, 3 * median);
56343
+ maxTotalMs = Math.max(1, Math.min(rawMax, cap));
56344
+ }
56345
+ }
56346
+ return { maxTotalMs, maxTokPerSec };
56347
+ }
56348
+ function padStartSafe2(s, n) {
56349
+ if (s.length >= n)
56350
+ return s.slice(s.length - n);
56351
+ return " ".repeat(n - s.length) + s;
56352
+ }
56353
+ function padEnd(s, n) {
56354
+ const vis = visibleLength(s);
56355
+ if (vis >= n)
56356
+ return s;
56357
+ return s + " ".repeat(n - vis);
56358
+ }
56359
+ function breakdownNum2(ms) {
56360
+ if (ms >= 1000)
56361
+ return formatLatency(ms);
56362
+ return `${Math.round(Math.max(0, ms))}`;
56363
+ }
56364
+ function buildBarsLine(timing, scales, isFastest, usable) {
56365
+ const t = timing;
56366
+ const showTokBar = usable >= PRINTER_BARS_FULL_WIDTH;
56367
+ const showBreakdown = usable >= PRINTER_BARS_FULL_WIDTH || usable >= PRINTER_BARS_NOTOK_WIDTH;
56368
+ const barCells = timelineBarCells(t.totalMs, scales.maxTotalMs, PRINTER_BAR_WIDTH);
56369
+ const stages = splitStageCells(t.ttfbMs, t.ttftMs, t.totalMs, barCells);
56370
+ const trackCells = Math.max(0, PRINTER_BAR_WIDTH - barCells);
56371
+ let timeline = "";
56372
+ if (stages.network > 0) {
56373
+ timeline += `${STAGE_BG_ANSI.network}${" ".repeat(stages.network)}${ANSI_RESET}`;
56374
+ }
56375
+ if (stages.server > 0) {
56376
+ timeline += `${STAGE_BG_ANSI.server}${" ".repeat(stages.server)}${ANSI_RESET}`;
56377
+ }
56378
+ if (stages.streaming > 0) {
56379
+ timeline += `${STAGE_BG_ANSI.streaming}${" ".repeat(stages.streaming)}${ANSI_RESET}`;
56380
+ }
56381
+ if (trackCells > 0) {
56382
+ timeline += `${pc.dim}${PRINTER_TRACK.repeat(trackCells)}${pc.reset}`;
56383
+ }
56384
+ const total = `${LATENCY_FG_ANSI}${padStartSafe2(formatLatency(t.totalMs), 7)}${pc.reset}`;
56385
+ let breakdown = "";
56386
+ if (showBreakdown) {
56387
+ const netMs = Math.max(0, t.ttfbMs);
56388
+ const srvMs = Math.max(0, t.ttftMs - t.ttfbMs);
56389
+ const strMs = Math.max(0, t.totalMs - t.ttftMs);
56390
+ const netFg = hexToAnsiFg(STAGE_FG.network);
56391
+ const srvFg = hexToAnsiFg(STAGE_FG.server);
56392
+ const strFg = hexToAnsiFg(STAGE_FG.streaming);
56393
+ breakdown = `${pc.dim} net ${pc.reset}${netFg}${padStartSafe2(breakdownNum2(netMs), STAGE_NUM_W2)}${pc.reset}` + `${pc.dim} srv ${pc.reset}${srvFg}${padStartSafe2(breakdownNum2(srvMs), STAGE_NUM_W2)}${pc.reset}` + `${pc.dim} str ${pc.reset}${strFg}${padStartSafe2(breakdownNum2(strMs), STAGE_NUM_W2)}${pc.reset}`;
56394
+ }
56395
+ const tokFg = hexToAnsiFg(throughputFg(t.tokensPerSec));
56396
+ let tokBar = "";
56397
+ if (showTokBar) {
56398
+ const tokCells = tokBarCells(t.tokensPerSec, scales.maxTokPerSec, PRINTER_TOK_WIDTH);
56399
+ const tokTrack = Math.max(0, PRINTER_TOK_WIDTH - tokCells);
56400
+ if (tokCells > 0) {
56401
+ tokBar += `${tokFg}${PRINTER_BAR_FILL.repeat(tokCells)}${pc.reset}`;
56402
+ }
56403
+ if (tokTrack > 0) {
56404
+ tokBar += `${pc.dim}${PRINTER_TRACK.repeat(tokTrack)}${pc.reset}`;
56405
+ }
56406
+ tokBar = ` ${tokBar} `;
56407
+ } else {
56408
+ tokBar = " ";
56409
+ }
56410
+ const tokValue = `${tokFg}${padStartSafe2(`${Math.round(t.tokensPerSec)} t/s`, PRINTER_TOK_VALUE_W)}${pc.reset}`;
56411
+ const crown = isFastest ? ` ${pc.brightGreen}\u25CF${pc.reset}` : "";
56412
+ return `${timeline} ${total}${breakdown}${tokBar}${tokValue}${crown}`;
56413
+ }
55027
56414
  function summaryColor(live, total) {
55028
56415
  if (total === 0 || live === 0)
55029
56416
  return pc.red;
@@ -55039,7 +56426,7 @@ function shortStatusLabel(probe, hasCreds, hint) {
55039
56426
  }
55040
56427
  switch (probe.state) {
55041
56428
  case "live":
55042
- return `${pc.green}\u2713 ${probe.latencyMs}ms${pc.reset}`;
56429
+ return `${pc.green}\u2713 ${LATENCY_FG_ANSI}${latencyBgAnsi(probe.latencyMs)} ${formatLatency(probe.latencyMs)} ${pc.reset}`;
55043
56430
  case "key-missing":
55044
56431
  return `${pc.dim}${pc.red}\u25CB missing${pc.reset}`;
55045
56432
  case "auth-failed":
@@ -55161,6 +56548,7 @@ function buildRowData(result, isLiveProbe) {
55161
56548
  if (entry.probe && isFailureState(entry.probe.state) && entry.probe.errorMessage) {
55162
56549
  errorDetail = stripAnsi3(entry.probe.errorMessage).replace(/\s+/g, " ").trim();
55163
56550
  }
56551
+ const barsTiming = entry.probe?.state === "live" && entry.probe.timing ? entry.probe.timing : undefined;
55164
56552
  return {
55165
56553
  num: `${i + 1}`,
55166
56554
  provider: entry.displayName,
@@ -55168,7 +56556,8 @@ function buildRowData(result, isLiveProbe) {
55168
56556
  status,
55169
56557
  errorDetail,
55170
56558
  fastest: isFastest,
55171
- slowest: isSlowest
56559
+ slowest: isSlowest,
56560
+ barsTiming
55172
56561
  };
55173
56562
  });
55174
56563
  }
@@ -55187,13 +56576,15 @@ function buildDirectRowData(result) {
55187
56576
  if (probe && isFailureState(probe.state) && probe.errorMessage) {
55188
56577
  errorDetail = stripAnsi3(probe.errorMessage).replace(/\s+/g, " ").trim();
55189
56578
  }
56579
+ const barsTiming = probe?.state === "live" && probe.timing ? probe.timing : undefined;
55190
56580
  return [
55191
56581
  {
55192
56582
  num: "1",
55193
56583
  provider: result.nativeProvider,
55194
56584
  spec: `${result.nativeProvider}@${result.model}`,
55195
56585
  status,
55196
- errorDetail
56586
+ errorDetail,
56587
+ barsTiming
55197
56588
  }
55198
56589
  ];
55199
56590
  }
@@ -55216,7 +56607,7 @@ function computeCardWidth(rows, widths, topTitleVis, topSummaryVis, footerVis) {
55216
56607
  width = maxAllowed;
55217
56608
  return width;
55218
56609
  }
55219
- function formatContextWindow(ctx) {
56610
+ function formatContextWindow2(ctx) {
55220
56611
  if (ctx <= 0)
55221
56612
  return "0K";
55222
56613
  if (ctx >= 1e6)
@@ -55238,7 +56629,7 @@ function buildKeyLine(activeEntry, directKeyVar) {
55238
56629
  return `${pc.bold}Key${pc.reset} ${pc.dim}\u2014${pc.reset}`;
55239
56630
  }
55240
56631
  function buildWireLine(wiring, activeProvider) {
55241
- const ctx = formatContextWindow(wiring.contextWindow);
56632
+ const ctx = formatContextWindow2(wiring.contextWindow);
55242
56633
  const head = activeProvider ? `${activeProvider} \u2192 ` : "";
55243
56634
  return `${pc.bold}Wire${pc.reset} ${head}${wiring.effectiveStreamFormat} \xB7 ${wiring.modelTranslator} \xB7 ${ctx}`;
55244
56635
  }
@@ -55273,7 +56664,7 @@ function computeRequiredWidth(result, isLiveProbe, directKeyVar) {
55273
56664
  const layout = buildCardLayout(result, isLiveProbe, directKeyVar);
55274
56665
  return computeCardWidth(layout.rows, layout.widths, visibleLength(layout.titleStyled), visibleLength(layout.summaryStyled), layout.footerVis);
55275
56666
  }
55276
- function renderCard(result, isLiveProbe, w, width, directKeyVar) {
56667
+ function renderCard(result, isLiveProbe, w, width, scales, directKeyVar) {
55277
56668
  const layout = buildCardLayout(result, isLiveProbe, directKeyVar);
55278
56669
  const {
55279
56670
  rows,
@@ -55308,6 +56699,17 @@ function renderCard(result, isLiveProbe, w, width, directKeyVar) {
55308
56699
  ];
55309
56700
  w(renderRow(cells, widths, width, bg) + `
55310
56701
  `);
56702
+ if (r.barsTiming) {
56703
+ const innerUsable = width - 2 - CARD_PADDING_LEFT - CARD_PADDING_RIGHT;
56704
+ const barsIndent = 4;
56705
+ const barsUsable = innerUsable - barsIndent;
56706
+ if (barsUsable >= PRINTER_BARS_MIN_WIDTH) {
56707
+ const barsLine = buildBarsLine(r.barsTiming, scales, false, barsUsable);
56708
+ const body = `${" ".repeat(barsIndent)}${barsLine}`;
56709
+ w(renderTextLine(body, width, bg) + `
56710
+ `);
56711
+ }
56712
+ }
55311
56713
  if (r.errorDetail) {
55312
56714
  const innerUsable = width - 2 - CARD_PADDING_LEFT - CARD_PADDING_RIGHT;
55313
56715
  const errorIndent = 4;
@@ -55357,18 +56759,160 @@ function renderCard(result, isLiveProbe, w, width, directKeyVar) {
55357
56759
  w(renderBorderBottom(width) + `
55358
56760
  `);
55359
56761
  }
56762
+ function renderLegend(w) {
56763
+ const net = STAGE_BG_ANSI.network;
56764
+ const srv = STAGE_BG_ANSI.server;
56765
+ const str = STAGE_BG_ANSI.streaming;
56766
+ const netFg = hexToAnsiFg(STAGE_FG.network);
56767
+ const srvFg = hexToAnsiFg(STAGE_FG.server);
56768
+ const strFg = hexToAnsiFg(STAGE_FG.streaming);
56769
+ w(` ${pc.dim}Stages:${pc.reset} ` + `${net} ${ANSI_RESET}${netFg} network${pc.reset} ` + `${srv} ${ANSI_RESET}${srvFg} server${pc.reset} ` + `${str} ${ANSI_RESET}${strFg} streaming${pc.reset} ` + `${pc.dim}\xB7\xB7 idle${pc.reset}
56770
+ `);
56771
+ w(` ${pc.dim}bar length = total time, shared scale (slowest = full bar) \xB7 ` + `tok/s scaled to fastest${pc.reset}
56772
+ `);
56773
+ w(`
56774
+ `);
56775
+ }
56776
+ function pickRepresentative(result) {
56777
+ for (const entry of result.chain ?? []) {
56778
+ if (entry.probe?.state === "live" && entry.probe.timing) {
56779
+ return { model: result.model, provider: entry.displayName, timing: entry.probe.timing };
56780
+ }
56781
+ }
56782
+ const direct = result.directProbe;
56783
+ if (direct?.state === "live" && direct.timing) {
56784
+ return { model: result.model, provider: result.nativeProvider, timing: direct.timing };
56785
+ }
56786
+ return { model: result.model, provider: result.nativeProvider };
56787
+ }
56788
+ function renderLeaderboard(results, scales, maxWidth, w) {
56789
+ const reps = results.map(pickRepresentative);
56790
+ const live = reps.filter((r) => r.timing).sort((a, b) => a.timing.totalMs - b.timing.totalMs);
56791
+ const unavailable = reps.filter((r) => !r.timing);
56792
+ if (live.length === 0)
56793
+ return;
56794
+ const allNames = reps.map((r) => r.model);
56795
+ const rawNameW = Math.max(5, ...allNames.map((n) => n.length));
56796
+ const nameW = Math.min(rawNameW, 28);
56797
+ const allProviders = reps.map((r) => r.provider);
56798
+ const rawProvW = Math.max(8, ...allProviders.map((p) => p.length));
56799
+ const provW = Math.min(rawProvW, 18);
56800
+ const rankW = Math.max(1, String(live.length).length);
56801
+ const MARGIN = 2;
56802
+ const leadW = MARGIN + rankW + 1 + 1 + 1 + nameW + 1 + provW + 1;
56803
+ const LB_TIMELINE = PRINTER_BAR_WIDTH + 2 + 7;
56804
+ const LB_BREAKDOWN = 2 + STAGE_NUM_W2 + 1 + STAGE_NUM_W2 + 1 + STAGE_NUM_W2;
56805
+ const LB_TOKBAR = 2 + PRINTER_TOK_WIDTH + 1;
56806
+ const LB_TOK_VALUE = PRINTER_TOK_VALUE_W;
56807
+ const LB_FULL = LB_TIMELINE + LB_BREAKDOWN + LB_TOKBAR + LB_TOK_VALUE;
56808
+ const LB_NOTOK = LB_TIMELINE + LB_BREAKDOWN + 2 + LB_TOK_VALUE;
56809
+ const width = Math.min(maxWidth, leadW + LB_FULL);
56810
+ const barsBudget = Math.max(0, width - leadW);
56811
+ const showTokBar = barsBudget >= LB_FULL;
56812
+ const showBreakdown = barsBudget >= LB_NOTOK;
56813
+ const margin = " ".repeat(MARGIN);
56814
+ const netFg = hexToAnsiFg(STAGE_FG.network);
56815
+ const srvFg = hexToAnsiFg(STAGE_FG.server);
56816
+ const strFg = hexToAnsiFg(STAGE_FG.streaming);
56817
+ w(`${margin}${pc.bold}${pc.cyan}Leaderboard${pc.reset}${pc.dim} \u2014 fastest model first${pc.reset}
56818
+ `);
56819
+ const rankHdr = " ".repeat(rankW) + " ";
56820
+ const nameHdr = padEnd(`${pc.dim}MODEL${pc.reset}`, nameW);
56821
+ const provHdr = padEnd(`${pc.dim}PROVIDER${pc.reset}`, provW);
56822
+ let header = `${margin}${rankHdr}${nameHdr} ${provHdr} ${pc.dim}${padEnd("TIMELINE", PRINTER_BAR_WIDTH)}${pc.reset} ${pc.dim}${padStartSafe2("TOTAL", 7)}${pc.reset}`;
56823
+ if (showBreakdown) {
56824
+ header += `${pc.dim} ${padEnd("net", STAGE_NUM_W2)} ${padEnd("srv", STAGE_NUM_W2)} ${padEnd("str", STAGE_NUM_W2)}${pc.reset}`;
56825
+ }
56826
+ if (showTokBar) {
56827
+ header += `${pc.dim} ${padEnd("tok/s", PRINTER_TOK_WIDTH)} ${padStartSafe2("", PRINTER_TOK_VALUE_W)}${pc.reset}`;
56828
+ } else {
56829
+ header += `${pc.dim} ${padStartSafe2("tok/s", PRINTER_TOK_VALUE_W)}${pc.reset}`;
56830
+ }
56831
+ w(header + `
56832
+ `);
56833
+ live.forEach((row, idx) => {
56834
+ const t = row.timing;
56835
+ const isFastest = idx === 0;
56836
+ const rankStr = padStartSafe2(String(idx + 1), rankW);
56837
+ const dot = isFastest ? `${pc.brightGreen}\u25CF${pc.reset}` : " ";
56838
+ const name = padEnd(`${pc.bold}${truncate2(row.model, nameW)}${pc.reset}`, nameW);
56839
+ const prov = padEnd(`${pc.dim}${truncate2(row.provider, provW)}${pc.reset}`, provW);
56840
+ const barCells = timelineBarCells(t.totalMs, scales.maxTotalMs, PRINTER_BAR_WIDTH);
56841
+ const stages = splitStageCells(t.ttfbMs, t.ttftMs, t.totalMs, barCells);
56842
+ const trackCells = Math.max(0, PRINTER_BAR_WIDTH - barCells);
56843
+ let timeline = "";
56844
+ if (stages.network > 0)
56845
+ timeline += `${STAGE_BG_ANSI.network}${" ".repeat(stages.network)}${ANSI_RESET}`;
56846
+ if (stages.server > 0)
56847
+ timeline += `${STAGE_BG_ANSI.server}${" ".repeat(stages.server)}${ANSI_RESET}`;
56848
+ if (stages.streaming > 0)
56849
+ timeline += `${STAGE_BG_ANSI.streaming}${" ".repeat(stages.streaming)}${ANSI_RESET}`;
56850
+ if (trackCells > 0)
56851
+ timeline += `${pc.dim}${PRINTER_TRACK.repeat(trackCells)}${pc.reset}`;
56852
+ const total = `${LATENCY_FG_ANSI}${padStartSafe2(formatLatency(t.totalMs), 7)}${pc.reset}`;
56853
+ let breakdown = "";
56854
+ if (showBreakdown) {
56855
+ const netMs = Math.max(0, t.ttfbMs);
56856
+ const srvMs = Math.max(0, t.ttftMs - t.ttfbMs);
56857
+ const strMs = Math.max(0, t.totalMs - t.ttftMs);
56858
+ breakdown = ` ${netFg}${padStartSafe2(breakdownNum2(netMs), STAGE_NUM_W2)}${pc.reset}` + ` ${srvFg}${padStartSafe2(breakdownNum2(srvMs), STAGE_NUM_W2)}${pc.reset}` + ` ${strFg}${padStartSafe2(breakdownNum2(strMs), STAGE_NUM_W2)}${pc.reset}`;
56859
+ }
56860
+ const tokFg = hexToAnsiFg(throughputFg(t.tokensPerSec));
56861
+ let tokBar = " ";
56862
+ if (showTokBar) {
56863
+ const tokCells = tokBarCells(t.tokensPerSec, scales.maxTokPerSec, PRINTER_TOK_WIDTH);
56864
+ const tokTrack = Math.max(0, PRINTER_TOK_WIDTH - tokCells);
56865
+ let bar = "";
56866
+ if (tokCells > 0)
56867
+ bar += `${tokFg}${PRINTER_BAR_FILL.repeat(tokCells)}${pc.reset}`;
56868
+ if (tokTrack > 0)
56869
+ bar += `${pc.dim}${PRINTER_TRACK.repeat(tokTrack)}${pc.reset}`;
56870
+ tokBar = ` ${bar} `;
56871
+ }
56872
+ const tokValue = `${tokFg}${padStartSafe2(`${Math.round(t.tokensPerSec)} t/s`, PRINTER_TOK_VALUE_W)}${pc.reset}`;
56873
+ w(`${margin}${rankStr} ${dot} ${name} ${prov} ${timeline} ${total}${breakdown}${tokBar}${tokValue}
56874
+ `);
56875
+ });
56876
+ for (const row of unavailable) {
56877
+ const rankStr = " ".repeat(rankW);
56878
+ const name = padEnd(`${pc.dim}${truncate2(row.model, nameW)}${pc.reset}`, nameW);
56879
+ const prov = padEnd(`${pc.dim}${truncate2(row.provider, provW)}${pc.reset}`, provW);
56880
+ w(`${margin}${rankStr} ${name} ${prov} ${pc.dim}\u2014 no live route${pc.reset}
56881
+ `);
56882
+ }
56883
+ const rowVis = leadW - MARGIN + LB_TIMELINE + (showBreakdown ? LB_BREAKDOWN : 0) + (showTokBar ? LB_TOKBAR : 2) + LB_TOK_VALUE;
56884
+ const ruleW = Math.max(10, rowVis);
56885
+ w(`${margin}${pc.dim}${"\u2500".repeat(ruleW)}${pc.reset}
56886
+ `);
56887
+ w(`
56888
+ `);
56889
+ }
55360
56890
  function printProbeResults(results, isLiveProbe) {
55361
56891
  const w = process.stderr.write.bind(process.stderr);
55362
56892
  w(`
55363
56893
  `);
56894
+ const scales = computeBarScales(results);
56895
+ const anyTimedLive = results.some((r) => r.directProbe?.state === "live" && r.directProbe.timing !== undefined) || results.some((r) => (r.chain ?? []).some((c) => c.probe?.state === "live" && c.probe.timing !== undefined));
56896
+ if (isLiveProbe && anyTimedLive) {
56897
+ renderLegend(w);
56898
+ }
55364
56899
  const requiredWidths = results.map((r) => computeRequiredWidth(r, isLiveProbe));
55365
56900
  const termCols = process.stderr.columns ?? process.stdout.columns ?? 100;
55366
56901
  const maxAllowed = Math.max(MIN_CARD_WIDTH, termCols - 4);
55367
56902
  let globalWidth = requiredWidths.reduce((a, b) => Math.max(a, b), MIN_CARD_WIDTH);
55368
56903
  if (globalWidth > maxAllowed)
55369
56904
  globalWidth = maxAllowed;
56905
+ const showedLeaderboard = isLiveProbe && anyTimedLive;
56906
+ if (showedLeaderboard) {
56907
+ renderLeaderboard(results, scales, maxAllowed, w);
56908
+ }
56909
+ if (showedLeaderboard) {
56910
+ w(` ${pc.bold}${pc.cyan}Details${pc.reset}${pc.dim} \u2014 per-model routing chains${pc.reset}
56911
+
56912
+ `);
56913
+ }
55370
56914
  for (const result of results) {
55371
- renderCard(result, isLiveProbe, w, globalWidth);
56915
+ renderCard(result, isLiveProbe, w, globalWidth, scales);
55372
56916
  w(`
55373
56917
  `);
55374
56918
  }
@@ -55377,9 +56921,10 @@ function printProbeResults(results, isLiveProbe) {
55377
56921
  w(`
55378
56922
  `);
55379
56923
  }
55380
- var pc, ANSI_RE2, MIN_CARD_WIDTH = 60, CARD_PADDING_LEFT = 2, CARD_PADDING_RIGHT = 2;
56924
+ var pc, ANSI_RE2, PRINTER_BAR_WIDTH = 24, PRINTER_TOK_WIDTH = 14, PRINTER_TRACK = "\xB7", PRINTER_BAR_FILL = "\u2588", STAGE_NUM_W2 = 6, PRINTER_TOK_VALUE_W = 9, PRINTER_BARS_FULL_WIDTH, PRINTER_BARS_NOTOK_WIDTH, PRINTER_BARS_MIN_WIDTH, MIN_CARD_WIDTH = 60, CARD_PADDING_LEFT = 2, CARD_PADDING_RIGHT = 2;
55381
56925
  var init_probe_results_printer = __esm(() => {
55382
56926
  init_probe_live();
56927
+ init_theme2();
55383
56928
  pc = {
55384
56929
  reset: "\x1B[0m",
55385
56930
  bold: "\x1B[1m",
@@ -55394,6 +56939,9 @@ var init_probe_results_printer = __esm(() => {
55394
56939
  bgSlowest: "\x1B[48;5;95m"
55395
56940
  };
55396
56941
  ANSI_RE2 = /\x1b\[[0-9;]*[A-Za-z]/g;
56942
+ PRINTER_BARS_FULL_WIDTH = 24 + 2 + 7 + 34 + 17 + 9;
56943
+ PRINTER_BARS_NOTOK_WIDTH = 24 + 2 + 7 + 34 + 2 + 9;
56944
+ PRINTER_BARS_MIN_WIDTH = 24 + 2 + 7 + 2 + 9;
55397
56945
  });
55398
56946
 
55399
56947
  // src/cli.ts
@@ -56164,6 +57712,20 @@ async function probeModelRouting(models, jsonOutput, options = { live: true, tim
56164
57712
  matchedPattern: undefined
56165
57713
  };
56166
57714
  }
57715
+ if (parsed.provider === "native-anthropic") {
57716
+ const opusModel = process.env[ENV.CLAUDISH_MODEL_OPUS] || process.env[ENV.ANTHROPIC_DEFAULT_OPUS_MODEL] || "claude-opus-4-1";
57717
+ return {
57718
+ routes: [
57719
+ {
57720
+ provider: "native-anthropic",
57721
+ modelSpec: opusModel,
57722
+ displayName: "Claude Code (Opus)"
57723
+ }
57724
+ ],
57725
+ source: "auto-chain",
57726
+ matchedPattern: undefined
57727
+ };
57728
+ }
56167
57729
  const routingRules = loadRoutingRules();
56168
57730
  const matched = matchRoutingRule(parsed.model, routingRules);
56169
57731
  if (matched) {
@@ -56197,7 +57759,12 @@ async function probeModelRouting(models, jsonOutput, options = { live: true, tim
56197
57759
  let hasCredentials = false;
56198
57760
  let credentialHint;
56199
57761
  let provenance;
56200
- if (providerDef?.isLocal) {
57762
+ if (route2.provider === "native-anthropic") {
57763
+ hasCredentials = !!process.env.ANTHROPIC_API_KEY;
57764
+ if (!hasCredentials) {
57765
+ credentialHint = "ANTHROPIC_API_KEY (required to probe Claude Code)";
57766
+ }
57767
+ } else if (providerDef?.isLocal) {
56201
57768
  hasCredentials = isLocalProviderEnabled(route2.provider);
56202
57769
  if (!hasCredentials) {
56203
57770
  credentialHint = "enable local provider in global config";
@@ -56228,6 +57795,49 @@ async function probeModelRouting(models, jsonOutput, options = { live: true, tim
56228
57795
  });
56229
57796
  return { parsed, chain, chainDetails };
56230
57797
  }
57798
+ function buildRoutingExplanation(parsed, chain) {
57799
+ if (parsed.provider === "native-anthropic") {
57800
+ return "native passthrough \xB7 default Claude Code (Opus)";
57801
+ }
57802
+ if (chain.source === "direct") {
57803
+ return `explicit \xB7 ${parsed.provider} (direct)`;
57804
+ }
57805
+ if (chain.source === "custom-rules" && chain.matchedPattern) {
57806
+ return `custom-rules \xB7 matched \`${chain.matchedPattern}\``;
57807
+ }
57808
+ if (chain.source === "auto-chain") {
57809
+ if (chain.matchedPattern && chain.matchedPattern !== "*") {
57810
+ return `auto-chain \xB7 default rule \`${chain.matchedPattern}\``;
57811
+ }
57812
+ return "auto-chain \xB7 catch-all \u2192 openrouter";
57813
+ }
57814
+ return chain.source;
57815
+ }
57816
+ function buildResultLinks(parsed, chainDetails, directProbe) {
57817
+ if (chainDetails.length === 0) {
57818
+ const directProviderDef = getProviderByName(parsed.provider);
57819
+ const directKeyInfo = API_KEY_MAP[parsed.provider];
57820
+ const directHasCreds = directProviderDef?.isLocal ? isLocalProviderEnabled(parsed.provider) : directKeyInfo?.envVar ? !!process.env[directKeyInfo.envVar] || (directKeyInfo.aliases?.some((a) => !!process.env[a]) ?? false) : true;
57821
+ return [
57822
+ {
57823
+ provider: parsed.provider,
57824
+ displayName: directProviderDef?.displayName ?? parsed.provider,
57825
+ modelId: parsed.model,
57826
+ hasCredentials: directHasCreds,
57827
+ credentialHint: directProviderDef?.isLocal && !directHasCreds ? "enable local provider in global config" : directKeyInfo?.envVar,
57828
+ probe: directProbe
57829
+ }
57830
+ ];
57831
+ }
57832
+ return chainDetails.map((c) => ({
57833
+ provider: c.provider,
57834
+ displayName: c.displayName,
57835
+ modelId: c.modelSpec.includes("@") ? c.modelSpec.slice(c.modelSpec.indexOf("@") + 1) : c.modelSpec,
57836
+ hasCredentials: c.hasCredentials,
57837
+ credentialHint: c.credentialHint,
57838
+ probe: c.probe
57839
+ }));
57840
+ }
56231
57841
  async function computeWiring(chainDetails, parsedModel) {
56232
57842
  const firstReadyRoute = chainDetails.find((c) => c.hasCredentials);
56233
57843
  if (!firstReadyRoute)
@@ -56360,7 +57970,10 @@ async function probeModelRouting(models, jsonOutput, options = { live: true, tim
56360
57970
  }
56361
57971
  const initialState = {
56362
57972
  steps: [],
56363
- links: []
57973
+ links: [],
57974
+ phase: "live",
57975
+ results: [],
57976
+ activeTab: "summary"
56364
57977
  };
56365
57978
  const tui = await startProbeTui(initialState);
56366
57979
  const addStep = (name, status) => {
@@ -56467,7 +58080,11 @@ async function probeModelRouting(models, jsonOutput, options = { live: true, tim
56467
58080
  errorMessage: String(e instanceof Error ? e.message : e)
56468
58081
  }));
56469
58082
  if (result.state === "live") {
56470
- updateLink(link.id, { status: "live", endTime: Date.now() });
58083
+ updateLink(link.id, {
58084
+ status: "live",
58085
+ endTime: Date.now(),
58086
+ timing: result.timing
58087
+ });
56471
58088
  } else {
56472
58089
  updateLink(link.id, {
56473
58090
  status: "failed",
@@ -56485,8 +58102,10 @@ async function probeModelRouting(models, jsonOutput, options = { live: true, tim
56485
58102
  }
56486
58103
  const isLiveProbe = !!liveProxy;
56487
58104
  const printable = [];
58105
+ const results = [];
56488
58106
  for (const { modelInput, parsed, chain, chainDetails } of modelChains) {
56489
58107
  const wiring = await computeWiring(chainDetails, parsed.model);
58108
+ const directProbe = directProbeResults.get(modelInput);
56490
58109
  printable.push({
56491
58110
  model: modelInput,
56492
58111
  nativeProvider: parsed.provider,
@@ -56502,18 +58121,41 @@ async function probeModelRouting(models, jsonOutput, options = { live: true, tim
56502
58121
  provenance: c.provenance,
56503
58122
  probe: c.probe
56504
58123
  })),
56505
- directProbe: directProbeResults.get(modelInput),
58124
+ directProbe,
58125
+ wiring
58126
+ });
58127
+ results.push({
58128
+ model: modelInput,
58129
+ nativeProvider: parsed.provider,
58130
+ isExplicit: parsed.isExplicitProvider,
58131
+ routingSource: chain.source,
58132
+ matchedPattern: chain.matchedPattern,
58133
+ routingExplanation: buildRoutingExplanation(parsed, chain),
58134
+ links: buildResultLinks(parsed, chainDetails, directProbe),
56506
58135
  wiring
56507
58136
  });
56508
58137
  }
56509
- if (liveProxy) {
56510
- try {
56511
- await liveProxy.shutdown();
56512
- } catch {}
56513
- liveProxy = null;
58138
+ const interactive = !!process.stdout.isTTY && !!process.stderr.isTTY;
58139
+ if (interactive) {
58140
+ if (liveProxy) {
58141
+ try {
58142
+ await liveProxy.shutdown();
58143
+ } catch {}
58144
+ liveProxy = null;
58145
+ }
58146
+ tui.store.setResults(results);
58147
+ await tui.waitForQuit();
58148
+ await tui.shutdown();
58149
+ } else {
58150
+ if (liveProxy) {
58151
+ try {
58152
+ await liveProxy.shutdown();
58153
+ } catch {}
58154
+ liveProxy = null;
58155
+ }
58156
+ await tui.shutdown();
58157
+ printProbeResults(printable, isLiveProbe);
56514
58158
  }
56515
- await tui.shutdown();
56516
- printProbeResults(printable, isLiveProbe);
56517
58159
  } finally {
56518
58160
  if (liveProxy) {
56519
58161
  try {
@@ -58045,7 +59687,7 @@ var init_providers = __esm(() => {
58045
59687
  });
58046
59688
 
58047
59689
  // src/tui/constants.ts
58048
- var COMMON_MODELS, PROVIDER_PREFIXES, CHAIN_PROVIDERS, HEADER_H = 1, TABS_H = 3, FOOTER_H = 1, DETAIL_H = 7, VERSION2 = "v5.16";
59690
+ var COMMON_MODELS, PROVIDER_PREFIXES, CHAIN_PROVIDERS, HEADER_H = 2, TABS_H = 3, FOOTER_H = 1, DETAIL_H = 7;
58049
59691
  var init_constants3 = __esm(() => {
58050
59692
  init_providers();
58051
59693
  COMMON_MODELS = [
@@ -58239,6 +59881,7 @@ function useProfileWizard(args) {
58239
59881
  const [suggestions, setSuggestions] = useState4([]);
58240
59882
  const [suggestionIndex, setSuggestionIndex] = useState4(-1);
58241
59883
  const [providerPickerIndex, setProviderPickerIndex] = useState4(0);
59884
+ const [scopeCursor, setScopeCursor] = useState4(0);
58242
59885
  const [providerPickerReturnMode, setProviderPickerReturnMode] = useState4("edit_profile_opus");
58243
59886
  const saveModelField = useCallback2((currentMode, fieldVal) => {
58244
59887
  const val = fieldVal.trim() === "auto" ? undefined : fieldVal.trim();
@@ -58304,6 +59947,7 @@ function useProfileWizard(args) {
58304
59947
  const startNewProfile = useCallback2(() => {
58305
59948
  setEditProfileValue("");
58306
59949
  setProfileScope("global");
59950
+ setScopeCursor(0);
58307
59951
  setMode("pick_profile_scope");
58308
59952
  setStatusMsg(null);
58309
59953
  }, [setMode, setStatusMsg]);
@@ -58322,9 +59966,19 @@ function useProfileWizard(args) {
58322
59966
  }, [setMode, setStatusMsg]);
58323
59967
  const pickScope = useCallback2((scope) => {
58324
59968
  setProfileScope(scope);
59969
+ setScopeCursor(scope === "global" ? 0 : 1);
58325
59970
  setEditProfileValue("");
58326
59971
  setMode("new_profile");
58327
59972
  }, [setMode]);
59973
+ const pickScopeAtCursor = useCallback2(() => {
59974
+ pickScope(scopeCursor === 0 ? "global" : "project");
59975
+ }, [pickScope, scopeCursor]);
59976
+ const setScopeCursorVerb = useCallback2((index) => {
59977
+ setScopeCursor(index === 0 ? 0 : 1);
59978
+ }, []);
59979
+ const setProviderPickerIndexVerb = useCallback2((index) => {
59980
+ setProviderPickerIndex(index < 0 ? 0 : index);
59981
+ }, []);
58328
59982
  const cancelPickScope = useCallback2(() => {
58329
59983
  setMode("browse");
58330
59984
  }, [setMode]);
@@ -58519,8 +60173,12 @@ function useProfileWizard(args) {
58519
60173
  suggestions,
58520
60174
  suggestionIndex,
58521
60175
  providerPickerIndex,
60176
+ scopeCursor,
58522
60177
  startNewProfile,
58523
60178
  pickScope,
60179
+ pickScopeAtCursor,
60180
+ setScopeCursor: setScopeCursorVerb,
60181
+ setProviderPickerIndex: setProviderPickerIndexVerb,
58524
60182
  cancelPickScope,
58525
60183
  startEditExisting,
58526
60184
  newProfileSubmit,
@@ -58561,7 +60219,7 @@ var init_useProfileWizard = __esm(() => {
58561
60219
 
58562
60220
  // src/tui/components/TabBar.tsx
58563
60221
  import { jsxDEV as jsxDEV3 } from "@opentui/react/jsx-dev-runtime";
58564
- function TabBar({ activeTab, statusMsg, width }) {
60222
+ function TabBar2({ activeTab, statusMsg }) {
58565
60223
  const tabs = [
58566
60224
  { label: "Providers", value: "providers", num: "1" },
58567
60225
  { label: "Profiles", value: "profiles", num: "2" },
@@ -58614,11 +60272,11 @@ function TabBar({ activeTab, statusMsg, width }) {
58614
60272
  /* @__PURE__ */ jsxDEV3("box", {
58615
60273
  height: 1,
58616
60274
  paddingX: 1,
58617
- children: /* @__PURE__ */ jsxDEV3("text", {
58618
- children: /* @__PURE__ */ jsxDEV3("span", {
58619
- fg: C.tabActiveBg,
58620
- children: "\u2500".repeat(Math.max(0, width - 2))
58621
- }, undefined, false, undefined, this)
60275
+ children: /* @__PURE__ */ jsxDEV3("box", {
60276
+ flexGrow: 1,
60277
+ border: ["top"],
60278
+ borderStyle: "single",
60279
+ borderColor: C.tabActiveBg
58622
60280
  }, undefined, false, undefined, this)
58623
60281
  }, undefined, false, undefined, this),
58624
60282
  /* @__PURE__ */ jsxDEV3("box", {
@@ -58691,26 +60349,8 @@ function Footer({ activeTab, mode, probeMode, providerCaps }) {
58691
60349
  if (showRemove)
58692
60350
  keys.push([C.red, "x", "remove"]);
58693
60351
  keys.push([C.dim, "q", "quit"]);
58694
- } else if (activeTab === "profiles" && mode === "pick_profile_scope") {
58695
- keys = [
58696
- [C.green, "g", "global"],
58697
- [C.cyan, "p", "project"],
58698
- [C.red, "Esc", "cancel"]
58699
- ];
58700
- } else if (activeTab === "profiles" && mode === "pick_provider_prefix") {
58701
- keys = [
58702
- [C.blue, "\u2191\u2193", "navigate"],
58703
- [C.green, "Enter", "select prefix"],
58704
- [C.red, "Esc", "back"]
58705
- ];
58706
60352
  } else if (activeTab === "profiles" && isProfileEditMode) {
58707
- keys = [
58708
- [C.green, "Enter", "save field"],
58709
- [C.blue, "Tab", "provider picker"],
58710
- [C.blue, "\u2191\u2193", "suggestion"],
58711
- [C.yellow, "a", "auto-route"],
58712
- [C.red, "Esc", "cancel"]
58713
- ];
60353
+ keys = [[C.dim, "wizard", "follow the panel above"]];
58714
60354
  } else if (activeTab === "profiles") {
58715
60355
  keys = [
58716
60356
  [C.blue, "\u2191\u2193", "navigate"],
@@ -58752,24 +60392,22 @@ function Footer({ activeTab, mode, probeMode, providerCaps }) {
58752
60392
  paddingX: 1,
58753
60393
  backgroundColor: C.bgAlt,
58754
60394
  children: /* @__PURE__ */ jsxDEV4("text", {
58755
- children: keys.map(([color, key, label], i) => /* @__PURE__ */ jsxDEV4("span", {
60395
+ children: keys.map(([_color, key, label], i) => /* @__PURE__ */ jsxDEV4("span", {
58756
60396
  children: [
58757
60397
  i > 0 && /* @__PURE__ */ jsxDEV4("span", {
58758
- fg: C.dim,
58759
- children: " \u2502 "
60398
+ children: " "
58760
60399
  }, undefined, false, undefined, this),
58761
60400
  /* @__PURE__ */ jsxDEV4("span", {
58762
- fg: color,
60401
+ fg: C.fg,
60402
+ bg: C.chipKeyBg,
58763
60403
  attributes: A.bold,
58764
- children: key
60404
+ children: ` ${key} `
58765
60405
  }, undefined, false, undefined, this),
58766
60406
  /* @__PURE__ */ jsxDEV4("span", {
58767
60407
  fg: C.fgMuted,
58768
- children: [
58769
- " ",
58770
- label
58771
- ]
58772
- }, undefined, true, undefined, this)
60408
+ bg: C.chipLabelBg,
60409
+ children: `${label} `
60410
+ }, undefined, false, undefined, this)
58773
60411
  ]
58774
60412
  }, i, true, undefined, this))
58775
60413
  }, undefined, false, undefined, this)
@@ -58807,13 +60445,21 @@ function ProvidersContent({
58807
60445
  displayProviders,
58808
60446
  providerIndex,
58809
60447
  testResults,
58810
- width,
58811
60448
  contentH,
58812
60449
  isInputMode,
58813
60450
  animTick
58814
60451
  }) {
58815
- const listH = contentH - 4;
58816
- let separatorRendered = false;
60452
+ const firstUnreadyIdx = displayProviders.findIndex((p) => providerAuthSource(p, config3) === null);
60453
+ const hasDivider = firstUnreadyIdx >= 0;
60454
+ const listH = contentH - 4 - (hasDivider ? 1 : 0);
60455
+ const scrollOffset = (() => {
60456
+ if (listH <= 0 || displayProviders.length <= listH)
60457
+ return 0;
60458
+ if (providerIndex < listH)
60459
+ return 0;
60460
+ const maxOffset = displayProviders.length - listH;
60461
+ return Math.min(providerIndex - listH + 1, maxOffset);
60462
+ })();
58817
60463
  const getRow = (p, idx) => {
58818
60464
  const auth = providerAuthSource(p, config3);
58819
60465
  const caps = providerAuthCapabilities(p, config3);
@@ -58836,9 +60482,7 @@ function ProvidersContent({
58836
60482
  } else {
58837
60483
  keyDisplay = "\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500";
58838
60484
  }
58839
- const isFirstUnready = !isReady && !separatorRendered;
58840
- if (isFirstUnready)
58841
- separatorRendered = true;
60485
+ const isFirstUnready = idx === firstUnreadyIdx;
58842
60486
  let statusFg = isReady ? C.green : C.dim;
58843
60487
  let statusText = p.isLocal ? isReady ? "enabled" : "disabled" : isReady ? "ready" : "not set";
58844
60488
  if (tr) {
@@ -58863,17 +60507,23 @@ function ProvidersContent({
58863
60507
  children: [
58864
60508
  isFirstUnready && /* @__PURE__ */ jsxDEV5("box", {
58865
60509
  height: 1,
60510
+ flexDirection: "row",
58866
60511
  paddingX: 1,
58867
- children: /* @__PURE__ */ jsxDEV5("text", {
58868
- children: /* @__PURE__ */ jsxDEV5("span", {
58869
- fg: C.dim,
58870
- children: [
58871
- "\u2500 not configured ",
58872
- "\u2500".repeat(Math.max(0, width - 22))
58873
- ]
58874
- }, undefined, true, undefined, this)
58875
- }, undefined, false, undefined, this)
58876
- }, undefined, false, undefined, this),
60512
+ children: [
60513
+ /* @__PURE__ */ jsxDEV5("text", {
60514
+ children: /* @__PURE__ */ jsxDEV5("span", {
60515
+ fg: C.dim,
60516
+ children: "\u2500 not configured "
60517
+ }, undefined, false, undefined, this)
60518
+ }, undefined, false, undefined, this),
60519
+ /* @__PURE__ */ jsxDEV5("box", {
60520
+ flexGrow: 1,
60521
+ border: ["top"],
60522
+ borderStyle: "single",
60523
+ borderColor: C.dim
60524
+ }, undefined, false, undefined, this)
60525
+ ]
60526
+ }, undefined, true, undefined, this),
58877
60527
  /* @__PURE__ */ jsxDEV5("box", {
58878
60528
  height: 1,
58879
60529
  flexGrow: 1,
@@ -59006,7 +60656,7 @@ function ProvidersContent({
59006
60656
  /* @__PURE__ */ jsxDEV5("box", {
59007
60657
  flexDirection: "column",
59008
60658
  style: { flexGrow: 1 },
59009
- children: displayProviders.slice(0, listH).map(getRow)
60659
+ children: displayProviders.slice(scrollOffset, scrollOffset + listH).map((p, i) => getRow(p, scrollOffset + i))
59010
60660
  }, undefined, false, undefined, this),
59011
60661
  /* @__PURE__ */ jsxDEV5("text", {
59012
60662
  height: 1,
@@ -59339,20 +60989,45 @@ var init_ProviderDetail = __esm(() => {
59339
60989
 
59340
60990
  // src/tui/components/ProfilesContent.tsx
59341
60991
  import { jsxDEV as jsxDEV7, Fragment as Fragment4 } from "@opentui/react/jsx-dev-runtime";
60992
+ function stepLabel(mode) {
60993
+ const idx = WIZARD_STEPS.indexOf(mode);
60994
+ const stepNo = idx >= 0 ? idx + 1 : 0;
60995
+ const prefix = stepNo > 0 ? `Step ${stepNo} of ${TOTAL_STEPS} \u2014 ` : "";
60996
+ switch (mode) {
60997
+ case "pick_profile_scope":
60998
+ return { title: "New Profile", header: `${prefix}Choose scope` };
60999
+ case "new_profile":
61000
+ return { title: "New Profile", header: `${prefix}Profile name` };
61001
+ case "edit_profile_opus":
61002
+ return { title: "New Profile", header: `${prefix}opus model` };
61003
+ case "edit_profile_sonnet":
61004
+ return { title: "New Profile", header: `${prefix}sonnet model` };
61005
+ case "edit_profile_haiku":
61006
+ return { title: "New Profile", header: `${prefix}haiku model` };
61007
+ case "edit_profile_subagent":
61008
+ return { title: "New Profile", header: `${prefix}subagent model (optional)` };
61009
+ case "pick_provider_prefix":
61010
+ return { title: "Choose provider", header: "Pick a provider prefix" };
61011
+ default:
61012
+ return { title: "New Profile", header: "" };
61013
+ }
61014
+ }
59342
61015
  function ProfilesContent({
59343
61016
  config: config3,
59344
61017
  activeTab,
59345
61018
  mode,
59346
61019
  profileScope,
59347
61020
  profileIndex,
59348
- editProfileName,
59349
61021
  editProfileValue,
59350
61022
  suggestions,
59351
61023
  suggestionIndex,
59352
61024
  providerPickerIndex,
59353
- contentH
61025
+ contentH,
61026
+ onScopeChange,
61027
+ onPrefixChange
59354
61028
  }) {
59355
61029
  const isProfileEditMode = mode === "new_profile" || mode === "pick_profile_scope" || mode === "pick_provider_prefix" || mode === "edit_profile_opus" || mode === "edit_profile_sonnet" || mode === "edit_profile_haiku" || mode === "edit_profile_subagent";
61030
+ const isTextStep = mode === "new_profile" || mode === "edit_profile_opus" || mode === "edit_profile_sonnet" || mode === "edit_profile_haiku" || mode === "edit_profile_subagent";
59356
61031
  const globalCfg = config3;
59357
61032
  const localCfg = loadLocalConfig();
59358
61033
  const localProfileNames = localCfg ? new Set(Object.keys(localCfg.profiles)) : new Set;
@@ -59367,7 +61042,17 @@ function ProfilesContent({
59367
61042
  }
59368
61043
  const activeProfileName = globalCfg.defaultProfile;
59369
61044
  const listH = contentH - 2;
59370
- const editPromptLabel = mode === "new_profile" ? `New ${profileScope} profile \u2014 name:` : mode === "pick_profile_scope" ? "Scope for new profile:" : mode === "pick_provider_prefix" ? "Select provider:" : mode === "edit_profile_opus" ? `${editProfileName} \u2014 opus model:` : mode === "edit_profile_sonnet" ? `${editProfileName} \u2014 sonnet model:` : mode === "edit_profile_haiku" ? `${editProfileName} \u2014 haiku model:` : mode === "edit_profile_subagent" ? `${editProfileName} \u2014 subagent model (optional):` : null;
61045
+ const { title: modalTitle, header: modalHeader } = stepLabel(mode);
61046
+ const scopeOptions = [
61047
+ { name: "global ~/.claudish/config.json", description: "", value: "global" },
61048
+ { name: "project ./.claudish.json", description: "", value: "project" }
61049
+ ];
61050
+ const prefixColW = PROVIDER_PREFIXES.reduce((max, p) => Math.max(max, p.prefix.length), 0) + 2;
61051
+ const prefixOptions = PROVIDER_PREFIXES.map((p) => ({
61052
+ name: `${p.prefix.padEnd(prefixColW)}${p.displayName}`,
61053
+ description: "",
61054
+ value: p.prefix
61055
+ }));
59371
61056
  return /* @__PURE__ */ jsxDEV7("box", {
59372
61057
  height: contentH,
59373
61058
  border: true,
@@ -59472,97 +61157,69 @@ function ProfilesContent({
59472
61157
  children: " No project-level profiles (.claudish.json)"
59473
61158
  }, undefined, false, undefined, this)
59474
61159
  }, undefined, false, undefined, this),
59475
- isProfileEditMode && editPromptLabel && /* @__PURE__ */ jsxDEV7("box", {
61160
+ isProfileEditMode && /* @__PURE__ */ jsxDEV7("box", {
61161
+ border: true,
61162
+ borderStyle: "rounded",
61163
+ borderColor: C.blue,
61164
+ title: modalTitle,
61165
+ titleAlignment: "left",
61166
+ backgroundColor: C.bg,
59476
61167
  flexDirection: "column",
59477
- paddingTop: 1,
61168
+ paddingX: 1,
61169
+ marginTop: 1,
59478
61170
  children: [
59479
61171
  /* @__PURE__ */ jsxDEV7("text", {
59480
61172
  children: /* @__PURE__ */ jsxDEV7("span", {
59481
- fg: C.blue,
61173
+ fg: C.cyan,
59482
61174
  attributes: A.bold,
59483
- children: editPromptLabel + " "
61175
+ children: modalHeader
59484
61176
  }, undefined, false, undefined, this)
59485
61177
  }, undefined, false, undefined, this),
59486
61178
  mode === "pick_profile_scope" && /* @__PURE__ */ jsxDEV7("box", {
59487
61179
  flexDirection: "column",
61180
+ paddingTop: 1,
59488
61181
  children: [
59489
- /* @__PURE__ */ jsxDEV7("box", {
59490
- height: 1,
59491
- flexDirection: "row",
59492
- children: [
59493
- /* @__PURE__ */ jsxDEV7("box", {
59494
- width: 16,
59495
- height: 1,
59496
- backgroundColor: C.bgHighlight,
59497
- paddingX: 1,
59498
- children: /* @__PURE__ */ jsxDEV7("text", {
59499
- children: [
59500
- /* @__PURE__ */ jsxDEV7("span", {
59501
- fg: C.green,
59502
- attributes: A.bold,
59503
- children: "g"
59504
- }, undefined, false, undefined, this),
59505
- /* @__PURE__ */ jsxDEV7("span", {
59506
- fg: C.white,
59507
- children: " global"
59508
- }, undefined, false, undefined, this)
59509
- ]
59510
- }, undefined, true, undefined, this)
59511
- }, undefined, false, undefined, this),
59512
- /* @__PURE__ */ jsxDEV7("box", {
59513
- width: 2
59514
- }, undefined, false, undefined, this),
59515
- /* @__PURE__ */ jsxDEV7("box", {
59516
- width: 16,
59517
- height: 1,
59518
- paddingX: 1,
59519
- children: /* @__PURE__ */ jsxDEV7("text", {
59520
- children: [
59521
- /* @__PURE__ */ jsxDEV7("span", {
59522
- fg: C.cyan,
59523
- attributes: A.bold,
59524
- children: "p"
59525
- }, undefined, false, undefined, this),
59526
- /* @__PURE__ */ jsxDEV7("span", {
59527
- fg: C.fgMuted,
59528
- children: " project (.claudish.json)"
59529
- }, undefined, false, undefined, this)
59530
- ]
59531
- }, undefined, true, undefined, this)
59532
- }, undefined, false, undefined, this)
59533
- ]
59534
- }, undefined, true, undefined, this),
61182
+ /* @__PURE__ */ jsxDEV7("select", {
61183
+ options: scopeOptions,
61184
+ focused: true,
61185
+ showDescription: false,
61186
+ wrapSelection: true,
61187
+ onChange: onScopeChange,
61188
+ backgroundColor: C.bg,
61189
+ textColor: C.fgMuted,
61190
+ selectedBackgroundColor: C.bgHighlight,
61191
+ selectedTextColor: C.white,
61192
+ height: scopeOptions.length
61193
+ }, undefined, false, undefined, this),
61194
+ /* @__PURE__ */ jsxDEV7("text", {
61195
+ children: /* @__PURE__ */ jsxDEV7("span", {
61196
+ fg: C.dim,
61197
+ children: " "
61198
+ }, undefined, false, undefined, this)
61199
+ }, undefined, false, undefined, this),
59535
61200
  /* @__PURE__ */ jsxDEV7("text", {
59536
61201
  children: [
59537
- /* @__PURE__ */ jsxDEV7("span", {
59538
- fg: C.green,
59539
- attributes: A.bold,
59540
- children: [
59541
- "g",
59542
- " "
59543
- ]
59544
- }, undefined, true, undefined, this),
59545
61202
  /* @__PURE__ */ jsxDEV7("span", {
59546
61203
  fg: C.fgMuted,
59547
- children: "global \xB7 "
61204
+ children: "\u2191\u2193 move \xB7 "
59548
61205
  }, undefined, false, undefined, this),
59549
61206
  /* @__PURE__ */ jsxDEV7("span", {
59550
- fg: C.cyan,
61207
+ fg: C.green,
59551
61208
  attributes: A.bold,
59552
61209
  children: [
59553
- "p",
61210
+ "\u23CE",
59554
61211
  " "
59555
61212
  ]
59556
61213
  }, undefined, true, undefined, this),
59557
61214
  /* @__PURE__ */ jsxDEV7("span", {
59558
61215
  fg: C.fgMuted,
59559
- children: "project \xB7 "
61216
+ children: "next \xB7 "
59560
61217
  }, undefined, false, undefined, this),
59561
61218
  /* @__PURE__ */ jsxDEV7("span", {
59562
61219
  fg: C.red,
59563
61220
  attributes: A.bold,
59564
61221
  children: [
59565
- "Esc",
61222
+ "esc",
59566
61223
  " "
59567
61224
  ]
59568
61225
  }, undefined, true, undefined, this),
@@ -59576,63 +61233,51 @@ function ProfilesContent({
59576
61233
  }, undefined, true, undefined, this),
59577
61234
  mode === "pick_provider_prefix" && /* @__PURE__ */ jsxDEV7("box", {
59578
61235
  flexDirection: "column",
61236
+ paddingTop: 1,
59579
61237
  children: [
59580
- PROVIDER_PREFIXES.slice(0, 8).map((p, idx) => /* @__PURE__ */ jsxDEV7("box", {
59581
- height: 1,
59582
- backgroundColor: idx === providerPickerIndex ? C.bgHighlight : C.bg,
59583
- children: /* @__PURE__ */ jsxDEV7("text", {
59584
- children: [
59585
- /* @__PURE__ */ jsxDEV7("span", {
59586
- fg: idx === providerPickerIndex ? C.white : C.dim,
59587
- children: " "
59588
- }, undefined, false, undefined, this),
59589
- /* @__PURE__ */ jsxDEV7("span", {
59590
- fg: idx === providerPickerIndex ? C.cyan : C.fgMuted,
59591
- attributes: A.boldIf(idx === providerPickerIndex),
59592
- children: p.prefix.padEnd(14).substring(0, 14)
59593
- }, undefined, false, undefined, this),
59594
- /* @__PURE__ */ jsxDEV7("span", {
59595
- fg: C.dim,
59596
- children: " "
59597
- }, undefined, false, undefined, this),
59598
- /* @__PURE__ */ jsxDEV7("span", {
59599
- fg: idx === providerPickerIndex ? C.fgMuted : C.dim,
59600
- children: p.displayName
59601
- }, undefined, false, undefined, this)
59602
- ]
59603
- }, undefined, true, undefined, this)
59604
- }, p.name, false, undefined, this)),
61238
+ /* @__PURE__ */ jsxDEV7("select", {
61239
+ options: prefixOptions,
61240
+ focused: true,
61241
+ showDescription: false,
61242
+ wrapSelection: true,
61243
+ selectedIndex: providerPickerIndex,
61244
+ onChange: onPrefixChange,
61245
+ backgroundColor: C.bg,
61246
+ textColor: C.fgMuted,
61247
+ selectedBackgroundColor: C.bgHighlight,
61248
+ selectedTextColor: C.cyan,
61249
+ height: Math.min(8, prefixOptions.length),
61250
+ showScrollIndicator: true
61251
+ }, undefined, false, undefined, this),
61252
+ /* @__PURE__ */ jsxDEV7("text", {
61253
+ children: /* @__PURE__ */ jsxDEV7("span", {
61254
+ fg: C.dim,
61255
+ children: " "
61256
+ }, undefined, false, undefined, this)
61257
+ }, undefined, false, undefined, this),
59605
61258
  /* @__PURE__ */ jsxDEV7("text", {
59606
61259
  children: [
59607
- /* @__PURE__ */ jsxDEV7("span", {
59608
- fg: C.blue,
59609
- attributes: A.bold,
59610
- children: [
59611
- "\u2191\u2193",
59612
- " "
59613
- ]
59614
- }, undefined, true, undefined, this),
59615
61260
  /* @__PURE__ */ jsxDEV7("span", {
59616
61261
  fg: C.fgMuted,
59617
- children: "navigate \xB7 "
61262
+ children: "\u2191\u2193 move \xB7 "
59618
61263
  }, undefined, false, undefined, this),
59619
61264
  /* @__PURE__ */ jsxDEV7("span", {
59620
61265
  fg: C.green,
59621
61266
  attributes: A.bold,
59622
61267
  children: [
59623
- "Enter",
61268
+ "\u23CE",
59624
61269
  " "
59625
61270
  ]
59626
61271
  }, undefined, true, undefined, this),
59627
61272
  /* @__PURE__ */ jsxDEV7("span", {
59628
61273
  fg: C.fgMuted,
59629
- children: "select prefix \xB7 "
61274
+ children: "select \xB7 "
59630
61275
  }, undefined, false, undefined, this),
59631
61276
  /* @__PURE__ */ jsxDEV7("span", {
59632
61277
  fg: C.red,
59633
61278
  attributes: A.bold,
59634
61279
  children: [
59635
- "Esc",
61280
+ "esc",
59636
61281
  " "
59637
61282
  ]
59638
61283
  }, undefined, true, undefined, this),
@@ -59644,9 +61289,23 @@ function ProfilesContent({
59644
61289
  }, undefined, true, undefined, this)
59645
61290
  ]
59646
61291
  }, undefined, true, undefined, this),
59647
- mode !== "pick_profile_scope" && mode !== "pick_provider_prefix" && /* @__PURE__ */ jsxDEV7("box", {
61292
+ isTextStep && /* @__PURE__ */ jsxDEV7("box", {
59648
61293
  flexDirection: "column",
61294
+ paddingTop: 1,
59649
61295
  children: [
61296
+ mode === "new_profile" && /* @__PURE__ */ jsxDEV7("text", {
61297
+ children: [
61298
+ /* @__PURE__ */ jsxDEV7("span", {
61299
+ fg: C.fgMuted,
61300
+ children: "scope: "
61301
+ }, undefined, false, undefined, this),
61302
+ /* @__PURE__ */ jsxDEV7("span", {
61303
+ fg: profileScope === "project" ? C.cyan : C.green,
61304
+ attributes: A.bold,
61305
+ children: profileScope
61306
+ }, undefined, false, undefined, this)
61307
+ ]
61308
+ }, undefined, true, undefined, this),
59650
61309
  /* @__PURE__ */ jsxDEV7("text", {
59651
61310
  children: [
59652
61311
  /* @__PURE__ */ jsxDEV7("span", {
@@ -59704,7 +61363,34 @@ function ProfilesContent({
59704
61363
  }, s, false, undefined, this);
59705
61364
  })
59706
61365
  }, undefined, false, undefined, this),
59707
- editProfileValue === "auto" ? /* @__PURE__ */ jsxDEV7("text", {
61366
+ mode === "new_profile" ? /* @__PURE__ */ jsxDEV7("text", {
61367
+ children: [
61368
+ /* @__PURE__ */ jsxDEV7("span", {
61369
+ fg: C.green,
61370
+ attributes: A.bold,
61371
+ children: [
61372
+ "\u23CE",
61373
+ " "
61374
+ ]
61375
+ }, undefined, true, undefined, this),
61376
+ /* @__PURE__ */ jsxDEV7("span", {
61377
+ fg: C.fgMuted,
61378
+ children: "next \xB7 "
61379
+ }, undefined, false, undefined, this),
61380
+ /* @__PURE__ */ jsxDEV7("span", {
61381
+ fg: C.red,
61382
+ attributes: A.bold,
61383
+ children: [
61384
+ "esc",
61385
+ " "
61386
+ ]
61387
+ }, undefined, true, undefined, this),
61388
+ /* @__PURE__ */ jsxDEV7("span", {
61389
+ fg: C.fgMuted,
61390
+ children: "cancel"
61391
+ }, undefined, false, undefined, this)
61392
+ ]
61393
+ }, undefined, true, undefined, this) : editProfileValue === "auto" ? /* @__PURE__ */ jsxDEV7("text", {
59708
61394
  children: [
59709
61395
  /* @__PURE__ */ jsxDEV7("span", {
59710
61396
  fg: C.yellow,
@@ -59716,25 +61402,25 @@ function ProfilesContent({
59716
61402
  }, undefined, true, undefined, this),
59717
61403
  /* @__PURE__ */ jsxDEV7("span", {
59718
61404
  fg: C.fgMuted,
59719
- children: "\u2014 claudish will use the routing table \xB7 "
61405
+ children: "\u2014 uses routing table \xB7 "
59720
61406
  }, undefined, false, undefined, this),
59721
61407
  /* @__PURE__ */ jsxDEV7("span", {
59722
61408
  fg: C.green,
59723
61409
  attributes: A.bold,
59724
61410
  children: [
59725
- "Enter",
61411
+ "\u23CE",
59726
61412
  " "
59727
61413
  ]
59728
61414
  }, undefined, true, undefined, this),
59729
61415
  /* @__PURE__ */ jsxDEV7("span", {
59730
61416
  fg: C.fgMuted,
59731
- children: "to confirm \xB7 "
61417
+ children: "next \xB7 "
59732
61418
  }, undefined, false, undefined, this),
59733
61419
  /* @__PURE__ */ jsxDEV7("span", {
59734
61420
  fg: C.red,
59735
61421
  attributes: A.bold,
59736
61422
  children: [
59737
- "Esc",
61423
+ "esc",
59738
61424
  " "
59739
61425
  ]
59740
61426
  }, undefined, true, undefined, this),
@@ -59749,25 +61435,25 @@ function ProfilesContent({
59749
61435
  fg: C.green,
59750
61436
  attributes: A.bold,
59751
61437
  children: [
59752
- "Enter",
61438
+ "\u23CE",
59753
61439
  " "
59754
61440
  ]
59755
61441
  }, undefined, true, undefined, this),
59756
61442
  /* @__PURE__ */ jsxDEV7("span", {
59757
61443
  fg: C.fgMuted,
59758
- children: "save \xB7 "
61444
+ children: "next \xB7 "
59759
61445
  }, undefined, false, undefined, this),
59760
61446
  /* @__PURE__ */ jsxDEV7("span", {
59761
61447
  fg: C.blue,
59762
61448
  attributes: A.bold,
59763
61449
  children: [
59764
- "Tab",
61450
+ "\u21E5",
59765
61451
  " "
59766
61452
  ]
59767
61453
  }, undefined, true, undefined, this),
59768
61454
  /* @__PURE__ */ jsxDEV7("span", {
59769
61455
  fg: C.fgMuted,
59770
- children: editProfileValue === "" ? "pick provider \xB7 " : "autocomplete \xB7 "
61456
+ children: editProfileValue === "" ? "provider \xB7 " : "complete \xB7 "
59771
61457
  }, undefined, false, undefined, this),
59772
61458
  /* @__PURE__ */ jsxDEV7("span", {
59773
61459
  fg: C.blue,
@@ -59779,7 +61465,7 @@ function ProfilesContent({
59779
61465
  }, undefined, true, undefined, this),
59780
61466
  /* @__PURE__ */ jsxDEV7("span", {
59781
61467
  fg: C.fgMuted,
59782
- children: "suggestion \xB7 "
61468
+ children: "pick \xB7 "
59783
61469
  }, undefined, false, undefined, this),
59784
61470
  /* @__PURE__ */ jsxDEV7("span", {
59785
61471
  fg: C.yellow,
@@ -59791,13 +61477,13 @@ function ProfilesContent({
59791
61477
  }, undefined, true, undefined, this),
59792
61478
  /* @__PURE__ */ jsxDEV7("span", {
59793
61479
  fg: C.fgMuted,
59794
- children: "auto-route \xB7 "
61480
+ children: "auto \xB7 "
59795
61481
  }, undefined, false, undefined, this),
59796
61482
  /* @__PURE__ */ jsxDEV7("span", {
59797
61483
  fg: C.red,
59798
61484
  attributes: A.bold,
59799
61485
  children: [
59800
- "Esc",
61486
+ "esc",
59801
61487
  " "
59802
61488
  ]
59803
61489
  }, undefined, true, undefined, this),
@@ -59814,10 +61500,20 @@ function ProfilesContent({
59814
61500
  ]
59815
61501
  }, undefined, true, undefined, this);
59816
61502
  }
61503
+ var WIZARD_STEPS, TOTAL_STEPS;
59817
61504
  var init_ProfilesContent = __esm(() => {
59818
61505
  init_theme2();
59819
61506
  init_constants3();
59820
61507
  init_profile_config();
61508
+ WIZARD_STEPS = [
61509
+ "pick_profile_scope",
61510
+ "new_profile",
61511
+ "edit_profile_opus",
61512
+ "edit_profile_sonnet",
61513
+ "edit_profile_haiku",
61514
+ "edit_profile_subagent"
61515
+ ];
61516
+ TOTAL_STEPS = WIZARD_STEPS.length;
59821
61517
  });
59822
61518
 
59823
61519
  // src/tui/components/ProfileDetail.tsx
@@ -59920,7 +61616,7 @@ var init_ProfileDetail = __esm(() => {
59920
61616
  });
59921
61617
 
59922
61618
  // src/tui/components/RoutingContent.tsx
59923
- import { useEffect as useEffect3, useRef as useRef2 } from "react";
61619
+ import { useEffect as useEffect3, useRef as useRef3 } from "react";
59924
61620
  import { jsxDEV as jsxDEV9, Fragment as Fragment6 } from "@opentui/react/jsx-dev-runtime";
59925
61621
  function chainStr(chain) {
59926
61622
  return chain.join(" \u2192 ");
@@ -59943,8 +61639,8 @@ function RoutingContent({
59943
61639
  editingExistingScope,
59944
61640
  routingScopeCursor
59945
61641
  }) {
59946
- const rulesScrollRef = useRef2(null);
59947
- const chainScrollRef = useRef2(null);
61642
+ const rulesScrollRef = useRef3(null);
61643
+ const chainScrollRef = useRef3(null);
59948
61644
  useEffect3(() => {
59949
61645
  const sb = rulesScrollRef.current;
59950
61646
  if (!sb || mergedRules.length === 0)
@@ -61132,12 +62828,12 @@ var init_PrivacyDetail = __esm(() => {
61132
62828
  });
61133
62829
 
61134
62830
  // src/tui/App.tsx
61135
- import { useKeyboard, useRenderer, useTerminalDimensions } from "@opentui/react";
62831
+ import { useKeyboard as useKeyboard2, useRenderer, useTerminalDimensions as useTerminalDimensions2 } from "@opentui/react";
61136
62832
  import { useCallback as useCallback3, useEffect as useEffect4, useMemo as useMemo2, useState as useState5 } from "react";
61137
62833
  import { jsxDEV as jsxDEV13, Fragment as Fragment7 } from "@opentui/react/jsx-dev-runtime";
61138
62834
  function App({ requestLogin } = {}) {
61139
62835
  const renderer = useRenderer();
61140
- const { width, height: height2 } = useTerminalDimensions();
62836
+ const { width, height: height2 } = useTerminalDimensions2();
61141
62837
  const [config3, setConfig] = useState5(() => loadConfig());
61142
62838
  const [bufStats, setBufStats] = useState5(() => getBufferStats());
61143
62839
  const [providerIndex, setProviderIndex] = useState5(0);
@@ -61186,7 +62882,6 @@ function App({ requestLogin } = {}) {
61186
62882
  const { probeMode, probeModel, probeResults } = probe;
61187
62883
  const wizard = useProfileWizard({ mode, setMode, refreshConfig, setStatusMsg });
61188
62884
  const {
61189
- editProfileName,
61190
62885
  editProfileValue,
61191
62886
  profileScope,
61192
62887
  suggestions,
@@ -61238,7 +62933,6 @@ function App({ requestLogin } = {}) {
61238
62933
  return out;
61239
62934
  }, [config3.routing, JSON.stringify(loadLocalConfig()?.routing ?? {})]);
61240
62935
  const profileName = config3.defaultProfile || "default";
61241
- const readyCount = PROVIDERS.filter((p) => !!(config3.apiKeys?.[p.apiKeyEnvVar] || process.env[p.apiKeyEnvVar])).length;
61242
62936
  const runProbeTest = useCallback3(async (prov) => {
61243
62937
  const provName = prov.name;
61244
62938
  setTestResults((prev) => ({ ...prev, [provName]: { status: "testing" } }));
@@ -61322,7 +63016,7 @@ function App({ requestLogin } = {}) {
61322
63016
  }));
61323
63017
  }
61324
63018
  }, []);
61325
- useKeyboard((key) => {
63019
+ useKeyboard2((key) => {
61326
63020
  if (key.ctrl && key.name === "c")
61327
63021
  return quit();
61328
63022
  if (probeMode === "input") {
@@ -61549,10 +63243,8 @@ function App({ requestLogin } = {}) {
61549
63243
  return;
61550
63244
  }
61551
63245
  if (mode === "pick_profile_scope") {
61552
- if (key.raw === "g" || key.raw === "G") {
61553
- wizard.pickScope("global");
61554
- } else if (key.raw === "p" || key.raw === "P") {
61555
- wizard.pickScope("project");
63246
+ if (key.name === "return" || key.name === "enter") {
63247
+ wizard.pickScopeAtCursor();
61556
63248
  } else if (key.name === "escape") {
61557
63249
  wizard.cancelPickScope();
61558
63250
  }
@@ -61571,11 +63263,7 @@ function App({ requestLogin } = {}) {
61571
63263
  return;
61572
63264
  }
61573
63265
  if (mode === "pick_provider_prefix") {
61574
- if (key.name === "up" || key.name === "k") {
61575
- wizard.prefixPickerUp();
61576
- } else if (key.name === "down" || key.name === "j") {
61577
- wizard.prefixPickerDown();
61578
- } else if (key.name === "return" || key.name === "enter") {
63266
+ if (key.name === "return" || key.name === "enter") {
61579
63267
  wizard.prefixPickerSubmit();
61580
63268
  } else if (key.name === "escape") {
61581
63269
  wizard.prefixPickerCancel();
@@ -61920,61 +63608,64 @@ function App({ requestLogin } = {}) {
61920
63608
  children: [
61921
63609
  /* @__PURE__ */ jsxDEV13("box", {
61922
63610
  height: HEADER_H,
61923
- flexDirection: "row",
63611
+ flexDirection: "column",
61924
63612
  backgroundColor: C.bgAlt,
61925
63613
  paddingX: 1,
61926
- children: /* @__PURE__ */ jsxDEV13("text", {
61927
- children: [
61928
- /* @__PURE__ */ jsxDEV13("span", {
61929
- fg: C.white,
61930
- attributes: A.bold,
61931
- children: "claudish"
61932
- }, undefined, false, undefined, this),
61933
- /* @__PURE__ */ jsxDEV13("span", {
61934
- fg: C.dim,
61935
- children: " \u2500 "
61936
- }, undefined, false, undefined, this),
61937
- /* @__PURE__ */ jsxDEV13("span", {
61938
- fg: C.blue,
61939
- attributes: A.bold,
61940
- children: VERSION2
61941
- }, undefined, false, undefined, this),
61942
- /* @__PURE__ */ jsxDEV13("span", {
61943
- fg: C.dim,
61944
- children: " \u2500 "
61945
- }, undefined, false, undefined, this),
61946
- /* @__PURE__ */ jsxDEV13("span", {
61947
- fg: C.orange,
61948
- attributes: A.bold,
63614
+ children: [
63615
+ /* @__PURE__ */ jsxDEV13("box", {
63616
+ height: 1,
63617
+ flexDirection: "row",
63618
+ children: /* @__PURE__ */ jsxDEV13("text", {
61949
63619
  children: [
61950
- "\u2605 ",
61951
- profileName
63620
+ /* @__PURE__ */ jsxDEV13("span", {
63621
+ fg: C.white,
63622
+ attributes: A.bold,
63623
+ children: "claudish"
63624
+ }, undefined, false, undefined, this),
63625
+ /* @__PURE__ */ jsxDEV13("span", {
63626
+ fg: C.dim,
63627
+ children: " \u2500 "
63628
+ }, undefined, false, undefined, this),
63629
+ /* @__PURE__ */ jsxDEV13("span", {
63630
+ fg: C.blue,
63631
+ attributes: A.bold,
63632
+ children: `v${VERSION}`
63633
+ }, undefined, false, undefined, this),
63634
+ /* @__PURE__ */ jsxDEV13("span", {
63635
+ fg: C.dim,
63636
+ children: " \u2500 "
63637
+ }, undefined, false, undefined, this),
63638
+ /* @__PURE__ */ jsxDEV13("span", {
63639
+ fg: C.fgMuted,
63640
+ children: "by MadAppGang"
63641
+ }, undefined, false, undefined, this),
63642
+ /* @__PURE__ */ jsxDEV13("span", {
63643
+ fg: C.dim,
63644
+ children: " \u2500 "
63645
+ }, undefined, false, undefined, this),
63646
+ /* @__PURE__ */ jsxDEV13("span", {
63647
+ fg: C.fgMuted,
63648
+ children: "profile: "
63649
+ }, undefined, false, undefined, this),
63650
+ /* @__PURE__ */ jsxDEV13("span", {
63651
+ fg: C.orange,
63652
+ attributes: A.bold,
63653
+ children: `[${profileName}]`
63654
+ }, undefined, false, undefined, this)
61952
63655
  ]
61953
- }, undefined, true, undefined, this),
61954
- /* @__PURE__ */ jsxDEV13("span", {
61955
- fg: C.dim,
61956
- children: " \u2500 "
61957
- }, undefined, false, undefined, this),
61958
- /* @__PURE__ */ jsxDEV13("span", {
61959
- fg: C.green,
61960
- attributes: A.bold,
61961
- children: readyCount
61962
- }, undefined, false, undefined, this),
61963
- /* @__PURE__ */ jsxDEV13("span", {
61964
- fg: C.fgMuted,
61965
- children: " providers configured"
61966
- }, undefined, false, undefined, this),
61967
- /* @__PURE__ */ jsxDEV13("span", {
61968
- fg: C.dim,
61969
- children: "\u2500".repeat(Math.max(1, width - 38 - profileName.length - VERSION2.length))
61970
- }, undefined, false, undefined, this)
61971
- ]
61972
- }, undefined, true, undefined, this)
61973
- }, undefined, false, undefined, this),
61974
- /* @__PURE__ */ jsxDEV13(TabBar, {
63656
+ }, undefined, true, undefined, this)
63657
+ }, undefined, false, undefined, this),
63658
+ /* @__PURE__ */ jsxDEV13("box", {
63659
+ flexGrow: 1,
63660
+ border: ["bottom"],
63661
+ borderStyle: "single",
63662
+ borderColor: C.dim
63663
+ }, undefined, false, undefined, this)
63664
+ ]
63665
+ }, undefined, true, undefined, this),
63666
+ /* @__PURE__ */ jsxDEV13(TabBar2, {
61975
63667
  activeTab,
61976
- statusMsg,
61977
- width
63668
+ statusMsg
61978
63669
  }, undefined, false, undefined, this),
61979
63670
  activeTab === "providers" && /* @__PURE__ */ jsxDEV13(Fragment7, {
61980
63671
  children: [
@@ -61983,7 +63674,6 @@ function App({ requestLogin } = {}) {
61983
63674
  displayProviders,
61984
63675
  providerIndex,
61985
63676
  testResults,
61986
- width,
61987
63677
  contentH,
61988
63678
  isInputMode,
61989
63679
  animTick
@@ -62013,13 +63703,14 @@ function App({ requestLogin } = {}) {
62013
63703
  mode,
62014
63704
  profileScope,
62015
63705
  profileIndex,
62016
- editProfileName,
62017
63706
  editProfileValue,
62018
63707
  suggestions,
62019
63708
  suggestionIndex,
62020
63709
  providerPickerIndex,
62021
63710
  width,
62022
- contentH
63711
+ contentH,
63712
+ onScopeChange: wizard.setScopeCursor,
63713
+ onPrefixChange: wizard.setProviderPickerIndex
62023
63714
  }, undefined, false, undefined, this),
62024
63715
  /* @__PURE__ */ jsxDEV13(ProfileDetail, {
62025
63716
  config: config3,