wiki-viewer 1.14.1 → 1.14.2

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 (384) hide show
  1. package/.next/standalone/.next/BUILD_ID +1 -1
  2. package/.next/standalone/.next/build-manifest.json +3 -3
  3. package/.next/standalone/.next/server/app/_global-error.html +1 -1
  4. package/.next/standalone/.next/server/app/_global-error.rsc +1 -1
  5. package/.next/standalone/.next/server/app/_global-error.segments/__PAGE__.segment.rsc +1 -1
  6. package/.next/standalone/.next/server/app/_global-error.segments/_full.segment.rsc +1 -1
  7. package/.next/standalone/.next/server/app/_global-error.segments/_head.segment.rsc +1 -1
  8. package/.next/standalone/.next/server/app/_global-error.segments/_index.segment.rsc +1 -1
  9. package/.next/standalone/.next/server/app/_global-error.segments/_tree.segment.rsc +1 -1
  10. package/.next/standalone/.next/server/app/_not-found.html +1 -1
  11. package/.next/standalone/.next/server/app/_not-found.rsc +1 -1
  12. package/.next/standalone/.next/server/app/_not-found.segments/_full.segment.rsc +1 -1
  13. package/.next/standalone/.next/server/app/_not-found.segments/_head.segment.rsc +1 -1
  14. package/.next/standalone/.next/server/app/_not-found.segments/_index.segment.rsc +1 -1
  15. package/.next/standalone/.next/server/app/_not-found.segments/_not-found/__PAGE__.segment.rsc +1 -1
  16. package/.next/standalone/.next/server/app/_not-found.segments/_not-found.segment.rsc +1 -1
  17. package/.next/standalone/.next/server/app/_not-found.segments/_tree.segment.rsc +1 -1
  18. package/.next/standalone/.next/server/app/api/agent/activity/route.js.nft.json +1 -1
  19. package/.next/standalone/.next/server/app/api/agent/events/[...path]/route.js.nft.json +1 -1
  20. package/.next/standalone/.next/server/app/api/agent/files/[...path]/route.js.nft.json +1 -1
  21. package/.next/standalone/.next/server/app/api/agent/fs/file/[...path]/route.js.nft.json +1 -1
  22. package/.next/standalone/.next/server/app/api/agent/fs/ls/[[...path]]/route.js.nft.json +1 -1
  23. package/.next/standalone/.next/server/app/api/agent/fs/move/route.js.nft.json +1 -1
  24. package/.next/standalone/.next/server/app/api/agent/fs/search/route.js.nft.json +1 -1
  25. package/.next/standalone/.next/server/app/api/agent/internal/span/route.js.nft.json +1 -1
  26. package/.next/standalone/.next/server/app/api/agent/settings/route.js.nft.json +1 -1
  27. package/.next/standalone/.next/server/app/api/agent/sidecar/[...path]/route.js.nft.json +1 -1
  28. package/.next/standalone/.next/server/app/api/assets/[...path]/route.js.nft.json +1 -1
  29. package/.next/standalone/.next/server/app/api/share/[token]/route.js.nft.json +1 -1
  30. package/.next/standalone/.next/server/app/api/share/route.js.nft.json +1 -1
  31. package/.next/standalone/.next/server/app/api/system/reveal/route.js.nft.json +1 -1
  32. package/.next/standalone/.next/server/app/api/system/set-root/route.js.nft.json +1 -1
  33. package/.next/standalone/.next/server/app/api/system/workspaces/[id]/open/route.js.nft.json +1 -1
  34. package/.next/standalone/.next/server/app/api/system/workspaces/[id]/refresh/route.js.nft.json +1 -1
  35. package/.next/standalone/.next/server/app/api/system/workspaces/[id]/route.js.nft.json +1 -1
  36. package/.next/standalone/.next/server/app/api/system/workspaces/route.js.nft.json +1 -1
  37. package/.next/standalone/.next/server/app/api/upload/[...path]/route.js.nft.json +1 -1
  38. package/.next/standalone/.next/server/app/api/wiki/app/route.js.nft.json +1 -1
  39. package/.next/standalone/.next/server/app/api/wiki/backlinks/route.js.nft.json +1 -1
  40. package/.next/standalone/.next/server/app/api/wiki/content/route.js.nft.json +1 -1
  41. package/.next/standalone/.next/server/app/api/wiki/download/route.js.nft.json +1 -1
  42. package/.next/standalone/.next/server/app/api/wiki/file/route.js.nft.json +1 -1
  43. package/.next/standalone/.next/server/app/api/wiki/folder/route.js.nft.json +1 -1
  44. package/.next/standalone/.next/server/app/api/wiki/git-branches/route.js.nft.json +1 -1
  45. package/.next/standalone/.next/server/app/api/wiki/git-checkout/route.js.nft.json +1 -1
  46. package/.next/standalone/.next/server/app/api/wiki/git-diff/route.js.nft.json +1 -1
  47. package/.next/standalone/.next/server/app/api/wiki/git-file-info/route.js.nft.json +1 -1
  48. package/.next/standalone/.next/server/app/api/wiki/git-history/route.js.nft.json +1 -1
  49. package/.next/standalone/.next/server/app/api/wiki/git-pull/route.js.nft.json +1 -1
  50. package/.next/standalone/.next/server/app/api/wiki/move/route.js.nft.json +1 -1
  51. package/.next/standalone/.next/server/app/api/wiki/new-file/route.js.nft.json +1 -1
  52. package/.next/standalone/.next/server/app/api/wiki/outlinks/route.js.nft.json +1 -1
  53. package/.next/standalone/.next/server/app/api/wiki/page/route.js.nft.json +1 -1
  54. package/.next/standalone/.next/server/app/api/wiki/presence/route.js.nft.json +1 -1
  55. package/.next/standalone/.next/server/app/api/wiki/route.js.nft.json +1 -1
  56. package/.next/standalone/.next/server/app/api/wiki/search/route.js.nft.json +1 -1
  57. package/.next/standalone/.next/server/app/api/wiki/slugs/route.js.nft.json +1 -1
  58. package/.next/standalone/.next/server/app/api/wiki/upload/route.js.nft.json +1 -1
  59. package/.next/standalone/.next/server/app/api/wiki/watch/route.js.nft.json +1 -1
  60. package/.next/standalone/.next/server/app/index.html +1 -1
  61. package/.next/standalone/.next/server/app/index.rsc +1 -1
  62. package/.next/standalone/.next/server/app/index.segments/__PAGE__.segment.rsc +1 -1
  63. package/.next/standalone/.next/server/app/index.segments/_full.segment.rsc +1 -1
  64. package/.next/standalone/.next/server/app/index.segments/_head.segment.rsc +1 -1
  65. package/.next/standalone/.next/server/app/index.segments/_index.segment.rsc +1 -1
  66. package/.next/standalone/.next/server/app/index.segments/_tree.segment.rsc +1 -1
  67. package/.next/standalone/.next/server/middleware-build-manifest.js +3 -3
  68. package/.next/standalone/.next/server/middleware-manifest.json +1 -1
  69. package/.next/standalone/.next/server/pages/404.html +1 -1
  70. package/.next/standalone/.next/server/pages/500.html +1 -1
  71. package/.next/standalone/package.json +1 -1
  72. package/bin/postbuild.js +21 -0
  73. package/package.json +1 -1
  74. package/.next/standalone/.github/workflows/publish.yml +0 -37
  75. package/.next/standalone/.handoffs/archive/handoff-20260612-113332.md +0 -98
  76. package/.next/standalone/.handoffs/archive/handoff-20260612-141032.md +0 -73
  77. package/.next/standalone/.pi/ownership.json +0 -3
  78. package/.next/standalone/AGENTS.md +0 -114
  79. package/.next/standalone/DESIGN.md +0 -521
  80. package/.next/standalone/README.md +0 -821
  81. package/.next/standalone/TODO.md +0 -20
  82. package/.next/standalone/agents/bootstrap-prompt.md +0 -14
  83. package/.next/standalone/agents/wiki-viewer-skill/SKILL.md +0 -456
  84. package/.next/standalone/bin/postbuild.js +0 -78
  85. package/.next/standalone/bin/wiki-viewer.js +0 -922
  86. package/.next/standalone/certificates/localhost-key.pem +0 -28
  87. package/.next/standalone/certificates/localhost.pem +0 -24
  88. package/.next/standalone/docs/agent-collab-plan.md +0 -1615
  89. package/.next/standalone/docs/agent-collab-v2-plan.md +0 -771
  90. package/.next/standalone/docs/agent-fs-plan.md +0 -232
  91. package/.next/standalone/docs/editorial-skin-spec.md +0 -242
  92. package/.next/standalone/docs/file-vs-collab-authority.md +0 -124
  93. package/.next/standalone/docs/mobile-readiness-spec.md +0 -229
  94. package/.next/standalone/docs/workspacing-plan.md +0 -364
  95. package/.next/standalone/packages/wiki-viewer-mcp/README.md +0 -195
  96. package/.next/standalone/packages/wiki-viewer-mcp/bench-e2e.mjs +0 -166
  97. package/.next/standalone/packages/wiki-viewer-mcp/bench-latency.mjs +0 -87
  98. package/.next/standalone/packages/wiki-viewer-mcp/bench-payload.mjs +0 -45
  99. package/.next/standalone/packages/wiki-viewer-mcp/dist/http-client.js +0 -331
  100. package/.next/standalone/packages/wiki-viewer-mcp/dist/index.js +0 -531
  101. package/.next/standalone/packages/wiki-viewer-mcp/dist/register.js +0 -94
  102. package/.next/standalone/packages/wiki-viewer-mcp/dist/state-cache.js +0 -28
  103. package/.next/standalone/packages/wiki-viewer-mcp/package-lock.json +0 -1716
  104. package/.next/standalone/packages/wiki-viewer-mcp/package.json +0 -41
  105. package/.next/standalone/packages/wiki-viewer-mcp/src/http-client.ts +0 -459
  106. package/.next/standalone/packages/wiki-viewer-mcp/src/index.ts +0 -638
  107. package/.next/standalone/packages/wiki-viewer-mcp/src/register.ts +0 -144
  108. package/.next/standalone/packages/wiki-viewer-mcp/src/state-cache.ts +0 -55
  109. package/.next/standalone/packages/wiki-viewer-mcp/tsconfig.json +0 -19
  110. package/.next/standalone/pnpm-lock.yaml +0 -6697
  111. package/.next/standalone/pnpm-workspace.yaml +0 -8
  112. package/.next/standalone/postcss.config.mjs +0 -2
  113. package/.next/standalone/src/app/api/agent/activity/route.ts +0 -59
  114. package/.next/standalone/src/app/api/agent/admin/agents/[agentId]/revoke/route.ts +0 -40
  115. package/.next/standalone/src/app/api/agent/admin/agents/route.ts +0 -33
  116. package/.next/standalone/src/app/api/agent/admin/registrations/[regId]/approve/route.ts +0 -83
  117. package/.next/standalone/src/app/api/agent/admin/registrations/[regId]/deny/route.ts +0 -36
  118. package/.next/standalone/src/app/api/agent/admin/registrations/route.ts +0 -27
  119. package/.next/standalone/src/app/api/agent/events/[...path]/route.ts +0 -148
  120. package/.next/standalone/src/app/api/agent/files/[...path]/route.ts +0 -219
  121. package/.next/standalone/src/app/api/agent/fs/file/[...path]/route.ts +0 -446
  122. package/.next/standalone/src/app/api/agent/fs/ls/[[...path]]/route.ts +0 -152
  123. package/.next/standalone/src/app/api/agent/fs/move/route.ts +0 -130
  124. package/.next/standalone/src/app/api/agent/fs/search/route.ts +0 -272
  125. package/.next/standalone/src/app/api/agent/internal/span/route.ts +0 -121
  126. package/.next/standalone/src/app/api/agent/register/[regId]/route.ts +0 -50
  127. package/.next/standalone/src/app/api/agent/register/route.ts +0 -118
  128. package/.next/standalone/src/app/api/agent/settings/route.ts +0 -34
  129. package/.next/standalone/src/app/api/agent/settings/token/regenerate/route.ts +0 -20
  130. package/.next/standalone/src/app/api/agent/sidecar/[...path]/route.ts +0 -53
  131. package/.next/standalone/src/app/api/agents/install/route.ts +0 -143
  132. package/.next/standalone/src/app/api/agents/skill/route.ts +0 -20
  133. package/.next/standalone/src/app/api/agents/skill.tar.gz/route.ts +0 -87
  134. package/.next/standalone/src/app/api/app-proxy/[...path]/route.ts +0 -247
  135. package/.next/standalone/src/app/api/assets/[...path]/route.ts +0 -75
  136. package/.next/standalone/src/app/api/auth/[...all]/route.ts +0 -7
  137. package/.next/standalone/src/app/api/owner/init/route.ts +0 -14
  138. package/.next/standalone/src/app/api/share/[token]/route.ts +0 -269
  139. package/.next/standalone/src/app/api/share/route.ts +0 -127
  140. package/.next/standalone/src/app/api/system/admins/route.ts +0 -103
  141. package/.next/standalone/src/app/api/system/auth-config/route.ts +0 -22
  142. package/.next/standalone/src/app/api/system/auth-settings/route.ts +0 -86
  143. package/.next/standalone/src/app/api/system/browse/route.ts +0 -82
  144. package/.next/standalone/src/app/api/system/clear-root/route.ts +0 -16
  145. package/.next/standalone/src/app/api/system/config/route.ts +0 -14
  146. package/.next/standalone/src/app/api/system/pins/route.ts +0 -38
  147. package/.next/standalone/src/app/api/system/reveal/route.ts +0 -36
  148. package/.next/standalone/src/app/api/system/root-status/route.ts +0 -13
  149. package/.next/standalone/src/app/api/system/set-root/route.ts +0 -53
  150. package/.next/standalone/src/app/api/system/users/route.ts +0 -120
  151. package/.next/standalone/src/app/api/system/workspaces/[id]/open/route.ts +0 -34
  152. package/.next/standalone/src/app/api/system/workspaces/[id]/refresh/route.ts +0 -32
  153. package/.next/standalone/src/app/api/system/workspaces/[id]/route.ts +0 -78
  154. package/.next/standalone/src/app/api/system/workspaces/route.ts +0 -128
  155. package/.next/standalone/src/app/api/upload/[...path]/route.ts +0 -85
  156. package/.next/standalone/src/app/api/wiki/app/route.ts +0 -60
  157. package/.next/standalone/src/app/api/wiki/backlinks/route.ts +0 -29
  158. package/.next/standalone/src/app/api/wiki/content/route.ts +0 -159
  159. package/.next/standalone/src/app/api/wiki/download/route.ts +0 -100
  160. package/.next/standalone/src/app/api/wiki/file/route.ts +0 -57
  161. package/.next/standalone/src/app/api/wiki/folder/route.ts +0 -34
  162. package/.next/standalone/src/app/api/wiki/git-branches/route.ts +0 -32
  163. package/.next/standalone/src/app/api/wiki/git-checkout/route.ts +0 -45
  164. package/.next/standalone/src/app/api/wiki/git-diff/route.ts +0 -33
  165. package/.next/standalone/src/app/api/wiki/git-file-info/route.ts +0 -27
  166. package/.next/standalone/src/app/api/wiki/git-history/route.ts +0 -27
  167. package/.next/standalone/src/app/api/wiki/git-pull/route.ts +0 -48
  168. package/.next/standalone/src/app/api/wiki/move/route.ts +0 -61
  169. package/.next/standalone/src/app/api/wiki/new-file/route.ts +0 -56
  170. package/.next/standalone/src/app/api/wiki/outlinks/route.ts +0 -76
  171. package/.next/standalone/src/app/api/wiki/page/route.ts +0 -92
  172. package/.next/standalone/src/app/api/wiki/presence/route.ts +0 -56
  173. package/.next/standalone/src/app/api/wiki/route.ts +0 -116
  174. package/.next/standalone/src/app/api/wiki/search/route.ts +0 -44
  175. package/.next/standalone/src/app/api/wiki/slugs/route.ts +0 -54
  176. package/.next/standalone/src/app/api/wiki/upload/route.ts +0 -95
  177. package/.next/standalone/src/app/api/wiki/watch/route.ts +0 -67
  178. package/.next/standalone/src/app/globals.css +0 -1249
  179. package/.next/standalone/src/app/icon.svg +0 -11
  180. package/.next/standalone/src/app/layout.tsx +0 -78
  181. package/.next/standalone/src/app/manifest.ts +0 -30
  182. package/.next/standalone/src/app/page.tsx +0 -3260
  183. package/.next/standalone/src/app/s/[token]/page.tsx +0 -357
  184. package/.next/standalone/src/app/signin/page.tsx +0 -16
  185. package/.next/standalone/src/app/signin/signin-form.tsx +0 -238
  186. package/.next/standalone/src/components/ai-panel/activity-row.tsx +0 -284
  187. package/.next/standalone/src/components/ai-panel/ai-panel.tsx +0 -311
  188. package/.next/standalone/src/components/ai-panel/token-section.tsx +0 -313
  189. package/.next/standalone/src/components/auth-settings-sheet.tsx +0 -474
  190. package/.next/standalone/src/components/confirm-dialog.tsx +0 -56
  191. package/.next/standalone/src/components/dir-picker.tsx +0 -606
  192. package/.next/standalone/src/components/editor/backlinks-panel.tsx +0 -139
  193. package/.next/standalone/src/components/editor/bubble-menu.tsx +0 -346
  194. package/.next/standalone/src/components/editor/callout-extension.ts +0 -36
  195. package/.next/standalone/src/components/editor/comment-pip.tsx +0 -56
  196. package/.next/standalone/src/components/editor/comment-thread.tsx +0 -254
  197. package/.next/standalone/src/components/editor/csv-viewer.tsx +0 -379
  198. package/.next/standalone/src/components/editor/document-outline.tsx +0 -230
  199. package/.next/standalone/src/components/editor/editor-toolbar.tsx +0 -564
  200. package/.next/standalone/src/components/editor/editor.tsx +0 -1327
  201. package/.next/standalone/src/components/editor/extensions/drag-handle.ts +0 -325
  202. package/.next/standalone/src/components/editor/extensions/heading-anchors.ts +0 -55
  203. package/.next/standalone/src/components/editor/extensions/proof-span.ts +0 -60
  204. package/.next/standalone/src/components/editor/extensions/resizable-image.tsx +0 -159
  205. package/.next/standalone/src/components/editor/extensions.ts +0 -150
  206. package/.next/standalone/src/components/editor/file-fallback-viewer.tsx +0 -75
  207. package/.next/standalone/src/components/editor/folder-index.tsx +0 -236
  208. package/.next/standalone/src/components/editor/google-doc-viewer.tsx +0 -73
  209. package/.next/standalone/src/components/editor/image-viewer.tsx +0 -57
  210. package/.next/standalone/src/components/editor/large-file-gate.tsx +0 -108
  211. package/.next/standalone/src/components/editor/link-popover.tsx +0 -111
  212. package/.next/standalone/src/components/editor/media-popover.tsx +0 -212
  213. package/.next/standalone/src/components/editor/media-viewer.tsx +0 -70
  214. package/.next/standalone/src/components/editor/mermaid-viewer.tsx +0 -286
  215. package/.next/standalone/src/components/editor/node-app-viewer.tsx +0 -328
  216. package/.next/standalone/src/components/editor/notebook-viewer.tsx +0 -371
  217. package/.next/standalone/src/components/editor/office/docx-viewer.tsx +0 -93
  218. package/.next/standalone/src/components/editor/office/office-chrome.tsx +0 -83
  219. package/.next/standalone/src/components/editor/office/pptx-viewer.tsx +0 -104
  220. package/.next/standalone/src/components/editor/office/xlsx-viewer.tsx +0 -192
  221. package/.next/standalone/src/components/editor/pdf-viewer.tsx +0 -32
  222. package/.next/standalone/src/components/editor/proof-span-popover.tsx +0 -162
  223. package/.next/standalone/src/components/editor/slash-commands.tsx +0 -629
  224. package/.next/standalone/src/components/editor/source-viewer.tsx +0 -289
  225. package/.next/standalone/src/components/editor/suggest-edit-popover.tsx +0 -229
  226. package/.next/standalone/src/components/editor/suggestion-card.tsx +0 -206
  227. package/.next/standalone/src/components/editor/table-menu.tsx +0 -232
  228. package/.next/standalone/src/components/editor/view-mode-comment-button.tsx +0 -77
  229. package/.next/standalone/src/components/editor/website-viewer.tsx +0 -75
  230. package/.next/standalone/src/components/editor/wiki-link-create-dialog.tsx +0 -189
  231. package/.next/standalone/src/components/editor/wiki-link-decorator.ts +0 -79
  232. package/.next/standalone/src/components/editor/wiki-link-extension.ts +0 -120
  233. package/.next/standalone/src/components/editor/wiki-link-picker.tsx +0 -250
  234. package/.next/standalone/src/components/layout/viewer-toolbar.tsx +0 -54
  235. package/.next/standalone/src/components/search/search-command-dialog.tsx +0 -246
  236. package/.next/standalone/src/components/search/sidebar-search-box.tsx +0 -121
  237. package/.next/standalone/src/components/search/snippet-text.tsx +0 -48
  238. package/.next/standalone/src/components/share-dialog.tsx +0 -307
  239. package/.next/standalone/src/components/theme-provider.tsx +0 -16
  240. package/.next/standalone/src/components/theme-toggle.tsx +0 -24
  241. package/.next/standalone/src/components/ui/badge.tsx +0 -35
  242. package/.next/standalone/src/components/ui/button.tsx +0 -56
  243. package/.next/standalone/src/components/ui/card.tsx +0 -63
  244. package/.next/standalone/src/components/ui/collapsible.tsx +0 -9
  245. package/.next/standalone/src/components/ui/command.tsx +0 -151
  246. package/.next/standalone/src/components/ui/context-menu.tsx +0 -191
  247. package/.next/standalone/src/components/ui/dialog.tsx +0 -119
  248. package/.next/standalone/src/components/ui/dropdown-menu.tsx +0 -194
  249. package/.next/standalone/src/components/ui/input.tsx +0 -22
  250. package/.next/standalone/src/components/ui/label.tsx +0 -25
  251. package/.next/standalone/src/components/ui/popover.tsx +0 -33
  252. package/.next/standalone/src/components/ui/scroll-area.tsx +0 -47
  253. package/.next/standalone/src/components/ui/select.tsx +0 -156
  254. package/.next/standalone/src/components/ui/separator.tsx +0 -30
  255. package/.next/standalone/src/components/ui/sheet.tsx +0 -140
  256. package/.next/standalone/src/components/ui/skeleton.tsx +0 -15
  257. package/.next/standalone/src/components/ui/switch.tsx +0 -28
  258. package/.next/standalone/src/components/ui/tabs.tsx +0 -54
  259. package/.next/standalone/src/components/ui/textarea.tsx +0 -21
  260. package/.next/standalone/src/components/ui/tip.tsx +0 -23
  261. package/.next/standalone/src/components/ui/toggle-group.tsx +0 -41
  262. package/.next/standalone/src/components/ui/tooltip.tsx +0 -27
  263. package/.next/standalone/src/components/view-width-toggle.tsx +0 -70
  264. package/.next/standalone/src/components/wiki/frontmatter-header.tsx +0 -164
  265. package/.next/standalone/src/hooks/use-is-mobile.ts +0 -14
  266. package/.next/standalone/src/lib/app-runner.ts +0 -272
  267. package/.next/standalone/src/lib/auth/admin.ts +0 -120
  268. package/.next/standalone/src/lib/auth/allowlist.ts +0 -50
  269. package/.next/standalone/src/lib/auth/client.ts +0 -4
  270. package/.next/standalone/src/lib/auth/csrf.ts +0 -68
  271. package/.next/standalone/src/lib/auth/server.ts +0 -215
  272. package/.next/standalone/src/lib/cabinets/tree.ts +0 -75
  273. package/.next/standalone/src/lib/config.ts +0 -114
  274. package/.next/standalone/src/lib/embeds/detect.ts +0 -142
  275. package/.next/standalone/src/lib/git-secrets.ts +0 -65
  276. package/.next/standalone/src/lib/git.ts +0 -503
  277. package/.next/standalone/src/lib/google/detect.ts +0 -107
  278. package/.next/standalone/src/lib/markdown/parse-frontmatter.ts +0 -104
  279. package/.next/standalone/src/lib/markdown/remark-wikilinks.ts +0 -100
  280. package/.next/standalone/src/lib/markdown/sanitize-schema.ts +0 -106
  281. package/.next/standalone/src/lib/markdown/to-html.ts +0 -282
  282. package/.next/standalone/src/lib/markdown/to-markdown.ts +0 -252
  283. package/.next/standalone/src/lib/proof/activity-shared.ts +0 -31
  284. package/.next/standalone/src/lib/proof/activity.ts +0 -74
  285. package/.next/standalone/src/lib/proof/audit.ts +0 -88
  286. package/.next/standalone/src/lib/proof/auth.ts +0 -143
  287. package/.next/standalone/src/lib/proof/block-refs.ts +0 -133
  288. package/.next/standalone/src/lib/proof/blocks.ts +0 -73
  289. package/.next/standalone/src/lib/proof/client-auth.ts +0 -23
  290. package/.next/standalone/src/lib/proof/collab-state.ts +0 -81
  291. package/.next/standalone/src/lib/proof/event-bus.ts +0 -47
  292. package/.next/standalone/src/lib/proof/file-lock.ts +0 -43
  293. package/.next/standalone/src/lib/proof/glob.ts +0 -51
  294. package/.next/standalone/src/lib/proof/idempotency.ts +0 -37
  295. package/.next/standalone/src/lib/proof/lease.ts +0 -117
  296. package/.next/standalone/src/lib/proof/mutex.ts +0 -36
  297. package/.next/standalone/src/lib/proof/ops-applier.ts +0 -727
  298. package/.next/standalone/src/lib/proof/owner-auth.ts +0 -2
  299. package/.next/standalone/src/lib/proof/pending.ts +0 -97
  300. package/.next/standalone/src/lib/proof/proof-span.ts +0 -141
  301. package/.next/standalone/src/lib/proof/rate-limit.ts +0 -53
  302. package/.next/standalone/src/lib/proof/raw-fs.ts +0 -197
  303. package/.next/standalone/src/lib/proof/register-rate-limit.ts +0 -53
  304. package/.next/standalone/src/lib/proof/registry.ts +0 -195
  305. package/.next/standalone/src/lib/proof/sidecar.ts +0 -103
  306. package/.next/standalone/src/lib/proof/suggest-capture.ts +0 -69
  307. package/.next/standalone/src/lib/proof/types.ts +0 -182
  308. package/.next/standalone/src/lib/proof-config.ts +0 -14
  309. package/.next/standalone/src/lib/root-dir.ts +0 -35
  310. package/.next/standalone/src/lib/search/indexable-exts.ts +0 -25
  311. package/.next/standalone/src/lib/search/indexer.ts +0 -634
  312. package/.next/standalone/src/lib/search/sanitize.ts +0 -35
  313. package/.next/standalone/src/lib/search/search-db.ts +0 -57
  314. package/.next/standalone/src/lib/search/watcher-pool.ts +0 -79
  315. package/.next/standalone/src/lib/shared-docs/db.ts +0 -177
  316. package/.next/standalone/src/lib/toast.ts +0 -9
  317. package/.next/standalone/src/lib/utils.ts +0 -6
  318. package/.next/standalone/src/lib/wiki-helpers.ts +0 -36
  319. package/.next/standalone/src/lib/workspace-client.ts +0 -82
  320. package/.next/standalone/src/lib/workspace-context.ts +0 -173
  321. package/.next/standalone/src/lib/workspaces.ts +0 -400
  322. package/.next/standalone/src/middleware.ts +0 -44
  323. package/.next/standalone/src/stores/ai-panel-store.ts +0 -79
  324. package/.next/standalone/src/stores/editor-store.ts +0 -439
  325. package/.next/standalone/src/stores/pin-store.ts +0 -56
  326. package/.next/standalone/src/stores/proof-store.ts +0 -124
  327. package/.next/standalone/src/stores/recent-store.ts +0 -51
  328. package/.next/standalone/src/stores/search-store.ts +0 -104
  329. package/.next/standalone/src/stores/show-hidden-store.ts +0 -26
  330. package/.next/standalone/src/stores/sidebar-width-store.ts +0 -39
  331. package/.next/standalone/src/stores/skin-store.ts +0 -42
  332. package/.next/standalone/src/stores/tree-store.ts +0 -52
  333. package/.next/standalone/src/stores/view-width-store.ts +0 -101
  334. package/.next/standalone/src/stores/wiki-slugs-store.ts +0 -75
  335. package/.next/standalone/src/tests/proof/activity-aggregator.test.ts +0 -146
  336. package/.next/standalone/src/tests/proof/admin-create-user.test.ts +0 -43
  337. package/.next/standalone/src/tests/proof/agent-fs.test.ts +0 -973
  338. package/.next/standalone/src/tests/proof/agent-ownership.test.ts +0 -140
  339. package/.next/standalone/src/tests/proof/agent-workspace-scope.test.ts +0 -134
  340. package/.next/standalone/src/tests/proof/agents-install.test.ts +0 -110
  341. package/.next/standalone/src/tests/proof/bench-write.ts +0 -179
  342. package/.next/standalone/src/tests/proof/better-auth.test.ts +0 -68
  343. package/.next/standalone/src/tests/proof/block-refs.test.ts +0 -108
  344. package/.next/standalone/src/tests/proof/blocks.test.ts +0 -92
  345. package/.next/standalone/src/tests/proof/collab-state.test.ts +0 -501
  346. package/.next/standalone/src/tests/proof/comments-ops.test.ts +0 -177
  347. package/.next/standalone/src/tests/proof/editor-roundtrip.test.ts +0 -85
  348. package/.next/standalone/src/tests/proof/external-edit.test.ts +0 -58
  349. package/.next/standalone/src/tests/proof/file-lock.test.ts +0 -80
  350. package/.next/standalone/src/tests/proof/git-branches-checkout.test.ts +0 -136
  351. package/.next/standalone/src/tests/proof/git-read-features.test.ts +0 -473
  352. package/.next/standalone/src/tests/proof/git-secrets.test.ts +0 -138
  353. package/.next/standalone/src/tests/proof/git-sparse.test.ts +0 -257
  354. package/.next/standalone/src/tests/proof/git-workspace.test.ts +0 -135
  355. package/.next/standalone/src/tests/proof/git.test.ts +0 -243
  356. package/.next/standalone/src/tests/proof/glob.test.ts +0 -82
  357. package/.next/standalone/src/tests/proof/helpers/auth-session.ts +0 -27
  358. package/.next/standalone/src/tests/proof/markdown-to-html.test.ts +0 -46
  359. package/.next/standalone/src/tests/proof/ops-applier.test.ts +0 -368
  360. package/.next/standalone/src/tests/proof/owner-init.test.ts +0 -2
  361. package/.next/standalone/src/tests/proof/parse-frontmatter.test.ts +0 -60
  362. package/.next/standalone/src/tests/proof/preload.ts +0 -21
  363. package/.next/standalone/src/tests/proof/proof-span.test.ts +0 -98
  364. package/.next/standalone/src/tests/proof/rate-limit.test.ts +0 -54
  365. package/.next/standalone/src/tests/proof/readonly-enforcement.test.ts +0 -161
  366. package/.next/standalone/src/tests/proof/reconcile-sidecar.test.ts +0 -195
  367. package/.next/standalone/src/tests/proof/registration-flow.test.ts +0 -330
  368. package/.next/standalone/src/tests/proof/registry.test.ts +0 -169
  369. package/.next/standalone/src/tests/proof/routes.test.ts +0 -516
  370. package/.next/standalone/src/tests/proof/search-index.test.ts +0 -376
  371. package/.next/standalone/src/tests/proof/sidecar-lifecycle.test.ts +0 -177
  372. package/.next/standalone/src/tests/proof/sidecar-trim.test.ts +0 -58
  373. package/.next/standalone/src/tests/proof/suggestion-ops.test.ts +0 -280
  374. package/.next/standalone/src/tests/proof/wiki-content-put.test.ts +0 -140
  375. package/.next/standalone/src/tests/proof/wiki-routes-auth.test.ts +0 -208
  376. package/.next/standalone/src/tests/proof/workspace-isolation.test.ts +0 -87
  377. package/.next/standalone/src/tests/proof/workspaces-api.test.ts +0 -227
  378. package/.next/standalone/src/types/index.ts +0 -47
  379. package/.next/standalone/tailwind.config.ts +0 -191
  380. package/.next/standalone/tsconfig.json +0 -41
  381. package/.next/standalone/tsconfig.tsbuildinfo +0 -1
  382. /package/.next/standalone/.next/static/{WMOTgfV82apmdovxzgbMx → rRyvFORvJoc5OWbCR2A_P}/_buildManifest.js +0 -0
  383. /package/.next/standalone/.next/static/{WMOTgfV82apmdovxzgbMx → rRyvFORvJoc5OWbCR2A_P}/_clientMiddlewareManifest.js +0 -0
  384. /package/.next/standalone/.next/static/{WMOTgfV82apmdovxzgbMx → rRyvFORvJoc5OWbCR2A_P}/_ssgManifest.js +0 -0
@@ -1,111 +0,0 @@
1
- "use client";
2
-
3
- import { ExternalLink, Link as LinkIcon, Trash2 } from "lucide-react";
4
- import { useEffect, useState } from "react";
5
-
6
- interface Props {
7
- anchor: { top: number; left: number };
8
- initialUrl?: string;
9
- onCancel: () => void;
10
- onApply: (url: string) => void;
11
- onRemove?: () => void;
12
- }
13
-
14
- export function LinkPopover({
15
- anchor,
16
- initialUrl = "",
17
- onCancel,
18
- onApply,
19
- onRemove,
20
- }: Props) {
21
- const [url, setUrl] = useState(initialUrl);
22
-
23
- useEffect(() => {
24
- const onKey = (e: KeyboardEvent) => {
25
- if (e.key === "Escape") onCancel();
26
- };
27
- window.addEventListener("keydown", onKey);
28
- return () => window.removeEventListener("keydown", onKey);
29
- }, [onCancel]);
30
-
31
- const apply = () => {
32
- const trimmed = url.trim();
33
- if (!trimmed) {
34
- onCancel();
35
- return;
36
- }
37
- onApply(trimmed);
38
- };
39
-
40
- return (
41
- <div
42
- className="absolute z-50 w-[340px] bg-popover border border-border rounded-lg shadow-xl overflow-hidden"
43
- style={{ top: anchor.top, left: anchor.left }}
44
- onMouseDown={(e) => e.stopPropagation()}
45
- >
46
- <div className="flex items-center justify-between px-3 py-2 border-b border-border">
47
- <div className="flex items-center gap-1.5 text-[12px] font-medium">
48
- <LinkIcon className="w-3.5 h-3.5" />
49
- {initialUrl ? "Edit link" : "Add link"}
50
- </div>
51
- <button
52
- type="button"
53
- onClick={onCancel}
54
- className="text-[11px] text-muted-foreground hover:text-foreground"
55
- >
56
- Cancel
57
- </button>
58
- </div>
59
-
60
- <div className="p-3 space-y-2">
61
- <input
62
- type="url"
63
- autoFocus
64
- value={url}
65
- placeholder="https://example.com"
66
- onChange={(e) => setUrl(e.target.value)}
67
- onKeyDown={(e) => {
68
- if (e.key === "Enter") {
69
- e.preventDefault();
70
- apply();
71
- }
72
- }}
73
- className="w-full bg-background border border-border rounded-md px-2.5 py-1.5 text-[12px] focus:outline-none focus:ring-2 focus:ring-primary/30"
74
- />
75
- <div className="flex items-center gap-2">
76
- <button
77
- type="button"
78
- onClick={apply}
79
- disabled={!url.trim()}
80
- className="flex-1 py-1.5 text-[12px] rounded-md bg-primary text-primary-foreground disabled:opacity-50 hover:bg-primary/90"
81
- >
82
- {initialUrl ? "Update" : "Add link"}
83
- </button>
84
- {initialUrl && (
85
- <>
86
- <a
87
- href={initialUrl}
88
- target="_blank"
89
- rel="noreferrer noopener"
90
- className="p-1.5 rounded-md border border-border hover:bg-accent text-muted-foreground hover:text-foreground"
91
- title="Open link"
92
- >
93
- <ExternalLink className="w-3.5 h-3.5" />
94
- </a>
95
- {onRemove && (
96
- <button
97
- type="button"
98
- onClick={onRemove}
99
- className="p-1.5 rounded-md border border-border hover:bg-accent text-destructive"
100
- title="Remove link"
101
- >
102
- <Trash2 className="w-3.5 h-3.5" />
103
- </button>
104
- )}
105
- </>
106
- )}
107
- </div>
108
- </div>
109
- </div>
110
- );
111
- }
@@ -1,212 +0,0 @@
1
- "use client";
2
-
3
- import { Clipboard, Link as LinkIcon, Upload } from "lucide-react";
4
- import { useRef, useState } from "react";
5
- import { cn } from "@/lib/utils";
6
- import { wsFetch } from "@/lib/workspace-client";
7
-
8
- export type MediaKind = "image" | "video" | "file";
9
-
10
- interface Props {
11
- kind: MediaKind;
12
- pagePath: string;
13
- onCancel: () => void;
14
- onInsert: (payload: { url: string; alt?: string; mimeType?: string }) => void;
15
- anchor: { top: number; left: number };
16
- }
17
-
18
- async function uploadFile(
19
- pagePath: string,
20
- file: File,
21
- ): Promise<{ url: string; filename: string } | null> {
22
- const formData = new FormData();
23
- formData.append("file", file);
24
- try {
25
- const res = await wsFetch(`/api/upload/${pagePath}`, {
26
- method: "POST",
27
- body: formData,
28
- });
29
- if (!res.ok) return null;
30
- const data = await res.json();
31
- return { url: data.url, filename: data.filename };
32
- } catch {
33
- return null;
34
- }
35
- }
36
-
37
- function mimeFor(kind: MediaKind) {
38
- if (kind === "image") return "image/*";
39
- if (kind === "video") return "video/*";
40
- return "*/*";
41
- }
42
-
43
- function titleFor(kind: MediaKind) {
44
- if (kind === "image") return "Insert image";
45
- if (kind === "video") return "Insert video";
46
- return "Attach file";
47
- }
48
-
49
- export function MediaPopover({
50
- kind,
51
- pagePath,
52
- onCancel,
53
- onInsert,
54
- anchor,
55
- }: Props) {
56
- const [tab, setTab] = useState<"upload" | "url">("upload");
57
- const [url, setUrl] = useState("");
58
- const [uploading, setUploading] = useState(false);
59
- const [err, setErr] = useState<string | null>(null);
60
- const fileInputRef = useRef<HTMLInputElement | null>(null);
61
-
62
- const handleFiles = async (files: FileList | null) => {
63
- if (!files || files.length === 0) return;
64
- setUploading(true);
65
- setErr(null);
66
- try {
67
- const file = files[0];
68
- const result = await uploadFile(pagePath, file);
69
- if (!result) {
70
- setErr("Upload failed.");
71
- return;
72
- }
73
- onInsert({ url: result.url, alt: file.name, mimeType: file.type });
74
- } finally {
75
- setUploading(false);
76
- }
77
- };
78
-
79
- const handleUrl = () => {
80
- const trimmed = url.trim();
81
- if (!trimmed) return;
82
- onInsert({ url: trimmed });
83
- };
84
-
85
- return (
86
- <div
87
- className="absolute z-50 w-[360px] bg-popover border border-border rounded-xl shadow-e-4 overflow-hidden"
88
- style={{ top: anchor.top, left: anchor.left }}
89
- onMouseDown={(e) => e.stopPropagation()}
90
- >
91
- <div className="flex items-center justify-between px-3 py-2 border-b border-border">
92
- <div className="text-[12px] font-medium">{titleFor(kind)}</div>
93
- <button
94
- type="button"
95
- onClick={onCancel}
96
- className="text-[11px] text-muted-foreground hover:text-foreground"
97
- >
98
- Cancel
99
- </button>
100
- </div>
101
-
102
- <div className="flex border-b border-border bg-muted/30">
103
- <button
104
- type="button"
105
- onClick={() => setTab("upload")}
106
- className={cn(
107
- "flex-1 py-1.5 text-[11px] flex items-center justify-center gap-1.5 transition-colors",
108
- tab === "upload"
109
- ? "bg-background text-foreground border-b-2 border-primary"
110
- : "text-muted-foreground hover:text-foreground",
111
- )}
112
- >
113
- <Upload className="w-3 h-3" /> Upload
114
- </button>
115
- <button
116
- type="button"
117
- onClick={() => setTab("url")}
118
- className={cn(
119
- "flex-1 py-1.5 text-[11px] flex items-center justify-center gap-1.5 transition-colors",
120
- tab === "url"
121
- ? "bg-background text-foreground border-b-2 border-primary"
122
- : "text-muted-foreground hover:text-foreground",
123
- )}
124
- >
125
- <LinkIcon className="w-3 h-3" /> From URL
126
- </button>
127
- </div>
128
-
129
- {tab === "upload" ? (
130
- <div
131
- className="p-4"
132
- onDragOver={(e) => {
133
- e.preventDefault();
134
- e.stopPropagation();
135
- }}
136
- onDrop={(e) => {
137
- e.preventDefault();
138
- e.stopPropagation();
139
- handleFiles(e.dataTransfer.files);
140
- }}
141
- >
142
- <button
143
- type="button"
144
- onClick={() => fileInputRef.current?.click()}
145
- disabled={uploading}
146
- className="w-full border-2 border-dashed border-border rounded-sm py-6 flex flex-col items-center justify-center text-muted-foreground hover:bg-accent/30 transition-colors"
147
- >
148
- <Upload className="w-5 h-5 mb-1.5" />
149
- <span className="text-[12px] font-medium">
150
- {uploading ? "Uploading…" : `Click to upload ${kind}`}
151
- </span>
152
- <span className="text-[10px] mt-0.5">or drop a file here</span>
153
- </button>
154
- <input
155
- ref={fileInputRef}
156
- type="file"
157
- accept={mimeFor(kind)}
158
- className="hidden"
159
- onChange={(e) => handleFiles(e.target.files)}
160
- />
161
- {err && (
162
- <div className="mt-2 text-[11px] text-destructive">{err}</div>
163
- )}
164
- </div>
165
- ) : (
166
- <div className="p-3 space-y-2">
167
- <input
168
- type="url"
169
- autoFocus
170
- value={url}
171
- placeholder={
172
- kind === "image"
173
- ? "https://example.com/image.png"
174
- : kind === "video"
175
- ? "https://example.com/video.mp4"
176
- : "https://example.com/file"
177
- }
178
- onChange={(e) => setUrl(e.target.value)}
179
- onKeyDown={(e) => {
180
- if (e.key === "Enter") {
181
- e.preventDefault();
182
- handleUrl();
183
- } else if (e.key === "Escape") {
184
- onCancel();
185
- }
186
- }}
187
- className="w-full bg-background border border-border rounded-sm px-2.5 py-1.5 text-[12px] focus:outline-none focus:ring-2 focus:ring-primary/30"
188
- />
189
- <button
190
- type="button"
191
- onClick={handleUrl}
192
- disabled={!url.trim()}
193
- className="w-full py-1.5 text-[12px] rounded-sm bg-primary text-primary-foreground disabled:opacity-50 hover:bg-primary/90"
194
- >
195
- Insert
196
- </button>
197
- </div>
198
- )}
199
-
200
- <div className="px-3 py-2 border-t border-border bg-muted/30 text-[10px] text-muted-foreground flex items-start gap-1.5">
201
- <Clipboard className="w-3 h-3 shrink-0 mt-[1px]" />
202
- <span>
203
- Tip: you can also{" "}
204
- <strong className="text-foreground/80">paste</strong> or{" "}
205
- <strong className="text-foreground/80">drag &amp; drop</strong> files
206
- directly into the page — they&apos;ll be saved alongside this page
207
- automatically.
208
- </span>
209
- </div>
210
- </div>
211
- );
212
- }
@@ -1,70 +0,0 @@
1
- "use client";
2
-
3
- import { Download, ExternalLink } from "lucide-react";
4
- import { ViewerToolbar } from "@/components/layout/viewer-toolbar";
5
- import { Button } from "@/components/ui/button";
6
- import { withWs } from "@/lib/workspace-client";
7
-
8
- interface MediaViewerProps {
9
- path: string;
10
- title: string;
11
- type: "video" | "audio";
12
- }
13
-
14
- export function MediaViewer({ path, type }: MediaViewerProps) {
15
- const src = withWs(`/api/assets/${path}`);
16
- const filename = path.split("/").pop() || path;
17
- const ext = filename.includes(".")
18
- ? filename.split(".").pop()?.toUpperCase()
19
- : type.toUpperCase();
20
-
21
- return (
22
- <div className="flex-1 flex flex-col overflow-hidden">
23
- <ViewerToolbar path={path} badge={ext}>
24
- <Button
25
- variant="ghost"
26
- size="sm"
27
- className="h-7 gap-1.5 text-xs"
28
- onClick={() => {
29
- const a = document.createElement("a");
30
- a.href = src;
31
- a.download = filename;
32
- a.click();
33
- }}
34
- >
35
- <Download className="h-3.5 w-3.5" />
36
- Download
37
- </Button>
38
- <Button
39
- variant="ghost"
40
- size="sm"
41
- className="h-7 gap-1.5 text-xs"
42
- onClick={() => window.open(src, "_blank")}
43
- >
44
- <ExternalLink className="h-3.5 w-3.5" />
45
- Open in new tab
46
- </Button>
47
- </ViewerToolbar>
48
- <div className="flex-1 overflow-auto flex items-center justify-center bg-[#1a1a1a] p-8">
49
- {type === "video" ? (
50
- <video
51
- src={src}
52
- controls
53
- className="max-w-full max-h-full rounded-md shadow-lg"
54
- >
55
- Your browser does not support the video element.
56
- </video>
57
- ) : (
58
- <div className="w-full max-w-lg space-y-4">
59
- <div className="text-center text-muted-foreground text-sm">
60
- {filename}
61
- </div>
62
- <audio src={src} controls className="w-full">
63
- Your browser does not support the audio element.
64
- </audio>
65
- </div>
66
- )}
67
- </div>
68
- </div>
69
- );
70
- }
@@ -1,286 +0,0 @@
1
- "use client";
2
-
3
- import {
4
- Check,
5
- Code2,
6
- Copy,
7
- Download,
8
- Eye,
9
- Maximize,
10
- ZoomIn,
11
- ZoomOut,
12
- } from "lucide-react";
13
- import { useCallback, useEffect, useRef, useState } from "react";
14
- import { ViewerToolbar } from "@/components/layout/viewer-toolbar";
15
- import { Button } from "@/components/ui/button";
16
- import { withWs, wsFetch } from "@/lib/workspace-client";
17
-
18
- interface MermaidViewerProps {
19
- path: string;
20
- title: string;
21
- }
22
-
23
- export function MermaidViewer({ path, title }: MermaidViewerProps) {
24
- const [source, setSource] = useState("");
25
- const [svg, setSvg] = useState("");
26
- const [error, setError] = useState("");
27
- const [loading, setLoading] = useState(true);
28
- const [showSource, setShowSource] = useState(false);
29
- const [copied, setCopied] = useState(false);
30
- const [zoom, setZoom] = useState(1);
31
- const [pan, setPan] = useState({ x: 0, y: 0 });
32
- const [isPanning, setIsPanning] = useState(false);
33
- const panStart = useRef({ x: 0, y: 0, panX: 0, panY: 0 });
34
- const containerRef = useRef<HTMLDivElement>(null);
35
- const viewportRef = useRef<HTMLDivElement>(null);
36
- const renderIdRef = useRef(0);
37
-
38
- const ZOOM_STEP = 0.25;
39
- const ZOOM_MIN = 0.25;
40
- const ZOOM_MAX = 5;
41
-
42
- const zoomIn = () => setZoom((z) => Math.min(z + ZOOM_STEP, ZOOM_MAX));
43
- const zoomOut = () => setZoom((z) => Math.max(z - ZOOM_STEP, ZOOM_MIN));
44
- const resetView = () => {
45
- setZoom(1);
46
- setPan({ x: 0, y: 0 });
47
- };
48
-
49
- // Mouse wheel zoom
50
- const handleWheel = useCallback((e: React.WheelEvent) => {
51
- if (e.ctrlKey || e.metaKey) {
52
- e.preventDefault();
53
- const delta = e.deltaY > 0 ? -ZOOM_STEP : ZOOM_STEP;
54
- setZoom((z) => Math.min(Math.max(z + delta, ZOOM_MIN), ZOOM_MAX));
55
- }
56
- }, []);
57
-
58
- // Pan via mouse drag
59
- const handlePointerDown = useCallback(
60
- (e: React.PointerEvent) => {
61
- if (e.button !== 0) return;
62
- setIsPanning(true);
63
- panStart.current = {
64
- x: e.clientX,
65
- y: e.clientY,
66
- panX: pan.x,
67
- panY: pan.y,
68
- };
69
- (e.target as HTMLElement).setPointerCapture(e.pointerId);
70
- },
71
- [pan],
72
- );
73
-
74
- const handlePointerMove = useCallback(
75
- (e: React.PointerEvent) => {
76
- if (!isPanning) return;
77
- setPan({
78
- x: panStart.current.panX + (e.clientX - panStart.current.x),
79
- y: panStart.current.panY + (e.clientY - panStart.current.y),
80
- });
81
- },
82
- [isPanning],
83
- );
84
-
85
- const handlePointerUp = useCallback(() => {
86
- setIsPanning(false);
87
- }, []);
88
-
89
- const assetUrl = withWs(`/api/assets/${path}`);
90
- const _filename = path.split("/").pop() || path;
91
-
92
- const fetchAndRender = useCallback(async () => {
93
- setLoading(true);
94
- setError("");
95
- try {
96
- const res = await wsFetch(assetUrl);
97
- if (!res.ok) throw new Error("Failed to fetch file");
98
- const text = await res.text();
99
- setSource(text);
100
-
101
- const mermaid = (await import("mermaid")).default;
102
- mermaid.initialize({
103
- startOnLoad: false,
104
- theme: document.documentElement.classList.contains("dark")
105
- ? "dark"
106
- : "default",
107
- securityLevel: "loose",
108
- suppressErrorRendering: true,
109
- });
110
-
111
- // Validate syntax first to avoid mermaid injecting error SVGs into the DOM
112
- await mermaid.parse(text.trim());
113
-
114
- const id = `mermaid-${++renderIdRef.current}`;
115
- const { svg: rendered } = await mermaid.render(id, text.trim());
116
- setSvg(rendered);
117
- } catch (err) {
118
- // Clean up any error elements mermaid may have injected into the DOM
119
- document
120
- .querySelectorAll('[id^="dmermaid-"], [id^="d"]:has(> .error-icon)')
121
- .forEach((el) => el.remove());
122
- setError(err instanceof Error ? err.message : "Failed to render diagram");
123
- } finally {
124
- setLoading(false);
125
- }
126
- }, [assetUrl]);
127
-
128
- useEffect(() => {
129
- void fetchAndRender();
130
- }, [fetchAndRender]);
131
-
132
- const copySource = () => {
133
- navigator.clipboard.writeText(source);
134
- setCopied(true);
135
- setTimeout(() => setCopied(false), 2000);
136
- };
137
-
138
- const downloadSvg = () => {
139
- if (!svg) return;
140
- const blob = new Blob([svg], { type: "image/svg+xml" });
141
- const url = URL.createObjectURL(blob);
142
- const a = document.createElement("a");
143
- a.href = url;
144
- a.download = `${title}.svg`;
145
- a.click();
146
- URL.revokeObjectURL(url);
147
- };
148
-
149
- return (
150
- <div className="flex-1 flex flex-col overflow-hidden">
151
- <ViewerToolbar path={path} badge="MERMAID">
152
- <Button
153
- variant="ghost"
154
- size="sm"
155
- className={`h-7 gap-1.5 text-xs ${showSource ? "bg-muted" : ""}`}
156
- onClick={() => setShowSource((v) => !v)}
157
- >
158
- {showSource ? (
159
- <Eye className="h-3.5 w-3.5" />
160
- ) : (
161
- <Code2 className="h-3.5 w-3.5" />
162
- )}
163
- {showSource ? "Diagram" : "Code"}
164
- </Button>
165
- <Button
166
- variant="ghost"
167
- size="sm"
168
- className="h-7 gap-1.5 text-xs"
169
- onClick={copySource}
170
- >
171
- {copied ? (
172
- <Check className="h-3.5 w-3.5 text-green-500" />
173
- ) : (
174
- <Copy className="h-3.5 w-3.5" />
175
- )}
176
- {copied ? "Copied" : "Copy"}
177
- </Button>
178
- {svg && !showSource && (
179
- <>
180
- <div className="h-4 w-px bg-border mx-0.5" />
181
- <Button
182
- variant="ghost"
183
- size="sm"
184
- className="h-7 w-7 p-0"
185
- onClick={zoomOut}
186
- title="Zoom out"
187
- >
188
- <ZoomOut className="h-3.5 w-3.5" />
189
- </Button>
190
- <span className="text-[11px] text-muted-foreground tabular-nums w-10 text-center select-none">
191
- {Math.round(zoom * 100)}%
192
- </span>
193
- <Button
194
- variant="ghost"
195
- size="sm"
196
- className="h-7 w-7 p-0"
197
- onClick={zoomIn}
198
- title="Zoom in"
199
- >
200
- <ZoomIn className="h-3.5 w-3.5" />
201
- </Button>
202
- <Button
203
- variant="ghost"
204
- size="sm"
205
- className="h-7 w-7 p-0"
206
- onClick={resetView}
207
- title="Reset view"
208
- >
209
- <Maximize className="h-3.5 w-3.5" />
210
- </Button>
211
- <div className="h-4 w-px bg-border mx-0.5" />
212
- </>
213
- )}
214
- {svg && (
215
- <Button
216
- variant="ghost"
217
- size="sm"
218
- className="h-7 gap-1.5 text-xs"
219
- onClick={downloadSvg}
220
- >
221
- <Download className="h-3.5 w-3.5" />
222
- SVG
223
- </Button>
224
- )}
225
- </ViewerToolbar>
226
- <div className="flex-1 overflow-auto">
227
- {loading ? (
228
- <div className="flex items-center justify-center h-full text-muted-foreground text-sm">
229
- Rendering diagram...
230
- </div>
231
- ) : showSource ? (
232
- <pre className="p-4 text-[13px] leading-relaxed font-mono bg-[#1e1e1e]">
233
- <code>
234
- {source.split("\n").map((line, i) => (
235
- <div key={i} className="flex">
236
- <span className="inline-block w-12 pr-4 text-right text-[#858585] select-none shrink-0">
237
- {i + 1}
238
- </span>
239
- <span className="text-[#d4d4d4] flex-1">{line || "\n"}</span>
240
- </div>
241
- ))}
242
- </code>
243
- </pre>
244
- ) : error ? (
245
- <div className="flex flex-col items-center justify-center h-full gap-4 text-sm p-8">
246
- <div className="flex flex-col items-center gap-2">
247
- <div className="h-10 w-10 rounded-full bg-red-500/10 flex items-center justify-center">
248
- <Code2 className="h-5 w-5 text-red-500" />
249
- </div>
250
- <p className="text-red-500 font-medium">Diagram syntax error</p>
251
- </div>
252
- <pre className="text-muted-foreground text-xs max-w-lg text-left bg-muted rounded-md p-3 overflow-auto whitespace-pre-wrap">
253
- {error}
254
- </pre>
255
- <Button
256
- variant="outline"
257
- size="sm"
258
- onClick={() => setShowSource(true)}
259
- >
260
- View source to fix
261
- </Button>
262
- </div>
263
- ) : (
264
- <div
265
- ref={viewportRef}
266
- className="relative w-full h-full overflow-hidden"
267
- style={{ cursor: isPanning ? "grabbing" : "grab" }}
268
- onWheel={handleWheel}
269
- onPointerDown={handlePointerDown}
270
- onPointerMove={handlePointerMove}
271
- onPointerUp={handlePointerUp}
272
- >
273
- <div
274
- ref={containerRef}
275
- className="flex items-center justify-center p-8 min-h-full [&_svg]:max-w-full origin-center select-none"
276
- style={{
277
- transform: `translate(${pan.x}px, ${pan.y}px) scale(${zoom})`,
278
- }}
279
- dangerouslySetInnerHTML={{ __html: svg }}
280
- />
281
- </div>
282
- )}
283
- </div>
284
- </div>
285
- );
286
- }