wiki-viewer 1.7.2 → 1.8.1

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 (424) hide show
  1. package/.next/standalone/.github/workflows/publish.yml +1 -1
  2. package/.next/standalone/.next/BUILD_ID +1 -1
  3. package/.next/standalone/.next/app-path-routes-manifest.json +6 -0
  4. package/.next/standalone/.next/build-manifest.json +3 -3
  5. package/.next/standalone/.next/prerender-manifest.json +3 -3
  6. package/.next/standalone/.next/routes-manifest.json +40 -0
  7. package/.next/standalone/.next/server/app/_global-error.html +1 -1
  8. package/.next/standalone/.next/server/app/_global-error.rsc +1 -1
  9. package/.next/standalone/.next/server/app/_global-error.segments/__PAGE__.segment.rsc +1 -1
  10. package/.next/standalone/.next/server/app/_global-error.segments/_full.segment.rsc +1 -1
  11. package/.next/standalone/.next/server/app/_global-error.segments/_head.segment.rsc +1 -1
  12. package/.next/standalone/.next/server/app/_global-error.segments/_index.segment.rsc +1 -1
  13. package/.next/standalone/.next/server/app/_global-error.segments/_tree.segment.rsc +1 -1
  14. package/.next/standalone/.next/server/app/_not-found/page_client-reference-manifest.js +1 -1
  15. package/.next/standalone/.next/server/app/_not-found.html +1 -1
  16. package/.next/standalone/.next/server/app/_not-found.rsc +2 -2
  17. package/.next/standalone/.next/server/app/_not-found.segments/_full.segment.rsc +2 -2
  18. package/.next/standalone/.next/server/app/_not-found.segments/_head.segment.rsc +1 -1
  19. package/.next/standalone/.next/server/app/_not-found.segments/_index.segment.rsc +2 -2
  20. package/.next/standalone/.next/server/app/_not-found.segments/_not-found/__PAGE__.segment.rsc +1 -1
  21. package/.next/standalone/.next/server/app/_not-found.segments/_not-found.segment.rsc +1 -1
  22. package/.next/standalone/.next/server/app/_not-found.segments/_tree.segment.rsc +2 -2
  23. package/.next/standalone/.next/server/app/api/agent/activity/route.js +6 -6
  24. package/.next/standalone/.next/server/app/api/agent/activity/route.js.nft.json +1 -1
  25. package/.next/standalone/.next/server/app/api/agent/admin/agents/[agentId]/revoke/route.js +6 -6
  26. package/.next/standalone/.next/server/app/api/agent/admin/agents/[agentId]/revoke/route.js.nft.json +1 -1
  27. package/.next/standalone/.next/server/app/api/agent/admin/agents/route.js +6 -6
  28. package/.next/standalone/.next/server/app/api/agent/admin/agents/route.js.nft.json +1 -1
  29. package/.next/standalone/.next/server/app/api/agent/admin/registrations/[regId]/approve/route.js +7 -7
  30. package/.next/standalone/.next/server/app/api/agent/admin/registrations/[regId]/approve/route.js.nft.json +1 -1
  31. package/.next/standalone/.next/server/app/api/agent/admin/registrations/[regId]/deny/route.js +5 -5
  32. package/.next/standalone/.next/server/app/api/agent/admin/registrations/[regId]/deny/route.js.nft.json +1 -1
  33. package/.next/standalone/.next/server/app/api/agent/admin/registrations/route.js +5 -5
  34. package/.next/standalone/.next/server/app/api/agent/admin/registrations/route.js.nft.json +1 -1
  35. package/.next/standalone/.next/server/app/api/agent/events/[...path]/route.js +8 -7
  36. package/.next/standalone/.next/server/app/api/agent/events/[...path]/route.js.nft.json +1 -1
  37. package/.next/standalone/.next/server/app/api/agent/files/[...path]/route.js +9 -8
  38. package/.next/standalone/.next/server/app/api/agent/files/[...path]/route.js.nft.json +1 -1
  39. package/.next/standalone/.next/server/app/api/agent/fs/file/[...path]/route.js +8 -7
  40. package/.next/standalone/.next/server/app/api/agent/fs/file/[...path]/route.js.nft.json +1 -1
  41. package/.next/standalone/.next/server/app/api/agent/fs/ls/[[...path]]/route.js +7 -7
  42. package/.next/standalone/.next/server/app/api/agent/fs/ls/[[...path]]/route.js.nft.json +1 -1
  43. package/.next/standalone/.next/server/app/api/agent/fs/move/route.js +6 -5
  44. package/.next/standalone/.next/server/app/api/agent/fs/move/route.js.nft.json +1 -1
  45. package/.next/standalone/.next/server/app/api/agent/fs/search/route.js +7 -6
  46. package/.next/standalone/.next/server/app/api/agent/fs/search/route.js.nft.json +1 -1
  47. package/.next/standalone/.next/server/app/api/agent/internal/span/route.js +6 -5
  48. package/.next/standalone/.next/server/app/api/agent/internal/span/route.js.nft.json +1 -1
  49. package/.next/standalone/.next/server/app/api/agent/settings/route.js +7 -7
  50. package/.next/standalone/.next/server/app/api/agent/settings/route.js.nft.json +1 -1
  51. package/.next/standalone/.next/server/app/api/agent/sidecar/[...path]/route.js +8 -7
  52. package/.next/standalone/.next/server/app/api/agent/sidecar/[...path]/route.js.nft.json +1 -1
  53. package/.next/standalone/.next/server/app/api/app-proxy/[...path]/route.js +2 -2
  54. package/.next/standalone/.next/server/app/api/app-proxy/[...path]/route.js.nft.json +1 -1
  55. package/.next/standalone/.next/server/app/api/assets/[...path]/route.js +8 -2
  56. package/.next/standalone/.next/server/app/api/assets/[...path]/route.js.nft.json +1 -1
  57. package/.next/standalone/.next/server/app/api/auth/[...all]/route.js +5 -5
  58. package/.next/standalone/.next/server/app/api/auth/[...all]/route.js.nft.json +1 -1
  59. package/.next/standalone/.next/server/app/api/system/admins/route/app-paths-manifest.json +3 -0
  60. package/.next/standalone/.next/server/app/api/system/admins/route/build-manifest.json +9 -0
  61. package/.next/standalone/.next/server/app/api/system/admins/route/server-reference-manifest.json +4 -0
  62. package/.next/standalone/.next/server/app/api/system/admins/route.js +14 -0
  63. package/.next/standalone/.next/server/app/api/system/admins/route.js.map +5 -0
  64. package/.next/standalone/.next/server/app/api/system/admins/route.js.nft.json +1 -0
  65. package/.next/standalone/.next/server/app/api/system/admins/route_client-reference-manifest.js +3 -0
  66. package/.next/standalone/.next/server/app/api/system/auth-config/route.js +6 -6
  67. package/.next/standalone/.next/server/app/api/system/auth-config/route.js.nft.json +1 -1
  68. package/.next/standalone/.next/server/app/api/system/auth-settings/route.js +4 -4
  69. package/.next/standalone/.next/server/app/api/system/auth-settings/route.js.nft.json +1 -1
  70. package/.next/standalone/.next/server/app/api/system/browse/route.js +4 -4
  71. package/.next/standalone/.next/server/app/api/system/browse/route.js.nft.json +1 -1
  72. package/.next/standalone/.next/server/app/api/system/clear-root/route.js +5 -5
  73. package/.next/standalone/.next/server/app/api/system/clear-root/route.js.nft.json +1 -1
  74. package/.next/standalone/.next/server/app/api/system/config/route.js +6 -6
  75. package/.next/standalone/.next/server/app/api/system/config/route.js.nft.json +1 -1
  76. package/.next/standalone/.next/server/app/api/system/pins/route.js +4 -4
  77. package/.next/standalone/.next/server/app/api/system/pins/route.js.nft.json +1 -1
  78. package/.next/standalone/.next/server/app/api/system/reveal/route.js +6 -6
  79. package/.next/standalone/.next/server/app/api/system/reveal/route.js.nft.json +1 -1
  80. package/.next/standalone/.next/server/app/api/system/root-status/route.js +5 -5
  81. package/.next/standalone/.next/server/app/api/system/root-status/route.js.nft.json +1 -1
  82. package/.next/standalone/.next/server/app/api/system/set-root/route.js +6 -6
  83. package/.next/standalone/.next/server/app/api/system/set-root/route.js.nft.json +1 -1
  84. package/.next/standalone/.next/server/app/api/system/users/route/app-paths-manifest.json +3 -0
  85. package/.next/standalone/.next/server/app/api/system/users/route/build-manifest.json +9 -0
  86. package/.next/standalone/.next/server/app/api/system/users/route/server-reference-manifest.json +4 -0
  87. package/.next/standalone/.next/server/app/api/system/users/route.js +14 -0
  88. package/.next/standalone/.next/server/app/api/system/users/route.js.map +5 -0
  89. package/.next/standalone/.next/server/app/api/system/users/route.js.nft.json +1 -0
  90. package/.next/standalone/.next/server/app/api/system/users/route_client-reference-manifest.js +3 -0
  91. package/.next/standalone/.next/server/app/api/system/workspaces/[id]/open/route/app-paths-manifest.json +3 -0
  92. package/.next/standalone/.next/server/app/api/system/workspaces/[id]/open/route/build-manifest.json +9 -0
  93. package/.next/standalone/.next/server/app/api/system/workspaces/[id]/open/route/server-reference-manifest.json +4 -0
  94. package/.next/standalone/.next/server/app/api/system/workspaces/[id]/open/route.js +14 -0
  95. package/.next/standalone/.next/server/app/api/system/workspaces/[id]/open/route.js.map +5 -0
  96. package/.next/standalone/.next/server/app/api/system/workspaces/[id]/open/route.js.nft.json +1 -0
  97. package/.next/standalone/.next/server/app/api/system/workspaces/[id]/open/route_client-reference-manifest.js +3 -0
  98. package/.next/standalone/.next/server/app/api/system/workspaces/[id]/route/app-paths-manifest.json +3 -0
  99. package/.next/standalone/.next/server/app/api/system/workspaces/[id]/route/build-manifest.json +9 -0
  100. package/.next/standalone/.next/server/app/api/system/workspaces/[id]/route/server-reference-manifest.json +4 -0
  101. package/.next/standalone/.next/server/app/api/system/workspaces/[id]/route.js +14 -0
  102. package/.next/standalone/.next/server/app/api/system/workspaces/[id]/route.js.map +5 -0
  103. package/.next/standalone/.next/server/app/api/system/workspaces/[id]/route.js.nft.json +1 -0
  104. package/.next/standalone/.next/server/app/api/system/workspaces/[id]/route_client-reference-manifest.js +3 -0
  105. package/.next/standalone/.next/server/app/api/system/workspaces/route/app-paths-manifest.json +3 -0
  106. package/.next/standalone/.next/server/app/api/system/workspaces/route/build-manifest.json +9 -0
  107. package/.next/standalone/.next/server/app/api/system/workspaces/route/server-reference-manifest.json +4 -0
  108. package/.next/standalone/.next/server/app/api/system/workspaces/route.js +14 -0
  109. package/.next/standalone/.next/server/app/api/system/workspaces/route.js.map +5 -0
  110. package/.next/standalone/.next/server/app/api/system/workspaces/route.js.nft.json +1 -0
  111. package/.next/standalone/.next/server/app/api/system/workspaces/route_client-reference-manifest.js +3 -0
  112. package/.next/standalone/.next/server/app/api/upload/[...path]/route.js +8 -2
  113. package/.next/standalone/.next/server/app/api/upload/[...path]/route.js.nft.json +1 -1
  114. package/.next/standalone/.next/server/app/api/wiki/app/route.js +5 -5
  115. package/.next/standalone/.next/server/app/api/wiki/app/route.js.nft.json +1 -1
  116. package/.next/standalone/.next/server/app/api/wiki/content/route.js +6 -6
  117. package/.next/standalone/.next/server/app/api/wiki/content/route.js.nft.json +1 -1
  118. package/.next/standalone/.next/server/app/api/wiki/download/route.js +7 -7
  119. package/.next/standalone/.next/server/app/api/wiki/download/route.js.nft.json +1 -1
  120. package/.next/standalone/.next/server/app/api/wiki/file/route.js +8 -2
  121. package/.next/standalone/.next/server/app/api/wiki/file/route.js.nft.json +1 -1
  122. package/.next/standalone/.next/server/app/api/wiki/folder/route.js +6 -6
  123. package/.next/standalone/.next/server/app/api/wiki/folder/route.js.nft.json +1 -1
  124. package/.next/standalone/.next/server/app/api/wiki/move/route.js +6 -6
  125. package/.next/standalone/.next/server/app/api/wiki/move/route.js.nft.json +1 -1
  126. package/.next/standalone/.next/server/app/api/wiki/new-file/route.js +7 -7
  127. package/.next/standalone/.next/server/app/api/wiki/new-file/route.js.nft.json +1 -1
  128. package/.next/standalone/.next/server/app/api/wiki/page/route.js +7 -7
  129. package/.next/standalone/.next/server/app/api/wiki/page/route.js.nft.json +1 -1
  130. package/.next/standalone/.next/server/app/api/wiki/presence/route.js +7 -7
  131. package/.next/standalone/.next/server/app/api/wiki/presence/route.js.nft.json +1 -1
  132. package/.next/standalone/.next/server/app/api/wiki/route.js +6 -6
  133. package/.next/standalone/.next/server/app/api/wiki/route.js.nft.json +1 -1
  134. package/.next/standalone/.next/server/app/api/wiki/search/route/app-paths-manifest.json +3 -0
  135. package/.next/standalone/.next/server/app/api/wiki/search/route/build-manifest.json +9 -0
  136. package/.next/standalone/.next/server/app/api/wiki/search/route/server-reference-manifest.json +4 -0
  137. package/.next/standalone/.next/server/app/api/wiki/search/route.js +15 -0
  138. package/.next/standalone/.next/server/app/api/wiki/search/route.js.map +5 -0
  139. package/.next/standalone/.next/server/app/api/wiki/search/route.js.nft.json +1 -0
  140. package/.next/standalone/.next/server/app/api/wiki/search/route_client-reference-manifest.js +3 -0
  141. package/.next/standalone/.next/server/app/api/wiki/slugs/route.js +6 -6
  142. package/.next/standalone/.next/server/app/api/wiki/slugs/route.js.nft.json +1 -1
  143. package/.next/standalone/.next/server/app/api/wiki/upload/route.js +7 -7
  144. package/.next/standalone/.next/server/app/api/wiki/upload/route.js.nft.json +1 -1
  145. package/.next/standalone/.next/server/app/api/wiki/watch/route.js +7 -9
  146. package/.next/standalone/.next/server/app/api/wiki/watch/route.js.nft.json +1 -1
  147. package/.next/standalone/.next/server/app/index.html +1 -1
  148. package/.next/standalone/.next/server/app/index.rsc +3 -3
  149. package/.next/standalone/.next/server/app/index.segments/__PAGE__.segment.rsc +2 -2
  150. package/.next/standalone/.next/server/app/index.segments/_full.segment.rsc +3 -3
  151. package/.next/standalone/.next/server/app/index.segments/_head.segment.rsc +1 -1
  152. package/.next/standalone/.next/server/app/index.segments/_index.segment.rsc +2 -2
  153. package/.next/standalone/.next/server/app/index.segments/_tree.segment.rsc +2 -2
  154. package/.next/standalone/.next/server/app/page.js.nft.json +1 -1
  155. package/.next/standalone/.next/server/app/page_client-reference-manifest.js +1 -1
  156. package/.next/standalone/.next/server/app/signin/page.js +1 -1
  157. package/.next/standalone/.next/server/app/signin/page.js.nft.json +1 -1
  158. package/.next/standalone/.next/server/app/signin/page_client-reference-manifest.js +1 -1
  159. package/.next/standalone/.next/server/app-paths-manifest.json +6 -0
  160. package/.next/standalone/.next/server/chunks/0p91_next_dist_esm_build_templates_app-route_0d2jbo5.js +1 -1
  161. package/.next/standalone/.next/server/chunks/0p91_next_dist_esm_build_templates_app-route_0ytral2.js +1 -1
  162. package/.next/standalone/.next/server/chunks/[root-of-the-server]__0-244bv._.js +16 -0
  163. package/.next/standalone/.next/server/chunks/{[root-of-the-server]__0xz-_0v._.js → [root-of-the-server]__0-inabx._.js} +2 -2
  164. package/.next/standalone/.next/server/chunks/{[root-of-the-server]__0-ao6a_._.js → [root-of-the-server]__0.-9jt0._.js} +1 -1
  165. package/.next/standalone/.next/server/chunks/{[root-of-the-server]__0~-r-8f._.js → [root-of-the-server]__00c1-dr._.js} +1 -1
  166. package/.next/standalone/.next/server/chunks/[root-of-the-server]__00lep-u._.js +3 -0
  167. package/.next/standalone/.next/server/chunks/[root-of-the-server]__00mtevo._.js +3 -0
  168. package/.next/standalone/.next/server/chunks/[root-of-the-server]__00qu86p._.js +3 -0
  169. package/.next/standalone/.next/server/chunks/[root-of-the-server]__012753j._.js +3 -0
  170. package/.next/standalone/.next/server/chunks/[root-of-the-server]__01hp8ax._.js +3 -0
  171. package/.next/standalone/.next/server/chunks/[root-of-the-server]__0269d2e._.js +1 -1
  172. package/.next/standalone/.next/server/chunks/{[root-of-the-server]__0jhr.ex._.js → [root-of-the-server]__02n6z97._.js} +1 -1
  173. package/.next/standalone/.next/server/chunks/[root-of-the-server]__036mhjp._.js +5 -0
  174. package/.next/standalone/.next/server/chunks/[root-of-the-server]__03p0ob1._.js +16 -0
  175. package/.next/standalone/.next/server/chunks/[root-of-the-server]__05t~v6l._.js +3 -0
  176. package/.next/standalone/.next/server/chunks/[root-of-the-server]__068ni_k._.js +3 -0
  177. package/.next/standalone/.next/server/chunks/{[root-of-the-server]__082nhm6._.js → [root-of-the-server]__07vphbd._.js} +1 -1
  178. package/.next/standalone/.next/server/chunks/{[root-of-the-server]__0pg6dn-._.js → [root-of-the-server]__08lkuwa._.js} +1 -1
  179. package/.next/standalone/.next/server/chunks/[root-of-the-server]__09cqzem._.js +3 -0
  180. package/.next/standalone/.next/server/chunks/{[root-of-the-server]__0p_ox-k._.js → [root-of-the-server]__09k4q9e._.js} +1 -1
  181. package/.next/standalone/.next/server/chunks/[root-of-the-server]__0_0_601._.js +3 -0
  182. package/.next/standalone/.next/server/chunks/[root-of-the-server]__0ae3dk6._.js +3 -0
  183. package/.next/standalone/.next/server/chunks/{[root-of-the-server]__0s28.4-._.js → [root-of-the-server]__0af-x45._.js} +1 -1
  184. package/.next/standalone/.next/server/chunks/[root-of-the-server]__0cqu-wm._.js +3 -0
  185. package/.next/standalone/.next/server/chunks/[root-of-the-server]__0d75a5q._.js +1 -1
  186. package/.next/standalone/.next/server/chunks/[root-of-the-server]__0d7x3e1._.js +3 -0
  187. package/.next/standalone/.next/server/chunks/[root-of-the-server]__0d7zxm_._.js +3 -0
  188. package/.next/standalone/.next/server/chunks/[root-of-the-server]__0e7vs98._.js +3 -0
  189. package/.next/standalone/.next/server/chunks/[root-of-the-server]__0fxzg4v._.js +3 -0
  190. package/.next/standalone/.next/server/chunks/[root-of-the-server]__0gda_iu._.js +3 -0
  191. package/.next/standalone/.next/server/chunks/[root-of-the-server]__0hu~q20._.js +3 -0
  192. package/.next/standalone/.next/server/chunks/[root-of-the-server]__0jk1uf4._.js +3 -0
  193. package/.next/standalone/.next/server/chunks/[root-of-the-server]__0l-8clq._.js +3 -0
  194. package/.next/standalone/.next/server/chunks/[root-of-the-server]__0lhka0x._.js +3 -0
  195. package/.next/standalone/.next/server/chunks/{[root-of-the-server]__0kdn1le._.js → [root-of-the-server]__0na11h0._.js} +2 -2
  196. package/.next/standalone/.next/server/chunks/[root-of-the-server]__0nd.b_c._.js +3 -0
  197. package/.next/standalone/.next/server/chunks/[root-of-the-server]__0otb8ra._.js +3 -0
  198. package/.next/standalone/.next/server/chunks/[root-of-the-server]__0p0-p__._.js +3 -0
  199. package/.next/standalone/.next/server/chunks/[root-of-the-server]__0piofm3._.js +3 -0
  200. package/.next/standalone/.next/server/chunks/[root-of-the-server]__0rrf-jr._.js +3 -0
  201. package/.next/standalone/.next/server/chunks/[root-of-the-server]__0s6_lzw._.js +3 -0
  202. package/.next/standalone/.next/server/chunks/[root-of-the-server]__0sh13v5._.js +3 -0
  203. package/.next/standalone/.next/server/chunks/[root-of-the-server]__0ta~flu._.js +3 -0
  204. package/.next/standalone/.next/server/chunks/[root-of-the-server]__0v4im4p._.js +3 -0
  205. package/.next/standalone/.next/server/chunks/{[root-of-the-server]__0qn8e~s._.js → [root-of-the-server]__0v_kyp-._.js} +1 -1
  206. package/.next/standalone/.next/server/chunks/[root-of-the-server]__0vatqe-._.js +3 -0
  207. package/.next/standalone/.next/server/chunks/[root-of-the-server]__0vdb2nr._.js +3 -0
  208. package/.next/standalone/.next/server/chunks/[root-of-the-server]__0wdh63w._.js +3 -0
  209. package/.next/standalone/.next/server/chunks/[root-of-the-server]__0z3wg9x._.js +12 -0
  210. package/.next/standalone/.next/server/chunks/{[root-of-the-server]__0mzo03s._.js → [root-of-the-server]__0~.-3yk._.js} +1 -1
  211. package/.next/standalone/.next/server/chunks/[root-of-the-server]__123._fe._.js +3 -0
  212. package/.next/standalone/.next/server/chunks/{[root-of-the-server]__12800b1._.js → [root-of-the-server]__12ee_s6._.js} +1 -1
  213. package/.next/standalone/.next/server/chunks/[root-of-the-server]__12onytt._.js +3 -0
  214. package/.next/standalone/.next/server/chunks/{[root-of-the-server]__04udrya._.js → [root-of-the-server]__12q8ch8._.js} +2 -2
  215. package/.next/standalone/.next/server/chunks/[root-of-the-server]__1377.79._.js +3 -0
  216. package/.next/standalone/.next/server/chunks/[root-of-the-server]__1378-ox._.js +3 -0
  217. package/.next/standalone/.next/server/chunks/[root-of-the-server]__13aid91._.js +3 -0
  218. package/.next/standalone/.next/server/chunks/[root-of-the-server]__13hp4tw._.js +12 -0
  219. package/.next/standalone/.next/server/chunks/_079xuln._.js +1 -1
  220. package/.next/standalone/.next/server/chunks/_0dr1r1g._.js +452 -0
  221. package/.next/standalone/.next/server/chunks/_101exke._.js +452 -0
  222. package/.next/standalone/.next/server/chunks/_next-internal_server_app_api_system_admins_route_actions_0dsm7cx.js +3 -0
  223. package/.next/standalone/.next/server/chunks/_next-internal_server_app_api_system_users_route_actions_0whj5cy.js +3 -0
  224. package/.next/standalone/.next/server/chunks/_next-internal_server_app_api_system_workspaces_[id]_open_route_actions_1087xu7.js +3 -0
  225. package/.next/standalone/.next/server/chunks/_next-internal_server_app_api_system_workspaces_[id]_route_actions_0~h7-8s.js +3 -0
  226. package/.next/standalone/.next/server/chunks/_next-internal_server_app_api_system_workspaces_route_actions_0mkalc3.js +3 -0
  227. package/.next/standalone/.next/server/chunks/_next-internal_server_app_api_wiki_search_route_actions_0inxu93.js +3 -0
  228. package/.next/standalone/.next/server/chunks/node_modules__pnpm_0aj5g-w._.js +1 -1
  229. package/.next/standalone/.next/server/chunks/src_lib_search_0d-_j3u._.js +46 -0
  230. package/.next/standalone/.next/server/chunks/src_lib_search_0ymmp0c._.js +46 -0
  231. package/.next/standalone/.next/server/chunks/ssr/{0~w0_katex_dist_katex_mjs_0b8ra51._.js → 0~w0_katex_dist_katex_mjs_04mhawr._.js} +1 -1
  232. package/.next/standalone/.next/server/chunks/ssr/12y~_mermaid_dist_chunks_mermaid_core_erDiagram-TEJ5UH35_mjs_0v6rnqy._.js +1 -1
  233. package/.next/standalone/.next/server/chunks/ssr/12y~_mermaid_dist_mermaid_core_mjs_0hj_n-~._.js +1 -1
  234. package/.next/standalone/.next/server/chunks/ssr/{[root-of-the-server]__0btcd4o._.js → [root-of-the-server]__02twzph._.js} +2 -2
  235. package/.next/standalone/.next/server/chunks/ssr/{[root-of-the-server]__0ytvlzs._.js → [root-of-the-server]__09~x2v~._.js} +2 -2
  236. package/.next/standalone/.next/server/chunks/ssr/_0pqaawz._.js +18 -18
  237. package/.next/standalone/.next/server/chunks/ssr/{node_modules__pnpm_0c71i8a._.js → node_modules__pnpm_0.96tmo._.js} +1 -1
  238. package/.next/standalone/.next/server/chunks/ssr/{node_modules__pnpm_0lm8e2c._.js → node_modules__pnpm_011vy_q._.js} +2 -2
  239. package/.next/standalone/.next/server/chunks/ssr/{node_modules__pnpm_0ezm2us._.js → node_modules__pnpm_01o_5qt._.js} +1 -1
  240. package/.next/standalone/.next/server/chunks/ssr/{node_modules__pnpm_0j3mvgg._.js → node_modules__pnpm_04n0h6.._.js} +1 -1
  241. package/.next/standalone/.next/server/chunks/ssr/{node_modules__pnpm_0~ln0by._.js → node_modules__pnpm_093dp2q._.js} +1 -1
  242. package/.next/standalone/.next/server/chunks/ssr/{node_modules__pnpm_11e~j49._.js → node_modules__pnpm_09ej62_._.js} +1 -1
  243. package/.next/standalone/.next/server/chunks/ssr/{node_modules__pnpm_0de8xt-._.js → node_modules__pnpm_09ljbdz._.js} +2 -2
  244. package/.next/standalone/.next/server/chunks/ssr/{node_modules__pnpm_0-x6zex._.js → node_modules__pnpm_09~_ob2._.js} +1 -1
  245. package/.next/standalone/.next/server/chunks/ssr/{node_modules__pnpm_0yq5z.h._.js → node_modules__pnpm_0a01ng7._.js} +2 -2
  246. package/.next/standalone/.next/server/chunks/ssr/{node_modules__pnpm_0kwc-vs._.js → node_modules__pnpm_0b8qx0g._.js} +1 -1
  247. package/.next/standalone/.next/server/chunks/ssr/{node_modules__pnpm_0hrbz84._.js → node_modules__pnpm_0bbc---._.js} +1 -1
  248. package/.next/standalone/.next/server/chunks/ssr/{node_modules__pnpm_0hobcbs._.js → node_modules__pnpm_0c.309.._.js} +1 -1
  249. package/.next/standalone/.next/server/chunks/ssr/{node_modules__pnpm_0rw91-f._.js → node_modules__pnpm_0c8aunj._.js} +1 -1
  250. package/.next/standalone/.next/server/chunks/ssr/{node_modules__pnpm_0o.c1z8._.js → node_modules__pnpm_0hk6xys._.js} +2 -2
  251. package/.next/standalone/.next/server/chunks/ssr/{node_modules__pnpm_0dboa_e._.js → node_modules__pnpm_0hlzy8f._.js} +1 -1
  252. package/.next/standalone/.next/server/chunks/ssr/{node_modules__pnpm_0j53hti._.js → node_modules__pnpm_0nw5ou2._.js} +1 -1
  253. package/.next/standalone/.next/server/chunks/ssr/{node_modules__pnpm_0xrmzh1._.js → node_modules__pnpm_0o.dn8o._.js} +1 -1
  254. package/.next/standalone/.next/server/chunks/ssr/{node_modules__pnpm_0cxwhfd._.js → node_modules__pnpm_0s0ur~d._.js} +1 -1
  255. package/.next/standalone/.next/server/chunks/ssr/{node_modules__pnpm_07rxv2x._.js → node_modules__pnpm_0shlang._.js} +1 -1
  256. package/.next/standalone/.next/server/chunks/ssr/{node_modules__pnpm_0i.pw_m._.js → node_modules__pnpm_0sq3c2r._.js} +1 -1
  257. package/.next/standalone/.next/server/chunks/ssr/{node_modules__pnpm_0ajzar9._.js → node_modules__pnpm_0t9jb7d._.js} +1 -1
  258. package/.next/standalone/.next/server/chunks/ssr/{node_modules__pnpm_012nt.s._.js → node_modules__pnpm_0wmx9kq._.js} +2 -2
  259. package/.next/standalone/.next/server/chunks/ssr/{node_modules__pnpm_0z~h2ow._.js → node_modules__pnpm_0xfx0sf._.js} +1 -1
  260. package/.next/standalone/.next/server/chunks/ssr/{node_modules__pnpm_0cbsnwf._.js → node_modules__pnpm_0yiz.-t._.js} +1 -1
  261. package/.next/standalone/.next/server/chunks/ssr/{node_modules__pnpm_0bum3-3._.js → node_modules__pnpm_11sut1u._.js} +1 -1
  262. package/.next/standalone/.next/server/chunks/ssr/{node_modules__pnpm_0mdo4i3._.js → node_modules__pnpm_124u4o2._.js} +2 -2
  263. package/.next/standalone/.next/server/chunks/ssr/{node_modules__pnpm_0il8j.j._.js → node_modules__pnpm_13tajgx._.js} +2 -2
  264. package/.next/standalone/.next/server/chunks/ssr/src_app_signin_00yk0vm._.js +2 -2
  265. package/.next/standalone/.next/server/edge/chunks/{08yl_next_dist_esm_build_templates_edge-wrapper_0o9h3w_.js → 08yl_next_dist_esm_build_templates_edge-wrapper_0xbpts6.js} +2 -2
  266. package/.next/standalone/.next/server/edge/chunks/[root-of-the-server]__0.pmgt2._.js +3 -0
  267. package/.next/standalone/.next/server/functions-config-manifest.json +6 -0
  268. package/.next/standalone/.next/server/middleware-build-manifest.js +3 -3
  269. package/.next/standalone/.next/server/middleware-manifest.json +8 -8
  270. package/.next/standalone/.next/server/pages/404.html +1 -1
  271. package/.next/standalone/.next/server/pages/500.html +1 -1
  272. package/.next/standalone/.next/server/server-reference-manifest.js +1 -1
  273. package/.next/standalone/.next/server/server-reference-manifest.json +1 -1
  274. package/.next/standalone/.next/static/chunks/0c_~zevf2n0r4.css +2 -0
  275. package/.next/standalone/.next/static/chunks/0l4842ez-0_66.js +129 -0
  276. package/.next/standalone/README.md +46 -2
  277. package/.next/standalone/agents/bootstrap-prompt.md +3 -1
  278. package/.next/standalone/agents/wiki-viewer-skill/SKILL.md +38 -11
  279. package/.next/standalone/docs/workspacing-plan.md +364 -0
  280. package/.next/standalone/package.json +2 -2
  281. package/.next/standalone/packages/wiki-viewer-mcp/README.md +6 -5
  282. package/.next/standalone/packages/wiki-viewer-mcp/dist/http-client.js +4 -0
  283. package/.next/standalone/packages/wiki-viewer-mcp/dist/index.js +4 -0
  284. package/.next/standalone/packages/wiki-viewer-mcp/src/http-client.ts +6 -0
  285. package/.next/standalone/packages/wiki-viewer-mcp/src/index.ts +5 -0
  286. package/.next/standalone/src/app/api/agent/activity/route.ts +9 -8
  287. package/.next/standalone/src/app/api/agent/events/[...path]/route.ts +20 -8
  288. package/.next/standalone/src/app/api/agent/files/[...path]/route.ts +16 -9
  289. package/.next/standalone/src/app/api/agent/fs/file/[...path]/route.ts +28 -18
  290. package/.next/standalone/src/app/api/agent/fs/ls/[[...path]]/route.ts +12 -7
  291. package/.next/standalone/src/app/api/agent/fs/move/route.ts +16 -11
  292. package/.next/standalone/src/app/api/agent/fs/search/route.ts +49 -13
  293. package/.next/standalone/src/app/api/agent/internal/span/route.ts +9 -5
  294. package/.next/standalone/src/app/api/agent/register/route.ts +9 -1
  295. package/.next/standalone/src/app/api/agent/settings/route.ts +7 -3
  296. package/.next/standalone/src/app/api/agent/sidecar/[...path]/route.ts +8 -4
  297. package/.next/standalone/src/app/api/agents/install/route.ts +20 -2
  298. package/.next/standalone/src/app/api/assets/[...path]/route.ts +9 -4
  299. package/.next/standalone/src/app/api/system/admins/route.ts +103 -0
  300. package/.next/standalone/src/app/api/system/reveal/route.ts +7 -6
  301. package/.next/standalone/src/app/api/system/set-root/route.ts +24 -1
  302. package/.next/standalone/src/app/api/system/users/route.ts +120 -0
  303. package/.next/standalone/src/app/api/system/workspaces/[id]/open/route.ts +34 -0
  304. package/.next/standalone/src/app/api/system/workspaces/[id]/route.ts +74 -0
  305. package/.next/standalone/src/app/api/system/workspaces/route.ts +67 -0
  306. package/.next/standalone/src/app/api/upload/[...path]/route.ts +10 -5
  307. package/.next/standalone/src/app/api/wiki/app/route.ts +10 -9
  308. package/.next/standalone/src/app/api/wiki/content/route.ts +14 -14
  309. package/.next/standalone/src/app/api/wiki/download/route.ts +7 -6
  310. package/.next/standalone/src/app/api/wiki/file/route.ts +7 -2
  311. package/.next/standalone/src/app/api/wiki/folder/route.ts +6 -5
  312. package/.next/standalone/src/app/api/wiki/move/route.ts +7 -7
  313. package/.next/standalone/src/app/api/wiki/new-file/route.ts +7 -6
  314. package/.next/standalone/src/app/api/wiki/page/route.ts +6 -5
  315. package/.next/standalone/src/app/api/wiki/presence/route.ts +8 -7
  316. package/.next/standalone/src/app/api/wiki/route.ts +13 -11
  317. package/.next/standalone/src/app/api/wiki/search/route.ts +44 -0
  318. package/.next/standalone/src/app/api/wiki/slugs/route.ts +8 -8
  319. package/.next/standalone/src/app/api/wiki/upload/route.ts +6 -5
  320. package/.next/standalone/src/app/api/wiki/watch/route.ts +16 -40
  321. package/.next/standalone/src/app/globals.css +484 -484
  322. package/.next/standalone/src/app/page.tsx +163 -49
  323. package/.next/standalone/src/components/auth-settings-sheet.tsx +171 -2
  324. package/.next/standalone/src/components/dir-picker.tsx +8 -6
  325. package/.next/standalone/src/components/editor/comment-thread.tsx +2 -1
  326. package/.next/standalone/src/components/editor/csv-viewer.tsx +3 -2
  327. package/.next/standalone/src/components/editor/editor-toolbar.tsx +2 -2
  328. package/.next/standalone/src/components/editor/editor.tsx +6 -5
  329. package/.next/standalone/src/components/editor/file-fallback-viewer.tsx +3 -2
  330. package/.next/standalone/src/components/editor/folder-index.tsx +2 -1
  331. package/.next/standalone/src/components/editor/image-viewer.tsx +2 -1
  332. package/.next/standalone/src/components/editor/media-popover.tsx +2 -1
  333. package/.next/standalone/src/components/editor/media-viewer.tsx +2 -1
  334. package/.next/standalone/src/components/editor/mermaid-viewer.tsx +3 -2
  335. package/.next/standalone/src/components/editor/node-app-viewer.tsx +4 -3
  336. package/.next/standalone/src/components/editor/notebook-viewer.tsx +3 -2
  337. package/.next/standalone/src/components/editor/office/docx-viewer.tsx +2 -1
  338. package/.next/standalone/src/components/editor/office/office-chrome.tsx +3 -2
  339. package/.next/standalone/src/components/editor/office/pptx-viewer.tsx +2 -1
  340. package/.next/standalone/src/components/editor/office/xlsx-viewer.tsx +2 -1
  341. package/.next/standalone/src/components/editor/pdf-viewer.tsx +2 -1
  342. package/.next/standalone/src/components/editor/proof-span-popover.tsx +2 -1
  343. package/.next/standalone/src/components/editor/source-viewer.tsx +3 -2
  344. package/.next/standalone/src/components/editor/suggest-edit-popover.tsx +2 -1
  345. package/.next/standalone/src/components/editor/suggestion-card.tsx +2 -1
  346. package/.next/standalone/src/components/editor/website-viewer.tsx +2 -1
  347. package/.next/standalone/src/components/editor/wiki-link-create-dialog.tsx +2 -1
  348. package/.next/standalone/src/components/search/search-command-dialog.tsx +109 -0
  349. package/.next/standalone/src/components/search/sidebar-search-box.tsx +121 -0
  350. package/.next/standalone/src/components/search/snippet-text.tsx +48 -0
  351. package/.next/standalone/src/components/ui/command.tsx +3 -2
  352. package/.next/standalone/src/lib/auth/admin.ts +112 -0
  353. package/.next/standalone/src/lib/auth/server.ts +13 -2
  354. package/.next/standalone/src/lib/config.ts +56 -4
  355. package/.next/standalone/src/lib/proof/audit.ts +19 -10
  356. package/.next/standalone/src/lib/proof/auth.ts +11 -0
  357. package/.next/standalone/src/lib/proof/collab-state.ts +4 -2
  358. package/.next/standalone/src/lib/proof/file-lock.ts +5 -0
  359. package/.next/standalone/src/lib/proof/idempotency.ts +5 -0
  360. package/.next/standalone/src/lib/proof/lease.ts +40 -27
  361. package/.next/standalone/src/lib/proof/mutex.ts +4 -0
  362. package/.next/standalone/src/lib/proof/raw-fs.ts +2 -3
  363. package/.next/standalone/src/lib/proof/registry.ts +5 -0
  364. package/.next/standalone/src/lib/search/indexable-exts.ts +25 -0
  365. package/.next/standalone/src/lib/search/indexer.ts +567 -0
  366. package/.next/standalone/src/lib/search/sanitize.ts +35 -0
  367. package/.next/standalone/src/lib/search/search-db.ts +57 -0
  368. package/.next/standalone/src/lib/search/watcher-pool.ts +79 -0
  369. package/.next/standalone/src/lib/workspace-client.ts +82 -0
  370. package/.next/standalone/src/lib/workspace-context.ts +142 -0
  371. package/.next/standalone/src/lib/workspaces.ts +196 -0
  372. package/.next/standalone/src/stores/ai-panel-store.ts +3 -2
  373. package/.next/standalone/src/stores/editor-store.ts +4 -3
  374. package/.next/standalone/src/stores/proof-store.ts +4 -3
  375. package/.next/standalone/src/stores/search-store.ts +86 -0
  376. package/.next/standalone/src/stores/wiki-slugs-store.ts +2 -1
  377. package/.next/standalone/src/tests/proof/admin-create-user.test.ts +43 -0
  378. package/.next/standalone/src/tests/proof/agent-workspace-scope.test.ts +134 -0
  379. package/.next/standalone/src/tests/proof/collab-state.test.ts +43 -41
  380. package/.next/standalone/src/tests/proof/preload.ts +21 -0
  381. package/.next/standalone/src/tests/proof/search-index.test.ts +339 -0
  382. package/.next/standalone/src/tests/proof/workspace-isolation.test.ts +87 -0
  383. package/.next/standalone/src/tests/proof/workspaces-api.test.ts +227 -0
  384. package/.next/standalone/tsconfig.tsbuildinfo +1 -1
  385. package/README.md +46 -2
  386. package/package.json +2 -2
  387. package/.next/standalone/.next/server/chunks/0p91_next_dist_esm_build_templates_app-route_0o~h4zq.js +0 -5
  388. package/.next/standalone/.next/server/chunks/[root-of-the-server]__0.hb9q2._.js +0 -3
  389. package/.next/standalone/.next/server/chunks/[root-of-the-server]__0.uux34._.js +0 -3
  390. package/.next/standalone/.next/server/chunks/[root-of-the-server]__0092hkp._.js +0 -3
  391. package/.next/standalone/.next/server/chunks/[root-of-the-server]__05f6x0i._.js +0 -3
  392. package/.next/standalone/.next/server/chunks/[root-of-the-server]__05idwm9._.js +0 -3
  393. package/.next/standalone/.next/server/chunks/[root-of-the-server]__06-dtd0._.js +0 -3
  394. package/.next/standalone/.next/server/chunks/[root-of-the-server]__06sek6_._.js +0 -3
  395. package/.next/standalone/.next/server/chunks/[root-of-the-server]__07fpqks._.js +0 -3
  396. package/.next/standalone/.next/server/chunks/[root-of-the-server]__094q5bj._.js +0 -3
  397. package/.next/standalone/.next/server/chunks/[root-of-the-server]__0awzyon._.js +0 -3
  398. package/.next/standalone/.next/server/chunks/[root-of-the-server]__0d_da6q._.js +0 -3
  399. package/.next/standalone/.next/server/chunks/[root-of-the-server]__0hhhvm7._.js +0 -3
  400. package/.next/standalone/.next/server/chunks/[root-of-the-server]__0kk26wc._.js +0 -3
  401. package/.next/standalone/.next/server/chunks/[root-of-the-server]__0km8suj._.js +0 -3
  402. package/.next/standalone/.next/server/chunks/[root-of-the-server]__0kur4ro._.js +0 -15
  403. package/.next/standalone/.next/server/chunks/[root-of-the-server]__0mkwoul._.js +0 -12
  404. package/.next/standalone/.next/server/chunks/[root-of-the-server]__0qc2~6l._.js +0 -15
  405. package/.next/standalone/.next/server/chunks/[root-of-the-server]__0qyd-o8._.js +0 -3
  406. package/.next/standalone/.next/server/chunks/[root-of-the-server]__0rkve~v._.js +0 -3
  407. package/.next/standalone/.next/server/chunks/[root-of-the-server]__0rzo40z._.js +0 -3
  408. package/.next/standalone/.next/server/chunks/[root-of-the-server]__0sjocwy._.js +0 -3
  409. package/.next/standalone/.next/server/chunks/[root-of-the-server]__0ssj9~d._.js +0 -3
  410. package/.next/standalone/.next/server/chunks/[root-of-the-server]__0s~i040._.js +0 -3
  411. package/.next/standalone/.next/server/chunks/[root-of-the-server]__0t220d-._.js +0 -3
  412. package/.next/standalone/.next/server/chunks/[root-of-the-server]__0t5mg.n._.js +0 -3
  413. package/.next/standalone/.next/server/chunks/[root-of-the-server]__0trsqf4._.js +0 -3
  414. package/.next/standalone/.next/server/chunks/[root-of-the-server]__0xq124z._.js +0 -3
  415. package/.next/standalone/.next/server/chunks/[root-of-the-server]__106uw_c._.js +0 -3
  416. package/.next/standalone/.next/server/chunks/[root-of-the-server]__10w2q~o._.js +0 -3
  417. package/.next/standalone/.next/server/chunks/[root-of-the-server]__13w-0iy._.js +0 -3
  418. package/.next/standalone/.next/server/chunks/src_lib_auth_server_ts_00f4e0h._.js +0 -452
  419. package/.next/standalone/.next/server/edge/chunks/[root-of-the-server]__0ug2rvl._.js +0 -3
  420. package/.next/standalone/.next/static/chunks/0vwkqw_rofm-c.js +0 -129
  421. package/.next/standalone/.next/static/chunks/0zay6349~v_wc.css +0 -2
  422. /package/.next/standalone/.next/static/{0XvNCOSEq7cbARTLtAolL → 17VWCQ9_AhwJBT4yjkvWG}/_buildManifest.js +0 -0
  423. /package/.next/standalone/.next/static/{0XvNCOSEq7cbARTLtAolL → 17VWCQ9_AhwJBT4yjkvWG}/_clientMiddlewareManifest.js +0 -0
  424. /package/.next/standalone/.next/static/{0XvNCOSEq7cbARTLtAolL → 17VWCQ9_AhwJBT4yjkvWG}/_ssgManifest.js +0 -0
@@ -50,8 +50,10 @@ import {
50
50
  DropdownMenu,
51
51
  DropdownMenuContent,
52
52
  DropdownMenuItem,
53
+ DropdownMenuSeparator,
53
54
  DropdownMenuTrigger,
54
55
  } from "@/components/ui/dropdown-menu";
56
+ import { getActiveWorkspaceId, withWs, wsFetch } from "@/lib/workspace-client";
55
57
  import { ThemeToggle } from "@/components/theme-toggle";
56
58
  import { AuthSettingsSheet } from "@/components/auth-settings-sheet";
57
59
  import { Button } from "@/components/ui/button";
@@ -63,6 +65,8 @@ import { parseFrontmatter } from "@/lib/markdown/parse-frontmatter";
63
65
  import { showError } from "@/lib/toast";
64
66
  import { cn } from "@/lib/utils";
65
67
  import { AIPanel } from "@/components/ai-panel/ai-panel";
68
+ import { SearchCommandDialog } from "@/components/search/search-command-dialog";
69
+ import { SidebarSearchBox } from "@/components/search/sidebar-search-box";
66
70
  import { useAIPanelStore } from "@/stores/ai-panel-store";
67
71
  import { useEditorStore } from "@/stores/editor-store";
68
72
  import { useViewWidthStore, VIEW_WIDTH_CLASS } from "@/stores/view-width-store";
@@ -168,7 +172,7 @@ function isHtmlFile(name: string) {
168
172
  }
169
173
 
170
174
  async function fetchDir(dir: string): Promise<TreeNode[]> {
171
- const res = await fetch(`/api/wiki?dir=${encodeURIComponent(dir)}`);
175
+ const res = await wsFetch(`/api/wiki?dir=${encodeURIComponent(dir)}`);
172
176
  if (!res.ok) return [];
173
177
  const data: {
174
178
  entries: Array<{
@@ -219,17 +223,47 @@ export default function Page() {
219
223
  // null = checking, false = not set, true = ready
220
224
  const [rootConfigured, setRootConfigured] = useState<boolean | null>(null);
221
225
  const [rootPath, setRootPath] = useState<string | null>(null);
226
+ // Workspace state
227
+ const [activeWorkspaceId, setActiveWorkspaceId] = useState<string | null>(() =>
228
+ typeof window !== "undefined" ? getActiveWorkspaceId() : null
229
+ );
230
+ const [workspaces, setWorkspaces] = useState<Array<{id:string;name:string;rootDir:string;lastOpenedAt?:string;createdAt:string}>>([]);
231
+ const [isWsAdmin, setIsWsAdmin] = useState(false);
232
+ const [addingWorkspace, setAddingWorkspace] = useState(false);
222
233
 
223
- useEffect(() => {
224
- fetch("/api/system/root-status")
225
- .then((r) => r.json())
226
- .then((d: { configured: boolean; path: string | null }) => {
227
- setRootConfigured(d.configured);
228
- setRootPath(d.path);
229
- })
230
- .catch(() => setRootConfigured(false));
234
+ const loadWorkspaces = useCallback(async () => {
235
+ try {
236
+ const res = await fetch("/api/system/workspaces");
237
+ if (!res.ok) throw new Error("Failed");
238
+ const d: { workspaces: Array<{id:string;name:string;rootDir:string;lastOpenedAt?:string;createdAt:string}>; isAdmin: boolean } = await res.json();
239
+ setWorkspaces(d.workspaces);
240
+ setIsWsAdmin(d.isAdmin);
241
+ if (d.workspaces.length > 0) {
242
+ setRootConfigured(true);
243
+ const urlWsId = new URLSearchParams(window.location.search).get("ws");
244
+ const inList = urlWsId ? d.workspaces.find((w) => w.id === urlWsId) : null;
245
+ const active = inList ?? [...d.workspaces].sort(
246
+ (a, b) => (b.lastOpenedAt ?? b.createdAt).localeCompare(a.lastOpenedAt ?? a.createdAt)
247
+ )[0];
248
+ setActiveWorkspaceId(active.id);
249
+ setRootPath(active.rootDir);
250
+ if (!inList) {
251
+ const u = new URL(location.href);
252
+ u.searchParams.set("ws", active.id);
253
+ history.replaceState(null, "", u.toString());
254
+ }
255
+ } else {
256
+ setRootConfigured(false);
257
+ }
258
+ } catch {
259
+ setRootConfigured(false);
260
+ }
231
261
  }, []);
232
262
 
263
+ useEffect(() => {
264
+ void loadWorkspaces();
265
+ }, [loadWorkspaces]);
266
+
233
267
  const editorCurrentPath = useEditorStore((s) => s.currentPath);
234
268
 
235
269
  // Path captured from the URL at first render, before any effect can clear it.
@@ -407,7 +441,7 @@ export default function Page() {
407
441
  if (!["editor", "text"].includes(kind) && !isText(openFile.name)) return;
408
442
  setFileLoading(true);
409
443
  try {
410
- const res = await fetch(
444
+ const res = await wsFetch(
411
445
  `/api/wiki/content?path=${encodeURIComponent(openFile.path)}`,
412
446
  );
413
447
  if (res.ok) {
@@ -449,7 +483,7 @@ export default function Page() {
449
483
  );
450
484
  }
451
485
 
452
- const es = new EventSource("/api/wiki/watch");
486
+ const es = new EventSource(withWs("/api/wiki/watch"));
453
487
 
454
488
  es.onmessage = (event) => {
455
489
  let data: { type: string; path: string };
@@ -544,7 +578,7 @@ export default function Page() {
544
578
  if (!["editor", "text"].includes(kind) && !isText(node.name)) return;
545
579
  setFileLoading(true);
546
580
  try {
547
- const res = await fetch(
581
+ const res = await wsFetch(
548
582
  `/api/wiki/content?path=${encodeURIComponent(node.path)}`,
549
583
  );
550
584
  if (res.ok) {
@@ -558,6 +592,16 @@ export default function Page() {
558
592
  setFileLoading(false);
559
593
  }
560
594
 
595
+ // Open a file from a search result: reveal it in the tree, then open it.
596
+ const openFromSearch = useCallback(
597
+ (relPath: string) => {
598
+ const name = relPath.split("/").pop() ?? relPath;
599
+ void revealPath(relPath);
600
+ void openViewer({ path: relPath, name, type: "file" } as TreeNode);
601
+ },
602
+ [revealPath],
603
+ );
604
+
561
605
  // biome-ignore lint/correctness/useExhaustiveDependencies: only react to editor path changes
562
606
  useEffect(() => {
563
607
  if (!editorCurrentPath) return;
@@ -610,23 +654,35 @@ export default function Page() {
610
654
  })();
611
655
  }, [rootLoaded, revealPath]);
612
656
 
613
- const handleChangeDir = async () => {
614
- await fetch("/api/system/clear-root", { method: "POST" });
657
+ const switchWorkspace = useCallback(async (id: string) => {
658
+ if (id === activeWorkspaceId) return;
659
+ try {
660
+ await fetch(`/api/system/workspaces/${id}/open`, { method: "POST" });
661
+ } catch {
662
+ /* best-effort lastOpened bump */
663
+ }
664
+ const u = new URL(location.href);
665
+ u.searchParams.set("ws", id);
666
+ u.searchParams.delete("path");
667
+ history.pushState(null, "", u.toString());
668
+ // Reset open file + caches; the key={activeWorkspaceId} remount clears the rest.
615
669
  setOpenFile(null);
616
670
  setFileContent(null);
617
671
  setEditing(false);
618
672
  setRoots([]);
619
673
  setRootLoaded(false);
620
674
  rootLoadingRef.current = false;
621
- setRootPath(null);
622
- setRootConfigured(false);
623
- };
675
+ useWikiSlugsStore.getState().invalidate();
676
+ const ws = workspaces.find((w) => w.id === id);
677
+ if (ws) setRootPath(ws.rootDir);
678
+ setActiveWorkspaceId(id);
679
+ }, [activeWorkspaceId, workspaces]);
624
680
 
625
681
  async function handleSave() {
626
682
  if (!openFile) return;
627
683
  setSaving(true);
628
684
  setSaveError(null);
629
- const res = await fetch("/api/wiki/content", {
685
+ const res = await wsFetch("/api/wiki/content", {
630
686
  method: "PUT",
631
687
  headers: { "Content-Type": "application/json" },
632
688
  body: JSON.stringify({
@@ -658,7 +714,7 @@ export default function Page() {
658
714
  const fd = new FormData();
659
715
  fd.append("file", file);
660
716
  fd.append("dir", dir);
661
- const res = await fetch("/api/wiki/upload", {
717
+ const res = await wsFetch("/api/wiki/upload", {
662
718
  method: "POST",
663
719
  body: fd,
664
720
  });
@@ -690,7 +746,7 @@ export default function Page() {
690
746
  if (!name || newFolderParent === null) return;
691
747
  setFolderError(null);
692
748
  const rel = newFolderParent ? `${newFolderParent}/${name}` : name;
693
- const res = await fetch("/api/wiki/folder", {
749
+ const res = await wsFetch("/api/wiki/folder", {
694
750
  method: "POST",
695
751
  headers: { "Content-Type": "application/json" },
696
752
  body: JSON.stringify({ path: rel }),
@@ -716,7 +772,7 @@ export default function Page() {
716
772
  setFileCreateError(null);
717
773
  const name = raw.includes(".") ? raw : `${raw}.md`;
718
774
  const rel = newFileParent ? `${newFileParent}/${name}` : name;
719
- const res = await fetch("/api/wiki/new-file", {
775
+ const res = await wsFetch("/api/wiki/new-file", {
720
776
  method: "POST",
721
777
  headers: { "Content-Type": "application/json" },
722
778
  body: JSON.stringify({ path: rel }),
@@ -744,7 +800,7 @@ export default function Page() {
744
800
  }
745
801
 
746
802
  function handleDownload(node: TreeNode) {
747
- const url = `/api/wiki/download?path=${encodeURIComponent(node.path)}`;
803
+ const url = withWs(`/api/wiki/download?path=${encodeURIComponent(node.path)}`);
748
804
  const a = document.createElement("a");
749
805
  a.href = url;
750
806
  a.download = node.type === "file" ? node.name : `${node.name}.zip`;
@@ -755,7 +811,7 @@ export default function Page() {
755
811
 
756
812
  async function handleDelete() {
757
813
  if (!deletingPath) return;
758
- await fetch("/api/wiki", {
814
+ await wsFetch("/api/wiki", {
759
815
  method: "DELETE",
760
816
  headers: { "Content-Type": "application/json" },
761
817
  body: JSON.stringify({ path: deletingPath }),
@@ -811,7 +867,7 @@ export default function Page() {
811
867
  const newPath = targetDirPath ? `${targetDirPath}/${node.name}` : node.name;
812
868
  if (newPath === node.path) return;
813
869
 
814
- const res = await fetch("/api/wiki/move", {
870
+ const res = await wsFetch("/api/wiki/move", {
815
871
  method: "POST",
816
872
  headers: { "Content-Type": "application/json" },
817
873
  body: JSON.stringify({ from: node.path, to: newPath }),
@@ -876,8 +932,8 @@ export default function Page() {
876
932
  className={cn(
877
933
  "flex items-center gap-1.5 rounded-sm px-2 py-1 text-sm cursor-pointer group transition-colors select-none",
878
934
  openFile?.path === node.path
879
- ? "bg-accent text-accent-foreground"
880
- : "hover:bg-accent/50",
935
+ ? "bg-accent-soft text-foreground font-medium"
936
+ : "hover:bg-muted",
881
937
  dragOverPath === node.path && "ring-2 ring-primary bg-primary-soft",
882
938
  node.name.startsWith(".") && "opacity-40",
883
939
  )}
@@ -907,17 +963,17 @@ export default function Page() {
907
963
  <Folder className={cn("h-4 w-4 shrink-0", openFile?.path !== node.path && "text-warning")} />
908
964
  )
909
965
  ) : node.type === "app" ? (
910
- <Globe className={cn("h-4 w-4 shrink-0", openFile?.path !== node.path && "text-accent")} />
966
+ <Globe className={cn("h-4 w-4 shrink-0", openFile?.path !== node.path && "text-foreground/70")} />
911
967
  ) : node.type === "node-app" ? (
912
968
  <Terminal className={cn("h-4 w-4 shrink-0", openFile?.path !== node.path && "text-emerald-500")} />
913
969
  ) : isHtmlFile(node.name) ? (
914
- <Globe className={cn("h-4 w-4 shrink-0", openFile?.path !== node.path && "text-accent/70")} />
970
+ <Globe className={cn("h-4 w-4 shrink-0", openFile?.path !== node.path && "text-foreground/60")} />
915
971
  ) : isImage(node.name) ? (
916
972
  <ImageIcon className={cn("h-4 w-4 shrink-0", openFile?.path !== node.path && "text-sunshine-700")} />
917
973
  ) : isText(node.name) ? (
918
- <FileText className={cn("h-4 w-4 shrink-0", openFile?.path !== node.path && "text-accent")} />
974
+ <FileText className={cn("h-4 w-4 shrink-0", openFile?.path !== node.path && "text-foreground/70")} />
919
975
  ) : (
920
- <File className={cn("h-4 w-4 shrink-0", openFile?.path !== node.path && "text-muted-foreground")} />
976
+ <File className={cn("h-4 w-4 shrink-0", openFile?.path !== node.path && "text-foreground/60")} />
921
977
  )}
922
978
 
923
979
  <span className="flex-1 truncate">{node.name}</span>
@@ -1104,21 +1160,41 @@ export default function Page() {
1104
1160
  }
1105
1161
 
1106
1162
  return (
1107
- <div className="flex h-screen gap-0 overflow-hidden bg-background">
1163
+ <div key={activeWorkspaceId ?? "none"} className="flex h-screen gap-0 overflow-hidden bg-background">
1108
1164
  {rootConfigured === null && (
1109
1165
  <div className="flex-1 flex items-center justify-center">
1110
1166
  <Loader2 className="h-5 w-5 animate-spin text-muted-foreground" />
1111
1167
  </div>
1112
1168
  )}
1113
1169
  {rootConfigured === false && (
1114
- <DirPicker onSelect={(path) => {
1170
+ <DirPicker onSelect={(workspaceId) => {
1171
+ const u = new URL(location.href);
1172
+ u.searchParams.set("ws", workspaceId);
1173
+ u.searchParams.delete("path");
1174
+ history.replaceState(null, "", u.toString());
1115
1175
  setRootLoaded(false);
1116
1176
  rootLoadingRef.current = false;
1117
- setRootPath(path);
1177
+ setActiveWorkspaceId(workspaceId);
1118
1178
  setRootConfigured(true);
1179
+ void loadWorkspaces();
1119
1180
  }} />
1120
1181
  )}
1121
- {rootConfigured === true && <>
1182
+ {rootConfigured === true && addingWorkspace && (
1183
+ <div className="flex-1 flex flex-col">
1184
+ <div className="flex items-center justify-end border-b px-3 py-2 bg-muted shrink-0">
1185
+ <Button size="sm" variant="ghost" className="h-7 gap-1.5 text-xs" onClick={() => setAddingWorkspace(false)}>
1186
+ <X className="h-3.5 w-3.5" /> Cancel
1187
+ </Button>
1188
+ </div>
1189
+ <DirPicker onSelect={(workspaceId) => {
1190
+ setAddingWorkspace(false);
1191
+ void loadWorkspaces();
1192
+ void switchWorkspace(workspaceId);
1193
+ }} />
1194
+ </div>
1195
+ )}
1196
+ {rootConfigured === true && !addingWorkspace && <>
1197
+ <SearchCommandDialog onOpenFile={openFromSearch} />
1122
1198
  {/* Tree sidebar */}
1123
1199
  {!sidebarCollapsed && (
1124
1200
  <Card className="flex flex-col w-72 shrink-0 overflow-hidden rounded-none border-r border-l-0 border-t-0 border-b-0">
@@ -1318,6 +1394,10 @@ export default function Page() {
1318
1394
  </div>
1319
1395
  )}
1320
1396
 
1397
+ <div className="border-b">
1398
+ <SidebarSearchBox onOpenFile={openFromSearch} />
1399
+ </div>
1400
+
1321
1401
  <div
1322
1402
  className={cn(
1323
1403
  "flex-1 overflow-auto py-1",
@@ -1365,21 +1445,55 @@ export default function Page() {
1365
1445
  renderNodes(roots)
1366
1446
  )}
1367
1447
  </div>
1368
- <div className="border-t px-3 py-2 flex items-center gap-2 bg-muted shrink-0">
1369
- <span
1370
- className="flex-1 text-xs text-muted-foreground font-mono truncate"
1371
- title={rootPath ?? ""}
1372
- >
1373
- {rootPath ?? ""}
1374
- </span>
1375
- <Button
1376
- size="sm"
1377
- variant="ghost"
1378
- className="h-6 shrink-0 text-xs px-2 text-muted-foreground hover:text-foreground"
1379
- onClick={handleChangeDir}
1380
- >
1381
- Change
1382
- </Button>
1448
+ <div className="border-t px-2 py-2 bg-muted shrink-0">
1449
+ <DropdownMenu>
1450
+ <DropdownMenuTrigger asChild>
1451
+ <Button
1452
+ size="sm"
1453
+ variant="ghost"
1454
+ className="w-full h-auto justify-between gap-2 px-2 py-1.5 text-left"
1455
+ title={rootPath ?? ""}
1456
+ >
1457
+ <span className="flex flex-col min-w-0">
1458
+ <span className="truncate text-xs font-medium">
1459
+ {workspaces.find((w) => w.id === activeWorkspaceId)?.name ?? "Workspace"}
1460
+ </span>
1461
+ <span className="truncate text-[10px] text-muted-foreground font-mono">
1462
+ {rootPath ?? ""}
1463
+ </span>
1464
+ </span>
1465
+ <ChevronDown className="h-3.5 w-3.5 shrink-0 opacity-60" />
1466
+ </Button>
1467
+ </DropdownMenuTrigger>
1468
+ <DropdownMenuContent align="start" className="w-60">
1469
+ {workspaces.map((w) => (
1470
+ <DropdownMenuItem
1471
+ key={w.id}
1472
+ onClick={() => void switchWorkspace(w.id)}
1473
+ className={cn("gap-2", w.id === activeWorkspaceId && "font-medium")}
1474
+ >
1475
+ {w.id === activeWorkspaceId ? (
1476
+ <Check className="h-3.5 w-3.5 shrink-0" />
1477
+ ) : (
1478
+ <span className="w-3.5 shrink-0" />
1479
+ )}
1480
+ <span className="flex flex-col min-w-0">
1481
+ <span className="truncate">{w.name}</span>
1482
+ <span className="truncate text-[10px] text-muted-foreground font-mono">{w.rootDir}</span>
1483
+ </span>
1484
+ </DropdownMenuItem>
1485
+ ))}
1486
+ {isWsAdmin && (
1487
+ <>
1488
+ <DropdownMenuSeparator />
1489
+ <DropdownMenuItem onClick={() => setAddingWorkspace(true)}>
1490
+ <FolderPlus className="mr-2 h-3.5 w-3.5" />
1491
+ Add workspace…
1492
+ </DropdownMenuItem>
1493
+ </>
1494
+ )}
1495
+ </DropdownMenuContent>
1496
+ </DropdownMenu>
1383
1497
  </div>
1384
1498
  </Card>
1385
1499
  )}
@@ -43,6 +43,32 @@ export function AuthSettingsSheet({
43
43
  const [rateLimit, setRateLimit] = useState<number | null>(null);
44
44
  const { data: session } = authClient.useSession();
45
45
 
46
+ // Admin management
47
+ const [isAdmin, setIsAdmin] = useState(false);
48
+ const [admins, setAdmins] = useState<string[]>([]);
49
+ const [adminUsers, setAdminUsers] = useState<Array<{ id: string; email: string; name: string }>>([]);
50
+ const [adminError, setAdminError] = useState<string | null>(null);
51
+ const [adminWorking, setAdminWorking] = useState<string | null>(null);
52
+ // Add-user form
53
+ const [newUserEmail, setNewUserEmail] = useState("");
54
+ const [newUserName, setNewUserName] = useState("");
55
+ const [creatingUser, setCreatingUser] = useState(false);
56
+ const [createdUser, setCreatedUser] = useState<{ email: string; tempPassword: string } | null>(null);
57
+
58
+ const loadAdmins = useCallback(async () => {
59
+ try {
60
+ const res = await fetch("/api/system/admins");
61
+ if (!res.ok) return;
62
+ const d: { admins?: string[]; isAdmin?: boolean; users?: Array<{ id: string; email: string; name: string }> } =
63
+ await res.json();
64
+ setIsAdmin(!!d.isAdmin);
65
+ setAdmins(d.admins ?? []);
66
+ setAdminUsers(d.users ?? []);
67
+ } catch {
68
+ /* ignore */
69
+ }
70
+ }, []);
71
+
46
72
  const load = useCallback(async () => {
47
73
  setLoading(true);
48
74
  setError(null);
@@ -62,8 +88,11 @@ export function AuthSettingsSheet({
62
88
  }, []);
63
89
 
64
90
  useEffect(() => {
65
- if (open) void load();
66
- }, [open, load]);
91
+ if (open) {
92
+ void load();
93
+ void loadAdmins();
94
+ }
95
+ }, [open, load, loadAdmins]);
67
96
 
68
97
  async function handleSave() {
69
98
  setSaving(true);
@@ -228,6 +257,146 @@ export function AuthSettingsSheet({
228
257
  )}
229
258
  </section>
230
259
 
260
+ {/* Admins — only visible to admins */}
261
+ {isAdmin && (
262
+ <section className="space-y-2">
263
+ <h3 className="text-xs font-semibold uppercase tracking-widest text-muted-foreground">
264
+ Admins
265
+ </h3>
266
+ <p className="text-xs leading-relaxed text-muted-foreground">
267
+ Admins can create workspaces, add users, and manage access.
268
+ </p>
269
+ {adminError && (
270
+ <div className="flex items-center gap-1.5 text-xs text-destructive">
271
+ <AlertCircle className="h-3.5 w-3.5 shrink-0" />
272
+ {adminError}
273
+ </div>
274
+ )}
275
+
276
+ {/* Add user */}
277
+ <div className="space-y-2 rounded-md border border-border p-3">
278
+ <div className="text-xs font-medium">Add user</div>
279
+ {createdUser ? (
280
+ <div className="space-y-2">
281
+ <p className="text-xs text-muted-foreground">
282
+ Created <span className="font-medium text-foreground">{createdUser.email}</span>. Share this temporary password now, it will not be shown again.
283
+ </p>
284
+ <div className="flex items-center gap-2">
285
+ <code className="flex-1 rounded bg-muted px-2 py-1.5 font-mono text-sm select-all">{createdUser.tempPassword}</code>
286
+ <button
287
+ type="button"
288
+ className="shrink-0 text-xs px-2 py-1 rounded border border-border hover:bg-accent"
289
+ onClick={() => void navigator.clipboard?.writeText(createdUser.tempPassword)}
290
+ >
291
+ Copy
292
+ </button>
293
+ </div>
294
+ <button
295
+ type="button"
296
+ className="text-xs text-muted-foreground hover:text-foreground"
297
+ onClick={() => { setCreatedUser(null); setNewUserEmail(""); setNewUserName(""); void loadAdmins(); }}
298
+ >
299
+ Done
300
+ </button>
301
+ </div>
302
+ ) : (
303
+ <div className="space-y-2">
304
+ <input
305
+ type="email"
306
+ value={newUserEmail}
307
+ onChange={(e) => setNewUserEmail(e.target.value)}
308
+ placeholder="email@team.com"
309
+ className="w-full rounded-md border border-border bg-background px-2 py-1.5 text-sm outline-none focus:ring-2 focus:ring-primary"
310
+ />
311
+ <input
312
+ type="text"
313
+ value={newUserName}
314
+ onChange={(e) => setNewUserName(e.target.value)}
315
+ placeholder="Name (optional)"
316
+ className="w-full rounded-md border border-border bg-background px-2 py-1.5 text-sm outline-none focus:ring-2 focus:ring-primary"
317
+ />
318
+ <Button
319
+ size="sm"
320
+ className="w-full gap-1.5"
321
+ disabled={creatingUser || !newUserEmail.trim()}
322
+ onClick={async () => {
323
+ setCreatingUser(true);
324
+ setAdminError(null);
325
+ try {
326
+ const res = await fetch("/api/system/users", {
327
+ method: "POST",
328
+ headers: { "Content-Type": "application/json" },
329
+ body: JSON.stringify({ email: newUserEmail.trim(), name: newUserName.trim() }),
330
+ });
331
+ const d: { ok?: boolean; email?: string; tempPassword?: string; error?: string; message?: string } = await res.json();
332
+ if (!res.ok || !d.tempPassword) {
333
+ setAdminError(d.message ?? d.error ?? "Failed to create user");
334
+ } else {
335
+ setCreatedUser({ email: d.email ?? newUserEmail.trim(), tempPassword: d.tempPassword });
336
+ }
337
+ } catch {
338
+ setAdminError("Network error");
339
+ } finally {
340
+ setCreatingUser(false);
341
+ }
342
+ }}
343
+ >
344
+ {creatingUser && <Loader2 className="h-3.5 w-3.5 animate-spin" />}
345
+ Create user
346
+ </Button>
347
+ </div>
348
+ )}
349
+ </div>
350
+ <div className="space-y-1 rounded-md border border-border overflow-hidden">
351
+ {adminUsers.map((u) => {
352
+ const isAdminUser = admins.includes(u.id);
353
+ return (
354
+ <div key={u.id} className="flex items-center justify-between px-3 py-2 bg-muted/40 hover:bg-muted/60 transition-colors">
355
+ <div className="text-sm min-w-0">
356
+ <div className="font-medium truncate">{u.name}</div>
357
+ <div className="text-xs text-muted-foreground truncate">{u.email}</div>
358
+ </div>
359
+ <button
360
+ type="button"
361
+ disabled={adminWorking === u.id}
362
+ className="ml-2 shrink-0 text-xs px-2 py-1 rounded border border-border hover:bg-accent disabled:opacity-50"
363
+ onClick={async () => {
364
+ setAdminWorking(u.id);
365
+ setAdminError(null);
366
+ try {
367
+ const res = await fetch("/api/system/admins", {
368
+ method: isAdminUser ? "DELETE" : "POST",
369
+ headers: { "Content-Type": "application/json" },
370
+ body: JSON.stringify({ userId: u.id }),
371
+ });
372
+ const d: { ok?: boolean; admins?: string[]; error?: string; message?: string } = await res.json();
373
+ if (!res.ok) {
374
+ setAdminError(d.message ?? d.error ?? "Failed");
375
+ } else if (d.admins) {
376
+ setAdmins(d.admins);
377
+ }
378
+ } catch {
379
+ setAdminError("Network error");
380
+ } finally {
381
+ setAdminWorking(null);
382
+ }
383
+ }}
384
+ >
385
+ {adminWorking === u.id ? (
386
+ <Loader2 className="h-3 w-3 animate-spin" />
387
+ ) : isAdminUser ? "Demote" : "Promote"}
388
+ </button>
389
+ </div>
390
+ );
391
+ })}
392
+ {adminUsers.length === 0 && (
393
+ <div className="px-3 py-2 text-xs text-muted-foreground">No users yet.</div>
394
+ )}
395
+ </div>
396
+ {/* TODO: per-workspace access editor (PATCH /api/system/workspaces/[id] allowedUserIds) */}
397
+ </section>
398
+ )}
399
+
231
400
  {/* Agent rate limit */}
232
401
  <section className="space-y-2">
233
402
  <h3 className="text-xs font-semibold uppercase tracking-widest text-muted-foreground">
@@ -29,7 +29,8 @@ interface BrowseResult {
29
29
  }
30
30
 
31
31
  interface Props {
32
- onSelect: (path: string) => void;
32
+ /** Called with the new workspace id after creation */
33
+ onSelect: (workspaceId: string) => void;
33
34
  }
34
35
 
35
36
  export function DirPicker({ onSelect }: Props) {
@@ -96,17 +97,18 @@ export function DirPicker({ onSelect }: Props) {
96
97
  if (!target) return;
97
98
  setSelecting(true);
98
99
  try {
99
- const res = await fetch("/api/system/set-root", {
100
+ const res = await fetch("/api/system/workspaces", {
100
101
  method: "POST",
101
102
  headers: { "Content-Type": "application/json" },
102
- body: JSON.stringify({ path: target }),
103
+ body: JSON.stringify({ rootDir: target }),
103
104
  });
104
105
  if (!res.ok) {
105
- const e: { error?: string } = await res.json();
106
- setError(e.error ?? "Cannot use that directory");
106
+ const e: { error?: string; message?: string } = await res.json();
107
+ setError(e.message ?? e.error ?? "Cannot use that directory");
107
108
  return;
108
109
  }
109
- onSelect(target);
110
+ const { workspace }: { workspace: { id: string } } = await res.json();
111
+ onSelect(workspace.id);
110
112
  } catch {
111
113
  setError("Network error");
112
114
  } finally {
@@ -4,6 +4,7 @@ import * as Popover from "@radix-ui/react-popover";
4
4
  import { useEffect, useRef, useState } from "react";
5
5
  import { authHeaders } from "@/lib/proof/client-auth";
6
6
  import { useProofStore } from "@/stores/proof-store";
7
+ import { wsFetch } from "@/lib/workspace-client";
7
8
  import type { Comment } from "@/lib/proof/types";
8
9
 
9
10
  // ── helpers ──────────────────────────────────────────────────────────────────
@@ -28,7 +29,7 @@ async function postOp(
28
29
  ops: object[],
29
30
  ): Promise<{ ok: boolean; stale: boolean; newRevision?: number }> {
30
31
  const encoded = encodeURIComponent(path).replace(/%2F/g, "/");
31
- const res = await fetch(`/api/agent/files/${encoded}`, {
32
+ const res = await wsFetch(`/api/agent/files/${encoded}`, {
32
33
  method: "POST",
33
34
  headers: {
34
35
  "Content-Type": "application/json",
@@ -2,6 +2,7 @@
2
2
 
3
3
  import { Code2, Download, Save } from "lucide-react";
4
4
  import { useCallback, useEffect, useState } from "react";
5
+ import { wsFetch } from "@/lib/workspace-client";
5
6
  import { ViewerToolbar } from "@/components/layout/viewer-toolbar";
6
7
  import { Button } from "@/components/ui/button";
7
8
 
@@ -80,7 +81,7 @@ export function CsvViewer({ path }: CsvViewerProps) {
80
81
  const csvUrl = `/api/assets/${path}`;
81
82
 
82
83
  useEffect(() => {
83
- fetch(csvUrl)
84
+ wsFetch(csvUrl)
84
85
  .then((r) => r.text())
85
86
  .then((text) => {
86
87
  setRawText(text);
@@ -121,7 +122,7 @@ export function CsvViewer({ path }: CsvViewerProps) {
121
122
  setSaving(true);
122
123
  const csv = sourceMode ? rawText : rowsToCsv(rows);
123
124
  try {
124
- await fetch(`/api/assets/${path}`, {
125
+ await wsFetch(`/api/assets/${path}`, {
125
126
  method: "PUT",
126
127
  headers: { "Content-Type": "text/plain" },
127
128
  body: csv,
@@ -85,9 +85,9 @@ function ToolButton({
85
85
  onAction(e);
86
86
  }}
87
87
  className={cn(
88
- "h-8 w-8 shrink-0 inline-flex items-center justify-center rounded-md text-foreground/80 hover:bg-accent transition-colors disabled:opacity-40",
88
+ "h-8 w-8 shrink-0 inline-flex items-center justify-center rounded-md text-foreground/80 hover:bg-accent hover:text-accent-foreground transition-colors disabled:opacity-40",
89
89
  active &&
90
- "bg-accent text-foreground ring-1 ring-inset ring-foreground/15",
90
+ "bg-accent text-accent-foreground ring-1 ring-inset ring-foreground/15",
91
91
  )}
92
92
  >
93
93
  <Icon className="h-4 w-4" />