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,8 +0,0 @@
1
- allowBuilds:
2
- '@prisma/client': set this to true or false
3
- better-sqlite3: true
4
- esbuild: true
5
- sharp: true
6
-
7
- overrides:
8
- kysely: 0.28.5
@@ -1,2 +0,0 @@
1
- const config = { plugins: { tailwindcss: {}, autoprefixer: {} } };
2
- export default config;
@@ -1,59 +0,0 @@
1
- import { NextResponse } from "next/server";
2
- import { checkAuth, enforceScope } from "@/lib/proof/auth";
3
- import { resolveWorkspaceForAgent } from "@/lib/workspace-context";
4
- import {
5
- aggregateActivity,
6
- ACTIVITY_DEFAULT_LIMIT,
7
- ACTIVITY_MAX_LIMIT,
8
- } from "@/lib/proof/activity";
9
- import { matchGlob } from "@/lib/proof/glob";
10
-
11
- export const runtime = "nodejs";
12
-
13
- export async function GET(req: Request): Promise<NextResponse> {
14
- const auth = await checkAuth(req);
15
- if (!auth.ok) {
16
- return NextResponse.json({ error: "UNAUTHORIZED" }, { status: 401 });
17
- }
18
-
19
- const wsx = await resolveWorkspaceForAgent(req);
20
- if (!wsx.ok) {
21
- return NextResponse.json({ error: wsx.code }, { status: wsx.status });
22
- }
23
- const { ws, rootDir } = wsx;
24
-
25
- const scopeCheck = enforceScope(auth.agent, { op: "read", workspaceId: ws.id });
26
- if (!scopeCheck.ok) {
27
- return NextResponse.json({ error: scopeCheck.code, message: scopeCheck.message }, { status: 403 });
28
- }
29
-
30
- const url = new URL(req.url);
31
- const rawLimit = url.searchParams.get("limit");
32
- const fileFilter = url.searchParams.get("file") ?? undefined;
33
-
34
- // Enforce scope on explicit file query parameter
35
- if (fileFilter) {
36
- const fileScope = enforceScope(auth.agent, { filePath: fileFilter, op: "read", workspaceId: ws.id });
37
- if (!fileScope.ok) {
38
- return NextResponse.json({ error: fileScope.code, message: fileScope.message }, { status: 403 });
39
- }
40
- }
41
-
42
- let limit = ACTIVITY_DEFAULT_LIMIT;
43
- if (rawLimit !== null) {
44
- const parsed = parseInt(rawLimit, 10);
45
- if (!isNaN(parsed) && parsed > 0) {
46
- limit = Math.min(parsed, ACTIVITY_MAX_LIMIT);
47
- }
48
- }
49
-
50
- const events = await aggregateActivity(rootDir, { limit, file: fileFilter });
51
-
52
- // Post-aggregation filter: drop events whose path falls outside agent scope
53
- const scopedPaths = auth.agent.scope.paths;
54
- const filtered = events.filter((ev) =>
55
- scopedPaths.some((pattern) => matchGlob(pattern, ev.path)),
56
- );
57
-
58
- return NextResponse.json({ events: filtered, count: filtered.length });
59
- }
@@ -1,40 +0,0 @@
1
- /**
2
- * POST /api/agent/admin/agents/:agentId/revoke
3
- *
4
- * Revoke (remove) a registered agent. Requires authenticated user session.
5
- */
6
- import { NextResponse } from "next/server";
7
- import { requireUser } from "@/lib/auth/server";
8
- import { readRegistry, removeAgent } from "@/lib/proof/registry";
9
-
10
- export const runtime = "nodejs";
11
-
12
- export async function POST(
13
- req: Request,
14
- { params }: { params: Promise<{ agentId: string }> },
15
- ): Promise<NextResponse> {
16
- const owner = await requireUser(req);
17
- if (!owner.ok) {
18
- return NextResponse.json({ error: "UNAUTHORIZED" }, { status: 401 });
19
- }
20
-
21
- const { agentId } = await params;
22
-
23
- // Check ownership before removal. Legacy agents (no ownerUserId) are
24
- // revocable by any authenticated user.
25
- const registry = await readRegistry();
26
- const agent = (registry?.agents ?? []).find((a) => a.id === agentId);
27
- if (!agent) {
28
- return NextResponse.json({ error: "NOT_FOUND", message: "Agent not found" }, { status: 404 });
29
- }
30
- if (agent.ownerUserId !== undefined && agent.ownerUserId !== owner.user.id) {
31
- return NextResponse.json({ error: "FORBIDDEN", message: "You do not own this agent" }, { status: 403 });
32
- }
33
-
34
- const removed = await removeAgent(agentId);
35
- if (!removed) {
36
- return NextResponse.json({ error: "NOT_FOUND", message: "Agent not found" }, { status: 404 });
37
- }
38
-
39
- return NextResponse.json({ ok: true });
40
- }
@@ -1,33 +0,0 @@
1
- /**
2
- * GET /api/agent/admin/agents
3
- *
4
- * List registered agents (no token hashes). Requires authenticated user session.
5
- */
6
- import { NextResponse } from "next/server";
7
- import { requireUser } from "@/lib/auth/server";
8
- import { readRegistry } from "@/lib/proof/registry";
9
-
10
- export const runtime = "nodejs";
11
-
12
- export async function GET(req: Request): Promise<NextResponse> {
13
- const owner = await requireUser(req);
14
- if (!owner.ok) {
15
- return NextResponse.json({ error: "UNAUTHORIZED" }, { status: 401 });
16
- }
17
-
18
- const registry = await readRegistry();
19
- // Show agents owned by this user. Legacy agents (no ownerUserId) are visible
20
- // to all authenticated users for back-compat.
21
- const agents = (registry?.agents ?? [])
22
- .filter((a) => a.ownerUserId === undefined || a.ownerUserId === owner.user.id)
23
- .map((a) => ({
24
- id: a.id,
25
- displayName: a.displayName,
26
- scope: a.scope,
27
- createdAt: a.createdAt,
28
- lastSeen: a.lastSeen,
29
- ownerUserId: a.ownerUserId,
30
- }));
31
-
32
- return NextResponse.json({ agents });
33
- }
@@ -1,83 +0,0 @@
1
- /**
2
- * POST /api/agent/admin/registrations/:regId/approve
3
- *
4
- * Approve a pending registration. Mints a token, stores agent, marks for pickup.
5
- * Requires authenticated user session.
6
- *
7
- * Body (optional): { scope?: AgentScope } — override requested scope.
8
- */
9
- import { randomBytes } from "node:crypto";
10
- import { NextResponse } from "next/server";
11
- import { requireUser } from "@/lib/auth/server";
12
- import { getRegistration, approveRegistration } from "@/lib/proof/pending";
13
- import { addAgent, hashToken } from "@/lib/proof/registry";
14
- import type { AgentScope } from "@/lib/proof/registry";
15
- import { validateScope } from "@/app/api/agent/register/route";
16
-
17
- export const runtime = "nodejs";
18
-
19
- export async function POST(
20
- req: Request,
21
- { params }: { params: Promise<{ regId: string }> },
22
- ): Promise<NextResponse> {
23
- const owner = await requireUser(req);
24
- if (!owner.ok) {
25
- return NextResponse.json({ error: "UNAUTHORIZED" }, { status: 401 });
26
- }
27
-
28
- const { regId } = await params;
29
- const reg = getRegistration(regId);
30
- if (!reg) {
31
- return NextResponse.json({ error: "NOT_FOUND", message: "Registration not found" }, { status: 404 });
32
- }
33
- if (reg.status !== "pending") {
34
- return NextResponse.json(
35
- { error: "CONFLICT", message: `Registration is already ${reg.status}` },
36
- { status: 409 },
37
- );
38
- }
39
-
40
- // Optional scope override — validate if present
41
- let scope: AgentScope = reg.requestedScope;
42
- try {
43
- const body = (await req.json()) as { scope?: unknown };
44
- if (body.scope !== undefined && body.scope !== null) {
45
- if (typeof body.scope !== "object" || Array.isArray(body.scope)) {
46
- return NextResponse.json(
47
- { error: "INVALID_PAYLOAD", message: "scope must be an object" },
48
- { status: 400 },
49
- );
50
- }
51
- const result = validateScope(body.scope as Record<string, unknown>);
52
- if ("error" in result) {
53
- return NextResponse.json(
54
- { error: "INVALID_PAYLOAD", message: result.error },
55
- { status: 400 },
56
- );
57
- }
58
- scope = result;
59
- }
60
- } catch {
61
- // No body or invalid JSON — use requestedScope
62
- }
63
-
64
- // Mint token
65
- const tokenPlaintext = randomBytes(32).toString("hex");
66
- const tokenHash = hashToken(tokenPlaintext);
67
-
68
- // Store agent in registry, bound to the approving user.
69
- await addAgent({
70
- id: reg.agentId,
71
- displayName: reg.displayName,
72
- tokenHash,
73
- scope,
74
- createdAt: new Date().toISOString(),
75
- lastSeen: new Date().toISOString(),
76
- ownerUserId: owner.user.id,
77
- });
78
-
79
- // Mark as approved with one-shot pickup token
80
- approveRegistration(regId, tokenPlaintext);
81
-
82
- return NextResponse.json({ ok: true, agentId: reg.agentId });
83
- }
@@ -1,36 +0,0 @@
1
- /**
2
- * POST /api/agent/admin/registrations/:regId/deny
3
- *
4
- * Deny a pending registration. Requires authenticated user session.
5
- */
6
- import { NextResponse } from "next/server";
7
- import { requireUser } from "@/lib/auth/server";
8
- import { getRegistration, denyRegistration } from "@/lib/proof/pending";
9
-
10
- export const runtime = "nodejs";
11
-
12
- export async function POST(
13
- req: Request,
14
- { params }: { params: Promise<{ regId: string }> },
15
- ): Promise<NextResponse> {
16
- const owner = await requireUser(req);
17
- if (!owner.ok) {
18
- return NextResponse.json({ error: "UNAUTHORIZED" }, { status: 401 });
19
- }
20
-
21
- const { regId } = await params;
22
- const reg = getRegistration(regId);
23
- if (!reg) {
24
- return NextResponse.json({ error: "NOT_FOUND", message: "Registration not found" }, { status: 404 });
25
- }
26
- if (reg.status !== "pending") {
27
- return NextResponse.json(
28
- { error: "CONFLICT", message: `Registration is already ${reg.status}` },
29
- { status: 409 },
30
- );
31
- }
32
-
33
- denyRegistration(regId);
34
-
35
- return NextResponse.json({ ok: true });
36
- }
@@ -1,27 +0,0 @@
1
- /**
2
- * GET /api/agent/admin/registrations
3
- *
4
- * List pending registrations. Requires authenticated user session.
5
- */
6
- import { NextResponse } from "next/server";
7
- import { requireUser } from "@/lib/auth/server";
8
- import { listPendingRegistrations } from "@/lib/proof/pending";
9
-
10
- export const runtime = "nodejs";
11
-
12
- export async function GET(req: Request): Promise<NextResponse> {
13
- const owner = await requireUser(req);
14
- if (!owner.ok) {
15
- return NextResponse.json({ error: "UNAUTHORIZED" }, { status: 401 });
16
- }
17
-
18
- const pending = listPendingRegistrations().map((r) => ({
19
- registrationId: r.registrationId,
20
- agentId: r.agentId,
21
- displayName: r.displayName,
22
- requestedScope: r.requestedScope,
23
- requestedAt: r.requestedAt,
24
- }));
25
-
26
- return NextResponse.json({ pending });
27
- }
@@ -1,148 +0,0 @@
1
- import { NextResponse } from "next/server";
2
- import { checkAuth, enforceScope, verifyBy } from "@/lib/proof/auth";
3
- import { readSidecar, writeSidecar, emptySidecar } from "@/lib/proof/sidecar";
4
- import { pollEvents } from "@/lib/proof/event-bus";
5
- import { withFileMutex } from "@/lib/proof/mutex";
6
- import { resolveWorkspaceForAgent } from "@/lib/workspace-context";
7
- import { safeWorkspacePath } from "@/lib/workspaces";
8
-
9
- export const runtime = "nodejs";
10
-
11
- const DEFAULT_LIMIT = 100;
12
- const MAX_LIMIT = 1000;
13
-
14
- function isMarkdown(p: string): boolean {
15
- return p.endsWith(".md") || p.endsWith(".markdown");
16
- }
17
-
18
- function mdPath(segments: string[]): string {
19
- return segments.join("/");
20
- }
21
-
22
- // GET /api/agent/events/<path> — poll events since `after`
23
- export async function GET(
24
- req: Request,
25
- { params }: { params: Promise<{ path: string[] }> },
26
- ): Promise<NextResponse> {
27
- const auth = await checkAuth(req);
28
- if (!auth.ok) {
29
- return NextResponse.json({ error: "UNAUTHORIZED" }, { status: 401 });
30
- }
31
-
32
- const wsx = await resolveWorkspaceForAgent(req);
33
- if (!wsx.ok) {
34
- return NextResponse.json({ error: wsx.code }, { status: wsx.status });
35
- }
36
- const { ws, rootDir } = wsx;
37
-
38
- const { path: segments } = await params;
39
- const rel = mdPath(segments);
40
-
41
- if (rel.startsWith(".proof")) {
42
- return NextResponse.json({ error: "INVALID_PATH", message: "Path must not be under .proof" }, { status: 400 });
43
- }
44
- if (!isMarkdown(rel)) {
45
- return NextResponse.json({ error: "INVALID_PATH", message: "Path must be .md or .markdown" }, { status: 400 });
46
- }
47
-
48
- const absPath = safeWorkspacePath(rootDir, rel);
49
- if (!absPath) {
50
- return NextResponse.json({ error: "INVALID_PATH", message: "Path traversal rejected" }, { status: 400 });
51
- }
52
-
53
- const scopeCheck = enforceScope(auth.agent, { filePath: rel, op: "read", workspaceId: ws.id });
54
- if (!scopeCheck.ok) {
55
- return NextResponse.json({ error: scopeCheck.code, message: scopeCheck.message }, { status: 403 });
56
- }
57
-
58
- const { searchParams } = new URL(req.url);
59
- const afterRaw = searchParams.get("after");
60
- const limitRaw = searchParams.get("limit");
61
-
62
- const after = afterRaw !== null ? parseInt(afterRaw, 10) : 0;
63
- let limit = limitRaw !== null ? parseInt(limitRaw, 10) : DEFAULT_LIMIT;
64
-
65
- if (Number.isNaN(after) || after < 0) {
66
- return NextResponse.json({ error: "INVALID_PARAM", message: "after must be a non-negative integer" }, { status: 400 });
67
- }
68
- if (Number.isNaN(limit) || limit <= 0) {
69
- limit = DEFAULT_LIMIT;
70
- }
71
- if (limit > MAX_LIMIT) {
72
- limit = MAX_LIMIT;
73
- }
74
-
75
- const sidecar = (await readSidecar(rootDir, rel)) ?? emptySidecar(rel);
76
- const events = pollEvents(sidecar, after, limit);
77
- const lastEventId = sidecar.nextEventId - 1;
78
-
79
- return NextResponse.json({ events, lastEventId });
80
- }
81
-
82
- // POST /api/agent/events/<path> — acknowledge events up to upToId
83
- export async function POST(
84
- req: Request,
85
- { params }: { params: Promise<{ path: string[] }> },
86
- ): Promise<NextResponse> {
87
- const auth = await checkAuth(req);
88
- if (!auth.ok) {
89
- return NextResponse.json({ error: "UNAUTHORIZED" }, { status: 401 });
90
- }
91
-
92
- const wsx = await resolveWorkspaceForAgent(req, "write");
93
- if (!wsx.ok) {
94
- return NextResponse.json({ error: wsx.code }, { status: wsx.status });
95
- }
96
- const { ws, rootDir } = wsx;
97
-
98
- const { path: segments } = await params;
99
- const rel = mdPath(segments);
100
-
101
- if (rel.startsWith(".proof")) {
102
- return NextResponse.json({ error: "INVALID_PATH", message: "Path must not be under .proof" }, { status: 400 });
103
- }
104
- if (!isMarkdown(rel)) {
105
- return NextResponse.json({ error: "INVALID_PATH", message: "Path must be .md or .markdown" }, { status: 400 });
106
- }
107
-
108
- const absPath = safeWorkspacePath(rootDir, rel);
109
- if (!absPath) {
110
- return NextResponse.json({ error: "INVALID_PATH", message: "Path traversal rejected" }, { status: 400 });
111
- }
112
-
113
- const scopeCheck = enforceScope(auth.agent, { filePath: rel, op: "mutate", workspaceId: ws.id });
114
- if (!scopeCheck.ok) {
115
- return NextResponse.json({ error: scopeCheck.code, message: scopeCheck.message }, { status: 403 });
116
- }
117
-
118
- let body: { upToId?: unknown; by?: unknown };
119
- try {
120
- body = (await req.json()) as { upToId?: unknown; by?: unknown };
121
- } catch {
122
- return NextResponse.json({ error: "INVALID_PAYLOAD", message: "Invalid JSON" }, { status: 400 });
123
- }
124
-
125
- if (typeof body.upToId !== "number") {
126
- return NextResponse.json({ error: "INVALID_PAYLOAD", message: "upToId (number) required" }, { status: 400 });
127
- }
128
- if (typeof body.by !== "string" || !body.by) {
129
- return NextResponse.json({ error: "INVALID_PAYLOAD", message: "by (string) required" }, { status: 400 });
130
- }
131
-
132
- const byCheck = verifyBy(auth.agent, body.by as string);
133
- if (!byCheck.ok) {
134
- return NextResponse.json({ error: byCheck.code, message: byCheck.message }, { status: 403 });
135
- }
136
-
137
- const upToId = body.upToId as number;
138
- const by = body.by as string;
139
-
140
- // Namespace mutex key with rootDir to prevent cross-workspace lock contention.
141
- await withFileMutex(`${rootDir}\0${rel}`, async () => {
142
- const sidecar = (await readSidecar(rootDir, rel)) ?? emptySidecar(rel);
143
- sidecar.lastAck[by] = upToId;
144
- await writeSidecar(rootDir, rel, sidecar);
145
- });
146
-
147
- return NextResponse.json({ ok: true });
148
- }
@@ -1,219 +0,0 @@
1
- /**
2
- * Agent files route — GET snapshot, POST apply-ops.
3
- *
4
- * Sample curl (§10 step 1 — read snapshot):
5
- * curl -H "Authorization: Bearer $AGENT_BEARER_TOKEN" \
6
- * http://localhost:3000/api/agent/files/notes.md
7
- *
8
- * Sample curl (§10 step 2 — apply ops):
9
- * curl -X POST \
10
- * -H "Authorization: Bearer $AGENT_BEARER_TOKEN" \
11
- * -H "Content-Type: application/json" \
12
- * -H "Idempotency-Key: req-$(uuidgen)" \
13
- * -d '{"baseRevision":0,"by":"ai:claude","ops":[{"type":"block.append","markdown":"Hello world."}]}' \
14
- * http://localhost:3000/api/agent/files/notes.md
15
- */
16
- import { createHash } from "node:crypto";
17
- import { NextResponse } from "next/server";
18
- import { checkAuth, enforceScope, verifyBy } from "@/lib/proof/auth";
19
- import { applyOps, readSnapshot } from "@/lib/proof/ops-applier";
20
- import { idempotency } from "@/lib/proof/idempotency";
21
- import { resolveWorkspaceForAgent } from "@/lib/workspace-context";
22
- import { safeWorkspacePath } from "@/lib/workspaces";
23
- import type { Op } from "@/lib/proof/types";
24
- import { checkAndConsume } from "@/lib/proof/rate-limit";
25
- import { computeCollabState } from "@/lib/proof/collab-state";
26
-
27
- export const runtime = "nodejs";
28
-
29
- function isMarkdown(p: string): boolean {
30
- return p.endsWith(".md") || p.endsWith(".markdown");
31
- }
32
-
33
- function mdPath(segments: string[]): string {
34
- return segments.join("/");
35
- }
36
-
37
- export async function GET(
38
- req: Request,
39
- { params }: { params: Promise<{ path: string[] }> },
40
- ): Promise<NextResponse> {
41
- const auth = await checkAuth(req);
42
- if (!auth.ok) {
43
- return NextResponse.json({ error: "UNAUTHORIZED" }, { status: 401 });
44
- }
45
-
46
- const { path: segments } = await params;
47
- const rel = mdPath(segments);
48
-
49
- if (rel.startsWith(".proof")) {
50
- return NextResponse.json({ error: "INVALID_PATH", message: "Path must not be under .proof" }, { status: 400 });
51
- }
52
- if (!isMarkdown(rel)) {
53
- return NextResponse.json({ error: "INVALID_PATH", message: "Path must be .md or .markdown" }, { status: 400 });
54
- }
55
-
56
- const wsx = await resolveWorkspaceForAgent(req);
57
- if (!wsx.ok) return NextResponse.json({ error: wsx.code }, { status: wsx.status });
58
- const { ws, rootDir } = wsx;
59
-
60
- const absPath = safeWorkspacePath(rootDir, rel);
61
- if (!absPath) {
62
- return NextResponse.json({ error: "INVALID_PATH", message: "Path traversal rejected" }, { status: 400 });
63
- }
64
-
65
- const scopeCheck = enforceScope(auth.agent, { filePath: rel, op: "read", workspaceId: ws.id });
66
- if (!scopeCheck.ok) {
67
- return NextResponse.json({ error: scopeCheck.code, message: scopeCheck.message }, { status: 403 });
68
- }
69
-
70
- const snapshot = await readSnapshot(rootDir, rel);
71
- if (!snapshot) {
72
- return NextResponse.json({ error: "NOT_FOUND", message: "File not found" }, { status: 404 });
73
- }
74
-
75
- const collab = await computeCollabState(rootDir, rel);
76
- const collabHeaders: Record<string, string> = {
77
- "X-Collab-State": collab.state,
78
- "X-Collab-Revision": String(collab.revision),
79
- };
80
- if (collab.snapshotUrl) {
81
- collabHeaders["X-Collab-Snapshot"] = collab.snapshotUrl;
82
- }
83
-
84
- return NextResponse.json(snapshot, { headers: collabHeaders });
85
- }
86
-
87
- export async function POST(
88
- req: Request,
89
- { params }: { params: Promise<{ path: string[] }> },
90
- ): Promise<NextResponse> {
91
- const auth = await checkAuth(req);
92
- if (!auth.ok) {
93
- return NextResponse.json({ error: "UNAUTHORIZED" }, { status: 401 });
94
- }
95
-
96
- const idempotencyKey = req.headers.get("idempotency-key");
97
- if (!idempotencyKey) {
98
- return NextResponse.json(
99
- { error: "MISSING_IDEMPOTENCY_KEY", message: "Idempotency-Key header is required" },
100
- { status: 400 },
101
- );
102
- }
103
-
104
- const { path: segments } = await params;
105
- const rel = mdPath(segments);
106
-
107
- if (rel.startsWith(".proof")) {
108
- return NextResponse.json({ error: "INVALID_PATH", message: "Path must not be under .proof" }, { status: 400 });
109
- }
110
- if (!isMarkdown(rel)) {
111
- return NextResponse.json({ error: "INVALID_PATH", message: "Path must be .md or .markdown" }, { status: 400 });
112
- }
113
-
114
- const wsx = await resolveWorkspaceForAgent(req, "write");
115
- if (!wsx.ok) return NextResponse.json({ error: wsx.code }, { status: wsx.status });
116
- const { ws, rootDir } = wsx;
117
-
118
- const absPath = safeWorkspacePath(rootDir, rel);
119
- if (!absPath) {
120
- return NextResponse.json({ error: "INVALID_PATH", message: "Path traversal rejected" }, { status: 400 });
121
- }
122
-
123
- // Read body for idempotency hash
124
- let rawBody: string;
125
- try {
126
- rawBody = await req.text();
127
- } catch {
128
- return NextResponse.json({ error: "INVALID_PAYLOAD", message: "Could not read request body" }, { status: 400 });
129
- }
130
-
131
- const payloadHash = createHash("sha256").update(rawBody, "utf8").digest("hex");
132
-
133
- // Check idempotency cache
134
- const cached = idempotency.get(`${rootDir}\u0000${idempotencyKey}`);
135
- if (cached) {
136
- if (cached.payloadHash !== payloadHash) {
137
- return NextResponse.json(
138
- { error: "IDEMPOTENCY_KEY_REUSED", message: "Same key, different payload" },
139
- { status: 409 },
140
- );
141
- }
142
- return new NextResponse(cached.body, {
143
- status: cached.status,
144
- headers: { "Content-Type": "application/json" },
145
- });
146
- }
147
-
148
- let body: { baseRevision?: unknown; by?: unknown; ops?: unknown };
149
- try {
150
- body = JSON.parse(rawBody) as { baseRevision?: unknown; by?: unknown; ops?: unknown };
151
- } catch {
152
- return NextResponse.json({ error: "INVALID_PAYLOAD", message: "Invalid JSON" }, { status: 400 });
153
- }
154
-
155
- if (typeof body.baseRevision !== "number") {
156
- return NextResponse.json({ error: "INVALID_PAYLOAD", message: "baseRevision (number) required" }, { status: 400 });
157
- }
158
- if (typeof body.by !== "string" || !body.by) {
159
- return NextResponse.json({ error: "INVALID_PAYLOAD", message: "by (string) required" }, { status: 400 });
160
- }
161
- if (!Array.isArray(body.ops)) {
162
- return NextResponse.json({ error: "INVALID_PAYLOAD", message: "ops (array) required" }, { status: 400 });
163
- }
164
-
165
- const scopeCheck = enforceScope(auth.agent, { filePath: rel, op: "mutate", workspaceId: ws.id });
166
- if (!scopeCheck.ok) {
167
- return NextResponse.json({ error: scopeCheck.code, message: scopeCheck.message }, { status: 403 });
168
- }
169
-
170
- const byCheck = verifyBy(auth.agent, body.by as string);
171
- if (!byCheck.ok) {
172
- return NextResponse.json({ error: byCheck.code, message: byCheck.message }, { status: 403 });
173
- }
174
-
175
- // Rate-limit mutations: count ops (all ops are mutations in this route)
176
- const opCount = (body.ops as Op[]).length || 1;
177
- const rl = checkAndConsume(body.by as string, opCount);
178
- if (!rl.ok) {
179
- const retryAfterSec = Math.ceil(rl.retryAfterMs / 1000);
180
- return new NextResponse(
181
- JSON.stringify({ error: "RATE_LIMITED", retryAfterMs: rl.retryAfterMs }),
182
- {
183
- status: 429,
184
- headers: {
185
- "Content-Type": "application/json",
186
- "Retry-After": String(retryAfterSec),
187
- },
188
- },
189
- );
190
- }
191
-
192
- const result = await applyOps({
193
- rootDir,
194
- mdPath: rel,
195
- baseRevision: body.baseRevision as number,
196
- by: body.by as string,
197
- ops: body.ops as Op[],
198
- });
199
-
200
- let responseBody: string;
201
- let status: number;
202
-
203
- if (result.ok) {
204
- status = 200;
205
- responseBody = JSON.stringify(result.snapshot);
206
- } else {
207
- status = result.status;
208
- const payload: Record<string, unknown> = { error: result.code, message: result.message };
209
- if (result.snapshot) payload.snapshot = result.snapshot;
210
- responseBody = JSON.stringify(payload);
211
- }
212
-
213
- idempotency.set(`${rootDir}\u0000${idempotencyKey}`, { payloadHash, status, body: responseBody });
214
-
215
- return new NextResponse(responseBody, {
216
- status,
217
- headers: { "Content-Type": "application/json" },
218
- });
219
- }