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
@@ -0,0 +1,67 @@
1
+ /**
2
+ * Workspace management API — list and create.
3
+ *
4
+ * GET /api/system/workspaces — any signed-in user; returns workspaces the
5
+ * caller can access + isAdmin flag.
6
+ * POST { rootDir, name? } — admin-only: create a new workspace.
7
+ *
8
+ * Bootstrap: first authenticated request triggers ensureBootstrapAdmin.
9
+ */
10
+ import { stat } from "node:fs/promises";
11
+ import { NextResponse } from "next/server";
12
+ import { checkOrigin } from "@/lib/auth/csrf";
13
+ import { requireUser } from "@/lib/auth/server";
14
+ import { isAdmin, requireAdmin, ensureBootstrapAdmin } from "@/lib/auth/admin";
15
+ import {
16
+ listWorkspaces,
17
+ createWorkspace,
18
+ migrateConfigToWorkspaces,
19
+ userCanAccess,
20
+ } from "@/lib/workspaces";
21
+
22
+ export const runtime = "nodejs";
23
+
24
+ export async function GET(request: Request) {
25
+ const auth = await requireUser(request);
26
+ if (!auth.ok) return NextResponse.json({ error: "UNAUTHORIZED" }, { status: 401 });
27
+
28
+ // Bootstrap: first authenticated user becomes admin if no admin set yet.
29
+ await ensureBootstrapAdmin(auth.user.id);
30
+ await migrateConfigToWorkspaces();
31
+
32
+ const admin = await isAdmin(auth.user.id, auth.user.email);
33
+ const all = await listWorkspaces();
34
+ const workspaces = all.filter((ws) => userCanAccess(ws, auth.user.id, admin));
35
+
36
+ return NextResponse.json({ workspaces, isAdmin: admin });
37
+ }
38
+
39
+ export async function POST(request: Request) {
40
+ const csrf = checkOrigin(request);
41
+ if (csrf) return csrf;
42
+
43
+ const authResult = await requireAdmin(request);
44
+ if (!authResult.ok)
45
+ return NextResponse.json({ error: authResult.code }, { status: authResult.status });
46
+
47
+ const body: { rootDir?: string; name?: string } = await request.json();
48
+ const rootDir = body.rootDir?.trim();
49
+ if (!rootDir) return NextResponse.json({ error: "Missing rootDir" }, { status: 400 });
50
+
51
+ // Validate directory
52
+ try {
53
+ const info = await stat(rootDir);
54
+ if (!info.isDirectory())
55
+ return NextResponse.json({ error: "Not a directory" }, { status: 400 });
56
+ } catch {
57
+ return NextResponse.json({ error: "Directory not found" }, { status: 404 });
58
+ }
59
+
60
+ const workspace = await createWorkspace({
61
+ rootDir,
62
+ name: body.name?.trim() || undefined,
63
+ createdBy: authResult.user.id,
64
+ });
65
+
66
+ return NextResponse.json({ ok: true, workspace });
67
+ }
@@ -1,7 +1,8 @@
1
1
  import { mkdir, stat, writeFile } from "node:fs/promises";
2
2
  import path from "node:path";
3
3
  import { NextResponse } from "next/server";
4
- import { getRootDir } from "@/lib/root-dir";
4
+ import { resolveWorkspaceForAgent } from "@/lib/workspace-context";
5
+ import { safeWorkspacePath } from "@/lib/workspaces";
5
6
 
6
7
  const MAX_UPLOAD_BYTES = 50 * 1024 * 1024;
7
8
 
@@ -32,13 +33,17 @@ export async function POST(
32
33
  request: Request,
33
34
  { params }: { params: Promise<{ path: string[] }> },
34
35
  ) {
36
+ const wsx = await resolveWorkspaceForAgent(request);
37
+ if (!wsx.ok) return NextResponse.json({ error: wsx.code }, { status: wsx.status });
38
+ const { rootDir } = wsx;
39
+
35
40
  const { path: segments } = await params;
36
41
  const subPath = (segments ?? []).join("/");
37
42
 
38
- // Save images in _uploads/ within getRootDir(), mirroring the page path
39
- const uploadsDir = path.join(getRootDir(), "_uploads", subPath);
40
- const resolved = path.resolve(uploadsDir);
41
- if (!resolved.startsWith(getRootDir() + path.sep) && resolved !== getRootDir())
43
+ // Save images in _uploads/ within rootDir, mirroring the page path
44
+ const uploadsDir = path.join(rootDir, "_uploads", subPath);
45
+ const resolved = safeWorkspacePath(rootDir, path.join("_uploads", subPath));
46
+ if (!resolved)
42
47
  return NextResponse.json({ error: "Invalid path" }, { status: 400 });
43
48
 
44
49
  let form: FormData;
@@ -1,14 +1,14 @@
1
1
  import path from "node:path";
2
2
  import { NextResponse } from "next/server";
3
3
  import { checkOrigin } from "@/lib/auth/csrf";
4
- import { requireUser } from "@/lib/auth/server";
4
+ import { resolveWorkspaceForUser } from "@/lib/workspace-context";
5
+ import { safeWorkspacePath } from "@/lib/workspaces";
5
6
  import { getStatus, startApp, stopApp } from "@/lib/app-runner";
6
- import { getRootDir, safeRootPath } from "@/lib/root-dir";
7
7
 
8
8
  // GET /api/wiki/app?path=relative/path
9
9
  export async function GET(request: Request) {
10
- const auth = await requireUser(request);
11
- if (!auth.ok) return NextResponse.json({ error: "UNAUTHORIZED" }, { status: 401 });
10
+ const ctx = await resolveWorkspaceForUser(request);
11
+ if (!ctx.ok) return NextResponse.json({ error: ctx.code }, { status: ctx.status });
12
12
 
13
13
  const { searchParams } = new URL(request.url);
14
14
  const rel = searchParams.get("path") ?? "";
@@ -19,15 +19,16 @@ export async function GET(request: Request) {
19
19
  export async function POST(request: Request) {
20
20
  const csrf = checkOrigin(request);
21
21
  if (csrf) return csrf;
22
- const auth = await requireUser(request);
23
- if (!auth.ok) return NextResponse.json({ error: "UNAUTHORIZED" }, { status: 401 });
22
+ const ctx = await resolveWorkspaceForUser(request);
23
+ if (!ctx.ok) return NextResponse.json({ error: ctx.code }, { status: ctx.status });
24
+ const { rootDir } = ctx;
24
25
 
25
26
  const body: { path?: string } = await request.json();
26
27
  const rel = body.path;
27
28
  if (!rel || typeof rel !== "string")
28
29
  return NextResponse.json({ error: "Missing path" }, { status: 400 });
29
30
 
30
- const abs = safeRootPath(rel);
31
+ const abs = safeWorkspacePath(rootDir, rel);
31
32
  if (!abs)
32
33
  return NextResponse.json({ error: "Invalid path" }, { status: 400 });
33
34
 
@@ -43,8 +44,8 @@ export async function POST(request: Request) {
43
44
  export async function DELETE(request: Request) {
44
45
  const csrf = checkOrigin(request);
45
46
  if (csrf) return csrf;
46
- const auth = await requireUser(request);
47
- if (!auth.ok) return NextResponse.json({ error: "UNAUTHORIZED" }, { status: 401 });
47
+ const ctx = await resolveWorkspaceForUser(request);
48
+ if (!ctx.ok) return NextResponse.json({ error: ctx.code }, { status: ctx.status });
48
49
 
49
50
  const body: { path?: string } = await request.json();
50
51
  const rel = body.path;
@@ -3,12 +3,12 @@ import { mkdir, readFile, writeFile } from "node:fs/promises";
3
3
  import path from "node:path";
4
4
  import { NextResponse } from "next/server";
5
5
  import { checkOrigin } from "@/lib/auth/csrf";
6
- import { requireUser } from "@/lib/auth/server";
6
+ import { resolveWorkspaceForUser } from "@/lib/workspace-context";
7
+ import { safeWorkspacePath } from "@/lib/workspaces";
7
8
  import { emitEvents, trimEvents } from "@/lib/proof/event-bus";
8
9
  import { withFileMutex } from "@/lib/proof/mutex";
9
10
  import { emptySidecar, readSidecar, writeSidecar } from "@/lib/proof/sidecar";
10
11
  import { SIDECAR_EVENT_TRIM_SIZE } from "@/lib/proof-config";
11
- import { getRootDir, safeRootPath } from "@/lib/root-dir";
12
12
 
13
13
  const TEXT_EXTS = new Set([
14
14
  "txt", "md", "markdown", "json", "yaml", "yml", "toml", "csv", "tsv",
@@ -35,12 +35,13 @@ function sha256content(content: string): string {
35
35
  }
36
36
 
37
37
  export async function GET(request: Request) {
38
- const sessionAuth = await requireUser(request);
39
- if (!sessionAuth.ok) return NextResponse.json({ error: "UNAUTHORIZED" }, { status: 401 });
38
+ const ctx = await resolveWorkspaceForUser(request);
39
+ if (!ctx.ok) return NextResponse.json({ error: ctx.code }, { status: ctx.status });
40
+ const { rootDir } = ctx;
40
41
 
41
42
  const { searchParams } = new URL(request.url);
42
43
  const rel = searchParams.get("path") ?? "";
43
- const filePath = safeRootPath(rel);
44
+ const filePath = safeWorkspacePath(rootDir, rel);
44
45
  if (!filePath)
45
46
  return NextResponse.json({ error: "Invalid path" }, { status: 400 });
46
47
  if (!isTextFile(path.basename(filePath)))
@@ -55,7 +56,6 @@ export async function GET(request: Request) {
55
56
  const content = buffer.toString("utf-8");
56
57
  const headers: Record<string, string> = {};
57
58
  if (isMarkdownFile(path.basename(filePath))) {
58
- const rootDir = getRootDir();
59
59
  const sc = await readSidecar(rootDir, rel);
60
60
  if (sc) {
61
61
  headers["X-Wiki-Revision"] = String(sc.revision);
@@ -71,10 +71,9 @@ export async function GET(request: Request) {
71
71
  export async function PUT(request: Request) {
72
72
  const csrf = checkOrigin(request);
73
73
  if (csrf) return csrf;
74
- const user = await requireUser(request);
75
- if (!user.ok) {
76
- return NextResponse.json({ error: "UNAUTHORIZED" }, { status: 401 });
77
- }
74
+ const ctx = await resolveWorkspaceForUser(request);
75
+ if (!ctx.ok) return NextResponse.json({ error: ctx.code }, { status: ctx.status });
76
+ const { rootDir } = ctx;
78
77
 
79
78
  const body: { path?: string; content?: string; baseRevision?: number } =
80
79
  await request.json();
@@ -84,7 +83,7 @@ export async function PUT(request: Request) {
84
83
  return NextResponse.json({ error: "Invalid path" }, { status: 400 });
85
84
  if (typeof content !== "string")
86
85
  return NextResponse.json({ error: "Missing content" }, { status: 400 });
87
- const filePath = safeRootPath(rel);
86
+ const filePath = safeWorkspacePath(rootDir, rel);
88
87
  if (!filePath)
89
88
  return NextResponse.json({ error: "Invalid path" }, { status: 400 });
90
89
  if (!isTextFile(path.basename(filePath)))
@@ -102,8 +101,9 @@ export async function PUT(request: Request) {
102
101
  }
103
102
 
104
103
  // Markdown files: mutex + sidecar revision check + fingerprint update + event.
105
- return withFileMutex(filePath, async () => {
106
- const rootDir = getRootDir();
104
+ // Use the same key format as the agent routes (`${rootDir}\0${rel}`) so a doc
105
+ // edited via both the editor and the agent fs API shares one lock.
106
+ return withFileMutex(`${rootDir}\u0000${rel}`, async () => {
107
107
  const sc = (await readSidecar(rootDir, rel)) ?? emptySidecar(rel);
108
108
 
109
109
  // baseRevision is required for markdown to prevent lost writes.
@@ -146,7 +146,7 @@ export async function PUT(request: Request) {
146
146
  {
147
147
  type: "file.edited",
148
148
  at: new Date().toISOString(),
149
- by: `user:${user.user.id}`,
149
+ by: `user:${ctx.userId}`,
150
150
  revision: newRevision,
151
151
  },
152
152
  ]);
@@ -4,8 +4,8 @@ import path from "node:path";
4
4
  import { Readable } from "node:stream";
5
5
  import JSZip from "jszip";
6
6
  import { NextResponse } from "next/server";
7
- import { requireUser } from "@/lib/auth/server";
8
- import { safeRootPath } from "@/lib/root-dir";
7
+ import { resolveWorkspaceForUser } from "@/lib/workspace-context";
8
+ import { safeWorkspacePath } from "@/lib/workspaces";
9
9
 
10
10
  // Skip noise that should never end up in a downloaded archive.
11
11
  const SKIP_DIRS = new Set([".git", "node_modules", ".next", ".proof"]);
@@ -37,13 +37,14 @@ async function addDirToZip(
37
37
  }
38
38
 
39
39
  export async function GET(request: Request) {
40
- const auth = await requireUser(request);
41
- if (!auth.ok)
42
- return NextResponse.json({ error: "UNAUTHORIZED" }, { status: 401 });
40
+ const ctx = await resolveWorkspaceForUser(request);
41
+ if (!ctx.ok)
42
+ return NextResponse.json({ error: ctx.code }, { status: ctx.status });
43
+ const { rootDir } = ctx;
43
44
 
44
45
  const { searchParams } = new URL(request.url);
45
46
  const rel = searchParams.get("path") ?? "";
46
- const target = safeRootPath(rel);
47
+ const target = safeWorkspacePath(rootDir, rel);
47
48
  if (!target)
48
49
  return NextResponse.json({ error: "Invalid path" }, { status: 400 });
49
50
 
@@ -1,7 +1,8 @@
1
1
  import { readFile, stat } from "node:fs/promises";
2
2
  import path from "node:path";
3
3
  import { NextResponse } from "next/server";
4
- import { safeRootPath } from "@/lib/root-dir";
4
+ import { resolveWorkspaceForAgent } from "@/lib/workspace-context";
5
+ import { safeWorkspacePath } from "@/lib/workspaces";
5
6
 
6
7
  const MIME_MAP: Record<string, string> = {
7
8
  jpg: "image/jpeg",
@@ -28,9 +29,13 @@ const MIME_MAP: Record<string, string> = {
28
29
  };
29
30
 
30
31
  export async function GET(request: Request) {
32
+ const wsx = await resolveWorkspaceForAgent(request);
33
+ if (!wsx.ok) return NextResponse.json({ error: wsx.code }, { status: wsx.status });
34
+ const { rootDir } = wsx;
35
+
31
36
  const { searchParams } = new URL(request.url);
32
37
  const rel = searchParams.get("path") ?? "";
33
- const filePath = safeRootPath(rel);
38
+ const filePath = safeWorkspacePath(rootDir, rel);
34
39
  if (!filePath)
35
40
  return NextResponse.json({ error: "Invalid path" }, { status: 400 });
36
41
  try {
@@ -1,14 +1,15 @@
1
1
  import { mkdir } from "node:fs/promises";
2
2
  import { NextResponse } from "next/server";
3
3
  import { checkOrigin } from "@/lib/auth/csrf";
4
- import { requireUser } from "@/lib/auth/server";
5
- import { safeRootPath } from "@/lib/root-dir";
4
+ import { resolveWorkspaceForUser } from "@/lib/workspace-context";
5
+ import { safeWorkspacePath } from "@/lib/workspaces";
6
6
 
7
7
  export async function POST(request: Request) {
8
8
  const csrf = checkOrigin(request);
9
9
  if (csrf) return csrf;
10
- const auth = await requireUser(request);
11
- if (!auth.ok) return NextResponse.json({ error: "UNAUTHORIZED" }, { status: 401 });
10
+ const ctx = await resolveWorkspaceForUser(request);
11
+ if (!ctx.ok) return NextResponse.json({ error: ctx.code }, { status: ctx.status });
12
+ const { rootDir } = ctx;
12
13
 
13
14
  const body: { path?: string } = await request.json();
14
15
  const rel = body.path;
@@ -17,7 +18,7 @@ export async function POST(request: Request) {
17
18
  return NextResponse.json({ error: "Invalid folder path" }, { status: 400 });
18
19
  }
19
20
 
20
- const folderPath = safeRootPath(rel);
21
+ const folderPath = safeWorkspacePath(rootDir, rel);
21
22
  if (!folderPath)
22
23
  return NextResponse.json({ error: "Invalid path" }, { status: 400 });
23
24
 
@@ -2,15 +2,16 @@ import { rename, stat } from "node:fs/promises";
2
2
  import path from "node:path";
3
3
  import { NextResponse } from "next/server";
4
4
  import { checkOrigin } from "@/lib/auth/csrf";
5
- import { requireUser } from "@/lib/auth/server";
6
- import { safeRootPath, getRootDir } from "@/lib/root-dir";
5
+ import { resolveWorkspaceForUser } from "@/lib/workspace-context";
6
+ import { safeWorkspacePath } from "@/lib/workspaces";
7
7
  import { moveSidecar } from "@/lib/proof/sidecar";
8
8
 
9
9
  export async function POST(request: Request) {
10
10
  const csrf = checkOrigin(request);
11
11
  if (csrf) return csrf;
12
- const auth = await requireUser(request);
13
- if (!auth.ok) return NextResponse.json({ error: "UNAUTHORIZED" }, { status: 401 });
12
+ const ctx = await resolveWorkspaceForUser(request);
13
+ if (!ctx.ok) return NextResponse.json({ error: ctx.code }, { status: ctx.status });
14
+ const { rootDir } = ctx;
14
15
 
15
16
  const body: { from?: string; to?: string } = await request.json();
16
17
  if (
@@ -25,8 +26,8 @@ export async function POST(request: Request) {
25
26
  );
26
27
  }
27
28
 
28
- const fromPath = safeRootPath(body.from);
29
- const toPath = safeRootPath(body.to);
29
+ const fromPath = safeWorkspacePath(rootDir, body.from);
30
+ const toPath = safeWorkspacePath(rootDir, body.to);
30
31
 
31
32
  if (!fromPath || !toPath)
32
33
  return NextResponse.json({ error: "Invalid path" }, { status: 400 });
@@ -50,7 +51,6 @@ export async function POST(request: Request) {
50
51
  // Fix latent bug: sidecar was orphaned on .md renames (R3)
51
52
  const fromExt = path.extname(body.from).toLowerCase();
52
53
  if (fromExt === ".md" || fromExt === ".markdown") {
53
- const rootDir = getRootDir();
54
54
  await moveSidecar(rootDir, body.from, body.to);
55
55
  }
56
56
 
@@ -2,15 +2,16 @@ import { mkdir, stat, writeFile } from "node:fs/promises";
2
2
  import path from "node:path";
3
3
  import { NextResponse } from "next/server";
4
4
  import { checkOrigin } from "@/lib/auth/csrf";
5
- import { requireUser } from "@/lib/auth/server";
6
- import { safeRootPath } from "@/lib/root-dir";
5
+ import { resolveWorkspaceForUser } from "@/lib/workspace-context";
6
+ import { safeWorkspacePath } from "@/lib/workspaces";
7
7
 
8
8
  export async function POST(request: Request) {
9
9
  const csrf = checkOrigin(request);
10
10
  if (csrf) return csrf;
11
- const auth = await requireUser(request);
12
- if (!auth.ok)
13
- return NextResponse.json({ error: "UNAUTHORIZED" }, { status: 401 });
11
+ const ctx = await resolveWorkspaceForUser(request);
12
+ if (!ctx.ok)
13
+ return NextResponse.json({ error: ctx.code }, { status: ctx.status });
14
+ const { rootDir } = ctx;
14
15
 
15
16
  const body: { path?: string } = await request.json();
16
17
  const rel = body.path;
@@ -22,7 +23,7 @@ export async function POST(request: Request) {
22
23
  return NextResponse.json({ error: "Invalid file path" }, { status: 400 });
23
24
  }
24
25
 
25
- const filePath = safeRootPath(rel);
26
+ const filePath = safeWorkspacePath(rootDir, rel);
26
27
  if (!filePath)
27
28
  return NextResponse.json({ error: "Invalid path" }, { status: 400 });
28
29
 
@@ -2,8 +2,8 @@ import { mkdir, stat, writeFile } from "node:fs/promises";
2
2
  import path from "node:path";
3
3
  import { NextResponse } from "next/server";
4
4
  import { checkOrigin } from "@/lib/auth/csrf";
5
- import { requireUser } from "@/lib/auth/server";
6
- import { safeRootPath } from "@/lib/root-dir";
5
+ import { resolveWorkspaceForUser } from "@/lib/workspace-context";
6
+ import { safeWorkspacePath } from "@/lib/workspaces";
7
7
 
8
8
  const VALID_DIRS = new Set(["entities", "concepts", "comparisons"]);
9
9
  const SLUG_RE = /^[a-z0-9-]+$/;
@@ -37,8 +37,9 @@ function singularType(
37
37
  export async function POST(request: Request) {
38
38
  const csrf = checkOrigin(request);
39
39
  if (csrf) return csrf;
40
- const auth = await requireUser(request);
41
- if (!auth.ok) return NextResponse.json({ error: "UNAUTHORIZED" }, { status: 401 });
40
+ const ctx = await resolveWorkspaceForUser(request);
41
+ if (!ctx.ok) return NextResponse.json({ error: ctx.code }, { status: ctx.status });
42
+ const { rootDir } = ctx;
42
43
 
43
44
  const body: PageBody = await request.json();
44
45
  const { dir, slug } = body;
@@ -51,7 +52,7 @@ export async function POST(request: Request) {
51
52
  }
52
53
 
53
54
  const relPath = `${dir}/${slug}.md`;
54
- const filePath = safeRootPath(relPath);
55
+ const filePath = safeWorkspacePath(rootDir, relPath);
55
56
  if (!filePath)
56
57
  return NextResponse.json({ error: "Invalid path" }, { status: 400 });
57
58
 
@@ -12,17 +12,18 @@
12
12
  export const runtime = "nodejs";
13
13
 
14
14
  import { NextResponse } from "next/server";
15
- import { requireUser } from "@/lib/auth/server";
15
+ import { resolveWorkspaceForUser } from "@/lib/workspace-context";
16
+ import { safeWorkspacePath } from "@/lib/workspaces";
16
17
  import { setLease, clearLease } from "@/lib/proof/lease";
17
- import { safeRootPath } from "@/lib/root-dir";
18
18
 
19
19
  function errJson(code: string, message: string, status: number): NextResponse {
20
20
  return NextResponse.json({ error: code, message }, { status });
21
21
  }
22
22
 
23
23
  export async function POST(req: Request): Promise<NextResponse> {
24
- const auth = await requireUser(req);
25
- if (!auth.ok) return errJson("UNAUTHORIZED", "Not authenticated", 401);
24
+ const ctx = await resolveWorkspaceForUser(req);
25
+ if (!ctx.ok) return errJson(ctx.code, "Not authenticated", ctx.status);
26
+ const { rootDir } = ctx;
26
27
 
27
28
  let body: { path?: unknown; action?: unknown };
28
29
  try {
@@ -40,15 +41,15 @@ export async function POST(req: Request): Promise<NextResponse> {
40
41
  }
41
42
 
42
43
  // Basic traversal guard
43
- if (!safeRootPath(relPath)) {
44
+ if (!safeWorkspacePath(rootDir, relPath)) {
44
45
  return errJson("INVALID_PATH", "Path traversal rejected", 400);
45
46
  }
46
47
 
47
48
  if (action === "open" || action === "heartbeat") {
48
- setLease(relPath, auth.user.id);
49
+ setLease(rootDir, relPath, ctx.userId);
49
50
  } else {
50
51
  // close
51
- clearLease(relPath, auth.user.id);
52
+ clearLease(rootDir, relPath, ctx.userId);
52
53
  }
53
54
 
54
55
  return NextResponse.json({ ok: true });
@@ -2,18 +2,19 @@ import { readdir, rmdir, stat, unlink } from "node:fs/promises";
2
2
  import path from "node:path";
3
3
  import { NextResponse } from "next/server";
4
4
  import { checkOrigin } from "@/lib/auth/csrf";
5
- import { requireUser } from "@/lib/auth/server";
6
- import { getRootDir, safeRootPath } from "@/lib/root-dir";
5
+ import { resolveWorkspaceForUser } from "@/lib/workspace-context";
6
+ import { safeWorkspacePath } from "@/lib/workspaces";
7
7
  import { isAppFolder, isNodeApp } from "@/lib/wiki-helpers";
8
8
 
9
9
  export async function GET(request: Request) {
10
- const auth = await requireUser(request);
11
- if (!auth.ok) return NextResponse.json({ error: "UNAUTHORIZED" }, { status: 401 });
10
+ const ctx = await resolveWorkspaceForUser(request);
11
+ if (!ctx.ok) return NextResponse.json({ error: ctx.code }, { status: ctx.status });
12
+ const { rootDir } = ctx;
12
13
 
13
14
  const { searchParams } = new URL(request.url);
14
15
  const dir = searchParams.get("dir") ?? "";
15
16
 
16
- const targetDir = safeRootPath(dir);
17
+ const targetDir = safeWorkspacePath(rootDir, dir);
17
18
  if (!targetDir)
18
19
  return NextResponse.json({ error: "Invalid path" }, { status: 400 });
19
20
 
@@ -31,7 +32,7 @@ export async function GET(request: Request) {
31
32
  const info = await stat(filePath);
32
33
  if (info.isDirectory()) {
33
34
  const relPath = dir ? `${dir}/${name}` : name;
34
- const nodeApp = await isNodeApp(getRootDir(), relPath);
35
+ const nodeApp = await isNodeApp(rootDir, relPath);
35
36
  if (nodeApp) {
36
37
  return {
37
38
  name,
@@ -39,7 +40,7 @@ export async function GET(request: Request) {
39
40
  modifiedAt: info.mtime.toISOString(),
40
41
  };
41
42
  }
42
- const isApp = await isAppFolder(getRootDir(), relPath);
43
+ const isApp = await isAppFolder(rootDir, relPath);
43
44
  return {
44
45
  name,
45
46
  type: (isApp ? "app" : "dir") as "app" | "dir",
@@ -74,16 +75,17 @@ export async function GET(request: Request) {
74
75
  export async function DELETE(request: Request) {
75
76
  const csrf = checkOrigin(request);
76
77
  if (csrf) return csrf;
77
- const auth = await requireUser(request);
78
- if (!auth.ok) return NextResponse.json({ error: "UNAUTHORIZED" }, { status: 401 });
78
+ const ctx = await resolveWorkspaceForUser(request);
79
+ if (!ctx.ok) return NextResponse.json({ error: ctx.code }, { status: ctx.status });
80
+ const { rootDir } = ctx;
79
81
 
80
82
  const body: { path?: string } = await request.json();
81
83
  const rel = body.path;
82
84
  if (!rel || typeof rel !== "string")
83
85
  return NextResponse.json({ error: "Invalid path" }, { status: 400 });
84
86
 
85
- const filePath = safeRootPath(rel);
86
- if (!filePath || filePath === getRootDir())
87
+ const filePath = safeWorkspacePath(rootDir, rel);
88
+ if (!filePath || filePath === rootDir)
87
89
  return NextResponse.json({ error: "Invalid path" }, { status: 400 });
88
90
 
89
91
  try {
@@ -0,0 +1,44 @@
1
+ export const runtime = "nodejs";
2
+
3
+ import { NextResponse } from "next/server";
4
+ import { checkOrigin } from "@/lib/auth/csrf";
5
+ import { resolveWorkspaceForUser } from "@/lib/workspace-context";
6
+ import { ensureIndexer, ftsSearch } from "@/lib/search/indexer";
7
+
8
+ const HARD_LIMIT = 200;
9
+
10
+ export async function POST(request: Request) {
11
+ const csrf = checkOrigin(request);
12
+ if (csrf) return csrf;
13
+
14
+ const ctx = await resolveWorkspaceForUser(request);
15
+ if (!ctx.ok) return NextResponse.json({ error: ctx.code }, { status: ctx.status });
16
+
17
+ let body: { query?: unknown; limit?: unknown };
18
+ try {
19
+ body = (await request.json()) as typeof body;
20
+ } catch {
21
+ return NextResponse.json({ error: "INVALID_PAYLOAD" }, { status: 400 });
22
+ }
23
+
24
+ const query = typeof body.query === "string" ? body.query : "";
25
+ const limit = Math.min(
26
+ typeof body.limit === "number" ? body.limit : 30,
27
+ HARD_LIMIT,
28
+ );
29
+
30
+ // Lazy init: fire-and-forget. Returns results from whatever is already indexed;
31
+ // index warms up in background on first call per workspace.
32
+ ensureIndexer(ctx.ws.id, ctx.rootDir).catch((e) =>
33
+ console.error("[search] ensureIndexer failed", e),
34
+ );
35
+
36
+ const result = ftsSearch(ctx.ws.id, query, limit);
37
+
38
+ return NextResponse.json({
39
+ kind: "fts",
40
+ query,
41
+ matches: result.matches,
42
+ truncated: result.truncated,
43
+ });
44
+ }
@@ -1,8 +1,7 @@
1
1
  import { readdir } from "node:fs/promises";
2
2
  import path from "node:path";
3
3
  import { NextResponse } from "next/server";
4
- import { requireUser } from "@/lib/auth/server";
5
- import { getRootDir } from "@/lib/root-dir";
4
+ import { resolveWorkspaceForUser } from "@/lib/workspace-context";
6
5
 
7
6
  type SlugBuckets = {
8
7
  entities: string[];
@@ -28,17 +27,18 @@ async function readMarkdownSlugsFromDir(dirPath: string): Promise<string[]> {
28
27
  }
29
28
 
30
29
  export async function GET(request: Request) {
31
- const auth = await requireUser(request);
32
- if (!auth.ok) return NextResponse.json({ error: "UNAUTHORIZED" }, { status: 401 });
30
+ const ctx = await resolveWorkspaceForUser(request);
31
+ if (!ctx.ok) return NextResponse.json({ error: ctx.code }, { status: ctx.status });
32
+ const { rootDir } = ctx;
33
33
 
34
34
  try {
35
35
  // Scan root + known dirs (entities, concepts, comparisons for wiki compat)
36
36
  // plus any other immediate subdirectories
37
37
  const [entities, concepts, comparisons, root] = await Promise.all([
38
- readMarkdownSlugsFromDir(path.join(getRootDir(), "entities")),
39
- readMarkdownSlugsFromDir(path.join(getRootDir(), "concepts")),
40
- readMarkdownSlugsFromDir(path.join(getRootDir(), "comparisons")),
41
- readMarkdownSlugsFromDir(getRootDir()),
38
+ readMarkdownSlugsFromDir(path.join(rootDir, "entities")),
39
+ readMarkdownSlugsFromDir(path.join(rootDir, "concepts")),
40
+ readMarkdownSlugsFromDir(path.join(rootDir, "comparisons")),
41
+ readMarkdownSlugsFromDir(rootDir),
42
42
  ]);
43
43
 
44
44
  const body: SlugBuckets = { entities, concepts, comparisons, root };
@@ -2,8 +2,8 @@ import { mkdir, writeFile } from "node:fs/promises";
2
2
  import path from "node:path";
3
3
  import { NextResponse } from "next/server";
4
4
  import { checkOrigin } from "@/lib/auth/csrf";
5
- import { requireUser } from "@/lib/auth/server";
6
- import { safeRootPath } from "@/lib/root-dir";
5
+ import { resolveWorkspaceForUser } from "@/lib/workspace-context";
6
+ import { safeWorkspacePath } from "@/lib/workspaces";
7
7
 
8
8
  const ALLOWED_MIME_TYPES = new Set([
9
9
  "application/pdf",
@@ -39,8 +39,9 @@ function sanitizeFilename(name: string): string {
39
39
  export async function POST(request: Request) {
40
40
  const csrf = checkOrigin(request);
41
41
  if (csrf) return csrf;
42
- const auth = await requireUser(request);
43
- if (!auth.ok) return NextResponse.json({ error: "UNAUTHORIZED" }, { status: 401 });
42
+ const ctx = await resolveWorkspaceForUser(request);
43
+ if (!ctx.ok) return NextResponse.json({ error: ctx.code }, { status: ctx.status });
44
+ const { rootDir } = ctx;
44
45
 
45
46
  let formData: FormData;
46
47
  try {
@@ -54,7 +55,7 @@ export async function POST(request: Request) {
54
55
  return NextResponse.json({ error: "No file provided" }, { status: 400 });
55
56
 
56
57
  const dir = (formData.get("dir") as string) ?? "";
57
- const targetDir = safeRootPath(dir);
58
+ const targetDir = safeWorkspacePath(rootDir, dir);
58
59
  if (!targetDir)
59
60
  return NextResponse.json({ error: "Invalid directory" }, { status: 400 });
60
61