@brainfish-ai/devdoc 0.1.41 → 0.1.43

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/ai-agents/.claude/skills/bootstrap-docs/SKILL.md +710 -79
  2. package/ai-agents/.claude/skills/check-docs/SKILL.md +83 -8
  3. package/ai-agents/.claude/skills/create-doc/SKILL.md +267 -55
  4. package/ai-agents/.claude/skills/update-doc/SKILL.md +162 -63
  5. package/ai-agents/.cursor/rules/devdoc-bootstrap.mdc +145 -15
  6. package/ai-agents/.cursor/rules/devdoc-create.mdc +108 -57
  7. package/ai-agents/.cursor/rules/devdoc-update.mdc +93 -70
  8. package/ai-agents/.cursor/rules/devdoc.mdc +21 -0
  9. package/ai-agents/schemas/docs.schema.json +332 -0
  10. package/ai-agents/schemas/theme.schema.json +243 -0
  11. package/dist/cli/commands/create.js +4 -9
  12. package/dist/cli/commands/deploy.js +50 -25
  13. package/dist/cli/commands/dev.js +19 -10
  14. package/package.json +3 -2
  15. package/renderer/app/api/assets/[...path]/route.js +108 -0
  16. package/renderer/app/api/assets/route.js +114 -0
  17. package/renderer/app/api/assets/upload/route.js +163 -0
  18. package/renderer/app/api/auth-schemes/route.js +58 -0
  19. package/renderer/app/api/chat/route.js +759 -0
  20. package/renderer/app/api/codegen/route.js +52 -0
  21. package/renderer/app/api/collections/route.js +675 -0
  22. package/renderer/app/api/debug/route.js +47 -0
  23. package/renderer/app/api/deploy/route.js +199 -0
  24. package/renderer/app/api/device/route.js +36 -0
  25. package/renderer/app/api/docs/route.js +205 -0
  26. package/renderer/app/api/domains/add/route.js +121 -0
  27. package/renderer/app/api/domains/lookup/route.js +43 -0
  28. package/renderer/app/api/domains/remove/route.js +89 -0
  29. package/renderer/app/api/domains/status/route.js +140 -0
  30. package/renderer/app/api/domains/verify/route.js +168 -0
  31. package/renderer/app/api/keys/regenerate/route.js +71 -0
  32. package/renderer/app/api/local-assets/[...path]/route.js +108 -0
  33. package/renderer/app/api/openapi-spec/route.js +73 -0
  34. package/renderer/app/api/projects/[slug]/route.js +129 -0
  35. package/renderer/app/api/projects/[slug]/stats/route.js +80 -0
  36. package/renderer/app/api/projects/register/route.js +176 -0
  37. package/renderer/app/api/proxy/route.js +139 -0
  38. package/renderer/app/api/proxy-stream/route.js +156 -0
  39. package/renderer/app/api/redirects/route.js +35 -0
  40. package/renderer/app/api/schema/route.js +85 -0
  41. package/renderer/app/api/subdomains/check/route.js +158 -0
  42. package/renderer/app/api/suggestions/route.js +175 -0
  43. package/renderer/app/layout.js +47 -0
  44. package/renderer/app/llms-full.txt/route.js +257 -0
  45. package/renderer/app/llms.txt/route.js +219 -0
  46. package/renderer/app/page.js +12 -0
  47. package/renderer/app/robots.txt/route.js +66 -0
  48. package/renderer/app/sitemap.xml/route.js +145 -0
  49. package/renderer/components/docs/index.js +8 -0
  50. package/renderer/components/docs/mdx/accordion.js +113 -0
  51. package/renderer/components/docs/mdx/badge.js +72 -0
  52. package/renderer/components/docs/mdx/callouts.js +137 -0
  53. package/renderer/components/docs/mdx/cards.js +175 -0
  54. package/renderer/components/docs/mdx/changelog.js +100 -0
  55. package/renderer/components/docs/mdx/code-block.js +147 -0
  56. package/renderer/components/docs/mdx/code-group.js +287 -0
  57. package/renderer/components/docs/mdx/file-embeds.js +82 -0
  58. package/renderer/components/docs/mdx/frame.js +59 -0
  59. package/renderer/components/docs/mdx/highlight.js +90 -0
  60. package/renderer/components/docs/mdx/iframe.js +69 -0
  61. package/renderer/components/docs/mdx/image.js +135 -0
  62. package/renderer/components/docs/mdx/index.js +134 -0
  63. package/renderer/components/docs/mdx/landing.js +315 -0
  64. package/renderer/components/docs/mdx/mermaid.js +212 -0
  65. package/renderer/components/docs/mdx/param-field.js +112 -0
  66. package/renderer/components/docs/mdx/steps.js +74 -0
  67. package/renderer/components/docs/mdx/tabs.js +50 -0
  68. package/renderer/components/docs/mdx-renderer.js +77 -0
  69. package/renderer/components/docs/navigation/breadcrumbs.js +64 -0
  70. package/renderer/components/docs/navigation/index.js +6 -0
  71. package/renderer/components/docs/navigation/page-nav.js +57 -0
  72. package/renderer/components/docs/navigation/sidebar.js +375 -0
  73. package/renderer/components/docs/navigation/toc.js +89 -0
  74. package/renderer/components/docs/notice.js +77 -0
  75. package/renderer/components/docs-header.js +202 -0
  76. package/renderer/components/docs-viewer/agent/agent-chat.js +1930 -0
  77. package/renderer/components/docs-viewer/agent/cards/debug-context-card.js +107 -0
  78. package/renderer/components/docs-viewer/agent/cards/endpoint-context-card.js +57 -0
  79. package/renderer/components/docs-viewer/agent/cards/index.js +45 -0
  80. package/renderer/components/docs-viewer/agent/cards/response-options-card.js +154 -0
  81. package/renderer/components/docs-viewer/agent/cards/types.js +22 -0
  82. package/renderer/components/docs-viewer/agent/chat-message.js +2 -0
  83. package/renderer/components/docs-viewer/agent/index.js +4 -0
  84. package/renderer/components/docs-viewer/agent/messages/assistant-message.js +108 -0
  85. package/renderer/components/docs-viewer/agent/messages/chat-message.js +34 -0
  86. package/renderer/components/docs-viewer/agent/messages/index.js +6 -0
  87. package/renderer/components/docs-viewer/agent/messages/tool-call-display.js +1065 -0
  88. package/renderer/components/docs-viewer/agent/messages/types.js +2 -0
  89. package/renderer/components/docs-viewer/agent/messages/typing-indicator.js +26 -0
  90. package/renderer/components/docs-viewer/agent/messages/user-message.js +37 -0
  91. package/renderer/components/docs-viewer/code-editor/{index.tsx → index.js} +1 -1
  92. package/renderer/components/docs-viewer/code-editor/notes-mode.js +1338 -0
  93. package/renderer/components/docs-viewer/content/changelog-page.js +297 -0
  94. package/renderer/components/docs-viewer/content/doc-page.js +264 -0
  95. package/renderer/components/docs-viewer/content/documentation-viewer.js +14 -0
  96. package/renderer/components/docs-viewer/content/index.js +29 -0
  97. package/renderer/components/docs-viewer/content/not-found-page.js +300 -0
  98. package/renderer/components/docs-viewer/content/request-details.js +528 -0
  99. package/renderer/components/docs-viewer/content/sections/auth.js +108 -0
  100. package/renderer/components/docs-viewer/content/sections/body.js +80 -0
  101. package/renderer/components/docs-viewer/content/sections/headers.js +64 -0
  102. package/renderer/components/docs-viewer/content/sections/overview.js +56 -0
  103. package/renderer/components/docs-viewer/content/sections/parameters.js +64 -0
  104. package/renderer/components/docs-viewer/content/sections/responses.js +91 -0
  105. package/renderer/components/docs-viewer/global-auth-modal.js +427 -0
  106. package/renderer/components/docs-viewer/index.js +1552 -0
  107. package/renderer/components/docs-viewer/playground/auth-editor.js +418 -0
  108. package/renderer/components/docs-viewer/playground/body-editor.js +240 -0
  109. package/renderer/components/docs-viewer/playground/code-editor.js +135 -0
  110. package/renderer/components/docs-viewer/playground/code-snippet.js +393 -0
  111. package/renderer/components/docs-viewer/playground/graphql-playground.js +734 -0
  112. package/renderer/components/docs-viewer/playground/index.js +682 -0
  113. package/renderer/components/docs-viewer/playground/key-value-editor.js +317 -0
  114. package/renderer/components/docs-viewer/playground/method-selector.js +65 -0
  115. package/renderer/components/docs-viewer/playground/request-builder.js +181 -0
  116. package/renderer/components/docs-viewer/playground/request-tabs.js +240 -0
  117. package/renderer/components/docs-viewer/playground/response-cards/idle-card.js +42 -0
  118. package/renderer/components/docs-viewer/playground/response-cards/index.js +72 -0
  119. package/renderer/components/docs-viewer/playground/response-cards/loading-card.js +24 -0
  120. package/renderer/components/docs-viewer/playground/response-cards/network-error-card.js +28 -0
  121. package/renderer/components/docs-viewer/playground/response-cards/response-body-card.js +308 -0
  122. package/renderer/components/docs-viewer/playground/response-cards/types.js +9 -0
  123. package/renderer/components/docs-viewer/playground/response-viewer.js +18 -0
  124. package/renderer/components/docs-viewer/search/index.js +2 -0
  125. package/renderer/components/docs-viewer/search/search-dialog.js +367 -0
  126. package/renderer/components/docs-viewer/search/use-search.js +89 -0
  127. package/renderer/components/docs-viewer/shared/markdown-renderer.js +423 -0
  128. package/renderer/components/docs-viewer/shared/method-badge.js +23 -0
  129. package/renderer/components/docs-viewer/shared/schema-viewer.js +321 -0
  130. package/renderer/components/docs-viewer/sidebar/collection-tree.js +222 -0
  131. package/renderer/components/docs-viewer/sidebar/endpoint-options.js +512 -0
  132. package/renderer/components/docs-viewer/sidebar/index.js +196 -0
  133. package/renderer/components/docs-viewer/sidebar/right-sidebar.js +163 -0
  134. package/renderer/components/docs-viewer/sidebar/sidebar-group.js +87 -0
  135. package/renderer/components/docs-viewer/sidebar/sidebar-item.js +172 -0
  136. package/renderer/components/docs-viewer/sidebar/sidebar-section.js +31 -0
  137. package/renderer/components/theme-provider.js +10 -0
  138. package/renderer/components/theme-toggle.js +106 -0
  139. package/renderer/components/ui/badge.js +29 -0
  140. package/renderer/components/ui/button.js +40 -0
  141. package/renderer/components/ui/dialog.js +50 -0
  142. package/renderer/components/ui/dropdown-menu.js +143 -0
  143. package/renderer/components/ui/input.js +12 -0
  144. package/renderer/components/ui/label.js +13 -0
  145. package/renderer/components/ui/navigation-menu.js +83 -0
  146. package/renderer/components/ui/select.js +116 -0
  147. package/renderer/components/ui/spinner.js +92 -0
  148. package/renderer/components/ui/tabs.js +34 -0
  149. package/renderer/components/ui/tooltip.js +43 -0
  150. package/renderer/hooks/use-code-copy.js +76 -0
  151. package/renderer/hooks/use-openapi-title.js +33 -0
  152. package/renderer/lib/api-docs/agent/index.js +4 -0
  153. package/renderer/lib/api-docs/agent/indexer.js +254 -0
  154. package/renderer/lib/api-docs/agent/spec-summary.js +227 -0
  155. package/renderer/lib/api-docs/agent/types.js +5 -0
  156. package/renderer/lib/api-docs/auth/auth-context.js +157 -0
  157. package/renderer/lib/api-docs/auth/auth-storage.js +66 -0
  158. package/renderer/lib/api-docs/auth/crypto.js +64 -0
  159. package/renderer/lib/api-docs/auth/index.js +3 -0
  160. package/renderer/lib/api-docs/code-editor/db.js +145 -0
  161. package/renderer/lib/api-docs/code-editor/hooks.js +254 -0
  162. package/renderer/lib/api-docs/code-editor/{index.ts → index.js} +3 -4
  163. package/renderer/lib/api-docs/code-editor/mode-context.js +154 -0
  164. package/renderer/lib/api-docs/code-editor/types.js +53 -0
  165. package/renderer/lib/api-docs/codegen/definitions.js +258 -0
  166. package/renderer/lib/api-docs/codegen/har.js +171 -0
  167. package/renderer/lib/api-docs/codegen/index.js +118 -0
  168. package/renderer/lib/api-docs/factories.js +136 -0
  169. package/renderer/lib/api-docs/{index.ts → index.js} +5 -10
  170. package/renderer/lib/api-docs/mobile-context.js +79 -0
  171. package/renderer/lib/api-docs/navigation-context.js +62 -0
  172. package/renderer/lib/api-docs/parsers/graphql/index.js +50 -0
  173. package/renderer/lib/api-docs/parsers/graphql/parser.js +350 -0
  174. package/renderer/lib/api-docs/parsers/graphql/transformer.js +215 -0
  175. package/renderer/lib/api-docs/parsers/graphql/types.js +46 -0
  176. package/renderer/lib/api-docs/parsers/openapi/dereferencer.js +43 -0
  177. package/renderer/lib/api-docs/parsers/openapi/extractors/auth.js +486 -0
  178. package/renderer/lib/api-docs/parsers/openapi/extractors/body.js +295 -0
  179. package/renderer/lib/api-docs/parsers/openapi/extractors/index.js +132 -0
  180. package/renderer/lib/api-docs/parsers/openapi/index.js +127 -0
  181. package/renderer/lib/api-docs/parsers/openapi/transformer.js +192 -0
  182. package/renderer/lib/api-docs/parsers/openapi/validator.js +24 -0
  183. package/renderer/lib/api-docs/playground/context.js +65 -0
  184. package/renderer/lib/api-docs/playground/navigation-context.js +74 -0
  185. package/renderer/lib/api-docs/playground/request-builder.js +163 -0
  186. package/renderer/lib/api-docs/playground/request-runner.js +224 -0
  187. package/renderer/lib/api-docs/playground/types.js +5 -0
  188. package/renderer/lib/api-docs/types.js +23 -0
  189. package/renderer/lib/api-docs/utils.js +212 -0
  190. package/renderer/lib/cache.js +157 -0
  191. package/renderer/lib/docs/config/domain-schema.js +161 -0
  192. package/renderer/lib/docs/config/index.js +5 -0
  193. package/renderer/lib/docs/config/loader.js +113 -0
  194. package/renderer/lib/docs/config/schema.js +269 -0
  195. package/renderer/lib/docs/index.js +8 -0
  196. package/renderer/lib/docs/mdx/compiler.js +128 -0
  197. package/renderer/lib/docs/mdx/frontmatter.js +73 -0
  198. package/renderer/lib/docs/mdx/index.js +8 -0
  199. package/renderer/lib/docs/navigation/generator.js +269 -0
  200. package/renderer/lib/docs/navigation/index.js +4 -0
  201. package/renderer/lib/docs/navigation/types.js +9 -0
  202. package/renderer/lib/docs-navigation-context.js +40 -0
  203. package/renderer/lib/multi-tenant/context.js +80 -0
  204. package/renderer/lib/storage/blob.js +767 -0
  205. package/renderer/lib/utils/icons.js +30 -0
  206. package/renderer/lib/utils.js +5 -0
  207. package/renderer/next.config.js +62 -0
  208. package/renderer/tsconfig.json +23 -5
  209. package/renderer/app/api/assets/[...path]/route.ts +0 -123
  210. package/renderer/app/api/assets/route.ts +0 -124
  211. package/renderer/app/api/assets/upload/route.ts +0 -177
  212. package/renderer/app/api/auth-schemes/route.ts +0 -77
  213. package/renderer/app/api/chat/route.ts +0 -858
  214. package/renderer/app/api/codegen/route.ts +0 -72
  215. package/renderer/app/api/collections/route.ts +0 -1002
  216. package/renderer/app/api/debug/route.ts +0 -53
  217. package/renderer/app/api/deploy/route.ts +0 -234
  218. package/renderer/app/api/device/route.ts +0 -42
  219. package/renderer/app/api/docs/route.ts +0 -201
  220. package/renderer/app/api/domains/add/route.ts +0 -132
  221. package/renderer/app/api/domains/lookup/route.ts +0 -43
  222. package/renderer/app/api/domains/remove/route.ts +0 -100
  223. package/renderer/app/api/domains/status/route.ts +0 -158
  224. package/renderer/app/api/domains/verify/route.ts +0 -181
  225. package/renderer/app/api/keys/regenerate/route.ts +0 -80
  226. package/renderer/app/api/local-assets/[...path]/route.ts +0 -122
  227. package/renderer/app/api/openapi-spec/route.ts +0 -151
  228. package/renderer/app/api/projects/[slug]/route.ts +0 -153
  229. package/renderer/app/api/projects/[slug]/stats/route.ts +0 -96
  230. package/renderer/app/api/projects/register/route.ts +0 -152
  231. package/renderer/app/api/proxy/route.ts +0 -149
  232. package/renderer/app/api/proxy-stream/route.ts +0 -168
  233. package/renderer/app/api/redirects/route.ts +0 -47
  234. package/renderer/app/api/schema/route.ts +0 -73
  235. package/renderer/app/api/subdomains/check/route.ts +0 -172
  236. package/renderer/app/api/suggestions/route.ts +0 -144
  237. package/renderer/app/layout.tsx +0 -54
  238. package/renderer/app/llms-full.txt/route.ts +0 -346
  239. package/renderer/app/llms.txt/route.ts +0 -279
  240. package/renderer/app/page.tsx +0 -14
  241. package/renderer/app/robots.txt/route.ts +0 -84
  242. package/renderer/app/sitemap.xml/route.ts +0 -199
  243. package/renderer/components/docs/index.ts +0 -12
  244. package/renderer/components/docs/mdx/accordion.tsx +0 -169
  245. package/renderer/components/docs/mdx/badge.tsx +0 -132
  246. package/renderer/components/docs/mdx/callouts.tsx +0 -154
  247. package/renderer/components/docs/mdx/cards.tsx +0 -241
  248. package/renderer/components/docs/mdx/changelog.tsx +0 -120
  249. package/renderer/components/docs/mdx/code-block.tsx +0 -186
  250. package/renderer/components/docs/mdx/code-group.tsx +0 -421
  251. package/renderer/components/docs/mdx/file-embeds.tsx +0 -105
  252. package/renderer/components/docs/mdx/frame.tsx +0 -112
  253. package/renderer/components/docs/mdx/highlight.tsx +0 -151
  254. package/renderer/components/docs/mdx/iframe.tsx +0 -134
  255. package/renderer/components/docs/mdx/image.tsx +0 -235
  256. package/renderer/components/docs/mdx/index.ts +0 -237
  257. package/renderer/components/docs/mdx/landing.tsx +0 -684
  258. package/renderer/components/docs/mdx/mermaid.tsx +0 -240
  259. package/renderer/components/docs/mdx/param-field.tsx +0 -200
  260. package/renderer/components/docs/mdx/steps.tsx +0 -113
  261. package/renderer/components/docs/mdx/tabs.tsx +0 -86
  262. package/renderer/components/docs/mdx-renderer.tsx +0 -100
  263. package/renderer/components/docs/navigation/breadcrumbs.tsx +0 -76
  264. package/renderer/components/docs/navigation/index.ts +0 -8
  265. package/renderer/components/docs/navigation/page-nav.tsx +0 -64
  266. package/renderer/components/docs/navigation/sidebar.tsx +0 -515
  267. package/renderer/components/docs/navigation/toc.tsx +0 -113
  268. package/renderer/components/docs/notice.tsx +0 -105
  269. package/renderer/components/docs-header.tsx +0 -278
  270. package/renderer/components/docs-viewer/agent/agent-chat.tsx +0 -2076
  271. package/renderer/components/docs-viewer/agent/cards/debug-context-card.tsx +0 -90
  272. package/renderer/components/docs-viewer/agent/cards/endpoint-context-card.tsx +0 -49
  273. package/renderer/components/docs-viewer/agent/cards/index.tsx +0 -50
  274. package/renderer/components/docs-viewer/agent/cards/response-options-card.tsx +0 -212
  275. package/renderer/components/docs-viewer/agent/cards/types.ts +0 -84
  276. package/renderer/components/docs-viewer/agent/chat-message.tsx +0 -17
  277. package/renderer/components/docs-viewer/agent/index.tsx +0 -6
  278. package/renderer/components/docs-viewer/agent/messages/assistant-message.tsx +0 -119
  279. package/renderer/components/docs-viewer/agent/messages/chat-message.tsx +0 -46
  280. package/renderer/components/docs-viewer/agent/messages/index.ts +0 -17
  281. package/renderer/components/docs-viewer/agent/messages/tool-call-display.tsx +0 -721
  282. package/renderer/components/docs-viewer/agent/messages/types.ts +0 -61
  283. package/renderer/components/docs-viewer/agent/messages/typing-indicator.tsx +0 -24
  284. package/renderer/components/docs-viewer/agent/messages/user-message.tsx +0 -51
  285. package/renderer/components/docs-viewer/code-editor/notes-mode.tsx +0 -1283
  286. package/renderer/components/docs-viewer/content/changelog-page.tsx +0 -331
  287. package/renderer/components/docs-viewer/content/doc-page.tsx +0 -367
  288. package/renderer/components/docs-viewer/content/documentation-viewer.tsx +0 -17
  289. package/renderer/components/docs-viewer/content/index.tsx +0 -29
  290. package/renderer/components/docs-viewer/content/not-found-page.tsx +0 -330
  291. package/renderer/components/docs-viewer/content/request-details.tsx +0 -330
  292. package/renderer/components/docs-viewer/content/sections/auth.tsx +0 -69
  293. package/renderer/components/docs-viewer/content/sections/body.tsx +0 -66
  294. package/renderer/components/docs-viewer/content/sections/headers.tsx +0 -43
  295. package/renderer/components/docs-viewer/content/sections/overview.tsx +0 -40
  296. package/renderer/components/docs-viewer/content/sections/parameters.tsx +0 -43
  297. package/renderer/components/docs-viewer/content/sections/responses.tsx +0 -87
  298. package/renderer/components/docs-viewer/global-auth-modal.tsx +0 -352
  299. package/renderer/components/docs-viewer/index.tsx +0 -1662
  300. package/renderer/components/docs-viewer/playground/auth-editor.tsx +0 -280
  301. package/renderer/components/docs-viewer/playground/body-editor.tsx +0 -221
  302. package/renderer/components/docs-viewer/playground/code-editor.tsx +0 -224
  303. package/renderer/components/docs-viewer/playground/code-snippet.tsx +0 -387
  304. package/renderer/components/docs-viewer/playground/graphql-playground.tsx +0 -745
  305. package/renderer/components/docs-viewer/playground/index.tsx +0 -671
  306. package/renderer/components/docs-viewer/playground/key-value-editor.tsx +0 -261
  307. package/renderer/components/docs-viewer/playground/method-selector.tsx +0 -60
  308. package/renderer/components/docs-viewer/playground/request-builder.tsx +0 -179
  309. package/renderer/components/docs-viewer/playground/request-tabs.tsx +0 -237
  310. package/renderer/components/docs-viewer/playground/response-cards/idle-card.tsx +0 -21
  311. package/renderer/components/docs-viewer/playground/response-cards/index.tsx +0 -93
  312. package/renderer/components/docs-viewer/playground/response-cards/loading-card.tsx +0 -16
  313. package/renderer/components/docs-viewer/playground/response-cards/network-error-card.tsx +0 -23
  314. package/renderer/components/docs-viewer/playground/response-cards/response-body-card.tsx +0 -268
  315. package/renderer/components/docs-viewer/playground/response-cards/types.ts +0 -82
  316. package/renderer/components/docs-viewer/playground/response-viewer.tsx +0 -43
  317. package/renderer/components/docs-viewer/search/index.ts +0 -2
  318. package/renderer/components/docs-viewer/search/search-dialog.tsx +0 -331
  319. package/renderer/components/docs-viewer/search/use-search.ts +0 -117
  320. package/renderer/components/docs-viewer/shared/markdown-renderer.tsx +0 -431
  321. package/renderer/components/docs-viewer/shared/method-badge.tsx +0 -41
  322. package/renderer/components/docs-viewer/shared/schema-viewer.tsx +0 -349
  323. package/renderer/components/docs-viewer/sidebar/collection-tree.tsx +0 -259
  324. package/renderer/components/docs-viewer/sidebar/endpoint-options.tsx +0 -316
  325. package/renderer/components/docs-viewer/sidebar/index.tsx +0 -282
  326. package/renderer/components/docs-viewer/sidebar/right-sidebar.tsx +0 -202
  327. package/renderer/components/docs-viewer/sidebar/sidebar-group.tsx +0 -118
  328. package/renderer/components/docs-viewer/sidebar/sidebar-item.tsx +0 -212
  329. package/renderer/components/docs-viewer/sidebar/sidebar-section.tsx +0 -38
  330. package/renderer/components/theme-provider.tsx +0 -11
  331. package/renderer/components/theme-toggle.tsx +0 -76
  332. package/renderer/components/ui/badge.tsx +0 -46
  333. package/renderer/components/ui/button.tsx +0 -59
  334. package/renderer/components/ui/dialog.tsx +0 -118
  335. package/renderer/components/ui/dropdown-menu.tsx +0 -257
  336. package/renderer/components/ui/input.tsx +0 -21
  337. package/renderer/components/ui/label.tsx +0 -24
  338. package/renderer/components/ui/navigation-menu.tsx +0 -168
  339. package/renderer/components/ui/select.tsx +0 -190
  340. package/renderer/components/ui/spinner.tsx +0 -114
  341. package/renderer/components/ui/tabs.tsx +0 -66
  342. package/renderer/components/ui/tooltip.tsx +0 -61
  343. package/renderer/hooks/use-code-copy.ts +0 -88
  344. package/renderer/hooks/use-openapi-title.ts +0 -44
  345. package/renderer/lib/api-docs/agent/index.ts +0 -6
  346. package/renderer/lib/api-docs/agent/indexer.ts +0 -323
  347. package/renderer/lib/api-docs/agent/spec-summary.ts +0 -335
  348. package/renderer/lib/api-docs/agent/types.ts +0 -116
  349. package/renderer/lib/api-docs/auth/auth-context.tsx +0 -225
  350. package/renderer/lib/api-docs/auth/auth-storage.ts +0 -87
  351. package/renderer/lib/api-docs/auth/crypto.ts +0 -89
  352. package/renderer/lib/api-docs/auth/index.ts +0 -4
  353. package/renderer/lib/api-docs/code-editor/db.ts +0 -164
  354. package/renderer/lib/api-docs/code-editor/hooks.ts +0 -266
  355. package/renderer/lib/api-docs/code-editor/mode-context.tsx +0 -207
  356. package/renderer/lib/api-docs/code-editor/types.ts +0 -105
  357. package/renderer/lib/api-docs/codegen/definitions.ts +0 -297
  358. package/renderer/lib/api-docs/codegen/har.ts +0 -251
  359. package/renderer/lib/api-docs/codegen/index.ts +0 -159
  360. package/renderer/lib/api-docs/factories.ts +0 -170
  361. package/renderer/lib/api-docs/mobile-context.tsx +0 -112
  362. package/renderer/lib/api-docs/navigation-context.tsx +0 -88
  363. package/renderer/lib/api-docs/parsers/graphql/README.md +0 -129
  364. package/renderer/lib/api-docs/parsers/graphql/index.ts +0 -91
  365. package/renderer/lib/api-docs/parsers/graphql/parser.ts +0 -491
  366. package/renderer/lib/api-docs/parsers/graphql/transformer.ts +0 -246
  367. package/renderer/lib/api-docs/parsers/graphql/types.ts +0 -283
  368. package/renderer/lib/api-docs/parsers/openapi/README.md +0 -32
  369. package/renderer/lib/api-docs/parsers/openapi/dereferencer.ts +0 -60
  370. package/renderer/lib/api-docs/parsers/openapi/extractors/auth.ts +0 -574
  371. package/renderer/lib/api-docs/parsers/openapi/extractors/body.ts +0 -403
  372. package/renderer/lib/api-docs/parsers/openapi/extractors/index.ts +0 -232
  373. package/renderer/lib/api-docs/parsers/openapi/index.ts +0 -171
  374. package/renderer/lib/api-docs/parsers/openapi/transformer.ts +0 -278
  375. package/renderer/lib/api-docs/parsers/openapi/validator.ts +0 -31
  376. package/renderer/lib/api-docs/playground/context.tsx +0 -107
  377. package/renderer/lib/api-docs/playground/navigation-context.tsx +0 -124
  378. package/renderer/lib/api-docs/playground/request-builder.ts +0 -223
  379. package/renderer/lib/api-docs/playground/request-runner.ts +0 -282
  380. package/renderer/lib/api-docs/playground/types.ts +0 -35
  381. package/renderer/lib/api-docs/types.ts +0 -269
  382. package/renderer/lib/api-docs/utils.ts +0 -311
  383. package/renderer/lib/cache.ts +0 -193
  384. package/renderer/lib/docs/config/domain-schema.ts +0 -260
  385. package/renderer/lib/docs/config/index.ts +0 -43
  386. package/renderer/lib/docs/config/loader.ts +0 -142
  387. package/renderer/lib/docs/config/schema.ts +0 -308
  388. package/renderer/lib/docs/index.ts +0 -12
  389. package/renderer/lib/docs/mdx/compiler.ts +0 -176
  390. package/renderer/lib/docs/mdx/frontmatter.ts +0 -91
  391. package/renderer/lib/docs/mdx/index.ts +0 -26
  392. package/renderer/lib/docs/navigation/generator.ts +0 -348
  393. package/renderer/lib/docs/navigation/index.ts +0 -12
  394. package/renderer/lib/docs/navigation/types.ts +0 -123
  395. package/renderer/lib/docs-navigation-context.tsx +0 -80
  396. package/renderer/lib/multi-tenant/context.ts +0 -105
  397. package/renderer/lib/storage/blob.ts +0 -1083
  398. package/renderer/lib/utils/icons.ts +0 -48
  399. package/renderer/lib/utils.ts +0 -6
  400. package/renderer/next.config.ts +0 -76
@@ -0,0 +1,1552 @@
1
+ 'use client';
2
+ import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
3
+ import { useEffect, useState, useCallback, useRef } from 'react';
4
+ import { Spinner } from '@phosphor-icons/react';
5
+ import { DocsSidebar } from './sidebar';
6
+ import { NotFoundPage } from './content/not-found-page';
7
+ import { ApiPlayground } from './playground';
8
+ import { RightSidebar } from './sidebar/right-sidebar';
9
+ import { RequestDetails } from './content/request-details';
10
+ import { DocPage } from './content/doc-page';
11
+ import { ChangelogPage } from './content/changelog-page';
12
+ import { GraphQLPlayground } from './playground/graphql-playground';
13
+ import { makeBrainfishCollection } from '@/lib/api-docs/factories';
14
+ import { parse, Kind } from 'graphql';
15
+ import { GlobalAuthModal } from './global-auth-modal';
16
+ import { AuthProvider } from '@/lib/api-docs/auth';
17
+ import { PlaygroundProvider, usePlaygroundPrefill } from '@/lib/api-docs/playground/context';
18
+ import { PlaygroundNavigationProvider, usePlaygroundNavigation } from '@/lib/api-docs/playground/navigation-context';
19
+ import { NavigationProvider } from '@/lib/api-docs/navigation-context';
20
+ import { ModeProvider, useModeContext } from '@/lib/api-docs/code-editor';
21
+ import { NotesMode } from './code-editor';
22
+ import { DocsHeader } from '@/components/docs-header';
23
+ import { Notice } from '../docs/notice';
24
+ import { DocsNavigationProvider } from '@/lib/docs-navigation-context';
25
+ import { Button } from '@/components/ui/button';
26
+ import { Code, TestTube, Book } from '@phosphor-icons/react';
27
+ import { cn } from '@/lib/utils';
28
+ import { SearchDialog, useSearch } from './search';
29
+ import { useTheme } from 'next-themes';
30
+ // Helper to convert GraphQL TypeNode to string
31
+ function typeNodeToString(typeNode) {
32
+ switch(typeNode.kind){
33
+ case Kind.NAMED_TYPE:
34
+ return typeNode.name.value;
35
+ case Kind.NON_NULL_TYPE:
36
+ return `${typeNodeToString(typeNode.type)}!`;
37
+ case Kind.LIST_TYPE:
38
+ return `[${typeNodeToString(typeNode.type)}]`;
39
+ default:
40
+ return 'Unknown';
41
+ }
42
+ }
43
+ // Parse GraphQL schema using the graphql library
44
+ function parseGraphQLSchema(schemaSDL) {
45
+ const operations = [];
46
+ try {
47
+ const ast = parse(schemaSDL);
48
+ // Find Query, Mutation, Subscription type definitions
49
+ for (const def of ast.definitions){
50
+ if (def.kind === Kind.OBJECT_TYPE_DEFINITION) {
51
+ const typeName = def.name.value;
52
+ // Only process root operation types
53
+ if (![
54
+ 'Query',
55
+ 'Mutation',
56
+ 'Subscription'
57
+ ].includes(typeName)) continue;
58
+ const operationType = typeName.toLowerCase();
59
+ // Process each field
60
+ for (const field of def.fields || []){
61
+ const name = field.name.value;
62
+ // Skip internal fields
63
+ if (name.startsWith('_')) continue;
64
+ // Get description
65
+ const description = field.description?.value || null;
66
+ // Get return type
67
+ const returnType = typeNodeToString(field.type);
68
+ // Build args string for query generation
69
+ const args = (field.arguments || []).map((arg)=>`${arg.name.value}: ${typeNodeToString(arg.type)}`).join(', ');
70
+ const query = generateGraphQLQuery(operationType, name, field.arguments || [], returnType);
71
+ const exampleVariables = generateGraphQLVariables(field.arguments || []);
72
+ operations.push({
73
+ id: `${operationType}-${name}`,
74
+ name,
75
+ description,
76
+ operationType,
77
+ query,
78
+ exampleVariables
79
+ });
80
+ }
81
+ }
82
+ }
83
+ } catch (err) {
84
+ console.error('[GraphQL Parser] Failed to parse schema:', err);
85
+ }
86
+ return operations;
87
+ }
88
+ // Generate example GraphQL query from AST
89
+ function generateGraphQLQuery(operationType, name, args, returnType) {
90
+ let query = `${operationType} ${name.charAt(0).toUpperCase() + name.slice(1)}`;
91
+ if (args.length > 0) {
92
+ const varDefs = args.map((arg)=>`$${arg.name.value}: ${typeNodeToString(arg.type)}`).join(', ');
93
+ query += `(${varDefs})`;
94
+ }
95
+ query += ` {\n ${name}`;
96
+ if (args.length > 0) {
97
+ const argPairs = args.map((arg)=>`${arg.name.value}: $${arg.name.value}`).join(', ');
98
+ query += `(${argPairs})`;
99
+ }
100
+ const baseType = returnType.replace(/[\[\]!]/g, '').trim();
101
+ if ([
102
+ 'String',
103
+ 'Int',
104
+ 'Float',
105
+ 'Boolean',
106
+ 'ID'
107
+ ].includes(baseType)) {
108
+ query += '\n}';
109
+ } else {
110
+ query += ` {\n id\n __typename\n }\n}`;
111
+ }
112
+ return query;
113
+ }
114
+ // Generate example variables from AST args
115
+ function generateGraphQLVariables(args) {
116
+ const variables = {};
117
+ for (const arg of args){
118
+ const name = arg.name.value;
119
+ const type = typeNodeToString(arg.type).replace(/[\[\]!]/g, '').trim();
120
+ switch(type){
121
+ case 'String':
122
+ variables[name] = 'example';
123
+ break;
124
+ case 'Int':
125
+ variables[name] = 1;
126
+ break;
127
+ case 'Float':
128
+ variables[name] = 1.0;
129
+ break;
130
+ case 'Boolean':
131
+ variables[name] = true;
132
+ break;
133
+ case 'ID':
134
+ variables[name] = '1';
135
+ break;
136
+ default:
137
+ variables[name] = {};
138
+ }
139
+ }
140
+ return variables;
141
+ }
142
+ // Convert GraphQL operations to BrainfishCollection for sidebar
143
+ function convertGraphQLToCollection(operations, endpoint) {
144
+ const queries = operations.filter((op)=>op.operationType === 'query');
145
+ const mutations = operations.filter((op)=>op.operationType === 'mutation');
146
+ const subscriptions = operations.filter((op)=>op.operationType === 'subscription');
147
+ const toRequest = (op)=>({
148
+ id: op.id,
149
+ name: op.name,
150
+ description: op.description || '',
151
+ method: 'POST',
152
+ endpoint,
153
+ params: [],
154
+ headers: [],
155
+ auth: {
156
+ authType: 'none',
157
+ authActive: false
158
+ },
159
+ body: {
160
+ contentType: 'application/json',
161
+ body: JSON.stringify({
162
+ query: op.query,
163
+ variables: op.exampleVariables
164
+ }, null, 2)
165
+ },
166
+ requestVariables: [],
167
+ responses: {},
168
+ tags: [
169
+ op.operationType
170
+ ]
171
+ });
172
+ const folders = [];
173
+ if (queries.length > 0) {
174
+ folders.push(makeBrainfishCollection({
175
+ name: 'Queries',
176
+ description: 'GraphQL Query operations',
177
+ requests: queries.map(toRequest),
178
+ folders: [],
179
+ variables: [],
180
+ auth: {
181
+ authType: 'none',
182
+ authActive: false
183
+ },
184
+ headers: []
185
+ }));
186
+ }
187
+ if (mutations.length > 0) {
188
+ folders.push(makeBrainfishCollection({
189
+ name: 'Mutations',
190
+ description: 'GraphQL Mutation operations',
191
+ requests: mutations.map(toRequest),
192
+ folders: [],
193
+ variables: [],
194
+ auth: {
195
+ authType: 'none',
196
+ authActive: false
197
+ },
198
+ headers: []
199
+ }));
200
+ }
201
+ if (subscriptions.length > 0) {
202
+ folders.push(makeBrainfishCollection({
203
+ name: 'Subscriptions',
204
+ description: 'GraphQL Subscription operations',
205
+ requests: subscriptions.map(toRequest),
206
+ folders: [],
207
+ variables: [],
208
+ auth: {
209
+ authType: 'none',
210
+ authActive: false
211
+ },
212
+ headers: []
213
+ }));
214
+ }
215
+ return makeBrainfishCollection({
216
+ name: 'GraphQL API',
217
+ description: 'GraphQL operations',
218
+ folders,
219
+ requests: [],
220
+ variables: [],
221
+ auth: {
222
+ authType: 'none',
223
+ authActive: false
224
+ },
225
+ headers: []
226
+ });
227
+ }
228
+ // Helper to find request by ID in collection
229
+ function findRequestById(collection, id) {
230
+ // Check direct requests
231
+ const found = collection.requests.find((r)=>r.id === id);
232
+ if (found) return found;
233
+ // Check folders recursively
234
+ for (const folder of collection.folders){
235
+ const request = findRequestById(folder, id);
236
+ if (request) return request;
237
+ }
238
+ return null;
239
+ }
240
+ // Helper to get the first endpoint from collection
241
+ function getFirstEndpoint(collection) {
242
+ // Check direct requests first
243
+ if (collection.requests.length > 0) {
244
+ return collection.requests[0];
245
+ }
246
+ // Check folders recursively
247
+ for (const folder of collection.folders){
248
+ const firstInFolder = getFirstEndpoint(folder);
249
+ if (firstInFolder) return firstInFolder;
250
+ }
251
+ return null;
252
+ }
253
+ // Helper to check if a doc group belongs to a specific tab
254
+ // Group IDs are formatted as: group-{tab-id}-{group-name}
255
+ function isGroupForTab(groupId, tabId) {
256
+ // Check if the group ID starts with "group-{tabId}-"
257
+ const prefix = `group-${tabId}-`;
258
+ return groupId.startsWith(prefix);
259
+ }
260
+ // Helper to check if a tab has doc groups (MDX pages)
261
+ function hasDocGroupsForTab(docGroups, tabId) {
262
+ if (!docGroups || docGroups.length === 0) return false;
263
+ // Check if any doc group belongs to this tab and has pages
264
+ return docGroups.some((g)=>isGroupForTab(g.id, tabId) && g.pages.length > 0);
265
+ }
266
+ // Helper to get the first page from doc groups for a tab
267
+ function getFirstDocPageForTab(docGroups, tabId) {
268
+ if (!docGroups || docGroups.length === 0) return null;
269
+ const tabDocGroup = docGroups.find((g)=>isGroupForTab(g.id, tabId) && g.pages.length > 0);
270
+ return tabDocGroup?.pages[0]?.slug || null;
271
+ }
272
+ function DocsContent() {
273
+ const [collection, setCollection] = useState(null);
274
+ const [selectedRequest, setSelectedRequest] = useState(null);
275
+ const [selectedDocSection, setSelectedDocSection] = useState(null);
276
+ const [selectedDocPage, setSelectedDocPage] = useState(null);
277
+ const [activeTab, setActiveTab] = useState('api-reference');
278
+ const [selectedApiVersion, setSelectedApiVersion] = useState(null);
279
+ const [loading, setLoading] = useState(true);
280
+ const [isVersionLoading, setIsVersionLoading] = useState(false) // For version switch only
281
+ ;
282
+ const [error, setError] = useState(null);
283
+ const [showAuthModal, setShowAuthModal] = useState(false);
284
+ const [notFoundSlug, setNotFoundSlug] = useState(null) // Track 404 for invalid URLs
285
+ ;
286
+ // Prefill context for agent
287
+ const { setPrefill } = usePlaygroundPrefill();
288
+ // Playground navigation context for tab navigation
289
+ const { navigateAndHighlight, resetNavigation } = usePlaygroundNavigation();
290
+ // Mode context for switching modes
291
+ const { switchToDocs } = useModeContext();
292
+ // Ref for the scrollable content area
293
+ const contentRef = useRef(null);
294
+ // Update URL hash without triggering navigation
295
+ // Format: #tab or #tab/type/id (e.g., #api-reference, #api-reference/endpoint/123, #guides/page/quickstart)
296
+ const updateUrlHash = useCallback((hash, tab)=>{
297
+ const currentTab = tab || activeTab;
298
+ let newUrl;
299
+ if (!hash) {
300
+ // Just the tab
301
+ newUrl = `#${currentTab}`;
302
+ } else {
303
+ // Tab + path
304
+ newUrl = `#${currentTab}/${hash}`;
305
+ }
306
+ window.history.pushState(null, '', newUrl);
307
+ }, [
308
+ activeTab
309
+ ]);
310
+ // Navigate to hash - used for initial load and popstate
311
+ // Parse hash format: #tab or #tab/type/id
312
+ const parseHash = useCallback((hash)=>{
313
+ if (!hash) return {
314
+ tab: null,
315
+ type: null,
316
+ id: null
317
+ };
318
+ const parts = hash.split('/');
319
+ const tab = parts[0] || null;
320
+ const type = parts[1] || null;
321
+ const id = parts.slice(2).join('/') || null // Rejoin in case id has slashes
322
+ ;
323
+ return {
324
+ tab,
325
+ type,
326
+ id
327
+ };
328
+ }, []);
329
+ const navigateToHash = useCallback((collectionData)=>{
330
+ const hash = window.location.hash.slice(1) // Remove #
331
+ ;
332
+ if (!hash) {
333
+ // No hash - auto-select first endpoint
334
+ setSelectedDocSection(null);
335
+ setSelectedDocPage(null);
336
+ const firstEndpoint = getFirstEndpoint(collectionData);
337
+ if (firstEndpoint) {
338
+ setSelectedRequest(firstEndpoint);
339
+ } else {
340
+ setSelectedRequest(null);
341
+ }
342
+ return;
343
+ }
344
+ // Notes mode is handled by ModeContext, just clear API selection
345
+ if (hash === 'notes' || hash.startsWith('notes/')) {
346
+ setSelectedRequest(null);
347
+ setSelectedDocSection(null);
348
+ setSelectedDocPage(null);
349
+ return;
350
+ }
351
+ // Parse new format: #tab/type/id
352
+ const { tab, type, id } = parseHash(hash);
353
+ // Set the active tab if specified
354
+ if (tab) {
355
+ setActiveTab(tab);
356
+ }
357
+ // Handle legacy format (endpoint/xxx, page/xxx, doc/xxx without tab prefix)
358
+ const legacyType = hash.startsWith('endpoint/') ? 'endpoint' : hash.startsWith('page/') ? 'page' : hash.startsWith('doc/') ? 'doc' : null;
359
+ const actualType = type || legacyType;
360
+ const actualId = id || (legacyType ? hash.replace(`${legacyType}/`, '') : null);
361
+ if (actualType === 'endpoint' && actualId) {
362
+ const request = findRequestById(collectionData, actualId);
363
+ if (request) {
364
+ setSelectedRequest(request);
365
+ setSelectedDocSection(null);
366
+ setSelectedDocPage(null);
367
+ setNotFoundSlug(null);
368
+ } else {
369
+ // Endpoint not found - show 404 page
370
+ setSelectedRequest(null);
371
+ setSelectedDocSection(null);
372
+ setSelectedDocPage(null);
373
+ setNotFoundSlug(`endpoint/${actualId}`);
374
+ }
375
+ } else if (actualType === 'page' && actualId) {
376
+ setNotFoundSlug(null); // Clear not found state - DocPage handles its own 404
377
+ setSelectedDocPage(actualId);
378
+ setSelectedRequest(null);
379
+ setSelectedDocSection(null);
380
+ } else if (actualType === 'doc' && actualId) {
381
+ setSelectedDocSection(actualId);
382
+ setSelectedRequest(null);
383
+ setSelectedDocPage(null);
384
+ // Scroll to section after DOM update
385
+ setTimeout(()=>{
386
+ const element = document.getElementById(actualId);
387
+ if (element) {
388
+ element.scrollIntoView({
389
+ behavior: 'smooth',
390
+ block: 'start'
391
+ });
392
+ }
393
+ }, 100);
394
+ } else if (tab && !type) {
395
+ // Just a tab, no specific content - show default for that tab
396
+ setSelectedRequest(null);
397
+ setSelectedDocSection(null);
398
+ setSelectedDocPage(null);
399
+ }
400
+ }, [
401
+ parseHash
402
+ ]);
403
+ const handleSelectRequest = useCallback((request)=>{
404
+ setSelectedRequest(request);
405
+ setSelectedDocSection(null);
406
+ setSelectedDocPage(null);
407
+ setNotFoundSlug(null); // Clear 404 state when selecting an endpoint
408
+ updateUrlHash(`endpoint/${request.id}`);
409
+ // Reset tab navigation so the new endpoint can determine its default tab
410
+ resetNavigation();
411
+ // Switch to Docs mode to show endpoint documentation first
412
+ switchToDocs();
413
+ }, [
414
+ updateUrlHash,
415
+ resetNavigation,
416
+ switchToDocs
417
+ ]);
418
+ const handleSelectDocumentation = useCallback((headingId)=>{
419
+ const isIntro = headingId === 'introduction';
420
+ setSelectedDocSection(isIntro ? null : headingId);
421
+ setSelectedRequest(null);
422
+ setSelectedDocPage(null);
423
+ setNotFoundSlug(null); // Clear 404 state
424
+ updateUrlHash(isIntro ? '' : `doc/${headingId}`);
425
+ // Switch to Docs mode when selecting documentation
426
+ switchToDocs();
427
+ setTimeout(()=>{
428
+ if (isIntro) {
429
+ contentRef.current?.scrollTo({
430
+ top: 0,
431
+ behavior: 'smooth'
432
+ });
433
+ } else {
434
+ const element = document.getElementById(headingId);
435
+ if (element) {
436
+ element.scrollIntoView({
437
+ behavior: 'smooth',
438
+ block: 'start'
439
+ });
440
+ }
441
+ }
442
+ }, 50);
443
+ }, [
444
+ updateUrlHash,
445
+ switchToDocs
446
+ ]);
447
+ const handleSelectDocPage = useCallback((slug)=>{
448
+ // Find which tab this doc page belongs to
449
+ let targetTab = activeTab;
450
+ let releaseSlug = null;
451
+ let sectionId = null;
452
+ // Parse section from slug (e.g., "essentials/markdown#headings" -> slug: "essentials/markdown", section: "headings")
453
+ let pageSlug = slug;
454
+ if (slug.includes('#')) {
455
+ const [pagePart, sectionPart] = slug.split('#');
456
+ pageSlug = pagePart;
457
+ sectionId = sectionPart;
458
+ }
459
+ // Special handling for changelog pages
460
+ if (pageSlug.startsWith('changelog/') || pageSlug === 'changelog') {
461
+ // Find the changelog tab
462
+ const changelogTab = collection?.navigationTabs?.find((t)=>t.type === 'changelog');
463
+ if (changelogTab) {
464
+ targetTab = changelogTab.id;
465
+ }
466
+ // Extract the release slug for scrolling (e.g., "changelog/v1.2.0" -> "v1.2.0")
467
+ if (pageSlug.startsWith('changelog/')) {
468
+ releaseSlug = pageSlug.replace('changelog/', '');
469
+ }
470
+ } else if (collection?.docGroups) {
471
+ for (const group of collection.docGroups){
472
+ const hasPage = (pages)=>{
473
+ for (const page of pages){
474
+ if (page.slug === pageSlug) return true;
475
+ if (page.children && hasPage(page.children)) return true;
476
+ }
477
+ return false;
478
+ };
479
+ if (hasPage(group.pages)) {
480
+ // Extract tab from group ID (e.g., "group-guides-getting-started" -> "guides")
481
+ const tabPart = group.id.replace('group-', '').split('-')[0];
482
+ // Find the actual tab ID that matches
483
+ const matchingTab = collection.navigationTabs?.find((t)=>t.id === tabPart || t.id.startsWith(tabPart));
484
+ if (matchingTab) {
485
+ targetTab = matchingTab.id;
486
+ }
487
+ break;
488
+ }
489
+ }
490
+ }
491
+ // Switch to the correct tab
492
+ setActiveTab(targetTab);
493
+ setSelectedDocPage(pageSlug);
494
+ setSelectedRequest(null);
495
+ setSelectedDocSection(null);
496
+ setNotFoundSlug(null); // Clear 404 state
497
+ updateUrlHash(`page/${pageSlug}`, targetTab);
498
+ switchToDocs();
499
+ // Scroll to specific release if navigating to a changelog entry
500
+ if (releaseSlug) {
501
+ // Wait for the changelog page to render, then scroll to the release
502
+ setTimeout(()=>{
503
+ const releaseElement = document.getElementById(`release-${releaseSlug}`);
504
+ if (releaseElement) {
505
+ releaseElement.scrollIntoView({
506
+ behavior: 'smooth',
507
+ block: 'start'
508
+ });
509
+ }
510
+ }, 600);
511
+ } else if (sectionId) {
512
+ // Scroll to section within the page after it renders
513
+ setTimeout(()=>{
514
+ const sectionElement = document.getElementById(sectionId);
515
+ if (sectionElement) {
516
+ sectionElement.scrollIntoView({
517
+ behavior: 'smooth',
518
+ block: 'start'
519
+ });
520
+ }
521
+ }, 300);
522
+ } else {
523
+ // Scroll to top of content when navigating to a new page
524
+ setTimeout(()=>{
525
+ contentRef.current?.scrollTo({
526
+ top: 0,
527
+ behavior: 'smooth'
528
+ });
529
+ }, 50);
530
+ }
531
+ }, [
532
+ updateUrlHash,
533
+ switchToDocs,
534
+ collection,
535
+ activeTab
536
+ ]);
537
+ // Handle API version change
538
+ const handleApiVersionChange = useCallback((version)=>{
539
+ if (version !== selectedApiVersion) {
540
+ setSelectedApiVersion(version);
541
+ // Clear selected request when switching versions as endpoints may differ
542
+ setSelectedRequest(null);
543
+ setSelectedDocSection(null);
544
+ }
545
+ }, [
546
+ selectedApiVersion
547
+ ]);
548
+ // Handle tab change from header
549
+ const handleTabChange = useCallback((tabId)=>{
550
+ setActiveTab(tabId);
551
+ // Reset mode to docs when switching tabs (exit sandbox/api-client mode)
552
+ switchToDocs();
553
+ // Find the tab config to check its type
554
+ const tabConfig = collection?.navigationTabs?.find((t)=>t.id === tabId);
555
+ const isApiTab = tabConfig?.type === 'openapi' || tabConfig?.type === 'graphql' || tabId === 'api-reference';
556
+ if (tabId === 'changelog') {
557
+ // Switch to Changelog tab
558
+ setSelectedDocPage(null);
559
+ setSelectedRequest(null);
560
+ setSelectedDocSection(null);
561
+ updateUrlHash('', tabId);
562
+ } else if (isApiTab) {
563
+ // API Reference or GraphQL tab
564
+ setSelectedDocSection(null);
565
+ // Check if there are doc groups for this tab (MDX pages)
566
+ const hasGroups = hasDocGroupsForTab(collection?.docGroups, tabId);
567
+ if (hasGroups) {
568
+ // Has doc groups - select the first page from groups
569
+ const firstPage = getFirstDocPageForTab(collection?.docGroups, tabId);
570
+ if (firstPage) {
571
+ setSelectedDocPage(firstPage);
572
+ setSelectedRequest(null);
573
+ updateUrlHash(`page/${firstPage}`, tabId);
574
+ switchToDocs();
575
+ } else {
576
+ // No pages in groups - auto-select first endpoint
577
+ setSelectedDocPage(null);
578
+ const firstEndpoint = collection ? getFirstEndpoint(collection) : null;
579
+ if (firstEndpoint) {
580
+ setSelectedRequest(firstEndpoint);
581
+ updateUrlHash(`endpoint/${firstEndpoint.id}`, tabId);
582
+ } else {
583
+ setSelectedRequest(null);
584
+ updateUrlHash('', tabId);
585
+ }
586
+ }
587
+ } else {
588
+ // No doc groups - auto-select first endpoint
589
+ setSelectedDocPage(null);
590
+ const firstEndpoint = collection ? getFirstEndpoint(collection) : null;
591
+ if (firstEndpoint) {
592
+ setSelectedRequest(firstEndpoint);
593
+ updateUrlHash(`endpoint/${firstEndpoint.id}`, tabId);
594
+ } else {
595
+ setSelectedRequest(null);
596
+ updateUrlHash('', tabId);
597
+ }
598
+ }
599
+ } else {
600
+ // Switch to a doc group tab - find and select the first page in that tab
601
+ setSelectedRequest(null);
602
+ setSelectedDocSection(null);
603
+ // Find the first doc group for this tab and select its first page
604
+ if (collection?.docGroups) {
605
+ const tabDocGroup = collection.docGroups.find((g)=>isGroupForTab(g.id, tabId));
606
+ if (tabDocGroup && tabDocGroup.pages.length > 0) {
607
+ const firstPage = tabDocGroup.pages[0];
608
+ setSelectedDocPage(firstPage.slug);
609
+ updateUrlHash(`page/${firstPage.slug}`, tabId);
610
+ switchToDocs();
611
+ } else {
612
+ setSelectedDocPage(null);
613
+ updateUrlHash('', tabId);
614
+ }
615
+ }
616
+ }
617
+ }, [
618
+ collection,
619
+ updateUrlHash,
620
+ switchToDocs
621
+ ]);
622
+ // Handler for agent navigation
623
+ const handleAgentNavigate = useCallback((endpointId)=>{
624
+ if (!collection) return;
625
+ const request = findRequestById(collection, endpointId);
626
+ if (request) {
627
+ // Set the tab to API Reference first
628
+ setActiveTab('api-reference');
629
+ // Then set the selected request
630
+ setSelectedRequest(request);
631
+ setSelectedDocSection(null);
632
+ setSelectedDocPage(null);
633
+ updateUrlHash(`endpoint/${endpointId}`, 'api-reference');
634
+ // Reset tab navigation so the new endpoint can determine its default tab
635
+ resetNavigation();
636
+ }
637
+ }, [
638
+ collection,
639
+ updateUrlHash,
640
+ resetNavigation
641
+ ]);
642
+ // Handler for agent prefilling parameters
643
+ const handleAgentPrefill = useCallback((data)=>{
644
+ console.log('[Agent] Prefill requested:', data);
645
+ setPrefill(data);
646
+ }, [
647
+ setPrefill
648
+ ]);
649
+ // State for debug context - used to trigger agent debugging
650
+ const [debugContext, setDebugContext] = useState(null);
651
+ // Handler for debug requests from playground
652
+ const handleDebugRequest = useCallback((context)=>{
653
+ setDebugContext(context);
654
+ }, []);
655
+ // Clear debug context after it's been used
656
+ const clearDebugContext = useCallback(()=>{
657
+ setDebugContext(null);
658
+ }, []);
659
+ // State for explain context - used to trigger agent explanation
660
+ const [explainContext, setExplainContext] = useState(null);
661
+ // Handler for explain requests from playground
662
+ const handleExplainRequest = useCallback((context)=>{
663
+ setExplainContext(context);
664
+ }, []);
665
+ // Clear explain context after it's been used
666
+ const clearExplainContext = useCallback(()=>{
667
+ setExplainContext(null);
668
+ }, []);
669
+ // Handle browser back/forward
670
+ useEffect(()=>{
671
+ if (!collection) return;
672
+ const handlePopState = ()=>{
673
+ navigateToHash(collection);
674
+ };
675
+ window.addEventListener('popstate', handlePopState);
676
+ return ()=>window.removeEventListener('popstate', handlePopState);
677
+ }, [
678
+ collection,
679
+ navigateToHash
680
+ ]);
681
+ // Dynamically set favicon from docs.json config
682
+ useEffect(()=>{
683
+ if (!collection?.docsFavicon) return;
684
+ const faviconPath = collection.docsFavicon;
685
+ // Update or create link elements for favicon
686
+ const updateFaviconLink = (rel, href)=>{
687
+ let link = document.querySelector(`link[rel="${rel}"]`);
688
+ if (!link) {
689
+ link = document.createElement('link');
690
+ link.rel = rel;
691
+ document.head.appendChild(link);
692
+ }
693
+ link.href = href;
694
+ };
695
+ // Determine the type based on file extension
696
+ const ext = faviconPath.split('.').pop()?.toLowerCase();
697
+ const type = ext === 'svg' ? 'image/svg+xml' : ext === 'png' ? 'image/png' : ext === 'ico' ? 'image/x-icon' : 'image/png';
698
+ // Update the favicon link with type
699
+ let iconLink = document.querySelector('link[rel="icon"]');
700
+ if (!iconLink) {
701
+ iconLink = document.createElement('link');
702
+ iconLink.rel = 'icon';
703
+ document.head.appendChild(iconLink);
704
+ }
705
+ iconLink.type = type;
706
+ iconLink.href = faviconPath;
707
+ // Also update shortcut icon and apple-touch-icon
708
+ updateFaviconLink('shortcut icon', faviconPath);
709
+ updateFaviconLink('apple-touch-icon', faviconPath);
710
+ }, [
711
+ collection?.docsFavicon
712
+ ]);
713
+ useEffect(()=>{
714
+ async function fetchCollection() {
715
+ try {
716
+ // Only show full loading on initial load
717
+ const isInitialLoad = !collection;
718
+ if (isInitialLoad) {
719
+ setLoading(true);
720
+ } else {
721
+ setIsVersionLoading(true);
722
+ }
723
+ setError(null);
724
+ // Build URL with version param if selected
725
+ const url = selectedApiVersion ? `/api/collections?version=${encodeURIComponent(selectedApiVersion)}` : '/api/collections';
726
+ const response = await fetch(url);
727
+ if (!response.ok) {
728
+ throw new Error(`Failed to fetch collection: ${response.status}`);
729
+ }
730
+ const data = await response.json();
731
+ setCollection(data);
732
+ // Set initial API version if not already set
733
+ if (!selectedApiVersion && data?.selectedApiVersion) {
734
+ setSelectedApiVersion(data.selectedApiVersion);
735
+ }
736
+ // Only run initial navigation logic on first load, not on version changes
737
+ if (isInitialLoad) {
738
+ // Set initial active tab from config (first tab) and select first item
739
+ let initialTabId = 'api-reference';
740
+ if (data?.navigationTabs && data.navigationTabs.length > 0) {
741
+ const sortedTabs = [
742
+ ...data.navigationTabs
743
+ ].sort((a, b)=>a.order - b.order);
744
+ initialTabId = sortedTabs[0].id;
745
+ setActiveTab(initialTabId);
746
+ }
747
+ // Handle initial hash navigation after collection loads
748
+ if (data) {
749
+ // Use setTimeout to ensure state is set before navigation
750
+ setTimeout(()=>{
751
+ const hash = window.location.hash.slice(1);
752
+ if (!hash) {
753
+ // No hash - set URL to initial tab
754
+ setSelectedDocSection(null);
755
+ // Find the tab config to check its type
756
+ const tabConfig = data.navigationTabs?.find((t)=>t.id === initialTabId);
757
+ const isApiTab = tabConfig?.type === 'openapi' || tabConfig?.type === 'graphql' || initialTabId === 'api-reference';
758
+ if (isApiTab) {
759
+ // API Reference or GraphQL tab
760
+ setSelectedDocSection(null);
761
+ // Check if there are doc groups for this tab (MDX pages)
762
+ const hasGroups = hasDocGroupsForTab(data.docGroups, initialTabId);
763
+ if (hasGroups) {
764
+ // Has doc groups - select the first page from groups
765
+ const firstPage = getFirstDocPageForTab(data.docGroups, initialTabId);
766
+ if (firstPage) {
767
+ setSelectedDocPage(firstPage);
768
+ setSelectedRequest(null);
769
+ updateUrlHash(`page/${firstPage}`, initialTabId);
770
+ } else {
771
+ // No pages in groups - auto-select first endpoint
772
+ setSelectedDocPage(null);
773
+ const firstEndpoint = getFirstEndpoint(data);
774
+ if (firstEndpoint) {
775
+ setSelectedRequest(firstEndpoint);
776
+ updateUrlHash(`endpoint/${firstEndpoint.id}`, initialTabId);
777
+ } else {
778
+ setSelectedRequest(null);
779
+ updateUrlHash('', initialTabId);
780
+ }
781
+ }
782
+ } else {
783
+ // No doc groups - auto-select first endpoint
784
+ setSelectedDocPage(null);
785
+ const firstEndpoint = getFirstEndpoint(data);
786
+ if (firstEndpoint) {
787
+ setSelectedRequest(firstEndpoint);
788
+ updateUrlHash(`endpoint/${firstEndpoint.id}`, initialTabId);
789
+ } else {
790
+ setSelectedRequest(null);
791
+ updateUrlHash('', initialTabId);
792
+ }
793
+ }
794
+ switchToDocs();
795
+ } else {
796
+ // Doc group tab - select first page
797
+ setSelectedRequest(null);
798
+ const tabDocGroup = data.docGroups?.find((g)=>isGroupForTab(g.id, initialTabId));
799
+ if (tabDocGroup && tabDocGroup.pages.length > 0) {
800
+ const firstPage = tabDocGroup.pages[0];
801
+ setSelectedDocPage(firstPage.slug);
802
+ updateUrlHash(`page/${firstPage.slug}`, initialTabId);
803
+ switchToDocs();
804
+ } else {
805
+ setSelectedDocPage(null);
806
+ updateUrlHash('', initialTabId);
807
+ switchToDocs();
808
+ }
809
+ }
810
+ } else if (hash === 'notes' || hash.startsWith('notes/')) {
811
+ // Notes mode - handled by ModeContext, just clear API selection
812
+ setSelectedRequest(null);
813
+ setSelectedDocSection(null);
814
+ } else {
815
+ // Parse the hash to get tab and content info
816
+ // Format: #tab or #tab/type/id (e.g., #api-reference/endpoint/123)
817
+ const parts = hash.split('/');
818
+ const hashTab = parts[0];
819
+ const hashType = parts[1];
820
+ const hashId = parts.slice(2).join('/');
821
+ // Set the tab from the hash
822
+ if (hashTab && data.navigationTabs?.some((t)=>t.id === hashTab)) {
823
+ setActiveTab(hashTab);
824
+ }
825
+ // Handle legacy format (endpoint/xxx without tab prefix)
826
+ const isLegacyFormat = hash.startsWith('endpoint/') || hash.startsWith('page/') || hash.startsWith('doc/');
827
+ const actualType = isLegacyFormat ? parts[0] : hashType;
828
+ const actualId = isLegacyFormat ? parts.slice(1).join('/') : hashId;
829
+ if (actualType === 'endpoint' && actualId) {
830
+ const request = findRequestById(data, actualId);
831
+ if (request) {
832
+ setSelectedRequest(request);
833
+ setSelectedDocSection(null);
834
+ setSelectedDocPage(null);
835
+ switchToDocs();
836
+ return;
837
+ } else {
838
+ setSelectedRequest(null);
839
+ setSelectedDocSection(null);
840
+ setSelectedDocPage(null);
841
+ switchToDocs();
842
+ }
843
+ } else if (actualType === 'page' && actualId) {
844
+ setSelectedDocPage(actualId);
845
+ setSelectedRequest(null);
846
+ setSelectedDocSection(null);
847
+ switchToDocs();
848
+ } else if (actualType === 'doc' && actualId) {
849
+ setSelectedDocSection(actualId);
850
+ setSelectedRequest(null);
851
+ setSelectedDocPage(null);
852
+ switchToDocs();
853
+ setTimeout(()=>{
854
+ const element = document.getElementById(actualId);
855
+ if (element) {
856
+ element.scrollIntoView({
857
+ behavior: 'smooth',
858
+ block: 'start'
859
+ });
860
+ }
861
+ }, 100);
862
+ } else if (hashTab && !hashType) {
863
+ // Just a tab, show its default content
864
+ setSelectedDocSection(null);
865
+ // Check if this is an API tab
866
+ const tabConfig = data.navigationTabs?.find((t)=>t.id === hashTab);
867
+ const isApiTab = tabConfig?.type === 'openapi' || tabConfig?.type === 'graphql' || hashTab === 'api-reference';
868
+ if (isApiTab) {
869
+ // Check if there are doc groups for this tab (MDX pages)
870
+ const hasGroups = hasDocGroupsForTab(data.docGroups, hashTab);
871
+ if (hasGroups) {
872
+ // Has doc groups - select the first page from groups
873
+ const firstPage = getFirstDocPageForTab(data.docGroups, hashTab);
874
+ if (firstPage) {
875
+ setSelectedDocPage(firstPage);
876
+ setSelectedRequest(null);
877
+ updateUrlHash(`page/${firstPage}`, hashTab);
878
+ } else {
879
+ // No pages in groups - auto-select first endpoint
880
+ setSelectedDocPage(null);
881
+ const firstEndpoint = getFirstEndpoint(data);
882
+ if (firstEndpoint) {
883
+ setSelectedRequest(firstEndpoint);
884
+ updateUrlHash(`endpoint/${firstEndpoint.id}`, hashTab);
885
+ } else {
886
+ setSelectedRequest(null);
887
+ }
888
+ }
889
+ } else {
890
+ // No doc groups - auto-select first endpoint
891
+ setSelectedDocPage(null);
892
+ const firstEndpoint = getFirstEndpoint(data);
893
+ if (firstEndpoint) {
894
+ setSelectedRequest(firstEndpoint);
895
+ updateUrlHash(`endpoint/${firstEndpoint.id}`, hashTab);
896
+ } else {
897
+ setSelectedRequest(null);
898
+ }
899
+ }
900
+ } else {
901
+ setSelectedDocPage(null);
902
+ setSelectedRequest(null);
903
+ }
904
+ switchToDocs();
905
+ }
906
+ }
907
+ }, 0);
908
+ }
909
+ } else {
910
+ // Version change - clear selected endpoint as it may not exist in the new version
911
+ setSelectedRequest(null);
912
+ setSelectedDocSection(null);
913
+ }
914
+ } catch (err) {
915
+ console.error('Error fetching collection:', err);
916
+ setError(err instanceof Error ? err.message : 'Failed to load API documentation');
917
+ } finally{
918
+ setLoading(false);
919
+ setIsVersionLoading(false);
920
+ }
921
+ }
922
+ fetchCollection();
923
+ // eslint-disable-next-line react-hooks/exhaustive-deps
924
+ }, [
925
+ switchToDocs,
926
+ selectedApiVersion
927
+ ]);
928
+ // Only show full-page loading on initial load
929
+ if (loading && !collection) {
930
+ return /*#__PURE__*/ _jsx("div", {
931
+ className: "flex items-center justify-center h-screen",
932
+ children: /*#__PURE__*/ _jsxs("div", {
933
+ className: "text-center",
934
+ children: [
935
+ /*#__PURE__*/ _jsx(Spinner, {
936
+ size: 32,
937
+ className: "text-muted-foreground animate-spin mx-auto mb-3"
938
+ }),
939
+ /*#__PURE__*/ _jsx("p", {
940
+ className: "text-sm text-muted-foreground",
941
+ children: "Loading API documentation..."
942
+ })
943
+ ]
944
+ })
945
+ });
946
+ }
947
+ if (error) {
948
+ return /*#__PURE__*/ _jsx("div", {
949
+ className: "flex items-center justify-center h-screen",
950
+ children: /*#__PURE__*/ _jsxs("div", {
951
+ className: "text-center",
952
+ children: [
953
+ /*#__PURE__*/ _jsx("p", {
954
+ className: "text-destructive text-lg mb-2",
955
+ children: "Error loading documentation"
956
+ }),
957
+ /*#__PURE__*/ _jsx("p", {
958
+ className: "text-muted-foreground",
959
+ children: error
960
+ })
961
+ ]
962
+ })
963
+ });
964
+ }
965
+ if (!collection) {
966
+ return /*#__PURE__*/ _jsx("div", {
967
+ className: "flex items-center justify-center h-screen",
968
+ children: /*#__PURE__*/ _jsxs("div", {
969
+ className: "text-center max-w-md",
970
+ children: [
971
+ /*#__PURE__*/ _jsx("p", {
972
+ className: "text-muted-foreground mb-2",
973
+ children: "No API documentation available"
974
+ }),
975
+ /*#__PURE__*/ _jsx("p", {
976
+ className: "text-sm text-muted-foreground",
977
+ children: "Please configure your Brainfish API credentials in your environment variables."
978
+ })
979
+ ]
980
+ })
981
+ });
982
+ }
983
+ // Only show "configure credentials" if there are no endpoints AND no doc groups
984
+ // Multi-tenant docs may have only doc groups without API endpoints
985
+ const hasDocGroups = collection.docGroups && collection.docGroups.length > 0;
986
+ const hasEndpoints = collection.requests.length > 0 || collection.folders.length > 0;
987
+ if (!hasEndpoints && !hasDocGroups) {
988
+ return /*#__PURE__*/ _jsx("div", {
989
+ className: "flex items-center justify-center h-screen",
990
+ children: /*#__PURE__*/ _jsxs("div", {
991
+ className: "text-center max-w-lg p-8",
992
+ children: [
993
+ /*#__PURE__*/ _jsx("h2", {
994
+ className: "text-2xl font-semibold mb-2",
995
+ children: collection.name || 'Documentation'
996
+ }),
997
+ /*#__PURE__*/ _jsx("p", {
998
+ className: "text-muted-foreground mb-6",
999
+ children: collection.description || 'No documentation content available yet.'
1000
+ }),
1001
+ /*#__PURE__*/ _jsxs("div", {
1002
+ className: "bg-muted/50 rounded-lg p-5 text-left text-sm space-y-4",
1003
+ children: [
1004
+ /*#__PURE__*/ _jsx("p", {
1005
+ className: "font-medium",
1006
+ children: "Get started with DevDoc:"
1007
+ }),
1008
+ /*#__PURE__*/ _jsxs("div", {
1009
+ className: "space-y-3",
1010
+ children: [
1011
+ /*#__PURE__*/ _jsxs("div", {
1012
+ children: [
1013
+ /*#__PURE__*/ _jsx("p", {
1014
+ className: "text-muted-foreground text-xs mb-1",
1015
+ children: "Create a new project"
1016
+ }),
1017
+ /*#__PURE__*/ _jsx("code", {
1018
+ className: "block bg-background px-3 py-2 rounded-md font-mono text-xs",
1019
+ children: "npx create-devdoc-doc my-docs"
1020
+ })
1021
+ ]
1022
+ }),
1023
+ /*#__PURE__*/ _jsxs("div", {
1024
+ children: [
1025
+ /*#__PURE__*/ _jsx("p", {
1026
+ className: "text-muted-foreground text-xs mb-1",
1027
+ children: "Start local development"
1028
+ }),
1029
+ /*#__PURE__*/ _jsx("code", {
1030
+ className: "block bg-background px-3 py-2 rounded-md font-mono text-xs",
1031
+ children: "npx devdoc dev"
1032
+ })
1033
+ ]
1034
+ }),
1035
+ /*#__PURE__*/ _jsxs("div", {
1036
+ children: [
1037
+ /*#__PURE__*/ _jsx("p", {
1038
+ className: "text-muted-foreground text-xs mb-1",
1039
+ children: "Deploy to production"
1040
+ }),
1041
+ /*#__PURE__*/ _jsx("code", {
1042
+ className: "block bg-background px-3 py-2 rounded-md font-mono text-xs",
1043
+ children: "npx devdoc deploy"
1044
+ })
1045
+ ]
1046
+ })
1047
+ ]
1048
+ }),
1049
+ /*#__PURE__*/ _jsxs("a", {
1050
+ href: "https://devdoc.sh",
1051
+ target: "_blank",
1052
+ rel: "noopener noreferrer",
1053
+ className: "inline-flex items-center gap-1.5 text-primary hover:underline text-sm font-medium",
1054
+ children: [
1055
+ "Learn more at devdoc.sh",
1056
+ /*#__PURE__*/ _jsx("svg", {
1057
+ className: "h-3.5 w-3.5",
1058
+ fill: "none",
1059
+ viewBox: "0 0 24 24",
1060
+ stroke: "currentColor",
1061
+ strokeWidth: 2,
1062
+ children: /*#__PURE__*/ _jsx("path", {
1063
+ strokeLinecap: "round",
1064
+ strokeLinejoin: "round",
1065
+ d: "M10 6H6a2 2 0 00-2 2v10a2 2 0 002 2h10a2 2 0 002-2v-4M14 4h6m0 0v6m0-6L10 14"
1066
+ })
1067
+ })
1068
+ ]
1069
+ })
1070
+ ]
1071
+ })
1072
+ ]
1073
+ })
1074
+ });
1075
+ }
1076
+ return /*#__PURE__*/ _jsx(NavigationProvider, {
1077
+ collection: collection,
1078
+ onSelectRequest: handleSelectRequest,
1079
+ children: /*#__PURE__*/ _jsx(DocsWithMode, {
1080
+ collection: collection,
1081
+ selectedRequest: selectedRequest,
1082
+ selectedDocSection: selectedDocSection,
1083
+ selectedDocPage: selectedDocPage,
1084
+ activeTab: activeTab,
1085
+ onTabChange: handleTabChange,
1086
+ contentRef: contentRef,
1087
+ showAuthModal: showAuthModal,
1088
+ setShowAuthModal: setShowAuthModal,
1089
+ handleSelectRequest: handleSelectRequest,
1090
+ handleSelectDocumentation: handleSelectDocumentation,
1091
+ handleSelectDocPage: handleSelectDocPage,
1092
+ handleDebugRequest: handleDebugRequest,
1093
+ handleExplainRequest: handleExplainRequest,
1094
+ handleAgentNavigate: handleAgentNavigate,
1095
+ handleAgentPrefill: handleAgentPrefill,
1096
+ debugContext: debugContext,
1097
+ clearDebugContext: clearDebugContext,
1098
+ explainContext: explainContext,
1099
+ clearExplainContext: clearExplainContext,
1100
+ navigateAndHighlight: navigateAndHighlight,
1101
+ selectedApiVersion: selectedApiVersion,
1102
+ handleApiVersionChange: handleApiVersionChange,
1103
+ isVersionLoading: isVersionLoading,
1104
+ notFoundSlug: notFoundSlug
1105
+ })
1106
+ });
1107
+ }
1108
+ // Mode toggle tabs - switches between Docs, API Client, and Notes
1109
+ function ModeToggleTabs({ hasEndpoint }) {
1110
+ const { mode, switchToDocs, switchToApiClient, switchToNotes } = useModeContext();
1111
+ return /*#__PURE__*/ _jsxs("div", {
1112
+ className: "flex items-center gap-1 p-1 rounded-lg bg-muted/50 shrink-0",
1113
+ children: [
1114
+ /*#__PURE__*/ _jsxs(Button, {
1115
+ variant: mode === 'docs' ? 'secondary' : 'ghost',
1116
+ size: "sm",
1117
+ onClick: ()=>switchToDocs(),
1118
+ className: cn("text-xs h-7 px-2 sm:px-3 gap-1.5", mode === 'docs' ? 'bg-background shadow-sm' : 'text-muted-foreground hover:text-foreground'),
1119
+ children: [
1120
+ /*#__PURE__*/ _jsx(Book, {
1121
+ className: "h-3.5 w-3.5",
1122
+ weight: "bold"
1123
+ }),
1124
+ /*#__PURE__*/ _jsx("span", {
1125
+ className: "hidden xs:inline",
1126
+ children: "Docs"
1127
+ })
1128
+ ]
1129
+ }),
1130
+ hasEndpoint && /*#__PURE__*/ _jsxs(Button, {
1131
+ variant: mode === 'api_client' ? 'secondary' : 'ghost',
1132
+ size: "sm",
1133
+ onClick: ()=>switchToApiClient(),
1134
+ className: cn("text-xs h-7 px-2 sm:px-3 gap-1.5", mode === 'api_client' ? 'bg-background shadow-sm' : 'text-muted-foreground hover:text-foreground'),
1135
+ children: [
1136
+ /*#__PURE__*/ _jsx(TestTube, {
1137
+ className: "h-3.5 w-3.5",
1138
+ weight: "bold"
1139
+ }),
1140
+ /*#__PURE__*/ _jsx("span", {
1141
+ className: "hidden xs:inline",
1142
+ children: "API Client"
1143
+ })
1144
+ ]
1145
+ }),
1146
+ /*#__PURE__*/ _jsxs(Button, {
1147
+ variant: mode === 'notes' ? 'secondary' : 'ghost',
1148
+ size: "sm",
1149
+ onClick: ()=>switchToNotes(),
1150
+ className: cn("text-xs h-7 px-2 sm:px-3 gap-1.5", mode === 'notes' ? 'bg-background shadow-sm' : 'text-muted-foreground hover:text-foreground'),
1151
+ children: [
1152
+ /*#__PURE__*/ _jsx(Code, {
1153
+ className: "h-3.5 w-3.5",
1154
+ weight: "bold"
1155
+ }),
1156
+ /*#__PURE__*/ _jsx("span", {
1157
+ className: "hidden xs:inline",
1158
+ children: "Sandbox"
1159
+ })
1160
+ ]
1161
+ })
1162
+ ]
1163
+ });
1164
+ }
1165
+ function DocsWithMode({ collection, selectedRequest, selectedDocSection, selectedDocPage, activeTab, onTabChange, contentRef, showAuthModal, setShowAuthModal, handleSelectRequest, handleSelectDocumentation, handleSelectDocPage, handleDebugRequest, handleExplainRequest, handleAgentNavigate, handleAgentPrefill, debugContext, clearDebugContext, explainContext, clearExplainContext, navigateAndHighlight, selectedApiVersion, handleApiVersionChange, isVersionLoading, notFoundSlug }) {
1166
+ const { mode, switchToDocs } = useModeContext();
1167
+ const { setTheme } = useTheme();
1168
+ // GraphQL state
1169
+ const [graphqlOperations, setGraphqlOperations] = useState([]);
1170
+ const [graphqlCollection, setGraphqlCollection] = useState(null);
1171
+ const [selectedGraphQLOperation, setSelectedGraphQLOperation] = useState(null);
1172
+ // Get API spec URL from environment or collection
1173
+ const apiSpecUrl = process.env.NEXT_PUBLIC_OPENAPI_URL || collection.name || 'default';
1174
+ // Check if there are endpoints
1175
+ const hasEndpoints = collection.folders.length > 0 || collection.requests.length > 0;
1176
+ // Search functionality
1177
+ const { isOpen: searchOpen, setIsOpen: setSearchOpen, openSearch, searchItems } = useSearch({
1178
+ requests: collection.requests,
1179
+ folders: collection.folders,
1180
+ docGroups: collection.docGroups
1181
+ });
1182
+ // Handle search item selection - use URL hash navigation
1183
+ const handleSearchSelect = useCallback((item)=>{
1184
+ if (item.type === 'endpoint') {
1185
+ // Navigate to endpoint via hash - format: #api-reference/endpoint/{id}
1186
+ window.location.hash = `api-reference/endpoint/${item.id}`;
1187
+ } else if (item.type === 'doc') {
1188
+ // Navigate to doc page via hash - the href already has the correct format
1189
+ // Extract tab and path from href (e.g., #guides/page/quickstart)
1190
+ const hashPath = item.href.replace('#', '');
1191
+ window.location.hash = hashPath;
1192
+ }
1193
+ }, []);
1194
+ // Wrap agent navigate to switch to Docs mode and navigate to endpoint
1195
+ const handleAgentNavigateWithModeSwitch = useCallback((endpointId)=>{
1196
+ // Just navigate - handleAgentNavigate already sets the tab via setActiveTab
1197
+ handleAgentNavigate(endpointId);
1198
+ }, [
1199
+ handleAgentNavigate
1200
+ ]);
1201
+ // Get the current content title for header
1202
+ // Find the active tab's config
1203
+ const activeTabConfig = collection.navigationTabs?.find((t)=>t.id === activeTab);
1204
+ const activeTabType = activeTabConfig?.type || 'docs';
1205
+ // Filter doc groups for sidebar based on active tab
1206
+ // Group IDs are like "group-guides-getting-started", tab IDs are like "guides"
1207
+ // Filter doc groups for sidebar based on active tab
1208
+ // Group IDs are formatted as: group-{tab-id}-{group-name}
1209
+ const filteredDocGroups = collection.docGroups?.filter((g)=>isGroupForTab(g.id, activeTab)) || [];
1210
+ // Show endpoints in sidebar only when OpenAPI tab is active
1211
+ const showEndpoints = activeTabType === 'openapi';
1212
+ // Show changelog when changelog tab is active
1213
+ const showChangelog = activeTabType === 'changelog';
1214
+ // Show GraphQL playground when graphql tab is active
1215
+ const showGraphQL = activeTabType === 'graphql';
1216
+ const activeGraphQLSchemas = activeTabConfig?.graphqlSchemas || [];
1217
+ // Get the first schema path for stable dependency
1218
+ const schemaPath = activeGraphQLSchemas[0]?.schema;
1219
+ const schemaEndpoint = activeGraphQLSchemas[0]?.endpoint;
1220
+ // Load GraphQL operations when graphql tab is active
1221
+ useEffect(()=>{
1222
+ if (!showGraphQL || !schemaPath) {
1223
+ setGraphqlOperations([]);
1224
+ setGraphqlCollection(null);
1225
+ setSelectedGraphQLOperation(null); // Clear selection when leaving GraphQL tab
1226
+ return;
1227
+ }
1228
+ // Load and parse GraphQL schema
1229
+ const loadGraphQLSchema = async ()=>{
1230
+ try {
1231
+ const response = await fetch(`/api/schema?path=${encodeURIComponent(schemaPath)}`);
1232
+ if (!response.ok) return;
1233
+ const schemaContent = await response.text();
1234
+ const operations = parseGraphQLSchema(schemaContent);
1235
+ setGraphqlOperations(operations);
1236
+ // Convert to BrainfishCollection for sidebar
1237
+ const gqlCollection = convertGraphQLToCollection(operations, schemaEndpoint || '');
1238
+ setGraphqlCollection(gqlCollection);
1239
+ } catch (err) {
1240
+ console.error('Failed to load GraphQL schema:', err);
1241
+ }
1242
+ };
1243
+ loadGraphQLSchema();
1244
+ }, [
1245
+ showGraphQL,
1246
+ schemaPath,
1247
+ schemaEndpoint
1248
+ ]);
1249
+ // Auto-select GraphQL operation from URL hash or default to first operation
1250
+ useEffect(()=>{
1251
+ if (!showGraphQL || graphqlOperations.length === 0) {
1252
+ return;
1253
+ }
1254
+ // Check if there's a selection in the URL hash first
1255
+ const hash = window.location.hash.slice(1) // Remove #
1256
+ ;
1257
+ if (hash) {
1258
+ const parts = hash.split('/');
1259
+ const hashType = parts[1];
1260
+ const hashId = parts.slice(2).join('/');
1261
+ if (hashType === 'endpoint' && hashId) {
1262
+ // Try to find and select the operation from the URL hash
1263
+ const operation = graphqlOperations.find((op)=>op.id === hashId);
1264
+ if (operation) {
1265
+ setSelectedGraphQLOperation(operation);
1266
+ return;
1267
+ }
1268
+ }
1269
+ }
1270
+ // If already have a selection, don't override it
1271
+ if (selectedGraphQLOperation) {
1272
+ return;
1273
+ }
1274
+ // Check if there are doc groups for this tab first
1275
+ const hasGroups = hasDocGroupsForTab(collection?.docGroups, activeTab);
1276
+ if (!hasGroups) {
1277
+ // No doc groups - auto-select first GraphQL operation
1278
+ const firstOperation = graphqlOperations[0];
1279
+ setSelectedGraphQLOperation(firstOperation);
1280
+ window.history.pushState(null, '', `#${activeTab}/endpoint/${firstOperation.id}`);
1281
+ }
1282
+ }, [
1283
+ showGraphQL,
1284
+ graphqlOperations,
1285
+ selectedGraphQLOperation,
1286
+ activeTab,
1287
+ collection?.docGroups
1288
+ ]);
1289
+ // Handle GraphQL operation selection from sidebar
1290
+ const handleSelectGraphQLOperation = useCallback((request)=>{
1291
+ // Find the matching GraphQL operation
1292
+ const operation = graphqlOperations.find((op)=>op.id === request.id);
1293
+ if (operation) {
1294
+ setSelectedGraphQLOperation(operation);
1295
+ // Update URL hash
1296
+ window.history.pushState(null, '', `#${activeTab}/endpoint/${request.id}`);
1297
+ switchToDocs();
1298
+ }
1299
+ }, [
1300
+ graphqlOperations,
1301
+ activeTab,
1302
+ switchToDocs
1303
+ ]);
1304
+ // Inject custom CSS and color variables
1305
+ useEffect(()=>{
1306
+ // Create or update style element for custom CSS
1307
+ let styleEl = document.getElementById('docs-custom-css');
1308
+ if (!styleEl) {
1309
+ styleEl = document.createElement('style');
1310
+ styleEl.id = 'docs-custom-css';
1311
+ document.head.appendChild(styleEl);
1312
+ }
1313
+ // Build CSS with color variables
1314
+ let cssContent = '';
1315
+ // Add color variables if provided
1316
+ // We set both --docs-primary (for custom CSS) and --primary (for Tailwind's bg-primary class)
1317
+ if (collection.docsColors) {
1318
+ const colors = collection.docsColors;
1319
+ cssContent += `:root {\n`;
1320
+ if (colors.primary) {
1321
+ cssContent += ` --docs-primary: ${colors.primary};\n`;
1322
+ cssContent += ` --primary: ${colors.primary};\n`;
1323
+ }
1324
+ if (colors.primaryLight) cssContent += ` --docs-primary-light: ${colors.primaryLight};\n`;
1325
+ if (colors.primaryDark) cssContent += ` --docs-primary-dark: ${colors.primaryDark};\n`;
1326
+ cssContent += `}\n`;
1327
+ // Also set for dark mode
1328
+ cssContent += `.dark {\n`;
1329
+ if (colors.primary) cssContent += ` --primary: ${colors.primary};\n`;
1330
+ cssContent += `}\n\n`;
1331
+ }
1332
+ // Add custom CSS if provided
1333
+ if (collection.customCss) {
1334
+ cssContent += collection.customCss;
1335
+ }
1336
+ styleEl.textContent = cssContent;
1337
+ return ()=>{
1338
+ // Cleanup on unmount
1339
+ const el = document.getElementById('docs-custom-css');
1340
+ if (el) el.remove();
1341
+ };
1342
+ }, [
1343
+ collection.customCss,
1344
+ collection.docsColors
1345
+ ]);
1346
+ // Apply default theme from theme.json on initial load
1347
+ // Use a ref to track if we've already applied the default theme
1348
+ const hasAppliedDefaultTheme = useRef(false);
1349
+ useEffect(()=>{
1350
+ if (collection?.defaultTheme && !hasAppliedDefaultTheme.current) {
1351
+ setTheme(collection.defaultTheme);
1352
+ hasAppliedDefaultTheme.current = true;
1353
+ }
1354
+ }, [
1355
+ collection?.defaultTheme,
1356
+ setTheme
1357
+ ]);
1358
+ return /*#__PURE__*/ _jsxs("div", {
1359
+ className: "docs-viewer-root flex flex-col h-screen overflow-hidden",
1360
+ children: [
1361
+ collection.notice && /*#__PURE__*/ _jsx(Notice, {
1362
+ config: collection.notice,
1363
+ storageKey: "docs-notice"
1364
+ }),
1365
+ /*#__PURE__*/ _jsx(SearchDialog, {
1366
+ open: searchOpen,
1367
+ onOpenChange: setSearchOpen,
1368
+ items: searchItems,
1369
+ onSelect: handleSearchSelect
1370
+ }),
1371
+ /*#__PURE__*/ _jsx(DocsHeader, {
1372
+ docGroups: collection.docGroups,
1373
+ navigationTabs: collection.navigationTabs,
1374
+ activeTab: activeTab,
1375
+ onTabChange: onTabChange,
1376
+ hasEndpoints: hasEndpoints,
1377
+ docsName: collection.docsName,
1378
+ docsLogo: collection.docsLogo,
1379
+ onSearchClick: openSearch,
1380
+ docsHeader: collection.docsHeader,
1381
+ docsNavbar: collection.docsNavbar
1382
+ }),
1383
+ /*#__PURE__*/ _jsxs("div", {
1384
+ className: "docs-layout flex flex-1 overflow-hidden relative z-0 min-h-0",
1385
+ children: [
1386
+ !showChangelog && /*#__PURE__*/ _jsx(DocsSidebar, {
1387
+ collection: {
1388
+ ...collection,
1389
+ // Show GraphQL operations when GraphQL tab is active, else show REST endpoints
1390
+ folders: showGraphQL && graphqlCollection ? graphqlCollection.folders : showEndpoints ? collection.folders : [],
1391
+ requests: showGraphQL && graphqlCollection ? graphqlCollection.requests : showEndpoints ? collection.requests : [],
1392
+ // Only show filtered doc groups
1393
+ docGroups: filteredDocGroups
1394
+ },
1395
+ selectedRequest: showGraphQL ? selectedGraphQLOperation ? {
1396
+ id: selectedGraphQLOperation.id
1397
+ } : null : selectedRequest,
1398
+ selectedDocSection: selectedDocSection,
1399
+ selectedDocPage: selectedDocPage,
1400
+ activeTab: activeTab,
1401
+ onSelectRequest: showGraphQL ? handleSelectGraphQLOperation : handleSelectRequest,
1402
+ onSelectDocumentation: handleSelectDocumentation,
1403
+ onSelectDocPage: handleSelectDocPage,
1404
+ apiVersions: collection.apiVersions,
1405
+ selectedApiVersion: selectedApiVersion,
1406
+ onApiVersionChange: handleApiVersionChange,
1407
+ isVersionLoading: isVersionLoading
1408
+ }),
1409
+ /*#__PURE__*/ _jsxs("div", {
1410
+ className: "docs-main flex-1 flex flex-col overflow-hidden",
1411
+ style: {
1412
+ minWidth: 0,
1413
+ flexBasis: 0,
1414
+ flexGrow: 1
1415
+ },
1416
+ children: [
1417
+ /*#__PURE__*/ _jsx("div", {
1418
+ className: "docs-main-header flex items-center justify-end px-3 sm:px-4 h-[41px] border-b border-border bg-muted/30 flex-shrink-0",
1419
+ children: /*#__PURE__*/ _jsx(ModeToggleTabs, {
1420
+ hasEndpoint: !!selectedRequest
1421
+ })
1422
+ }),
1423
+ mode === 'docs' ? /*#__PURE__*/ _jsx(DocsNavigationProvider, {
1424
+ onNavigateToPage: handleSelectDocPage,
1425
+ onSwitchTab: onTabChange,
1426
+ activeTab: activeTab,
1427
+ children: /*#__PURE__*/ _jsx("div", {
1428
+ ref: contentRef,
1429
+ className: cn("docs-content-area flex-1 bg-background min-w-0", showChangelog || showGraphQL && selectedGraphQLOperation ? "overflow-hidden flex flex-col" : "overflow-y-auto scroll-smooth"),
1430
+ children: showGraphQL && selectedGraphQLOperation ? /*#__PURE__*/ _jsx("div", {
1431
+ className: "flex-1 flex flex-col h-full",
1432
+ children: /*#__PURE__*/ _jsx(GraphQLPlayground, {
1433
+ endpoint: activeGraphQLSchemas[0]?.endpoint || '',
1434
+ defaultQuery: selectedGraphQLOperation?.query,
1435
+ operations: graphqlOperations,
1436
+ selectedOperationId: selectedGraphQLOperation?.id,
1437
+ hideExplorer: true,
1438
+ headers: {},
1439
+ theme: "dark"
1440
+ })
1441
+ }) : showChangelog ? /*#__PURE__*/ _jsx(ChangelogPage, {
1442
+ releases: collection.changelogReleases || [],
1443
+ tabName: activeTabConfig?.tab
1444
+ }) : selectedRequest ? /*#__PURE__*/ _jsx(RequestDetails, {
1445
+ request: selectedRequest
1446
+ }) : selectedDocPage ? /*#__PURE__*/ _jsx(DocPage, {
1447
+ slug: selectedDocPage,
1448
+ onSearch: openSearch
1449
+ }) : notFoundSlug ? /*#__PURE__*/ _jsx(NotFoundPage, {
1450
+ slug: notFoundSlug,
1451
+ onSearch: openSearch
1452
+ }) : /*#__PURE__*/ _jsx("div", {
1453
+ className: "flex-1 flex items-center justify-center bg-background",
1454
+ children: /*#__PURE__*/ _jsxs("div", {
1455
+ className: "text-center text-muted-foreground",
1456
+ children: [
1457
+ /*#__PURE__*/ _jsx(Book, {
1458
+ className: "h-12 w-12 mx-auto mb-3 opacity-40"
1459
+ }),
1460
+ /*#__PURE__*/ _jsx("p", {
1461
+ className: "text-sm",
1462
+ children: "Select an endpoint from the sidebar"
1463
+ })
1464
+ ]
1465
+ })
1466
+ })
1467
+ })
1468
+ }) : mode === 'notes' ? /*#__PURE__*/ _jsx("div", {
1469
+ className: "flex-1 flex flex-col min-h-0 overflow-hidden",
1470
+ children: /*#__PURE__*/ _jsx(NotesMode, {
1471
+ apiSpecUrl: apiSpecUrl,
1472
+ apiName: collection.name
1473
+ })
1474
+ }) : selectedRequest ? /*#__PURE__*/ _jsx("div", {
1475
+ className: "flex-1 flex flex-col min-h-0 overflow-hidden",
1476
+ children: /*#__PURE__*/ _jsx(ApiPlayground, {
1477
+ request: selectedRequest,
1478
+ onDebugRequest: handleDebugRequest,
1479
+ onExplainRequest: handleExplainRequest
1480
+ })
1481
+ }) : /*#__PURE__*/ _jsx("div", {
1482
+ className: "flex-1 flex items-center justify-center bg-background",
1483
+ children: /*#__PURE__*/ _jsxs("div", {
1484
+ className: "text-center text-muted-foreground",
1485
+ children: [
1486
+ /*#__PURE__*/ _jsx(TestTube, {
1487
+ className: "h-12 w-12 mx-auto mb-3 opacity-40"
1488
+ }),
1489
+ /*#__PURE__*/ _jsx("p", {
1490
+ className: "text-sm",
1491
+ children: "Select an endpoint from the sidebar to test"
1492
+ })
1493
+ ]
1494
+ })
1495
+ })
1496
+ ]
1497
+ }),
1498
+ /*#__PURE__*/ _jsx(RightSidebar, {
1499
+ request: selectedRequest,
1500
+ collection: collection,
1501
+ apiSummary: collection.apiSummary,
1502
+ onNavigateToEndpoint: handleAgentNavigateWithModeSwitch,
1503
+ onPrefillParameters: handleAgentPrefill,
1504
+ debugContext: debugContext,
1505
+ onClearDebugContext: clearDebugContext,
1506
+ explainContext: explainContext,
1507
+ onClearExplainContext: clearExplainContext,
1508
+ onOpenGlobalAuth: ()=>setShowAuthModal(true),
1509
+ onNavigateToAuthTab: ()=>{
1510
+ navigateAndHighlight('auth', {
1511
+ type: 'auth'
1512
+ }, true);
1513
+ },
1514
+ onNavigateToParamsTab: ()=>{
1515
+ navigateAndHighlight('params', {
1516
+ type: 'param'
1517
+ }, true);
1518
+ },
1519
+ onNavigateToBodyTab: ()=>{
1520
+ navigateAndHighlight('body', {
1521
+ type: 'body'
1522
+ }, true);
1523
+ },
1524
+ onNavigateToHeadersTab: ()=>{
1525
+ navigateAndHighlight('headers', {
1526
+ type: 'header'
1527
+ }, true);
1528
+ },
1529
+ onNavigateToDocSection: handleSelectDocumentation,
1530
+ onNavigateToDocPage: handleSelectDocPage
1531
+ })
1532
+ ]
1533
+ }),
1534
+ /*#__PURE__*/ _jsx(GlobalAuthModal, {
1535
+ open: showAuthModal,
1536
+ onClose: ()=>setShowAuthModal(false)
1537
+ })
1538
+ ]
1539
+ });
1540
+ }
1541
+ // Wrapper component with providers
1542
+ export function Docs() {
1543
+ return /*#__PURE__*/ _jsx(AuthProvider, {
1544
+ children: /*#__PURE__*/ _jsx(ModeProvider, {
1545
+ children: /*#__PURE__*/ _jsx(PlaygroundProvider, {
1546
+ children: /*#__PURE__*/ _jsx(PlaygroundNavigationProvider, {
1547
+ children: /*#__PURE__*/ _jsx(DocsContent, {})
1548
+ })
1549
+ })
1550
+ })
1551
+ });
1552
+ }