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,727 +0,0 @@
1
- import { readFile, writeFile } from "node:fs/promises";
2
- import { createHash } from "node:crypto";
3
- import path from "node:path";
4
- import type { RootContent } from "mdast";
5
- import type { Op, Block, Snapshot, Sidecar, ProofEvent, Comment, Suggestion } from "./types";
6
- import { parseBlocks, blockToMarkdown, blocksToMarkdown } from "./blocks";
7
- import { assignRefs, resolveRef, computeRefDelta, textHash } from "./block-refs";
8
- import { wrapAsProofSpan, newSpanId } from "./proof-span";
9
- import { readSidecar, writeSidecar, emptySidecar } from "./sidecar";
10
- import { withFileMutex } from "./mutex";
11
- import { emitEvents, trimEvents } from "./event-bus";
12
- import { SIDECAR_EVENT_TRIM_SIZE, SIDECAR_TRIM_EVERY_N_MUTATIONS } from "../proof-config";
13
-
14
- function sha256file(content: string): string {
15
- return "sha256:" + createHash("sha256").update(content, "utf8").digest("hex");
16
- }
17
-
18
- function shortId(prefix: string): string {
19
- return prefix + Math.floor(Math.random() * 0xffff).toString(16).padStart(4, "0");
20
- }
21
-
22
- function nowIso(): string {
23
- return new Date().toISOString();
24
- }
25
-
26
- function cloneSidecar(sc: Sidecar): Sidecar {
27
- return JSON.parse(JSON.stringify(sc)) as Sidecar;
28
- }
29
-
30
- /**
31
- * Wrap op markdown for AI agents: inserts proof-span marks on text-bearing blocks.
32
- * Returns { wrappedMarkdown, blockProvenance }.
33
- */
34
- function wrapForAi(
35
- markdown: string,
36
- by: string,
37
- basis: string | undefined,
38
- basisDetail: string | undefined,
39
- inResponseTo: string | undefined,
40
- sidecar: Sidecar,
41
- blockRef: string,
42
- ): string {
43
- const attrs = {
44
- spanId: newSpanId(),
45
- origin: "ai" as const,
46
- basis: basis ?? "inferred",
47
- basisDetail,
48
- by,
49
- at: nowIso(),
50
- inResponseTo,
51
- };
52
- const wrapped = wrapAsProofSpan(markdown, attrs);
53
- if (wrapped === null) {
54
- // Non-wrappable block type. Record in sidecar.blockProvenance instead.
55
- if (!sidecar.blockProvenance) sidecar.blockProvenance = {};
56
- sidecar.blockProvenance[blockRef] = attrs;
57
- return markdown;
58
- }
59
- return wrapped;
60
- }
61
-
62
- /**
63
- * Parse op markdown into mdast nodes, assign refs, and wrap for AI if needed.
64
- */
65
- function opMarkdownToBlocks(
66
- markdown: string,
67
- by: string,
68
- basis: string | undefined,
69
- basisDetail: string | undefined,
70
- inResponseTo: string | undefined,
71
- isAi: boolean,
72
- workingBlocks: Block[],
73
- workingSidecar: Sidecar,
74
- ): { nodes: RootContent[]; refs: string[] } {
75
- const nodes = parseBlocks(markdown);
76
- const usedRefs = new Set(workingBlocks.map((b) => b.ref));
77
- const refs: string[] = [];
78
-
79
- for (let i = 0; i < nodes.length; i++) {
80
- const node = nodes[i];
81
- let md = blockToMarkdown(node);
82
-
83
- // Mint a provisional ref for this new block
84
- const hash = "b" + createHash("sha256").update(md, "utf8").digest("hex").slice(0, 6);
85
- let ref = hash;
86
- let counter = 0;
87
- while (usedRefs.has(ref)) {
88
- ref = `${hash}_${counter++}`;
89
- }
90
- usedRefs.add(ref);
91
- refs.push(ref);
92
-
93
- if (isAi) {
94
- md = wrapForAi(md, by, basis, basisDetail, inResponseTo, workingSidecar, ref);
95
- // Reparse the wrapped markdown to get the updated node
96
- const reparsed = parseBlocks(md);
97
- if (reparsed.length > 0) {
98
- nodes[i] = reparsed[0];
99
- }
100
- }
101
- }
102
-
103
- return { nodes, refs };
104
- }
105
-
106
- function markOrphanedRefsStale(sidecar: Sidecar, newRefMap: Record<string, unknown>): void {
107
- const validRefs = new Set(Object.keys(newRefMap));
108
- for (const s of sidecar.suggestions) {
109
- if (s.status === "pending" && !validRefs.has(s.ref)) {
110
- s.stale = true;
111
- }
112
- }
113
- for (const c of sidecar.comments) {
114
- if (!c.resolved && !validRefs.has(c.ref)) {
115
- c.stale = true;
116
- }
117
- }
118
- }
119
-
120
- function buildSnapshot(
121
- mdPath: string,
122
- blocks: Block[],
123
- sidecar: Sidecar,
124
- ): Snapshot {
125
- return {
126
- path: mdPath,
127
- revision: sidecar.revision,
128
- createdAt: sidecar.createdAt,
129
- updatedAt: sidecar.updatedAt,
130
- fingerprint: sidecar.fingerprint,
131
- blocks,
132
- comments: sidecar.comments,
133
- suggestions: sidecar.suggestions.filter((s) => s.status === "pending"),
134
- lastEventId: sidecar.nextEventId - 1,
135
- };
136
- }
137
-
138
- /**
139
- * Reconcile a sidecar after a file was modified outside of block-ops.
140
- * Rebuilds refMap, bumps revision, marks orphaned anchors stale, emits event, writes sidecar.
141
- *
142
- * Callers MUST hold `withFileMutex(mdPath, ...)` before calling.
143
- *
144
- * Used by:
145
- * - readSnapshot: eventType="file.externallyEdited", by="system"
146
- * - raw-fs PUT (Phase 2): eventType="file.rawWritten", by="ai:<id>"
147
- */
148
- export async function reconcileSidecar(args: {
149
- rootDir: string;
150
- mdPath: string;
151
- content: string;
152
- sidecar: Sidecar; // mutated in place
153
- by: string;
154
- eventType: string;
155
- fingerprint: string; // pre-computed sha256 of content
156
- }): Promise<{ snapshot: Snapshot; blocks: Block[] }> {
157
- const { rootDir, mdPath, content, sidecar, by, eventType, fingerprint } = args;
158
- const nodes = parseBlocks(content);
159
- const { blocks, newRefMap } = assignRefs(nodes, sidecar);
160
- const oldFingerprint = sidecar.fingerprint;
161
- sidecar.refMap = newRefMap;
162
- sidecar.revision += 1;
163
- sidecar.updatedAt = nowIso();
164
- sidecar.fingerprint = fingerprint;
165
- markOrphanedRefsStale(sidecar, newRefMap);
166
- const eventPayload: Omit<ProofEvent, "id"> & Record<string, unknown> = {
167
- type: eventType,
168
- at: nowIso(),
169
- by,
170
- fingerprint,
171
- };
172
- if (eventType === "file.rawWritten") {
173
- eventPayload.oldSha = oldFingerprint;
174
- eventPayload.newSha = fingerprint;
175
- }
176
- emitEvents(sidecar, [eventPayload as Omit<ProofEvent, "id">]);
177
- await writeSidecar(rootDir, mdPath, sidecar);
178
- return { snapshot: buildSnapshot(mdPath, blocks, sidecar), blocks };
179
- }
180
-
181
- /**
182
- * Pure read: load file, parse blocks, assign refs, return snapshot.
183
- * Detects external edits (fingerprint mismatch) and records them in the sidecar.
184
- */
185
- export async function readSnapshot(
186
- rootDir: string,
187
- mdPath: string,
188
- ): Promise<Snapshot | null> {
189
- const absPath = path.join(rootDir, mdPath);
190
- let content: string;
191
- try {
192
- content = await readFile(absPath, "utf-8");
193
- } catch (err) {
194
- if ((err as NodeJS.ErrnoException).code === "ENOENT") return null;
195
- throw err;
196
- }
197
-
198
- const sidecar = (await readSidecar(rootDir, mdPath)) ?? emptySidecar(mdPath);
199
- const fingerprint = sha256file(content);
200
-
201
- // Detect external edits: fingerprint set and mismatched
202
- if (sidecar.fingerprint && sidecar.fingerprint !== fingerprint) {
203
- return withFileMutex(mdPath, async () => {
204
- // Re-read under mutex to avoid TOCTOU
205
- let freshContent: string;
206
- try {
207
- freshContent = await readFile(absPath, "utf-8");
208
- } catch (err) {
209
- if ((err as NodeJS.ErrnoException).code === "ENOENT") return null;
210
- throw err;
211
- }
212
- const freshSidecar = (await readSidecar(rootDir, mdPath)) ?? emptySidecar(mdPath);
213
- const freshFingerprint = sha256file(freshContent);
214
-
215
- if (freshSidecar.fingerprint && freshSidecar.fingerprint !== freshFingerprint) {
216
- const { snapshot } = await reconcileSidecar({
217
- rootDir,
218
- mdPath,
219
- content: freshContent,
220
- sidecar: freshSidecar,
221
- by: "system",
222
- eventType: "file.externallyEdited",
223
- fingerprint: freshFingerprint,
224
- });
225
- return snapshot;
226
- }
227
-
228
- // Another writer already updated — just build snapshot from current state
229
- const nodes = parseBlocks(freshContent);
230
- const { blocks } = assignRefs(nodes, freshSidecar);
231
- return buildSnapshot(mdPath, blocks, freshSidecar);
232
- });
233
- }
234
-
235
- const nodes = parseBlocks(content);
236
- const { blocks, newRefMap } = assignRefs(nodes, sidecar);
237
-
238
- // Sync sidecar refMap if it's empty (first read) and persist fingerprint
239
- if (Object.keys(sidecar.refMap).length === 0) {
240
- sidecar.refMap = newRefMap;
241
- sidecar.fingerprint = fingerprint;
242
- // Persist so future readSnapshot calls can detect external edits
243
- await writeSidecar(rootDir, mdPath, sidecar);
244
- }
245
-
246
- return buildSnapshot(mdPath, blocks, sidecar);
247
- }
248
-
249
- type ApplyResult =
250
- | { ok: true; snapshot: Snapshot; emittedEvents: ProofEvent[] }
251
- | {
252
- ok: false;
253
- status: number;
254
- code: string;
255
- message: string;
256
- snapshot?: Snapshot;
257
- };
258
-
259
- /**
260
- * Apply a batch of ops to a file, with revision check, mutex, and atomic write.
261
- */
262
- export async function applyOps(args: {
263
- rootDir: string;
264
- mdPath: string;
265
- baseRevision: number;
266
- by: string;
267
- ops: Op[];
268
- }): Promise<ApplyResult> {
269
- const { rootDir, mdPath, baseRevision, by, ops } = args;
270
-
271
- return withFileMutex(mdPath, async (): Promise<ApplyResult> => {
272
- const absPath = path.join(rootDir, mdPath);
273
-
274
- let content: string;
275
- try {
276
- content = await readFile(absPath, "utf-8");
277
- } catch (err) {
278
- if ((err as NodeJS.ErrnoException).code === "ENOENT") {
279
- return { ok: false, status: 404, code: "FILE_NOT_FOUND", message: "File not found" };
280
- }
281
- throw err;
282
- }
283
-
284
- const fingerprint = sha256file(content);
285
- let sidecar = (await readSidecar(rootDir, mdPath)) ?? emptySidecar(mdPath);
286
-
287
- const isAi = by.startsWith("ai:");
288
-
289
- // Detect external edits — reconcile eagerly inside the mutex (R2: do not let lazy reconcile miss)
290
- if (sidecar.fingerprint && sidecar.fingerprint !== fingerprint) {
291
- const { snapshot: freshSnapshot } = await reconcileSidecar({
292
- rootDir,
293
- mdPath,
294
- content,
295
- sidecar,
296
- by: "system",
297
- eventType: "file.externallyEdited",
298
- fingerprint,
299
- });
300
- // Return STALE_REVISION so caller knows to re-fetch
301
- return {
302
- ok: false,
303
- status: 409,
304
- code: "STALE_REVISION",
305
- message: "File was externally edited. Fetch the new snapshot and retry.",
306
- snapshot: freshSnapshot,
307
- };
308
- }
309
-
310
- // Initialize fingerprint if not set
311
- if (!sidecar.fingerprint) {
312
- sidecar.fingerprint = fingerprint;
313
- }
314
-
315
- const nodes = parseBlocks(content);
316
- const { blocks: assignedBlocks, newRefMap } = assignRefs(nodes, sidecar);
317
- sidecar.refMap = newRefMap;
318
-
319
- // Revision check
320
- if (baseRevision !== sidecar.revision) {
321
- return {
322
- ok: false,
323
- status: 409,
324
- code: "STALE_REVISION",
325
- message: `Base revision ${baseRevision} does not match current revision ${sidecar.revision}.`,
326
- snapshot: buildSnapshot(mdPath, assignedBlocks, sidecar),
327
- };
328
- }
329
-
330
- // Working copies
331
- let workingNodes = [...nodes];
332
- let workingBlocks = [...assignedBlocks];
333
- const workingSidecar = cloneSidecar(sidecar);
334
- const workingEvents: Array<Omit<ProofEvent, "id">> = [];
335
- const collectedAliases: Record<string, string> = {};
336
-
337
- const currentRefs = () => new Set(workingBlocks.map((b) => b.ref));
338
-
339
- function findBlockIndex(ref: string): number {
340
- const resolved = resolveRef(workingSidecar, ref, currentRefs());
341
- if (!resolved) return -1;
342
- return workingBlocks.findIndex((b) => b.ref === resolved);
343
- }
344
-
345
- // Apply ops
346
- for (const op of ops) {
347
- const at = nowIso();
348
-
349
- switch (op.type) {
350
- case "block.replace": {
351
- const idx = findBlockIndex(op.ref);
352
- if (idx === -1) {
353
- return {
354
- ok: false,
355
- status: 409,
356
- code: "BLOCK_NOT_FOUND",
357
- message: `Block ref "${op.ref}" not found.`,
358
- snapshot: buildSnapshot(mdPath, workingBlocks, workingSidecar),
359
- };
360
- }
361
- const oldRef = workingBlocks[idx].ref;
362
-
363
- const { nodes: newNodes, refs: newRefs } = opMarkdownToBlocks(
364
- op.markdown, by, op.basis, op.basisDetail, op.inResponseTo,
365
- isAi, workingBlocks.filter((_, i) => i !== idx), workingSidecar,
366
- );
367
-
368
- workingNodes.splice(idx, 1, ...newNodes);
369
- const newBlocks = newNodes.map((n, ni) => {
370
- const md = blockToMarkdown(n);
371
- return { ref: newRefs[ni], type: "paragraph" as const, markdown: md };
372
- });
373
- workingBlocks.splice(idx, 1, ...newBlocks);
374
-
375
- // Re-assign proper block types
376
- const reparse = assignRefs(newNodes, null);
377
- for (let ni = 0; ni < newBlocks.length; ni++) {
378
- workingBlocks[idx + ni] = { ...reparse.blocks[ni], ref: newRefs[ni] };
379
- }
380
-
381
- if (newRefs[0]) collectedAliases[oldRef] = newRefs[0];
382
- workingEvents.push({
383
- type: "block.replaced",
384
- at,
385
- by,
386
- ref: oldRef,
387
- newRef: newRefs[0] ?? null,
388
- });
389
- break;
390
- }
391
-
392
- case "block.insertAfter": {
393
- const idx = findBlockIndex(op.ref);
394
- if (idx === -1) {
395
- return {
396
- ok: false,
397
- status: 409,
398
- code: "BLOCK_NOT_FOUND",
399
- message: `Block ref "${op.ref}" not found.`,
400
- snapshot: buildSnapshot(mdPath, workingBlocks, workingSidecar),
401
- };
402
- }
403
- const { nodes: newNodes, refs: newRefs } = opMarkdownToBlocks(
404
- op.markdown, by, op.basis, op.basisDetail, op.inResponseTo,
405
- isAi, workingBlocks, workingSidecar,
406
- );
407
- const newBlockList = newNodes.map((n, ni) => {
408
- const reparse = assignRefs([n], null);
409
- return { ...reparse.blocks[0], ref: newRefs[ni] };
410
- });
411
- workingNodes.splice(idx + 1, 0, ...newNodes);
412
- workingBlocks.splice(idx + 1, 0, ...newBlockList);
413
- workingEvents.push({ type: "block.inserted", at, by, after: op.ref, refs: newRefs });
414
- break;
415
- }
416
-
417
- case "block.insertBefore": {
418
- const idx = findBlockIndex(op.ref);
419
- if (idx === -1) {
420
- return {
421
- ok: false,
422
- status: 409,
423
- code: "BLOCK_NOT_FOUND",
424
- message: `Block ref "${op.ref}" not found.`,
425
- snapshot: buildSnapshot(mdPath, workingBlocks, workingSidecar),
426
- };
427
- }
428
- const { nodes: newNodes, refs: newRefs } = opMarkdownToBlocks(
429
- op.markdown, by, op.basis, op.basisDetail, op.inResponseTo,
430
- isAi, workingBlocks, workingSidecar,
431
- );
432
- const newBlockList = newNodes.map((n, ni) => {
433
- const reparse = assignRefs([n], null);
434
- return { ...reparse.blocks[0], ref: newRefs[ni] };
435
- });
436
- workingNodes.splice(idx, 0, ...newNodes);
437
- workingBlocks.splice(idx, 0, ...newBlockList);
438
- workingEvents.push({ type: "block.inserted", at, by, before: op.ref, refs: newRefs });
439
- break;
440
- }
441
-
442
- case "block.delete": {
443
- const idx = findBlockIndex(op.ref);
444
- if (idx === -1) {
445
- return {
446
- ok: false,
447
- status: 409,
448
- code: "BLOCK_NOT_FOUND",
449
- message: `Block ref "${op.ref}" not found.`,
450
- snapshot: buildSnapshot(mdPath, workingBlocks, workingSidecar),
451
- };
452
- }
453
- workingNodes.splice(idx, 1);
454
- workingBlocks.splice(idx, 1);
455
- workingEvents.push({ type: "block.deleted", at, by, ref: op.ref });
456
- break;
457
- }
458
-
459
- case "block.append": {
460
- const { nodes: newNodes, refs: newRefs } = opMarkdownToBlocks(
461
- op.markdown, by, op.basis, op.basisDetail, op.inResponseTo,
462
- isAi, workingBlocks, workingSidecar,
463
- );
464
- const newBlockList = newNodes.map((n, ni) => {
465
- const reparse = assignRefs([n], null);
466
- return { ...reparse.blocks[0], ref: newRefs[ni] };
467
- });
468
- workingNodes.push(...newNodes);
469
- workingBlocks.push(...newBlockList);
470
- workingEvents.push({ type: "block.inserted", at, by, position: "end", refs: newRefs });
471
- break;
472
- }
473
-
474
- case "block.prepend": {
475
- const { nodes: newNodes, refs: newRefs } = opMarkdownToBlocks(
476
- op.markdown, by, op.basis, op.basisDetail, op.inResponseTo,
477
- isAi, workingBlocks, workingSidecar,
478
- );
479
- const newBlockList = newNodes.map((n, ni) => {
480
- const reparse = assignRefs([n], null);
481
- return { ...reparse.blocks[0], ref: newRefs[ni] };
482
- });
483
- workingNodes.unshift(...newNodes);
484
- workingBlocks.unshift(...newBlockList);
485
- workingEvents.push({ type: "block.inserted", at, by, position: "start", refs: newRefs });
486
- break;
487
- }
488
-
489
- case "comment.add": {
490
- const refs = currentRefs();
491
- const resolved = resolveRef(workingSidecar, op.ref, refs);
492
- if (!resolved) {
493
- return {
494
- ok: false,
495
- status: 409,
496
- code: "BLOCK_NOT_FOUND",
497
- message: `Block ref "${op.ref}" not found.`,
498
- snapshot: buildSnapshot(mdPath, workingBlocks, workingSidecar),
499
- };
500
- }
501
- const comment: Comment = {
502
- id: shortId("c"),
503
- ref: resolved,
504
- resolved: false,
505
- createdAt: at,
506
- turns: [{ by, text: op.text, at }],
507
- };
508
- workingSidecar.comments.push(comment);
509
- workingEvents.push({ type: "comment.added", at, by, commentId: comment.id, ref: resolved, text: op.text });
510
- break;
511
- }
512
-
513
- case "comment.reply": {
514
- const comment = workingSidecar.comments.find((c) => c.id === op.commentId);
515
- if (!comment) {
516
- return {
517
- ok: false,
518
- status: 409,
519
- code: "COMMENT_NOT_FOUND",
520
- message: `Comment "${op.commentId}" not found.`,
521
- snapshot: buildSnapshot(mdPath, workingBlocks, workingSidecar),
522
- };
523
- }
524
- comment.turns.push({ by, text: op.text, at });
525
- workingEvents.push({ type: "comment.replied", at, by, commentId: op.commentId, text: op.text });
526
- break;
527
- }
528
-
529
- case "comment.resolve": {
530
- const comment = workingSidecar.comments.find((c) => c.id === op.commentId);
531
- if (!comment) {
532
- return {
533
- ok: false,
534
- status: 409,
535
- code: "COMMENT_NOT_FOUND",
536
- message: `Comment "${op.commentId}" not found.`,
537
- snapshot: buildSnapshot(mdPath, workingBlocks, workingSidecar),
538
- };
539
- }
540
- comment.resolved = true;
541
- workingEvents.push({ type: "comment.resolved", at, by, commentId: op.commentId });
542
- break;
543
- }
544
-
545
- case "comment.reopen": {
546
- const comment = workingSidecar.comments.find((c) => c.id === op.commentId);
547
- if (!comment) {
548
- return {
549
- ok: false,
550
- status: 409,
551
- code: "COMMENT_NOT_FOUND",
552
- message: `Comment "${op.commentId}" not found.`,
553
- snapshot: buildSnapshot(mdPath, workingBlocks, workingSidecar),
554
- };
555
- }
556
- comment.resolved = false;
557
- workingEvents.push({ type: "comment.reopened", at, by, commentId: op.commentId });
558
- break;
559
- }
560
-
561
- case "suggestion.add": {
562
- const refs = currentRefs();
563
- const resolved = resolveRef(workingSidecar, op.ref, refs);
564
- if (!resolved) {
565
- return {
566
- ok: false,
567
- status: 409,
568
- code: "BLOCK_NOT_FOUND",
569
- message: `Block ref "${op.ref}" not found.`,
570
- snapshot: buildSnapshot(mdPath, workingBlocks, workingSidecar),
571
- };
572
- }
573
-
574
- const suggestion: Suggestion = {
575
- id: shortId("s"),
576
- ref: resolved,
577
- kind: op.kind,
578
- status: "pending",
579
- by,
580
- markdown: op.markdown,
581
- basis: op.basis as Suggestion["basis"],
582
- basisDetail: op.basisDetail,
583
- createdAt: at,
584
- };
585
-
586
- if (op.status === "accepted") {
587
- // Apply immediately
588
- suggestion.status = "accepted";
589
- suggestion.resolvedAt = at;
590
- suggestion.resolvedBy = by;
591
- workingSidecar.archivedSuggestions.push(suggestion);
592
- workingEvents.push({ type: "suggestion.added", at, by, suggestionId: suggestion.id });
593
- workingEvents.push({ type: "suggestion.accepted", at, by, suggestionId: suggestion.id });
594
- // Apply as block op inline
595
- const inlineOp: Op = op.kind === "replace"
596
- ? { type: "block.replace", ref: resolved, markdown: op.markdown ?? "" }
597
- : op.kind === "insertAfter"
598
- ? { type: "block.insertAfter", ref: resolved, markdown: op.markdown ?? "" }
599
- : op.kind === "insertBefore"
600
- ? { type: "block.insertBefore", ref: resolved, markdown: op.markdown ?? "" }
601
- : { type: "block.delete", ref: resolved };
602
- // Recursively handle by pushing to ops (not safe for complex cases, do inline)
603
- // For simplicity, fall through to apply the block op directly
604
- ops.push(inlineOp);
605
- } else {
606
- workingSidecar.suggestions.push(suggestion);
607
- workingEvents.push({ type: "suggestion.added", at, by, suggestionId: suggestion.id });
608
- }
609
- break;
610
- }
611
-
612
- case "suggestion.accept": {
613
- const sugIdx = workingSidecar.suggestions.findIndex((s) => s.id === op.suggestionId);
614
- if (sugIdx === -1) {
615
- return {
616
- ok: false,
617
- status: 409,
618
- code: "SUGGESTION_NOT_FOUND",
619
- message: `Suggestion "${op.suggestionId}" not found.`,
620
- snapshot: buildSnapshot(mdPath, workingBlocks, workingSidecar),
621
- };
622
- }
623
- const sug = workingSidecar.suggestions[sugIdx];
624
- sug.status = "accepted";
625
- sug.resolvedAt = at;
626
- sug.resolvedBy = by;
627
- workingSidecar.suggestions.splice(sugIdx, 1);
628
- workingSidecar.archivedSuggestions.push(sug);
629
-
630
- // Supersede other pending suggestions for the same ref
631
- const toSupersede = workingSidecar.suggestions.filter(
632
- (s) => s.ref === sug.ref && s.status === "pending",
633
- );
634
- for (const other of toSupersede) {
635
- other.status = "rejected";
636
- other.resolvedAt = at;
637
- other.resolvedBy = "system";
638
- workingSidecar.suggestions.splice(workingSidecar.suggestions.indexOf(other), 1);
639
- workingSidecar.archivedSuggestions.push(other);
640
- workingEvents.push({
641
- type: "suggestion.rejected",
642
- at,
643
- by: "system",
644
- suggestionId: other.id,
645
- reason: "superseded",
646
- });
647
- }
648
-
649
- // Apply as block op
650
- const applyOp: Op = sug.kind === "replace"
651
- ? { type: "block.replace", ref: sug.ref, markdown: sug.markdown ?? "" }
652
- : sug.kind === "insertAfter"
653
- ? { type: "block.insertAfter", ref: sug.ref, markdown: sug.markdown ?? "" }
654
- : sug.kind === "insertBefore"
655
- ? { type: "block.insertBefore", ref: sug.ref, markdown: sug.markdown ?? "" }
656
- : { type: "block.delete", ref: sug.ref };
657
- ops.push(applyOp);
658
- workingEvents.push({ type: "suggestion.accepted", at, by, suggestionId: op.suggestionId });
659
- break;
660
- }
661
-
662
- case "suggestion.reject": {
663
- const sugIdx = workingSidecar.suggestions.findIndex((s) => s.id === op.suggestionId);
664
- if (sugIdx === -1) {
665
- return {
666
- ok: false,
667
- status: 409,
668
- code: "SUGGESTION_NOT_FOUND",
669
- message: `Suggestion "${op.suggestionId}" not found.`,
670
- snapshot: buildSnapshot(mdPath, workingBlocks, workingSidecar),
671
- };
672
- }
673
- const sug = workingSidecar.suggestions[sugIdx];
674
- sug.status = "rejected";
675
- sug.resolvedAt = at;
676
- sug.resolvedBy = by;
677
- workingSidecar.suggestions.splice(sugIdx, 1);
678
- workingSidecar.archivedSuggestions.push(sug);
679
- workingEvents.push({ type: "suggestion.rejected", at, by, suggestionId: op.suggestionId });
680
- break;
681
- }
682
-
683
- default:
684
- return { ok: false, status: 400, code: "INVALID_PAYLOAD", message: "Unknown op type" };
685
- }
686
- }
687
-
688
- // Rebuild final markdown from working nodes
689
- const newMarkdown = blocksToMarkdown(workingNodes);
690
- const newFingerprint = sha256file(newMarkdown);
691
-
692
- // Recompute refMap and aliases
693
- const reparsedNodes = parseBlocks(newMarkdown);
694
- const { blocks: finalBlocks, newRefMap: finalRefMap } = assignRefs(reparsedNodes, workingSidecar);
695
-
696
- const oldHashToRef = new Map<string, string>();
697
- for (const [ref, entry] of Object.entries(workingSidecar.refMap)) {
698
- if (!oldHashToRef.has(entry.textHash)) oldHashToRef.set(entry.textHash, ref);
699
- }
700
- const { refAliases } = computeRefDelta(workingSidecar.refMap, oldHashToRef, finalBlocks);
701
- Object.assign(collectedAliases, refAliases);
702
-
703
- workingSidecar.revision += 1;
704
- workingSidecar.updatedAt = nowIso();
705
- workingSidecar.fingerprint = newFingerprint;
706
- workingSidecar.refMap = finalRefMap;
707
- workingSidecar.refAliases = collectedAliases;
708
-
709
- // Emit all collected events
710
- const emitted = emitEvents(workingSidecar, workingEvents);
711
-
712
- // Trim if needed
713
- if (workingSidecar.revision % SIDECAR_TRIM_EVERY_N_MUTATIONS === 0) {
714
- trimEvents(workingSidecar, SIDECAR_EVENT_TRIM_SIZE);
715
- }
716
-
717
- // Atomic write
718
- await writeFile(path.join(rootDir, mdPath), newMarkdown, "utf-8");
719
- await writeSidecar(rootDir, mdPath, workingSidecar);
720
-
721
- return {
722
- ok: true,
723
- snapshot: buildSnapshot(mdPath, finalBlocks, workingSidecar),
724
- emittedEvents: emitted,
725
- };
726
- });
727
- }