wiki-viewer 1.14.1 → 1.14.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (384) hide show
  1. package/.next/standalone/.next/BUILD_ID +1 -1
  2. package/.next/standalone/.next/build-manifest.json +3 -3
  3. package/.next/standalone/.next/server/app/_global-error.html +1 -1
  4. package/.next/standalone/.next/server/app/_global-error.rsc +1 -1
  5. package/.next/standalone/.next/server/app/_global-error.segments/__PAGE__.segment.rsc +1 -1
  6. package/.next/standalone/.next/server/app/_global-error.segments/_full.segment.rsc +1 -1
  7. package/.next/standalone/.next/server/app/_global-error.segments/_head.segment.rsc +1 -1
  8. package/.next/standalone/.next/server/app/_global-error.segments/_index.segment.rsc +1 -1
  9. package/.next/standalone/.next/server/app/_global-error.segments/_tree.segment.rsc +1 -1
  10. package/.next/standalone/.next/server/app/_not-found.html +1 -1
  11. package/.next/standalone/.next/server/app/_not-found.rsc +1 -1
  12. package/.next/standalone/.next/server/app/_not-found.segments/_full.segment.rsc +1 -1
  13. package/.next/standalone/.next/server/app/_not-found.segments/_head.segment.rsc +1 -1
  14. package/.next/standalone/.next/server/app/_not-found.segments/_index.segment.rsc +1 -1
  15. package/.next/standalone/.next/server/app/_not-found.segments/_not-found/__PAGE__.segment.rsc +1 -1
  16. package/.next/standalone/.next/server/app/_not-found.segments/_not-found.segment.rsc +1 -1
  17. package/.next/standalone/.next/server/app/_not-found.segments/_tree.segment.rsc +1 -1
  18. package/.next/standalone/.next/server/app/api/agent/activity/route.js.nft.json +1 -1
  19. package/.next/standalone/.next/server/app/api/agent/events/[...path]/route.js.nft.json +1 -1
  20. package/.next/standalone/.next/server/app/api/agent/files/[...path]/route.js.nft.json +1 -1
  21. package/.next/standalone/.next/server/app/api/agent/fs/file/[...path]/route.js.nft.json +1 -1
  22. package/.next/standalone/.next/server/app/api/agent/fs/ls/[[...path]]/route.js.nft.json +1 -1
  23. package/.next/standalone/.next/server/app/api/agent/fs/move/route.js.nft.json +1 -1
  24. package/.next/standalone/.next/server/app/api/agent/fs/search/route.js.nft.json +1 -1
  25. package/.next/standalone/.next/server/app/api/agent/internal/span/route.js.nft.json +1 -1
  26. package/.next/standalone/.next/server/app/api/agent/settings/route.js.nft.json +1 -1
  27. package/.next/standalone/.next/server/app/api/agent/sidecar/[...path]/route.js.nft.json +1 -1
  28. package/.next/standalone/.next/server/app/api/assets/[...path]/route.js.nft.json +1 -1
  29. package/.next/standalone/.next/server/app/api/share/[token]/route.js.nft.json +1 -1
  30. package/.next/standalone/.next/server/app/api/share/route.js.nft.json +1 -1
  31. package/.next/standalone/.next/server/app/api/system/reveal/route.js.nft.json +1 -1
  32. package/.next/standalone/.next/server/app/api/system/set-root/route.js.nft.json +1 -1
  33. package/.next/standalone/.next/server/app/api/system/workspaces/[id]/open/route.js.nft.json +1 -1
  34. package/.next/standalone/.next/server/app/api/system/workspaces/[id]/refresh/route.js.nft.json +1 -1
  35. package/.next/standalone/.next/server/app/api/system/workspaces/[id]/route.js.nft.json +1 -1
  36. package/.next/standalone/.next/server/app/api/system/workspaces/route.js.nft.json +1 -1
  37. package/.next/standalone/.next/server/app/api/upload/[...path]/route.js.nft.json +1 -1
  38. package/.next/standalone/.next/server/app/api/wiki/app/route.js.nft.json +1 -1
  39. package/.next/standalone/.next/server/app/api/wiki/backlinks/route.js.nft.json +1 -1
  40. package/.next/standalone/.next/server/app/api/wiki/content/route.js.nft.json +1 -1
  41. package/.next/standalone/.next/server/app/api/wiki/download/route.js.nft.json +1 -1
  42. package/.next/standalone/.next/server/app/api/wiki/file/route.js.nft.json +1 -1
  43. package/.next/standalone/.next/server/app/api/wiki/folder/route.js.nft.json +1 -1
  44. package/.next/standalone/.next/server/app/api/wiki/git-branches/route.js.nft.json +1 -1
  45. package/.next/standalone/.next/server/app/api/wiki/git-checkout/route.js.nft.json +1 -1
  46. package/.next/standalone/.next/server/app/api/wiki/git-diff/route.js.nft.json +1 -1
  47. package/.next/standalone/.next/server/app/api/wiki/git-file-info/route.js.nft.json +1 -1
  48. package/.next/standalone/.next/server/app/api/wiki/git-history/route.js.nft.json +1 -1
  49. package/.next/standalone/.next/server/app/api/wiki/git-pull/route.js.nft.json +1 -1
  50. package/.next/standalone/.next/server/app/api/wiki/move/route.js.nft.json +1 -1
  51. package/.next/standalone/.next/server/app/api/wiki/new-file/route.js.nft.json +1 -1
  52. package/.next/standalone/.next/server/app/api/wiki/outlinks/route.js.nft.json +1 -1
  53. package/.next/standalone/.next/server/app/api/wiki/page/route.js.nft.json +1 -1
  54. package/.next/standalone/.next/server/app/api/wiki/presence/route.js.nft.json +1 -1
  55. package/.next/standalone/.next/server/app/api/wiki/route.js.nft.json +1 -1
  56. package/.next/standalone/.next/server/app/api/wiki/search/route.js.nft.json +1 -1
  57. package/.next/standalone/.next/server/app/api/wiki/slugs/route.js.nft.json +1 -1
  58. package/.next/standalone/.next/server/app/api/wiki/upload/route.js.nft.json +1 -1
  59. package/.next/standalone/.next/server/app/api/wiki/watch/route.js.nft.json +1 -1
  60. package/.next/standalone/.next/server/app/index.html +1 -1
  61. package/.next/standalone/.next/server/app/index.rsc +1 -1
  62. package/.next/standalone/.next/server/app/index.segments/__PAGE__.segment.rsc +1 -1
  63. package/.next/standalone/.next/server/app/index.segments/_full.segment.rsc +1 -1
  64. package/.next/standalone/.next/server/app/index.segments/_head.segment.rsc +1 -1
  65. package/.next/standalone/.next/server/app/index.segments/_index.segment.rsc +1 -1
  66. package/.next/standalone/.next/server/app/index.segments/_tree.segment.rsc +1 -1
  67. package/.next/standalone/.next/server/middleware-build-manifest.js +3 -3
  68. package/.next/standalone/.next/server/middleware-manifest.json +1 -1
  69. package/.next/standalone/.next/server/pages/404.html +1 -1
  70. package/.next/standalone/.next/server/pages/500.html +1 -1
  71. package/.next/standalone/package.json +1 -1
  72. package/bin/postbuild.js +21 -0
  73. package/package.json +1 -1
  74. package/.next/standalone/.github/workflows/publish.yml +0 -37
  75. package/.next/standalone/.handoffs/archive/handoff-20260612-113332.md +0 -98
  76. package/.next/standalone/.handoffs/archive/handoff-20260612-141032.md +0 -73
  77. package/.next/standalone/.pi/ownership.json +0 -3
  78. package/.next/standalone/AGENTS.md +0 -114
  79. package/.next/standalone/DESIGN.md +0 -521
  80. package/.next/standalone/README.md +0 -821
  81. package/.next/standalone/TODO.md +0 -20
  82. package/.next/standalone/agents/bootstrap-prompt.md +0 -14
  83. package/.next/standalone/agents/wiki-viewer-skill/SKILL.md +0 -456
  84. package/.next/standalone/bin/postbuild.js +0 -78
  85. package/.next/standalone/bin/wiki-viewer.js +0 -922
  86. package/.next/standalone/certificates/localhost-key.pem +0 -28
  87. package/.next/standalone/certificates/localhost.pem +0 -24
  88. package/.next/standalone/docs/agent-collab-plan.md +0 -1615
  89. package/.next/standalone/docs/agent-collab-v2-plan.md +0 -771
  90. package/.next/standalone/docs/agent-fs-plan.md +0 -232
  91. package/.next/standalone/docs/editorial-skin-spec.md +0 -242
  92. package/.next/standalone/docs/file-vs-collab-authority.md +0 -124
  93. package/.next/standalone/docs/mobile-readiness-spec.md +0 -229
  94. package/.next/standalone/docs/workspacing-plan.md +0 -364
  95. package/.next/standalone/packages/wiki-viewer-mcp/README.md +0 -195
  96. package/.next/standalone/packages/wiki-viewer-mcp/bench-e2e.mjs +0 -166
  97. package/.next/standalone/packages/wiki-viewer-mcp/bench-latency.mjs +0 -87
  98. package/.next/standalone/packages/wiki-viewer-mcp/bench-payload.mjs +0 -45
  99. package/.next/standalone/packages/wiki-viewer-mcp/dist/http-client.js +0 -331
  100. package/.next/standalone/packages/wiki-viewer-mcp/dist/index.js +0 -531
  101. package/.next/standalone/packages/wiki-viewer-mcp/dist/register.js +0 -94
  102. package/.next/standalone/packages/wiki-viewer-mcp/dist/state-cache.js +0 -28
  103. package/.next/standalone/packages/wiki-viewer-mcp/package-lock.json +0 -1716
  104. package/.next/standalone/packages/wiki-viewer-mcp/package.json +0 -41
  105. package/.next/standalone/packages/wiki-viewer-mcp/src/http-client.ts +0 -459
  106. package/.next/standalone/packages/wiki-viewer-mcp/src/index.ts +0 -638
  107. package/.next/standalone/packages/wiki-viewer-mcp/src/register.ts +0 -144
  108. package/.next/standalone/packages/wiki-viewer-mcp/src/state-cache.ts +0 -55
  109. package/.next/standalone/packages/wiki-viewer-mcp/tsconfig.json +0 -19
  110. package/.next/standalone/pnpm-lock.yaml +0 -6697
  111. package/.next/standalone/pnpm-workspace.yaml +0 -8
  112. package/.next/standalone/postcss.config.mjs +0 -2
  113. package/.next/standalone/src/app/api/agent/activity/route.ts +0 -59
  114. package/.next/standalone/src/app/api/agent/admin/agents/[agentId]/revoke/route.ts +0 -40
  115. package/.next/standalone/src/app/api/agent/admin/agents/route.ts +0 -33
  116. package/.next/standalone/src/app/api/agent/admin/registrations/[regId]/approve/route.ts +0 -83
  117. package/.next/standalone/src/app/api/agent/admin/registrations/[regId]/deny/route.ts +0 -36
  118. package/.next/standalone/src/app/api/agent/admin/registrations/route.ts +0 -27
  119. package/.next/standalone/src/app/api/agent/events/[...path]/route.ts +0 -148
  120. package/.next/standalone/src/app/api/agent/files/[...path]/route.ts +0 -219
  121. package/.next/standalone/src/app/api/agent/fs/file/[...path]/route.ts +0 -446
  122. package/.next/standalone/src/app/api/agent/fs/ls/[[...path]]/route.ts +0 -152
  123. package/.next/standalone/src/app/api/agent/fs/move/route.ts +0 -130
  124. package/.next/standalone/src/app/api/agent/fs/search/route.ts +0 -272
  125. package/.next/standalone/src/app/api/agent/internal/span/route.ts +0 -121
  126. package/.next/standalone/src/app/api/agent/register/[regId]/route.ts +0 -50
  127. package/.next/standalone/src/app/api/agent/register/route.ts +0 -118
  128. package/.next/standalone/src/app/api/agent/settings/route.ts +0 -34
  129. package/.next/standalone/src/app/api/agent/settings/token/regenerate/route.ts +0 -20
  130. package/.next/standalone/src/app/api/agent/sidecar/[...path]/route.ts +0 -53
  131. package/.next/standalone/src/app/api/agents/install/route.ts +0 -143
  132. package/.next/standalone/src/app/api/agents/skill/route.ts +0 -20
  133. package/.next/standalone/src/app/api/agents/skill.tar.gz/route.ts +0 -87
  134. package/.next/standalone/src/app/api/app-proxy/[...path]/route.ts +0 -247
  135. package/.next/standalone/src/app/api/assets/[...path]/route.ts +0 -75
  136. package/.next/standalone/src/app/api/auth/[...all]/route.ts +0 -7
  137. package/.next/standalone/src/app/api/owner/init/route.ts +0 -14
  138. package/.next/standalone/src/app/api/share/[token]/route.ts +0 -269
  139. package/.next/standalone/src/app/api/share/route.ts +0 -127
  140. package/.next/standalone/src/app/api/system/admins/route.ts +0 -103
  141. package/.next/standalone/src/app/api/system/auth-config/route.ts +0 -22
  142. package/.next/standalone/src/app/api/system/auth-settings/route.ts +0 -86
  143. package/.next/standalone/src/app/api/system/browse/route.ts +0 -82
  144. package/.next/standalone/src/app/api/system/clear-root/route.ts +0 -16
  145. package/.next/standalone/src/app/api/system/config/route.ts +0 -14
  146. package/.next/standalone/src/app/api/system/pins/route.ts +0 -38
  147. package/.next/standalone/src/app/api/system/reveal/route.ts +0 -36
  148. package/.next/standalone/src/app/api/system/root-status/route.ts +0 -13
  149. package/.next/standalone/src/app/api/system/set-root/route.ts +0 -53
  150. package/.next/standalone/src/app/api/system/users/route.ts +0 -120
  151. package/.next/standalone/src/app/api/system/workspaces/[id]/open/route.ts +0 -34
  152. package/.next/standalone/src/app/api/system/workspaces/[id]/refresh/route.ts +0 -32
  153. package/.next/standalone/src/app/api/system/workspaces/[id]/route.ts +0 -78
  154. package/.next/standalone/src/app/api/system/workspaces/route.ts +0 -128
  155. package/.next/standalone/src/app/api/upload/[...path]/route.ts +0 -85
  156. package/.next/standalone/src/app/api/wiki/app/route.ts +0 -60
  157. package/.next/standalone/src/app/api/wiki/backlinks/route.ts +0 -29
  158. package/.next/standalone/src/app/api/wiki/content/route.ts +0 -159
  159. package/.next/standalone/src/app/api/wiki/download/route.ts +0 -100
  160. package/.next/standalone/src/app/api/wiki/file/route.ts +0 -57
  161. package/.next/standalone/src/app/api/wiki/folder/route.ts +0 -34
  162. package/.next/standalone/src/app/api/wiki/git-branches/route.ts +0 -32
  163. package/.next/standalone/src/app/api/wiki/git-checkout/route.ts +0 -45
  164. package/.next/standalone/src/app/api/wiki/git-diff/route.ts +0 -33
  165. package/.next/standalone/src/app/api/wiki/git-file-info/route.ts +0 -27
  166. package/.next/standalone/src/app/api/wiki/git-history/route.ts +0 -27
  167. package/.next/standalone/src/app/api/wiki/git-pull/route.ts +0 -48
  168. package/.next/standalone/src/app/api/wiki/move/route.ts +0 -61
  169. package/.next/standalone/src/app/api/wiki/new-file/route.ts +0 -56
  170. package/.next/standalone/src/app/api/wiki/outlinks/route.ts +0 -76
  171. package/.next/standalone/src/app/api/wiki/page/route.ts +0 -92
  172. package/.next/standalone/src/app/api/wiki/presence/route.ts +0 -56
  173. package/.next/standalone/src/app/api/wiki/route.ts +0 -116
  174. package/.next/standalone/src/app/api/wiki/search/route.ts +0 -44
  175. package/.next/standalone/src/app/api/wiki/slugs/route.ts +0 -54
  176. package/.next/standalone/src/app/api/wiki/upload/route.ts +0 -95
  177. package/.next/standalone/src/app/api/wiki/watch/route.ts +0 -67
  178. package/.next/standalone/src/app/globals.css +0 -1249
  179. package/.next/standalone/src/app/icon.svg +0 -11
  180. package/.next/standalone/src/app/layout.tsx +0 -78
  181. package/.next/standalone/src/app/manifest.ts +0 -30
  182. package/.next/standalone/src/app/page.tsx +0 -3260
  183. package/.next/standalone/src/app/s/[token]/page.tsx +0 -357
  184. package/.next/standalone/src/app/signin/page.tsx +0 -16
  185. package/.next/standalone/src/app/signin/signin-form.tsx +0 -238
  186. package/.next/standalone/src/components/ai-panel/activity-row.tsx +0 -284
  187. package/.next/standalone/src/components/ai-panel/ai-panel.tsx +0 -311
  188. package/.next/standalone/src/components/ai-panel/token-section.tsx +0 -313
  189. package/.next/standalone/src/components/auth-settings-sheet.tsx +0 -474
  190. package/.next/standalone/src/components/confirm-dialog.tsx +0 -56
  191. package/.next/standalone/src/components/dir-picker.tsx +0 -606
  192. package/.next/standalone/src/components/editor/backlinks-panel.tsx +0 -139
  193. package/.next/standalone/src/components/editor/bubble-menu.tsx +0 -346
  194. package/.next/standalone/src/components/editor/callout-extension.ts +0 -36
  195. package/.next/standalone/src/components/editor/comment-pip.tsx +0 -56
  196. package/.next/standalone/src/components/editor/comment-thread.tsx +0 -254
  197. package/.next/standalone/src/components/editor/csv-viewer.tsx +0 -379
  198. package/.next/standalone/src/components/editor/document-outline.tsx +0 -230
  199. package/.next/standalone/src/components/editor/editor-toolbar.tsx +0 -564
  200. package/.next/standalone/src/components/editor/editor.tsx +0 -1327
  201. package/.next/standalone/src/components/editor/extensions/drag-handle.ts +0 -325
  202. package/.next/standalone/src/components/editor/extensions/heading-anchors.ts +0 -55
  203. package/.next/standalone/src/components/editor/extensions/proof-span.ts +0 -60
  204. package/.next/standalone/src/components/editor/extensions/resizable-image.tsx +0 -159
  205. package/.next/standalone/src/components/editor/extensions.ts +0 -150
  206. package/.next/standalone/src/components/editor/file-fallback-viewer.tsx +0 -75
  207. package/.next/standalone/src/components/editor/folder-index.tsx +0 -236
  208. package/.next/standalone/src/components/editor/google-doc-viewer.tsx +0 -73
  209. package/.next/standalone/src/components/editor/image-viewer.tsx +0 -57
  210. package/.next/standalone/src/components/editor/large-file-gate.tsx +0 -108
  211. package/.next/standalone/src/components/editor/link-popover.tsx +0 -111
  212. package/.next/standalone/src/components/editor/media-popover.tsx +0 -212
  213. package/.next/standalone/src/components/editor/media-viewer.tsx +0 -70
  214. package/.next/standalone/src/components/editor/mermaid-viewer.tsx +0 -286
  215. package/.next/standalone/src/components/editor/node-app-viewer.tsx +0 -328
  216. package/.next/standalone/src/components/editor/notebook-viewer.tsx +0 -371
  217. package/.next/standalone/src/components/editor/office/docx-viewer.tsx +0 -93
  218. package/.next/standalone/src/components/editor/office/office-chrome.tsx +0 -83
  219. package/.next/standalone/src/components/editor/office/pptx-viewer.tsx +0 -104
  220. package/.next/standalone/src/components/editor/office/xlsx-viewer.tsx +0 -192
  221. package/.next/standalone/src/components/editor/pdf-viewer.tsx +0 -32
  222. package/.next/standalone/src/components/editor/proof-span-popover.tsx +0 -162
  223. package/.next/standalone/src/components/editor/slash-commands.tsx +0 -629
  224. package/.next/standalone/src/components/editor/source-viewer.tsx +0 -289
  225. package/.next/standalone/src/components/editor/suggest-edit-popover.tsx +0 -229
  226. package/.next/standalone/src/components/editor/suggestion-card.tsx +0 -206
  227. package/.next/standalone/src/components/editor/table-menu.tsx +0 -232
  228. package/.next/standalone/src/components/editor/view-mode-comment-button.tsx +0 -77
  229. package/.next/standalone/src/components/editor/website-viewer.tsx +0 -75
  230. package/.next/standalone/src/components/editor/wiki-link-create-dialog.tsx +0 -189
  231. package/.next/standalone/src/components/editor/wiki-link-decorator.ts +0 -79
  232. package/.next/standalone/src/components/editor/wiki-link-extension.ts +0 -120
  233. package/.next/standalone/src/components/editor/wiki-link-picker.tsx +0 -250
  234. package/.next/standalone/src/components/layout/viewer-toolbar.tsx +0 -54
  235. package/.next/standalone/src/components/search/search-command-dialog.tsx +0 -246
  236. package/.next/standalone/src/components/search/sidebar-search-box.tsx +0 -121
  237. package/.next/standalone/src/components/search/snippet-text.tsx +0 -48
  238. package/.next/standalone/src/components/share-dialog.tsx +0 -307
  239. package/.next/standalone/src/components/theme-provider.tsx +0 -16
  240. package/.next/standalone/src/components/theme-toggle.tsx +0 -24
  241. package/.next/standalone/src/components/ui/badge.tsx +0 -35
  242. package/.next/standalone/src/components/ui/button.tsx +0 -56
  243. package/.next/standalone/src/components/ui/card.tsx +0 -63
  244. package/.next/standalone/src/components/ui/collapsible.tsx +0 -9
  245. package/.next/standalone/src/components/ui/command.tsx +0 -151
  246. package/.next/standalone/src/components/ui/context-menu.tsx +0 -191
  247. package/.next/standalone/src/components/ui/dialog.tsx +0 -119
  248. package/.next/standalone/src/components/ui/dropdown-menu.tsx +0 -194
  249. package/.next/standalone/src/components/ui/input.tsx +0 -22
  250. package/.next/standalone/src/components/ui/label.tsx +0 -25
  251. package/.next/standalone/src/components/ui/popover.tsx +0 -33
  252. package/.next/standalone/src/components/ui/scroll-area.tsx +0 -47
  253. package/.next/standalone/src/components/ui/select.tsx +0 -156
  254. package/.next/standalone/src/components/ui/separator.tsx +0 -30
  255. package/.next/standalone/src/components/ui/sheet.tsx +0 -140
  256. package/.next/standalone/src/components/ui/skeleton.tsx +0 -15
  257. package/.next/standalone/src/components/ui/switch.tsx +0 -28
  258. package/.next/standalone/src/components/ui/tabs.tsx +0 -54
  259. package/.next/standalone/src/components/ui/textarea.tsx +0 -21
  260. package/.next/standalone/src/components/ui/tip.tsx +0 -23
  261. package/.next/standalone/src/components/ui/toggle-group.tsx +0 -41
  262. package/.next/standalone/src/components/ui/tooltip.tsx +0 -27
  263. package/.next/standalone/src/components/view-width-toggle.tsx +0 -70
  264. package/.next/standalone/src/components/wiki/frontmatter-header.tsx +0 -164
  265. package/.next/standalone/src/hooks/use-is-mobile.ts +0 -14
  266. package/.next/standalone/src/lib/app-runner.ts +0 -272
  267. package/.next/standalone/src/lib/auth/admin.ts +0 -120
  268. package/.next/standalone/src/lib/auth/allowlist.ts +0 -50
  269. package/.next/standalone/src/lib/auth/client.ts +0 -4
  270. package/.next/standalone/src/lib/auth/csrf.ts +0 -68
  271. package/.next/standalone/src/lib/auth/server.ts +0 -215
  272. package/.next/standalone/src/lib/cabinets/tree.ts +0 -75
  273. package/.next/standalone/src/lib/config.ts +0 -114
  274. package/.next/standalone/src/lib/embeds/detect.ts +0 -142
  275. package/.next/standalone/src/lib/git-secrets.ts +0 -65
  276. package/.next/standalone/src/lib/git.ts +0 -503
  277. package/.next/standalone/src/lib/google/detect.ts +0 -107
  278. package/.next/standalone/src/lib/markdown/parse-frontmatter.ts +0 -104
  279. package/.next/standalone/src/lib/markdown/remark-wikilinks.ts +0 -100
  280. package/.next/standalone/src/lib/markdown/sanitize-schema.ts +0 -106
  281. package/.next/standalone/src/lib/markdown/to-html.ts +0 -282
  282. package/.next/standalone/src/lib/markdown/to-markdown.ts +0 -252
  283. package/.next/standalone/src/lib/proof/activity-shared.ts +0 -31
  284. package/.next/standalone/src/lib/proof/activity.ts +0 -74
  285. package/.next/standalone/src/lib/proof/audit.ts +0 -88
  286. package/.next/standalone/src/lib/proof/auth.ts +0 -143
  287. package/.next/standalone/src/lib/proof/block-refs.ts +0 -133
  288. package/.next/standalone/src/lib/proof/blocks.ts +0 -73
  289. package/.next/standalone/src/lib/proof/client-auth.ts +0 -23
  290. package/.next/standalone/src/lib/proof/collab-state.ts +0 -81
  291. package/.next/standalone/src/lib/proof/event-bus.ts +0 -47
  292. package/.next/standalone/src/lib/proof/file-lock.ts +0 -43
  293. package/.next/standalone/src/lib/proof/glob.ts +0 -51
  294. package/.next/standalone/src/lib/proof/idempotency.ts +0 -37
  295. package/.next/standalone/src/lib/proof/lease.ts +0 -117
  296. package/.next/standalone/src/lib/proof/mutex.ts +0 -36
  297. package/.next/standalone/src/lib/proof/ops-applier.ts +0 -727
  298. package/.next/standalone/src/lib/proof/owner-auth.ts +0 -2
  299. package/.next/standalone/src/lib/proof/pending.ts +0 -97
  300. package/.next/standalone/src/lib/proof/proof-span.ts +0 -141
  301. package/.next/standalone/src/lib/proof/rate-limit.ts +0 -53
  302. package/.next/standalone/src/lib/proof/raw-fs.ts +0 -197
  303. package/.next/standalone/src/lib/proof/register-rate-limit.ts +0 -53
  304. package/.next/standalone/src/lib/proof/registry.ts +0 -195
  305. package/.next/standalone/src/lib/proof/sidecar.ts +0 -103
  306. package/.next/standalone/src/lib/proof/suggest-capture.ts +0 -69
  307. package/.next/standalone/src/lib/proof/types.ts +0 -182
  308. package/.next/standalone/src/lib/proof-config.ts +0 -14
  309. package/.next/standalone/src/lib/root-dir.ts +0 -35
  310. package/.next/standalone/src/lib/search/indexable-exts.ts +0 -25
  311. package/.next/standalone/src/lib/search/indexer.ts +0 -634
  312. package/.next/standalone/src/lib/search/sanitize.ts +0 -35
  313. package/.next/standalone/src/lib/search/search-db.ts +0 -57
  314. package/.next/standalone/src/lib/search/watcher-pool.ts +0 -79
  315. package/.next/standalone/src/lib/shared-docs/db.ts +0 -177
  316. package/.next/standalone/src/lib/toast.ts +0 -9
  317. package/.next/standalone/src/lib/utils.ts +0 -6
  318. package/.next/standalone/src/lib/wiki-helpers.ts +0 -36
  319. package/.next/standalone/src/lib/workspace-client.ts +0 -82
  320. package/.next/standalone/src/lib/workspace-context.ts +0 -173
  321. package/.next/standalone/src/lib/workspaces.ts +0 -400
  322. package/.next/standalone/src/middleware.ts +0 -44
  323. package/.next/standalone/src/stores/ai-panel-store.ts +0 -79
  324. package/.next/standalone/src/stores/editor-store.ts +0 -439
  325. package/.next/standalone/src/stores/pin-store.ts +0 -56
  326. package/.next/standalone/src/stores/proof-store.ts +0 -124
  327. package/.next/standalone/src/stores/recent-store.ts +0 -51
  328. package/.next/standalone/src/stores/search-store.ts +0 -104
  329. package/.next/standalone/src/stores/show-hidden-store.ts +0 -26
  330. package/.next/standalone/src/stores/sidebar-width-store.ts +0 -39
  331. package/.next/standalone/src/stores/skin-store.ts +0 -42
  332. package/.next/standalone/src/stores/tree-store.ts +0 -52
  333. package/.next/standalone/src/stores/view-width-store.ts +0 -101
  334. package/.next/standalone/src/stores/wiki-slugs-store.ts +0 -75
  335. package/.next/standalone/src/tests/proof/activity-aggregator.test.ts +0 -146
  336. package/.next/standalone/src/tests/proof/admin-create-user.test.ts +0 -43
  337. package/.next/standalone/src/tests/proof/agent-fs.test.ts +0 -973
  338. package/.next/standalone/src/tests/proof/agent-ownership.test.ts +0 -140
  339. package/.next/standalone/src/tests/proof/agent-workspace-scope.test.ts +0 -134
  340. package/.next/standalone/src/tests/proof/agents-install.test.ts +0 -110
  341. package/.next/standalone/src/tests/proof/bench-write.ts +0 -179
  342. package/.next/standalone/src/tests/proof/better-auth.test.ts +0 -68
  343. package/.next/standalone/src/tests/proof/block-refs.test.ts +0 -108
  344. package/.next/standalone/src/tests/proof/blocks.test.ts +0 -92
  345. package/.next/standalone/src/tests/proof/collab-state.test.ts +0 -501
  346. package/.next/standalone/src/tests/proof/comments-ops.test.ts +0 -177
  347. package/.next/standalone/src/tests/proof/editor-roundtrip.test.ts +0 -85
  348. package/.next/standalone/src/tests/proof/external-edit.test.ts +0 -58
  349. package/.next/standalone/src/tests/proof/file-lock.test.ts +0 -80
  350. package/.next/standalone/src/tests/proof/git-branches-checkout.test.ts +0 -136
  351. package/.next/standalone/src/tests/proof/git-read-features.test.ts +0 -473
  352. package/.next/standalone/src/tests/proof/git-secrets.test.ts +0 -138
  353. package/.next/standalone/src/tests/proof/git-sparse.test.ts +0 -257
  354. package/.next/standalone/src/tests/proof/git-workspace.test.ts +0 -135
  355. package/.next/standalone/src/tests/proof/git.test.ts +0 -243
  356. package/.next/standalone/src/tests/proof/glob.test.ts +0 -82
  357. package/.next/standalone/src/tests/proof/helpers/auth-session.ts +0 -27
  358. package/.next/standalone/src/tests/proof/markdown-to-html.test.ts +0 -46
  359. package/.next/standalone/src/tests/proof/ops-applier.test.ts +0 -368
  360. package/.next/standalone/src/tests/proof/owner-init.test.ts +0 -2
  361. package/.next/standalone/src/tests/proof/parse-frontmatter.test.ts +0 -60
  362. package/.next/standalone/src/tests/proof/preload.ts +0 -21
  363. package/.next/standalone/src/tests/proof/proof-span.test.ts +0 -98
  364. package/.next/standalone/src/tests/proof/rate-limit.test.ts +0 -54
  365. package/.next/standalone/src/tests/proof/readonly-enforcement.test.ts +0 -161
  366. package/.next/standalone/src/tests/proof/reconcile-sidecar.test.ts +0 -195
  367. package/.next/standalone/src/tests/proof/registration-flow.test.ts +0 -330
  368. package/.next/standalone/src/tests/proof/registry.test.ts +0 -169
  369. package/.next/standalone/src/tests/proof/routes.test.ts +0 -516
  370. package/.next/standalone/src/tests/proof/search-index.test.ts +0 -376
  371. package/.next/standalone/src/tests/proof/sidecar-lifecycle.test.ts +0 -177
  372. package/.next/standalone/src/tests/proof/sidecar-trim.test.ts +0 -58
  373. package/.next/standalone/src/tests/proof/suggestion-ops.test.ts +0 -280
  374. package/.next/standalone/src/tests/proof/wiki-content-put.test.ts +0 -140
  375. package/.next/standalone/src/tests/proof/wiki-routes-auth.test.ts +0 -208
  376. package/.next/standalone/src/tests/proof/workspace-isolation.test.ts +0 -87
  377. package/.next/standalone/src/tests/proof/workspaces-api.test.ts +0 -227
  378. package/.next/standalone/src/types/index.ts +0 -47
  379. package/.next/standalone/tailwind.config.ts +0 -191
  380. package/.next/standalone/tsconfig.json +0 -41
  381. package/.next/standalone/tsconfig.tsbuildinfo +0 -1
  382. /package/.next/standalone/.next/static/{WMOTgfV82apmdovxzgbMx → rRyvFORvJoc5OWbCR2A_P}/_buildManifest.js +0 -0
  383. /package/.next/standalone/.next/static/{WMOTgfV82apmdovxzgbMx → rRyvFORvJoc5OWbCR2A_P}/_clientMiddlewareManifest.js +0 -0
  384. /package/.next/standalone/.next/static/{WMOTgfV82apmdovxzgbMx → rRyvFORvJoc5OWbCR2A_P}/_ssgManifest.js +0 -0
@@ -1,446 +0,0 @@
1
- /**
2
- * Tier-1 Raw FS — file read/write/delete.
3
- *
4
- * GET /api/agent/fs/file/<path> Read raw bytes (Range supported).
5
- * PUT /api/agent/fs/file/<path> Atomic whole-file write.
6
- * DELETE /api/agent/fs/file/<path> Delete file (+ sidecar for .md).
7
- */
8
- export const runtime = "nodejs";
9
-
10
- import { readFile, stat, unlink, rm } from "node:fs/promises";
11
- import path from "node:path";
12
- import { NextResponse } from "next/server";
13
- import { checkAuth, enforceScope } from "@/lib/proof/auth";
14
- import { resolveWorkspaceForAgent } from "@/lib/workspace-context";
15
- import { safeWorkspacePath } from "@/lib/workspaces";
16
- import { withFileMutex } from "@/lib/proof/mutex";
17
- import { readSidecar, emptySidecar, deleteSidecar } from "@/lib/proof/sidecar";
18
- import { reconcileSidecar } from "@/lib/proof/ops-applier";
19
- import { writeAuditRow } from "@/lib/proof/audit";
20
- import {
21
- safeAbsPath,
22
- sha256ofBuf,
23
- extractShaHex,
24
- mimeByExt,
25
- isMarkdown,
26
- atomicWrite,
27
- ensureParentDir,
28
- looksLikeBinary,
29
- } from "@/lib/proof/raw-fs";
30
- import { computeCollabState } from "@/lib/proof/collab-state";
31
-
32
- // ── Helpers ──────────────────────────────────────────────────────────────────
33
-
34
- function rel(segments: string[]): string {
35
- return segments.join("/");
36
- }
37
-
38
- function errJson(code: string, message: string, status: number): NextResponse {
39
- return NextResponse.json({ error: code, message }, { status });
40
- }
41
-
42
- // ── GET ──────────────────────────────────────────────────────────────────────
43
-
44
- export async function GET(
45
- req: Request,
46
- { params }: { params: Promise<{ path: string[] }> },
47
- ): Promise<NextResponse> {
48
- const auth = await checkAuth(req);
49
- if (!auth.ok) return errJson("UNAUTHORIZED", auth.message ?? "Unauthorized", 401);
50
-
51
- const { path: segments } = await params;
52
- const relPath = rel(segments);
53
-
54
- const wsx = await resolveWorkspaceForAgent(req);
55
- if (!wsx.ok) return errJson(wsx.code, wsx.code, wsx.status);
56
- const { ws, rootDir } = wsx;
57
-
58
- const basic = safeWorkspacePath(rootDir, relPath);
59
- if (!basic) return errJson("INVALID_PATH", "Path traversal rejected", 400);
60
-
61
- const absPath = await safeAbsPath(rootDir, relPath);
62
- if (!absPath) return errJson("INVALID_PATH", "Path rejected (symlink escape or denied)", 400);
63
-
64
- const scope = enforceScope(auth.agent, { filePath: relPath, op: "read", workspaceId: ws.id });
65
- if (!scope.ok) return errJson(scope.code, scope.message, 403);
66
-
67
- let data: Buffer;
68
- let fileStat: Awaited<ReturnType<typeof stat>>;
69
- try {
70
- [data, fileStat] = await Promise.all([readFile(absPath), stat(absPath)]);
71
- } catch (e) {
72
- if ((e as NodeJS.ErrnoException).code === "ENOENT") {
73
- return errJson("NOT_FOUND", "File not found", 404);
74
- }
75
- throw e;
76
- }
77
-
78
- if (fileStat.isDirectory()) {
79
- return errJson("IS_DIRECTORY", "Path is a directory; use /api/agent/fs/ls/", 400);
80
- }
81
-
82
- const sha = sha256ofBuf(data);
83
- const baseHeaders: Record<string, string> = {
84
- "ETag": `"${sha}"`,
85
- "X-File-Size": String(fileStat.size),
86
- "X-File-Mtime": fileStat.mtime.toISOString(),
87
- "Content-Type": mimeByExt(relPath),
88
- "Accept-Ranges": "bytes",
89
- };
90
-
91
- // X-Collab-* headers (§3.5 mode signal)
92
- const collab = await computeCollabState(rootDir, relPath);
93
- if (collab.state !== "not-markdown") {
94
- baseHeaders["X-Collab-State"] = collab.state;
95
- baseHeaders["X-Collab-Revision"] = String(collab.revision);
96
- baseHeaders["X-Collab-Snapshot"] = collab.snapshotUrl!;
97
- } else {
98
- baseHeaders["X-Collab-State"] = collab.state;
99
- }
100
-
101
- const rangeHeader = req.headers.get("range");
102
- if (rangeHeader) {
103
- const match = /^bytes=(\d+)-(\d*)$/.exec(rangeHeader);
104
- if (!match) {
105
- return new NextResponse("Invalid Range header", { status: 416 });
106
- }
107
- const start = parseInt(match[1]!, 10);
108
- const endRaw = match[2] ? parseInt(match[2], 10) : data.length - 1;
109
- if (start > endRaw || start >= data.length) {
110
- return new NextResponse(null, {
111
- status: 416,
112
- headers: { "Content-Range": `bytes */${data.length}` },
113
- });
114
- }
115
- const end = Math.min(endRaw, data.length - 1);
116
- const slice = data.slice(start, end + 1);
117
- return new NextResponse(slice as unknown as BodyInit, {
118
- status: 206,
119
- headers: {
120
- ...baseHeaders,
121
- "Content-Range": `bytes ${start}-${end}/${data.length}`,
122
- "Content-Length": String(slice.length),
123
- },
124
- });
125
- }
126
-
127
- return new NextResponse(data as unknown as BodyInit, {
128
- status: 200,
129
- headers: { ...baseHeaders, "Content-Length": String(data.length) },
130
- });
131
- }
132
-
133
- // ── Shared mutation path (PUT + PATCH) ────────────────────────────────────────
134
-
135
- /**
136
- * Single code path for all Tier-1 byte mutations so PUT and PATCH cannot drift
137
- * on auth/scope/If-Match/R6/atomicWrite/reconcile/audit.
138
- *
139
- * `computeNewBody` receives the existing file buffer (or null if absent) and
140
- * returns the new bytes, or an error response to short-circuit (e.g. PATCH
141
- * match-count mismatch). `op` is the audit verb ("put" | "patch").
142
- */
143
- async function applyMutation(
144
- req: Request,
145
- segments: string[],
146
- opts: {
147
- op: "put" | "patch";
148
- allowCreate: boolean;
149
- computeNewBody: (existing: Buffer | null) => Buffer | NextResponse;
150
- },
151
- ): Promise<NextResponse> {
152
- const auth = await checkAuth(req);
153
- if (!auth.ok) return errJson("UNAUTHORIZED", auth.message ?? "Unauthorized", 401);
154
-
155
- const wsx = await resolveWorkspaceForAgent(req, "write");
156
- if (!wsx.ok) return errJson(wsx.code, wsx.code, wsx.status);
157
- const { ws, rootDir } = wsx;
158
-
159
- const relPath = rel(segments);
160
- const url = new URL(req.url);
161
- const mkdirs = url.searchParams.get("mkdirs") === "true";
162
- const force = url.searchParams.get("force") === "true";
163
-
164
- const basic = safeWorkspacePath(rootDir, relPath);
165
- if (!basic) return errJson("INVALID_PATH", "Path traversal rejected", 400);
166
-
167
- const absPath = await safeAbsPath(rootDir, relPath);
168
- if (!absPath) return errJson("INVALID_PATH", "Path rejected (symlink escape or denied)", 400);
169
-
170
- const scope = enforceScope(auth.agent, { filePath: relPath, op: "mutate", workspaceId: ws.id });
171
- if (!scope.ok) return errJson(scope.code, scope.message, 403);
172
-
173
- const ifMatch = req.headers.get("if-match");
174
- const ifCollabMatch = req.headers.get("if-collab-match");
175
-
176
- // The whole read-existing → precondition → compute → write → reconcile → audit
177
- // sequence runs inside the mutex for .md (so R6 and reconcile are atomic with
178
- // the write); non-.md runs it without the mutex.
179
- const doMutation = async (): Promise<NextResponse> => {
180
- // Read existing
181
- let existingBuf: Buffer | null = null;
182
- let existingSha: string | undefined;
183
- try {
184
- existingBuf = await readFile(absPath);
185
- existingSha = sha256ofBuf(existingBuf);
186
- } catch (e) {
187
- if ((e as NodeJS.ErrnoException).code !== "ENOENT") throw e;
188
- }
189
- const existed = existingBuf !== null;
190
-
191
- if (existed) {
192
- // Overwrite: If-Match required by default (unless ?force=true)
193
- if (!force && !ifMatch) {
194
- return errJson(
195
- "PRECONDITION_REQUIRED",
196
- "If-Match header required for overwrites (use ?force=true to bypass with audit)",
197
- 412,
198
- );
199
- }
200
- if (ifMatch && extractShaHex(ifMatch) !== extractShaHex(existingSha!)) {
201
- return errJson("PRECONDITION_FAILED", "If-Match sha256 mismatch", 412);
202
- }
203
- } else {
204
- if (!opts.allowCreate) {
205
- return errJson("NOT_FOUND", "File not found", 404);
206
- }
207
- const parentOk = await ensureParentDir(absPath, mkdirs);
208
- if (!parentOk) {
209
- return errJson(
210
- "PARENT_NOT_FOUND",
211
- "Parent directory does not exist (use ?mkdirs=true to create)",
212
- 400,
213
- );
214
- }
215
- }
216
-
217
- // R6: for .md, re-check collab state atomically (inside mutex)
218
- if (isMarkdown(relPath)) {
219
- const { state, revision, snapshotUrl } = await computeCollabState(rootDir, relPath);
220
- if (state === "active") {
221
- const matchVal = ifCollabMatch?.trim();
222
- if (!force && (!matchVal || matchVal !== String(revision))) {
223
- return NextResponse.json(
224
- {
225
- error: "COLLAB_ACTIVE",
226
- message:
227
- "File is in active collaborative session. Use block-ops (Tier-2) or supply a matching If-Collab-Match header. Use ?force=true to override (audited).",
228
- snapshotUrl,
229
- revision,
230
- },
231
- { status: 409 },
232
- );
233
- }
234
- }
235
- }
236
-
237
- // Compute new bytes (PUT: request body; PATCH: str-replace on existing)
238
- const computed = opts.computeNewBody(existingBuf);
239
- if (computed instanceof NextResponse) return computed;
240
- const bodyBuf = computed;
241
- const newSha = sha256ofBuf(bodyBuf);
242
-
243
- await atomicWrite(absPath, bodyBuf);
244
-
245
- if (isMarkdown(relPath)) {
246
- const content = bodyBuf.toString("utf-8");
247
- const sidecar = (await readSidecar(rootDir, relPath)) ?? emptySidecar(relPath);
248
- await reconcileSidecar({
249
- rootDir,
250
- mdPath: relPath,
251
- content,
252
- sidecar,
253
- by: auth.agent.id,
254
- eventType: "file.rawWritten",
255
- fingerprint: newSha,
256
- });
257
- }
258
-
259
- writeAuditRow({
260
- agentId: auth.agent.id,
261
- op: opts.op,
262
- path: relPath,
263
- oldSha: existingSha,
264
- newSha,
265
- forced: force,
266
- workspaceId: ws.id,
267
- });
268
-
269
- const st = await stat(absPath);
270
- return NextResponse.json({
271
- path: relPath,
272
- sha256: newSha,
273
- size: st.size,
274
- mtime: st.mtime.toISOString(),
275
- created: !existed,
276
- });
277
- };
278
-
279
- return isMarkdown(relPath) ? withFileMutex(`${rootDir}\u0000${relPath}`, doMutation) : doMutation();
280
- }
281
-
282
- // ── PUT ──────────────────────────────────────────────────────────────────────
283
-
284
- export async function PUT(
285
- req: Request,
286
- { params }: { params: Promise<{ path: string[] }> },
287
- ): Promise<NextResponse> {
288
- const { path: segments } = await params;
289
- const bodyBuf = Buffer.from(await req.arrayBuffer());
290
- return applyMutation(req, segments, {
291
- op: "put",
292
- allowCreate: true,
293
- computeNewBody: () => bodyBuf,
294
- });
295
- }
296
-
297
- // ── PATCH ─────────────────────────────────────────────────────────────────────
298
- // Server-side str-replace so agents send only the change, not the whole file.
299
- // Strict: exact substring (no regex), text/UTF-8 only, If-Match required,
300
- // expectedOccurrences must match exactly (default 1). Shares applyMutation, so
301
- // lock / R6 / reconcile / audit behave identically to PUT.
302
-
303
- const MAX_PATCH_STRING = 1_000_000; // 1MB cap on find/replace strings
304
-
305
- export async function PATCH(
306
- req: Request,
307
- { params }: { params: Promise<{ path: string[] }> },
308
- ): Promise<NextResponse> {
309
- const { path: segments } = await params;
310
-
311
- let body: { find?: unknown; replace?: unknown; expectedOccurrences?: unknown };
312
- try {
313
- body = (await req.json()) as typeof body;
314
- } catch {
315
- return errJson("INVALID_PAYLOAD", "Body must be JSON {find, replace, expectedOccurrences?}", 400);
316
- }
317
- const find = body.find;
318
- const replace = body.replace;
319
- if (typeof find !== "string" || typeof replace !== "string") {
320
- return errJson("INVALID_PAYLOAD", "find and replace must be strings", 400);
321
- }
322
- if (find.length === 0) {
323
- return errJson("INVALID_PAYLOAD", "find must not be empty", 400);
324
- }
325
- if (find.length > MAX_PATCH_STRING || replace.length > MAX_PATCH_STRING) {
326
- return errJson("PAYLOAD_TOO_LARGE", "find/replace exceeds 1MB limit", 413);
327
- }
328
- let expected = 1;
329
- if (body.expectedOccurrences !== undefined) {
330
- if (typeof body.expectedOccurrences !== "number" || !Number.isInteger(body.expectedOccurrences) || body.expectedOccurrences < 1) {
331
- return errJson("INVALID_PAYLOAD", "expectedOccurrences must be a positive integer", 400);
332
- }
333
- expected = body.expectedOccurrences;
334
- }
335
-
336
- return applyMutation(req, segments, {
337
- op: "patch",
338
- allowCreate: false, // patch only edits existing files
339
- computeNewBody: (existing) => {
340
- if (existing === null) return errJson("NOT_FOUND", "File not found", 404);
341
- if (looksLikeBinary(existing)) {
342
- return errJson("UNSUPPORTED", "Cannot patch binary / non-text file", 415);
343
- }
344
- let text: string;
345
- try {
346
- text = new TextDecoder("utf-8", { fatal: true }).decode(existing);
347
- } catch {
348
- return errJson("UNSUPPORTED", "File is not valid UTF-8", 415);
349
- }
350
- // Count exact occurrences (no regex).
351
- let count = 0;
352
- let idx = text.indexOf(find);
353
- while (idx !== -1) {
354
- count++;
355
- idx = text.indexOf(find, idx + find.length);
356
- }
357
- if (count !== expected) {
358
- return NextResponse.json(
359
- {
360
- error: "MATCH_COUNT_MISMATCH",
361
- message: `Expected ${expected} occurrence(s) of find, found ${count}. Re-read the file or adjust expectedOccurrences.`,
362
- found: count,
363
- expected,
364
- },
365
- { status: 422 },
366
- );
367
- }
368
- // Replace all (count == expected) occurrences, literally.
369
- return Buffer.from(text.split(find).join(replace), "utf-8");
370
- },
371
- });
372
- }
373
-
374
- // ── DELETE ───────────────────────────────────────────────────────────────────
375
-
376
- export async function DELETE(
377
- req: Request,
378
- { params }: { params: Promise<{ path: string[] }> },
379
- ): Promise<NextResponse> {
380
- const auth = await checkAuth(req);
381
- if (!auth.ok) return errJson("UNAUTHORIZED", auth.message ?? "Unauthorized", 401);
382
-
383
- const { path: segments } = await params;
384
- const relPath = rel(segments);
385
- const url = new URL(req.url);
386
- const recursive = url.searchParams.get("recursive") === "true";
387
-
388
- const wsx = await resolveWorkspaceForAgent(req, "write");
389
- if (!wsx.ok) return errJson(wsx.code, wsx.code, wsx.status);
390
- const { ws, rootDir } = wsx;
391
-
392
- const basic = safeWorkspacePath(rootDir, relPath);
393
- if (!basic) return errJson("INVALID_PATH", "Path traversal rejected", 400);
394
-
395
- const absPath = await safeAbsPath(rootDir, relPath);
396
- if (!absPath) return errJson("INVALID_PATH", "Path rejected (symlink escape or denied)", 400);
397
-
398
- // Requires "delete" scope op
399
- const scope = enforceScope(auth.agent, { filePath: relPath, op: "delete", workspaceId: ws.id });
400
- if (!scope.ok) return errJson(scope.code, scope.message, 403);
401
-
402
- const ifMatch = req.headers.get("if-match");
403
-
404
- let fileStat: Awaited<ReturnType<typeof stat>>;
405
- try {
406
- fileStat = await stat(absPath);
407
- } catch (e) {
408
- if ((e as NodeJS.ErrnoException).code === "ENOENT") {
409
- return errJson("NOT_FOUND", "File not found", 404);
410
- }
411
- throw e;
412
- }
413
-
414
- if (fileStat.isDirectory()) {
415
- if (!recursive) {
416
- return errJson("IS_DIRECTORY", "Use ?recursive=true to delete a directory", 400);
417
- }
418
- // Directory delete — no single sha, skip If-Match; require recursive flag as confirmation
419
- await rm(absPath, { recursive: true, force: true });
420
- writeAuditRow({ agentId: auth.agent.id, op: "delete", path: relPath, forced: false, workspaceId: ws.id });
421
- return NextResponse.json({ deleted: relPath });
422
- }
423
-
424
- // File: If-Match required as confirmation
425
- if (!ifMatch) {
426
- return errJson("PRECONDITION_REQUIRED", "If-Match header required for delete", 412);
427
- }
428
-
429
- const existing = await readFile(absPath);
430
- const existingSha = sha256ofBuf(existing);
431
- if (extractShaHex(ifMatch) !== extractShaHex(existingSha)) {
432
- return errJson("PRECONDITION_FAILED", "If-Match sha256 mismatch", 412);
433
- }
434
-
435
- if (isMarkdown(relPath)) {
436
- await withFileMutex(`${rootDir}\u0000${relPath}`, async () => {
437
- await unlink(absPath);
438
- await deleteSidecar(rootDir, relPath);
439
- });
440
- } else {
441
- await unlink(absPath);
442
- }
443
-
444
- writeAuditRow({ agentId: auth.agent.id, op: "delete", path: relPath, oldSha: existingSha, forced: false, workspaceId: ws.id });
445
- return NextResponse.json({ deleted: relPath });
446
- }
@@ -1,152 +0,0 @@
1
- /**
2
- * Tier-1 Raw FS — directory listing.
3
- *
4
- * GET /api/agent/fs/ls[/<path>]?recursive&limit=N&depth=N
5
- *
6
- * Returns {path, entries, truncated}.
7
- * Each entry: {name, path, type, size?, mtime?}.
8
- * Excludes .proof/ and .git/. Scope-filters every returned path.
9
- */
10
- export const runtime = "nodejs";
11
-
12
- import { readdir, stat } from "node:fs/promises";
13
- import path from "node:path";
14
- import { NextResponse } from "next/server";
15
- import { checkAuth, enforceScope } from "@/lib/proof/auth";
16
- import { resolveWorkspaceForAgent } from "@/lib/workspace-context";
17
- import { safeWorkspacePath } from "@/lib/workspaces";
18
- import { safeAbsPath } from "@/lib/proof/raw-fs";
19
- import type { Agent } from "@/lib/proof/registry";
20
-
21
- const HARD_MAX_ENTRIES = 10_000;
22
- const HARD_MAX_DEPTH = 20;
23
-
24
- export interface LsEntry {
25
- name: string;
26
- path: string;
27
- type: "file" | "dir" | "symlink";
28
- size?: number;
29
- mtime?: string;
30
- }
31
-
32
- function errJson(code: string, message: string, status: number): NextResponse {
33
- return NextResponse.json({ error: code, message }, { status });
34
- }
35
-
36
- /** Skip these names at any depth */
37
- const SKIP_NAMES = new Set([".proof", ".git"]);
38
-
39
- async function walkDir(
40
- rootDir: string,
41
- relDir: string,
42
- agent: Agent,
43
- recursive: boolean,
44
- depth: number,
45
- maxDepth: number,
46
- limit: number,
47
- results: LsEntry[],
48
- workspaceId?: string,
49
- ): Promise<void> {
50
- if (depth > maxDepth || results.length >= limit) return;
51
-
52
- const absDir = path.join(rootDir, relDir);
53
- // eslint-disable-next-line @typescript-eslint/no-explicit-any
54
- let items: any[];
55
- try {
56
- items = await readdir(absDir, { withFileTypes: true }) as any[];
57
- } catch {
58
- return;
59
- }
60
-
61
- for (const item of items) {
62
- if (results.length >= limit) break;
63
- if (SKIP_NAMES.has(item.name)) continue;
64
-
65
- const childRel = relDir ? `${relDir}/${item.name}` : item.name;
66
-
67
- // Scope check per entry
68
- const sc = enforceScope(agent, { filePath: childRel, op: "read", workspaceId });
69
- if (!sc.ok) continue;
70
-
71
- let type: LsEntry["type"];
72
- let size: number | undefined;
73
- let mtime: string | undefined;
74
-
75
- if (item.isSymbolicLink()) {
76
- type = "symlink";
77
- } else if (item.isDirectory()) {
78
- type = "dir";
79
- } else {
80
- type = "file";
81
- try {
82
- const st = await stat(path.join(rootDir, childRel));
83
- size = st.size;
84
- mtime = st.mtime.toISOString();
85
- } catch {
86
- // best-effort
87
- }
88
- }
89
-
90
- results.push({ name: item.name, path: childRel, type, size, mtime });
91
-
92
- if (recursive && type === "dir") {
93
- await walkDir(rootDir, childRel, agent, recursive, depth + 1, maxDepth, limit, results, workspaceId);
94
- }
95
- }
96
- }
97
-
98
- export async function GET(
99
- req: Request,
100
- { params }: { params: Promise<{ path?: string[] }> },
101
- ): Promise<NextResponse> {
102
- const auth = await checkAuth(req);
103
- if (!auth.ok) return errJson("UNAUTHORIZED", auth.message ?? "Unauthorized", 401);
104
-
105
- const { path: segments } = await params;
106
- const relPath = segments ? segments.join("/") : "";
107
-
108
- const wsx = await resolveWorkspaceForAgent(req);
109
- if (!wsx.ok) return errJson(wsx.code, wsx.code, wsx.status);
110
- const { ws, rootDir } = wsx;
111
-
112
- if (relPath) {
113
- const basic = safeWorkspacePath(rootDir, relPath);
114
- if (!basic) return errJson("INVALID_PATH", "Path traversal rejected", 400);
115
- const safe = await safeAbsPath(rootDir, relPath);
116
- if (!safe) return errJson("INVALID_PATH", "Path rejected (symlink escape or denied)", 400);
117
- }
118
-
119
- const url = new URL(req.url);
120
- const recursive = url.searchParams.has("recursive");
121
- const limit = Math.min(
122
- parseInt(url.searchParams.get("limit") ?? "1000", 10) || 1000,
123
- HARD_MAX_ENTRIES,
124
- );
125
- const depth = Math.min(
126
- parseInt(url.searchParams.get("depth") ?? "10", 10) || 10,
127
- HARD_MAX_DEPTH,
128
- );
129
-
130
- // Verify the dir actually exists
131
- const absDir = relPath ? path.join(rootDir, relPath) : rootDir;
132
- try {
133
- const st = await stat(absDir);
134
- if (!st.isDirectory()) {
135
- return errJson("NOT_A_DIRECTORY", "Path is not a directory", 400);
136
- }
137
- } catch (e) {
138
- if ((e as NodeJS.ErrnoException).code === "ENOENT") {
139
- return errJson("NOT_FOUND", "Directory not found", 404);
140
- }
141
- throw e;
142
- }
143
-
144
- const entries: LsEntry[] = [];
145
- await walkDir(rootDir, relPath, auth.agent, recursive, 0, depth, limit, entries, ws.id);
146
-
147
- return NextResponse.json({
148
- path: relPath,
149
- entries,
150
- truncated: entries.length >= limit,
151
- });
152
- }