@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,190 @@
1
+ import { useCallback, useEffect } from "react";
2
+
3
+ const NAV_ATTR = "data-nav-id";
4
+ const NAV_ACTION_ATTR = "data-nav-action";
5
+
6
+ export type NavAction = "toggle" | "expand" | "collapse";
7
+
8
+ function findNavItems(container: HTMLElement): HTMLElement[] {
9
+ return Array.from(container.querySelectorAll<HTMLElement>(`[${NAV_ATTR}]`));
10
+ }
11
+
12
+ function isFocusTarget(node: EventTarget | null): node is HTMLElement {
13
+ return node instanceof HTMLElement;
14
+ }
15
+
16
+ function findClosestNavItem(target: HTMLElement, container: HTMLElement): HTMLElement | null {
17
+ let el: HTMLElement | null = target;
18
+ while (el !== null && el !== container) {
19
+ if (el.hasAttribute(NAV_ATTR)) return el;
20
+ el = el.parentElement;
21
+ }
22
+ if (target.hasAttribute(NAV_ATTR)) return target;
23
+ return null;
24
+ }
25
+
26
+ function getAction(el: HTMLElement): NavAction | null {
27
+ const val = el.getAttribute(NAV_ACTION_ATTR);
28
+ if (val === "toggle" || val === "expand" || val === "collapse") return val;
29
+ return null;
30
+ }
31
+
32
+ function focusAndScroll(el: HTMLElement): void {
33
+ el.focus({ preventScroll: true });
34
+ el.scrollIntoView({ block: "nearest", behavior: "smooth" });
35
+ }
36
+
37
+ function safeItemAt(items: HTMLElement[], index: number): HTMLElement | null {
38
+ const el = items[index];
39
+ return el ?? null;
40
+ }
41
+
42
+ function isEditableTarget(target: HTMLElement): boolean {
43
+ const tag = target.tagName;
44
+ if (tag === "INPUT" || tag === "TEXTAREA") return true;
45
+ if (target.isContentEditable) return true;
46
+ return false;
47
+ }
48
+
49
+ /**
50
+ * Enables keyboard navigation within a log-list container.
51
+ *
52
+ * Navigation keys:
53
+ * - ArrowUp / Shift+W : previous item
54
+ * - ArrowDown / Shift+S : next item
55
+ * - ArrowLeft / Shift+A : collapse or move to prev item
56
+ * - ArrowRight / Shift+D : expand or move to next item
57
+ * - Space : toggle expand/collapse
58
+ *
59
+ * Attach `data-nav-id` to any focusable navigation item.
60
+ * Attach `data-nav-action` ("toggle" | "expand" | "collapse") for items
61
+ * that support expand/collapse.
62
+ */
63
+ export function useKeyboardNavigation(
64
+ /** Ref to the inner container that holds all nav items. */
65
+ containerRef: React.RefObject<HTMLElement | null>,
66
+ /** Ref to the outer focus-receiving wrapper (the one with tabIndex).
67
+ * Defaults to `containerRef` when omitted. */
68
+ wrapperRef?: React.RefObject<HTMLElement | null>,
69
+ ): void {
70
+ const rootRef = wrapperRef ?? containerRef;
71
+
72
+ const handleFocusContainer = useCallback(
73
+ (e: FocusEvent) => {
74
+ const container = containerRef.current;
75
+ if (!container) return;
76
+ const target = e.target;
77
+ if (!isFocusTarget(target)) return;
78
+ if (target !== rootRef.current) return;
79
+ if (!container.contains(target)) return;
80
+ const items = findNavItems(container);
81
+ const first = safeItemAt(items, 0);
82
+ if (first !== null) focusAndScroll(first);
83
+ },
84
+ [containerRef, rootRef],
85
+ );
86
+
87
+ useEffect(() => {
88
+ const root = rootRef.current;
89
+ const container = containerRef.current;
90
+ if (!root || !container) return;
91
+
92
+ const handleKeyDown = (e: KeyboardEvent) => {
93
+ const target = e.target;
94
+ if (!isFocusTarget(target)) return;
95
+
96
+ if (!container.contains(target)) return;
97
+
98
+ if (isEditableTarget(target)) return;
99
+
100
+ const items = findNavItems(container);
101
+ if (items.length === 0) return;
102
+
103
+ const current = findClosestNavItem(target, container);
104
+ const currentIdx = current !== null ? items.indexOf(current) : -1;
105
+
106
+ let handled = false;
107
+
108
+ switch (e.key) {
109
+ case "ArrowUp":
110
+ case "W": {
111
+ if (e.key === "W" && !e.shiftKey) break;
112
+ e.preventDefault();
113
+ const prevIdx =
114
+ currentIdx > 0 ? currentIdx - 1 : currentIdx === -1 ? items.length - 1 : -1;
115
+ if (prevIdx !== -1) {
116
+ const prev = safeItemAt(items, prevIdx);
117
+ if (prev !== null) focusAndScroll(prev);
118
+ }
119
+ handled = true;
120
+ break;
121
+ }
122
+ case "ArrowDown":
123
+ case "S": {
124
+ if (e.key === "S" && !e.shiftKey) break;
125
+ e.preventDefault();
126
+ const nextIdx =
127
+ currentIdx < items.length - 1 ? currentIdx + 1 : currentIdx === -1 ? 0 : -1;
128
+ if (nextIdx !== -1) {
129
+ const next = safeItemAt(items, nextIdx);
130
+ if (next !== null) focusAndScroll(next);
131
+ }
132
+ handled = true;
133
+ break;
134
+ }
135
+ case "ArrowLeft":
136
+ case "A": {
137
+ if (e.key === "A" && !e.shiftKey) break;
138
+ if (current === null) break;
139
+ e.preventDefault();
140
+ const action = getAction(current);
141
+ if (action === "collapse") {
142
+ current.click();
143
+ } else if (currentIdx > 0) {
144
+ const prev = safeItemAt(items, currentIdx - 1);
145
+ if (prev !== null) focusAndScroll(prev);
146
+ }
147
+ handled = true;
148
+ break;
149
+ }
150
+ case "ArrowRight":
151
+ case "D": {
152
+ if (e.key === "D" && !e.shiftKey) break;
153
+ if (current === null) break;
154
+ e.preventDefault();
155
+ const action = getAction(current);
156
+ if (action === "expand") {
157
+ current.click();
158
+ } else if (currentIdx < items.length - 1) {
159
+ const next = safeItemAt(items, currentIdx + 1);
160
+ if (next !== null) focusAndScroll(next);
161
+ }
162
+ handled = true;
163
+ break;
164
+ }
165
+ case " ": {
166
+ if (current === null) break;
167
+ e.preventDefault();
168
+ const action = getAction(current);
169
+ if (action !== null) current.click();
170
+ handled = true;
171
+ break;
172
+ }
173
+ }
174
+
175
+ if (handled) {
176
+ e.stopPropagation();
177
+ }
178
+ };
179
+
180
+ document.addEventListener("keydown", handleKeyDown, { capture: true });
181
+ return () => document.removeEventListener("keydown", handleKeyDown, { capture: true });
182
+ }, [containerRef, rootRef]);
183
+
184
+ useEffect(() => {
185
+ const root = rootRef.current;
186
+ if (!root) return;
187
+ root.addEventListener("focus", handleFocusContainer);
188
+ return () => root.removeEventListener("focus", handleFocusContainer);
189
+ }, [handleFocusContainer, rootRef]);
190
+ }
@@ -0,0 +1,66 @@
1
+ import { extractStopReason, isTurnBoundary, type StopReason } from "../../lib/stopReason";
2
+ import type { CapturedLog } from "../../proxy/schemas";
3
+ import { resolveLogFormat } from "./log-formats";
4
+
5
+ export type TurnEntry = {
6
+ log: CapturedLog;
7
+ stopReason: StopReason;
8
+ };
9
+
10
+ export type TurnGroupData = {
11
+ entries: TurnEntry[];
12
+ turnIndex: number;
13
+ };
14
+
15
+ type ConversationLike = {
16
+ logs: CapturedLog[];
17
+ };
18
+
19
+ export function shouldRenderConversationContent(standalone: boolean, expanded: boolean): boolean {
20
+ return standalone || expanded;
21
+ }
22
+
23
+ export function isTurnCollapsible(
24
+ entryCount: number,
25
+ isComplete: boolean,
26
+ isPending: boolean,
27
+ ): boolean {
28
+ return entryCount > 1 && isComplete && !isPending;
29
+ }
30
+
31
+ export function buildTurnGroups(logs: CapturedLog[]): TurnGroupData[] {
32
+ const groups: TurnGroupData[] = [];
33
+ let entries: TurnEntry[] = [];
34
+ let turnIndex = 0;
35
+
36
+ for (const log of logs) {
37
+ entries.push({ log, stopReason: extractStopReason(log) });
38
+ const current = entries[entries.length - 1];
39
+ if (current !== undefined && isTurnBoundary(current.stopReason)) {
40
+ groups.push({ entries, turnIndex });
41
+ entries = [];
42
+ turnIndex += 1;
43
+ }
44
+ }
45
+
46
+ if (entries.length > 0) groups.push({ entries, turnIndex });
47
+ return groups;
48
+ }
49
+
50
+ export function buildValidPredecessors(groups: ConversationLike[]): Map<number, CapturedLog> {
51
+ const predecessors = new Map<number, CapturedLog>();
52
+
53
+ for (const group of groups) {
54
+ for (let index = 1; index < group.logs.length; index += 1) {
55
+ const current = group.logs[index];
56
+ const previous = group.logs[index - 1];
57
+ if (current === undefined || previous === undefined) continue;
58
+ const currentFormat = resolveLogFormat(current);
59
+ const previousFormat = resolveLogFormat(previous);
60
+ if (currentFormat === "unknown" || currentFormat !== previousFormat) continue;
61
+ predecessors.set(current.id, previous);
62
+ }
63
+ }
64
+
65
+ return predecessors;
66
+ }
@@ -0,0 +1,47 @@
1
+ import { cva, type VariantProps } from "class-variance-authority";
2
+ import { Slot } from "radix-ui";
3
+ import * as React from "react";
4
+
5
+ import { cn } from "../../lib/utils";
6
+
7
+ const badgeVariants = cva(
8
+ "inline-flex items-center justify-center rounded-full border border-transparent px-2 py-0.5 text-xs font-medium w-fit whitespace-nowrap shrink-0 [&>svg]:size-3 gap-1 [&>svg]:pointer-events-none focus-visible:border-ring focus-visible:ring-ring/50 focus-visible:ring-[3px] aria-invalid:ring-destructive/20 dark:aria-invalid:ring-destructive/40 aria-invalid:border-destructive transition-[color,box-shadow] overflow-hidden",
9
+ {
10
+ variants: {
11
+ variant: {
12
+ default: "bg-primary text-primary-foreground [a&]:hover:bg-primary/90",
13
+ secondary: "bg-secondary text-secondary-foreground [a&]:hover:bg-secondary/90",
14
+ destructive:
15
+ "bg-destructive text-white [a&]:hover:bg-destructive/90 focus-visible:ring-destructive/20 dark:focus-visible:ring-destructive/40 dark:bg-destructive/60",
16
+ outline:
17
+ "border-border text-foreground [a&]:hover:bg-accent [a&]:hover:text-accent-foreground",
18
+ ghost: "[a&]:hover:bg-accent [a&]:hover:text-accent-foreground",
19
+ link: "text-primary underline-offset-4 [a&]:hover:underline",
20
+ },
21
+ },
22
+ defaultVariants: {
23
+ variant: "default",
24
+ },
25
+ },
26
+ );
27
+
28
+ function Badge({
29
+ className,
30
+ variant = "default",
31
+ asChild = false,
32
+ ...props
33
+ }: React.ComponentProps<"span"> &
34
+ VariantProps<typeof badgeVariants> & { asChild?: boolean }): React.JSX.Element {
35
+ const Comp = asChild ? Slot.Root : "span";
36
+
37
+ return (
38
+ <Comp
39
+ data-slot="badge"
40
+ data-variant={variant}
41
+ className={cn(badgeVariants({ variant }), className)}
42
+ {...props}
43
+ />
44
+ );
45
+ }
46
+
47
+ export { Badge, badgeVariants };
@@ -0,0 +1,47 @@
1
+ import { cva, type VariantProps } from "class-variance-authority";
2
+ import * as React from "react";
3
+
4
+ import { cn } from "../../lib/utils";
5
+
6
+ const buttonVariants = cva(
7
+ "inline-flex items-center justify-center gap-2 whitespace-nowrap rounded-md text-sm font-medium transition-colors focus-visible:border-ring focus-visible:ring-ring/50 focus-visible:outline-ring focus-visible:ring-[3px] disabled:pointer-events-none disabled:opacity-50 [&_svg]:pointer-events-none [&_svg]:shrink-0",
8
+ {
9
+ variants: {
10
+ variant: {
11
+ default: "bg-primary text-primary-foreground hover:bg-primary/90",
12
+ destructive: "bg-destructive text-white hover:bg-destructive/90",
13
+ outline: "border border-input bg-background hover:bg-accent hover:text-accent-foreground",
14
+ secondary: "bg-secondary text-secondary-foreground hover:bg-secondary/80",
15
+ ghost: "hover:bg-accent hover:text-accent-foreground",
16
+ link: "text-primary underline-offset-4 hover:underline",
17
+ },
18
+ size: {
19
+ default: "h-9 px-4 py-2",
20
+ sm: "h-8 rounded-md px-3 text-xs",
21
+ lg: "h-10 rounded-md px-8",
22
+ icon: "size-9",
23
+ },
24
+ },
25
+ defaultVariants: {
26
+ variant: "default",
27
+ size: "default",
28
+ },
29
+ },
30
+ );
31
+
32
+ function Button({
33
+ className,
34
+ variant,
35
+ size,
36
+ ...props
37
+ }: React.ComponentProps<"button"> & VariantProps<typeof buttonVariants>): React.JSX.Element {
38
+ return (
39
+ <button
40
+ data-slot="button"
41
+ className={cn(buttonVariants({ variant, size, className }))}
42
+ {...props}
43
+ />
44
+ );
45
+ }
46
+
47
+ export { Button, buttonVariants };
@@ -0,0 +1,21 @@
1
+ import { Collapsible as CollapsiblePrimitive } from "radix-ui";
2
+
3
+ function Collapsible({
4
+ ...props
5
+ }: React.ComponentProps<typeof CollapsiblePrimitive.Root>): React.JSX.Element {
6
+ return <CollapsiblePrimitive.Root data-slot="collapsible" {...props} />;
7
+ }
8
+
9
+ function CollapsibleTrigger({
10
+ ...props
11
+ }: React.ComponentProps<typeof CollapsiblePrimitive.CollapsibleTrigger>): React.JSX.Element {
12
+ return <CollapsiblePrimitive.CollapsibleTrigger data-slot="collapsible-trigger" {...props} />;
13
+ }
14
+
15
+ function CollapsibleContent({
16
+ ...props
17
+ }: React.ComponentProps<typeof CollapsiblePrimitive.CollapsibleContent>): React.JSX.Element {
18
+ return <CollapsiblePrimitive.CollapsibleContent data-slot="collapsible-content" {...props} />;
19
+ }
20
+
21
+ export { Collapsible, CollapsibleTrigger, CollapsibleContent };
@@ -0,0 +1,51 @@
1
+ import { type JSX } from "react";
2
+ import { Dialog, DialogContent, DialogHeader, DialogTitle } from "../ui/dialog";
3
+ import { Button } from "../ui/button";
4
+
5
+ export type ConfirmDialogVariant = "default" | "destructive";
6
+
7
+ export type ConfirmDialogProps = {
8
+ open: boolean;
9
+ onOpenChange: (open: boolean) => void;
10
+ title: string;
11
+ description: string;
12
+ confirmLabel?: string;
13
+ variant?: ConfirmDialogVariant;
14
+ onConfirm: () => void;
15
+ };
16
+
17
+ export function ConfirmDialog({
18
+ open,
19
+ onOpenChange,
20
+ title,
21
+ description,
22
+ confirmLabel = "Confirm",
23
+ variant = "default",
24
+ onConfirm,
25
+ }: ConfirmDialogProps): JSX.Element {
26
+ return (
27
+ <Dialog open={open} onOpenChange={onOpenChange}>
28
+ <DialogContent>
29
+ <DialogHeader>
30
+ <DialogTitle>{title}</DialogTitle>
31
+ </DialogHeader>
32
+ <p className="text-sm text-muted-foreground">{description}</p>
33
+ <div className="flex justify-end gap-2 pt-2">
34
+ <Button variant="outline" size="sm" onClick={() => onOpenChange(false)}>
35
+ Cancel
36
+ </Button>
37
+ <Button
38
+ variant={variant}
39
+ size="sm"
40
+ onClick={() => {
41
+ onConfirm();
42
+ onOpenChange(false);
43
+ }}
44
+ >
45
+ {confirmLabel}
46
+ </Button>
47
+ </div>
48
+ </DialogContent>
49
+ </Dialog>
50
+ );
51
+ }
@@ -0,0 +1,95 @@
1
+ import type { JSX } from "react";
2
+ import { cn } from "../../lib/utils";
3
+
4
+ /**
5
+ * Small inline-SVG crab mark used in the inspector header. Stroke-based so
6
+ * the colour follows `currentColor` — pair with a Tailwind text colour class
7
+ * (e.g. `text-amber-500`) to recolour without editing the SVG. Sized to
8
+ * match the title text by default; pass `className` to override.
9
+ *
10
+ * Plays on the project owner's `TonyClaw` handle and keeps the title bar
11
+ * visually distinct in the same way Claude Code's CLI uses a small
12
+ * block-cursor mark next to its name.
13
+ */
14
+ export function CrabLogo({ className }: { className?: string }): JSX.Element {
15
+ return (
16
+ <svg
17
+ viewBox="0 0 24 24"
18
+ fill="none"
19
+ stroke="currentColor"
20
+ strokeWidth="1.5"
21
+ strokeLinecap="round"
22
+ strokeLinejoin="round"
23
+ aria-hidden="true"
24
+ className={cn("inline-block size-5", className)}
25
+ >
26
+ {/* Body */}
27
+ <path d="M5 13 C5 9 8 7 12 7 C16 7 19 9 19 13 C19 16 16 18 12 18 C8 18 5 16 5 13 Z" />
28
+ {/* Left claw */}
29
+ <path d="M5 11 C3.5 9.5 1.5 10 2 12.5 C2.5 14 4 13.5 5 12.5" />
30
+ {/* Right claw */}
31
+ <path d="M19 11 C20.5 9.5 22.5 10 22 12.5 C21.5 14 20 13.5 19 12.5" />
32
+ {/* Eye stalks */}
33
+ <line x1="10" y1="7" x2="9.5" y2="5" />
34
+ <line x1="14" y1="7" x2="14.5" y2="5" />
35
+ {/* Eyes */}
36
+ <circle cx="9.5" cy="4.5" r="0.9" fill="currentColor" stroke="none" />
37
+ <circle cx="14.5" cy="4.5" r="0.9" fill="currentColor" stroke="none" />
38
+ {/* Legs */}
39
+ <line x1="6.5" y1="16" x2="4.5" y2="19.5" />
40
+ <line x1="9" y1="17.5" x2="8" y2="20.5" />
41
+ <line x1="15" y1="17.5" x2="16" y2="20.5" />
42
+ <line x1="17.5" y1="16" x2="19.5" y2="19.5" />
43
+ {/* Duanwu zongzi charms */}
44
+ <g>
45
+ <path
46
+ d="M5.6 17.7 L8.4 15.4 L10.8 18 C9.1 18.9 7.2 18.8 5.6 17.7 Z"
47
+ fill="#2f6b3f"
48
+ stroke="none"
49
+ opacity="0.95"
50
+ />
51
+ <path
52
+ d="M6.9 17.5 L8.4 16 L9.8 17.7 C8.9 18.1 7.8 18.1 6.9 17.5 Z"
53
+ fill="#6fb36f"
54
+ stroke="none"
55
+ opacity="0.95"
56
+ />
57
+ <path d="M8.4 16 L8.4 18.4" stroke="#d6b45f" strokeWidth="0.34" />
58
+ <circle cx="10.6" cy="17.75" r="0.36" fill="#c2412d" stroke="none" />
59
+ </g>
60
+ <g>
61
+ <path
62
+ d="M8 16.5 L11.9 13.6 L15.8 16.8 C13.3 18.4 10.4 18.3 8 16.5 Z"
63
+ fill="#2f6b3f"
64
+ stroke="none"
65
+ opacity="0.97"
66
+ />
67
+ <path
68
+ d="M9.8 16.3 L11.9 14.4 L14.3 16.5 C12.8 17.4 11.3 17.4 9.8 16.3 Z"
69
+ fill="#6fb36f"
70
+ stroke="none"
71
+ opacity="0.95"
72
+ />
73
+ <path d="M11.9 14.3 L11.9 17.8" stroke="#d6b45f" strokeWidth="0.42" />
74
+ <path d="M9.8 16.3 C11.2 15.8 12.9 15.9 14.3 16.5" stroke="#9fca78" strokeWidth="0.36" />
75
+ <circle cx="15.6" cy="16.75" r="0.43" fill="#c2412d" stroke="none" />
76
+ </g>
77
+ <g>
78
+ <path
79
+ d="M13.6 18.1 L16.2 15.7 L18.5 18.2 C17.1 19.1 15.2 19 13.6 18.1 Z"
80
+ fill="#2f6b3f"
81
+ stroke="none"
82
+ opacity="0.95"
83
+ />
84
+ <path
85
+ d="M14.8 17.9 L16.2 16.3 L17.5 18 C16.6 18.4 15.7 18.4 14.8 17.9 Z"
86
+ fill="#6fb36f"
87
+ stroke="none"
88
+ opacity="0.95"
89
+ />
90
+ <path d="M16.2 16.3 L16.2 18.6" stroke="#d6b45f" strokeWidth="0.34" />
91
+ <circle cx="18.35" cy="18.15" r="0.36" fill="#c2412d" stroke="none" />
92
+ </g>
93
+ </svg>
94
+ );
95
+ }