@tonyclaw/agent-inspector 2.1.14 → 2.1.16

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 (70) hide show
  1. package/.output/nitro.json +1 -1
  2. package/.output/public/assets/CompareDrawer-Ccrrcx1j.js +1 -0
  3. package/.output/public/assets/ProxyViewerContainer-DLqClc9A.js +106 -0
  4. package/.output/public/assets/ReplayDialog-C7axhr-l.js +1 -0
  5. package/.output/public/assets/{RequestAnatomy-BNahe83D.js → RequestAnatomy-WOptg8j_.js} +1 -1
  6. package/.output/public/assets/{ResponseView-DSOnGqi6.js → ResponseView-CSAcxh_M.js} +2 -2
  7. package/.output/public/assets/{StreamingChunkSequence-BEKTDklB.js → StreamingChunkSequence-DJS5KhPx.js} +1 -1
  8. package/.output/public/assets/_sessionId-DUSalzKH.js +1 -0
  9. package/.output/public/assets/index-BPpA21dY.css +1 -0
  10. package/.output/public/assets/index-Bt0Az2I2.js +1 -0
  11. package/.output/public/assets/{index-DWOkqdCa.js → index-DMPNh46t.js} +1 -1
  12. package/.output/public/assets/{json-viewer-C2JpgcW0.js → json-viewer-inX5QSa3.js} +1 -1
  13. package/.output/public/assets/{main-CSONBwwn.js → main-aCAKYGSD.js} +2 -2
  14. package/.output/server/_libs/lucide-react.mjs +224 -194
  15. package/.output/server/{_sessionId-CPAa37n5.mjs → _sessionId-C0fhvQnn.mjs} +2 -2
  16. package/.output/server/_ssr/{CompareDrawer-ceW5VxMo.mjs → CompareDrawer-CO-Ti5sg.mjs} +36 -15
  17. package/.output/server/_ssr/{ProxyViewerContainer-CDfEE_w-.mjs → ProxyViewerContainer-N4J7uBCX.mjs} +1153 -494
  18. package/.output/server/_ssr/{ReplayDialog-V0s_eEbR.mjs → ReplayDialog-J1VxC0In.mjs} +14 -7
  19. package/.output/server/_ssr/{RequestAnatomy-f1ccwR9d.mjs → RequestAnatomy-DBH-F3rq.mjs} +3 -3
  20. package/.output/server/_ssr/{ResponseView-BIRrqG4H.mjs → ResponseView-DLFwV7Hd.mjs} +3 -3
  21. package/.output/server/_ssr/{StreamingChunkSequence-V3JFjCgX.mjs → StreamingChunkSequence-BywmuND0.mjs} +3 -3
  22. package/.output/server/_ssr/{index-DsykulzS.mjs → index-CStymIc0.mjs} +2 -2
  23. package/.output/server/_ssr/index.mjs +2 -2
  24. package/.output/server/_ssr/{json-viewer-Dcnm0Ivf.mjs → json-viewer-DlQu0N1x.mjs} +3 -3
  25. package/.output/server/_ssr/{router-4bdm6Mt2.mjs → router-CQ4Zxhmr.mjs} +118 -47
  26. package/.output/server/{_tanstack-start-manifest_v-Xp4CO64V.mjs → _tanstack-start-manifest_v-BHeJBGfo.mjs} +1 -1
  27. package/.output/server/index.mjs +75 -75
  28. package/package.json +1 -1
  29. package/src/components/ProxyViewer.tsx +174 -107
  30. package/src/components/ProxyViewerContainer.tsx +77 -67
  31. package/src/components/alerts/AlertsDialog.tsx +2 -1
  32. package/src/components/clients/ClientLogo.tsx +132 -0
  33. package/src/components/groups/GroupsDialog.tsx +37 -14
  34. package/src/components/providers/ProviderCard.tsx +1 -1
  35. package/src/components/providers/ProviderForm.tsx +18 -18
  36. package/src/components/providers/ProviderLogo.tsx +6 -1
  37. package/src/components/providers/ProvidersPanel.tsx +6 -6
  38. package/src/components/providers/SettingsDialog.tsx +13 -6
  39. package/src/components/proxy-viewer/AgentTraceSummary.tsx +62 -29
  40. package/src/components/proxy-viewer/CompareDrawer.tsx +38 -8
  41. package/src/components/proxy-viewer/ConversationGroup.tsx +43 -32
  42. package/src/components/proxy-viewer/ConversationGroupList.tsx +452 -89
  43. package/src/components/proxy-viewer/ConversationHeader.tsx +65 -61
  44. package/src/components/proxy-viewer/LogEntry.tsx +31 -18
  45. package/src/components/proxy-viewer/LogEntryHeader.tsx +42 -49
  46. package/src/components/proxy-viewer/ProviderLogoStack.tsx +60 -0
  47. package/src/components/proxy-viewer/ReplayDialog.tsx +8 -2
  48. package/src/components/proxy-viewer/RequestToolsPanel.tsx +9 -9
  49. package/src/components/proxy-viewer/ThreadConnector.tsx +22 -11
  50. package/src/components/proxy-viewer/TurnGroup.tsx +30 -36
  51. package/src/components/proxy-viewer/TurnGroupList.tsx +3 -0
  52. package/src/components/proxy-viewer/viewerState.ts +5 -6
  53. package/src/components/ui/icon-trigger.ts +2 -0
  54. package/src/components/ui/transient-toast.tsx +104 -0
  55. package/src/lib/sessionInfoContract.ts +5 -0
  56. package/src/lib/stopReason.ts +48 -16
  57. package/src/mcp/server.ts +71 -27
  58. package/src/mcp/toolHandlers.ts +23 -4
  59. package/src/proxy/formats/openai/alibabaProvider.ts +0 -4
  60. package/src/proxy/sessionInfo.ts +36 -3
  61. package/src/proxy/sessionSupervisor.ts +20 -1
  62. package/src/proxy/store.ts +1 -1
  63. package/src/routes/api/providers.$providerId.test.log.ts +8 -4
  64. package/styles/globals.css +180 -180
  65. package/.output/public/assets/CompareDrawer-DjgjIFx7.js +0 -1
  66. package/.output/public/assets/ProxyViewerContainer-CWUQZLYy.js +0 -106
  67. package/.output/public/assets/ReplayDialog-CU0Tbb2c.js +0 -1
  68. package/.output/public/assets/_sessionId-Cif8JZdn.js +0 -1
  69. package/.output/public/assets/index-D_WfwzUi.js +0 -1
  70. package/.output/public/assets/index-DtLuQrs0.css +0 -1
@@ -1,5 +1,5 @@
1
1
  import { r as reactExports, j as jsxRuntimeExports, a as React } from "../_libs/react.mjs";
2
- import { I as InspectorGroupsListResponseSchema, C as CapturedLogSchema, D as DEFAULT_CAPTURE_MODE, a as DEFAULT_SLOW_RESPONSE_THRESHOLD_SECONDS, b as DEFAULT_PROVIDER_TEST_TIMEOUT_SECONDS, c as DEFAULT_TIME_DISPLAY_FORMAT, d as RuntimeConfigSchema, p as packageJson, P as ProviderConfigSchema, i as apiFormatForPath, n as GroupEvidenceExportResultSchema, o as DeleteInspectorGroupResponseSchema, v as createPendingProviderTestResults, w as ProviderTestResultsSchema, x as createFailedProviderTestResults, M as MAX_SLOW_RESPONSE_THRESHOLD_SECONDS, y as MAX_PROVIDER_TEST_TIMEOUT_SECONDS, T as TimeDisplayFormatSchema, j as getSessionPath, l as AlertSummarySchema, m as AlertListResponseSchema, G as GroupEvidenceReadResponseSchema, t as maskApiKey, q as providerHasContextMetadata, r as findProviderModelMetadata, s as safeGetOwnProperty, K as KnowledgeCandidateSchema, f as parseOpenAIResponse, g as parseOpenAIResponsesResponse, O as OpenAIRequestSchema, h as OpenAIResponsesRequestSchema, A as AnthropicResponseSchema$1, e as AnthropicRequestSchema, z as resolveProviderContextWindow, u as buildUpstreamUrl, k as stripClaudeCodeBillingHeader, L as LogBodyChunkSchema, B as isPlainRecord } from "./router-4bdm6Mt2.mjs";
2
+ import { I as InspectorGroupsListResponseSchema, C as CapturedLogSchema, D as DEFAULT_CAPTURE_MODE, a as DEFAULT_SLOW_RESPONSE_THRESHOLD_SECONDS, b as DEFAULT_PROVIDER_TEST_TIMEOUT_SECONDS, c as DEFAULT_TIME_DISPLAY_FORMAT, d as RuntimeConfigSchema, p as packageJson, P as ProviderConfigSchema, i as apiFormatForPath, n as GroupEvidenceExportResultSchema, o as DeleteInspectorGroupResponseSchema, v as createPendingProviderTestResults, w as ProviderTestResultsSchema, x as createFailedProviderTestResults, M as MAX_SLOW_RESPONSE_THRESHOLD_SECONDS, y as MAX_PROVIDER_TEST_TIMEOUT_SECONDS, T as TimeDisplayFormatSchema, l as AlertSummarySchema, m as AlertListResponseSchema, G as GroupEvidenceReadResponseSchema, t as maskApiKey, q as providerHasContextMetadata, r as findProviderModelMetadata, f as parseOpenAIResponse, g as parseOpenAIResponsesResponse, O as OpenAIRequestSchema, h as OpenAIResponsesRequestSchema, A as AnthropicResponseSchema$1, e as AnthropicRequestSchema, s as safeGetOwnProperty, z as resolveProviderContextWindow, j as getSessionPath, u as buildUpstreamUrl, K as KnowledgeCandidateSchema, B as isPlainRecord, k as stripClaudeCodeBillingHeader, L as LogBodyChunkSchema } from "./router-CQ4Zxhmr.mjs";
3
3
  import { u as useSWR, a as useSWRConfig } from "../_libs/swr.mjs";
4
4
  import { J as JSZip } from "../_libs/jszip.mjs";
5
5
  import { c as clsx } from "../_libs/clsx.mjs";
@@ -9,7 +9,7 @@ import { c as cva } from "../_libs/class-variance-authority.mjs";
9
9
  import { u as useWindowVirtualizer, a as useVirtualizer } from "../_libs/tanstack__react-virtual.mjs";
10
10
  import { d as diffJson, a as diffLines } from "../_libs/diff.mjs";
11
11
  import { R as Root2, T as Trigger, I as Icon, V as Value, P as Portal, C as Content2, a as Viewport, b as Item, c as ItemIndicator, d as ItemText, S as ScrollUpButton, e as ScrollDownButton } from "../_libs/radix-ui__react-select.mjs";
12
- import { I as Info, C as ChevronDown, a as Check, X, U as Upload, D as Download, F as FileBraces, T as Trash2, P as Plus, A as ArrowLeft, b as ChevronUp, c as Copy, d as ChevronsLeft, e as ChevronLeft, f as ChevronRight, g as ChevronsRight, h as Clapperboard, S as Siren, G as Gauge, L as LoaderCircle, R as RefreshCw, i as Layers, j as Settings, k as Scan, l as CircleAlert, m as Terminal, n as ArrowUpRight, o as ArrowDownRight, p as User, q as Clock, M as MessageSquare, Z as Zap, E as ExternalLink, W as Wrench, r as TriangleAlert, B as Brain, s as Bell, t as Clock3, u as ShieldAlert, v as EyeOff, w as Eye, x as RotateCw, y as Pencil, z as CircleX, H as ShieldCheck, J as Save, K as FileSearch, N as CircleCheck, O as CloudUpload, Q as Minus, V as CircleCheckBig, Y as CircleQuestionMark, _ as Server, $ as Lock, a0 as Wifi, a1 as WifiOff, a2 as OctagonAlert, a3 as Radio, a4 as Globe, a5 as FileTerminal, a6 as ChevronsUp, a7 as ChevronsDown, a8 as FileDiff, a9 as History, aa as RotateCcw, ab as Search, ac as GitCompareArrows, ad as ArrowUp, ae as ArrowDown, af as Ellipsis, ag as CodeXml, ah as Blocks, ai as MousePointerClick, aj as FileText, ak as Rows3, al as Columns2 } from "../_libs/lucide-react.mjs";
12
+ import { T as TriangleAlert, C as CircleCheck, X, I as Info, a as ChevronDown, b as Check, U as Upload, D as Download, F as FileBraces, c as Trash2, P as Plus, A as ArrowLeft, d as ChevronUp, e as Copy, f as ChevronsLeft, g as ChevronLeft, h as ChevronRight, i as ChevronsRight, j as Clapperboard, S as Siren, G as Gauge, L as LoaderCircle, R as RefreshCw, k as Layers, l as Settings, M as Monitor, m as Scan, n as CircleAlert, o as Terminal, p as ArrowUpRight, q as ArrowDownRight, r as Cpu, s as FolderOpen, B as Bell, t as Clock3, u as ShieldAlert, E as EyeOff, v as Eye, w as ExternalLink, x as RotateCw, y as Clock, z as Pencil, H as MessageSquare, Z as Zap, W as Wrench, J as Brain, K as Minus, N as CircleCheckBig, O as CircleQuestionMark, Q as Server, V as Lock, Y as Wifi, _ as WifiOff, $ as CircleX, a0 as ShieldCheck, a1 as Save, a2 as FileSearch, a3 as CloudUpload, a4 as OctagonAlert, a5 as Radio, a6 as Globe, a7 as FileTerminal, a8 as ChevronsUp, a9 as ChevronsDown, aa as FileDiff, ab as History, ac as RotateCcw, ad as Search, ae as GitCompareArrows, af as ArrowUp, ag as ArrowDown, ah as Ellipsis, ai as CodeXml, aj as Blocks, ak as MousePointerClick, al as FileText, am as Rows3, an as Columns2 } from "../_libs/lucide-react.mjs";
13
13
  import { u as union, d as object, a as array, l as literal, b as string, n as number, c as boolean, _ as _enum } from "../_libs/zod.mjs";
14
14
  import { S as Slot } from "../_libs/radix-ui__react-slot.mjs";
15
15
  import { R as Root2$1, L as List, T as Trigger$2, C as Content$1 } from "../_libs/radix-ui__react-tabs.mjs";
@@ -771,6 +771,111 @@ function ConfirmDialog({
771
771
  ] })
772
772
  ] }) });
773
773
  }
774
+ const CLIENT_LABELS = {
775
+ codex: "Codex",
776
+ opencode: "OpenCode",
777
+ "mimo-code": "MiMo Code",
778
+ "claude-code": "Claude Code"
779
+ };
780
+ function normalize(value) {
781
+ return value?.toLowerCase() ?? "";
782
+ }
783
+ function matchesAny(value, candidates) {
784
+ for (const candidate of candidates) {
785
+ if (value.includes(candidate)) return true;
786
+ }
787
+ return false;
788
+ }
789
+ function detectClientApp(input) {
790
+ const haystack = [
791
+ normalize(input.userAgent),
792
+ normalize(input.conversationId),
793
+ normalize(input.clientProjectFolder)
794
+ ].join(" ");
795
+ if (matchesAny(haystack, ["mimocode", "mimo-code", "mimo code"])) return "mimo-code";
796
+ if (matchesAny(haystack, ["opencode", "open-code", "open code"])) return "opencode";
797
+ if (matchesAny(haystack, ["claude-code", "claude code", "claudecode"])) return "claude-code";
798
+ if (matchesAny(haystack, ["codex desktop", "codex-cli", "openai-codex", "codex"])) {
799
+ return "codex";
800
+ }
801
+ return "unknown";
802
+ }
803
+ function clientAppLabel(client) {
804
+ switch (client) {
805
+ case "codex":
806
+ case "opencode":
807
+ case "mimo-code":
808
+ case "claude-code":
809
+ return CLIENT_LABELS[client];
810
+ case "unknown":
811
+ return null;
812
+ }
813
+ }
814
+ function CodexMark() {
815
+ return /* @__PURE__ */ jsxRuntimeExports.jsxs("svg", { viewBox: "0 0 24 24", className: "size-full", "aria-hidden": "true", children: [
816
+ /* @__PURE__ */ jsxRuntimeExports.jsx("circle", { cx: "12", cy: "12", r: "8", fill: "none", stroke: "currentColor", strokeWidth: "2.2" }),
817
+ /* @__PURE__ */ jsxRuntimeExports.jsx(
818
+ "path",
819
+ {
820
+ d: "M14.8 8.6a4.8 4.8 0 1 0 0 6.8",
821
+ fill: "none",
822
+ stroke: "currentColor",
823
+ strokeLinecap: "round",
824
+ strokeWidth: "2.2"
825
+ }
826
+ )
827
+ ] });
828
+ }
829
+ function OpenCodeMark() {
830
+ return /* @__PURE__ */ jsxRuntimeExports.jsxs("svg", { viewBox: "0 0 24 24", className: "size-full", "aria-hidden": "true", children: [
831
+ /* @__PURE__ */ jsxRuntimeExports.jsx("path", { d: "M7 4h10v16H7z", fill: "none", stroke: "currentColor", strokeWidth: "2.2" }),
832
+ /* @__PURE__ */ jsxRuntimeExports.jsx("path", { d: "M10 8h4M10 12h4M10 16h2", stroke: "currentColor", strokeLinecap: "round" })
833
+ ] });
834
+ }
835
+ function MiMoCodeMark() {
836
+ return /* @__PURE__ */ jsxRuntimeExports.jsx("svg", { viewBox: "0 0 24 24", className: "size-full", "aria-hidden": "true", children: /* @__PURE__ */ jsxRuntimeExports.jsx(
837
+ "path",
838
+ {
839
+ d: "M5 18V6h3.2l3.8 6.1L15.8 6H19v12h-3V11.3l-3.1 5h-1.8L8 11.3V18z",
840
+ fill: "currentColor"
841
+ }
842
+ ) });
843
+ }
844
+ function ClaudeCodeMark() {
845
+ return /* @__PURE__ */ jsxRuntimeExports.jsx("svg", { viewBox: "0 0 24 24", className: "size-full", "aria-hidden": "true", children: /* @__PURE__ */ jsxRuntimeExports.jsx(
846
+ "path",
847
+ {
848
+ fill: "currentColor",
849
+ fillRule: "evenodd",
850
+ clipRule: "evenodd",
851
+ d: "M21 10.95h3v3.1h-3v3.03h-1.49V20H18v-2.92h-1.49V20H15v-2.92H9V20H7.49v-2.92H6V20H4.49v-2.92H3v-3.03H0v-3.1h3V5h18v5.95zM6 10.95h1.49V8.1H6v2.85zm10.51 0H18V8.1h-1.49v2.85z"
852
+ }
853
+ ) });
854
+ }
855
+ function ClientLogo({
856
+ client,
857
+ className
858
+ }) {
859
+ const label = clientAppLabel(client);
860
+ if (label === null) return null;
861
+ return /* @__PURE__ */ jsxRuntimeExports.jsxs(
862
+ "span",
863
+ {
864
+ className: cn(
865
+ "border border-border bg-muted/40 inline-flex size-6 shrink-0 items-center justify-center rounded-md p-1 text-cyan-100",
866
+ className
867
+ ),
868
+ "aria-label": label,
869
+ title: label,
870
+ children: [
871
+ client === "codex" && /* @__PURE__ */ jsxRuntimeExports.jsx(CodexMark, {}),
872
+ client === "opencode" && /* @__PURE__ */ jsxRuntimeExports.jsx(OpenCodeMark, {}),
873
+ client === "mimo-code" && /* @__PURE__ */ jsxRuntimeExports.jsx(MiMoCodeMark, {}),
874
+ client === "claude-code" && /* @__PURE__ */ jsxRuntimeExports.jsx(ClaudeCodeMark, {})
875
+ ]
876
+ }
877
+ );
878
+ }
774
879
  const AnthropicLogoSvg = "data:image/svg+xml,%3csvg%20height='2500'%20viewBox='0%206.603%201192.672%201193.397'%20width='2500'%20xmlns='http://www.w3.org/2000/svg'%3e%3cpath%20d='m233.96%20800.215%20234.684-131.678%203.947-11.436-3.947-6.363h-11.436l-39.221-2.416-134.094-3.624-116.296-4.832-112.67-6.04-28.35-6.04-26.577-35.035%202.738-17.477%2023.84-16.027%2034.147%202.98%2075.463%205.155%20113.235%207.812%2082.147%204.832%20121.692%2012.644h19.329l2.738-7.812-6.604-4.832-5.154-4.832-117.182-79.41-126.845-83.92-66.443-48.321-35.92-24.484-18.12-22.953-7.813-50.093%2032.618-35.92%2043.812%202.98%2011.195%202.98%2044.375%2034.147%2094.792%2073.37%20123.786%2091.167%2018.12%2015.06%207.249-5.154.886-3.624-8.135-13.61-67.329-121.692-71.838-123.785-31.974-51.302-8.456-30.765c-2.98-12.645-5.154-23.275-5.154-36.242l37.127-50.416%2020.537-6.604%2049.53%206.604%2020.86%2018.121%2030.765%2070.39%2049.852%20110.818%2077.315%20150.684%2022.631%2044.698%2012.08%2041.396%204.51%2012.645h7.813v-7.248l6.362-84.886%2011.759-104.215%2011.436-134.094%203.946-37.772%2018.685-45.262%2037.127-24.482%2028.994%2013.852%2023.839%2034.148-3.303%2022.067-14.174%2092.134-27.785%20144.323-18.121%2096.644h10.55l12.08-12.08%2048.887-64.913%2082.147-102.685%2036.242-40.752%2042.282-45.02%2027.14-21.423h51.303l37.772%2056.135-16.913%2057.986-52.832%2067.007-43.812%2056.779-62.82%2084.563-39.22%2067.651%203.623%205.396%209.343-.886%20141.906-30.201%2076.671-13.852%2091.49-15.705%2041.396%2019.329%204.51%2019.65-16.269%2040.189-97.852%2024.16-114.764%2022.954-170.9%2040.43-2.093%201.53%202.416%202.98%2076.993%207.248%2032.94%201.771h80.617l150.12%2011.195%2039.222%2025.933%2023.517%2031.732-3.946%2024.16-60.403%2030.766-81.503-19.33-190.228-45.26-65.235-16.27h-9.02v5.397l54.362%2053.154%2099.624%2089.96%20124.752%20115.973%206.362%2028.671-16.027%2022.63-16.912-2.415-109.611-82.47-42.282-37.127-95.758-80.618h-6.363v8.456l22.067%2032.296%20116.537%20175.167%206.04%2053.719-8.456%2017.476-30.201%2010.55-33.181-6.04-68.215-95.758-70.39-107.84-56.778-96.644-6.926%203.947-33.503%20360.886-15.705%2018.443-36.243%2013.852-30.201-22.953-16.027-37.127%2016.027-73.37%2019.329-95.758%2015.704-76.107%2014.175-94.55%208.456-31.41-.563-2.094-6.927.886-71.275%2097.852-108.402%20146.497-85.772%2091.812-20.537%208.134-35.597-18.443%203.301-32.94%2019.893-29.315%20118.712-151.007%2071.597-93.583%2046.228-54.04-.322-7.813h-2.738l-315.302%20204.725-56.135%207.248-24.16-22.63%202.98-37.128%2011.435-12.08%2094.792-65.236-.322.323z'%20fill='%23d97757'/%3e%3c/svg%3e";
775
880
  const OpenAILogoSvg = "data:image/svg+xml,%3csvg%20height='2500'%20viewBox='-1%20-.1%20949.1%20959.8'%20width='2474'%20xmlns='http://www.w3.org/2000/svg'%3e%3cpath%20d='m925.8%20456.3c10.4%2023.2%2017%2048%2019.7%2073.3%202.6%2025.3%201.3%2050.9-4.1%2075.8-5.3%2024.9-14.5%2048.8-27.3%2070.8-8.4%2014.7-18.3%2028.5-29.7%2041.2-11.3%2012.6-23.9%2024-37.6%2034-13.8%2010-28.5%2018.4-44.1%2025.3-15.5%206.8-31.7%2012-48.3%2015.4-7.8%2024.2-19.4%2047.1-34.4%2067.7-14.9%2020.6-33%2038.7-53.6%2053.6-20.6%2015-43.4%2026.6-67.6%2034.4-24.2%207.9-49.5%2011.8-75%2011.8-16.9.1-33.9-1.7-50.5-5.1-16.5-3.5-32.7-8.8-48.2-15.7s-30.2-15.5-43.9-25.5c-13.6-10-26.2-21.5-37.4-34.2-25%205.4-50.6%206.7-75.9%204.1-25.3-2.7-50.1-9.3-73.4-19.7-23.2-10.3-44.7-24.3-63.6-41.4s-35-37.1-47.7-59.1c-8.5-14.7-15.5-30.2-20.8-46.3s-8.8-32.7-10.6-49.6c-1.8-16.8-1.7-33.8.1-50.7%201.8-16.8%205.5-33.4%2010.8-49.5-17-18.9-31-40.4-41.4-63.6-10.3-23.3-17-48-19.6-73.3-2.7-25.3-1.3-50.9%204-75.8s14.5-48.8%2027.3-70.8c8.4-14.7%2018.3-28.6%2029.6-41.2s24-24%2037.7-34%2028.5-18.5%2044-25.3c15.6-6.9%2031.8-12%2048.4-15.4%207.8-24.3%2019.4-47.1%2034.3-67.7%2015-20.6%2033.1-38.7%2053.7-53.7%2020.6-14.9%2043.4-26.5%2067.6-34.4%2024.2-7.8%2049.5-11.8%2075-11.7%2016.9-.1%2033.9%201.6%2050.5%205.1s32.8%208.7%2048.3%2015.6c15.5%207%2030.2%2015.5%2043.9%2025.5%2013.7%2010.1%2026.3%2021.5%2037.5%2034.2%2024.9-5.3%2050.5-6.6%2075.8-4s50%209.3%2073.3%2019.6c23.2%2010.4%2044.7%2024.3%2063.6%2041.4%2018.9%2017%2035%2036.9%2047.7%2059%208.5%2014.6%2015.5%2030.1%2020.8%2046.3%205.3%2016.1%208.9%2032.7%2010.6%2049.6%201.8%2016.9%201.8%2033.9-.1%2050.8-1.8%2016.9-5.5%2033.5-10.8%2049.6%2017.1%2018.9%2031%2040.3%2041.4%2063.6zm-333.2%20426.9c21.8-9%2041.6-22.3%2058.3-39s30-36.5%2039-58.4c9-21.8%2013.7-45.2%2013.7-68.8v-223q-.1-.3-.2-.7-.1-.3-.3-.6-.2-.3-.5-.5-.3-.3-.6-.4l-80.7-46.6v269.4c0%202.7-.4%205.5-1.1%208.1-.7%202.7-1.7%205.2-3.1%207.6s-3%204.6-5%206.5a32.1%2032.1%200%200%201%20-6.5%205l-191.1%20110.3c-1.6%201-4.3%202.4-5.7%203.2%207.9%206.7%2016.5%2012.6%2025.5%2017.8%209.1%205.2%2018.5%209.6%2028.3%2013.2%209.8%203.5%2019.9%206.2%2030.1%208%2010.3%201.8%2020.7%202.7%2031.1%202.7%2023.6%200%2047-4.7%2068.8-13.8zm-455.1-151.4c11.9%2020.5%2027.6%2038.3%2046.3%2052.7%2018.8%2014.4%2040.1%2024.9%2062.9%2031s46.6%207.7%2070%204.6%2045.9-10.7%2066.4-22.5l193.2-111.5.5-.5q.2-.2.3-.6.2-.3.3-.6v-94l-233.2%20134.9c-2.4%201.4-4.9%202.4-7.5%203.2-2.7.7-5.4%201-8.2%201-2.7%200-5.4-.3-8.1-1-2.6-.8-5.2-1.8-7.6-3.2l-191.1-110.4c-1.7-1-4.2-2.5-5.6-3.4-1.8%2010.3-2.7%2020.7-2.7%2031.1s1%2020.8%202.8%2031.1c1.8%2010.2%204.6%2020.3%208.1%2030.1%203.6%209.8%208%2019.2%2013.2%2028.2zm-50.2-417c-11.8%2020.5-19.4%2043.1-22.5%2066.5s-1.5%2047.1%204.6%2070c6.1%2022.8%2016.6%2044.1%2031%2062.9%2014.4%2018.7%2032.3%2034.4%2052.7%2046.2l193.1%20111.6q.3.1.7.2h.7q.4%200%20.7-.2.3-.1.6-.3l81-46.8-233.2-134.6c-2.3-1.4-4.5-3.1-6.5-5a32.1%2032.1%200%200%201%20-5-6.5c-1.3-2.4-2.4-4.9-3.1-7.6-.7-2.6-1.1-5.3-1-8.1v-227.1c-9.8%203.6-19.3%208-28.3%2013.2-9%205.3-17.5%2011.3-25.5%2018-7.9%206.7-15.3%2014.1-22%2022.1-6.7%207.9-12.6%2016.5-17.8%2025.5zm663.3%20154.4c2.4%201.4%204.6%203%206.6%205%201.9%201.9%203.6%204.1%205%206.5%201.3%202.4%202.4%205%203.1%207.6.6%202.7%201%205.4.9%208.2v227.1c32.1-11.8%2060.1-32.5%2080.8-59.7%2020.8-27.2%2033.3-59.7%2036.2-93.7s-3.9-68.2-19.7-98.5-39.9-55.5-69.5-72.5l-193.1-111.6q-.3-.1-.7-.2h-.7q-.3.1-.7.2-.3.1-.6.3l-80.6%2046.6%20233.2%20134.7zm80.5-121h-.1v.1zm-.1-.1c5.8-33.6%201.9-68.2-11.3-99.7-13.1-31.5-35-58.6-63-78.2-28-19.5-61-30.7-95.1-32.2-34.2-1.4-68%206.9-97.6%2023.9l-193.1%20111.5q-.3.2-.5.5l-.4.6q-.1.3-.2.7-.1.3-.1.7v93.2l233.2-134.7c2.4-1.4%205-2.4%207.6-3.2%202.7-.7%205.4-1%208.1-1%202.8%200%205.5.3%208.2%201%202.6.8%205.1%201.8%207.5%203.2l191.1%20110.4c1.7%201%204.2%202.4%205.6%203.3zm-505.3-103.2c0-2.7.4-5.4%201.1-8.1.7-2.6%201.7-5.2%203.1-7.6%201.4-2.3%203-4.5%205-6.5%201.9-1.9%204.1-3.6%206.5-4.9l191.1-110.3c1.8-1.1%204.3-2.5%205.7-3.2-26.2-21.9-58.2-35.9-92.1-40.2-33.9-4.4-68.3%201-99.2%2015.5-31%2014.5-57.2%2037.6-75.5%2066.4-18.3%2028.9-28%2062.3-28%2096.5v223q.1.4.2.7.1.3.3.6.2.3.5.6.2.2.6.4l80.7%2046.6zm43.8%20294.7%20103.9%2060%20103.9-60v-119.9l-103.8-60-103.9%2060z'/%3e%3c/svg%3e";
776
881
  const DeepSeekLogoSvg = "data:image/svg+xml,%3csvg%20fill='none'%20height='1320'%20viewBox='3.771%206.973%2023.993%2017.652'%20width='2500'%20xmlns='http://www.w3.org/2000/svg'%3e%3cpath%20d='m27.501%208.469c-.252-.123-.36.111-.508.23-.05.04-.093.09-.135.135-.368.395-.797.652-1.358.621-.821-.045-1.521.213-2.14.842-.132-.776-.57-1.238-1.235-1.535-.349-.155-.701-.309-.944-.645-.171-.238-.217-.504-.303-.765-.054-.159-.108-.32-.29-.348-.197-.031-.274.135-.352.273-.31.567-.43%201.192-.419%201.825.028%201.421.628%202.554%201.82%203.36.136.093.17.186.128.321-.081.278-.178.547-.264.824-.054.178-.135.217-.324.14a5.448%205.448%200%200%201%20-1.719-1.169c-.848-.82-1.614-1.726-2.57-2.435-.225-.166-.449-.32-.681-.467-.976-.95.128-1.729.383-1.82.267-.096.093-.428-.77-.424s-1.653.293-2.659.677a2.782%202.782%200%200%201%20-.46.135%209.554%209.554%200%200%200%20-2.853-.1c-1.866.21-3.356%201.092-4.452%202.6-1.315%201.81-1.625%203.87-1.246%206.018.399%202.261%201.552%204.136%203.326%205.601%201.837%201.518%203.955%202.262%206.37%202.12%201.466-.085%203.1-.282%204.942-1.842.465.23.952.322%201.762.392.623.059%201.223-.031%201.687-.127.728-.154.677-.828.414-.953-2.132-.994-1.665-.59-2.09-.916%201.084-1.285%202.717-2.619%203.356-6.94.05-.343.007-.558%200-.837-.004-.168.034-.235.228-.254a4.084%204.084%200%200%200%201.529-.47c1.382-.757%201.938-1.997%202.07-3.485.02-.227-.004-.463-.243-.582zm-12.041%2013.391c-2.067-1.627-3.07-2.162-3.483-2.138-.387.021-.318.465-.233.754.089.285.205.482.368.732.113.166.19.414-.112.598-.666.414-1.823-.139-1.878-.166-1.347-.793-2.473-1.842-3.267-3.276-.765-1.38-1.21-2.861-1.284-4.441-.02-.383.093-.518.472-.586a4.692%204.692%200%200%201%201.514-.04c2.109.31%203.905%201.255%205.41%202.749.86.853%201.51%201.871%202.18%202.865.711%201.057%201.478%202.063%202.454%202.887.343.289.619.51.881.672-.792.088-2.117.107-3.022-.61zm.99-6.38a.304.304%200%201%201%20.609%200c0%20.17-.136.304-.306.304a.3.3%200%200%201%20-.303-.305zm3.077%201.581c-.197.08-.394.15-.584.159a1.246%201.246%200%200%201%20-.79-.252c-.27-.227-.463-.354-.546-.752a1.752%201.752%200%200%201%20.016-.582c.07-.324-.008-.531-.235-.72-.187-.155-.422-.196-.682-.196a.551.551%200%200%201%20-.252-.078c-.108-.055-.197-.19-.112-.356.027-.053.159-.183.19-.207.352-.201.758-.135%201.134.016.349.142.611.404.99.773.388.448.457.573.678.906.174.264.333.534.441.842.066.192-.02.35-.248.448z'%20fill='%234d6bfe'/%3e%3c/svg%3e";
@@ -785,12 +890,16 @@ const PROVIDER_MAP = {
785
890
  "o3-": "openai",
786
891
  "deepseek-": "deepseek",
787
892
  MiniMax: "minimax",
788
- qwen: "qwen",
789
- "glm-": "zhipuai"
893
+ qwen: "qwen"
790
894
  };
895
+ function isGlmModel(modelLower) {
896
+ const normalized = modelLower.replace(/[_\s]+/g, "-");
897
+ return normalized.split(/[/:@]/).some((segment2) => segment2.startsWith("glm-"));
898
+ }
791
899
  function detectProvider(model) {
792
900
  if (model === null) return "unknown";
793
901
  const modelLower = model.toLowerCase();
902
+ if (isGlmModel(modelLower)) return "zhipuai";
794
903
  for (const [prefix, provider] of Object.entries(PROVIDER_MAP)) {
795
904
  if (modelLower.startsWith(prefix.toLowerCase())) {
796
905
  return provider;
@@ -893,6 +1002,38 @@ function TooltipContent({
893
1002
  }
894
1003
  ) });
895
1004
  }
1005
+ const MAX_VISIBLE_LOGOS = 3;
1006
+ const ROW_CHEVRON_SLOT_CLASS = "flex h-8 w-5 shrink-0 items-center justify-center text-muted-foreground";
1007
+ function ProviderLogoStack({
1008
+ items,
1009
+ ariaLabel,
1010
+ className
1011
+ }) {
1012
+ if (items.length === 0) {
1013
+ return /* @__PURE__ */ jsxRuntimeExports.jsx("span", { className: cn("flex h-8 w-12 shrink-0 items-center", className), "aria-hidden": "true" });
1014
+ }
1015
+ const visibleItems = items.slice(0, MAX_VISIBLE_LOGOS);
1016
+ const overflowCount = items.length - visibleItems.length;
1017
+ return /* @__PURE__ */ jsxRuntimeExports.jsx(TooltipProvider, { delayDuration: 150, children: /* @__PURE__ */ jsxRuntimeExports.jsxs("span", { className: cn("flex h-8 w-12 shrink-0 items-center", className), "aria-label": ariaLabel, children: [
1018
+ visibleItems.map((item, index) => /* @__PURE__ */ jsxRuntimeExports.jsxs(Tooltip, { children: [
1019
+ /* @__PURE__ */ jsxRuntimeExports.jsx(TooltipTrigger, { asChild: true, children: /* @__PURE__ */ jsxRuntimeExports.jsx(
1020
+ "span",
1021
+ {
1022
+ className: cn(
1023
+ "border border-border bg-muted/40 inline-flex size-6 shrink-0 items-center justify-center rounded-md",
1024
+ index > 0 && "-ml-2"
1025
+ ),
1026
+ children: /* @__PURE__ */ jsxRuntimeExports.jsx(ProviderLogo, { provider: item.provider, className: "size-4" })
1027
+ }
1028
+ ) }),
1029
+ /* @__PURE__ */ jsxRuntimeExports.jsx(TooltipContent, { children: item.tooltip })
1030
+ ] }, `${item.provider}-${String(index)}`)),
1031
+ overflowCount > 0 && /* @__PURE__ */ jsxRuntimeExports.jsxs("span", { className: "border border-border bg-muted/40 -ml-2 inline-flex h-6 min-w-6 shrink-0 items-center justify-center rounded-md px-1 font-mono text-[10px] text-muted-foreground", children: [
1032
+ "+",
1033
+ overflowCount
1034
+ ] })
1035
+ ] }) });
1036
+ }
896
1037
  function forEachCodePoint(text, visit) {
897
1038
  for (const ch of Array.from(text)) {
898
1039
  visit(ch);
@@ -1283,6 +1424,8 @@ function ConversationHeader({
1283
1424
  userAgent,
1284
1425
  clientPid,
1285
1426
  clientProjectFolder,
1427
+ showClientIdentity = true,
1428
+ showProcessMetadata = true,
1286
1429
  timeDisplayFormat,
1287
1430
  onClear
1288
1431
  }) {
@@ -1299,6 +1442,17 @@ function ConversationHeader({
1299
1442
  },
1300
1443
  [conversationId]
1301
1444
  );
1445
+ const providerLogoItems = providers?.map(({ provider, models }) => ({
1446
+ provider,
1447
+ tooltip: models.length === 1 ? models[0] ?? provider : models.join(", ")
1448
+ })) ?? [];
1449
+ const clientApp = detectClientApp({ userAgent, conversationId, clientProjectFolder });
1450
+ const detectedClientLabel = clientAppLabel(clientApp);
1451
+ const hasUserAgent = userAgent !== null && userAgent !== void 0 && userAgent !== "";
1452
+ const clientDisplayLabel = detectedClientLabel ?? userAgent ?? null;
1453
+ const clientTooltip = detectedClientLabel !== null && hasUserAgent ? `${detectedClientLabel} - ${userAgent}` : null;
1454
+ const isFallbackConversation = conversationId.startsWith("PID:") || conversationId.includes("|");
1455
+ const compactSessionLabel = conversationId.length > 24 ? conversationId.slice(0, 12) + "..." + conversationId.slice(-12) : conversationId;
1302
1456
  return /* @__PURE__ */ jsxRuntimeExports.jsxs(
1303
1457
  "div",
1304
1458
  {
@@ -1307,10 +1461,10 @@ function ConversationHeader({
1307
1461
  "data-nav-id": `conv-${conversationId}`,
1308
1462
  "data-nav-action": expanded ? "collapse" : "expand",
1309
1463
  className: cn(
1310
- "flex items-center gap-3 px-3 py-2 cursor-pointer transition-colors",
1311
- "hover:bg-muted/50",
1464
+ "border border-border bg-card shadow-sm flex cursor-pointer items-center gap-3 rounded-[8px] px-3 py-2 transition-colors",
1465
+ "hover:border-cyan-200/20",
1312
1466
  "select-none",
1313
- "border border-border rounded-lg mb-2 bg-background sticky top-0 z-10",
1467
+ "sticky top-0 z-10 mb-2",
1314
1468
  "focus-visible:ring-2 focus-visible:ring-ring focus-visible:ring-offset-1 focus-visible:outline-none"
1315
1469
  ),
1316
1470
  onClick: onToggle,
@@ -1322,19 +1476,19 @@ function ConversationHeader({
1322
1476
  }
1323
1477
  },
1324
1478
  children: [
1325
- expanded ? /* @__PURE__ */ jsxRuntimeExports.jsx(ChevronDown, { className: "size-4 text-muted-foreground shrink-0" }) : isLoading ? /* @__PURE__ */ jsxRuntimeExports.jsx(LoaderCircle, { className: "size-4 animate-spin text-muted-foreground shrink-0" }) : /* @__PURE__ */ jsxRuntimeExports.jsx(ChevronRight, { className: "size-4 text-muted-foreground shrink-0" }),
1326
- conversationId.startsWith("PID:") || conversationId.includes("|") ? /* @__PURE__ */ jsxRuntimeExports.jsxs(jsxRuntimeExports.Fragment, { children: [
1479
+ /* @__PURE__ */ jsxRuntimeExports.jsx(ProviderLogoStack, { items: providerLogoItems, ariaLabel: "Models used in this session" }),
1480
+ isFallbackConversation && showProcessMetadata ? /* @__PURE__ */ jsxRuntimeExports.jsxs(jsxRuntimeExports.Fragment, { children: [
1327
1481
  clientPid !== null && clientPid !== void 0 ? /* @__PURE__ */ jsxRuntimeExports.jsxs(
1328
1482
  "span",
1329
1483
  {
1330
- className: "text-purple-400/90 font-mono text-xs font-semibold shrink-0",
1484
+ className: "shrink-0 font-mono text-xs font-semibold text-violet-200",
1331
1485
  title: `PID ${clientPid}`,
1332
1486
  children: [
1333
1487
  "PID ",
1334
1488
  clientPid
1335
1489
  ]
1336
1490
  }
1337
- ) : /* @__PURE__ */ jsxRuntimeExports.jsx("span", { className: "text-purple-400/90 font-mono text-xs font-semibold shrink-0", children: conversationId }),
1491
+ ) : /* @__PURE__ */ jsxRuntimeExports.jsx("span", { className: "shrink-0 font-mono text-xs font-semibold text-violet-200", children: conversationId }),
1338
1492
  clientProjectFolder !== null && clientProjectFolder !== void 0 && clientProjectFolder !== "" && /* @__PURE__ */ jsxRuntimeExports.jsx(
1339
1493
  "span",
1340
1494
  {
@@ -1347,15 +1501,15 @@ function ConversationHeader({
1347
1501
  /* @__PURE__ */ jsxRuntimeExports.jsx(
1348
1502
  "span",
1349
1503
  {
1350
- className: "text-purple-400/90 font-mono text-xs font-semibold shrink-0",
1504
+ className: "shrink-0 font-mono text-xs font-semibold text-violet-200",
1351
1505
  title: conversationId,
1352
- children: conversationId.length > 24 ? conversationId.slice(0, 12) + "..." + conversationId.slice(-12) : conversationId
1506
+ children: isFallbackConversation ? "sessionless" : compactSessionLabel
1353
1507
  }
1354
1508
  ),
1355
- clientPid !== null && clientPid !== void 0 && /* @__PURE__ */ jsxRuntimeExports.jsxs(
1509
+ showProcessMetadata && clientPid !== null && clientPid !== void 0 && /* @__PURE__ */ jsxRuntimeExports.jsxs(
1356
1510
  "span",
1357
1511
  {
1358
- className: "text-muted-foreground text-xs font-mono tabular-nums shrink-0 px-1.5 py-0.5 rounded border border-border bg-muted/40",
1512
+ className: "border border-border bg-muted/40 shrink-0 rounded px-1.5 py-0.5 font-mono text-xs tabular-nums text-muted-foreground",
1359
1513
  title: `Client process ID ${clientPid}`,
1360
1514
  children: [
1361
1515
  "PID ",
@@ -1364,28 +1518,17 @@ function ConversationHeader({
1364
1518
  }
1365
1519
  )
1366
1520
  ] }),
1367
- userAgent !== null && userAgent !== void 0 && userAgent !== "" && /* @__PURE__ */ jsxRuntimeExports.jsxs(
1521
+ showClientIdentity && clientDisplayLabel !== null && clientDisplayLabel !== "" && /* @__PURE__ */ jsxRuntimeExports.jsxs(
1368
1522
  "span",
1369
1523
  {
1370
1524
  className: "flex items-center gap-1 text-muted-foreground text-xs shrink-0",
1371
- title: userAgent,
1525
+ title: clientTooltip ?? clientDisplayLabel,
1372
1526
  children: [
1373
- /* @__PURE__ */ jsxRuntimeExports.jsx(User, { className: "size-3" }),
1374
- /* @__PURE__ */ jsxRuntimeExports.jsx("span", { className: "font-mono tabular-nums truncate max-w-[120px]", children: userAgent })
1527
+ /* @__PURE__ */ jsxRuntimeExports.jsx(ClientLogo, { client: clientApp, className: "size-5" }),
1528
+ /* @__PURE__ */ jsxRuntimeExports.jsx("span", { className: "font-mono tabular-nums truncate max-w-[120px]", children: clientDisplayLabel })
1375
1529
  ]
1376
1530
  }
1377
1531
  ),
1378
- providers !== void 0 && providers.length > 0 && /* @__PURE__ */ jsxRuntimeExports.jsx(TooltipProvider, { delayDuration: 150, children: /* @__PURE__ */ jsxRuntimeExports.jsx(
1379
- "span",
1380
- {
1381
- className: "flex items-center gap-0.5 shrink-0",
1382
- "aria-label": "Models used in this session",
1383
- children: providers.map(({ provider, models }) => /* @__PURE__ */ jsxRuntimeExports.jsxs(Tooltip, { children: [
1384
- /* @__PURE__ */ jsxRuntimeExports.jsx(TooltipTrigger, { asChild: true, children: /* @__PURE__ */ jsxRuntimeExports.jsx("span", { className: "shrink-0", children: /* @__PURE__ */ jsxRuntimeExports.jsx(ProviderLogo, { provider, className: "size-4" }) }) }),
1385
- /* @__PURE__ */ jsxRuntimeExports.jsx(TooltipContent, { children: models.length === 1 ? models[0] : models.join(", ") })
1386
- ] }, provider))
1387
- }
1388
- ) }),
1389
1532
  /* @__PURE__ */ jsxRuntimeExports.jsxs("span", { className: "flex items-center gap-1 text-muted-foreground text-xs shrink-0", children: [
1390
1533
  /* @__PURE__ */ jsxRuntimeExports.jsx(Clock, { className: "size-3" }),
1391
1534
  /* @__PURE__ */ jsxRuntimeExports.jsx("span", { className: "font-mono tabular-nums", children: formatTimestampRange(startTime, endTime, timeDisplayFormat) })
@@ -1419,7 +1562,7 @@ function ConversationHeader({
1419
1562
  },
1420
1563
  "aria-label": `Open session ${conversationId} in a new tab`,
1421
1564
  title: "Open this session in a new tab",
1422
- className: "text-muted-foreground hover:text-foreground transition-colors shrink-0 inline-flex items-center justify-center size-8 rounded hover:bg-muted cursor-pointer",
1565
+ className: "border border-input bg-background hover:bg-accent hover:text-accent-foreground inline-flex size-8 shrink-0 cursor-pointer items-center justify-center rounded-md text-muted-foreground transition-colors hover:text-foreground",
1423
1566
  children: /* @__PURE__ */ jsxRuntimeExports.jsx(ExternalLink, { className: "size-3.5" })
1424
1567
  }
1425
1568
  ),
@@ -1430,10 +1573,18 @@ function ConversationHeader({
1430
1573
  onClick: handleClearClick,
1431
1574
  "aria-label": `Clear group (${totalCalls} request${totalCalls !== 1 ? "s" : ""})`,
1432
1575
  title: "Clear this group",
1433
- className: "text-muted-foreground hover:text-foreground transition-colors shrink-0 inline-flex items-center justify-center size-8 rounded hover:bg-muted cursor-pointer",
1576
+ className: "border border-input bg-background hover:bg-accent hover:text-accent-foreground inline-flex size-8 shrink-0 cursor-pointer items-center justify-center rounded-md text-muted-foreground transition-colors hover:text-foreground",
1434
1577
  children: /* @__PURE__ */ jsxRuntimeExports.jsx(Trash2, { className: "size-3.5" })
1435
1578
  }
1436
1579
  ),
1580
+ /* @__PURE__ */ jsxRuntimeExports.jsx(
1581
+ "span",
1582
+ {
1583
+ className: "border border-input bg-background hover:bg-accent hover:text-accent-foreground inline-flex size-8 shrink-0 items-center justify-center rounded-md text-slate-200",
1584
+ "aria-hidden": "true",
1585
+ children: expanded ? /* @__PURE__ */ jsxRuntimeExports.jsx(ChevronDown, { className: "size-4 shrink-0" }) : isLoading ? /* @__PURE__ */ jsxRuntimeExports.jsx(LoaderCircle, { className: "size-4 shrink-0 animate-spin" }) : /* @__PURE__ */ jsxRuntimeExports.jsx(ChevronRight, { className: "size-4 shrink-0" })
1586
+ }
1587
+ ),
1437
1588
  /* @__PURE__ */ jsxRuntimeExports.jsx(
1438
1589
  ConfirmDialog,
1439
1590
  {
@@ -1453,10 +1604,10 @@ function ConversationHeader({
1453
1604
  );
1454
1605
  }
1455
1606
  function getConversationId(log) {
1456
- if (log.isTest === true) return "provider-test";
1457
1607
  if (log.sessionId !== null && log.sessionId !== "" && log.sessionId !== void 0) {
1458
1608
  return log.sessionId;
1459
1609
  }
1610
+ if (log.isTest === true) return "provider-test";
1460
1611
  const hasPid = log.clientPid !== null && log.clientPid !== void 0;
1461
1612
  const hasFolder = log.clientProjectFolder !== null && log.clientProjectFolder !== void 0;
1462
1613
  if (!hasPid && !hasFolder) return "default";
@@ -1519,6 +1670,33 @@ function readLogFocusRequest(event) {
1519
1670
  function isRecord(value) {
1520
1671
  return typeof value === "object" && value !== null && !Array.isArray(value);
1521
1672
  }
1673
+ function normalizeAnthropicStopReason(value) {
1674
+ switch (value) {
1675
+ case "end_turn":
1676
+ case "tool_use":
1677
+ return value;
1678
+ default:
1679
+ return null;
1680
+ }
1681
+ }
1682
+ function normalizeOpenAIFinishReason(value) {
1683
+ switch (value) {
1684
+ case "stop":
1685
+ case "length":
1686
+ return value;
1687
+ default:
1688
+ return null;
1689
+ }
1690
+ }
1691
+ function isResponsesLengthLimitReason(value) {
1692
+ switch (value) {
1693
+ case "max_output_tokens":
1694
+ case "max_tokens":
1695
+ return true;
1696
+ default:
1697
+ return false;
1698
+ }
1699
+ }
1522
1700
  function extractStopReason(log) {
1523
1701
  if (log.responseText === null) return null;
1524
1702
  try {
@@ -1528,13 +1706,14 @@ function extractStopReason(log) {
1528
1706
  }
1529
1707
  if (!isRecord(json)) return null;
1530
1708
  if (typeof json.stop_reason === "string") {
1531
- if (json.stop_reason === "end_turn" || json.stop_reason === "tool_use") {
1532
- return json.stop_reason;
1533
- }
1534
- return null;
1709
+ return normalizeAnthropicStopReason(json.stop_reason);
1535
1710
  }
1536
- if (Array.isArray(json.choices) && json.choices.length > 0 && isRecord(json.choices[0]) && typeof json.choices[0].finish_reason === "string" && json.choices[0].finish_reason === "stop") {
1537
- return "stop";
1711
+ if (Array.isArray(json.choices)) {
1712
+ for (const choice of json.choices) {
1713
+ if (!isRecord(choice) || typeof choice.finish_reason !== "string") continue;
1714
+ const reason = normalizeOpenAIFinishReason(choice.finish_reason);
1715
+ if (reason !== null) return reason;
1716
+ }
1538
1717
  }
1539
1718
  if (Array.isArray(json.output)) {
1540
1719
  for (const item of json.output) {
@@ -1546,13 +1725,19 @@ function extractStopReason(log) {
1546
1725
  return "stop";
1547
1726
  }
1548
1727
  }
1728
+ if (json.status === "incomplete" && isRecord(json.incomplete_details)) {
1729
+ const reason = json.incomplete_details.reason;
1730
+ if (typeof reason === "string" && isResponsesLengthLimitReason(reason)) {
1731
+ return "length";
1732
+ }
1733
+ }
1549
1734
  return null;
1550
1735
  } catch {
1551
1736
  return null;
1552
1737
  }
1553
1738
  }
1554
1739
  function isTurnBoundary(stopReason) {
1555
- return stopReason === "end_turn" || stopReason === "stop";
1740
+ return stopReason === "end_turn" || stopReason === "stop" || stopReason === "length";
1556
1741
  }
1557
1742
  function SvgShell({
1558
1743
  className,
@@ -2099,27 +2284,27 @@ function useCopyFeedback(text) {
2099
2284
  return { copied, copy };
2100
2285
  }
2101
2286
  const LazyCompareDrawer = reactExports.lazy(
2102
- () => import("./CompareDrawer-ceW5VxMo.mjs").then((m) => ({ default: m.CompareDrawer }))
2287
+ () => import("./CompareDrawer-CO-Ti5sg.mjs").then((m) => ({ default: m.CompareDrawer }))
2103
2288
  );
2104
2289
  const LazyReplayDialog = reactExports.lazy(
2105
- () => import("./ReplayDialog-V0s_eEbR.mjs").then((m) => ({ default: m.ReplayDialog }))
2290
+ () => import("./ReplayDialog-J1VxC0In.mjs").then((m) => ({ default: m.ReplayDialog }))
2106
2291
  );
2107
2292
  const LazyRequestAnatomy = reactExports.lazy(
2108
- () => import("./RequestAnatomy-f1ccwR9d.mjs").then((m) => ({ default: m.RequestAnatomy }))
2293
+ () => import("./RequestAnatomy-DBH-F3rq.mjs").then((m) => ({ default: m.RequestAnatomy }))
2109
2294
  );
2110
2295
  const LazyResponseView = reactExports.lazy(
2111
- () => import("./ResponseView-BIRrqG4H.mjs").then((m) => ({ default: m.ResponseView }))
2296
+ () => import("./ResponseView-DLFwV7Hd.mjs").then((m) => ({ default: m.ResponseView }))
2112
2297
  );
2113
2298
  const LazyStreamingChunkSequence = reactExports.lazy(
2114
- () => import("./StreamingChunkSequence-V3JFjCgX.mjs").then((m) => ({
2299
+ () => import("./StreamingChunkSequence-BywmuND0.mjs").then((m) => ({
2115
2300
  default: m.StreamingChunkSequence
2116
2301
  }))
2117
2302
  );
2118
2303
  const LazyJsonViewer = reactExports.lazy(
2119
- () => import("./json-viewer-Dcnm0Ivf.mjs").then((m) => ({ default: m.JsonViewer }))
2304
+ () => import("./json-viewer-DlQu0N1x.mjs").then((m) => ({ default: m.JsonViewer }))
2120
2305
  );
2121
2306
  const LazyJsonViewerFromString = reactExports.lazy(
2122
- () => import("./json-viewer-Dcnm0Ivf.mjs").then((m) => ({ default: m.JsonViewerFromString }))
2307
+ () => import("./json-viewer-DlQu0N1x.mjs").then((m) => ({ default: m.JsonViewerFromString }))
2123
2308
  );
2124
2309
  const HIGHLIGHT_DURATION_MS = 1200;
2125
2310
  const MAX_HIGHLIGHT_ATTEMPTS = 12;
@@ -2543,35 +2728,31 @@ function Badge({
2543
2728
  );
2544
2729
  }
2545
2730
  const STATUS_BADGE_CLASSES = {
2546
- success: "bg-emerald-400/[0.08] text-emerald-200 border-emerald-300/25",
2731
+ success: "bg-slate-300/[0.08] text-slate-100 border-slate-300/20",
2547
2732
  client_error: "bg-amber-300/[0.10] text-amber-100 border-amber-300/30",
2548
2733
  server_error: "bg-rose-400/[0.10] text-rose-100 border-rose-300/30",
2549
2734
  pending: "bg-cyan-300/[0.08] text-cyan-100 border-cyan-300/25"
2550
2735
  };
2551
2736
  const STATUS_CUE_CLASSES = {
2552
2737
  success: {
2553
- frame: "border-emerald-300/20 bg-emerald-300/[0.06] text-emerald-100",
2554
- dot: "bg-emerald-300 shadow-[0_0_14px_rgba(110,231,183,0.8)]",
2555
- rail: "bg-emerald-300/45 shadow-[0_0_22px_rgba(110,231,183,0.28)]"
2738
+ frame: "border-cyan-200/15 bg-white/[0.04] text-slate-100",
2739
+ dot: "bg-cyan-200/80 shadow-[0_0_14px_rgba(125,211,252,0.65)]"
2556
2740
  },
2557
2741
  client_error: {
2558
2742
  frame: "border-amber-300/25 bg-amber-300/[0.08] text-amber-100",
2559
- dot: "bg-amber-200 shadow-[0_0_14px_rgba(252,211,77,0.8)]",
2560
- rail: "bg-amber-300/50 shadow-[0_0_22px_rgba(252,211,77,0.28)]"
2743
+ dot: "bg-amber-200 shadow-[0_0_14px_rgba(252,211,77,0.8)]"
2561
2744
  },
2562
2745
  server_error: {
2563
2746
  frame: "border-rose-300/25 bg-rose-300/[0.08] text-rose-100",
2564
- dot: "bg-rose-300 shadow-[0_0_14px_rgba(253,164,175,0.8)]",
2565
- rail: "bg-rose-300/50 shadow-[0_0_22px_rgba(253,164,175,0.28)]"
2747
+ dot: "bg-rose-300 shadow-[0_0_14px_rgba(253,164,175,0.8)]"
2566
2748
  },
2567
2749
  pending: {
2568
2750
  frame: "border-cyan-300/25 bg-cyan-300/[0.08] text-cyan-100",
2569
- dot: "bg-cyan-200 shadow-[0_0_14px_rgba(103,232,249,0.8)]",
2570
- rail: "bg-cyan-300/50 shadow-[0_0_22px_rgba(103,232,249,0.28)]"
2751
+ dot: "bg-cyan-200 shadow-[0_0_14px_rgba(103,232,249,0.8)]"
2571
2752
  }
2572
2753
  };
2573
- const HEADER_ACTION_BUTTON_CLASS = "size-8 border-white/10 bg-[#0a0d11] text-muted-foreground shadow-none hover:border-cyan-300/30 hover:bg-cyan-400/10 hover:text-cyan-100";
2574
- const TELEMETRY_CHIP_CLASS = "flex h-7 items-center gap-1 rounded-md border border-white/10 bg-black/20 px-2 text-xs shadow-[inset_0_1px_0_rgba(255,255,255,0.04)]";
2754
+ const HEADER_ACTION_BUTTON_CLASS = "border border-input bg-background hover:bg-accent hover:text-accent-foreground size-8 text-muted-foreground shadow-none hover:text-cyan-100";
2755
+ const TELEMETRY_CHIP_CLASS = "border border-border bg-muted/40 flex h-7 items-center gap-1 rounded-md px-2 text-xs";
2575
2756
  function formatElapsed$3(ms) {
2576
2757
  if (ms < 1e3) return `${ms}ms`;
2577
2758
  return `${(ms / 1e3).toFixed(1)}s`;
@@ -2598,7 +2779,7 @@ function CacheTrendIndicator({ trend }) {
2598
2779
  const Icon2 = isUp ? ArrowUp : ArrowDown;
2599
2780
  const sign = isUp ? "+" : "-";
2600
2781
  return /* @__PURE__ */ jsxRuntimeExports.jsxs("span", { className: "flex items-center gap-0.5 text-muted-foreground tabular-nums", children: [
2601
- /* @__PURE__ */ jsxRuntimeExports.jsx(Icon2, { className: isUp ? "size-3 text-emerald-400" : "size-3 text-rose-400" }),
2782
+ /* @__PURE__ */ jsxRuntimeExports.jsx(Icon2, { className: isUp ? "size-3 text-cyan-300" : "size-3 text-rose-400" }),
2602
2783
  /* @__PURE__ */ jsxRuntimeExports.jsxs("span", { className: "font-mono", children: [
2603
2784
  sign,
2604
2785
  formatTokens(trend.delta)
@@ -2607,6 +2788,7 @@ function CacheTrendIndicator({ trend }) {
2607
2788
  }
2608
2789
  const LogEntryHeader = reactExports.memo(function({
2609
2790
  log,
2791
+ displayNumber,
2610
2792
  messageCount = null,
2611
2793
  toolCount = null,
2612
2794
  expanded,
@@ -2616,6 +2798,7 @@ const LogEntryHeader = reactExports.memo(function({
2616
2798
  tabActions,
2617
2799
  onReplay,
2618
2800
  slowResponseThresholdSeconds = 0,
2801
+ showClientMetadata = true,
2619
2802
  timeDisplayFormat
2620
2803
  }) {
2621
2804
  const statusCategory = getStatusCategory(log.responseStatus);
@@ -2641,8 +2824,8 @@ const LogEntryHeader = reactExports.memo(function({
2641
2824
  "data-nav-action": expanded ? "collapse" : "expand",
2642
2825
  className: cn(
2643
2826
  "group/header relative isolate flex min-w-0 flex-wrap items-center gap-x-2 gap-y-1 overflow-hidden px-3 py-2 cursor-pointer transition-[background-color,border-color,box-shadow]",
2644
- expanded ? "bg-[linear-gradient(90deg,#0f1720_0%,#090d12_50%,#07090d_100%)] shadow-[inset_0_1px_0_rgba(255,255,255,0.06)]" : "bg-[#080b10] hover:bg-[#0b1016]",
2645
- "select-none before:pointer-events-none before:absolute before:inset-x-0 before:top-0 before:h-px before:bg-white/10",
2827
+ expanded ? "bg-white/[0.035] shadow-[inset_0_1px_0_rgba(255,255,255,0.10)]" : "bg-transparent hover:bg-white/[0.035]",
2828
+ "select-none before:pointer-events-none before:absolute before:inset-x-3 before:top-0 before:h-px before:bg-white/12",
2646
2829
  "focus-visible:ring-2 focus-visible:ring-ring focus-visible:ring-offset-1 focus-visible:outline-none"
2647
2830
  ),
2648
2831
  onClick: onToggle,
@@ -2653,34 +2836,23 @@ const LogEntryHeader = reactExports.memo(function({
2653
2836
  }
2654
2837
  },
2655
2838
  children: [
2656
- /* @__PURE__ */ jsxRuntimeExports.jsx(
2657
- "span",
2658
- {
2659
- className: cn(
2660
- "absolute left-0 top-2 bottom-2 w-0.5 rounded-r-full transition-colors",
2661
- statusCue.rail
2662
- ),
2663
- "aria-hidden": "true"
2664
- }
2665
- ),
2666
2839
  /* @__PURE__ */ jsxRuntimeExports.jsxs(
2667
2840
  "span",
2668
2841
  {
2669
2842
  className: cn(
2670
- "inline-flex h-8 shrink-0 items-center gap-2 rounded-md border px-2 font-mono shadow-[inset_0_1px_0_rgba(255,255,255,0.05)]",
2843
+ "border border-border bg-muted/40 inline-flex h-8 shrink-0 items-center gap-2 rounded-md px-2 font-mono",
2671
2844
  statusCue.frame
2672
2845
  ),
2673
2846
  children: [
2674
2847
  /* @__PURE__ */ jsxRuntimeExports.jsx("span", { className: cn("size-1.5 rounded-full", statusCue.dot), "aria-hidden": "true" }),
2675
- /* @__PURE__ */ jsxRuntimeExports.jsx("span", { className: "text-[9px] font-semibold uppercase tracking-normal text-current/65", children: "Shot" }),
2676
- /* @__PURE__ */ jsxRuntimeExports.jsxs("span", { className: "text-xs font-semibold tabular-nums", children: [
2848
+ /* @__PURE__ */ jsxRuntimeExports.jsxs("span", { className: "text-xs font-semibold tabular-nums", title: `Log ID ${String(log.id)}`, children: [
2677
2849
  "#",
2678
- log.id
2850
+ displayNumber
2679
2851
  ] })
2680
2852
  ]
2681
2853
  }
2682
2854
  ),
2683
- /* @__PURE__ */ jsxRuntimeExports.jsxs("span", { className: "flex h-7 items-center gap-1 rounded-md border border-white/10 bg-black/20 px-2 text-muted-foreground text-xs shrink-0", children: [
2855
+ /* @__PURE__ */ jsxRuntimeExports.jsxs("span", { className: "border border-border bg-muted/40 flex h-7 shrink-0 items-center gap-1 rounded-md px-2 text-xs text-muted-foreground", children: [
2684
2856
  /* @__PURE__ */ jsxRuntimeExports.jsx(Clock, { className: "size-3" }),
2685
2857
  /* @__PURE__ */ jsxRuntimeExports.jsx("span", { className: "font-mono tabular-nums", title: log.timestamp, children: formatTimestamp$2(log.timestamp, timeDisplayFormat) })
2686
2858
  ] }),
@@ -2749,7 +2921,7 @@ const LogEntryHeader = reactExports.memo(function({
2749
2921
  /* @__PURE__ */ jsxRuntimeExports.jsx(TooltipContent, { children: "Time to first streaming chunk" })
2750
2922
  ] }),
2751
2923
  log.streaming && tokenRateLabel !== null && /* @__PURE__ */ jsxRuntimeExports.jsxs(Tooltip, { children: [
2752
- /* @__PURE__ */ jsxRuntimeExports.jsx(TooltipTrigger, { asChild: true, children: /* @__PURE__ */ jsxRuntimeExports.jsxs("span", { className: cn(TELEMETRY_CHIP_CLASS, "shrink-0 text-emerald-300"), children: [
2924
+ /* @__PURE__ */ jsxRuntimeExports.jsx(TooltipTrigger, { asChild: true, children: /* @__PURE__ */ jsxRuntimeExports.jsxs("span", { className: cn(TELEMETRY_CHIP_CLASS, "shrink-0 text-cyan-300"), children: [
2753
2925
  /* @__PURE__ */ jsxRuntimeExports.jsx(Gauge, { className: "size-3" }),
2754
2926
  /* @__PURE__ */ jsxRuntimeExports.jsx("span", { className: "font-mono tabular-nums", children: tokenRateLabel })
2755
2927
  ] }) }),
@@ -2767,7 +2939,7 @@ const LogEntryHeader = reactExports.memo(function({
2767
2939
  ),
2768
2940
  children: [
2769
2941
  "IN ",
2770
- log.inputTokens !== null ? formatTokens(log.inputTokens) : ""
2942
+ log.inputTokens !== null ? formatTokens(log.inputTokens) : "n/a"
2771
2943
  ]
2772
2944
  }
2773
2945
  ),
@@ -2781,7 +2953,7 @@ const LogEntryHeader = reactExports.memo(function({
2781
2953
  ),
2782
2954
  children: [
2783
2955
  "OUT ",
2784
- log.outputTokens !== null ? formatTokens(log.outputTokens) : ""
2956
+ log.outputTokens !== null ? formatTokens(log.outputTokens) : "n/a"
2785
2957
  ]
2786
2958
  }
2787
2959
  )
@@ -2789,7 +2961,7 @@ const LogEntryHeader = reactExports.memo(function({
2789
2961
  ] }),
2790
2962
  log.cacheCreationInputTokens !== null && log.cacheCreationInputTokens > 0 && /* @__PURE__ */ jsxRuntimeExports.jsxs("span", { className: cn(TELEMETRY_CHIP_CLASS, "shrink-0"), children: [
2791
2963
  /* @__PURE__ */ jsxRuntimeExports.jsx(CacheTrendIndicator, { trend: cacheTrend?.creation ?? null }),
2792
- /* @__PURE__ */ jsxRuntimeExports.jsxs("span", { className: "font-mono tabular-nums text-emerald-400", children: [
2964
+ /* @__PURE__ */ jsxRuntimeExports.jsxs("span", { className: "font-mono tabular-nums text-cyan-300", children: [
2793
2965
  "KV Cache +",
2794
2966
  formatTokens(log.cacheCreationInputTokens)
2795
2967
  ] })
@@ -2820,7 +2992,7 @@ const LogEntryHeader = reactExports.memo(function({
2820
2992
  ]
2821
2993
  }
2822
2994
  ),
2823
- (hasClientPid || hasClientProjectFolder) && /* @__PURE__ */ jsxRuntimeExports.jsxs(Tooltip, { children: [
2995
+ showClientMetadata && (hasClientPid || hasClientProjectFolder) && /* @__PURE__ */ jsxRuntimeExports.jsxs(Tooltip, { children: [
2824
2996
  /* @__PURE__ */ jsxRuntimeExports.jsx(TooltipTrigger, { asChild: true, children: /* @__PURE__ */ jsxRuntimeExports.jsxs("span", { className: cn(TELEMETRY_CHIP_CLASS, "hidden shrink-0 text-purple-300 xl:flex"), children: [
2825
2997
  /* @__PURE__ */ jsxRuntimeExports.jsx(FileTerminal, { className: "size-3" }),
2826
2998
  hasClientProjectFolder ? /* @__PURE__ */ jsxRuntimeExports.jsx("span", { className: "font-mono tabular-nums", children: log.clientProjectFolder }) : /* @__PURE__ */ jsxRuntimeExports.jsxs("span", { className: "font-mono tabular-nums", children: [
@@ -2903,7 +3075,7 @@ const LogEntryHeader = reactExports.memo(function({
2903
3075
  className: HEADER_ACTION_BUTTON_CLASS,
2904
3076
  onClick: action.onCopy,
2905
3077
  "aria-label": action.copyCopied ? "Copied" : action.copyLabel,
2906
- children: action.copyCopied ? /* @__PURE__ */ jsxRuntimeExports.jsx(Check, { className: "size-3.5 text-emerald-500" }) : /* @__PURE__ */ jsxRuntimeExports.jsx(Copy, { className: "size-3.5" })
3078
+ children: action.copyCopied ? /* @__PURE__ */ jsxRuntimeExports.jsx(Check, { className: "size-3.5 text-cyan-300" }) : /* @__PURE__ */ jsxRuntimeExports.jsx(Copy, { className: "size-3.5" })
2907
3079
  }
2908
3080
  ) }),
2909
3081
  /* @__PURE__ */ jsxRuntimeExports.jsx(TooltipContent, { children: action.copyCopied ? "Copied to clipboard" : action.copyLabel })
@@ -2927,7 +3099,14 @@ const LogEntryHeader = reactExports.memo(function({
2927
3099
  ]
2928
3100
  }
2929
3101
  ),
2930
- expanded ? /* @__PURE__ */ jsxRuntimeExports.jsx(ChevronDown, { className: "size-4 text-muted-foreground shrink-0" }) : /* @__PURE__ */ jsxRuntimeExports.jsx(ChevronRight, { className: "size-4 text-muted-foreground shrink-0" })
3102
+ /* @__PURE__ */ jsxRuntimeExports.jsx(
3103
+ "span",
3104
+ {
3105
+ className: "border border-input bg-background hover:bg-accent hover:text-accent-foreground inline-flex size-8 shrink-0 items-center justify-center rounded-md text-slate-200",
3106
+ "aria-hidden": "true",
3107
+ children: expanded ? /* @__PURE__ */ jsxRuntimeExports.jsx(ChevronDown, { className: "size-4 shrink-0" }) : /* @__PURE__ */ jsxRuntimeExports.jsx(ChevronRight, { className: "size-4 shrink-0" })
3108
+ }
3109
+ )
2931
3110
  ]
2932
3111
  }
2933
3112
  ) });
@@ -3059,7 +3238,7 @@ function ToolRow({ tool, called }) {
3059
3238
  const [open, setOpen] = reactExports.useState(false);
3060
3239
  const nameCopy = useCopyFeedback(tool.name);
3061
3240
  const hasDetails = tool.description !== null || tool.requiredParameters.length > 0 || tool.schema !== null;
3062
- return /* @__PURE__ */ jsxRuntimeExports.jsx(Collapsible, { open, onOpenChange: setOpen, children: /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "rounded-md border border-white/10 bg-black/20 shadow-[inset_0_1px_0_rgba(255,255,255,0.03)]", children: [
3241
+ return /* @__PURE__ */ jsxRuntimeExports.jsx(Collapsible, { open, onOpenChange: setOpen, children: /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "border border-border bg-card shadow-sm rounded-[8px]", children: [
3063
3242
  /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "flex min-w-0 items-center gap-2 px-2.5 py-2", children: [
3064
3243
  /* @__PURE__ */ jsxRuntimeExports.jsxs(
3065
3244
  "button",
@@ -3094,17 +3273,17 @@ function ToolRow({ tool, called }) {
3094
3273
  "button",
3095
3274
  {
3096
3275
  type: "button",
3097
- className: "inline-flex size-7 shrink-0 items-center justify-center rounded text-muted-foreground transition-colors hover:bg-muted hover:text-foreground focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring",
3276
+ className: "border border-input bg-background hover:bg-accent hover:text-accent-foreground inline-flex size-7 shrink-0 items-center justify-center rounded-md text-muted-foreground transition-colors hover:text-foreground focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring",
3098
3277
  onClick: nameCopy.copy,
3099
3278
  "aria-label": nameCopy.copied ? "Copied tool name" : "Copy tool name",
3100
3279
  children: nameCopy.copied ? /* @__PURE__ */ jsxRuntimeExports.jsx(Check, { className: "size-3.5 text-emerald-400" }) : /* @__PURE__ */ jsxRuntimeExports.jsx(Copy, { className: "size-3.5" })
3101
3280
  }
3102
3281
  )
3103
3282
  ] }),
3104
- /* @__PURE__ */ jsxRuntimeExports.jsx(CollapsibleContent, { children: open && /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "space-y-2 border-t border-white/10 bg-white/[0.02] px-2.5 py-2", children: [
3283
+ /* @__PURE__ */ jsxRuntimeExports.jsx(CollapsibleContent, { children: open && /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "space-y-2 border-t border-white/10 bg-white/[0.025] px-2.5 py-2", children: [
3105
3284
  tool.description !== null && /* @__PURE__ */ jsxRuntimeExports.jsx("p", { className: "text-xs leading-relaxed text-muted-foreground", children: tool.description }),
3106
3285
  /* @__PURE__ */ jsxRuntimeExports.jsx(RequiredParameters, { names: tool.requiredParameters }),
3107
- tool.schema !== null && /* @__PURE__ */ jsxRuntimeExports.jsx(ScrollArea, { className: "max-h-64 rounded-md border border-white/10 bg-[#06080b] p-2", children: /* @__PURE__ */ jsxRuntimeExports.jsx(
3286
+ tool.schema !== null && /* @__PURE__ */ jsxRuntimeExports.jsx(ScrollArea, { className: "border border-border bg-card shadow-sm max-h-64 rounded-[8px] p-2", children: /* @__PURE__ */ jsxRuntimeExports.jsx(
3108
3287
  reactExports.Suspense,
3109
3288
  {
3110
3289
  fallback: /* @__PURE__ */ jsxRuntimeExports.jsx("div", { className: "text-xs text-muted-foreground", children: "Loading JSON..." }),
@@ -3134,7 +3313,7 @@ const RequestTools = reactExports.memo(function RequestTools2({
3134
3313
  if (summary === null) return null;
3135
3314
  const previewTools = summary.tools.slice(0, 6);
3136
3315
  const hiddenPreviewCount = summary.tools.length - previewTools.length;
3137
- return /* @__PURE__ */ jsxRuntimeExports.jsxs("section", { className: "mb-3 overflow-hidden rounded-md border border-white/10 bg-[#080b0f] shadow-[inset_0_1px_0_rgba(255,255,255,0.04)]", children: [
3316
+ return /* @__PURE__ */ jsxRuntimeExports.jsxs("section", { className: "border border-border bg-card shadow-sm mb-3 overflow-hidden rounded-[8px]", children: [
3138
3317
  /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "flex min-w-0 flex-wrap items-center gap-2 px-3 py-2", children: [
3139
3318
  /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "flex min-w-0 flex-1 items-center gap-2", children: [
3140
3319
  /* @__PURE__ */ jsxRuntimeExports.jsx(Wrench, { className: "size-4 shrink-0 text-sky-300/80" }),
@@ -3178,7 +3357,7 @@ const RequestTools = reactExports.memo(function RequestTools2({
3178
3357
  type: "button",
3179
3358
  variant: "ghost",
3180
3359
  size: "sm",
3181
- className: "h-7 border border-white/10 bg-black/20 px-2 text-muted-foreground hover:border-cyan-300/30 hover:bg-cyan-400/10 hover:text-cyan-100",
3360
+ className: "h-7 px-2 text-muted-foreground hover:text-cyan-100",
3182
3361
  onClick: () => setExpanded((value) => !value),
3183
3362
  "aria-expanded": expanded,
3184
3363
  children: [
@@ -3188,7 +3367,7 @@ const RequestTools = reactExports.memo(function RequestTools2({
3188
3367
  }
3189
3368
  )
3190
3369
  ] }),
3191
- /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "flex min-w-0 flex-wrap gap-1.5 border-t border-white/10 bg-black/10 px-3 py-2", children: [
3370
+ /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "flex min-w-0 flex-wrap gap-1.5 border-t border-white/10 bg-white/[0.025] px-3 py-2", children: [
3192
3371
  previewTools.map((tool) => /* @__PURE__ */ jsxRuntimeExports.jsx(
3193
3372
  Badge,
3194
3373
  {
@@ -3206,8 +3385,8 @@ const RequestTools = reactExports.memo(function RequestTools2({
3206
3385
  hiddenPreviewCount
3207
3386
  ] })
3208
3387
  ] }),
3209
- expanded && /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "space-y-2 border-t border-white/10 bg-black/15 px-3 py-3", children: [
3210
- /* @__PURE__ */ jsxRuntimeExports.jsxs("label", { className: "flex h-8 items-center gap-2 rounded-md border border-white/10 bg-[#06080b] px-2 text-xs", children: [
3388
+ expanded && /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "space-y-2 border-t border-white/10 bg-black/10 px-3 py-3", children: [
3389
+ /* @__PURE__ */ jsxRuntimeExports.jsxs("label", { className: "border border-input bg-background hover:bg-accent hover:text-accent-foreground flex h-8 items-center gap-2 rounded-md px-2 text-xs", children: [
3211
3390
  /* @__PURE__ */ jsxRuntimeExports.jsx(Search, { className: "size-3.5 shrink-0 text-muted-foreground" }),
3212
3391
  /* @__PURE__ */ jsxRuntimeExports.jsx(
3213
3392
  "input",
@@ -3412,7 +3591,7 @@ const FULL_LOG_HYDRATION_TIMEOUT_MS = 15e3;
3412
3591
  const BODY_CHUNK_TIMEOUT_MS = 15e3;
3413
3592
  const BODY_CHUNK_BYTES = 256 * 1024;
3414
3593
  const CHUNKED_BODY_THRESHOLD_BYTES = 1024 * 1024;
3415
- const TAB_TRIGGER_CLASS = "h-9 flex-none rounded-none border-0 border-b-2 border-transparent bg-transparent px-3 text-xs font-semibold text-muted-foreground shadow-none transition-colors hover:bg-cyan-400/[0.05] hover:text-foreground data-[state=active]:border-cyan-300 data-[state=active]:bg-cyan-300/[0.04] data-[state=active]:text-cyan-100 data-[state=active]:shadow-none";
3594
+ const TAB_TRIGGER_CLASS = "h-9 flex-none rounded-md border border-transparent bg-transparent px-3 text-xs font-semibold text-muted-foreground shadow-none transition-colors hover:border-white/10 hover:bg-white/[0.045] hover:text-foreground data-[state=active]:border-cyan-200/25 data-[state=active]:bg-cyan-300/[0.08] data-[state=active]:text-cyan-100 data-[state=active]:shadow-none";
3416
3595
  function createEmptyBodyPreviewState(totalBytes = null) {
3417
3596
  return {
3418
3597
  status: "idle",
@@ -3463,7 +3642,7 @@ function ExpandedPanel({
3463
3642
  "div",
3464
3643
  {
3465
3644
  className: cn(
3466
- "inspector-scrollbar mx-3 mb-3 max-h-[72vh] overflow-auto rounded-md border border-cyan-300/10 bg-[#05070a] p-3 shadow-[0_16px_45px_rgba(0,0,0,0.24),inset_0_1px_0_rgba(255,255,255,0.05)]",
3645
+ "border border-border bg-card shadow-sm inspector-scrollbar mx-3 mb-3 max-h-[72vh] overflow-auto rounded-[8px] p-3",
3467
3646
  className
3468
3647
  ),
3469
3648
  children
@@ -3471,10 +3650,10 @@ function ExpandedPanel({
3471
3650
  );
3472
3651
  }
3473
3652
  function EmptyState({ children }) {
3474
- return /* @__PURE__ */ jsxRuntimeExports.jsx("div", { className: "rounded-md border border-dashed border-white/10 bg-white/[0.02] px-3 py-5 text-center text-xs italic text-muted-foreground", children });
3653
+ return /* @__PURE__ */ jsxRuntimeExports.jsx("div", { className: "border border-border bg-muted/40 rounded-md border-dashed px-3 py-5 text-center text-xs italic text-muted-foreground", children });
3475
3654
  }
3476
3655
  function RawTextBlock({ children }) {
3477
- return /* @__PURE__ */ jsxRuntimeExports.jsx("pre", { className: "inspector-scrollbar max-h-[64vh] overflow-auto whitespace-pre-wrap break-words rounded-md border border-white/10 bg-black/30 p-3 font-mono text-xs leading-relaxed text-muted-foreground", children });
3656
+ return /* @__PURE__ */ jsxRuntimeExports.jsx("pre", { className: "border border-border bg-card shadow-sm inspector-scrollbar max-h-[64vh] overflow-auto whitespace-pre-wrap break-words rounded-[8px] p-3 font-mono text-xs leading-relaxed text-muted-foreground", children });
3478
3657
  }
3479
3658
  const NOTICE_TONE_CLASSES = {
3480
3659
  loading: "border-cyan-400/25 bg-cyan-400/[0.06] text-cyan-100",
@@ -3526,7 +3705,7 @@ function BodyPreviewNotice({
3526
3705
  type: "button",
3527
3706
  variant: "outline",
3528
3707
  size: "sm",
3529
- className: "h-7 border-white/10 bg-black/20 text-xs text-cyan-100 hover:border-cyan-300/35 hover:bg-cyan-400/10",
3708
+ className: "border border-input bg-background hover:bg-accent hover:text-accent-foreground h-7 text-xs text-cyan-100",
3530
3709
  onClick: onLoadMore,
3531
3710
  children: actionLabel
3532
3711
  }
@@ -3541,12 +3720,12 @@ function HeaderRows({
3541
3720
  }) {
3542
3721
  const entries = headers === void 0 ? [] : Object.entries(headers).sort(([left], [right]) => left.localeCompare(right));
3543
3722
  if (entries.length === 0) return /* @__PURE__ */ jsxRuntimeExports.jsx(EmptyState, { children: emptyLabel });
3544
- return /* @__PURE__ */ jsxRuntimeExports.jsx("div", { className: "overflow-hidden rounded-md border border-white/10 bg-black/20 font-mono text-xs", children: entries.map(([key, value]) => /* @__PURE__ */ jsxRuntimeExports.jsxs(
3723
+ return /* @__PURE__ */ jsxRuntimeExports.jsx("div", { className: "border border-border bg-card shadow-sm overflow-hidden rounded-[8px] font-mono text-xs", children: entries.map(([key, value]) => /* @__PURE__ */ jsxRuntimeExports.jsxs(
3545
3724
  "div",
3546
3725
  {
3547
- className: "grid min-w-0 grid-cols-[minmax(140px,0.32fr)_minmax(0,1fr)] border-b border-white/5 last:border-b-0",
3726
+ className: "grid min-w-0 grid-cols-[minmax(140px,0.32fr)_minmax(0,1fr)] border-b border-white/10 last:border-b-0",
3548
3727
  children: [
3549
- /* @__PURE__ */ jsxRuntimeExports.jsx("div", { className: "min-w-0 truncate border-r border-white/5 bg-white/[0.03] px-2.5 py-2 font-semibold text-cyan-200", children: key }),
3728
+ /* @__PURE__ */ jsxRuntimeExports.jsx("div", { className: "min-w-0 truncate border-r border-white/10 bg-white/[0.035] px-2.5 py-2 font-semibold text-cyan-200", children: key }),
3550
3729
  /* @__PURE__ */ jsxRuntimeExports.jsx("div", { className: "min-w-0 truncate px-2.5 py-2 text-muted-foreground", title: value, children: value })
3551
3730
  ]
3552
3731
  },
@@ -3565,7 +3744,7 @@ function DiffToggleButton({
3565
3744
  size: "sm",
3566
3745
  className: cn(
3567
3746
  "h-8 border-white/10 text-xs shadow-none",
3568
- active ? "bg-cyan-300 text-black hover:bg-cyan-200" : "bg-[#0a0d11] text-muted-foreground hover:border-cyan-300/30 hover:bg-cyan-400/10 hover:text-cyan-100"
3747
+ active ? "bg-cyan-300 text-black hover:bg-cyan-200" : "border border-input bg-background hover:bg-accent hover:text-accent-foreground text-muted-foreground hover:text-cyan-100"
3569
3748
  ),
3570
3749
  onClick,
3571
3750
  "aria-pressed": active,
@@ -3599,12 +3778,14 @@ const HeadersDiffContent = reactExports.memo(function({
3599
3778
  });
3600
3779
  const LogEntry = reactExports.memo(function({
3601
3780
  log,
3781
+ displayNumber,
3602
3782
  viewMode = "simple",
3603
3783
  strip,
3604
3784
  slowResponseThresholdSeconds,
3605
3785
  timeDisplayFormat,
3606
3786
  cacheTrend = null,
3607
- onCompareWithPrevious
3787
+ onCompareWithPrevious,
3788
+ showClientMetadata = true
3608
3789
  }) {
3609
3790
  const [expanded, setExpanded] = reactExports.useState(false);
3610
3791
  const [replayOpen, setReplayOpen] = reactExports.useState(false);
@@ -3901,8 +4082,8 @@ const LogEntry = reactExports.memo(function({
3901
4082
  "div",
3902
4083
  {
3903
4084
  className: cn(
3904
- "relative mb-2 overflow-hidden rounded-lg border bg-[#07090d] transition-[background-color,border-color,box-shadow]",
3905
- expanded ? "border-cyan-300/25 shadow-[0_24px_80px_rgba(0,0,0,0.34),0_0_0_1px_rgba(103,232,249,0.04),inset_0_1px_0_rgba(255,255,255,0.06)]" : "border-white/10 shadow-[0_6px_24px_rgba(0,0,0,0.16)] hover:border-cyan-300/15"
4085
+ "border border-border bg-card shadow-sm relative mb-2 overflow-hidden rounded-[8px] transition-[background-color,border-color,box-shadow]",
4086
+ expanded ? "border-cyan-200/25 shadow-[0_24px_80px_rgba(0,0,0,0.36),0_0_0_1px_rgba(103,232,249,0.05),inset_0_1px_0_rgba(255,255,255,0.14)]" : "hover:border-cyan-200/18"
3906
4087
  ),
3907
4088
  children: [
3908
4089
  /* @__PURE__ */ jsxRuntimeExports.jsx(
@@ -3910,7 +4091,7 @@ const LogEntry = reactExports.memo(function({
3910
4091
  {
3911
4092
  className: cn(
3912
4093
  "pointer-events-none absolute inset-y-3 left-1 w-px rounded-full",
3913
- expanded ? "bg-cyan-300/45 shadow-[0_0_20px_rgba(103,232,249,0.28)]" : "bg-white/10"
4094
+ expanded ? "bg-cyan-200/55 shadow-[0_0_20px_rgba(103,232,249,0.26)]" : "bg-white/12"
3914
4095
  ),
3915
4096
  "aria-hidden": "true"
3916
4097
  }
@@ -3926,12 +4107,14 @@ const LogEntry = reactExports.memo(function({
3926
4107
  LogEntryHeader,
3927
4108
  {
3928
4109
  log: displayLog,
4110
+ displayNumber,
3929
4111
  messageCount: requestAnalysis.messageCount,
3930
4112
  toolCount: requestAnalysis.toolCount,
3931
4113
  expanded,
3932
4114
  onToggle: handleToggleExpanded,
3933
4115
  cacheTrend,
3934
4116
  slowResponseThresholdSeconds,
4117
+ showClientMetadata,
3935
4118
  timeDisplayFormat,
3936
4119
  activeTab,
3937
4120
  tabActions,
@@ -3943,14 +4126,14 @@ const LogEntry = reactExports.memo(function({
3943
4126
  expanded && /* @__PURE__ */ jsxRuntimeExports.jsxs(
3944
4127
  "div",
3945
4128
  {
3946
- className: "relative border-t border-cyan-300/10 bg-[linear-gradient(180deg,#06090d_0%,#040506_100%)] pt-2",
4129
+ className: "relative border-t border-white/10 bg-black/[0.18] pt-2",
3947
4130
  onClick: (e) => e.stopPropagation(),
3948
4131
  onKeyDown: (e) => e.stopPropagation(),
3949
4132
  children: [
3950
4133
  /* @__PURE__ */ jsxRuntimeExports.jsx(
3951
4134
  "div",
3952
4135
  {
3953
- className: "pointer-events-none absolute inset-x-0 top-0 h-12 bg-gradient-to-b from-cyan-300/[0.035] to-transparent",
4136
+ className: "pointer-events-none absolute inset-x-0 top-0 h-12 bg-gradient-to-b from-white/[0.05] to-transparent",
3954
4137
  "aria-hidden": "true"
3955
4138
  }
3956
4139
  ),
@@ -3959,7 +4142,7 @@ const LogEntry = reactExports.memo(function({
3959
4142
  TabsList,
3960
4143
  {
3961
4144
  variant: "line",
3962
- className: "inspector-scrollbar relative mx-3 h-auto w-[calc(100%-1.5rem)] justify-start overflow-x-auto rounded-none border-b border-cyan-300/10 bg-black/10 p-0",
4145
+ className: "border border-border bg-muted/40 inspector-scrollbar relative mx-3 h-auto w-[calc(100%-1.5rem)] justify-start overflow-x-auto rounded-[8px] p-1",
3963
4146
  children: [
3964
4147
  viewMode === "full" && /* @__PURE__ */ jsxRuntimeExports.jsx(TabsTrigger, { className: TAB_TRIGGER_CLASS, value: "raw-headers", children: "Raw Headers" }),
3965
4148
  viewMode === "full" && /* @__PURE__ */ jsxRuntimeExports.jsx(TabsTrigger, { className: TAB_TRIGGER_CLASS, value: "headers", children: "Headers" }),
@@ -4134,9 +4317,30 @@ const LogEntry = reactExports.memo(function({
4134
4317
  ]
4135
4318
  }
4136
4319
  ),
4137
- /* @__PURE__ */ jsxRuntimeExports.jsx(reactExports.Suspense, { fallback: null, children: /* @__PURE__ */ jsxRuntimeExports.jsx(LazyReplayDialog, { log: displayLog, open: replayOpen, onOpenChange: setReplayOpen }) })
4320
+ /* @__PURE__ */ jsxRuntimeExports.jsx(reactExports.Suspense, { fallback: null, children: /* @__PURE__ */ jsxRuntimeExports.jsx(
4321
+ LazyReplayDialog,
4322
+ {
4323
+ log: displayLog,
4324
+ displayNumber,
4325
+ open: replayOpen,
4326
+ onOpenChange: setReplayOpen
4327
+ }
4328
+ ) })
4138
4329
  ] });
4139
4330
  });
4331
+ function boundaryTitle(stopReason) {
4332
+ switch (stopReason) {
4333
+ case "end_turn":
4334
+ return "End of Turn (Anthropic)";
4335
+ case "stop":
4336
+ return "End of Turn (OpenAI)";
4337
+ case "length":
4338
+ return "End of Turn (length limit)";
4339
+ case "tool_use":
4340
+ case null:
4341
+ return "End of Turn";
4342
+ }
4343
+ }
4140
4344
  function ThreadConnector({
4141
4345
  stopReason,
4142
4346
  isPending,
@@ -4147,7 +4351,7 @@ function ThreadConnector({
4147
4351
  collapsible = false,
4148
4352
  onToggle
4149
4353
  }) {
4150
- const isBoundary = stopReason === "end_turn" || stopReason === "stop";
4354
+ const isBoundary = isTurnBoundary(stopReason);
4151
4355
  const isFusedBoundary = isOnlyEntry && isTurnStart && isBoundary;
4152
4356
  const isRunning = isPending && !isBoundary;
4153
4357
  const Crab = reactExports.useMemo(() => getCrabVariant(crabIndex), [crabIndex]);
@@ -4173,34 +4377,27 @@ function ThreadConnector({
4173
4377
  FusedCrab,
4174
4378
  {
4175
4379
  className: cn(
4176
- "size-3.5 text-[#80FF00]",
4380
+ "size-3.5 text-cyan-300/90",
4177
4381
  "animate-crab-settle",
4178
- "drop-shadow-[0_0_4px_rgba(128,255,0,0.5)]"
4382
+ "drop-shadow-[0_0_4px_rgba(103,232,249,0.35)]"
4179
4383
  )
4180
4384
  }
4181
- ) }) : isBoundary ? /* @__PURE__ */ jsxRuntimeExports.jsx(
4182
- "span",
4385
+ ) }) : isBoundary ? /* @__PURE__ */ jsxRuntimeExports.jsx("span", { title: boundaryTitle(stopReason), ...interactiveProps, children: /* @__PURE__ */ jsxRuntimeExports.jsx(
4386
+ Crab,
4183
4387
  {
4184
- title: stopReason === "end_turn" ? "End of Turn (Anthropic)" : "End of Turn (OpenAI)",
4185
- ...interactiveProps,
4186
- children: /* @__PURE__ */ jsxRuntimeExports.jsx(
4187
- Crab,
4188
- {
4189
- className: cn(
4190
- "size-3.5 text-amber-400",
4191
- "animate-crab-settle",
4192
- "drop-shadow-[0_0_4px_rgba(251,191,36,0.5)]"
4193
- )
4194
- }
4388
+ className: cn(
4389
+ "size-3.5 text-amber-400",
4390
+ "animate-crab-settle",
4391
+ "drop-shadow-[0_0_4px_rgba(251,191,36,0.5)]"
4195
4392
  )
4196
4393
  }
4197
- ) : isTurnStart ? /* @__PURE__ */ jsxRuntimeExports.jsx("span", { title: "Start of turn", ...interactiveProps, children: /* @__PURE__ */ jsxRuntimeExports.jsx(
4394
+ ) }) : isTurnStart ? /* @__PURE__ */ jsxRuntimeExports.jsx("span", { title: "Start of turn", ...interactiveProps, children: /* @__PURE__ */ jsxRuntimeExports.jsx(
4198
4395
  Crab,
4199
4396
  {
4200
4397
  className: cn(
4201
- "size-3.5 text-emerald-400",
4398
+ "size-3.5 text-cyan-300/85",
4202
4399
  "animate-crab-appear",
4203
- "drop-shadow-[0_0_4px_rgba(52,211,153,0.5)]"
4400
+ "drop-shadow-[0_0_4px_rgba(103,232,249,0.32)]"
4204
4401
  )
4205
4402
  }
4206
4403
  ) }) : isRunning ? /* @__PURE__ */ jsxRuntimeExports.jsx("span", { title: "Processing…", children: /* @__PURE__ */ jsxRuntimeExports.jsx(Crab, { className: cn("size-3.5 text-amber-300/80", "animate-crab-crawl") }) }) : /* @__PURE__ */ jsxRuntimeExports.jsx("span", { children: /* @__PURE__ */ jsxRuntimeExports.jsx(Crab, { className: "size-3.5 text-muted-foreground/40" }) }),
@@ -4263,9 +4460,6 @@ function responseMayContainToolTrace(log, format) {
4263
4460
  return false;
4264
4461
  }
4265
4462
  }
4266
- function shouldRenderConversationContent(standalone, expanded) {
4267
- return standalone || expanded;
4268
- }
4269
4463
  function isTurnCollapsible(entryCount, isComplete, isPending) {
4270
4464
  return entryCount > 1 && isComplete && !isPending;
4271
4465
  }
@@ -4273,8 +4467,10 @@ function buildTurnGroups(logs) {
4273
4467
  const groups = [];
4274
4468
  let entries = [];
4275
4469
  let turnIndex = 0;
4276
- for (const log of logs) {
4277
- entries.push({ log, stopReason: extractStopReason(log) });
4470
+ for (let index = 0; index < logs.length; index += 1) {
4471
+ const log = logs[index];
4472
+ if (log === void 0) continue;
4473
+ entries.push({ log, stopReason: extractStopReason(log), sessionLogNumber: index + 1 });
4278
4474
  const current = entries[entries.length - 1];
4279
4475
  if (current !== void 0 && isTurnBoundary(current.stopReason)) {
4280
4476
  groups.push({ entries, turnIndex });
@@ -4493,7 +4689,8 @@ const TurnGroup = reactExports.memo(function TurnGroup2({
4493
4689
  comparisonPredecessors,
4494
4690
  turnIndex = 0,
4495
4691
  timeDisplayFormat,
4496
- pendingFocusRequest
4692
+ pendingFocusRequest,
4693
+ showLogClientMetadata = true
4497
4694
  }) {
4498
4695
  const lastIdx = entries.length - 1;
4499
4696
  const lastStop = entries[lastIdx]?.stopReason ?? null;
@@ -4564,17 +4761,9 @@ const TurnGroup = reactExports.memo(function TurnGroup2({
4564
4761
  maxElapsed
4565
4762
  };
4566
4763
  }, [entries, lastIdx]);
4567
- const uniqueProviders = reactExports.useMemo(() => {
4568
- const seen = /* @__PURE__ */ new Set();
4569
- for (const e of entries) {
4570
- const p = detectProvider(e.log.model);
4571
- if (p !== "unknown") seen.add(p);
4572
- }
4573
- return [...seen];
4574
- }, [entries]);
4575
4764
  const StartCrab = reactExports.useMemo(() => getCrabVariant(entries[0]?.log.id ?? 0), [entries]);
4576
4765
  const EndCrab = reactExports.useMemo(() => getCrabVariant(entries[lastIdx]?.log.id ?? 0), [entries, lastIdx]);
4577
- const bgClass = turnIndex % 2 === 0 ? "bg-[#070a0f]" : "bg-[#090d12]";
4766
+ const bgClass = turnIndex % 2 === 0 ? "bg-white/[0.012]" : "bg-cyan-300/[0.012]";
4578
4767
  const aggregateIsSlow = aggregate.maxElapsed !== null && slowResponseThresholdSeconds > 0 && aggregate.maxElapsed > slowResponseThresholdSeconds * 1e3;
4579
4768
  const toolEventsByLogId = reactExports.useMemo(() => {
4580
4769
  const events = /* @__PURE__ */ new Map();
@@ -4619,7 +4808,7 @@ const TurnGroup = reactExports.memo(function TurnGroup2({
4619
4808
  "aria-label": collapsed ? void 0 : turnLabel,
4620
4809
  "data-nav-id": collapsed ? void 0 : `turn-${String(firstLogId)}`,
4621
4810
  className: cn(
4622
- "border rounded-lg transition-[border-color,box-shadow]",
4811
+ "rounded-[8px] border transition-[border-color,box-shadow]",
4623
4812
  isPending ? "border-amber-300/15 shadow-[0_0_0_1px_rgba(252,211,77,0.04)]" : "border-transparent",
4624
4813
  !collapsed && "focus-visible:ring-2 focus-visible:ring-ring focus-visible:ring-offset-1 focus-visible:outline-none"
4625
4814
  ),
@@ -4649,7 +4838,7 @@ const TurnGroup = reactExports.memo(function TurnGroup2({
4649
4838
  {
4650
4839
  role: "button",
4651
4840
  tabIndex: 0,
4652
- title: "Start of turn click to expand",
4841
+ title: "Start of turn - click to expand",
4653
4842
  className: "cursor-pointer",
4654
4843
  onClick: (e) => {
4655
4844
  e.stopPropagation();
@@ -4665,8 +4854,8 @@ const TurnGroup = reactExports.memo(function TurnGroup2({
4665
4854
  StartCrab,
4666
4855
  {
4667
4856
  className: cn(
4668
- "size-3.5 text-emerald-400",
4669
- "animate-crab-appear drop-shadow-[0_0_4px_rgba(52,211,153,0.5)]"
4857
+ "size-3.5 text-cyan-300/85",
4858
+ "animate-crab-appear drop-shadow-[0_0_4px_rgba(103,232,249,0.32)]"
4670
4859
  )
4671
4860
  }
4672
4861
  )
@@ -4678,7 +4867,7 @@ const TurnGroup = reactExports.memo(function TurnGroup2({
4678
4867
  {
4679
4868
  role: "button",
4680
4869
  tabIndex: 0,
4681
- title: "End of Turn click to expand",
4870
+ title: "End of Turn - click to expand",
4682
4871
  className: "cursor-pointer",
4683
4872
  onClick: (e) => {
4684
4873
  e.stopPropagation();
@@ -4707,21 +4896,31 @@ const TurnGroup = reactExports.memo(function TurnGroup2({
4707
4896
  {
4708
4897
  className: cn(
4709
4898
  "flex-1 min-w-0 mb-0.5 rounded-lg border border-cyan-300/10 py-1.5 px-3 flex items-center gap-3 text-xs shadow-[inset_0_1px_0_rgba(255,255,255,0.04)]",
4899
+ "border border-border bg-card shadow-sm",
4710
4900
  bgClass
4711
4901
  ),
4712
4902
  children: [
4713
- /* @__PURE__ */ jsxRuntimeExports.jsxs("span", { className: "text-blue-400/80 font-mono font-semibold tabular-nums shrink-0", children: [
4714
- "#",
4715
- entries[0]?.log.id ?? "?",
4716
- " ~ #",
4717
- entries[lastIdx]?.log.id ?? "?"
4718
- ] }),
4903
+ /* @__PURE__ */ jsxRuntimeExports.jsx("span", { className: ROW_CHEVRON_SLOT_CLASS, children: /* @__PURE__ */ jsxRuntimeExports.jsx(ChevronRight, { className: "size-4 shrink-0" }) }),
4904
+ /* @__PURE__ */ jsxRuntimeExports.jsxs(
4905
+ "span",
4906
+ {
4907
+ className: "text-blue-400/80 font-mono font-semibold tabular-nums shrink-0",
4908
+ title: `Log IDs ${String(entries[0]?.log.id ?? "?")} ~ ${String(
4909
+ entries[lastIdx]?.log.id ?? "?"
4910
+ )}`,
4911
+ children: [
4912
+ "#",
4913
+ entries[0]?.sessionLogNumber ?? "?",
4914
+ " ~ #",
4915
+ entries[lastIdx]?.sessionLogNumber ?? "?"
4916
+ ]
4917
+ }
4918
+ ),
4719
4919
  /* @__PURE__ */ jsxRuntimeExports.jsxs("span", { className: "text-muted-foreground shrink-0", children: [
4720
4920
  entries.length,
4721
4921
  " request",
4722
4922
  entries.length > 1 ? "s" : ""
4723
4923
  ] }),
4724
- uniqueProviders.length > 0 && /* @__PURE__ */ jsxRuntimeExports.jsx("span", { className: "flex items-center gap-0.5 shrink-0", children: uniqueProviders.map((p) => /* @__PURE__ */ jsxRuntimeExports.jsx(ProviderLogo, { provider: p, className: "size-4" }, p)) }),
4725
4924
  aggregate.maxElapsed !== null && /* @__PURE__ */ jsxRuntimeExports.jsx(TooltipProvider, { children: /* @__PURE__ */ jsxRuntimeExports.jsxs(Tooltip, { children: [
4726
4925
  /* @__PURE__ */ jsxRuntimeExports.jsx(TooltipTrigger, { asChild: true, children: /* @__PURE__ */ jsxRuntimeExports.jsxs(
4727
4926
  "span",
@@ -4755,8 +4954,7 @@ const TurnGroup = reactExports.memo(function TurnGroup2({
4755
4954
  ] })
4756
4955
  ] })
4757
4956
  ] }),
4758
- /* @__PURE__ */ jsxRuntimeExports.jsx("span", { className: "flex-1 min-w-0" }),
4759
- /* @__PURE__ */ jsxRuntimeExports.jsx(ChevronRight, { className: "size-4 text-muted-foreground shrink-0" })
4957
+ /* @__PURE__ */ jsxRuntimeExports.jsx("span", { className: "flex-1 min-w-0" })
4760
4958
  ]
4761
4959
  }
4762
4960
  )
@@ -4783,16 +4981,18 @@ const TurnGroup = reactExports.memo(function TurnGroup2({
4783
4981
  onToggle: toggleCollapse
4784
4982
  }
4785
4983
  ),
4786
- /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: cn("flex-1 min-w-0 mb-0.5 rounded-lg", bgClass), children: [
4984
+ /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: cn("flex-1 min-w-0 mb-0.5 rounded-[8px]", bgClass), children: [
4787
4985
  /* @__PURE__ */ jsxRuntimeExports.jsx(
4788
4986
  LogEntry,
4789
4987
  {
4790
4988
  log,
4989
+ displayNumber: entry.sessionLogNumber,
4791
4990
  viewMode,
4792
4991
  strip,
4793
4992
  slowResponseThresholdSeconds,
4794
4993
  timeDisplayFormat,
4795
4994
  cacheTrend: cacheTrends?.get(log.id) ?? null,
4995
+ showClientMetadata: showLogClientMetadata,
4796
4996
  onCompareWithPrevious: comparisonPredecessors.has(log.id) ? onCompareWithPrevious : void 0
4797
4997
  }
4798
4998
  ),
@@ -4806,7 +5006,7 @@ const TurnGroup = reactExports.memo(function TurnGroup2({
4806
5006
  });
4807
5007
  const VIRTUALIZE_TURN_THRESHOLD = 24;
4808
5008
  const ESTIMATED_TURN_HEIGHT = 132;
4809
- const VIRTUAL_OVERSCAN$1 = 8;
5009
+ const VIRTUAL_OVERSCAN = 8;
4810
5010
  function shouldVirtualizeTurnGroups(turnCount) {
4811
5011
  return turnCount > VIRTUALIZE_TURN_THRESHOLD;
4812
5012
  }
@@ -4834,7 +5034,8 @@ function renderTurnGroup(turnGroup, props, pendingFocusRequest) {
4834
5034
  onCompareWithPrevious: props.onCompareWithPrevious,
4835
5035
  comparisonPredecessors: props.comparisonPredecessors,
4836
5036
  turnIndex: turnGroup.turnIndex,
4837
- pendingFocusRequest
5037
+ pendingFocusRequest,
5038
+ showLogClientMetadata: props.showLogClientMetadata
4838
5039
  },
4839
5040
  turnGroup.turnIndex
4840
5041
  );
@@ -4853,7 +5054,7 @@ function VirtualizedTurnGroupList(props) {
4853
5054
  const virtualizer = useWindowVirtualizer({
4854
5055
  count: turnGroups.length,
4855
5056
  estimateSize: () => ESTIMATED_TURN_HEIGHT,
4856
- overscan: VIRTUAL_OVERSCAN$1,
5057
+ overscan: VIRTUAL_OVERSCAN,
4857
5058
  getItemKey: (index) => turnGroups[index]?.turnIndex ?? index
4858
5059
  });
4859
5060
  const turnIndexByLogId = reactExports.useMemo(() => buildLogTurnIndex(turnGroups), [turnGroups]);
@@ -4966,6 +5167,18 @@ function firstToolLog(logs) {
4966
5167
  }
4967
5168
  return null;
4968
5169
  }
5170
+ function buildDisplayNumberByLogId$1(logs) {
5171
+ const result = /* @__PURE__ */ new Map();
5172
+ for (let index = 0; index < logs.length; index += 1) {
5173
+ const log = logs[index];
5174
+ if (log === void 0) continue;
5175
+ result.set(log.id, index + 1);
5176
+ }
5177
+ return result;
5178
+ }
5179
+ function displayLogNumber(logId, displayNumberByLogId) {
5180
+ return String(displayNumberByLogId.get(logId) ?? logId);
5181
+ }
4969
5182
  function buildTraceInsights(input) {
4970
5183
  const insights = [
4971
5184
  {
@@ -4980,7 +5193,7 @@ function buildTraceInsights(input) {
4980
5193
  insights.push({
4981
5194
  kind: "tool",
4982
5195
  title: `${String(input.summary.toolCallCount)} tool call${input.summary.toolCallCount === 1 ? "" : "s"}`,
4983
- detail: `First tool evidence at #${String(toolLog.id)}`,
5196
+ detail: `First tool evidence at #${displayLogNumber(toolLog.id, input.displayNumberByLogId)}`,
4984
5197
  logId: toolLog.id
4985
5198
  });
4986
5199
  }
@@ -4989,7 +5202,7 @@ function buildTraceInsights(input) {
4989
5202
  insights.push({
4990
5203
  kind: "failure",
4991
5204
  title: `Failure #${String(failure.responseStatus)}`,
4992
- detail: `First failed request is #${String(failure.id)}`,
5205
+ detail: `First failed request is #${displayLogNumber(failure.id, input.displayNumberByLogId)}`,
4993
5206
  logId: failure.id
4994
5207
  });
4995
5208
  }
@@ -4998,7 +5211,7 @@ function buildTraceInsights(input) {
4998
5211
  insights.push({
4999
5212
  kind: "slow",
5000
5213
  title: `Slowest ${formatElapsed$1(input.summary.maxElapsedMs)}`,
5001
- detail: `Max latency observed at #${String(slowest.id)}`,
5214
+ detail: `Max latency observed at #${displayLogNumber(slowest.id, input.displayNumberByLogId)}`,
5002
5215
  logId: slowest.id
5003
5216
  });
5004
5217
  }
@@ -5086,12 +5299,13 @@ function previewText(value, maxLength) {
5086
5299
  if (normalized.length <= maxLength) return normalized;
5087
5300
  return `${normalized.slice(0, maxLength - 3)}...`;
5088
5301
  }
5089
- function logRangeLabel(logIds) {
5302
+ function logRangeLabel(logIds, displayNumberByLogId) {
5090
5303
  const first = logIds[0];
5091
5304
  const last = logIds[logIds.length - 1];
5092
5305
  if (first === void 0) return "No evidence logs";
5093
- if (last === void 0 || first === last) return `#${String(first)}`;
5094
- return `#${String(first)}-#${String(last)}`;
5306
+ const firstLabel = displayLogNumber(first, displayNumberByLogId);
5307
+ if (last === void 0 || first === last) return `#${firstLabel}`;
5308
+ return `#${firstLabel}-#${displayLogNumber(last, displayNumberByLogId)}`;
5095
5309
  }
5096
5310
  function tagsToText(tags) {
5097
5311
  return tags.join(", ");
@@ -5104,7 +5318,8 @@ function CandidateItem({
5104
5318
  isPromoting,
5105
5319
  isUpdating,
5106
5320
  onPromoteCandidate,
5107
- onUpdateCandidate
5321
+ onUpdateCandidate,
5322
+ displayNumberByLogId
5108
5323
  }) {
5109
5324
  const [editing, setEditing] = reactExports.useState(false);
5110
5325
  const [draftType, setDraftType] = reactExports.useState(candidate.type);
@@ -5147,7 +5362,7 @@ function CandidateItem({
5147
5362
  if (saved) setEditing(false);
5148
5363
  }, [candidate.id, draftContent, draftTags, draftTitle, draftType, onUpdateCandidate]);
5149
5364
  if (editing) {
5150
- return /* @__PURE__ */ jsxRuntimeExports.jsx("div", { className: "rounded-md border border-border/80 bg-background/60 px-2.5 py-2", children: /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "grid gap-2", children: [
5365
+ return /* @__PURE__ */ jsxRuntimeExports.jsx("div", { className: "border border-border bg-card shadow-sm rounded-[8px] px-2.5 py-2", children: /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "grid gap-2", children: [
5151
5366
  /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "flex flex-wrap items-center gap-2", children: [
5152
5367
  /* @__PURE__ */ jsxRuntimeExports.jsxs(
5153
5368
  "select",
@@ -5160,7 +5375,7 @@ function CandidateItem({
5160
5375
  );
5161
5376
  if (parsed.success) setDraftType(parsed.data);
5162
5377
  },
5163
- className: "h-7 rounded-md border border-input bg-background px-2 text-xs",
5378
+ className: "border border-input bg-background hover:bg-accent hover:text-accent-foreground h-7 rounded-md px-2 text-xs",
5164
5379
  "aria-label": "Candidate type",
5165
5380
  children: [
5166
5381
  /* @__PURE__ */ jsxRuntimeExports.jsx("option", { value: "episode", children: "episode" }),
@@ -5176,7 +5391,7 @@ function CandidateItem({
5176
5391
  value: draftTitle,
5177
5392
  disabled: isUpdating,
5178
5393
  onChange: (event) => setDraftTitle(event.currentTarget.value),
5179
- className: "h-7 min-w-[220px] flex-1 rounded-md border border-input bg-background px-2 text-xs",
5394
+ className: "border border-input bg-background hover:bg-accent hover:text-accent-foreground h-7 min-w-[220px] flex-1 rounded-md px-2 text-xs",
5180
5395
  "aria-label": "Candidate title"
5181
5396
  }
5182
5397
  )
@@ -5187,7 +5402,7 @@ function CandidateItem({
5187
5402
  value: draftContent,
5188
5403
  disabled: isUpdating,
5189
5404
  onChange: (event) => setDraftContent(event.currentTarget.value),
5190
- className: "min-h-28 rounded-md border border-input bg-background px-2 py-1.5 font-mono text-[11px] leading-relaxed",
5405
+ className: "border border-input bg-background hover:bg-accent hover:text-accent-foreground min-h-28 rounded-md px-2 py-1.5 font-mono text-[11px] leading-relaxed",
5191
5406
  "aria-label": "Candidate content"
5192
5407
  }
5193
5408
  ),
@@ -5197,7 +5412,7 @@ function CandidateItem({
5197
5412
  value: draftTags,
5198
5413
  disabled: isUpdating,
5199
5414
  onChange: (event) => setDraftTags(event.currentTarget.value),
5200
- className: "h-7 rounded-md border border-input bg-background px-2 text-xs",
5415
+ className: "border border-input bg-background hover:bg-accent hover:text-accent-foreground h-7 rounded-md px-2 text-xs",
5201
5416
  "aria-label": "Candidate tags"
5202
5417
  }
5203
5418
  ),
@@ -5273,7 +5488,7 @@ function CandidateItem({
5273
5488
  /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "mt-2 flex flex-wrap items-center gap-x-3 gap-y-1 text-[10px] text-muted-foreground", children: [
5274
5489
  /* @__PURE__ */ jsxRuntimeExports.jsxs("span", { className: "inline-flex items-center gap-1", children: [
5275
5490
  /* @__PURE__ */ jsxRuntimeExports.jsx(FileSearch, { className: "size-3" }),
5276
- logRangeLabel(candidate.logIds)
5491
+ logRangeLabel(candidate.logIds, displayNumberByLogId)
5277
5492
  ] }),
5278
5493
  /* @__PURE__ */ jsxRuntimeExports.jsxs("span", { className: "inline-flex items-center gap-1", children: [
5279
5494
  /* @__PURE__ */ jsxRuntimeExports.jsx(ShieldCheck, { className: "size-3" }),
@@ -5289,23 +5504,27 @@ function CandidateItem({
5289
5504
  ] })
5290
5505
  ] }),
5291
5506
  /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "mt-1 flex flex-wrap items-center gap-1.5", children: [
5292
- candidate.logIds.map((logId) => /* @__PURE__ */ jsxRuntimeExports.jsxs(
5293
- "a",
5294
- {
5295
- href: `#${getLogAnchor(logId)}`,
5296
- onClick: (event) => {
5297
- event.preventDefault();
5298
- jumpToLog(logId);
5507
+ candidate.logIds.map((logId) => {
5508
+ const displayNumber = displayLogNumber(logId, displayNumberByLogId);
5509
+ return /* @__PURE__ */ jsxRuntimeExports.jsxs(
5510
+ "a",
5511
+ {
5512
+ href: `#${getLogAnchor(logId)}`,
5513
+ onClick: (event) => {
5514
+ event.preventDefault();
5515
+ jumpToLog(logId);
5516
+ },
5517
+ className: "rounded border border-blue-400/25 px-1.5 py-0.5 font-mono text-[10px] text-blue-400 underline-offset-2 transition-colors hover:bg-blue-400/10 hover:text-blue-300 hover:underline focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring",
5518
+ "aria-label": `Jump to evidence log ${displayNumber}`,
5519
+ title: `Log ID ${String(logId)}`,
5520
+ children: [
5521
+ "#",
5522
+ displayNumber
5523
+ ]
5299
5524
  },
5300
- className: "rounded border border-blue-400/25 px-1.5 py-0.5 font-mono text-[10px] text-blue-400 underline-offset-2 transition-colors hover:bg-blue-400/10 hover:text-blue-300 hover:underline focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring",
5301
- "aria-label": `Jump to evidence log ${String(logId)}`,
5302
- children: [
5303
- "#",
5304
- logId
5305
- ]
5306
- },
5307
- logId
5308
- )),
5525
+ logId
5526
+ );
5527
+ }),
5309
5528
  /* @__PURE__ */ jsxRuntimeExports.jsx("span", { className: "flex-1" }),
5310
5529
  canEdit && /* @__PURE__ */ jsxRuntimeExports.jsxs(
5311
5530
  Button,
@@ -5345,7 +5564,8 @@ function CandidateList({
5345
5564
  promotingCandidateIds,
5346
5565
  updatingCandidateIds,
5347
5566
  onPromoteCandidate,
5348
- onUpdateCandidate
5567
+ onUpdateCandidate,
5568
+ displayNumberByLogId
5349
5569
  }) {
5350
5570
  if (candidates.length === 0) return null;
5351
5571
  return /* @__PURE__ */ jsxRuntimeExports.jsx("div", { className: "mt-2 grid gap-1.5", children: candidates.map((candidate) => /* @__PURE__ */ jsxRuntimeExports.jsx(
@@ -5355,7 +5575,8 @@ function CandidateList({
5355
5575
  isPromoting: promotingCandidateIds.has(candidate.id),
5356
5576
  isUpdating: updatingCandidateIds.has(candidate.id),
5357
5577
  onPromoteCandidate,
5358
- onUpdateCandidate
5578
+ onUpdateCandidate,
5579
+ displayNumberByLogId
5359
5580
  },
5360
5581
  candidate.id
5361
5582
  )) });
@@ -5384,9 +5605,10 @@ function AgentTraceSummary({
5384
5605
  () => buildTraceSummary(logs, slowResponseThresholdSeconds, candidates.length),
5385
5606
  [candidates.length, logs, slowResponseThresholdSeconds]
5386
5607
  );
5608
+ const displayNumberByLogId = reactExports.useMemo(() => buildDisplayNumberByLogId$1(logs), [logs]);
5387
5609
  const traceInsights = reactExports.useMemo(
5388
- () => buildTraceInsights({ logs, scopeId, summary, candidates }),
5389
- [candidates, logs, scopeId, summary]
5610
+ () => buildTraceInsights({ logs, scopeId, summary, candidates, displayNumberByLogId }),
5611
+ [candidates, displayNumberByLogId, logs, scopeId, summary]
5390
5612
  );
5391
5613
  const showElapsedSummary = showRollupMetrics || summary.maxElapsedMs !== null;
5392
5614
  const timeRange = reactExports.useMemo(
@@ -5524,7 +5746,7 @@ function AgentTraceSummary({
5524
5746
  []
5525
5747
  );
5526
5748
  if (logs.length === 0) return null;
5527
- return /* @__PURE__ */ jsxRuntimeExports.jsxs("section", { className: "mb-2 rounded-lg border border-border bg-muted/10 px-3 py-2", children: [
5749
+ return /* @__PURE__ */ jsxRuntimeExports.jsxs("section", { className: "border border-border bg-card shadow-sm mb-2 rounded-[8px] px-3 py-2", children: [
5528
5750
  /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "flex flex-wrap items-center gap-x-3 gap-y-2 text-xs", children: [
5529
5751
  showRollupMetrics && /* @__PURE__ */ jsxRuntimeExports.jsxs("span", { className: "inline-flex items-center gap-1.5 font-semibold text-foreground", children: [
5530
5752
  /* @__PURE__ */ jsxRuntimeExports.jsx(MessageSquare, { className: "size-3.5 text-blue-400" }),
@@ -5614,7 +5836,8 @@ function AgentTraceSummary({
5614
5836
  promotingCandidateIds,
5615
5837
  updatingCandidateIds,
5616
5838
  onPromoteCandidate: promoteCandidate,
5617
- onUpdateCandidate: updateCandidate
5839
+ onUpdateCandidate: updateCandidate,
5840
+ displayNumberByLogId
5618
5841
  }
5619
5842
  )
5620
5843
  ] });
@@ -5671,13 +5894,15 @@ const ConversationGroup = reactExports.memo(function({
5671
5894
  onCompareWithPrevious,
5672
5895
  comparisonPredecessors,
5673
5896
  onClearGroup,
5674
- standalone = false,
5675
- hasPinnedSessionContext = false,
5897
+ showClientIdentity = true,
5898
+ showProcessMetadata = true,
5899
+ showLogClientMetadata = true,
5900
+ defaultExpanded = false,
5676
5901
  timeDisplayFormat,
5677
5902
  expanded: controlledExpanded,
5678
5903
  onExpandedChange
5679
5904
  }) {
5680
- const [internalExpanded, setInternalExpanded] = reactExports.useState(false);
5905
+ const [internalExpanded, setInternalExpanded] = reactExports.useState(defaultExpanded);
5681
5906
  const expanded = controlledExpanded ?? internalExpanded;
5682
5907
  const setExpanded = reactExports.useCallback(
5683
5908
  (nextExpanded) => {
@@ -5689,18 +5914,20 @@ const ConversationGroup = reactExports.memo(function({
5689
5914
  },
5690
5915
  [onExpandedChange]
5691
5916
  );
5917
+ reactExports.useEffect(() => {
5918
+ if (!defaultExpanded || controlledExpanded !== void 0) return;
5919
+ setInternalExpanded(true);
5920
+ }, [controlledExpanded, defaultExpanded]);
5692
5921
  const stats = reactExports.useMemo(() => computeStats(group.logs), [group.logs]);
5693
5922
  const providers = reactExports.useMemo(() => collectProviders(group.logs), [group.logs]);
5694
5923
  const startTime = group.logs[0]?.timestamp ?? (/* @__PURE__ */ new Date()).toISOString();
5695
5924
  const endTime = group.logs[group.logs.length - 1]?.timestamp ?? (/* @__PURE__ */ new Date()).toISOString();
5696
5925
  const isLoading = group.logs.some((log) => log.responseStatus === null);
5697
- const showTraceRollupMetrics = standalone && !hasPinnedSessionContext;
5698
5926
  const clientPid = reactExports.useMemo(() => getFirstClientPid(group.logs), [group.logs]);
5699
5927
  const clientProjectFolder = reactExports.useMemo(() => getFirstClientProjectFolder(group.logs), [group.logs]);
5700
5928
  const turnGroups = reactExports.useMemo(() => buildTurnGroups(group.logs), [group.logs]);
5701
5929
  reactExports.useEffect(() => {
5702
5930
  const handleLogFocusRequest = (event) => {
5703
- if (standalone) return;
5704
5931
  const request = readLogFocusRequest(event);
5705
5932
  if (request === null) return;
5706
5933
  if (!group.logs.some((log) => log.id === request.logId)) return;
@@ -5710,9 +5937,9 @@ const ConversationGroup = reactExports.memo(function({
5710
5937
  return () => {
5711
5938
  window.removeEventListener(LOG_FOCUS_REQUEST_EVENT, handleLogFocusRequest);
5712
5939
  };
5713
- }, [group.logs, setExpanded, standalone]);
5940
+ }, [group.logs, setExpanded]);
5714
5941
  return /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "mb-2", children: [
5715
- !standalone && /* @__PURE__ */ jsxRuntimeExports.jsx(
5942
+ /* @__PURE__ */ jsxRuntimeExports.jsx(
5716
5943
  ConversationHeader,
5717
5944
  {
5718
5945
  conversationId: group.conversationId,
@@ -5728,18 +5955,20 @@ const ConversationGroup = reactExports.memo(function({
5728
5955
  userAgent: group.logs[0]?.userAgent ?? null,
5729
5956
  clientPid,
5730
5957
  clientProjectFolder,
5958
+ showClientIdentity,
5959
+ showProcessMetadata,
5731
5960
  timeDisplayFormat,
5732
5961
  onClear: () => onClearGroup(group.logs.map((l) => l.id))
5733
5962
  }
5734
5963
  ),
5735
- shouldRenderConversationContent(standalone, expanded) && /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { children: [
5964
+ expanded && /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { children: [
5736
5965
  /* @__PURE__ */ jsxRuntimeExports.jsx(
5737
5966
  AgentTraceSummary,
5738
5967
  {
5739
5968
  logs: group.logs,
5740
5969
  scopeId: group.conversationId,
5741
5970
  slowResponseThresholdSeconds,
5742
- showRollupMetrics: showTraceRollupMetrics,
5971
+ showRollupMetrics: false,
5743
5972
  timeDisplayFormat
5744
5973
  }
5745
5974
  ),
@@ -5753,7 +5982,8 @@ const ConversationGroup = reactExports.memo(function({
5753
5982
  timeDisplayFormat,
5754
5983
  cacheTrends,
5755
5984
  onCompareWithPrevious,
5756
- comparisonPredecessors
5985
+ comparisonPredecessors,
5986
+ showLogClientMetadata
5757
5987
  }
5758
5988
  )
5759
5989
  ] })
@@ -5958,6 +6188,7 @@ function useAlertSummary() {
5958
6188
  mutate: response.mutate
5959
6189
  };
5960
6190
  }
6191
+ const INSPECTOR_ICON_TRIGGER_CLASS = "relative size-8 rounded-md border border-input bg-background text-muted-foreground transition-colors hover:bg-accent hover:text-accent-foreground focus-visible:ring-ring/50";
5961
6192
  const ALERT_CATEGORIES = [
5962
6193
  "request-failure",
5963
6194
  "request-timeout",
@@ -6318,7 +6549,7 @@ function AlertsDialog() {
6318
6549
  type: "button",
6319
6550
  variant: "ghost",
6320
6551
  size: "icon",
6321
- className: "relative size-8",
6552
+ className: INSPECTOR_ICON_TRIGGER_CLASS,
6322
6553
  "aria-label": "Alerts",
6323
6554
  title: "Alerts",
6324
6555
  children: [
@@ -6614,6 +6845,12 @@ function firstNonEmpty(...values) {
6614
6845
  }
6615
6846
  return "-";
6616
6847
  }
6848
+ function firstOptionalText(...values) {
6849
+ for (const value of values) {
6850
+ if (value !== null && value !== void 0 && value.trim().length > 0) return value;
6851
+ }
6852
+ return null;
6853
+ }
6617
6854
  function providerModel(member) {
6618
6855
  const provider = member.provider;
6619
6856
  const model = member.model;
@@ -6776,7 +7013,7 @@ function GroupsDialog() {
6776
7013
  type: "button",
6777
7014
  variant: "ghost",
6778
7015
  size: "icon",
6779
- className: "relative size-8",
7016
+ className: INSPECTOR_ICON_TRIGGER_CLASS,
6780
7017
  "aria-label": "Evaluation groups",
6781
7018
  title: "Evaluation groups",
6782
7019
  children: [
@@ -7215,6 +7452,14 @@ function MemberRow({
7215
7452
  const tokens = session?.tokenUsage.total ?? null;
7216
7453
  const firstChunkMs = log?.firstChunkMs ?? null;
7217
7454
  const sessionLabel = firstNonEmpty(member.label, member.sessionId);
7455
+ const clientUserAgent = firstOptionalText(session?.clientUserAgent, log?.userAgent, member.agent);
7456
+ const clientProjectFolder = session?.clientProjectFolder ?? null;
7457
+ const clientApp = detectClientApp({
7458
+ userAgent: clientUserAgent,
7459
+ conversationId: member.sessionId,
7460
+ clientProjectFolder
7461
+ });
7462
+ const clientLabel2 = clientAppLabel(clientApp);
7218
7463
  return /* @__PURE__ */ jsxRuntimeExports.jsxs("tr", { className: "border-b border-border last:border-0 hover:bg-muted/20", children: [
7219
7464
  /* @__PURE__ */ jsxRuntimeExports.jsxs("td", { className: "max-w-56 px-3 py-2", children: [
7220
7465
  /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "flex min-w-0 items-center gap-1.5", children: [
@@ -7233,6 +7478,7 @@ function MemberRow({
7233
7478
  children: isExpanded ? /* @__PURE__ */ jsxRuntimeExports.jsx(ChevronDown, { className: "size-3.5" }) : /* @__PURE__ */ jsxRuntimeExports.jsx(ChevronRight, { className: "size-3.5" })
7234
7479
  }
7235
7480
  ),
7481
+ clientLabel2 !== null && /* @__PURE__ */ jsxRuntimeExports.jsx(ClientLogo, { client: clientApp, className: "size-5" }),
7236
7482
  canOpenLiveSession ? /* @__PURE__ */ jsxRuntimeExports.jsxs(
7237
7483
  "a",
7238
7484
  {
@@ -7380,28 +7626,31 @@ function LatestLogsPreview({ logs }) {
7380
7626
  }
7381
7627
  return /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "overflow-hidden rounded-md border border-border", children: [
7382
7628
  /* @__PURE__ */ jsxRuntimeExports.jsx("div", { className: "border-b border-border bg-muted/30 px-3 py-2 text-[11px] font-semibold uppercase tracking-wide text-muted-foreground", children: "Latest logs" }),
7383
- /* @__PURE__ */ jsxRuntimeExports.jsx("div", { className: "divide-y divide-border", children: visibleLogs.map((log) => /* @__PURE__ */ jsxRuntimeExports.jsxs(
7384
- "div",
7385
- {
7386
- className: "grid gap-2 px-3 py-2 text-xs sm:grid-cols-[72px_1fr_88px_88px]",
7387
- children: [
7388
- /* @__PURE__ */ jsxRuntimeExports.jsxs("span", { className: "font-mono text-muted-foreground", children: [
7389
- "#",
7390
- log.id
7391
- ] }),
7392
- /* @__PURE__ */ jsxRuntimeExports.jsxs("span", { className: "min-w-0 truncate", children: [
7393
- displayText(log.model),
7394
- " · ",
7395
- log.apiFormat,
7396
- " · ",
7397
- log.path
7398
- ] }),
7399
- /* @__PURE__ */ jsxRuntimeExports.jsx("span", { className: "font-mono text-muted-foreground", children: formatMs(log.firstChunkMs) }),
7400
- /* @__PURE__ */ jsxRuntimeExports.jsx("span", { className: "font-mono text-muted-foreground", children: formatMs(log.latencyMs) })
7401
- ]
7402
- },
7403
- log.id
7404
- )) })
7629
+ /* @__PURE__ */ jsxRuntimeExports.jsx("div", { className: "divide-y divide-border", children: visibleLogs.map((log) => {
7630
+ const displayNumber = log.sessionLogNumber ?? log.id;
7631
+ return /* @__PURE__ */ jsxRuntimeExports.jsxs(
7632
+ "div",
7633
+ {
7634
+ className: "grid gap-2 px-3 py-2 text-xs sm:grid-cols-[72px_1fr_88px_88px]",
7635
+ children: [
7636
+ /* @__PURE__ */ jsxRuntimeExports.jsxs("span", { className: "font-mono text-muted-foreground", title: `Log ID ${String(log.id)}`, children: [
7637
+ "#",
7638
+ displayNumber
7639
+ ] }),
7640
+ /* @__PURE__ */ jsxRuntimeExports.jsxs("span", { className: "min-w-0 truncate", children: [
7641
+ displayText(log.model),
7642
+ " · ",
7643
+ log.apiFormat,
7644
+ " · ",
7645
+ log.path
7646
+ ] }),
7647
+ /* @__PURE__ */ jsxRuntimeExports.jsx("span", { className: "font-mono text-muted-foreground", children: formatMs(log.firstChunkMs) }),
7648
+ /* @__PURE__ */ jsxRuntimeExports.jsx("span", { className: "font-mono text-muted-foreground", children: formatMs(log.latencyMs) })
7649
+ ]
7650
+ },
7651
+ log.id
7652
+ );
7653
+ }) })
7405
7654
  ] });
7406
7655
  }
7407
7656
  function MemberMetadata({ entries }) {
@@ -7987,7 +8236,7 @@ function ProviderCard({
7987
8236
  return /* @__PURE__ */ jsxRuntimeExports.jsxs(
7988
8237
  "div",
7989
8238
  {
7990
- className: `border rounded-lg p-4 flex flex-col gap-3 bg-card transition-all duration-500 ${isHighlighted === true ? "ring-2 ring-primary shadow-md" : ""}`,
8239
+ className: `border border-border bg-card shadow-sm flex flex-col gap-3 rounded-[8px] p-4 transition-all duration-500 ${isHighlighted === true ? "ring-2 ring-primary shadow-md" : ""}`,
7991
8240
  children: [
7992
8241
  /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "flex items-start justify-between gap-2", children: [
7993
8242
  /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "flex items-center gap-2 min-w-0", children: [
@@ -8287,7 +8536,7 @@ const MINIMAX_MODELS = [
8287
8536
  "MiniMax M2.1-highspeed",
8288
8537
  "MiniMax M2"
8289
8538
  ];
8290
- const ALIBABA_MODELS = ["glm-5", "glm-5.1", "glm-5.2", "qwen3.6-plus", "qwen3.7-max"];
8539
+ const ALIBABA_MODELS = ["qwen3.6-plus", "qwen3.7-max"];
8291
8540
  const ZHIPU_MODELS = [
8292
8541
  "glm-5.2",
8293
8542
  "glm-5.1",
@@ -8411,7 +8660,7 @@ function EndpointUrlPreview({
8411
8660
  }) {
8412
8661
  const finalUrl = previewEndpointUrl(baseUrl, endpoint);
8413
8662
  if (finalUrl === null) return null;
8414
- return /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "rounded-md border border-border/70 bg-muted/35 px-3 py-2 text-xs", children: [
8663
+ return /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "border border-border bg-muted/40 rounded-md px-3 py-2 text-xs", children: [
8415
8664
  /* @__PURE__ */ jsxRuntimeExports.jsx("div", { className: "text-muted-foreground", children: "Final URL" }),
8416
8665
  /* @__PURE__ */ jsxRuntimeExports.jsx("div", { className: "break-all font-mono text-foreground", children: finalUrl })
8417
8666
  ] });
@@ -8724,7 +8973,7 @@ function ProviderForm({ provider, onSubmit, onCancel }) {
8724
8973
  ),
8725
8974
  className: "w-full rounded-md border border-input bg-background px-3 py-2 text-sm ring-offset-background focus-visible:border-ring focus-visible:outline-ring focus-visible:ring-[3px] disabled:cursor-not-allowed disabled:opacity-50",
8726
8975
  children: [
8727
- /* @__PURE__ */ jsxRuntimeExports.jsx("option", { value: "", children: "" }),
8976
+ /* @__PURE__ */ jsxRuntimeExports.jsx("option", { value: "", children: "Unspecified" }),
8728
8977
  /* @__PURE__ */ jsxRuntimeExports.jsx("option", { value: "personal", children: "个人 (Personal)" }),
8729
8978
  /* @__PURE__ */ jsxRuntimeExports.jsx("option", { value: "company", children: "公司 (Company)" })
8730
8979
  ]
@@ -8746,7 +8995,7 @@ function ProviderForm({ provider, onSubmit, onCancel }) {
8746
8995
  }
8747
8996
  ),
8748
8997
  errors.modelMetadataUrl !== void 0 && /* @__PURE__ */ jsxRuntimeExports.jsx("p", { className: "text-xs text-destructive", children: errors.modelMetadataUrl }),
8749
- modelMetadataUrl.trim() === "" && /* @__PURE__ */ jsxRuntimeExports.jsx("div", { className: "rounded-md border border-border bg-muted/20 px-3 py-2 text-xs text-muted-foreground", children: "Built-in limits cover DeepSeek v4 pro/flash, MiniMax M3/M2.7/M2.5/M2.1, and GLM coding models. Use a registry URL for private or custom model limits." }),
8998
+ modelMetadataUrl.trim() === "" && /* @__PURE__ */ jsxRuntimeExports.jsx("div", { className: "border border-border bg-muted/40 rounded-md px-3 py-2 text-xs text-muted-foreground", children: "Built-in limits cover DeepSeek v4 pro/flash, MiniMax M3/M2.7/M2.5/M2.1, and GLM coding models. Use a registry URL for private or custom model limits." }),
8750
8999
  provider !== void 0 && !hasContextMetadata && modelMetadataUrl.trim() === "" && /* @__PURE__ */ jsxRuntimeExports.jsx("p", { className: "text-xs text-amber-400", children: "This provider has no matching context metadata yet." }),
8751
9000
  modelMetadataUrl.trim() !== "" && /* @__PURE__ */ jsxRuntimeExports.jsx("p", { className: "text-xs text-muted-foreground", children: "Agent Inspector will refresh model limits from this JSON registry after save." })
8752
9001
  ] }),
@@ -8811,7 +9060,7 @@ function ProviderForm({ provider, onSubmit, onCancel }) {
8811
9060
  ref: (el) => {
8812
9061
  modelRowRefs.current[i] = el;
8813
9062
  },
8814
- className: "space-y-2 rounded-md border border-border bg-muted/10 p-2",
9063
+ className: "border border-border bg-card shadow-sm space-y-2 rounded-[8px] p-2",
8815
9064
  children: [
8816
9065
  /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "flex items-center gap-2", children: [
8817
9066
  /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "relative flex-1", children: [
@@ -8836,7 +9085,7 @@ function ProviderForm({ provider, onSubmit, onCancel }) {
8836
9085
  children: /* @__PURE__ */ jsxRuntimeExports.jsx(ChevronDown, { className: "size-4" })
8837
9086
  }
8838
9087
  ),
8839
- openModelDropdown === i && /* @__PURE__ */ jsxRuntimeExports.jsx("div", { className: "absolute left-0 right-0 top-full mt-1 z-50 bg-popover border border-border rounded-md shadow-md max-h-48 overflow-y-auto", children: suggestedModels.map((opt) => /* @__PURE__ */ jsxRuntimeExports.jsx(
9088
+ openModelDropdown === i && /* @__PURE__ */ jsxRuntimeExports.jsx("div", { className: "bg-popover text-popover-foreground absolute left-0 right-0 top-full z-50 mt-1 max-h-48 overflow-y-auto rounded-md border shadow-md", children: suggestedModels.map((opt) => /* @__PURE__ */ jsxRuntimeExports.jsx(
8840
9089
  "button",
8841
9090
  {
8842
9091
  type: "button",
@@ -8844,7 +9093,7 @@ function ProviderForm({ provider, onSubmit, onCancel }) {
8844
9093
  updateModel(i, opt);
8845
9094
  setOpenModelDropdown(null);
8846
9095
  },
8847
- className: "w-full text-left px-3 py-2 text-sm hover:bg-muted transition-colors",
9096
+ className: "w-full px-3 py-2 text-left text-sm transition-colors hover:bg-white/[0.06]",
8848
9097
  children: opt
8849
9098
  },
8850
9099
  opt
@@ -8966,7 +9215,7 @@ function ProviderForm({ provider, onSubmit, onCancel }) {
8966
9215
  errors.models !== void 0 && /* @__PURE__ */ jsxRuntimeExports.jsx("p", { className: "text-xs text-destructive", children: errors.models })
8967
9216
  ] }),
8968
9217
  /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "space-y-2", children: [
8969
- /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "flex gap-1 border-b border-border", children: [
9218
+ /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "border border-border bg-muted/40 flex gap-1 rounded-[8px] p-1", children: [
8970
9219
  /* @__PURE__ */ jsxRuntimeExports.jsx(TooltipProvider, { children: /* @__PURE__ */ jsxRuntimeExports.jsxs(Tooltip, { children: [
8971
9220
  /* @__PURE__ */ jsxRuntimeExports.jsx(TooltipTrigger, { asChild: true, children: /* @__PURE__ */ jsxRuntimeExports.jsx(
8972
9221
  "button",
@@ -8996,7 +9245,7 @@ function ProviderForm({ provider, onSubmit, onCancel }) {
8996
9245
  ] }),
8997
9246
  activeTab === "anthropic" && /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "space-y-2", children: [
8998
9247
  /* @__PURE__ */ jsxRuntimeExports.jsx("label", { htmlFor: "provider-anthropic-base-url", className: "text-sm font-medium", children: "Anthropic Base URL" }),
8999
- /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "flex min-w-0 overflow-hidden rounded-md border border-input bg-background ring-offset-background focus-within:border-ring focus-within:outline-ring focus-within:ring-[3px]", children: [
9248
+ /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "border border-input bg-background hover:bg-accent hover:text-accent-foreground flex min-w-0 overflow-hidden rounded-md focus-within:border-ring focus-within:outline-ring focus-within:ring-[3px]", children: [
9000
9249
  /* @__PURE__ */ jsxRuntimeExports.jsx(
9001
9250
  "input",
9002
9251
  {
@@ -9008,10 +9257,10 @@ function ProviderForm({ provider, onSubmit, onCancel }) {
9008
9257
  setAnthropicBaseUrl(e.target.value);
9009
9258
  },
9010
9259
  placeholder: "https://api.anthropic.com",
9011
- className: "min-w-0 flex-1 bg-background px-3 py-2 text-sm placeholder:text-muted-foreground focus-visible:outline-none disabled:cursor-not-allowed disabled:opacity-50"
9260
+ className: "min-w-0 flex-1 bg-transparent px-3 py-2 text-sm placeholder:text-muted-foreground focus-visible:outline-none disabled:cursor-not-allowed disabled:opacity-50"
9012
9261
  }
9013
9262
  ),
9014
- /* @__PURE__ */ jsxRuntimeExports.jsx("span", { className: "shrink-0 select-none border-l bg-muted px-3 py-2 font-mono text-xs text-muted-foreground", children: ANTHROPIC_MESSAGES_ENDPOINT })
9263
+ /* @__PURE__ */ jsxRuntimeExports.jsx("span", { className: "shrink-0 select-none border-l border-white/10 bg-white/[0.04] px-3 py-2 font-mono text-xs text-muted-foreground", children: ANTHROPIC_MESSAGES_ENDPOINT })
9015
9264
  ] }),
9016
9265
  errors.anthropicBaseUrl !== void 0 && /* @__PURE__ */ jsxRuntimeExports.jsx("p", { className: "text-xs text-destructive", children: errors.anthropicBaseUrl }),
9017
9266
  /* @__PURE__ */ jsxRuntimeExports.jsx(EndpointUrlPreview, { baseUrl: anthropicBaseUrl, endpoint: ANTHROPIC_MESSAGES_ENDPOINT }),
@@ -9020,7 +9269,7 @@ function ProviderForm({ provider, onSubmit, onCancel }) {
9020
9269
  activeTab === "openai" && /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "space-y-4", children: [
9021
9270
  /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "space-y-2", children: [
9022
9271
  /* @__PURE__ */ jsxRuntimeExports.jsx("label", { htmlFor: "provider-openai-base-url", className: "text-sm font-medium", children: "OpenAI Chat Base URL" }),
9023
- /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "flex min-w-0 overflow-hidden rounded-md border border-input bg-background ring-offset-background focus-within:border-ring focus-within:outline-ring focus-within:ring-[3px]", children: [
9272
+ /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "border border-input bg-background hover:bg-accent hover:text-accent-foreground flex min-w-0 overflow-hidden rounded-md focus-within:border-ring focus-within:outline-ring focus-within:ring-[3px]", children: [
9024
9273
  /* @__PURE__ */ jsxRuntimeExports.jsx(
9025
9274
  "input",
9026
9275
  {
@@ -9032,10 +9281,10 @@ function ProviderForm({ provider, onSubmit, onCancel }) {
9032
9281
  setOpenaiBaseUrl(e.target.value);
9033
9282
  },
9034
9283
  placeholder: "https://api.openai.com",
9035
- className: "min-w-0 flex-1 bg-background px-3 py-2 text-sm placeholder:text-muted-foreground focus-visible:outline-none disabled:cursor-not-allowed disabled:opacity-50"
9284
+ className: "min-w-0 flex-1 bg-transparent px-3 py-2 text-sm placeholder:text-muted-foreground focus-visible:outline-none disabled:cursor-not-allowed disabled:opacity-50"
9036
9285
  }
9037
9286
  ),
9038
- /* @__PURE__ */ jsxRuntimeExports.jsx("span", { className: "shrink-0 select-none border-l bg-muted px-3 py-2 font-mono text-xs text-muted-foreground", children: OPENAI_CHAT_COMPLETIONS_ENDPOINT })
9287
+ /* @__PURE__ */ jsxRuntimeExports.jsx("span", { className: "shrink-0 select-none border-l border-white/10 bg-white/[0.04] px-3 py-2 font-mono text-xs text-muted-foreground", children: OPENAI_CHAT_COMPLETIONS_ENDPOINT })
9039
9288
  ] }),
9040
9289
  errors.openaiBaseUrl !== void 0 && /* @__PURE__ */ jsxRuntimeExports.jsx("p", { className: "text-xs text-destructive", children: errors.openaiBaseUrl }),
9041
9290
  /* @__PURE__ */ jsxRuntimeExports.jsx(
@@ -9049,7 +9298,7 @@ function ProviderForm({ provider, onSubmit, onCancel }) {
9049
9298
  ] }),
9050
9299
  /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "space-y-2", children: [
9051
9300
  /* @__PURE__ */ jsxRuntimeExports.jsx("label", { htmlFor: "provider-openai-responses-base-url", className: "text-sm font-medium", children: "OpenAI Responses Base URL" }),
9052
- /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "flex min-w-0 overflow-hidden rounded-md border border-input bg-background ring-offset-background focus-within:border-ring focus-within:outline-ring focus-within:ring-[3px]", children: [
9301
+ /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "border border-input bg-background hover:bg-accent hover:text-accent-foreground flex min-w-0 overflow-hidden rounded-md focus-within:border-ring focus-within:outline-ring focus-within:ring-[3px]", children: [
9053
9302
  /* @__PURE__ */ jsxRuntimeExports.jsx(
9054
9303
  "input",
9055
9304
  {
@@ -9061,10 +9310,10 @@ function ProviderForm({ provider, onSubmit, onCancel }) {
9061
9310
  setOpenaiResponsesBaseUrl(e.target.value);
9062
9311
  },
9063
9312
  placeholder: "https://api.openai.com",
9064
- className: "min-w-0 flex-1 bg-background px-3 py-2 text-sm placeholder:text-muted-foreground focus-visible:outline-none disabled:cursor-not-allowed disabled:opacity-50"
9313
+ className: "min-w-0 flex-1 bg-transparent px-3 py-2 text-sm placeholder:text-muted-foreground focus-visible:outline-none disabled:cursor-not-allowed disabled:opacity-50"
9065
9314
  }
9066
9315
  ),
9067
- /* @__PURE__ */ jsxRuntimeExports.jsx("span", { className: "shrink-0 select-none border-l bg-muted px-3 py-2 font-mono text-xs text-muted-foreground", children: OPENAI_RESPONSES_ENDPOINT })
9316
+ /* @__PURE__ */ jsxRuntimeExports.jsx("span", { className: "shrink-0 select-none border-l border-white/10 bg-white/[0.04] px-3 py-2 font-mono text-xs text-muted-foreground", children: OPENAI_RESPONSES_ENDPOINT })
9068
9317
  ] }),
9069
9318
  errors.openaiResponsesBaseUrl !== void 0 && /* @__PURE__ */ jsxRuntimeExports.jsx("p", { className: "text-xs text-destructive", children: errors.openaiResponsesBaseUrl }),
9070
9319
  /* @__PURE__ */ jsxRuntimeExports.jsx(
@@ -9092,7 +9341,7 @@ function ProviderForm({ provider, onSubmit, onCancel }) {
9092
9341
  ),
9093
9342
  /* @__PURE__ */ jsxRuntimeExports.jsx("p", { className: "text-xs text-muted-foreground", children: "Optional API documentation URL. If not set, uses known provider docs." })
9094
9343
  ] }),
9095
- /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "sticky bottom-0 bg-card border-t flex gap-2 justify-end pt-2 pb-2", children: [
9344
+ /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "border border-border bg-background/95 shadow-sm sticky bottom-0 flex justify-end gap-2 rounded-[8px] px-3 py-2", children: [
9096
9345
  /* @__PURE__ */ jsxRuntimeExports.jsx(Button, { type: "button", variant: "outline", onClick: onCancel, disabled: isSubmitting, children: "Cancel" }),
9097
9346
  /* @__PURE__ */ jsxRuntimeExports.jsx(Button, { type: "submit", disabled: isSubmitting, children: isSubmitting ? "Saving..." : provider ? "Update Provider" : "Add Provider" })
9098
9347
  ] })
@@ -9503,7 +9752,7 @@ function ProvidersPanel({
9503
9752
  }
9504
9753
  if (showForm || editingProvider) {
9505
9754
  return /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "space-y-4", children: [
9506
- /* @__PURE__ */ jsxRuntimeExports.jsx("div", { className: "flex items-center justify-between sticky top-0 bg-background z-10 pb-2", children: /* @__PURE__ */ jsxRuntimeExports.jsx("h3", { className: "text-lg font-medium", children: editingProvider ? "Edit Provider" : "Add New Provider" }) }),
9755
+ /* @__PURE__ */ jsxRuntimeExports.jsx("div", { className: "border border-border bg-background/95 shadow-sm sticky top-0 z-10 flex items-center justify-between rounded-[8px] px-3 py-2", children: /* @__PURE__ */ jsxRuntimeExports.jsx("h3", { className: "text-lg font-medium", children: editingProvider ? "Edit Provider" : "Add New Provider" }) }),
9507
9756
  /* @__PURE__ */ jsxRuntimeExports.jsx(
9508
9757
  ProviderForm,
9509
9758
  {
@@ -9518,7 +9767,7 @@ function ProvidersPanel({
9518
9767
  ] });
9519
9768
  }
9520
9769
  return /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "space-y-4", children: [
9521
- /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "flex items-center justify-between sticky top-0 z-10 bg-background pb-2", children: [
9770
+ /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "border border-border bg-background/95 shadow-sm sticky top-0 z-10 flex items-center justify-between rounded-[8px] px-3 py-2", children: [
9522
9771
  /* @__PURE__ */ jsxRuntimeExports.jsx("h3", { className: "text-lg font-medium", children: "Providers" }),
9523
9772
  /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "flex items-center gap-2", children: [
9524
9773
  /* @__PURE__ */ jsxRuntimeExports.jsx(TooltipProvider, { children: /* @__PURE__ */ jsxRuntimeExports.jsxs(Tooltip, { children: [
@@ -9585,7 +9834,7 @@ function ProvidersPanel({
9585
9834
  ] })
9586
9835
  ] })
9587
9836
  ] }),
9588
- configPath !== null && /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "flex items-center gap-2 text-xs text-muted-foreground bg-muted/30 rounded-md px-3 py-2", children: [
9837
+ configPath !== null && /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "border border-border bg-card shadow-sm flex items-center gap-2 rounded-[8px] px-3 py-2 text-xs text-muted-foreground", children: [
9589
9838
  /* @__PURE__ */ jsxRuntimeExports.jsx("span", { className: "shrink-0", children: "Config:" }),
9590
9839
  /* @__PURE__ */ jsxRuntimeExports.jsx("span", { className: "font-mono truncate", title: configPath, children: configPath }),
9591
9840
  /* @__PURE__ */ jsxRuntimeExports.jsx(TooltipProvider, { children: /* @__PURE__ */ jsxRuntimeExports.jsxs(Tooltip, { children: [
@@ -9608,18 +9857,18 @@ function ProvidersPanel({
9608
9857
  /* @__PURE__ */ jsxRuntimeExports.jsx(TooltipContent, { children: "Copy config file path to clipboard" })
9609
9858
  ] }) })
9610
9859
  ] }),
9611
- error !== null && /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "flex items-center gap-2 text-sm text-destructive bg-destructive/10 rounded-md px-3 py-2", children: [
9860
+ error !== null && /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "border border-border bg-card shadow-sm flex items-center gap-2 rounded-[8px] px-3 py-2 text-sm text-destructive", children: [
9612
9861
  /* @__PURE__ */ jsxRuntimeExports.jsx(CircleAlert, { className: "size-4 shrink-0" }),
9613
9862
  error
9614
9863
  ] }),
9615
- providers.length === 0 ? /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "text-center py-12 space-y-3", children: [
9864
+ providers.length === 0 ? /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "border border-border bg-card shadow-sm space-y-3 rounded-[8px] py-12 text-center", children: [
9616
9865
  /* @__PURE__ */ jsxRuntimeExports.jsx("p", { className: "text-sm text-muted-foreground", children: "No providers configured yet." }),
9617
9866
  /* @__PURE__ */ jsxRuntimeExports.jsxs(Button, { onClick: () => setShowForm(true), variant: "outline", size: "sm", children: [
9618
9867
  /* @__PURE__ */ jsxRuntimeExports.jsx(Plus, { className: "size-4" }),
9619
9868
  "Add Your First Provider"
9620
9869
  ] })
9621
9870
  ] }) : /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "space-y-3", children: [
9622
- /* @__PURE__ */ jsxRuntimeExports.jsx("div", { className: "flex gap-1 border-b border-border", children: ["all", "personal", "company"].map((tab) => /* @__PURE__ */ jsxRuntimeExports.jsx(TooltipProvider, { children: /* @__PURE__ */ jsxRuntimeExports.jsxs(Tooltip, { children: [
9871
+ /* @__PURE__ */ jsxRuntimeExports.jsx("div", { className: "border border-border bg-muted/40 flex gap-1 rounded-[8px] p-1", children: ["all", "personal", "company"].map((tab) => /* @__PURE__ */ jsxRuntimeExports.jsx(TooltipProvider, { children: /* @__PURE__ */ jsxRuntimeExports.jsxs(Tooltip, { children: [
9623
9872
  /* @__PURE__ */ jsxRuntimeExports.jsx(TooltipTrigger, { asChild: true, children: /* @__PURE__ */ jsxRuntimeExports.jsx(
9624
9873
  "button",
9625
9874
  {
@@ -9716,10 +9965,20 @@ function SettingsDialog() {
9716
9965
  []
9717
9966
  );
9718
9967
  return /* @__PURE__ */ jsxRuntimeExports.jsxs(Dialog, { open, onOpenChange: setOpen, children: [
9719
- /* @__PURE__ */ jsxRuntimeExports.jsx(DialogTrigger, { asChild: true, children: /* @__PURE__ */ jsxRuntimeExports.jsxs(Button, { variant: "ghost", size: "icon", className: "size-8", children: [
9720
- /* @__PURE__ */ jsxRuntimeExports.jsx(Settings, { className: "size-4" }),
9721
- /* @__PURE__ */ jsxRuntimeExports.jsx("span", { className: "sr-only", children: "Settings" })
9722
- ] }) }),
9968
+ /* @__PURE__ */ jsxRuntimeExports.jsx(DialogTrigger, { asChild: true, children: /* @__PURE__ */ jsxRuntimeExports.jsxs(
9969
+ Button,
9970
+ {
9971
+ variant: "ghost",
9972
+ size: "icon",
9973
+ className: INSPECTOR_ICON_TRIGGER_CLASS,
9974
+ "aria-label": "Settings",
9975
+ title: "Settings",
9976
+ children: [
9977
+ /* @__PURE__ */ jsxRuntimeExports.jsx(Settings, { className: "size-4" }),
9978
+ /* @__PURE__ */ jsxRuntimeExports.jsx("span", { className: "sr-only", children: "Settings" })
9979
+ ]
9980
+ }
9981
+ ) }),
9723
9982
  /* @__PURE__ */ jsxRuntimeExports.jsxs(DialogContent, { className: "max-w-2xl max-h-[80vh] overflow-hidden flex flex-col", children: [
9724
9983
  /* @__PURE__ */ jsxRuntimeExports.jsx(DialogHeader, { children: /* @__PURE__ */ jsxRuntimeExports.jsx(DialogTitle, { children: "Settings" }) }),
9725
9984
  /* @__PURE__ */ jsxRuntimeExports.jsxs(Tabs, { value: activeTab, onValueChange: setActiveTab, className: "flex-1 overflow-hidden", children: [
@@ -9850,14 +10109,14 @@ function StorageSettingsTab() {
9850
10109
  onCopy: handleCopy
9851
10110
  }
9852
10111
  ),
9853
- /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "rounded-md border border-border bg-muted/20 px-3 py-2", children: [
10112
+ /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "border border-border bg-muted/40 rounded-md px-3 py-2", children: [
9854
10113
  /* @__PURE__ */ jsxRuntimeExports.jsx("div", { className: "font-medium", children: "In-memory logs" }),
9855
10114
  /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "mt-1 font-mono text-muted-foreground", children: [
9856
10115
  stats.memoryCount.toLocaleString(),
9857
10116
  " loaded"
9858
10117
  ] })
9859
10118
  ] }),
9860
- /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "rounded-md border border-border bg-muted/20 px-3 py-2", children: [
10119
+ /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "border border-border bg-muted/40 rounded-md px-3 py-2", children: [
9861
10120
  /* @__PURE__ */ jsxRuntimeExports.jsx("div", { className: "font-medium", children: "Log files" }),
9862
10121
  /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "mt-1 font-mono text-muted-foreground", children: [
9863
10122
  stats.logFileCount.toLocaleString(),
@@ -9865,7 +10124,7 @@ function StorageSettingsTab() {
9865
10124
  formatBytes(stats.logBytes)
9866
10125
  ] })
9867
10126
  ] }),
9868
- /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "rounded-md border border-border bg-muted/20 px-3 py-2", children: [
10127
+ /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "border border-border bg-muted/40 rounded-md px-3 py-2", children: [
9869
10128
  /* @__PURE__ */ jsxRuntimeExports.jsx("div", { className: "font-medium", children: "Streaming chunks" }),
9870
10129
  /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "mt-1 font-mono text-muted-foreground", children: [
9871
10130
  stats.chunkFileCount.toLocaleString(),
@@ -9873,7 +10132,7 @@ function StorageSettingsTab() {
9873
10132
  formatBytes(stats.chunkBytes)
9874
10133
  ] })
9875
10134
  ] }),
9876
- /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "rounded-md border border-border bg-muted/20 px-3 py-2", children: [
10135
+ /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "border border-border bg-muted/40 rounded-md px-3 py-2", children: [
9877
10136
  /* @__PURE__ */ jsxRuntimeExports.jsx("div", { className: "font-medium", children: "Session archives" }),
9878
10137
  /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "mt-1 font-mono text-muted-foreground", children: [
9879
10138
  stats.sessionArchiveFileCount.toLocaleString(),
@@ -9894,7 +10153,7 @@ function CopyableSetupValue({
9894
10153
  onCopy
9895
10154
  }) {
9896
10155
  const copied = copiedId === id;
9897
- return /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "min-w-0 rounded-md border border-border bg-muted/20 px-3 py-2", children: [
10156
+ return /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "border border-border bg-muted/40 min-w-0 rounded-md px-3 py-2", children: [
9898
10157
  /* @__PURE__ */ jsxRuntimeExports.jsx("div", { className: "mb-1 text-xs font-medium text-muted-foreground", children: label }),
9899
10158
  /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "flex min-w-0 items-center gap-2", children: [
9900
10159
  /* @__PURE__ */ jsxRuntimeExports.jsx("code", { className: "min-w-0 flex-1 truncate font-mono text-xs text-foreground", children: value }),
@@ -10396,107 +10655,370 @@ function compareField(previous, current) {
10396
10655
  if (current < previous) return { direction: "down", delta: previous - current };
10397
10656
  return null;
10398
10657
  }
10399
- const VIRTUALIZE_GROUP_THRESHOLD = 30;
10400
- const ESTIMATED_GROUP_HEIGHT = 112;
10401
- const VIRTUAL_OVERSCAN = 6;
10402
- function shouldVirtualizeConversationGroups(groupCount) {
10403
- return groupCount > VIRTUALIZE_GROUP_THRESHOLD;
10658
+ function firstUserAgent(logs) {
10659
+ for (const log of logs) {
10660
+ const userAgent = log.userAgent;
10661
+ if (userAgent !== null && userAgent !== void 0 && userAgent !== "") return userAgent;
10662
+ }
10663
+ return null;
10404
10664
  }
10405
- function ConversationGroupList({
10406
- groups,
10407
- standalone,
10408
- ...groupProps
10409
- }) {
10410
- if (!shouldVirtualizeConversationGroups(groups.length)) {
10411
- return /* @__PURE__ */ jsxRuntimeExports.jsx(jsxRuntimeExports.Fragment, { children: groups.map((group) => /* @__PURE__ */ jsxRuntimeExports.jsx(ConversationGroup, { group, standalone, ...groupProps }, group.id)) });
10665
+ function firstClientPid(logs) {
10666
+ for (const log of logs) {
10667
+ const clientPid = log.clientPid;
10668
+ if (clientPid !== null && clientPid !== void 0) return clientPid;
10412
10669
  }
10413
- return /* @__PURE__ */ jsxRuntimeExports.jsx(VirtualizedConversationGroupList, { groups, standalone, ...groupProps });
10670
+ return null;
10671
+ }
10672
+ function firstClientProjectFolder(logs) {
10673
+ for (const log of logs) {
10674
+ const projectFolder = log.clientProjectFolder;
10675
+ if (projectFolder !== null && projectFolder !== void 0 && projectFolder !== "") {
10676
+ return projectFolder;
10677
+ }
10678
+ }
10679
+ return null;
10680
+ }
10681
+ function groupClient(group) {
10682
+ return detectClientApp({
10683
+ userAgent: firstUserAgent(group.logs),
10684
+ conversationId: group.conversationId,
10685
+ clientProjectFolder: firstClientProjectFolder(group.logs)
10686
+ });
10687
+ }
10688
+ function fallbackClientLabel(userAgent) {
10689
+ if (userAgent === null || userAgent === "") return "Unknown IDE";
10690
+ const firstToken = userAgent.split(/[ /;]/)[0] ?? "";
10691
+ if (firstToken === "") return "Unknown IDE";
10692
+ return firstToken;
10693
+ }
10694
+ function clientLabel(client, userAgent) {
10695
+ const knownLabel = clientAppLabel(client);
10696
+ if (knownLabel !== null) return knownLabel;
10697
+ return fallbackClientLabel(userAgent);
10698
+ }
10699
+ function bucketKey(value) {
10700
+ if (value === null || value === "") return "unknown";
10701
+ return String(value);
10702
+ }
10703
+ function ideKey(client, userAgent, projectFolder) {
10704
+ if (client !== "unknown") return client;
10705
+ return `unknown:${bucketKey(userAgent)}:${bucketKey(projectFolder)}`;
10706
+ }
10707
+ function processKey(clientPid, projectFolder) {
10708
+ return `${bucketKey(clientPid)}:${bucketKey(projectFolder)}`;
10709
+ }
10710
+ function sortLogsByTimestamp(logs) {
10711
+ return [...logs].sort((a, b) => a.timestamp.localeCompare(b.timestamp));
10712
+ }
10713
+ function firstTimestamp(logs) {
10714
+ return sortLogsByTimestamp(logs)[0]?.timestamp ?? "";
10715
+ }
10716
+ function sortByFirstLogTime(items) {
10717
+ return [...items].sort((a, b) => firstTimestamp(a.logs).localeCompare(firstTimestamp(b.logs)));
10718
+ }
10719
+ function buildConversationHierarchy(groups) {
10720
+ const ideGroups = /* @__PURE__ */ new Map();
10721
+ for (const group of groups) {
10722
+ const userAgent = firstUserAgent(group.logs);
10723
+ const projectFolder = firstClientProjectFolder(group.logs);
10724
+ const client = groupClient(group);
10725
+ const currentIdeKey = ideKey(client, userAgent, projectFolder);
10726
+ let ideGroup = ideGroups.get(currentIdeKey);
10727
+ if (ideGroup === void 0) {
10728
+ ideGroup = {
10729
+ id: currentIdeKey,
10730
+ client,
10731
+ label: clientLabel(client, userAgent),
10732
+ userAgent,
10733
+ processes: /* @__PURE__ */ new Map(),
10734
+ logs: []
10735
+ };
10736
+ ideGroups.set(currentIdeKey, ideGroup);
10737
+ }
10738
+ ideGroup.logs.push(...group.logs);
10739
+ const clientPid = firstClientPid(group.logs);
10740
+ const currentProcessKey = `${currentIdeKey}:${processKey(clientPid, projectFolder)}`;
10741
+ let processGroup = ideGroup.processes.get(currentProcessKey);
10742
+ if (processGroup === void 0) {
10743
+ processGroup = {
10744
+ id: currentProcessKey,
10745
+ clientPid,
10746
+ clientProjectFolder: projectFolder,
10747
+ sessions: [],
10748
+ logs: []
10749
+ };
10750
+ ideGroup.processes.set(currentProcessKey, processGroup);
10751
+ }
10752
+ processGroup.sessions.push(group);
10753
+ processGroup.logs.push(...group.logs);
10754
+ }
10755
+ const hierarchy = [];
10756
+ for (const ideGroup of ideGroups.values()) {
10757
+ const processes = sortByFirstLogTime(
10758
+ [...ideGroup.processes.values()].map((processGroup) => ({
10759
+ id: processGroup.id,
10760
+ clientPid: processGroup.clientPid,
10761
+ clientProjectFolder: processGroup.clientProjectFolder,
10762
+ sessions: sortByFirstLogTime(processGroup.sessions),
10763
+ logs: sortLogsByTimestamp(processGroup.logs)
10764
+ }))
10765
+ );
10766
+ hierarchy.push({
10767
+ id: ideGroup.id,
10768
+ client: ideGroup.client,
10769
+ label: ideGroup.label,
10770
+ userAgent: ideGroup.userAgent,
10771
+ processes,
10772
+ logs: sortLogsByTimestamp(ideGroup.logs)
10773
+ });
10774
+ }
10775
+ return sortByFirstLogTime(hierarchy);
10776
+ }
10777
+ function formatTokenCount(count) {
10778
+ if (count <= 0) return "0";
10779
+ return formatTokens(count);
10780
+ }
10781
+ function tokenTotals(logs) {
10782
+ let inputTokens = 0;
10783
+ let outputTokens = 0;
10784
+ for (const log of logs) {
10785
+ if (log.inputTokens !== null && log.inputTokens !== void 0) inputTokens += log.inputTokens;
10786
+ if (log.outputTokens !== null && log.outputTokens !== void 0) {
10787
+ outputTokens += log.outputTokens;
10788
+ }
10789
+ }
10790
+ return { inputTokens, outputTokens };
10791
+ }
10792
+ function countSessions(processes) {
10793
+ let sessions = 0;
10794
+ for (const processGroup of processes) {
10795
+ sessions += processGroup.sessions.length;
10796
+ }
10797
+ return sessions;
10798
+ }
10799
+ function shortProjectPath(projectFolder) {
10800
+ if (projectFolder === null || projectFolder === "") return null;
10801
+ const parts = projectFolder.replaceAll("\\", "/").split("/").filter((part) => part !== "");
10802
+ const leaf = parts[parts.length - 1];
10803
+ if (leaf === void 0) return projectFolder;
10804
+ const parent = parts[parts.length - 2];
10805
+ if (parent === void 0) return leaf;
10806
+ return `${parent}/${leaf}`;
10807
+ }
10808
+ function SummaryChip({
10809
+ label,
10810
+ value,
10811
+ className
10812
+ }) {
10813
+ return /* @__PURE__ */ jsxRuntimeExports.jsxs(
10814
+ "span",
10815
+ {
10816
+ className: cn(
10817
+ "border border-border bg-muted/40 inline-flex h-7 items-center gap-1 rounded-md px-2 text-xs text-muted-foreground",
10818
+ className
10819
+ ),
10820
+ children: [
10821
+ /* @__PURE__ */ jsxRuntimeExports.jsx("span", { className: "font-mono text-[10px] uppercase tracking-[0.12em] text-white/35", children: label }),
10822
+ /* @__PURE__ */ jsxRuntimeExports.jsx("span", { className: "font-mono tabular-nums text-slate-100", children: value })
10823
+ ]
10824
+ }
10825
+ );
10414
10826
  }
10415
- function VirtualizedConversationGroupList({
10827
+ function ConversationGroupList({
10416
10828
  groups,
10417
- standalone,
10418
10829
  ...groupProps
10419
10830
  }) {
10420
- const [expandedByGroupId, setExpandedByGroupId] = reactExports.useState(
10421
- () => /* @__PURE__ */ new Map()
10831
+ const hierarchy = reactExports.useMemo(() => buildConversationHierarchy(groups), [groups]);
10832
+ const [collapsedIdeIds, setCollapsedIdeIds] = reactExports.useState(() => /* @__PURE__ */ new Set());
10833
+ const [collapsedProcessIds, setCollapsedProcessIds] = reactExports.useState(
10834
+ () => /* @__PURE__ */ new Set()
10422
10835
  );
10423
- const virtualizer = useWindowVirtualizer({
10424
- count: groups.length,
10425
- estimateSize: () => ESTIMATED_GROUP_HEIGHT,
10426
- overscan: VIRTUAL_OVERSCAN,
10427
- getItemKey: (index) => groups[index]?.id ?? index
10428
- });
10429
- const setGroupExpanded = reactExports.useCallback((groupId, expanded) => {
10430
- setExpandedByGroupId((previous) => {
10431
- const next = new Map(previous);
10432
- if (expanded) {
10433
- next.set(groupId, true);
10836
+ const toggleIde = reactExports.useCallback((id) => {
10837
+ setCollapsedIdeIds((previous) => {
10838
+ const next = new Set(previous);
10839
+ if (next.has(id)) {
10840
+ next.delete(id);
10434
10841
  } else {
10435
- next.delete(groupId);
10842
+ next.add(id);
10436
10843
  }
10437
10844
  return next;
10438
10845
  });
10439
10846
  }, []);
10440
- const indexByLogId = reactExports.useMemo(() => {
10441
- const result = /* @__PURE__ */ new Map();
10442
- for (let index = 0; index < groups.length; index++) {
10443
- const group = groups[index];
10444
- if (group === void 0) continue;
10445
- for (const log of group.logs) {
10446
- result.set(log.id, index);
10847
+ const toggleProcess = reactExports.useCallback((id) => {
10848
+ setCollapsedProcessIds((previous) => {
10849
+ const next = new Set(previous);
10850
+ if (next.has(id)) {
10851
+ next.delete(id);
10852
+ } else {
10853
+ next.add(id);
10447
10854
  }
10448
- }
10449
- return result;
10450
- }, [groups]);
10451
- reactExports.useEffect(() => {
10452
- const handleLogFocusRequest = (event) => {
10453
- const request = readLogFocusRequest(event);
10454
- if (request === null) return;
10455
- const index = indexByLogId.get(request.logId);
10456
- if (index === void 0) return;
10457
- const group = groups[index];
10458
- if (group === void 0) return;
10459
- setGroupExpanded(group.id, true);
10460
- virtualizer.scrollToIndex(index, { align: "center" });
10461
- };
10462
- window.addEventListener(LOG_FOCUS_REQUEST_EVENT, handleLogFocusRequest);
10463
- return () => {
10464
- window.removeEventListener(LOG_FOCUS_REQUEST_EVENT, handleLogFocusRequest);
10465
- };
10466
- }, [groups, indexByLogId, setGroupExpanded, virtualizer]);
10467
- return /* @__PURE__ */ jsxRuntimeExports.jsx(
10468
- "div",
10855
+ return next;
10856
+ });
10857
+ }, []);
10858
+ return /* @__PURE__ */ jsxRuntimeExports.jsx("div", { className: "space-y-4", children: hierarchy.map((ideGroup) => /* @__PURE__ */ jsxRuntimeExports.jsx(
10859
+ IdeGroupSection,
10469
10860
  {
10470
- className: "relative w-full",
10471
- style: { height: `${virtualizer.getTotalSize()}px` },
10472
- "data-virtualized-conversation-list": "true",
10473
- children: virtualizer.getVirtualItems().map((virtualItem) => {
10474
- const group = groups[virtualItem.index];
10475
- if (group === void 0) return null;
10476
- return /* @__PURE__ */ jsxRuntimeExports.jsx(
10477
- "div",
10861
+ group: ideGroup,
10862
+ collapsed: collapsedIdeIds.has(ideGroup.id),
10863
+ collapsedProcessIds,
10864
+ onToggleIde: () => toggleIde(ideGroup.id),
10865
+ onToggleProcess: toggleProcess,
10866
+ conversationProps: groupProps
10867
+ },
10868
+ ideGroup.id
10869
+ )) });
10870
+ }
10871
+ function IdeGroupSection({
10872
+ group,
10873
+ collapsed,
10874
+ collapsedProcessIds,
10875
+ onToggleIde,
10876
+ onToggleProcess,
10877
+ conversationProps
10878
+ }) {
10879
+ const totals = tokenTotals(group.logs);
10880
+ const sessionCount = countSessions(group.processes);
10881
+ const logCount = group.logs.length;
10882
+ return /* @__PURE__ */ jsxRuntimeExports.jsxs(
10883
+ "section",
10884
+ {
10885
+ className: cn("border border-border bg-card shadow-sm relative isolate rounded-[8px]"),
10886
+ "data-ide-group": group.id,
10887
+ children: [
10888
+ /* @__PURE__ */ jsxRuntimeExports.jsxs(
10889
+ "button",
10478
10890
  {
10479
- "data-index": virtualItem.index,
10480
- ref: virtualizer.measureElement,
10481
- className: "absolute left-0 top-0 w-full",
10482
- style: { transform: `translateY(${virtualItem.start}px)` },
10483
- children: /* @__PURE__ */ jsxRuntimeExports.jsx(
10484
- ConversationGroup,
10485
- {
10486
- group,
10487
- standalone,
10488
- expanded: expandedByGroupId.get(group.id) ?? false,
10489
- onExpandedChange: (expanded) => setGroupExpanded(group.id, expanded),
10490
- ...groupProps
10491
- }
10492
- )
10891
+ type: "button",
10892
+ className: "flex w-full min-w-0 items-center gap-3 px-4 py-3 text-left transition-colors hover:bg-white/[0.03] focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-cyan-300/45",
10893
+ onClick: onToggleIde,
10894
+ "aria-expanded": !collapsed,
10895
+ children: [
10896
+ group.client === "unknown" ? /* @__PURE__ */ jsxRuntimeExports.jsx("span", { className: "border border-border bg-muted/40 inline-flex size-10 shrink-0 items-center justify-center rounded-[8px] text-slate-200", children: /* @__PURE__ */ jsxRuntimeExports.jsx(Monitor, { className: "size-5" }) }) : /* @__PURE__ */ jsxRuntimeExports.jsx(ClientLogo, { client: group.client, className: "size-10 rounded-[8px] text-cyan-100" }),
10897
+ /* @__PURE__ */ jsxRuntimeExports.jsxs("span", { className: "min-w-0 flex-1", children: [
10898
+ /* @__PURE__ */ jsxRuntimeExports.jsxs("span", { className: "flex min-w-0 items-center gap-2", children: [
10899
+ /* @__PURE__ */ jsxRuntimeExports.jsx(
10900
+ "span",
10901
+ {
10902
+ className: "truncate text-sm font-semibold text-slate-50",
10903
+ title: group.userAgent ?? group.label,
10904
+ children: group.label
10905
+ }
10906
+ ),
10907
+ /* @__PURE__ */ jsxRuntimeExports.jsx("span", { className: "rounded border border-cyan-200/15 bg-cyan-300/[0.06] px-1.5 py-0.5 font-mono text-[10px] uppercase tracking-[0.16em] text-cyan-100/75", children: "IDE" })
10908
+ ] }),
10909
+ /* @__PURE__ */ jsxRuntimeExports.jsxs("span", { className: "mt-1 flex flex-wrap items-center gap-x-3 gap-y-1 text-xs text-muted-foreground", children: [
10910
+ /* @__PURE__ */ jsxRuntimeExports.jsxs("span", { children: [
10911
+ group.processes.length,
10912
+ " process",
10913
+ group.processes.length !== 1 ? "es" : ""
10914
+ ] }),
10915
+ /* @__PURE__ */ jsxRuntimeExports.jsxs("span", { children: [
10916
+ sessionCount,
10917
+ " session",
10918
+ sessionCount !== 1 ? "s" : ""
10919
+ ] }),
10920
+ /* @__PURE__ */ jsxRuntimeExports.jsxs("span", { children: [
10921
+ logCount,
10922
+ " log",
10923
+ logCount !== 1 ? "s" : ""
10924
+ ] })
10925
+ ] })
10926
+ ] }),
10927
+ /* @__PURE__ */ jsxRuntimeExports.jsxs("span", { className: "hidden shrink-0 items-center gap-2 md:flex", children: [
10928
+ /* @__PURE__ */ jsxRuntimeExports.jsx(SummaryChip, { label: "IN", value: formatTokenCount(totals.inputTokens) }),
10929
+ /* @__PURE__ */ jsxRuntimeExports.jsx(SummaryChip, { label: "OUT", value: formatTokenCount(totals.outputTokens) })
10930
+ ] }),
10931
+ /* @__PURE__ */ jsxRuntimeExports.jsx("span", { className: "border border-input bg-background hover:bg-accent hover:text-accent-foreground inline-flex size-8 shrink-0 items-center justify-center rounded-md text-slate-200", children: collapsed ? /* @__PURE__ */ jsxRuntimeExports.jsx(ChevronRight, { className: "size-4" }) : /* @__PURE__ */ jsxRuntimeExports.jsx(ChevronDown, { className: "size-4" }) })
10932
+ ]
10933
+ }
10934
+ ),
10935
+ !collapsed && /* @__PURE__ */ jsxRuntimeExports.jsx("div", { className: "space-y-3 border-t border-white/10 px-3 pb-3 pt-3 sm:px-4", children: group.processes.map((processGroup) => /* @__PURE__ */ jsxRuntimeExports.jsx(
10936
+ ProcessGroupSection,
10937
+ {
10938
+ group: processGroup,
10939
+ collapsed: collapsedProcessIds.has(processGroup.id),
10940
+ onToggle: () => onToggleProcess(processGroup.id),
10941
+ conversationProps
10493
10942
  },
10494
- virtualItem.key
10495
- );
10496
- })
10943
+ processGroup.id
10944
+ )) })
10945
+ ]
10497
10946
  }
10498
10947
  );
10499
10948
  }
10949
+ function ProcessGroupSection({
10950
+ group,
10951
+ collapsed,
10952
+ onToggle,
10953
+ conversationProps
10954
+ }) {
10955
+ const totals = tokenTotals(group.logs);
10956
+ const projectLabel = shortProjectPath(group.clientProjectFolder);
10957
+ const sessionCount = group.sessions.length;
10958
+ const logCount = group.logs.length;
10959
+ const processLabel = group.clientPid !== null && group.clientPid !== void 0 ? `PID ${group.clientPid}` : "process";
10960
+ return /* @__PURE__ */ jsxRuntimeExports.jsxs("section", { className: "relative pl-5", children: [
10961
+ /* @__PURE__ */ jsxRuntimeExports.jsx("span", { className: "absolute bottom-0 left-2 top-0 w-px bg-white/12", "aria-hidden": "true" }),
10962
+ /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "border border-border bg-card shadow-sm overflow-hidden rounded-[8px]", children: [
10963
+ /* @__PURE__ */ jsxRuntimeExports.jsxs(
10964
+ "button",
10965
+ {
10966
+ type: "button",
10967
+ className: "flex w-full min-w-0 items-center gap-3 px-3 py-2.5 text-left transition-colors hover:bg-white/[0.035] focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-cyan-300/40",
10968
+ onClick: onToggle,
10969
+ "aria-expanded": !collapsed,
10970
+ children: [
10971
+ /* @__PURE__ */ jsxRuntimeExports.jsx("span", { className: "border border-border bg-muted/40 inline-flex size-8 shrink-0 items-center justify-center rounded-md text-amber-100", children: /* @__PURE__ */ jsxRuntimeExports.jsx(Cpu, { className: "size-4" }) }),
10972
+ /* @__PURE__ */ jsxRuntimeExports.jsxs("span", { className: "min-w-0 flex-1", children: [
10973
+ /* @__PURE__ */ jsxRuntimeExports.jsxs("span", { className: "flex min-w-0 flex-wrap items-center gap-x-2 gap-y-1", children: [
10974
+ /* @__PURE__ */ jsxRuntimeExports.jsx("span", { className: "font-mono text-xs font-semibold tabular-nums text-slate-100", children: processLabel }),
10975
+ projectLabel !== null && /* @__PURE__ */ jsxRuntimeExports.jsxs(
10976
+ "span",
10977
+ {
10978
+ className: "inline-flex min-w-0 items-center gap-1 text-xs text-muted-foreground",
10979
+ title: group.clientProjectFolder ?? projectLabel,
10980
+ children: [
10981
+ /* @__PURE__ */ jsxRuntimeExports.jsx(FolderOpen, { className: "size-3 shrink-0" }),
10982
+ /* @__PURE__ */ jsxRuntimeExports.jsx("span", { className: "truncate font-mono", children: projectLabel })
10983
+ ]
10984
+ }
10985
+ )
10986
+ ] }),
10987
+ /* @__PURE__ */ jsxRuntimeExports.jsxs("span", { className: "mt-1 flex flex-wrap items-center gap-x-3 gap-y-1 text-xs text-muted-foreground", children: [
10988
+ /* @__PURE__ */ jsxRuntimeExports.jsxs("span", { children: [
10989
+ sessionCount,
10990
+ " session",
10991
+ sessionCount !== 1 ? "s" : ""
10992
+ ] }),
10993
+ /* @__PURE__ */ jsxRuntimeExports.jsxs("span", { children: [
10994
+ logCount,
10995
+ " log",
10996
+ logCount !== 1 ? "s" : ""
10997
+ ] })
10998
+ ] })
10999
+ ] }),
11000
+ /* @__PURE__ */ jsxRuntimeExports.jsxs("span", { className: "hidden shrink-0 items-center gap-2 md:flex", children: [
11001
+ /* @__PURE__ */ jsxRuntimeExports.jsx(SummaryChip, { label: "IN", value: formatTokenCount(totals.inputTokens) }),
11002
+ /* @__PURE__ */ jsxRuntimeExports.jsx(SummaryChip, { label: "OUT", value: formatTokenCount(totals.outputTokens) })
11003
+ ] }),
11004
+ /* @__PURE__ */ jsxRuntimeExports.jsx("span", { className: "border border-input bg-background hover:bg-accent hover:text-accent-foreground inline-flex size-7 shrink-0 items-center justify-center rounded-md text-slate-200", children: collapsed ? /* @__PURE__ */ jsxRuntimeExports.jsx(ChevronRight, { className: "size-4" }) : /* @__PURE__ */ jsxRuntimeExports.jsx(ChevronDown, { className: "size-4" }) })
11005
+ ]
11006
+ }
11007
+ ),
11008
+ !collapsed && /* @__PURE__ */ jsxRuntimeExports.jsx("div", { className: "space-y-2 border-t border-white/10 p-2 sm:p-3", children: group.sessions.map((session) => /* @__PURE__ */ jsxRuntimeExports.jsx(
11009
+ ConversationGroup,
11010
+ {
11011
+ group: session,
11012
+ ...conversationProps,
11013
+ showClientIdentity: false,
11014
+ showLogClientMetadata: false,
11015
+ showProcessMetadata: false
11016
+ },
11017
+ session.id
11018
+ )) })
11019
+ ] })
11020
+ ] });
11021
+ }
10500
11022
  const NAV_ATTR = "data-nav-id";
10501
11023
  const NAV_ACTION_ATTR = "data-nav-action";
10502
11024
  function findNavItems(container) {
@@ -11556,6 +12078,20 @@ function truncateSessionId(id) {
11556
12078
  if (id.length <= 30) return id;
11557
12079
  return `${id.slice(0, 12)}...${id.slice(-12)}`;
11558
12080
  }
12081
+ function buildDisplayNumberByLogId(groups) {
12082
+ const result = /* @__PURE__ */ new Map();
12083
+ for (const group of groups) {
12084
+ for (let index = 0; index < group.logs.length; index += 1) {
12085
+ const log = group.logs[index];
12086
+ if (log === void 0) continue;
12087
+ result.set(log.id, index + 1);
12088
+ }
12089
+ }
12090
+ return result;
12091
+ }
12092
+ function displayNumberForLog(log, displayNumberByLogId) {
12093
+ return displayNumberByLogId.get(log.id) ?? log.id;
12094
+ }
11559
12095
  function shouldShowRawExport(captureMode) {
11560
12096
  return captureMode === "full";
11561
12097
  }
@@ -11646,13 +12182,13 @@ function slateStatusClass(status) {
11646
12182
  case "watch":
11647
12183
  return "border-amber-300/35 bg-amber-400/10 text-amber-100";
11648
12184
  case "clear":
11649
- return "border-emerald-400/30 bg-emerald-500/10 text-emerald-100";
12185
+ return "border-slate-300/20 bg-slate-300/[0.08] text-slate-100";
11650
12186
  }
11651
12187
  }
11652
12188
  function SessionOpeningSlate({ stats }) {
11653
12189
  if (stats.requests === 0) return null;
11654
- return /* @__PURE__ */ jsxRuntimeExports.jsx("div", { className: "mb-4 rounded-md border border-border bg-[#0c0d0f] shadow-[0_14px_50px_rgba(0,0,0,0.25)]", children: /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "grid grid-cols-2 gap-0 md:grid-cols-[minmax(220px,1.2fr)_repeat(4,minmax(120px,1fr))]", children: [
11655
- /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "col-span-2 border-b border-border/70 px-4 py-3 md:col-span-1 md:border-b-0 md:border-r", children: [
12190
+ return /* @__PURE__ */ jsxRuntimeExports.jsx("div", { className: "border border-border bg-card shadow-sm mb-4 rounded-[8px]", children: /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "grid grid-cols-2 gap-0 md:grid-cols-[minmax(220px,1.2fr)_repeat(4,minmax(120px,1fr))]", children: [
12191
+ /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "col-span-2 border-b border-white/10 px-4 py-3 md:col-span-1 md:border-b-0 md:border-r", children: [
11656
12192
  /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "flex items-center gap-2 text-[10px] font-semibold uppercase text-muted-foreground", children: [
11657
12193
  /* @__PURE__ */ jsxRuntimeExports.jsx(Clapperboard, { className: "size-3.5 text-cyan-300" }),
11658
12194
  "Opening Slate"
@@ -11660,7 +12196,7 @@ function SessionOpeningSlate({ stats }) {
11660
12196
  /* @__PURE__ */ jsxRuntimeExports.jsx("div", { className: "mt-2 min-w-0 truncate font-mono text-sm font-semibold text-foreground", children: stats.modelLabel }),
11661
12197
  /* @__PURE__ */ jsxRuntimeExports.jsx("div", { className: "mt-1 truncate font-mono text-[11px] text-muted-foreground", children: stats.timeRange ?? "Timeline pending" })
11662
12198
  ] }),
11663
- /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "border-r border-b border-border/70 px-4 py-3 md:border-b-0", children: [
12199
+ /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "border-r border-b border-white/10 px-4 py-3 md:border-b-0", children: [
11664
12200
  /* @__PURE__ */ jsxRuntimeExports.jsx("div", { className: "text-[10px] uppercase text-muted-foreground", children: "Status" }),
11665
12201
  /* @__PURE__ */ jsxRuntimeExports.jsx(
11666
12202
  "div",
@@ -11673,11 +12209,11 @@ function SessionOpeningSlate({ stats }) {
11673
12209
  }
11674
12210
  )
11675
12211
  ] }),
11676
- /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "border-b border-border/70 px-4 py-3 md:border-b-0 md:border-r", children: [
12212
+ /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "border-b border-white/10 px-4 py-3 md:border-b-0 md:border-r", children: [
11677
12213
  /* @__PURE__ */ jsxRuntimeExports.jsx("div", { className: "text-[10px] uppercase text-muted-foreground", children: "Requests" }),
11678
12214
  /* @__PURE__ */ jsxRuntimeExports.jsx("div", { className: "mt-2 font-mono text-xl font-semibold text-foreground", children: stats.requests })
11679
12215
  ] }),
11680
- /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "border-r border-border/70 px-4 py-3 md:border-r", children: [
12216
+ /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "border-r border-white/10 px-4 py-3 md:border-r", children: [
11681
12217
  /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "flex items-center gap-1 text-[10px] uppercase text-muted-foreground", children: [
11682
12218
  /* @__PURE__ */ jsxRuntimeExports.jsx(Siren, { className: "size-3 text-red-300" }),
11683
12219
  "Failure"
@@ -11761,7 +12297,7 @@ function sessionRiskBarClass(risk) {
11761
12297
  case "unknown":
11762
12298
  return "bg-muted-foreground/50";
11763
12299
  case "ok":
11764
- return "bg-emerald-400";
12300
+ return "bg-cyan-300";
11765
12301
  }
11766
12302
  }
11767
12303
  function formatContextWindow(summary) {
@@ -11803,7 +12339,7 @@ function evidenceChipClass(value) {
11803
12339
  return "border-amber-300/35 bg-amber-400/10 text-amber-100";
11804
12340
  }
11805
12341
  if (normalized.includes("pass") || normalized.includes("complete") || normalized.includes("accept")) {
11806
- return "border-emerald-400/30 bg-emerald-500/10 text-emerald-100";
12342
+ return "border-cyan-300/25 bg-cyan-400/10 text-cyan-100";
11807
12343
  }
11808
12344
  return "border-border/70 bg-background/70 text-muted-foreground";
11809
12345
  }
@@ -11836,13 +12372,13 @@ function SessionMembershipPanel({
11836
12372
  ].filter(
11837
12373
  (value) => value !== null && value.label.length > 0 && value.value.length > 0
11838
12374
  );
11839
- return /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "mb-3 overflow-hidden rounded-md border border-border bg-[#0c0d0f] text-xs", children: [
12375
+ return /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "border border-border bg-card shadow-sm mb-3 rounded-[8px] text-xs", children: [
11840
12376
  /* @__PURE__ */ jsxRuntimeExports.jsxs(
11841
12377
  "button",
11842
12378
  {
11843
12379
  type: "button",
11844
12380
  onClick: () => setOpen((value) => !value),
11845
- className: "flex w-full items-center gap-3 px-3 py-2 text-left transition-colors hover:bg-muted/30",
12381
+ className: "flex w-full items-center gap-3 px-3 py-2 text-left transition-colors hover:bg-white/[0.04]",
11846
12382
  "aria-expanded": open,
11847
12383
  children: [
11848
12384
  /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "min-w-0 flex-1", children: [
@@ -11871,7 +12407,7 @@ function SessionMembershipPanel({
11871
12407
  ]
11872
12408
  }
11873
12409
  ),
11874
- open && /* @__PURE__ */ jsxRuntimeExports.jsx("div", { className: "space-y-2 border-t border-border/70 px-3 py-2", children: memberships.map((membership) => {
12410
+ open && /* @__PURE__ */ jsxRuntimeExports.jsx("div", { className: "space-y-2 border-t border-white/10 px-3 py-2", children: memberships.map((membership) => {
11875
12411
  const member = membership.member;
11876
12412
  const metadataRows = getMemberMetadataRows(member);
11877
12413
  return /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "min-w-0", children: [
@@ -11903,7 +12439,7 @@ function SessionMembershipPanel({
11903
12439
  metadataRows.length > 0 && /* @__PURE__ */ jsxRuntimeExports.jsx("div", { className: "mt-2 grid gap-1 sm:grid-cols-2 xl:grid-cols-3", children: metadataRows.map((row) => /* @__PURE__ */ jsxRuntimeExports.jsxs(
11904
12440
  "div",
11905
12441
  {
11906
- className: "min-w-0 rounded border border-border/60 px-2 py-1",
12442
+ className: "border border-border bg-muted/40 min-w-0 rounded-md px-2 py-1",
11907
12443
  children: [
11908
12444
  /* @__PURE__ */ jsxRuntimeExports.jsx("div", { className: "font-mono text-[10px] text-muted-foreground", children: row.key }),
11909
12445
  /* @__PURE__ */ jsxRuntimeExports.jsx(
@@ -11947,7 +12483,7 @@ function LogPaginationButton({
11947
12483
  type: "button",
11948
12484
  onClick,
11949
12485
  disabled,
11950
- className: "inline-flex h-8 items-center gap-1.5 rounded-md px-2.5 text-xs text-muted-foreground transition-colors hover:bg-muted hover:text-foreground disabled:cursor-not-allowed disabled:opacity-45",
12486
+ className: "border border-input bg-background hover:bg-accent hover:text-accent-foreground inline-flex h-8 items-center gap-1.5 rounded-md px-2.5 text-xs text-muted-foreground transition-colors hover:text-foreground disabled:cursor-not-allowed disabled:opacity-45",
11951
12487
  title,
11952
12488
  children: [
11953
12489
  icon,
@@ -11968,7 +12504,7 @@ function LogPaginationBar({
11968
12504
  {
11969
12505
  className: cn(
11970
12506
  "flex min-h-9 flex-col gap-2 px-1 py-1 sm:flex-row sm:items-center",
11971
- embedded ? "border-t border-border/70 pt-2" : "mb-3 rounded-md border border-border bg-muted/10 px-2"
12507
+ embedded ? "border-t border-white/10 pt-2" : "border border-border bg-card shadow-sm mb-3 rounded-[8px] px-2"
11972
12508
  ),
11973
12509
  children: [
11974
12510
  /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "w-full min-w-0 px-1 font-mono text-[11px] text-muted-foreground sm:flex-1", children: [
@@ -12036,7 +12572,7 @@ function sessionRiskClass(risk) {
12036
12572
  case "unknown":
12037
12573
  return "text-muted-foreground";
12038
12574
  case "ok":
12039
- return "text-emerald-300";
12575
+ return "text-cyan-200";
12040
12576
  }
12041
12577
  }
12042
12578
  function sessionHealthClass(level) {
@@ -12046,7 +12582,7 @@ function sessionHealthClass(level) {
12046
12582
  case "optimizable":
12047
12583
  return "border-amber-400/25 bg-amber-400/8 text-amber-100";
12048
12584
  case "ok":
12049
- return "border-emerald-400/25 bg-emerald-400/8 text-emerald-100";
12585
+ return "border-cyan-300/25 bg-cyan-400/8 text-cyan-100";
12050
12586
  }
12051
12587
  }
12052
12588
  function sessionHealthLabel(level) {
@@ -12097,14 +12633,14 @@ function CopyableCommand({ command }) {
12097
12633
  setTimeout(() => setCopied(false), 2e3);
12098
12634
  });
12099
12635
  }, [command]);
12100
- return /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "inline-flex items-center gap-2 bg-muted rounded-md px-3 py-2", children: [
12101
- /* @__PURE__ */ jsxRuntimeExports.jsx("pre", { className: "text-blue-500 font-mono text-sm m-0", children: command }),
12636
+ return /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "border border-border bg-muted/40 inline-flex max-w-full items-center gap-2 rounded-md px-3 py-2", children: [
12637
+ /* @__PURE__ */ jsxRuntimeExports.jsx("pre", { className: "m-0 overflow-x-auto font-mono text-sm text-cyan-200", children: command }),
12102
12638
  /* @__PURE__ */ jsxRuntimeExports.jsx(
12103
12639
  "button",
12104
12640
  {
12105
12641
  type: "button",
12106
12642
  onClick: handleCopy,
12107
- className: "text-muted-foreground hover:text-foreground transition-colors shrink-0 cursor-pointer",
12643
+ className: "shrink-0 cursor-pointer text-muted-foreground transition-colors hover:text-foreground",
12108
12644
  "aria-label": "Copy command",
12109
12645
  children: copied ? /* @__PURE__ */ jsxRuntimeExports.jsx(Check, { className: "size-4" }) : /* @__PURE__ */ jsxRuntimeExports.jsx(Copy, { className: "size-4" })
12110
12646
  }
@@ -12113,14 +12649,30 @@ function CopyableCommand({ command }) {
12113
12649
  }
12114
12650
  function McpReadyBadge() {
12115
12651
  return /* @__PURE__ */ jsxRuntimeExports.jsx(TooltipProvider, { children: /* @__PURE__ */ jsxRuntimeExports.jsxs(Tooltip, { children: [
12116
- /* @__PURE__ */ jsxRuntimeExports.jsx(TooltipTrigger, { asChild: true, children: /* @__PURE__ */ jsxRuntimeExports.jsxs("span", { className: "inline-flex h-7 items-center gap-2 rounded-md border border-cyan-400/30 bg-cyan-500/10 px-2.5 font-mono text-[11px] font-medium text-cyan-300 shadow-[0_0_16px_rgba(34,211,238,0.08)]", children: [
12117
- /* @__PURE__ */ jsxRuntimeExports.jsx("span", { className: "size-1.5 rounded-full bg-emerald-300 shadow-[0_0_8px_rgba(110,231,183,0.8)]" }),
12652
+ /* @__PURE__ */ jsxRuntimeExports.jsx(TooltipTrigger, { asChild: true, children: /* @__PURE__ */ jsxRuntimeExports.jsxs("span", { className: "border border-border bg-muted/40 inline-flex h-7 items-center gap-2 rounded-md px-2.5 font-mono text-[11px] font-medium text-cyan-200", children: [
12653
+ /* @__PURE__ */ jsxRuntimeExports.jsx("span", { className: "size-1.5 rounded-full bg-cyan-200 shadow-[0_0_8px_rgba(125,211,252,0.75)]" }),
12118
12654
  "MCP Ready",
12119
12655
  /* @__PURE__ */ jsxRuntimeExports.jsx("span", { className: "hidden text-cyan-200/70 sm:inline", children: "/api/mcp" })
12120
12656
  ] }) }),
12121
12657
  /* @__PURE__ */ jsxRuntimeExports.jsx(TooltipContent, { sideOffset: 8, className: "max-w-[320px] text-left leading-relaxed", children: "Coding agents can inspect logs, replay requests, test providers, and debug sessions through MCP at /api/mcp." })
12122
12658
  ] }) });
12123
12659
  }
12660
+ function SidebarPanel({
12661
+ label,
12662
+ children,
12663
+ className
12664
+ }) {
12665
+ return /* @__PURE__ */ jsxRuntimeExports.jsxs("section", { className: cn("border border-border bg-card shadow-sm rounded-[8px]", className), children: [
12666
+ /* @__PURE__ */ jsxRuntimeExports.jsx("div", { className: "border-b border-white/10 px-3 py-2", children: /* @__PURE__ */ jsxRuntimeExports.jsx("div", { className: "font-mono text-[10px] font-semibold uppercase tracking-[0.14em] text-white/40", children: label }) }),
12667
+ /* @__PURE__ */ jsxRuntimeExports.jsx("div", { className: "p-3", children })
12668
+ ] });
12669
+ }
12670
+ function SidebarMetric({ label, value }) {
12671
+ return /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "border border-border bg-muted/40 min-w-0 rounded-md px-2 py-2", children: [
12672
+ /* @__PURE__ */ jsxRuntimeExports.jsx("div", { className: "truncate font-mono text-lg font-semibold leading-6 text-slate-100", children: value }),
12673
+ /* @__PURE__ */ jsxRuntimeExports.jsx("div", { className: "mt-0.5 truncate font-mono text-[10px] uppercase tracking-[0.12em] text-white/35", children: label })
12674
+ ] });
12675
+ }
12124
12676
  const CRAB_VARIANT_COLORS = [
12125
12677
  "text-amber-500",
12126
12678
  "text-rose-500",
@@ -12166,7 +12718,7 @@ function BrandHeader({
12166
12718
  crabEntrancePhase
12167
12719
  }) {
12168
12720
  if (compact) {
12169
- return /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "pb-3", children: [
12721
+ return /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "border border-border bg-card shadow-sm rounded-[8px] p-3", children: [
12170
12722
  /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "flex items-start justify-between gap-3", children: [
12171
12723
  /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "flex min-w-0 items-start gap-2", children: [
12172
12724
  /* @__PURE__ */ jsxRuntimeExports.jsx(CrabFamily, { compact: true, entrancePhase: crabEntrancePhase }),
@@ -12221,7 +12773,7 @@ function SessionContextLogButton({ label, logId }) {
12221
12773
  {
12222
12774
  type: "button",
12223
12775
  onClick: () => openLogContext(logId),
12224
- className: "inline-flex h-5 items-center rounded px-1 font-mono text-[10px] text-muted-foreground transition-colors hover:bg-muted hover:text-foreground",
12776
+ className: "inline-flex h-5 items-center rounded px-1 font-mono text-[10px] text-muted-foreground transition-colors hover:bg-white/[0.06] hover:text-foreground",
12225
12777
  title: `Open Context for ${formatLogReference(logId)}`,
12226
12778
  children: [
12227
12779
  label,
@@ -12253,7 +12805,7 @@ function SessionContextProgressBar({
12253
12805
  children: /* @__PURE__ */ jsxRuntimeExports.jsxs(
12254
12806
  "span",
12255
12807
  {
12256
- className: "relative block h-2.5 overflow-hidden rounded-full border border-border/70 bg-background transition-colors group-hover:border-foreground/30",
12808
+ className: "relative block h-2.5 overflow-hidden rounded-full border border-white/10 bg-black/25 transition-colors group-hover:border-cyan-200/35",
12257
12809
  role: "meter",
12258
12810
  "aria-label": ariaLabel,
12259
12811
  "aria-valuemin": 0,
@@ -12290,7 +12842,7 @@ function SessionModelContextRow({ summary }) {
12290
12842
  const openLatestContext = () => {
12291
12843
  openLogContext(summary.latest.logId);
12292
12844
  };
12293
- return /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "grid gap-x-4 gap-y-2 border-t border-border/60 py-2 first:border-t-0 lg:grid-cols-[minmax(180px,1fr)_minmax(260px,1fr)_minmax(260px,1.4fr)]", children: [
12845
+ return /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "grid gap-x-4 gap-y-2 border-t border-white/10 py-2 first:border-t-0 lg:grid-cols-[minmax(180px,1fr)_minmax(260px,1fr)_minmax(260px,1.4fr)]", children: [
12294
12846
  /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "min-w-0", children: [
12295
12847
  /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "flex min-w-0 items-center gap-2", children: [
12296
12848
  /* @__PURE__ */ jsxRuntimeExports.jsx(
@@ -12348,7 +12900,7 @@ function SessionModelContextRow({ summary }) {
12348
12900
  {
12349
12901
  className: cn(
12350
12902
  "size-3",
12351
- trend !== null && trend > 0 ? "text-amber-300" : "text-emerald-300"
12903
+ trend !== null && trend > 0 ? "text-amber-300" : "text-cyan-300"
12352
12904
  )
12353
12905
  }
12354
12906
  ),
@@ -12387,7 +12939,7 @@ function SessionContextSummaryPanel({
12387
12939
  summary
12388
12940
  }) {
12389
12941
  if (summary.models.length === 0) return null;
12390
- return /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "mt-3 border-t border-border/70 pt-2", children: [
12942
+ return /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "mt-3 border-t border-white/10 pt-2", children: [
12391
12943
  /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "mb-1 flex items-center justify-between gap-2", children: [
12392
12944
  /* @__PURE__ */ jsxRuntimeExports.jsx("div", { className: "text-[11px] font-semibold uppercase tracking-normal text-muted-foreground", children: "Session Context" }),
12393
12945
  /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "font-mono text-[10px] text-muted-foreground", children: [
@@ -12435,13 +12987,13 @@ function SessionContextBar({
12435
12987
  setTimeout(() => setCopied(false), 2e3);
12436
12988
  });
12437
12989
  }, []);
12438
- return /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "mb-3 rounded-md border border-border bg-muted/15 px-3 py-2 text-xs", children: [
12990
+ return /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "border border-border bg-card shadow-sm mb-3 rounded-[8px] px-3 py-2 text-xs", children: [
12439
12991
  /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "flex flex-wrap items-center gap-2", children: [
12440
12992
  showBackLink && /* @__PURE__ */ jsxRuntimeExports.jsx(
12441
12993
  "a",
12442
12994
  {
12443
12995
  href: "/",
12444
- className: "inline-flex size-8 shrink-0 items-center justify-center rounded-md text-muted-foreground transition-colors hover:bg-muted hover:text-foreground",
12996
+ className: "border border-input bg-background hover:bg-accent hover:text-accent-foreground inline-flex size-8 shrink-0 items-center justify-center rounded-md text-muted-foreground transition-colors hover:text-foreground",
12445
12997
  "aria-label": "Back to all sessions",
12446
12998
  title: "Back to all sessions",
12447
12999
  children: /* @__PURE__ */ jsxRuntimeExports.jsx(ArrowLeft, { className: "size-3.5" })
@@ -12479,7 +13031,7 @@ function SessionContextBar({
12479
13031
  {
12480
13032
  type: "button",
12481
13033
  onClick: () => setDetailsOpen((value) => !value),
12482
- className: "inline-flex h-8 shrink-0 items-center gap-1.5 rounded-md border border-border bg-background/60 px-2.5 font-mono text-[11px] text-muted-foreground transition-colors hover:bg-muted hover:text-foreground",
13034
+ className: "border border-input bg-background hover:bg-accent hover:text-accent-foreground inline-flex h-8 shrink-0 items-center gap-1.5 rounded-md px-2.5 font-mono text-[11px] text-muted-foreground transition-colors hover:text-foreground",
12483
13035
  "aria-expanded": detailsOpen,
12484
13036
  title: detailsOpen ? "Hide context details" : "Show context details",
12485
13037
  children: [
@@ -12493,7 +13045,7 @@ function SessionContextBar({
12493
13045
  {
12494
13046
  type: "button",
12495
13047
  onClick: handleCopyLink,
12496
- className: "inline-flex size-8 shrink-0 items-center justify-center rounded-md text-muted-foreground transition-colors hover:bg-muted hover:text-foreground",
13048
+ className: "border border-input bg-background hover:bg-accent hover:text-accent-foreground inline-flex size-8 shrink-0 items-center justify-center rounded-md text-muted-foreground transition-colors hover:text-foreground",
12497
13049
  "aria-label": copied ? "Copied session link" : "Copy session link",
12498
13050
  title: copied ? "Copied session link" : "Copy session link",
12499
13051
  children: copied ? /* @__PURE__ */ jsxRuntimeExports.jsx(Check, { className: "size-3.5" }) : /* @__PURE__ */ jsxRuntimeExports.jsx(Copy, { className: "size-3.5" })
@@ -12513,6 +13065,7 @@ function ProxyViewer({
12513
13065
  onModelChange,
12514
13066
  onClearAll,
12515
13067
  onClearGroup,
13068
+ onNotify,
12516
13069
  onImportLogs,
12517
13070
  viewMode,
12518
13071
  captureMode,
@@ -12566,13 +13119,17 @@ function ProxyViewer({
12566
13119
  try {
12567
13120
  const result = await exportLogsAsZip(logs, mode);
12568
13121
  if (!result.ok) {
12569
- setExportError(result.message);
13122
+ if (onNotify !== void 0) {
13123
+ onNotify({ message: result.message, tone: "error" });
13124
+ } else {
13125
+ setExportError(result.message);
13126
+ }
12570
13127
  }
12571
13128
  } finally {
12572
13129
  setExporting(null);
12573
13130
  }
12574
13131
  },
12575
- [logs]
13132
+ [logs, onNotify]
12576
13133
  );
12577
13134
  const handleImportClick = reactExports.useCallback(() => {
12578
13135
  importInputRef.current?.click();
@@ -12587,16 +13144,24 @@ function ProxyViewer({
12587
13144
  setImportStatus(null);
12588
13145
  void onImportLogs(file).then((result) => {
12589
13146
  const skipped = result.skipped > 0 ? `, skipped ${String(result.skipped)}` : "";
12590
- setImportStatus(
12591
- `Imported ${String(result.imported)} logs as ${result.sessionId}${skipped}.`
12592
- );
13147
+ const message = `Imported ${String(result.imported)} logs as ${result.sessionId}${skipped}.`;
13148
+ if (onNotify !== void 0) {
13149
+ onNotify({ message, tone: "success" });
13150
+ } else {
13151
+ setImportStatus(message);
13152
+ }
12593
13153
  }).catch((err) => {
12594
- setImportError(err instanceof Error ? err.message : "Failed to import logs");
13154
+ const message = err instanceof Error ? err.message : "Failed to import logs";
13155
+ if (onNotify !== void 0) {
13156
+ onNotify({ message, tone: "error" });
13157
+ } else {
13158
+ setImportError(message);
13159
+ }
12595
13160
  }).finally(() => {
12596
13161
  setImporting(false);
12597
13162
  });
12598
13163
  },
12599
- [onImportLogs]
13164
+ [onImportLogs, onNotify]
12600
13165
  );
12601
13166
  reactExports.useEffect(() => {
12602
13167
  setComparePair(null);
@@ -12605,6 +13170,7 @@ function ProxyViewer({
12605
13170
  setComparePair(null);
12606
13171
  }, []);
12607
13172
  const groups = reactExports.useMemo(() => groupLogsByConversation(logs), [logs]);
13173
+ const displayNumberByLogId = reactExports.useMemo(() => buildDisplayNumberByLogId(groups), [groups]);
12608
13174
  const sessionContextScope = reactExports.useMemo(
12609
13175
  () => resolveSessionContextScope({ pinnedSessionId, selectedSession, sessions, logs }),
12610
13176
  [logs, pinnedSessionId, selectedSession, sessions]
@@ -12640,38 +13206,38 @@ function ProxyViewer({
12640
13206
  },
12641
13207
  [comparisonPredecessors]
12642
13208
  );
12643
- return /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "min-h-screen w-full bg-[#070809] text-foreground", children: [
13209
+ return /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "bg-background min-h-screen w-full text-foreground", children: [
12644
13210
  /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "grid min-h-screen w-full grid-cols-1 lg:grid-cols-[340px_minmax(0,1fr)] xl:grid-cols-[360px_minmax(0,1fr)]", children: [
12645
- /* @__PURE__ */ jsxRuntimeExports.jsx("aside", { className: "border-b border-border bg-[#090a0c] lg:sticky lg:top-0 lg:h-screen lg:overflow-y-auto lg:border-b-0 lg:border-r", children: /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "space-y-4 p-4", children: [
13211
+ /* @__PURE__ */ jsxRuntimeExports.jsx("aside", { className: "bg-background border-b lg:sticky lg:top-0 lg:h-screen lg:overflow-y-auto lg:border-b-0 lg:border-r", children: /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "space-y-4 p-4", children: [
12646
13212
  /* @__PURE__ */ jsxRuntimeExports.jsx(BrandHeader, { compact: true, crabEntrancePhase }),
12647
- /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "grid grid-cols-3 gap-2 border-y border-border/70 py-3", children: [
12648
- /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "min-w-0", children: [
12649
- /* @__PURE__ */ jsxRuntimeExports.jsx("div", { className: "font-mono text-lg font-semibold text-foreground", children: logs.length }),
12650
- /* @__PURE__ */ jsxRuntimeExports.jsx("div", { className: "text-[10px] uppercase text-muted-foreground", children: "Requests" })
12651
- ] }),
12652
- /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "min-w-0", children: [
12653
- /* @__PURE__ */ jsxRuntimeExports.jsx("div", { className: "font-mono text-lg font-semibold text-foreground", children: formatTokens(hasSessionContext ? sessionContextTotalIn : totalIn) }),
12654
- /* @__PURE__ */ jsxRuntimeExports.jsx("div", { className: "text-[10px] uppercase text-muted-foreground", children: "Input" })
12655
- ] }),
12656
- /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "min-w-0", children: [
12657
- /* @__PURE__ */ jsxRuntimeExports.jsx("div", { className: "font-mono text-lg font-semibold text-foreground", children: formatTokens(hasSessionContext ? sessionContextTotalOut : totalOut) }),
12658
- /* @__PURE__ */ jsxRuntimeExports.jsx("div", { className: "text-[10px] uppercase text-muted-foreground", children: "Output" })
12659
- ] })
12660
- ] }),
12661
- /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "space-y-2", children: [
12662
- /* @__PURE__ */ jsxRuntimeExports.jsx("div", { className: "text-[10px] font-semibold uppercase tracking-normal text-muted-foreground", children: "Workspace" }),
12663
- /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "rounded-md border border-border bg-[#0c0d0f] px-3 py-2", children: [
12664
- /* @__PURE__ */ jsxRuntimeExports.jsx(
12665
- "div",
12666
- {
12667
- className: "font-mono text-xs font-semibold text-purple-300",
12668
- title: activeScopeLabel,
12669
- children: activeScopeLabel
12670
- }
12671
- ),
12672
- /* @__PURE__ */ jsxRuntimeExports.jsx("div", { className: "mt-1 text-[11px] text-muted-foreground", children: isPinnedSessionPage ? "Session workspace" : "Live workspace" })
12673
- ] })
12674
- ] }),
13213
+ /* @__PURE__ */ jsxRuntimeExports.jsx(SidebarPanel, { label: "Session", children: /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "grid grid-cols-3 gap-2", children: [
13214
+ /* @__PURE__ */ jsxRuntimeExports.jsx(SidebarMetric, { label: "Requests", value: logs.length }),
13215
+ /* @__PURE__ */ jsxRuntimeExports.jsx(
13216
+ SidebarMetric,
13217
+ {
13218
+ label: "Input",
13219
+ value: formatTokens(hasSessionContext ? sessionContextTotalIn : totalIn)
13220
+ }
13221
+ ),
13222
+ /* @__PURE__ */ jsxRuntimeExports.jsx(
13223
+ SidebarMetric,
13224
+ {
13225
+ label: "Output",
13226
+ value: formatTokens(hasSessionContext ? sessionContextTotalOut : totalOut)
13227
+ }
13228
+ )
13229
+ ] }) }),
13230
+ /* @__PURE__ */ jsxRuntimeExports.jsx(SidebarPanel, { label: "Workspace", children: /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "border border-border bg-muted/40 rounded-md px-3 py-2", children: [
13231
+ /* @__PURE__ */ jsxRuntimeExports.jsx(
13232
+ "div",
13233
+ {
13234
+ className: "truncate font-mono text-xs font-semibold text-cyan-100",
13235
+ title: activeScopeLabel,
13236
+ children: activeScopeLabel
13237
+ }
13238
+ ),
13239
+ /* @__PURE__ */ jsxRuntimeExports.jsx("div", { className: "mt-1 text-[11px] text-muted-foreground", children: isPinnedSessionPage ? "Session workspace" : "Live workspace" })
13240
+ ] }) }),
12675
13241
  hasSessionContext && sessionContextScope !== null && /* @__PURE__ */ jsxRuntimeExports.jsx(
12676
13242
  SessionContextBar,
12677
13243
  {
@@ -12685,26 +13251,25 @@ function ProxyViewer({
12685
13251
  }
12686
13252
  ),
12687
13253
  hasSessionContext && pinnedSessionId !== void 0 && sessionMemberships.length > 0 && /* @__PURE__ */ jsxRuntimeExports.jsx(SessionMembershipPanel, { memberships: sessionMemberships }),
12688
- /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "space-y-2", children: [
12689
- /* @__PURE__ */ jsxRuntimeExports.jsx("div", { className: "text-[10px] font-semibold uppercase tracking-normal text-muted-foreground", children: "Filters" }),
13254
+ /* @__PURE__ */ jsxRuntimeExports.jsx(SidebarPanel, { label: "Filters", children: /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "space-y-2", children: [
12690
13255
  !hideSessionFilter && /* @__PURE__ */ jsxRuntimeExports.jsxs(Select, { value: selectedSession, onValueChange: onSessionChange, children: [
12691
- /* @__PURE__ */ jsxRuntimeExports.jsx(SelectTrigger, { className: "h-9 w-full text-xs", children: /* @__PURE__ */ jsxRuntimeExports.jsx(SelectValue, { placeholder: "All sessions" }) }),
13256
+ /* @__PURE__ */ jsxRuntimeExports.jsx(SelectTrigger, { className: "border border-input bg-background hover:bg-accent hover:text-accent-foreground h-9 w-full text-xs", children: /* @__PURE__ */ jsxRuntimeExports.jsx(SelectValue, { placeholder: "All sessions" }) }),
12692
13257
  /* @__PURE__ */ jsxRuntimeExports.jsxs(SelectContent, { children: [
12693
13258
  /* @__PURE__ */ jsxRuntimeExports.jsx(SelectItem, { value: "__all__", children: "All sessions" }),
12694
13259
  sessions.map((s) => /* @__PURE__ */ jsxRuntimeExports.jsx(SelectItem, { value: s, children: truncateSessionId(s) }, s))
12695
13260
  ] })
12696
13261
  ] }),
12697
13262
  /* @__PURE__ */ jsxRuntimeExports.jsxs(Select, { value: selectedModel, onValueChange: onModelChange, children: [
12698
- /* @__PURE__ */ jsxRuntimeExports.jsx(SelectTrigger, { className: "h-9 w-full text-xs", children: /* @__PURE__ */ jsxRuntimeExports.jsx(SelectValue, { placeholder: "All models" }) }),
13263
+ /* @__PURE__ */ jsxRuntimeExports.jsx(SelectTrigger, { className: "border border-input bg-background hover:bg-accent hover:text-accent-foreground h-9 w-full text-xs", children: /* @__PURE__ */ jsxRuntimeExports.jsx(SelectValue, { placeholder: "All models" }) }),
12699
13264
  /* @__PURE__ */ jsxRuntimeExports.jsxs(SelectContent, { children: [
12700
13265
  /* @__PURE__ */ jsxRuntimeExports.jsx(SelectItem, { value: "__all__", children: "All models" }),
12701
13266
  models.map((m) => /* @__PURE__ */ jsxRuntimeExports.jsx(SelectItem, { value: m, children: m }, m))
12702
13267
  ] })
12703
13268
  ] })
12704
- ] })
13269
+ ] }) })
12705
13270
  ] }) }),
12706
13271
  /* @__PURE__ */ jsxRuntimeExports.jsxs("main", { className: "min-w-0", children: [
12707
- /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "sticky top-0 z-30 border-b border-border bg-[#08090b]/95 px-4 py-3 shadow-[0_12px_40px_rgba(0,0,0,0.24)] backdrop-blur lg:px-5", children: [
13272
+ /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "border border-border bg-background/95 shadow-sm sticky top-0 z-30 border-b px-4 py-3 lg:px-5", children: [
12708
13273
  /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "flex flex-wrap items-center gap-2", children: [
12709
13274
  /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "min-w-[180px] flex-1", children: [
12710
13275
  /* @__PURE__ */ jsxRuntimeExports.jsx("div", { className: "text-sm font-semibold text-foreground", children: "Logs" }),
@@ -12727,7 +13292,7 @@ function ProxyViewer({
12727
13292
  type: "button",
12728
13293
  onClick: handleImportClick,
12729
13294
  disabled: importing,
12730
- className: "inline-flex h-8 items-center gap-1.5 rounded-md px-3 text-xs text-muted-foreground transition-colors hover:bg-muted hover:text-foreground disabled:cursor-not-allowed disabled:opacity-50",
13295
+ className: "border border-input bg-background hover:bg-accent hover:text-accent-foreground inline-flex h-8 items-center gap-1.5 rounded-md px-3 text-xs text-muted-foreground transition-colors hover:text-foreground disabled:cursor-not-allowed disabled:opacity-50",
12731
13296
  title: "Import Agent Inspector export",
12732
13297
  children: importing ? /* @__PURE__ */ jsxRuntimeExports.jsx("span", { children: "Importing..." }) : /* @__PURE__ */ jsxRuntimeExports.jsxs(jsxRuntimeExports.Fragment, { children: [
12733
13298
  /* @__PURE__ */ jsxRuntimeExports.jsx(Upload, { className: "size-3.5" }),
@@ -12744,7 +13309,7 @@ function ProxyViewer({
12744
13309
  void handleExport("redacted");
12745
13310
  },
12746
13311
  disabled: exporting !== null,
12747
- className: "inline-flex h-8 items-center gap-1.5 rounded-md px-3 text-xs text-muted-foreground transition-colors hover:bg-muted hover:text-foreground disabled:cursor-not-allowed disabled:opacity-50",
13312
+ className: "border border-input bg-background hover:bg-accent hover:text-accent-foreground inline-flex h-8 items-center gap-1.5 rounded-md px-3 text-xs text-muted-foreground transition-colors hover:text-foreground disabled:cursor-not-allowed disabled:opacity-50",
12748
13313
  title: "Export redacted logs as JSON ZIP",
12749
13314
  children: exporting === "redacted" ? /* @__PURE__ */ jsxRuntimeExports.jsx("span", { children: "Exporting..." }) : /* @__PURE__ */ jsxRuntimeExports.jsxs(jsxRuntimeExports.Fragment, { children: [
12750
13315
  /* @__PURE__ */ jsxRuntimeExports.jsx(Download, { className: "size-3.5" }),
@@ -12760,7 +13325,7 @@ function ProxyViewer({
12760
13325
  void handleExport("raw");
12761
13326
  },
12762
13327
  disabled: exporting !== null,
12763
- className: "inline-flex h-8 items-center gap-1.5 rounded-md px-2.5 text-xs text-muted-foreground transition-colors hover:bg-muted hover:text-foreground disabled:cursor-not-allowed disabled:opacity-50",
13328
+ className: "border border-input bg-background hover:bg-accent hover:text-accent-foreground inline-flex h-8 items-center gap-1.5 rounded-md px-2.5 text-xs text-muted-foreground transition-colors hover:text-foreground disabled:cursor-not-allowed disabled:opacity-50",
12764
13329
  title: "Export raw logs without redaction",
12765
13330
  children: exporting === "raw" ? /* @__PURE__ */ jsxRuntimeExports.jsx("span", { children: "Exporting..." }) : /* @__PURE__ */ jsxRuntimeExports.jsxs(jsxRuntimeExports.Fragment, { children: [
12766
13331
  /* @__PURE__ */ jsxRuntimeExports.jsx(FileBraces, { className: "size-3.5" }),
@@ -12773,7 +13338,7 @@ function ProxyViewer({
12773
13338
  {
12774
13339
  type: "button",
12775
13340
  onClick: onClearAll,
12776
- className: "inline-flex h-8 items-center gap-1.5 rounded-md px-3 text-xs text-muted-foreground transition-colors hover:bg-muted hover:text-foreground",
13341
+ className: "border border-input bg-background hover:bg-accent hover:text-accent-foreground inline-flex h-8 items-center gap-1.5 rounded-md px-3 text-xs text-muted-foreground transition-colors hover:text-foreground",
12777
13342
  title: "Clear all logs",
12778
13343
  children: [
12779
13344
  /* @__PURE__ */ jsxRuntimeExports.jsx(Trash2, { className: "size-3.5" }),
@@ -12783,13 +13348,13 @@ function ProxyViewer({
12783
13348
  )
12784
13349
  ] }),
12785
13350
  /* @__PURE__ */ jsxRuntimeExports.jsx(LogPaginationBar, { logs, pagination, embedded: true }),
12786
- exportError !== null && /* @__PURE__ */ jsxRuntimeExports.jsx("div", { className: "mt-2 rounded-md border border-destructive/30 bg-destructive/10 px-3 py-2 text-xs text-destructive", children: exportError }),
12787
- importError !== null && /* @__PURE__ */ jsxRuntimeExports.jsx("div", { className: "mt-2 rounded-md border border-destructive/30 bg-destructive/10 px-3 py-2 text-xs text-destructive", children: importError }),
12788
- importStatus !== null && importError === null && /* @__PURE__ */ jsxRuntimeExports.jsx("div", { className: "mt-2 rounded-md border border-emerald-500/25 bg-emerald-500/10 px-3 py-2 text-xs text-emerald-200", children: importStatus })
13351
+ onNotify === void 0 && exportError !== null && /* @__PURE__ */ jsxRuntimeExports.jsx("div", { className: "mt-2 rounded-md border border-destructive/30 bg-destructive/10 px-3 py-2 text-xs text-destructive", children: exportError }),
13352
+ onNotify === void 0 && importError !== null && /* @__PURE__ */ jsxRuntimeExports.jsx("div", { className: "mt-2 rounded-md border border-destructive/30 bg-destructive/10 px-3 py-2 text-xs text-destructive", children: importError }),
13353
+ onNotify === void 0 && importStatus !== null && importError === null && /* @__PURE__ */ jsxRuntimeExports.jsx("div", { className: "mt-2 rounded-md border border-cyan-400/25 bg-cyan-500/10 px-3 py-2 text-xs text-cyan-100", children: importStatus })
12789
13354
  ] }),
12790
13355
  /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "px-4 py-4 lg:px-5", children: [
12791
13356
  /* @__PURE__ */ jsxRuntimeExports.jsx(SessionOpeningSlate, { stats: slateStats }),
12792
- logs.length === 0 ? selectedSession !== "__all__" ? /* @__PURE__ */ jsxRuntimeExports.jsx("div", { className: "py-16 text-center text-muted-foreground", children: /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "mx-auto max-w-xl space-y-4 rounded-md border border-border bg-muted/10 px-4 py-8", children: [
13357
+ logs.length === 0 ? selectedSession !== "__all__" ? /* @__PURE__ */ jsxRuntimeExports.jsx("div", { className: "py-16 text-center text-muted-foreground", children: /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "border border-border bg-card shadow-sm mx-auto max-w-xl space-y-4 rounded-[8px] px-4 py-8", children: [
12793
13358
  /* @__PURE__ */ jsxRuntimeExports.jsx("p", { className: "text-sm font-medium", children: isLoading ? "Loading session data..." : "Session not found" }),
12794
13359
  /* @__PURE__ */ jsxRuntimeExports.jsx("p", { className: "inline-block max-w-full rounded bg-muted px-3 py-1 font-mono text-xs break-all", children: truncateSessionId(selectedSession) }),
12795
13360
  sessionMemberships.length > 0 && /* @__PURE__ */ jsxRuntimeExports.jsx("div", { className: "text-left", children: /* @__PURE__ */ jsxRuntimeExports.jsx(SessionMembershipPanel, { memberships: sessionMemberships }) }),
@@ -12806,7 +13371,7 @@ function ProxyViewer({
12806
13371
  }
12807
13372
  )
12808
13373
  ] })
12809
- ] }) }) : /* @__PURE__ */ jsxRuntimeExports.jsx("div", { className: "py-16 text-center text-muted-foreground", children: /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "mx-auto max-w-2xl space-y-4 rounded-md border border-border bg-muted/10 px-4 py-8", children: [
13374
+ ] }) }) : /* @__PURE__ */ jsxRuntimeExports.jsx("div", { className: "py-16 text-center text-muted-foreground", children: /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "border border-border bg-card shadow-sm mx-auto max-w-2xl space-y-4 rounded-[8px] px-4 py-8", children: [
12810
13375
  /* @__PURE__ */ jsxRuntimeExports.jsx("p", { className: "text-sm", children: "No requests captured yet." }),
12811
13376
  /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "flex flex-col items-center gap-2", children: [
12812
13377
  /* @__PURE__ */ jsxRuntimeExports.jsx(CopyableCommand, { command: "ANTHROPIC_BASE_URL=http://localhost:25947/proxy <your-tool>" }),
@@ -12831,8 +13396,7 @@ function ProxyViewer({
12831
13396
  onCompareWithPrevious: handleCompareWithPrevious,
12832
13397
  comparisonPredecessors,
12833
13398
  onClearGroup,
12834
- standalone: groups.length === 1,
12835
- hasPinnedSessionContext: hasSessionContext,
13399
+ defaultExpanded: groups.length === 1,
12836
13400
  timeDisplayFormat
12837
13401
  }
12838
13402
  ) }),
@@ -12843,9 +13407,91 @@ function ProxyViewer({
12843
13407
  ] })
12844
13408
  ] })
12845
13409
  ] }),
12846
- comparePair !== null && /* @__PURE__ */ jsxRuntimeExports.jsx(reactExports.Suspense, { fallback: null, children: /* @__PURE__ */ jsxRuntimeExports.jsx(LazyCompareDrawer, { left: comparePair[0], right: comparePair[1], onClose: closeCompare }) })
13410
+ comparePair !== null && /* @__PURE__ */ jsxRuntimeExports.jsx(reactExports.Suspense, { fallback: null, children: /* @__PURE__ */ jsxRuntimeExports.jsx(
13411
+ LazyCompareDrawer,
13412
+ {
13413
+ left: comparePair[0],
13414
+ right: comparePair[1],
13415
+ leftDisplayNumber: displayNumberForLog(comparePair[0], displayNumberByLogId),
13416
+ rightDisplayNumber: displayNumberForLog(comparePair[1], displayNumberByLogId),
13417
+ onClose: closeCompare
13418
+ }
13419
+ ) })
12847
13420
  ] });
12848
13421
  }
13422
+ const TRANSIENT_TOAST_AUTO_DISMISS_MS = 3e3;
13423
+ function createNextTransientToast(previous, input) {
13424
+ return {
13425
+ id: (previous?.id ?? 0) + 1,
13426
+ message: input.message,
13427
+ tone: input.tone ?? "error"
13428
+ };
13429
+ }
13430
+ function useTransientToast() {
13431
+ const [notice, setNotice] = reactExports.useState(null);
13432
+ const showToast = reactExports.useCallback((input) => {
13433
+ setNotice((previous) => createNextTransientToast(previous, input));
13434
+ }, []);
13435
+ const dismissToast = reactExports.useCallback(() => {
13436
+ setNotice(null);
13437
+ }, []);
13438
+ reactExports.useEffect(() => {
13439
+ if (notice === null) return void 0;
13440
+ const timeout = window.setTimeout(() => {
13441
+ setNotice(null);
13442
+ }, TRANSIENT_TOAST_AUTO_DISMISS_MS);
13443
+ return () => {
13444
+ window.clearTimeout(timeout);
13445
+ };
13446
+ }, [notice]);
13447
+ return { notice, showToast, dismissToast };
13448
+ }
13449
+ function TransientToast({
13450
+ notice,
13451
+ onDismiss
13452
+ }) {
13453
+ if (notice === null) return null;
13454
+ const isError = notice.tone === "error";
13455
+ const Icon2 = isError ? TriangleAlert : CircleCheck;
13456
+ return /* @__PURE__ */ jsxRuntimeExports.jsx(
13457
+ "div",
13458
+ {
13459
+ "aria-atomic": "true",
13460
+ "aria-live": "polite",
13461
+ className: "pointer-events-none fixed top-4 right-4 z-[100] w-[min(calc(100vw-2rem),26rem)]",
13462
+ role: "status",
13463
+ children: /* @__PURE__ */ jsxRuntimeExports.jsxs(
13464
+ "div",
13465
+ {
13466
+ className: cn(
13467
+ "pointer-events-auto flex items-start gap-2 rounded-md border px-3 py-2 text-sm shadow-[0_18px_50px_rgba(0,0,0,0.45)] backdrop-blur",
13468
+ isError ? "border-red-400/30 bg-[#16090b]/95 text-red-100" : "border-cyan-300/25 bg-[#071318]/95 text-cyan-100"
13469
+ ),
13470
+ children: [
13471
+ /* @__PURE__ */ jsxRuntimeExports.jsx(
13472
+ Icon2,
13473
+ {
13474
+ className: cn("mt-0.5 size-4 shrink-0", isError ? "text-red-300" : "text-cyan-200")
13475
+ }
13476
+ ),
13477
+ /* @__PURE__ */ jsxRuntimeExports.jsx("div", { className: "min-w-0 flex-1 break-words leading-5", children: notice.message }),
13478
+ /* @__PURE__ */ jsxRuntimeExports.jsx(
13479
+ "button",
13480
+ {
13481
+ type: "button",
13482
+ className: "inline-flex size-6 shrink-0 items-center justify-center rounded-md text-current/70 transition-colors hover:bg-white/10 hover:text-current",
13483
+ "aria-label": "Dismiss notification",
13484
+ onClick: onDismiss,
13485
+ children: /* @__PURE__ */ jsxRuntimeExports.jsx(X, { className: "size-3.5" })
13486
+ }
13487
+ )
13488
+ ]
13489
+ },
13490
+ notice.id
13491
+ )
13492
+ }
13493
+ );
13494
+ }
12849
13495
  const SSEUpdateSchema = union([
12850
13496
  object({
12851
13497
  type: literal("init"),
@@ -12958,7 +13604,7 @@ function ProxyViewerContainer({
12958
13604
  const [allLogs, setAllLogs] = reactExports.useState([]);
12959
13605
  const [selectedSession, setSelectedSession] = reactExports.useState(initialSessionId ?? "__all__");
12960
13606
  const [selectedModel, setSelectedModel] = reactExports.useState("__all__");
12961
- const [error, setError] = reactExports.useState(null);
13607
+ const { notice, showToast, dismissToast } = useTransientToast();
12962
13608
  const [streamInitialized, setStreamInitialized] = reactExports.useState(initialSessionId === void 0);
12963
13609
  const [logPage, setLogPage] = reactExports.useState(null);
12964
13610
  const [sessionPageLoading, setSessionPageLoading] = reactExports.useState(initialSessionId !== void 0);
@@ -12971,6 +13617,12 @@ function ProxyViewerContainer({
12971
13617
  const logIndexRef = reactExports.useRef(/* @__PURE__ */ new Map());
12972
13618
  const pendingUpdatesRef = reactExports.useRef([]);
12973
13619
  const flushTimerRef = reactExports.useRef(null);
13620
+ const showErrorToast = reactExports.useCallback(
13621
+ (message) => {
13622
+ showToast({ message, tone: "error" });
13623
+ },
13624
+ [showToast]
13625
+ );
12974
13626
  const logs = reactExports.useMemo(
12975
13627
  () => filterLogs(allLogs, selectedSession, selectedModel),
12976
13628
  [allLogs, selectedSession, selectedModel]
@@ -13026,7 +13678,7 @@ function ProxyViewerContainer({
13026
13678
  const parsed = JSON.parse(rawData);
13027
13679
  const updateResult = SSEUpdateSchema.safeParse(parsed);
13028
13680
  if (!updateResult.success) {
13029
- setError("Failed to parse SSE data");
13681
+ showErrorToast("Failed to parse SSE data");
13030
13682
  return;
13031
13683
  }
13032
13684
  const update = updateResult.data;
@@ -13040,16 +13692,16 @@ function ProxyViewerContainer({
13040
13692
  logIndexRef.current = buildLogIndex(nextLogs);
13041
13693
  setAllLogs(nextLogs);
13042
13694
  setStreamInitialized(true);
13043
- setError(null);
13695
+ dismissToast();
13044
13696
  } else if (update.type === "update") {
13045
13697
  scheduleUpdate(update.log);
13046
13698
  }
13047
13699
  } catch {
13048
- setError("Failed to parse SSE data");
13700
+ showErrorToast("Failed to parse SSE data");
13049
13701
  }
13050
13702
  };
13051
13703
  es.onerror = () => {
13052
- setError("SSE connection lost, reconnecting...");
13704
+ showErrorToast("SSE connection lost, reconnecting...");
13053
13705
  setStreamInitialized(true);
13054
13706
  es.close();
13055
13707
  if (reconnectTimeoutRef.current !== null) {
@@ -13057,14 +13709,14 @@ function ProxyViewerContainer({
13057
13709
  }
13058
13710
  reconnectTimeoutRef.current = setTimeout(connectSSE, 3e3);
13059
13711
  };
13060
- }, [initialSessionId, scheduleUpdate]);
13712
+ }, [dismissToast, initialSessionId, scheduleUpdate, showErrorToast]);
13061
13713
  const loadSessionPage = reactExports.useCallback(
13062
13714
  (request) => {
13063
13715
  if (initialSessionId === void 0) return;
13064
13716
  const requestId = sessionPageRequestIdRef.current + 1;
13065
13717
  sessionPageRequestIdRef.current = requestId;
13066
13718
  setSessionPageLoading(true);
13067
- setError(null);
13719
+ dismissToast();
13068
13720
  void fetchJson(buildSessionLogsPageUrl(initialSessionId, request), LogCursorPageSchema).then((page) => {
13069
13721
  if (sessionPageRequestIdRef.current !== requestId) return;
13070
13722
  const nextLogs = page.logs;
@@ -13073,16 +13725,16 @@ function ProxyViewerContainer({
13073
13725
  setLogPage(page);
13074
13726
  setSelectedSession(initialSessionId);
13075
13727
  setSessionPageLoading(false);
13076
- setError(null);
13728
+ dismissToast();
13077
13729
  }).catch((err) => {
13078
13730
  if (sessionPageRequestIdRef.current !== requestId) return;
13079
13731
  setAllLogs([]);
13080
13732
  setLogPage(null);
13081
13733
  setSessionPageLoading(false);
13082
- setError(err instanceof Error ? err.message : "Failed to load session logs");
13734
+ showErrorToast(err instanceof Error ? err.message : "Failed to load session logs");
13083
13735
  });
13084
13736
  },
13085
- [initialSessionId]
13737
+ [dismissToast, initialSessionId, showErrorToast]
13086
13738
  );
13087
13739
  reactExports.useEffect(() => {
13088
13740
  if (initialSessionId === void 0) {
@@ -13188,64 +13840,70 @@ function ProxyViewerContainer({
13188
13840
  }
13189
13841
  });
13190
13842
  if (!res.ok) {
13191
- setError("Failed to clear logs");
13843
+ showErrorToast("Failed to clear logs");
13192
13844
  return;
13193
13845
  }
13194
13846
  logIndexRef.current.clear();
13195
13847
  setAllLogs([]);
13196
- setError(null);
13848
+ dismissToast();
13197
13849
  } catch (err) {
13198
- setError(err instanceof Error ? err.message : "Unknown error clearing logs");
13850
+ showErrorToast(err instanceof Error ? err.message : "Unknown error clearing logs");
13199
13851
  }
13200
13852
  })();
13201
- }, [allLogs, initialSessionId]);
13202
- const handleClearGroup = reactExports.useCallback((ids) => {
13203
- if (ids.length === 0) return;
13204
- void (async () => {
13205
- try {
13206
- const res = await fetch("/api/logs", {
13207
- method: "DELETE",
13208
- headers: { "Content-Type": "application/json" },
13209
- body: JSON.stringify({ ids })
13210
- });
13211
- if (!res.ok) {
13212
- setError("Failed to clear group");
13213
- return;
13853
+ }, [allLogs, dismissToast, initialSessionId, showErrorToast]);
13854
+ const handleClearGroup = reactExports.useCallback(
13855
+ (ids) => {
13856
+ if (ids.length === 0) return;
13857
+ void (async () => {
13858
+ try {
13859
+ const res = await fetch("/api/logs", {
13860
+ method: "DELETE",
13861
+ headers: { "Content-Type": "application/json" },
13862
+ body: JSON.stringify({ ids })
13863
+ });
13864
+ if (!res.ok) {
13865
+ showErrorToast("Failed to clear group");
13866
+ return;
13867
+ }
13868
+ const idSet = new Set(ids);
13869
+ setAllLogs((prev) => {
13870
+ const remaining = prev.filter((l) => !idSet.has(l.id));
13871
+ logIndexRef.current = buildLogIndex(remaining);
13872
+ return remaining;
13873
+ });
13874
+ dismissToast();
13875
+ } catch (err) {
13876
+ showErrorToast(err instanceof Error ? err.message : "Unknown error clearing group");
13214
13877
  }
13215
- const idSet = new Set(ids);
13216
- setAllLogs((prev) => {
13217
- const remaining = prev.filter((l) => !idSet.has(l.id));
13218
- logIndexRef.current = buildLogIndex(remaining);
13219
- return remaining;
13220
- });
13221
- setError(null);
13222
- } catch (err) {
13223
- setError(err instanceof Error ? err.message : "Unknown error clearing group");
13224
- }
13225
- })();
13226
- }, []);
13227
- const handleImportLogs = reactExports.useCallback(async (file) => {
13228
- const formData = new FormData();
13229
- formData.set("file", file);
13230
- const result = await fetchJson("/api/logs/import", ImportLogsResponseSchema, {
13231
- method: "POST",
13232
- body: formData
13233
- });
13234
- setAllLogs((prev) => {
13235
- const importedIds = new Set(result.logs.map((log) => log.id));
13236
- const next = [...prev.filter((log) => !importedIds.has(log.id)), ...result.logs].sort(
13237
- (left, right) => left.id - right.id
13238
- );
13239
- const trimmed = trimClientLogs(next);
13240
- logIndexRef.current = buildLogIndex(trimmed);
13241
- return trimmed;
13242
- });
13243
- setSelectedSession(result.sessionId);
13244
- setSelectedModel("__all__");
13245
- setLogPage(null);
13246
- setError(null);
13247
- return result;
13248
- }, []);
13878
+ })();
13879
+ },
13880
+ [dismissToast, showErrorToast]
13881
+ );
13882
+ const handleImportLogs = reactExports.useCallback(
13883
+ async (file) => {
13884
+ const formData = new FormData();
13885
+ formData.set("file", file);
13886
+ const result = await fetchJson("/api/logs/import", ImportLogsResponseSchema, {
13887
+ method: "POST",
13888
+ body: formData
13889
+ });
13890
+ setAllLogs((prev) => {
13891
+ const importedIds = new Set(result.logs.map((log) => log.id));
13892
+ const next = [...prev.filter((log) => !importedIds.has(log.id)), ...result.logs].sort(
13893
+ (left, right) => left.id - right.id
13894
+ );
13895
+ const trimmed = trimClientLogs(next);
13896
+ logIndexRef.current = buildLogIndex(trimmed);
13897
+ return trimmed;
13898
+ });
13899
+ setSelectedSession(result.sessionId);
13900
+ setSelectedModel("__all__");
13901
+ setLogPage(null);
13902
+ dismissToast();
13903
+ return result;
13904
+ },
13905
+ [dismissToast]
13906
+ );
13249
13907
  const { strip, captureMode, slowResponseThresholdSeconds, timeDisplayFormat } = useStripConfig();
13250
13908
  const viewMode = captureMode;
13251
13909
  const loadOldestPage = reactExports.useCallback(() => {
@@ -13291,7 +13949,7 @@ function ProxyViewerContainer({
13291
13949
  sessionPageLoading
13292
13950
  ]);
13293
13951
  return /* @__PURE__ */ jsxRuntimeExports.jsxs(jsxRuntimeExports.Fragment, { children: [
13294
- error !== null && /* @__PURE__ */ jsxRuntimeExports.jsx("div", { className: "fixed top-4 right-4 bg-destructive text-destructive-foreground px-4 py-2 rounded-md text-sm z-50", children: error }),
13952
+ /* @__PURE__ */ jsxRuntimeExports.jsx(TransientToast, { notice, onDismiss: dismissToast }),
13295
13953
  /* @__PURE__ */ jsxRuntimeExports.jsx(OnboardingBanner, {}),
13296
13954
  /* @__PURE__ */ jsxRuntimeExports.jsx(
13297
13955
  ProxyViewer,
@@ -13305,6 +13963,7 @@ function ProxyViewerContainer({
13305
13963
  onModelChange: setSelectedModel,
13306
13964
  onClearAll: handleClearAll,
13307
13965
  onClearGroup: handleClearGroup,
13966
+ onNotify: showToast,
13308
13967
  onImportLogs: initialSessionId === void 0 ? handleImportLogs : void 0,
13309
13968
  isLoading: initialSessionId === void 0 ? !streamInitialized : sessionPageLoading,
13310
13969
  pagination,