@tonyclaw/agent-inspector 2.0.3 → 2.0.4

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 (53) hide show
  1. package/.output/nitro.json +1 -1
  2. package/.output/public/assets/{CompareDrawer-D5A4bTfV.js → CompareDrawer-BCH_fsLm.js} +1 -1
  3. package/.output/public/assets/ProxyViewerContainer-D85_UANk.js +101 -0
  4. package/.output/public/assets/{ReplayDialog-CxUk_TF0.js → ReplayDialog-DTeaHHit.js} +1 -1
  5. package/.output/public/assets/RequestAnatomy-DZ8grAih.js +1 -0
  6. package/.output/public/assets/ResponseView-Cldm6RCi.js +1 -0
  7. package/.output/public/assets/{StreamingChunkSequence-DHk4SGGL.js → StreamingChunkSequence-3x4p-yT7.js} +1 -1
  8. package/.output/public/assets/_sessionId-YqWFBu6d.js +1 -0
  9. package/.output/public/assets/index-BIw2H6jO.js +1 -0
  10. package/.output/public/assets/index-CobXD0yH.css +1 -0
  11. package/.output/public/assets/{json-viewer-BbU0n8eM.js → json-viewer-BrzjD7qI.js} +1 -1
  12. package/.output/public/assets/{main-CZT_F-gu.js → main-mgxeUdZQ.js} +2 -2
  13. package/.output/server/{_sessionId-B-s9P7fJ.mjs → _sessionId-C4xsxIWm.mjs} +2 -2
  14. package/.output/server/_ssr/{CompareDrawer-C08L3UOO.mjs → CompareDrawer-DuWEpqQ7.mjs} +3 -3
  15. package/.output/server/_ssr/{ProxyViewerContainer-CMWl3Ijy.mjs → ProxyViewerContainer-Cckz5qKu.mjs} +167 -87
  16. package/.output/server/_ssr/{ReplayDialog-CPDo9_G5.mjs → ReplayDialog-BDRcr8E5.mjs} +4 -4
  17. package/.output/server/_ssr/{RequestAnatomy-D9wt_K1E.mjs → RequestAnatomy-BoO2_Ij0.mjs} +4 -4
  18. package/.output/server/_ssr/{ResponseView-DXaL7nY3.mjs → ResponseView-DZiPBxvO.mjs} +20 -16
  19. package/.output/server/_ssr/{StreamingChunkSequence-B_hudZyb.mjs → StreamingChunkSequence-D-be7KEL.mjs} +3 -3
  20. package/.output/server/_ssr/{index-CuE_BN86.mjs → index-5RImHKfu.mjs} +2 -2
  21. package/.output/server/_ssr/index.mjs +2 -2
  22. package/.output/server/_ssr/{json-viewer-Ci6kkjde.mjs → json-viewer-aJhb93ZK.mjs} +2 -2
  23. package/.output/server/_ssr/{router-BemxgIg7.mjs → router-Dgkv5nKP.mjs} +22 -14
  24. package/.output/server/{_tanstack-start-manifest_v--L1_b4sd.mjs → _tanstack-start-manifest_v-B8rrWXjr.mjs} +1 -1
  25. package/.output/server/index.mjs +61 -61
  26. package/package.json +1 -1
  27. package/src/components/ProxyViewer.tsx +25 -15
  28. package/src/components/ProxyViewerContainer.tsx +2 -1
  29. package/src/components/providers/SettingsDialog.tsx +45 -1
  30. package/src/components/proxy-viewer/AgentTraceSummary.tsx +103 -45
  31. package/src/components/proxy-viewer/AnswerMarkdown.tsx +16 -0
  32. package/src/components/proxy-viewer/ConversationGroup.tsx +12 -0
  33. package/src/components/proxy-viewer/ConversationHeader.tsx +6 -6
  34. package/src/components/proxy-viewer/LogEntry.tsx +5 -5
  35. package/src/components/proxy-viewer/LogEntryHeader.tsx +9 -14
  36. package/src/components/proxy-viewer/ResponseView.tsx +2 -6
  37. package/src/components/proxy-viewer/ToolTraceEvents.tsx +3 -4
  38. package/src/components/proxy-viewer/TurnGroup.tsx +4 -0
  39. package/src/components/proxy-viewer/anatomy/SegmentBar.tsx +2 -2
  40. package/src/components/proxy-viewer/formats/anthropic/ContentBlocks.tsx +6 -12
  41. package/src/components/proxy-viewer/formats/openai/ResponseView.tsx +10 -14
  42. package/src/lib/runtimeConfig.ts +6 -0
  43. package/src/lib/timeDisplay.ts +22 -0
  44. package/src/lib/useOnboarding.ts +2 -0
  45. package/src/lib/useStripConfig.ts +16 -0
  46. package/src/proxy/config.ts +3 -0
  47. package/src/routes/api/config.ts +5 -1
  48. package/.output/public/assets/ProxyViewerContainer-Da0jpBkp.js +0 -101
  49. package/.output/public/assets/RequestAnatomy-DIlzjgjJ.js +0 -1
  50. package/.output/public/assets/ResponseView-DQCuKJ1G.js +0 -1
  51. package/.output/public/assets/_sessionId-dY1TTl7N.js +0 -1
  52. package/.output/public/assets/index-D7wwbwly.css +0 -1
  53. package/.output/public/assets/index-FqQZbfl2.js +0 -1
@@ -1,5 +1,5 @@
1
1
  import { r as reactExports, j as jsxRuntimeExports, a as React } from "../_libs/react.mjs";
2
- import { C as CapturedLogSchema, D as DEFAULT_SLOW_RESPONSE_THRESHOLD_SECONDS, a as RuntimeConfigSchema, r as requestFormatForPath, d as createPendingProviderTestResults, P as ProviderTestResultsSchema, e as createFailedProviderTestResults, M as MAX_SLOW_RESPONSE_THRESHOLD_SECONDS, g as getSessionPath, f as ProviderConfigSchema, K as KnowledgeCandidateSchema, s as stripClaudeCodeBillingHeader, c as safeGetOwnProperty, p as parseOpenAIResponse, O as OpenAIRequestSchema, A as AnthropicResponseSchema$1, b as AnthropicRequestSchema } from "./router-BemxgIg7.mjs";
2
+ import { C as CapturedLogSchema, D as DEFAULT_SLOW_RESPONSE_THRESHOLD_SECONDS, a as DEFAULT_TIME_DISPLAY_FORMAT, b as RuntimeConfigSchema, r as requestFormatForPath, e as createPendingProviderTestResults, P as ProviderTestResultsSchema, f as createFailedProviderTestResults, M as MAX_SLOW_RESPONSE_THRESHOLD_SECONDS, T as TimeDisplayFormatSchema, g as getSessionPath, h as ProviderConfigSchema, K as KnowledgeCandidateSchema, s as stripClaudeCodeBillingHeader, d as safeGetOwnProperty, p as parseOpenAIResponse, O as OpenAIRequestSchema, A as AnthropicResponseSchema$1, c as AnthropicRequestSchema } from "./router-Dgkv5nKP.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";
@@ -71,10 +71,12 @@ function useStripConfig() {
71
71
  const { mutate: globalMutate } = useSWRConfig();
72
72
  const strip = response.data?.stripClaudeCodeBillingHeader ?? false;
73
73
  const slowResponseThresholdSeconds = response.data?.slowResponseThresholdSeconds ?? DEFAULT_SLOW_RESPONSE_THRESHOLD_SECONDS;
74
+ const timeDisplayFormat = response.data?.timeDisplayFormat ?? DEFAULT_TIME_DISPLAY_FORMAT;
74
75
  const optimisticConfig = (patch) => ({
75
76
  stripClaudeCodeBillingHeader: response.data?.stripClaudeCodeBillingHeader ?? false,
76
77
  hasSeenOnboarding: response.data?.hasSeenOnboarding ?? false,
77
78
  slowResponseThresholdSeconds: response.data?.slowResponseThresholdSeconds ?? DEFAULT_SLOW_RESPONSE_THRESHOLD_SECONDS,
79
+ timeDisplayFormat: response.data?.timeDisplayFormat ?? DEFAULT_TIME_DISPLAY_FORMAT,
78
80
  ...patch
79
81
  });
80
82
  const setStrip = async (next) => {
@@ -99,13 +101,22 @@ function useStripConfig() {
99
101
  }
100
102
  );
101
103
  };
104
+ const setTimeDisplayFormat = async (next) => {
105
+ await globalMutate(STRIP_CONFIG_SWR_KEY, setRuntimeConfig({ timeDisplayFormat: next }), {
106
+ optimisticData: optimisticConfig({ timeDisplayFormat: next }),
107
+ rollbackOnError: true,
108
+ revalidate: false
109
+ });
110
+ };
102
111
  return {
103
112
  strip,
104
113
  slowResponseThresholdSeconds,
114
+ timeDisplayFormat,
105
115
  isLoading: response.isLoading,
106
116
  isError: response.error !== void 0,
107
117
  setStrip,
108
- setSlowResponseThresholdSeconds
118
+ setSlowResponseThresholdSeconds,
119
+ setTimeDisplayFormat
109
120
  };
110
121
  }
111
122
  const ONBOARDING_SWR_KEY = "/api/config";
@@ -145,7 +156,8 @@ function useOnboarding() {
145
156
  optimisticData: {
146
157
  stripClaudeCodeBillingHeader: response.data?.stripClaudeCodeBillingHeader ?? false,
147
158
  hasSeenOnboarding: true,
148
- slowResponseThresholdSeconds: response.data?.slowResponseThresholdSeconds ?? DEFAULT_SLOW_RESPONSE_THRESHOLD_SECONDS
159
+ slowResponseThresholdSeconds: response.data?.slowResponseThresholdSeconds ?? DEFAULT_SLOW_RESPONSE_THRESHOLD_SECONDS,
160
+ timeDisplayFormat: response.data?.timeDisplayFormat ?? DEFAULT_TIME_DISPLAY_FORMAT
149
161
  },
150
162
  rollbackOnError: true,
151
163
  revalidate: false
@@ -261,6 +273,21 @@ async function exportLogsAsZip(logs) {
261
273
  document.body.removeChild(anchor);
262
274
  URL.revokeObjectURL(url);
263
275
  }
276
+ function formatTimestamp(iso, format) {
277
+ switch (format) {
278
+ case "full":
279
+ return iso;
280
+ case "time":
281
+ return new Date(iso).toLocaleTimeString([], {
282
+ hour: "2-digit",
283
+ minute: "2-digit",
284
+ second: "2-digit"
285
+ });
286
+ }
287
+ }
288
+ function formatTimestampRange(startedAt, endedAt, format) {
289
+ return `${formatTimestamp(startedAt, format)} - ${formatTimestamp(endedAt, format)}`;
290
+ }
264
291
  function cn(...inputs) {
265
292
  return twMerge(clsx(inputs));
266
293
  }
@@ -275,7 +302,7 @@ function getStatusCategory(status) {
275
302
  if (status >= 500) return "server_error";
276
303
  return "pending";
277
304
  }
278
- const version = "2.0.3";
305
+ const version = "2.0.4";
279
306
  const packageJson = {
280
307
  version
281
308
  };
@@ -469,10 +496,6 @@ const API_FORMAT_LABELS = {
469
496
  openai: "OpenAI",
470
497
  unknown: "Unknown"
471
498
  };
472
- function formatTimestamp(iso) {
473
- const date = new Date(iso);
474
- return date.toLocaleTimeString([], { hour: "2-digit", minute: "2-digit", second: "2-digit" });
475
- }
476
499
  function ConversationHeader({
477
500
  conversationId,
478
501
  startTime,
@@ -486,6 +509,7 @@ function ConversationHeader({
486
509
  hideApiFormat = false,
487
510
  isLoading = false,
488
511
  userAgent,
512
+ timeDisplayFormat,
489
513
  onClear
490
514
  }) {
491
515
  const [confirmOpen, setConfirmOpen] = reactExports.useState(false);
@@ -559,11 +583,7 @@ function ConversationHeader({
559
583
  ),
560
584
  /* @__PURE__ */ jsxRuntimeExports.jsxs("span", { className: "flex items-center gap-1 text-muted-foreground text-xs shrink-0", children: [
561
585
  /* @__PURE__ */ jsxRuntimeExports.jsx(Clock, { className: "size-3" }),
562
- /* @__PURE__ */ jsxRuntimeExports.jsxs("span", { className: "font-mono tabular-nums", children: [
563
- formatTimestamp(startTime),
564
- " - ",
565
- formatTimestamp(endTime)
566
- ] })
586
+ /* @__PURE__ */ jsxRuntimeExports.jsx("span", { className: "font-mono tabular-nums", children: formatTimestampRange(startTime, endTime, timeDisplayFormat) })
567
587
  ] }),
568
588
  /* @__PURE__ */ jsxRuntimeExports.jsxs("span", { className: "flex items-center gap-1 text-muted-foreground text-xs shrink-0", children: [
569
589
  /* @__PURE__ */ jsxRuntimeExports.jsx(MessageSquare, { className: "size-3" }),
@@ -1343,27 +1363,27 @@ function useCopyFeedback(text) {
1343
1363
  return { copied, copy };
1344
1364
  }
1345
1365
  const LazyCompareDrawer = reactExports.lazy(
1346
- () => import("./CompareDrawer-C08L3UOO.mjs").then((m) => ({ default: m.CompareDrawer }))
1366
+ () => import("./CompareDrawer-DuWEpqQ7.mjs").then((m) => ({ default: m.CompareDrawer }))
1347
1367
  );
1348
1368
  const LazyReplayDialog = reactExports.lazy(
1349
- () => import("./ReplayDialog-CPDo9_G5.mjs").then((m) => ({ default: m.ReplayDialog }))
1369
+ () => import("./ReplayDialog-BDRcr8E5.mjs").then((m) => ({ default: m.ReplayDialog }))
1350
1370
  );
1351
1371
  const LazyRequestAnatomy = reactExports.lazy(
1352
- () => import("./RequestAnatomy-D9wt_K1E.mjs").then((m) => ({ default: m.RequestAnatomy }))
1372
+ () => import("./RequestAnatomy-BoO2_Ij0.mjs").then((m) => ({ default: m.RequestAnatomy }))
1353
1373
  );
1354
1374
  const LazyResponseView = reactExports.lazy(
1355
- () => import("./ResponseView-DXaL7nY3.mjs").then((m) => ({ default: m.ResponseView }))
1375
+ () => import("./ResponseView-DZiPBxvO.mjs").then((m) => ({ default: m.ResponseView }))
1356
1376
  );
1357
1377
  const LazyStreamingChunkSequence = reactExports.lazy(
1358
- () => import("./StreamingChunkSequence-B_hudZyb.mjs").then((m) => ({
1378
+ () => import("./StreamingChunkSequence-D-be7KEL.mjs").then((m) => ({
1359
1379
  default: m.StreamingChunkSequence
1360
1380
  }))
1361
1381
  );
1362
1382
  const LazyJsonViewer = reactExports.lazy(
1363
- () => import("./json-viewer-Ci6kkjde.mjs").then((m) => ({ default: m.JsonViewer }))
1383
+ () => import("./json-viewer-aJhb93ZK.mjs").then((m) => ({ default: m.JsonViewer }))
1364
1384
  );
1365
1385
  const LazyJsonViewerFromString = reactExports.lazy(
1366
- () => import("./json-viewer-Ci6kkjde.mjs").then((m) => ({ default: m.JsonViewerFromString }))
1386
+ () => import("./json-viewer-aJhb93ZK.mjs").then((m) => ({ default: m.JsonViewerFromString }))
1367
1387
  );
1368
1388
  const HIGHLIGHT_DURATION_MS = 1200;
1369
1389
  const MAX_HIGHLIGHT_ATTEMPTS = 12;
@@ -1780,17 +1800,16 @@ const LogEntryHeader = reactExports.memo(function({
1780
1800
  toolCount = null,
1781
1801
  expanded,
1782
1802
  onToggle,
1783
- responseToolNames = null,
1784
1803
  cacheTrend = null,
1785
1804
  activeTab,
1786
1805
  tabActions,
1787
1806
  onReplay,
1788
- slowResponseThresholdSeconds = 0
1807
+ slowResponseThresholdSeconds = 0,
1808
+ timeDisplayFormat
1789
1809
  }) {
1790
1810
  const statusCategory = getStatusCategory(log.responseStatus);
1791
1811
  const isSlowResponse = log.elapsedMs !== null && slowResponseThresholdSeconds > 0 && log.elapsedMs > slowResponseThresholdSeconds * 1e3;
1792
1812
  const hasTokens = log.inputTokens !== null || log.outputTokens !== null;
1793
- const toolNamesJoined = reactExports.useMemo(() => responseToolNames?.join(", ") ?? null, [responseToolNames]);
1794
1813
  return /* @__PURE__ */ jsxRuntimeExports.jsx(TooltipProvider, { children: /* @__PURE__ */ jsxRuntimeExports.jsxs(
1795
1814
  "div",
1796
1815
  {
@@ -1819,7 +1838,7 @@ const LogEntryHeader = reactExports.memo(function({
1819
1838
  ] }),
1820
1839
  /* @__PURE__ */ jsxRuntimeExports.jsxs("span", { className: "flex items-center gap-1 text-muted-foreground text-xs shrink-0", children: [
1821
1840
  /* @__PURE__ */ jsxRuntimeExports.jsx(Clock, { className: "size-3" }),
1822
- /* @__PURE__ */ jsxRuntimeExports.jsx("span", { className: "font-mono tabular-nums", children: log.timestamp })
1841
+ /* @__PURE__ */ jsxRuntimeExports.jsx("span", { className: "font-mono tabular-nums", title: log.timestamp, children: formatTimestamp(log.timestamp, timeDisplayFormat) })
1823
1842
  ] }),
1824
1843
  log.model !== null && /* @__PURE__ */ jsxRuntimeExports.jsxs(Tooltip, { children: [
1825
1844
  /* @__PURE__ */ jsxRuntimeExports.jsx(TooltipTrigger, { asChild: true, children: /* @__PURE__ */ jsxRuntimeExports.jsx("span", { className: "shrink-0", children: /* @__PURE__ */ jsxRuntimeExports.jsx(ProviderLogo, { provider: detectProvider(log.model), className: "size-4" }) }) }),
@@ -1912,10 +1931,6 @@ const LogEntryHeader = reactExports.memo(function({
1912
1931
  /* @__PURE__ */ jsxRuntimeExports.jsx(Wrench, { className: "size-3" }),
1913
1932
  /* @__PURE__ */ jsxRuntimeExports.jsx("span", { className: "font-mono tabular-nums", children: toolCount })
1914
1933
  ] }),
1915
- responseToolNames !== null && responseToolNames.length > 0 && /* @__PURE__ */ jsxRuntimeExports.jsxs("span", { className: "flex items-center gap-1 text-amber-400/80 text-xs shrink-0", children: [
1916
- /* @__PURE__ */ jsxRuntimeExports.jsx(Wrench, { className: "size-3" }),
1917
- /* @__PURE__ */ jsxRuntimeExports.jsx("span", { className: "font-mono tabular-nums truncate max-w-[160px]", children: toolNamesJoined })
1918
- ] }),
1919
1934
  log.origin !== null && /* @__PURE__ */ jsxRuntimeExports.jsxs(
1920
1935
  "span",
1921
1936
  {
@@ -2403,6 +2418,7 @@ const LogEntry = reactExports.memo(function({
2403
2418
  viewMode = "simple",
2404
2419
  strip,
2405
2420
  slowResponseThresholdSeconds,
2421
+ timeDisplayFormat,
2406
2422
  cacheTrend = null,
2407
2423
  onCompareWithPrevious
2408
2424
  }) {
@@ -2419,10 +2435,6 @@ const LogEntry = reactExports.memo(function({
2419
2435
  () => adapter.analyzeRequest(log.rawRequestBody),
2420
2436
  [adapter, log.rawRequestBody]
2421
2437
  );
2422
- const responseAnalysis = reactExports.useMemo(
2423
- () => adapter.analyzeResponse(log.responseText),
2424
- [adapter, log.responseText]
2425
- );
2426
2438
  const strippedRequestBody = reactExports.useMemo(() => {
2427
2439
  if (!strip || resolvedFormat !== "anthropic" || log.rawRequestBody === null) {
2428
2440
  return null;
@@ -2555,9 +2567,9 @@ const LogEntry = reactExports.memo(function({
2555
2567
  toolCount: requestAnalysis.toolCount,
2556
2568
  expanded,
2557
2569
  onToggle: () => setExpanded(!expanded),
2558
- responseToolNames: responseAnalysis.toolNames,
2559
2570
  cacheTrend,
2560
2571
  slowResponseThresholdSeconds,
2572
+ timeDisplayFormat,
2561
2573
  activeTab,
2562
2574
  tabActions,
2563
2575
  onReplay: onCompareWithPrevious === void 0 ? void 0 : () => {
@@ -2769,14 +2781,10 @@ function ToolTraceEvents({ events }) {
2769
2781
  return /* @__PURE__ */ jsxRuntimeExports.jsx("div", { className: "mx-3 mb-2 grid gap-1.5", children: events.map((event) => /* @__PURE__ */ jsxRuntimeExports.jsxs(
2770
2782
  "div",
2771
2783
  {
2772
- className: "flex min-w-0 items-center gap-2 rounded-md border border-amber-500/20 bg-amber-500/5 px-2.5 py-1.5 text-xs",
2784
+ className: "flex min-w-0 items-center gap-2 rounded-md border border-border/70 bg-muted/20 px-2.5 py-1.5 text-xs",
2773
2785
  children: [
2774
- /* @__PURE__ */ jsxRuntimeExports.jsx(Wrench, { className: "size-3.5 shrink-0 text-amber-400" }),
2775
- /* @__PURE__ */ jsxRuntimeExports.jsx("span", { className: "font-mono font-semibold text-amber-300", children: event.name }),
2776
- /* @__PURE__ */ jsxRuntimeExports.jsxs("span", { className: "font-mono text-muted-foreground", children: [
2777
- "#",
2778
- event.logId
2779
- ] }),
2786
+ /* @__PURE__ */ jsxRuntimeExports.jsx(Wrench, { className: "size-3.5 shrink-0 text-sky-400/70" }),
2787
+ /* @__PURE__ */ jsxRuntimeExports.jsx("span", { className: "font-mono font-semibold text-foreground/80", children: event.name }),
2780
2788
  event.argumentsPreview !== null && /* @__PURE__ */ jsxRuntimeExports.jsxs(jsxRuntimeExports.Fragment, { children: [
2781
2789
  /* @__PURE__ */ jsxRuntimeExports.jsx(ChevronRight, { className: "size-3 shrink-0 text-muted-foreground/60" }),
2782
2790
  /* @__PURE__ */ jsxRuntimeExports.jsx("span", { className: "min-w-0 truncate font-mono text-muted-foreground", children: event.argumentsPreview })
@@ -2964,7 +2972,8 @@ const TurnGroup = reactExports.memo(function TurnGroup2({
2964
2972
  cacheTrends,
2965
2973
  onCompareWithPrevious,
2966
2974
  comparisonPredecessors,
2967
- turnIndex = 0
2975
+ turnIndex = 0,
2976
+ timeDisplayFormat
2968
2977
  }) {
2969
2978
  const lastIdx = entries.length - 1;
2970
2979
  const lastStop = entries[lastIdx]?.stopReason ?? null;
@@ -3219,6 +3228,7 @@ const TurnGroup = reactExports.memo(function TurnGroup2({
3219
3228
  viewMode,
3220
3229
  strip,
3221
3230
  slowResponseThresholdSeconds,
3231
+ timeDisplayFormat,
3222
3232
  cacheTrend: cacheTrends?.get(log.id) ?? null,
3223
3233
  onCompareWithPrevious: comparisonPredecessors.has(log.id) ? onCompareWithPrevious : void 0
3224
3234
  }
@@ -3239,23 +3249,23 @@ function formatElapsed(ms) {
3239
3249
  if (ms < 1e3) return `${String(ms)}ms`;
3240
3250
  return `${(ms / 1e3).toFixed(1)}s`;
3241
3251
  }
3242
- function formatTimeRange$1(startedAt, endedAt) {
3252
+ function formatTimeRange$1(startedAt, endedAt, timeDisplayFormat) {
3243
3253
  if (startedAt === null || endedAt === null) return null;
3244
- const format = (iso) => new Date(iso).toLocaleTimeString([], {
3245
- hour: "2-digit",
3246
- minute: "2-digit",
3247
- second: "2-digit"
3248
- });
3249
- return `${format(startedAt)} - ${format(endedAt)}`;
3254
+ return formatTimestampRange(startedAt, endedAt, timeDisplayFormat);
3255
+ }
3256
+ function formatCandidateCount(count) {
3257
+ return `${String(count)} candidate${count === 1 ? "" : "s"}`;
3250
3258
  }
3251
- function scrollToLog(logId) {
3252
- const target = document.getElementById(`log-${String(logId)}`);
3259
+ function getLogAnchor(logId) {
3260
+ return `log-${String(logId)}`;
3261
+ }
3262
+ function jumpToLog(logId) {
3263
+ const anchor = getLogAnchor(logId);
3264
+ const target = document.getElementById(anchor);
3265
+ window.history.replaceState(null, "", `#${anchor}`);
3253
3266
  if (!(target instanceof HTMLElement)) return;
3254
3267
  target.scrollIntoView({ block: "center", behavior: "smooth" });
3255
3268
  target.focus({ preventScroll: true });
3256
- if (target.getAttribute("data-nav-action") === "expand") {
3257
- target.click();
3258
- }
3259
3269
  }
3260
3270
  function CandidateList({ candidates }) {
3261
3271
  if (candidates.length === 0) return null;
@@ -3270,11 +3280,15 @@ function CandidateList({ candidates }) {
3270
3280
  /* @__PURE__ */ jsxRuntimeExports.jsx("span", { className: "shrink-0 font-mono text-[10px] text-muted-foreground", children: candidate.status })
3271
3281
  ] }),
3272
3282
  /* @__PURE__ */ jsxRuntimeExports.jsx("div", { className: "mt-1 flex flex-wrap items-center gap-1.5", children: candidate.logIds.map((logId) => /* @__PURE__ */ jsxRuntimeExports.jsxs(
3273
- "button",
3283
+ "a",
3274
3284
  {
3275
- type: "button",
3276
- onClick: () => scrollToLog(logId),
3277
- className: "rounded border border-border px-1.5 py-0.5 font-mono text-[10px] text-blue-400 transition-colors hover:bg-muted hover:text-blue-300",
3285
+ href: `#${getLogAnchor(logId)}`,
3286
+ onClick: (event) => {
3287
+ event.preventDefault();
3288
+ jumpToLog(logId);
3289
+ },
3290
+ 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",
3291
+ "aria-label": `Jump to evidence log ${String(logId)}`,
3278
3292
  children: [
3279
3293
  "#",
3280
3294
  logId
@@ -3290,20 +3304,25 @@ function CandidateList({ candidates }) {
3290
3304
  function AgentTraceSummary({
3291
3305
  logs,
3292
3306
  scopeId,
3293
- slowResponseThresholdSeconds
3307
+ slowResponseThresholdSeconds,
3308
+ showRollupMetrics,
3309
+ timeDisplayFormat
3294
3310
  }) {
3295
3311
  const [candidates, setCandidates] = reactExports.useState([]);
3312
+ const [candidatesExpanded, setCandidatesExpanded] = reactExports.useState(true);
3296
3313
  const [candidateState, setCandidateState] = reactExports.useState({
3297
3314
  status: "idle",
3298
3315
  error: null
3299
3316
  });
3317
+ const hasCandidates = candidates.length > 0;
3300
3318
  const summary = reactExports.useMemo(
3301
3319
  () => buildTraceSummary(logs, slowResponseThresholdSeconds, candidates.length),
3302
3320
  [candidates.length, logs, slowResponseThresholdSeconds]
3303
3321
  );
3322
+ const showElapsedSummary = showRollupMetrics || summary.maxElapsedMs !== null;
3304
3323
  const timeRange = reactExports.useMemo(
3305
- () => formatTimeRange$1(summary.startedAt, summary.endedAt),
3306
- [summary.endedAt, summary.startedAt]
3324
+ () => formatTimeRange$1(summary.startedAt, summary.endedAt, timeDisplayFormat),
3325
+ [summary.endedAt, summary.startedAt, timeDisplayFormat]
3307
3326
  );
3308
3327
  const createCandidates = reactExports.useCallback(() => {
3309
3328
  if (logs.length === 0 || candidateState.status === "loading") return;
@@ -3324,6 +3343,7 @@ function AgentTraceSummary({
3324
3343
  }
3325
3344
  const parsed = await parseJsonResponse$1(response, CandidateResponseSchema);
3326
3345
  setCandidates(parsed.candidates);
3346
+ setCandidatesExpanded(parsed.candidates.length > 0);
3327
3347
  setCandidateState({ status: "ready", error: null });
3328
3348
  } catch (error) {
3329
3349
  setCandidateState({
@@ -3336,17 +3356,17 @@ function AgentTraceSummary({
3336
3356
  if (logs.length === 0) return null;
3337
3357
  return /* @__PURE__ */ jsxRuntimeExports.jsxs("section", { className: "mb-2 rounded-lg border border-border bg-muted/10 px-3 py-2", children: [
3338
3358
  /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "flex flex-wrap items-center gap-x-3 gap-y-2 text-xs", children: [
3339
- /* @__PURE__ */ jsxRuntimeExports.jsxs("span", { className: "inline-flex items-center gap-1.5 font-semibold text-foreground", children: [
3359
+ showRollupMetrics && /* @__PURE__ */ jsxRuntimeExports.jsxs("span", { className: "inline-flex items-center gap-1.5 font-semibold text-foreground", children: [
3340
3360
  /* @__PURE__ */ jsxRuntimeExports.jsx(MessageSquare, { className: "size-3.5 text-blue-400" }),
3341
3361
  summary.llmCallCount,
3342
3362
  " LLM"
3343
3363
  ] }),
3344
3364
  /* @__PURE__ */ jsxRuntimeExports.jsxs("span", { className: "inline-flex items-center gap-1.5 text-muted-foreground", children: [
3345
- /* @__PURE__ */ jsxRuntimeExports.jsx(Wrench, { className: "size-3.5 text-amber-400" }),
3365
+ /* @__PURE__ */ jsxRuntimeExports.jsx(Wrench, { className: "size-3.5 text-sky-400/70" }),
3346
3366
  summary.toolCallCount,
3347
3367
  " tools"
3348
3368
  ] }),
3349
- /* @__PURE__ */ jsxRuntimeExports.jsxs("span", { className: "inline-flex items-center gap-1.5 text-muted-foreground", children: [
3369
+ showRollupMetrics && /* @__PURE__ */ jsxRuntimeExports.jsxs("span", { className: "inline-flex items-center gap-1.5 text-muted-foreground", children: [
3350
3370
  /* @__PURE__ */ jsxRuntimeExports.jsx(Zap, { className: "size-3.5 text-emerald-400" }),
3351
3371
  /* @__PURE__ */ jsxRuntimeExports.jsxs("span", { className: "font-mono", children: [
3352
3372
  formatTokens(summary.totalInputTokens),
@@ -3363,15 +3383,15 @@ function AgentTraceSummary({
3363
3383
  formatTokens(summary.totalCacheReadInputTokens)
3364
3384
  ] })
3365
3385
  ] }),
3366
- /* @__PURE__ */ jsxRuntimeExports.jsxs("span", { className: "inline-flex items-center gap-1.5 text-muted-foreground", children: [
3386
+ showElapsedSummary && /* @__PURE__ */ jsxRuntimeExports.jsxs("span", { className: "inline-flex items-center gap-1.5 text-muted-foreground", children: [
3367
3387
  /* @__PURE__ */ jsxRuntimeExports.jsx(Clock, { className: "size-3.5" }),
3368
- /* @__PURE__ */ jsxRuntimeExports.jsx("span", { className: "font-mono", children: formatElapsed(summary.totalElapsedMs) }),
3388
+ showRollupMetrics && /* @__PURE__ */ jsxRuntimeExports.jsx("span", { className: "font-mono", children: formatElapsed(summary.totalElapsedMs) }),
3369
3389
  summary.maxElapsedMs !== null && /* @__PURE__ */ jsxRuntimeExports.jsxs("span", { className: "font-mono text-muted-foreground/70", children: [
3370
3390
  "max ",
3371
3391
  formatElapsed(summary.maxElapsedMs)
3372
3392
  ] })
3373
3393
  ] }),
3374
- timeRange !== null && /* @__PURE__ */ jsxRuntimeExports.jsx("span", { className: "font-mono text-muted-foreground/70", children: timeRange }),
3394
+ showRollupMetrics && timeRange !== null && /* @__PURE__ */ jsxRuntimeExports.jsx("span", { className: "font-mono text-muted-foreground/70", children: timeRange }),
3375
3395
  (summary.failedCallCount > 0 || summary.pendingCallCount > 0 || summary.slowCallCount > 0) && /* @__PURE__ */ jsxRuntimeExports.jsxs("span", { className: "inline-flex items-center gap-1.5 text-amber-400", children: [
3376
3396
  /* @__PURE__ */ jsxRuntimeExports.jsx(TriangleAlert, { className: "size-3.5" }),
3377
3397
  /* @__PURE__ */ jsxRuntimeExports.jsxs("span", { className: "font-mono", children: [
@@ -3385,10 +3405,7 @@ function AgentTraceSummary({
3385
3405
  ] })
3386
3406
  ] }),
3387
3407
  /* @__PURE__ */ jsxRuntimeExports.jsx("span", { className: "flex-1" }),
3388
- /* @__PURE__ */ jsxRuntimeExports.jsxs(Badge, { variant: "outline", className: "h-6 px-2 text-[10px] font-mono", children: [
3389
- summary.knowledgeCandidateCount,
3390
- " memory"
3391
- ] }),
3408
+ hasCandidates && /* @__PURE__ */ jsxRuntimeExports.jsx(Badge, { variant: "outline", className: "h-6 px-2 text-[10px] font-mono", children: formatCandidateCount(summary.knowledgeCandidateCount) }),
3392
3409
  /* @__PURE__ */ jsxRuntimeExports.jsxs(
3393
3410
  Button,
3394
3411
  {
@@ -3403,10 +3420,23 @@ function AgentTraceSummary({
3403
3420
  "Candidate"
3404
3421
  ]
3405
3422
  }
3423
+ ),
3424
+ hasCandidates && /* @__PURE__ */ jsxRuntimeExports.jsx(
3425
+ Button,
3426
+ {
3427
+ type: "button",
3428
+ variant: "ghost",
3429
+ size: "icon",
3430
+ className: "size-7 text-muted-foreground",
3431
+ onClick: () => setCandidatesExpanded((value) => !value),
3432
+ "aria-expanded": candidatesExpanded,
3433
+ "aria-label": candidatesExpanded ? "Collapse memory candidates" : "Expand memory candidates",
3434
+ children: candidatesExpanded ? /* @__PURE__ */ jsxRuntimeExports.jsx(ChevronDown, { className: "size-3.5" }) : /* @__PURE__ */ jsxRuntimeExports.jsx(ChevronRight, { className: "size-3.5" })
3435
+ }
3406
3436
  )
3407
3437
  ] }),
3408
3438
  candidateState.status === "failed" && /* @__PURE__ */ jsxRuntimeExports.jsx("p", { className: "mt-2 text-xs text-destructive", children: candidateState.error }),
3409
- /* @__PURE__ */ jsxRuntimeExports.jsx(CandidateList, { candidates })
3439
+ candidatesExpanded && /* @__PURE__ */ jsxRuntimeExports.jsx(CandidateList, { candidates })
3410
3440
  ] });
3411
3441
  }
3412
3442
  function computeStats(logs) {
@@ -3427,7 +3457,9 @@ const ConversationGroup = reactExports.memo(function({
3427
3457
  onCompareWithPrevious,
3428
3458
  comparisonPredecessors,
3429
3459
  onClearGroup,
3430
- standalone = false
3460
+ standalone = false,
3461
+ hasPinnedSessionContext = false,
3462
+ timeDisplayFormat
3431
3463
  }) {
3432
3464
  const [expanded, setExpanded] = reactExports.useState(false);
3433
3465
  const stats = reactExports.useMemo(() => computeStats(group.logs), [group.logs]);
@@ -3435,6 +3467,7 @@ const ConversationGroup = reactExports.memo(function({
3435
3467
  const endTime = group.logs[group.logs.length - 1]?.timestamp ?? (/* @__PURE__ */ new Date()).toISOString();
3436
3468
  const mixed = hasMixedApiFormat(group.logs);
3437
3469
  const isLoading = group.logs.some((log) => log.responseStatus === null);
3470
+ const showTraceRollupMetrics = standalone && !hasPinnedSessionContext;
3438
3471
  const turnGroups = reactExports.useMemo(() => buildTurnGroups(group.logs), [group.logs]);
3439
3472
  return /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "mb-2", children: [
3440
3473
  !standalone && /* @__PURE__ */ jsxRuntimeExports.jsx(
@@ -3452,6 +3485,7 @@ const ConversationGroup = reactExports.memo(function({
3452
3485
  hideApiFormat: mixed,
3453
3486
  isLoading,
3454
3487
  userAgent: group.logs[0]?.userAgent ?? null,
3488
+ timeDisplayFormat,
3455
3489
  onClear: () => onClearGroup(group.logs.map((l) => l.id))
3456
3490
  }
3457
3491
  ),
@@ -3461,7 +3495,9 @@ const ConversationGroup = reactExports.memo(function({
3461
3495
  {
3462
3496
  logs: group.logs,
3463
3497
  scopeId: group.conversationId,
3464
- slowResponseThresholdSeconds
3498
+ slowResponseThresholdSeconds,
3499
+ showRollupMetrics: showTraceRollupMetrics,
3500
+ timeDisplayFormat
3465
3501
  }
3466
3502
  ),
3467
3503
  turnGroups.map((tg) => /* @__PURE__ */ jsxRuntimeExports.jsx(
@@ -3471,6 +3507,7 @@ const ConversationGroup = reactExports.memo(function({
3471
3507
  viewMode,
3472
3508
  strip,
3473
3509
  slowResponseThresholdSeconds,
3510
+ timeDisplayFormat,
3474
3511
  cacheTrends,
3475
3512
  onCompareWithPrevious,
3476
3513
  comparisonPredecessors,
@@ -5336,9 +5373,11 @@ function ProxySettingsTab() {
5336
5373
  const {
5337
5374
  strip,
5338
5375
  slowResponseThresholdSeconds,
5376
+ timeDisplayFormat,
5339
5377
  isLoading,
5340
5378
  setStrip,
5341
- setSlowResponseThresholdSeconds
5379
+ setSlowResponseThresholdSeconds,
5380
+ setTimeDisplayFormat
5342
5381
  } = useStripConfig();
5343
5382
  const [error, setError] = reactExports.useState(null);
5344
5383
  const [pending, setPending] = reactExports.useState(false);
@@ -5370,6 +5409,20 @@ function ProxySettingsTab() {
5370
5409
  },
5371
5410
  [setSlowResponseThresholdSeconds]
5372
5411
  );
5412
+ const handleTimeDisplayFormatChange = reactExports.useCallback(
5413
+ async (next) => {
5414
+ setError(null);
5415
+ setPending(true);
5416
+ try {
5417
+ await setTimeDisplayFormat(next);
5418
+ } catch (err) {
5419
+ setError(err instanceof Error ? err.message : String(err));
5420
+ } finally {
5421
+ setPending(false);
5422
+ }
5423
+ },
5424
+ [setTimeDisplayFormat]
5425
+ );
5373
5426
  return /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "space-y-4", children: [
5374
5427
  /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "space-y-1", children: [
5375
5428
  /* @__PURE__ */ jsxRuntimeExports.jsx("h3", { className: "text-sm font-semibold", children: "Claude Code billing header" }),
@@ -5430,6 +5483,28 @@ function ProxySettingsTab() {
5430
5483
  /* @__PURE__ */ jsxRuntimeExports.jsx("span", { className: "text-xs text-muted-foreground", children: "seconds" })
5431
5484
  ] })
5432
5485
  ] }),
5486
+ /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "space-y-1", children: [
5487
+ /* @__PURE__ */ jsxRuntimeExports.jsx("label", { htmlFor: "time-display-format", className: "text-sm font-semibold", children: "Time display" }),
5488
+ /* @__PURE__ */ jsxRuntimeExports.jsx("p", { className: "text-xs text-muted-foreground", children: "Controls timestamps in session summaries, conversation headers, and log rows." }),
5489
+ /* @__PURE__ */ jsxRuntimeExports.jsxs(
5490
+ "select",
5491
+ {
5492
+ id: "time-display-format",
5493
+ value: timeDisplayFormat,
5494
+ disabled: isLoading || pending,
5495
+ onChange: (event) => {
5496
+ const parsed = TimeDisplayFormatSchema.safeParse(event.currentTarget.value);
5497
+ if (!parsed.success) return;
5498
+ void handleTimeDisplayFormatChange(parsed.data);
5499
+ },
5500
+ className: "h-8 rounded-md border border-input bg-background px-2 text-sm disabled:cursor-not-allowed disabled:opacity-50",
5501
+ children: [
5502
+ /* @__PURE__ */ jsxRuntimeExports.jsx("option", { value: "time", children: "Time only" }),
5503
+ /* @__PURE__ */ jsxRuntimeExports.jsx("option", { value: "full", children: "Full ISO" })
5504
+ ]
5505
+ }
5506
+ )
5507
+ ] }),
5433
5508
  error !== null && /* @__PURE__ */ jsxRuntimeExports.jsxs("p", { className: "text-xs text-destructive", children: [
5434
5509
  "Failed to save: ",
5435
5510
  error
@@ -5616,16 +5691,11 @@ function computeTokenSummary(logs) {
5616
5691
  }
5617
5692
  return { totalIn, totalOut };
5618
5693
  }
5619
- function formatTimeRange(logs) {
5694
+ function formatTimeRange(logs, timeDisplayFormat) {
5620
5695
  const first = logs[0];
5621
5696
  const last = logs[logs.length - 1];
5622
5697
  if (first === void 0 || last === void 0) return null;
5623
- const format = (iso) => new Date(iso).toLocaleTimeString([], {
5624
- hour: "2-digit",
5625
- minute: "2-digit",
5626
- second: "2-digit"
5627
- });
5628
- return `${format(first.timestamp)} - ${format(last.timestamp)}`;
5698
+ return formatTimestampRange(first.timestamp, last.timestamp, timeDisplayFormat);
5629
5699
  }
5630
5700
  function getFirstUserAgent(logs) {
5631
5701
  for (const log of logs) {
@@ -5700,10 +5770,14 @@ function SessionContextBar({
5700
5770
  sessionId,
5701
5771
  logs,
5702
5772
  totalIn,
5703
- totalOut
5773
+ totalOut,
5774
+ timeDisplayFormat
5704
5775
  }) {
5705
5776
  const [copied, setCopied] = reactExports.useState(false);
5706
- const timeRange = reactExports.useMemo(() => formatTimeRange(logs), [logs]);
5777
+ const timeRange = reactExports.useMemo(
5778
+ () => formatTimeRange(logs, timeDisplayFormat),
5779
+ [logs, timeDisplayFormat]
5780
+ );
5707
5781
  const userAgent = reactExports.useMemo(() => getFirstUserAgent(logs), [logs]);
5708
5782
  const handleCopyLink = reactExports.useCallback(() => {
5709
5783
  void window.navigator.clipboard.writeText(window.location.href).then(() => {
@@ -5776,6 +5850,7 @@ function ProxyViewer({
5776
5850
  onViewModeChange,
5777
5851
  strip,
5778
5852
  slowResponseThresholdSeconds,
5853
+ timeDisplayFormat,
5779
5854
  hideSessionFilter = false,
5780
5855
  pinnedSessionId
5781
5856
  }) {
@@ -5822,6 +5897,7 @@ function ProxyViewer({
5822
5897
  setComparePair(null);
5823
5898
  }, []);
5824
5899
  const groups = reactExports.useMemo(() => groupLogsByConversation(logs), [logs]);
5900
+ const hasPinnedSessionContext = pinnedSessionId !== void 0;
5825
5901
  const cacheTrends = reactExports.useMemo(() => computeCacheTrends(groups), [groups]);
5826
5902
  const comparisonPredecessors = reactExports.useMemo(() => buildValidPredecessors(groups), [groups]);
5827
5903
  const handleCompareWithPrevious = reactExports.useCallback(
@@ -5895,7 +5971,8 @@ function ProxyViewer({
5895
5971
  sessionId: pinnedSessionId,
5896
5972
  logs,
5897
5973
  totalIn,
5898
- totalOut
5974
+ totalOut,
5975
+ timeDisplayFormat
5899
5976
  }
5900
5977
  ),
5901
5978
  /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "flex items-center gap-3 mb-4", children: [
@@ -5934,7 +6011,7 @@ function ProxyViewer({
5934
6011
  )
5935
6012
  ] }),
5936
6013
  /* @__PURE__ */ jsxRuntimeExports.jsx("div", { className: "flex-1" }),
5937
- /* @__PURE__ */ jsxRuntimeExports.jsxs("span", { className: "text-muted-foreground text-xs font-mono", children: [
6014
+ !hasPinnedSessionContext && /* @__PURE__ */ jsxRuntimeExports.jsxs("span", { className: "text-muted-foreground text-xs font-mono", children: [
5938
6015
  logs.length,
5939
6016
  " request",
5940
6017
  logs.length !== 1 ? "s" : "",
@@ -6005,7 +6082,9 @@ function ProxyViewer({
6005
6082
  onCompareWithPrevious: handleCompareWithPrevious,
6006
6083
  comparisonPredecessors,
6007
6084
  onClearGroup,
6008
- standalone: groups.length === 1
6085
+ standalone: groups.length === 1,
6086
+ hasPinnedSessionContext,
6087
+ timeDisplayFormat
6009
6088
  },
6010
6089
  group.id
6011
6090
  )) })
@@ -6263,7 +6342,7 @@ function ProxyViewerContainer({
6263
6342
  }
6264
6343
  })();
6265
6344
  }, []);
6266
- const { strip, slowResponseThresholdSeconds } = useStripConfig();
6345
+ const { strip, slowResponseThresholdSeconds, timeDisplayFormat } = useStripConfig();
6267
6346
  return /* @__PURE__ */ jsxRuntimeExports.jsxs(jsxRuntimeExports.Fragment, { children: [
6268
6347
  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 }),
6269
6348
  /* @__PURE__ */ jsxRuntimeExports.jsx(OnboardingBanner, {}),
@@ -6283,6 +6362,7 @@ function ProxyViewerContainer({
6283
6362
  onViewModeChange: setViewMode,
6284
6363
  strip,
6285
6364
  slowResponseThresholdSeconds,
6365
+ timeDisplayFormat,
6286
6366
  hideSessionFilter: initialSessionId !== void 0,
6287
6367
  pinnedSessionId: initialSessionId
6288
6368
  }
@@ -1,10 +1,10 @@
1
1
  import { r as reactExports, j as jsxRuntimeExports } from "../_libs/react.mjs";
2
- import { D as Dialog, b as DialogContent, d as DialogHeader, e as DialogTitle, T as Tabs, h as TabsList, i as TabsTrigger, j as TabsContent, k as TooltipProvider, l as Tooltip, m as TooltipTrigger, n as TooltipContent, o as Button } from "./ProxyViewerContainer-CMWl3Ijy.mjs";
3
- import { ResponseView } from "./ResponseView-DXaL7nY3.mjs";
4
- import "./router-BemxgIg7.mjs";
2
+ import { D as Dialog, b as DialogContent, d as DialogHeader, e as DialogTitle, T as Tabs, h as TabsList, i as TabsTrigger, j as TabsContent, k as TooltipProvider, l as Tooltip, m as TooltipTrigger, n as TooltipContent, o as Button } from "./ProxyViewerContainer-Cckz5qKu.mjs";
3
+ import { ResponseView } from "./ResponseView-DZiPBxvO.mjs";
4
+ import "./router-Dgkv5nKP.mjs";
5
5
  import "../_libs/modelcontextprotocol__server.mjs";
6
6
  import "../_libs/jszip.mjs";
7
- import "./json-viewer-Ci6kkjde.mjs";
7
+ import "./json-viewer-aJhb93ZK.mjs";
8
8
  import { s as RotateCcw } from "../_libs/lucide-react.mjs";
9
9
  import { d as object, c as boolean, n as number, b as string } from "../_libs/zod.mjs";
10
10
  import "../_libs/swr.mjs";