@tonyclaw/agent-inspector 2.0.0

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 (400) hide show
  1. package/.output/cli.js +1611 -0
  2. package/.output/nitro.json +17 -0
  3. package/.output/public/assets/CompareDrawer-CU5ZrWcL.js +1 -0
  4. package/.output/public/assets/ProxyViewerContainer-pEBqVp1d.js +101 -0
  5. package/.output/public/assets/ReplayDialog-F58yNg5j.js +1 -0
  6. package/.output/public/assets/RequestAnatomy-C9lT0qE_.js +1 -0
  7. package/.output/public/assets/ResponseView-DHJq6bnz.js +1 -0
  8. package/.output/public/assets/StreamingChunkSequence-BTgfpFUT.js +1 -0
  9. package/.output/public/assets/_sessionId-DsNRbnNm.js +1 -0
  10. package/.output/public/assets/alibaba-TTwafVwX.svg +1 -0
  11. package/.output/public/assets/index-CpWG2hFn.css +1 -0
  12. package/.output/public/assets/index-DmBV8Gve.js +1 -0
  13. package/.output/public/assets/json-viewer-CZVYLR8j.js +14 -0
  14. package/.output/public/assets/main-DHs7FBK3.js +18 -0
  15. package/.output/public/assets/minimax-BPMzvuL-.jpeg +0 -0
  16. package/.output/public/assets/qwen-CONDcHqt.png +0 -0
  17. package/.output/public/assets/zhipuai-BPNAnxo-.svg +219 -0
  18. package/.output/server/_chunks/ssr-renderer.mjs +22 -0
  19. package/.output/server/_libs/@radix-ui/react-accessible-icon+[...].mjs +1 -0
  20. package/.output/server/_libs/@radix-ui/react-dismissable-layer+[...].mjs +210 -0
  21. package/.output/server/_libs/@radix-ui/react-navigation-menu+[...].mjs +2 -0
  22. package/.output/server/_libs/@radix-ui/react-one-time-password-field+[...].mjs +2 -0
  23. package/.output/server/_libs/@radix-ui/react-password-toggle-field+[...].mjs +2 -0
  24. package/.output/server/_libs/@radix-ui/react-use-callback-ref+[...].mjs +11 -0
  25. package/.output/server/_libs/@radix-ui/react-use-controllable-state+[...].mjs +69 -0
  26. package/.output/server/_libs/@radix-ui/react-use-effect-event+[...].mjs +1 -0
  27. package/.output/server/_libs/@radix-ui/react-use-escape-keydown+[...].mjs +17 -0
  28. package/.output/server/_libs/@radix-ui/react-use-is-hydrated+[...].mjs +1 -0
  29. package/.output/server/_libs/@radix-ui/react-use-layout-effect+[...].mjs +6 -0
  30. package/.output/server/_libs/@radix-ui/react-visually-hidden+[...].mjs +34 -0
  31. package/.output/server/_libs/ajv-formats.mjs +330 -0
  32. package/.output/server/_libs/ajv.mjs +11444 -0
  33. package/.output/server/_libs/aria-hidden.mjs +122 -0
  34. package/.output/server/_libs/atomically.mjs +152 -0
  35. package/.output/server/_libs/bail.mjs +8 -0
  36. package/.output/server/_libs/cfworker__json-schema.mjs +1 -0
  37. package/.output/server/_libs/character-entities.mjs +2130 -0
  38. package/.output/server/_libs/class-variance-authority.mjs +44 -0
  39. package/.output/server/_libs/clsx.mjs +16 -0
  40. package/.output/server/_libs/comma-separated-tokens.mjs +10 -0
  41. package/.output/server/_libs/conf.mjs +635 -0
  42. package/.output/server/_libs/cookie-es.mjs +58 -0
  43. package/.output/server/_libs/core-util-is.mjs +75 -0
  44. package/.output/server/_libs/croner.mjs +1 -0
  45. package/.output/server/_libs/crossws.mjs +1 -0
  46. package/.output/server/_libs/debounce-fn.mjs +69 -0
  47. package/.output/server/_libs/decode-named-character-reference+[...].mjs +8 -0
  48. package/.output/server/_libs/dequal.mjs +27 -0
  49. package/.output/server/_libs/detect-node-es.mjs +1 -0
  50. package/.output/server/_libs/devlop.mjs +8 -0
  51. package/.output/server/_libs/diff.mjs +320 -0
  52. package/.output/server/_libs/dot-prop.mjs +265 -0
  53. package/.output/server/_libs/env-paths.mjs +57 -0
  54. package/.output/server/_libs/estree-util-is-identifier-name.mjs +11 -0
  55. package/.output/server/_libs/extend.mjs +97 -0
  56. package/.output/server/_libs/fast-deep-equal.mjs +38 -0
  57. package/.output/server/_libs/fast-uri.mjs +812 -0
  58. package/.output/server/_libs/floating-ui__core.mjs +725 -0
  59. package/.output/server/_libs/floating-ui__dom.mjs +622 -0
  60. package/.output/server/_libs/floating-ui__react-dom.mjs +292 -0
  61. package/.output/server/_libs/floating-ui__utils.mjs +320 -0
  62. package/.output/server/_libs/get-nonce.mjs +9 -0
  63. package/.output/server/_libs/h3-v2.mjs +276 -0
  64. package/.output/server/_libs/h3.mjs +408 -0
  65. package/.output/server/_libs/hast-util-to-jsx-runtime.mjs +388 -0
  66. package/.output/server/_libs/hast-util-whitespace.mjs +10 -0
  67. package/.output/server/_libs/hookable.mjs +1 -0
  68. package/.output/server/_libs/html-url-attributes.mjs +26 -0
  69. package/.output/server/_libs/immediate.mjs +74 -0
  70. package/.output/server/_libs/inherits.mjs +50 -0
  71. package/.output/server/_libs/inline-style-parser.mjs +142 -0
  72. package/.output/server/_libs/is-plain-obj.mjs +10 -0
  73. package/.output/server/_libs/isarray.mjs +14 -0
  74. package/.output/server/_libs/isbot.mjs +20 -0
  75. package/.output/server/_libs/json-schema-traverse.mjs +180 -0
  76. package/.output/server/_libs/jszip.mjs +3051 -0
  77. package/.output/server/_libs/lie.mjs +273 -0
  78. package/.output/server/_libs/lucide-react.mjs +492 -0
  79. package/.output/server/_libs/mdast-util-from-markdown.mjs +717 -0
  80. package/.output/server/_libs/mdast-util-to-hast.mjs +710 -0
  81. package/.output/server/_libs/mdast-util-to-string.mjs +38 -0
  82. package/.output/server/_libs/micromark-core-commonmark.mjs +2259 -0
  83. package/.output/server/_libs/micromark-factory-destination.mjs +94 -0
  84. package/.output/server/_libs/micromark-factory-label.mjs +63 -0
  85. package/.output/server/_libs/micromark-factory-space.mjs +24 -0
  86. package/.output/server/_libs/micromark-factory-title.mjs +65 -0
  87. package/.output/server/_libs/micromark-factory-whitespace.mjs +22 -0
  88. package/.output/server/_libs/micromark-util-character.mjs +44 -0
  89. package/.output/server/_libs/micromark-util-chunked.mjs +36 -0
  90. package/.output/server/_libs/micromark-util-classify-character+[...].mjs +12 -0
  91. package/.output/server/_libs/micromark-util-combine-extensions+[...].mjs +41 -0
  92. package/.output/server/_libs/micromark-util-decode-numeric-character-reference+[...].mjs +19 -0
  93. package/.output/server/_libs/micromark-util-decode-string.mjs +21 -0
  94. package/.output/server/_libs/micromark-util-encode.mjs +1 -0
  95. package/.output/server/_libs/micromark-util-html-tag-name.mjs +69 -0
  96. package/.output/server/_libs/micromark-util-normalize-identifier+[...].mjs +6 -0
  97. package/.output/server/_libs/micromark-util-resolve-all.mjs +15 -0
  98. package/.output/server/_libs/micromark-util-sanitize-uri.mjs +41 -0
  99. package/.output/server/_libs/micromark-util-subtokenize.mjs +346 -0
  100. package/.output/server/_libs/micromark.mjs +906 -0
  101. package/.output/server/_libs/mimic-function.mjs +47 -0
  102. package/.output/server/_libs/modelcontextprotocol__server.mjs +9738 -0
  103. package/.output/server/_libs/ocache.mjs +1 -0
  104. package/.output/server/_libs/ohash.mjs +1 -0
  105. package/.output/server/_libs/pako.mjs +4223 -0
  106. package/.output/server/_libs/process-nextick-args.mjs +48 -0
  107. package/.output/server/_libs/property-information.mjs +1209 -0
  108. package/.output/server/_libs/radix-ui.mjs +1 -0
  109. package/.output/server/_libs/radix-ui__number.mjs +6 -0
  110. package/.output/server/_libs/radix-ui__primitive.mjs +11 -0
  111. package/.output/server/_libs/radix-ui__react-accordion.mjs +1 -0
  112. package/.output/server/_libs/radix-ui__react-alert-dialog.mjs +1 -0
  113. package/.output/server/_libs/radix-ui__react-arrow.mjs +23 -0
  114. package/.output/server/_libs/radix-ui__react-aspect-ratio.mjs +1 -0
  115. package/.output/server/_libs/radix-ui__react-avatar.mjs +1 -0
  116. package/.output/server/_libs/radix-ui__react-checkbox.mjs +1 -0
  117. package/.output/server/_libs/radix-ui__react-collapsible.mjs +144 -0
  118. package/.output/server/_libs/radix-ui__react-collection.mjs +69 -0
  119. package/.output/server/_libs/radix-ui__react-compose-refs.mjs +39 -0
  120. package/.output/server/_libs/radix-ui__react-context-menu.mjs +1 -0
  121. package/.output/server/_libs/radix-ui__react-context.mjs +78 -0
  122. package/.output/server/_libs/radix-ui__react-dialog.mjs +325 -0
  123. package/.output/server/_libs/radix-ui__react-direction.mjs +9 -0
  124. package/.output/server/_libs/radix-ui__react-dropdown-menu.mjs +1 -0
  125. package/.output/server/_libs/radix-ui__react-focus-guards.mjs +29 -0
  126. package/.output/server/_libs/radix-ui__react-focus-scope.mjs +206 -0
  127. package/.output/server/_libs/radix-ui__react-form.mjs +1 -0
  128. package/.output/server/_libs/radix-ui__react-hover-card.mjs +1 -0
  129. package/.output/server/_libs/radix-ui__react-id.mjs +14 -0
  130. package/.output/server/_libs/radix-ui__react-label.mjs +1 -0
  131. package/.output/server/_libs/radix-ui__react-menu.mjs +1 -0
  132. package/.output/server/_libs/radix-ui__react-menubar.mjs +1 -0
  133. package/.output/server/_libs/radix-ui__react-popover.mjs +1 -0
  134. package/.output/server/_libs/radix-ui__react-popper.mjs +286 -0
  135. package/.output/server/_libs/radix-ui__react-portal.mjs +16 -0
  136. package/.output/server/_libs/radix-ui__react-presence.mjs +128 -0
  137. package/.output/server/_libs/radix-ui__react-primitive.mjs +42 -0
  138. package/.output/server/_libs/radix-ui__react-progress.mjs +1 -0
  139. package/.output/server/_libs/radix-ui__react-radio-group.mjs +1 -0
  140. package/.output/server/_libs/radix-ui__react-roving-focus.mjs +224 -0
  141. package/.output/server/_libs/radix-ui__react-scroll-area.mjs +721 -0
  142. package/.output/server/_libs/radix-ui__react-select.mjs +1163 -0
  143. package/.output/server/_libs/radix-ui__react-separator.mjs +28 -0
  144. package/.output/server/_libs/radix-ui__react-slider.mjs +1 -0
  145. package/.output/server/_libs/radix-ui__react-slot.mjs +99 -0
  146. package/.output/server/_libs/radix-ui__react-switch.mjs +1 -0
  147. package/.output/server/_libs/radix-ui__react-tabs.mjs +189 -0
  148. package/.output/server/_libs/radix-ui__react-toast.mjs +2 -0
  149. package/.output/server/_libs/radix-ui__react-toggle-group.mjs +1 -0
  150. package/.output/server/_libs/radix-ui__react-toggle.mjs +1 -0
  151. package/.output/server/_libs/radix-ui__react-toolbar.mjs +1 -0
  152. package/.output/server/_libs/radix-ui__react-tooltip.mjs +495 -0
  153. package/.output/server/_libs/radix-ui__react-use-previous.mjs +14 -0
  154. package/.output/server/_libs/radix-ui__react-use-size.mjs +39 -0
  155. package/.output/server/_libs/react-dom.mjs +10781 -0
  156. package/.output/server/_libs/react-markdown.mjs +147 -0
  157. package/.output/server/_libs/react-remove-scroll-bar.mjs +82 -0
  158. package/.output/server/_libs/react-remove-scroll.mjs +328 -0
  159. package/.output/server/_libs/react-style-singleton.mjs +69 -0
  160. package/.output/server/_libs/react.mjs +515 -0
  161. package/.output/server/_libs/readable-stream.mjs +1518 -0
  162. package/.output/server/_libs/remark-parse.mjs +19 -0
  163. package/.output/server/_libs/remark-rehype.mjs +21 -0
  164. package/.output/server/_libs/rou3.mjs +14 -0
  165. package/.output/server/_libs/safe-buffer.mjs +64 -0
  166. package/.output/server/_libs/semver.mjs +1938 -0
  167. package/.output/server/_libs/seroval-plugins.mjs +58 -0
  168. package/.output/server/_libs/seroval.mjs +1765 -0
  169. package/.output/server/_libs/setimmediate.mjs +152 -0
  170. package/.output/server/_libs/space-separated-tokens.mjs +6 -0
  171. package/.output/server/_libs/srvx.mjs +1029 -0
  172. package/.output/server/_libs/stubborn-fs.mjs +91 -0
  173. package/.output/server/_libs/stubborn-utils.mjs +66 -0
  174. package/.output/server/_libs/style-to-js.mjs +72 -0
  175. package/.output/server/_libs/style-to-object.mjs +38 -0
  176. package/.output/server/_libs/swr.mjs +939 -0
  177. package/.output/server/_libs/tailwind-merge.mjs +3010 -0
  178. package/.output/server/_libs/tanstack__history.mjs +217 -0
  179. package/.output/server/_libs/tanstack__react-router.mjs +1480 -0
  180. package/.output/server/_libs/tanstack__react-store.mjs +1 -0
  181. package/.output/server/_libs/tanstack__react-virtual.mjs +44 -0
  182. package/.output/server/_libs/tanstack__router-core.mjs +4827 -0
  183. package/.output/server/_libs/tanstack__store.mjs +1 -0
  184. package/.output/server/_libs/tanstack__virtual-core.mjs +1225 -0
  185. package/.output/server/_libs/tiny-invariant.mjs +12 -0
  186. package/.output/server/_libs/tiny-warning.mjs +5 -0
  187. package/.output/server/_libs/trim-lines.mjs +41 -0
  188. package/.output/server/_libs/trough.mjs +85 -0
  189. package/.output/server/_libs/tslib.mjs +1 -0
  190. package/.output/server/_libs/ufo.mjs +54 -0
  191. package/.output/server/_libs/uint8array-extras.mjs +69 -0
  192. package/.output/server/_libs/ungap__structured-clone.mjs +212 -0
  193. package/.output/server/_libs/unified.mjs +661 -0
  194. package/.output/server/_libs/unist-util-is.mjs +100 -0
  195. package/.output/server/_libs/unist-util-position.mjs +27 -0
  196. package/.output/server/_libs/unist-util-stringify-position.mjs +27 -0
  197. package/.output/server/_libs/unist-util-visit-parents.mjs +82 -0
  198. package/.output/server/_libs/unist-util-visit.mjs +24 -0
  199. package/.output/server/_libs/unstorage.mjs +1 -0
  200. package/.output/server/_libs/use-callback-ref.mjs +66 -0
  201. package/.output/server/_libs/use-sidecar.mjs +106 -0
  202. package/.output/server/_libs/use-sync-external-store.mjs +64 -0
  203. package/.output/server/_libs/util-deprecate.mjs +12 -0
  204. package/.output/server/_libs/vfile-message.mjs +138 -0
  205. package/.output/server/_libs/vfile.mjs +467 -0
  206. package/.output/server/_libs/when-exit.mjs +53 -0
  207. package/.output/server/_libs/zod.mjs +4524 -0
  208. package/.output/server/_sessionId-wMLPvC5g.mjs +123 -0
  209. package/.output/server/_ssr/CompareDrawer-BU4V0uVf.mjs +1041 -0
  210. package/.output/server/_ssr/ProxyViewerContainer-BnRwFEnn.mjs +5972 -0
  211. package/.output/server/_ssr/ReplayDialog-C7dn9pd_.mjs +322 -0
  212. package/.output/server/_ssr/RequestAnatomy-C1rWpe9-.mjs +353 -0
  213. package/.output/server/_ssr/ResponseView-hGpPaYsf.mjs +602 -0
  214. package/.output/server/_ssr/StreamingChunkSequence-BRWI1r_G.mjs +302 -0
  215. package/.output/server/_ssr/index-BKURLVPz.mjs +118 -0
  216. package/.output/server/_ssr/index.mjs +1184 -0
  217. package/.output/server/_ssr/json-viewer-BBd2DtQP.mjs +515 -0
  218. package/.output/server/_ssr/router-BcZ0D6AB.mjs +6317 -0
  219. package/.output/server/_ssr/start-HYkvq4Ni.mjs +4 -0
  220. package/.output/server/_tanstack-start-manifest_v-1y8ZVxRI.mjs +4 -0
  221. package/.output/server/index.mjs +436 -0
  222. package/.output/server/node_modules/tslib/modules/index.js +70 -0
  223. package/.output/server/node_modules/tslib/modules/package.json +3 -0
  224. package/.output/server/node_modules/tslib/package.json +47 -0
  225. package/.output/server/node_modules/tslib/tslib.js +484 -0
  226. package/.output/server/package.json +9 -0
  227. package/LICENSE +21 -0
  228. package/README.md +52 -0
  229. package/package.json +110 -0
  230. package/src/assets/favicon.svg +31 -0
  231. package/src/assets/logos/alibaba.svg +1 -0
  232. package/src/assets/logos/anthropic.svg +1 -0
  233. package/src/assets/logos/claude-code.svg +4 -0
  234. package/src/assets/logos/deepseek.svg +1 -0
  235. package/src/assets/logos/mcp.png +0 -0
  236. package/src/assets/logos/minimax.jpeg +0 -0
  237. package/src/assets/logos/openai.svg +1 -0
  238. package/src/assets/logos/opencode.svg +4 -0
  239. package/src/assets/logos/qwen.png +0 -0
  240. package/src/assets/logos/zhipuai.svg +219 -0
  241. package/src/cli/detect-tools.ts +147 -0
  242. package/src/cli/doctor.ts +521 -0
  243. package/src/cli/onboard.ts +224 -0
  244. package/src/cli/templates/command-onboard.ts +17 -0
  245. package/src/cli/templates/skill-onboard.ts +547 -0
  246. package/src/cli.ts +345 -0
  247. package/src/components/OnboardingBanner.tsx +67 -0
  248. package/src/components/ProxyViewer.tsx +545 -0
  249. package/src/components/ProxyViewerContainer.tsx +363 -0
  250. package/src/components/providers/ImportWizardDialog.tsx +349 -0
  251. package/src/components/providers/ProviderCard.tsx +474 -0
  252. package/src/components/providers/ProviderForm.tsx +494 -0
  253. package/src/components/providers/ProviderLogo.tsx +117 -0
  254. package/src/components/providers/ProvidersPanel.tsx +619 -0
  255. package/src/components/providers/SettingsDialog.tsx +202 -0
  256. package/src/components/proxy-viewer/CompareDrawer.tsx +893 -0
  257. package/src/components/proxy-viewer/ConversationGroup.tsx +107 -0
  258. package/src/components/proxy-viewer/ConversationHeader.tsx +300 -0
  259. package/src/components/proxy-viewer/LogEntry.tsx +543 -0
  260. package/src/components/proxy-viewer/LogEntryHeader.tsx +501 -0
  261. package/src/components/proxy-viewer/ReplayDialog.tsx +218 -0
  262. package/src/components/proxy-viewer/ResponseView.tsx +171 -0
  263. package/src/components/proxy-viewer/StreamingChunkSequence.tsx +188 -0
  264. package/src/components/proxy-viewer/ThreadConnector.tsx +136 -0
  265. package/src/components/proxy-viewer/TurnGroup.tsx +337 -0
  266. package/src/components/proxy-viewer/anatomy/RequestAnatomy.tsx +98 -0
  267. package/src/components/proxy-viewer/anatomy/SegmentBar.tsx +196 -0
  268. package/src/components/proxy-viewer/anatomy/tokenEstimate.ts +53 -0
  269. package/src/components/proxy-viewer/anatomy/types.ts +39 -0
  270. package/src/components/proxy-viewer/anatomy/useAnatomyJump.ts +114 -0
  271. package/src/components/proxy-viewer/cacheTrend.ts +50 -0
  272. package/src/components/proxy-viewer/diff/DiffView.tsx +321 -0
  273. package/src/components/proxy-viewer/diff/computeDiff.ts +178 -0
  274. package/src/components/proxy-viewer/diff/index.ts +3 -0
  275. package/src/components/proxy-viewer/formats/anthropic/ContentBlocks.tsx +157 -0
  276. package/src/components/proxy-viewer/formats/anthropic/ResponseView.tsx +66 -0
  277. package/src/components/proxy-viewer/formats/anthropic/thinkingExtract.ts +21 -0
  278. package/src/components/proxy-viewer/formats/index.tsx +33 -0
  279. package/src/components/proxy-viewer/formats/openai/ResponseView.tsx +170 -0
  280. package/src/components/proxy-viewer/index.ts +9 -0
  281. package/src/components/proxy-viewer/lazy.ts +37 -0
  282. package/src/components/proxy-viewer/log-formats/anthropic.ts +194 -0
  283. package/src/components/proxy-viewer/log-formats/index.ts +23 -0
  284. package/src/components/proxy-viewer/log-formats/openai.ts +167 -0
  285. package/src/components/proxy-viewer/log-formats/types.ts +40 -0
  286. package/src/components/proxy-viewer/log-formats/unknown.ts +18 -0
  287. package/src/components/proxy-viewer/logEntryVisibility.ts +39 -0
  288. package/src/components/proxy-viewer/requestDiff.ts +277 -0
  289. package/src/components/proxy-viewer/useCopyFeedback.ts +36 -0
  290. package/src/components/proxy-viewer/useKeyboardNavigation.ts +190 -0
  291. package/src/components/proxy-viewer/viewerState.ts +66 -0
  292. package/src/components/ui/badge.tsx +47 -0
  293. package/src/components/ui/button.tsx +47 -0
  294. package/src/components/ui/collapsible.tsx +21 -0
  295. package/src/components/ui/confirm-dialog.tsx +51 -0
  296. package/src/components/ui/crab-logo.tsx +95 -0
  297. package/src/components/ui/crab-variants.tsx +467 -0
  298. package/src/components/ui/dialog.tsx +129 -0
  299. package/src/components/ui/json-expansion-button.tsx +56 -0
  300. package/src/components/ui/json-viewer-bulk.ts +97 -0
  301. package/src/components/ui/json-viewer.tsx +494 -0
  302. package/src/components/ui/mcp-logo.tsx +20 -0
  303. package/src/components/ui/scroll-area.tsx +54 -0
  304. package/src/components/ui/select.tsx +178 -0
  305. package/src/components/ui/separator.tsx +28 -0
  306. package/src/components/ui/tabs.tsx +88 -0
  307. package/src/components/ui/tooltip.tsx +51 -0
  308. package/src/index.css +11 -0
  309. package/src/knowledge/candidateStore.ts +63 -0
  310. package/src/knowledge/distiller.ts +98 -0
  311. package/src/knowledge/openclawClient.ts +118 -0
  312. package/src/knowledge/redactor.ts +80 -0
  313. package/src/knowledge/types.ts +84 -0
  314. package/src/lib/apiClient.ts +49 -0
  315. package/src/lib/export-logs.ts +51 -0
  316. package/src/lib/mask.ts +4 -0
  317. package/src/lib/objectUtils.ts +22 -0
  318. package/src/lib/providerContract.ts +26 -0
  319. package/src/lib/providerTestContract.ts +107 -0
  320. package/src/lib/runtimeConfig.ts +25 -0
  321. package/src/lib/serverPort.ts +41 -0
  322. package/src/lib/sessionUrl.ts +44 -0
  323. package/src/lib/stopReason.ts +58 -0
  324. package/src/lib/useOnboarding.ts +80 -0
  325. package/src/lib/useProviders.ts +30 -0
  326. package/src/lib/useStripConfig.ts +108 -0
  327. package/src/lib/utils.ts +21 -0
  328. package/src/mcp/loopback.ts +76 -0
  329. package/src/mcp/previewExtractor.ts +166 -0
  330. package/src/mcp/server.ts +396 -0
  331. package/src/mcp/toolHandlers.ts +341 -0
  332. package/src/proxy/chunkStorage.ts +112 -0
  333. package/src/proxy/claudeCodeStrip.ts +99 -0
  334. package/src/proxy/config.ts +172 -0
  335. package/src/proxy/constants.ts +47 -0
  336. package/src/proxy/dataDir.ts +86 -0
  337. package/src/proxy/formats/anthropic/anthropicProvider.ts +75 -0
  338. package/src/proxy/formats/anthropic/handler.ts +71 -0
  339. package/src/proxy/formats/anthropic/index.ts +14 -0
  340. package/src/proxy/formats/anthropic/register.ts +4 -0
  341. package/src/proxy/formats/anthropic/schemas.ts +237 -0
  342. package/src/proxy/formats/anthropic/stream.ts +205 -0
  343. package/src/proxy/formats/handler.ts +46 -0
  344. package/src/proxy/formats/index.ts +12 -0
  345. package/src/proxy/formats/jsonSchema.ts +36 -0
  346. package/src/proxy/formats/openai/alibabaProvider.ts +38 -0
  347. package/src/proxy/formats/openai/handler.ts +96 -0
  348. package/src/proxy/formats/openai/index.ts +25 -0
  349. package/src/proxy/formats/openai/provider.ts +50 -0
  350. package/src/proxy/formats/openai/register.ts +4 -0
  351. package/src/proxy/formats/openai/schemas.ts +187 -0
  352. package/src/proxy/formats/openai/stream.ts +206 -0
  353. package/src/proxy/formats/protocol.ts +50 -0
  354. package/src/proxy/formats/providerRegistry.ts +51 -0
  355. package/src/proxy/formats/providers/index.ts +3 -0
  356. package/src/proxy/formats/registry.ts +66 -0
  357. package/src/proxy/handler.ts +334 -0
  358. package/src/proxy/logFinalizer.ts +305 -0
  359. package/src/proxy/logFinalizer.worker.ts +24 -0
  360. package/src/proxy/logIndex.ts +268 -0
  361. package/src/proxy/logger.ts +179 -0
  362. package/src/proxy/openaiOrphanToolStrip.ts +142 -0
  363. package/src/proxy/providerImporters.ts +491 -0
  364. package/src/proxy/providers.ts +613 -0
  365. package/src/proxy/schemas.ts +209 -0
  366. package/src/proxy/sessionProcess.ts +140 -0
  367. package/src/proxy/sessionRuntime.ts +85 -0
  368. package/src/proxy/sessionSupervisor.ts +283 -0
  369. package/src/proxy/sessionWorkerEntry.ts +26 -0
  370. package/src/proxy/socketTracker.ts +255 -0
  371. package/src/proxy/store.ts +412 -0
  372. package/src/proxy/upstream.ts +90 -0
  373. package/src/router.tsx +16 -0
  374. package/src/routes/__root.tsx +45 -0
  375. package/src/routes/api/config.paths.ts +14 -0
  376. package/src/routes/api/config.ts +53 -0
  377. package/src/routes/api/health.ts +15 -0
  378. package/src/routes/api/knowledge.candidates.$candidateId.promote.ts +32 -0
  379. package/src/routes/api/knowledge.candidates.ts +10 -0
  380. package/src/routes/api/knowledge.project-context.ts +18 -0
  381. package/src/routes/api/knowledge.search.ts +31 -0
  382. package/src/routes/api/knowledge.sessions.$sessionId.candidates.ts +16 -0
  383. package/src/routes/api/logs.$id.chunks.ts +36 -0
  384. package/src/routes/api/logs.$id.replay.ts +191 -0
  385. package/src/routes/api/logs.$id.ts +22 -0
  386. package/src/routes/api/logs.stream.ts +74 -0
  387. package/src/routes/api/logs.ts +59 -0
  388. package/src/routes/api/mcp.ts +25 -0
  389. package/src/routes/api/models.ts +10 -0
  390. package/src/routes/api/providers.$providerId.test.log.ts +293 -0
  391. package/src/routes/api/providers.$providerId.ts +50 -0
  392. package/src/routes/api/providers.export.ts +26 -0
  393. package/src/routes/api/providers.import.ts +47 -0
  394. package/src/routes/api/providers.scan.ts +23 -0
  395. package/src/routes/api/providers.ts +45 -0
  396. package/src/routes/api/sessions.ts +17 -0
  397. package/src/routes/index.tsx +6 -0
  398. package/src/routes/proxy/$.ts +15 -0
  399. package/src/routes/session/$sessionId.tsx +23 -0
  400. package/styles/globals.css +188 -0
@@ -0,0 +1,1041 @@
1
+ import { r as reactExports, j as jsxRuntimeExports } from "../_libs/react.mjs";
2
+ import { g as getLogFormatAdapter, r as resolveLogFormat, a as getConversationId, c as cn, B as Badge, f as formatTokens } from "./ProxyViewerContainer-BnRwFEnn.mjs";
3
+ import { JsonViewerFromString } from "./json-viewer-BBd2DtQP.mjs";
4
+ import "./router-BcZ0D6AB.mjs";
5
+ import "../_libs/modelcontextprotocol__server.mjs";
6
+ import "../_libs/jszip.mjs";
7
+ import { X, J as Rows3, K as Columns2, m as Minus, P as Plus, l as Pencil, f as ChevronRight, N as Equal, C as Check, a as Copy } from "../_libs/lucide-react.mjs";
8
+ import "../_libs/swr.mjs";
9
+ import "../_libs/use-sync-external-store.mjs";
10
+ import "../_libs/dequal.mjs";
11
+ import "../_libs/clsx.mjs";
12
+ import "../_libs/tailwind-merge.mjs";
13
+ import "../_libs/class-variance-authority.mjs";
14
+ import "../_libs/radix-ui__react-dialog.mjs";
15
+ import "../_libs/radix-ui__primitive.mjs";
16
+ import "../_libs/radix-ui__react-compose-refs.mjs";
17
+ import "../_libs/radix-ui__react-context.mjs";
18
+ import "../_libs/radix-ui__react-id.mjs";
19
+ import "../_libs/@radix-ui/react-use-layout-effect+[...].mjs";
20
+ import "../_libs/@radix-ui/react-use-controllable-state+[...].mjs";
21
+ import "../_libs/@radix-ui/react-dismissable-layer+[...].mjs";
22
+ import "../_libs/radix-ui__react-primitive.mjs";
23
+ import "../_libs/react-dom.mjs";
24
+ import "util";
25
+ import "async_hooks";
26
+ import "stream";
27
+ import "crypto";
28
+ import "../_libs/radix-ui__react-slot.mjs";
29
+ import "../_libs/@radix-ui/react-use-callback-ref+[...].mjs";
30
+ import "../_libs/@radix-ui/react-use-escape-keydown+[...].mjs";
31
+ import "../_libs/radix-ui__react-focus-scope.mjs";
32
+ import "../_libs/radix-ui__react-portal.mjs";
33
+ import "../_libs/radix-ui__react-presence.mjs";
34
+ import "../_libs/radix-ui__react-focus-guards.mjs";
35
+ import "../_libs/react-remove-scroll.mjs";
36
+ import "tslib";
37
+ import "../_libs/react-remove-scroll-bar.mjs";
38
+ import "../_libs/react-style-singleton.mjs";
39
+ import "../_libs/get-nonce.mjs";
40
+ import "../_libs/use-sidecar.mjs";
41
+ import "../_libs/use-callback-ref.mjs";
42
+ import "../_libs/aria-hidden.mjs";
43
+ import "../_libs/diff.mjs";
44
+ import "../_libs/tanstack__react-virtual.mjs";
45
+ import "../_libs/tanstack__virtual-core.mjs";
46
+ import "../_libs/radix-ui__react-select.mjs";
47
+ import "../_libs/radix-ui__number.mjs";
48
+ import "../_libs/radix-ui__react-collection.mjs";
49
+ import "../_libs/radix-ui__react-direction.mjs";
50
+ import "../_libs/radix-ui__react-popper.mjs";
51
+ import "../_libs/floating-ui__react-dom.mjs";
52
+ import "../_libs/floating-ui__dom.mjs";
53
+ import "../_libs/floating-ui__core.mjs";
54
+ import "../_libs/floating-ui__utils.mjs";
55
+ import "../_libs/radix-ui__react-arrow.mjs";
56
+ import "../_libs/radix-ui__react-use-size.mjs";
57
+ import "../_libs/radix-ui__react-use-previous.mjs";
58
+ import "../_libs/@radix-ui/react-visually-hidden+[...].mjs";
59
+ import "../_libs/zod.mjs";
60
+ import "../_libs/radix-ui__react-tooltip.mjs";
61
+ import "../_libs/radix-ui__react-tabs.mjs";
62
+ import "../_libs/radix-ui__react-roving-focus.mjs";
63
+ import "../_libs/react-markdown.mjs";
64
+ import "../_libs/devlop.mjs";
65
+ import "../_libs/unified.mjs";
66
+ import "../_libs/bail.mjs";
67
+ import "../_libs/extend.mjs";
68
+ import "../_libs/is-plain-obj.mjs";
69
+ import "../_libs/trough.mjs";
70
+ import "../_libs/vfile.mjs";
71
+ import "../_libs/vfile-message.mjs";
72
+ import "../_libs/unist-util-stringify-position.mjs";
73
+ import "node:process";
74
+ import "node:path";
75
+ import "node:url";
76
+ import "../_libs/remark-parse.mjs";
77
+ import "../_libs/mdast-util-from-markdown.mjs";
78
+ import "../_libs/micromark-util-decode-numeric-character-reference+[...].mjs";
79
+ import "../_libs/micromark-util-decode-string.mjs";
80
+ import "../_libs/decode-named-character-reference+[...].mjs";
81
+ import "../_libs/character-entities.mjs";
82
+ import "../_libs/micromark-util-normalize-identifier+[...].mjs";
83
+ import "../_libs/micromark.mjs";
84
+ import "../_libs/micromark-util-combine-extensions+[...].mjs";
85
+ import "../_libs/micromark-util-chunked.mjs";
86
+ import "../_libs/micromark-factory-space.mjs";
87
+ import "../_libs/micromark-util-character.mjs";
88
+ import "../_libs/micromark-core-commonmark.mjs";
89
+ import "../_libs/micromark-util-classify-character+[...].mjs";
90
+ import "../_libs/micromark-util-resolve-all.mjs";
91
+ import "../_libs/micromark-util-subtokenize.mjs";
92
+ import "../_libs/micromark-factory-destination.mjs";
93
+ import "../_libs/micromark-factory-label.mjs";
94
+ import "../_libs/micromark-factory-title.mjs";
95
+ import "../_libs/micromark-factory-whitespace.mjs";
96
+ import "../_libs/micromark-util-html-tag-name.mjs";
97
+ import "../_libs/mdast-util-to-string.mjs";
98
+ import "../_libs/remark-rehype.mjs";
99
+ import "../_libs/mdast-util-to-hast.mjs";
100
+ import "../_libs/ungap__structured-clone.mjs";
101
+ import "../_libs/micromark-util-sanitize-uri.mjs";
102
+ import "../_libs/unist-util-position.mjs";
103
+ import "../_libs/trim-lines.mjs";
104
+ import "../_libs/unist-util-visit.mjs";
105
+ import "../_libs/unist-util-visit-parents.mjs";
106
+ import "../_libs/unist-util-is.mjs";
107
+ import "../_libs/hast-util-to-jsx-runtime.mjs";
108
+ import "../_libs/comma-separated-tokens.mjs";
109
+ import "../_libs/property-information.mjs";
110
+ import "../_libs/space-separated-tokens.mjs";
111
+ import "../_libs/style-to-js.mjs";
112
+ import "../_libs/style-to-object.mjs";
113
+ import "../_libs/inline-style-parser.mjs";
114
+ import "../_libs/hast-util-whitespace.mjs";
115
+ import "../_libs/estree-util-is-identifier-name.mjs";
116
+ import "../_libs/html-url-attributes.mjs";
117
+ import "../_libs/tanstack__react-router.mjs";
118
+ import "../_libs/tiny-warning.mjs";
119
+ import "../_libs/tanstack__router-core.mjs";
120
+ import "../_libs/cookie-es.mjs";
121
+ import "../_libs/tanstack__history.mjs";
122
+ import "../_libs/tiny-invariant.mjs";
123
+ import "../_libs/seroval.mjs";
124
+ import "../_libs/seroval-plugins.mjs";
125
+ import "node:stream/web";
126
+ import "node:stream";
127
+ import "../_libs/isbot.mjs";
128
+ import "node:fs";
129
+ import "node:fs/promises";
130
+ import "node:buffer";
131
+ import "node:child_process";
132
+ import "../_libs/conf.mjs";
133
+ import "node:util";
134
+ import "node:crypto";
135
+ import "node:assert";
136
+ import "../_libs/dot-prop.mjs";
137
+ import "../_libs/env-paths.mjs";
138
+ import "node:os";
139
+ import "../_libs/atomically.mjs";
140
+ import "../_libs/stubborn-fs.mjs";
141
+ import "../_libs/stubborn-utils.mjs";
142
+ import "../_libs/when-exit.mjs";
143
+ import "../_libs/ajv.mjs";
144
+ import "../_libs/fast-deep-equal.mjs";
145
+ import "../_libs/json-schema-traverse.mjs";
146
+ import "../_libs/fast-uri.mjs";
147
+ import "../_libs/ajv-formats.mjs";
148
+ import "../_libs/debounce-fn.mjs";
149
+ import "../_libs/mimic-function.mjs";
150
+ import "../_libs/semver.mjs";
151
+ import "../_libs/uint8array-extras.mjs";
152
+ import "node:worker_threads";
153
+ import "../_libs/readable-stream.mjs";
154
+ import "events";
155
+ import "node:string_decoder";
156
+ import "../_libs/process-nextick-args.mjs";
157
+ import "../_libs/isarray.mjs";
158
+ import "../_libs/safe-buffer.mjs";
159
+ import "buffer";
160
+ import "../_libs/core-util-is.mjs";
161
+ import "../_libs/inherits.mjs";
162
+ import "../_libs/util-deprecate.mjs";
163
+ import "../_libs/lie.mjs";
164
+ import "../_libs/immediate.mjs";
165
+ import "../_libs/setimmediate.mjs";
166
+ import "../_libs/pako.mjs";
167
+ const ROOT_PATH = "";
168
+ function formatPath(segments) {
169
+ if (segments.length === 0) return ROOT_PATH;
170
+ let out = "";
171
+ for (let i = 0; i < segments.length; i++) {
172
+ const seg = segments[i];
173
+ if (seg === void 0) continue;
174
+ if (typeof seg === "number") {
175
+ out += `[${seg}]`;
176
+ } else if (i === 0) {
177
+ out += seg;
178
+ } else {
179
+ out += `.${seg}`;
180
+ }
181
+ }
182
+ return out;
183
+ }
184
+ function isPlainObject(value) {
185
+ return typeof value === "object" && value !== null && !Array.isArray(value);
186
+ }
187
+ function normalizeRequest(raw) {
188
+ if (typeof raw === "string") {
189
+ try {
190
+ return toNode(JSON.parse(raw));
191
+ } catch {
192
+ return { kind: "primitive", value: raw };
193
+ }
194
+ }
195
+ return toNode(raw);
196
+ }
197
+ function toNode(value) {
198
+ if (value === null) return { kind: "primitive", value: null };
199
+ if (typeof value === "string") return { kind: "primitive", value };
200
+ if (typeof value === "number") return { kind: "primitive", value };
201
+ if (typeof value === "boolean") return { kind: "primitive", value };
202
+ if (Array.isArray(value)) {
203
+ return { kind: "array", value: value.map((v) => toNode(v)) };
204
+ }
205
+ if (isPlainObject(value)) {
206
+ const out = {};
207
+ for (const k of Object.keys(value).sort()) {
208
+ out[k] = toNode(value[k]);
209
+ }
210
+ return { kind: "object", value: out };
211
+ }
212
+ return { kind: "primitive", value: null };
213
+ }
214
+ function diffTrees(left, right) {
215
+ const ops = [];
216
+ walk([], left, right, ops);
217
+ return ops;
218
+ }
219
+ function walk(segments, left, right, out) {
220
+ const path = formatPath(segments);
221
+ if (nodeEqual(left, right)) {
222
+ out.push({ kind: "equal", path, value: left });
223
+ return;
224
+ }
225
+ if (left.kind !== right.kind) {
226
+ out.push({ kind: "changed", path, left, right });
227
+ return;
228
+ }
229
+ if (left.kind === "primitive" && right.kind === "primitive") {
230
+ out.push({ kind: "changed", path, left, right });
231
+ return;
232
+ }
233
+ if (left.kind === "object" && right.kind === "object") {
234
+ const leftKeys = Object.keys(left.value);
235
+ const rightKeys = Object.keys(right.value);
236
+ const rightKeySet = new Set(rightKeys);
237
+ for (const k of leftKeys) {
238
+ const lChild = left.value[k];
239
+ if (lChild === void 0) continue;
240
+ if (!rightKeySet.has(k)) {
241
+ out.push({
242
+ kind: "removed",
243
+ path: formatPath([...segments, k]),
244
+ value: lChild
245
+ });
246
+ } else {
247
+ const rChild = right.value[k];
248
+ if (rChild === void 0) continue;
249
+ walk([...segments, k], lChild, rChild, out);
250
+ }
251
+ }
252
+ for (const k of rightKeys) {
253
+ if (leftKeys.includes(k)) continue;
254
+ const rChild = right.value[k];
255
+ if (rChild === void 0) continue;
256
+ out.push({
257
+ kind: "added",
258
+ path: formatPath([...segments, k]),
259
+ value: rChild
260
+ });
261
+ }
262
+ return;
263
+ }
264
+ if (left.kind === "array" && right.kind === "array") {
265
+ const minLen = Math.min(left.value.length, right.value.length);
266
+ for (let i = 0; i < minLen; i++) {
267
+ const lChild = left.value[i];
268
+ const rChild = right.value[i];
269
+ if (lChild === void 0 || rChild === void 0) continue;
270
+ walk([...segments, i], lChild, rChild, out);
271
+ }
272
+ for (let i = minLen; i < right.value.length; i++) {
273
+ const rChild = right.value[i];
274
+ if (rChild === void 0) continue;
275
+ out.push({
276
+ kind: "added",
277
+ path: formatPath([...segments, i]),
278
+ value: rChild
279
+ });
280
+ }
281
+ for (let i = minLen; i < left.value.length; i++) {
282
+ const lChild = left.value[i];
283
+ if (lChild === void 0) continue;
284
+ out.push({
285
+ kind: "removed",
286
+ path: formatPath([...segments, i]),
287
+ value: lChild
288
+ });
289
+ }
290
+ }
291
+ }
292
+ function nodeEqual(a, b) {
293
+ if (a.kind !== b.kind) return false;
294
+ if (a.kind === "primitive" && b.kind === "primitive") {
295
+ return a.value === b.value;
296
+ }
297
+ if (a.kind === "array" && b.kind === "array") {
298
+ if (a.value.length !== b.value.length) return false;
299
+ for (let i = 0; i < a.value.length; i++) {
300
+ const ai = a.value[i];
301
+ const bi = b.value[i];
302
+ if (ai === void 0 || bi === void 0) return false;
303
+ if (!nodeEqual(ai, bi)) return false;
304
+ }
305
+ return true;
306
+ }
307
+ if (a.kind === "object" && b.kind === "object") {
308
+ const aKeys = Object.keys(a.value);
309
+ const bKeys = Object.keys(b.value);
310
+ if (aKeys.length !== bKeys.length) return false;
311
+ for (const k of aKeys) {
312
+ const av = a.value[k];
313
+ const bv = b.value[k];
314
+ if (av === void 0 || bv === void 0) return false;
315
+ if (!nodeEqual(av, bv)) return false;
316
+ }
317
+ return true;
318
+ }
319
+ return false;
320
+ }
321
+ function previewNode(node, maxLen = 80) {
322
+ let s;
323
+ switch (node.kind) {
324
+ case "primitive":
325
+ s = node.value === null ? "null" : JSON.stringify(node.value);
326
+ break;
327
+ case "array":
328
+ s = `[… ${node.value.length} items]`;
329
+ break;
330
+ case "object":
331
+ s = `{… ${Object.keys(node.value).length} keys}`;
332
+ break;
333
+ }
334
+ if (s.length > maxLen) s = `${s.slice(0, maxLen - 1)}…`;
335
+ return s;
336
+ }
337
+ function nodeToJsonString(node, indent = 2) {
338
+ return JSON.stringify(nodeToJsonValue(node), null, indent);
339
+ }
340
+ function nodeToJsonValue(node) {
341
+ switch (node.kind) {
342
+ case "primitive":
343
+ return node.value;
344
+ case "array":
345
+ return node.value.map(nodeToJsonValue);
346
+ case "object": {
347
+ const out = {};
348
+ for (const [k, v] of Object.entries(node.value)) {
349
+ out[k] = nodeToJsonValue(v);
350
+ }
351
+ return out;
352
+ }
353
+ }
354
+ }
355
+ function parentPath(path) {
356
+ if (path === "") return "";
357
+ for (let i = path.length - 1; i >= 0; i--) {
358
+ const ch = path[i];
359
+ if (ch === "." || ch === "[") {
360
+ return path.substring(0, i);
361
+ }
362
+ }
363
+ return "";
364
+ }
365
+ function isDeepEqual(op) {
366
+ return op.kind === "equal" && (op.value.kind === "object" || op.value.kind === "array");
367
+ }
368
+ function groupContiguousEquals(ops) {
369
+ const out = [];
370
+ let i = 0;
371
+ while (i < ops.length) {
372
+ const op = ops[i];
373
+ if (op !== void 0 && isDeepEqual(op)) {
374
+ const startParent = parentPath(op.path);
375
+ let j = i + 1;
376
+ while (j < ops.length) {
377
+ const next = ops[j];
378
+ if (next === void 0) break;
379
+ if (!isDeepEqual(next)) break;
380
+ if (parentPath(next.path) !== startParent) break;
381
+ j++;
382
+ }
383
+ if (j - i > 1) {
384
+ const equalOps = [];
385
+ for (let k = i; k < j; k++) {
386
+ const eop = ops[k];
387
+ if (eop !== void 0 && eop.kind === "equal") {
388
+ equalOps.push(eop);
389
+ }
390
+ }
391
+ out.push({ kind: "equal-run", ops: equalOps });
392
+ i = j;
393
+ continue;
394
+ }
395
+ }
396
+ if (op !== void 0) {
397
+ out.push({ kind: "single", op });
398
+ }
399
+ i++;
400
+ }
401
+ return out;
402
+ }
403
+ const KIND_VISUAL = {
404
+ added: {
405
+ icon: Plus,
406
+ accent: "text-emerald-600 dark:text-emerald-400",
407
+ bg: "bg-emerald-500/5 hover:bg-emerald-500/10",
408
+ border: "border-l-emerald-500",
409
+ label: "ADDED"
410
+ },
411
+ removed: {
412
+ icon: Minus,
413
+ accent: "text-rose-600 dark:text-rose-400",
414
+ bg: "bg-rose-500/5 hover:bg-rose-500/10",
415
+ border: "border-l-rose-500",
416
+ label: "REMOVED"
417
+ },
418
+ changed: {
419
+ icon: Pencil,
420
+ accent: "text-amber-600 dark:text-amber-400",
421
+ bg: "bg-amber-500/5 hover:bg-amber-500/10",
422
+ border: "border-l-amber-500",
423
+ label: "CHANGED"
424
+ },
425
+ equal: {
426
+ icon: Equal,
427
+ accent: "text-muted-foreground/70",
428
+ bg: "bg-muted/20 hover:bg-muted/30",
429
+ border: "border-l-muted-foreground/20",
430
+ label: "EQUAL"
431
+ }
432
+ };
433
+ function EqualRunRow({
434
+ ops,
435
+ expanded,
436
+ onToggle
437
+ }) {
438
+ const first = ops[0];
439
+ const last = ops[ops.length - 1];
440
+ if (first === void 0 || last === void 0) {
441
+ return /* @__PURE__ */ jsxRuntimeExports.jsx("div", { className: "text-muted-foreground/40 text-xs", children: "—" });
442
+ }
443
+ const firstPath = first.path;
444
+ const lastPath = last.path;
445
+ const label = ops.length === 1 ? firstPath : `${firstPath} … ${lastPath}`;
446
+ const summary = first.value.kind === "array" ? `${ops.length} equal arrays` : first.value.kind === "object" ? `${ops.length} equal objects` : "equal";
447
+ const v = KIND_VISUAL.equal;
448
+ return /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: cn("border-l-4 rounded-sm", v.border, v.bg), children: [
449
+ /* @__PURE__ */ jsxRuntimeExports.jsxs(
450
+ "button",
451
+ {
452
+ type: "button",
453
+ onClick: onToggle,
454
+ className: "w-full text-left flex items-center gap-2 px-3 py-1.5 text-xs text-muted-foreground cursor-pointer",
455
+ children: [
456
+ /* @__PURE__ */ jsxRuntimeExports.jsx(
457
+ ChevronRight,
458
+ {
459
+ className: cn("size-3 transition-transform shrink-0", expanded && "rotate-90")
460
+ }
461
+ ),
462
+ /* @__PURE__ */ jsxRuntimeExports.jsx(v.icon, { className: cn("size-3 shrink-0", v.accent) }),
463
+ /* @__PURE__ */ jsxRuntimeExports.jsx("span", { className: "font-mono truncate flex-1", title: `${firstPath} … ${lastPath}`, children: label }),
464
+ /* @__PURE__ */ jsxRuntimeExports.jsx("span", { className: cn("text-[10px] uppercase tracking-wider shrink-0", v.accent), children: v.label }),
465
+ /* @__PURE__ */ jsxRuntimeExports.jsxs("span", { className: "text-muted-foreground/60 shrink-0", children: [
466
+ "(",
467
+ summary,
468
+ ")"
469
+ ] })
470
+ ]
471
+ }
472
+ ),
473
+ expanded && /* @__PURE__ */ jsxRuntimeExports.jsx("div", { className: "ml-5 mt-1 mb-2 space-y-2 pr-2", children: ops.map((op) => /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "border border-border/50 rounded p-2 bg-muted/20", children: [
474
+ /* @__PURE__ */ jsxRuntimeExports.jsx("div", { className: "font-mono text-xs text-muted-foreground mb-1", children: op.path }),
475
+ /* @__PURE__ */ jsxRuntimeExports.jsx(JsonViewerFromString, { text: nodeToJsonString(op.value), defaultExpandDepth: 0 })
476
+ ] }, op.path)) })
477
+ ] });
478
+ }
479
+ function UnifiedOpRow({
480
+ op,
481
+ idx,
482
+ copiedPath,
483
+ onCopyPath,
484
+ expanded,
485
+ onToggle
486
+ }) {
487
+ const v = KIND_VISUAL[op.kind];
488
+ const Icon = v.icon;
489
+ const isExpandable = op.kind === "added" || op.kind === "removed" ? op.value.kind === "object" || op.value.kind === "array" : op.kind === "changed" ? op.left.kind === "object" || op.left.kind === "array" || op.right.kind === "object" || op.right.kind === "array" : false;
490
+ const preview = op.kind === "changed" ? [
491
+ {
492
+ text: previewNode(op.left, 400),
493
+ tone: "text-rose-700 dark:text-rose-300 line-through"
494
+ },
495
+ { text: previewNode(op.right, 400), tone: "text-emerald-700 dark:text-emerald-300" }
496
+ ] : op.kind === "removed" ? [
497
+ {
498
+ text: previewNode(op.value, 400),
499
+ tone: "text-rose-700 dark:text-rose-300 line-through"
500
+ }
501
+ ] : op.kind === "added" ? [{ text: previewNode(op.value, 400), tone: "text-emerald-700 dark:text-emerald-300" }] : [{ text: previewNode(op.value, 400), tone: "text-muted-foreground" }];
502
+ const justCopied = copiedPath === op.path && op.path !== "";
503
+ return /* @__PURE__ */ jsxRuntimeExports.jsxs(
504
+ "div",
505
+ {
506
+ "data-diff-idx": idx,
507
+ "data-diff-kind": op.kind,
508
+ className: cn("border-l-4 rounded-sm px-3 py-2 my-0.5 transition-colors", v.border, v.bg),
509
+ children: [
510
+ /* @__PURE__ */ jsxRuntimeExports.jsxs(
511
+ "button",
512
+ {
513
+ type: "button",
514
+ onClick: onToggle,
515
+ disabled: !isExpandable,
516
+ className: cn(
517
+ "w-full flex items-center gap-2 text-xs text-left rounded-sm",
518
+ isExpandable ? "cursor-pointer" : "cursor-default"
519
+ ),
520
+ "aria-expanded": isExpandable ? expanded : void 0,
521
+ "aria-label": isExpandable ? expanded ? `Collapse ${op.path || "root"}` : `Expand ${op.path || "root"}` : void 0,
522
+ children: [
523
+ isExpandable ? /* @__PURE__ */ jsxRuntimeExports.jsx(
524
+ ChevronRight,
525
+ {
526
+ className: cn(
527
+ "size-3 shrink-0 transition-transform",
528
+ v.accent,
529
+ expanded && "rotate-90"
530
+ )
531
+ }
532
+ ) : /* @__PURE__ */ jsxRuntimeExports.jsx("span", { className: "size-3 shrink-0", "aria-hidden": "true" }),
533
+ /* @__PURE__ */ jsxRuntimeExports.jsx(Icon, { className: cn("size-3.5 shrink-0", v.accent), strokeWidth: 2.5 }),
534
+ /* @__PURE__ */ jsxRuntimeExports.jsx("span", { className: "font-mono truncate flex-1 min-w-0", title: op.path || "(root)", children: op.path === "" ? "(root)" : op.path }),
535
+ /* @__PURE__ */ jsxRuntimeExports.jsx(
536
+ "span",
537
+ {
538
+ className: cn(
539
+ "text-[9px] font-bold uppercase tracking-wider shrink-0 px-1.5 py-0.5 rounded",
540
+ v.accent,
541
+ op.kind === "equal" ? "bg-muted/40" : "bg-background/60"
542
+ ),
543
+ children: v.label
544
+ }
545
+ ),
546
+ op.path !== "" && /* @__PURE__ */ jsxRuntimeExports.jsx(
547
+ "span",
548
+ {
549
+ role: "button",
550
+ tabIndex: 0,
551
+ onClick: (e) => {
552
+ e.stopPropagation();
553
+ onCopyPath(op.path);
554
+ },
555
+ onKeyDown: (e) => {
556
+ if (e.key === "Enter" || e.key === " ") {
557
+ e.stopPropagation();
558
+ e.preventDefault();
559
+ onCopyPath(op.path);
560
+ }
561
+ },
562
+ className: cn(
563
+ "shrink-0 p-1 rounded transition-colors cursor-pointer inline-flex items-center justify-center",
564
+ justCopied ? "text-emerald-500" : "text-muted-foreground/50 hover:text-foreground hover:bg-muted"
565
+ ),
566
+ "aria-label": justCopied ? "Copied" : "Copy",
567
+ title: justCopied ? "Copied!" : "Copy",
568
+ children: justCopied ? /* @__PURE__ */ jsxRuntimeExports.jsx(Check, { className: "size-3" }) : /* @__PURE__ */ jsxRuntimeExports.jsx(Copy, { className: "size-3" })
569
+ }
570
+ )
571
+ ]
572
+ }
573
+ ),
574
+ preview.map((p, i) => (
575
+ // biome-ignore lint/suspicious/noArrayIndexKey: preview list is rebuilt on every render and is positional
576
+ /* @__PURE__ */ jsxRuntimeExports.jsx("div", { className: cn("font-mono text-xs mt-1 break-all pl-5", p.tone), children: p.text }, i)
577
+ )),
578
+ /* @__PURE__ */ jsxRuntimeExports.jsx(
579
+ "div",
580
+ {
581
+ className: "overflow-hidden transition-all duration-200",
582
+ style: { maxHeight: expanded && isExpandable ? "2000px" : "0" },
583
+ "aria-hidden": !expanded,
584
+ children: expanded && isExpandable && op.kind !== "equal" ? /* @__PURE__ */ jsxRuntimeExports.jsx(ExpandedSubtree, { op }) : null
585
+ }
586
+ )
587
+ ]
588
+ }
589
+ );
590
+ }
591
+ function ExpandedSubtree({ op }) {
592
+ if (op.kind === "added" || op.kind === "removed") {
593
+ return /* @__PURE__ */ jsxRuntimeExports.jsx("div", { className: "pl-5 mt-2 border border-border/50 rounded p-2 bg-muted/20", children: /* @__PURE__ */ jsxRuntimeExports.jsx(JsonViewerFromString, { text: nodeToJsonString(op.value), defaultExpandDepth: 0 }) });
594
+ }
595
+ const leftIsStructured = op.left.kind === "object" || op.left.kind === "array";
596
+ const rightIsStructured = op.right.kind === "object" || op.right.kind === "array";
597
+ if (!leftIsStructured && !rightIsStructured) {
598
+ return /* @__PURE__ */ jsxRuntimeExports.jsx("div", { className: "pl-5 mt-2 text-xs text-muted-foreground/70 italic", children: "Primitive values are shown inline above." });
599
+ }
600
+ return /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "pl-5 mt-2 grid grid-cols-1 md:grid-cols-2 gap-2", children: [
601
+ /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "border border-rose-500/30 rounded p-2 bg-rose-500/5", children: [
602
+ /* @__PURE__ */ jsxRuntimeExports.jsx("div", { className: "text-[10px] uppercase tracking-wider text-rose-500 mb-1", children: "Old" }),
603
+ /* @__PURE__ */ jsxRuntimeExports.jsx(JsonViewerFromString, { text: nodeToJsonString(op.left), defaultExpandDepth: 0 })
604
+ ] }),
605
+ /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "border border-emerald-500/30 rounded p-2 bg-emerald-500/5", children: [
606
+ /* @__PURE__ */ jsxRuntimeExports.jsx("div", { className: "text-[10px] uppercase tracking-wider text-emerald-500 mb-1", children: "New" }),
607
+ /* @__PURE__ */ jsxRuntimeExports.jsx(JsonViewerFromString, { text: nodeToJsonString(op.right), defaultExpandDepth: 0 })
608
+ ] })
609
+ ] });
610
+ }
611
+ function SummaryChips({
612
+ counts,
613
+ onJumpTo
614
+ }) {
615
+ const total = counts.added + counts.removed + counts.changed;
616
+ return /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "px-4 py-2 border-b border-border bg-muted/20 flex items-center gap-2 text-xs flex-wrap", children: [
617
+ /* @__PURE__ */ jsxRuntimeExports.jsxs("span", { className: "text-muted-foreground font-medium", children: [
618
+ total,
619
+ " ",
620
+ total === 1 ? "change" : "changes"
621
+ ] }),
622
+ /* @__PURE__ */ jsxRuntimeExports.jsxs(
623
+ "button",
624
+ {
625
+ type: "button",
626
+ onClick: () => onJumpTo("removed"),
627
+ disabled: counts.removed === 0,
628
+ className: cn(
629
+ "inline-flex items-center gap-1 px-2 py-0.5 rounded-full border cursor-pointer transition-colors",
630
+ counts.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"
631
+ ),
632
+ title: counts.removed > 0 ? "Jump to first removed" : "No removals",
633
+ children: [
634
+ /* @__PURE__ */ jsxRuntimeExports.jsx(Minus, { className: "size-3" }),
635
+ counts.removed,
636
+ " removed"
637
+ ]
638
+ }
639
+ ),
640
+ /* @__PURE__ */ jsxRuntimeExports.jsxs(
641
+ "button",
642
+ {
643
+ type: "button",
644
+ onClick: () => onJumpTo("added"),
645
+ disabled: counts.added === 0,
646
+ className: cn(
647
+ "inline-flex items-center gap-1 px-2 py-0.5 rounded-full border cursor-pointer transition-colors",
648
+ counts.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"
649
+ ),
650
+ title: counts.added > 0 ? "Jump to first added" : "No additions",
651
+ children: [
652
+ /* @__PURE__ */ jsxRuntimeExports.jsx(Plus, { className: "size-3" }),
653
+ counts.added,
654
+ " added"
655
+ ]
656
+ }
657
+ ),
658
+ /* @__PURE__ */ jsxRuntimeExports.jsxs(
659
+ "button",
660
+ {
661
+ type: "button",
662
+ onClick: () => onJumpTo("changed"),
663
+ disabled: counts.changed === 0,
664
+ className: cn(
665
+ "inline-flex items-center gap-1 px-2 py-0.5 rounded-full border cursor-pointer transition-colors",
666
+ counts.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"
667
+ ),
668
+ title: counts.changed > 0 ? "Jump to first changed" : "No changes",
669
+ children: [
670
+ /* @__PURE__ */ jsxRuntimeExports.jsx(Pencil, { className: "size-3" }),
671
+ counts.changed,
672
+ " changed"
673
+ ]
674
+ }
675
+ )
676
+ ] });
677
+ }
678
+ function ModeToggle({
679
+ mode,
680
+ onChange
681
+ }) {
682
+ return /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "inline-flex rounded-md border border-border overflow-hidden", children: [
683
+ /* @__PURE__ */ jsxRuntimeExports.jsxs(
684
+ "button",
685
+ {
686
+ type: "button",
687
+ onClick: () => onChange("unified"),
688
+ "aria-pressed": mode === "unified",
689
+ className: cn(
690
+ "flex items-center gap-1 px-2 py-1 text-xs transition-colors cursor-pointer",
691
+ mode === "unified" ? "bg-muted text-foreground" : "hover:bg-muted/50 text-muted-foreground"
692
+ ),
693
+ title: "Unified view (single column, emphasized diffs)",
694
+ children: [
695
+ /* @__PURE__ */ jsxRuntimeExports.jsx(Rows3, { className: "size-3" }),
696
+ "Unified"
697
+ ]
698
+ }
699
+ ),
700
+ /* @__PURE__ */ jsxRuntimeExports.jsxs(
701
+ "button",
702
+ {
703
+ type: "button",
704
+ onClick: () => onChange("split"),
705
+ "aria-pressed": mode === "split",
706
+ className: cn(
707
+ "flex items-center gap-1 px-2 py-1 text-xs transition-colors border-l border-border cursor-pointer",
708
+ mode === "split" ? "bg-muted text-foreground" : "hover:bg-muted/50 text-muted-foreground"
709
+ ),
710
+ title: "Split view (path | left | right)",
711
+ children: [
712
+ /* @__PURE__ */ jsxRuntimeExports.jsx(Columns2, { className: "size-3" }),
713
+ "Split"
714
+ ]
715
+ }
716
+ )
717
+ ] });
718
+ }
719
+ function SideSummary({ log, side }) {
720
+ const conversationId = getConversationId(log);
721
+ return /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "flex-1 min-w-0 space-y-1 text-xs", children: [
722
+ /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "flex items-center gap-2", children: [
723
+ /* @__PURE__ */ jsxRuntimeExports.jsx(
724
+ Badge,
725
+ {
726
+ variant: "outline",
727
+ className: cn(
728
+ "text-[10px] px-1.5 py-0 h-5 font-mono shrink-0",
729
+ side === "left" ? "border-rose-500/40 text-rose-400" : "border-emerald-500/40 text-emerald-400"
730
+ ),
731
+ children: side === "left" ? "← Left" : "Right →"
732
+ }
733
+ ),
734
+ /* @__PURE__ */ jsxRuntimeExports.jsxs("span", { className: "font-mono text-blue-400/80", children: [
735
+ "#",
736
+ log.id
737
+ ] }),
738
+ log.model !== null && /* @__PURE__ */ jsxRuntimeExports.jsx("span", { className: "font-mono text-muted-foreground truncate", children: log.model })
739
+ ] }),
740
+ /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "flex items-center gap-3 text-muted-foreground font-mono", children: [
741
+ log.cacheCreationInputTokens !== null && log.cacheCreationInputTokens > 0 && /* @__PURE__ */ jsxRuntimeExports.jsxs("span", { className: "text-emerald-400", children: [
742
+ "Cache +",
743
+ formatTokens(log.cacheCreationInputTokens)
744
+ ] }),
745
+ log.cacheReadInputTokens !== null && log.cacheReadInputTokens > 0 && /* @__PURE__ */ jsxRuntimeExports.jsxs("span", { className: "text-purple-400", children: [
746
+ "Cache ~",
747
+ formatTokens(log.cacheReadInputTokens)
748
+ ] }),
749
+ /* @__PURE__ */ jsxRuntimeExports.jsx("span", { className: "truncate", title: log.timestamp, children: log.timestamp })
750
+ ] }),
751
+ /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "text-muted-foreground/70 font-mono truncate", title: conversationId, children: [
752
+ "session: ",
753
+ conversationId
754
+ ] })
755
+ ] });
756
+ }
757
+ function CompareDrawer({ left, right, onClose }) {
758
+ const ops = reactExports.useMemo(() => {
759
+ const leftRequest = getLogFormatAdapter(resolveLogFormat(left)).analyzeRequest(
760
+ left.rawRequestBody
761
+ );
762
+ const rightRequest = getLogFormatAdapter(resolveLogFormat(right)).analyzeRequest(
763
+ right.rawRequestBody
764
+ );
765
+ const l = normalizeRequest(leftRequest.comparisonValue);
766
+ const r = normalizeRequest(rightRequest.comparisonValue);
767
+ return diffTrees(l, r);
768
+ }, [
769
+ left.apiFormat,
770
+ left.path,
771
+ left.rawRequestBody,
772
+ right.apiFormat,
773
+ right.path,
774
+ right.rawRequestBody
775
+ ]);
776
+ const grouped = reactExports.useMemo(() => groupContiguousEquals(ops), [ops]);
777
+ const counts = reactExports.useMemo(() => {
778
+ let added = 0;
779
+ let removed = 0;
780
+ let changed = 0;
781
+ for (const g of grouped) {
782
+ if (g.kind !== "single") continue;
783
+ switch (g.op.kind) {
784
+ case "added":
785
+ added++;
786
+ break;
787
+ case "removed":
788
+ removed++;
789
+ break;
790
+ case "changed":
791
+ changed++;
792
+ break;
793
+ }
794
+ }
795
+ return { added, removed, changed };
796
+ }, [grouped]);
797
+ const [expandedRuns, setExpandedRuns] = reactExports.useState(/* @__PURE__ */ new Set());
798
+ const toggleRun = (idx) => {
799
+ setExpandedRuns((prev) => {
800
+ const next = new Set(prev);
801
+ if (next.has(idx)) next.delete(idx);
802
+ else next.add(idx);
803
+ return next;
804
+ });
805
+ };
806
+ const [expandedRows, setExpandedRows] = reactExports.useState(/* @__PURE__ */ new Set());
807
+ const toggleRow = (idx) => {
808
+ setExpandedRows((prev) => {
809
+ const next = new Set(prev);
810
+ if (next.has(idx)) next.delete(idx);
811
+ else next.add(idx);
812
+ return next;
813
+ });
814
+ };
815
+ reactExports.useEffect(() => {
816
+ setExpandedRows(/* @__PURE__ */ new Set());
817
+ }, [left.id, right.id]);
818
+ const [mode, setMode] = reactExports.useState("unified");
819
+ const bodyRef = reactExports.useRef(null);
820
+ const [copiedPath, setCopiedPath] = reactExports.useState(null);
821
+ const copyResetTimer = reactExports.useRef(null);
822
+ const onCopyPath = (path) => {
823
+ void window.navigator.clipboard.writeText(path).then(() => {
824
+ setCopiedPath(path);
825
+ if (copyResetTimer.current !== null) clearTimeout(copyResetTimer.current);
826
+ copyResetTimer.current = setTimeout(() => setCopiedPath(null), 1500);
827
+ });
828
+ };
829
+ reactExports.useEffect(() => {
830
+ return () => {
831
+ if (copyResetTimer.current !== null) clearTimeout(copyResetTimer.current);
832
+ };
833
+ }, []);
834
+ const jumpToKind = (kind) => {
835
+ const idx = grouped.findIndex((g) => g.kind === "single" && g.op.kind === kind);
836
+ if (idx === -1) return;
837
+ const root = bodyRef.current;
838
+ if (root === null) return;
839
+ const el = root.querySelector(`[data-diff-idx="${idx}"]`);
840
+ if (el !== null) {
841
+ el.scrollIntoView({ behavior: "smooth", block: "center" });
842
+ }
843
+ };
844
+ reactExports.useEffect(() => {
845
+ const onKey = (e) => {
846
+ if (e.key === "Escape") onClose();
847
+ };
848
+ document.addEventListener("keydown", onKey);
849
+ const prevOverflow = document.body.style.overflow;
850
+ document.body.style.overflow = "hidden";
851
+ return () => {
852
+ document.removeEventListener("keydown", onKey);
853
+ document.body.style.overflow = prevOverflow;
854
+ };
855
+ }, [onClose]);
856
+ const sameSession = getConversationId(left) === getConversationId(right);
857
+ const allEqual = ops.length === 1 && ops[0]?.kind === "equal";
858
+ return /* @__PURE__ */ jsxRuntimeExports.jsxs(
859
+ "div",
860
+ {
861
+ className: "fixed inset-0 z-50 flex justify-end",
862
+ role: "dialog",
863
+ "aria-modal": "true",
864
+ "aria-label": "Compare two log requests",
865
+ children: [
866
+ /* @__PURE__ */ jsxRuntimeExports.jsx(
867
+ "button",
868
+ {
869
+ type: "button",
870
+ onClick: onClose,
871
+ "aria-label": "Close compare drawer",
872
+ className: "absolute inset-0 bg-black/40 cursor-default",
873
+ tabIndex: -1
874
+ }
875
+ ),
876
+ /* @__PURE__ */ jsxRuntimeExports.jsxs(
877
+ "div",
878
+ {
879
+ className: cn(
880
+ "relative bg-background border-l border-border shadow-xl",
881
+ "w-full md:w-[70vw] max-w-[1100px] flex flex-col h-full"
882
+ ),
883
+ onClick: (e) => e.stopPropagation(),
884
+ onKeyDown: (e) => e.stopPropagation(),
885
+ children: [
886
+ /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "flex items-start gap-4 px-4 py-3 border-b border-border", children: [
887
+ /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "flex-1 flex gap-4 min-w-0", children: [
888
+ /* @__PURE__ */ jsxRuntimeExports.jsx(SideSummary, { log: left, side: "left" }),
889
+ /* @__PURE__ */ jsxRuntimeExports.jsx(SideSummary, { log: right, side: "right" })
890
+ ] }),
891
+ /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "flex items-center gap-2 shrink-0", children: [
892
+ /* @__PURE__ */ jsxRuntimeExports.jsx(ModeToggle, { mode, onChange: setMode }),
893
+ /* @__PURE__ */ jsxRuntimeExports.jsx(
894
+ "button",
895
+ {
896
+ type: "button",
897
+ onClick: onClose,
898
+ "aria-label": "Close",
899
+ className: "p-1 rounded text-muted-foreground hover:text-foreground hover:bg-muted cursor-pointer",
900
+ children: /* @__PURE__ */ jsxRuntimeExports.jsx(X, { className: "size-4" })
901
+ }
902
+ )
903
+ ] })
904
+ ] }),
905
+ !sameSession && /* @__PURE__ */ jsxRuntimeExports.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." }),
906
+ allEqual ? /* @__PURE__ */ jsxRuntimeExports.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." }) : /* @__PURE__ */ jsxRuntimeExports.jsxs(jsxRuntimeExports.Fragment, { children: [
907
+ /* @__PURE__ */ jsxRuntimeExports.jsx(SummaryChips, { counts, onJumpTo: jumpToKind }),
908
+ /* @__PURE__ */ jsxRuntimeExports.jsx("div", { ref: bodyRef, className: "flex-1 min-h-0 overflow-y-auto", children: mode === "unified" ? /* @__PURE__ */ jsxRuntimeExports.jsx("div", { className: "px-3 py-2 space-y-0.5", children: grouped.map((g, i) => {
909
+ if (g.kind === "equal-run") {
910
+ return /* @__PURE__ */ jsxRuntimeExports.jsx(
911
+ EqualRunRow,
912
+ {
913
+ ops: g.ops,
914
+ expanded: expandedRuns.has(i),
915
+ onToggle: () => toggleRun(i)
916
+ },
917
+ `r${i}`
918
+ );
919
+ }
920
+ const op = g.op;
921
+ return /* @__PURE__ */ jsxRuntimeExports.jsx(
922
+ UnifiedOpRow,
923
+ {
924
+ op,
925
+ idx: i,
926
+ copiedPath,
927
+ onCopyPath,
928
+ expanded: expandedRows.has(i),
929
+ onToggle: () => toggleRow(i)
930
+ },
931
+ `o${i}`
932
+ );
933
+ }) }) : /* @__PURE__ */ jsxRuntimeExports.jsx(SplitBody, { grouped, left, right }) })
934
+ ] })
935
+ ]
936
+ }
937
+ )
938
+ ]
939
+ }
940
+ );
941
+ }
942
+ function SplitBody({
943
+ grouped,
944
+ left,
945
+ right
946
+ }) {
947
+ return /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "grid grid-cols-[200px_1fr_1fr] gap-x-2 gap-y-0.5 px-3 py-2 text-xs", children: [
948
+ /* @__PURE__ */ jsxRuntimeExports.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: [
949
+ /* @__PURE__ */ jsxRuntimeExports.jsx("span", { children: "Path" }),
950
+ /* @__PURE__ */ jsxRuntimeExports.jsxs("span", { children: [
951
+ "Left (Log #",
952
+ left.id,
953
+ ")"
954
+ ] }),
955
+ /* @__PURE__ */ jsxRuntimeExports.jsxs("span", { children: [
956
+ "Right (Log #",
957
+ right.id,
958
+ ")"
959
+ ] })
960
+ ] }),
961
+ grouped.map((g, i) => {
962
+ if (g.kind === "equal-run") {
963
+ return /* @__PURE__ */ jsxRuntimeExports.jsxs(
964
+ "div",
965
+ {
966
+ className: "col-span-3 px-2 py-1 text-xs text-muted-foreground/60",
967
+ children: [
968
+ g.ops.length,
969
+ " equal siblings collapsed — switch to Unified to expand"
970
+ ]
971
+ },
972
+ i
973
+ );
974
+ }
975
+ const op = g.op;
976
+ if (op.kind === "equal") {
977
+ return /* @__PURE__ */ jsxRuntimeExports.jsxs(
978
+ "div",
979
+ {
980
+ className: "col-span-3 grid grid-cols-[200px_1fr_1fr] gap-x-2 px-2 py-0.5 text-muted-foreground",
981
+ children: [
982
+ /* @__PURE__ */ jsxRuntimeExports.jsx("span", { className: "font-mono text-xs truncate", title: op.path, children: op.path }),
983
+ /* @__PURE__ */ jsxRuntimeExports.jsx("span", { className: "font-mono text-xs break-all opacity-60", children: previewNode(op.value, 200) }),
984
+ /* @__PURE__ */ jsxRuntimeExports.jsx("span", { className: "font-mono text-xs break-all opacity-60", children: previewNode(op.value, 200) })
985
+ ]
986
+ },
987
+ i
988
+ );
989
+ }
990
+ if (op.kind === "added") {
991
+ return /* @__PURE__ */ jsxRuntimeExports.jsxs(
992
+ "div",
993
+ {
994
+ className: "col-span-3 px-2 py-1 rounded text-xs border-l-2 border-l-emerald-400/70 bg-emerald-500/5",
995
+ children: [
996
+ /* @__PURE__ */ jsxRuntimeExports.jsx("div", { className: "font-mono text-xs text-muted-foreground mb-0.5", children: op.path }),
997
+ /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "font-mono break-all text-emerald-300/90", children: [
998
+ "+ ",
999
+ previewNode(op.value, 400)
1000
+ ] })
1001
+ ]
1002
+ },
1003
+ i
1004
+ );
1005
+ }
1006
+ if (op.kind === "removed") {
1007
+ return /* @__PURE__ */ jsxRuntimeExports.jsxs(
1008
+ "div",
1009
+ {
1010
+ className: "col-span-3 px-2 py-1 rounded text-xs border-l-2 border-l-rose-400/70 bg-rose-500/5",
1011
+ children: [
1012
+ /* @__PURE__ */ jsxRuntimeExports.jsx("div", { className: "font-mono text-xs text-muted-foreground mb-0.5", children: op.path }),
1013
+ /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "font-mono break-all text-rose-300/90 line-through", children: [
1014
+ "− ",
1015
+ previewNode(op.value, 400)
1016
+ ] })
1017
+ ]
1018
+ },
1019
+ i
1020
+ );
1021
+ }
1022
+ return /* @__PURE__ */ jsxRuntimeExports.jsxs(
1023
+ "div",
1024
+ {
1025
+ className: "col-span-3 px-2 py-1 rounded text-xs border-l-2 border-l-amber-400/70 bg-amber-500/5",
1026
+ children: [
1027
+ /* @__PURE__ */ jsxRuntimeExports.jsx("div", { className: "font-mono text-xs text-muted-foreground mb-1", children: op.path }),
1028
+ /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "grid grid-cols-2 gap-2", children: [
1029
+ /* @__PURE__ */ jsxRuntimeExports.jsx("div", { className: "font-mono text-rose-300/90 break-all line-through", children: previewNode(op.left, 400) }),
1030
+ /* @__PURE__ */ jsxRuntimeExports.jsx("div", { className: "font-mono text-emerald-300/90 break-all", children: previewNode(op.right, 400) })
1031
+ ] })
1032
+ ]
1033
+ },
1034
+ i
1035
+ );
1036
+ })
1037
+ ] });
1038
+ }
1039
+ export {
1040
+ CompareDrawer
1041
+ };