wiki-viewer 1.14.1 → 2.0.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 (559) hide show
  1. package/.next/standalone/.next/BUILD_ID +1 -1
  2. package/.next/standalone/.next/build-manifest.json +3 -3
  3. package/.next/standalone/.next/server/app/_global-error.html +1 -1
  4. package/.next/standalone/.next/server/app/_global-error.rsc +1 -1
  5. package/.next/standalone/.next/server/app/_global-error.segments/__PAGE__.segment.rsc +1 -1
  6. package/.next/standalone/.next/server/app/_global-error.segments/_full.segment.rsc +1 -1
  7. package/.next/standalone/.next/server/app/_global-error.segments/_head.segment.rsc +1 -1
  8. package/.next/standalone/.next/server/app/_global-error.segments/_index.segment.rsc +1 -1
  9. package/.next/standalone/.next/server/app/_global-error.segments/_tree.segment.rsc +1 -1
  10. package/.next/standalone/.next/server/app/_not-found/page_client-reference-manifest.js +1 -1
  11. package/.next/standalone/.next/server/app/_not-found.html +1 -1
  12. package/.next/standalone/.next/server/app/_not-found.rsc +2 -2
  13. package/.next/standalone/.next/server/app/_not-found.segments/_full.segment.rsc +2 -2
  14. package/.next/standalone/.next/server/app/_not-found.segments/_head.segment.rsc +1 -1
  15. package/.next/standalone/.next/server/app/_not-found.segments/_index.segment.rsc +2 -2
  16. package/.next/standalone/.next/server/app/_not-found.segments/_not-found/__PAGE__.segment.rsc +1 -1
  17. package/.next/standalone/.next/server/app/_not-found.segments/_not-found.segment.rsc +1 -1
  18. package/.next/standalone/.next/server/app/_not-found.segments/_tree.segment.rsc +2 -2
  19. package/.next/standalone/.next/server/app/api/agent/activity/route.js +6 -6
  20. package/.next/standalone/.next/server/app/api/agent/activity/route.js.nft.json +1 -1
  21. package/.next/standalone/.next/server/app/api/agent/events/[...path]/route.js +8 -8
  22. package/.next/standalone/.next/server/app/api/agent/events/[...path]/route.js.nft.json +1 -1
  23. package/.next/standalone/.next/server/app/api/agent/files/[...path]/route.js +9 -9
  24. package/.next/standalone/.next/server/app/api/agent/files/[...path]/route.js.nft.json +1 -1
  25. package/.next/standalone/.next/server/app/api/agent/fs/file/[...path]/route.js +8 -8
  26. package/.next/standalone/.next/server/app/api/agent/fs/file/[...path]/route.js.nft.json +1 -1
  27. package/.next/standalone/.next/server/app/api/agent/fs/ls/[[...path]]/route.js +8 -8
  28. package/.next/standalone/.next/server/app/api/agent/fs/ls/[[...path]]/route.js.nft.json +1 -1
  29. package/.next/standalone/.next/server/app/api/agent/fs/move/route.js +8 -8
  30. package/.next/standalone/.next/server/app/api/agent/fs/move/route.js.nft.json +1 -1
  31. package/.next/standalone/.next/server/app/api/agent/fs/search/route.js +9 -9
  32. package/.next/standalone/.next/server/app/api/agent/fs/search/route.js.nft.json +1 -1
  33. package/.next/standalone/.next/server/app/api/agent/internal/span/route.js +8 -8
  34. package/.next/standalone/.next/server/app/api/agent/internal/span/route.js.nft.json +1 -1
  35. package/.next/standalone/.next/server/app/api/agent/settings/route.js +7 -7
  36. package/.next/standalone/.next/server/app/api/agent/settings/route.js.nft.json +1 -1
  37. package/.next/standalone/.next/server/app/api/agent/sidecar/[...path]/route.js +6 -6
  38. package/.next/standalone/.next/server/app/api/agent/sidecar/[...path]/route.js.nft.json +1 -1
  39. package/.next/standalone/.next/server/app/api/app-proxy/[...path]/route.js.nft.json +1 -1
  40. package/.next/standalone/.next/server/app/api/assets/[...path]/route.js +5 -5
  41. package/.next/standalone/.next/server/app/api/assets/[...path]/route.js.nft.json +1 -1
  42. package/.next/standalone/.next/server/app/api/share/[token]/route.js +6 -5
  43. package/.next/standalone/.next/server/app/api/share/[token]/route.js.nft.json +1 -1
  44. package/.next/standalone/.next/server/app/api/share/route.js +4 -4
  45. package/.next/standalone/.next/server/app/api/share/route.js.nft.json +1 -1
  46. package/.next/standalone/.next/server/app/api/system/browse/route.js.nft.json +1 -1
  47. package/.next/standalone/.next/server/app/api/system/clear-root/route.js.nft.json +1 -1
  48. package/.next/standalone/.next/server/app/api/system/reveal/route.js +6 -6
  49. package/.next/standalone/.next/server/app/api/system/reveal/route.js.nft.json +1 -1
  50. package/.next/standalone/.next/server/app/api/system/root-status/route.js.nft.json +1 -1
  51. package/.next/standalone/.next/server/app/api/system/set-root/route.js +6 -5
  52. package/.next/standalone/.next/server/app/api/system/set-root/route.js.nft.json +1 -1
  53. package/.next/standalone/.next/server/app/api/system/workspaces/[id]/open/route.js +5 -4
  54. package/.next/standalone/.next/server/app/api/system/workspaces/[id]/open/route.js.nft.json +1 -1
  55. package/.next/standalone/.next/server/app/api/system/workspaces/[id]/refresh/route.js +6 -5
  56. package/.next/standalone/.next/server/app/api/system/workspaces/[id]/refresh/route.js.nft.json +1 -1
  57. package/.next/standalone/.next/server/app/api/system/workspaces/[id]/route.js +5 -4
  58. package/.next/standalone/.next/server/app/api/system/workspaces/[id]/route.js.nft.json +1 -1
  59. package/.next/standalone/.next/server/app/api/system/workspaces/route.js +7 -6
  60. package/.next/standalone/.next/server/app/api/system/workspaces/route.js.nft.json +1 -1
  61. package/.next/standalone/.next/server/app/api/upload/[...path]/route.js +5 -5
  62. package/.next/standalone/.next/server/app/api/upload/[...path]/route.js.nft.json +1 -1
  63. package/.next/standalone/.next/server/app/api/wiki/app/route.js +7 -7
  64. package/.next/standalone/.next/server/app/api/wiki/app/route.js.nft.json +1 -1
  65. package/.next/standalone/.next/server/app/api/wiki/backlinks/route.js +7 -7
  66. package/.next/standalone/.next/server/app/api/wiki/backlinks/route.js.nft.json +1 -1
  67. package/.next/standalone/.next/server/app/api/wiki/content/route.js +7 -7
  68. package/.next/standalone/.next/server/app/api/wiki/content/route.js.nft.json +1 -1
  69. package/.next/standalone/.next/server/app/api/wiki/download/route.js +6 -6
  70. package/.next/standalone/.next/server/app/api/wiki/download/route.js.nft.json +1 -1
  71. package/.next/standalone/.next/server/app/api/wiki/file/route.js +5 -5
  72. package/.next/standalone/.next/server/app/api/wiki/file/route.js.nft.json +1 -1
  73. package/.next/standalone/.next/server/app/api/wiki/folder/route.js +5 -5
  74. package/.next/standalone/.next/server/app/api/wiki/folder/route.js.nft.json +1 -1
  75. package/.next/standalone/.next/server/app/api/wiki/git-branches/route.js +4 -4
  76. package/.next/standalone/.next/server/app/api/wiki/git-branches/route.js.nft.json +1 -1
  77. package/.next/standalone/.next/server/app/api/wiki/git-checkout/route.js +6 -6
  78. package/.next/standalone/.next/server/app/api/wiki/git-checkout/route.js.nft.json +1 -1
  79. package/.next/standalone/.next/server/app/api/wiki/git-diff/route.js +4 -4
  80. package/.next/standalone/.next/server/app/api/wiki/git-diff/route.js.nft.json +1 -1
  81. package/.next/standalone/.next/server/app/api/wiki/git-file-info/route.js +4 -4
  82. package/.next/standalone/.next/server/app/api/wiki/git-file-info/route.js.nft.json +1 -1
  83. package/.next/standalone/.next/server/app/api/wiki/git-history/route.js +4 -4
  84. package/.next/standalone/.next/server/app/api/wiki/git-history/route.js.nft.json +1 -1
  85. package/.next/standalone/.next/server/app/api/wiki/git-pull/route.js +8 -8
  86. package/.next/standalone/.next/server/app/api/wiki/git-pull/route.js.nft.json +1 -1
  87. package/.next/standalone/.next/server/app/api/wiki/move/route.js +6 -6
  88. package/.next/standalone/.next/server/app/api/wiki/move/route.js.nft.json +1 -1
  89. package/.next/standalone/.next/server/app/api/wiki/new-file/route.js +5 -5
  90. package/.next/standalone/.next/server/app/api/wiki/new-file/route.js.nft.json +1 -1
  91. package/.next/standalone/.next/server/app/api/wiki/outlinks/route.js +7 -7
  92. package/.next/standalone/.next/server/app/api/wiki/outlinks/route.js.nft.json +1 -1
  93. package/.next/standalone/.next/server/app/api/wiki/page/route.js +5 -5
  94. package/.next/standalone/.next/server/app/api/wiki/page/route.js.nft.json +1 -1
  95. package/.next/standalone/.next/server/app/api/wiki/presence/route.js +6 -6
  96. package/.next/standalone/.next/server/app/api/wiki/presence/route.js.nft.json +1 -1
  97. package/.next/standalone/.next/server/app/api/wiki/route.js +5 -5
  98. package/.next/standalone/.next/server/app/api/wiki/route.js.nft.json +1 -1
  99. package/.next/standalone/.next/server/app/api/wiki/search/route.js +5 -5
  100. package/.next/standalone/.next/server/app/api/wiki/search/route.js.nft.json +1 -1
  101. package/.next/standalone/.next/server/app/api/wiki/slugs/route.js +5 -5
  102. package/.next/standalone/.next/server/app/api/wiki/slugs/route.js.nft.json +1 -1
  103. package/.next/standalone/.next/server/app/api/wiki/upload/route.js +5 -5
  104. package/.next/standalone/.next/server/app/api/wiki/upload/route.js.nft.json +1 -1
  105. package/.next/standalone/.next/server/app/api/wiki/watch/route.js +5 -5
  106. package/.next/standalone/.next/server/app/api/wiki/watch/route.js.nft.json +1 -1
  107. package/.next/standalone/.next/server/app/index.html +1 -1
  108. package/.next/standalone/.next/server/app/index.rsc +3 -3
  109. package/.next/standalone/.next/server/app/index.segments/__PAGE__.segment.rsc +2 -2
  110. package/.next/standalone/.next/server/app/index.segments/_full.segment.rsc +3 -3
  111. package/.next/standalone/.next/server/app/index.segments/_head.segment.rsc +1 -1
  112. package/.next/standalone/.next/server/app/index.segments/_index.segment.rsc +2 -2
  113. package/.next/standalone/.next/server/app/index.segments/_tree.segment.rsc +2 -2
  114. package/.next/standalone/.next/server/app/page.js.nft.json +1 -1
  115. package/.next/standalone/.next/server/app/page_client-reference-manifest.js +1 -1
  116. package/.next/standalone/.next/server/app/s/[token]/page_client-reference-manifest.js +1 -1
  117. package/.next/standalone/.next/server/app/signin/page_client-reference-manifest.js +1 -1
  118. package/.next/standalone/.next/server/chunks/[root-of-the-server]__0-jzw2_._.js +3 -0
  119. package/.next/standalone/.next/server/chunks/[root-of-the-server]__0.-oq-7._.js +3 -0
  120. package/.next/standalone/.next/server/chunks/[root-of-the-server]__000spch._.js +3 -0
  121. package/.next/standalone/.next/server/chunks/[root-of-the-server]__01oin-a._.js +3 -0
  122. package/.next/standalone/.next/server/chunks/[root-of-the-server]__01qcera._.js +16 -0
  123. package/.next/standalone/.next/server/chunks/[root-of-the-server]__02.uul~._.js +3 -0
  124. package/.next/standalone/.next/server/chunks/[root-of-the-server]__024967n._.js +3 -0
  125. package/.next/standalone/.next/server/chunks/[root-of-the-server]__06booxp._.js +3 -0
  126. package/.next/standalone/.next/server/chunks/[root-of-the-server]__071_pmz._.js +3 -0
  127. package/.next/standalone/.next/server/chunks/[root-of-the-server]__0_0bqpg._.js +3 -0
  128. package/.next/standalone/.next/server/chunks/[root-of-the-server]__0_1f2cw._.js +3 -0
  129. package/.next/standalone/.next/server/chunks/[root-of-the-server]__0a6j6r4._.js +3 -0
  130. package/.next/standalone/.next/server/chunks/[root-of-the-server]__0aoqat-._.js +3 -0
  131. package/.next/standalone/.next/server/chunks/[root-of-the-server]__0as-u6z._.js +3 -0
  132. package/.next/standalone/.next/server/chunks/[root-of-the-server]__0bvtbax._.js +3 -0
  133. package/.next/standalone/.next/server/chunks/[root-of-the-server]__0c-ee48._.js +5 -0
  134. package/.next/standalone/.next/server/chunks/[root-of-the-server]__0e_9pc5._.js +3 -0
  135. package/.next/standalone/.next/server/chunks/[root-of-the-server]__0esmskc._.js +3 -0
  136. package/.next/standalone/.next/server/chunks/[root-of-the-server]__0fshk._._.js +20 -0
  137. package/.next/standalone/.next/server/chunks/[root-of-the-server]__0fu72o7._.js +3 -0
  138. package/.next/standalone/.next/server/chunks/[root-of-the-server]__0k9mili._.js +3 -0
  139. package/.next/standalone/.next/server/chunks/[root-of-the-server]__0l-wu5u._.js +3 -0
  140. package/.next/standalone/.next/server/chunks/[root-of-the-server]__0lvz22t._.js +20 -0
  141. package/.next/standalone/.next/server/chunks/[root-of-the-server]__0n-chxk._.js +16 -0
  142. package/.next/standalone/.next/server/chunks/[root-of-the-server]__0n9zdf0._.js +3 -0
  143. package/.next/standalone/.next/server/chunks/[root-of-the-server]__0nmx3k2._.js +12 -0
  144. package/.next/standalone/.next/server/chunks/[root-of-the-server]__0nzlmkb._.js +3 -0
  145. package/.next/standalone/.next/server/chunks/[root-of-the-server]__0o0v6hf._.js +3 -0
  146. package/.next/standalone/.next/server/chunks/[root-of-the-server]__0s38pid._.js +3 -0
  147. package/.next/standalone/.next/server/chunks/[root-of-the-server]__0s_8poz._.js +3 -0
  148. package/.next/standalone/.next/server/chunks/[root-of-the-server]__0sfrx~.._.js +3 -0
  149. package/.next/standalone/.next/server/chunks/[root-of-the-server]__0sggstu._.js +3 -0
  150. package/.next/standalone/.next/server/chunks/[root-of-the-server]__0u81k~2._.js +3 -0
  151. package/.next/standalone/.next/server/chunks/[root-of-the-server]__0uibxf_._.js +3 -0
  152. package/.next/standalone/.next/server/chunks/[root-of-the-server]__0wfv_by._.js +3 -0
  153. package/.next/standalone/.next/server/chunks/[root-of-the-server]__0wlj-yw._.js +3 -0
  154. package/.next/standalone/.next/server/chunks/[root-of-the-server]__0w~__xz._.js +3 -0
  155. package/.next/standalone/.next/server/chunks/[root-of-the-server]__0yat~ul._.js +3 -0
  156. package/.next/standalone/.next/server/chunks/[root-of-the-server]__0yxauu6._.js +3 -0
  157. package/.next/standalone/.next/server/chunks/[root-of-the-server]__0zbkgnr._.js +3 -0
  158. package/.next/standalone/.next/server/chunks/[root-of-the-server]__0zv_j05._.js +3 -0
  159. package/.next/standalone/.next/server/chunks/[root-of-the-server]__0~rntxj._.js +3 -0
  160. package/.next/standalone/.next/server/chunks/src_lib_search_0d-_j3u._.js +4 -4
  161. package/.next/standalone/.next/server/chunks/src_lib_search_0ymmp0c._.js +3 -3
  162. package/.next/standalone/.next/server/chunks/src_lib_workspaces_ts_0qon40u._.js +4 -0
  163. package/.next/standalone/.next/server/chunks/ssr/{0~w0_katex_dist_katex_mjs_029cdbg._.js → 0~w0_katex_dist_katex_mjs_0s4yb1t._.js} +1 -1
  164. package/.next/standalone/.next/server/chunks/ssr/{[root-of-the-server]__0z41nrr._.js → [root-of-the-server]__10te1ye._.js} +2 -2
  165. package/.next/standalone/.next/server/chunks/ssr/{node_modules__pnpm_13p348f._.js → node_modules__pnpm_0-a_zjq._.js} +1 -1
  166. package/.next/standalone/.next/server/chunks/ssr/{node_modules__pnpm_0gos._c._.js → node_modules__pnpm_02l_1_8._.js} +1 -1
  167. package/.next/standalone/.next/server/chunks/ssr/{node_modules__pnpm_0ru1i2-._.js → node_modules__pnpm_03rzttw._.js} +2 -2
  168. package/.next/standalone/.next/server/chunks/ssr/{node_modules__pnpm_08xpp3w._.js → node_modules__pnpm_04frxp9._.js} +1 -1
  169. package/.next/standalone/.next/server/chunks/ssr/{node_modules__pnpm_0b8odbc._.js → node_modules__pnpm_057-t6m._.js} +1 -1
  170. package/.next/standalone/.next/server/chunks/ssr/{node_modules__pnpm_0f_n_zp._.js → node_modules__pnpm_05_oahi._.js} +1 -1
  171. package/.next/standalone/.next/server/chunks/ssr/{node_modules__pnpm_0~i3a.i._.js → node_modules__pnpm_05ans~m._.js} +1 -1
  172. package/.next/standalone/.next/server/chunks/ssr/{node_modules__pnpm_0i2m0b.._.js → node_modules__pnpm_06-2ia.._.js} +2 -2
  173. package/.next/standalone/.next/server/chunks/ssr/{node_modules__pnpm_0aha1~u._.js → node_modules__pnpm_086.ow4._.js} +1 -1
  174. package/.next/standalone/.next/server/chunks/ssr/{node_modules__pnpm_0w.kwue._.js → node_modules__pnpm_0cahog3._.js} +1 -1
  175. package/.next/standalone/.next/server/chunks/ssr/{node_modules__pnpm_0e0r_qk._.js → node_modules__pnpm_0cxanql._.js} +2 -2
  176. package/.next/standalone/.next/server/chunks/ssr/{node_modules__pnpm_0ajqqlq._.js → node_modules__pnpm_0e09gmf._.js} +1 -1
  177. package/.next/standalone/.next/server/chunks/ssr/{node_modules__pnpm_0hzzx9d._.js → node_modules__pnpm_0eqjo2f._.js} +1 -1
  178. package/.next/standalone/.next/server/chunks/ssr/{node_modules__pnpm_02bje_g._.js → node_modules__pnpm_0f-yazg._.js} +1 -1
  179. package/.next/standalone/.next/server/chunks/ssr/{node_modules__pnpm_0xk042~._.js → node_modules__pnpm_0iu44jv._.js} +1 -1
  180. package/.next/standalone/.next/server/chunks/ssr/{node_modules__pnpm_11ede0p._.js → node_modules__pnpm_0jh8q66._.js} +2 -2
  181. package/.next/standalone/.next/server/chunks/ssr/{node_modules__pnpm_0k-7uzm._.js → node_modules__pnpm_0m39f~t._.js} +1 -1
  182. package/.next/standalone/.next/server/chunks/ssr/{node_modules__pnpm_0xr.ztu._.js → node_modules__pnpm_0ma-8l.._.js} +1 -1
  183. package/.next/standalone/.next/server/chunks/ssr/{node_modules__pnpm_0i6_kfe._.js → node_modules__pnpm_0met6sx._.js} +2 -2
  184. package/.next/standalone/.next/server/chunks/ssr/{node_modules__pnpm_04v1_ty._.js → node_modules__pnpm_0mtrsi0._.js} +2 -2
  185. package/.next/standalone/.next/server/chunks/ssr/{node_modules__pnpm_0607~kg._.js → node_modules__pnpm_0n_swwn._.js} +2 -2
  186. package/.next/standalone/.next/server/chunks/ssr/{node_modules__pnpm_0t4l89_._.js → node_modules__pnpm_0ndyy93._.js} +1 -1
  187. package/.next/standalone/.next/server/chunks/ssr/{node_modules__pnpm_0-_58b8._.js → node_modules__pnpm_0s-cj7c._.js} +1 -1
  188. package/.next/standalone/.next/server/chunks/ssr/{node_modules__pnpm_0y2h_cz._.js → node_modules__pnpm_0tr41-t._.js} +1 -1
  189. package/.next/standalone/.next/server/chunks/ssr/{node_modules__pnpm_08edl1n._.js → node_modules__pnpm_0u.uija._.js} +1 -1
  190. package/.next/standalone/.next/server/chunks/ssr/{node_modules__pnpm_0026mgr._.js → node_modules__pnpm_0wiyn6d._.js} +1 -1
  191. package/.next/standalone/.next/server/chunks/ssr/{node_modules__pnpm_09o_spj._.js → node_modules__pnpm_0ygzt82._.js} +1 -1
  192. package/.next/standalone/.next/server/chunks/ssr/src_app_page_tsx_0ss2.w7._.js +2 -2
  193. package/.next/standalone/.next/server/middleware-build-manifest.js +3 -3
  194. package/.next/standalone/.next/server/middleware-manifest.json +1 -1
  195. package/.next/standalone/.next/server/pages/404.html +1 -1
  196. package/.next/standalone/.next/server/pages/500.html +1 -1
  197. package/.next/standalone/.next/static/chunks/0ci7khnv7i~7_.js +17 -0
  198. package/.next/standalone/.next/static/chunks/0sx~65~lg4mgl.css +5 -0
  199. package/.next/standalone/package.json +1 -1
  200. package/README.md +88 -17
  201. package/bin/postbuild.js +21 -0
  202. package/bin/wiki-viewer.js +198 -6
  203. package/package.json +1 -1
  204. package/.next/standalone/.github/workflows/publish.yml +0 -37
  205. package/.next/standalone/.handoffs/archive/handoff-20260612-113332.md +0 -98
  206. package/.next/standalone/.handoffs/archive/handoff-20260612-141032.md +0 -73
  207. package/.next/standalone/.next/server/chunks/[root-of-the-server]__0-.y6im._.js +0 -3
  208. package/.next/standalone/.next/server/chunks/[root-of-the-server]__0-3_t2y._.js +0 -3
  209. package/.next/standalone/.next/server/chunks/[root-of-the-server]__0-kjkzt._.js +0 -3
  210. package/.next/standalone/.next/server/chunks/[root-of-the-server]__0-puax4._.js +0 -4
  211. package/.next/standalone/.next/server/chunks/[root-of-the-server]__01h996g._.js +0 -3
  212. package/.next/standalone/.next/server/chunks/[root-of-the-server]__0329ktu._.js +0 -3
  213. package/.next/standalone/.next/server/chunks/[root-of-the-server]__03_xj4r._.js +0 -3
  214. package/.next/standalone/.next/server/chunks/[root-of-the-server]__05398dt._.js +0 -4
  215. package/.next/standalone/.next/server/chunks/[root-of-the-server]__06lfvxh._.js +0 -3
  216. package/.next/standalone/.next/server/chunks/[root-of-the-server]__06w0aet._.js +0 -3
  217. package/.next/standalone/.next/server/chunks/[root-of-the-server]__070_p2a._.js +0 -4
  218. package/.next/standalone/.next/server/chunks/[root-of-the-server]__0905hi1._.js +0 -21
  219. package/.next/standalone/.next/server/chunks/[root-of-the-server]__0aa63~j._.js +0 -5
  220. package/.next/standalone/.next/server/chunks/[root-of-the-server]__0avcplk._.js +0 -4
  221. package/.next/standalone/.next/server/chunks/[root-of-the-server]__0b8_kyo._.js +0 -16
  222. package/.next/standalone/.next/server/chunks/[root-of-the-server]__0bticq1._.js +0 -3
  223. package/.next/standalone/.next/server/chunks/[root-of-the-server]__0bwevvu._.js +0 -3
  224. package/.next/standalone/.next/server/chunks/[root-of-the-server]__0c__k3q._.js +0 -4
  225. package/.next/standalone/.next/server/chunks/[root-of-the-server]__0cp~z4x._.js +0 -3
  226. package/.next/standalone/.next/server/chunks/[root-of-the-server]__0fmdv9h._.js +0 -20
  227. package/.next/standalone/.next/server/chunks/[root-of-the-server]__0h0qbwr._.js +0 -3
  228. package/.next/standalone/.next/server/chunks/[root-of-the-server]__0jk~oyi._.js +0 -3
  229. package/.next/standalone/.next/server/chunks/[root-of-the-server]__0ndq77b._.js +0 -3
  230. package/.next/standalone/.next/server/chunks/[root-of-the-server]__0nvgpuk._.js +0 -3
  231. package/.next/standalone/.next/server/chunks/[root-of-the-server]__0ocvng2._.js +0 -3
  232. package/.next/standalone/.next/server/chunks/[root-of-the-server]__0ps4h~.._.js +0 -3
  233. package/.next/standalone/.next/server/chunks/[root-of-the-server]__0q7jqwp._.js +0 -12
  234. package/.next/standalone/.next/server/chunks/[root-of-the-server]__0qew~6p._.js +0 -3
  235. package/.next/standalone/.next/server/chunks/[root-of-the-server]__0s_9f-a._.js +0 -3
  236. package/.next/standalone/.next/server/chunks/[root-of-the-server]__0uv7b8u._.js +0 -3
  237. package/.next/standalone/.next/server/chunks/[root-of-the-server]__0uv8.9i._.js +0 -3
  238. package/.next/standalone/.next/server/chunks/[root-of-the-server]__0vfe2io._.js +0 -4
  239. package/.next/standalone/.next/server/chunks/[root-of-the-server]__0w11kjy._.js +0 -3
  240. package/.next/standalone/.next/server/chunks/[root-of-the-server]__0wc-.e4._.js +0 -3
  241. package/.next/standalone/.next/server/chunks/[root-of-the-server]__0ymovmp._.js +0 -3
  242. package/.next/standalone/.next/server/chunks/[root-of-the-server]__0~c6ouv._.js +0 -3
  243. package/.next/standalone/.next/server/chunks/[root-of-the-server]__0~rhs0u._.js +0 -16
  244. package/.next/standalone/.next/server/chunks/[root-of-the-server]__10h9tid._.js +0 -3
  245. package/.next/standalone/.next/server/chunks/[root-of-the-server]__10yk-u1._.js +0 -3
  246. package/.next/standalone/.next/server/chunks/[root-of-the-server]__11105ew._.js +0 -3
  247. package/.next/standalone/.next/server/chunks/[root-of-the-server]__11a3dhw._.js +0 -3
  248. package/.next/standalone/.next/server/chunks/[root-of-the-server]__13420tt._.js +0 -3
  249. package/.next/standalone/.next/server/chunks/[root-of-the-server]__13h~pdf._.js +0 -3
  250. package/.next/standalone/.next/static/chunks/02kg.lbkfi1yc.css +0 -5
  251. package/.next/standalone/.next/static/chunks/0rcwd6-.iu~nd.js +0 -17
  252. package/.next/standalone/.pi/ownership.json +0 -3
  253. package/.next/standalone/AGENTS.md +0 -114
  254. package/.next/standalone/DESIGN.md +0 -521
  255. package/.next/standalone/README.md +0 -821
  256. package/.next/standalone/TODO.md +0 -20
  257. package/.next/standalone/agents/bootstrap-prompt.md +0 -14
  258. package/.next/standalone/agents/wiki-viewer-skill/SKILL.md +0 -456
  259. package/.next/standalone/bin/postbuild.js +0 -78
  260. package/.next/standalone/bin/wiki-viewer.js +0 -922
  261. package/.next/standalone/certificates/localhost-key.pem +0 -28
  262. package/.next/standalone/certificates/localhost.pem +0 -24
  263. package/.next/standalone/docs/agent-collab-plan.md +0 -1615
  264. package/.next/standalone/docs/agent-collab-v2-plan.md +0 -771
  265. package/.next/standalone/docs/agent-fs-plan.md +0 -232
  266. package/.next/standalone/docs/editorial-skin-spec.md +0 -242
  267. package/.next/standalone/docs/file-vs-collab-authority.md +0 -124
  268. package/.next/standalone/docs/mobile-readiness-spec.md +0 -229
  269. package/.next/standalone/docs/workspacing-plan.md +0 -364
  270. package/.next/standalone/packages/wiki-viewer-mcp/README.md +0 -195
  271. package/.next/standalone/packages/wiki-viewer-mcp/bench-e2e.mjs +0 -166
  272. package/.next/standalone/packages/wiki-viewer-mcp/bench-latency.mjs +0 -87
  273. package/.next/standalone/packages/wiki-viewer-mcp/bench-payload.mjs +0 -45
  274. package/.next/standalone/packages/wiki-viewer-mcp/dist/http-client.js +0 -331
  275. package/.next/standalone/packages/wiki-viewer-mcp/dist/index.js +0 -531
  276. package/.next/standalone/packages/wiki-viewer-mcp/dist/register.js +0 -94
  277. package/.next/standalone/packages/wiki-viewer-mcp/dist/state-cache.js +0 -28
  278. package/.next/standalone/packages/wiki-viewer-mcp/package-lock.json +0 -1716
  279. package/.next/standalone/packages/wiki-viewer-mcp/package.json +0 -41
  280. package/.next/standalone/packages/wiki-viewer-mcp/src/http-client.ts +0 -459
  281. package/.next/standalone/packages/wiki-viewer-mcp/src/index.ts +0 -638
  282. package/.next/standalone/packages/wiki-viewer-mcp/src/register.ts +0 -144
  283. package/.next/standalone/packages/wiki-viewer-mcp/src/state-cache.ts +0 -55
  284. package/.next/standalone/packages/wiki-viewer-mcp/tsconfig.json +0 -19
  285. package/.next/standalone/pnpm-lock.yaml +0 -6697
  286. package/.next/standalone/pnpm-workspace.yaml +0 -8
  287. package/.next/standalone/postcss.config.mjs +0 -2
  288. package/.next/standalone/src/app/api/agent/activity/route.ts +0 -59
  289. package/.next/standalone/src/app/api/agent/admin/agents/[agentId]/revoke/route.ts +0 -40
  290. package/.next/standalone/src/app/api/agent/admin/agents/route.ts +0 -33
  291. package/.next/standalone/src/app/api/agent/admin/registrations/[regId]/approve/route.ts +0 -83
  292. package/.next/standalone/src/app/api/agent/admin/registrations/[regId]/deny/route.ts +0 -36
  293. package/.next/standalone/src/app/api/agent/admin/registrations/route.ts +0 -27
  294. package/.next/standalone/src/app/api/agent/events/[...path]/route.ts +0 -148
  295. package/.next/standalone/src/app/api/agent/files/[...path]/route.ts +0 -219
  296. package/.next/standalone/src/app/api/agent/fs/file/[...path]/route.ts +0 -446
  297. package/.next/standalone/src/app/api/agent/fs/ls/[[...path]]/route.ts +0 -152
  298. package/.next/standalone/src/app/api/agent/fs/move/route.ts +0 -130
  299. package/.next/standalone/src/app/api/agent/fs/search/route.ts +0 -272
  300. package/.next/standalone/src/app/api/agent/internal/span/route.ts +0 -121
  301. package/.next/standalone/src/app/api/agent/register/[regId]/route.ts +0 -50
  302. package/.next/standalone/src/app/api/agent/register/route.ts +0 -118
  303. package/.next/standalone/src/app/api/agent/settings/route.ts +0 -34
  304. package/.next/standalone/src/app/api/agent/settings/token/regenerate/route.ts +0 -20
  305. package/.next/standalone/src/app/api/agent/sidecar/[...path]/route.ts +0 -53
  306. package/.next/standalone/src/app/api/agents/install/route.ts +0 -143
  307. package/.next/standalone/src/app/api/agents/skill/route.ts +0 -20
  308. package/.next/standalone/src/app/api/agents/skill.tar.gz/route.ts +0 -87
  309. package/.next/standalone/src/app/api/app-proxy/[...path]/route.ts +0 -247
  310. package/.next/standalone/src/app/api/assets/[...path]/route.ts +0 -75
  311. package/.next/standalone/src/app/api/auth/[...all]/route.ts +0 -7
  312. package/.next/standalone/src/app/api/owner/init/route.ts +0 -14
  313. package/.next/standalone/src/app/api/share/[token]/route.ts +0 -269
  314. package/.next/standalone/src/app/api/share/route.ts +0 -127
  315. package/.next/standalone/src/app/api/system/admins/route.ts +0 -103
  316. package/.next/standalone/src/app/api/system/auth-config/route.ts +0 -22
  317. package/.next/standalone/src/app/api/system/auth-settings/route.ts +0 -86
  318. package/.next/standalone/src/app/api/system/browse/route.ts +0 -82
  319. package/.next/standalone/src/app/api/system/clear-root/route.ts +0 -16
  320. package/.next/standalone/src/app/api/system/config/route.ts +0 -14
  321. package/.next/standalone/src/app/api/system/pins/route.ts +0 -38
  322. package/.next/standalone/src/app/api/system/reveal/route.ts +0 -36
  323. package/.next/standalone/src/app/api/system/root-status/route.ts +0 -13
  324. package/.next/standalone/src/app/api/system/set-root/route.ts +0 -53
  325. package/.next/standalone/src/app/api/system/users/route.ts +0 -120
  326. package/.next/standalone/src/app/api/system/workspaces/[id]/open/route.ts +0 -34
  327. package/.next/standalone/src/app/api/system/workspaces/[id]/refresh/route.ts +0 -32
  328. package/.next/standalone/src/app/api/system/workspaces/[id]/route.ts +0 -78
  329. package/.next/standalone/src/app/api/system/workspaces/route.ts +0 -128
  330. package/.next/standalone/src/app/api/upload/[...path]/route.ts +0 -85
  331. package/.next/standalone/src/app/api/wiki/app/route.ts +0 -60
  332. package/.next/standalone/src/app/api/wiki/backlinks/route.ts +0 -29
  333. package/.next/standalone/src/app/api/wiki/content/route.ts +0 -159
  334. package/.next/standalone/src/app/api/wiki/download/route.ts +0 -100
  335. package/.next/standalone/src/app/api/wiki/file/route.ts +0 -57
  336. package/.next/standalone/src/app/api/wiki/folder/route.ts +0 -34
  337. package/.next/standalone/src/app/api/wiki/git-branches/route.ts +0 -32
  338. package/.next/standalone/src/app/api/wiki/git-checkout/route.ts +0 -45
  339. package/.next/standalone/src/app/api/wiki/git-diff/route.ts +0 -33
  340. package/.next/standalone/src/app/api/wiki/git-file-info/route.ts +0 -27
  341. package/.next/standalone/src/app/api/wiki/git-history/route.ts +0 -27
  342. package/.next/standalone/src/app/api/wiki/git-pull/route.ts +0 -48
  343. package/.next/standalone/src/app/api/wiki/move/route.ts +0 -61
  344. package/.next/standalone/src/app/api/wiki/new-file/route.ts +0 -56
  345. package/.next/standalone/src/app/api/wiki/outlinks/route.ts +0 -76
  346. package/.next/standalone/src/app/api/wiki/page/route.ts +0 -92
  347. package/.next/standalone/src/app/api/wiki/presence/route.ts +0 -56
  348. package/.next/standalone/src/app/api/wiki/route.ts +0 -116
  349. package/.next/standalone/src/app/api/wiki/search/route.ts +0 -44
  350. package/.next/standalone/src/app/api/wiki/slugs/route.ts +0 -54
  351. package/.next/standalone/src/app/api/wiki/upload/route.ts +0 -95
  352. package/.next/standalone/src/app/api/wiki/watch/route.ts +0 -67
  353. package/.next/standalone/src/app/globals.css +0 -1249
  354. package/.next/standalone/src/app/icon.svg +0 -11
  355. package/.next/standalone/src/app/layout.tsx +0 -78
  356. package/.next/standalone/src/app/manifest.ts +0 -30
  357. package/.next/standalone/src/app/page.tsx +0 -3260
  358. package/.next/standalone/src/app/s/[token]/page.tsx +0 -357
  359. package/.next/standalone/src/app/signin/page.tsx +0 -16
  360. package/.next/standalone/src/app/signin/signin-form.tsx +0 -238
  361. package/.next/standalone/src/components/ai-panel/activity-row.tsx +0 -284
  362. package/.next/standalone/src/components/ai-panel/ai-panel.tsx +0 -311
  363. package/.next/standalone/src/components/ai-panel/token-section.tsx +0 -313
  364. package/.next/standalone/src/components/auth-settings-sheet.tsx +0 -474
  365. package/.next/standalone/src/components/confirm-dialog.tsx +0 -56
  366. package/.next/standalone/src/components/dir-picker.tsx +0 -606
  367. package/.next/standalone/src/components/editor/backlinks-panel.tsx +0 -139
  368. package/.next/standalone/src/components/editor/bubble-menu.tsx +0 -346
  369. package/.next/standalone/src/components/editor/callout-extension.ts +0 -36
  370. package/.next/standalone/src/components/editor/comment-pip.tsx +0 -56
  371. package/.next/standalone/src/components/editor/comment-thread.tsx +0 -254
  372. package/.next/standalone/src/components/editor/csv-viewer.tsx +0 -379
  373. package/.next/standalone/src/components/editor/document-outline.tsx +0 -230
  374. package/.next/standalone/src/components/editor/editor-toolbar.tsx +0 -564
  375. package/.next/standalone/src/components/editor/editor.tsx +0 -1327
  376. package/.next/standalone/src/components/editor/extensions/drag-handle.ts +0 -325
  377. package/.next/standalone/src/components/editor/extensions/heading-anchors.ts +0 -55
  378. package/.next/standalone/src/components/editor/extensions/proof-span.ts +0 -60
  379. package/.next/standalone/src/components/editor/extensions/resizable-image.tsx +0 -159
  380. package/.next/standalone/src/components/editor/extensions.ts +0 -150
  381. package/.next/standalone/src/components/editor/file-fallback-viewer.tsx +0 -75
  382. package/.next/standalone/src/components/editor/folder-index.tsx +0 -236
  383. package/.next/standalone/src/components/editor/google-doc-viewer.tsx +0 -73
  384. package/.next/standalone/src/components/editor/image-viewer.tsx +0 -57
  385. package/.next/standalone/src/components/editor/large-file-gate.tsx +0 -108
  386. package/.next/standalone/src/components/editor/link-popover.tsx +0 -111
  387. package/.next/standalone/src/components/editor/media-popover.tsx +0 -212
  388. package/.next/standalone/src/components/editor/media-viewer.tsx +0 -70
  389. package/.next/standalone/src/components/editor/mermaid-viewer.tsx +0 -286
  390. package/.next/standalone/src/components/editor/node-app-viewer.tsx +0 -328
  391. package/.next/standalone/src/components/editor/notebook-viewer.tsx +0 -371
  392. package/.next/standalone/src/components/editor/office/docx-viewer.tsx +0 -93
  393. package/.next/standalone/src/components/editor/office/office-chrome.tsx +0 -83
  394. package/.next/standalone/src/components/editor/office/pptx-viewer.tsx +0 -104
  395. package/.next/standalone/src/components/editor/office/xlsx-viewer.tsx +0 -192
  396. package/.next/standalone/src/components/editor/pdf-viewer.tsx +0 -32
  397. package/.next/standalone/src/components/editor/proof-span-popover.tsx +0 -162
  398. package/.next/standalone/src/components/editor/slash-commands.tsx +0 -629
  399. package/.next/standalone/src/components/editor/source-viewer.tsx +0 -289
  400. package/.next/standalone/src/components/editor/suggest-edit-popover.tsx +0 -229
  401. package/.next/standalone/src/components/editor/suggestion-card.tsx +0 -206
  402. package/.next/standalone/src/components/editor/table-menu.tsx +0 -232
  403. package/.next/standalone/src/components/editor/view-mode-comment-button.tsx +0 -77
  404. package/.next/standalone/src/components/editor/website-viewer.tsx +0 -75
  405. package/.next/standalone/src/components/editor/wiki-link-create-dialog.tsx +0 -189
  406. package/.next/standalone/src/components/editor/wiki-link-decorator.ts +0 -79
  407. package/.next/standalone/src/components/editor/wiki-link-extension.ts +0 -120
  408. package/.next/standalone/src/components/editor/wiki-link-picker.tsx +0 -250
  409. package/.next/standalone/src/components/layout/viewer-toolbar.tsx +0 -54
  410. package/.next/standalone/src/components/search/search-command-dialog.tsx +0 -246
  411. package/.next/standalone/src/components/search/sidebar-search-box.tsx +0 -121
  412. package/.next/standalone/src/components/search/snippet-text.tsx +0 -48
  413. package/.next/standalone/src/components/share-dialog.tsx +0 -307
  414. package/.next/standalone/src/components/theme-provider.tsx +0 -16
  415. package/.next/standalone/src/components/theme-toggle.tsx +0 -24
  416. package/.next/standalone/src/components/ui/badge.tsx +0 -35
  417. package/.next/standalone/src/components/ui/button.tsx +0 -56
  418. package/.next/standalone/src/components/ui/card.tsx +0 -63
  419. package/.next/standalone/src/components/ui/collapsible.tsx +0 -9
  420. package/.next/standalone/src/components/ui/command.tsx +0 -151
  421. package/.next/standalone/src/components/ui/context-menu.tsx +0 -191
  422. package/.next/standalone/src/components/ui/dialog.tsx +0 -119
  423. package/.next/standalone/src/components/ui/dropdown-menu.tsx +0 -194
  424. package/.next/standalone/src/components/ui/input.tsx +0 -22
  425. package/.next/standalone/src/components/ui/label.tsx +0 -25
  426. package/.next/standalone/src/components/ui/popover.tsx +0 -33
  427. package/.next/standalone/src/components/ui/scroll-area.tsx +0 -47
  428. package/.next/standalone/src/components/ui/select.tsx +0 -156
  429. package/.next/standalone/src/components/ui/separator.tsx +0 -30
  430. package/.next/standalone/src/components/ui/sheet.tsx +0 -140
  431. package/.next/standalone/src/components/ui/skeleton.tsx +0 -15
  432. package/.next/standalone/src/components/ui/switch.tsx +0 -28
  433. package/.next/standalone/src/components/ui/tabs.tsx +0 -54
  434. package/.next/standalone/src/components/ui/textarea.tsx +0 -21
  435. package/.next/standalone/src/components/ui/tip.tsx +0 -23
  436. package/.next/standalone/src/components/ui/toggle-group.tsx +0 -41
  437. package/.next/standalone/src/components/ui/tooltip.tsx +0 -27
  438. package/.next/standalone/src/components/view-width-toggle.tsx +0 -70
  439. package/.next/standalone/src/components/wiki/frontmatter-header.tsx +0 -164
  440. package/.next/standalone/src/hooks/use-is-mobile.ts +0 -14
  441. package/.next/standalone/src/lib/app-runner.ts +0 -272
  442. package/.next/standalone/src/lib/auth/admin.ts +0 -120
  443. package/.next/standalone/src/lib/auth/allowlist.ts +0 -50
  444. package/.next/standalone/src/lib/auth/client.ts +0 -4
  445. package/.next/standalone/src/lib/auth/csrf.ts +0 -68
  446. package/.next/standalone/src/lib/auth/server.ts +0 -215
  447. package/.next/standalone/src/lib/cabinets/tree.ts +0 -75
  448. package/.next/standalone/src/lib/config.ts +0 -114
  449. package/.next/standalone/src/lib/embeds/detect.ts +0 -142
  450. package/.next/standalone/src/lib/git-secrets.ts +0 -65
  451. package/.next/standalone/src/lib/git.ts +0 -503
  452. package/.next/standalone/src/lib/google/detect.ts +0 -107
  453. package/.next/standalone/src/lib/markdown/parse-frontmatter.ts +0 -104
  454. package/.next/standalone/src/lib/markdown/remark-wikilinks.ts +0 -100
  455. package/.next/standalone/src/lib/markdown/sanitize-schema.ts +0 -106
  456. package/.next/standalone/src/lib/markdown/to-html.ts +0 -282
  457. package/.next/standalone/src/lib/markdown/to-markdown.ts +0 -252
  458. package/.next/standalone/src/lib/proof/activity-shared.ts +0 -31
  459. package/.next/standalone/src/lib/proof/activity.ts +0 -74
  460. package/.next/standalone/src/lib/proof/audit.ts +0 -88
  461. package/.next/standalone/src/lib/proof/auth.ts +0 -143
  462. package/.next/standalone/src/lib/proof/block-refs.ts +0 -133
  463. package/.next/standalone/src/lib/proof/blocks.ts +0 -73
  464. package/.next/standalone/src/lib/proof/client-auth.ts +0 -23
  465. package/.next/standalone/src/lib/proof/collab-state.ts +0 -81
  466. package/.next/standalone/src/lib/proof/event-bus.ts +0 -47
  467. package/.next/standalone/src/lib/proof/file-lock.ts +0 -43
  468. package/.next/standalone/src/lib/proof/glob.ts +0 -51
  469. package/.next/standalone/src/lib/proof/idempotency.ts +0 -37
  470. package/.next/standalone/src/lib/proof/lease.ts +0 -117
  471. package/.next/standalone/src/lib/proof/mutex.ts +0 -36
  472. package/.next/standalone/src/lib/proof/ops-applier.ts +0 -727
  473. package/.next/standalone/src/lib/proof/owner-auth.ts +0 -2
  474. package/.next/standalone/src/lib/proof/pending.ts +0 -97
  475. package/.next/standalone/src/lib/proof/proof-span.ts +0 -141
  476. package/.next/standalone/src/lib/proof/rate-limit.ts +0 -53
  477. package/.next/standalone/src/lib/proof/raw-fs.ts +0 -197
  478. package/.next/standalone/src/lib/proof/register-rate-limit.ts +0 -53
  479. package/.next/standalone/src/lib/proof/registry.ts +0 -195
  480. package/.next/standalone/src/lib/proof/sidecar.ts +0 -103
  481. package/.next/standalone/src/lib/proof/suggest-capture.ts +0 -69
  482. package/.next/standalone/src/lib/proof/types.ts +0 -182
  483. package/.next/standalone/src/lib/proof-config.ts +0 -14
  484. package/.next/standalone/src/lib/root-dir.ts +0 -35
  485. package/.next/standalone/src/lib/search/indexable-exts.ts +0 -25
  486. package/.next/standalone/src/lib/search/indexer.ts +0 -634
  487. package/.next/standalone/src/lib/search/sanitize.ts +0 -35
  488. package/.next/standalone/src/lib/search/search-db.ts +0 -57
  489. package/.next/standalone/src/lib/search/watcher-pool.ts +0 -79
  490. package/.next/standalone/src/lib/shared-docs/db.ts +0 -177
  491. package/.next/standalone/src/lib/toast.ts +0 -9
  492. package/.next/standalone/src/lib/utils.ts +0 -6
  493. package/.next/standalone/src/lib/wiki-helpers.ts +0 -36
  494. package/.next/standalone/src/lib/workspace-client.ts +0 -82
  495. package/.next/standalone/src/lib/workspace-context.ts +0 -173
  496. package/.next/standalone/src/lib/workspaces.ts +0 -400
  497. package/.next/standalone/src/middleware.ts +0 -44
  498. package/.next/standalone/src/stores/ai-panel-store.ts +0 -79
  499. package/.next/standalone/src/stores/editor-store.ts +0 -439
  500. package/.next/standalone/src/stores/pin-store.ts +0 -56
  501. package/.next/standalone/src/stores/proof-store.ts +0 -124
  502. package/.next/standalone/src/stores/recent-store.ts +0 -51
  503. package/.next/standalone/src/stores/search-store.ts +0 -104
  504. package/.next/standalone/src/stores/show-hidden-store.ts +0 -26
  505. package/.next/standalone/src/stores/sidebar-width-store.ts +0 -39
  506. package/.next/standalone/src/stores/skin-store.ts +0 -42
  507. package/.next/standalone/src/stores/tree-store.ts +0 -52
  508. package/.next/standalone/src/stores/view-width-store.ts +0 -101
  509. package/.next/standalone/src/stores/wiki-slugs-store.ts +0 -75
  510. package/.next/standalone/src/tests/proof/activity-aggregator.test.ts +0 -146
  511. package/.next/standalone/src/tests/proof/admin-create-user.test.ts +0 -43
  512. package/.next/standalone/src/tests/proof/agent-fs.test.ts +0 -973
  513. package/.next/standalone/src/tests/proof/agent-ownership.test.ts +0 -140
  514. package/.next/standalone/src/tests/proof/agent-workspace-scope.test.ts +0 -134
  515. package/.next/standalone/src/tests/proof/agents-install.test.ts +0 -110
  516. package/.next/standalone/src/tests/proof/bench-write.ts +0 -179
  517. package/.next/standalone/src/tests/proof/better-auth.test.ts +0 -68
  518. package/.next/standalone/src/tests/proof/block-refs.test.ts +0 -108
  519. package/.next/standalone/src/tests/proof/blocks.test.ts +0 -92
  520. package/.next/standalone/src/tests/proof/collab-state.test.ts +0 -501
  521. package/.next/standalone/src/tests/proof/comments-ops.test.ts +0 -177
  522. package/.next/standalone/src/tests/proof/editor-roundtrip.test.ts +0 -85
  523. package/.next/standalone/src/tests/proof/external-edit.test.ts +0 -58
  524. package/.next/standalone/src/tests/proof/file-lock.test.ts +0 -80
  525. package/.next/standalone/src/tests/proof/git-branches-checkout.test.ts +0 -136
  526. package/.next/standalone/src/tests/proof/git-read-features.test.ts +0 -473
  527. package/.next/standalone/src/tests/proof/git-secrets.test.ts +0 -138
  528. package/.next/standalone/src/tests/proof/git-sparse.test.ts +0 -257
  529. package/.next/standalone/src/tests/proof/git-workspace.test.ts +0 -135
  530. package/.next/standalone/src/tests/proof/git.test.ts +0 -243
  531. package/.next/standalone/src/tests/proof/glob.test.ts +0 -82
  532. package/.next/standalone/src/tests/proof/helpers/auth-session.ts +0 -27
  533. package/.next/standalone/src/tests/proof/markdown-to-html.test.ts +0 -46
  534. package/.next/standalone/src/tests/proof/ops-applier.test.ts +0 -368
  535. package/.next/standalone/src/tests/proof/owner-init.test.ts +0 -2
  536. package/.next/standalone/src/tests/proof/parse-frontmatter.test.ts +0 -60
  537. package/.next/standalone/src/tests/proof/preload.ts +0 -21
  538. package/.next/standalone/src/tests/proof/proof-span.test.ts +0 -98
  539. package/.next/standalone/src/tests/proof/rate-limit.test.ts +0 -54
  540. package/.next/standalone/src/tests/proof/readonly-enforcement.test.ts +0 -161
  541. package/.next/standalone/src/tests/proof/reconcile-sidecar.test.ts +0 -195
  542. package/.next/standalone/src/tests/proof/registration-flow.test.ts +0 -330
  543. package/.next/standalone/src/tests/proof/registry.test.ts +0 -169
  544. package/.next/standalone/src/tests/proof/routes.test.ts +0 -516
  545. package/.next/standalone/src/tests/proof/search-index.test.ts +0 -376
  546. package/.next/standalone/src/tests/proof/sidecar-lifecycle.test.ts +0 -177
  547. package/.next/standalone/src/tests/proof/sidecar-trim.test.ts +0 -58
  548. package/.next/standalone/src/tests/proof/suggestion-ops.test.ts +0 -280
  549. package/.next/standalone/src/tests/proof/wiki-content-put.test.ts +0 -140
  550. package/.next/standalone/src/tests/proof/wiki-routes-auth.test.ts +0 -208
  551. package/.next/standalone/src/tests/proof/workspace-isolation.test.ts +0 -87
  552. package/.next/standalone/src/tests/proof/workspaces-api.test.ts +0 -227
  553. package/.next/standalone/src/types/index.ts +0 -47
  554. package/.next/standalone/tailwind.config.ts +0 -191
  555. package/.next/standalone/tsconfig.json +0 -41
  556. package/.next/standalone/tsconfig.tsbuildinfo +0 -1
  557. /package/.next/standalone/.next/static/{WMOTgfV82apmdovxzgbMx → ecpoWt_SP3WkUTh0NsnuT}/_buildManifest.js +0 -0
  558. /package/.next/standalone/.next/static/{WMOTgfV82apmdovxzgbMx → ecpoWt_SP3WkUTh0NsnuT}/_clientMiddlewareManifest.js +0 -0
  559. /package/.next/standalone/.next/static/{WMOTgfV82apmdovxzgbMx → ecpoWt_SP3WkUTh0NsnuT}/_ssgManifest.js +0 -0
@@ -1,634 +0,0 @@
1
- /**
2
- * FTS5 full-text search indexer.
3
- *
4
- * Lifecycle:
5
- * - ensureIndexer(wsId, rootDir) -- idempotent; starts background initial scan once
6
- * - indexFile / deleteFile -- incremental updates (called by chokidar listener)
7
- * - ftsSearch -- BM25 search query
8
- * - purgeWorkspace -- called on workspace delete
9
- *
10
- * Thread safety: better-sqlite3 is synchronous and single-threaded. All DB
11
- * writes are serialised through JS's single thread. Event-loop blocking from the
12
- * initial scan is avoided by yielding via setImmediate every INITIAL_YIELD_EVERY files.
13
- */
14
- import { createHash } from "node:crypto";
15
- import { readFile, readdir, stat } from "node:fs/promises";
16
- import type { Dirent } from "node:fs";
17
- import path from "node:path";
18
- import { getSearchDb } from "./search-db";
19
- import { sanitizeFtsQuery } from "./sanitize";
20
- import { isIndexableExt, isMarkdownExt } from "./indexable-exts";
21
- import { isDeniedRelPath, looksLikeBinary, safeAbsPath } from "../proof/raw-fs";
22
- import { isNodeApp, isAppFolder } from "../wiki-helpers";
23
- import { parseFrontmatter } from "../markdown/parse-frontmatter";
24
- import { subscribe } from "./watcher-pool";
25
-
26
- // ── Constants ──────────────────────────────────────────────────────────────────
27
-
28
- const MAX_INDEX_BYTES = 1024 * 1024; // 1 MiB body cap
29
- const BATCH_SIZE = 50; // max files per DB transaction
30
- const BATCH_TIMEOUT_MS = 2000; // flush pending queue after this many ms
31
- const INITIAL_YIELD_EVERY = 64; // setImmediate yield every N files
32
-
33
- const SKIP_DIRS = new Set([".proof", ".git", "node_modules", ".next"]);
34
-
35
- // ── Per-workspace state ────────────────────────────────────────────────────────
36
-
37
- interface WsState {
38
- rootDir: string;
39
- initialScanDone: boolean;
40
- initialScanPromise: Promise<void> | null;
41
- pendingPaths: Set<string>;
42
- pendingTimer: ReturnType<typeof setTimeout> | null;
43
- unsubscribeWatcher: (() => void) | null;
44
- }
45
-
46
- const states = new Map<string, WsState>();
47
-
48
- function getState(wsId: string, rootDir: string): WsState {
49
- let s = states.get(wsId);
50
- if (!s) {
51
- s = {
52
- rootDir,
53
- initialScanDone: false,
54
- initialScanPromise: null,
55
- pendingPaths: new Set(),
56
- pendingTimer: null,
57
- unsubscribeWatcher: null,
58
- };
59
- states.set(wsId, s);
60
- }
61
- return s;
62
- }
63
-
64
- // ── DB helpers ─────────────────────────────────────────────────────────────────
65
-
66
- function upsertDoc(
67
- wsId: string,
68
- relPath: string,
69
- name: string,
70
- frontmatter: string,
71
- body: string,
72
- size: number,
73
- mtimeNs: bigint,
74
- sha: string,
75
- ): void {
76
- const db = getSearchDb();
77
- // DELETE + INSERT because FTS5 has no native UPSERT.
78
- db.prepare(`DELETE FROM docs WHERE ws = ? AND path = ?`).run(wsId, relPath);
79
- db.prepare(`INSERT INTO docs (ws, path, name, frontmatter, body) VALUES (?, ?, ?, ?, ?)`)
80
- .run(wsId, relPath, name, frontmatter, body);
81
- db.prepare(`
82
- INSERT INTO docs_meta (ws, path, size, mtime_ns, sha, indexed_at)
83
- VALUES (?, ?, ?, ?, ?, ?)
84
- ON CONFLICT(ws, path) DO UPDATE SET
85
- size = excluded.size,
86
- mtime_ns = excluded.mtime_ns,
87
- sha = excluded.sha,
88
- indexed_at = excluded.indexed_at
89
- `).run(wsId, relPath, size, String(mtimeNs), sha, new Date().toISOString());
90
- }
91
-
92
- function removeDoc(wsId: string, relPath: string): void {
93
- const db = getSearchDb();
94
- db.prepare(`DELETE FROM docs WHERE ws = ? AND path = ?`).run(wsId, relPath);
95
- db.prepare(`DELETE FROM docs_meta WHERE ws = ? AND path = ?`).run(wsId, relPath);
96
- }
97
-
98
- // ── Text extraction ────────────────────────────────────────────────────────────
99
-
100
- async function extractText(
101
- absPath: string,
102
- relPath: string,
103
- ): Promise<{ name: string; frontmatter: string; body: string; sha: string; size: number; mtimeNs: bigint } | null> {
104
- let st: Awaited<ReturnType<typeof stat>>;
105
- try {
106
- st = await stat(absPath);
107
- } catch {
108
- return null;
109
- }
110
-
111
- const size = st.size;
112
- const mtimeNs = BigInt(Math.round(st.mtimeMs * 1_000_000));
113
- const name = path.basename(relPath);
114
-
115
- if (size > MAX_INDEX_BYTES) {
116
- // Too large: index filename only, no body.
117
- return { name, frontmatter: "", body: "", sha: "", size, mtimeNs };
118
- }
119
-
120
- let buf: Buffer;
121
- try {
122
- buf = await readFile(absPath);
123
- } catch {
124
- return null;
125
- }
126
-
127
- const sha = "sha256:" + createHash("sha256").update(buf).digest("hex");
128
-
129
- if (looksLikeBinary(buf)) {
130
- return { name, frontmatter: "", body: "", sha, size, mtimeNs };
131
- }
132
-
133
- const text = buf.toString("utf-8");
134
-
135
- if (isMarkdownExt(name)) {
136
- const parsed = parseFrontmatter(text);
137
- const fmStr = Object.entries(parsed.data)
138
- .map(([k, v]) => `${k} ${Array.isArray(v) ? (v as unknown[]).join(" ") : String(v)}`)
139
- .join(" ");
140
- return { name, frontmatter: fmStr, body: parsed.body, sha, size, mtimeNs };
141
- }
142
-
143
- return { name, frontmatter: "", body: text, sha, size, mtimeNs };
144
- }
145
-
146
- // ── Index one file ─────────────────────────────────────────────────────────────
147
-
148
- async function indexOnePath(wsId: string, rootDir: string, relPath: string): Promise<void> {
149
- if (isDeniedRelPath(relPath)) return;
150
-
151
- // App-dir contents are opaque leaves; never index files inside an app folder.
152
- if (await isUnderApp(rootDir, relPath)) {
153
- removeDoc(wsId, relPath);
154
- return;
155
- }
156
-
157
- // Symlink-escape guard: resolve the realpath and confirm it stays under root.
158
- // A symlink whose target escapes the workspace must never be indexed.
159
- const absPath = await safeAbsPath(rootDir, relPath);
160
- if (!absPath) {
161
- removeDoc(wsId, relPath);
162
- return;
163
- }
164
- const db = getSearchDb();
165
-
166
- // Fast-path: check size+mtime against existing meta
167
- let st: Awaited<ReturnType<typeof stat>>;
168
- try {
169
- st = await stat(absPath);
170
- } catch {
171
- // File gone - remove it
172
- removeDoc(wsId, relPath);
173
- return;
174
- }
175
-
176
- if (!st.isFile()) return;
177
-
178
- const size = st.size;
179
- const mtimeNs = BigInt(Math.round(st.mtimeMs * 1_000_000));
180
-
181
- const meta = db.prepare(`SELECT size, mtime_ns, sha FROM docs_meta WHERE ws = ? AND path = ?`)
182
- .get(wsId, relPath) as { size: number; mtime_ns: string; sha: string } | undefined;
183
-
184
- if (meta && meta.size === size && BigInt(meta.mtime_ns) === mtimeNs) {
185
- // Unchanged - skip
186
- return;
187
- }
188
-
189
- const extracted = await extractText(absPath, relPath);
190
- if (!extracted) return;
191
-
192
- // If we got a sha and it matches the existing meta, just touch indexed_at
193
- if (meta && extracted.sha && extracted.sha === meta.sha) {
194
- db.prepare(`UPDATE docs_meta SET indexed_at = ? WHERE ws = ? AND path = ?`)
195
- .run(new Date().toISOString(), wsId, relPath);
196
- return;
197
- }
198
-
199
- const name = path.basename(relPath);
200
- if (!isIndexableExt(name) && !isMarkdownExt(name)) {
201
- // Non-text: index name only so filename searches work
202
- upsertDoc(wsId, relPath, name, "", "", size, mtimeNs, extracted.sha);
203
- return;
204
- }
205
-
206
- upsertDoc(wsId, relPath, extracted.name, extracted.frontmatter, extracted.body, extracted.size, extracted.mtimeNs, extracted.sha);
207
- }
208
-
209
- // ── File tree walker ───────────────────────────────────────────────────────────
210
-
211
- async function* walkFiles(rootDir: string, relDir: string): AsyncGenerator<string> {
212
- let items: Dirent[];
213
- try {
214
- items = await readdir(path.join(rootDir, relDir), { withFileTypes: true });
215
- } catch {
216
- return;
217
- }
218
- for (const item of items) {
219
- if (SKIP_DIRS.has(item.name)) continue;
220
- const childRel = relDir ? `${relDir}/${item.name}` : item.name;
221
- if (item.isDirectory()) {
222
- // App dirs (package.json or index.html) are opaque leaves in the UI:
223
- // clicking runs the app, it is not a browsable folder. Do not index
224
- // their contents so search does not surface bundled app internals.
225
- if (await isNodeApp(rootDir, childRel) || await isAppFolder(rootDir, childRel)) {
226
- continue;
227
- }
228
- yield* walkFiles(rootDir, childRel);
229
- } else if (item.isFile() || item.isSymbolicLink()) {
230
- yield childRel;
231
- }
232
- }
233
- }
234
-
235
- /**
236
- * True if any ancestor directory of relPath is an app folder (node-app or
237
- * static app). Used by the incremental path so file events inside an app dir
238
- * are ignored, matching the initial-scan walker which does not recurse into
239
- * app dirs.
240
- */
241
- async function isUnderApp(rootDir: string, relPath: string): Promise<boolean> {
242
- const parts = relPath.split("/");
243
- for (let i = 1; i < parts.length; i++) {
244
- const ancestor = parts.slice(0, i).join("/");
245
- if (await isNodeApp(rootDir, ancestor) || await isAppFolder(rootDir, ancestor)) {
246
- return true;
247
- }
248
- }
249
- return false;
250
- }
251
-
252
- // ── Initial scan ───────────────────────────────────────────────────────────────
253
-
254
- async function initialScan(wsId: string, rootDir: string): Promise<void> {
255
- const db = getSearchDb();
256
- let batch: Array<() => void> = [];
257
- let fileCount = 0;
258
-
259
- async function flushBatch() {
260
- if (batch.length === 0) return;
261
- const ops = batch;
262
- batch = [];
263
- db.transaction(() => {
264
- for (const op of ops) op();
265
- })();
266
- }
267
-
268
- for await (const relPath of walkFiles(rootDir, "")) {
269
- if (isDeniedRelPath(relPath)) continue;
270
-
271
- // Schedule the actual index work
272
- const relPathCopy = relPath;
273
-
274
- // Symlink-escape guard: skip anything whose realpath leaves the workspace.
275
- const absPath = await safeAbsPath(rootDir, relPathCopy);
276
- if (!absPath) continue;
277
-
278
- // Stat + read inline (can't easily capture async in sync txn)
279
- // We collect the data async, then write in a batch txn
280
- let st: Awaited<ReturnType<typeof stat>>;
281
- try {
282
- st = await stat(absPath);
283
- } catch {
284
- continue;
285
- }
286
- if (!st.isFile()) continue;
287
-
288
- const size = st.size;
289
- const mtimeNs = BigInt(Math.round(st.mtimeMs * 1_000_000));
290
-
291
- const meta = db.prepare(`SELECT size, mtime_ns FROM docs_meta WHERE ws = ? AND path = ?`)
292
- .get(wsId, relPathCopy) as { size: number; mtime_ns: string } | undefined;
293
-
294
- if (meta && meta.size === size && BigInt(meta.mtime_ns) === mtimeNs) {
295
- fileCount++;
296
- if (fileCount % INITIAL_YIELD_EVERY === 0) {
297
- await new Promise<void>((r) => setImmediate(r));
298
- }
299
- continue;
300
- }
301
-
302
- const extracted = await extractText(absPath, relPathCopy);
303
- if (!extracted) continue;
304
-
305
- const name = path.basename(relPathCopy);
306
- const shouldIndexBody = isIndexableExt(name) || isMarkdownExt(name);
307
- const fBody = shouldIndexBody ? extracted.body : "";
308
- const fFm = shouldIndexBody ? extracted.frontmatter : "";
309
-
310
- const capSize = extracted.size;
311
- const capMtime = extracted.mtimeNs;
312
- const capSha = extracted.sha;
313
-
314
- batch.push(() => {
315
- db.prepare(`DELETE FROM docs WHERE ws = ? AND path = ?`).run(wsId, relPathCopy);
316
- db.prepare(`INSERT INTO docs (ws, path, name, frontmatter, body) VALUES (?, ?, ?, ?, ?)`)
317
- .run(wsId, relPathCopy, extracted.name, fFm, fBody);
318
- db.prepare(`
319
- INSERT INTO docs_meta (ws, path, size, mtime_ns, sha, indexed_at)
320
- VALUES (?, ?, ?, ?, ?, ?)
321
- ON CONFLICT(ws, path) DO UPDATE SET
322
- size = excluded.size,
323
- mtime_ns = excluded.mtime_ns,
324
- sha = excluded.sha,
325
- indexed_at = excluded.indexed_at
326
- `).run(wsId, relPathCopy, capSize, String(capMtime), capSha, new Date().toISOString());
327
- });
328
-
329
- fileCount++;
330
-
331
- if (batch.length >= BATCH_SIZE) {
332
- await flushBatch();
333
- await new Promise<void>((r) => setImmediate(r));
334
- } else if (fileCount % INITIAL_YIELD_EVERY === 0) {
335
- await new Promise<void>((r) => setImmediate(r));
336
- }
337
- }
338
-
339
- await flushBatch();
340
- }
341
-
342
- // ── Batch queue (incremental updates from chokidar) ────────────────────────────
343
-
344
- function enqueueIndex(wsId: string, relPath: string): void {
345
- const s = states.get(wsId);
346
- if (!s) return;
347
- s.pendingPaths.add(relPath);
348
- if (s.pendingTimer) return; // already scheduled
349
- s.pendingTimer = setTimeout(() => flushQueue(wsId), BATCH_TIMEOUT_MS);
350
- }
351
-
352
- function flushQueue(wsId: string): void {
353
- const s = states.get(wsId);
354
- if (!s || s.pendingPaths.size === 0) return;
355
- s.pendingTimer = null;
356
- const paths = Array.from(s.pendingPaths);
357
- s.pendingPaths.clear();
358
-
359
- // Index each in a background promise; errors are logged not thrown.
360
- // Work is chunked at BATCH_SIZE with a setImmediate yield between chunks so a
361
- // large burst of file changes can never block the event loop in one big
362
- // synchronous transaction.
363
- const db = getSearchDb();
364
- const rootDir = s.rootDir;
365
- void (async () => {
366
- let ops: Array<() => void> = [];
367
-
368
- const flushOps = async () => {
369
- if (ops.length === 0) return;
370
- const chunk = ops;
371
- ops = [];
372
- db.transaction(() => { for (const op of chunk) op(); })();
373
- await new Promise<void>((r) => setImmediate(r));
374
- };
375
-
376
- for (const relPath of paths) {
377
- // App-dir contents are opaque leaves; never index files inside one.
378
- if (await isUnderApp(rootDir, relPath)) {
379
- ops.push(() => removeDoc(wsId, relPath));
380
- if (ops.length >= BATCH_SIZE) await flushOps();
381
- continue;
382
- }
383
- // Symlink-escape guard before any read.
384
- const absPath = await safeAbsPath(rootDir, relPath);
385
- if (!absPath) {
386
- ops.push(() => removeDoc(wsId, relPath));
387
- if (ops.length >= BATCH_SIZE) await flushOps();
388
- continue;
389
- }
390
- const extracted = await extractText(absPath, relPath).catch(() => null);
391
- if (!extracted) {
392
- ops.push(() => removeDoc(wsId, relPath));
393
- if (ops.length >= BATCH_SIZE) await flushOps();
394
- continue;
395
- }
396
- const name = path.basename(relPath);
397
- const shouldIndexBody = isIndexableExt(name) || isMarkdownExt(name);
398
- const capSize = extracted.size;
399
- const capMtime = extracted.mtimeNs;
400
- const capSha = extracted.sha;
401
- const fBody = shouldIndexBody ? extracted.body : "";
402
- const fFm = shouldIndexBody ? extracted.frontmatter : "";
403
- ops.push(() => {
404
- db.prepare(`DELETE FROM docs WHERE ws = ? AND path = ?`).run(wsId, relPath);
405
- db.prepare(`INSERT INTO docs (ws, path, name, frontmatter, body) VALUES (?, ?, ?, ?, ?)`)
406
- .run(wsId, relPath, extracted.name, fFm, fBody);
407
- db.prepare(`
408
- INSERT INTO docs_meta (ws, path, size, mtime_ns, sha, indexed_at)
409
- VALUES (?, ?, ?, ?, ?, ?)
410
- ON CONFLICT(ws, path) DO UPDATE SET
411
- size = excluded.size,
412
- mtime_ns = excluded.mtime_ns,
413
- sha = excluded.sha,
414
- indexed_at = excluded.indexed_at
415
- `).run(wsId, relPath, capSize, String(capMtime), capSha, new Date().toISOString());
416
- });
417
- if (ops.length >= BATCH_SIZE) await flushOps();
418
- }
419
- await flushOps();
420
- })().catch((e) => console.error("[search] flushQueue error", e));
421
- }
422
-
423
- // ── Public API ─────────────────────────────────────────────────────────────────
424
-
425
- /**
426
- * Ensure the indexer is running for this workspace.
427
- * Idempotent: concurrent calls share one initial-scan promise.
428
- * Fire-and-forget from request handlers (catch the promise externally).
429
- */
430
- export async function ensureIndexer(wsId: string, rootDir: string): Promise<void> {
431
- const s = getState(wsId, rootDir);
432
-
433
- if (s.initialScanDone) return;
434
-
435
- if (!s.initialScanPromise) {
436
- // Subscribe to chokidar (permanent listener -- watcher stays alive while indexer exists).
437
- if (!s.unsubscribeWatcher) {
438
- s.unsubscribeWatcher = subscribe(wsId, rootDir, (ev, relPath) => {
439
- if (!relPath || isDeniedRelPath(relPath)) return;
440
- if (ev === "add" || ev === "change") {
441
- enqueueIndex(wsId, relPath);
442
- } else if (ev === "unlink") {
443
- void deleteFile(wsId, relPath);
444
- }
445
- });
446
- }
447
-
448
- // Kick off the scan in the background via setImmediate to not block the
449
- // calling request. The promise is stored so subsequent ensureIndexer calls
450
- // await the same scan instead of spawning a second one.
451
- s.initialScanPromise = new Promise<void>((resolve) => {
452
- setImmediate(() => {
453
- void initialScan(wsId, rootDir).then(() => {
454
- s.initialScanDone = true;
455
- resolve();
456
- }).catch((e) => {
457
- console.error("[search] initial scan error", e);
458
- s.initialScanPromise = null; // allow retry
459
- resolve();
460
- });
461
- });
462
- });
463
- }
464
-
465
- // Do NOT await: callers call fire-and-forget. Search works on whatever is already indexed.
466
- // (Tests use _waitForIdle to synchronise.)
467
- }
468
-
469
- /** Index a single file (called on chokidar change/add events). */
470
- export async function indexFile(wsId: string, rootDir: string, relPath: string): Promise<void> {
471
- await indexOnePath(wsId, rootDir, relPath);
472
- }
473
-
474
- /** Remove a single file from the index. */
475
- export async function deleteFile(wsId: string, relPath: string): Promise<void> {
476
- removeDoc(wsId, relPath);
477
- }
478
-
479
- /** Remove all indexed data for a workspace (called on workspace delete). */
480
- export async function purgeWorkspace(wsId: string): Promise<void> {
481
- const db = getSearchDb();
482
- db.transaction(() => {
483
- db.prepare(`DELETE FROM docs WHERE ws = ?`).run(wsId);
484
- db.prepare(`DELETE FROM docs_meta WHERE ws = ?`).run(wsId);
485
- })();
486
- // Clean up module state
487
- const s = states.get(wsId);
488
- if (s) {
489
- if (s.pendingTimer) clearTimeout(s.pendingTimer);
490
- s.unsubscribeWatcher?.();
491
- states.delete(wsId);
492
- }
493
- }
494
-
495
- export interface IndexedMatch {
496
- path: string;
497
- score: number; // negated BM25 rank (higher = better)
498
- snippet: string;
499
- }
500
-
501
- export interface SearchResult {
502
- matches: IndexedMatch[];
503
- truncated: boolean;
504
- }
505
-
506
- /**
507
- * Full-text search within a single workspace.
508
- *
509
- * CRITICAL: ws isolation is enforced by `WHERE ws = ?` on every query.
510
- * This is the ONLY place in the codebase that executes SELECT ... FROM docs
511
- * returning rows to callers. The ws column is always bound as the first param.
512
- */
513
- export function ftsSearch(wsId: string, query: string, limit: number): SearchResult {
514
- const sanitized = sanitizeFtsQuery(query);
515
- if (!sanitized) return { matches: [], truncated: false };
516
-
517
- const hardLimit = Math.min(Math.max(1, limit), 200);
518
- const db = getSearchDb();
519
-
520
- let rows: Array<{ path: string; score: number; snippet: string }>;
521
- try {
522
- rows = db.prepare(`
523
- SELECT path,
524
- rank AS score,
525
- snippet(docs, 4, '<mark>', '</mark>', '\u2026', 12) AS snippet
526
- FROM docs
527
- WHERE ws = ? AND docs MATCH ?
528
- ORDER BY rank
529
- LIMIT ?
530
- `).all(wsId, sanitized, hardLimit + 1) as typeof rows;
531
- } catch (e) {
532
- console.error("[search] ftsSearch error", e);
533
- return { matches: [], truncated: false };
534
- }
535
-
536
- const truncated = rows.length > hardLimit;
537
- return {
538
- matches: rows.slice(0, hardLimit).map((r) => ({
539
- path: r.path,
540
- score: -r.score,
541
- snippet: r.snippet ?? "",
542
- })),
543
- truncated,
544
- };
545
- }
546
-
547
- // ── Backlinks ────────────────────────────────────────────────────────────────
548
-
549
- export interface Backlink {
550
- path: string;
551
- snippet: string;
552
- }
553
-
554
- /**
555
- * True if `body` contains an actual wiki-link to `slug`: `[[slug]]`,
556
- * `[[slug|alias]]`, or `[[slug#anchor]]`. FTS matches tokenised prose, so we
557
- * re-check the raw text to drop false positives (a page merely mentioning the
558
- * word, not linking to it).
559
- */
560
- function hasWikiLinkTo(body: string, slug: string): boolean {
561
- const esc = slug.replace(/[.*+?^${}()|[\]\\]/g, "\\$&");
562
- const re = new RegExp(`\\[\\[${esc}(?:\\|[^\\]#|]+|#[a-z0-9-]+)?\\]\\]`, "i");
563
- return re.test(body);
564
- }
565
-
566
- /**
567
- * Resolve confirmed backlinks to a page in one in-process pass.
568
- *
569
- * Replaces the old client-side N+1 (search → fetch each candidate's content over
570
- * HTTP). FTS is a coarse candidate filter; we read each candidate's `body` column
571
- * directly from SQLite and confirm a literal `[[slug]]` link. No file I/O, no
572
- * HTTP round-trips.
573
- *
574
- * ws isolation enforced by `WHERE ws = ?` (see ftsSearch contract).
575
- */
576
- export function resolveBacklinks(
577
- wsId: string,
578
- slug: string,
579
- excludePath: string,
580
- limit: number,
581
- ): Backlink[] {
582
- const sanitized = sanitizeFtsQuery(slug);
583
- if (!sanitized) return [];
584
-
585
- const candidateCap = Math.min(Math.max(1, limit), 200);
586
- const db = getSearchDb();
587
-
588
- let rows: Array<{ path: string; snippet: string; body: string }>;
589
- try {
590
- rows = db.prepare(`
591
- SELECT path,
592
- snippet(docs, 4, '<mark>', '</mark>', '…', 12) AS snippet,
593
- body
594
- FROM docs
595
- WHERE ws = ? AND docs MATCH ?
596
- ORDER BY rank
597
- LIMIT ?
598
- `).all(wsId, sanitized, candidateCap) as typeof rows;
599
- } catch (e) {
600
- console.error("[search] resolveBacklinks error", e);
601
- return [];
602
- }
603
-
604
- const out: Backlink[] = [];
605
- for (const r of rows) {
606
- if (r.path === excludePath) continue;
607
- if (!/\.md$/i.test(r.path)) continue;
608
- if (!hasWikiLinkTo(r.body, slug)) continue;
609
- out.push({ path: r.path, snippet: r.snippet ?? "" });
610
- }
611
- return out;
612
- }
613
-
614
- // ── Test hooks ─────────────────────────────────────────────────────────────────
615
-
616
- /** Reset all module-level state (for tests). */
617
- export function _resetIndexer(): void {
618
- for (const s of states.values()) {
619
- if (s.pendingTimer) clearTimeout(s.pendingTimer);
620
- s.unsubscribeWatcher?.();
621
- }
622
- states.clear();
623
- }
624
-
625
- /**
626
- * Wait until the initial scan for wsId has completed (for tests).
627
- * Resolves immediately if the scan is already done.
628
- */
629
- export async function _waitForIdle(wsId: string): Promise<void> {
630
- const s = states.get(wsId);
631
- if (!s) return;
632
- if (s.initialScanDone) return;
633
- if (s.initialScanPromise) await s.initialScanPromise;
634
- }
@@ -1,35 +0,0 @@
1
- /**
2
- * FTS5 user-query sanitizer.
3
- *
4
- * Converts raw user input into a safe FTS5 MATCH expression.
5
- * Strategy: whitelist alphanumerics + hyphen + underscore, double-quote
6
- * every token, optionally preserve trailing * for prefix search.
7
- * This neutralizes ALL FTS5 operators (AND, OR, NOT, NEAR, (, ), ^)
8
- * because quoted tokens are treated as literal phrases, not operators.
9
- */
10
-
11
- /** Match Unicode letters, numbers, hyphen, underscore, optionally followed by *. */
12
- const TOKEN_RE = /[\p{L}\p{N}_-]+\*?/gu;
13
-
14
- /** Max tokens accepted per query (prevents degenerate query bombs). */
15
- const MAX_TOKENS = 16;
16
-
17
- /**
18
- * Returns a sanitized FTS5 query string, or "" if the input is empty
19
- * or contains no valid tokens. An empty return means the caller should
20
- * short-circuit and return no results without hitting FTS5.
21
- */
22
- export function sanitizeFtsQuery(raw: string): string {
23
- const tokens = (raw.match(TOKEN_RE) ?? []).slice(0, MAX_TOKENS);
24
- if (tokens.length === 0) return "";
25
- return tokens
26
- .map((t) => {
27
- const star = t.endsWith("*");
28
- const core = star ? t.slice(0, -1) : t;
29
- if (!core) return null; // trailing * with empty body
30
- const escaped = core.replace(/"/g, '""');
31
- return `"${escaped}"` + (star ? "*" : "");
32
- })
33
- .filter(Boolean)
34
- .join(" ");
35
- }