@brainfish-ai/devdoc 0.1.42 → 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 (388) hide show
  1. package/dist/cli/commands/dev.js +19 -10
  2. package/package.json +3 -2
  3. package/renderer/app/api/assets/[...path]/route.js +108 -0
  4. package/renderer/app/api/assets/route.js +114 -0
  5. package/renderer/app/api/assets/upload/route.js +163 -0
  6. package/renderer/app/api/auth-schemes/route.js +58 -0
  7. package/renderer/app/api/chat/route.js +759 -0
  8. package/renderer/app/api/codegen/route.js +52 -0
  9. package/renderer/app/api/collections/route.js +675 -0
  10. package/renderer/app/api/debug/route.js +47 -0
  11. package/renderer/app/api/deploy/route.js +199 -0
  12. package/renderer/app/api/device/route.js +36 -0
  13. package/renderer/app/api/docs/route.js +205 -0
  14. package/renderer/app/api/domains/add/route.js +121 -0
  15. package/renderer/app/api/domains/lookup/route.js +43 -0
  16. package/renderer/app/api/domains/remove/route.js +89 -0
  17. package/renderer/app/api/domains/status/route.js +140 -0
  18. package/renderer/app/api/domains/verify/route.js +168 -0
  19. package/renderer/app/api/keys/regenerate/route.js +71 -0
  20. package/renderer/app/api/local-assets/[...path]/route.js +108 -0
  21. package/renderer/app/api/openapi-spec/route.js +73 -0
  22. package/renderer/app/api/projects/[slug]/route.js +129 -0
  23. package/renderer/app/api/projects/[slug]/stats/route.js +80 -0
  24. package/renderer/app/api/projects/register/route.js +176 -0
  25. package/renderer/app/api/proxy/route.js +139 -0
  26. package/renderer/app/api/proxy-stream/route.js +156 -0
  27. package/renderer/app/api/redirects/route.js +35 -0
  28. package/renderer/app/api/schema/route.js +85 -0
  29. package/renderer/app/api/subdomains/check/route.js +158 -0
  30. package/renderer/app/api/suggestions/route.js +175 -0
  31. package/renderer/app/layout.js +47 -0
  32. package/renderer/app/llms-full.txt/route.js +257 -0
  33. package/renderer/app/llms.txt/route.js +219 -0
  34. package/renderer/app/page.js +12 -0
  35. package/renderer/app/robots.txt/route.js +66 -0
  36. package/renderer/app/sitemap.xml/route.js +145 -0
  37. package/renderer/components/docs/index.js +8 -0
  38. package/renderer/components/docs/mdx/accordion.js +113 -0
  39. package/renderer/components/docs/mdx/badge.js +72 -0
  40. package/renderer/components/docs/mdx/callouts.js +137 -0
  41. package/renderer/components/docs/mdx/cards.js +175 -0
  42. package/renderer/components/docs/mdx/changelog.js +100 -0
  43. package/renderer/components/docs/mdx/code-block.js +147 -0
  44. package/renderer/components/docs/mdx/code-group.js +287 -0
  45. package/renderer/components/docs/mdx/file-embeds.js +82 -0
  46. package/renderer/components/docs/mdx/frame.js +59 -0
  47. package/renderer/components/docs/mdx/highlight.js +90 -0
  48. package/renderer/components/docs/mdx/iframe.js +69 -0
  49. package/renderer/components/docs/mdx/image.js +135 -0
  50. package/renderer/components/docs/mdx/index.js +134 -0
  51. package/renderer/components/docs/mdx/landing.js +315 -0
  52. package/renderer/components/docs/mdx/mermaid.js +212 -0
  53. package/renderer/components/docs/mdx/param-field.js +112 -0
  54. package/renderer/components/docs/mdx/steps.js +74 -0
  55. package/renderer/components/docs/mdx/tabs.js +50 -0
  56. package/renderer/components/docs/mdx-renderer.js +77 -0
  57. package/renderer/components/docs/navigation/breadcrumbs.js +64 -0
  58. package/renderer/components/docs/navigation/index.js +6 -0
  59. package/renderer/components/docs/navigation/page-nav.js +57 -0
  60. package/renderer/components/docs/navigation/sidebar.js +375 -0
  61. package/renderer/components/docs/navigation/toc.js +89 -0
  62. package/renderer/components/docs/notice.js +77 -0
  63. package/renderer/components/docs-header.js +202 -0
  64. package/renderer/components/docs-viewer/agent/agent-chat.js +1930 -0
  65. package/renderer/components/docs-viewer/agent/cards/debug-context-card.js +107 -0
  66. package/renderer/components/docs-viewer/agent/cards/endpoint-context-card.js +57 -0
  67. package/renderer/components/docs-viewer/agent/cards/index.js +45 -0
  68. package/renderer/components/docs-viewer/agent/cards/response-options-card.js +154 -0
  69. package/renderer/components/docs-viewer/agent/cards/types.js +22 -0
  70. package/renderer/components/docs-viewer/agent/chat-message.js +2 -0
  71. package/renderer/components/docs-viewer/agent/index.js +4 -0
  72. package/renderer/components/docs-viewer/agent/messages/assistant-message.js +108 -0
  73. package/renderer/components/docs-viewer/agent/messages/chat-message.js +34 -0
  74. package/renderer/components/docs-viewer/agent/messages/index.js +6 -0
  75. package/renderer/components/docs-viewer/agent/messages/tool-call-display.js +1065 -0
  76. package/renderer/components/docs-viewer/agent/messages/types.js +2 -0
  77. package/renderer/components/docs-viewer/agent/messages/typing-indicator.js +26 -0
  78. package/renderer/components/docs-viewer/agent/messages/user-message.js +37 -0
  79. package/renderer/components/docs-viewer/code-editor/{index.tsx → index.js} +1 -1
  80. package/renderer/components/docs-viewer/code-editor/notes-mode.js +1338 -0
  81. package/renderer/components/docs-viewer/content/changelog-page.js +297 -0
  82. package/renderer/components/docs-viewer/content/doc-page.js +264 -0
  83. package/renderer/components/docs-viewer/content/documentation-viewer.js +14 -0
  84. package/renderer/components/docs-viewer/content/index.js +29 -0
  85. package/renderer/components/docs-viewer/content/not-found-page.js +300 -0
  86. package/renderer/components/docs-viewer/content/request-details.js +528 -0
  87. package/renderer/components/docs-viewer/content/sections/auth.js +108 -0
  88. package/renderer/components/docs-viewer/content/sections/body.js +80 -0
  89. package/renderer/components/docs-viewer/content/sections/headers.js +64 -0
  90. package/renderer/components/docs-viewer/content/sections/overview.js +56 -0
  91. package/renderer/components/docs-viewer/content/sections/parameters.js +64 -0
  92. package/renderer/components/docs-viewer/content/sections/responses.js +91 -0
  93. package/renderer/components/docs-viewer/global-auth-modal.js +427 -0
  94. package/renderer/components/docs-viewer/index.js +1552 -0
  95. package/renderer/components/docs-viewer/playground/auth-editor.js +418 -0
  96. package/renderer/components/docs-viewer/playground/body-editor.js +240 -0
  97. package/renderer/components/docs-viewer/playground/code-editor.js +135 -0
  98. package/renderer/components/docs-viewer/playground/code-snippet.js +393 -0
  99. package/renderer/components/docs-viewer/playground/graphql-playground.js +734 -0
  100. package/renderer/components/docs-viewer/playground/index.js +682 -0
  101. package/renderer/components/docs-viewer/playground/key-value-editor.js +317 -0
  102. package/renderer/components/docs-viewer/playground/method-selector.js +65 -0
  103. package/renderer/components/docs-viewer/playground/request-builder.js +181 -0
  104. package/renderer/components/docs-viewer/playground/request-tabs.js +240 -0
  105. package/renderer/components/docs-viewer/playground/response-cards/idle-card.js +42 -0
  106. package/renderer/components/docs-viewer/playground/response-cards/index.js +72 -0
  107. package/renderer/components/docs-viewer/playground/response-cards/loading-card.js +24 -0
  108. package/renderer/components/docs-viewer/playground/response-cards/network-error-card.js +28 -0
  109. package/renderer/components/docs-viewer/playground/response-cards/response-body-card.js +308 -0
  110. package/renderer/components/docs-viewer/playground/response-cards/types.js +9 -0
  111. package/renderer/components/docs-viewer/playground/response-viewer.js +18 -0
  112. package/renderer/components/docs-viewer/search/index.js +2 -0
  113. package/renderer/components/docs-viewer/search/search-dialog.js +367 -0
  114. package/renderer/components/docs-viewer/search/use-search.js +89 -0
  115. package/renderer/components/docs-viewer/shared/markdown-renderer.js +423 -0
  116. package/renderer/components/docs-viewer/shared/method-badge.js +23 -0
  117. package/renderer/components/docs-viewer/shared/schema-viewer.js +321 -0
  118. package/renderer/components/docs-viewer/sidebar/collection-tree.js +222 -0
  119. package/renderer/components/docs-viewer/sidebar/endpoint-options.js +512 -0
  120. package/renderer/components/docs-viewer/sidebar/index.js +196 -0
  121. package/renderer/components/docs-viewer/sidebar/right-sidebar.js +163 -0
  122. package/renderer/components/docs-viewer/sidebar/sidebar-group.js +87 -0
  123. package/renderer/components/docs-viewer/sidebar/sidebar-item.js +172 -0
  124. package/renderer/components/docs-viewer/sidebar/sidebar-section.js +31 -0
  125. package/renderer/components/theme-provider.js +10 -0
  126. package/renderer/components/theme-toggle.js +106 -0
  127. package/renderer/components/ui/badge.js +29 -0
  128. package/renderer/components/ui/button.js +40 -0
  129. package/renderer/components/ui/dialog.js +50 -0
  130. package/renderer/components/ui/dropdown-menu.js +143 -0
  131. package/renderer/components/ui/input.js +12 -0
  132. package/renderer/components/ui/label.js +13 -0
  133. package/renderer/components/ui/navigation-menu.js +83 -0
  134. package/renderer/components/ui/select.js +116 -0
  135. package/renderer/components/ui/spinner.js +92 -0
  136. package/renderer/components/ui/tabs.js +34 -0
  137. package/renderer/components/ui/tooltip.js +43 -0
  138. package/renderer/hooks/use-code-copy.js +76 -0
  139. package/renderer/hooks/use-openapi-title.js +33 -0
  140. package/renderer/lib/api-docs/agent/index.js +4 -0
  141. package/renderer/lib/api-docs/agent/indexer.js +254 -0
  142. package/renderer/lib/api-docs/agent/spec-summary.js +227 -0
  143. package/renderer/lib/api-docs/agent/types.js +5 -0
  144. package/renderer/lib/api-docs/auth/auth-context.js +157 -0
  145. package/renderer/lib/api-docs/auth/auth-storage.js +66 -0
  146. package/renderer/lib/api-docs/auth/crypto.js +64 -0
  147. package/renderer/lib/api-docs/auth/index.js +3 -0
  148. package/renderer/lib/api-docs/code-editor/db.js +145 -0
  149. package/renderer/lib/api-docs/code-editor/hooks.js +254 -0
  150. package/renderer/lib/api-docs/code-editor/{index.ts → index.js} +3 -4
  151. package/renderer/lib/api-docs/code-editor/mode-context.js +154 -0
  152. package/renderer/lib/api-docs/code-editor/types.js +53 -0
  153. package/renderer/lib/api-docs/codegen/definitions.js +258 -0
  154. package/renderer/lib/api-docs/codegen/har.js +171 -0
  155. package/renderer/lib/api-docs/codegen/index.js +118 -0
  156. package/renderer/lib/api-docs/factories.js +136 -0
  157. package/renderer/lib/api-docs/{index.ts → index.js} +5 -10
  158. package/renderer/lib/api-docs/mobile-context.js +79 -0
  159. package/renderer/lib/api-docs/navigation-context.js +62 -0
  160. package/renderer/lib/api-docs/parsers/graphql/index.js +50 -0
  161. package/renderer/lib/api-docs/parsers/graphql/parser.js +350 -0
  162. package/renderer/lib/api-docs/parsers/graphql/transformer.js +215 -0
  163. package/renderer/lib/api-docs/parsers/graphql/types.js +46 -0
  164. package/renderer/lib/api-docs/parsers/openapi/dereferencer.js +43 -0
  165. package/renderer/lib/api-docs/parsers/openapi/extractors/auth.js +486 -0
  166. package/renderer/lib/api-docs/parsers/openapi/extractors/body.js +295 -0
  167. package/renderer/lib/api-docs/parsers/openapi/extractors/index.js +132 -0
  168. package/renderer/lib/api-docs/parsers/openapi/index.js +127 -0
  169. package/renderer/lib/api-docs/parsers/openapi/transformer.js +192 -0
  170. package/renderer/lib/api-docs/parsers/openapi/validator.js +24 -0
  171. package/renderer/lib/api-docs/playground/context.js +65 -0
  172. package/renderer/lib/api-docs/playground/navigation-context.js +74 -0
  173. package/renderer/lib/api-docs/playground/request-builder.js +163 -0
  174. package/renderer/lib/api-docs/playground/request-runner.js +224 -0
  175. package/renderer/lib/api-docs/playground/types.js +5 -0
  176. package/renderer/lib/api-docs/types.js +23 -0
  177. package/renderer/lib/api-docs/utils.js +212 -0
  178. package/renderer/lib/cache.js +157 -0
  179. package/renderer/lib/docs/config/domain-schema.js +161 -0
  180. package/renderer/lib/docs/config/index.js +5 -0
  181. package/renderer/lib/docs/config/loader.js +113 -0
  182. package/renderer/lib/docs/config/schema.js +269 -0
  183. package/renderer/lib/docs/index.js +8 -0
  184. package/renderer/lib/docs/mdx/compiler.js +128 -0
  185. package/renderer/lib/docs/mdx/frontmatter.js +73 -0
  186. package/renderer/lib/docs/mdx/index.js +8 -0
  187. package/renderer/lib/docs/navigation/generator.js +269 -0
  188. package/renderer/lib/docs/navigation/index.js +4 -0
  189. package/renderer/lib/docs/navigation/types.js +9 -0
  190. package/renderer/lib/docs-navigation-context.js +40 -0
  191. package/renderer/lib/multi-tenant/context.js +80 -0
  192. package/renderer/lib/storage/blob.js +767 -0
  193. package/renderer/lib/utils/icons.js +30 -0
  194. package/renderer/lib/utils.js +5 -0
  195. package/renderer/next.config.js +62 -0
  196. package/renderer/tsconfig.json +23 -5
  197. package/renderer/app/api/assets/[...path]/route.ts +0 -123
  198. package/renderer/app/api/assets/route.ts +0 -124
  199. package/renderer/app/api/assets/upload/route.ts +0 -177
  200. package/renderer/app/api/auth-schemes/route.ts +0 -77
  201. package/renderer/app/api/chat/route.ts +0 -858
  202. package/renderer/app/api/codegen/route.ts +0 -72
  203. package/renderer/app/api/collections/route.ts +0 -1002
  204. package/renderer/app/api/debug/route.ts +0 -53
  205. package/renderer/app/api/deploy/route.ts +0 -234
  206. package/renderer/app/api/device/route.ts +0 -42
  207. package/renderer/app/api/docs/route.ts +0 -201
  208. package/renderer/app/api/domains/add/route.ts +0 -132
  209. package/renderer/app/api/domains/lookup/route.ts +0 -43
  210. package/renderer/app/api/domains/remove/route.ts +0 -100
  211. package/renderer/app/api/domains/status/route.ts +0 -158
  212. package/renderer/app/api/domains/verify/route.ts +0 -181
  213. package/renderer/app/api/keys/regenerate/route.ts +0 -80
  214. package/renderer/app/api/local-assets/[...path]/route.ts +0 -122
  215. package/renderer/app/api/openapi-spec/route.ts +0 -151
  216. package/renderer/app/api/projects/[slug]/route.ts +0 -153
  217. package/renderer/app/api/projects/[slug]/stats/route.ts +0 -96
  218. package/renderer/app/api/projects/register/route.ts +0 -152
  219. package/renderer/app/api/proxy/route.ts +0 -149
  220. package/renderer/app/api/proxy-stream/route.ts +0 -168
  221. package/renderer/app/api/redirects/route.ts +0 -47
  222. package/renderer/app/api/schema/route.ts +0 -73
  223. package/renderer/app/api/subdomains/check/route.ts +0 -172
  224. package/renderer/app/api/suggestions/route.ts +0 -144
  225. package/renderer/app/layout.tsx +0 -54
  226. package/renderer/app/llms-full.txt/route.ts +0 -346
  227. package/renderer/app/llms.txt/route.ts +0 -279
  228. package/renderer/app/page.tsx +0 -14
  229. package/renderer/app/robots.txt/route.ts +0 -84
  230. package/renderer/app/sitemap.xml/route.ts +0 -199
  231. package/renderer/components/docs/index.ts +0 -12
  232. package/renderer/components/docs/mdx/accordion.tsx +0 -169
  233. package/renderer/components/docs/mdx/badge.tsx +0 -132
  234. package/renderer/components/docs/mdx/callouts.tsx +0 -154
  235. package/renderer/components/docs/mdx/cards.tsx +0 -241
  236. package/renderer/components/docs/mdx/changelog.tsx +0 -120
  237. package/renderer/components/docs/mdx/code-block.tsx +0 -186
  238. package/renderer/components/docs/mdx/code-group.tsx +0 -421
  239. package/renderer/components/docs/mdx/file-embeds.tsx +0 -105
  240. package/renderer/components/docs/mdx/frame.tsx +0 -112
  241. package/renderer/components/docs/mdx/highlight.tsx +0 -151
  242. package/renderer/components/docs/mdx/iframe.tsx +0 -134
  243. package/renderer/components/docs/mdx/image.tsx +0 -235
  244. package/renderer/components/docs/mdx/index.ts +0 -237
  245. package/renderer/components/docs/mdx/landing.tsx +0 -684
  246. package/renderer/components/docs/mdx/mermaid.tsx +0 -240
  247. package/renderer/components/docs/mdx/param-field.tsx +0 -200
  248. package/renderer/components/docs/mdx/steps.tsx +0 -113
  249. package/renderer/components/docs/mdx/tabs.tsx +0 -86
  250. package/renderer/components/docs/mdx-renderer.tsx +0 -100
  251. package/renderer/components/docs/navigation/breadcrumbs.tsx +0 -76
  252. package/renderer/components/docs/navigation/index.ts +0 -8
  253. package/renderer/components/docs/navigation/page-nav.tsx +0 -64
  254. package/renderer/components/docs/navigation/sidebar.tsx +0 -515
  255. package/renderer/components/docs/navigation/toc.tsx +0 -113
  256. package/renderer/components/docs/notice.tsx +0 -105
  257. package/renderer/components/docs-header.tsx +0 -278
  258. package/renderer/components/docs-viewer/agent/agent-chat.tsx +0 -2076
  259. package/renderer/components/docs-viewer/agent/cards/debug-context-card.tsx +0 -90
  260. package/renderer/components/docs-viewer/agent/cards/endpoint-context-card.tsx +0 -49
  261. package/renderer/components/docs-viewer/agent/cards/index.tsx +0 -50
  262. package/renderer/components/docs-viewer/agent/cards/response-options-card.tsx +0 -212
  263. package/renderer/components/docs-viewer/agent/cards/types.ts +0 -84
  264. package/renderer/components/docs-viewer/agent/chat-message.tsx +0 -17
  265. package/renderer/components/docs-viewer/agent/index.tsx +0 -6
  266. package/renderer/components/docs-viewer/agent/messages/assistant-message.tsx +0 -119
  267. package/renderer/components/docs-viewer/agent/messages/chat-message.tsx +0 -46
  268. package/renderer/components/docs-viewer/agent/messages/index.ts +0 -17
  269. package/renderer/components/docs-viewer/agent/messages/tool-call-display.tsx +0 -721
  270. package/renderer/components/docs-viewer/agent/messages/types.ts +0 -61
  271. package/renderer/components/docs-viewer/agent/messages/typing-indicator.tsx +0 -24
  272. package/renderer/components/docs-viewer/agent/messages/user-message.tsx +0 -51
  273. package/renderer/components/docs-viewer/code-editor/notes-mode.tsx +0 -1283
  274. package/renderer/components/docs-viewer/content/changelog-page.tsx +0 -331
  275. package/renderer/components/docs-viewer/content/doc-page.tsx +0 -367
  276. package/renderer/components/docs-viewer/content/documentation-viewer.tsx +0 -17
  277. package/renderer/components/docs-viewer/content/index.tsx +0 -29
  278. package/renderer/components/docs-viewer/content/not-found-page.tsx +0 -330
  279. package/renderer/components/docs-viewer/content/request-details.tsx +0 -330
  280. package/renderer/components/docs-viewer/content/sections/auth.tsx +0 -69
  281. package/renderer/components/docs-viewer/content/sections/body.tsx +0 -66
  282. package/renderer/components/docs-viewer/content/sections/headers.tsx +0 -43
  283. package/renderer/components/docs-viewer/content/sections/overview.tsx +0 -40
  284. package/renderer/components/docs-viewer/content/sections/parameters.tsx +0 -43
  285. package/renderer/components/docs-viewer/content/sections/responses.tsx +0 -87
  286. package/renderer/components/docs-viewer/global-auth-modal.tsx +0 -352
  287. package/renderer/components/docs-viewer/index.tsx +0 -1670
  288. package/renderer/components/docs-viewer/playground/auth-editor.tsx +0 -280
  289. package/renderer/components/docs-viewer/playground/body-editor.tsx +0 -221
  290. package/renderer/components/docs-viewer/playground/code-editor.tsx +0 -224
  291. package/renderer/components/docs-viewer/playground/code-snippet.tsx +0 -387
  292. package/renderer/components/docs-viewer/playground/graphql-playground.tsx +0 -745
  293. package/renderer/components/docs-viewer/playground/index.tsx +0 -671
  294. package/renderer/components/docs-viewer/playground/key-value-editor.tsx +0 -261
  295. package/renderer/components/docs-viewer/playground/method-selector.tsx +0 -60
  296. package/renderer/components/docs-viewer/playground/request-builder.tsx +0 -179
  297. package/renderer/components/docs-viewer/playground/request-tabs.tsx +0 -237
  298. package/renderer/components/docs-viewer/playground/response-cards/idle-card.tsx +0 -21
  299. package/renderer/components/docs-viewer/playground/response-cards/index.tsx +0 -93
  300. package/renderer/components/docs-viewer/playground/response-cards/loading-card.tsx +0 -16
  301. package/renderer/components/docs-viewer/playground/response-cards/network-error-card.tsx +0 -23
  302. package/renderer/components/docs-viewer/playground/response-cards/response-body-card.tsx +0 -268
  303. package/renderer/components/docs-viewer/playground/response-cards/types.ts +0 -82
  304. package/renderer/components/docs-viewer/playground/response-viewer.tsx +0 -43
  305. package/renderer/components/docs-viewer/search/index.ts +0 -2
  306. package/renderer/components/docs-viewer/search/search-dialog.tsx +0 -331
  307. package/renderer/components/docs-viewer/search/use-search.ts +0 -117
  308. package/renderer/components/docs-viewer/shared/markdown-renderer.tsx +0 -431
  309. package/renderer/components/docs-viewer/shared/method-badge.tsx +0 -41
  310. package/renderer/components/docs-viewer/shared/schema-viewer.tsx +0 -349
  311. package/renderer/components/docs-viewer/sidebar/collection-tree.tsx +0 -259
  312. package/renderer/components/docs-viewer/sidebar/endpoint-options.tsx +0 -316
  313. package/renderer/components/docs-viewer/sidebar/index.tsx +0 -282
  314. package/renderer/components/docs-viewer/sidebar/right-sidebar.tsx +0 -202
  315. package/renderer/components/docs-viewer/sidebar/sidebar-group.tsx +0 -118
  316. package/renderer/components/docs-viewer/sidebar/sidebar-item.tsx +0 -212
  317. package/renderer/components/docs-viewer/sidebar/sidebar-section.tsx +0 -38
  318. package/renderer/components/theme-provider.tsx +0 -11
  319. package/renderer/components/theme-toggle.tsx +0 -76
  320. package/renderer/components/ui/badge.tsx +0 -46
  321. package/renderer/components/ui/button.tsx +0 -59
  322. package/renderer/components/ui/dialog.tsx +0 -118
  323. package/renderer/components/ui/dropdown-menu.tsx +0 -257
  324. package/renderer/components/ui/input.tsx +0 -21
  325. package/renderer/components/ui/label.tsx +0 -24
  326. package/renderer/components/ui/navigation-menu.tsx +0 -168
  327. package/renderer/components/ui/select.tsx +0 -190
  328. package/renderer/components/ui/spinner.tsx +0 -114
  329. package/renderer/components/ui/tabs.tsx +0 -66
  330. package/renderer/components/ui/tooltip.tsx +0 -61
  331. package/renderer/hooks/use-code-copy.ts +0 -88
  332. package/renderer/hooks/use-openapi-title.ts +0 -44
  333. package/renderer/lib/api-docs/agent/index.ts +0 -6
  334. package/renderer/lib/api-docs/agent/indexer.ts +0 -323
  335. package/renderer/lib/api-docs/agent/spec-summary.ts +0 -335
  336. package/renderer/lib/api-docs/agent/types.ts +0 -116
  337. package/renderer/lib/api-docs/auth/auth-context.tsx +0 -225
  338. package/renderer/lib/api-docs/auth/auth-storage.ts +0 -87
  339. package/renderer/lib/api-docs/auth/crypto.ts +0 -89
  340. package/renderer/lib/api-docs/auth/index.ts +0 -4
  341. package/renderer/lib/api-docs/code-editor/db.ts +0 -164
  342. package/renderer/lib/api-docs/code-editor/hooks.ts +0 -266
  343. package/renderer/lib/api-docs/code-editor/mode-context.tsx +0 -207
  344. package/renderer/lib/api-docs/code-editor/types.ts +0 -105
  345. package/renderer/lib/api-docs/codegen/definitions.ts +0 -297
  346. package/renderer/lib/api-docs/codegen/har.ts +0 -251
  347. package/renderer/lib/api-docs/codegen/index.ts +0 -159
  348. package/renderer/lib/api-docs/factories.ts +0 -170
  349. package/renderer/lib/api-docs/mobile-context.tsx +0 -112
  350. package/renderer/lib/api-docs/navigation-context.tsx +0 -88
  351. package/renderer/lib/api-docs/parsers/graphql/README.md +0 -129
  352. package/renderer/lib/api-docs/parsers/graphql/index.ts +0 -91
  353. package/renderer/lib/api-docs/parsers/graphql/parser.ts +0 -491
  354. package/renderer/lib/api-docs/parsers/graphql/transformer.ts +0 -246
  355. package/renderer/lib/api-docs/parsers/graphql/types.ts +0 -283
  356. package/renderer/lib/api-docs/parsers/openapi/README.md +0 -32
  357. package/renderer/lib/api-docs/parsers/openapi/dereferencer.ts +0 -60
  358. package/renderer/lib/api-docs/parsers/openapi/extractors/auth.ts +0 -574
  359. package/renderer/lib/api-docs/parsers/openapi/extractors/body.ts +0 -403
  360. package/renderer/lib/api-docs/parsers/openapi/extractors/index.ts +0 -232
  361. package/renderer/lib/api-docs/parsers/openapi/index.ts +0 -171
  362. package/renderer/lib/api-docs/parsers/openapi/transformer.ts +0 -278
  363. package/renderer/lib/api-docs/parsers/openapi/validator.ts +0 -31
  364. package/renderer/lib/api-docs/playground/context.tsx +0 -107
  365. package/renderer/lib/api-docs/playground/navigation-context.tsx +0 -124
  366. package/renderer/lib/api-docs/playground/request-builder.ts +0 -223
  367. package/renderer/lib/api-docs/playground/request-runner.ts +0 -282
  368. package/renderer/lib/api-docs/playground/types.ts +0 -35
  369. package/renderer/lib/api-docs/types.ts +0 -269
  370. package/renderer/lib/api-docs/utils.ts +0 -311
  371. package/renderer/lib/cache.ts +0 -193
  372. package/renderer/lib/docs/config/domain-schema.ts +0 -260
  373. package/renderer/lib/docs/config/index.ts +0 -43
  374. package/renderer/lib/docs/config/loader.ts +0 -142
  375. package/renderer/lib/docs/config/schema.ts +0 -308
  376. package/renderer/lib/docs/index.ts +0 -12
  377. package/renderer/lib/docs/mdx/compiler.ts +0 -176
  378. package/renderer/lib/docs/mdx/frontmatter.ts +0 -91
  379. package/renderer/lib/docs/mdx/index.ts +0 -26
  380. package/renderer/lib/docs/navigation/generator.ts +0 -348
  381. package/renderer/lib/docs/navigation/index.ts +0 -12
  382. package/renderer/lib/docs/navigation/types.ts +0 -123
  383. package/renderer/lib/docs-navigation-context.tsx +0 -80
  384. package/renderer/lib/multi-tenant/context.ts +0 -105
  385. package/renderer/lib/storage/blob.ts +0 -1083
  386. package/renderer/lib/utils/icons.ts +0 -48
  387. package/renderer/lib/utils.ts +0 -6
  388. package/renderer/next.config.ts +0 -76
@@ -0,0 +1,1338 @@
1
+ 'use client';
2
+ import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
3
+ import React, { useState, useCallback, useEffect, useRef, useMemo } from 'react';
4
+ import Editor from '@monaco-editor/react';
5
+ import { File, Folder, FolderOpen, X, FloppyDisk, CaretRight, CaretDown, Spinner, Plus, Minus, Eye, Code, Trash, ArrowsOut, ArrowClockwise } from '@phosphor-icons/react';
6
+ import { Tooltip, TooltipContent, TooltipTrigger } from '@/components/ui/tooltip';
7
+ import { Button } from '@/components/ui/button';
8
+ import { cn } from '@/lib/utils';
9
+ import { useModeContext, useWorkspace, useNotes, useEditorState, getMonacoLanguage, getFileType, supportsPreview } from '@/lib/api-docs/code-editor';
10
+ // VSCode-style file icon with color coding
11
+ function FileIcon({ path, className }) {
12
+ const type = getFileType(path);
13
+ const colorMap = {
14
+ 'javascript': 'text-yellow-400',
15
+ 'typescript': 'text-blue-400',
16
+ 'python': 'text-green-500',
17
+ 'go': 'text-cyan-400',
18
+ 'ruby': 'text-red-400',
19
+ 'php': 'text-purple-400',
20
+ 'shell': 'text-green-400',
21
+ 'markdown': 'text-blue-300',
22
+ 'mermaid': 'text-pink-400',
23
+ 'json': 'text-yellow-500',
24
+ 'yaml': 'text-red-300',
25
+ 'text': 'text-zinc-400'
26
+ };
27
+ return /*#__PURE__*/ _jsx(File, {
28
+ className: cn('h-4 w-4 flex-shrink-0', colorMap[type] || 'text-zinc-400', className),
29
+ weight: "fill"
30
+ });
31
+ }
32
+ function buildFileTree(files) {
33
+ const root = [];
34
+ // Filter out .folder placeholder files - they're only used internally to create folder structure
35
+ const visibleFiles = files.filter((f)=>!f.path.endsWith('.folder') && !f.path.includes('/.folder'));
36
+ const sortedFiles = [
37
+ ...visibleFiles
38
+ ].sort((a, b)=>a.path.localeCompare(b.path));
39
+ for (const file of sortedFiles){
40
+ const parts = file.path.split('/');
41
+ let current = root;
42
+ for(let i = 0; i < parts.length; i++){
43
+ const part = parts[i];
44
+ const isLastPart = i === parts.length - 1;
45
+ const currentPath = parts.slice(0, i + 1).join('/');
46
+ let existing = current.find((n)=>n.name === part);
47
+ if (!existing) {
48
+ existing = {
49
+ name: part,
50
+ path: currentPath,
51
+ isFolder: !isLastPart,
52
+ children: isLastPart ? undefined : [],
53
+ file: isLastPart ? file : undefined
54
+ };
55
+ current.push(existing);
56
+ }
57
+ if (!isLastPart && existing.children) {
58
+ current = existing.children;
59
+ }
60
+ }
61
+ }
62
+ // Sort: folders first, then alphabetically
63
+ const sortNodes = (nodes)=>{
64
+ return nodes.sort((a, b)=>{
65
+ if (a.isFolder !== b.isFolder) return a.isFolder ? -1 : 1;
66
+ return a.name.localeCompare(b.name);
67
+ }).map((node)=>({
68
+ ...node,
69
+ children: node.children ? sortNodes(node.children) : undefined
70
+ }));
71
+ };
72
+ return sortNodes(root);
73
+ }
74
+ function FileTreeItem({ node, depth, activeFile, expandedFolders, onFileClick, onFolderToggle, onDelete }) {
75
+ const isExpanded = expandedFolders.has(node.path);
76
+ const isActive = activeFile === node.path;
77
+ const [showContextMenu, setShowContextMenu] = useState(null);
78
+ // Close context menu
79
+ useEffect(()=>{
80
+ if (showContextMenu) {
81
+ const handleClick = ()=>setShowContextMenu(null);
82
+ const handleKeyDown = (e)=>{
83
+ if (e.key === 'Escape') setShowContextMenu(null);
84
+ };
85
+ document.addEventListener('click', handleClick);
86
+ document.addEventListener('keydown', handleKeyDown);
87
+ return ()=>{
88
+ document.removeEventListener('click', handleClick);
89
+ document.removeEventListener('keydown', handleKeyDown);
90
+ };
91
+ }
92
+ }, [
93
+ showContextMenu
94
+ ]);
95
+ const handleClick = (e)=>{
96
+ e.preventDefault();
97
+ if (node.isFolder) {
98
+ onFolderToggle(node.path);
99
+ } else {
100
+ onFileClick(node.path);
101
+ }
102
+ };
103
+ const handleContextMenu = (e)=>{
104
+ e.preventDefault();
105
+ setShowContextMenu({
106
+ x: e.clientX,
107
+ y: e.clientY
108
+ });
109
+ };
110
+ return /*#__PURE__*/ _jsxs("div", {
111
+ className: "relative",
112
+ children: [
113
+ /*#__PURE__*/ _jsxs("button", {
114
+ onClick: handleClick,
115
+ onContextMenu: handleContextMenu,
116
+ className: cn('w-full flex items-center gap-1 text-[13px] text-left transition-colors group', isActive && 'sandbox-file-active', !isActive && 'sandbox-file-hover'),
117
+ style: {
118
+ height: '22px',
119
+ paddingLeft: `${depth * 8 + 4}px`,
120
+ paddingRight: '8px'
121
+ },
122
+ children: [
123
+ /*#__PURE__*/ _jsx("span", {
124
+ className: "w-4 h-4 flex items-center justify-center flex-shrink-0",
125
+ children: node.isFolder && (isExpanded ? /*#__PURE__*/ _jsx(CaretDown, {
126
+ className: "h-3 w-3 text-zinc-400",
127
+ weight: "bold"
128
+ }) : /*#__PURE__*/ _jsx(CaretRight, {
129
+ className: "h-3 w-3 text-zinc-400",
130
+ weight: "bold"
131
+ }))
132
+ }),
133
+ node.isFolder ? isExpanded ? /*#__PURE__*/ _jsx(FolderOpen, {
134
+ className: "h-4 w-4 text-amber-400 flex-shrink-0",
135
+ weight: "fill"
136
+ }) : /*#__PURE__*/ _jsx(Folder, {
137
+ className: "h-4 w-4 text-amber-400 flex-shrink-0",
138
+ weight: "fill"
139
+ }) : /*#__PURE__*/ _jsx(FileIcon, {
140
+ path: node.path
141
+ }),
142
+ /*#__PURE__*/ _jsx("span", {
143
+ className: cn('truncate ml-1', isActive && 'text-white', !isActive && 'text-zinc-300'),
144
+ children: node.name
145
+ })
146
+ ]
147
+ }),
148
+ showContextMenu && !node.isFolder && /*#__PURE__*/ _jsx("div", {
149
+ className: "fixed z-50 min-w-[140px] py-1 sandbox-context-menu rounded shadow-xl",
150
+ style: {
151
+ left: showContextMenu.x,
152
+ top: showContextMenu.y
153
+ },
154
+ onClick: (e)=>e.stopPropagation(),
155
+ children: /*#__PURE__*/ _jsxs("button", {
156
+ onClick: ()=>{
157
+ onDelete?.(node.path);
158
+ setShowContextMenu(null);
159
+ },
160
+ className: "w-full flex items-center gap-2 px-3 py-1.5 text-[13px] sandbox-context-menu-delete text-left",
161
+ children: [
162
+ /*#__PURE__*/ _jsx(Trash, {
163
+ className: "h-4 w-4"
164
+ }),
165
+ "Delete"
166
+ ]
167
+ })
168
+ }),
169
+ node.isFolder && isExpanded && node.children && /*#__PURE__*/ _jsx("div", {
170
+ children: node.children.map((child)=>/*#__PURE__*/ _jsx(FileTreeItem, {
171
+ node: child,
172
+ depth: depth + 1,
173
+ activeFile: activeFile,
174
+ expandedFolders: expandedFolders,
175
+ onFileClick: onFileClick,
176
+ onFolderToggle: onFolderToggle,
177
+ onDelete: onDelete
178
+ }, child.path))
179
+ })
180
+ ]
181
+ });
182
+ }
183
+ // Editor tabs
184
+ function EditorTabs({ tabs, activeTab, onTabClick, onTabClose }) {
185
+ if (tabs.length === 0) return null;
186
+ return /*#__PURE__*/ _jsxs("div", {
187
+ className: "flex items-center h-[35px] sandbox-tabs overflow-x-auto",
188
+ children: [
189
+ tabs.map((path)=>{
190
+ const fileName = path.split('/').pop() || path;
191
+ const isActive = path === activeTab;
192
+ return /*#__PURE__*/ _jsxs("div", {
193
+ className: cn('relative flex items-center gap-1.5 px-3 h-full text-[13px] cursor-pointer group min-w-0', isActive ? 'sandbox-tab-active' : 'sandbox-tab-inactive'),
194
+ onClick: ()=>onTabClick(path),
195
+ children: [
196
+ isActive && /*#__PURE__*/ _jsx("div", {
197
+ className: "absolute top-0 left-0 right-0 h-[2px] sandbox-tab-indicator"
198
+ }),
199
+ /*#__PURE__*/ _jsx(FileIcon, {
200
+ path: path,
201
+ className: "h-4 w-4 flex-shrink-0"
202
+ }),
203
+ /*#__PURE__*/ _jsx("span", {
204
+ className: "truncate",
205
+ children: fileName
206
+ }),
207
+ /*#__PURE__*/ _jsx("button", {
208
+ onClick: (e)=>{
209
+ e.stopPropagation();
210
+ onTabClose(path);
211
+ },
212
+ className: cn('p-0.5 rounded flex-shrink-0 ml-1 sandbox-tab-close', isActive ? '' : 'opacity-0 group-hover:opacity-100'),
213
+ children: /*#__PURE__*/ _jsx(X, {
214
+ className: "h-3 w-3"
215
+ })
216
+ })
217
+ ]
218
+ }, path);
219
+ }),
220
+ /*#__PURE__*/ _jsx("div", {
221
+ className: "flex-1 h-full sandbox-tabs"
222
+ })
223
+ ]
224
+ });
225
+ }
226
+ // Note type templates
227
+ const noteTemplates = [
228
+ {
229
+ ext: '.py',
230
+ name: 'Python',
231
+ color: 'text-green-400',
232
+ bg: 'bg-green-500/10 hover:bg-green-500/20 border-green-500/30',
233
+ desc: 'Python script'
234
+ },
235
+ {
236
+ ext: '.ts',
237
+ name: 'TypeScript',
238
+ color: 'text-blue-400',
239
+ bg: 'bg-blue-500/10 hover:bg-blue-500/20 border-blue-500/30',
240
+ desc: 'TypeScript code'
241
+ },
242
+ {
243
+ ext: '.js',
244
+ name: 'JavaScript',
245
+ color: 'text-yellow-400',
246
+ bg: 'bg-yellow-500/10 hover:bg-yellow-500/20 border-yellow-500/30',
247
+ desc: 'JavaScript code'
248
+ },
249
+ {
250
+ ext: '.md',
251
+ name: 'Markdown',
252
+ color: 'text-blue-300',
253
+ bg: 'bg-blue-400/10 hover:bg-blue-400/20 border-blue-400/30',
254
+ desc: 'Documentation'
255
+ },
256
+ {
257
+ ext: '.mmd',
258
+ name: 'Mermaid',
259
+ color: 'text-pink-400',
260
+ bg: 'bg-pink-500/10 hover:bg-pink-500/20 border-pink-500/30',
261
+ desc: 'Diagrams'
262
+ },
263
+ {
264
+ ext: '.json',
265
+ name: 'JSON',
266
+ color: 'text-yellow-500',
267
+ bg: 'bg-yellow-500/10 hover:bg-yellow-500/20 border-yellow-500/30',
268
+ desc: 'Data/Config'
269
+ },
270
+ {
271
+ ext: '.go',
272
+ name: 'Go',
273
+ color: 'text-cyan-400',
274
+ bg: 'bg-cyan-500/10 hover:bg-cyan-500/20 border-cyan-500/30',
275
+ desc: 'Go code'
276
+ },
277
+ {
278
+ ext: '.rb',
279
+ name: 'Ruby',
280
+ color: 'text-red-400',
281
+ bg: 'bg-red-500/10 hover:bg-red-500/20 border-red-500/30',
282
+ desc: 'Ruby script'
283
+ }
284
+ ];
285
+ // New file dialog - VSCode style command palette
286
+ function NewNoteDialog({ open, onOpenChange, onCreateNote }) {
287
+ const [fileName, setFileName] = useState('');
288
+ const [selectedTemplate, setSelectedTemplate] = useState(null);
289
+ const inputRef = useRef(null);
290
+ // Reset on open
291
+ useEffect(()=>{
292
+ if (open) {
293
+ setFileName('');
294
+ setSelectedTemplate(null);
295
+ setTimeout(()=>inputRef.current?.focus(), 50);
296
+ }
297
+ }, [
298
+ open
299
+ ]);
300
+ // Detect file type from name
301
+ const detectedType = useMemo(()=>{
302
+ const ext = fileName.match(/\.[^.]+$/)?.[0];
303
+ return noteTemplates.find((t)=>t.ext === ext) || null;
304
+ }, [
305
+ fileName
306
+ ]);
307
+ const handleCreate = ()=>{
308
+ if (!fileName.trim()) return;
309
+ let finalName = fileName.trim();
310
+ // Add extension if not present and template selected
311
+ if (selectedTemplate && !finalName.includes('.')) {
312
+ finalName += selectedTemplate.ext;
313
+ }
314
+ onCreateNote(finalName);
315
+ setFileName('');
316
+ setSelectedTemplate(null);
317
+ onOpenChange(false);
318
+ };
319
+ const handleTemplateClick = (template)=>{
320
+ setSelectedTemplate(template);
321
+ // Update file name with new extension
322
+ const baseName = fileName.replace(/\.[^.]+$/, '') || 'untitled';
323
+ setFileName(baseName + template.ext);
324
+ inputRef.current?.focus();
325
+ };
326
+ const handleKeyDown = (e)=>{
327
+ if (e.key === 'Enter' && fileName.trim()) {
328
+ handleCreate();
329
+ }
330
+ if (e.key === 'Escape') {
331
+ onOpenChange(false);
332
+ }
333
+ };
334
+ const activeTemplate = detectedType || selectedTemplate;
335
+ if (!open) return null;
336
+ return /*#__PURE__*/ _jsxs("div", {
337
+ className: "fixed inset-0 z-50 flex items-start justify-center pt-[15vh]",
338
+ children: [
339
+ /*#__PURE__*/ _jsx("div", {
340
+ className: "absolute inset-0 bg-black/50",
341
+ onClick: ()=>onOpenChange(false)
342
+ }),
343
+ /*#__PURE__*/ _jsxs("div", {
344
+ className: "relative w-full max-w-lg mx-4 bg-[#1e1e1e] border border-[#454545] rounded-lg shadow-2xl overflow-hidden",
345
+ children: [
346
+ /*#__PURE__*/ _jsxs("div", {
347
+ className: "flex items-center gap-3 p-3 border-b border-[#3c3c3c]",
348
+ children: [
349
+ /*#__PURE__*/ _jsx("div", {
350
+ className: cn("w-8 h-8 rounded flex items-center justify-center flex-shrink-0 transition-colors", activeTemplate ? activeTemplate.bg : "bg-[#2d2d2d]"),
351
+ children: /*#__PURE__*/ _jsx(File, {
352
+ className: cn("h-4 w-4", activeTemplate?.color || "text-zinc-400"),
353
+ weight: "fill"
354
+ })
355
+ }),
356
+ /*#__PURE__*/ _jsx("input", {
357
+ ref: inputRef,
358
+ type: "text",
359
+ value: fileName,
360
+ onChange: (e)=>setFileName(e.target.value),
361
+ onKeyDown: handleKeyDown,
362
+ placeholder: "Enter file name...",
363
+ className: "flex-1 bg-transparent text-sm text-zinc-100 placeholder:text-zinc-500 outline-none"
364
+ }),
365
+ fileName.trim() && /*#__PURE__*/ _jsx("button", {
366
+ onClick: handleCreate,
367
+ className: "px-3 py-1.5 text-xs font-medium bg-[#007acc] hover:bg-[#006bb3] text-white rounded transition-colors",
368
+ children: "Create"
369
+ })
370
+ ]
371
+ }),
372
+ /*#__PURE__*/ _jsxs("div", {
373
+ className: "p-3",
374
+ children: [
375
+ /*#__PURE__*/ _jsx("p", {
376
+ className: "text-[11px] uppercase tracking-wider text-zinc-500 mb-2 px-1",
377
+ children: "Select type"
378
+ }),
379
+ /*#__PURE__*/ _jsx("div", {
380
+ className: "grid grid-cols-4 gap-2",
381
+ children: noteTemplates.map((template)=>{
382
+ const isActive = activeTemplate?.ext === template.ext;
383
+ return /*#__PURE__*/ _jsxs("button", {
384
+ onClick: ()=>handleTemplateClick(template),
385
+ className: cn("flex flex-col items-center gap-1.5 p-3 rounded-lg border transition-all", isActive ? `${template.bg} border-current` : "bg-[#2d2d2d] border-[#3c3c3c] hover:bg-[#333333] hover:border-[#4c4c4c]"),
386
+ children: [
387
+ /*#__PURE__*/ _jsx(File, {
388
+ className: cn("h-5 w-5", template.color),
389
+ weight: "fill"
390
+ }),
391
+ /*#__PURE__*/ _jsx("span", {
392
+ className: cn("text-[11px] font-medium", isActive ? template.color : "text-zinc-300"),
393
+ children: template.name
394
+ })
395
+ ]
396
+ }, template.ext);
397
+ })
398
+ })
399
+ ]
400
+ }),
401
+ /*#__PURE__*/ _jsxs("div", {
402
+ className: "px-4 py-2.5 bg-[#252526] border-t border-[#3c3c3c] flex items-center justify-between",
403
+ children: [
404
+ /*#__PURE__*/ _jsxs("p", {
405
+ className: "text-[11px] text-zinc-500",
406
+ children: [
407
+ "Tip: Use ",
408
+ /*#__PURE__*/ _jsx("code", {
409
+ className: "px-1 py-0.5 bg-[#3c3c3c] rounded text-zinc-400",
410
+ children: "folder/file.ext"
411
+ }),
412
+ " for nested files"
413
+ ]
414
+ }),
415
+ /*#__PURE__*/ _jsxs("div", {
416
+ className: "flex items-center gap-2 text-[11px] text-zinc-500",
417
+ children: [
418
+ /*#__PURE__*/ _jsx("span", {
419
+ className: "px-1.5 py-0.5 bg-[#3c3c3c] rounded text-[10px]",
420
+ children: "↵"
421
+ }),
422
+ /*#__PURE__*/ _jsx("span", {
423
+ children: "Create"
424
+ }),
425
+ /*#__PURE__*/ _jsx("span", {
426
+ className: "px-1.5 py-0.5 bg-[#3c3c3c] rounded text-[10px]",
427
+ children: "Esc"
428
+ }),
429
+ /*#__PURE__*/ _jsx("span", {
430
+ children: "Cancel"
431
+ })
432
+ ]
433
+ })
434
+ ]
435
+ })
436
+ ]
437
+ })
438
+ ]
439
+ });
440
+ }
441
+ // Error Boundary for Mermaid Preview
442
+ class MermaidErrorBoundary extends React.Component {
443
+ static getDerivedStateFromError(error) {
444
+ return {
445
+ hasError: true,
446
+ error: error.message
447
+ };
448
+ }
449
+ componentDidCatch(error, errorInfo) {
450
+ console.error('[MermaidErrorBoundary] Error:', error, errorInfo);
451
+ }
452
+ // Reset error when code changes
453
+ componentDidUpdate(prevProps) {
454
+ if (prevProps.code !== this.props.code && this.state.hasError) {
455
+ this.setState({
456
+ hasError: false,
457
+ error: null
458
+ });
459
+ }
460
+ }
461
+ render() {
462
+ if (this.state.hasError) {
463
+ return /*#__PURE__*/ _jsxs("div", {
464
+ className: "flex flex-col items-center justify-center h-full text-zinc-400 text-sm p-4 gap-4",
465
+ children: [
466
+ /*#__PURE__*/ _jsxs("p", {
467
+ className: "text-red-400",
468
+ children: [
469
+ "Render Error: ",
470
+ this.state.error
471
+ ]
472
+ }),
473
+ /*#__PURE__*/ _jsxs("div", {
474
+ className: "w-full max-w-lg",
475
+ children: [
476
+ /*#__PURE__*/ _jsx("p", {
477
+ className: "text-xs text-zinc-500 mb-2",
478
+ children: "Source:"
479
+ }),
480
+ /*#__PURE__*/ _jsx("pre", {
481
+ className: "p-4 bg-[#2d2d2d] rounded text-xs overflow-auto max-h-[200px] text-zinc-300",
482
+ children: this.props.code
483
+ })
484
+ ]
485
+ })
486
+ ]
487
+ });
488
+ }
489
+ return this.props.children;
490
+ }
491
+ constructor(props){
492
+ super(props);
493
+ this.state = {
494
+ hasError: false,
495
+ error: null
496
+ };
497
+ }
498
+ }
499
+ // Mermaid preview component with zoom/pan
500
+ function MermaidPreviewInner({ code }) {
501
+ const containerRef = useRef(null);
502
+ const contentRef = useRef(null);
503
+ const [svg, setSvg] = useState('');
504
+ const [error, setError] = useState(null);
505
+ const [loading, setLoading] = useState(true);
506
+ const renderIdRef = useRef(0);
507
+ // Zoom and pan state
508
+ const [scale, setScale] = useState(1);
509
+ const [position, setPosition] = useState({
510
+ x: 0,
511
+ y: 0
512
+ });
513
+ const [isDragging, setIsDragging] = useState(false);
514
+ const dragStart = useRef({
515
+ x: 0,
516
+ y: 0
517
+ });
518
+ const positionStart = useRef({
519
+ x: 0,
520
+ y: 0
521
+ });
522
+ useEffect(()=>{
523
+ if (!code.trim()) {
524
+ setLoading(false);
525
+ setSvg('');
526
+ setError(null);
527
+ return;
528
+ }
529
+ const currentRenderId = ++renderIdRef.current;
530
+ setLoading(true);
531
+ setError(null);
532
+ const renderDiagram = async ()=>{
533
+ try {
534
+ const mermaid = (await import('mermaid')).default;
535
+ mermaid.initialize({
536
+ startOnLoad: false,
537
+ theme: 'dark',
538
+ themeVariables: {
539
+ // Force dark backgrounds everywhere
540
+ background: '#1e1e1e',
541
+ primaryColor: '#3b82f6',
542
+ primaryTextColor: '#ffffff',
543
+ primaryBorderColor: '#60a5fa',
544
+ secondaryColor: '#3b82f6',
545
+ secondaryTextColor: '#ffffff',
546
+ secondaryBorderColor: '#60a5fa',
547
+ tertiaryColor: '#3b82f6',
548
+ tertiaryTextColor: '#ffffff',
549
+ tertiaryBorderColor: '#60a5fa',
550
+ // Node backgrounds - force blue
551
+ mainBkg: '#3b82f6',
552
+ nodeBkg: '#3b82f6',
553
+ nodeBorder: '#60a5fa',
554
+ nodeTextColor: '#ffffff',
555
+ // Cluster styling
556
+ clusterBkg: '#27272a',
557
+ clusterBorder: '#52525b',
558
+ titleColor: '#ffffff',
559
+ // Lines
560
+ lineColor: '#94a3b8',
561
+ // Font
562
+ fontFamily: 'system-ui, sans-serif',
563
+ fontSize: '14px'
564
+ },
565
+ flowchart: {
566
+ htmlLabels: true,
567
+ useMaxWidth: true
568
+ }
569
+ });
570
+ // Use unique ID to avoid conflicts
571
+ const { svg: renderedSvg } = await mermaid.render(`mermaid-${currentRenderId}-${Date.now()}`, code);
572
+ // Only update if this is still the latest render
573
+ if (currentRenderId === renderIdRef.current) {
574
+ setSvg(renderedSvg);
575
+ setError(null);
576
+ // Reset zoom/pan when diagram changes
577
+ setScale(1);
578
+ setPosition({
579
+ x: 0,
580
+ y: 0
581
+ });
582
+ }
583
+ } catch (err) {
584
+ if (currentRenderId === renderIdRef.current) {
585
+ // Extract meaningful error message from mermaid errors
586
+ let errorMessage = 'Failed to render diagram';
587
+ if (err instanceof Error) {
588
+ // Mermaid errors often have detailed messages
589
+ errorMessage = err.message;
590
+ // Clean up common mermaid error prefixes
591
+ if (errorMessage.includes('Parse error')) {
592
+ const match = errorMessage.match(/Parse error on line (\d+)/);
593
+ if (match) {
594
+ errorMessage = `Syntax error on line ${match[1]}`;
595
+ }
596
+ }
597
+ } else if (typeof err === 'string') {
598
+ errorMessage = err;
599
+ } else if (err && typeof err === 'object' && 'str' in err) {
600
+ // Mermaid sometimes returns {str: "error message"}
601
+ errorMessage = String(err.str);
602
+ }
603
+ setError(errorMessage);
604
+ setSvg(''); // Clear any previous SVG
605
+ }
606
+ } finally{
607
+ if (currentRenderId === renderIdRef.current) {
608
+ setLoading(false);
609
+ }
610
+ }
611
+ };
612
+ // Debounce rendering
613
+ const timer = setTimeout(renderDiagram, 300);
614
+ return ()=>clearTimeout(timer);
615
+ }, [
616
+ code
617
+ ]);
618
+ // Handle mouse wheel zoom
619
+ const handleWheel = useCallback((e)=>{
620
+ e.preventDefault();
621
+ const delta = e.deltaY > 0 ? -0.1 : 0.1;
622
+ setScale((prev)=>Math.min(Math.max(0.25, prev + delta), 3));
623
+ }, []);
624
+ // Handle mouse down for pan
625
+ const handleMouseDown = useCallback((e)=>{
626
+ if (e.button !== 0) return; // Only left click
627
+ setIsDragging(true);
628
+ dragStart.current = {
629
+ x: e.clientX,
630
+ y: e.clientY
631
+ };
632
+ positionStart.current = position;
633
+ }, [
634
+ position
635
+ ]);
636
+ // Handle mouse move for pan
637
+ const handleMouseMove = useCallback((e)=>{
638
+ if (!isDragging) return;
639
+ const dx = e.clientX - dragStart.current.x;
640
+ const dy = e.clientY - dragStart.current.y;
641
+ setPosition({
642
+ x: positionStart.current.x + dx,
643
+ y: positionStart.current.y + dy
644
+ });
645
+ }, [
646
+ isDragging
647
+ ]);
648
+ // Handle mouse up
649
+ const handleMouseUp = useCallback(()=>{
650
+ setIsDragging(false);
651
+ }, []);
652
+ // Handle zoom controls
653
+ const zoomIn = useCallback(()=>setScale((prev)=>Math.min(prev + 0.25, 3)), []);
654
+ const zoomOut = useCallback(()=>setScale((prev)=>Math.max(prev - 0.25, 0.25)), []);
655
+ const resetView = useCallback(()=>{
656
+ setScale(1);
657
+ setPosition({
658
+ x: 0,
659
+ y: 0
660
+ });
661
+ }, []);
662
+ if (loading) {
663
+ return /*#__PURE__*/ _jsxs("div", {
664
+ className: "flex items-center justify-center h-full text-zinc-500 text-sm",
665
+ children: [
666
+ /*#__PURE__*/ _jsx(Spinner, {
667
+ className: "h-5 w-5 animate-spin mr-2"
668
+ }),
669
+ "Rendering diagram..."
670
+ ]
671
+ });
672
+ }
673
+ if (error) {
674
+ return /*#__PURE__*/ _jsxs("div", {
675
+ className: "flex flex-col items-center justify-center h-full text-zinc-400 text-sm p-4 gap-4",
676
+ children: [
677
+ /*#__PURE__*/ _jsxs("p", {
678
+ className: "text-red-400",
679
+ children: [
680
+ "Syntax Error: ",
681
+ error
682
+ ]
683
+ }),
684
+ /*#__PURE__*/ _jsxs("div", {
685
+ className: "w-full max-w-lg",
686
+ children: [
687
+ /*#__PURE__*/ _jsx("p", {
688
+ className: "text-xs text-zinc-500 mb-2",
689
+ children: "Source:"
690
+ }),
691
+ /*#__PURE__*/ _jsx("pre", {
692
+ className: "p-4 bg-[#2d2d2d] rounded text-xs overflow-auto max-h-[200px] text-zinc-300",
693
+ children: code
694
+ })
695
+ ]
696
+ })
697
+ ]
698
+ });
699
+ }
700
+ return /*#__PURE__*/ _jsxs("div", {
701
+ className: "relative h-full w-full bg-[#1e1e1e]",
702
+ children: [
703
+ /*#__PURE__*/ _jsxs("div", {
704
+ className: "absolute top-3 right-3 z-10 flex items-center gap-1 bg-[#2d2d2d] rounded-md border border-[#3c3c3c] p-1",
705
+ children: [
706
+ /*#__PURE__*/ _jsx("button", {
707
+ onClick: zoomOut,
708
+ className: "p-1.5 hover:bg-[#3c3c3c] rounded text-zinc-400 hover:text-zinc-200 transition-colors",
709
+ title: "Zoom out",
710
+ children: /*#__PURE__*/ _jsx(Minus, {
711
+ className: "h-4 w-4"
712
+ })
713
+ }),
714
+ /*#__PURE__*/ _jsxs("span", {
715
+ className: "text-xs text-zinc-400 min-w-[3rem] text-center",
716
+ children: [
717
+ Math.round(scale * 100),
718
+ "%"
719
+ ]
720
+ }),
721
+ /*#__PURE__*/ _jsx("button", {
722
+ onClick: zoomIn,
723
+ className: "p-1.5 hover:bg-[#3c3c3c] rounded text-zinc-400 hover:text-zinc-200 transition-colors",
724
+ title: "Zoom in",
725
+ children: /*#__PURE__*/ _jsx(Plus, {
726
+ className: "h-4 w-4"
727
+ })
728
+ }),
729
+ /*#__PURE__*/ _jsx("div", {
730
+ className: "w-px h-4 bg-[#3c3c3c] mx-1"
731
+ }),
732
+ /*#__PURE__*/ _jsx("button", {
733
+ onClick: resetView,
734
+ className: "p-1.5 hover:bg-[#3c3c3c] rounded text-zinc-400 hover:text-zinc-200 transition-colors",
735
+ title: "Reset view",
736
+ children: /*#__PURE__*/ _jsx(ArrowsOut, {
737
+ className: "h-4 w-4"
738
+ })
739
+ })
740
+ ]
741
+ }),
742
+ /*#__PURE__*/ _jsx("div", {
743
+ ref: containerRef,
744
+ className: "h-full w-full overflow-hidden cursor-grab active:cursor-grabbing",
745
+ onWheel: handleWheel,
746
+ onMouseDown: handleMouseDown,
747
+ onMouseMove: handleMouseMove,
748
+ onMouseUp: handleMouseUp,
749
+ onMouseLeave: handleMouseUp,
750
+ children: /*#__PURE__*/ _jsx("div", {
751
+ ref: contentRef,
752
+ className: "h-full w-full flex items-center justify-center [&_svg]:max-w-none",
753
+ style: {
754
+ transform: `translate(${position.x}px, ${position.y}px) scale(${scale})`,
755
+ transformOrigin: 'center center',
756
+ transition: isDragging ? 'none' : 'transform 0.1s ease-out'
757
+ },
758
+ dangerouslySetInnerHTML: {
759
+ __html: svg
760
+ }
761
+ })
762
+ }),
763
+ /*#__PURE__*/ _jsx("div", {
764
+ className: "absolute bottom-3 left-3 text-[10px] text-zinc-600",
765
+ children: "Scroll to zoom • Drag to pan"
766
+ })
767
+ ]
768
+ });
769
+ }
770
+ // Mermaid preview with error boundary wrapper
771
+ function MermaidPreview({ code }) {
772
+ return /*#__PURE__*/ _jsx(MermaidErrorBoundary, {
773
+ code: code,
774
+ children: /*#__PURE__*/ _jsx(MermaidPreviewInner, {
775
+ code: code
776
+ })
777
+ });
778
+ }
779
+ // Main Notes Mode component
780
+ export function NotesMode({ apiSpecUrl, apiName }) {
781
+ const { activeFilePath, setActiveFilePath, streamingContent, setStreamingContent, notesRefreshTrigger } = useModeContext();
782
+ const { workspace, loading: workspaceLoading } = useWorkspace(apiSpecUrl, apiName);
783
+ const { notes, loading: notesLoading, createNote, readNote, updateNote, deleteNote, refresh } = useNotes(workspace?.id || null);
784
+ const { state: editorState, openTab, closeTab, setActiveTab, clearAllTabs } = useEditorState(workspace?.id || null);
785
+ // Editor refs
786
+ const editorRef = useRef(null);
787
+ // Local state
788
+ const [fileContent, setFileContent] = useState('');
789
+ const [isModified, setIsModified] = useState(false);
790
+ const [isSaving, setIsSaving] = useState(false);
791
+ const [isLoadingContent, setIsLoadingContent] = useState(false);
792
+ const [expandedFolders, setExpandedFolders] = useState(new Set());
793
+ const [showNewNote, setShowNewNote] = useState(false);
794
+ const [showPreview, setShowPreview] = useState(false);
795
+ // Build file tree
796
+ const fileTree = useMemo(()=>buildFileTree(notes), [
797
+ notes
798
+ ]);
799
+ // Refresh notes when triggered by agent (delete, update operations)
800
+ useEffect(()=>{
801
+ if (notesRefreshTrigger > 0) {
802
+ refresh();
803
+ }
804
+ }, [
805
+ notesRefreshTrigger,
806
+ refresh
807
+ ]);
808
+ // Clear tabs when all notes are deleted
809
+ useEffect(()=>{
810
+ if (!notesLoading && notes.length === 0 && editorState?.openTabs && editorState.openTabs.length > 0) {
811
+ clearAllTabs();
812
+ setFileContent('');
813
+ }
814
+ }, [
815
+ notes.length,
816
+ notesLoading,
817
+ editorState?.openTabs,
818
+ clearAllTabs
819
+ ]);
820
+ // State validation: Clean up orphaned tabs (pointing to deleted files)
821
+ useEffect(()=>{
822
+ if (notesLoading || !editorState?.openTabs || editorState.openTabs.length === 0) return;
823
+ const notePaths = new Set(notes.map((n)=>n.path));
824
+ const orphanedTabs = editorState.openTabs.filter((tab)=>!notePaths.has(tab));
825
+ if (orphanedTabs.length > 0) {
826
+ console.log('[NotesMode] Cleaning up orphaned tabs:', orphanedTabs);
827
+ // Close each orphaned tab
828
+ orphanedTabs.forEach((tab)=>closeTab(tab));
829
+ }
830
+ }, [
831
+ notes,
832
+ notesLoading,
833
+ editorState?.openTabs,
834
+ closeTab
835
+ ]);
836
+ // State validation: Clear stuck streaming state (no active streaming after 30s)
837
+ useEffect(()=>{
838
+ if (!streamingContent?.isStreaming) return;
839
+ const timeout = setTimeout(()=>{
840
+ if (streamingContent?.isStreaming) {
841
+ console.log('[NotesMode] Clearing stuck streaming state');
842
+ setStreamingContent(null);
843
+ }
844
+ }, 30000) // 30 second timeout
845
+ ;
846
+ return ()=>clearTimeout(timeout);
847
+ }, [
848
+ streamingContent?.isStreaming,
849
+ setStreamingContent
850
+ ]);
851
+ // Load file content when active tab changes
852
+ useEffect(()=>{
853
+ if (!editorState?.activeTab) {
854
+ setFileContent('');
855
+ setIsLoadingContent(false);
856
+ return;
857
+ }
858
+ setIsLoadingContent(true);
859
+ const loadContent = async ()=>{
860
+ const content = await readNote(editorState.activeTab);
861
+ setFileContent(content);
862
+ setIsModified(false);
863
+ setIsLoadingContent(false);
864
+ };
865
+ loadContent();
866
+ }, [
867
+ editorState?.activeTab,
868
+ readNote
869
+ ]);
870
+ // Track last processed path to avoid re-processing
871
+ const lastProcessedPath = useRef(null);
872
+ // Handle file navigation from agent
873
+ useEffect(()=>{
874
+ if (activeFilePath && workspace) {
875
+ // Strip timestamp from path if present (used to force refresh)
876
+ const cleanPath = activeFilePath.split('?')[0];
877
+ const hasTimestamp = activeFilePath.includes('?t=');
878
+ // Skip if we've already processed this path (unless it has a timestamp for force refresh)
879
+ if (lastProcessedPath.current === cleanPath && !hasTimestamp) {
880
+ return;
881
+ }
882
+ lastProcessedPath.current = cleanPath;
883
+ // Refresh notes first to ensure file is in the list
884
+ refresh().then(async ()=>{
885
+ openTab(cleanPath);
886
+ // Auto-enable preview for mermaid files
887
+ if (cleanPath.endsWith('.mmd')) {
888
+ setShowPreview(true);
889
+ }
890
+ // If this was a write operation (has timestamp), force content reload
891
+ if (hasTimestamp) {
892
+ setIsLoadingContent(true);
893
+ const content = await readNote(cleanPath);
894
+ setFileContent(content);
895
+ setIsModified(false);
896
+ setIsLoadingContent(false);
897
+ // Clear streaming content after file is loaded (prevents flash of empty content)
898
+ if (streamingContent?.path === cleanPath) {
899
+ setStreamingContent(null);
900
+ }
901
+ }
902
+ // Expand parent folders
903
+ const parts = cleanPath.split('/');
904
+ if (parts.length > 1) {
905
+ const foldersToExpand = parts.slice(0, -1).map((_, i)=>parts.slice(0, i + 1).join('/'));
906
+ setExpandedFolders((prev)=>{
907
+ const next = new Set(prev);
908
+ foldersToExpand.forEach((f)=>next.add(f));
909
+ return next;
910
+ });
911
+ }
912
+ });
913
+ }
914
+ }, [
915
+ activeFilePath,
916
+ workspace,
917
+ openTab,
918
+ refresh,
919
+ readNote,
920
+ streamingContent,
921
+ setStreamingContent
922
+ ]);
923
+ // Handle folder toggle
924
+ const handleFolderToggle = useCallback((path)=>{
925
+ setExpandedFolders((prev)=>{
926
+ const next = new Set(prev);
927
+ if (next.has(path)) {
928
+ next.delete(path);
929
+ } else {
930
+ next.add(path);
931
+ }
932
+ return next;
933
+ });
934
+ }, []);
935
+ // Handle content change
936
+ const handleContentChange = useCallback((value)=>{
937
+ if (value !== undefined) {
938
+ setFileContent(value);
939
+ setIsModified(true);
940
+ }
941
+ }, []);
942
+ // Handle save
943
+ const handleSave = useCallback(async ()=>{
944
+ if (!editorState?.activeTab || !isModified) return;
945
+ setIsSaving(true);
946
+ try {
947
+ await updateNote(editorState.activeTab, fileContent);
948
+ setIsModified(false);
949
+ } finally{
950
+ setIsSaving(false);
951
+ }
952
+ }, [
953
+ editorState?.activeTab,
954
+ fileContent,
955
+ isModified,
956
+ updateNote
957
+ ]);
958
+ // Keyboard shortcuts
959
+ useEffect(()=>{
960
+ const handleKeyDown = (e)=>{
961
+ if ((e.metaKey || e.ctrlKey) && e.key === 's') {
962
+ e.preventDefault();
963
+ handleSave();
964
+ }
965
+ if ((e.metaKey || e.ctrlKey) && e.key === 'n') {
966
+ e.preventDefault();
967
+ setShowNewNote(true);
968
+ }
969
+ };
970
+ window.addEventListener('keydown', handleKeyDown);
971
+ return ()=>window.removeEventListener('keydown', handleKeyDown);
972
+ }, [
973
+ handleSave
974
+ ]);
975
+ // Handle create note
976
+ const handleCreateNote = useCallback(async (path)=>{
977
+ await createNote(path, '');
978
+ await refresh();
979
+ await openTab(path);
980
+ }, [
981
+ createNote,
982
+ refresh,
983
+ openTab
984
+ ]);
985
+ // Handle delete note
986
+ const handleDeleteNote = useCallback(async (path)=>{
987
+ await deleteNote(path);
988
+ closeTab(path);
989
+ await refresh();
990
+ }, [
991
+ deleteNote,
992
+ closeTab,
993
+ refresh
994
+ ]);
995
+ // Handle reset workspace (clears all state)
996
+ const handleResetWorkspace = useCallback(async ()=>{
997
+ if (!window.confirm('Reset workspace? This will clear all notes and tabs.')) {
998
+ return;
999
+ }
1000
+ try {
1001
+ // Clear all notes from IndexedDB
1002
+ for (const note of notes){
1003
+ await deleteNote(note.path);
1004
+ }
1005
+ // Clear all tabs
1006
+ clearAllTabs();
1007
+ // Clear streaming content
1008
+ setStreamingContent(null);
1009
+ // Clear file content
1010
+ setFileContent('');
1011
+ setIsModified(false);
1012
+ // Refresh notes list
1013
+ await refresh();
1014
+ console.log('[NotesMode] Workspace reset complete');
1015
+ } catch (err) {
1016
+ console.error('[NotesMode] Failed to reset workspace:', err);
1017
+ }
1018
+ }, [
1019
+ notes,
1020
+ deleteNote,
1021
+ clearAllTabs,
1022
+ setStreamingContent,
1023
+ refresh
1024
+ ]);
1025
+ // Handle editor mount
1026
+ const handleEditorMount = (editor)=>{
1027
+ editorRef.current = editor;
1028
+ };
1029
+ // Check if current file supports preview
1030
+ const currentFileSupportsPreview = editorState?.activeTab ? supportsPreview(editorState.activeTab) : false;
1031
+ const currentFileType = editorState?.activeTab ? getFileType(editorState.activeTab) : null;
1032
+ // Auto-enable preview for mermaid files when tab changes
1033
+ useEffect(()=>{
1034
+ if (editorState?.activeTab?.endsWith('.mmd')) {
1035
+ setShowPreview(true);
1036
+ }
1037
+ }, [
1038
+ editorState?.activeTab
1039
+ ]);
1040
+ // Auto-scroll editor to end while streaming
1041
+ useEffect(()=>{
1042
+ if (streamingContent?.isStreaming && editorRef.current) {
1043
+ const model = editorRef.current.getModel();
1044
+ if (model) {
1045
+ const lineCount = model.getLineCount();
1046
+ editorRef.current.revealLine(lineCount);
1047
+ // Also position cursor at the end
1048
+ editorRef.current.setPosition({
1049
+ lineNumber: lineCount,
1050
+ column: 1
1051
+ });
1052
+ }
1053
+ }
1054
+ }, [
1055
+ streamingContent?.content,
1056
+ streamingContent?.isStreaming
1057
+ ]);
1058
+ // Loading state
1059
+ if (workspaceLoading || notesLoading) {
1060
+ return /*#__PURE__*/ _jsx("div", {
1061
+ className: "flex items-center justify-center h-full sandbox-bg",
1062
+ children: /*#__PURE__*/ _jsx(Spinner, {
1063
+ className: "h-6 w-6 animate-spin sandbox-text-muted"
1064
+ })
1065
+ });
1066
+ }
1067
+ return /*#__PURE__*/ _jsxs("div", {
1068
+ className: "flex flex-col h-full sandbox-bg",
1069
+ children: [
1070
+ /*#__PURE__*/ _jsxs("div", {
1071
+ className: "flex items-center justify-between px-3 py-1.5 sandbox-header",
1072
+ children: [
1073
+ /*#__PURE__*/ _jsxs("div", {
1074
+ className: "flex items-center gap-2",
1075
+ children: [
1076
+ /*#__PURE__*/ _jsx("span", {
1077
+ className: "text-xs sandbox-text-secondary",
1078
+ children: workspace?.name || 'Notes'
1079
+ }),
1080
+ isModified && /*#__PURE__*/ _jsx("span", {
1081
+ className: "text-[11px] sandbox-text-warning font-medium",
1082
+ children: "● Unsaved"
1083
+ })
1084
+ ]
1085
+ }),
1086
+ /*#__PURE__*/ _jsxs("div", {
1087
+ className: "flex items-center gap-1.5",
1088
+ children: [
1089
+ currentFileSupportsPreview && /*#__PURE__*/ _jsxs(Button, {
1090
+ variant: "ghost",
1091
+ size: "sm",
1092
+ onClick: ()=>setShowPreview(!showPreview),
1093
+ className: cn("h-7 px-2 sandbox-btn", showPreview ? "sandbox-btn-active" : ""),
1094
+ children: [
1095
+ showPreview ? /*#__PURE__*/ _jsx(Code, {
1096
+ className: "h-3.5 w-3.5 mr-1"
1097
+ }) : /*#__PURE__*/ _jsx(Eye, {
1098
+ className: "h-3.5 w-3.5 mr-1"
1099
+ }),
1100
+ /*#__PURE__*/ _jsx("span", {
1101
+ className: "text-xs",
1102
+ children: showPreview ? 'Code' : 'Preview'
1103
+ })
1104
+ ]
1105
+ }),
1106
+ /*#__PURE__*/ _jsxs(Button, {
1107
+ variant: "ghost",
1108
+ size: "sm",
1109
+ onClick: ()=>setShowNewNote(true),
1110
+ className: "sandbox-btn h-7 px-2",
1111
+ children: [
1112
+ /*#__PURE__*/ _jsx(Plus, {
1113
+ className: "h-3.5 w-3.5 mr-1"
1114
+ }),
1115
+ /*#__PURE__*/ _jsx("span", {
1116
+ className: "text-xs",
1117
+ children: "New"
1118
+ })
1119
+ ]
1120
+ }),
1121
+ /*#__PURE__*/ _jsxs(Button, {
1122
+ variant: "ghost",
1123
+ size: "sm",
1124
+ onClick: handleSave,
1125
+ disabled: !isModified || isSaving,
1126
+ className: "sandbox-btn h-7 px-2 disabled:opacity-40",
1127
+ children: [
1128
+ /*#__PURE__*/ _jsx(FloppyDisk, {
1129
+ className: "h-3.5 w-3.5 mr-1"
1130
+ }),
1131
+ /*#__PURE__*/ _jsx("span", {
1132
+ className: "text-xs",
1133
+ children: "Save"
1134
+ })
1135
+ ]
1136
+ }),
1137
+ (notes.length > 0 || (editorState?.openTabs?.length ?? 0) > 0) && /*#__PURE__*/ _jsxs(Tooltip, {
1138
+ children: [
1139
+ /*#__PURE__*/ _jsx(TooltipTrigger, {
1140
+ asChild: true,
1141
+ children: /*#__PURE__*/ _jsx(Button, {
1142
+ variant: "ghost",
1143
+ size: "sm",
1144
+ onClick: handleResetWorkspace,
1145
+ className: "sandbox-btn-danger h-7 w-7 p-0",
1146
+ children: /*#__PURE__*/ _jsx(ArrowClockwise, {
1147
+ className: "h-3.5 w-3.5"
1148
+ })
1149
+ })
1150
+ }),
1151
+ /*#__PURE__*/ _jsx(TooltipContent, {
1152
+ side: "bottom",
1153
+ children: "Reset workspace"
1154
+ })
1155
+ ]
1156
+ })
1157
+ ]
1158
+ })
1159
+ ]
1160
+ }),
1161
+ /*#__PURE__*/ _jsxs("div", {
1162
+ className: "flex flex-1 overflow-hidden",
1163
+ children: [
1164
+ /*#__PURE__*/ _jsxs("div", {
1165
+ className: "w-52 flex-shrink-0 border-r border-[#3c3c3c] flex flex-col bg-[#181818]",
1166
+ children: [
1167
+ /*#__PURE__*/ _jsx("div", {
1168
+ className: "px-2.5 py-1.5 border-b border-[#3c3c3c] bg-[#252526]",
1169
+ children: /*#__PURE__*/ _jsx("span", {
1170
+ className: "text-[11px] font-medium uppercase tracking-wider text-zinc-400",
1171
+ children: "Notes"
1172
+ })
1173
+ }),
1174
+ /*#__PURE__*/ _jsx("div", {
1175
+ className: "flex-1 overflow-y-auto",
1176
+ children: notes.length === 0 ? /*#__PURE__*/ _jsxs("div", {
1177
+ className: "px-3 py-4 text-xs text-zinc-500 text-center",
1178
+ children: [
1179
+ /*#__PURE__*/ _jsx("p", {
1180
+ className: "mb-2",
1181
+ children: "No notes yet"
1182
+ }),
1183
+ /*#__PURE__*/ _jsx(Button, {
1184
+ variant: "link",
1185
+ size: "sm",
1186
+ className: "text-xs text-blue-400 hover:text-blue-300",
1187
+ onClick: ()=>setShowNewNote(true),
1188
+ children: "Create your first note"
1189
+ })
1190
+ ]
1191
+ }) : fileTree.map((node)=>/*#__PURE__*/ _jsx(FileTreeItem, {
1192
+ node: node,
1193
+ depth: 0,
1194
+ activeFile: editorState?.activeTab || null,
1195
+ expandedFolders: expandedFolders,
1196
+ onFileClick: (path)=>{
1197
+ openTab(path);
1198
+ setActiveFilePath(path); // Update URL
1199
+ },
1200
+ onFolderToggle: handleFolderToggle,
1201
+ onDelete: handleDeleteNote
1202
+ }, node.path))
1203
+ })
1204
+ ]
1205
+ }),
1206
+ /*#__PURE__*/ _jsxs("div", {
1207
+ className: "flex-1 flex flex-col overflow-hidden bg-[#1e1e1e]",
1208
+ children: [
1209
+ /*#__PURE__*/ _jsx(EditorTabs, {
1210
+ tabs: editorState?.openTabs || [],
1211
+ activeTab: editorState?.activeTab || null,
1212
+ onTabClick: (path)=>{
1213
+ setActiveTab(path);
1214
+ setActiveFilePath(path); // Update URL
1215
+ },
1216
+ onTabClose: closeTab
1217
+ }),
1218
+ /*#__PURE__*/ _jsxs("div", {
1219
+ className: "flex-1 overflow-hidden relative",
1220
+ children: [
1221
+ isLoadingContent && !streamingContent?.isStreaming && /*#__PURE__*/ _jsx("div", {
1222
+ className: "absolute inset-0 bg-[#1e1e1e] z-10 flex items-center justify-center",
1223
+ children: /*#__PURE__*/ _jsxs("div", {
1224
+ className: "flex items-center gap-2 text-zinc-400",
1225
+ children: [
1226
+ /*#__PURE__*/ _jsx(Spinner, {
1227
+ className: "h-5 w-5 animate-spin"
1228
+ }),
1229
+ /*#__PURE__*/ _jsx("span", {
1230
+ className: "text-sm",
1231
+ children: "Loading content..."
1232
+ })
1233
+ ]
1234
+ })
1235
+ }),
1236
+ streamingContent?.isStreaming && streamingContent.path === editorState?.activeTab && /*#__PURE__*/ _jsxs("div", {
1237
+ className: "absolute top-2 right-2 z-10 flex items-center gap-2 px-2 py-1 rounded bg-blue-600/80 text-white text-xs",
1238
+ children: [
1239
+ /*#__PURE__*/ _jsx(Spinner, {
1240
+ className: "h-3 w-3 animate-spin"
1241
+ }),
1242
+ /*#__PURE__*/ _jsx("span", {
1243
+ children: "AI writing..."
1244
+ })
1245
+ ]
1246
+ }),
1247
+ editorState?.activeTab ? showPreview && currentFileType === 'mermaid' ? /*#__PURE__*/ _jsx(MermaidPreview, {
1248
+ code: streamingContent?.isStreaming && streamingContent.path === editorState.activeTab ? streamingContent.content : fileContent
1249
+ }) : /*#__PURE__*/ _jsx(Editor, {
1250
+ height: "100%",
1251
+ language: getMonacoLanguage(editorState.activeTab),
1252
+ value: streamingContent?.isStreaming && streamingContent.path === editorState.activeTab ? streamingContent.content : fileContent,
1253
+ onChange: handleContentChange,
1254
+ onMount: handleEditorMount,
1255
+ options: {
1256
+ minimap: {
1257
+ enabled: false
1258
+ },
1259
+ fontSize: 13,
1260
+ fontFamily: "'JetBrains Mono', 'Fira Code', monospace",
1261
+ lineNumbers: 'on',
1262
+ scrollBeyondLastLine: false,
1263
+ wordWrap: 'on',
1264
+ tabSize: 2,
1265
+ automaticLayout: true,
1266
+ padding: {
1267
+ top: 8,
1268
+ bottom: 8
1269
+ },
1270
+ renderWhitespace: 'selection',
1271
+ bracketPairColorization: {
1272
+ enabled: true
1273
+ },
1274
+ cursorBlinking: 'smooth',
1275
+ smoothScrolling: true,
1276
+ lineHeight: 20,
1277
+ readOnly: streamingContent?.isStreaming && streamingContent.path === editorState.activeTab
1278
+ },
1279
+ theme: "vs-dark"
1280
+ }) : /*#__PURE__*/ _jsx("div", {
1281
+ className: "flex items-center justify-center h-full",
1282
+ children: /*#__PURE__*/ _jsxs("div", {
1283
+ className: "text-center",
1284
+ children: [
1285
+ /*#__PURE__*/ _jsx("div", {
1286
+ className: "w-16 h-16 mx-auto mb-4 rounded-lg bg-[#2d2d2d] flex items-center justify-center",
1287
+ children: /*#__PURE__*/ _jsx(File, {
1288
+ className: "h-8 w-8 text-zinc-600"
1289
+ })
1290
+ }),
1291
+ /*#__PURE__*/ _jsx("p", {
1292
+ className: "text-sm text-zinc-500 mb-1",
1293
+ children: "No file open"
1294
+ }),
1295
+ /*#__PURE__*/ _jsx("p", {
1296
+ className: "text-xs text-zinc-600",
1297
+ children: "Create a note or select one from the sidebar"
1298
+ })
1299
+ ]
1300
+ })
1301
+ })
1302
+ ]
1303
+ })
1304
+ ]
1305
+ })
1306
+ ]
1307
+ }),
1308
+ /*#__PURE__*/ _jsxs("div", {
1309
+ className: "flex items-center justify-between h-[22px] px-2.5 border-t border-[#3c3c3c] bg-[#007acc] text-white text-[11px]",
1310
+ children: [
1311
+ /*#__PURE__*/ _jsx("div", {
1312
+ className: "flex items-center gap-3",
1313
+ children: editorState?.activeTab && /*#__PURE__*/ _jsx("span", {
1314
+ className: "opacity-90",
1315
+ children: getFileType(editorState.activeTab)
1316
+ })
1317
+ }),
1318
+ /*#__PURE__*/ _jsx("div", {
1319
+ className: "flex items-center gap-3",
1320
+ children: /*#__PURE__*/ _jsxs("span", {
1321
+ className: "opacity-70",
1322
+ children: [
1323
+ notes.length,
1324
+ " note",
1325
+ notes.length !== 1 ? 's' : ''
1326
+ ]
1327
+ })
1328
+ })
1329
+ ]
1330
+ }),
1331
+ /*#__PURE__*/ _jsx(NewNoteDialog, {
1332
+ open: showNewNote,
1333
+ onOpenChange: setShowNewNote,
1334
+ onCreateNote: handleCreateNote
1335
+ })
1336
+ ]
1337
+ });
1338
+ }