@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,1163 @@
1
+ import { r as reactExports, j as jsxRuntimeExports } from "./react.mjs";
2
+ import { r as reactDomExports } from "./react-dom.mjs";
3
+ import { c as clamp } from "./radix-ui__number.mjs";
4
+ import { c as composeEventHandlers } from "./radix-ui__primitive.mjs";
5
+ import { c as createCollection } from "./radix-ui__react-collection.mjs";
6
+ import { u as useComposedRefs } from "./radix-ui__react-compose-refs.mjs";
7
+ import { c as createContextScope } from "./radix-ui__react-context.mjs";
8
+ import { u as useDirection } from "./radix-ui__react-direction.mjs";
9
+ import { D as DismissableLayer } from "./@radix-ui/react-dismissable-layer+[...].mjs";
10
+ import { u as useFocusGuards } from "./radix-ui__react-focus-guards.mjs";
11
+ import { F as FocusScope } from "./radix-ui__react-focus-scope.mjs";
12
+ import { u as useId } from "./radix-ui__react-id.mjs";
13
+ import { R as Root2$1, A as Anchor, c as createPopperScope, C as Content, a as Arrow } from "./radix-ui__react-popper.mjs";
14
+ import { P as Portal$1 } from "./radix-ui__react-portal.mjs";
15
+ import { P as Primitive } from "./radix-ui__react-primitive.mjs";
16
+ import { c as createSlot } from "./radix-ui__react-slot.mjs";
17
+ import { u as useCallbackRef } from "./@radix-ui/react-use-callback-ref+[...].mjs";
18
+ import { u as useControllableState } from "./@radix-ui/react-use-controllable-state+[...].mjs";
19
+ import { u as useLayoutEffect2 } from "./@radix-ui/react-use-layout-effect+[...].mjs";
20
+ import { u as usePrevious } from "./radix-ui__react-use-previous.mjs";
21
+ import { V as VISUALLY_HIDDEN_STYLES } from "./@radix-ui/react-visually-hidden+[...].mjs";
22
+ import { h as hideOthers } from "./aria-hidden.mjs";
23
+ import { R as ReactRemoveScroll } from "./react-remove-scroll.mjs";
24
+ var OPEN_KEYS = [" ", "Enter", "ArrowUp", "ArrowDown"];
25
+ var SELECTION_KEYS = [" ", "Enter"];
26
+ var SELECT_NAME = "Select";
27
+ var [Collection, useCollection, createCollectionScope] = createCollection(SELECT_NAME);
28
+ var [createSelectContext] = createContextScope(SELECT_NAME, [
29
+ createCollectionScope,
30
+ createPopperScope
31
+ ]);
32
+ var usePopperScope = createPopperScope();
33
+ var [SelectProvider, useSelectContext] = createSelectContext(SELECT_NAME);
34
+ var [SelectNativeOptionsProvider, useSelectNativeOptionsContext] = createSelectContext(SELECT_NAME);
35
+ var Select = (props) => {
36
+ const {
37
+ __scopeSelect,
38
+ children,
39
+ open: openProp,
40
+ defaultOpen,
41
+ onOpenChange,
42
+ value: valueProp,
43
+ defaultValue,
44
+ onValueChange,
45
+ dir,
46
+ name,
47
+ autoComplete,
48
+ disabled,
49
+ required,
50
+ form
51
+ } = props;
52
+ const popperScope = usePopperScope(__scopeSelect);
53
+ const [trigger, setTrigger] = reactExports.useState(null);
54
+ const [valueNode, setValueNode] = reactExports.useState(null);
55
+ const [valueNodeHasChildren, setValueNodeHasChildren] = reactExports.useState(false);
56
+ const direction = useDirection(dir);
57
+ const [open, setOpen] = useControllableState({
58
+ prop: openProp,
59
+ defaultProp: defaultOpen ?? false,
60
+ onChange: onOpenChange,
61
+ caller: SELECT_NAME
62
+ });
63
+ const [value, setValue] = useControllableState({
64
+ prop: valueProp,
65
+ defaultProp: defaultValue,
66
+ onChange: onValueChange,
67
+ caller: SELECT_NAME
68
+ });
69
+ const triggerPointerDownPosRef = reactExports.useRef(null);
70
+ const isFormControl = trigger ? form || !!trigger.closest("form") : true;
71
+ const [nativeOptionsSet, setNativeOptionsSet] = reactExports.useState(/* @__PURE__ */ new Set());
72
+ const nativeSelectKey = Array.from(nativeOptionsSet).map((option) => option.props.value).join(";");
73
+ return /* @__PURE__ */ jsxRuntimeExports.jsx(Root2$1, { ...popperScope, children: /* @__PURE__ */ jsxRuntimeExports.jsxs(
74
+ SelectProvider,
75
+ {
76
+ required,
77
+ scope: __scopeSelect,
78
+ trigger,
79
+ onTriggerChange: setTrigger,
80
+ valueNode,
81
+ onValueNodeChange: setValueNode,
82
+ valueNodeHasChildren,
83
+ onValueNodeHasChildrenChange: setValueNodeHasChildren,
84
+ contentId: useId(),
85
+ value,
86
+ onValueChange: setValue,
87
+ open,
88
+ onOpenChange: setOpen,
89
+ dir: direction,
90
+ triggerPointerDownPosRef,
91
+ disabled,
92
+ children: [
93
+ /* @__PURE__ */ jsxRuntimeExports.jsx(Collection.Provider, { scope: __scopeSelect, children: /* @__PURE__ */ jsxRuntimeExports.jsx(
94
+ SelectNativeOptionsProvider,
95
+ {
96
+ scope: props.__scopeSelect,
97
+ onNativeOptionAdd: reactExports.useCallback((option) => {
98
+ setNativeOptionsSet((prev) => new Set(prev).add(option));
99
+ }, []),
100
+ onNativeOptionRemove: reactExports.useCallback((option) => {
101
+ setNativeOptionsSet((prev) => {
102
+ const optionsSet = new Set(prev);
103
+ optionsSet.delete(option);
104
+ return optionsSet;
105
+ });
106
+ }, []),
107
+ children
108
+ }
109
+ ) }),
110
+ isFormControl ? /* @__PURE__ */ jsxRuntimeExports.jsxs(
111
+ SelectBubbleInput,
112
+ {
113
+ "aria-hidden": true,
114
+ required,
115
+ tabIndex: -1,
116
+ name,
117
+ autoComplete,
118
+ value,
119
+ onChange: (event) => setValue(event.target.value),
120
+ disabled,
121
+ form,
122
+ children: [
123
+ value === void 0 ? /* @__PURE__ */ jsxRuntimeExports.jsx("option", { value: "" }) : null,
124
+ Array.from(nativeOptionsSet)
125
+ ]
126
+ },
127
+ nativeSelectKey
128
+ ) : null
129
+ ]
130
+ }
131
+ ) });
132
+ };
133
+ Select.displayName = SELECT_NAME;
134
+ var TRIGGER_NAME = "SelectTrigger";
135
+ var SelectTrigger = reactExports.forwardRef(
136
+ (props, forwardedRef) => {
137
+ const { __scopeSelect, disabled = false, ...triggerProps } = props;
138
+ const popperScope = usePopperScope(__scopeSelect);
139
+ const context = useSelectContext(TRIGGER_NAME, __scopeSelect);
140
+ const isDisabled = context.disabled || disabled;
141
+ const composedRefs = useComposedRefs(forwardedRef, context.onTriggerChange);
142
+ const getItems = useCollection(__scopeSelect);
143
+ const pointerTypeRef = reactExports.useRef("touch");
144
+ const [searchRef, handleTypeaheadSearch, resetTypeahead] = useTypeaheadSearch((search) => {
145
+ const enabledItems = getItems().filter((item) => !item.disabled);
146
+ const currentItem = enabledItems.find((item) => item.value === context.value);
147
+ const nextItem = findNextItem(enabledItems, search, currentItem);
148
+ if (nextItem !== void 0) {
149
+ context.onValueChange(nextItem.value);
150
+ }
151
+ });
152
+ const handleOpen = (pointerEvent) => {
153
+ if (!isDisabled) {
154
+ context.onOpenChange(true);
155
+ resetTypeahead();
156
+ }
157
+ if (pointerEvent) {
158
+ context.triggerPointerDownPosRef.current = {
159
+ x: Math.round(pointerEvent.pageX),
160
+ y: Math.round(pointerEvent.pageY)
161
+ };
162
+ }
163
+ };
164
+ return /* @__PURE__ */ jsxRuntimeExports.jsx(Anchor, { asChild: true, ...popperScope, children: /* @__PURE__ */ jsxRuntimeExports.jsx(
165
+ Primitive.button,
166
+ {
167
+ type: "button",
168
+ role: "combobox",
169
+ "aria-controls": context.contentId,
170
+ "aria-expanded": context.open,
171
+ "aria-required": context.required,
172
+ "aria-autocomplete": "none",
173
+ dir: context.dir,
174
+ "data-state": context.open ? "open" : "closed",
175
+ disabled: isDisabled,
176
+ "data-disabled": isDisabled ? "" : void 0,
177
+ "data-placeholder": shouldShowPlaceholder(context.value) ? "" : void 0,
178
+ ...triggerProps,
179
+ ref: composedRefs,
180
+ onClick: composeEventHandlers(triggerProps.onClick, (event) => {
181
+ event.currentTarget.focus();
182
+ if (pointerTypeRef.current !== "mouse") {
183
+ handleOpen(event);
184
+ }
185
+ }),
186
+ onPointerDown: composeEventHandlers(triggerProps.onPointerDown, (event) => {
187
+ pointerTypeRef.current = event.pointerType;
188
+ const target = event.target;
189
+ if (target.hasPointerCapture(event.pointerId)) {
190
+ target.releasePointerCapture(event.pointerId);
191
+ }
192
+ if (event.button === 0 && event.ctrlKey === false && event.pointerType === "mouse") {
193
+ handleOpen(event);
194
+ event.preventDefault();
195
+ }
196
+ }),
197
+ onKeyDown: composeEventHandlers(triggerProps.onKeyDown, (event) => {
198
+ const isTypingAhead = searchRef.current !== "";
199
+ const isModifierKey = event.ctrlKey || event.altKey || event.metaKey;
200
+ if (!isModifierKey && event.key.length === 1) handleTypeaheadSearch(event.key);
201
+ if (isTypingAhead && event.key === " ") return;
202
+ if (OPEN_KEYS.includes(event.key)) {
203
+ handleOpen();
204
+ event.preventDefault();
205
+ }
206
+ })
207
+ }
208
+ ) });
209
+ }
210
+ );
211
+ SelectTrigger.displayName = TRIGGER_NAME;
212
+ var VALUE_NAME = "SelectValue";
213
+ var SelectValue = reactExports.forwardRef(
214
+ (props, forwardedRef) => {
215
+ const { __scopeSelect, className, style, children, placeholder = "", ...valueProps } = props;
216
+ const context = useSelectContext(VALUE_NAME, __scopeSelect);
217
+ const { onValueNodeHasChildrenChange } = context;
218
+ const hasChildren = children !== void 0;
219
+ const composedRefs = useComposedRefs(forwardedRef, context.onValueNodeChange);
220
+ useLayoutEffect2(() => {
221
+ onValueNodeHasChildrenChange(hasChildren);
222
+ }, [onValueNodeHasChildrenChange, hasChildren]);
223
+ return /* @__PURE__ */ jsxRuntimeExports.jsx(
224
+ Primitive.span,
225
+ {
226
+ ...valueProps,
227
+ ref: composedRefs,
228
+ style: { pointerEvents: "none" },
229
+ children: shouldShowPlaceholder(context.value) ? /* @__PURE__ */ jsxRuntimeExports.jsx(jsxRuntimeExports.Fragment, { children: placeholder }) : children
230
+ }
231
+ );
232
+ }
233
+ );
234
+ SelectValue.displayName = VALUE_NAME;
235
+ var ICON_NAME = "SelectIcon";
236
+ var SelectIcon = reactExports.forwardRef(
237
+ (props, forwardedRef) => {
238
+ const { __scopeSelect, children, ...iconProps } = props;
239
+ return /* @__PURE__ */ jsxRuntimeExports.jsx(Primitive.span, { "aria-hidden": true, ...iconProps, ref: forwardedRef, children: children || "▼" });
240
+ }
241
+ );
242
+ SelectIcon.displayName = ICON_NAME;
243
+ var PORTAL_NAME = "SelectPortal";
244
+ var SelectPortal = (props) => {
245
+ return /* @__PURE__ */ jsxRuntimeExports.jsx(Portal$1, { asChild: true, ...props });
246
+ };
247
+ SelectPortal.displayName = PORTAL_NAME;
248
+ var CONTENT_NAME = "SelectContent";
249
+ var SelectContent = reactExports.forwardRef(
250
+ (props, forwardedRef) => {
251
+ const context = useSelectContext(CONTENT_NAME, props.__scopeSelect);
252
+ const [fragment, setFragment] = reactExports.useState();
253
+ useLayoutEffect2(() => {
254
+ setFragment(new DocumentFragment());
255
+ }, []);
256
+ if (!context.open) {
257
+ const frag = fragment;
258
+ return frag ? reactDomExports.createPortal(
259
+ /* @__PURE__ */ jsxRuntimeExports.jsx(SelectContentProvider, { scope: props.__scopeSelect, children: /* @__PURE__ */ jsxRuntimeExports.jsx(Collection.Slot, { scope: props.__scopeSelect, children: /* @__PURE__ */ jsxRuntimeExports.jsx("div", { children: props.children }) }) }),
260
+ frag
261
+ ) : null;
262
+ }
263
+ return /* @__PURE__ */ jsxRuntimeExports.jsx(SelectContentImpl, { ...props, ref: forwardedRef });
264
+ }
265
+ );
266
+ SelectContent.displayName = CONTENT_NAME;
267
+ var CONTENT_MARGIN = 10;
268
+ var [SelectContentProvider, useSelectContentContext] = createSelectContext(CONTENT_NAME);
269
+ var CONTENT_IMPL_NAME = "SelectContentImpl";
270
+ var Slot = createSlot("SelectContent.RemoveScroll");
271
+ var SelectContentImpl = reactExports.forwardRef(
272
+ (props, forwardedRef) => {
273
+ const {
274
+ __scopeSelect,
275
+ position = "item-aligned",
276
+ onCloseAutoFocus,
277
+ onEscapeKeyDown,
278
+ onPointerDownOutside,
279
+ //
280
+ // PopperContent props
281
+ side,
282
+ sideOffset,
283
+ align,
284
+ alignOffset,
285
+ arrowPadding,
286
+ collisionBoundary,
287
+ collisionPadding,
288
+ sticky,
289
+ hideWhenDetached,
290
+ avoidCollisions,
291
+ //
292
+ ...contentProps
293
+ } = props;
294
+ const context = useSelectContext(CONTENT_NAME, __scopeSelect);
295
+ const [content, setContent] = reactExports.useState(null);
296
+ const [viewport, setViewport] = reactExports.useState(null);
297
+ const composedRefs = useComposedRefs(forwardedRef, (node) => setContent(node));
298
+ const [selectedItem, setSelectedItem] = reactExports.useState(null);
299
+ const [selectedItemText, setSelectedItemText] = reactExports.useState(
300
+ null
301
+ );
302
+ const getItems = useCollection(__scopeSelect);
303
+ const [isPositioned, setIsPositioned] = reactExports.useState(false);
304
+ const firstValidItemFoundRef = reactExports.useRef(false);
305
+ reactExports.useEffect(() => {
306
+ if (content) return hideOthers(content);
307
+ }, [content]);
308
+ useFocusGuards();
309
+ const focusFirst = reactExports.useCallback(
310
+ (candidates) => {
311
+ const [firstItem, ...restItems] = getItems().map((item) => item.ref.current);
312
+ const [lastItem] = restItems.slice(-1);
313
+ const PREVIOUSLY_FOCUSED_ELEMENT = document.activeElement;
314
+ for (const candidate of candidates) {
315
+ if (candidate === PREVIOUSLY_FOCUSED_ELEMENT) return;
316
+ candidate?.scrollIntoView({ block: "nearest" });
317
+ if (candidate === firstItem && viewport) viewport.scrollTop = 0;
318
+ if (candidate === lastItem && viewport) viewport.scrollTop = viewport.scrollHeight;
319
+ candidate?.focus();
320
+ if (document.activeElement !== PREVIOUSLY_FOCUSED_ELEMENT) return;
321
+ }
322
+ },
323
+ [getItems, viewport]
324
+ );
325
+ const focusSelectedItem = reactExports.useCallback(
326
+ () => focusFirst([selectedItem, content]),
327
+ [focusFirst, selectedItem, content]
328
+ );
329
+ reactExports.useEffect(() => {
330
+ if (isPositioned) {
331
+ focusSelectedItem();
332
+ }
333
+ }, [isPositioned, focusSelectedItem]);
334
+ const { onOpenChange, triggerPointerDownPosRef } = context;
335
+ reactExports.useEffect(() => {
336
+ if (content) {
337
+ let pointerMoveDelta = { x: 0, y: 0 };
338
+ const handlePointerMove = (event) => {
339
+ pointerMoveDelta = {
340
+ x: Math.abs(Math.round(event.pageX) - (triggerPointerDownPosRef.current?.x ?? 0)),
341
+ y: Math.abs(Math.round(event.pageY) - (triggerPointerDownPosRef.current?.y ?? 0))
342
+ };
343
+ };
344
+ const handlePointerUp = (event) => {
345
+ if (pointerMoveDelta.x <= 10 && pointerMoveDelta.y <= 10) {
346
+ event.preventDefault();
347
+ } else {
348
+ if (!content.contains(event.target)) {
349
+ onOpenChange(false);
350
+ }
351
+ }
352
+ document.removeEventListener("pointermove", handlePointerMove);
353
+ triggerPointerDownPosRef.current = null;
354
+ };
355
+ if (triggerPointerDownPosRef.current !== null) {
356
+ document.addEventListener("pointermove", handlePointerMove);
357
+ document.addEventListener("pointerup", handlePointerUp, { capture: true, once: true });
358
+ }
359
+ return () => {
360
+ document.removeEventListener("pointermove", handlePointerMove);
361
+ document.removeEventListener("pointerup", handlePointerUp, { capture: true });
362
+ };
363
+ }
364
+ }, [content, onOpenChange, triggerPointerDownPosRef]);
365
+ reactExports.useEffect(() => {
366
+ const close = () => onOpenChange(false);
367
+ window.addEventListener("blur", close);
368
+ window.addEventListener("resize", close);
369
+ return () => {
370
+ window.removeEventListener("blur", close);
371
+ window.removeEventListener("resize", close);
372
+ };
373
+ }, [onOpenChange]);
374
+ const [searchRef, handleTypeaheadSearch] = useTypeaheadSearch((search) => {
375
+ const enabledItems = getItems().filter((item) => !item.disabled);
376
+ const currentItem = enabledItems.find((item) => item.ref.current === document.activeElement);
377
+ const nextItem = findNextItem(enabledItems, search, currentItem);
378
+ if (nextItem) {
379
+ setTimeout(() => nextItem.ref.current.focus());
380
+ }
381
+ });
382
+ const itemRefCallback = reactExports.useCallback(
383
+ (node, value, disabled) => {
384
+ const isFirstValidItem = !firstValidItemFoundRef.current && !disabled;
385
+ const isSelectedItem = context.value !== void 0 && context.value === value;
386
+ if (isSelectedItem || isFirstValidItem) {
387
+ setSelectedItem(node);
388
+ if (isFirstValidItem) firstValidItemFoundRef.current = true;
389
+ }
390
+ },
391
+ [context.value]
392
+ );
393
+ const handleItemLeave = reactExports.useCallback(() => content?.focus(), [content]);
394
+ const itemTextRefCallback = reactExports.useCallback(
395
+ (node, value, disabled) => {
396
+ const isFirstValidItem = !firstValidItemFoundRef.current && !disabled;
397
+ const isSelectedItem = context.value !== void 0 && context.value === value;
398
+ if (isSelectedItem || isFirstValidItem) {
399
+ setSelectedItemText(node);
400
+ }
401
+ },
402
+ [context.value]
403
+ );
404
+ const SelectPosition = position === "popper" ? SelectPopperPosition : SelectItemAlignedPosition;
405
+ const popperContentProps = SelectPosition === SelectPopperPosition ? {
406
+ side,
407
+ sideOffset,
408
+ align,
409
+ alignOffset,
410
+ arrowPadding,
411
+ collisionBoundary,
412
+ collisionPadding,
413
+ sticky,
414
+ hideWhenDetached,
415
+ avoidCollisions
416
+ } : {};
417
+ return /* @__PURE__ */ jsxRuntimeExports.jsx(
418
+ SelectContentProvider,
419
+ {
420
+ scope: __scopeSelect,
421
+ content,
422
+ viewport,
423
+ onViewportChange: setViewport,
424
+ itemRefCallback,
425
+ selectedItem,
426
+ onItemLeave: handleItemLeave,
427
+ itemTextRefCallback,
428
+ focusSelectedItem,
429
+ selectedItemText,
430
+ position,
431
+ isPositioned,
432
+ searchRef,
433
+ children: /* @__PURE__ */ jsxRuntimeExports.jsx(ReactRemoveScroll, { as: Slot, allowPinchZoom: true, children: /* @__PURE__ */ jsxRuntimeExports.jsx(
434
+ FocusScope,
435
+ {
436
+ asChild: true,
437
+ trapped: context.open,
438
+ onMountAutoFocus: (event) => {
439
+ event.preventDefault();
440
+ },
441
+ onUnmountAutoFocus: composeEventHandlers(onCloseAutoFocus, (event) => {
442
+ context.trigger?.focus({ preventScroll: true });
443
+ event.preventDefault();
444
+ }),
445
+ children: /* @__PURE__ */ jsxRuntimeExports.jsx(
446
+ DismissableLayer,
447
+ {
448
+ asChild: true,
449
+ disableOutsidePointerEvents: true,
450
+ onEscapeKeyDown,
451
+ onPointerDownOutside,
452
+ onFocusOutside: (event) => event.preventDefault(),
453
+ onDismiss: () => context.onOpenChange(false),
454
+ children: /* @__PURE__ */ jsxRuntimeExports.jsx(
455
+ SelectPosition,
456
+ {
457
+ role: "listbox",
458
+ id: context.contentId,
459
+ "data-state": context.open ? "open" : "closed",
460
+ dir: context.dir,
461
+ onContextMenu: (event) => event.preventDefault(),
462
+ ...contentProps,
463
+ ...popperContentProps,
464
+ onPlaced: () => setIsPositioned(true),
465
+ ref: composedRefs,
466
+ style: {
467
+ // flex layout so we can place the scroll buttons properly
468
+ display: "flex",
469
+ flexDirection: "column",
470
+ // reset the outline by default as the content MAY get focused
471
+ outline: "none",
472
+ ...contentProps.style
473
+ },
474
+ onKeyDown: composeEventHandlers(contentProps.onKeyDown, (event) => {
475
+ const isModifierKey = event.ctrlKey || event.altKey || event.metaKey;
476
+ if (event.key === "Tab") event.preventDefault();
477
+ if (!isModifierKey && event.key.length === 1) handleTypeaheadSearch(event.key);
478
+ if (["ArrowUp", "ArrowDown", "Home", "End"].includes(event.key)) {
479
+ const items = getItems().filter((item) => !item.disabled);
480
+ let candidateNodes = items.map((item) => item.ref.current);
481
+ if (["ArrowUp", "End"].includes(event.key)) {
482
+ candidateNodes = candidateNodes.slice().reverse();
483
+ }
484
+ if (["ArrowUp", "ArrowDown"].includes(event.key)) {
485
+ const currentElement = event.target;
486
+ const currentIndex = candidateNodes.indexOf(currentElement);
487
+ candidateNodes = candidateNodes.slice(currentIndex + 1);
488
+ }
489
+ setTimeout(() => focusFirst(candidateNodes));
490
+ event.preventDefault();
491
+ }
492
+ })
493
+ }
494
+ )
495
+ }
496
+ )
497
+ }
498
+ ) })
499
+ }
500
+ );
501
+ }
502
+ );
503
+ SelectContentImpl.displayName = CONTENT_IMPL_NAME;
504
+ var ITEM_ALIGNED_POSITION_NAME = "SelectItemAlignedPosition";
505
+ var SelectItemAlignedPosition = reactExports.forwardRef((props, forwardedRef) => {
506
+ const { __scopeSelect, onPlaced, ...popperProps } = props;
507
+ const context = useSelectContext(CONTENT_NAME, __scopeSelect);
508
+ const contentContext = useSelectContentContext(CONTENT_NAME, __scopeSelect);
509
+ const [contentWrapper, setContentWrapper] = reactExports.useState(null);
510
+ const [content, setContent] = reactExports.useState(null);
511
+ const composedRefs = useComposedRefs(forwardedRef, (node) => setContent(node));
512
+ const getItems = useCollection(__scopeSelect);
513
+ const shouldExpandOnScrollRef = reactExports.useRef(false);
514
+ const shouldRepositionRef = reactExports.useRef(true);
515
+ const { viewport, selectedItem, selectedItemText, focusSelectedItem } = contentContext;
516
+ const position = reactExports.useCallback(() => {
517
+ if (context.trigger && context.valueNode && contentWrapper && content && viewport && selectedItem && selectedItemText) {
518
+ const triggerRect = context.trigger.getBoundingClientRect();
519
+ const contentRect = content.getBoundingClientRect();
520
+ const valueNodeRect = context.valueNode.getBoundingClientRect();
521
+ const itemTextRect = selectedItemText.getBoundingClientRect();
522
+ if (context.dir !== "rtl") {
523
+ const itemTextOffset = itemTextRect.left - contentRect.left;
524
+ const left = valueNodeRect.left - itemTextOffset;
525
+ const leftDelta = triggerRect.left - left;
526
+ const minContentWidth = triggerRect.width + leftDelta;
527
+ const contentWidth = Math.max(minContentWidth, contentRect.width);
528
+ const rightEdge = window.innerWidth - CONTENT_MARGIN;
529
+ const clampedLeft = clamp(left, [
530
+ CONTENT_MARGIN,
531
+ // Prevents the content from going off the starting edge of the
532
+ // viewport. It may still go off the ending edge, but this can be
533
+ // controlled by the user since they may want to manage overflow in a
534
+ // specific way.
535
+ // https://github.com/radix-ui/primitives/issues/2049
536
+ Math.max(CONTENT_MARGIN, rightEdge - contentWidth)
537
+ ]);
538
+ contentWrapper.style.minWidth = minContentWidth + "px";
539
+ contentWrapper.style.left = clampedLeft + "px";
540
+ } else {
541
+ const itemTextOffset = contentRect.right - itemTextRect.right;
542
+ const right = window.innerWidth - valueNodeRect.right - itemTextOffset;
543
+ const rightDelta = window.innerWidth - triggerRect.right - right;
544
+ const minContentWidth = triggerRect.width + rightDelta;
545
+ const contentWidth = Math.max(minContentWidth, contentRect.width);
546
+ const leftEdge = window.innerWidth - CONTENT_MARGIN;
547
+ const clampedRight = clamp(right, [
548
+ CONTENT_MARGIN,
549
+ Math.max(CONTENT_MARGIN, leftEdge - contentWidth)
550
+ ]);
551
+ contentWrapper.style.minWidth = minContentWidth + "px";
552
+ contentWrapper.style.right = clampedRight + "px";
553
+ }
554
+ const items = getItems();
555
+ const availableHeight = window.innerHeight - CONTENT_MARGIN * 2;
556
+ const itemsHeight = viewport.scrollHeight;
557
+ const contentStyles = window.getComputedStyle(content);
558
+ const contentBorderTopWidth = parseInt(contentStyles.borderTopWidth, 10);
559
+ const contentPaddingTop = parseInt(contentStyles.paddingTop, 10);
560
+ const contentBorderBottomWidth = parseInt(contentStyles.borderBottomWidth, 10);
561
+ const contentPaddingBottom = parseInt(contentStyles.paddingBottom, 10);
562
+ const fullContentHeight = contentBorderTopWidth + contentPaddingTop + itemsHeight + contentPaddingBottom + contentBorderBottomWidth;
563
+ const minContentHeight = Math.min(selectedItem.offsetHeight * 5, fullContentHeight);
564
+ const viewportStyles = window.getComputedStyle(viewport);
565
+ const viewportPaddingTop = parseInt(viewportStyles.paddingTop, 10);
566
+ const viewportPaddingBottom = parseInt(viewportStyles.paddingBottom, 10);
567
+ const topEdgeToTriggerMiddle = triggerRect.top + triggerRect.height / 2 - CONTENT_MARGIN;
568
+ const triggerMiddleToBottomEdge = availableHeight - topEdgeToTriggerMiddle;
569
+ const selectedItemHalfHeight = selectedItem.offsetHeight / 2;
570
+ const itemOffsetMiddle = selectedItem.offsetTop + selectedItemHalfHeight;
571
+ const contentTopToItemMiddle = contentBorderTopWidth + contentPaddingTop + itemOffsetMiddle;
572
+ const itemMiddleToContentBottom = fullContentHeight - contentTopToItemMiddle;
573
+ const willAlignWithoutTopOverflow = contentTopToItemMiddle <= topEdgeToTriggerMiddle;
574
+ if (willAlignWithoutTopOverflow) {
575
+ const isLastItem = items.length > 0 && selectedItem === items[items.length - 1].ref.current;
576
+ contentWrapper.style.bottom = "0px";
577
+ const viewportOffsetBottom = content.clientHeight - viewport.offsetTop - viewport.offsetHeight;
578
+ const clampedTriggerMiddleToBottomEdge = Math.max(
579
+ triggerMiddleToBottomEdge,
580
+ selectedItemHalfHeight + // viewport might have padding bottom, include it to avoid a scrollable viewport
581
+ (isLastItem ? viewportPaddingBottom : 0) + viewportOffsetBottom + contentBorderBottomWidth
582
+ );
583
+ const height = contentTopToItemMiddle + clampedTriggerMiddleToBottomEdge;
584
+ contentWrapper.style.height = height + "px";
585
+ } else {
586
+ const isFirstItem = items.length > 0 && selectedItem === items[0].ref.current;
587
+ contentWrapper.style.top = "0px";
588
+ const clampedTopEdgeToTriggerMiddle = Math.max(
589
+ topEdgeToTriggerMiddle,
590
+ contentBorderTopWidth + viewport.offsetTop + // viewport might have padding top, include it to avoid a scrollable viewport
591
+ (isFirstItem ? viewportPaddingTop : 0) + selectedItemHalfHeight
592
+ );
593
+ const height = clampedTopEdgeToTriggerMiddle + itemMiddleToContentBottom;
594
+ contentWrapper.style.height = height + "px";
595
+ viewport.scrollTop = contentTopToItemMiddle - topEdgeToTriggerMiddle + viewport.offsetTop;
596
+ }
597
+ contentWrapper.style.margin = `${CONTENT_MARGIN}px 0`;
598
+ contentWrapper.style.minHeight = minContentHeight + "px";
599
+ contentWrapper.style.maxHeight = availableHeight + "px";
600
+ onPlaced?.();
601
+ requestAnimationFrame(() => shouldExpandOnScrollRef.current = true);
602
+ }
603
+ }, [
604
+ getItems,
605
+ context.trigger,
606
+ context.valueNode,
607
+ contentWrapper,
608
+ content,
609
+ viewport,
610
+ selectedItem,
611
+ selectedItemText,
612
+ context.dir,
613
+ onPlaced
614
+ ]);
615
+ useLayoutEffect2(() => position(), [position]);
616
+ const [contentZIndex, setContentZIndex] = reactExports.useState();
617
+ useLayoutEffect2(() => {
618
+ if (content) setContentZIndex(window.getComputedStyle(content).zIndex);
619
+ }, [content]);
620
+ const handleScrollButtonChange = reactExports.useCallback(
621
+ (node) => {
622
+ if (node && shouldRepositionRef.current === true) {
623
+ position();
624
+ focusSelectedItem?.();
625
+ shouldRepositionRef.current = false;
626
+ }
627
+ },
628
+ [position, focusSelectedItem]
629
+ );
630
+ return /* @__PURE__ */ jsxRuntimeExports.jsx(
631
+ SelectViewportProvider,
632
+ {
633
+ scope: __scopeSelect,
634
+ contentWrapper,
635
+ shouldExpandOnScrollRef,
636
+ onScrollButtonChange: handleScrollButtonChange,
637
+ children: /* @__PURE__ */ jsxRuntimeExports.jsx(
638
+ "div",
639
+ {
640
+ ref: setContentWrapper,
641
+ style: {
642
+ display: "flex",
643
+ flexDirection: "column",
644
+ position: "fixed",
645
+ zIndex: contentZIndex
646
+ },
647
+ children: /* @__PURE__ */ jsxRuntimeExports.jsx(
648
+ Primitive.div,
649
+ {
650
+ ...popperProps,
651
+ ref: composedRefs,
652
+ style: {
653
+ // When we get the height of the content, it includes borders. If we were to set
654
+ // the height without having `boxSizing: 'border-box'` it would be too big.
655
+ boxSizing: "border-box",
656
+ // We need to ensure the content doesn't get taller than the wrapper
657
+ maxHeight: "100%",
658
+ ...popperProps.style
659
+ }
660
+ }
661
+ )
662
+ }
663
+ )
664
+ }
665
+ );
666
+ });
667
+ SelectItemAlignedPosition.displayName = ITEM_ALIGNED_POSITION_NAME;
668
+ var POPPER_POSITION_NAME = "SelectPopperPosition";
669
+ var SelectPopperPosition = reactExports.forwardRef((props, forwardedRef) => {
670
+ const {
671
+ __scopeSelect,
672
+ align = "start",
673
+ collisionPadding = CONTENT_MARGIN,
674
+ ...popperProps
675
+ } = props;
676
+ const popperScope = usePopperScope(__scopeSelect);
677
+ return /* @__PURE__ */ jsxRuntimeExports.jsx(
678
+ Content,
679
+ {
680
+ ...popperScope,
681
+ ...popperProps,
682
+ ref: forwardedRef,
683
+ align,
684
+ collisionPadding,
685
+ style: {
686
+ // Ensure border-box for floating-ui calculations
687
+ boxSizing: "border-box",
688
+ ...popperProps.style,
689
+ // re-namespace exposed content custom properties
690
+ ...{
691
+ "--radix-select-content-transform-origin": "var(--radix-popper-transform-origin)",
692
+ "--radix-select-content-available-width": "var(--radix-popper-available-width)",
693
+ "--radix-select-content-available-height": "var(--radix-popper-available-height)",
694
+ "--radix-select-trigger-width": "var(--radix-popper-anchor-width)",
695
+ "--radix-select-trigger-height": "var(--radix-popper-anchor-height)"
696
+ }
697
+ }
698
+ }
699
+ );
700
+ });
701
+ SelectPopperPosition.displayName = POPPER_POSITION_NAME;
702
+ var [SelectViewportProvider, useSelectViewportContext] = createSelectContext(CONTENT_NAME, {});
703
+ var VIEWPORT_NAME = "SelectViewport";
704
+ var SelectViewport = reactExports.forwardRef(
705
+ (props, forwardedRef) => {
706
+ const { __scopeSelect, nonce, ...viewportProps } = props;
707
+ const contentContext = useSelectContentContext(VIEWPORT_NAME, __scopeSelect);
708
+ const viewportContext = useSelectViewportContext(VIEWPORT_NAME, __scopeSelect);
709
+ const composedRefs = useComposedRefs(forwardedRef, contentContext.onViewportChange);
710
+ const prevScrollTopRef = reactExports.useRef(0);
711
+ return /* @__PURE__ */ jsxRuntimeExports.jsxs(jsxRuntimeExports.Fragment, { children: [
712
+ /* @__PURE__ */ jsxRuntimeExports.jsx(
713
+ "style",
714
+ {
715
+ dangerouslySetInnerHTML: {
716
+ __html: `[data-radix-select-viewport]{scrollbar-width:none;-ms-overflow-style:none;-webkit-overflow-scrolling:touch;}[data-radix-select-viewport]::-webkit-scrollbar{display:none}`
717
+ },
718
+ nonce
719
+ }
720
+ ),
721
+ /* @__PURE__ */ jsxRuntimeExports.jsx(Collection.Slot, { scope: __scopeSelect, children: /* @__PURE__ */ jsxRuntimeExports.jsx(
722
+ Primitive.div,
723
+ {
724
+ "data-radix-select-viewport": "",
725
+ role: "presentation",
726
+ ...viewportProps,
727
+ ref: composedRefs,
728
+ style: {
729
+ // we use position: 'relative' here on the `viewport` so that when we call
730
+ // `selectedItem.offsetTop` in calculations, the offset is relative to the viewport
731
+ // (independent of the scrollUpButton).
732
+ position: "relative",
733
+ flex: 1,
734
+ // Viewport should only be scrollable in the vertical direction.
735
+ // This won't work in vertical writing modes, so we'll need to
736
+ // revisit this if/when that is supported
737
+ // https://developer.chrome.com/blog/vertical-form-controls
738
+ overflow: "hidden auto",
739
+ ...viewportProps.style
740
+ },
741
+ onScroll: composeEventHandlers(viewportProps.onScroll, (event) => {
742
+ const viewport = event.currentTarget;
743
+ const { contentWrapper, shouldExpandOnScrollRef } = viewportContext;
744
+ if (shouldExpandOnScrollRef?.current && contentWrapper) {
745
+ const scrolledBy = Math.abs(prevScrollTopRef.current - viewport.scrollTop);
746
+ if (scrolledBy > 0) {
747
+ const availableHeight = window.innerHeight - CONTENT_MARGIN * 2;
748
+ const cssMinHeight = parseFloat(contentWrapper.style.minHeight);
749
+ const cssHeight = parseFloat(contentWrapper.style.height);
750
+ const prevHeight = Math.max(cssMinHeight, cssHeight);
751
+ if (prevHeight < availableHeight) {
752
+ const nextHeight = prevHeight + scrolledBy;
753
+ const clampedNextHeight = Math.min(availableHeight, nextHeight);
754
+ const heightDiff = nextHeight - clampedNextHeight;
755
+ contentWrapper.style.height = clampedNextHeight + "px";
756
+ if (contentWrapper.style.bottom === "0px") {
757
+ viewport.scrollTop = heightDiff > 0 ? heightDiff : 0;
758
+ contentWrapper.style.justifyContent = "flex-end";
759
+ }
760
+ }
761
+ }
762
+ }
763
+ prevScrollTopRef.current = viewport.scrollTop;
764
+ })
765
+ }
766
+ ) })
767
+ ] });
768
+ }
769
+ );
770
+ SelectViewport.displayName = VIEWPORT_NAME;
771
+ var GROUP_NAME = "SelectGroup";
772
+ var [SelectGroupContextProvider, useSelectGroupContext] = createSelectContext(GROUP_NAME);
773
+ var SelectGroup = reactExports.forwardRef(
774
+ (props, forwardedRef) => {
775
+ const { __scopeSelect, ...groupProps } = props;
776
+ const groupId = useId();
777
+ return /* @__PURE__ */ jsxRuntimeExports.jsx(SelectGroupContextProvider, { scope: __scopeSelect, id: groupId, children: /* @__PURE__ */ jsxRuntimeExports.jsx(Primitive.div, { role: "group", "aria-labelledby": groupId, ...groupProps, ref: forwardedRef }) });
778
+ }
779
+ );
780
+ SelectGroup.displayName = GROUP_NAME;
781
+ var LABEL_NAME = "SelectLabel";
782
+ var SelectLabel = reactExports.forwardRef(
783
+ (props, forwardedRef) => {
784
+ const { __scopeSelect, ...labelProps } = props;
785
+ const groupContext = useSelectGroupContext(LABEL_NAME, __scopeSelect);
786
+ return /* @__PURE__ */ jsxRuntimeExports.jsx(Primitive.div, { id: groupContext.id, ...labelProps, ref: forwardedRef });
787
+ }
788
+ );
789
+ SelectLabel.displayName = LABEL_NAME;
790
+ var ITEM_NAME = "SelectItem";
791
+ var [SelectItemContextProvider, useSelectItemContext] = createSelectContext(ITEM_NAME);
792
+ var SelectItem = reactExports.forwardRef(
793
+ (props, forwardedRef) => {
794
+ const {
795
+ __scopeSelect,
796
+ value,
797
+ disabled = false,
798
+ textValue: textValueProp,
799
+ ...itemProps
800
+ } = props;
801
+ const context = useSelectContext(ITEM_NAME, __scopeSelect);
802
+ const contentContext = useSelectContentContext(ITEM_NAME, __scopeSelect);
803
+ const isSelected = context.value === value;
804
+ const [textValue, setTextValue] = reactExports.useState(textValueProp ?? "");
805
+ const [isFocused, setIsFocused] = reactExports.useState(false);
806
+ const composedRefs = useComposedRefs(
807
+ forwardedRef,
808
+ (node) => contentContext.itemRefCallback?.(node, value, disabled)
809
+ );
810
+ const textId = useId();
811
+ const pointerTypeRef = reactExports.useRef("touch");
812
+ const handleSelect = () => {
813
+ if (!disabled) {
814
+ context.onValueChange(value);
815
+ context.onOpenChange(false);
816
+ }
817
+ };
818
+ if (value === "") {
819
+ throw new Error(
820
+ "A <Select.Item /> must have a value prop that is not an empty string. This is because the Select value can be set to an empty string to clear the selection and show the placeholder."
821
+ );
822
+ }
823
+ return /* @__PURE__ */ jsxRuntimeExports.jsx(
824
+ SelectItemContextProvider,
825
+ {
826
+ scope: __scopeSelect,
827
+ value,
828
+ disabled,
829
+ textId,
830
+ isSelected,
831
+ onItemTextChange: reactExports.useCallback((node) => {
832
+ setTextValue((prevTextValue) => prevTextValue || (node?.textContent ?? "").trim());
833
+ }, []),
834
+ children: /* @__PURE__ */ jsxRuntimeExports.jsx(
835
+ Collection.ItemSlot,
836
+ {
837
+ scope: __scopeSelect,
838
+ value,
839
+ disabled,
840
+ textValue,
841
+ children: /* @__PURE__ */ jsxRuntimeExports.jsx(
842
+ Primitive.div,
843
+ {
844
+ role: "option",
845
+ "aria-labelledby": textId,
846
+ "data-highlighted": isFocused ? "" : void 0,
847
+ "aria-selected": isSelected && isFocused,
848
+ "data-state": isSelected ? "checked" : "unchecked",
849
+ "aria-disabled": disabled || void 0,
850
+ "data-disabled": disabled ? "" : void 0,
851
+ tabIndex: disabled ? void 0 : -1,
852
+ ...itemProps,
853
+ ref: composedRefs,
854
+ onFocus: composeEventHandlers(itemProps.onFocus, () => setIsFocused(true)),
855
+ onBlur: composeEventHandlers(itemProps.onBlur, () => setIsFocused(false)),
856
+ onClick: composeEventHandlers(itemProps.onClick, () => {
857
+ if (pointerTypeRef.current !== "mouse") handleSelect();
858
+ }),
859
+ onPointerUp: composeEventHandlers(itemProps.onPointerUp, () => {
860
+ if (pointerTypeRef.current === "mouse") handleSelect();
861
+ }),
862
+ onPointerDown: composeEventHandlers(itemProps.onPointerDown, (event) => {
863
+ pointerTypeRef.current = event.pointerType;
864
+ }),
865
+ onPointerMove: composeEventHandlers(itemProps.onPointerMove, (event) => {
866
+ pointerTypeRef.current = event.pointerType;
867
+ if (disabled) {
868
+ contentContext.onItemLeave?.();
869
+ } else if (pointerTypeRef.current === "mouse") {
870
+ event.currentTarget.focus({ preventScroll: true });
871
+ }
872
+ }),
873
+ onPointerLeave: composeEventHandlers(itemProps.onPointerLeave, (event) => {
874
+ if (event.currentTarget === document.activeElement) {
875
+ contentContext.onItemLeave?.();
876
+ }
877
+ }),
878
+ onKeyDown: composeEventHandlers(itemProps.onKeyDown, (event) => {
879
+ const isTypingAhead = contentContext.searchRef?.current !== "";
880
+ if (isTypingAhead && event.key === " ") return;
881
+ if (SELECTION_KEYS.includes(event.key)) handleSelect();
882
+ if (event.key === " ") event.preventDefault();
883
+ })
884
+ }
885
+ )
886
+ }
887
+ )
888
+ }
889
+ );
890
+ }
891
+ );
892
+ SelectItem.displayName = ITEM_NAME;
893
+ var ITEM_TEXT_NAME = "SelectItemText";
894
+ var SelectItemText = reactExports.forwardRef(
895
+ (props, forwardedRef) => {
896
+ const { __scopeSelect, className, style, ...itemTextProps } = props;
897
+ const context = useSelectContext(ITEM_TEXT_NAME, __scopeSelect);
898
+ const contentContext = useSelectContentContext(ITEM_TEXT_NAME, __scopeSelect);
899
+ const itemContext = useSelectItemContext(ITEM_TEXT_NAME, __scopeSelect);
900
+ const nativeOptionsContext = useSelectNativeOptionsContext(ITEM_TEXT_NAME, __scopeSelect);
901
+ const [itemTextNode, setItemTextNode] = reactExports.useState(null);
902
+ const composedRefs = useComposedRefs(
903
+ forwardedRef,
904
+ (node) => setItemTextNode(node),
905
+ itemContext.onItemTextChange,
906
+ (node) => contentContext.itemTextRefCallback?.(node, itemContext.value, itemContext.disabled)
907
+ );
908
+ const textContent = itemTextNode?.textContent;
909
+ const nativeOption = reactExports.useMemo(
910
+ () => /* @__PURE__ */ jsxRuntimeExports.jsx("option", { value: itemContext.value, disabled: itemContext.disabled, children: textContent }, itemContext.value),
911
+ [itemContext.disabled, itemContext.value, textContent]
912
+ );
913
+ const { onNativeOptionAdd, onNativeOptionRemove } = nativeOptionsContext;
914
+ useLayoutEffect2(() => {
915
+ onNativeOptionAdd(nativeOption);
916
+ return () => onNativeOptionRemove(nativeOption);
917
+ }, [onNativeOptionAdd, onNativeOptionRemove, nativeOption]);
918
+ return /* @__PURE__ */ jsxRuntimeExports.jsxs(jsxRuntimeExports.Fragment, { children: [
919
+ /* @__PURE__ */ jsxRuntimeExports.jsx(Primitive.span, { id: itemContext.textId, ...itemTextProps, ref: composedRefs }),
920
+ itemContext.isSelected && context.valueNode && !context.valueNodeHasChildren ? reactDomExports.createPortal(itemTextProps.children, context.valueNode) : null
921
+ ] });
922
+ }
923
+ );
924
+ SelectItemText.displayName = ITEM_TEXT_NAME;
925
+ var ITEM_INDICATOR_NAME = "SelectItemIndicator";
926
+ var SelectItemIndicator = reactExports.forwardRef(
927
+ (props, forwardedRef) => {
928
+ const { __scopeSelect, ...itemIndicatorProps } = props;
929
+ const itemContext = useSelectItemContext(ITEM_INDICATOR_NAME, __scopeSelect);
930
+ return itemContext.isSelected ? /* @__PURE__ */ jsxRuntimeExports.jsx(Primitive.span, { "aria-hidden": true, ...itemIndicatorProps, ref: forwardedRef }) : null;
931
+ }
932
+ );
933
+ SelectItemIndicator.displayName = ITEM_INDICATOR_NAME;
934
+ var SCROLL_UP_BUTTON_NAME = "SelectScrollUpButton";
935
+ var SelectScrollUpButton = reactExports.forwardRef((props, forwardedRef) => {
936
+ const contentContext = useSelectContentContext(SCROLL_UP_BUTTON_NAME, props.__scopeSelect);
937
+ const viewportContext = useSelectViewportContext(SCROLL_UP_BUTTON_NAME, props.__scopeSelect);
938
+ const [canScrollUp, setCanScrollUp] = reactExports.useState(false);
939
+ const composedRefs = useComposedRefs(forwardedRef, viewportContext.onScrollButtonChange);
940
+ useLayoutEffect2(() => {
941
+ if (contentContext.viewport && contentContext.isPositioned) {
942
+ let handleScroll2 = function() {
943
+ const canScrollUp2 = viewport.scrollTop > 0;
944
+ setCanScrollUp(canScrollUp2);
945
+ };
946
+ const viewport = contentContext.viewport;
947
+ handleScroll2();
948
+ viewport.addEventListener("scroll", handleScroll2);
949
+ return () => viewport.removeEventListener("scroll", handleScroll2);
950
+ }
951
+ }, [contentContext.viewport, contentContext.isPositioned]);
952
+ return canScrollUp ? /* @__PURE__ */ jsxRuntimeExports.jsx(
953
+ SelectScrollButtonImpl,
954
+ {
955
+ ...props,
956
+ ref: composedRefs,
957
+ onAutoScroll: () => {
958
+ const { viewport, selectedItem } = contentContext;
959
+ if (viewport && selectedItem) {
960
+ viewport.scrollTop = viewport.scrollTop - selectedItem.offsetHeight;
961
+ }
962
+ }
963
+ }
964
+ ) : null;
965
+ });
966
+ SelectScrollUpButton.displayName = SCROLL_UP_BUTTON_NAME;
967
+ var SCROLL_DOWN_BUTTON_NAME = "SelectScrollDownButton";
968
+ var SelectScrollDownButton = reactExports.forwardRef((props, forwardedRef) => {
969
+ const contentContext = useSelectContentContext(SCROLL_DOWN_BUTTON_NAME, props.__scopeSelect);
970
+ const viewportContext = useSelectViewportContext(SCROLL_DOWN_BUTTON_NAME, props.__scopeSelect);
971
+ const [canScrollDown, setCanScrollDown] = reactExports.useState(false);
972
+ const composedRefs = useComposedRefs(forwardedRef, viewportContext.onScrollButtonChange);
973
+ useLayoutEffect2(() => {
974
+ if (contentContext.viewport && contentContext.isPositioned) {
975
+ let handleScroll2 = function() {
976
+ const maxScroll = viewport.scrollHeight - viewport.clientHeight;
977
+ const canScrollDown2 = Math.ceil(viewport.scrollTop) < maxScroll;
978
+ setCanScrollDown(canScrollDown2);
979
+ };
980
+ const viewport = contentContext.viewport;
981
+ handleScroll2();
982
+ viewport.addEventListener("scroll", handleScroll2);
983
+ return () => viewport.removeEventListener("scroll", handleScroll2);
984
+ }
985
+ }, [contentContext.viewport, contentContext.isPositioned]);
986
+ return canScrollDown ? /* @__PURE__ */ jsxRuntimeExports.jsx(
987
+ SelectScrollButtonImpl,
988
+ {
989
+ ...props,
990
+ ref: composedRefs,
991
+ onAutoScroll: () => {
992
+ const { viewport, selectedItem } = contentContext;
993
+ if (viewport && selectedItem) {
994
+ viewport.scrollTop = viewport.scrollTop + selectedItem.offsetHeight;
995
+ }
996
+ }
997
+ }
998
+ ) : null;
999
+ });
1000
+ SelectScrollDownButton.displayName = SCROLL_DOWN_BUTTON_NAME;
1001
+ var SelectScrollButtonImpl = reactExports.forwardRef((props, forwardedRef) => {
1002
+ const { __scopeSelect, onAutoScroll, ...scrollIndicatorProps } = props;
1003
+ const contentContext = useSelectContentContext("SelectScrollButton", __scopeSelect);
1004
+ const autoScrollTimerRef = reactExports.useRef(null);
1005
+ const getItems = useCollection(__scopeSelect);
1006
+ const clearAutoScrollTimer = reactExports.useCallback(() => {
1007
+ if (autoScrollTimerRef.current !== null) {
1008
+ window.clearInterval(autoScrollTimerRef.current);
1009
+ autoScrollTimerRef.current = null;
1010
+ }
1011
+ }, []);
1012
+ reactExports.useEffect(() => {
1013
+ return () => clearAutoScrollTimer();
1014
+ }, [clearAutoScrollTimer]);
1015
+ useLayoutEffect2(() => {
1016
+ const activeItem = getItems().find((item) => item.ref.current === document.activeElement);
1017
+ activeItem?.ref.current?.scrollIntoView({ block: "nearest" });
1018
+ }, [getItems]);
1019
+ return /* @__PURE__ */ jsxRuntimeExports.jsx(
1020
+ Primitive.div,
1021
+ {
1022
+ "aria-hidden": true,
1023
+ ...scrollIndicatorProps,
1024
+ ref: forwardedRef,
1025
+ style: { flexShrink: 0, ...scrollIndicatorProps.style },
1026
+ onPointerDown: composeEventHandlers(scrollIndicatorProps.onPointerDown, () => {
1027
+ if (autoScrollTimerRef.current === null) {
1028
+ autoScrollTimerRef.current = window.setInterval(onAutoScroll, 50);
1029
+ }
1030
+ }),
1031
+ onPointerMove: composeEventHandlers(scrollIndicatorProps.onPointerMove, () => {
1032
+ contentContext.onItemLeave?.();
1033
+ if (autoScrollTimerRef.current === null) {
1034
+ autoScrollTimerRef.current = window.setInterval(onAutoScroll, 50);
1035
+ }
1036
+ }),
1037
+ onPointerLeave: composeEventHandlers(scrollIndicatorProps.onPointerLeave, () => {
1038
+ clearAutoScrollTimer();
1039
+ })
1040
+ }
1041
+ );
1042
+ });
1043
+ var SEPARATOR_NAME = "SelectSeparator";
1044
+ var SelectSeparator = reactExports.forwardRef(
1045
+ (props, forwardedRef) => {
1046
+ const { __scopeSelect, ...separatorProps } = props;
1047
+ return /* @__PURE__ */ jsxRuntimeExports.jsx(Primitive.div, { "aria-hidden": true, ...separatorProps, ref: forwardedRef });
1048
+ }
1049
+ );
1050
+ SelectSeparator.displayName = SEPARATOR_NAME;
1051
+ var ARROW_NAME = "SelectArrow";
1052
+ var SelectArrow = reactExports.forwardRef(
1053
+ (props, forwardedRef) => {
1054
+ const { __scopeSelect, ...arrowProps } = props;
1055
+ const popperScope = usePopperScope(__scopeSelect);
1056
+ const context = useSelectContext(ARROW_NAME, __scopeSelect);
1057
+ const contentContext = useSelectContentContext(ARROW_NAME, __scopeSelect);
1058
+ return context.open && contentContext.position === "popper" ? /* @__PURE__ */ jsxRuntimeExports.jsx(Arrow, { ...popperScope, ...arrowProps, ref: forwardedRef }) : null;
1059
+ }
1060
+ );
1061
+ SelectArrow.displayName = ARROW_NAME;
1062
+ var BUBBLE_INPUT_NAME = "SelectBubbleInput";
1063
+ var SelectBubbleInput = reactExports.forwardRef(
1064
+ ({ __scopeSelect, value, ...props }, forwardedRef) => {
1065
+ const ref = reactExports.useRef(null);
1066
+ const composedRefs = useComposedRefs(forwardedRef, ref);
1067
+ const prevValue = usePrevious(value);
1068
+ reactExports.useEffect(() => {
1069
+ const select = ref.current;
1070
+ if (!select) return;
1071
+ const selectProto = window.HTMLSelectElement.prototype;
1072
+ const descriptor = Object.getOwnPropertyDescriptor(
1073
+ selectProto,
1074
+ "value"
1075
+ );
1076
+ const setValue = descriptor.set;
1077
+ if (prevValue !== value && setValue) {
1078
+ const event = new Event("change", { bubbles: true });
1079
+ setValue.call(select, value);
1080
+ select.dispatchEvent(event);
1081
+ }
1082
+ }, [prevValue, value]);
1083
+ return /* @__PURE__ */ jsxRuntimeExports.jsx(
1084
+ Primitive.select,
1085
+ {
1086
+ ...props,
1087
+ style: { ...VISUALLY_HIDDEN_STYLES, ...props.style },
1088
+ ref: composedRefs,
1089
+ defaultValue: value
1090
+ }
1091
+ );
1092
+ }
1093
+ );
1094
+ SelectBubbleInput.displayName = BUBBLE_INPUT_NAME;
1095
+ function shouldShowPlaceholder(value) {
1096
+ return value === "" || value === void 0;
1097
+ }
1098
+ function useTypeaheadSearch(onSearchChange) {
1099
+ const handleSearchChange = useCallbackRef(onSearchChange);
1100
+ const searchRef = reactExports.useRef("");
1101
+ const timerRef = reactExports.useRef(0);
1102
+ const handleTypeaheadSearch = reactExports.useCallback(
1103
+ (key) => {
1104
+ const search = searchRef.current + key;
1105
+ handleSearchChange(search);
1106
+ (function updateSearch(value) {
1107
+ searchRef.current = value;
1108
+ window.clearTimeout(timerRef.current);
1109
+ if (value !== "") timerRef.current = window.setTimeout(() => updateSearch(""), 1e3);
1110
+ })(search);
1111
+ },
1112
+ [handleSearchChange]
1113
+ );
1114
+ const resetTypeahead = reactExports.useCallback(() => {
1115
+ searchRef.current = "";
1116
+ window.clearTimeout(timerRef.current);
1117
+ }, []);
1118
+ reactExports.useEffect(() => {
1119
+ return () => window.clearTimeout(timerRef.current);
1120
+ }, []);
1121
+ return [searchRef, handleTypeaheadSearch, resetTypeahead];
1122
+ }
1123
+ function findNextItem(items, search, currentItem) {
1124
+ const isRepeated = search.length > 1 && Array.from(search).every((char) => char === search[0]);
1125
+ const normalizedSearch = isRepeated ? search[0] : search;
1126
+ const currentItemIndex = currentItem ? items.indexOf(currentItem) : -1;
1127
+ let wrappedItems = wrapArray(items, Math.max(currentItemIndex, 0));
1128
+ const excludeCurrentItem = normalizedSearch.length === 1;
1129
+ if (excludeCurrentItem) wrappedItems = wrappedItems.filter((v) => v !== currentItem);
1130
+ const nextItem = wrappedItems.find(
1131
+ (item) => item.textValue.toLowerCase().startsWith(normalizedSearch.toLowerCase())
1132
+ );
1133
+ return nextItem !== currentItem ? nextItem : void 0;
1134
+ }
1135
+ function wrapArray(array, startIndex) {
1136
+ return array.map((_, index) => array[(startIndex + index) % array.length]);
1137
+ }
1138
+ var Root2 = Select;
1139
+ var Trigger = SelectTrigger;
1140
+ var Value = SelectValue;
1141
+ var Icon = SelectIcon;
1142
+ var Portal = SelectPortal;
1143
+ var Content2 = SelectContent;
1144
+ var Viewport = SelectViewport;
1145
+ var Item = SelectItem;
1146
+ var ItemText = SelectItemText;
1147
+ var ItemIndicator = SelectItemIndicator;
1148
+ var ScrollUpButton = SelectScrollUpButton;
1149
+ var ScrollDownButton = SelectScrollDownButton;
1150
+ export {
1151
+ Content2 as C,
1152
+ Icon as I,
1153
+ Portal as P,
1154
+ Root2 as R,
1155
+ ScrollUpButton as S,
1156
+ Trigger as T,
1157
+ Value as V,
1158
+ Viewport as a,
1159
+ Item as b,
1160
+ ItemIndicator as c,
1161
+ ItemText as d,
1162
+ ScrollDownButton as e
1163
+ };