wiki-viewer 1.7.2 → 1.8.0

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 (414) hide show
  1. package/.next/standalone/.next/BUILD_ID +1 -1
  2. package/.next/standalone/.next/app-path-routes-manifest.json +6 -0
  3. package/.next/standalone/.next/build-manifest.json +3 -3
  4. package/.next/standalone/.next/prerender-manifest.json +3 -3
  5. package/.next/standalone/.next/routes-manifest.json +40 -0
  6. package/.next/standalone/.next/server/app/_global-error.html +1 -1
  7. package/.next/standalone/.next/server/app/_global-error.rsc +1 -1
  8. package/.next/standalone/.next/server/app/_global-error.segments/__PAGE__.segment.rsc +1 -1
  9. package/.next/standalone/.next/server/app/_global-error.segments/_full.segment.rsc +1 -1
  10. package/.next/standalone/.next/server/app/_global-error.segments/_head.segment.rsc +1 -1
  11. package/.next/standalone/.next/server/app/_global-error.segments/_index.segment.rsc +1 -1
  12. package/.next/standalone/.next/server/app/_global-error.segments/_tree.segment.rsc +1 -1
  13. package/.next/standalone/.next/server/app/_not-found/page_client-reference-manifest.js +1 -1
  14. package/.next/standalone/.next/server/app/_not-found.html +1 -1
  15. package/.next/standalone/.next/server/app/_not-found.rsc +2 -2
  16. package/.next/standalone/.next/server/app/_not-found.segments/_full.segment.rsc +2 -2
  17. package/.next/standalone/.next/server/app/_not-found.segments/_head.segment.rsc +1 -1
  18. package/.next/standalone/.next/server/app/_not-found.segments/_index.segment.rsc +2 -2
  19. package/.next/standalone/.next/server/app/_not-found.segments/_not-found/__PAGE__.segment.rsc +1 -1
  20. package/.next/standalone/.next/server/app/_not-found.segments/_not-found.segment.rsc +1 -1
  21. package/.next/standalone/.next/server/app/_not-found.segments/_tree.segment.rsc +2 -2
  22. package/.next/standalone/.next/server/app/api/agent/activity/route.js +6 -6
  23. package/.next/standalone/.next/server/app/api/agent/activity/route.js.nft.json +1 -1
  24. package/.next/standalone/.next/server/app/api/agent/admin/agents/[agentId]/revoke/route.js +6 -6
  25. package/.next/standalone/.next/server/app/api/agent/admin/agents/[agentId]/revoke/route.js.nft.json +1 -1
  26. package/.next/standalone/.next/server/app/api/agent/admin/agents/route.js +6 -6
  27. package/.next/standalone/.next/server/app/api/agent/admin/agents/route.js.nft.json +1 -1
  28. package/.next/standalone/.next/server/app/api/agent/admin/registrations/[regId]/approve/route.js +7 -7
  29. package/.next/standalone/.next/server/app/api/agent/admin/registrations/[regId]/approve/route.js.nft.json +1 -1
  30. package/.next/standalone/.next/server/app/api/agent/admin/registrations/[regId]/deny/route.js +5 -5
  31. package/.next/standalone/.next/server/app/api/agent/admin/registrations/[regId]/deny/route.js.nft.json +1 -1
  32. package/.next/standalone/.next/server/app/api/agent/admin/registrations/route.js +5 -5
  33. package/.next/standalone/.next/server/app/api/agent/admin/registrations/route.js.nft.json +1 -1
  34. package/.next/standalone/.next/server/app/api/agent/events/[...path]/route.js +8 -7
  35. package/.next/standalone/.next/server/app/api/agent/events/[...path]/route.js.nft.json +1 -1
  36. package/.next/standalone/.next/server/app/api/agent/files/[...path]/route.js +9 -8
  37. package/.next/standalone/.next/server/app/api/agent/files/[...path]/route.js.nft.json +1 -1
  38. package/.next/standalone/.next/server/app/api/agent/fs/file/[...path]/route.js +8 -7
  39. package/.next/standalone/.next/server/app/api/agent/fs/file/[...path]/route.js.nft.json +1 -1
  40. package/.next/standalone/.next/server/app/api/agent/fs/ls/[[...path]]/route.js +7 -7
  41. package/.next/standalone/.next/server/app/api/agent/fs/ls/[[...path]]/route.js.nft.json +1 -1
  42. package/.next/standalone/.next/server/app/api/agent/fs/move/route.js +6 -5
  43. package/.next/standalone/.next/server/app/api/agent/fs/move/route.js.nft.json +1 -1
  44. package/.next/standalone/.next/server/app/api/agent/fs/search/route.js +7 -6
  45. package/.next/standalone/.next/server/app/api/agent/fs/search/route.js.nft.json +1 -1
  46. package/.next/standalone/.next/server/app/api/agent/internal/span/route.js +6 -5
  47. package/.next/standalone/.next/server/app/api/agent/internal/span/route.js.nft.json +1 -1
  48. package/.next/standalone/.next/server/app/api/agent/settings/route.js +7 -7
  49. package/.next/standalone/.next/server/app/api/agent/settings/route.js.nft.json +1 -1
  50. package/.next/standalone/.next/server/app/api/agent/sidecar/[...path]/route.js +8 -7
  51. package/.next/standalone/.next/server/app/api/agent/sidecar/[...path]/route.js.nft.json +1 -1
  52. package/.next/standalone/.next/server/app/api/app-proxy/[...path]/route.js +2 -2
  53. package/.next/standalone/.next/server/app/api/app-proxy/[...path]/route.js.nft.json +1 -1
  54. package/.next/standalone/.next/server/app/api/assets/[...path]/route.js +8 -2
  55. package/.next/standalone/.next/server/app/api/assets/[...path]/route.js.nft.json +1 -1
  56. package/.next/standalone/.next/server/app/api/auth/[...all]/route.js +5 -5
  57. package/.next/standalone/.next/server/app/api/auth/[...all]/route.js.nft.json +1 -1
  58. package/.next/standalone/.next/server/app/api/system/admins/route/app-paths-manifest.json +3 -0
  59. package/.next/standalone/.next/server/app/api/system/admins/route/build-manifest.json +9 -0
  60. package/.next/standalone/.next/server/app/api/system/admins/route/server-reference-manifest.json +4 -0
  61. package/.next/standalone/.next/server/app/api/system/admins/route.js +14 -0
  62. package/.next/standalone/.next/server/app/api/system/admins/route.js.map +5 -0
  63. package/.next/standalone/.next/server/app/api/system/admins/route.js.nft.json +1 -0
  64. package/.next/standalone/.next/server/app/api/system/admins/route_client-reference-manifest.js +3 -0
  65. package/.next/standalone/.next/server/app/api/system/auth-config/route.js +6 -6
  66. package/.next/standalone/.next/server/app/api/system/auth-config/route.js.nft.json +1 -1
  67. package/.next/standalone/.next/server/app/api/system/auth-settings/route.js +4 -4
  68. package/.next/standalone/.next/server/app/api/system/auth-settings/route.js.nft.json +1 -1
  69. package/.next/standalone/.next/server/app/api/system/browse/route.js +4 -4
  70. package/.next/standalone/.next/server/app/api/system/browse/route.js.nft.json +1 -1
  71. package/.next/standalone/.next/server/app/api/system/clear-root/route.js +5 -5
  72. package/.next/standalone/.next/server/app/api/system/clear-root/route.js.nft.json +1 -1
  73. package/.next/standalone/.next/server/app/api/system/config/route.js +6 -6
  74. package/.next/standalone/.next/server/app/api/system/config/route.js.nft.json +1 -1
  75. package/.next/standalone/.next/server/app/api/system/pins/route.js +4 -4
  76. package/.next/standalone/.next/server/app/api/system/pins/route.js.nft.json +1 -1
  77. package/.next/standalone/.next/server/app/api/system/reveal/route.js +6 -6
  78. package/.next/standalone/.next/server/app/api/system/reveal/route.js.nft.json +1 -1
  79. package/.next/standalone/.next/server/app/api/system/root-status/route.js +5 -5
  80. package/.next/standalone/.next/server/app/api/system/root-status/route.js.nft.json +1 -1
  81. package/.next/standalone/.next/server/app/api/system/set-root/route.js +6 -6
  82. package/.next/standalone/.next/server/app/api/system/set-root/route.js.nft.json +1 -1
  83. package/.next/standalone/.next/server/app/api/system/users/route/app-paths-manifest.json +3 -0
  84. package/.next/standalone/.next/server/app/api/system/users/route/build-manifest.json +9 -0
  85. package/.next/standalone/.next/server/app/api/system/users/route/server-reference-manifest.json +4 -0
  86. package/.next/standalone/.next/server/app/api/system/users/route.js +14 -0
  87. package/.next/standalone/.next/server/app/api/system/users/route.js.map +5 -0
  88. package/.next/standalone/.next/server/app/api/system/users/route.js.nft.json +1 -0
  89. package/.next/standalone/.next/server/app/api/system/users/route_client-reference-manifest.js +3 -0
  90. package/.next/standalone/.next/server/app/api/system/workspaces/[id]/open/route/app-paths-manifest.json +3 -0
  91. package/.next/standalone/.next/server/app/api/system/workspaces/[id]/open/route/build-manifest.json +9 -0
  92. package/.next/standalone/.next/server/app/api/system/workspaces/[id]/open/route/server-reference-manifest.json +4 -0
  93. package/.next/standalone/.next/server/app/api/system/workspaces/[id]/open/route.js +14 -0
  94. package/.next/standalone/.next/server/app/api/system/workspaces/[id]/open/route.js.map +5 -0
  95. package/.next/standalone/.next/server/app/api/system/workspaces/[id]/open/route.js.nft.json +1 -0
  96. package/.next/standalone/.next/server/app/api/system/workspaces/[id]/open/route_client-reference-manifest.js +3 -0
  97. package/.next/standalone/.next/server/app/api/system/workspaces/[id]/route/app-paths-manifest.json +3 -0
  98. package/.next/standalone/.next/server/app/api/system/workspaces/[id]/route/build-manifest.json +9 -0
  99. package/.next/standalone/.next/server/app/api/system/workspaces/[id]/route/server-reference-manifest.json +4 -0
  100. package/.next/standalone/.next/server/app/api/system/workspaces/[id]/route.js +14 -0
  101. package/.next/standalone/.next/server/app/api/system/workspaces/[id]/route.js.map +5 -0
  102. package/.next/standalone/.next/server/app/api/system/workspaces/[id]/route.js.nft.json +1 -0
  103. package/.next/standalone/.next/server/app/api/system/workspaces/[id]/route_client-reference-manifest.js +3 -0
  104. package/.next/standalone/.next/server/app/api/system/workspaces/route/app-paths-manifest.json +3 -0
  105. package/.next/standalone/.next/server/app/api/system/workspaces/route/build-manifest.json +9 -0
  106. package/.next/standalone/.next/server/app/api/system/workspaces/route/server-reference-manifest.json +4 -0
  107. package/.next/standalone/.next/server/app/api/system/workspaces/route.js +14 -0
  108. package/.next/standalone/.next/server/app/api/system/workspaces/route.js.map +5 -0
  109. package/.next/standalone/.next/server/app/api/system/workspaces/route.js.nft.json +1 -0
  110. package/.next/standalone/.next/server/app/api/system/workspaces/route_client-reference-manifest.js +3 -0
  111. package/.next/standalone/.next/server/app/api/upload/[...path]/route.js +8 -2
  112. package/.next/standalone/.next/server/app/api/upload/[...path]/route.js.nft.json +1 -1
  113. package/.next/standalone/.next/server/app/api/wiki/app/route.js +5 -5
  114. package/.next/standalone/.next/server/app/api/wiki/app/route.js.nft.json +1 -1
  115. package/.next/standalone/.next/server/app/api/wiki/content/route.js +6 -6
  116. package/.next/standalone/.next/server/app/api/wiki/content/route.js.nft.json +1 -1
  117. package/.next/standalone/.next/server/app/api/wiki/download/route.js +7 -7
  118. package/.next/standalone/.next/server/app/api/wiki/download/route.js.nft.json +1 -1
  119. package/.next/standalone/.next/server/app/api/wiki/file/route.js +8 -2
  120. package/.next/standalone/.next/server/app/api/wiki/file/route.js.nft.json +1 -1
  121. package/.next/standalone/.next/server/app/api/wiki/folder/route.js +6 -6
  122. package/.next/standalone/.next/server/app/api/wiki/folder/route.js.nft.json +1 -1
  123. package/.next/standalone/.next/server/app/api/wiki/move/route.js +6 -6
  124. package/.next/standalone/.next/server/app/api/wiki/move/route.js.nft.json +1 -1
  125. package/.next/standalone/.next/server/app/api/wiki/new-file/route.js +7 -7
  126. package/.next/standalone/.next/server/app/api/wiki/new-file/route.js.nft.json +1 -1
  127. package/.next/standalone/.next/server/app/api/wiki/page/route.js +7 -7
  128. package/.next/standalone/.next/server/app/api/wiki/page/route.js.nft.json +1 -1
  129. package/.next/standalone/.next/server/app/api/wiki/presence/route.js +7 -7
  130. package/.next/standalone/.next/server/app/api/wiki/presence/route.js.nft.json +1 -1
  131. package/.next/standalone/.next/server/app/api/wiki/route.js +6 -6
  132. package/.next/standalone/.next/server/app/api/wiki/route.js.nft.json +1 -1
  133. package/.next/standalone/.next/server/app/api/wiki/search/route/app-paths-manifest.json +3 -0
  134. package/.next/standalone/.next/server/app/api/wiki/search/route/build-manifest.json +9 -0
  135. package/.next/standalone/.next/server/app/api/wiki/search/route/server-reference-manifest.json +4 -0
  136. package/.next/standalone/.next/server/app/api/wiki/search/route.js +15 -0
  137. package/.next/standalone/.next/server/app/api/wiki/search/route.js.map +5 -0
  138. package/.next/standalone/.next/server/app/api/wiki/search/route.js.nft.json +1 -0
  139. package/.next/standalone/.next/server/app/api/wiki/search/route_client-reference-manifest.js +3 -0
  140. package/.next/standalone/.next/server/app/api/wiki/slugs/route.js +6 -6
  141. package/.next/standalone/.next/server/app/api/wiki/slugs/route.js.nft.json +1 -1
  142. package/.next/standalone/.next/server/app/api/wiki/upload/route.js +7 -7
  143. package/.next/standalone/.next/server/app/api/wiki/upload/route.js.nft.json +1 -1
  144. package/.next/standalone/.next/server/app/api/wiki/watch/route.js +7 -9
  145. package/.next/standalone/.next/server/app/api/wiki/watch/route.js.nft.json +1 -1
  146. package/.next/standalone/.next/server/app/index.html +1 -1
  147. package/.next/standalone/.next/server/app/index.rsc +3 -3
  148. package/.next/standalone/.next/server/app/index.segments/__PAGE__.segment.rsc +2 -2
  149. package/.next/standalone/.next/server/app/index.segments/_full.segment.rsc +3 -3
  150. package/.next/standalone/.next/server/app/index.segments/_head.segment.rsc +1 -1
  151. package/.next/standalone/.next/server/app/index.segments/_index.segment.rsc +2 -2
  152. package/.next/standalone/.next/server/app/index.segments/_tree.segment.rsc +2 -2
  153. package/.next/standalone/.next/server/app/page.js.nft.json +1 -1
  154. package/.next/standalone/.next/server/app/page_client-reference-manifest.js +1 -1
  155. package/.next/standalone/.next/server/app/signin/page.js +1 -1
  156. package/.next/standalone/.next/server/app/signin/page.js.nft.json +1 -1
  157. package/.next/standalone/.next/server/app/signin/page_client-reference-manifest.js +1 -1
  158. package/.next/standalone/.next/server/app-paths-manifest.json +6 -0
  159. package/.next/standalone/.next/server/chunks/0p91_next_dist_esm_build_templates_app-route_0d2jbo5.js +1 -1
  160. package/.next/standalone/.next/server/chunks/0p91_next_dist_esm_build_templates_app-route_0ytral2.js +1 -1
  161. package/.next/standalone/.next/server/chunks/[root-of-the-server]__0-244bv._.js +16 -0
  162. package/.next/standalone/.next/server/chunks/{[root-of-the-server]__0xz-_0v._.js → [root-of-the-server]__0-inabx._.js} +2 -2
  163. package/.next/standalone/.next/server/chunks/{[root-of-the-server]__0-ao6a_._.js → [root-of-the-server]__0.-9jt0._.js} +1 -1
  164. package/.next/standalone/.next/server/chunks/{[root-of-the-server]__0~-r-8f._.js → [root-of-the-server]__00c1-dr._.js} +1 -1
  165. package/.next/standalone/.next/server/chunks/[root-of-the-server]__00lep-u._.js +3 -0
  166. package/.next/standalone/.next/server/chunks/[root-of-the-server]__00mtevo._.js +3 -0
  167. package/.next/standalone/.next/server/chunks/[root-of-the-server]__00qu86p._.js +3 -0
  168. package/.next/standalone/.next/server/chunks/[root-of-the-server]__012753j._.js +3 -0
  169. package/.next/standalone/.next/server/chunks/[root-of-the-server]__01hp8ax._.js +3 -0
  170. package/.next/standalone/.next/server/chunks/{[root-of-the-server]__0jhr.ex._.js → [root-of-the-server]__02n6z97._.js} +1 -1
  171. package/.next/standalone/.next/server/chunks/[root-of-the-server]__036mhjp._.js +5 -0
  172. package/.next/standalone/.next/server/chunks/[root-of-the-server]__03p0ob1._.js +16 -0
  173. package/.next/standalone/.next/server/chunks/[root-of-the-server]__05t~v6l._.js +3 -0
  174. package/.next/standalone/.next/server/chunks/[root-of-the-server]__068ni_k._.js +3 -0
  175. package/.next/standalone/.next/server/chunks/{[root-of-the-server]__082nhm6._.js → [root-of-the-server]__07vphbd._.js} +1 -1
  176. package/.next/standalone/.next/server/chunks/{[root-of-the-server]__0pg6dn-._.js → [root-of-the-server]__08lkuwa._.js} +1 -1
  177. package/.next/standalone/.next/server/chunks/[root-of-the-server]__09cqzem._.js +3 -0
  178. package/.next/standalone/.next/server/chunks/{[root-of-the-server]__0p_ox-k._.js → [root-of-the-server]__09k4q9e._.js} +1 -1
  179. package/.next/standalone/.next/server/chunks/[root-of-the-server]__0_0_601._.js +3 -0
  180. package/.next/standalone/.next/server/chunks/[root-of-the-server]__0ae3dk6._.js +3 -0
  181. package/.next/standalone/.next/server/chunks/{[root-of-the-server]__0s28.4-._.js → [root-of-the-server]__0af-x45._.js} +1 -1
  182. package/.next/standalone/.next/server/chunks/[root-of-the-server]__0cqu-wm._.js +3 -0
  183. package/.next/standalone/.next/server/chunks/[root-of-the-server]__0d75a5q._.js +1 -1
  184. package/.next/standalone/.next/server/chunks/[root-of-the-server]__0d7x3e1._.js +3 -0
  185. package/.next/standalone/.next/server/chunks/[root-of-the-server]__0d7zxm_._.js +3 -0
  186. package/.next/standalone/.next/server/chunks/[root-of-the-server]__0e7vs98._.js +3 -0
  187. package/.next/standalone/.next/server/chunks/[root-of-the-server]__0fxzg4v._.js +3 -0
  188. package/.next/standalone/.next/server/chunks/[root-of-the-server]__0gda_iu._.js +3 -0
  189. package/.next/standalone/.next/server/chunks/[root-of-the-server]__0hu~q20._.js +3 -0
  190. package/.next/standalone/.next/server/chunks/[root-of-the-server]__0jk1uf4._.js +3 -0
  191. package/.next/standalone/.next/server/chunks/[root-of-the-server]__0l-8clq._.js +3 -0
  192. package/.next/standalone/.next/server/chunks/[root-of-the-server]__0lhka0x._.js +3 -0
  193. package/.next/standalone/.next/server/chunks/{[root-of-the-server]__0kdn1le._.js → [root-of-the-server]__0na11h0._.js} +2 -2
  194. package/.next/standalone/.next/server/chunks/[root-of-the-server]__0nd.b_c._.js +3 -0
  195. package/.next/standalone/.next/server/chunks/[root-of-the-server]__0otb8ra._.js +3 -0
  196. package/.next/standalone/.next/server/chunks/[root-of-the-server]__0p0-p__._.js +3 -0
  197. package/.next/standalone/.next/server/chunks/[root-of-the-server]__0piofm3._.js +3 -0
  198. package/.next/standalone/.next/server/chunks/[root-of-the-server]__0rrf-jr._.js +3 -0
  199. package/.next/standalone/.next/server/chunks/[root-of-the-server]__0s6_lzw._.js +3 -0
  200. package/.next/standalone/.next/server/chunks/[root-of-the-server]__0sh13v5._.js +3 -0
  201. package/.next/standalone/.next/server/chunks/[root-of-the-server]__0ta~flu._.js +3 -0
  202. package/.next/standalone/.next/server/chunks/[root-of-the-server]__0v4im4p._.js +3 -0
  203. package/.next/standalone/.next/server/chunks/{[root-of-the-server]__0qn8e~s._.js → [root-of-the-server]__0v_kyp-._.js} +1 -1
  204. package/.next/standalone/.next/server/chunks/[root-of-the-server]__0vatqe-._.js +3 -0
  205. package/.next/standalone/.next/server/chunks/[root-of-the-server]__0vdb2nr._.js +3 -0
  206. package/.next/standalone/.next/server/chunks/[root-of-the-server]__0wdh63w._.js +3 -0
  207. package/.next/standalone/.next/server/chunks/[root-of-the-server]__0z3wg9x._.js +12 -0
  208. package/.next/standalone/.next/server/chunks/{[root-of-the-server]__0mzo03s._.js → [root-of-the-server]__0~.-3yk._.js} +1 -1
  209. package/.next/standalone/.next/server/chunks/[root-of-the-server]__123._fe._.js +3 -0
  210. package/.next/standalone/.next/server/chunks/{[root-of-the-server]__12800b1._.js → [root-of-the-server]__12ee_s6._.js} +1 -1
  211. package/.next/standalone/.next/server/chunks/[root-of-the-server]__12onytt._.js +3 -0
  212. package/.next/standalone/.next/server/chunks/{[root-of-the-server]__04udrya._.js → [root-of-the-server]__12q8ch8._.js} +2 -2
  213. package/.next/standalone/.next/server/chunks/[root-of-the-server]__1377.79._.js +3 -0
  214. package/.next/standalone/.next/server/chunks/[root-of-the-server]__1378-ox._.js +3 -0
  215. package/.next/standalone/.next/server/chunks/[root-of-the-server]__13aid91._.js +3 -0
  216. package/.next/standalone/.next/server/chunks/[root-of-the-server]__13hp4tw._.js +12 -0
  217. package/.next/standalone/.next/server/chunks/_079xuln._.js +1 -1
  218. package/.next/standalone/.next/server/chunks/_0dr1r1g._.js +452 -0
  219. package/.next/standalone/.next/server/chunks/_101exke._.js +452 -0
  220. package/.next/standalone/.next/server/chunks/_next-internal_server_app_api_system_admins_route_actions_0dsm7cx.js +3 -0
  221. package/.next/standalone/.next/server/chunks/_next-internal_server_app_api_system_users_route_actions_0whj5cy.js +3 -0
  222. package/.next/standalone/.next/server/chunks/_next-internal_server_app_api_system_workspaces_[id]_open_route_actions_1087xu7.js +3 -0
  223. package/.next/standalone/.next/server/chunks/_next-internal_server_app_api_system_workspaces_[id]_route_actions_0~h7-8s.js +3 -0
  224. package/.next/standalone/.next/server/chunks/_next-internal_server_app_api_system_workspaces_route_actions_0mkalc3.js +3 -0
  225. package/.next/standalone/.next/server/chunks/_next-internal_server_app_api_wiki_search_route_actions_0inxu93.js +3 -0
  226. package/.next/standalone/.next/server/chunks/node_modules__pnpm_0aj5g-w._.js +1 -1
  227. package/.next/standalone/.next/server/chunks/src_lib_search_0d-_j3u._.js +46 -0
  228. package/.next/standalone/.next/server/chunks/src_lib_search_0ymmp0c._.js +46 -0
  229. 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
  230. package/.next/standalone/.next/server/chunks/ssr/12y~_mermaid_dist_chunks_mermaid_core_erDiagram-TEJ5UH35_mjs_0v6rnqy._.js +1 -1
  231. package/.next/standalone/.next/server/chunks/ssr/12y~_mermaid_dist_mermaid_core_mjs_0hj_n-~._.js +1 -1
  232. package/.next/standalone/.next/server/chunks/ssr/{[root-of-the-server]__0btcd4o._.js → [root-of-the-server]__02twzph._.js} +2 -2
  233. package/.next/standalone/.next/server/chunks/ssr/{[root-of-the-server]__0ytvlzs._.js → [root-of-the-server]__09~x2v~._.js} +2 -2
  234. package/.next/standalone/.next/server/chunks/ssr/_0pqaawz._.js +18 -18
  235. package/.next/standalone/.next/server/chunks/ssr/{node_modules__pnpm_0c71i8a._.js → node_modules__pnpm_0.96tmo._.js} +1 -1
  236. package/.next/standalone/.next/server/chunks/ssr/{node_modules__pnpm_0lm8e2c._.js → node_modules__pnpm_011vy_q._.js} +2 -2
  237. package/.next/standalone/.next/server/chunks/ssr/{node_modules__pnpm_0ezm2us._.js → node_modules__pnpm_01o_5qt._.js} +1 -1
  238. package/.next/standalone/.next/server/chunks/ssr/{node_modules__pnpm_0j3mvgg._.js → node_modules__pnpm_04n0h6.._.js} +1 -1
  239. package/.next/standalone/.next/server/chunks/ssr/{node_modules__pnpm_0~ln0by._.js → node_modules__pnpm_093dp2q._.js} +1 -1
  240. package/.next/standalone/.next/server/chunks/ssr/{node_modules__pnpm_11e~j49._.js → node_modules__pnpm_09ej62_._.js} +1 -1
  241. package/.next/standalone/.next/server/chunks/ssr/{node_modules__pnpm_0de8xt-._.js → node_modules__pnpm_09ljbdz._.js} +2 -2
  242. package/.next/standalone/.next/server/chunks/ssr/{node_modules__pnpm_0-x6zex._.js → node_modules__pnpm_09~_ob2._.js} +1 -1
  243. package/.next/standalone/.next/server/chunks/ssr/{node_modules__pnpm_0yq5z.h._.js → node_modules__pnpm_0a01ng7._.js} +2 -2
  244. package/.next/standalone/.next/server/chunks/ssr/{node_modules__pnpm_0kwc-vs._.js → node_modules__pnpm_0b8qx0g._.js} +1 -1
  245. package/.next/standalone/.next/server/chunks/ssr/{node_modules__pnpm_0hrbz84._.js → node_modules__pnpm_0bbc---._.js} +1 -1
  246. package/.next/standalone/.next/server/chunks/ssr/{node_modules__pnpm_0hobcbs._.js → node_modules__pnpm_0c.309.._.js} +1 -1
  247. package/.next/standalone/.next/server/chunks/ssr/{node_modules__pnpm_0rw91-f._.js → node_modules__pnpm_0c8aunj._.js} +1 -1
  248. package/.next/standalone/.next/server/chunks/ssr/{node_modules__pnpm_0o.c1z8._.js → node_modules__pnpm_0hk6xys._.js} +2 -2
  249. package/.next/standalone/.next/server/chunks/ssr/{node_modules__pnpm_0dboa_e._.js → node_modules__pnpm_0hlzy8f._.js} +1 -1
  250. package/.next/standalone/.next/server/chunks/ssr/{node_modules__pnpm_0j53hti._.js → node_modules__pnpm_0nw5ou2._.js} +1 -1
  251. package/.next/standalone/.next/server/chunks/ssr/{node_modules__pnpm_0xrmzh1._.js → node_modules__pnpm_0o.dn8o._.js} +1 -1
  252. package/.next/standalone/.next/server/chunks/ssr/{node_modules__pnpm_0cxwhfd._.js → node_modules__pnpm_0s0ur~d._.js} +1 -1
  253. package/.next/standalone/.next/server/chunks/ssr/{node_modules__pnpm_07rxv2x._.js → node_modules__pnpm_0shlang._.js} +1 -1
  254. package/.next/standalone/.next/server/chunks/ssr/{node_modules__pnpm_0i.pw_m._.js → node_modules__pnpm_0sq3c2r._.js} +1 -1
  255. package/.next/standalone/.next/server/chunks/ssr/{node_modules__pnpm_0ajzar9._.js → node_modules__pnpm_0t9jb7d._.js} +1 -1
  256. package/.next/standalone/.next/server/chunks/ssr/{node_modules__pnpm_012nt.s._.js → node_modules__pnpm_0wmx9kq._.js} +2 -2
  257. package/.next/standalone/.next/server/chunks/ssr/{node_modules__pnpm_0z~h2ow._.js → node_modules__pnpm_0xfx0sf._.js} +1 -1
  258. package/.next/standalone/.next/server/chunks/ssr/{node_modules__pnpm_0cbsnwf._.js → node_modules__pnpm_0yiz.-t._.js} +1 -1
  259. package/.next/standalone/.next/server/chunks/ssr/{node_modules__pnpm_0bum3-3._.js → node_modules__pnpm_11sut1u._.js} +1 -1
  260. package/.next/standalone/.next/server/chunks/ssr/{node_modules__pnpm_0mdo4i3._.js → node_modules__pnpm_124u4o2._.js} +2 -2
  261. package/.next/standalone/.next/server/chunks/ssr/{node_modules__pnpm_0il8j.j._.js → node_modules__pnpm_13tajgx._.js} +2 -2
  262. package/.next/standalone/.next/server/chunks/ssr/src_app_signin_00yk0vm._.js +2 -2
  263. 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
  264. package/.next/standalone/.next/server/edge/chunks/[root-of-the-server]__0.pmgt2._.js +3 -0
  265. package/.next/standalone/.next/server/functions-config-manifest.json +6 -0
  266. package/.next/standalone/.next/server/middleware-build-manifest.js +3 -3
  267. package/.next/standalone/.next/server/middleware-manifest.json +8 -8
  268. package/.next/standalone/.next/server/pages/404.html +1 -1
  269. package/.next/standalone/.next/server/pages/500.html +1 -1
  270. package/.next/standalone/.next/server/server-reference-manifest.js +1 -1
  271. package/.next/standalone/.next/server/server-reference-manifest.json +1 -1
  272. package/.next/standalone/.next/static/chunks/0c_~zevf2n0r4.css +2 -0
  273. package/.next/standalone/.next/static/chunks/0l4842ez-0_66.js +129 -0
  274. package/.next/standalone/README.md +46 -2
  275. package/.next/standalone/docs/workspacing-plan.md +364 -0
  276. package/.next/standalone/package.json +2 -2
  277. package/.next/standalone/src/app/api/agent/activity/route.ts +9 -8
  278. package/.next/standalone/src/app/api/agent/events/[...path]/route.ts +20 -8
  279. package/.next/standalone/src/app/api/agent/files/[...path]/route.ts +16 -9
  280. package/.next/standalone/src/app/api/agent/fs/file/[...path]/route.ts +28 -18
  281. package/.next/standalone/src/app/api/agent/fs/ls/[[...path]]/route.ts +12 -7
  282. package/.next/standalone/src/app/api/agent/fs/move/route.ts +16 -11
  283. package/.next/standalone/src/app/api/agent/fs/search/route.ts +49 -13
  284. package/.next/standalone/src/app/api/agent/internal/span/route.ts +9 -5
  285. package/.next/standalone/src/app/api/agent/register/route.ts +9 -1
  286. package/.next/standalone/src/app/api/agent/settings/route.ts +7 -3
  287. package/.next/standalone/src/app/api/agent/sidecar/[...path]/route.ts +8 -4
  288. package/.next/standalone/src/app/api/assets/[...path]/route.ts +9 -4
  289. package/.next/standalone/src/app/api/system/admins/route.ts +103 -0
  290. package/.next/standalone/src/app/api/system/reveal/route.ts +7 -6
  291. package/.next/standalone/src/app/api/system/set-root/route.ts +24 -1
  292. package/.next/standalone/src/app/api/system/users/route.ts +120 -0
  293. package/.next/standalone/src/app/api/system/workspaces/[id]/open/route.ts +34 -0
  294. package/.next/standalone/src/app/api/system/workspaces/[id]/route.ts +74 -0
  295. package/.next/standalone/src/app/api/system/workspaces/route.ts +67 -0
  296. package/.next/standalone/src/app/api/upload/[...path]/route.ts +10 -5
  297. package/.next/standalone/src/app/api/wiki/app/route.ts +10 -9
  298. package/.next/standalone/src/app/api/wiki/content/route.ts +14 -14
  299. package/.next/standalone/src/app/api/wiki/download/route.ts +7 -6
  300. package/.next/standalone/src/app/api/wiki/file/route.ts +7 -2
  301. package/.next/standalone/src/app/api/wiki/folder/route.ts +6 -5
  302. package/.next/standalone/src/app/api/wiki/move/route.ts +7 -7
  303. package/.next/standalone/src/app/api/wiki/new-file/route.ts +7 -6
  304. package/.next/standalone/src/app/api/wiki/page/route.ts +6 -5
  305. package/.next/standalone/src/app/api/wiki/presence/route.ts +8 -7
  306. package/.next/standalone/src/app/api/wiki/route.ts +13 -11
  307. package/.next/standalone/src/app/api/wiki/search/route.ts +44 -0
  308. package/.next/standalone/src/app/api/wiki/slugs/route.ts +8 -8
  309. package/.next/standalone/src/app/api/wiki/upload/route.ts +6 -5
  310. package/.next/standalone/src/app/api/wiki/watch/route.ts +16 -40
  311. package/.next/standalone/src/app/globals.css +484 -484
  312. package/.next/standalone/src/app/page.tsx +163 -49
  313. package/.next/standalone/src/components/auth-settings-sheet.tsx +171 -2
  314. package/.next/standalone/src/components/dir-picker.tsx +8 -6
  315. package/.next/standalone/src/components/editor/comment-thread.tsx +2 -1
  316. package/.next/standalone/src/components/editor/csv-viewer.tsx +3 -2
  317. package/.next/standalone/src/components/editor/editor-toolbar.tsx +2 -2
  318. package/.next/standalone/src/components/editor/editor.tsx +6 -5
  319. package/.next/standalone/src/components/editor/file-fallback-viewer.tsx +3 -2
  320. package/.next/standalone/src/components/editor/folder-index.tsx +2 -1
  321. package/.next/standalone/src/components/editor/image-viewer.tsx +2 -1
  322. package/.next/standalone/src/components/editor/media-popover.tsx +2 -1
  323. package/.next/standalone/src/components/editor/media-viewer.tsx +2 -1
  324. package/.next/standalone/src/components/editor/mermaid-viewer.tsx +3 -2
  325. package/.next/standalone/src/components/editor/node-app-viewer.tsx +4 -3
  326. package/.next/standalone/src/components/editor/notebook-viewer.tsx +3 -2
  327. package/.next/standalone/src/components/editor/office/docx-viewer.tsx +2 -1
  328. package/.next/standalone/src/components/editor/office/office-chrome.tsx +3 -2
  329. package/.next/standalone/src/components/editor/office/pptx-viewer.tsx +2 -1
  330. package/.next/standalone/src/components/editor/office/xlsx-viewer.tsx +2 -1
  331. package/.next/standalone/src/components/editor/pdf-viewer.tsx +2 -1
  332. package/.next/standalone/src/components/editor/proof-span-popover.tsx +2 -1
  333. package/.next/standalone/src/components/editor/source-viewer.tsx +3 -2
  334. package/.next/standalone/src/components/editor/suggest-edit-popover.tsx +2 -1
  335. package/.next/standalone/src/components/editor/suggestion-card.tsx +2 -1
  336. package/.next/standalone/src/components/editor/website-viewer.tsx +2 -1
  337. package/.next/standalone/src/components/editor/wiki-link-create-dialog.tsx +2 -1
  338. package/.next/standalone/src/components/search/search-command-dialog.tsx +109 -0
  339. package/.next/standalone/src/components/search/sidebar-search-box.tsx +121 -0
  340. package/.next/standalone/src/components/search/snippet-text.tsx +48 -0
  341. package/.next/standalone/src/components/ui/command.tsx +3 -2
  342. package/.next/standalone/src/lib/auth/admin.ts +112 -0
  343. package/.next/standalone/src/lib/auth/server.ts +13 -2
  344. package/.next/standalone/src/lib/config.ts +56 -4
  345. package/.next/standalone/src/lib/proof/audit.ts +19 -10
  346. package/.next/standalone/src/lib/proof/auth.ts +11 -0
  347. package/.next/standalone/src/lib/proof/collab-state.ts +4 -2
  348. package/.next/standalone/src/lib/proof/file-lock.ts +5 -0
  349. package/.next/standalone/src/lib/proof/idempotency.ts +5 -0
  350. package/.next/standalone/src/lib/proof/lease.ts +40 -27
  351. package/.next/standalone/src/lib/proof/mutex.ts +4 -0
  352. package/.next/standalone/src/lib/proof/raw-fs.ts +2 -3
  353. package/.next/standalone/src/lib/proof/registry.ts +5 -0
  354. package/.next/standalone/src/lib/search/indexable-exts.ts +25 -0
  355. package/.next/standalone/src/lib/search/indexer.ts +567 -0
  356. package/.next/standalone/src/lib/search/sanitize.ts +35 -0
  357. package/.next/standalone/src/lib/search/search-db.ts +57 -0
  358. package/.next/standalone/src/lib/search/watcher-pool.ts +79 -0
  359. package/.next/standalone/src/lib/workspace-client.ts +82 -0
  360. package/.next/standalone/src/lib/workspace-context.ts +142 -0
  361. package/.next/standalone/src/lib/workspaces.ts +196 -0
  362. package/.next/standalone/src/stores/ai-panel-store.ts +3 -2
  363. package/.next/standalone/src/stores/editor-store.ts +4 -3
  364. package/.next/standalone/src/stores/proof-store.ts +4 -3
  365. package/.next/standalone/src/stores/search-store.ts +86 -0
  366. package/.next/standalone/src/stores/wiki-slugs-store.ts +2 -1
  367. package/.next/standalone/src/tests/proof/admin-create-user.test.ts +43 -0
  368. package/.next/standalone/src/tests/proof/agent-workspace-scope.test.ts +134 -0
  369. package/.next/standalone/src/tests/proof/collab-state.test.ts +43 -41
  370. package/.next/standalone/src/tests/proof/preload.ts +21 -0
  371. package/.next/standalone/src/tests/proof/search-index.test.ts +339 -0
  372. package/.next/standalone/src/tests/proof/workspace-isolation.test.ts +87 -0
  373. package/.next/standalone/src/tests/proof/workspaces-api.test.ts +227 -0
  374. package/.next/standalone/tsconfig.tsbuildinfo +1 -1
  375. package/README.md +46 -2
  376. package/package.json +2 -2
  377. package/.next/standalone/.next/server/chunks/0p91_next_dist_esm_build_templates_app-route_0o~h4zq.js +0 -5
  378. package/.next/standalone/.next/server/chunks/[root-of-the-server]__0.hb9q2._.js +0 -3
  379. package/.next/standalone/.next/server/chunks/[root-of-the-server]__0.uux34._.js +0 -3
  380. package/.next/standalone/.next/server/chunks/[root-of-the-server]__0092hkp._.js +0 -3
  381. package/.next/standalone/.next/server/chunks/[root-of-the-server]__05f6x0i._.js +0 -3
  382. package/.next/standalone/.next/server/chunks/[root-of-the-server]__05idwm9._.js +0 -3
  383. package/.next/standalone/.next/server/chunks/[root-of-the-server]__06-dtd0._.js +0 -3
  384. package/.next/standalone/.next/server/chunks/[root-of-the-server]__06sek6_._.js +0 -3
  385. package/.next/standalone/.next/server/chunks/[root-of-the-server]__07fpqks._.js +0 -3
  386. package/.next/standalone/.next/server/chunks/[root-of-the-server]__094q5bj._.js +0 -3
  387. package/.next/standalone/.next/server/chunks/[root-of-the-server]__0awzyon._.js +0 -3
  388. package/.next/standalone/.next/server/chunks/[root-of-the-server]__0d_da6q._.js +0 -3
  389. package/.next/standalone/.next/server/chunks/[root-of-the-server]__0hhhvm7._.js +0 -3
  390. package/.next/standalone/.next/server/chunks/[root-of-the-server]__0kk26wc._.js +0 -3
  391. package/.next/standalone/.next/server/chunks/[root-of-the-server]__0km8suj._.js +0 -3
  392. package/.next/standalone/.next/server/chunks/[root-of-the-server]__0kur4ro._.js +0 -15
  393. package/.next/standalone/.next/server/chunks/[root-of-the-server]__0mkwoul._.js +0 -12
  394. package/.next/standalone/.next/server/chunks/[root-of-the-server]__0qc2~6l._.js +0 -15
  395. package/.next/standalone/.next/server/chunks/[root-of-the-server]__0qyd-o8._.js +0 -3
  396. package/.next/standalone/.next/server/chunks/[root-of-the-server]__0rkve~v._.js +0 -3
  397. package/.next/standalone/.next/server/chunks/[root-of-the-server]__0rzo40z._.js +0 -3
  398. package/.next/standalone/.next/server/chunks/[root-of-the-server]__0sjocwy._.js +0 -3
  399. package/.next/standalone/.next/server/chunks/[root-of-the-server]__0ssj9~d._.js +0 -3
  400. package/.next/standalone/.next/server/chunks/[root-of-the-server]__0s~i040._.js +0 -3
  401. package/.next/standalone/.next/server/chunks/[root-of-the-server]__0t220d-._.js +0 -3
  402. package/.next/standalone/.next/server/chunks/[root-of-the-server]__0t5mg.n._.js +0 -3
  403. package/.next/standalone/.next/server/chunks/[root-of-the-server]__0trsqf4._.js +0 -3
  404. package/.next/standalone/.next/server/chunks/[root-of-the-server]__0xq124z._.js +0 -3
  405. package/.next/standalone/.next/server/chunks/[root-of-the-server]__106uw_c._.js +0 -3
  406. package/.next/standalone/.next/server/chunks/[root-of-the-server]__10w2q~o._.js +0 -3
  407. package/.next/standalone/.next/server/chunks/[root-of-the-server]__13w-0iy._.js +0 -3
  408. package/.next/standalone/.next/server/chunks/src_lib_auth_server_ts_00f4e0h._.js +0 -452
  409. package/.next/standalone/.next/server/edge/chunks/[root-of-the-server]__0ug2rvl._.js +0 -3
  410. package/.next/standalone/.next/static/chunks/0vwkqw_rofm-c.js +0 -129
  411. package/.next/standalone/.next/static/chunks/0zay6349~v_wc.css +0 -2
  412. /package/.next/standalone/.next/static/{0XvNCOSEq7cbARTLtAolL → t7B6nXaoD1jo9f61t3aeK}/_buildManifest.js +0 -0
  413. /package/.next/standalone/.next/static/{0XvNCOSEq7cbARTLtAolL → t7B6nXaoD1jo9f61t3aeK}/_clientMiddlewareManifest.js +0 -0
  414. /package/.next/standalone/.next/static/{0XvNCOSEq7cbARTLtAolL → t7B6nXaoD1jo9f61t3aeK}/_ssgManifest.js +0 -0
@@ -0,0 +1,86 @@
1
+ /**
2
+ * Zustand store for full-text search state.
3
+ * Shared between the cmd+k palette and the sidebar search box.
4
+ */
5
+ import { create } from "zustand";
6
+ import { wsFetch } from "@/lib/workspace-client";
7
+
8
+ export interface SearchMatch {
9
+ path: string;
10
+ score: number;
11
+ snippet: string;
12
+ }
13
+
14
+ interface SearchState {
15
+ query: string;
16
+ results: SearchMatch[];
17
+ loading: boolean;
18
+ truncated: boolean;
19
+ open: boolean;
20
+ setQuery: (q: string) => void;
21
+ setOpen: (b: boolean) => void;
22
+ search: (q: string) => Promise<void>;
23
+ clear: () => void;
24
+ }
25
+
26
+ let abortRef: AbortController | null = null;
27
+
28
+ export const useSearchStore = create<SearchState>((set) => ({
29
+ query: "",
30
+ results: [],
31
+ loading: false,
32
+ truncated: false,
33
+ open: false,
34
+
35
+ setQuery: (q) => set({ query: q }),
36
+ setOpen: (b) => set({ open: b }),
37
+
38
+ clear: () => {
39
+ abortRef?.abort();
40
+ set({ query: "", results: [], loading: false, truncated: false });
41
+ },
42
+
43
+ search: async (q) => {
44
+ abortRef?.abort();
45
+ const ctrl = new AbortController();
46
+ abortRef = ctrl;
47
+
48
+ if (!q.trim()) {
49
+ set({ results: [], loading: false, truncated: false });
50
+ return;
51
+ }
52
+
53
+ set({ loading: true });
54
+
55
+ try {
56
+ const r = await wsFetch("/api/wiki/search", {
57
+ method: "POST",
58
+ headers: { "Content-Type": "application/json" },
59
+ body: JSON.stringify({ query: q, limit: 30 }),
60
+ signal: ctrl.signal,
61
+ });
62
+
63
+ if (!r.ok) {
64
+ set({ results: [], loading: false, truncated: false });
65
+ return;
66
+ }
67
+
68
+ const d = (await r.json()) as {
69
+ matches?: SearchMatch[];
70
+ truncated?: boolean;
71
+ };
72
+
73
+ if (ctrl.signal.aborted) return;
74
+
75
+ set({
76
+ results: d.matches ?? [],
77
+ truncated: !!d.truncated,
78
+ loading: false,
79
+ });
80
+ } catch (e) {
81
+ if ((e as Error).name !== "AbortError") {
82
+ set({ loading: false });
83
+ }
84
+ }
85
+ },
86
+ }));
@@ -1,5 +1,6 @@
1
1
  "use client";
2
2
  import { create } from "zustand";
3
+ import { wsFetch } from "@/lib/workspace-client";
3
4
 
4
5
  type Dir = "entities" | "concepts" | "comparisons" | "root";
5
6
 
@@ -36,7 +37,7 @@ export const useWikiSlugsStore = create<WikiSlugsState>((set, get) => ({
36
37
 
37
38
  set({ loading: true });
38
39
  try {
39
- const res = await fetch("/api/wiki/slugs");
40
+ const res = await wsFetch("/api/wiki/slugs");
40
41
  if (!res.ok) throw new Error("Failed to fetch wiki slugs");
41
42
  const buckets = (await res.json()) as SlugBuckets;
42
43
 
@@ -0,0 +1,43 @@
1
+ import { test } from "node:test";
2
+ import assert from "node:assert/strict";
3
+ import { mkdtempSync } from "node:fs";
4
+ import { tmpdir } from "node:os";
5
+ import path from "node:path";
6
+
7
+ test("admin create-user: bypasses allowlist, returns temp password, dup 409, unauth 401", async () => {
8
+ process.env.HOME = mkdtempSync(path.join(tmpdir(), "adduser-"));
9
+ process.env.WIKI_OWNER_HOSTS = "localhost";
10
+ const { writeConfig } = await import("../../lib/config.js");
11
+ const { auth, authReady } = await import("../../lib/auth/server.js");
12
+ await authReady();
13
+ const adminRes = await auth.api.signUpEmail({ body: { email: "admin@x.com", password: "test1234!", name: "Admin" }, asResponse: true });
14
+ const cookie = (adminRes.headers.get("set-cookie") ?? "").split(/,(?=[^ ])/).map(c=>c.split(";")[0].trim()).join("; ");
15
+ const adminBody = await adminRes.json() as any;
16
+ const { ensureBootstrapAdmin } = await import("../../lib/auth/admin.js");
17
+ await ensureBootstrapAdmin(adminBody.user.id);
18
+ // lock allowlist; admin create must bypass
19
+ await writeConfig({ allowedEmails: ["onlythis@allowed.com"] });
20
+ const { POST } = await import("../../app/api/system/users/route.js");
21
+ const req = new Request("http://localhost:3000/api/system/users", {
22
+ method: "POST",
23
+ headers: { "Content-Type": "application/json", Origin: "http://localhost:3000", cookie },
24
+ body: JSON.stringify({ email: "newbie@notallowed.com", name: "New Bie" }),
25
+ });
26
+ const res = await POST(req);
27
+ const out = await res.json() as any;
28
+ assert.equal(res.status, 200);
29
+ assert.ok(out.tempPassword && out.tempPassword.length >= 16, "temp password returned");
30
+ assert.equal(out.email, "newbie@notallowed.com");
31
+ // dup -> 409
32
+ const res2 = await POST(new Request("http://localhost:3000/api/system/users", {
33
+ method: "POST", headers: { "Content-Type": "application/json", Origin: "http://localhost:3000", cookie },
34
+ body: JSON.stringify({ email: "newbie@notallowed.com" }),
35
+ }));
36
+ assert.equal(res2.status, 409);
37
+ // non-admin -> 403 (no cookie)
38
+ const res3 = await POST(new Request("http://localhost:3000/api/system/users", {
39
+ method: "POST", headers: { "Content-Type": "application/json", Origin: "http://localhost:3000" },
40
+ body: JSON.stringify({ email: "x@y.com" }),
41
+ }));
42
+ assert.equal(res3.status, 401);
43
+ });
@@ -0,0 +1,134 @@
1
+ /**
2
+ * Phase C — Agent workspace scoping.
3
+ *
4
+ * Proves an agent whose scope.workspaceId is pinned to one workspace is
5
+ * rejected (403) when a request resolves to a DIFFERENT workspace, and
6
+ * allowed (200) when it matches. An agent with no workspaceId (wildcard)
7
+ * works in any workspace.
8
+ */
9
+ import { test, before, after } from "node:test";
10
+ import assert from "node:assert/strict";
11
+ import { mkdtemp, rm, writeFile, mkdir } from "node:fs/promises";
12
+ import { tmpdir } from "node:os";
13
+ import path from "node:path";
14
+ import { randomBytes } from "node:crypto";
15
+
16
+ import { setRootDir } from "../../lib/root-dir.js";
17
+ import { ensureRegistry, addAgent, hashToken } from "../../lib/proof/registry.js";
18
+ import { writeConfig } from "../../lib/config.js";
19
+ import type { Workspace } from "../../lib/workspaces.js";
20
+
21
+ let tmpHome: string;
22
+ let rootA: string;
23
+ let rootB: string;
24
+ let wsA: Workspace;
25
+ let wsB: Workspace;
26
+
27
+ let fileGET: (req: Request, ctx: { params: Promise<{ path: string[] }> }) => Promise<Response>;
28
+
29
+ const PINNED_TOKEN = randomBytes(32).toString("hex");
30
+ const WILDCARD_TOKEN = randomBytes(32).toString("hex");
31
+
32
+ function headers(token: string, id: string): Record<string, string> {
33
+ return { Authorization: `Bearer ${token}`, "X-Agent-Id": id };
34
+ }
35
+
36
+ function makeCtx(segments: string[]): { params: Promise<{ path: string[] }> } {
37
+ return { params: Promise.resolve({ path: segments }) };
38
+ }
39
+
40
+ before(async () => {
41
+ tmpHome = await mkdtemp(path.join(tmpdir(), "ws-scope-home-"));
42
+ rootA = await mkdtemp(path.join(tmpdir(), "ws-scope-A-"));
43
+ rootB = await mkdtemp(path.join(tmpdir(), "ws-scope-B-"));
44
+ process.env.HOME = tmpHome;
45
+ setRootDir(rootA); // fallback (unused once registry has workspaces)
46
+
47
+ wsA = {
48
+ id: "ws_AAAAAA",
49
+ name: "A",
50
+ rootDir: rootA,
51
+ createdAt: new Date().toISOString(),
52
+ lastOpenedAt: new Date().toISOString(),
53
+ };
54
+ wsB = {
55
+ id: "ws_BBBBBB",
56
+ name: "B",
57
+ rootDir: rootB,
58
+ createdAt: new Date().toISOString(),
59
+ lastOpenedAt: new Date().toISOString(),
60
+ };
61
+ // Seed registry so resolveWorkspaceForAgent picks by ?ws= instead of fallback.
62
+ await writeConfig({ workspaces: [wsA, wsB] });
63
+
64
+ await ensureRegistry();
65
+ await addAgent({
66
+ id: "ai:pinned",
67
+ displayName: "Pinned to A",
68
+ tokenHash: hashToken(PINNED_TOKEN),
69
+ scope: { paths: ["**/*"], ops: ["read", "mutate"], workspaceId: wsA.id },
70
+ createdAt: new Date().toISOString(),
71
+ lastSeen: new Date().toISOString(),
72
+ });
73
+ await addAgent({
74
+ id: "ai:wildcard",
75
+ displayName: "Wildcard",
76
+ tokenHash: hashToken(WILDCARD_TOKEN),
77
+ scope: { paths: ["**/*"], ops: ["read", "mutate"] }, // no workspaceId
78
+ createdAt: new Date().toISOString(),
79
+ lastSeen: new Date().toISOString(),
80
+ });
81
+
82
+ await writeFile(path.join(rootA, "a.txt"), "in A");
83
+ await writeFile(path.join(rootB, "b.txt"), "in B");
84
+
85
+ const fileRoute = await import("../../app/api/agent/fs/file/[...path]/route.js");
86
+ fileGET = fileRoute.GET;
87
+ });
88
+
89
+ async function rmQuiet(p: string): Promise<void> {
90
+ // File-lock sentinels may be written concurrently during teardown → retry.
91
+ for (let i = 0; i < 3; i++) {
92
+ try {
93
+ await rm(p, { recursive: true, force: true });
94
+ return;
95
+ } catch {
96
+ await new Promise((r) => setTimeout(r, 50));
97
+ }
98
+ }
99
+ }
100
+
101
+ after(async () => {
102
+ await rmQuiet(tmpHome);
103
+ await rmQuiet(rootA);
104
+ await rmQuiet(rootB);
105
+ });
106
+
107
+ test("pinned agent: 200 in its own workspace", async () => {
108
+ const req = new Request(`http://localhost/api/agent/fs/file/a.txt?ws=${wsA.id}`, {
109
+ headers: headers(PINNED_TOKEN, "ai:pinned"),
110
+ });
111
+ const res = await fileGET(req, makeCtx(["a.txt"]));
112
+ assert.equal(res.status, 200);
113
+ assert.equal(await res.text(), "in A");
114
+ });
115
+
116
+ test("pinned agent: 403 when request resolves to a different workspace", async () => {
117
+ const req = new Request(`http://localhost/api/agent/fs/file/b.txt?ws=${wsB.id}`, {
118
+ headers: headers(PINNED_TOKEN, "ai:pinned"),
119
+ });
120
+ const res = await fileGET(req, makeCtx(["b.txt"]));
121
+ assert.equal(res.status, 403);
122
+ });
123
+
124
+ test("wildcard agent: 200 in either workspace", async () => {
125
+ const reqA = new Request(`http://localhost/api/agent/fs/file/a.txt?ws=${wsA.id}`, {
126
+ headers: headers(WILDCARD_TOKEN, "ai:wildcard"),
127
+ });
128
+ assert.equal((await fileGET(reqA, makeCtx(["a.txt"]))).status, 200);
129
+
130
+ const reqB = new Request(`http://localhost/api/agent/fs/file/b.txt?ws=${wsB.id}`, {
131
+ headers: headers(WILDCARD_TOKEN, "ai:wildcard"),
132
+ });
133
+ assert.equal((await fileGET(reqB, makeCtx(["b.txt"]))).status, 200);
134
+ });
@@ -98,66 +98,68 @@ after(async () => {
98
98
 
99
99
  // ── Lease store unit tests ────────────────────────────────────────────────────
100
100
 
101
+ const TEST_NS = "/test-ns";
102
+
101
103
  describe("lease store", () => {
102
104
  before(() => _resetLeaseStore());
103
105
  after(() => _resetLeaseStore());
104
106
 
105
107
  test("new path has generation 0, no active lease", () => {
106
108
  _resetLeaseStore();
107
- assert.equal(leaseGeneration("docs/a.md"), 0);
108
- assert.equal(hasActiveLease("docs/a.md"), false);
109
+ assert.equal(leaseGeneration(TEST_NS, "docs/a.md"), 0);
110
+ assert.equal(hasActiveLease(TEST_NS, "docs/a.md"), false);
109
111
  });
110
112
 
111
113
  test("setLease makes lease active, bumps generation 0→1", () => {
112
114
  _resetLeaseStore();
113
- setLease("docs/a.md", "u1");
114
- assert.equal(hasActiveLease("docs/a.md"), true);
115
- assert.equal(leaseGeneration("docs/a.md"), 1);
115
+ setLease(TEST_NS, "docs/a.md", "u1");
116
+ assert.equal(hasActiveLease(TEST_NS, "docs/a.md"), true);
117
+ assert.equal(leaseGeneration(TEST_NS, "docs/a.md"), 1);
116
118
  });
117
119
 
118
120
  test("second setLease (heartbeat) does NOT bump generation again", () => {
119
121
  _resetLeaseStore();
120
- setLease("docs/a.md", "u1");
121
- const gen = leaseGeneration("docs/a.md");
122
- setLease("docs/a.md", "u1"); // heartbeat
123
- assert.equal(leaseGeneration("docs/a.md"), gen); // unchanged
122
+ setLease(TEST_NS, "docs/a.md", "u1");
123
+ const gen = leaseGeneration(TEST_NS, "docs/a.md");
124
+ setLease(TEST_NS, "docs/a.md", "u1"); // heartbeat
125
+ assert.equal(leaseGeneration(TEST_NS, "docs/a.md"), gen); // unchanged
124
126
  });
125
127
 
126
128
  test("clearLease removes active lease and bumps generation 1→2", () => {
127
129
  _resetLeaseStore();
128
- setLease("docs/a.md", "u1");
129
- assert.equal(leaseGeneration("docs/a.md"), 1);
130
- clearLease("docs/a.md", "u1");
131
- assert.equal(hasActiveLease("docs/a.md"), false);
132
- assert.equal(leaseGeneration("docs/a.md"), 2);
130
+ setLease(TEST_NS, "docs/a.md", "u1");
131
+ assert.equal(leaseGeneration(TEST_NS, "docs/a.md"), 1);
132
+ clearLease(TEST_NS, "docs/a.md", "u1");
133
+ assert.equal(hasActiveLease(TEST_NS, "docs/a.md"), false);
134
+ assert.equal(leaseGeneration(TEST_NS, "docs/a.md"), 2);
133
135
  });
134
136
 
135
137
  test("clearLease by different user is no-op", () => {
136
138
  _resetLeaseStore();
137
- setLease("docs/a.md", "u1");
138
- clearLease("docs/a.md", "u-other");
139
- assert.equal(hasActiveLease("docs/a.md"), true);
140
- assert.equal(leaseGeneration("docs/a.md"), 1);
139
+ setLease(TEST_NS, "docs/a.md", "u1");
140
+ clearLease(TEST_NS, "docs/a.md", "u-other");
141
+ assert.equal(hasActiveLease(TEST_NS, "docs/a.md"), true);
142
+ assert.equal(leaseGeneration(TEST_NS, "docs/a.md"), 1);
141
143
  });
142
144
 
143
145
  test("expired lease (via short TTL) returns false and bumps generation", async () => {
144
146
  _resetLeaseStore();
145
- setLease("docs/expire.md", "u1", 10); // 10ms TTL
146
- assert.equal(hasActiveLease("docs/expire.md"), true);
147
+ setLease(TEST_NS, "docs/expire.md", "u1", 10); // 10ms TTL
148
+ assert.equal(hasActiveLease(TEST_NS, "docs/expire.md"), true);
147
149
  await new Promise((r) => setTimeout(r, 20));
148
- assert.equal(hasActiveLease("docs/expire.md"), false);
150
+ assert.equal(hasActiveLease(TEST_NS, "docs/expire.md"), false);
149
151
  // generation bumped on expiry check
150
- assert.ok(leaseGeneration("docs/expire.md") >= 2);
152
+ assert.ok(leaseGeneration(TEST_NS, "docs/expire.md") >= 2);
151
153
  });
152
154
 
153
155
  test("set after expiry = new 0→1 transition, bumps again", async () => {
154
156
  _resetLeaseStore();
155
- setLease("docs/exp2.md", "u1", 10);
157
+ setLease(TEST_NS, "docs/exp2.md", "u1", 10);
156
158
  await new Promise((r) => setTimeout(r, 20));
157
- hasActiveLease("docs/exp2.md"); // triggers sweep
158
- const genAfterExpiry = leaseGeneration("docs/exp2.md");
159
- setLease("docs/exp2.md", "u1"); // fresh open
160
- assert.equal(leaseGeneration("docs/exp2.md"), genAfterExpiry + 1);
159
+ hasActiveLease(TEST_NS, "docs/exp2.md"); // triggers sweep
160
+ const genAfterExpiry = leaseGeneration(TEST_NS, "docs/exp2.md");
161
+ setLease(TEST_NS, "docs/exp2.md", "u1"); // fresh open
162
+ assert.equal(leaseGeneration(TEST_NS, "docs/exp2.md"), genAfterExpiry + 1);
161
163
  });
162
164
  });
163
165
 
@@ -252,11 +254,11 @@ describe("computeCollabState", () => {
252
254
  const mdPath = "lease-only.md";
253
255
  await writeFile(path.join(tmpRoot, mdPath), "# lease only");
254
256
  // No sidecar; human opens it
255
- setLease(mdPath, "human-user-1");
257
+ setLease(tmpRoot, mdPath, "human-user-1");
256
258
  const result = await computeCollabState(tmpRoot, mdPath);
257
259
  assert.equal(result.state, "active");
258
260
  assert.equal(result.revision, 1); // 0 + gen(1)
259
- clearLease(mdPath, "human-user-1");
261
+ clearLease(tmpRoot, mdPath, "human-user-1");
260
262
  });
261
263
 
262
264
  test("revision = sidecar.revision + leaseGeneration", async () => {
@@ -269,10 +271,10 @@ describe("computeCollabState", () => {
269
271
  const r1 = await computeCollabState(tmpRoot, mdPath);
270
272
  assert.equal(r1.revision, 7);
271
273
  // open lease: gen=1, revision=8
272
- setLease(mdPath, "u1");
274
+ setLease(tmpRoot, mdPath, "u1");
273
275
  const r2 = await computeCollabState(tmpRoot, mdPath);
274
276
  assert.equal(r2.revision, 8);
275
- clearLease(mdPath, "u1");
277
+ clearLease(tmpRoot, mdPath, "u1");
276
278
  });
277
279
 
278
280
  test("stale pending suggestion does NOT count as active artifact", async () => {
@@ -332,14 +334,14 @@ describe("X-Collab headers on GET fs/file", () => {
332
334
  _resetLeaseStore();
333
335
  const mdPath = "hdr-active.md";
334
336
  await writeFile(path.join(tmpRoot, mdPath), "# active");
335
- setLease(mdPath, "human-1");
337
+ setLease(tmpRoot, mdPath, "human-1");
336
338
  const req = new Request(fileUrl(mdPath), {
337
339
  headers: agentHeaders(READ_TOKEN, "ai:reader"),
338
340
  });
339
341
  const res = await fileGET(req, makeCtx([mdPath]));
340
342
  assert.equal(res.status, 200);
341
343
  assert.equal(res.headers.get("x-collab-state"), "active");
342
- clearLease(mdPath, "human-1");
344
+ clearLease(tmpRoot, mdPath, "human-1");
343
345
  });
344
346
  });
345
347
 
@@ -367,13 +369,13 @@ describe("X-Collab headers on Tier-2 GET agent/files", () => {
367
369
  _resetLeaseStore();
368
370
  const mdPath = "tier2-active.md";
369
371
  await writeFile(path.join(tmpRoot, mdPath), "# active");
370
- setLease(mdPath, "h1");
372
+ setLease(tmpRoot, mdPath, "h1");
371
373
  const req = new Request(tier2Url(mdPath), {
372
374
  headers: agentHeaders(READ_TOKEN, "ai:reader"),
373
375
  });
374
376
  const res = await tier2GET(req, makeCtx([mdPath]));
375
377
  assert.equal(res.headers.get("x-collab-state"), "active");
376
- clearLease(mdPath, "h1");
378
+ clearLease(tmpRoot, mdPath, "h1");
377
379
  });
378
380
  });
379
381
 
@@ -409,7 +411,7 @@ describe("R6 TOCTOU enforcement on raw .md PUT", () => {
409
411
  const oldSha = sha256hex(Buffer.from(initial));
410
412
 
411
413
  // Simulate: agent read the file, then human opens it (lease set)
412
- setLease(mdPath, "human-racer");
414
+ setLease(tmpRoot, mdPath, "human-racer");
413
415
 
414
416
  // Agent tries raw PUT without If-Collab-Match
415
417
  const req = new Request(fileUrl(mdPath), {
@@ -427,7 +429,7 @@ describe("R6 TOCTOU enforcement on raw .md PUT", () => {
427
429
  assert.ok(body.snapshotUrl, "snapshotUrl in response");
428
430
  assert.ok(typeof body.revision === "number", "revision in response");
429
431
 
430
- clearLease(mdPath, "human-racer");
432
+ clearLease(tmpRoot, mdPath, "human-racer");
431
433
  });
432
434
 
433
435
  test("PUT .md with matching If-Collab-Match → 200", async () => {
@@ -437,7 +439,7 @@ describe("R6 TOCTOU enforcement on raw .md PUT", () => {
437
439
  await writeFile(path.join(tmpRoot, mdPath), initial);
438
440
  const oldSha = sha256hex(Buffer.from(initial));
439
441
 
440
- setLease(mdPath, "human-match");
442
+ setLease(tmpRoot, mdPath, "human-match");
441
443
  // Get the current revision
442
444
  const { revision } = await computeCollabState(tmpRoot, mdPath);
443
445
 
@@ -453,7 +455,7 @@ describe("R6 TOCTOU enforcement on raw .md PUT", () => {
453
455
  const res = await filePUT(req, makeCtx([mdPath]));
454
456
  assert.equal(res.status, 200, "matching If-Collab-Match should allow write");
455
457
 
456
- clearLease(mdPath, "human-match");
458
+ clearLease(tmpRoot, mdPath, "human-match");
457
459
  });
458
460
 
459
461
  test("PUT .md with ?force=true bypasses R6 even on active doc → 200", async () => {
@@ -463,7 +465,7 @@ describe("R6 TOCTOU enforcement on raw .md PUT", () => {
463
465
  await writeFile(path.join(tmpRoot, mdPath), initial);
464
466
  const oldSha = sha256hex(Buffer.from(initial));
465
467
 
466
- setLease(mdPath, "human-force");
468
+ setLease(tmpRoot, mdPath, "human-force");
467
469
 
468
470
  const req = new Request(fileUrl(mdPath, "?force=true"), {
469
471
  method: "PUT",
@@ -476,7 +478,7 @@ describe("R6 TOCTOU enforcement on raw .md PUT", () => {
476
478
  const res = await filePUT(req, makeCtx([mdPath]));
477
479
  assert.equal(res.status, 200, "?force=true should bypass R6");
478
480
 
479
- clearLease(mdPath, "human-force");
481
+ clearLease(tmpRoot, mdPath, "human-force");
480
482
  });
481
483
 
482
484
  test("PUT non-.md file is never blocked by R6 (no collab state)", async () => {
@@ -0,0 +1,21 @@
1
+ /**
2
+ * Test preload — runs before any test module is imported (via `tsx --import`).
3
+ *
4
+ * auth/server.ts resolves the SQLite DB path from $HOME at module-load time.
5
+ * Several test files import route handlers (and thus auth/server) at the top of
6
+ * the file, before their before() hook can override HOME. Without this preload
7
+ * those imports freeze the DB path to the real ~/.wiki-viewer/auth.db and the
8
+ * suite writes thousands of @test.local users into it.
9
+ *
10
+ * Forcing HOME to a throwaway tmp dir here, before anything else loads,
11
+ * guarantees every test run is isolated from the developer's real config.
12
+ */
13
+ import { mkdtempSync } from "node:fs";
14
+ import { tmpdir } from "node:os";
15
+ import path from "node:path";
16
+
17
+ if (!process.env.WIKI_TEST_HOME) {
18
+ const home = mkdtempSync(path.join(tmpdir(), "wiki-test-home-"));
19
+ process.env.HOME = home;
20
+ process.env.WIKI_TEST_HOME = home;
21
+ }