@tonyclaw/agent-inspector 3.0.15 → 3.0.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 (32) hide show
  1. package/.output/nitro.json +1 -1
  2. package/.output/public/assets/{CompareDrawer-UaIxykqz.js → CompareDrawer-BJmxAiM0.js} +1 -1
  3. package/.output/public/assets/{ProxyViewerContainer-DlpfcX56.js → ProxyViewerContainer-C40Nig73.js} +27 -27
  4. package/.output/public/assets/{ReplayDialog-BFFomU1m.js → ReplayDialog-CkLdOMJr.js} +1 -1
  5. package/.output/public/assets/{RequestAnatomy-DKQJBt_c.js → RequestAnatomy-DemOFfSc.js} +1 -1
  6. package/.output/public/assets/{ResponseView-D7yotmne.js → ResponseView-9LhpuDo7.js} +2 -2
  7. package/.output/public/assets/{StreamingChunkSequence-Da-6WNFG.js → StreamingChunkSequence-RRWYBOdz.js} +1 -1
  8. package/.output/public/assets/{_sessionId-ByTXLS-w.js → _sessionId-CWEh2Jsn.js} +1 -1
  9. package/.output/public/assets/{index-BrM8t5mc.js → index-Lwir70Rs.js} +1 -1
  10. package/.output/public/assets/index-hjNWJZGE.js +1 -0
  11. package/.output/public/assets/{json-viewer-DyjXQdVu.js → json-viewer-D8gvbDlB.js} +1 -1
  12. package/.output/public/assets/{main-Zv_gjZMb.js → main-ovrz0tyD.js} +7 -7
  13. package/.output/server/{_sessionId-GcFhWT0i.mjs → _sessionId-zI_GFX_7.mjs} +2 -2
  14. package/.output/server/_ssr/{CompareDrawer-BV7dw1TN.mjs → CompareDrawer-Ckcx1RVu.mjs} +2 -2
  15. package/.output/server/_ssr/{ProxyViewerContainer-CcgfvaS4.mjs → ProxyViewerContainer-BgXewlIr.mjs} +16 -12
  16. package/.output/server/_ssr/{ReplayDialog-B7sBKxIO.mjs → ReplayDialog-wx3nDtZn.mjs} +3 -3
  17. package/.output/server/_ssr/{RequestAnatomy-s_9Veje2.mjs → RequestAnatomy-DN80zt0G.mjs} +2 -2
  18. package/.output/server/_ssr/{ResponseView-DsOFPCvF.mjs → ResponseView-DD7rTu_l.mjs} +2 -2
  19. package/.output/server/_ssr/{StreamingChunkSequence-CyA1XtiF.mjs → StreamingChunkSequence-DAgz6Vvw.mjs} +2 -2
  20. package/.output/server/_ssr/{index-CDDRt201.mjs → index-dcTjp8du.mjs} +14 -5
  21. package/.output/server/_ssr/index.mjs +2 -2
  22. package/.output/server/_ssr/{json-viewer-BFV-xtRM.mjs → json-viewer-N2cuzGWR.mjs} +2 -2
  23. package/.output/server/_ssr/{router-B2Q7vHPM.mjs → router-BfQ0QsD5.mjs} +77 -6
  24. package/.output/server/{_tanstack-start-manifest_v-Dm_GmuRz.mjs → _tanstack-start-manifest_v-BXnYrbcJ.mjs} +1 -1
  25. package/.output/server/index.mjs +68 -68
  26. package/package.json +1 -1
  27. package/src/components/ProxyViewer.tsx +9 -4
  28. package/src/lib/chunkLoadRecovery.ts +83 -0
  29. package/src/routes/__root.tsx +6 -3
  30. package/src/routes/index.tsx +25 -1
  31. package/src/routes/session/$sessionId.tsx +1 -0
  32. package/.output/public/assets/index-CGpPRty8.js +0 -1
@@ -2055,9 +2055,8 @@ export function ProxyViewer({
2055
2055
  const [importError, setImportError] = useState<string | null>(null);
2056
2056
  const [deleteDialogOpen, setDeleteDialogOpen] = useState(false);
2057
2057
  const [deletingCurrentView, setDeletingCurrentView] = useState(false);
2058
- const [detailsPanelCollapsed, setDetailsPanelCollapsed] = useState(
2059
- readStoredDetailsPanelCollapsed,
2060
- );
2058
+ const [detailsPanelCollapsed, setDetailsPanelCollapsed] = useState(true);
2059
+ const [detailsPanelStorageLoaded, setDetailsPanelStorageLoaded] = useState(false);
2061
2060
  const [comparePair, setComparePair] = useState<[CapturedLog, CapturedLog] | null>(null);
2062
2061
  const [crabEntrancePhase, setCrabEntrancePhase] = useState<"hidden" | "playing" | "done">(
2063
2062
  "hidden",
@@ -2099,11 +2098,17 @@ export function ProxyViewer({
2099
2098
  }, []);
2100
2099
 
2101
2100
  useEffect(() => {
2101
+ setDetailsPanelCollapsed(readStoredDetailsPanelCollapsed());
2102
+ setDetailsPanelStorageLoaded(true);
2103
+ }, []);
2104
+
2105
+ useEffect(() => {
2106
+ if (!detailsPanelStorageLoaded) return;
2102
2107
  window.localStorage.setItem(
2103
2108
  DETAILS_PANEL_COLLAPSED_STORAGE_KEY,
2104
2109
  detailsPanelCollapsed ? "1" : "0",
2105
2110
  );
2106
- }, [detailsPanelCollapsed]);
2111
+ }, [detailsPanelCollapsed, detailsPanelStorageLoaded]);
2107
2112
 
2108
2113
  useEffect(() => {
2109
2114
  if (pinnedSessionId === undefined) {
@@ -0,0 +1,83 @@
1
+ const CHUNK_LOAD_RELOAD_AT_KEY = "agent-inspector.chunkLoadReloadAt";
2
+ const CHUNK_LOAD_RELOAD_WINDOW_MS = 15_000;
3
+
4
+ const CHUNK_LOAD_FAILURE_PATTERNS = [
5
+ "failed to fetch dynamically imported module",
6
+ "failed to load module script",
7
+ "importing a module script failed",
8
+ "error loading dynamically imported module",
9
+ "loading chunk",
10
+ "unable to preload css",
11
+ ];
12
+
13
+ function messageFromReason(reason: unknown): string {
14
+ if (reason instanceof Error) {
15
+ return reason.message;
16
+ }
17
+
18
+ if (typeof reason === "string") {
19
+ return reason;
20
+ }
21
+
22
+ return "";
23
+ }
24
+
25
+ function isChunkLoadFailureMessage(message: string): boolean {
26
+ const normalizedMessage = message.toLowerCase();
27
+ return CHUNK_LOAD_FAILURE_PATTERNS.some((pattern) => normalizedMessage.includes(pattern));
28
+ }
29
+
30
+ function readLastReloadAt(): number {
31
+ const storedValue = window.sessionStorage.getItem(CHUNK_LOAD_RELOAD_AT_KEY);
32
+ if (storedValue === null) {
33
+ return 0;
34
+ }
35
+
36
+ const parsedValue = Number(storedValue);
37
+ return Number.isFinite(parsedValue) ? parsedValue : 0;
38
+ }
39
+
40
+ function reloadOnceForChunkFailure(): void {
41
+ const now = Date.now();
42
+ const lastReloadAt = readLastReloadAt();
43
+ if (now - lastReloadAt < CHUNK_LOAD_RELOAD_WINDOW_MS) {
44
+ return;
45
+ }
46
+
47
+ window.sessionStorage.setItem(CHUNK_LOAD_RELOAD_AT_KEY, String(now));
48
+ window.location.reload();
49
+ }
50
+
51
+ export function installChunkLoadRecovery(): () => void {
52
+ if (typeof window === "undefined") {
53
+ return () => {};
54
+ }
55
+
56
+ const handleUnhandledRejection = (event: PromiseRejectionEvent): void => {
57
+ const message = messageFromReason(event.reason);
58
+ if (!isChunkLoadFailureMessage(message)) {
59
+ return;
60
+ }
61
+
62
+ event.preventDefault();
63
+ reloadOnceForChunkFailure();
64
+ };
65
+
66
+ const handleError = (event: ErrorEvent): void => {
67
+ const message = event.message !== "" ? event.message : messageFromReason(event.error);
68
+ if (!isChunkLoadFailureMessage(message)) {
69
+ return;
70
+ }
71
+
72
+ event.preventDefault();
73
+ reloadOnceForChunkFailure();
74
+ };
75
+
76
+ window.addEventListener("unhandledrejection", handleUnhandledRejection);
77
+ window.addEventListener("error", handleError);
78
+
79
+ return () => {
80
+ window.removeEventListener("unhandledrejection", handleUnhandledRejection);
81
+ window.removeEventListener("error", handleError);
82
+ };
83
+ }
@@ -1,9 +1,10 @@
1
1
  /// <reference types="vite/client" />
2
2
  import { Outlet, createRootRoute, HeadContent, Scripts } from "@tanstack/react-router";
3
- import type { ReactNode } from "react";
3
+ import { useEffect, type ReactNode } from "react";
4
4
  import { SWRConfig } from "swr";
5
5
  import faviconSvg from "../assets/favicon.svg?url";
6
6
  import appCss from "../index.css?url";
7
+ import { installChunkLoadRecovery } from "../lib/chunkLoadRecovery";
7
8
 
8
9
  export const Route = createRootRoute({
9
10
  head: () => ({
@@ -22,6 +23,8 @@ export const Route = createRootRoute({
22
23
  });
23
24
 
24
25
  function RootComponent() {
26
+ useEffect(() => installChunkLoadRecovery(), []);
27
+
25
28
  return (
26
29
  <RootDocument>
27
30
  <Outlet />
@@ -57,11 +60,11 @@ function RootNotFoundComponent() {
57
60
 
58
61
  function RootDocument({ children }: Readonly<{ children: ReactNode }>) {
59
62
  return (
60
- <html lang="en" className="dark">
63
+ <html lang="en" className="dark" suppressHydrationWarning={true}>
61
64
  <head>
62
65
  <HeadContent />
63
66
  </head>
64
- <body>
67
+ <body suppressHydrationWarning={true}>
65
68
  <SWRConfig value={{ revalidateOnFocus: false, revalidateIfStale: false }}>
66
69
  {children}
67
70
  </SWRConfig>
@@ -1,6 +1,30 @@
1
1
  import { createFileRoute } from "@tanstack/react-router";
2
+ import { useEffect, useState, type JSX } from "react";
2
3
  import { ProxyViewerContainer } from "../components/ProxyViewerContainer";
3
4
 
4
5
  export const Route = createFileRoute("/")({
5
- component: ProxyViewerContainer,
6
+ ssr: false,
7
+ component: ClientOnlyProxyViewerRoute,
6
8
  });
9
+
10
+ function ClientOnlyProxyViewerRoute(): JSX.Element {
11
+ const [mounted, setMounted] = useState(false);
12
+
13
+ useEffect(() => {
14
+ setMounted(true);
15
+ }, []);
16
+
17
+ if (!mounted) {
18
+ return (
19
+ <main className="min-h-screen bg-background text-foreground">
20
+ <div className="mx-auto flex min-h-screen w-full max-w-2xl flex-col justify-center px-6 py-16 text-center">
21
+ <div className="rounded-[8px] border border-border bg-card px-4 py-8 shadow-sm">
22
+ <p className="text-sm font-medium text-muted-foreground">Loading Inspector...</p>
23
+ </div>
24
+ </div>
25
+ </main>
26
+ );
27
+ }
28
+
29
+ return <ProxyViewerContainer />;
30
+ }
@@ -9,6 +9,7 @@ import { decodeSessionIdFromPath, encodeSessionIdForPath } from "../../lib/sessi
9
9
  * and Unicode project paths survive dev-server URL normalization.
10
10
  */
11
11
  export const Route = createFileRoute("/session/$sessionId")({
12
+ ssr: false,
12
13
  component: SessionViewerRoute,
13
14
  parseParams: (params) => ({
14
15
  sessionId: decodeSessionIdFromPath(params.sessionId),
@@ -1 +0,0 @@
1
- import{P as o}from"./ProxyViewerContainer-DlpfcX56.js";import"./main-Zv_gjZMb.js";const r=o;export{r as component};