@tonyclaw/agent-inspector 2.1.24 → 3.0.1

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 (37) hide show
  1. package/.output/cli.js +85 -30
  2. package/.output/nitro.json +1 -1
  3. package/.output/public/assets/{CompareDrawer-DsHSCHSx.js → CompareDrawer-BgcAk1te.js} +1 -1
  4. package/.output/public/assets/{ProxyViewerContainer-GI3xErl5.js → ProxyViewerContainer-7b_uwvT7.js} +6 -6
  5. package/.output/public/assets/{ReplayDialog-D0ixqStX.js → ReplayDialog-7Pvhjbjk.js} +1 -1
  6. package/.output/public/assets/{RequestAnatomy-BG5mb14k.js → RequestAnatomy-BX-UKYQg.js} +1 -1
  7. package/.output/public/assets/{ResponseView-Bgns6xum.js → ResponseView-zFxGX8xH.js} +2 -2
  8. package/.output/public/assets/{StreamingChunkSequence-BeqKXAS6.js → StreamingChunkSequence-DzXzVtBF.js} +1 -1
  9. package/.output/public/assets/{_sessionId-Nme0kuTf.js → _sessionId-CmsUOEIS.js} +1 -1
  10. package/.output/public/assets/{index-hbDdeKtc.js → index-DXR7RB48.js} +1 -1
  11. package/.output/public/assets/index-MfTE52Ty.js +1 -0
  12. package/.output/public/assets/{json-viewer-CWxF2eLV.js → json-viewer-CiMN_9sG.js} +1 -1
  13. package/.output/public/assets/{main-BDfcCp_1.js → main-Ba9x64uY.js} +2 -2
  14. package/.output/server/{_sessionId-DOHtZHvJ.mjs → _sessionId-B8GZtC4P.mjs} +2 -2
  15. package/.output/server/_ssr/{CompareDrawer-HMfALocK.mjs → CompareDrawer-SBDtZDAp.mjs} +2 -2
  16. package/.output/server/_ssr/{ProxyViewerContainer-DgnyaJPd.mjs → ProxyViewerContainer-B__2O0zh.mjs} +12 -12
  17. package/.output/server/_ssr/{ReplayDialog-DyIQdJHE.mjs → ReplayDialog-D0u1VHz_.mjs} +3 -3
  18. package/.output/server/_ssr/{RequestAnatomy-8v4e8mYT.mjs → RequestAnatomy-ClvQ3RFh.mjs} +2 -2
  19. package/.output/server/_ssr/{ResponseView-D17WnkXv.mjs → ResponseView-B4UAvUym.mjs} +2 -2
  20. package/.output/server/_ssr/{StreamingChunkSequence-CALVBf-R.mjs → StreamingChunkSequence-D_aiGGzz.mjs} +2 -2
  21. package/.output/server/_ssr/{index-D8EDemF-.mjs → index-DuWacKr6.mjs} +2 -2
  22. package/.output/server/_ssr/index.mjs +2 -2
  23. package/.output/server/_ssr/{json-viewer-BgrtJGqX.mjs → json-viewer-CmNMVinH.mjs} +2 -2
  24. package/.output/server/_ssr/{router-D3qLyERI.mjs → router-BP46kVrE.mjs} +30 -5
  25. package/.output/server/{_tanstack-start-manifest_v-6qZpokPP.mjs → _tanstack-start-manifest_v-DltuTRfm.mjs} +1 -1
  26. package/.output/server/index.mjs +61 -61
  27. package/README.md +30 -8
  28. package/package.json +1 -1
  29. package/src/cli/doctor.ts +1 -1
  30. package/src/cli/onboard.ts +15 -9
  31. package/src/cli.ts +96 -34
  32. package/src/components/ProxyViewer.tsx +2 -2
  33. package/src/components/providers/SettingsDialog.tsx +2 -2
  34. package/src/lib/serverPort.ts +9 -3
  35. package/src/proxy/sessionProcess.ts +22 -1
  36. package/src/proxy/socketTracker.ts +1 -1
  37. package/.output/public/assets/index-CUKpd9jb.js +0 -1
package/.output/cli.js CHANGED
@@ -1403,6 +1403,9 @@ function stringArrayEquals(value, expected) {
1403
1403
  }
1404
1404
  return value.every((item, index) => item === expected[index]);
1405
1405
  }
1406
+ function knownMcpEndpoints(endpoint) {
1407
+ return endpoint === DEFAULT_MCP_URL ? [DEFAULT_MCP_URL, LEGACY_MCP_URL] : [endpoint];
1408
+ }
1406
1409
  function isAgentLocalEntry(value, endpoint, ignoreEnabled) {
1407
1410
  if (!isObject2(value)) {
1408
1411
  return false;
@@ -1412,13 +1415,11 @@ function isAgentLocalEntry(value, endpoint, ignoreEnabled) {
1412
1415
  return false;
1413
1416
  }
1414
1417
  const env = value["environment"];
1415
- const usesUrlArg = stringArrayEquals(value["command"], [
1416
- "agent-inspector-mcp",
1417
- "stdio",
1418
- "--url",
1419
- endpoint
1420
- ]);
1421
- const usesEnv = stringArrayEquals(value["command"], ["agent-inspector-mcp", "stdio"]) && isObject2(env) && env["AGENT_INSPECTOR_MCP_URL"] === endpoint;
1418
+ const endpoints = knownMcpEndpoints(endpoint);
1419
+ const usesUrlArg = endpoints.some(
1420
+ (candidate) => stringArrayEquals(value["command"], ["agent-inspector-mcp", "stdio", "--url", candidate])
1421
+ );
1422
+ const usesEnv = stringArrayEquals(value["command"], ["agent-inspector-mcp", "stdio"]) && isObject2(env) && endpoints.some((candidate) => env["AGENT_INSPECTOR_MCP_URL"] === candidate);
1422
1423
  return value["type"] === "local" && (usesUrlArg || usesEnv);
1423
1424
  }
1424
1425
  function isAgentRemoteEntry(value, endpoint, ignoreEnabled) {
@@ -1429,7 +1430,7 @@ function isAgentRemoteEntry(value, endpoint, ignoreEnabled) {
1429
1430
  if (!ignoreEnabled && enabled === false) {
1430
1431
  return false;
1431
1432
  }
1432
- return value["type"] === "remote" && value["url"] === endpoint;
1433
+ return value["type"] === "remote" && knownMcpEndpoints(endpoint).some((candidate) => value["url"] === candidate);
1433
1434
  }
1434
1435
  function isKnownAgentEntry(value, endpoint, ignoreEnabled) {
1435
1436
  return isAgentLocalEntry(value, endpoint, ignoreEnabled) || isAgentRemoteEntry(value, endpoint, ignoreEnabled);
@@ -2190,7 +2191,7 @@ Next steps:
2190
2191
  }
2191
2192
  return 0;
2192
2193
  }
2193
- var __filename, __dirname, DEFAULT_PORT, DEFAULT_MCP_URL, SKILL_DIR_NAME, SKILL_FILE_NAME, COMMAND_FILE_NAME, GENERATED_VERSION_PATTERN, FRONTMATTER_PATTERN, SEMVER_PATTERN;
2194
+ var __filename, __dirname, DEFAULT_PORT, DEFAULT_MCP_URL, LEGACY_MCP_URL, SKILL_DIR_NAME, SKILL_FILE_NAME, COMMAND_FILE_NAME, GENERATED_VERSION_PATTERN, FRONTMATTER_PATTERN, SEMVER_PATTERN;
2194
2195
  var init_onboard = __esm({
2195
2196
  "src/cli/onboard.ts"() {
2196
2197
  "use strict";
@@ -2200,8 +2201,9 @@ var init_onboard = __esm({
2200
2201
  init_skill_onboard();
2201
2202
  __filename = fileURLToPath(import.meta.url);
2202
2203
  __dirname = dirname(__filename);
2203
- DEFAULT_PORT = 25947;
2204
+ DEFAULT_PORT = 9527;
2204
2205
  DEFAULT_MCP_URL = `http://localhost:${DEFAULT_PORT}/api/mcp`;
2206
+ LEGACY_MCP_URL = "http://localhost:25947/api/mcp";
2205
2207
  SKILL_DIR_NAME = "agent-inspector-onboard";
2206
2208
  SKILL_FILE_NAME = "SKILL.md";
2207
2209
  COMMAND_FILE_NAME = process.platform === "win32" ? "agent-inspector-onboard.md" : "agent-inspector:onboard.md";
@@ -2753,7 +2755,7 @@ var init_doctor = __esm({
2753
2755
  "src/cli/doctor.ts"() {
2754
2756
  "use strict";
2755
2757
  init_dataDir();
2756
- DEFAULT_PORT2 = 25947;
2758
+ DEFAULT_PORT2 = 9527;
2757
2759
  PROBE_TIMEOUT_MS = 2e3;
2758
2760
  EXTENSION_REQUIRED_FILES = [
2759
2761
  "manifest.json",
@@ -17098,8 +17100,9 @@ function toBuffer(chunk) {
17098
17100
  // src/cli.ts
17099
17101
  var __filename2 = fileURLToPath2(import.meta.url);
17100
17102
  var __dirname2 = dirname2(__filename2);
17101
- var DEFAULT_PORT3 = 25947;
17102
- var DEFAULT_UPSTREAM_PORT = 25949;
17103
+ var DEFAULT_PORT3 = 9527;
17104
+ var LEGACY_ALIAS_PORT = 25947;
17105
+ var DEFAULT_UPSTREAM_PORT = 9529;
17103
17106
  var LOCAL_PROBE_TIMEOUT_MS = 2e3;
17104
17107
  var BRANDED_WINDOWS_RUNTIME_EXE = "agent-inspector.exe";
17105
17108
  var DEFAULT_CAPTURE_MODE = "simple";
@@ -17198,6 +17201,8 @@ function openBrowser(targetUrl) {
17198
17201
  detached: true,
17199
17202
  windowsHide: true
17200
17203
  });
17204
+ browserProcess.once("error", () => {
17205
+ });
17201
17206
  browserProcess.unref();
17202
17207
  }
17203
17208
  function waitForProcessExit(child) {
@@ -17264,6 +17269,19 @@ function printAccessHints(port, host) {
17264
17269
  console.log(line);
17265
17270
  }
17266
17271
  }
17272
+ function pickUpstreamPort(publicPort, legacyAliasPort) {
17273
+ const candidates = [
17274
+ DEFAULT_UPSTREAM_PORT,
17275
+ publicPort + 2 <= 65535 ? publicPort + 2 : publicPort - 2,
17276
+ LEGACY_ALIAS_PORT + 2
17277
+ ];
17278
+ for (const candidate of candidates) {
17279
+ if (Number.isInteger(candidate) && candidate > 0 && candidate <= 65535 && candidate !== publicPort && candidate !== legacyAliasPort) {
17280
+ return candidate;
17281
+ }
17282
+ }
17283
+ return DEFAULT_UPSTREAM_PORT;
17284
+ }
17267
17285
  async function tryStartIdentityProxy(identityPort, upstreamPort, upstreamHost) {
17268
17286
  try {
17269
17287
  const server = await startIdentityProxy({
@@ -17281,7 +17299,7 @@ async function tryStartIdentityProxy(identityPort, upstreamPort, upstreamHost) {
17281
17299
  }
17282
17300
  }
17283
17301
  async function runStart(args) {
17284
- const envPort = process.env["PORT"];
17302
+ const envPort = process.env["AGENT_INSPECTOR_PORT"] ?? process.env["PORT"];
17285
17303
  const portDefault = envPort !== void 0 ? Number(envPort) : DEFAULT_PORT3;
17286
17304
  const envHost = process.env["NITRO_HOST"] ?? process.env["HOST"];
17287
17305
  const envMode = process.env["AGENT_INSPECTOR_CAPTURE_MODE"] ?? process.env["AGENT_INSPECTOR_MODE"];
@@ -17296,7 +17314,7 @@ async function runStart(args) {
17296
17314
  let captureMode = DEFAULT_CAPTURE_MODE;
17297
17315
  let captureModeWasSpecified = false;
17298
17316
  let enableIdentityProxy = true;
17299
- let identityProxyPort = process.env["AGENT_INSPECTOR_PORT"] !== void 0 ? Number(process.env["AGENT_INSPECTOR_PORT"]) : DEFAULT_PORT3;
17317
+ let legacyAliasEnabled = true;
17300
17318
  if (envMode !== void 0 && envMode !== "") {
17301
17319
  const parsedMode = parseCaptureMode(envMode);
17302
17320
  if (parsedMode === null) {
@@ -17402,10 +17420,13 @@ async function runStart(args) {
17402
17420
  process.exitCode = 1;
17403
17421
  return;
17404
17422
  }
17405
- identityProxyPort = parsed;
17423
+ port = parsed;
17406
17424
  i++;
17407
17425
  break;
17408
17426
  }
17427
+ case "--no-legacy-port":
17428
+ legacyAliasEnabled = false;
17429
+ break;
17409
17430
  default:
17410
17431
  break;
17411
17432
  }
@@ -17472,7 +17493,8 @@ async function runStart(args) {
17472
17493
  } catch {
17473
17494
  }
17474
17495
  }
17475
- const upstreamPort = enableIdentityProxy ? DEFAULT_UPSTREAM_PORT : port;
17496
+ const legacyAliasPort = enableIdentityProxy && legacyAliasEnabled && port === DEFAULT_PORT3 ? LEGACY_ALIAS_PORT : null;
17497
+ const upstreamPort = enableIdentityProxy ? pickUpstreamPort(port, legacyAliasPort) : port;
17476
17498
  process.env["PORT"] = String(upstreamPort);
17477
17499
  const url2 = urlForHost(port, host);
17478
17500
  if (!forceRestart && await isInspectorHealthy(port, host)) {
@@ -17501,8 +17523,8 @@ async function runStart(args) {
17501
17523
  const restartPorts = /* @__PURE__ */ new Set();
17502
17524
  restartPorts.add(port);
17503
17525
  if (enableIdentityProxy) {
17504
- restartPorts.add(identityProxyPort);
17505
17526
  restartPorts.add(upstreamPort);
17527
+ if (legacyAliasPort !== null) restartPorts.add(legacyAliasPort);
17506
17528
  }
17507
17529
  for (const targetPort of restartPorts) {
17508
17530
  killProcessOnPort(targetPort);
@@ -17512,6 +17534,11 @@ async function runStart(args) {
17512
17534
  console.log(` Capture mode: ${captureMode}`);
17513
17535
  console.log(` Proxy: ${url2}/proxy`);
17514
17536
  printAccessHints(port, host);
17537
+ if (legacyAliasPort !== null) {
17538
+ console.log(` Legacy UI: http://localhost:${legacyAliasPort}`);
17539
+ console.log(` Legacy proxy: http://localhost:${legacyAliasPort}/proxy`);
17540
+ console.log(` Legacy MCP: http://localhost:${legacyAliasPort}/api/mcp`);
17541
+ }
17515
17542
  console.log(``);
17516
17543
  console.log(`Route AI coding tools through the proxy:`);
17517
17544
  console.log(` Claude Code: ANTHROPIC_BASE_URL=${url2}/proxy claude`);
@@ -17556,6 +17583,8 @@ async function runStart(args) {
17556
17583
  serverEnv["HOST"] = host;
17557
17584
  serverEnv["NITRO_HOST"] = host;
17558
17585
  }
17586
+ serverEnv["AGENT_INSPECTOR_PUBLIC_PORT"] = String(port);
17587
+ serverEnv["PROXY_PORT"] = String(port);
17559
17588
  serverEnv["AGENT_INSPECTOR_CAPTURE_MODE"] = captureMode;
17560
17589
  const serverProcess = spawn(serverCommand.command, serverCommand.args, {
17561
17590
  stdio: background ? ["ignore", "ignore", "ignore"] : ["ignore", "pipe", "pipe"],
@@ -17563,6 +17592,10 @@ async function runStart(args) {
17563
17592
  env: serverEnv,
17564
17593
  windowsHide: background
17565
17594
  });
17595
+ serverProcess.once("error", (err) => {
17596
+ console.error(`Failed to start Agent Inspector runtime: ${err.message}`);
17597
+ });
17598
+ const serverExit = waitForProcessExit(serverProcess);
17566
17599
  if (!background) {
17567
17600
  pipeServerOutput(serverProcess, {
17568
17601
  enableIdentityProxy,
@@ -17570,23 +17603,39 @@ async function runStart(args) {
17570
17603
  upstreamPort
17571
17604
  });
17572
17605
  }
17573
- const identityProxy = enableIdentityProxy ? await tryStartIdentityProxy(identityProxyPort, upstreamPort, host) : null;
17606
+ const identityProxies = [];
17607
+ if (enableIdentityProxy) {
17608
+ const primaryProxy = await tryStartIdentityProxy(port, upstreamPort, host);
17609
+ if (primaryProxy !== null) {
17610
+ identityProxies.push({ label: "primary", port, server: primaryProxy });
17611
+ }
17612
+ if (legacyAliasPort !== null) {
17613
+ const legacyProxy = await tryStartIdentityProxy(legacyAliasPort, upstreamPort, host);
17614
+ if (legacyProxy !== null) {
17615
+ identityProxies.push({ label: "legacy", port: legacyAliasPort, server: legacyProxy });
17616
+ }
17617
+ }
17618
+ }
17574
17619
  if (background) {
17575
17620
  serverProcess.unref();
17576
17621
  if (await waitForInspectorHealthy(upstreamPort, 5e3, host)) {
17577
17622
  console.log(`agent-inspector background server is ready at ${url2}`);
17578
- if (identityProxy !== null) {
17579
- console.log(`Identity proxy ready on port ${identityProxyPort} (PID-attributing proxy).`);
17623
+ if (identityProxies.length > 0) {
17624
+ console.log(`Identity proxy ready on port ${port} (PID-attributing proxy).`);
17580
17625
  }
17581
17626
  printAccessHints(port, host);
17582
- if (identityProxy !== null) {
17627
+ if (legacyAliasPort !== null) {
17628
+ console.log(` Legacy proxy: http://localhost:${legacyAliasPort}/proxy`);
17629
+ console.log(` Legacy MCP: http://localhost:${legacyAliasPort}/api/mcp`);
17630
+ }
17631
+ if (identityProxies.length > 0) {
17583
17632
  console.log(
17584
17633
  ``,
17585
17634
  `Route AI coding tools through the identity proxy for accurate PID attribution:`,
17586
- ` Claude Code: ANTHROPIC_BASE_URL=http://localhost:${identityProxyPort}/proxy claude`,
17587
- ` OpenCode: LLM_BASE_URL=http://localhost:${identityProxyPort}/proxy opencode`,
17588
- ` MiMo Code: OPENAI_BASE_URL=http://localhost:${identityProxyPort}/proxy mimo`,
17589
- ` (Direct ${port} still works; it falls back to OS-scan heuristic.)`
17635
+ ` Claude Code: ANTHROPIC_BASE_URL=http://localhost:${port}/proxy claude`,
17636
+ ` OpenCode: LLM_BASE_URL=http://localhost:${port}/proxy opencode`,
17637
+ ` MiMo Code: OPENAI_BASE_URL=http://localhost:${port}/proxy mimo`,
17638
+ legacyAliasPort === null ? ` Override the port with --port <n> when needed.` : ` Legacy configs using http://localhost:${legacyAliasPort}/proxy still work.`
17590
17639
  );
17591
17640
  }
17592
17641
  return;
@@ -17595,15 +17644,21 @@ async function runStart(args) {
17595
17644
  process.exitCode = 1;
17596
17645
  return;
17597
17646
  }
17598
- if (identityProxy !== null) {
17647
+ if (identityProxies.length > 0) {
17599
17648
  console.log(``);
17600
17649
  console.log(`Identity proxy ready at ${url2} (PID-attributing public entrypoint).`);
17650
+ if (legacyAliasPort !== null) {
17651
+ const legacyReady = identityProxies.some((proxy) => proxy.label === "legacy");
17652
+ if (legacyReady) {
17653
+ console.log(` Legacy alias ready at http://localhost:${legacyAliasPort}.`);
17654
+ }
17655
+ }
17601
17656
  if (upstreamPort !== port) {
17602
17657
  console.log(` Internal runtime port ${upstreamPort} is hidden behind the public proxy.`);
17603
17658
  }
17604
17659
  }
17605
- process.exitCode = await waitForProcessExit(serverProcess);
17606
- if (identityProxy !== null) {
17607
- await new Promise((resolve2) => identityProxy.close(() => resolve2()));
17660
+ process.exitCode = await serverExit;
17661
+ for (const proxy of identityProxies) {
17662
+ await new Promise((resolve2) => proxy.server.close(() => resolve2()));
17608
17663
  }
17609
17664
  }
@@ -1,5 +1,5 @@
1
1
  {
2
- "date": "2026-07-06T23:47:38.605Z",
2
+ "date": "2026-07-07T00:48:06.729Z",
3
3
  "preset": "node-server",
4
4
  "framework": {
5
5
  "name": "nitro",
@@ -1 +1 @@
1
- import{r as h,j as t}from"./main-BDfcCp_1.js";import{c as Z,g as $,r as L,a as q,X as ee,b as m,B as te,f as P,R as re,C as ne,M as V,d as _,e as M,h as B,i as se,j as ae,k as oe,L as ie}from"./ProxyViewerContainer-GI3xErl5.js";const de=[["line",{x1:"5",x2:"19",y1:"9",y2:"9",key:"1nwqeh"}],["line",{x1:"5",x2:"19",y1:"15",y2:"15",key:"g8yjpy"}]],le=Z("equal",de),ce="";function j(e){if(e.length===0)return ce;let r="";for(let n=0;n<e.length;n++){const a=e[n];a!==void 0&&(typeof a=="number"?r+=`[${a}]`:n===0?r+=a:r+=`.${a}`)}return r}function ue(e){return typeof e=="object"&&e!==null&&!Array.isArray(e)}function D(e){if(typeof e=="string")try{return C(JSON.parse(e))}catch{return{kind:"primitive",value:e}}return C(e)}function C(e){if(e===null)return{kind:"primitive",value:null};if(typeof e=="string")return{kind:"primitive",value:e};if(typeof e=="number")return{kind:"primitive",value:e};if(typeof e=="boolean")return{kind:"primitive",value:e};if(Array.isArray(e))return{kind:"array",value:e.map(r=>C(r))};if(ue(e)){const r={};for(const n of Object.keys(e).sort())r[n]=C(e[n]);return{kind:"object",value:r}}return{kind:"primitive",value:null}}function xe(e,r){const n=[];return R([],e,r,n),n}function R(e,r,n,a){const d=j(e);if(S(r,n)){a.push({kind:"equal",path:d,value:r});return}if(r.kind!==n.kind){a.push({kind:"changed",path:d,left:r,right:n});return}if(r.kind==="primitive"&&n.kind==="primitive"){a.push({kind:"changed",path:d,left:r,right:n});return}if(r.kind==="object"&&n.kind==="object"){const i=Object.keys(r.value),s=Object.keys(n.value),o=new Set(s);for(const l of i){const f=r.value[l];if(f!==void 0)if(!o.has(l))a.push({kind:"removed",path:j([...e,l]),value:f});else{const p=n.value[l];if(p===void 0)continue;R([...e,l],f,p,a)}}for(const l of s){if(i.includes(l))continue;const f=n.value[l];f!==void 0&&a.push({kind:"added",path:j([...e,l]),value:f})}return}if(r.kind==="array"&&n.kind==="array"){const i=Math.min(r.value.length,n.value.length);for(let s=0;s<i;s++){const o=r.value[s],l=n.value[s];o===void 0||l===void 0||R([...e,s],o,l,a)}for(let s=i;s<n.value.length;s++){const o=n.value[s];o!==void 0&&a.push({kind:"added",path:j([...e,s]),value:o})}for(let s=i;s<r.value.length;s++){const o=r.value[s];o!==void 0&&a.push({kind:"removed",path:j([...e,s]),value:o})}}}function S(e,r){if(e.kind!==r.kind)return!1;if(e.kind==="primitive"&&r.kind==="primitive")return e.value===r.value;if(e.kind==="array"&&r.kind==="array"){if(e.value.length!==r.value.length)return!1;for(let n=0;n<e.value.length;n++){const a=e.value[n],d=r.value[n];if(a===void 0||d===void 0||!S(a,d))return!1}return!0}if(e.kind==="object"&&r.kind==="object"){const n=Object.keys(e.value),a=Object.keys(r.value);if(n.length!==a.length)return!1;for(const d of n){const i=e.value[d],s=r.value[d];if(i===void 0||s===void 0||!S(i,s))return!1}return!0}return!1}function v(e,r=80){let n;switch(e.kind){case"primitive":n=e.value===null?"null":JSON.stringify(e.value);break;case"array":n=`[… ${e.value.length} items]`;break;case"object":n=`{… ${Object.keys(e.value).length} keys}`;break}return n.length>r&&(n=`${n.slice(0,r-1)}…`),n}function N(e,r=2){return JSON.stringify(E(e),null,r)}function E(e){switch(e.kind){case"primitive":return e.value;case"array":return e.value.map(E);case"object":{const r={};for(const[n,a]of Object.entries(e.value))r[n]=E(a);return r}}}function w({text:e,defaultExpandDepth:r}){return t.jsx(h.Suspense,{fallback:t.jsx("div",{className:"text-xs text-muted-foreground",children:"Loading JSON..."}),children:t.jsx(ie,{text:e,defaultExpandDepth:r})})}function K(e){if(e==="")return"";for(let r=e.length-1;r>=0;r--){const n=e[r];if(n==="."||n==="[")return e.substring(0,r)}return""}function A(e){return e.kind==="equal"&&(e.value.kind==="object"||e.value.kind==="array")}function me(e){const r=[];let n=0;for(;n<e.length;){const a=e[n];if(a!==void 0&&A(a)){const d=K(a.path);let i=n+1;for(;i<e.length;){const s=e[i];if(s===void 0||!A(s)||K(s.path)!==d)break;i++}if(i-n>1){const s=[];for(let o=n;o<i;o++){const l=e[o];l!==void 0&&l.kind==="equal"&&s.push(l)}r.push({kind:"equal-run",ops:s}),n=i;continue}}a!==void 0&&r.push({kind:"single",op:a}),n++}return r}const F={added:{icon:_,accent:"text-emerald-600 dark:text-emerald-400",bg:"bg-emerald-500/5 hover:bg-emerald-500/10",border:"border-l-emerald-500",label:"ADDED"},removed:{icon:V,accent:"text-rose-600 dark:text-rose-400",bg:"bg-rose-500/5 hover:bg-rose-500/10",border:"border-l-rose-500",label:"REMOVED"},changed:{icon:M,accent:"text-amber-600 dark:text-amber-400",bg:"bg-amber-500/5 hover:bg-amber-500/10",border:"border-l-amber-500",label:"CHANGED"},equal:{icon:le,accent:"text-muted-foreground/70",bg:"bg-muted/20 hover:bg-muted/30",border:"border-l-muted-foreground/20",label:"EQUAL"}};function fe({ops:e,expanded:r,onToggle:n}){const a=e[0],d=e[e.length-1];if(a===void 0||d===void 0)return t.jsx("div",{className:"text-muted-foreground/40 text-xs",children:"—"});const i=a.path,s=d.path,o=e.length===1?i:`${i} … ${s}`,l=a.value.kind==="array"?`${e.length} equal arrays`:a.value.kind==="object"?`${e.length} equal objects`:"equal",f=F.equal;return t.jsxs("div",{className:m("border-l-4 rounded-sm",f.border,f.bg),children:[t.jsxs("button",{type:"button",onClick:n,className:"w-full text-left flex items-center gap-2 px-3 py-1.5 text-xs text-muted-foreground cursor-pointer",children:[t.jsx(B,{className:m("size-3 transition-transform shrink-0",r&&"rotate-90")}),t.jsx(f.icon,{className:m("size-3 shrink-0",f.accent)}),t.jsx("span",{className:"font-mono truncate flex-1",title:`${i} … ${s}`,children:o}),t.jsx("span",{className:m("text-[10px] uppercase tracking-wider shrink-0",f.accent),children:f.label}),t.jsxs("span",{className:"text-muted-foreground/60 shrink-0",children:["(",l,")"]})]}),r&&t.jsx("div",{className:"ml-5 mt-1 mb-2 space-y-2 pr-2",children:e.map(p=>t.jsxs("div",{className:"border border-border/50 rounded p-2 bg-muted/20",children:[t.jsx("div",{className:"font-mono text-xs text-muted-foreground mb-1",children:p.path}),t.jsx(w,{text:N(p.value),defaultExpandDepth:0})]},p.path))})]})}function pe({op:e,idx:r,copiedPath:n,onCopyPath:a,expanded:d,onToggle:i}){const s=F[e.kind],o=s.icon,l=e.kind==="added"||e.kind==="removed"?e.value.kind==="object"||e.value.kind==="array":e.kind==="changed"?e.left.kind==="object"||e.left.kind==="array"||e.right.kind==="object"||e.right.kind==="array":!1,f=e.kind==="changed"?[{text:v(e.left,400),tone:"text-rose-700 dark:text-rose-300 line-through"},{text:v(e.right,400),tone:"text-emerald-700 dark:text-emerald-300"}]:e.kind==="removed"?[{text:v(e.value,400),tone:"text-rose-700 dark:text-rose-300 line-through"}]:e.kind==="added"?[{text:v(e.value,400),tone:"text-emerald-700 dark:text-emerald-300"}]:[{text:v(e.value,400),tone:"text-muted-foreground"}],p=n===e.path&&e.path!=="";return t.jsxs("div",{"data-diff-idx":r,"data-diff-kind":e.kind,className:m("border-l-4 rounded-sm px-3 py-2 my-0.5 transition-colors",s.border,s.bg),children:[t.jsxs("button",{type:"button",onClick:i,disabled:!l,className:m("w-full flex items-center gap-2 text-xs text-left rounded-sm",l?"cursor-pointer":"cursor-default"),"aria-expanded":l?d:void 0,"aria-label":l?d?`Collapse ${e.path||"root"}`:`Expand ${e.path||"root"}`:void 0,children:[l?t.jsx(B,{className:m("size-3 shrink-0 transition-transform",s.accent,d&&"rotate-90")}):t.jsx("span",{className:"size-3 shrink-0","aria-hidden":"true"}),t.jsx(o,{className:m("size-3.5 shrink-0",s.accent),strokeWidth:2.5}),t.jsx("span",{className:"font-mono truncate flex-1 min-w-0",title:e.path||"(root)",children:e.path===""?"(root)":e.path}),t.jsx("span",{className:m("text-[9px] font-bold uppercase tracking-wider shrink-0 px-1.5 py-0.5 rounded",s.accent,e.kind==="equal"?"bg-muted/40":"bg-background/60"),children:s.label}),e.path!==""&&t.jsx("span",{role:"button",tabIndex:0,onClick:b=>{b.stopPropagation(),a(e.path)},onKeyDown:b=>{(b.key==="Enter"||b.key===" ")&&(b.stopPropagation(),b.preventDefault(),a(e.path))},className:m("shrink-0 p-1 rounded transition-colors cursor-pointer inline-flex items-center justify-center",p?"text-emerald-500":"text-muted-foreground/50 hover:text-foreground hover:bg-muted"),"aria-label":p?"Copied":"Copy",title:p?"Copied!":"Copy",children:p?t.jsx(se,{className:"size-3"}):t.jsx(ae,{className:"size-3"})})]}),f.map((b,y)=>t.jsx("div",{className:m("font-mono text-xs mt-1 break-all pl-5",b.tone),children:b.text},y)),t.jsx("div",{className:"overflow-hidden transition-all duration-200",style:{maxHeight:d&&l?"2000px":"0"},"aria-hidden":!d,children:d&&l&&e.kind!=="equal"?t.jsx(he,{op:e}):null})]})}function he({op:e}){if(e.kind==="added"||e.kind==="removed")return t.jsx("div",{className:"pl-5 mt-2 border border-border/50 rounded p-2 bg-muted/20",children:t.jsx(w,{text:N(e.value),defaultExpandDepth:0})});const r=e.left.kind==="object"||e.left.kind==="array",n=e.right.kind==="object"||e.right.kind==="array";return!r&&!n?t.jsx("div",{className:"pl-5 mt-2 text-xs text-muted-foreground/70 italic",children:"Primitive values are shown inline above."}):t.jsxs("div",{className:"pl-5 mt-2 grid grid-cols-1 md:grid-cols-2 gap-2",children:[t.jsxs("div",{className:"border border-rose-500/30 rounded p-2 bg-rose-500/5",children:[t.jsx("div",{className:"text-[10px] uppercase tracking-wider text-rose-500 mb-1",children:"Old"}),t.jsx(w,{text:N(e.left),defaultExpandDepth:0})]}),t.jsxs("div",{className:"border border-emerald-500/30 rounded p-2 bg-emerald-500/5",children:[t.jsx("div",{className:"text-[10px] uppercase tracking-wider text-emerald-500 mb-1",children:"New"}),t.jsx(w,{text:N(e.right),defaultExpandDepth:0})]})]})}function be({counts:e,onJumpTo:r}){const n=e.added+e.removed+e.changed;return t.jsxs("div",{className:"px-4 py-2 border-b border-border bg-muted/20 flex items-center gap-2 text-xs flex-wrap",children:[t.jsxs("span",{className:"text-muted-foreground font-medium",children:[n," ",n===1?"change":"changes"]}),t.jsxs("button",{type:"button",onClick:()=>r("removed"),disabled:e.removed===0,className:m("inline-flex items-center gap-1 px-2 py-0.5 rounded-full border cursor-pointer transition-colors",e.removed>0?"border-rose-500/40 text-rose-600 dark:text-rose-400 bg-rose-500/10 hover:bg-rose-500/20":"border-border text-muted-foreground/40 cursor-not-allowed"),title:e.removed>0?"Jump to first removed":"No removals",children:[t.jsx(V,{className:"size-3"}),e.removed," removed"]}),t.jsxs("button",{type:"button",onClick:()=>r("added"),disabled:e.added===0,className:m("inline-flex items-center gap-1 px-2 py-0.5 rounded-full border cursor-pointer transition-colors",e.added>0?"border-emerald-500/40 text-emerald-600 dark:text-emerald-400 bg-emerald-500/10 hover:bg-emerald-500/20":"border-border text-muted-foreground/40 cursor-not-allowed"),title:e.added>0?"Jump to first added":"No additions",children:[t.jsx(_,{className:"size-3"}),e.added," added"]}),t.jsxs("button",{type:"button",onClick:()=>r("changed"),disabled:e.changed===0,className:m("inline-flex items-center gap-1 px-2 py-0.5 rounded-full border cursor-pointer transition-colors",e.changed>0?"border-amber-500/40 text-amber-600 dark:text-amber-400 bg-amber-500/10 hover:bg-amber-500/20":"border-border text-muted-foreground/40 cursor-not-allowed"),title:e.changed>0?"Jump to first changed":"No changes",children:[t.jsx(M,{className:"size-3"}),e.changed," changed"]})]})}function ve({mode:e,onChange:r}){return t.jsxs("div",{className:"inline-flex rounded-md border border-border overflow-hidden",children:[t.jsxs("button",{type:"button",onClick:()=>r("unified"),"aria-pressed":e==="unified",className:m("flex items-center gap-1 px-2 py-1 text-xs transition-colors cursor-pointer",e==="unified"?"bg-muted text-foreground":"hover:bg-muted/50 text-muted-foreground"),title:"Unified view (single column, emphasized diffs)",children:[t.jsx(re,{className:"size-3"}),"Unified"]}),t.jsxs("button",{type:"button",onClick:()=>r("split"),"aria-pressed":e==="split",className:m("flex items-center gap-1 px-2 py-1 text-xs transition-colors border-l border-border cursor-pointer",e==="split"?"bg-muted text-foreground":"hover:bg-muted/50 text-muted-foreground"),title:"Split view (path | left | right)",children:[t.jsx(ne,{className:"size-3"}),"Split"]})]})}function J({log:e,side:r,displayNumber:n}){const a=q(e);return t.jsxs("div",{className:"flex-1 min-w-0 space-y-1 text-xs",children:[t.jsxs("div",{className:"flex items-center gap-2",children:[t.jsx(te,{variant:"outline",className:m("text-[10px] px-1.5 py-0 h-5 font-mono shrink-0",r==="left"?"border-rose-500/40 text-rose-400":"border-emerald-500/40 text-emerald-400"),children:r==="left"?"← Left":"Right →"}),t.jsxs("span",{className:"font-mono text-blue-400/80",title:`Log ID ${String(e.id)}`,children:["#",n]}),e.model!==null&&t.jsx("span",{className:"font-mono text-muted-foreground truncate",children:e.model})]}),t.jsxs("div",{className:"flex items-center gap-3 text-muted-foreground font-mono",children:[e.cacheCreationInputTokens!==null&&e.cacheCreationInputTokens>0&&t.jsxs("span",{className:"text-emerald-400",children:["KV Cache +",P(e.cacheCreationInputTokens)]}),e.cacheReadInputTokens!==null&&e.cacheReadInputTokens>0&&t.jsxs("span",{className:"text-purple-400",children:["KV Cache ~",P(e.cacheReadInputTokens)]}),t.jsx("span",{className:"truncate",title:e.timestamp,children:e.timestamp})]}),t.jsxs("div",{className:"text-muted-foreground/70 font-mono truncate",title:a,children:["session: ",a]})]})}function ye({left:e,right:r,leftDisplayNumber:n,rightDisplayNumber:a,onClose:d}){const i=h.useMemo(()=>{const c=$(L(e)).analyzeRequest(e.rawRequestBody),u=$(L(r)).analyzeRequest(r.rawRequestBody),x=D(c.comparisonValue),g=D(u.comparisonValue);return xe(x,g)},[e.apiFormat,e.path,e.rawRequestBody,r.apiFormat,r.path,r.rawRequestBody]),s=h.useMemo(()=>me(i),[i]),o=h.useMemo(()=>{let c=0,u=0,x=0;for(const g of s)if(g.kind==="single")switch(g.op.kind){case"added":c++;break;case"removed":u++;break;case"changed":x++;break}return{added:c,removed:u,changed:x}},[s]),[l,f]=h.useState(new Set),p=c=>{f(u=>{const x=new Set(u);return x.has(c)?x.delete(c):x.add(c),x})},[b,y]=h.useState(new Set),U=c=>{y(u=>{const x=new Set(u);return x.has(c)?x.delete(c):x.add(c),x})};h.useEffect(()=>{y(new Set)},[e.id,r.id]);const[T,H]=h.useState("unified"),I=h.useRef(null),[G,z]=h.useState(null),k=h.useRef(null),Q=c=>{oe(c).then(u=>{u&&(z(c),k.current!==null&&clearTimeout(k.current),k.current=setTimeout(()=>z(null),1500))})};h.useEffect(()=>()=>{k.current!==null&&clearTimeout(k.current)},[]);const W=c=>{const u=s.findIndex(O=>O.kind==="single"&&O.op.kind===c);if(u===-1)return;const x=I.current;if(x===null)return;const g=x.querySelector(`[data-diff-idx="${u}"]`);g!==null&&g.scrollIntoView({behavior:"smooth",block:"center"})};h.useEffect(()=>{const c=x=>{x.key==="Escape"&&d()};document.addEventListener("keydown",c);const u=document.body.style.overflow;return document.body.style.overflow="hidden",()=>{document.removeEventListener("keydown",c),document.body.style.overflow=u}},[d]);const X=q(e)===q(r),Y=i.length===1&&i[0]?.kind==="equal";return t.jsxs("div",{className:"fixed inset-0 z-50 flex justify-end",role:"dialog","aria-modal":"true","aria-label":"Compare two log requests",children:[t.jsx("button",{type:"button",onClick:d,"aria-label":"Close compare drawer",className:"absolute inset-0 bg-black/40 cursor-default",tabIndex:-1}),t.jsxs("div",{className:m("relative bg-background border-l border-border shadow-xl","w-full md:w-[70vw] max-w-[1100px] flex flex-col h-full"),onClick:c=>c.stopPropagation(),onKeyDown:c=>c.stopPropagation(),children:[t.jsxs("div",{className:"flex items-start gap-4 px-4 py-3 border-b border-border",children:[t.jsxs("div",{className:"flex-1 flex gap-4 min-w-0",children:[t.jsx(J,{log:e,side:"left",displayNumber:n}),t.jsx(J,{log:r,side:"right",displayNumber:a})]}),t.jsxs("div",{className:"flex items-center gap-2 shrink-0",children:[t.jsx(ve,{mode:T,onChange:H}),t.jsx("button",{type:"button",onClick:d,"aria-label":"Close",className:"p-1 rounded text-muted-foreground hover:text-foreground hover:bg-muted cursor-pointer",children:t.jsx(ee,{className:"size-4"})})]})]}),!X&&t.jsx("div",{className:"px-4 py-1.5 text-xs text-amber-400 bg-amber-500/10 border-b border-border",children:"Heads up: the two selected logs are from different sessions."}),Y?t.jsx("div",{className:"flex-1 min-h-0 overflow-y-auto flex items-center justify-center text-muted-foreground text-sm",children:"The two Request payloads are identical."}):t.jsxs(t.Fragment,{children:[t.jsx(be,{counts:o,onJumpTo:W}),t.jsx("div",{ref:I,className:"flex-1 min-h-0 overflow-y-auto",children:T==="unified"?t.jsx("div",{className:"px-3 py-2 space-y-0.5",children:s.map((c,u)=>{if(c.kind==="equal-run")return t.jsx(fe,{ops:c.ops,expanded:l.has(u),onToggle:()=>p(u)},`r${u}`);const x=c.op;return t.jsx(pe,{op:x,idx:u,copiedPath:G,onCopyPath:Q,expanded:b.has(u),onToggle:()=>U(u)},`o${u}`)})}):t.jsx(ge,{grouped:s,left:e,right:r,leftDisplayNumber:n,rightDisplayNumber:a})})]})]})]})}function ge({grouped:e,left:r,right:n,leftDisplayNumber:a,rightDisplayNumber:d}){return t.jsxs("div",{className:"grid grid-cols-[200px_1fr_1fr] gap-x-2 gap-y-0.5 px-3 py-2 text-xs",children:[t.jsxs("div",{className:"grid grid-cols-[200px_1fr_1fr] gap-x-2 col-span-3 pb-2 mb-2 border-b border-border text-[10px] uppercase tracking-wider text-muted-foreground",children:[t.jsx("span",{children:"Path"}),t.jsxs("span",{title:`Log ID ${String(r.id)}`,children:["Left (Log #",a,")"]}),t.jsxs("span",{title:`Log ID ${String(n.id)}`,children:["Right (Log #",d,")"]})]}),e.map((i,s)=>{if(i.kind==="equal-run")return t.jsxs("div",{className:"col-span-3 px-2 py-1 text-xs text-muted-foreground/60",children:[i.ops.length," equal siblings collapsed — switch to Unified to expand"]},s);const o=i.op;return o.kind==="equal"?t.jsxs("div",{className:"col-span-3 grid grid-cols-[200px_1fr_1fr] gap-x-2 px-2 py-0.5 text-muted-foreground",children:[t.jsx("span",{className:"font-mono text-xs truncate",title:o.path,children:o.path}),t.jsx("span",{className:"font-mono text-xs break-all opacity-60",children:v(o.value,200)}),t.jsx("span",{className:"font-mono text-xs break-all opacity-60",children:v(o.value,200)})]},s):o.kind==="added"?t.jsxs("div",{className:"col-span-3 px-2 py-1 rounded text-xs border-l-2 border-l-emerald-400/70 bg-emerald-500/5",children:[t.jsx("div",{className:"font-mono text-xs text-muted-foreground mb-0.5",children:o.path}),t.jsxs("div",{className:"font-mono break-all text-emerald-300/90",children:["+ ",v(o.value,400)]})]},s):o.kind==="removed"?t.jsxs("div",{className:"col-span-3 px-2 py-1 rounded text-xs border-l-2 border-l-rose-400/70 bg-rose-500/5",children:[t.jsx("div",{className:"font-mono text-xs text-muted-foreground mb-0.5",children:o.path}),t.jsxs("div",{className:"font-mono break-all text-rose-300/90 line-through",children:["− ",v(o.value,400)]})]},s):t.jsxs("div",{className:"col-span-3 px-2 py-1 rounded text-xs border-l-2 border-l-amber-400/70 bg-amber-500/5",children:[t.jsx("div",{className:"font-mono text-xs text-muted-foreground mb-1",children:o.path}),t.jsxs("div",{className:"grid grid-cols-2 gap-2",children:[t.jsx("div",{className:"font-mono text-rose-300/90 break-all line-through",children:v(o.left,400)}),t.jsx("div",{className:"font-mono text-emerald-300/90 break-all",children:v(o.right,400)})]})]},s)})]})}export{ye as CompareDrawer};
1
+ import{r as h,j as t}from"./main-Ba9x64uY.js";import{c as Z,g as $,r as L,a as q,X as ee,b as m,B as te,f as P,R as re,C as ne,M as V,d as _,e as M,h as B,i as se,j as ae,k as oe,L as ie}from"./ProxyViewerContainer-7b_uwvT7.js";const de=[["line",{x1:"5",x2:"19",y1:"9",y2:"9",key:"1nwqeh"}],["line",{x1:"5",x2:"19",y1:"15",y2:"15",key:"g8yjpy"}]],le=Z("equal",de),ce="";function j(e){if(e.length===0)return ce;let r="";for(let n=0;n<e.length;n++){const a=e[n];a!==void 0&&(typeof a=="number"?r+=`[${a}]`:n===0?r+=a:r+=`.${a}`)}return r}function ue(e){return typeof e=="object"&&e!==null&&!Array.isArray(e)}function D(e){if(typeof e=="string")try{return C(JSON.parse(e))}catch{return{kind:"primitive",value:e}}return C(e)}function C(e){if(e===null)return{kind:"primitive",value:null};if(typeof e=="string")return{kind:"primitive",value:e};if(typeof e=="number")return{kind:"primitive",value:e};if(typeof e=="boolean")return{kind:"primitive",value:e};if(Array.isArray(e))return{kind:"array",value:e.map(r=>C(r))};if(ue(e)){const r={};for(const n of Object.keys(e).sort())r[n]=C(e[n]);return{kind:"object",value:r}}return{kind:"primitive",value:null}}function xe(e,r){const n=[];return R([],e,r,n),n}function R(e,r,n,a){const d=j(e);if(S(r,n)){a.push({kind:"equal",path:d,value:r});return}if(r.kind!==n.kind){a.push({kind:"changed",path:d,left:r,right:n});return}if(r.kind==="primitive"&&n.kind==="primitive"){a.push({kind:"changed",path:d,left:r,right:n});return}if(r.kind==="object"&&n.kind==="object"){const i=Object.keys(r.value),s=Object.keys(n.value),o=new Set(s);for(const l of i){const f=r.value[l];if(f!==void 0)if(!o.has(l))a.push({kind:"removed",path:j([...e,l]),value:f});else{const p=n.value[l];if(p===void 0)continue;R([...e,l],f,p,a)}}for(const l of s){if(i.includes(l))continue;const f=n.value[l];f!==void 0&&a.push({kind:"added",path:j([...e,l]),value:f})}return}if(r.kind==="array"&&n.kind==="array"){const i=Math.min(r.value.length,n.value.length);for(let s=0;s<i;s++){const o=r.value[s],l=n.value[s];o===void 0||l===void 0||R([...e,s],o,l,a)}for(let s=i;s<n.value.length;s++){const o=n.value[s];o!==void 0&&a.push({kind:"added",path:j([...e,s]),value:o})}for(let s=i;s<r.value.length;s++){const o=r.value[s];o!==void 0&&a.push({kind:"removed",path:j([...e,s]),value:o})}}}function S(e,r){if(e.kind!==r.kind)return!1;if(e.kind==="primitive"&&r.kind==="primitive")return e.value===r.value;if(e.kind==="array"&&r.kind==="array"){if(e.value.length!==r.value.length)return!1;for(let n=0;n<e.value.length;n++){const a=e.value[n],d=r.value[n];if(a===void 0||d===void 0||!S(a,d))return!1}return!0}if(e.kind==="object"&&r.kind==="object"){const n=Object.keys(e.value),a=Object.keys(r.value);if(n.length!==a.length)return!1;for(const d of n){const i=e.value[d],s=r.value[d];if(i===void 0||s===void 0||!S(i,s))return!1}return!0}return!1}function v(e,r=80){let n;switch(e.kind){case"primitive":n=e.value===null?"null":JSON.stringify(e.value);break;case"array":n=`[… ${e.value.length} items]`;break;case"object":n=`{… ${Object.keys(e.value).length} keys}`;break}return n.length>r&&(n=`${n.slice(0,r-1)}…`),n}function N(e,r=2){return JSON.stringify(E(e),null,r)}function E(e){switch(e.kind){case"primitive":return e.value;case"array":return e.value.map(E);case"object":{const r={};for(const[n,a]of Object.entries(e.value))r[n]=E(a);return r}}}function w({text:e,defaultExpandDepth:r}){return t.jsx(h.Suspense,{fallback:t.jsx("div",{className:"text-xs text-muted-foreground",children:"Loading JSON..."}),children:t.jsx(ie,{text:e,defaultExpandDepth:r})})}function K(e){if(e==="")return"";for(let r=e.length-1;r>=0;r--){const n=e[r];if(n==="."||n==="[")return e.substring(0,r)}return""}function A(e){return e.kind==="equal"&&(e.value.kind==="object"||e.value.kind==="array")}function me(e){const r=[];let n=0;for(;n<e.length;){const a=e[n];if(a!==void 0&&A(a)){const d=K(a.path);let i=n+1;for(;i<e.length;){const s=e[i];if(s===void 0||!A(s)||K(s.path)!==d)break;i++}if(i-n>1){const s=[];for(let o=n;o<i;o++){const l=e[o];l!==void 0&&l.kind==="equal"&&s.push(l)}r.push({kind:"equal-run",ops:s}),n=i;continue}}a!==void 0&&r.push({kind:"single",op:a}),n++}return r}const F={added:{icon:_,accent:"text-emerald-600 dark:text-emerald-400",bg:"bg-emerald-500/5 hover:bg-emerald-500/10",border:"border-l-emerald-500",label:"ADDED"},removed:{icon:V,accent:"text-rose-600 dark:text-rose-400",bg:"bg-rose-500/5 hover:bg-rose-500/10",border:"border-l-rose-500",label:"REMOVED"},changed:{icon:M,accent:"text-amber-600 dark:text-amber-400",bg:"bg-amber-500/5 hover:bg-amber-500/10",border:"border-l-amber-500",label:"CHANGED"},equal:{icon:le,accent:"text-muted-foreground/70",bg:"bg-muted/20 hover:bg-muted/30",border:"border-l-muted-foreground/20",label:"EQUAL"}};function fe({ops:e,expanded:r,onToggle:n}){const a=e[0],d=e[e.length-1];if(a===void 0||d===void 0)return t.jsx("div",{className:"text-muted-foreground/40 text-xs",children:"—"});const i=a.path,s=d.path,o=e.length===1?i:`${i} … ${s}`,l=a.value.kind==="array"?`${e.length} equal arrays`:a.value.kind==="object"?`${e.length} equal objects`:"equal",f=F.equal;return t.jsxs("div",{className:m("border-l-4 rounded-sm",f.border,f.bg),children:[t.jsxs("button",{type:"button",onClick:n,className:"w-full text-left flex items-center gap-2 px-3 py-1.5 text-xs text-muted-foreground cursor-pointer",children:[t.jsx(B,{className:m("size-3 transition-transform shrink-0",r&&"rotate-90")}),t.jsx(f.icon,{className:m("size-3 shrink-0",f.accent)}),t.jsx("span",{className:"font-mono truncate flex-1",title:`${i} … ${s}`,children:o}),t.jsx("span",{className:m("text-[10px] uppercase tracking-wider shrink-0",f.accent),children:f.label}),t.jsxs("span",{className:"text-muted-foreground/60 shrink-0",children:["(",l,")"]})]}),r&&t.jsx("div",{className:"ml-5 mt-1 mb-2 space-y-2 pr-2",children:e.map(p=>t.jsxs("div",{className:"border border-border/50 rounded p-2 bg-muted/20",children:[t.jsx("div",{className:"font-mono text-xs text-muted-foreground mb-1",children:p.path}),t.jsx(w,{text:N(p.value),defaultExpandDepth:0})]},p.path))})]})}function pe({op:e,idx:r,copiedPath:n,onCopyPath:a,expanded:d,onToggle:i}){const s=F[e.kind],o=s.icon,l=e.kind==="added"||e.kind==="removed"?e.value.kind==="object"||e.value.kind==="array":e.kind==="changed"?e.left.kind==="object"||e.left.kind==="array"||e.right.kind==="object"||e.right.kind==="array":!1,f=e.kind==="changed"?[{text:v(e.left,400),tone:"text-rose-700 dark:text-rose-300 line-through"},{text:v(e.right,400),tone:"text-emerald-700 dark:text-emerald-300"}]:e.kind==="removed"?[{text:v(e.value,400),tone:"text-rose-700 dark:text-rose-300 line-through"}]:e.kind==="added"?[{text:v(e.value,400),tone:"text-emerald-700 dark:text-emerald-300"}]:[{text:v(e.value,400),tone:"text-muted-foreground"}],p=n===e.path&&e.path!=="";return t.jsxs("div",{"data-diff-idx":r,"data-diff-kind":e.kind,className:m("border-l-4 rounded-sm px-3 py-2 my-0.5 transition-colors",s.border,s.bg),children:[t.jsxs("button",{type:"button",onClick:i,disabled:!l,className:m("w-full flex items-center gap-2 text-xs text-left rounded-sm",l?"cursor-pointer":"cursor-default"),"aria-expanded":l?d:void 0,"aria-label":l?d?`Collapse ${e.path||"root"}`:`Expand ${e.path||"root"}`:void 0,children:[l?t.jsx(B,{className:m("size-3 shrink-0 transition-transform",s.accent,d&&"rotate-90")}):t.jsx("span",{className:"size-3 shrink-0","aria-hidden":"true"}),t.jsx(o,{className:m("size-3.5 shrink-0",s.accent),strokeWidth:2.5}),t.jsx("span",{className:"font-mono truncate flex-1 min-w-0",title:e.path||"(root)",children:e.path===""?"(root)":e.path}),t.jsx("span",{className:m("text-[9px] font-bold uppercase tracking-wider shrink-0 px-1.5 py-0.5 rounded",s.accent,e.kind==="equal"?"bg-muted/40":"bg-background/60"),children:s.label}),e.path!==""&&t.jsx("span",{role:"button",tabIndex:0,onClick:b=>{b.stopPropagation(),a(e.path)},onKeyDown:b=>{(b.key==="Enter"||b.key===" ")&&(b.stopPropagation(),b.preventDefault(),a(e.path))},className:m("shrink-0 p-1 rounded transition-colors cursor-pointer inline-flex items-center justify-center",p?"text-emerald-500":"text-muted-foreground/50 hover:text-foreground hover:bg-muted"),"aria-label":p?"Copied":"Copy",title:p?"Copied!":"Copy",children:p?t.jsx(se,{className:"size-3"}):t.jsx(ae,{className:"size-3"})})]}),f.map((b,y)=>t.jsx("div",{className:m("font-mono text-xs mt-1 break-all pl-5",b.tone),children:b.text},y)),t.jsx("div",{className:"overflow-hidden transition-all duration-200",style:{maxHeight:d&&l?"2000px":"0"},"aria-hidden":!d,children:d&&l&&e.kind!=="equal"?t.jsx(he,{op:e}):null})]})}function he({op:e}){if(e.kind==="added"||e.kind==="removed")return t.jsx("div",{className:"pl-5 mt-2 border border-border/50 rounded p-2 bg-muted/20",children:t.jsx(w,{text:N(e.value),defaultExpandDepth:0})});const r=e.left.kind==="object"||e.left.kind==="array",n=e.right.kind==="object"||e.right.kind==="array";return!r&&!n?t.jsx("div",{className:"pl-5 mt-2 text-xs text-muted-foreground/70 italic",children:"Primitive values are shown inline above."}):t.jsxs("div",{className:"pl-5 mt-2 grid grid-cols-1 md:grid-cols-2 gap-2",children:[t.jsxs("div",{className:"border border-rose-500/30 rounded p-2 bg-rose-500/5",children:[t.jsx("div",{className:"text-[10px] uppercase tracking-wider text-rose-500 mb-1",children:"Old"}),t.jsx(w,{text:N(e.left),defaultExpandDepth:0})]}),t.jsxs("div",{className:"border border-emerald-500/30 rounded p-2 bg-emerald-500/5",children:[t.jsx("div",{className:"text-[10px] uppercase tracking-wider text-emerald-500 mb-1",children:"New"}),t.jsx(w,{text:N(e.right),defaultExpandDepth:0})]})]})}function be({counts:e,onJumpTo:r}){const n=e.added+e.removed+e.changed;return t.jsxs("div",{className:"px-4 py-2 border-b border-border bg-muted/20 flex items-center gap-2 text-xs flex-wrap",children:[t.jsxs("span",{className:"text-muted-foreground font-medium",children:[n," ",n===1?"change":"changes"]}),t.jsxs("button",{type:"button",onClick:()=>r("removed"),disabled:e.removed===0,className:m("inline-flex items-center gap-1 px-2 py-0.5 rounded-full border cursor-pointer transition-colors",e.removed>0?"border-rose-500/40 text-rose-600 dark:text-rose-400 bg-rose-500/10 hover:bg-rose-500/20":"border-border text-muted-foreground/40 cursor-not-allowed"),title:e.removed>0?"Jump to first removed":"No removals",children:[t.jsx(V,{className:"size-3"}),e.removed," removed"]}),t.jsxs("button",{type:"button",onClick:()=>r("added"),disabled:e.added===0,className:m("inline-flex items-center gap-1 px-2 py-0.5 rounded-full border cursor-pointer transition-colors",e.added>0?"border-emerald-500/40 text-emerald-600 dark:text-emerald-400 bg-emerald-500/10 hover:bg-emerald-500/20":"border-border text-muted-foreground/40 cursor-not-allowed"),title:e.added>0?"Jump to first added":"No additions",children:[t.jsx(_,{className:"size-3"}),e.added," added"]}),t.jsxs("button",{type:"button",onClick:()=>r("changed"),disabled:e.changed===0,className:m("inline-flex items-center gap-1 px-2 py-0.5 rounded-full border cursor-pointer transition-colors",e.changed>0?"border-amber-500/40 text-amber-600 dark:text-amber-400 bg-amber-500/10 hover:bg-amber-500/20":"border-border text-muted-foreground/40 cursor-not-allowed"),title:e.changed>0?"Jump to first changed":"No changes",children:[t.jsx(M,{className:"size-3"}),e.changed," changed"]})]})}function ve({mode:e,onChange:r}){return t.jsxs("div",{className:"inline-flex rounded-md border border-border overflow-hidden",children:[t.jsxs("button",{type:"button",onClick:()=>r("unified"),"aria-pressed":e==="unified",className:m("flex items-center gap-1 px-2 py-1 text-xs transition-colors cursor-pointer",e==="unified"?"bg-muted text-foreground":"hover:bg-muted/50 text-muted-foreground"),title:"Unified view (single column, emphasized diffs)",children:[t.jsx(re,{className:"size-3"}),"Unified"]}),t.jsxs("button",{type:"button",onClick:()=>r("split"),"aria-pressed":e==="split",className:m("flex items-center gap-1 px-2 py-1 text-xs transition-colors border-l border-border cursor-pointer",e==="split"?"bg-muted text-foreground":"hover:bg-muted/50 text-muted-foreground"),title:"Split view (path | left | right)",children:[t.jsx(ne,{className:"size-3"}),"Split"]})]})}function J({log:e,side:r,displayNumber:n}){const a=q(e);return t.jsxs("div",{className:"flex-1 min-w-0 space-y-1 text-xs",children:[t.jsxs("div",{className:"flex items-center gap-2",children:[t.jsx(te,{variant:"outline",className:m("text-[10px] px-1.5 py-0 h-5 font-mono shrink-0",r==="left"?"border-rose-500/40 text-rose-400":"border-emerald-500/40 text-emerald-400"),children:r==="left"?"← Left":"Right →"}),t.jsxs("span",{className:"font-mono text-blue-400/80",title:`Log ID ${String(e.id)}`,children:["#",n]}),e.model!==null&&t.jsx("span",{className:"font-mono text-muted-foreground truncate",children:e.model})]}),t.jsxs("div",{className:"flex items-center gap-3 text-muted-foreground font-mono",children:[e.cacheCreationInputTokens!==null&&e.cacheCreationInputTokens>0&&t.jsxs("span",{className:"text-emerald-400",children:["KV Cache +",P(e.cacheCreationInputTokens)]}),e.cacheReadInputTokens!==null&&e.cacheReadInputTokens>0&&t.jsxs("span",{className:"text-purple-400",children:["KV Cache ~",P(e.cacheReadInputTokens)]}),t.jsx("span",{className:"truncate",title:e.timestamp,children:e.timestamp})]}),t.jsxs("div",{className:"text-muted-foreground/70 font-mono truncate",title:a,children:["session: ",a]})]})}function ye({left:e,right:r,leftDisplayNumber:n,rightDisplayNumber:a,onClose:d}){const i=h.useMemo(()=>{const c=$(L(e)).analyzeRequest(e.rawRequestBody),u=$(L(r)).analyzeRequest(r.rawRequestBody),x=D(c.comparisonValue),g=D(u.comparisonValue);return xe(x,g)},[e.apiFormat,e.path,e.rawRequestBody,r.apiFormat,r.path,r.rawRequestBody]),s=h.useMemo(()=>me(i),[i]),o=h.useMemo(()=>{let c=0,u=0,x=0;for(const g of s)if(g.kind==="single")switch(g.op.kind){case"added":c++;break;case"removed":u++;break;case"changed":x++;break}return{added:c,removed:u,changed:x}},[s]),[l,f]=h.useState(new Set),p=c=>{f(u=>{const x=new Set(u);return x.has(c)?x.delete(c):x.add(c),x})},[b,y]=h.useState(new Set),U=c=>{y(u=>{const x=new Set(u);return x.has(c)?x.delete(c):x.add(c),x})};h.useEffect(()=>{y(new Set)},[e.id,r.id]);const[T,H]=h.useState("unified"),I=h.useRef(null),[G,z]=h.useState(null),k=h.useRef(null),Q=c=>{oe(c).then(u=>{u&&(z(c),k.current!==null&&clearTimeout(k.current),k.current=setTimeout(()=>z(null),1500))})};h.useEffect(()=>()=>{k.current!==null&&clearTimeout(k.current)},[]);const W=c=>{const u=s.findIndex(O=>O.kind==="single"&&O.op.kind===c);if(u===-1)return;const x=I.current;if(x===null)return;const g=x.querySelector(`[data-diff-idx="${u}"]`);g!==null&&g.scrollIntoView({behavior:"smooth",block:"center"})};h.useEffect(()=>{const c=x=>{x.key==="Escape"&&d()};document.addEventListener("keydown",c);const u=document.body.style.overflow;return document.body.style.overflow="hidden",()=>{document.removeEventListener("keydown",c),document.body.style.overflow=u}},[d]);const X=q(e)===q(r),Y=i.length===1&&i[0]?.kind==="equal";return t.jsxs("div",{className:"fixed inset-0 z-50 flex justify-end",role:"dialog","aria-modal":"true","aria-label":"Compare two log requests",children:[t.jsx("button",{type:"button",onClick:d,"aria-label":"Close compare drawer",className:"absolute inset-0 bg-black/40 cursor-default",tabIndex:-1}),t.jsxs("div",{className:m("relative bg-background border-l border-border shadow-xl","w-full md:w-[70vw] max-w-[1100px] flex flex-col h-full"),onClick:c=>c.stopPropagation(),onKeyDown:c=>c.stopPropagation(),children:[t.jsxs("div",{className:"flex items-start gap-4 px-4 py-3 border-b border-border",children:[t.jsxs("div",{className:"flex-1 flex gap-4 min-w-0",children:[t.jsx(J,{log:e,side:"left",displayNumber:n}),t.jsx(J,{log:r,side:"right",displayNumber:a})]}),t.jsxs("div",{className:"flex items-center gap-2 shrink-0",children:[t.jsx(ve,{mode:T,onChange:H}),t.jsx("button",{type:"button",onClick:d,"aria-label":"Close",className:"p-1 rounded text-muted-foreground hover:text-foreground hover:bg-muted cursor-pointer",children:t.jsx(ee,{className:"size-4"})})]})]}),!X&&t.jsx("div",{className:"px-4 py-1.5 text-xs text-amber-400 bg-amber-500/10 border-b border-border",children:"Heads up: the two selected logs are from different sessions."}),Y?t.jsx("div",{className:"flex-1 min-h-0 overflow-y-auto flex items-center justify-center text-muted-foreground text-sm",children:"The two Request payloads are identical."}):t.jsxs(t.Fragment,{children:[t.jsx(be,{counts:o,onJumpTo:W}),t.jsx("div",{ref:I,className:"flex-1 min-h-0 overflow-y-auto",children:T==="unified"?t.jsx("div",{className:"px-3 py-2 space-y-0.5",children:s.map((c,u)=>{if(c.kind==="equal-run")return t.jsx(fe,{ops:c.ops,expanded:l.has(u),onToggle:()=>p(u)},`r${u}`);const x=c.op;return t.jsx(pe,{op:x,idx:u,copiedPath:G,onCopyPath:Q,expanded:b.has(u),onToggle:()=>U(u)},`o${u}`)})}):t.jsx(ge,{grouped:s,left:e,right:r,leftDisplayNumber:n,rightDisplayNumber:a})})]})]})]})}function ge({grouped:e,left:r,right:n,leftDisplayNumber:a,rightDisplayNumber:d}){return t.jsxs("div",{className:"grid grid-cols-[200px_1fr_1fr] gap-x-2 gap-y-0.5 px-3 py-2 text-xs",children:[t.jsxs("div",{className:"grid grid-cols-[200px_1fr_1fr] gap-x-2 col-span-3 pb-2 mb-2 border-b border-border text-[10px] uppercase tracking-wider text-muted-foreground",children:[t.jsx("span",{children:"Path"}),t.jsxs("span",{title:`Log ID ${String(r.id)}`,children:["Left (Log #",a,")"]}),t.jsxs("span",{title:`Log ID ${String(n.id)}`,children:["Right (Log #",d,")"]})]}),e.map((i,s)=>{if(i.kind==="equal-run")return t.jsxs("div",{className:"col-span-3 px-2 py-1 text-xs text-muted-foreground/60",children:[i.ops.length," equal siblings collapsed — switch to Unified to expand"]},s);const o=i.op;return o.kind==="equal"?t.jsxs("div",{className:"col-span-3 grid grid-cols-[200px_1fr_1fr] gap-x-2 px-2 py-0.5 text-muted-foreground",children:[t.jsx("span",{className:"font-mono text-xs truncate",title:o.path,children:o.path}),t.jsx("span",{className:"font-mono text-xs break-all opacity-60",children:v(o.value,200)}),t.jsx("span",{className:"font-mono text-xs break-all opacity-60",children:v(o.value,200)})]},s):o.kind==="added"?t.jsxs("div",{className:"col-span-3 px-2 py-1 rounded text-xs border-l-2 border-l-emerald-400/70 bg-emerald-500/5",children:[t.jsx("div",{className:"font-mono text-xs text-muted-foreground mb-0.5",children:o.path}),t.jsxs("div",{className:"font-mono break-all text-emerald-300/90",children:["+ ",v(o.value,400)]})]},s):o.kind==="removed"?t.jsxs("div",{className:"col-span-3 px-2 py-1 rounded text-xs border-l-2 border-l-rose-400/70 bg-rose-500/5",children:[t.jsx("div",{className:"font-mono text-xs text-muted-foreground mb-0.5",children:o.path}),t.jsxs("div",{className:"font-mono break-all text-rose-300/90 line-through",children:["− ",v(o.value,400)]})]},s):t.jsxs("div",{className:"col-span-3 px-2 py-1 rounded text-xs border-l-2 border-l-amber-400/70 bg-amber-500/5",children:[t.jsx("div",{className:"font-mono text-xs text-muted-foreground mb-1",children:o.path}),t.jsxs("div",{className:"grid grid-cols-2 gap-2",children:[t.jsx("div",{className:"font-mono text-rose-300/90 break-all line-through",children:v(o.left,400)}),t.jsx("div",{className:"font-mono text-emerald-300/90 break-all",children:v(o.right,400)})]})]},s)})]})}export{ye as CompareDrawer};