@tonyclaw/agent-inspector 2.0.42 → 2.0.43

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 (32) hide show
  1. package/.output/nitro.json +1 -1
  2. package/.output/public/assets/{CompareDrawer-Cfqxlo-U.js → CompareDrawer-CxM1gCfL.js} +1 -1
  3. package/.output/public/assets/{ProxyViewerContainer-CE9pAX4c.js → ProxyViewerContainer-TtRG-0E7.js} +37 -37
  4. package/.output/public/assets/{ReplayDialog-daRidZo_.js → ReplayDialog-UseUkucS.js} +1 -1
  5. package/.output/public/assets/{RequestAnatomy-CJ7EPQGQ.js → RequestAnatomy-aPxgEJ2L.js} +1 -1
  6. package/.output/public/assets/{ResponseView-xBmr54hB.js → ResponseView-DA-F4F97.js} +1 -1
  7. package/.output/public/assets/{StreamingChunkSequence-nK-0LpbM.js → StreamingChunkSequence-JSQEPeNS.js} +1 -1
  8. package/.output/public/assets/_sessionId-BEXuCWq5.js +1 -0
  9. package/.output/public/assets/index-Bhsa_2xX.js +1 -0
  10. package/.output/public/assets/index-DOWlRJ0W.css +1 -0
  11. package/.output/public/assets/{main-DOy_Q96H.js → main-BpGVJcpB.js} +2 -2
  12. package/.output/server/{_sessionId-DtYRZHlM.mjs → _sessionId-DGn-TENM.mjs} +2 -2
  13. package/.output/server/_ssr/{CompareDrawer-fy1ARwtx.mjs → CompareDrawer-CFElCSYY.mjs} +2 -2
  14. package/.output/server/_ssr/{ProxyViewerContainer-9GJtCWCq.mjs → ProxyViewerContainer-B7SR9mrD.mjs} +258 -76
  15. package/.output/server/_ssr/{ReplayDialog-BrS7syOE.mjs → ReplayDialog-DfKapj0k.mjs} +3 -3
  16. package/.output/server/_ssr/{RequestAnatomy-BtWt1cWY.mjs → RequestAnatomy-CUxTCg31.mjs} +2 -2
  17. package/.output/server/_ssr/{ResponseView-CkKGYE6m.mjs → ResponseView-BXY0w197.mjs} +2 -2
  18. package/.output/server/_ssr/{StreamingChunkSequence-C7rB3osr.mjs → StreamingChunkSequence-CzMnES9H.mjs} +2 -2
  19. package/.output/server/_ssr/{index-D24WforP.mjs → index-CVlT-REW.mjs} +2 -2
  20. package/.output/server/_ssr/index.mjs +2 -2
  21. package/.output/server/_ssr/{router-CVqVjBzJ.mjs → router-B2d1LUx6.mjs} +4 -4
  22. package/.output/server/{_tanstack-start-manifest_v-DSikvwru.mjs → _tanstack-start-manifest_v-Drpi28BM.mjs} +1 -1
  23. package/.output/server/index.mjs +61 -61
  24. package/package.json +1 -1
  25. package/src/components/ProxyViewer.tsx +156 -17
  26. package/src/components/ProxyViewerContainer.tsx +66 -4
  27. package/src/components/groups/GroupsDialog.tsx +11 -10
  28. package/src/components/proxy-viewer/LogEntry.tsx +107 -56
  29. package/src/components/ui/dialog.tsx +1 -1
  30. package/.output/public/assets/_sessionId-CbWEG5ej.js +0 -1
  31. package/.output/public/assets/index-BfGJEb-2.css +0 -1
  32. package/.output/public/assets/index-D1MkoT4l.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_CAPTURE_MODE, a as DEFAULT_SLOW_RESPONSE_THRESHOLD_SECONDS, b as DEFAULT_PROVIDER_TEST_TIMEOUT_SECONDS, c as DEFAULT_TIME_DISPLAY_FORMAT, v as packageJson, i as GroupEvidenceExportResultSchema, j as DeleteInspectorGroupResponseSchema, d as RuntimeConfigSchema, P as ProviderConfigSchema, f as apiFormatForPath, n as createPendingProviderTestResults, o as ProviderTestResultsSchema, q as createFailedProviderTestResults, M as MAX_SLOW_RESPONSE_THRESHOLD_SECONDS, r as MAX_PROVIDER_TEST_TIMEOUT_SECONDS, T as TimeDisplayFormatSchema, m as maskApiKey, k as providerHasContextMetadata, l as findProviderModelMetadata, g as getSessionPath, p as parseOpenAIResponse, O as OpenAIRequestSchema, A as AnthropicResponseSchema$1, e as AnthropicRequestSchema, s as safeGetOwnProperty, t as resolveProviderContextWindow, K as KnowledgeCandidateSchema, h as stripClaudeCodeBillingHeader, u as isPlainRecord, G as GroupEvidenceReadResponseSchema, I as InspectorGroupsListResponseSchema } from "./router-CVqVjBzJ.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, v as packageJson, i as GroupEvidenceExportResultSchema, j as DeleteInspectorGroupResponseSchema, d as RuntimeConfigSchema, P as ProviderConfigSchema, f as apiFormatForPath, n as createPendingProviderTestResults, o as ProviderTestResultsSchema, q as createFailedProviderTestResults, M as MAX_SLOW_RESPONSE_THRESHOLD_SECONDS, r as MAX_PROVIDER_TEST_TIMEOUT_SECONDS, T as TimeDisplayFormatSchema, m as maskApiKey, k as providerHasContextMetadata, l as findProviderModelMetadata, g as getSessionPath, p as parseOpenAIResponse, O as OpenAIRequestSchema, A as AnthropicResponseSchema$1, e as AnthropicRequestSchema, s as safeGetOwnProperty, t as resolveProviderContextWindow, K as KnowledgeCandidateSchema, h as stripClaudeCodeBillingHeader, u as isPlainRecord, G as GroupEvidenceReadResponseSchema } from "./router-B2d1LUx6.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";
@@ -629,7 +629,7 @@ function DialogOverlay({
629
629
  {
630
630
  "data-slot": "dialog-overlay",
631
631
  className: cn(
632
- "fixed inset-0 z-50 bg-black/80 data-[state=open]:animate-in data-[state=closed]:animate-out data-[state=closed]:fade-out-0 data-[state=open]:fade-in-0",
632
+ "fixed inset-0 z-40 bg-black/80 data-[state=open]:animate-in data-[state=closed]:animate-out data-[state=closed]:fade-out-0 data-[state=open]:fade-in-0",
633
633
  className
634
634
  ),
635
635
  ...props
@@ -1937,19 +1937,19 @@ function useCopyFeedback(text) {
1937
1937
  return { copied, copy };
1938
1938
  }
1939
1939
  const LazyCompareDrawer = reactExports.lazy(
1940
- () => import("./CompareDrawer-fy1ARwtx.mjs").then((m) => ({ default: m.CompareDrawer }))
1940
+ () => import("./CompareDrawer-CFElCSYY.mjs").then((m) => ({ default: m.CompareDrawer }))
1941
1941
  );
1942
1942
  const LazyReplayDialog = reactExports.lazy(
1943
- () => import("./ReplayDialog-BrS7syOE.mjs").then((m) => ({ default: m.ReplayDialog }))
1943
+ () => import("./ReplayDialog-DfKapj0k.mjs").then((m) => ({ default: m.ReplayDialog }))
1944
1944
  );
1945
1945
  const LazyRequestAnatomy = reactExports.lazy(
1946
- () => import("./RequestAnatomy-BtWt1cWY.mjs").then((m) => ({ default: m.RequestAnatomy }))
1946
+ () => import("./RequestAnatomy-CUxTCg31.mjs").then((m) => ({ default: m.RequestAnatomy }))
1947
1947
  );
1948
1948
  const LazyResponseView = reactExports.lazy(
1949
- () => import("./ResponseView-CkKGYE6m.mjs").then((m) => ({ default: m.ResponseView }))
1949
+ () => import("./ResponseView-BXY0w197.mjs").then((m) => ({ default: m.ResponseView }))
1950
1950
  );
1951
1951
  const LazyStreamingChunkSequence = reactExports.lazy(
1952
- () => import("./StreamingChunkSequence-C7rB3osr.mjs").then((m) => ({
1952
+ () => import("./StreamingChunkSequence-CzMnES9H.mjs").then((m) => ({
1953
1953
  default: m.StreamingChunkSequence
1954
1954
  }))
1955
1955
  );
@@ -3505,6 +3505,9 @@ function resolveFocusedTab(tab, anatomySegments) {
3505
3505
  return "request";
3506
3506
  }
3507
3507
  }
3508
+ function shouldHydrateLogBody(log) {
3509
+ return log.bodyContentMode === "compact" || log.bodyContentMode === "truncated";
3510
+ }
3508
3511
  function DiffToggleButton({
3509
3512
  active,
3510
3513
  onClick
@@ -3561,40 +3564,43 @@ const LogEntry = reactExports.memo(function({
3561
3564
  const [requestDiff, setRequestDiff] = reactExports.useState(false);
3562
3565
  const [activeTab, setActiveTab] = reactExports.useState("request");
3563
3566
  const [expandToPath, setExpandToPath] = reactExports.useState(null);
3567
+ const [hydratedLog, setHydratedLog] = reactExports.useState(null);
3568
+ const [bodyHydrationState, setBodyHydrationState] = reactExports.useState("idle");
3564
3569
  const requestJsonRef = reactExports.useRef(null);
3565
- const resolvedFormat = resolveLogFormat(log);
3570
+ const displayLog = hydratedLog ?? log;
3571
+ const resolvedFormat = resolveLogFormat(displayLog);
3566
3572
  const adapter = getLogFormatAdapter(resolvedFormat);
3567
3573
  const requestAnalysis = reactExports.useMemo(
3568
- () => adapter.analyzeRequest(log.rawRequestBody),
3569
- [adapter, log.rawRequestBody]
3574
+ () => adapter.analyzeRequest(displayLog.rawRequestBody),
3575
+ [adapter, displayLog.rawRequestBody]
3570
3576
  );
3571
3577
  const responseAnalysis = reactExports.useMemo(
3572
- () => adapter.analyzeResponse(log.responseText),
3573
- [adapter, log.responseText]
3578
+ () => adapter.analyzeResponse(displayLog.responseText),
3579
+ [adapter, displayLog.responseText]
3574
3580
  );
3575
3581
  const strippedRequestBody = reactExports.useMemo(() => {
3576
- if (!strip || resolvedFormat !== "anthropic" || log.rawRequestBody === null) {
3582
+ if (!strip || resolvedFormat !== "anthropic" || displayLog.rawRequestBody === null) {
3577
3583
  return null;
3578
3584
  }
3579
- return stripClaudeCodeBillingHeader(log.rawRequestBody).body;
3580
- }, [log.rawRequestBody, resolvedFormat, strip]);
3581
- const displayedRequestBody = strippedRequestBody ?? log.rawRequestBody;
3585
+ return stripClaudeCodeBillingHeader(displayLog.rawRequestBody).body;
3586
+ }, [displayLog.rawRequestBody, resolvedFormat, strip]);
3587
+ const displayedRequestBody = strippedRequestBody ?? displayLog.rawRequestBody;
3582
3588
  const requestExpansion = useJsonBulkExpansion(displayedRequestBody);
3583
- const rawRequestExpansion = useJsonBulkExpansion(log.rawRequestBody);
3584
- const responseExpansion = useJsonBulkExpansion(log.responseText);
3589
+ const rawRequestExpansion = useJsonBulkExpansion(displayLog.rawRequestBody);
3590
+ const responseExpansion = useJsonBulkExpansion(displayLog.responseText);
3585
3591
  const headersText = reactExports.useMemo(
3586
- () => log.headers && Object.keys(log.headers).length > 0 ? JSON.stringify(log.headers, null, 2) : null,
3587
- [log.headers]
3592
+ () => displayLog.headers && Object.keys(displayLog.headers).length > 0 ? JSON.stringify(displayLog.headers, null, 2) : null,
3593
+ [displayLog.headers]
3588
3594
  );
3589
3595
  const rawHeadersText = reactExports.useMemo(
3590
- () => log.rawHeaders && Object.keys(log.rawHeaders).length > 0 ? JSON.stringify(log.rawHeaders, null, 2) : null,
3591
- [log.rawHeaders]
3596
+ () => displayLog.rawHeaders && Object.keys(displayLog.rawHeaders).length > 0 ? JSON.stringify(displayLog.rawHeaders, null, 2) : null,
3597
+ [displayLog.rawHeaders]
3592
3598
  );
3593
3599
  const requestCopy = useCopyFeedback(displayedRequestBody);
3594
- const rawRequestCopy = useCopyFeedback(log.rawRequestBody);
3600
+ const rawRequestCopy = useCopyFeedback(displayLog.rawRequestBody);
3595
3601
  const headersCopy = useCopyFeedback(headersText);
3596
3602
  const rawHeadersCopy = useCopyFeedback(rawHeadersText);
3597
- const responseCopy = useCopyFeedback(log.responseText);
3603
+ const responseCopy = useCopyFeedback(displayLog.responseText);
3598
3604
  const tabActions = reactExports.useMemo(
3599
3605
  () => ({
3600
3606
  request: {
@@ -3614,15 +3620,15 @@ const LogEntry = reactExports.memo(function({
3614
3620
  resolvedFormat,
3615
3621
  viewMode,
3616
3622
  strip,
3617
- log.rawRequestBody !== null
3623
+ displayLog.rawRequestBody !== null
3618
3624
  ) ? { active: requestDiff, onToggle: () => setRequestDiff(!requestDiff) } : void 0,
3619
3625
  diffWithPrevious: onCompareWithPrevious === void 0 ? void 0 : () => {
3620
- onCompareWithPrevious(log);
3626
+ onCompareWithPrevious(displayLog);
3621
3627
  }
3622
3628
  },
3623
3629
  "raw-request": {
3624
3630
  copyLabel: "Copy raw request",
3625
- copyText: log.rawRequestBody,
3631
+ copyText: displayLog.rawRequestBody,
3626
3632
  copyCopied: rawRequestCopy.copied,
3627
3633
  onCopy: rawRequestCopy.copy,
3628
3634
  expansion: {
@@ -3648,7 +3654,7 @@ const LogEntry = reactExports.memo(function({
3648
3654
  },
3649
3655
  raw: {
3650
3656
  copyLabel: "Copy response",
3651
- copyText: log.responseText,
3657
+ copyText: displayLog.responseText,
3652
3658
  copyCopied: responseCopy.copied,
3653
3659
  onCopy: responseCopy.copy,
3654
3660
  expansion: {
@@ -3663,14 +3669,15 @@ const LogEntry = reactExports.memo(function({
3663
3669
  requestCopy,
3664
3670
  requestExpansion,
3665
3671
  requestDiff,
3666
- log.rawRequestBody,
3672
+ displayLog,
3673
+ displayLog.rawRequestBody,
3667
3674
  rawRequestCopy,
3668
3675
  rawRequestExpansion,
3669
3676
  headersText,
3670
3677
  headersCopy,
3671
3678
  rawHeadersText,
3672
3679
  rawHeadersCopy,
3673
- log.responseText,
3680
+ displayLog.responseText,
3674
3681
  responseCopy,
3675
3682
  responseExpansion,
3676
3683
  resolvedFormat,
@@ -3687,7 +3694,7 @@ const LogEntry = reactExports.memo(function({
3687
3694
  () => parseRequestTools(requestExpansion.parsedData),
3688
3695
  [requestExpansion.parsedData]
3689
3696
  );
3690
- const warnings = log.warnings ?? [];
3697
+ const warnings = displayLog.warnings ?? [];
3691
3698
  const anatomyPaths = reactExports.useMemo(() => {
3692
3699
  if (anatomySegments === null) return void 0;
3693
3700
  return new Set(anatomySegments.map((s) => s.path));
@@ -3706,6 +3713,28 @@ const LogEntry = reactExports.memo(function({
3706
3713
  }
3707
3714
  setExpanded(nextExpanded);
3708
3715
  }, [anatomySegments, expanded]);
3716
+ reactExports.useEffect(() => {
3717
+ setHydratedLog(null);
3718
+ setBodyHydrationState("idle");
3719
+ }, [log.id]);
3720
+ reactExports.useEffect(() => {
3721
+ if (!expanded) return;
3722
+ if (!shouldHydrateLogBody(log)) return;
3723
+ if (hydratedLog !== null || bodyHydrationState !== "idle") return;
3724
+ let cancelled = false;
3725
+ setBodyHydrationState("loading");
3726
+ void fetchJson(`/api/logs/${String(log.id)}`, CapturedLogSchema).then((fullLog) => {
3727
+ if (cancelled) return;
3728
+ setHydratedLog(fullLog);
3729
+ setBodyHydrationState("idle");
3730
+ }).catch(() => {
3731
+ if (cancelled) return;
3732
+ setBodyHydrationState("failed");
3733
+ });
3734
+ return () => {
3735
+ cancelled = true;
3736
+ };
3737
+ }, [bodyHydrationState, expanded, hydratedLog, log.bodyContentMode, log.id]);
3709
3738
  reactExports.useEffect(() => {
3710
3739
  const handleLogFocusRequest = (event) => {
3711
3740
  const request = readLogFocusRequest(event);
@@ -3724,7 +3753,7 @@ const LogEntry = reactExports.memo(function({
3724
3753
  /* @__PURE__ */ jsxRuntimeExports.jsx(
3725
3754
  LogEntryHeader,
3726
3755
  {
3727
- log,
3756
+ log: displayLog,
3728
3757
  messageCount: requestAnalysis.messageCount,
3729
3758
  toolCount: requestAnalysis.toolCount,
3730
3759
  expanded,
@@ -3749,15 +3778,17 @@ const LogEntry = reactExports.memo(function({
3749
3778
  viewMode === "full" && /* @__PURE__ */ jsxRuntimeExports.jsx(TabsTrigger, { value: "raw", children: "Raw Response" }),
3750
3779
  /* @__PURE__ */ jsxRuntimeExports.jsx(TabsTrigger, { value: "parsed", children: "Response" })
3751
3780
  ] }),
3752
- shouldShowRawRequestTab(resolvedFormat, viewMode, strip) && /* @__PURE__ */ jsxRuntimeExports.jsx(TabsContent, { value: "raw-request", children: activeTab === "raw-request" && /* @__PURE__ */ jsxRuntimeExports.jsx("div", { className: "px-4 pt-1 pb-3", children: log.rawRequestBody === null ? /* @__PURE__ */ jsxRuntimeExports.jsx("p", { className: "text-xs text-muted-foreground italic", children: "No request body" }) : rawRequestExpansion.parsedData !== null ? /* @__PURE__ */ jsxRuntimeExports.jsx(reactExports.Suspense, { fallback: /* @__PURE__ */ jsxRuntimeExports.jsx(TabFallback, {}), children: /* @__PURE__ */ jsxRuntimeExports.jsx(
3781
+ shouldShowRawRequestTab(resolvedFormat, viewMode, strip) && /* @__PURE__ */ jsxRuntimeExports.jsx(TabsContent, { value: "raw-request", children: activeTab === "raw-request" && /* @__PURE__ */ jsxRuntimeExports.jsx("div", { className: "px-4 pt-1 pb-3", children: displayLog.rawRequestBody === null ? /* @__PURE__ */ jsxRuntimeExports.jsx("p", { className: "text-xs text-muted-foreground italic", children: "No request body" }) : rawRequestExpansion.parsedData !== null ? /* @__PURE__ */ jsxRuntimeExports.jsx(reactExports.Suspense, { fallback: /* @__PURE__ */ jsxRuntimeExports.jsx(TabFallback, {}), children: /* @__PURE__ */ jsxRuntimeExports.jsx(
3753
3782
  LazyJsonViewer,
3754
3783
  {
3755
3784
  data: rawRequestExpansion.parsedData,
3756
3785
  bulkDepth: rawRequestExpansion.bulkDepth,
3757
3786
  bulkRevision: rawRequestExpansion.bulkRevision
3758
3787
  }
3759
- ) }) : /* @__PURE__ */ jsxRuntimeExports.jsx("pre", { className: "font-mono text-xs whitespace-pre-wrap break-words", children: log.rawRequestBody }) }) }),
3788
+ ) }) : /* @__PURE__ */ jsxRuntimeExports.jsx("pre", { className: "font-mono text-xs whitespace-pre-wrap break-words", children: displayLog.rawRequestBody }) }) }),
3760
3789
  /* @__PURE__ */ jsxRuntimeExports.jsx(TabsContent, { value: "request", children: activeTab === "request" && /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "px-4 pt-1 pb-3", children: [
3790
+ bodyHydrationState === "loading" && /* @__PURE__ */ jsxRuntimeExports.jsx("div", { className: "mb-3 rounded border border-border bg-muted/30 p-3 text-xs text-muted-foreground", children: "Loading full request and response bodies..." }),
3791
+ bodyHydrationState === "failed" && /* @__PURE__ */ jsxRuntimeExports.jsx("div", { className: "mb-3 rounded border border-amber-500/30 bg-amber-500/10 p-3 text-xs text-amber-200", children: "Full request and response bodies could not be loaded. Compact metadata is still available." }),
3761
3792
  warnings.length > 0 && /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "mb-3 rounded border border-amber-500/30 bg-amber-500/10 p-3 text-xs", children: [
3762
3793
  /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "flex items-center gap-2 font-semibold text-amber-300", children: [
3763
3794
  /* @__PURE__ */ jsxRuntimeExports.jsx(TriangleAlert, { className: "size-3.5" }),
@@ -3775,7 +3806,7 @@ const LogEntry = reactExports.memo(function({
3775
3806
  requestDiff ? /* @__PURE__ */ jsxRuntimeExports.jsx(
3776
3807
  RequestDiffContent,
3777
3808
  {
3778
- rawBody: log.rawRequestBody,
3809
+ rawBody: displayLog.rawRequestBody,
3779
3810
  displayedBody: displayedRequestBody,
3780
3811
  emptyLabel: "No transformation applied; raw and sent request bodies are identical."
3781
3812
  }
@@ -3794,8 +3825,8 @@ const LogEntry = reactExports.memo(function({
3794
3825
  LazyRequestAnatomy,
3795
3826
  {
3796
3827
  parsed: requestExpansion.parsedData,
3797
- inputTokens: log.inputTokens ?? null,
3798
- model: log.model,
3828
+ inputTokens: displayLog.inputTokens ?? null,
3829
+ model: displayLog.model,
3799
3830
  segments: anatomySegments,
3800
3831
  onSegmentActivate: jumpToAnatomySegment
3801
3832
  }
@@ -3803,7 +3834,7 @@ const LogEntry = reactExports.memo(function({
3803
3834
  viewMode === "full" && /* @__PURE__ */ jsxRuntimeExports.jsx(TabsContent, { value: "headers", children: activeTab === "headers" && /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "px-4 pt-1 pb-3", children: [
3804
3835
  /* @__PURE__ */ jsxRuntimeExports.jsx("div", { className: "flex justify-end gap-2 mb-2", children: shouldShowHeadersDiffButton(
3805
3836
  viewMode,
3806
- log.rawHeaders !== void 0 && Object.keys(log.rawHeaders).length > 0
3837
+ displayLog.rawHeaders !== void 0 && Object.keys(displayLog.rawHeaders).length > 0
3807
3838
  ) && /* @__PURE__ */ jsxRuntimeExports.jsx(
3808
3839
  DiffToggleButton,
3809
3840
  {
@@ -3817,11 +3848,11 @@ const LogEntry = reactExports.memo(function({
3817
3848
  headersDiff ? /* @__PURE__ */ jsxRuntimeExports.jsx(
3818
3849
  HeadersDiffContent,
3819
3850
  {
3820
- rawHeaders: log.rawHeaders,
3821
- headers: log.headers,
3851
+ rawHeaders: displayLog.rawHeaders,
3852
+ headers: displayLog.headers,
3822
3853
  emptyLabel: "No transformation applied; raw and processed headers are identical."
3823
3854
  }
3824
- ) : log.headers && Object.keys(log.headers).length > 0 ? /* @__PURE__ */ jsxRuntimeExports.jsx("div", { className: "space-y-1 font-mono text-xs", children: Object.entries(log.headers).sort(([a], [b]) => a.localeCompare(b)).map(([key, value]) => /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "flex gap-2", children: [
3855
+ ) : displayLog.headers && Object.keys(displayLog.headers).length > 0 ? /* @__PURE__ */ jsxRuntimeExports.jsx("div", { className: "space-y-1 font-mono text-xs", children: Object.entries(displayLog.headers).sort(([a], [b]) => a.localeCompare(b)).map(([key, value]) => /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "flex gap-2", children: [
3825
3856
  /* @__PURE__ */ jsxRuntimeExports.jsxs("span", { className: "text-blue-600 dark:text-blue-400 font-semibold shrink-0", children: [
3826
3857
  key,
3827
3858
  ":"
@@ -3829,7 +3860,7 @@ const LogEntry = reactExports.memo(function({
3829
3860
  /* @__PURE__ */ jsxRuntimeExports.jsx("span", { className: "text-muted-foreground truncate", title: value, children: value })
3830
3861
  ] }, key)) }) : /* @__PURE__ */ jsxRuntimeExports.jsx("p", { className: "text-xs text-muted-foreground italic", children: "No headers captured" })
3831
3862
  ] }) }),
3832
- viewMode === "full" && /* @__PURE__ */ jsxRuntimeExports.jsx(TabsContent, { value: "raw-headers", children: activeTab === "raw-headers" && /* @__PURE__ */ jsxRuntimeExports.jsx("div", { className: "px-4 pt-1 pb-3", children: log.rawHeaders && Object.keys(log.rawHeaders).length > 0 ? /* @__PURE__ */ jsxRuntimeExports.jsx("div", { className: "space-y-1 font-mono text-xs", children: Object.entries(log.rawHeaders).sort(([a], [b]) => a.localeCompare(b)).map(([key, value]) => /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "flex gap-2", children: [
3863
+ viewMode === "full" && /* @__PURE__ */ jsxRuntimeExports.jsx(TabsContent, { value: "raw-headers", children: activeTab === "raw-headers" && /* @__PURE__ */ jsxRuntimeExports.jsx("div", { className: "px-4 pt-1 pb-3", children: displayLog.rawHeaders && Object.keys(displayLog.rawHeaders).length > 0 ? /* @__PURE__ */ jsxRuntimeExports.jsx("div", { className: "space-y-1 font-mono text-xs", children: Object.entries(displayLog.rawHeaders).sort(([a], [b]) => a.localeCompare(b)).map(([key, value]) => /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "flex gap-2", children: [
3833
3864
  /* @__PURE__ */ jsxRuntimeExports.jsxs("span", { className: "text-blue-600 dark:text-blue-400 font-semibold shrink-0", children: [
3834
3865
  key,
3835
3866
  ":"
@@ -3837,44 +3868,44 @@ const LogEntry = reactExports.memo(function({
3837
3868
  /* @__PURE__ */ jsxRuntimeExports.jsx("span", { className: "text-muted-foreground truncate", title: value, children: value })
3838
3869
  ] }, key)) }) : /* @__PURE__ */ jsxRuntimeExports.jsx("p", { className: "text-xs text-muted-foreground italic", children: "No raw headers captured" }) }) }),
3839
3870
  /* @__PURE__ */ jsxRuntimeExports.jsx(TabsContent, { value: "raw", children: activeTab === "raw" && /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "px-4 pt-1 pb-3 space-y-3", children: [
3840
- log.error !== void 0 && log.error !== null && /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "rounded border border-destructive/50 bg-destructive/10 p-3 text-xs", children: [
3871
+ displayLog.error !== void 0 && displayLog.error !== null && /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "rounded border border-destructive/50 bg-destructive/10 p-3 text-xs", children: [
3841
3872
  /* @__PURE__ */ jsxRuntimeExports.jsx("div", { className: "font-semibold text-destructive mb-1", children: "SSE Error" }),
3842
- /* @__PURE__ */ jsxRuntimeExports.jsx("div", { className: "text-muted-foreground font-mono", children: log.error })
3873
+ /* @__PURE__ */ jsxRuntimeExports.jsx("div", { className: "text-muted-foreground font-mono", children: displayLog.error })
3843
3874
  ] }),
3844
- log.responseText !== null ? /* @__PURE__ */ jsxRuntimeExports.jsx(reactExports.Suspense, { fallback: /* @__PURE__ */ jsxRuntimeExports.jsx(TabFallback, {}), children: /* @__PURE__ */ jsxRuntimeExports.jsx(
3875
+ displayLog.responseText !== null ? /* @__PURE__ */ jsxRuntimeExports.jsx(reactExports.Suspense, { fallback: /* @__PURE__ */ jsxRuntimeExports.jsx(TabFallback, {}), children: /* @__PURE__ */ jsxRuntimeExports.jsx(
3845
3876
  LazyJsonViewerFromString,
3846
3877
  {
3847
- text: log.responseText,
3878
+ text: displayLog.responseText,
3848
3879
  defaultExpandDepth: 0,
3849
3880
  bulkDepth: responseExpansion.bulkDepth,
3850
3881
  bulkRevision: responseExpansion.bulkRevision
3851
3882
  }
3852
3883
  ) }) : /* @__PURE__ */ jsxRuntimeExports.jsx("p", { className: "text-xs text-muted-foreground italic", children: "No response" }),
3853
- log.streaming === true && /* @__PURE__ */ jsxRuntimeExports.jsx(reactExports.Suspense, { fallback: /* @__PURE__ */ jsxRuntimeExports.jsx(TabFallback, {}), children: /* @__PURE__ */ jsxRuntimeExports.jsx(
3884
+ displayLog.streaming === true && /* @__PURE__ */ jsxRuntimeExports.jsx(reactExports.Suspense, { fallback: /* @__PURE__ */ jsxRuntimeExports.jsx(TabFallback, {}), children: /* @__PURE__ */ jsxRuntimeExports.jsx(
3854
3885
  LazyStreamingChunkSequence,
3855
3886
  {
3856
- logId: log.id,
3857
- truncated: log.streamingChunksPath !== null
3887
+ logId: displayLog.id,
3888
+ truncated: displayLog.streamingChunksPath !== null
3858
3889
  }
3859
3890
  ) })
3860
3891
  ] }) }),
3861
3892
  /* @__PURE__ */ jsxRuntimeExports.jsx(TabsContent, { value: "parsed", children: activeTab === "parsed" && /* @__PURE__ */ jsxRuntimeExports.jsx("div", { className: "px-4 pt-1 pb-3", children: /* @__PURE__ */ jsxRuntimeExports.jsx(reactExports.Suspense, { fallback: /* @__PURE__ */ jsxRuntimeExports.jsx(TabFallback, {}), children: /* @__PURE__ */ jsxRuntimeExports.jsx(
3862
3893
  LazyResponseView,
3863
3894
  {
3864
- responseText: log.responseText,
3865
- responseStatus: log.responseStatus,
3866
- streaming: log.streaming,
3867
- inputTokens: log.inputTokens,
3868
- outputTokens: log.outputTokens,
3869
- cacheCreationInputTokens: log.cacheCreationInputTokens,
3870
- cacheReadInputTokens: log.cacheReadInputTokens,
3895
+ responseText: displayLog.responseText,
3896
+ responseStatus: displayLog.responseStatus,
3897
+ streaming: displayLog.streaming,
3898
+ inputTokens: displayLog.inputTokens,
3899
+ outputTokens: displayLog.outputTokens,
3900
+ cacheCreationInputTokens: displayLog.cacheCreationInputTokens,
3901
+ cacheReadInputTokens: displayLog.cacheReadInputTokens,
3871
3902
  apiFormat: resolvedFormat,
3872
- error: log.error
3903
+ error: displayLog.error
3873
3904
  }
3874
3905
  ) }) }) })
3875
3906
  ] }) })
3876
3907
  ] }),
3877
- /* @__PURE__ */ jsxRuntimeExports.jsx(reactExports.Suspense, { fallback: null, children: /* @__PURE__ */ jsxRuntimeExports.jsx(LazyReplayDialog, { log, open: replayOpen, onOpenChange: setReplayOpen }) })
3908
+ /* @__PURE__ */ jsxRuntimeExports.jsx(reactExports.Suspense, { fallback: null, children: /* @__PURE__ */ jsxRuntimeExports.jsx(LazyReplayDialog, { log: displayLog, open: replayOpen, onOpenChange: setReplayOpen }) })
3878
3909
  ] });
3879
3910
  });
3880
3911
  function ThreadConnector({
@@ -6217,21 +6248,24 @@ function MemberRow({ row }) {
6217
6248
  const errors = session?.errorCount ?? null;
6218
6249
  const tokens = session?.tokenUsage.total ?? null;
6219
6250
  const firstChunkMs = log?.firstChunkMs ?? null;
6251
+ const sessionLabel = firstNonEmpty(member.label, member.sessionId);
6220
6252
  return /* @__PURE__ */ jsxRuntimeExports.jsxs("tr", { className: "border-b border-border last:border-0", children: [
6221
6253
  /* @__PURE__ */ jsxRuntimeExports.jsxs("td", { className: "max-w-56 px-3 py-2", children: [
6222
- /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "flex min-w-0 items-center gap-2", children: [
6223
- /* @__PURE__ */ jsxRuntimeExports.jsx(
6224
- "a",
6225
- {
6226
- href: sessionPath,
6227
- target: "_blank",
6228
- rel: "noreferrer",
6229
- className: "min-w-0 truncate font-mono text-xs text-primary hover:underline",
6230
- children: firstNonEmpty(member.label, member.sessionId)
6231
- }
6232
- ),
6233
- /* @__PURE__ */ jsxRuntimeExports.jsx(ExternalLink, { className: "size-3 shrink-0 text-muted-foreground" })
6234
- ] }),
6254
+ /* @__PURE__ */ jsxRuntimeExports.jsxs(
6255
+ "a",
6256
+ {
6257
+ href: sessionPath,
6258
+ target: "_blank",
6259
+ rel: "noreferrer",
6260
+ className: "inline-flex max-w-full min-w-0 items-center gap-2 rounded-sm font-mono text-xs text-primary outline-none hover:underline focus-visible:ring-2 focus-visible:ring-ring focus-visible:ring-offset-2",
6261
+ "aria-label": `Open session ${sessionLabel}`,
6262
+ title: `Open session ${sessionLabel}`,
6263
+ children: [
6264
+ /* @__PURE__ */ jsxRuntimeExports.jsx("span", { className: "min-w-0 truncate", children: sessionLabel }),
6265
+ /* @__PURE__ */ jsxRuntimeExports.jsx(ExternalLink, { className: "size-3 shrink-0 text-muted-foreground" })
6266
+ ]
6267
+ }
6268
+ ),
6235
6269
  /* @__PURE__ */ jsxRuntimeExports.jsx("div", { className: "mt-0.5 truncate text-[11px] text-muted-foreground", children: displayText(member.agent) })
6236
6270
  ] }),
6237
6271
  /* @__PURE__ */ jsxRuntimeExports.jsx("td", { className: "max-w-52 px-3 py-2", children: /* @__PURE__ */ jsxRuntimeExports.jsx("span", { className: "block truncate", children: providerModel(member) }) }),
@@ -10298,6 +10332,99 @@ function formatContextWindow(summary) {
10298
10332
  if (tokens === null) return "Context window unknown";
10299
10333
  return `Context window ${formatContextWindowTokens(tokens)}`;
10300
10334
  }
10335
+ const MEMBER_METADATA_KEYS = [
10336
+ "score",
10337
+ "decision",
10338
+ "final_status",
10339
+ "validation_pass_ratio",
10340
+ "semantic_memory_score",
10341
+ "opencode_exit",
10342
+ "actual_model",
10343
+ "run_dir",
10344
+ "workspace",
10345
+ "project_dir",
10346
+ "work_dir"
10347
+ ];
10348
+ function formatMetadataValue(value) {
10349
+ if (typeof value === "string") return value.length > 0 ? value : null;
10350
+ if (typeof value === "number" || typeof value === "boolean") return String(value);
10351
+ if (value === null) return null;
10352
+ return JSON.stringify(value);
10353
+ }
10354
+ function getMemberMetadataRows(member) {
10355
+ const rows = [];
10356
+ for (const key of MEMBER_METADATA_KEYS) {
10357
+ const value = member.metadata[key];
10358
+ if (value === void 0) continue;
10359
+ const formatted = formatMetadataValue(value);
10360
+ if (formatted !== null) rows.push({ key, value: formatted });
10361
+ }
10362
+ return rows;
10363
+ }
10364
+ function SessionMembershipPanel({
10365
+ memberships
10366
+ }) {
10367
+ if (memberships.length === 0) return null;
10368
+ return /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "mb-4 rounded-md border border-border bg-muted/10 px-3 py-2 text-xs", children: [
10369
+ /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "mb-2 flex items-center justify-between gap-2", children: [
10370
+ /* @__PURE__ */ jsxRuntimeExports.jsx("div", { className: "font-semibold text-foreground", children: "Group Member Evidence" }),
10371
+ /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "font-mono text-[10px] text-muted-foreground", children: [
10372
+ memberships.length,
10373
+ " group",
10374
+ memberships.length === 1 ? "" : "s"
10375
+ ] })
10376
+ ] }),
10377
+ /* @__PURE__ */ jsxRuntimeExports.jsx("div", { className: "space-y-2", children: memberships.map((membership) => {
10378
+ const member = membership.member;
10379
+ const metadataRows = getMemberMetadataRows(member);
10380
+ return /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "min-w-0", children: [
10381
+ /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "flex min-w-0 flex-wrap items-center gap-x-2 gap-y-1", children: [
10382
+ /* @__PURE__ */ jsxRuntimeExports.jsx(
10383
+ "span",
10384
+ {
10385
+ className: "truncate font-medium text-foreground",
10386
+ title: membership.groupTitle,
10387
+ children: membership.groupTitle
10388
+ }
10389
+ ),
10390
+ /* @__PURE__ */ jsxRuntimeExports.jsx("span", { className: "font-mono text-[10px] uppercase text-muted-foreground", children: membership.groupStatus }),
10391
+ member.status !== null && /* @__PURE__ */ jsxRuntimeExports.jsxs("span", { className: "font-mono text-[10px] text-muted-foreground", children: [
10392
+ "member ",
10393
+ member.status
10394
+ ] })
10395
+ ] }),
10396
+ /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "mt-1 flex min-w-0 flex-wrap items-center gap-x-3 gap-y-1 text-muted-foreground", children: [
10397
+ /* @__PURE__ */ jsxRuntimeExports.jsx("span", { className: "font-mono", title: member.sessionId, children: truncateSessionId(member.sessionId) }),
10398
+ member.label !== null && /* @__PURE__ */ jsxRuntimeExports.jsx("span", { children: member.label }),
10399
+ member.provider !== null && /* @__PURE__ */ jsxRuntimeExports.jsx("span", { children: member.provider }),
10400
+ member.model !== null && /* @__PURE__ */ jsxRuntimeExports.jsx("span", { className: "font-mono", children: member.model }),
10401
+ member.runId !== null && /* @__PURE__ */ jsxRuntimeExports.jsxs("span", { className: "font-mono", title: member.runId, children: [
10402
+ "run ",
10403
+ truncateSessionId(member.runId)
10404
+ ] })
10405
+ ] }),
10406
+ 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(
10407
+ "div",
10408
+ {
10409
+ className: "min-w-0 rounded border border-border/60 px-2 py-1",
10410
+ children: [
10411
+ /* @__PURE__ */ jsxRuntimeExports.jsx("div", { className: "font-mono text-[10px] text-muted-foreground", children: row.key }),
10412
+ /* @__PURE__ */ jsxRuntimeExports.jsx(
10413
+ "div",
10414
+ {
10415
+ className: "truncate font-mono text-[11px] text-foreground",
10416
+ title: row.value,
10417
+ children: row.value
10418
+ }
10419
+ )
10420
+ ]
10421
+ },
10422
+ row.key
10423
+ )) })
10424
+ ] }, `${membership.groupId}:${member.id}`);
10425
+ }) })
10426
+ ] });
10427
+ }
10301
10428
  function formatRequestCount(count) {
10302
10429
  return `${count} ${count === 1 ? "request" : "requests"}`;
10303
10430
  }
@@ -10703,6 +10830,8 @@ function ProxyViewer({
10703
10830
  strip,
10704
10831
  slowResponseThresholdSeconds,
10705
10832
  timeDisplayFormat,
10833
+ isLoading = false,
10834
+ sessionMemberships = [],
10706
10835
  hideSessionFilter = false,
10707
10836
  pinnedSessionId
10708
10837
  }) {
@@ -10856,6 +10985,7 @@ function ProxyViewer({
10856
10985
  showBackLink: sessionContextScope.showBackLink
10857
10986
  }
10858
10987
  ),
10988
+ hasSessionContext && pinnedSessionId !== void 0 && sessionMemberships.length > 0 && /* @__PURE__ */ jsxRuntimeExports.jsx(SessionMembershipPanel, { memberships: sessionMemberships }),
10859
10989
  /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "flex items-center gap-3 mb-4", children: [
10860
10990
  !hideSessionFilter && /* @__PURE__ */ jsxRuntimeExports.jsxs(Select, { value: selectedSession, onValueChange: onSessionChange, children: [
10861
10991
  /* @__PURE__ */ jsxRuntimeExports.jsx(SelectTrigger, { className: "flex-1 max-w-[350px] text-xs", children: /* @__PURE__ */ jsxRuntimeExports.jsx(SelectValue, { placeholder: "All sessions" }) }),
@@ -10947,9 +11077,10 @@ function ProxyViewer({
10947
11077
  exportError !== null && /* @__PURE__ */ jsxRuntimeExports.jsx("div", { className: "mb-4 rounded-md border border-destructive/30 bg-destructive/10 px-3 py-2 text-xs text-destructive", children: exportError })
10948
11078
  ] }),
10949
11079
  /* @__PURE__ */ jsxRuntimeExports.jsx("div", { children: logs.length === 0 ? selectedSession !== "__all__" ? /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "text-center text-muted-foreground py-16 space-y-4", children: [
10950
- /* @__PURE__ */ jsxRuntimeExports.jsx("p", { className: "text-sm font-medium", children: "Session not found" }),
11080
+ /* @__PURE__ */ jsxRuntimeExports.jsx("p", { className: "text-sm font-medium", children: isLoading ? "Loading session data..." : "Session not found" }),
10951
11081
  /* @__PURE__ */ jsxRuntimeExports.jsx("p", { className: "text-xs font-mono bg-muted px-3 py-1 rounded inline-block max-w-[500px] break-all", children: truncateSessionId(selectedSession) }),
10952
- /* @__PURE__ */ jsxRuntimeExports.jsxs("p", { className: "text-xs", children: [
11082
+ sessionMemberships.length > 0 && /* @__PURE__ */ jsxRuntimeExports.jsx("div", { className: "mx-auto max-w-3xl text-left", children: /* @__PURE__ */ jsxRuntimeExports.jsx(SessionMembershipPanel, { memberships: sessionMemberships }) }),
11083
+ !isLoading && /* @__PURE__ */ jsxRuntimeExports.jsxs("p", { className: "text-xs", children: [
10953
11084
  "This session may have been cleared or never existed.",
10954
11085
  " ",
10955
11086
  hideSessionFilter ? /* @__PURE__ */ jsxRuntimeExports.jsx("a", { href: "/", className: "underline hover:text-foreground transition-colors", children: "Back to all sessions" }) : /* @__PURE__ */ jsxRuntimeExports.jsx(
@@ -11007,6 +11138,25 @@ const SSEUpdateSchema = union([
11007
11138
  log: CapturedLogSchema
11008
11139
  })
11009
11140
  ]);
11141
+ function buildSessionMembershipEvidence(groups, sessionId) {
11142
+ const memberships = [];
11143
+ for (const group of groups) {
11144
+ for (const member of group.members) {
11145
+ if (member.sessionId !== sessionId) continue;
11146
+ memberships.push({
11147
+ groupId: group.id,
11148
+ groupTitle: group.title,
11149
+ groupKind: group.kind,
11150
+ groupStatus: group.status,
11151
+ groupTask: group.task,
11152
+ groupProject: group.project,
11153
+ groupEvidence: group.evidence,
11154
+ member
11155
+ });
11156
+ }
11157
+ }
11158
+ return memberships;
11159
+ }
11010
11160
  function extractSessions(logs) {
11011
11161
  const set = /* @__PURE__ */ new Set();
11012
11162
  for (const l of logs) {
@@ -11034,9 +11184,13 @@ const HASH_SCROLL_ATTEMPTS = 12;
11034
11184
  const HASH_HIGHLIGHT_MS = 1800;
11035
11185
  const MAX_CLIENT_LOGS = 500;
11036
11186
  function buildLogsStreamUrl(sessionId) {
11037
- if (sessionId === void 0) return "/api/logs/stream";
11038
- const params = new URLSearchParams({ sessionId });
11039
- return `/api/logs/stream?${params.toString()}`;
11187
+ const params = new URLSearchParams();
11188
+ if (sessionId !== void 0) {
11189
+ params.set("sessionId", sessionId);
11190
+ params.set("compact", "1");
11191
+ }
11192
+ const query = params.toString();
11193
+ return query.length > 0 ? `/api/logs/stream?${query}` : "/api/logs/stream";
11040
11194
  }
11041
11195
  function buildLogIndex(logs) {
11042
11196
  const idx = /* @__PURE__ */ new Map();
@@ -11058,6 +11212,8 @@ function ProxyViewerContainer({
11058
11212
  const [selectedModel, setSelectedModel] = reactExports.useState("__all__");
11059
11213
  const [viewMode, setViewMode] = reactExports.useState("simple");
11060
11214
  const [error, setError] = reactExports.useState(null);
11215
+ const [streamInitialized, setStreamInitialized] = reactExports.useState(initialSessionId === void 0);
11216
+ const [sessionMemberships, setSessionMemberships] = reactExports.useState([]);
11061
11217
  const eventSourceRef = reactExports.useRef(null);
11062
11218
  const reconnectTimeoutRef = reactExports.useRef(null);
11063
11219
  const handledHashRef = reactExports.useRef(null);
@@ -11104,6 +11260,7 @@ function ProxyViewerContainer({
11104
11260
  if (eventSourceRef.current) {
11105
11261
  eventSourceRef.current.close();
11106
11262
  }
11263
+ setStreamInitialized(false);
11107
11264
  const es = new EventSource(buildLogsStreamUrl(initialSessionId));
11108
11265
  eventSourceRef.current = es;
11109
11266
  es.onmessage = (event) => {
@@ -11125,6 +11282,7 @@ function ProxyViewerContainer({
11125
11282
  const nextLogs = trimClientLogs(update.logs);
11126
11283
  logIndexRef.current = buildLogIndex(nextLogs);
11127
11284
  setAllLogs(nextLogs);
11285
+ setStreamInitialized(true);
11128
11286
  setError(null);
11129
11287
  } else if (update.type === "update") {
11130
11288
  scheduleUpdate(update.log);
@@ -11135,6 +11293,7 @@ function ProxyViewerContainer({
11135
11293
  };
11136
11294
  es.onerror = () => {
11137
11295
  setError("SSE connection lost, reconnecting...");
11296
+ setStreamInitialized(true);
11138
11297
  es.close();
11139
11298
  if (reconnectTimeoutRef.current !== null) {
11140
11299
  clearTimeout(reconnectTimeoutRef.current);
@@ -11142,6 +11301,27 @@ function ProxyViewerContainer({
11142
11301
  reconnectTimeoutRef.current = setTimeout(connectSSE, 3e3);
11143
11302
  };
11144
11303
  }, [initialSessionId, scheduleUpdate]);
11304
+ reactExports.useEffect(() => {
11305
+ if (initialSessionId === void 0) {
11306
+ setSessionMemberships([]);
11307
+ return;
11308
+ }
11309
+ let cancelled = false;
11310
+ void fetch("/api/groups").then(async (response) => {
11311
+ if (!response.ok) return null;
11312
+ const raw = await response.json();
11313
+ const parsed = InspectorGroupsListResponseSchema.safeParse(raw);
11314
+ return parsed.success ? parsed.data.groups : null;
11315
+ }).then((groups) => {
11316
+ if (cancelled || groups === null) return;
11317
+ setSessionMemberships(buildSessionMembershipEvidence(groups, initialSessionId));
11318
+ }).catch(() => {
11319
+ if (!cancelled) setSessionMemberships([]);
11320
+ });
11321
+ return () => {
11322
+ cancelled = true;
11323
+ };
11324
+ }, [initialSessionId]);
11145
11325
  reactExports.useEffect(() => {
11146
11326
  connectSSE();
11147
11327
  return () => {
@@ -11272,6 +11452,8 @@ function ProxyViewerContainer({
11272
11452
  onModelChange: setSelectedModel,
11273
11453
  onClearAll: handleClearAll,
11274
11454
  onClearGroup: handleClearGroup,
11455
+ isLoading: initialSessionId !== void 0 && !streamInitialized,
11456
+ sessionMemberships,
11275
11457
  viewMode,
11276
11458
  onViewModeChange: setViewMode,
11277
11459
  captureMode,
@@ -1,7 +1,7 @@
1
1
  import { r as reactExports, j as jsxRuntimeExports } from "../_libs/react.mjs";
2
- import { u as useProviders, D as Dialog, d as DialogContent, e as DialogHeader, h as DialogTitle, T as Tabs, i as TabsList, j as TabsTrigger, k as TabsContent, l as Button, m as TooltipProvider, n as Tooltip, o as TooltipTrigger, p as TooltipContent, q as dispatchLogFocusRequest } from "./ProxyViewerContainer-9GJtCWCq.mjs";
3
- import { ResponseView } from "./ResponseView-CkKGYE6m.mjs";
4
- import { C as CapturedLogSchema } from "./router-CVqVjBzJ.mjs";
2
+ import { u as useProviders, D as Dialog, d as DialogContent, e as DialogHeader, h as DialogTitle, T as Tabs, i as TabsList, j as TabsTrigger, k as TabsContent, l as Button, m as TooltipProvider, n as Tooltip, o as TooltipTrigger, p as TooltipContent, q as dispatchLogFocusRequest } from "./ProxyViewerContainer-B7SR9mrD.mjs";
3
+ import { ResponseView } from "./ResponseView-BXY0w197.mjs";
4
+ import { C as CapturedLogSchema } from "./router-B2d1LUx6.mjs";
5
5
  import "../_libs/jszip.mjs";
6
6
  import "../_libs/modelcontextprotocol__server.mjs";
7
7
  import { V as RotateCcw, ae as Braces, af as Minimize2 } from "../_libs/lucide-react.mjs";
@@ -1,6 +1,6 @@
1
1
  import { r as reactExports, j as jsxRuntimeExports } from "../_libs/react.mjs";
2
- import { u as useProviders, s as analyzeContextIntelligence, f as formatTokens, m as TooltipProvider, c as cn, n as Tooltip, o as TooltipTrigger, p as TooltipContent, S as SegmentBar, R as ROLE_COLOR_CLASSES, A as ANATOMY_ROLE_LABELS, t as formatContextWindowTokens, C as CONTEXT_USAGE_THRESHOLDS } from "./ProxyViewerContainer-9GJtCWCq.mjs";
3
- import "./router-CVqVjBzJ.mjs";
2
+ import { u as useProviders, s as analyzeContextIntelligence, f as formatTokens, m as TooltipProvider, c as cn, n as Tooltip, o as TooltipTrigger, p as TooltipContent, S as SegmentBar, R as ROLE_COLOR_CLASSES, A as ANATOMY_ROLE_LABELS, t as formatContextWindowTokens, C as CONTEXT_USAGE_THRESHOLDS } from "./ProxyViewerContainer-B7SR9mrD.mjs";
3
+ import "./router-B2d1LUx6.mjs";
4
4
  import "../_libs/modelcontextprotocol__server.mjs";
5
5
  import "../_libs/jszip.mjs";
6
6
  import { ag as Info, c as ChevronDown, l as ChevronRight } from "../_libs/lucide-react.mjs";