claudish 7.2.0 → 7.3.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 +1738 -366
  2. package/package.json +5 -5
package/dist/index.js CHANGED
@@ -33157,7 +33157,7 @@ var init_vision_proxy = __esm(() => {
33157
33157
  });
33158
33158
 
33159
33159
  // src/version.ts
33160
- var VERSION = "7.2.0";
33160
+ var VERSION = "7.3.0";
33161
33161
 
33162
33162
  // src/telemetry.ts
33163
33163
  var exports_telemetry = {};
@@ -54328,23 +54328,34 @@ async function probeLink(proxyUrl, link, timeoutMs) {
54328
54328
  signal: AbortSignal.timeout(timeoutMs)
54329
54329
  });
54330
54330
  } catch (e) {
54331
- const latencyMs2 = Date.now() - startedAt;
54331
+ const latencyMs = Date.now() - startedAt;
54332
54332
  const name = e?.name || "";
54333
54333
  const msg = String(e?.message || e);
54334
54334
  if (name === "TimeoutError" || name === "AbortError" || /timeout/i.test(msg)) {
54335
- return { state: "timeout", latencyMs: latencyMs2, errorMessage: msg };
54335
+ return { state: "timeout", latencyMs, errorMessage: msg };
54336
54336
  }
54337
- return { state: "network-error", latencyMs: latencyMs2, errorMessage: msg };
54337
+ return { state: "network-error", latencyMs, errorMessage: msg };
54338
54338
  }
54339
- const latencyMs = Date.now() - startedAt;
54339
+ const ttfbMs = Date.now() - startedAt;
54340
54340
  if (!response.ok) {
54341
54341
  const body = await safeReadBody(response);
54342
- return annotateOAuthHint(classifyHttpError(response.status, body, latencyMs), link.provider, isOAuth);
54343
- }
54344
- const streamResult = await consumeProbeStream(response, timeoutMs);
54342
+ return annotateOAuthHint(classifyHttpError(response.status, body, ttfbMs), link.provider, isOAuth);
54343
+ }
54344
+ const streamResult = await consumeProbeStream(response, timeoutMs, startedAt);
54345
+ const totalMs = Date.now() - startedAt;
54346
+ let timing;
54347
+ if (streamResult.state === "live" && streamResult.ttftMs !== undefined && !streamResult.truncated) {
54348
+ const ttftMs = streamResult.ttftMs;
54349
+ const tokens = streamResult.tokens ?? 0;
54350
+ const streamMs = Math.max(STREAM_MS_FLOOR, totalMs - ttftMs);
54351
+ const tokensPerSec = tokens > 0 ? tokens / streamMs * 1000 : 0;
54352
+ timing = { ttfbMs, ttftMs, totalMs, tokens, tokensPerSec };
54353
+ }
54354
+ const { ttftMs: _ttft, tokens: _tok, truncated: _trunc, ...rest } = streamResult;
54345
54355
  return annotateOAuthHint({
54346
- ...streamResult,
54347
- latencyMs: Date.now() - startedAt
54356
+ ...rest,
54357
+ latencyMs: totalMs,
54358
+ timing
54348
54359
  }, link.provider, isOAuth);
54349
54360
  }
54350
54361
  function annotateOAuthHint(result, provider, isOAuth) {
@@ -54428,7 +54439,7 @@ function extractErrorMessage(body) {
54428
54439
  return;
54429
54440
  return trimmed.length > 160 ? `${trimmed.slice(0, 157)}...` : trimmed;
54430
54441
  }
54431
- async function consumeProbeStream(response, timeoutMs) {
54442
+ async function consumeProbeStream(response, timeoutMs, startedAt) {
54432
54443
  const body = response.body;
54433
54444
  if (!body) {
54434
54445
  return { state: "error", errorMessage: "empty response body" };
@@ -54437,11 +54448,19 @@ async function consumeProbeStream(response, timeoutMs) {
54437
54448
  const decoder = new TextDecoder;
54438
54449
  let buffered = "";
54439
54450
  const deadline = Date.now() + timeoutMs;
54451
+ let ttftMs;
54452
+ let sawContent = false;
54453
+ let textChars = 0;
54454
+ let reportedTokens;
54455
+ let errorVerdict = null;
54456
+ let completed = false;
54440
54457
  try {
54441
54458
  while (Date.now() < deadline) {
54442
54459
  const { value, done } = await reader.read();
54443
- if (done)
54460
+ if (done) {
54461
+ completed = true;
54444
54462
  break;
54463
+ }
54445
54464
  buffered += decoder.decode(value, { stream: true });
54446
54465
  const events = buffered.split(`
54447
54466
 
@@ -54449,29 +54468,71 @@ async function consumeProbeStream(response, timeoutMs) {
54449
54468
  buffered = events.pop() ?? "";
54450
54469
  for (const event of events) {
54451
54470
  const verdict = interpretSseEvent(event);
54452
- if (verdict === "live") {
54453
- try {
54454
- await reader.cancel();
54455
- } catch {}
54456
- return { state: "live" };
54471
+ if (verdict && typeof verdict === "object" && verdict.state !== "live") {
54472
+ errorVerdict = verdict;
54473
+ break;
54457
54474
  }
54458
- if (verdict && verdict.state !== "live") {
54459
- try {
54460
- await reader.cancel();
54461
- } catch {}
54462
- return verdict;
54475
+ const acct = accountStreamEvent(event);
54476
+ if (acct.contentDelta) {
54477
+ if (ttftMs === undefined)
54478
+ ttftMs = Date.now() - startedAt;
54479
+ sawContent = true;
54463
54480
  }
54481
+ if (acct.textChars)
54482
+ textChars += acct.textChars;
54483
+ if (acct.outputTokens !== undefined)
54484
+ reportedTokens = acct.outputTokens;
54464
54485
  }
54486
+ if (errorVerdict)
54487
+ break;
54465
54488
  }
54466
54489
  } catch (e) {
54467
- return {
54468
- state: "network-error",
54469
- errorMessage: String(e?.message || e)
54470
- };
54490
+ if (!sawContent) {
54491
+ return { state: "network-error", errorMessage: String(e?.message || e) };
54492
+ }
54493
+ } finally {
54494
+ try {
54495
+ await reader.cancel();
54496
+ } catch {}
54471
54497
  }
54498
+ if (errorVerdict)
54499
+ return errorVerdict;
54500
+ if (sawContent) {
54501
+ const tokens = reportedTokens ?? Math.max(1, Math.round(textChars / 4));
54502
+ return { state: "live", ttftMs, tokens, truncated: !completed };
54503
+ }
54504
+ return { state: "error", errorMessage: "stream ended without content" };
54505
+ }
54506
+ function accountStreamEvent(rawEvent) {
54507
+ let dataPayload = "";
54508
+ for (const line of rawEvent.split(`
54509
+ `)) {
54510
+ if (line.startsWith("data:"))
54511
+ dataPayload += line.slice(5).trim();
54512
+ }
54513
+ if (!dataPayload || dataPayload === "[DONE]") {
54514
+ return { contentDelta: false, textChars: 0 };
54515
+ }
54516
+ let parsed;
54517
+ try {
54518
+ parsed = JSON.parse(dataPayload);
54519
+ } catch {
54520
+ return { contentDelta: false, textChars: 0 };
54521
+ }
54522
+ let textChars = 0;
54523
+ let contentDelta = false;
54524
+ const text = parsed?.delta?.text ?? (Array.isArray(parsed?.choices) ? parsed.choices[0]?.delta?.content : undefined);
54525
+ if (typeof text === "string" && text.length > 0) {
54526
+ contentDelta = true;
54527
+ textChars = text.length;
54528
+ } else if (parsed?.type === "content_block_delta" || parsed?.type === "content_block_start") {
54529
+ contentDelta = true;
54530
+ }
54531
+ const outputTokens = parsed?.usage?.output_tokens ?? parsed?.message?.usage?.output_tokens ?? parsed?.usage?.completion_tokens;
54472
54532
  return {
54473
- state: "error",
54474
- errorMessage: "stream ended without content"
54533
+ contentDelta,
54534
+ textChars,
54535
+ outputTokens: typeof outputTokens === "number" ? outputTokens : undefined
54475
54536
  };
54476
54537
  }
54477
54538
  function interpretSseEvent(rawEvent) {
@@ -54562,7 +54623,7 @@ function isReadyState(state) {
54562
54623
  function isFailureState(state) {
54563
54624
  return state === "auth-failed" || state === "model-not-found" || state === "rate-limited" || state === "server-error" || state === "timeout" || state === "network-error" || state === "error";
54564
54625
  }
54565
- var OAUTH_PROVIDERS2, PROBE_PROMPT = "ping", PROBE_MAX_TOKENS = 1;
54626
+ var STREAM_MS_FLOOR = 50, OAUTH_PROVIDERS2, PROBE_PROMPT = "Count from one to twenty in words, one per line.", PROBE_MAX_TOKENS = 64;
54566
54627
  var init_probe_live = __esm(() => {
54567
54628
  OAUTH_PROVIDERS2 = new Set(["vertex", "gemini-codeassist"]);
54568
54629
  });
@@ -54583,7 +54644,108 @@ var init_probe_runner = __esm(() => {
54583
54644
 
54584
54645
  // src/tui/theme.ts
54585
54646
  import { createTextAttributes } from "@opentui/core";
54586
- var C, bold, A;
54647
+ function latencyBucket(ms) {
54648
+ const v = Math.max(0, ms);
54649
+ for (const b of LATENCY_BUCKETS) {
54650
+ if (v < b.maxMs)
54651
+ return b;
54652
+ }
54653
+ return LATENCY_BUCKETS[LATENCY_BUCKETS.length - 1];
54654
+ }
54655
+ function formatLatency(ms) {
54656
+ if (ms < 1000)
54657
+ return `${Math.round(ms)}ms`;
54658
+ return `${(ms / 1000).toFixed(2)}s`;
54659
+ }
54660
+ function latencyBg(ms) {
54661
+ return latencyBucket(ms).hex;
54662
+ }
54663
+ function latencyBgAnsi(ms) {
54664
+ const hex3 = latencyBucket(ms).hex;
54665
+ const r = parseInt(hex3.slice(1, 3), 16);
54666
+ const g = parseInt(hex3.slice(3, 5), 16);
54667
+ const b = parseInt(hex3.slice(5, 7), 16);
54668
+ return `\x1B[48;2;${r};${g};${b}m`;
54669
+ }
54670
+ function hexToAnsiBg(hex3) {
54671
+ const r = parseInt(hex3.slice(1, 3), 16);
54672
+ const g = parseInt(hex3.slice(3, 5), 16);
54673
+ const b = parseInt(hex3.slice(5, 7), 16);
54674
+ return `\x1B[48;2;${r};${g};${b}m`;
54675
+ }
54676
+ function hexToAnsiFg(hex3) {
54677
+ const r = parseInt(hex3.slice(1, 3), 16);
54678
+ const g = parseInt(hex3.slice(3, 5), 16);
54679
+ const b = parseInt(hex3.slice(5, 7), 16);
54680
+ return `\x1B[38;2;${r};${g};${b}m`;
54681
+ }
54682
+ function throughputFg(tokensPerSec) {
54683
+ if (tokensPerSec >= 100)
54684
+ return C.brightGreen;
54685
+ if (tokensPerSec >= 40)
54686
+ return C.orange;
54687
+ return "#9e2b2b";
54688
+ }
54689
+ function timelineBarCells(totalMs, maxTotalMs, barWidth) {
54690
+ if (barWidth <= 0)
54691
+ return 0;
54692
+ const denom = maxTotalMs > 0 ? maxTotalMs : 1;
54693
+ const raw2 = Math.round(barWidth * Math.max(0, totalMs) / denom);
54694
+ return Math.min(barWidth, Math.max(1, raw2));
54695
+ }
54696
+ function splitStageCells(ttfbMs, ttftMs, totalMs, barCells) {
54697
+ const net = Math.max(0, ttfbMs);
54698
+ const srv = Math.max(0, ttftMs - ttfbMs);
54699
+ const str = Math.max(0, totalMs - ttftMs);
54700
+ const durations = [net, srv, str];
54701
+ const sum = net + srv + str;
54702
+ if (barCells <= 0)
54703
+ return { network: 0, server: 0, streaming: 0 };
54704
+ if (sum <= 0) {
54705
+ return { network: barCells, server: 0, streaming: 0 };
54706
+ }
54707
+ const exact = durations.map((d) => barCells * d / sum);
54708
+ const floors = exact.map((e) => Math.floor(e));
54709
+ let used = floors[0] + floors[1] + floors[2];
54710
+ let leftover = barCells - used;
54711
+ const remainders = exact.map((e, i) => ({ i, rem: e - Math.floor(e) })).sort((a, b) => b.rem - a.rem);
54712
+ for (let k = 0;k < leftover; k++) {
54713
+ floors[remainders[k % 3].i] += 1;
54714
+ }
54715
+ if (barCells >= 3) {
54716
+ for (let i = 0;i < 3; i++) {
54717
+ if (durations[i] > 0 && floors[i] === 0) {
54718
+ let donor = 0;
54719
+ for (let j = 1;j < 3; j++) {
54720
+ if (floors[j] > floors[donor])
54721
+ donor = j;
54722
+ }
54723
+ if (floors[donor] > 1) {
54724
+ floors[donor] -= 1;
54725
+ floors[i] += 1;
54726
+ }
54727
+ }
54728
+ }
54729
+ }
54730
+ used = floors[0] + floors[1] + floors[2];
54731
+ leftover = barCells - used;
54732
+ if (leftover !== 0) {
54733
+ let big = 0;
54734
+ for (let j = 1;j < 3; j++)
54735
+ if (durations[j] > durations[big])
54736
+ big = j;
54737
+ floors[big] = Math.max(0, floors[big] + leftover);
54738
+ }
54739
+ return { network: floors[0], server: floors[1], streaming: floors[2] };
54740
+ }
54741
+ function tokBarCells(tokensPerSec, maxTokPerSec, tokWidth) {
54742
+ if (tokWidth <= 0)
54743
+ return 0;
54744
+ const denom = maxTokPerSec > 0 ? maxTokPerSec : 1;
54745
+ const raw2 = Math.round(tokWidth * Math.max(0, tokensPerSec) / denom);
54746
+ return Math.min(tokWidth, Math.max(0, raw2));
54747
+ }
54748
+ 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
54749
  var init_theme2 = __esm(() => {
54588
54750
  C = {
54589
54751
  bg: "#000000",
@@ -54610,17 +54772,42 @@ var init_theme2 = __esm(() => {
54610
54772
  tabActiveFg: "#ffffff",
54611
54773
  tabInactiveFg: "#0088ff",
54612
54774
  pillKeyBg: "#2d6e3e",
54613
- pillOauthBg: "#1f6d75"
54775
+ pillOauthBg: "#1f6d75",
54776
+ chipKeyBg: "#3a3a3a",
54777
+ chipLabelBg: "#222222"
54614
54778
  };
54615
54779
  bold = createTextAttributes({ bold: true });
54616
54780
  A = {
54617
54781
  bold,
54618
54782
  boldIf: (enabled) => enabled ? bold : undefined
54619
54783
  };
54784
+ LATENCY_BUCKETS = [
54785
+ { maxMs: 500, hex: "#1f8f3b" },
54786
+ { maxMs: 1000, hex: "#2d6e3e" },
54787
+ { maxMs: 3000, hex: "#8a7d1e" },
54788
+ { maxMs: 6000, hex: "#b5651d" },
54789
+ { maxMs: Infinity, hex: "#9e2b2b" }
54790
+ ];
54791
+ STAGE_BG = {
54792
+ network: "#00b3c4",
54793
+ server: "#2563ff",
54794
+ streaming: "#ffcc00"
54795
+ };
54796
+ STAGE_FG = {
54797
+ network: C.cyan,
54798
+ server: C.blue,
54799
+ streaming: C.yellow
54800
+ };
54801
+ STAGE_BG_ANSI = {
54802
+ network: hexToAnsiBg(STAGE_BG.network),
54803
+ server: hexToAnsiBg(STAGE_BG.server),
54804
+ streaming: hexToAnsiBg(STAGE_BG.streaming)
54805
+ };
54620
54806
  });
54621
54807
 
54622
54808
  // src/probe/probe-tui-app.tsx
54623
- import { useEffect as useEffect2, useState as useState2 } from "react";
54809
+ import { useEffect as useEffect2, useRef as useRef2, useState as useState2 } from "react";
54810
+ import { useKeyboard, useTerminalDimensions } from "@opentui/react";
54624
54811
  import { jsxDEV, Fragment } from "@opentui/react/jsx-dev-runtime";
54625
54812
 
54626
54813
  class ProbeStore {
@@ -54637,6 +54824,12 @@ class ProbeStore {
54637
54824
  for (const fn of this.listeners)
54638
54825
  fn();
54639
54826
  }
54827
+ setResults(results) {
54828
+ this.setState((prev) => ({ ...prev, results, phase: "done" }));
54829
+ }
54830
+ setActiveTab(tab) {
54831
+ this.setState((prev) => ({ ...prev, activeTab: tab }));
54832
+ }
54640
54833
  subscribe(fn) {
54641
54834
  this.listeners.add(fn);
54642
54835
  return () => {
@@ -54659,6 +54852,61 @@ function useAnimationFrame(active) {
54659
54852
  }, [active]);
54660
54853
  return frame;
54661
54854
  }
54855
+ function deriveLayout(width) {
54856
+ if (width < 60) {
54857
+ return { barWidth: 0, tokWidth: 0, showBreakdown: false, pillFallback: true };
54858
+ }
54859
+ if (width < 80) {
54860
+ return {
54861
+ barWidth: TIMELINE_BAR_NARROW,
54862
+ tokWidth: 0,
54863
+ showBreakdown: false,
54864
+ pillFallback: false
54865
+ };
54866
+ }
54867
+ if (width < 100) {
54868
+ return {
54869
+ barWidth: TIMELINE_BAR_FULL,
54870
+ tokWidth: 0,
54871
+ showBreakdown: true,
54872
+ pillFallback: false
54873
+ };
54874
+ }
54875
+ return {
54876
+ barWidth: TIMELINE_BAR_FULL,
54877
+ tokWidth: TOK_BAR_FULL,
54878
+ showBreakdown: true,
54879
+ pillFallback: false
54880
+ };
54881
+ }
54882
+ function computeRowWidth(layout, maxNameLen) {
54883
+ let w = 4 + 5 + 2 + maxNameLen + 2;
54884
+ if (layout.pillFallback) {
54885
+ w += TOTAL_COL + 2 + 25;
54886
+ return w;
54887
+ }
54888
+ w += layout.barWidth + 2 + TOTAL_COL;
54889
+ if (layout.showBreakdown) {
54890
+ w += BREAKDOWN_COL;
54891
+ } else {
54892
+ w += 2;
54893
+ }
54894
+ if (layout.tokWidth > 0) {
54895
+ w += layout.tokWidth + 1;
54896
+ }
54897
+ w += TOK_VALUE_COL;
54898
+ return w;
54899
+ }
54900
+ function padStartSafe(s, n) {
54901
+ if (s.length >= n)
54902
+ return s.slice(s.length - n);
54903
+ return " ".repeat(n - s.length) + s;
54904
+ }
54905
+ function breakdownNum(ms) {
54906
+ if (ms >= 1000)
54907
+ return formatLatency(ms);
54908
+ return `${Math.round(Math.max(0, ms))}`;
54909
+ }
54662
54910
  function formatElapsed(ms) {
54663
54911
  const seconds = Math.floor(ms / 1000);
54664
54912
  const mins = Math.floor(seconds / 60);
@@ -54743,7 +54991,7 @@ function Banner() {
54743
54991
  ]
54744
54992
  }, undefined, true, undefined, this);
54745
54993
  }
54746
- function StepIndicator({ step }) {
54994
+ function StepLine({ steps }) {
54747
54995
  const iconMap = {
54748
54996
  pending: "\u25CB",
54749
54997
  running: "\u25CC",
@@ -54756,103 +55004,267 @@ function StepIndicator({ step }) {
54756
55004
  done: C.green,
54757
55005
  error: C.red
54758
55006
  };
55007
+ if (steps.length === 0)
55008
+ return /* @__PURE__ */ jsxDEV("text", {
55009
+ children: " "
55010
+ }, undefined, false, undefined, this);
55011
+ const active = steps.find((s) => s.status === "running" || s.status === "error") ?? steps[steps.length - 1];
54759
55012
  return /* @__PURE__ */ jsxDEV("text", {
54760
55013
  children: [
54761
55014
  /* @__PURE__ */ jsxDEV("span", {
54762
55015
  children: " "
54763
55016
  }, undefined, false, undefined, this),
54764
- /* @__PURE__ */ jsxDEV("span", {
54765
- fg: colorMap[step.status],
55017
+ steps.map((s, i) => /* @__PURE__ */ jsxDEV("span", {
55018
+ fg: colorMap[s.status],
54766
55019
  children: [
54767
- iconMap[step.status],
54768
- " ",
54769
- step.name
55020
+ iconMap[s.status],
55021
+ i < steps.length - 1 ? " " : ""
54770
55022
  ]
54771
- }, undefined, true, undefined, this)
55023
+ }, `${s.name}-${i}`, true, undefined, this)),
55024
+ /* @__PURE__ */ jsxDEV("span", {
55025
+ fg: C.dim,
55026
+ children: " "
55027
+ }, undefined, false, undefined, this),
55028
+ /* @__PURE__ */ jsxDEV("span", {
55029
+ fg: colorMap[active.status],
55030
+ children: active.name
55031
+ }, undefined, false, undefined, this)
54772
55032
  ]
54773
55033
  }, undefined, true, undefined, this);
54774
55034
  }
54775
55035
  function ProgressBar({
54776
55036
  link,
54777
55037
  animFrame,
54778
- maxNameLen
55038
+ maxNameLen,
55039
+ layout,
55040
+ maxTotalMs,
55041
+ maxTokPerSec,
55042
+ isRunFastest
54779
55043
  }) {
54780
55044
  const elapsedMs = link.status === "waiting" ? 0 : link.startTime ? (link.endTime ?? Date.now()) - link.startTime : 0;
54781
55045
  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
55046
  const displayName = padEndSafe(link.displayName, maxNameLen);
54820
- return /* @__PURE__ */ jsxDEV("text", {
55047
+ const prefix = /* @__PURE__ */ jsxDEV(Fragment, {
54821
55048
  children: [
54822
55049
  /* @__PURE__ */ jsxDEV("span", {
54823
55050
  fg: C.dim,
54824
55051
  children: ` ${elapsed} `
54825
55052
  }, undefined, false, undefined, this),
54826
55053
  /* @__PURE__ */ jsxDEV("span", {
54827
- fg: barColor,
54828
- children: bar
55054
+ fg: C.fg,
55055
+ children: displayName
54829
55056
  }, undefined, false, undefined, this),
54830
55057
  /* @__PURE__ */ jsxDEV("span", {
54831
55058
  fg: C.dim,
54832
55059
  children: " "
55060
+ }, undefined, false, undefined, this)
55061
+ ]
55062
+ }, undefined, true, undefined, this);
55063
+ if (layout.pillFallback) {
55064
+ if (link.status === "live") {
55065
+ const latency = link.timing?.totalMs ?? elapsedMs;
55066
+ return /* @__PURE__ */ jsxDEV("text", {
55067
+ children: [
55068
+ prefix,
55069
+ /* @__PURE__ */ jsxDEV("span", {
55070
+ fg: C.green,
55071
+ children: "\u2713 live \xB7 "
55072
+ }, undefined, false, undefined, this),
55073
+ /* @__PURE__ */ jsxDEV("span", {
55074
+ fg: latencyFg,
55075
+ bg: latencyBg(latency),
55076
+ children: ` ${formatLatency(latency)} `
55077
+ }, undefined, false, undefined, this)
55078
+ ]
55079
+ }, undefined, true, undefined, this);
55080
+ }
55081
+ return /* @__PURE__ */ jsxDEV("text", {
55082
+ children: [
55083
+ prefix,
55084
+ renderNonLiveStatus(link, false)
55085
+ ]
55086
+ }, undefined, true, undefined, this);
55087
+ }
55088
+ if (link.status !== "live" || !link.timing) {
55089
+ return /* @__PURE__ */ jsxDEV("text", {
55090
+ children: [
55091
+ prefix,
55092
+ renderTimelineSlot(link, animFrame, layout.barWidth),
55093
+ /* @__PURE__ */ jsxDEV("span", {
55094
+ fg: C.dim,
55095
+ children: " "
55096
+ }, undefined, false, undefined, this),
55097
+ renderNonLiveStatus(link, true)
55098
+ ]
55099
+ }, undefined, true, undefined, this);
55100
+ }
55101
+ const t = link.timing;
55102
+ const barCells = timelineBarCells(t.totalMs, maxTotalMs, layout.barWidth);
55103
+ const stages = splitStageCells(t.ttfbMs, t.ttftMs, t.totalMs, barCells);
55104
+ const trackCells = Math.max(0, layout.barWidth - barCells);
55105
+ const netMs = Math.max(0, t.ttfbMs);
55106
+ const srvMs = Math.max(0, t.ttftMs - t.ttfbMs);
55107
+ const strMs = Math.max(0, t.totalMs - t.ttftMs);
55108
+ const tokColor = throughputFg(t.tokensPerSec);
55109
+ const tokCells = layout.tokWidth > 0 ? tokBarCells(t.tokensPerSec, maxTokPerSec, layout.tokWidth) : 0;
55110
+ const tokTrack = Math.max(0, layout.tokWidth - tokCells);
55111
+ const tokValue = padStartSafe(`${Math.round(t.tokensPerSec)} t/s`, TOK_VALUE_COL);
55112
+ const netStr = padStartSafe(breakdownNum(netMs), STAGE_NUM_W);
55113
+ const srvStr = padStartSafe(breakdownNum(srvMs), STAGE_NUM_W);
55114
+ const strStr = padStartSafe(breakdownNum(strMs), STAGE_NUM_W);
55115
+ return /* @__PURE__ */ jsxDEV("text", {
55116
+ children: [
55117
+ prefix,
55118
+ stages.network > 0 && /* @__PURE__ */ jsxDEV("span", {
55119
+ bg: STAGE_BG.network,
55120
+ children: " ".repeat(stages.network)
55121
+ }, undefined, false, undefined, this),
55122
+ stages.server > 0 && /* @__PURE__ */ jsxDEV("span", {
55123
+ bg: STAGE_BG.server,
55124
+ children: " ".repeat(stages.server)
55125
+ }, undefined, false, undefined, this),
55126
+ stages.streaming > 0 && /* @__PURE__ */ jsxDEV("span", {
55127
+ bg: STAGE_BG.streaming,
55128
+ children: " ".repeat(stages.streaming)
55129
+ }, undefined, false, undefined, this),
55130
+ trackCells > 0 && /* @__PURE__ */ jsxDEV("span", {
55131
+ fg: C.dim,
55132
+ children: TRACK_CHAR.repeat(trackCells)
54833
55133
  }, undefined, false, undefined, this),
54834
55134
  /* @__PURE__ */ jsxDEV("span", {
54835
- fg: C.fg,
54836
- children: displayName
55135
+ fg: C.dim,
55136
+ children: " "
54837
55137
  }, undefined, false, undefined, this),
54838
55138
  /* @__PURE__ */ jsxDEV("span", {
55139
+ fg: C.white,
55140
+ children: padStartSafe(formatLatency(t.totalMs), TOTAL_COL)
55141
+ }, undefined, false, undefined, this),
55142
+ layout.showBreakdown && /* @__PURE__ */ jsxDEV(Fragment, {
55143
+ children: [
55144
+ /* @__PURE__ */ jsxDEV("span", {
55145
+ fg: C.dim,
55146
+ children: " net "
55147
+ }, undefined, false, undefined, this),
55148
+ /* @__PURE__ */ jsxDEV("span", {
55149
+ fg: STAGE_FG.network,
55150
+ children: netStr
55151
+ }, undefined, false, undefined, this),
55152
+ /* @__PURE__ */ jsxDEV("span", {
55153
+ fg: C.dim,
55154
+ children: " srv "
55155
+ }, undefined, false, undefined, this),
55156
+ /* @__PURE__ */ jsxDEV("span", {
55157
+ fg: STAGE_FG.server,
55158
+ children: srvStr
55159
+ }, undefined, false, undefined, this),
55160
+ /* @__PURE__ */ jsxDEV("span", {
55161
+ fg: C.dim,
55162
+ children: " str "
55163
+ }, undefined, false, undefined, this),
55164
+ /* @__PURE__ */ jsxDEV("span", {
55165
+ fg: STAGE_FG.streaming,
55166
+ children: strStr
55167
+ }, undefined, false, undefined, this)
55168
+ ]
55169
+ }, undefined, true, undefined, this),
55170
+ layout.tokWidth > 0 && /* @__PURE__ */ jsxDEV(Fragment, {
55171
+ children: [
55172
+ /* @__PURE__ */ jsxDEV("span", {
55173
+ fg: C.dim,
55174
+ children: " "
55175
+ }, undefined, false, undefined, this),
55176
+ tokCells > 0 && /* @__PURE__ */ jsxDEV("span", {
55177
+ fg: tokColor,
55178
+ children: BAR_FILL.repeat(tokCells)
55179
+ }, undefined, false, undefined, this),
55180
+ tokTrack > 0 && /* @__PURE__ */ jsxDEV("span", {
55181
+ fg: C.dim,
55182
+ children: TRACK_CHAR.repeat(tokTrack)
55183
+ }, undefined, false, undefined, this),
55184
+ /* @__PURE__ */ jsxDEV("span", {
55185
+ fg: C.dim,
55186
+ children: " "
55187
+ }, undefined, false, undefined, this)
55188
+ ]
55189
+ }, undefined, true, undefined, this),
55190
+ layout.tokWidth === 0 && /* @__PURE__ */ jsxDEV("span", {
54839
55191
  fg: C.dim,
54840
55192
  children: " "
54841
55193
  }, undefined, false, undefined, this),
54842
55194
  /* @__PURE__ */ jsxDEV("span", {
54843
- fg: statusColor,
54844
- children: statusText
55195
+ fg: tokColor,
55196
+ children: tokValue
55197
+ }, undefined, false, undefined, this),
55198
+ isRunFastest && /* @__PURE__ */ jsxDEV("span", {
55199
+ fg: C.brightGreen,
55200
+ children: " \u25CF"
54845
55201
  }, undefined, false, undefined, this)
54846
55202
  ]
54847
55203
  }, undefined, true, undefined, this);
54848
55204
  }
55205
+ function renderTimelineSlot(link, animFrame, barWidth) {
55206
+ if (barWidth <= 0)
55207
+ return null;
55208
+ switch (link.status) {
55209
+ case "probing": {
55210
+ let animated = "";
55211
+ for (let i = 0;i < barWidth; i++) {
55212
+ animated += ANIM_FRAMES[(animFrame + i) % ANIM_FRAMES.length];
55213
+ }
55214
+ return /* @__PURE__ */ jsxDEV("span", {
55215
+ fg: C.cyan,
55216
+ children: animated
55217
+ }, undefined, false, undefined, this);
55218
+ }
55219
+ case "failed":
55220
+ return /* @__PURE__ */ jsxDEV("span", {
55221
+ fg: C.red,
55222
+ children: padEndSafe(`\u2717 ${stripAnsi2(link.error || "failed")}`, barWidth)
55223
+ }, undefined, false, undefined, this);
55224
+ case "waiting":
55225
+ default:
55226
+ return /* @__PURE__ */ jsxDEV("span", {
55227
+ fg: C.dim,
55228
+ children: "\u2591".repeat(barWidth)
55229
+ }, undefined, false, undefined, this);
55230
+ }
55231
+ }
55232
+ function renderNonLiveStatus(link, hasSlot) {
55233
+ switch (link.status) {
55234
+ case "probing": {
55235
+ const elapsedMs = link.startTime ? Date.now() - link.startTime : 0;
55236
+ return /* @__PURE__ */ jsxDEV("span", {
55237
+ fg: C.cyan,
55238
+ children: `\u23F3 probing ${formatElapsed(elapsedMs)}`
55239
+ }, undefined, false, undefined, this);
55240
+ }
55241
+ case "failed":
55242
+ return hasSlot ? /* @__PURE__ */ jsxDEV("span", {
55243
+ fg: C.red,
55244
+ children: "\u2717"
55245
+ }, undefined, false, undefined, this) : /* @__PURE__ */ jsxDEV("span", {
55246
+ fg: C.red,
55247
+ children: `\u2717 ${stripAnsi2(link.error || "failed")}`
55248
+ }, undefined, false, undefined, this);
55249
+ case "waiting":
55250
+ default:
55251
+ return /* @__PURE__ */ jsxDEV("span", {
55252
+ fg: C.dim,
55253
+ children: "\u23F3 waiting\u2026"
55254
+ }, undefined, false, undefined, this);
55255
+ }
55256
+ }
54849
55257
  function ModelGroup({
54850
55258
  model,
54851
55259
  links,
54852
55260
  animFrame,
54853
55261
  maxNameLen,
54854
55262
  rowWidth,
54855
- isLast
55263
+ isLast,
55264
+ layout,
55265
+ maxTotalMs,
55266
+ maxTokPerSec,
55267
+ fastestLinkId
54856
55268
  }) {
54857
55269
  const headerWidth = rowWidth - 2;
54858
55270
  const totalPad = Math.max(0, headerWidth - model.length);
@@ -54884,14 +55296,500 @@ function ModelGroup({
54884
55296
  links.map((link) => /* @__PURE__ */ jsxDEV(ProgressBar, {
54885
55297
  link,
54886
55298
  animFrame,
54887
- maxNameLen
55299
+ maxNameLen,
55300
+ layout,
55301
+ maxTotalMs,
55302
+ maxTokPerSec,
55303
+ isRunFastest: fastestLinkId === link.id
54888
55304
  }, link.id, false, undefined, this))
54889
55305
  ]
54890
55306
  }, undefined, true, undefined, this);
54891
55307
  }
54892
- function ProbeApp({ store }) {
55308
+ function TabBar({ activeTab }) {
55309
+ const tab = (label, active) => /* @__PURE__ */ jsxDEV("span", {
55310
+ bg: active ? C.tabActiveBg : C.tabInactiveBg,
55311
+ fg: active ? C.tabActiveFg : C.tabInactiveFg,
55312
+ attributes: active ? A.bold : undefined,
55313
+ children: ` ${label} `
55314
+ }, undefined, false, undefined, this);
55315
+ return /* @__PURE__ */ jsxDEV("box", {
55316
+ flexDirection: "column",
55317
+ paddingTop: 1,
55318
+ paddingBottom: 1,
55319
+ children: /* @__PURE__ */ jsxDEV("text", {
55320
+ children: [
55321
+ /* @__PURE__ */ jsxDEV("span", {
55322
+ fg: C.dim,
55323
+ children: " "
55324
+ }, undefined, false, undefined, this),
55325
+ tab("1 Leaderboard", activeTab === "leaderboard"),
55326
+ /* @__PURE__ */ jsxDEV("span", {
55327
+ children: " "
55328
+ }, undefined, false, undefined, this),
55329
+ tab("2 Details", activeTab === "details")
55330
+ ]
55331
+ }, undefined, true, undefined, this)
55332
+ }, undefined, false, undefined, this);
55333
+ }
55334
+ function Legend({ rowWidth }) {
55335
+ const ruleWidth = Math.max(1, Math.min(rowWidth, 120));
55336
+ return /* @__PURE__ */ jsxDEV("box", {
55337
+ flexDirection: "column",
55338
+ children: [
55339
+ /* @__PURE__ */ jsxDEV("text", {
55340
+ children: [
55341
+ /* @__PURE__ */ jsxDEV("span", {
55342
+ bg: STAGE_BG.network,
55343
+ children: " "
55344
+ }, undefined, false, undefined, this),
55345
+ /* @__PURE__ */ jsxDEV("span", {
55346
+ fg: STAGE_FG.network,
55347
+ children: " net "
55348
+ }, undefined, false, undefined, this),
55349
+ /* @__PURE__ */ jsxDEV("span", {
55350
+ bg: STAGE_BG.server,
55351
+ children: " "
55352
+ }, undefined, false, undefined, this),
55353
+ /* @__PURE__ */ jsxDEV("span", {
55354
+ fg: STAGE_FG.server,
55355
+ children: " srv "
55356
+ }, undefined, false, undefined, this),
55357
+ /* @__PURE__ */ jsxDEV("span", {
55358
+ bg: STAGE_BG.streaming,
55359
+ children: " "
55360
+ }, undefined, false, undefined, this),
55361
+ /* @__PURE__ */ jsxDEV("span", {
55362
+ fg: STAGE_FG.streaming,
55363
+ children: " str "
55364
+ }, undefined, false, undefined, this),
55365
+ /* @__PURE__ */ jsxDEV("span", {
55366
+ fg: C.dim,
55367
+ children: "\xB7\xB7 idle \xB7 bar = total time (shared scale) \xB7 tok/s color = absolute"
55368
+ }, undefined, false, undefined, this)
55369
+ ]
55370
+ }, undefined, true, undefined, this),
55371
+ /* @__PURE__ */ jsxDEV("text", {
55372
+ children: /* @__PURE__ */ jsxDEV("span", {
55373
+ fg: C.dim,
55374
+ children: " " + "\u2500".repeat(ruleWidth)
55375
+ }, undefined, false, undefined, this)
55376
+ }, undefined, false, undefined, this)
55377
+ ]
55378
+ }, undefined, true, undefined, this);
55379
+ }
55380
+ function formatContextWindow(ctx) {
55381
+ if (ctx <= 0)
55382
+ return "0";
55383
+ if (ctx >= 1e6)
55384
+ return `${(ctx / 1e6).toFixed(1)}M`;
55385
+ return `${Math.round(ctx / 1000)}K`;
55386
+ }
55387
+ function ruleKeyForModel(model) {
55388
+ const at = model.indexOf("@");
55389
+ return at >= 0 ? model.slice(at + 1) : model;
55390
+ }
55391
+ function detailRowWidth(provW, layout) {
55392
+ let w = 2 + 1 + 1 + provW + 2 + 1 + 2;
55393
+ w += layout.barWidth + 2 + TOTAL_COL;
55394
+ if (layout.showBreakdown)
55395
+ w += BREAKDOWN_COL;
55396
+ else
55397
+ w += 2;
55398
+ if (layout.tokWidth > 0)
55399
+ w += layout.tokWidth + 1;
55400
+ w += TOK_VALUE_COL;
55401
+ return w;
55402
+ }
55403
+ function shortFailureReason(probe, hasCreds) {
55404
+ if (!probe)
55405
+ return hasCreds ? "not probed" : "key missing";
55406
+ if (probe.state === "key-missing")
55407
+ return "key missing";
55408
+ return stripAnsi2(describeProbeState(probe));
55409
+ }
55410
+ function DetailLinkRow({
55411
+ link,
55412
+ isWinner,
55413
+ provW,
55414
+ layout,
55415
+ maxTotalMs,
55416
+ maxTokPerSec
55417
+ }) {
55418
+ const probe = link.probe;
55419
+ const isLive = probe?.state === "live" && !!probe.timing;
55420
+ const winnerMark = isWinner ? /* @__PURE__ */ jsxDEV("span", {
55421
+ fg: C.brightGreen,
55422
+ children: "\u25CF"
55423
+ }, undefined, false, undefined, this) : /* @__PURE__ */ jsxDEV("span", {
55424
+ children: " "
55425
+ }, undefined, false, undefined, this);
55426
+ const provider = /* @__PURE__ */ jsxDEV("span", {
55427
+ fg: C.fg,
55428
+ children: padEndSafe(link.displayName, provW)
55429
+ }, undefined, false, undefined, this);
55430
+ const lead = /* @__PURE__ */ jsxDEV(Fragment, {
55431
+ children: [
55432
+ /* @__PURE__ */ jsxDEV("span", {
55433
+ fg: C.dim,
55434
+ children: " "
55435
+ }, undefined, false, undefined, this),
55436
+ winnerMark,
55437
+ /* @__PURE__ */ jsxDEV("span", {
55438
+ children: " "
55439
+ }, undefined, false, undefined, this),
55440
+ provider,
55441
+ /* @__PURE__ */ jsxDEV("span", {
55442
+ children: " "
55443
+ }, undefined, false, undefined, this)
55444
+ ]
55445
+ }, undefined, true, undefined, this);
55446
+ if (!isLive || !probe?.timing) {
55447
+ return /* @__PURE__ */ jsxDEV("text", {
55448
+ children: [
55449
+ lead,
55450
+ /* @__PURE__ */ jsxDEV("span", {
55451
+ fg: C.red,
55452
+ children: "\u2717 "
55453
+ }, undefined, false, undefined, this),
55454
+ /* @__PURE__ */ jsxDEV("span", {
55455
+ fg: C.red,
55456
+ children: shortFailureReason(probe, link.hasCredentials)
55457
+ }, undefined, false, undefined, this)
55458
+ ]
55459
+ }, undefined, true, undefined, this);
55460
+ }
55461
+ const t = probe.timing;
55462
+ const barCells = timelineBarCells(t.totalMs, maxTotalMs, layout.barWidth);
55463
+ const stages = splitStageCells(t.ttfbMs, t.ttftMs, t.totalMs, barCells);
55464
+ const trackCells = Math.max(0, layout.barWidth - barCells);
55465
+ const netMs = Math.max(0, t.ttfbMs);
55466
+ const srvMs = Math.max(0, t.ttftMs - t.ttfbMs);
55467
+ const strMs = Math.max(0, t.totalMs - t.ttftMs);
55468
+ const netStr = padStartSafe(breakdownNum(netMs), STAGE_NUM_W);
55469
+ const srvStr = padStartSafe(breakdownNum(srvMs), STAGE_NUM_W);
55470
+ const strStr = padStartSafe(breakdownNum(strMs), STAGE_NUM_W);
55471
+ const tokColor = throughputFg(t.tokensPerSec);
55472
+ const tokCells = layout.tokWidth > 0 ? tokBarCells(t.tokensPerSec, maxTokPerSec, layout.tokWidth) : 0;
55473
+ const tokTrack = Math.max(0, layout.tokWidth - tokCells);
55474
+ const tokValue = padStartSafe(`${Math.round(t.tokensPerSec)} t/s`, TOK_VALUE_COL);
55475
+ return /* @__PURE__ */ jsxDEV("text", {
55476
+ children: [
55477
+ lead,
55478
+ /* @__PURE__ */ jsxDEV("span", {
55479
+ fg: C.green,
55480
+ children: "\u2713 "
55481
+ }, undefined, false, undefined, this),
55482
+ stages.network > 0 && /* @__PURE__ */ jsxDEV("span", {
55483
+ bg: STAGE_BG.network,
55484
+ children: " ".repeat(stages.network)
55485
+ }, undefined, false, undefined, this),
55486
+ stages.server > 0 && /* @__PURE__ */ jsxDEV("span", {
55487
+ bg: STAGE_BG.server,
55488
+ children: " ".repeat(stages.server)
55489
+ }, undefined, false, undefined, this),
55490
+ stages.streaming > 0 && /* @__PURE__ */ jsxDEV("span", {
55491
+ bg: STAGE_BG.streaming,
55492
+ children: " ".repeat(stages.streaming)
55493
+ }, undefined, false, undefined, this),
55494
+ trackCells > 0 && /* @__PURE__ */ jsxDEV("span", {
55495
+ fg: C.dim,
55496
+ children: TRACK_CHAR.repeat(trackCells)
55497
+ }, undefined, false, undefined, this),
55498
+ /* @__PURE__ */ jsxDEV("span", {
55499
+ fg: C.dim,
55500
+ children: " "
55501
+ }, undefined, false, undefined, this),
55502
+ /* @__PURE__ */ jsxDEV("span", {
55503
+ fg: C.white,
55504
+ children: padStartSafe(formatLatency(t.totalMs), TOTAL_COL)
55505
+ }, undefined, false, undefined, this),
55506
+ layout.showBreakdown && /* @__PURE__ */ jsxDEV(Fragment, {
55507
+ children: [
55508
+ /* @__PURE__ */ jsxDEV("span", {
55509
+ fg: C.dim,
55510
+ children: " net "
55511
+ }, undefined, false, undefined, this),
55512
+ /* @__PURE__ */ jsxDEV("span", {
55513
+ fg: STAGE_FG.network,
55514
+ children: netStr
55515
+ }, undefined, false, undefined, this),
55516
+ /* @__PURE__ */ jsxDEV("span", {
55517
+ fg: C.dim,
55518
+ children: " srv "
55519
+ }, undefined, false, undefined, this),
55520
+ /* @__PURE__ */ jsxDEV("span", {
55521
+ fg: STAGE_FG.server,
55522
+ children: srvStr
55523
+ }, undefined, false, undefined, this),
55524
+ /* @__PURE__ */ jsxDEV("span", {
55525
+ fg: C.dim,
55526
+ children: " str "
55527
+ }, undefined, false, undefined, this),
55528
+ /* @__PURE__ */ jsxDEV("span", {
55529
+ fg: STAGE_FG.streaming,
55530
+ children: strStr
55531
+ }, undefined, false, undefined, this)
55532
+ ]
55533
+ }, undefined, true, undefined, this),
55534
+ layout.tokWidth > 0 && /* @__PURE__ */ jsxDEV(Fragment, {
55535
+ children: [
55536
+ /* @__PURE__ */ jsxDEV("span", {
55537
+ fg: C.dim,
55538
+ children: " "
55539
+ }, undefined, false, undefined, this),
55540
+ tokCells > 0 && /* @__PURE__ */ jsxDEV("span", {
55541
+ fg: tokColor,
55542
+ children: BAR_FILL.repeat(tokCells)
55543
+ }, undefined, false, undefined, this),
55544
+ tokTrack > 0 && /* @__PURE__ */ jsxDEV("span", {
55545
+ fg: C.dim,
55546
+ children: TRACK_CHAR.repeat(tokTrack)
55547
+ }, undefined, false, undefined, this),
55548
+ /* @__PURE__ */ jsxDEV("span", {
55549
+ fg: C.dim,
55550
+ children: " "
55551
+ }, undefined, false, undefined, this)
55552
+ ]
55553
+ }, undefined, true, undefined, this),
55554
+ layout.tokWidth === 0 && /* @__PURE__ */ jsxDEV("span", {
55555
+ fg: C.dim,
55556
+ children: " "
55557
+ }, undefined, false, undefined, this),
55558
+ /* @__PURE__ */ jsxDEV("span", {
55559
+ fg: tokColor,
55560
+ children: tokValue
55561
+ }, undefined, false, undefined, this)
55562
+ ]
55563
+ }, undefined, true, undefined, this);
55564
+ }
55565
+ function DetailModel({
55566
+ result,
55567
+ provW,
55568
+ headerW,
55569
+ layout,
55570
+ maxTotalMs,
55571
+ maxTokPerSec,
55572
+ isLast
55573
+ }) {
55574
+ const winnerIdx = result.links.findIndex((l) => l.probe?.state === "live" && !!l.probe.timing);
55575
+ const winner = winnerIdx >= 0 ? result.links[winnerIdx] : undefined;
55576
+ const gap = Math.max(2, headerW - result.model.length - result.routingExplanation.length - 2);
55577
+ const wiring = result.wiring;
55578
+ const wireLine = winner && wiring ? `wire (${winner.displayName}): ${wiring.effectiveStreamFormat} \xB7 ${wiring.modelTranslator} \xB7 ${formatContextWindow(wiring.contextWindow)} ctx` : "wire: \u2014";
55579
+ const routeChain = result.links.map((l) => l.displayName).join(" \u2192 ");
55580
+ const liveLinks = result.links.filter((l) => l.probe?.state === "live" && !!l.probe.timing);
55581
+ let fastestByLatency;
55582
+ let fastestByTput;
55583
+ for (const l of liveLinks) {
55584
+ const t = l.probe.timing;
55585
+ if (!fastestByLatency || t.totalMs < fastestByLatency.probe.timing.totalMs) {
55586
+ fastestByLatency = l;
55587
+ }
55588
+ if (!fastestByTput || t.tokensPerSec > fastestByTput.probe.timing.tokensPerSec) {
55589
+ fastestByTput = l;
55590
+ }
55591
+ }
55592
+ const winnerT = winner?.probe?.timing;
55593
+ const candidates = [];
55594
+ if (winner && winnerT) {
55595
+ if (fastestByLatency && fastestByLatency !== winner && fastestByLatency.probe.timing.totalMs < winnerT.totalMs) {
55596
+ candidates.push({
55597
+ link: fastestByLatency,
55598
+ factor: winnerT.totalMs / Math.max(1, fastestByLatency.probe.timing.totalMs),
55599
+ axis: "latency"
55600
+ });
55601
+ }
55602
+ if (fastestByTput && fastestByTput !== winner && fastestByTput.probe.timing.tokensPerSec > winnerT.tokensPerSec && winnerT.tokensPerSec > 0) {
55603
+ candidates.push({
55604
+ link: fastestByTput,
55605
+ factor: fastestByTput.probe.timing.tokensPerSec / winnerT.tokensPerSec,
55606
+ axis: "throughput"
55607
+ });
55608
+ }
55609
+ }
55610
+ const suggestion = candidates.sort((a, b) => b.factor - a.factor)[0];
55611
+ const showSuggestion = !!suggestion;
55612
+ const ruleKey = ruleKeyForModel(result.model);
55613
+ return /* @__PURE__ */ jsxDEV("box", {
55614
+ flexDirection: "column",
55615
+ marginBottom: isLast ? 0 : 1,
55616
+ children: [
55617
+ /* @__PURE__ */ jsxDEV("text", {
55618
+ children: [
55619
+ /* @__PURE__ */ jsxDEV("span", {
55620
+ fg: C.dim,
55621
+ children: " "
55622
+ }, undefined, false, undefined, this),
55623
+ /* @__PURE__ */ jsxDEV("span", {
55624
+ fg: C.cyan,
55625
+ attributes: A.bold,
55626
+ children: result.model
55627
+ }, undefined, false, undefined, this),
55628
+ /* @__PURE__ */ jsxDEV("span", {
55629
+ fg: C.dim,
55630
+ children: " ".repeat(gap)
55631
+ }, undefined, false, undefined, this),
55632
+ /* @__PURE__ */ jsxDEV("span", {
55633
+ fg: C.dim,
55634
+ children: result.routingExplanation
55635
+ }, undefined, false, undefined, this)
55636
+ ]
55637
+ }, undefined, true, undefined, this),
55638
+ result.links.map((link, i) => /* @__PURE__ */ jsxDEV(DetailLinkRow, {
55639
+ link,
55640
+ isWinner: i === winnerIdx,
55641
+ provW,
55642
+ layout,
55643
+ maxTotalMs,
55644
+ maxTokPerSec
55645
+ }, `${result.model}:${link.provider}:${i}`, false, undefined, this)),
55646
+ /* @__PURE__ */ jsxDEV("text", {
55647
+ children: /* @__PURE__ */ jsxDEV("span", {
55648
+ fg: C.dim,
55649
+ children: ` ${wireLine}`
55650
+ }, undefined, false, undefined, this)
55651
+ }, undefined, false, undefined, this),
55652
+ /* @__PURE__ */ jsxDEV("text", {
55653
+ children: [
55654
+ /* @__PURE__ */ jsxDEV("span", {
55655
+ fg: C.dim,
55656
+ children: " route: "
55657
+ }, undefined, false, undefined, this),
55658
+ /* @__PURE__ */ jsxDEV("span", {
55659
+ fg: C.fgMuted,
55660
+ children: routeChain || "\u2014"
55661
+ }, undefined, false, undefined, this),
55662
+ winner && /* @__PURE__ */ jsxDEV(Fragment, {
55663
+ children: [
55664
+ /* @__PURE__ */ jsxDEV("span", {
55665
+ fg: C.dim,
55666
+ children: " \xB7 uses "
55667
+ }, undefined, false, undefined, this),
55668
+ /* @__PURE__ */ jsxDEV("span", {
55669
+ fg: C.green,
55670
+ children: winner.displayName
55671
+ }, undefined, false, undefined, this),
55672
+ /* @__PURE__ */ jsxDEV("span", {
55673
+ fg: C.dim,
55674
+ children: " (first credentialed live link)"
55675
+ }, undefined, false, undefined, this)
55676
+ ]
55677
+ }, undefined, true, undefined, this)
55678
+ ]
55679
+ }, undefined, true, undefined, this),
55680
+ showSuggestion && /* @__PURE__ */ jsxDEV("text", {
55681
+ children: [
55682
+ /* @__PURE__ */ jsxDEV("span", {
55683
+ fg: C.yellow,
55684
+ attributes: A.bold,
55685
+ children: " \u26A1 "
55686
+ }, undefined, false, undefined, this),
55687
+ /* @__PURE__ */ jsxDEV("span", {
55688
+ fg: C.fg,
55689
+ children: suggestion.link.displayName
55690
+ }, undefined, false, undefined, this),
55691
+ /* @__PURE__ */ jsxDEV("span", {
55692
+ fg: C.green,
55693
+ children: ` is ${suggestion.factor.toFixed(1)}\xD7 faster ${suggestion.axis === "latency" ? "end-to-end" : "throughput"}`
55694
+ }, undefined, false, undefined, this),
55695
+ /* @__PURE__ */ jsxDEV("span", {
55696
+ fg: C.dim,
55697
+ 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)`
55698
+ }, undefined, false, undefined, this),
55699
+ /* @__PURE__ */ jsxDEV("span", {
55700
+ fg: C.dim,
55701
+ children: ` \u2014 add routing: `
55702
+ }, undefined, false, undefined, this),
55703
+ /* @__PURE__ */ jsxDEV("span", {
55704
+ fg: C.cyan,
55705
+ children: `"${ruleKey}": ["${suggestion.link.provider}"]`
55706
+ }, undefined, false, undefined, this)
55707
+ ]
55708
+ }, undefined, true, undefined, this)
55709
+ ]
55710
+ }, undefined, true, undefined, this);
55711
+ }
55712
+ function DetailsView({
55713
+ results,
55714
+ layout,
55715
+ termWidth,
55716
+ maxTotalMs,
55717
+ maxTokPerSec
55718
+ }) {
55719
+ const provW = Math.min(22, Math.max(8, ...results.flatMap((r) => r.links.map((l) => l.displayName.length))));
55720
+ const headerW = Math.max(24, Math.min(detailRowWidth(provW, layout), (termWidth || 100) - 3));
55721
+ return /* @__PURE__ */ jsxDEV("box", {
55722
+ flexDirection: "column",
55723
+ children: results.map((r, idx) => /* @__PURE__ */ jsxDEV(DetailModel, {
55724
+ result: r,
55725
+ provW,
55726
+ headerW,
55727
+ layout,
55728
+ maxTotalMs,
55729
+ maxTokPerSec,
55730
+ isLast: idx === results.length - 1
55731
+ }, r.model, false, undefined, this))
55732
+ }, undefined, false, undefined, this);
55733
+ }
55734
+ function ProbeApp({
55735
+ store,
55736
+ onQuit
55737
+ }) {
54893
55738
  const state = useProbeStore(store);
54894
- const animFrame = useAnimationFrame(true);
55739
+ const animFrame = useAnimationFrame(state.phase === "live");
55740
+ const { height: termHeight, width: termWidth } = useTerminalDimensions();
55741
+ const isDone = state.phase === "done";
55742
+ const listScrollRef = useRef2(null);
55743
+ useKeyboard((key) => {
55744
+ if (isDone) {
55745
+ if (key.name === "q" || key.name === "escape") {
55746
+ onQuit?.();
55747
+ return;
55748
+ }
55749
+ if (key.name === "tab") {
55750
+ store.setActiveTab(store.getState().activeTab === "leaderboard" ? "details" : "leaderboard");
55751
+ return;
55752
+ }
55753
+ if (key.name === "1") {
55754
+ store.setActiveTab("leaderboard");
55755
+ return;
55756
+ }
55757
+ if (key.name === "2") {
55758
+ store.setActiveTab("details");
55759
+ return;
55760
+ }
55761
+ }
55762
+ const sb = listScrollRef.current;
55763
+ if (!sb)
55764
+ return;
55765
+ const page = Math.max(1, sb.viewport.height - 1);
55766
+ switch (key.name) {
55767
+ case "up":
55768
+ case "k":
55769
+ sb.scrollBy(-1);
55770
+ break;
55771
+ case "down":
55772
+ case "j":
55773
+ sb.scrollBy(1);
55774
+ break;
55775
+ case "pageup":
55776
+ sb.scrollBy(-page);
55777
+ break;
55778
+ case "pagedown":
55779
+ case "space":
55780
+ sb.scrollBy(page);
55781
+ break;
55782
+ case "home":
55783
+ sb.scrollTo(0);
55784
+ break;
55785
+ case "end":
55786
+ sb.scrollTo(sb.content.height);
55787
+ break;
55788
+ case "g":
55789
+ sb.scrollTo(key.shift ? sb.content.height : 0);
55790
+ break;
55791
+ }
55792
+ });
54895
55793
  const groups = [];
54896
55794
  for (const link of state.links) {
54897
55795
  let group = groups.find((g) => g.model === link.model);
@@ -54902,36 +55800,105 @@ function ProbeApp({ store }) {
54902
55800
  group.links.push(link);
54903
55801
  }
54904
55802
  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;
55803
+ const layout = deriveLayout(termWidth || 100);
55804
+ const rowWidth = computeRowWidth(layout, maxNameLen);
55805
+ let maxTotalMs = 1;
55806
+ let maxTokPerSec = 1;
55807
+ let fastestLinkId = null;
55808
+ let fastestTokPerSec = -Infinity;
55809
+ for (const link of state.links) {
55810
+ if (link.status !== "live" || !link.timing)
55811
+ continue;
55812
+ const t = link.timing;
55813
+ if (t.totalMs > maxTotalMs)
55814
+ maxTotalMs = t.totalMs;
55815
+ const streamMs = Math.max(STREAM_MS_FLOOR, t.totalMs - t.ttftMs);
55816
+ const scaledTps = t.tokens > 0 ? t.tokens / streamMs * 1000 : 0;
55817
+ if (scaledTps > maxTokPerSec)
55818
+ maxTokPerSec = scaledTps;
55819
+ if (t.tokensPerSec > fastestTokPerSec) {
55820
+ fastestTokPerSec = t.tokensPerSec;
55821
+ fastestLinkId = link.id;
55822
+ }
55823
+ }
55824
+ if (fastestTokPerSec <= 0)
55825
+ fastestLinkId = null;
55826
+ const showDetails = isDone && state.activeTab === "details";
55827
+ const stepsRows = isDone ? 0 : state.steps.length > 0 ? 1 : 0;
55828
+ const tabBarRows = isDone ? TAB_BAR_ROWS : 0;
55829
+ const legendRows = showDetails ? 0 : LEGEND_ROWS;
55830
+ const listH = Math.max(MIN_LIST_H, termHeight - BANNER_ROWS - stepsRows - tabBarRows - legendRows - SCROLL_HINT_ROWS);
55831
+ const sbForHint = listScrollRef.current;
55832
+ const overflow = sbForHint ? sbForHint.content.height > sbForHint.viewport.height : true;
55833
+ const scrollKeys = "\u2191\u2193 scroll \xB7 PgUp/PgDn page \xB7 g/G top/bottom";
55834
+ const footerHint = isDone ? " " + (overflow ? scrollKeys + " \xB7 " : "") + "Tab/1/2 switch \xB7 q quit" : " " + (overflow ? scrollKeys : "");
54906
55835
  return /* @__PURE__ */ jsxDEV("box", {
54907
55836
  flexDirection: "column",
54908
55837
  children: [
54909
- /* @__PURE__ */ jsxDEV(Banner, {}, undefined, false, undefined, this),
54910
55838
  /* @__PURE__ */ jsxDEV("box", {
54911
55839
  flexDirection: "column",
54912
- paddingY: 1,
54913
- children: state.steps.map((step, i) => /* @__PURE__ */ jsxDEV(StepIndicator, {
54914
- step
54915
- }, `${step.name}-${i}`, false, undefined, this))
55840
+ height: BANNER_ROWS,
55841
+ children: /* @__PURE__ */ jsxDEV(Banner, {}, undefined, false, undefined, this)
54916
55842
  }, undefined, false, undefined, this),
54917
- groups.length > 0 ? /* @__PURE__ */ jsxDEV("box", {
55843
+ isDone ? /* @__PURE__ */ jsxDEV(TabBar, {
55844
+ activeTab: state.activeTab
55845
+ }, undefined, false, undefined, this) : /* @__PURE__ */ jsxDEV("box", {
54918
55846
  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
55847
+ children: /* @__PURE__ */ jsxDEV(StepLine, {
55848
+ steps: state.steps
55849
+ }, undefined, false, undefined, this)
55850
+ }, undefined, false, undefined, this),
55851
+ groups.length > 0 ? /* @__PURE__ */ jsxDEV(Fragment, {
55852
+ children: [
55853
+ !showDetails && /* @__PURE__ */ jsxDEV("box", {
55854
+ flexDirection: "column",
55855
+ height: LEGEND_ROWS,
55856
+ children: /* @__PURE__ */ jsxDEV(Legend, {
55857
+ rowWidth
55858
+ }, undefined, false, undefined, this)
55859
+ }, undefined, false, undefined, this),
55860
+ /* @__PURE__ */ jsxDEV("scrollbox", {
55861
+ ref: listScrollRef,
55862
+ scrollX: false,
55863
+ scrollY: true,
55864
+ focused: true,
55865
+ style: { height: listH },
55866
+ children: showDetails ? /* @__PURE__ */ jsxDEV(DetailsView, {
55867
+ results: state.results,
55868
+ layout,
55869
+ termWidth,
55870
+ maxTotalMs,
55871
+ maxTokPerSec
55872
+ }, undefined, false, undefined, this) : groups.map((g, idx) => /* @__PURE__ */ jsxDEV(ModelGroup, {
55873
+ model: g.model,
55874
+ links: g.links,
55875
+ animFrame,
55876
+ maxNameLen,
55877
+ rowWidth,
55878
+ isLast: idx === groups.length - 1,
55879
+ layout,
55880
+ maxTotalMs,
55881
+ maxTokPerSec,
55882
+ fastestLinkId
55883
+ }, g.model, false, undefined, this))
55884
+ }, undefined, false, undefined, this),
55885
+ /* @__PURE__ */ jsxDEV("text", {
55886
+ children: /* @__PURE__ */ jsxDEV("span", {
55887
+ fg: C.dim,
55888
+ children: footerHint
55889
+ }, undefined, false, undefined, this)
55890
+ }, undefined, false, undefined, this)
55891
+ ]
55892
+ }, undefined, true, undefined, this) : null
54928
55893
  ]
54929
- }, undefined, true, undefined, this);
55894
+ }, state.phase, true, undefined, this);
54930
55895
  }
54931
- var ANIM_FRAMES, BAR_WIDTH = 20;
55896
+ 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
55897
  var init_probe_tui_app = __esm(() => {
54933
55898
  init_theme2();
55899
+ init_probe_live();
54934
55900
  ANIM_FRAMES = ["\u2593", "\u2592", "\u2591", "\u2592"];
55901
+ BREAKDOWN_COL = 16 + 3 * STAGE_NUM_W;
54935
55902
  });
54936
55903
 
54937
55904
  // src/probe/probe-tui-runtime.tsx
@@ -54942,13 +55909,25 @@ async function startProbeTui(initial) {
54942
55909
  const renderer = await createCliRenderer({
54943
55910
  stdout: process.stderr,
54944
55911
  useAlternateScreen: false,
54945
- useMouse: false,
55912
+ useMouse: true,
54946
55913
  exitOnCtrlC: true
54947
55914
  });
54948
55915
  const store = new ProbeStore(initial);
55916
+ let resolveQuit;
55917
+ const quitPromise = new Promise((resolve3) => {
55918
+ resolveQuit = resolve3;
55919
+ });
55920
+ let quit = false;
55921
+ const onQuit = () => {
55922
+ if (quit)
55923
+ return;
55924
+ quit = true;
55925
+ resolveQuit();
55926
+ };
54949
55927
  const root = createRoot(renderer);
54950
55928
  root.render(/* @__PURE__ */ jsxDEV2(ProbeApp, {
54951
- store
55929
+ store,
55930
+ onQuit
54952
55931
  }, undefined, false, undefined, this));
54953
55932
  let destroyed = false;
54954
55933
  const shutdown = async () => {
@@ -54962,7 +55941,7 @@ async function startProbeTui(initial) {
54962
55941
  renderer.destroy();
54963
55942
  } catch {}
54964
55943
  };
54965
- return { store, shutdown };
55944
+ return { store, waitForQuit: () => quitPromise, shutdown };
54966
55945
  }
54967
55946
  var init_probe_tui_runtime = __esm(() => {
54968
55947
  init_probe_tui_app();
@@ -55024,6 +56003,104 @@ function wordWrap(text, maxWidth) {
55024
56003
  lines.push(current);
55025
56004
  return lines;
55026
56005
  }
56006
+ function computeBarScales(results) {
56007
+ let maxTokPerSec = 1;
56008
+ const liveTotals = [];
56009
+ const consider = (probe) => {
56010
+ if (!probe || probe.state !== "live" || !probe.timing)
56011
+ return;
56012
+ const t = probe.timing;
56013
+ liveTotals.push(t.totalMs);
56014
+ const streamMs = Math.max(STREAM_MS_FLOOR, t.totalMs - t.ttftMs);
56015
+ const scaledTps = t.tokens > 0 ? t.tokens / streamMs * 1000 : 0;
56016
+ if (scaledTps > maxTokPerSec)
56017
+ maxTokPerSec = scaledTps;
56018
+ };
56019
+ for (const r of results) {
56020
+ consider(r.directProbe);
56021
+ for (const c of r.chain ?? [])
56022
+ consider(c.probe);
56023
+ }
56024
+ let maxTotalMs = 1;
56025
+ if (liveTotals.length > 0) {
56026
+ const sorted = [...liveTotals].sort((a, b) => a - b);
56027
+ const rawMax = sorted[sorted.length - 1];
56028
+ maxTotalMs = Math.max(1, rawMax);
56029
+ if (sorted.length >= 3) {
56030
+ const median = sorted[Math.floor((sorted.length - 1) / 2)];
56031
+ const secondSlowest = sorted[sorted.length - 2];
56032
+ const cap = Math.max(secondSlowest, 3 * median);
56033
+ maxTotalMs = Math.max(1, Math.min(rawMax, cap));
56034
+ }
56035
+ }
56036
+ return { maxTotalMs, maxTokPerSec };
56037
+ }
56038
+ function padStartSafe2(s, n) {
56039
+ if (s.length >= n)
56040
+ return s.slice(s.length - n);
56041
+ return " ".repeat(n - s.length) + s;
56042
+ }
56043
+ function padEnd(s, n) {
56044
+ const vis = visibleLength(s);
56045
+ if (vis >= n)
56046
+ return s;
56047
+ return s + " ".repeat(n - vis);
56048
+ }
56049
+ function breakdownNum2(ms) {
56050
+ if (ms >= 1000)
56051
+ return formatLatency(ms);
56052
+ return `${Math.round(Math.max(0, ms))}`;
56053
+ }
56054
+ function buildBarsLine(timing, scales, isFastest, usable) {
56055
+ const t = timing;
56056
+ const showTokBar = usable >= PRINTER_BARS_FULL_WIDTH;
56057
+ const showBreakdown = usable >= PRINTER_BARS_FULL_WIDTH || usable >= PRINTER_BARS_NOTOK_WIDTH;
56058
+ const barCells = timelineBarCells(t.totalMs, scales.maxTotalMs, PRINTER_BAR_WIDTH);
56059
+ const stages = splitStageCells(t.ttfbMs, t.ttftMs, t.totalMs, barCells);
56060
+ const trackCells = Math.max(0, PRINTER_BAR_WIDTH - barCells);
56061
+ let timeline = "";
56062
+ if (stages.network > 0) {
56063
+ timeline += `${STAGE_BG_ANSI.network}${" ".repeat(stages.network)}${ANSI_RESET}`;
56064
+ }
56065
+ if (stages.server > 0) {
56066
+ timeline += `${STAGE_BG_ANSI.server}${" ".repeat(stages.server)}${ANSI_RESET}`;
56067
+ }
56068
+ if (stages.streaming > 0) {
56069
+ timeline += `${STAGE_BG_ANSI.streaming}${" ".repeat(stages.streaming)}${ANSI_RESET}`;
56070
+ }
56071
+ if (trackCells > 0) {
56072
+ timeline += `${pc.dim}${PRINTER_TRACK.repeat(trackCells)}${pc.reset}`;
56073
+ }
56074
+ const total = `${LATENCY_FG_ANSI}${padStartSafe2(formatLatency(t.totalMs), 7)}${pc.reset}`;
56075
+ let breakdown = "";
56076
+ if (showBreakdown) {
56077
+ const netMs = Math.max(0, t.ttfbMs);
56078
+ const srvMs = Math.max(0, t.ttftMs - t.ttfbMs);
56079
+ const strMs = Math.max(0, t.totalMs - t.ttftMs);
56080
+ const netFg = hexToAnsiFg(STAGE_FG.network);
56081
+ const srvFg = hexToAnsiFg(STAGE_FG.server);
56082
+ const strFg = hexToAnsiFg(STAGE_FG.streaming);
56083
+ 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}`;
56084
+ }
56085
+ const tokFg = hexToAnsiFg(throughputFg(t.tokensPerSec));
56086
+ let tokBar = "";
56087
+ if (showTokBar) {
56088
+ const tokCells = tokBarCells(t.tokensPerSec, scales.maxTokPerSec, PRINTER_TOK_WIDTH);
56089
+ const tokTrack = Math.max(0, PRINTER_TOK_WIDTH - tokCells);
56090
+ if (tokCells > 0) {
56091
+ tokBar += `${tokFg}${PRINTER_BAR_FILL.repeat(tokCells)}${pc.reset}`;
56092
+ }
56093
+ if (tokTrack > 0) {
56094
+ tokBar += `${pc.dim}${PRINTER_TRACK.repeat(tokTrack)}${pc.reset}`;
56095
+ }
56096
+ tokBar = ` ${tokBar} `;
56097
+ } else {
56098
+ tokBar = " ";
56099
+ }
56100
+ const tokValue = `${tokFg}${padStartSafe2(`${Math.round(t.tokensPerSec)} t/s`, PRINTER_TOK_VALUE_W)}${pc.reset}`;
56101
+ const crown = isFastest ? ` ${pc.brightGreen}\u25CF${pc.reset}` : "";
56102
+ return `${timeline} ${total}${breakdown}${tokBar}${tokValue}${crown}`;
56103
+ }
55027
56104
  function summaryColor(live, total) {
55028
56105
  if (total === 0 || live === 0)
55029
56106
  return pc.red;
@@ -55039,7 +56116,7 @@ function shortStatusLabel(probe, hasCreds, hint) {
55039
56116
  }
55040
56117
  switch (probe.state) {
55041
56118
  case "live":
55042
- return `${pc.green}\u2713 ${probe.latencyMs}ms${pc.reset}`;
56119
+ return `${pc.green}\u2713 ${LATENCY_FG_ANSI}${latencyBgAnsi(probe.latencyMs)} ${formatLatency(probe.latencyMs)} ${pc.reset}`;
55043
56120
  case "key-missing":
55044
56121
  return `${pc.dim}${pc.red}\u25CB missing${pc.reset}`;
55045
56122
  case "auth-failed":
@@ -55161,6 +56238,7 @@ function buildRowData(result, isLiveProbe) {
55161
56238
  if (entry.probe && isFailureState(entry.probe.state) && entry.probe.errorMessage) {
55162
56239
  errorDetail = stripAnsi3(entry.probe.errorMessage).replace(/\s+/g, " ").trim();
55163
56240
  }
56241
+ const barsTiming = entry.probe?.state === "live" && entry.probe.timing ? entry.probe.timing : undefined;
55164
56242
  return {
55165
56243
  num: `${i + 1}`,
55166
56244
  provider: entry.displayName,
@@ -55168,7 +56246,8 @@ function buildRowData(result, isLiveProbe) {
55168
56246
  status,
55169
56247
  errorDetail,
55170
56248
  fastest: isFastest,
55171
- slowest: isSlowest
56249
+ slowest: isSlowest,
56250
+ barsTiming
55172
56251
  };
55173
56252
  });
55174
56253
  }
@@ -55187,13 +56266,15 @@ function buildDirectRowData(result) {
55187
56266
  if (probe && isFailureState(probe.state) && probe.errorMessage) {
55188
56267
  errorDetail = stripAnsi3(probe.errorMessage).replace(/\s+/g, " ").trim();
55189
56268
  }
56269
+ const barsTiming = probe?.state === "live" && probe.timing ? probe.timing : undefined;
55190
56270
  return [
55191
56271
  {
55192
56272
  num: "1",
55193
56273
  provider: result.nativeProvider,
55194
56274
  spec: `${result.nativeProvider}@${result.model}`,
55195
56275
  status,
55196
- errorDetail
56276
+ errorDetail,
56277
+ barsTiming
55197
56278
  }
55198
56279
  ];
55199
56280
  }
@@ -55216,7 +56297,7 @@ function computeCardWidth(rows, widths, topTitleVis, topSummaryVis, footerVis) {
55216
56297
  width = maxAllowed;
55217
56298
  return width;
55218
56299
  }
55219
- function formatContextWindow(ctx) {
56300
+ function formatContextWindow2(ctx) {
55220
56301
  if (ctx <= 0)
55221
56302
  return "0K";
55222
56303
  if (ctx >= 1e6)
@@ -55238,7 +56319,7 @@ function buildKeyLine(activeEntry, directKeyVar) {
55238
56319
  return `${pc.bold}Key${pc.reset} ${pc.dim}\u2014${pc.reset}`;
55239
56320
  }
55240
56321
  function buildWireLine(wiring, activeProvider) {
55241
- const ctx = formatContextWindow(wiring.contextWindow);
56322
+ const ctx = formatContextWindow2(wiring.contextWindow);
55242
56323
  const head = activeProvider ? `${activeProvider} \u2192 ` : "";
55243
56324
  return `${pc.bold}Wire${pc.reset} ${head}${wiring.effectiveStreamFormat} \xB7 ${wiring.modelTranslator} \xB7 ${ctx}`;
55244
56325
  }
@@ -55273,7 +56354,7 @@ function computeRequiredWidth(result, isLiveProbe, directKeyVar) {
55273
56354
  const layout = buildCardLayout(result, isLiveProbe, directKeyVar);
55274
56355
  return computeCardWidth(layout.rows, layout.widths, visibleLength(layout.titleStyled), visibleLength(layout.summaryStyled), layout.footerVis);
55275
56356
  }
55276
- function renderCard(result, isLiveProbe, w, width, directKeyVar) {
56357
+ function renderCard(result, isLiveProbe, w, width, scales, directKeyVar) {
55277
56358
  const layout = buildCardLayout(result, isLiveProbe, directKeyVar);
55278
56359
  const {
55279
56360
  rows,
@@ -55308,6 +56389,17 @@ function renderCard(result, isLiveProbe, w, width, directKeyVar) {
55308
56389
  ];
55309
56390
  w(renderRow(cells, widths, width, bg) + `
55310
56391
  `);
56392
+ if (r.barsTiming) {
56393
+ const innerUsable = width - 2 - CARD_PADDING_LEFT - CARD_PADDING_RIGHT;
56394
+ const barsIndent = 4;
56395
+ const barsUsable = innerUsable - barsIndent;
56396
+ if (barsUsable >= PRINTER_BARS_MIN_WIDTH) {
56397
+ const barsLine = buildBarsLine(r.barsTiming, scales, false, barsUsable);
56398
+ const body = `${" ".repeat(barsIndent)}${barsLine}`;
56399
+ w(renderTextLine(body, width, bg) + `
56400
+ `);
56401
+ }
56402
+ }
55311
56403
  if (r.errorDetail) {
55312
56404
  const innerUsable = width - 2 - CARD_PADDING_LEFT - CARD_PADDING_RIGHT;
55313
56405
  const errorIndent = 4;
@@ -55357,18 +56449,172 @@ function renderCard(result, isLiveProbe, w, width, directKeyVar) {
55357
56449
  w(renderBorderBottom(width) + `
55358
56450
  `);
55359
56451
  }
56452
+ function renderLegend(w) {
56453
+ const net = STAGE_BG_ANSI.network;
56454
+ const srv = STAGE_BG_ANSI.server;
56455
+ const str = STAGE_BG_ANSI.streaming;
56456
+ const netFg = hexToAnsiFg(STAGE_FG.network);
56457
+ const srvFg = hexToAnsiFg(STAGE_FG.server);
56458
+ const strFg = hexToAnsiFg(STAGE_FG.streaming);
56459
+ 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}
56460
+ `);
56461
+ w(` ${pc.dim}bar length = total time, shared scale (slowest = full bar) \xB7 ` + `tok/s scaled to fastest${pc.reset}
56462
+ `);
56463
+ w(`
56464
+ `);
56465
+ }
56466
+ function pickRepresentative(result) {
56467
+ for (const entry of result.chain ?? []) {
56468
+ if (entry.probe?.state === "live" && entry.probe.timing) {
56469
+ return { model: result.model, provider: entry.displayName, timing: entry.probe.timing };
56470
+ }
56471
+ }
56472
+ const direct = result.directProbe;
56473
+ if (direct?.state === "live" && direct.timing) {
56474
+ return { model: result.model, provider: result.nativeProvider, timing: direct.timing };
56475
+ }
56476
+ return { model: result.model, provider: result.nativeProvider };
56477
+ }
56478
+ function renderLeaderboard(results, scales, maxWidth, w) {
56479
+ const reps = results.map(pickRepresentative);
56480
+ const live = reps.filter((r) => r.timing).sort((a, b) => a.timing.totalMs - b.timing.totalMs);
56481
+ const unavailable = reps.filter((r) => !r.timing);
56482
+ if (live.length === 0)
56483
+ return;
56484
+ const allNames = reps.map((r) => r.model);
56485
+ const rawNameW = Math.max(5, ...allNames.map((n) => n.length));
56486
+ const nameW = Math.min(rawNameW, 28);
56487
+ const allProviders = reps.map((r) => r.provider);
56488
+ const rawProvW = Math.max(8, ...allProviders.map((p) => p.length));
56489
+ const provW = Math.min(rawProvW, 18);
56490
+ const rankW = Math.max(1, String(live.length).length);
56491
+ const MARGIN = 2;
56492
+ const leadW = MARGIN + rankW + 1 + 1 + 1 + nameW + 1 + provW + 1;
56493
+ const LB_TIMELINE = PRINTER_BAR_WIDTH + 2 + 7;
56494
+ const LB_BREAKDOWN = 2 + STAGE_NUM_W2 + 1 + STAGE_NUM_W2 + 1 + STAGE_NUM_W2;
56495
+ const LB_TOKBAR = 2 + PRINTER_TOK_WIDTH + 1;
56496
+ const LB_TOK_VALUE = PRINTER_TOK_VALUE_W;
56497
+ const LB_FULL = LB_TIMELINE + LB_BREAKDOWN + LB_TOKBAR + LB_TOK_VALUE;
56498
+ const LB_NOTOK = LB_TIMELINE + LB_BREAKDOWN + 2 + LB_TOK_VALUE;
56499
+ const width = Math.min(maxWidth, leadW + LB_FULL);
56500
+ const barsBudget = Math.max(0, width - leadW);
56501
+ const showTokBar = barsBudget >= LB_FULL;
56502
+ const showBreakdown = barsBudget >= LB_NOTOK;
56503
+ const margin = " ".repeat(MARGIN);
56504
+ const netFg = hexToAnsiFg(STAGE_FG.network);
56505
+ const srvFg = hexToAnsiFg(STAGE_FG.server);
56506
+ const strFg = hexToAnsiFg(STAGE_FG.streaming);
56507
+ w(`${margin}${pc.bold}${pc.cyan}Leaderboard${pc.reset}${pc.dim} \u2014 fastest model first${pc.reset}
56508
+ `);
56509
+ const rankHdr = " ".repeat(rankW) + " ";
56510
+ const nameHdr = padEnd(`${pc.dim}MODEL${pc.reset}`, nameW);
56511
+ const provHdr = padEnd(`${pc.dim}PROVIDER${pc.reset}`, provW);
56512
+ let header = `${margin}${rankHdr}${nameHdr} ${provHdr} ${pc.dim}${padEnd("TIMELINE", PRINTER_BAR_WIDTH)}${pc.reset} ${pc.dim}${padStartSafe2("TOTAL", 7)}${pc.reset}`;
56513
+ if (showBreakdown) {
56514
+ header += `${pc.dim} ${padEnd("net", STAGE_NUM_W2)} ${padEnd("srv", STAGE_NUM_W2)} ${padEnd("str", STAGE_NUM_W2)}${pc.reset}`;
56515
+ }
56516
+ if (showTokBar) {
56517
+ header += `${pc.dim} ${padEnd("tok/s", PRINTER_TOK_WIDTH)} ${padStartSafe2("", PRINTER_TOK_VALUE_W)}${pc.reset}`;
56518
+ } else {
56519
+ header += `${pc.dim} ${padStartSafe2("tok/s", PRINTER_TOK_VALUE_W)}${pc.reset}`;
56520
+ }
56521
+ w(header + `
56522
+ `);
56523
+ live.forEach((row, idx) => {
56524
+ const t = row.timing;
56525
+ const isFastest = idx === 0;
56526
+ const rankStr = padStartSafe2(String(idx + 1), rankW);
56527
+ const dot = isFastest ? `${pc.brightGreen}\u25CF${pc.reset}` : " ";
56528
+ const name = padEnd(`${pc.bold}${truncate2(row.model, nameW)}${pc.reset}`, nameW);
56529
+ const prov = padEnd(`${pc.dim}${truncate2(row.provider, provW)}${pc.reset}`, provW);
56530
+ const barCells = timelineBarCells(t.totalMs, scales.maxTotalMs, PRINTER_BAR_WIDTH);
56531
+ const stages = splitStageCells(t.ttfbMs, t.ttftMs, t.totalMs, barCells);
56532
+ const trackCells = Math.max(0, PRINTER_BAR_WIDTH - barCells);
56533
+ let timeline = "";
56534
+ if (stages.network > 0)
56535
+ timeline += `${STAGE_BG_ANSI.network}${" ".repeat(stages.network)}${ANSI_RESET}`;
56536
+ if (stages.server > 0)
56537
+ timeline += `${STAGE_BG_ANSI.server}${" ".repeat(stages.server)}${ANSI_RESET}`;
56538
+ if (stages.streaming > 0)
56539
+ timeline += `${STAGE_BG_ANSI.streaming}${" ".repeat(stages.streaming)}${ANSI_RESET}`;
56540
+ if (trackCells > 0)
56541
+ timeline += `${pc.dim}${PRINTER_TRACK.repeat(trackCells)}${pc.reset}`;
56542
+ const total = `${LATENCY_FG_ANSI}${padStartSafe2(formatLatency(t.totalMs), 7)}${pc.reset}`;
56543
+ let breakdown = "";
56544
+ if (showBreakdown) {
56545
+ const netMs = Math.max(0, t.ttfbMs);
56546
+ const srvMs = Math.max(0, t.ttftMs - t.ttfbMs);
56547
+ const strMs = Math.max(0, t.totalMs - t.ttftMs);
56548
+ 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}`;
56549
+ }
56550
+ const tokFg = hexToAnsiFg(throughputFg(t.tokensPerSec));
56551
+ let tokBar = " ";
56552
+ if (showTokBar) {
56553
+ const tokCells = tokBarCells(t.tokensPerSec, scales.maxTokPerSec, PRINTER_TOK_WIDTH);
56554
+ const tokTrack = Math.max(0, PRINTER_TOK_WIDTH - tokCells);
56555
+ let bar = "";
56556
+ if (tokCells > 0)
56557
+ bar += `${tokFg}${PRINTER_BAR_FILL.repeat(tokCells)}${pc.reset}`;
56558
+ if (tokTrack > 0)
56559
+ bar += `${pc.dim}${PRINTER_TRACK.repeat(tokTrack)}${pc.reset}`;
56560
+ tokBar = ` ${bar} `;
56561
+ }
56562
+ const tokValue = `${tokFg}${padStartSafe2(`${Math.round(t.tokensPerSec)} t/s`, PRINTER_TOK_VALUE_W)}${pc.reset}`;
56563
+ w(`${margin}${rankStr} ${dot} ${name} ${prov} ${timeline} ${total}${breakdown}${tokBar}${tokValue}
56564
+ `);
56565
+ });
56566
+ for (const row of unavailable) {
56567
+ const rankStr = " ".repeat(rankW);
56568
+ const name = padEnd(`${pc.dim}${truncate2(row.model, nameW)}${pc.reset}`, nameW);
56569
+ const prov = padEnd(`${pc.dim}${truncate2(row.provider, provW)}${pc.reset}`, provW);
56570
+ w(`${margin}${rankStr} ${name} ${prov} ${pc.dim}\u2014 no live route${pc.reset}
56571
+ `);
56572
+ }
56573
+ const rowVis = leadW - MARGIN + LB_TIMELINE + (showBreakdown ? LB_BREAKDOWN : 0) + (showTokBar ? LB_TOKBAR : 2) + LB_TOK_VALUE;
56574
+ const ruleW = Math.max(10, rowVis);
56575
+ w(`${margin}${pc.dim}${"\u2500".repeat(ruleW)}${pc.reset}
56576
+ `);
56577
+ w(`
56578
+ `);
56579
+ }
56580
+ function printLeaderboardScrollback(results, isLiveProbe) {
56581
+ const w = process.stderr.write.bind(process.stderr);
56582
+ 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));
56583
+ if (!isLiveProbe || !anyTimedLive)
56584
+ return;
56585
+ const scales = computeBarScales(results);
56586
+ const termCols = process.stderr.columns ?? process.stdout.columns ?? 100;
56587
+ const maxAllowed = Math.max(MIN_CARD_WIDTH, termCols - 4);
56588
+ w(`
56589
+ `);
56590
+ renderLeaderboard(results, scales, maxAllowed, w);
56591
+ }
55360
56592
  function printProbeResults(results, isLiveProbe) {
55361
56593
  const w = process.stderr.write.bind(process.stderr);
55362
56594
  w(`
55363
56595
  `);
56596
+ const scales = computeBarScales(results);
56597
+ 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));
56598
+ if (isLiveProbe && anyTimedLive) {
56599
+ renderLegend(w);
56600
+ }
55364
56601
  const requiredWidths = results.map((r) => computeRequiredWidth(r, isLiveProbe));
55365
56602
  const termCols = process.stderr.columns ?? process.stdout.columns ?? 100;
55366
56603
  const maxAllowed = Math.max(MIN_CARD_WIDTH, termCols - 4);
55367
56604
  let globalWidth = requiredWidths.reduce((a, b) => Math.max(a, b), MIN_CARD_WIDTH);
55368
56605
  if (globalWidth > maxAllowed)
55369
56606
  globalWidth = maxAllowed;
56607
+ const showedLeaderboard = isLiveProbe && anyTimedLive;
56608
+ if (showedLeaderboard) {
56609
+ renderLeaderboard(results, scales, maxAllowed, w);
56610
+ }
56611
+ if (showedLeaderboard) {
56612
+ w(` ${pc.bold}${pc.cyan}Details${pc.reset}${pc.dim} \u2014 per-model routing chains${pc.reset}
56613
+
56614
+ `);
56615
+ }
55370
56616
  for (const result of results) {
55371
- renderCard(result, isLiveProbe, w, globalWidth);
56617
+ renderCard(result, isLiveProbe, w, globalWidth, scales);
55372
56618
  w(`
55373
56619
  `);
55374
56620
  }
@@ -55377,9 +56623,10 @@ function printProbeResults(results, isLiveProbe) {
55377
56623
  w(`
55378
56624
  `);
55379
56625
  }
55380
- var pc, ANSI_RE2, MIN_CARD_WIDTH = 60, CARD_PADDING_LEFT = 2, CARD_PADDING_RIGHT = 2;
56626
+ 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
56627
  var init_probe_results_printer = __esm(() => {
55382
56628
  init_probe_live();
56629
+ init_theme2();
55383
56630
  pc = {
55384
56631
  reset: "\x1B[0m",
55385
56632
  bold: "\x1B[1m",
@@ -55394,6 +56641,9 @@ var init_probe_results_printer = __esm(() => {
55394
56641
  bgSlowest: "\x1B[48;5;95m"
55395
56642
  };
55396
56643
  ANSI_RE2 = /\x1b\[[0-9;]*[A-Za-z]/g;
56644
+ PRINTER_BARS_FULL_WIDTH = 24 + 2 + 7 + 34 + 17 + 9;
56645
+ PRINTER_BARS_NOTOK_WIDTH = 24 + 2 + 7 + 34 + 2 + 9;
56646
+ PRINTER_BARS_MIN_WIDTH = 24 + 2 + 7 + 2 + 9;
55397
56647
  });
55398
56648
 
55399
56649
  // src/cli.ts
@@ -56228,6 +57478,46 @@ async function probeModelRouting(models, jsonOutput, options = { live: true, tim
56228
57478
  });
56229
57479
  return { parsed, chain, chainDetails };
56230
57480
  }
57481
+ function buildRoutingExplanation(parsed, chain) {
57482
+ if (chain.source === "direct") {
57483
+ return `explicit \xB7 ${parsed.provider} (direct)`;
57484
+ }
57485
+ if (chain.source === "custom-rules" && chain.matchedPattern) {
57486
+ return `custom-rules \xB7 matched \`${chain.matchedPattern}\``;
57487
+ }
57488
+ if (chain.source === "auto-chain") {
57489
+ if (chain.matchedPattern && chain.matchedPattern !== "*") {
57490
+ return `auto-chain \xB7 default rule \`${chain.matchedPattern}\``;
57491
+ }
57492
+ return "auto-chain \xB7 catch-all \u2192 openrouter";
57493
+ }
57494
+ return chain.source;
57495
+ }
57496
+ function buildResultLinks(parsed, chainDetails, directProbe) {
57497
+ if (chainDetails.length === 0) {
57498
+ const directProviderDef = getProviderByName(parsed.provider);
57499
+ const directKeyInfo = API_KEY_MAP[parsed.provider];
57500
+ const directHasCreds = directProviderDef?.isLocal ? isLocalProviderEnabled(parsed.provider) : directKeyInfo?.envVar ? !!process.env[directKeyInfo.envVar] || (directKeyInfo.aliases?.some((a) => !!process.env[a]) ?? false) : true;
57501
+ return [
57502
+ {
57503
+ provider: parsed.provider,
57504
+ displayName: directProviderDef?.displayName ?? parsed.provider,
57505
+ modelId: parsed.model,
57506
+ hasCredentials: directHasCreds,
57507
+ credentialHint: directProviderDef?.isLocal && !directHasCreds ? "enable local provider in global config" : directKeyInfo?.envVar,
57508
+ probe: directProbe
57509
+ }
57510
+ ];
57511
+ }
57512
+ return chainDetails.map((c) => ({
57513
+ provider: c.provider,
57514
+ displayName: c.displayName,
57515
+ modelId: c.modelSpec.includes("@") ? c.modelSpec.slice(c.modelSpec.indexOf("@") + 1) : c.modelSpec,
57516
+ hasCredentials: c.hasCredentials,
57517
+ credentialHint: c.credentialHint,
57518
+ probe: c.probe
57519
+ }));
57520
+ }
56231
57521
  async function computeWiring(chainDetails, parsedModel) {
56232
57522
  const firstReadyRoute = chainDetails.find((c) => c.hasCredentials);
56233
57523
  if (!firstReadyRoute)
@@ -56360,7 +57650,10 @@ async function probeModelRouting(models, jsonOutput, options = { live: true, tim
56360
57650
  }
56361
57651
  const initialState = {
56362
57652
  steps: [],
56363
- links: []
57653
+ links: [],
57654
+ phase: "live",
57655
+ results: [],
57656
+ activeTab: "leaderboard"
56364
57657
  };
56365
57658
  const tui = await startProbeTui(initialState);
56366
57659
  const addStep = (name, status) => {
@@ -56467,7 +57760,11 @@ async function probeModelRouting(models, jsonOutput, options = { live: true, tim
56467
57760
  errorMessage: String(e instanceof Error ? e.message : e)
56468
57761
  }));
56469
57762
  if (result.state === "live") {
56470
- updateLink(link.id, { status: "live", endTime: Date.now() });
57763
+ updateLink(link.id, {
57764
+ status: "live",
57765
+ endTime: Date.now(),
57766
+ timing: result.timing
57767
+ });
56471
57768
  } else {
56472
57769
  updateLink(link.id, {
56473
57770
  status: "failed",
@@ -56485,8 +57782,10 @@ async function probeModelRouting(models, jsonOutput, options = { live: true, tim
56485
57782
  }
56486
57783
  const isLiveProbe = !!liveProxy;
56487
57784
  const printable = [];
57785
+ const results = [];
56488
57786
  for (const { modelInput, parsed, chain, chainDetails } of modelChains) {
56489
57787
  const wiring = await computeWiring(chainDetails, parsed.model);
57788
+ const directProbe = directProbeResults.get(modelInput);
56490
57789
  printable.push({
56491
57790
  model: modelInput,
56492
57791
  nativeProvider: parsed.provider,
@@ -56502,18 +57801,42 @@ async function probeModelRouting(models, jsonOutput, options = { live: true, tim
56502
57801
  provenance: c.provenance,
56503
57802
  probe: c.probe
56504
57803
  })),
56505
- directProbe: directProbeResults.get(modelInput),
57804
+ directProbe,
57805
+ wiring
57806
+ });
57807
+ results.push({
57808
+ model: modelInput,
57809
+ nativeProvider: parsed.provider,
57810
+ isExplicit: parsed.isExplicitProvider,
57811
+ routingSource: chain.source,
57812
+ matchedPattern: chain.matchedPattern,
57813
+ routingExplanation: buildRoutingExplanation(parsed, chain),
57814
+ links: buildResultLinks(parsed, chainDetails, directProbe),
56506
57815
  wiring
56507
57816
  });
56508
57817
  }
56509
- if (liveProxy) {
56510
- try {
56511
- await liveProxy.shutdown();
56512
- } catch {}
56513
- liveProxy = null;
57818
+ const interactive = !!process.stdout.isTTY && !!process.stderr.isTTY;
57819
+ if (interactive) {
57820
+ if (liveProxy) {
57821
+ try {
57822
+ await liveProxy.shutdown();
57823
+ } catch {}
57824
+ liveProxy = null;
57825
+ }
57826
+ tui.store.setResults(results);
57827
+ await tui.waitForQuit();
57828
+ await tui.shutdown();
57829
+ printLeaderboardScrollback(printable, isLiveProbe);
57830
+ } else {
57831
+ if (liveProxy) {
57832
+ try {
57833
+ await liveProxy.shutdown();
57834
+ } catch {}
57835
+ liveProxy = null;
57836
+ }
57837
+ await tui.shutdown();
57838
+ printProbeResults(printable, isLiveProbe);
56514
57839
  }
56515
- await tui.shutdown();
56516
- printProbeResults(printable, isLiveProbe);
56517
57840
  } finally {
56518
57841
  if (liveProxy) {
56519
57842
  try {
@@ -58045,7 +59368,7 @@ var init_providers = __esm(() => {
58045
59368
  });
58046
59369
 
58047
59370
  // 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";
59371
+ var COMMON_MODELS, PROVIDER_PREFIXES, CHAIN_PROVIDERS, HEADER_H = 2, TABS_H = 3, FOOTER_H = 1, DETAIL_H = 7;
58049
59372
  var init_constants3 = __esm(() => {
58050
59373
  init_providers();
58051
59374
  COMMON_MODELS = [
@@ -58239,6 +59562,7 @@ function useProfileWizard(args) {
58239
59562
  const [suggestions, setSuggestions] = useState4([]);
58240
59563
  const [suggestionIndex, setSuggestionIndex] = useState4(-1);
58241
59564
  const [providerPickerIndex, setProviderPickerIndex] = useState4(0);
59565
+ const [scopeCursor, setScopeCursor] = useState4(0);
58242
59566
  const [providerPickerReturnMode, setProviderPickerReturnMode] = useState4("edit_profile_opus");
58243
59567
  const saveModelField = useCallback2((currentMode, fieldVal) => {
58244
59568
  const val = fieldVal.trim() === "auto" ? undefined : fieldVal.trim();
@@ -58304,6 +59628,7 @@ function useProfileWizard(args) {
58304
59628
  const startNewProfile = useCallback2(() => {
58305
59629
  setEditProfileValue("");
58306
59630
  setProfileScope("global");
59631
+ setScopeCursor(0);
58307
59632
  setMode("pick_profile_scope");
58308
59633
  setStatusMsg(null);
58309
59634
  }, [setMode, setStatusMsg]);
@@ -58322,9 +59647,19 @@ function useProfileWizard(args) {
58322
59647
  }, [setMode, setStatusMsg]);
58323
59648
  const pickScope = useCallback2((scope) => {
58324
59649
  setProfileScope(scope);
59650
+ setScopeCursor(scope === "global" ? 0 : 1);
58325
59651
  setEditProfileValue("");
58326
59652
  setMode("new_profile");
58327
59653
  }, [setMode]);
59654
+ const pickScopeAtCursor = useCallback2(() => {
59655
+ pickScope(scopeCursor === 0 ? "global" : "project");
59656
+ }, [pickScope, scopeCursor]);
59657
+ const setScopeCursorVerb = useCallback2((index) => {
59658
+ setScopeCursor(index === 0 ? 0 : 1);
59659
+ }, []);
59660
+ const setProviderPickerIndexVerb = useCallback2((index) => {
59661
+ setProviderPickerIndex(index < 0 ? 0 : index);
59662
+ }, []);
58328
59663
  const cancelPickScope = useCallback2(() => {
58329
59664
  setMode("browse");
58330
59665
  }, [setMode]);
@@ -58519,8 +59854,12 @@ function useProfileWizard(args) {
58519
59854
  suggestions,
58520
59855
  suggestionIndex,
58521
59856
  providerPickerIndex,
59857
+ scopeCursor,
58522
59858
  startNewProfile,
58523
59859
  pickScope,
59860
+ pickScopeAtCursor,
59861
+ setScopeCursor: setScopeCursorVerb,
59862
+ setProviderPickerIndex: setProviderPickerIndexVerb,
58524
59863
  cancelPickScope,
58525
59864
  startEditExisting,
58526
59865
  newProfileSubmit,
@@ -58561,7 +59900,7 @@ var init_useProfileWizard = __esm(() => {
58561
59900
 
58562
59901
  // src/tui/components/TabBar.tsx
58563
59902
  import { jsxDEV as jsxDEV3 } from "@opentui/react/jsx-dev-runtime";
58564
- function TabBar({ activeTab, statusMsg, width }) {
59903
+ function TabBar2({ activeTab, statusMsg }) {
58565
59904
  const tabs = [
58566
59905
  { label: "Providers", value: "providers", num: "1" },
58567
59906
  { label: "Profiles", value: "profiles", num: "2" },
@@ -58614,11 +59953,11 @@ function TabBar({ activeTab, statusMsg, width }) {
58614
59953
  /* @__PURE__ */ jsxDEV3("box", {
58615
59954
  height: 1,
58616
59955
  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)
59956
+ children: /* @__PURE__ */ jsxDEV3("box", {
59957
+ flexGrow: 1,
59958
+ border: ["top"],
59959
+ borderStyle: "single",
59960
+ borderColor: C.tabActiveBg
58622
59961
  }, undefined, false, undefined, this)
58623
59962
  }, undefined, false, undefined, this),
58624
59963
  /* @__PURE__ */ jsxDEV3("box", {
@@ -58691,26 +60030,8 @@ function Footer({ activeTab, mode, probeMode, providerCaps }) {
58691
60030
  if (showRemove)
58692
60031
  keys.push([C.red, "x", "remove"]);
58693
60032
  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
60033
  } 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
- ];
60034
+ keys = [[C.dim, "wizard", "follow the panel above"]];
58714
60035
  } else if (activeTab === "profiles") {
58715
60036
  keys = [
58716
60037
  [C.blue, "\u2191\u2193", "navigate"],
@@ -58752,24 +60073,22 @@ function Footer({ activeTab, mode, probeMode, providerCaps }) {
58752
60073
  paddingX: 1,
58753
60074
  backgroundColor: C.bgAlt,
58754
60075
  children: /* @__PURE__ */ jsxDEV4("text", {
58755
- children: keys.map(([color, key, label], i) => /* @__PURE__ */ jsxDEV4("span", {
60076
+ children: keys.map(([_color, key, label], i) => /* @__PURE__ */ jsxDEV4("span", {
58756
60077
  children: [
58757
60078
  i > 0 && /* @__PURE__ */ jsxDEV4("span", {
58758
- fg: C.dim,
58759
- children: " \u2502 "
60079
+ children: " "
58760
60080
  }, undefined, false, undefined, this),
58761
60081
  /* @__PURE__ */ jsxDEV4("span", {
58762
- fg: color,
60082
+ fg: C.fg,
60083
+ bg: C.chipKeyBg,
58763
60084
  attributes: A.bold,
58764
- children: key
60085
+ children: ` ${key} `
58765
60086
  }, undefined, false, undefined, this),
58766
60087
  /* @__PURE__ */ jsxDEV4("span", {
58767
60088
  fg: C.fgMuted,
58768
- children: [
58769
- " ",
58770
- label
58771
- ]
58772
- }, undefined, true, undefined, this)
60089
+ bg: C.chipLabelBg,
60090
+ children: `${label} `
60091
+ }, undefined, false, undefined, this)
58773
60092
  ]
58774
60093
  }, i, true, undefined, this))
58775
60094
  }, undefined, false, undefined, this)
@@ -58807,13 +60126,21 @@ function ProvidersContent({
58807
60126
  displayProviders,
58808
60127
  providerIndex,
58809
60128
  testResults,
58810
- width,
58811
60129
  contentH,
58812
60130
  isInputMode,
58813
60131
  animTick
58814
60132
  }) {
58815
- const listH = contentH - 4;
58816
- let separatorRendered = false;
60133
+ const firstUnreadyIdx = displayProviders.findIndex((p) => providerAuthSource(p, config3) === null);
60134
+ const hasDivider = firstUnreadyIdx >= 0;
60135
+ const listH = contentH - 4 - (hasDivider ? 1 : 0);
60136
+ const scrollOffset = (() => {
60137
+ if (listH <= 0 || displayProviders.length <= listH)
60138
+ return 0;
60139
+ if (providerIndex < listH)
60140
+ return 0;
60141
+ const maxOffset = displayProviders.length - listH;
60142
+ return Math.min(providerIndex - listH + 1, maxOffset);
60143
+ })();
58817
60144
  const getRow = (p, idx) => {
58818
60145
  const auth = providerAuthSource(p, config3);
58819
60146
  const caps = providerAuthCapabilities(p, config3);
@@ -58836,9 +60163,7 @@ function ProvidersContent({
58836
60163
  } else {
58837
60164
  keyDisplay = "\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500";
58838
60165
  }
58839
- const isFirstUnready = !isReady && !separatorRendered;
58840
- if (isFirstUnready)
58841
- separatorRendered = true;
60166
+ const isFirstUnready = idx === firstUnreadyIdx;
58842
60167
  let statusFg = isReady ? C.green : C.dim;
58843
60168
  let statusText = p.isLocal ? isReady ? "enabled" : "disabled" : isReady ? "ready" : "not set";
58844
60169
  if (tr) {
@@ -58863,17 +60188,23 @@ function ProvidersContent({
58863
60188
  children: [
58864
60189
  isFirstUnready && /* @__PURE__ */ jsxDEV5("box", {
58865
60190
  height: 1,
60191
+ flexDirection: "row",
58866
60192
  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),
60193
+ children: [
60194
+ /* @__PURE__ */ jsxDEV5("text", {
60195
+ children: /* @__PURE__ */ jsxDEV5("span", {
60196
+ fg: C.dim,
60197
+ children: "\u2500 not configured "
60198
+ }, undefined, false, undefined, this)
60199
+ }, undefined, false, undefined, this),
60200
+ /* @__PURE__ */ jsxDEV5("box", {
60201
+ flexGrow: 1,
60202
+ border: ["top"],
60203
+ borderStyle: "single",
60204
+ borderColor: C.dim
60205
+ }, undefined, false, undefined, this)
60206
+ ]
60207
+ }, undefined, true, undefined, this),
58877
60208
  /* @__PURE__ */ jsxDEV5("box", {
58878
60209
  height: 1,
58879
60210
  flexGrow: 1,
@@ -59006,7 +60337,7 @@ function ProvidersContent({
59006
60337
  /* @__PURE__ */ jsxDEV5("box", {
59007
60338
  flexDirection: "column",
59008
60339
  style: { flexGrow: 1 },
59009
- children: displayProviders.slice(0, listH).map(getRow)
60340
+ children: displayProviders.slice(scrollOffset, scrollOffset + listH).map((p, i) => getRow(p, scrollOffset + i))
59010
60341
  }, undefined, false, undefined, this),
59011
60342
  /* @__PURE__ */ jsxDEV5("text", {
59012
60343
  height: 1,
@@ -59339,20 +60670,45 @@ var init_ProviderDetail = __esm(() => {
59339
60670
 
59340
60671
  // src/tui/components/ProfilesContent.tsx
59341
60672
  import { jsxDEV as jsxDEV7, Fragment as Fragment4 } from "@opentui/react/jsx-dev-runtime";
60673
+ function stepLabel(mode) {
60674
+ const idx = WIZARD_STEPS.indexOf(mode);
60675
+ const stepNo = idx >= 0 ? idx + 1 : 0;
60676
+ const prefix = stepNo > 0 ? `Step ${stepNo} of ${TOTAL_STEPS} \u2014 ` : "";
60677
+ switch (mode) {
60678
+ case "pick_profile_scope":
60679
+ return { title: "New Profile", header: `${prefix}Choose scope` };
60680
+ case "new_profile":
60681
+ return { title: "New Profile", header: `${prefix}Profile name` };
60682
+ case "edit_profile_opus":
60683
+ return { title: "New Profile", header: `${prefix}opus model` };
60684
+ case "edit_profile_sonnet":
60685
+ return { title: "New Profile", header: `${prefix}sonnet model` };
60686
+ case "edit_profile_haiku":
60687
+ return { title: "New Profile", header: `${prefix}haiku model` };
60688
+ case "edit_profile_subagent":
60689
+ return { title: "New Profile", header: `${prefix}subagent model (optional)` };
60690
+ case "pick_provider_prefix":
60691
+ return { title: "Choose provider", header: "Pick a provider prefix" };
60692
+ default:
60693
+ return { title: "New Profile", header: "" };
60694
+ }
60695
+ }
59342
60696
  function ProfilesContent({
59343
60697
  config: config3,
59344
60698
  activeTab,
59345
60699
  mode,
59346
60700
  profileScope,
59347
60701
  profileIndex,
59348
- editProfileName,
59349
60702
  editProfileValue,
59350
60703
  suggestions,
59351
60704
  suggestionIndex,
59352
60705
  providerPickerIndex,
59353
- contentH
60706
+ contentH,
60707
+ onScopeChange,
60708
+ onPrefixChange
59354
60709
  }) {
59355
60710
  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";
60711
+ const isTextStep = mode === "new_profile" || mode === "edit_profile_opus" || mode === "edit_profile_sonnet" || mode === "edit_profile_haiku" || mode === "edit_profile_subagent";
59356
60712
  const globalCfg = config3;
59357
60713
  const localCfg = loadLocalConfig();
59358
60714
  const localProfileNames = localCfg ? new Set(Object.keys(localCfg.profiles)) : new Set;
@@ -59367,7 +60723,17 @@ function ProfilesContent({
59367
60723
  }
59368
60724
  const activeProfileName = globalCfg.defaultProfile;
59369
60725
  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;
60726
+ const { title: modalTitle, header: modalHeader } = stepLabel(mode);
60727
+ const scopeOptions = [
60728
+ { name: "global ~/.claudish/config.json", description: "", value: "global" },
60729
+ { name: "project ./.claudish.json", description: "", value: "project" }
60730
+ ];
60731
+ const prefixColW = PROVIDER_PREFIXES.reduce((max, p) => Math.max(max, p.prefix.length), 0) + 2;
60732
+ const prefixOptions = PROVIDER_PREFIXES.map((p) => ({
60733
+ name: `${p.prefix.padEnd(prefixColW)}${p.displayName}`,
60734
+ description: "",
60735
+ value: p.prefix
60736
+ }));
59371
60737
  return /* @__PURE__ */ jsxDEV7("box", {
59372
60738
  height: contentH,
59373
60739
  border: true,
@@ -59472,97 +60838,69 @@ function ProfilesContent({
59472
60838
  children: " No project-level profiles (.claudish.json)"
59473
60839
  }, undefined, false, undefined, this)
59474
60840
  }, undefined, false, undefined, this),
59475
- isProfileEditMode && editPromptLabel && /* @__PURE__ */ jsxDEV7("box", {
60841
+ isProfileEditMode && /* @__PURE__ */ jsxDEV7("box", {
60842
+ border: true,
60843
+ borderStyle: "rounded",
60844
+ borderColor: C.blue,
60845
+ title: modalTitle,
60846
+ titleAlignment: "left",
60847
+ backgroundColor: C.bg,
59476
60848
  flexDirection: "column",
59477
- paddingTop: 1,
60849
+ paddingX: 1,
60850
+ marginTop: 1,
59478
60851
  children: [
59479
60852
  /* @__PURE__ */ jsxDEV7("text", {
59480
60853
  children: /* @__PURE__ */ jsxDEV7("span", {
59481
- fg: C.blue,
60854
+ fg: C.cyan,
59482
60855
  attributes: A.bold,
59483
- children: editPromptLabel + " "
60856
+ children: modalHeader
59484
60857
  }, undefined, false, undefined, this)
59485
60858
  }, undefined, false, undefined, this),
59486
60859
  mode === "pick_profile_scope" && /* @__PURE__ */ jsxDEV7("box", {
59487
60860
  flexDirection: "column",
60861
+ paddingTop: 1,
59488
60862
  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),
60863
+ /* @__PURE__ */ jsxDEV7("select", {
60864
+ options: scopeOptions,
60865
+ focused: true,
60866
+ showDescription: false,
60867
+ wrapSelection: true,
60868
+ onChange: onScopeChange,
60869
+ backgroundColor: C.bg,
60870
+ textColor: C.fgMuted,
60871
+ selectedBackgroundColor: C.bgHighlight,
60872
+ selectedTextColor: C.white,
60873
+ height: scopeOptions.length
60874
+ }, undefined, false, undefined, this),
60875
+ /* @__PURE__ */ jsxDEV7("text", {
60876
+ children: /* @__PURE__ */ jsxDEV7("span", {
60877
+ fg: C.dim,
60878
+ children: " "
60879
+ }, undefined, false, undefined, this)
60880
+ }, undefined, false, undefined, this),
59535
60881
  /* @__PURE__ */ jsxDEV7("text", {
59536
60882
  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
60883
  /* @__PURE__ */ jsxDEV7("span", {
59546
60884
  fg: C.fgMuted,
59547
- children: "global \xB7 "
60885
+ children: "\u2191\u2193 move \xB7 "
59548
60886
  }, undefined, false, undefined, this),
59549
60887
  /* @__PURE__ */ jsxDEV7("span", {
59550
- fg: C.cyan,
60888
+ fg: C.green,
59551
60889
  attributes: A.bold,
59552
60890
  children: [
59553
- "p",
60891
+ "\u23CE",
59554
60892
  " "
59555
60893
  ]
59556
60894
  }, undefined, true, undefined, this),
59557
60895
  /* @__PURE__ */ jsxDEV7("span", {
59558
60896
  fg: C.fgMuted,
59559
- children: "project \xB7 "
60897
+ children: "next \xB7 "
59560
60898
  }, undefined, false, undefined, this),
59561
60899
  /* @__PURE__ */ jsxDEV7("span", {
59562
60900
  fg: C.red,
59563
60901
  attributes: A.bold,
59564
60902
  children: [
59565
- "Esc",
60903
+ "esc",
59566
60904
  " "
59567
60905
  ]
59568
60906
  }, undefined, true, undefined, this),
@@ -59576,63 +60914,51 @@ function ProfilesContent({
59576
60914
  }, undefined, true, undefined, this),
59577
60915
  mode === "pick_provider_prefix" && /* @__PURE__ */ jsxDEV7("box", {
59578
60916
  flexDirection: "column",
60917
+ paddingTop: 1,
59579
60918
  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)),
60919
+ /* @__PURE__ */ jsxDEV7("select", {
60920
+ options: prefixOptions,
60921
+ focused: true,
60922
+ showDescription: false,
60923
+ wrapSelection: true,
60924
+ selectedIndex: providerPickerIndex,
60925
+ onChange: onPrefixChange,
60926
+ backgroundColor: C.bg,
60927
+ textColor: C.fgMuted,
60928
+ selectedBackgroundColor: C.bgHighlight,
60929
+ selectedTextColor: C.cyan,
60930
+ height: Math.min(8, prefixOptions.length),
60931
+ showScrollIndicator: true
60932
+ }, undefined, false, undefined, this),
60933
+ /* @__PURE__ */ jsxDEV7("text", {
60934
+ children: /* @__PURE__ */ jsxDEV7("span", {
60935
+ fg: C.dim,
60936
+ children: " "
60937
+ }, undefined, false, undefined, this)
60938
+ }, undefined, false, undefined, this),
59605
60939
  /* @__PURE__ */ jsxDEV7("text", {
59606
60940
  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
60941
  /* @__PURE__ */ jsxDEV7("span", {
59616
60942
  fg: C.fgMuted,
59617
- children: "navigate \xB7 "
60943
+ children: "\u2191\u2193 move \xB7 "
59618
60944
  }, undefined, false, undefined, this),
59619
60945
  /* @__PURE__ */ jsxDEV7("span", {
59620
60946
  fg: C.green,
59621
60947
  attributes: A.bold,
59622
60948
  children: [
59623
- "Enter",
60949
+ "\u23CE",
59624
60950
  " "
59625
60951
  ]
59626
60952
  }, undefined, true, undefined, this),
59627
60953
  /* @__PURE__ */ jsxDEV7("span", {
59628
60954
  fg: C.fgMuted,
59629
- children: "select prefix \xB7 "
60955
+ children: "select \xB7 "
59630
60956
  }, undefined, false, undefined, this),
59631
60957
  /* @__PURE__ */ jsxDEV7("span", {
59632
60958
  fg: C.red,
59633
60959
  attributes: A.bold,
59634
60960
  children: [
59635
- "Esc",
60961
+ "esc",
59636
60962
  " "
59637
60963
  ]
59638
60964
  }, undefined, true, undefined, this),
@@ -59644,9 +60970,23 @@ function ProfilesContent({
59644
60970
  }, undefined, true, undefined, this)
59645
60971
  ]
59646
60972
  }, undefined, true, undefined, this),
59647
- mode !== "pick_profile_scope" && mode !== "pick_provider_prefix" && /* @__PURE__ */ jsxDEV7("box", {
60973
+ isTextStep && /* @__PURE__ */ jsxDEV7("box", {
59648
60974
  flexDirection: "column",
60975
+ paddingTop: 1,
59649
60976
  children: [
60977
+ mode === "new_profile" && /* @__PURE__ */ jsxDEV7("text", {
60978
+ children: [
60979
+ /* @__PURE__ */ jsxDEV7("span", {
60980
+ fg: C.fgMuted,
60981
+ children: "scope: "
60982
+ }, undefined, false, undefined, this),
60983
+ /* @__PURE__ */ jsxDEV7("span", {
60984
+ fg: profileScope === "project" ? C.cyan : C.green,
60985
+ attributes: A.bold,
60986
+ children: profileScope
60987
+ }, undefined, false, undefined, this)
60988
+ ]
60989
+ }, undefined, true, undefined, this),
59650
60990
  /* @__PURE__ */ jsxDEV7("text", {
59651
60991
  children: [
59652
60992
  /* @__PURE__ */ jsxDEV7("span", {
@@ -59704,7 +61044,34 @@ function ProfilesContent({
59704
61044
  }, s, false, undefined, this);
59705
61045
  })
59706
61046
  }, undefined, false, undefined, this),
59707
- editProfileValue === "auto" ? /* @__PURE__ */ jsxDEV7("text", {
61047
+ mode === "new_profile" ? /* @__PURE__ */ jsxDEV7("text", {
61048
+ children: [
61049
+ /* @__PURE__ */ jsxDEV7("span", {
61050
+ fg: C.green,
61051
+ attributes: A.bold,
61052
+ children: [
61053
+ "\u23CE",
61054
+ " "
61055
+ ]
61056
+ }, undefined, true, undefined, this),
61057
+ /* @__PURE__ */ jsxDEV7("span", {
61058
+ fg: C.fgMuted,
61059
+ children: "next \xB7 "
61060
+ }, undefined, false, undefined, this),
61061
+ /* @__PURE__ */ jsxDEV7("span", {
61062
+ fg: C.red,
61063
+ attributes: A.bold,
61064
+ children: [
61065
+ "esc",
61066
+ " "
61067
+ ]
61068
+ }, undefined, true, undefined, this),
61069
+ /* @__PURE__ */ jsxDEV7("span", {
61070
+ fg: C.fgMuted,
61071
+ children: "cancel"
61072
+ }, undefined, false, undefined, this)
61073
+ ]
61074
+ }, undefined, true, undefined, this) : editProfileValue === "auto" ? /* @__PURE__ */ jsxDEV7("text", {
59708
61075
  children: [
59709
61076
  /* @__PURE__ */ jsxDEV7("span", {
59710
61077
  fg: C.yellow,
@@ -59716,25 +61083,25 @@ function ProfilesContent({
59716
61083
  }, undefined, true, undefined, this),
59717
61084
  /* @__PURE__ */ jsxDEV7("span", {
59718
61085
  fg: C.fgMuted,
59719
- children: "\u2014 claudish will use the routing table \xB7 "
61086
+ children: "\u2014 uses routing table \xB7 "
59720
61087
  }, undefined, false, undefined, this),
59721
61088
  /* @__PURE__ */ jsxDEV7("span", {
59722
61089
  fg: C.green,
59723
61090
  attributes: A.bold,
59724
61091
  children: [
59725
- "Enter",
61092
+ "\u23CE",
59726
61093
  " "
59727
61094
  ]
59728
61095
  }, undefined, true, undefined, this),
59729
61096
  /* @__PURE__ */ jsxDEV7("span", {
59730
61097
  fg: C.fgMuted,
59731
- children: "to confirm \xB7 "
61098
+ children: "next \xB7 "
59732
61099
  }, undefined, false, undefined, this),
59733
61100
  /* @__PURE__ */ jsxDEV7("span", {
59734
61101
  fg: C.red,
59735
61102
  attributes: A.bold,
59736
61103
  children: [
59737
- "Esc",
61104
+ "esc",
59738
61105
  " "
59739
61106
  ]
59740
61107
  }, undefined, true, undefined, this),
@@ -59749,25 +61116,25 @@ function ProfilesContent({
59749
61116
  fg: C.green,
59750
61117
  attributes: A.bold,
59751
61118
  children: [
59752
- "Enter",
61119
+ "\u23CE",
59753
61120
  " "
59754
61121
  ]
59755
61122
  }, undefined, true, undefined, this),
59756
61123
  /* @__PURE__ */ jsxDEV7("span", {
59757
61124
  fg: C.fgMuted,
59758
- children: "save \xB7 "
61125
+ children: "next \xB7 "
59759
61126
  }, undefined, false, undefined, this),
59760
61127
  /* @__PURE__ */ jsxDEV7("span", {
59761
61128
  fg: C.blue,
59762
61129
  attributes: A.bold,
59763
61130
  children: [
59764
- "Tab",
61131
+ "\u21E5",
59765
61132
  " "
59766
61133
  ]
59767
61134
  }, undefined, true, undefined, this),
59768
61135
  /* @__PURE__ */ jsxDEV7("span", {
59769
61136
  fg: C.fgMuted,
59770
- children: editProfileValue === "" ? "pick provider \xB7 " : "autocomplete \xB7 "
61137
+ children: editProfileValue === "" ? "provider \xB7 " : "complete \xB7 "
59771
61138
  }, undefined, false, undefined, this),
59772
61139
  /* @__PURE__ */ jsxDEV7("span", {
59773
61140
  fg: C.blue,
@@ -59779,7 +61146,7 @@ function ProfilesContent({
59779
61146
  }, undefined, true, undefined, this),
59780
61147
  /* @__PURE__ */ jsxDEV7("span", {
59781
61148
  fg: C.fgMuted,
59782
- children: "suggestion \xB7 "
61149
+ children: "pick \xB7 "
59783
61150
  }, undefined, false, undefined, this),
59784
61151
  /* @__PURE__ */ jsxDEV7("span", {
59785
61152
  fg: C.yellow,
@@ -59791,13 +61158,13 @@ function ProfilesContent({
59791
61158
  }, undefined, true, undefined, this),
59792
61159
  /* @__PURE__ */ jsxDEV7("span", {
59793
61160
  fg: C.fgMuted,
59794
- children: "auto-route \xB7 "
61161
+ children: "auto \xB7 "
59795
61162
  }, undefined, false, undefined, this),
59796
61163
  /* @__PURE__ */ jsxDEV7("span", {
59797
61164
  fg: C.red,
59798
61165
  attributes: A.bold,
59799
61166
  children: [
59800
- "Esc",
61167
+ "esc",
59801
61168
  " "
59802
61169
  ]
59803
61170
  }, undefined, true, undefined, this),
@@ -59814,10 +61181,20 @@ function ProfilesContent({
59814
61181
  ]
59815
61182
  }, undefined, true, undefined, this);
59816
61183
  }
61184
+ var WIZARD_STEPS, TOTAL_STEPS;
59817
61185
  var init_ProfilesContent = __esm(() => {
59818
61186
  init_theme2();
59819
61187
  init_constants3();
59820
61188
  init_profile_config();
61189
+ WIZARD_STEPS = [
61190
+ "pick_profile_scope",
61191
+ "new_profile",
61192
+ "edit_profile_opus",
61193
+ "edit_profile_sonnet",
61194
+ "edit_profile_haiku",
61195
+ "edit_profile_subagent"
61196
+ ];
61197
+ TOTAL_STEPS = WIZARD_STEPS.length;
59821
61198
  });
59822
61199
 
59823
61200
  // src/tui/components/ProfileDetail.tsx
@@ -59920,7 +61297,7 @@ var init_ProfileDetail = __esm(() => {
59920
61297
  });
59921
61298
 
59922
61299
  // src/tui/components/RoutingContent.tsx
59923
- import { useEffect as useEffect3, useRef as useRef2 } from "react";
61300
+ import { useEffect as useEffect3, useRef as useRef3 } from "react";
59924
61301
  import { jsxDEV as jsxDEV9, Fragment as Fragment6 } from "@opentui/react/jsx-dev-runtime";
59925
61302
  function chainStr(chain) {
59926
61303
  return chain.join(" \u2192 ");
@@ -59943,8 +61320,8 @@ function RoutingContent({
59943
61320
  editingExistingScope,
59944
61321
  routingScopeCursor
59945
61322
  }) {
59946
- const rulesScrollRef = useRef2(null);
59947
- const chainScrollRef = useRef2(null);
61323
+ const rulesScrollRef = useRef3(null);
61324
+ const chainScrollRef = useRef3(null);
59948
61325
  useEffect3(() => {
59949
61326
  const sb = rulesScrollRef.current;
59950
61327
  if (!sb || mergedRules.length === 0)
@@ -61132,12 +62509,12 @@ var init_PrivacyDetail = __esm(() => {
61132
62509
  });
61133
62510
 
61134
62511
  // src/tui/App.tsx
61135
- import { useKeyboard, useRenderer, useTerminalDimensions } from "@opentui/react";
62512
+ import { useKeyboard as useKeyboard2, useRenderer, useTerminalDimensions as useTerminalDimensions2 } from "@opentui/react";
61136
62513
  import { useCallback as useCallback3, useEffect as useEffect4, useMemo as useMemo2, useState as useState5 } from "react";
61137
62514
  import { jsxDEV as jsxDEV13, Fragment as Fragment7 } from "@opentui/react/jsx-dev-runtime";
61138
62515
  function App({ requestLogin } = {}) {
61139
62516
  const renderer = useRenderer();
61140
- const { width, height: height2 } = useTerminalDimensions();
62517
+ const { width, height: height2 } = useTerminalDimensions2();
61141
62518
  const [config3, setConfig] = useState5(() => loadConfig());
61142
62519
  const [bufStats, setBufStats] = useState5(() => getBufferStats());
61143
62520
  const [providerIndex, setProviderIndex] = useState5(0);
@@ -61186,7 +62563,6 @@ function App({ requestLogin } = {}) {
61186
62563
  const { probeMode, probeModel, probeResults } = probe;
61187
62564
  const wizard = useProfileWizard({ mode, setMode, refreshConfig, setStatusMsg });
61188
62565
  const {
61189
- editProfileName,
61190
62566
  editProfileValue,
61191
62567
  profileScope,
61192
62568
  suggestions,
@@ -61238,7 +62614,6 @@ function App({ requestLogin } = {}) {
61238
62614
  return out;
61239
62615
  }, [config3.routing, JSON.stringify(loadLocalConfig()?.routing ?? {})]);
61240
62616
  const profileName = config3.defaultProfile || "default";
61241
- const readyCount = PROVIDERS.filter((p) => !!(config3.apiKeys?.[p.apiKeyEnvVar] || process.env[p.apiKeyEnvVar])).length;
61242
62617
  const runProbeTest = useCallback3(async (prov) => {
61243
62618
  const provName = prov.name;
61244
62619
  setTestResults((prev) => ({ ...prev, [provName]: { status: "testing" } }));
@@ -61322,7 +62697,7 @@ function App({ requestLogin } = {}) {
61322
62697
  }));
61323
62698
  }
61324
62699
  }, []);
61325
- useKeyboard((key) => {
62700
+ useKeyboard2((key) => {
61326
62701
  if (key.ctrl && key.name === "c")
61327
62702
  return quit();
61328
62703
  if (probeMode === "input") {
@@ -61549,10 +62924,8 @@ function App({ requestLogin } = {}) {
61549
62924
  return;
61550
62925
  }
61551
62926
  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");
62927
+ if (key.name === "return" || key.name === "enter") {
62928
+ wizard.pickScopeAtCursor();
61556
62929
  } else if (key.name === "escape") {
61557
62930
  wizard.cancelPickScope();
61558
62931
  }
@@ -61571,11 +62944,7 @@ function App({ requestLogin } = {}) {
61571
62944
  return;
61572
62945
  }
61573
62946
  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") {
62947
+ if (key.name === "return" || key.name === "enter") {
61579
62948
  wizard.prefixPickerSubmit();
61580
62949
  } else if (key.name === "escape") {
61581
62950
  wizard.prefixPickerCancel();
@@ -61920,61 +63289,64 @@ function App({ requestLogin } = {}) {
61920
63289
  children: [
61921
63290
  /* @__PURE__ */ jsxDEV13("box", {
61922
63291
  height: HEADER_H,
61923
- flexDirection: "row",
63292
+ flexDirection: "column",
61924
63293
  backgroundColor: C.bgAlt,
61925
63294
  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,
63295
+ children: [
63296
+ /* @__PURE__ */ jsxDEV13("box", {
63297
+ height: 1,
63298
+ flexDirection: "row",
63299
+ children: /* @__PURE__ */ jsxDEV13("text", {
61949
63300
  children: [
61950
- "\u2605 ",
61951
- profileName
63301
+ /* @__PURE__ */ jsxDEV13("span", {
63302
+ fg: C.white,
63303
+ attributes: A.bold,
63304
+ children: "claudish"
63305
+ }, undefined, false, undefined, this),
63306
+ /* @__PURE__ */ jsxDEV13("span", {
63307
+ fg: C.dim,
63308
+ children: " \u2500 "
63309
+ }, undefined, false, undefined, this),
63310
+ /* @__PURE__ */ jsxDEV13("span", {
63311
+ fg: C.blue,
63312
+ attributes: A.bold,
63313
+ children: `v${VERSION}`
63314
+ }, undefined, false, undefined, this),
63315
+ /* @__PURE__ */ jsxDEV13("span", {
63316
+ fg: C.dim,
63317
+ children: " \u2500 "
63318
+ }, undefined, false, undefined, this),
63319
+ /* @__PURE__ */ jsxDEV13("span", {
63320
+ fg: C.fgMuted,
63321
+ children: "by MadAppGang"
63322
+ }, undefined, false, undefined, this),
63323
+ /* @__PURE__ */ jsxDEV13("span", {
63324
+ fg: C.dim,
63325
+ children: " \u2500 "
63326
+ }, undefined, false, undefined, this),
63327
+ /* @__PURE__ */ jsxDEV13("span", {
63328
+ fg: C.fgMuted,
63329
+ children: "profile: "
63330
+ }, undefined, false, undefined, this),
63331
+ /* @__PURE__ */ jsxDEV13("span", {
63332
+ fg: C.orange,
63333
+ attributes: A.bold,
63334
+ children: `[${profileName}]`
63335
+ }, undefined, false, undefined, this)
61952
63336
  ]
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, {
63337
+ }, undefined, true, undefined, this)
63338
+ }, undefined, false, undefined, this),
63339
+ /* @__PURE__ */ jsxDEV13("box", {
63340
+ flexGrow: 1,
63341
+ border: ["bottom"],
63342
+ borderStyle: "single",
63343
+ borderColor: C.dim
63344
+ }, undefined, false, undefined, this)
63345
+ ]
63346
+ }, undefined, true, undefined, this),
63347
+ /* @__PURE__ */ jsxDEV13(TabBar2, {
61975
63348
  activeTab,
61976
- statusMsg,
61977
- width
63349
+ statusMsg
61978
63350
  }, undefined, false, undefined, this),
61979
63351
  activeTab === "providers" && /* @__PURE__ */ jsxDEV13(Fragment7, {
61980
63352
  children: [
@@ -61983,7 +63355,6 @@ function App({ requestLogin } = {}) {
61983
63355
  displayProviders,
61984
63356
  providerIndex,
61985
63357
  testResults,
61986
- width,
61987
63358
  contentH,
61988
63359
  isInputMode,
61989
63360
  animTick
@@ -62013,13 +63384,14 @@ function App({ requestLogin } = {}) {
62013
63384
  mode,
62014
63385
  profileScope,
62015
63386
  profileIndex,
62016
- editProfileName,
62017
63387
  editProfileValue,
62018
63388
  suggestions,
62019
63389
  suggestionIndex,
62020
63390
  providerPickerIndex,
62021
63391
  width,
62022
- contentH
63392
+ contentH,
63393
+ onScopeChange: wizard.setScopeCursor,
63394
+ onPrefixChange: wizard.setProviderPickerIndex
62023
63395
  }, undefined, false, undefined, this),
62024
63396
  /* @__PURE__ */ jsxDEV13(ProfileDetail, {
62025
63397
  config: config3,