@agent-native/core 0.100.1 → 0.101.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 (387) hide show
  1. package/corpus/README.md +2 -2
  2. package/corpus/core/CHANGELOG.md +73 -0
  3. package/corpus/core/docs/content/locales/ar-SA/pr-visual-recap.mdx +48 -30
  4. package/corpus/core/docs/content/locales/ar-SA/template-plan.mdx +7 -0
  5. package/corpus/core/docs/content/locales/de-DE/pr-visual-recap.mdx +48 -30
  6. package/corpus/core/docs/content/locales/de-DE/template-plan.mdx +7 -0
  7. package/corpus/core/docs/content/locales/es-ES/pr-visual-recap.mdx +48 -30
  8. package/corpus/core/docs/content/locales/es-ES/template-plan.mdx +14 -0
  9. package/corpus/core/docs/content/locales/fr-FR/pr-visual-recap.mdx +48 -30
  10. package/corpus/core/docs/content/locales/fr-FR/template-plan.mdx +7 -0
  11. package/corpus/core/docs/content/locales/hi-IN/pr-visual-recap.mdx +48 -30
  12. package/corpus/core/docs/content/locales/hi-IN/template-plan.mdx +7 -0
  13. package/corpus/core/docs/content/locales/ja-JP/pr-visual-recap.mdx +48 -30
  14. package/corpus/core/docs/content/locales/ja-JP/template-plan.mdx +7 -0
  15. package/corpus/core/docs/content/locales/ko-KR/pr-visual-recap.mdx +48 -30
  16. package/corpus/core/docs/content/locales/ko-KR/template-plan.mdx +7 -0
  17. package/corpus/core/docs/content/locales/pt-BR/pr-visual-recap.mdx +48 -30
  18. package/corpus/core/docs/content/locales/pt-BR/template-plan.mdx +14 -0
  19. package/corpus/core/docs/content/locales/zh-CN/pr-visual-recap.mdx +48 -30
  20. package/corpus/core/docs/content/locales/zh-CN/template-plan.mdx +7 -0
  21. package/corpus/core/docs/content/locales/zh-TW/pr-visual-recap.mdx +48 -30
  22. package/corpus/core/docs/content/locales/zh-TW/template-plan.mdx +7 -0
  23. package/corpus/core/docs/content/pr-visual-recap.mdx +50 -32
  24. package/corpus/core/docs/content/template-plan.mdx +14 -0
  25. package/corpus/core/docs/content/toolkit-comments-review.mdx +16 -2
  26. package/corpus/core/package.json +4 -1
  27. package/corpus/core/src/a2a/index.ts +2 -1
  28. package/corpus/core/src/a2a/server.ts +34 -9
  29. package/corpus/core/src/agent/production-agent.ts +56 -10
  30. package/corpus/core/src/cli/create.ts +47 -19
  31. package/corpus/core/src/cli/pr-visual-recap-workflow.ts +2 -3
  32. package/corpus/core/src/cli/recap.ts +3 -4932
  33. package/corpus/core/src/cli/skills-content/visual-plan-skill.ts +6 -4
  34. package/corpus/core/src/cli/skills-content/visual-recap-skill.ts +7 -1
  35. package/corpus/core/src/client/AgentPanel.tsx +19 -17
  36. package/corpus/core/src/client/AssistantChat.tsx +4 -0
  37. package/corpus/core/src/client/analytics.ts +8 -1
  38. package/corpus/core/src/client/chat/markdown-renderer.tsx +54 -8
  39. package/corpus/core/src/client/chat/message-components.tsx +8 -2
  40. package/corpus/core/src/client/clipboard.ts +28 -1
  41. package/corpus/core/src/client/composer/PromptComposer.tsx +4 -0
  42. package/corpus/core/src/client/composer/TiptapComposer.tsx +30 -3
  43. package/corpus/core/src/client/guided-questions.tsx +4 -0
  44. package/corpus/core/src/client/i18n.tsx +2 -1
  45. package/corpus/core/src/client/index.ts +4 -0
  46. package/corpus/core/src/client/review/ReviewCommentComposer.tsx +108 -0
  47. package/corpus/core/src/client/review/ReviewThreadPanel.tsx +482 -150
  48. package/corpus/core/src/client/review/index.ts +8 -0
  49. package/corpus/core/src/client/review/use-review.ts +35 -1
  50. package/corpus/core/src/client/use-agent-chat-context.ts +3 -2
  51. package/corpus/core/src/integrations/webhook-handler.ts +4 -2
  52. package/corpus/core/src/review/actions/create-review-comment.ts +2 -1
  53. package/corpus/core/src/review/actions/get-review-feedback.ts +6 -11
  54. package/corpus/core/src/review/actions/list-review-comments.ts +38 -4
  55. package/corpus/core/src/review/actions/reply-review-comment.ts +33 -22
  56. package/corpus/core/src/review/actions/resolve-review-thread.ts +29 -2
  57. package/corpus/core/src/review/actions/send-review-thread-to-agent.ts +62 -0
  58. package/corpus/core/src/review/identity.ts +101 -0
  59. package/corpus/core/src/review/index.ts +14 -0
  60. package/corpus/core/src/review/store.ts +315 -8
  61. package/corpus/core/src/review/types.ts +4 -0
  62. package/corpus/core/src/secrets/crypto.ts +98 -47
  63. package/corpus/core/src/secrets/index.ts +2 -1
  64. package/corpus/core/src/secrets/schema.ts +3 -0
  65. package/corpus/core/src/secrets/storage.ts +164 -31
  66. package/corpus/core/src/server/action-discovery.ts +4 -0
  67. package/corpus/core/src/server/action-routes.ts +125 -4
  68. package/corpus/core/src/server/agent-chat/plugin-options.ts +16 -0
  69. package/corpus/core/src/server/agent-chat-plugin.ts +1 -0
  70. package/corpus/core/src/server/index.ts +8 -0
  71. package/corpus/core/src/vite/action-types-plugin.ts +4 -0
  72. package/corpus/templates/analytics/changelog/2026-07-14-daily-dashboard-email-captures-authenticate-with-a-sessi.md +6 -0
  73. package/corpus/templates/analytics/server/lib/dashboard-report.ts +156 -3
  74. package/corpus/templates/assets/app/components/generation/GenerationResults.tsx +402 -142
  75. package/corpus/templates/assets/app/components/layout/Layout.tsx +4 -0
  76. package/corpus/templates/assets/app/hooks/use-navigation-state.ts +3 -1
  77. package/corpus/templates/assets/app/i18n/zh-TW.ts +1 -0
  78. package/corpus/templates/assets/app/i18n-data.ts +1 -0
  79. package/corpus/templates/assets/app/routes/library.tsx +187 -48
  80. package/corpus/templates/assets/changelog/2026-07-13-assets-keeps-the-right-chat-sidebar-closed-when-the-full-pag.md +6 -0
  81. package/corpus/templates/assets/changelog/2026-07-13-merged-the-candidates-panel-into-the-library-as-a-drafts-tab.md +6 -0
  82. package/corpus/templates/chat/app/lib/agent-page.tsx +40 -0
  83. package/corpus/templates/chat/app/routes/agent.tsx +5 -3
  84. package/corpus/templates/chat/changelog/2026-07-14-fixed-chat-template-startup-with-older-core-versions.md +6 -0
  85. package/corpus/templates/clips/.agents/skills/ai-video-tools/SKILL.md +5 -0
  86. package/corpus/templates/clips/AGENTS.md +4 -0
  87. package/corpus/templates/clips/actions/get-feature-flags.ts +30 -0
  88. package/corpus/templates/clips/actions/lib/transcript-preview.ts +48 -0
  89. package/corpus/templates/clips/actions/request-transcript.ts +41 -1
  90. package/corpus/templates/clips/actions/view-screen.ts +5 -9
  91. package/corpus/templates/clips/app/components/library/library-layout.tsx +1 -1
  92. package/corpus/templates/clips/app/components/player/video-player.tsx +39 -1
  93. package/corpus/templates/clips/app/hooks/use-desktop-promo.ts +6 -12
  94. package/corpus/templates/clips/app/hooks/use-mse-video-source.ts +146 -0
  95. package/corpus/templates/clips/app/lib/capture-install-options.ts +21 -0
  96. package/corpus/templates/clips/app/lib/fmp4.ts +271 -0
  97. package/corpus/templates/clips/app/lib/mse-video-loader.ts +585 -0
  98. package/corpus/templates/clips/app/routes/_app.dictate.tsx +0 -4
  99. package/corpus/templates/clips/app/routes/_app.meetings.$meetingId.tsx +5 -13
  100. package/corpus/templates/clips/app/routes/_app.meetings._index.tsx +2 -37
  101. package/corpus/templates/clips/app/routes/download.tsx +3 -2
  102. package/corpus/templates/clips/changelog/2026-07-10-shared-clips-now-start-playing-instantly-instead-of-showing-.md +6 -0
  103. package/corpus/templates/clips/changelog/2026-07-14-clips-now-distinguishes-transcript-previews-from-incomplete-.md +6 -0
  104. package/corpus/templates/clips/changelog/2026-07-14-desktop-app-prompts-stay-hidden-after-you-download-the-insta.md +6 -0
  105. package/corpus/templates/clips/desktop/src/lib/recorder.ts +5 -0
  106. package/corpus/templates/clips/desktop/src/overlays/recording-pill.tsx +10 -0
  107. package/corpus/templates/clips/desktop/src-tauri/src/lib.rs +4 -0
  108. package/corpus/templates/clips/desktop/src-tauri/src/native_screen/custom_capture.rs +2518 -0
  109. package/corpus/templates/clips/desktop/src-tauri/src/native_screen/live_upload.rs +353 -0
  110. package/corpus/templates/clips/desktop/src-tauri/src/native_screen.rs +558 -67
  111. package/corpus/templates/clips/desktop/src-tauri/src/recording_indicator.rs +11 -1
  112. package/corpus/templates/clips/desktop/src-tauri/src/remote_flags.rs +188 -0
  113. package/corpus/templates/clips/desktop/src-tauri/src/whisper_speech.rs +1 -1
  114. package/corpus/templates/clips/server/lib/post-finalize-dispatch.ts +1 -0
  115. package/corpus/templates/clips/server/plugins/agent-chat.ts +5 -0
  116. package/corpus/templates/clips/server/routes/api/_agent-native-background/post-finalize-worker.post.ts +5 -1
  117. package/corpus/templates/clips/shared/feature-flags.ts +41 -0
  118. package/corpus/templates/design/.agents/skills/design-generation/SKILL.md +3 -0
  119. package/corpus/templates/design/.agents/skills/design-review-feedback/SKILL.md +42 -0
  120. package/corpus/templates/design/AGENTS.md +6 -0
  121. package/corpus/templates/design/README.md +1 -0
  122. package/corpus/templates/design/actions/navigate.ts +4 -4
  123. package/corpus/templates/design/actions/view-screen.ts +116 -2
  124. package/corpus/templates/design/agent-native.app-skill.json +5 -0
  125. package/corpus/templates/design/app/components/design/DesignCanvas.tsx +52 -59
  126. package/corpus/templates/design/app/components/design/DesignExtensionsPanel.tsx +13 -9
  127. package/corpus/templates/design/app/components/design/EditPanel.tsx +79 -11
  128. package/corpus/templates/design/app/components/design/LayersPanel.tsx +78 -65
  129. package/corpus/templates/design/app/components/design/ReviewCommentsPanel.tsx +161 -0
  130. package/corpus/templates/design/app/components/design/ReviewStatusControl.tsx +96 -0
  131. package/corpus/templates/design/app/components/design/bridge/hit-test.bridge.ts +166 -0
  132. package/corpus/templates/design/app/components/layout/Layout.tsx +1 -0
  133. package/corpus/templates/design/app/components/visual-editor/ReviewCanvasPins.tsx +1077 -0
  134. package/corpus/templates/design/app/components/visual-editor/index.ts +1 -0
  135. package/corpus/templates/design/app/components/visual-editor/review-canvas-state.ts +42 -0
  136. package/corpus/templates/design/app/hooks/use-design-systems.ts +2 -2
  137. package/corpus/templates/design/app/hooks/use-navigation-state.ts +9 -6
  138. package/corpus/templates/design/app/hooks/use-question-flow.ts +7 -1
  139. package/corpus/templates/design/app/i18n/ar-SA.ts +56 -1
  140. package/corpus/templates/design/app/i18n/de-DE.ts +57 -1
  141. package/corpus/templates/design/app/i18n/en-US.ts +56 -1
  142. package/corpus/templates/design/app/i18n/es-ES.ts +56 -1
  143. package/corpus/templates/design/app/i18n/fr-FR.ts +57 -1
  144. package/corpus/templates/design/app/i18n/hi-IN.ts +56 -1
  145. package/corpus/templates/design/app/i18n/ja-JP.ts +56 -1
  146. package/corpus/templates/design/app/i18n/ko-KR.ts +56 -1
  147. package/corpus/templates/design/app/i18n/pt-BR.ts +57 -1
  148. package/corpus/templates/design/app/i18n/zh-CN.ts +56 -1
  149. package/corpus/templates/design/app/i18n/zh-TW.ts +51 -0
  150. package/corpus/templates/design/app/pages/Present.tsx +172 -14
  151. package/corpus/templates/design/app/pages/design-editor/overview-camera.ts +23 -0
  152. package/corpus/templates/design/app/pages/design-editor/tool-state.ts +10 -0
  153. package/corpus/templates/design/app/pages/present-review-state.ts +18 -0
  154. package/corpus/templates/design/app/public-routes.ts +8 -0
  155. package/corpus/templates/design/app/root.tsx +7 -6
  156. package/corpus/templates/design/changelog/2026-07-13-dragged-design-assets-now-appear-at-the-visible-drop-locatio.md +6 -0
  157. package/corpus/templates/design/changelog/2026-07-13-reviewers-can-pin-comments-on-shared-designs-and-apply-verif.md +6 -0
  158. package/corpus/templates/design/server/plugins/agent-chat.ts +10 -0
  159. package/corpus/templates/design/server/plugins/auth.ts +7 -5
  160. package/corpus/templates/design/server/plugins/review.ts +9 -0
  161. package/corpus/templates/design/shared/review-anchor.ts +83 -0
  162. package/corpus/templates/design/shared/review-summary.ts +25 -0
  163. package/corpus/templates/forms/.agents/skills/form-publishing/SKILL.md +2 -0
  164. package/corpus/templates/forms/AGENTS.md +4 -0
  165. package/corpus/templates/forms/actions/create-form.ts +2 -1
  166. package/corpus/templates/forms/actions/update-form.ts +5 -2
  167. package/corpus/templates/forms/app/i18n/ar-SA.ts +3 -0
  168. package/corpus/templates/forms/app/i18n/de-DE.ts +3 -0
  169. package/corpus/templates/forms/app/i18n/en-US.ts +3 -0
  170. package/corpus/templates/forms/app/i18n/es-ES.ts +3 -0
  171. package/corpus/templates/forms/app/i18n/fr-FR.ts +3 -0
  172. package/corpus/templates/forms/app/i18n/hi-IN.ts +3 -0
  173. package/corpus/templates/forms/app/i18n/ja-JP.ts +3 -0
  174. package/corpus/templates/forms/app/i18n/ko-KR.ts +3 -0
  175. package/corpus/templates/forms/app/i18n/pt-BR.ts +3 -0
  176. package/corpus/templates/forms/app/i18n/zh-CN.ts +3 -0
  177. package/corpus/templates/forms/app/i18n/zh-TW.ts +3 -0
  178. package/corpus/templates/forms/app/pages/FormBuilderPage.tsx +19 -0
  179. package/corpus/templates/forms/changelog/2026-07-14-fixed-the-ask-forms-loading-input-appearing-above-the-welcom.md +6 -0
  180. package/corpus/templates/forms/changelog/2026-07-14-form-social-previews-now-show-the-form-title-description-and.md +6 -0
  181. package/corpus/templates/forms/changelog/2026-07-14-forms-can-email-the-form-owner-when-new-responses-arrive.md +6 -0
  182. package/corpus/templates/forms/server/handlers/submissions.ts +17 -0
  183. package/corpus/templates/forms/server/lib/form-og-image.ts +64 -6
  184. package/corpus/templates/forms/server/lib/public-form-ssr.ts +6 -2
  185. package/corpus/templates/forms/server/lib/response-email.ts +65 -0
  186. package/corpus/templates/forms/server/plugins/agent-chat.ts +1 -0
  187. package/corpus/templates/forms/server/routes/api/forms/og/[...slug]/og.png.get.ts +184 -0
  188. package/corpus/templates/forms/shared/types.ts +2 -0
  189. package/corpus/templates/plan/.agents/skills/visual-plan/SKILL.md +6 -4
  190. package/corpus/templates/plan/.agents/skills/visual-recap/SKILL.md +7 -1
  191. package/dist/a2a/index.d.ts +2 -1
  192. package/dist/a2a/index.d.ts.map +1 -1
  193. package/dist/a2a/index.js +1 -1
  194. package/dist/a2a/index.js.map +1 -1
  195. package/dist/a2a/server.d.ts +25 -0
  196. package/dist/a2a/server.d.ts.map +1 -1
  197. package/dist/a2a/server.js +30 -6
  198. package/dist/a2a/server.js.map +1 -1
  199. package/dist/agent/production-agent.d.ts +2 -0
  200. package/dist/agent/production-agent.d.ts.map +1 -1
  201. package/dist/agent/production-agent.js +37 -12
  202. package/dist/agent/production-agent.js.map +1 -1
  203. package/dist/cli/create.d.ts +5 -3
  204. package/dist/cli/create.d.ts.map +1 -1
  205. package/dist/cli/create.js +44 -19
  206. package/dist/cli/create.js.map +1 -1
  207. package/dist/cli/pr-visual-recap-workflow.d.ts +2 -2
  208. package/dist/cli/pr-visual-recap-workflow.d.ts.map +1 -1
  209. package/dist/cli/pr-visual-recap-workflow.js +2 -2
  210. package/dist/cli/pr-visual-recap-workflow.js.map +1 -1
  211. package/dist/cli/recap.d.ts +3 -562
  212. package/dist/cli/recap.d.ts.map +1 -1
  213. package/dist/cli/recap.js +3 -3875
  214. package/dist/cli/recap.js.map +1 -1
  215. package/dist/cli/skills-content/visual-plan-skill.d.ts +1 -1
  216. package/dist/cli/skills-content/visual-plan-skill.d.ts.map +1 -1
  217. package/dist/cli/skills-content/visual-plan-skill.js +6 -4
  218. package/dist/cli/skills-content/visual-plan-skill.js.map +1 -1
  219. package/dist/cli/skills-content/visual-recap-skill.d.ts +1 -1
  220. package/dist/cli/skills-content/visual-recap-skill.d.ts.map +1 -1
  221. package/dist/cli/skills-content/visual-recap-skill.js +7 -1
  222. package/dist/cli/skills-content/visual-recap-skill.js.map +1 -1
  223. package/dist/client/AgentPanel.d.ts.map +1 -1
  224. package/dist/client/AgentPanel.js +3 -3
  225. package/dist/client/AgentPanel.js.map +1 -1
  226. package/dist/client/AssistantChat.d.ts +2 -0
  227. package/dist/client/AssistantChat.d.ts.map +1 -1
  228. package/dist/client/AssistantChat.js +2 -2
  229. package/dist/client/AssistantChat.js.map +1 -1
  230. package/dist/client/analytics.d.ts +5 -0
  231. package/dist/client/analytics.d.ts.map +1 -1
  232. package/dist/client/analytics.js +3 -1
  233. package/dist/client/analytics.js.map +1 -1
  234. package/dist/client/chat/markdown-renderer.d.ts +1 -0
  235. package/dist/client/chat/markdown-renderer.d.ts.map +1 -1
  236. package/dist/client/chat/markdown-renderer.js +36 -1
  237. package/dist/client/chat/markdown-renderer.js.map +1 -1
  238. package/dist/client/chat/message-components.d.ts.map +1 -1
  239. package/dist/client/chat/message-components.js +5 -2
  240. package/dist/client/chat/message-components.js.map +1 -1
  241. package/dist/client/clipboard.d.ts +3 -1
  242. package/dist/client/clipboard.d.ts.map +1 -1
  243. package/dist/client/clipboard.js +24 -1
  244. package/dist/client/clipboard.js.map +1 -1
  245. package/dist/client/composer/PromptComposer.d.ts +2 -0
  246. package/dist/client/composer/PromptComposer.d.ts.map +1 -1
  247. package/dist/client/composer/PromptComposer.js +2 -2
  248. package/dist/client/composer/PromptComposer.js.map +1 -1
  249. package/dist/client/composer/TiptapComposer.d.ts +3 -1
  250. package/dist/client/composer/TiptapComposer.d.ts.map +1 -1
  251. package/dist/client/composer/TiptapComposer.js +20 -5
  252. package/dist/client/composer/TiptapComposer.js.map +1 -1
  253. package/dist/client/guided-questions.d.ts +3 -1
  254. package/dist/client/guided-questions.d.ts.map +1 -1
  255. package/dist/client/guided-questions.js +2 -1
  256. package/dist/client/guided-questions.js.map +1 -1
  257. package/dist/client/i18n.d.ts.map +1 -1
  258. package/dist/client/i18n.js +3 -1
  259. package/dist/client/i18n.js.map +1 -1
  260. package/dist/client/index.d.ts +1 -1
  261. package/dist/client/index.d.ts.map +1 -1
  262. package/dist/client/index.js +1 -1
  263. package/dist/client/index.js.map +1 -1
  264. package/dist/client/review/ReviewCommentComposer.d.ts +18 -0
  265. package/dist/client/review/ReviewCommentComposer.d.ts.map +1 -0
  266. package/dist/client/review/ReviewCommentComposer.js +30 -0
  267. package/dist/client/review/ReviewCommentComposer.js.map +1 -0
  268. package/dist/client/review/ReviewThreadPanel.d.ts +28 -1
  269. package/dist/client/review/ReviewThreadPanel.d.ts.map +1 -1
  270. package/dist/client/review/ReviewThreadPanel.js +151 -39
  271. package/dist/client/review/ReviewThreadPanel.js.map +1 -1
  272. package/dist/client/review/index.d.ts +3 -2
  273. package/dist/client/review/index.d.ts.map +1 -1
  274. package/dist/client/review/index.js +2 -1
  275. package/dist/client/review/index.js.map +1 -1
  276. package/dist/client/review/use-review.d.ts +23 -0
  277. package/dist/client/review/use-review.d.ts.map +1 -1
  278. package/dist/client/review/use-review.js +3 -0
  279. package/dist/client/review/use-review.js.map +1 -1
  280. package/dist/client/use-agent-chat-context.d.ts +1 -1
  281. package/dist/client/use-agent-chat-context.d.ts.map +1 -1
  282. package/dist/client/use-agent-chat-context.js +4 -2
  283. package/dist/client/use-agent-chat-context.js.map +1 -1
  284. package/dist/collab/awareness.d.ts +2 -2
  285. package/dist/collab/awareness.d.ts.map +1 -1
  286. package/dist/collab/struct-routes.d.ts +1 -1
  287. package/dist/file-upload/actions/upload-image.d.ts +1 -1
  288. package/dist/integrations/webhook-handler.d.ts.map +1 -1
  289. package/dist/integrations/webhook-handler.js +3 -2
  290. package/dist/integrations/webhook-handler.js.map +1 -1
  291. package/dist/notifications/routes.d.ts +3 -3
  292. package/dist/observability/routes.d.ts +5 -5
  293. package/dist/progress/routes.d.ts +1 -1
  294. package/dist/provider-api/corpus-jobs.d.ts +2 -2
  295. package/dist/resources/handlers.d.ts +2 -2
  296. package/dist/review/actions/create-review-comment.js +2 -1
  297. package/dist/review/actions/create-review-comment.js.map +1 -1
  298. package/dist/review/actions/get-review-feedback.js +6 -11
  299. package/dist/review/actions/get-review-feedback.js.map +1 -1
  300. package/dist/review/actions/list-review-comments.d.ts +1 -0
  301. package/dist/review/actions/list-review-comments.js +25 -4
  302. package/dist/review/actions/list-review-comments.js.map +1 -1
  303. package/dist/review/actions/reply-review-comment.js +12 -5
  304. package/dist/review/actions/reply-review-comment.js.map +1 -1
  305. package/dist/review/actions/resolve-review-thread.d.ts +3 -0
  306. package/dist/review/actions/resolve-review-thread.js +20 -3
  307. package/dist/review/actions/resolve-review-thread.js.map +1 -1
  308. package/dist/review/actions/send-review-thread-to-agent.d.ts +17 -0
  309. package/dist/review/actions/send-review-thread-to-agent.d.ts.map +1 -0
  310. package/dist/review/actions/send-review-thread-to-agent.js +49 -0
  311. package/dist/review/actions/send-review-thread-to-agent.js.map +1 -0
  312. package/dist/review/identity.d.ts +6 -0
  313. package/dist/review/identity.d.ts.map +1 -0
  314. package/dist/review/identity.js +68 -0
  315. package/dist/review/identity.js.map +1 -0
  316. package/dist/review/index.d.ts +3 -1
  317. package/dist/review/index.d.ts.map +1 -1
  318. package/dist/review/index.js +2 -1
  319. package/dist/review/index.js.map +1 -1
  320. package/dist/review/store.d.ts +36 -0
  321. package/dist/review/store.d.ts.map +1 -1
  322. package/dist/review/store.js +223 -8
  323. package/dist/review/store.js.map +1 -1
  324. package/dist/review/types.d.ts +4 -0
  325. package/dist/review/types.d.ts.map +1 -1
  326. package/dist/review/types.js.map +1 -1
  327. package/dist/secrets/crypto.d.ts +35 -13
  328. package/dist/secrets/crypto.d.ts.map +1 -1
  329. package/dist/secrets/crypto.js +78 -41
  330. package/dist/secrets/crypto.js.map +1 -1
  331. package/dist/secrets/index.d.ts.map +1 -1
  332. package/dist/secrets/index.js +2 -1
  333. package/dist/secrets/index.js.map +1 -1
  334. package/dist/secrets/routes.d.ts +9 -9
  335. package/dist/secrets/schema.d.ts +20 -1
  336. package/dist/secrets/schema.d.ts.map +1 -1
  337. package/dist/secrets/schema.js +3 -0
  338. package/dist/secrets/schema.js.map +1 -1
  339. package/dist/secrets/storage.d.ts +7 -7
  340. package/dist/secrets/storage.d.ts.map +1 -1
  341. package/dist/secrets/storage.js +121 -30
  342. package/dist/secrets/storage.js.map +1 -1
  343. package/dist/server/action-discovery.d.ts.map +1 -1
  344. package/dist/server/action-discovery.js +4 -0
  345. package/dist/server/action-discovery.js.map +1 -1
  346. package/dist/server/action-routes.d.ts +45 -0
  347. package/dist/server/action-routes.d.ts.map +1 -1
  348. package/dist/server/action-routes.js +71 -5
  349. package/dist/server/action-routes.js.map +1 -1
  350. package/dist/server/agent-chat/plugin-options.d.ts +16 -0
  351. package/dist/server/agent-chat/plugin-options.d.ts.map +1 -1
  352. package/dist/server/agent-chat/plugin-options.js.map +1 -1
  353. package/dist/server/agent-chat-plugin.d.ts.map +1 -1
  354. package/dist/server/agent-chat-plugin.js +1 -0
  355. package/dist/server/agent-chat-plugin.js.map +1 -1
  356. package/dist/server/index.d.ts +3 -1
  357. package/dist/server/index.d.ts.map +1 -1
  358. package/dist/server/index.js +2 -0
  359. package/dist/server/index.js.map +1 -1
  360. package/dist/vite/action-types-plugin.d.ts.map +1 -1
  361. package/dist/vite/action-types-plugin.js +4 -0
  362. package/dist/vite/action-types-plugin.js.map +1 -1
  363. package/docs/content/locales/ar-SA/pr-visual-recap.mdx +48 -30
  364. package/docs/content/locales/ar-SA/template-plan.mdx +7 -0
  365. package/docs/content/locales/de-DE/pr-visual-recap.mdx +48 -30
  366. package/docs/content/locales/de-DE/template-plan.mdx +7 -0
  367. package/docs/content/locales/es-ES/pr-visual-recap.mdx +48 -30
  368. package/docs/content/locales/es-ES/template-plan.mdx +14 -0
  369. package/docs/content/locales/fr-FR/pr-visual-recap.mdx +48 -30
  370. package/docs/content/locales/fr-FR/template-plan.mdx +7 -0
  371. package/docs/content/locales/hi-IN/pr-visual-recap.mdx +48 -30
  372. package/docs/content/locales/hi-IN/template-plan.mdx +7 -0
  373. package/docs/content/locales/ja-JP/pr-visual-recap.mdx +48 -30
  374. package/docs/content/locales/ja-JP/template-plan.mdx +7 -0
  375. package/docs/content/locales/ko-KR/pr-visual-recap.mdx +48 -30
  376. package/docs/content/locales/ko-KR/template-plan.mdx +7 -0
  377. package/docs/content/locales/pt-BR/pr-visual-recap.mdx +48 -30
  378. package/docs/content/locales/pt-BR/template-plan.mdx +14 -0
  379. package/docs/content/locales/zh-CN/pr-visual-recap.mdx +48 -30
  380. package/docs/content/locales/zh-CN/template-plan.mdx +7 -0
  381. package/docs/content/locales/zh-TW/pr-visual-recap.mdx +48 -30
  382. package/docs/content/locales/zh-TW/template-plan.mdx +7 -0
  383. package/docs/content/pr-visual-recap.mdx +50 -32
  384. package/docs/content/template-plan.mdx +14 -0
  385. package/docs/content/toolkit-comments-review.mdx +16 -2
  386. package/package.json +4 -1
  387. package/corpus/templates/forms/server/routes/api/forms/og/[slug]/og.png.get.ts +0 -45
@@ -1,3 +1,7 @@
1
+ export {
2
+ ReviewCommentComposer,
3
+ type ReviewCommentComposerProps,
4
+ } from "./ReviewCommentComposer.js";
1
5
  export {
2
6
  ReviewStatusBadge,
3
7
  type ReviewStatusBadgeProps,
@@ -6,6 +10,8 @@ export {
6
10
  ReviewThreadPanel,
7
11
  buildReviewThreads,
8
12
  type ReviewThread,
13
+ type ReviewCommentCapability,
14
+ type ReviewThreadCapability,
9
15
  type ReviewThreadPanelProps,
10
16
  } from "./ReviewThreadPanel.js";
11
17
  export {
@@ -17,6 +23,7 @@ export {
17
23
  useReviewComments,
18
24
  useReviewFeedback,
19
25
  useSetReviewStatus,
26
+ useSendReviewThreadToAgent,
20
27
  type ConsumeReviewFeedbackInput,
21
28
  type CreateReviewCommentInput,
22
29
  type DeleteReviewCommentInput,
@@ -27,4 +34,5 @@ export {
27
34
  type ReplyReviewCommentInput,
28
35
  type ResolveReviewThreadInput,
29
36
  type SetReviewStatusInput,
37
+ type SendReviewThreadToAgentInput,
30
38
  } from "./use-review.js";
@@ -20,6 +20,10 @@ export interface ListReviewCommentsParams {
20
20
  export interface ListReviewCommentsResult {
21
21
  comments: ReviewComment[];
22
22
  reviewStatus: ReviewStatusEntry | null;
23
+ summary: {
24
+ openCount: number;
25
+ agentQueueCount: number;
26
+ };
23
27
  }
24
28
 
25
29
  export interface GetReviewFeedbackParams {
@@ -62,6 +66,7 @@ export interface ResolveReviewThreadInput {
62
66
  resourceId: string;
63
67
  threadId?: string;
64
68
  commentId?: string;
69
+ resolutionNote?: string;
65
70
  }
66
71
 
67
72
  export interface DeleteReviewCommentInput {
@@ -76,6 +81,12 @@ export interface ConsumeReviewFeedbackInput {
76
81
  commentIds: string[];
77
82
  }
78
83
 
84
+ export interface SendReviewThreadToAgentInput {
85
+ resourceType: string;
86
+ resourceId: string;
87
+ threadId: string;
88
+ }
89
+
79
90
  export interface SetReviewStatusInput {
80
91
  resourceType: string;
81
92
  resourceId: string;
@@ -126,7 +137,13 @@ export function useReplyReviewComment() {
126
137
 
127
138
  export function useResolveReviewThread() {
128
139
  return useActionMutation<
129
- { threadId: string; resolved: true; updatedCount: number },
140
+ {
141
+ threadId: string;
142
+ resolved: true;
143
+ updatedCount: number;
144
+ resolutionNote: string | null;
145
+ comment: ReviewComment;
146
+ },
130
147
  ResolveReviewThreadInput
131
148
  >("resolve-review-thread");
132
149
  }
@@ -145,6 +162,23 @@ export function useConsumeReviewFeedback() {
145
162
  >("consume-review-feedback");
146
163
  }
147
164
 
165
+ export function useSendReviewThreadToAgent() {
166
+ return useActionMutation<
167
+ {
168
+ resourceType: string;
169
+ resourceId: string;
170
+ threadId: string;
171
+ resolutionTarget: "agent";
172
+ consumedAt: null;
173
+ updatedCount: number;
174
+ ownerEmail: string | null;
175
+ orgId: string | null;
176
+ visibility: "private" | "org" | "public";
177
+ },
178
+ SendReviewThreadToAgentInput
179
+ >("send-review-thread-to-agent");
180
+ }
181
+
148
182
  export function useSetReviewStatus() {
149
183
  return useActionMutation<ReviewStatusEntry, SetReviewStatusInput>(
150
184
  "set-review-status",
@@ -26,7 +26,7 @@ export interface UseAgentChatContextResult extends AgentChatContextState {
26
26
  * composer's staged context chips. Simple send/prefill flows should use
27
27
  * `sendToAgentChat({ message, context, submit })` directly.
28
28
  */
29
- export function useAgentChatContext(): UseAgentChatContextResult {
29
+ export function useAgentChatContext(enabled = true): UseAgentChatContextResult {
30
30
  const appStateVersion = useChangeVersion("app-state");
31
31
  const state = useSyncExternalStore(
32
32
  subscribeAgentChatContext,
@@ -35,8 +35,9 @@ export function useAgentChatContext(): UseAgentChatContextResult {
35
35
  );
36
36
 
37
37
  useEffect(() => {
38
+ if (!enabled) return;
38
39
  void refreshAgentChatContext();
39
- }, [appStateVersion]);
40
+ }, [appStateVersion, enabled]);
40
41
 
41
42
  const set = useCallback((item: AgentChatContextSetOptions) => {
42
43
  setAgentChatContextItem(item);
@@ -74,6 +74,8 @@ import {
74
74
  const PROCESSOR_DISPATCH_SETTLE_WAIT_MS = 1_500;
75
75
  const DEFERRED_RESPONSE_DISPATCH_SETTLE_WAIT_MS = 1_500;
76
76
  const DEFERRED_RESPONSE_MAX_HANDLER_MS = 2_500;
77
+ const EMPTY_INTEGRATION_RESPONSE_MESSAGE =
78
+ "The model finished without a visible answer. Try again, or open the thread in Dispatch to inspect the run.";
77
79
 
78
80
  type ToolDoneEvent = { type: "tool_done"; tool: string; result: string };
79
81
 
@@ -972,7 +974,7 @@ async function processIncomingMessage(
972
974
  "If it was a complex analytics question, opening the analytics app " +
973
975
  "directly is the most reliable way to get an answer right now.";
974
976
  } else {
975
- responseText = "(No response)";
977
+ responseText = EMPTY_INTEGRATION_RESPONSE_MESSAGE;
976
978
  }
977
979
  }
978
980
  if (approval?.type === "approval_required") {
@@ -995,7 +997,7 @@ async function processIncomingMessage(
995
997
  }
996
998
  const threadDeepLinkUrl =
997
999
  appBaseUrl && threadId
998
- ? `${appBaseUrl}/?thread=${threadId}`
1000
+ ? `${appBaseUrl}/chat/${encodeURIComponent(threadId)}`
999
1001
  : undefined;
1000
1002
 
1001
1003
  // Format and send back to platform — update the "thinking…"
@@ -1,6 +1,7 @@
1
1
  import { z } from "zod";
2
2
 
3
3
  import { defineAction } from "../../action.js";
4
+ import { reviewAuthorNameFromContext } from "../identity.js";
4
5
  import { extractReviewMentions, normalizeReviewMentions } from "../mentions.js";
5
6
  import {
6
7
  assertReviewableResourceAccess,
@@ -68,7 +69,7 @@ export default defineAction({
68
69
  anchor: args.anchor ?? null,
69
70
  body: args.body,
70
71
  authorEmail: actionCtx?.userEmail ?? null,
71
- authorName: args.authorName ?? actionCtx?.userEmail ?? null,
72
+ authorName: args.authorName ?? reviewAuthorNameFromContext(actionCtx),
72
73
  createdBy: actorKindFromContext(actionCtx),
73
74
  resolutionTarget,
74
75
  mentions,
@@ -37,18 +37,13 @@ export default defineAction({
37
37
  bypassScope: true,
38
38
  includeResolved: false,
39
39
  includeDeleted: false,
40
+ rootOnly: true,
41
+ resolutionTargets: args.includeHumanTargeted
42
+ ? undefined
43
+ : ["agent", null],
44
+ unconsumedOnly: true,
40
45
  limit: args.limit,
41
46
  });
42
- return {
43
- comments: comments.filter((comment) => {
44
- if (comment.consumedAt) {
45
- return false;
46
- }
47
- if (args.includeHumanTargeted) {
48
- return true;
49
- }
50
- return comment.resolutionTarget !== "human";
51
- }),
52
- };
47
+ return { comments };
53
48
  },
54
49
  });
@@ -1,8 +1,17 @@
1
1
  import { z } from "zod";
2
2
 
3
3
  import { defineAction } from "../../action.js";
4
+ import {
5
+ redactPublicReviewCommentIdentity,
6
+ redactPublicReviewStatusIdentity,
7
+ shouldRedactReviewIdentity,
8
+ } from "../identity.js";
4
9
  import { assertReviewableResourceAccess } from "../registry.js";
5
- import { getReviewStatus, queryReviewComments } from "../store.js";
10
+ import {
11
+ getReviewStatus,
12
+ getReviewThreadSummary,
13
+ queryReviewComments,
14
+ } from "../store.js";
6
15
  import type { ReviewResourceContext } from "../types.js";
7
16
 
8
17
  const schema = z.object({
@@ -19,11 +28,12 @@ export default defineAction({
19
28
  "List inline comments, annotations, and review threads for a resource.",
20
29
  schema,
21
30
  http: { method: "GET" },
31
+ requiresAuth: false,
22
32
  readOnly: true,
23
33
  parallelSafe: true,
24
34
  run: async (args, ctx) => {
25
35
  const actionCtx = ctx as ReviewResourceContext | undefined;
26
- await assertReviewableResourceAccess(
36
+ const access = await assertReviewableResourceAccess(
27
37
  args.resourceType,
28
38
  args.resourceId,
29
39
  actionCtx,
@@ -33,7 +43,7 @@ export default defineAction({
33
43
  userEmail: actionCtx?.userEmail ?? null,
34
44
  orgId: actionCtx?.orgId ?? null,
35
45
  };
36
- const [comments, reviewStatus] = await Promise.all([
46
+ const [comments, reviewStatus, summary] = await Promise.all([
37
47
  queryReviewComments({
38
48
  resourceType: args.resourceType,
39
49
  resourceId: args.resourceId,
@@ -47,7 +57,31 @@ export default defineAction({
47
57
  getReviewStatus(args.resourceType, args.resourceId, scope, {
48
58
  bypassScope: true,
49
59
  }),
60
+ getReviewThreadSummary({
61
+ resourceType: args.resourceType,
62
+ resourceId: args.resourceId,
63
+ scope,
64
+ bypassScope: true,
65
+ targetId: args.targetId,
66
+ }),
50
67
  ]);
51
- return { comments, reviewStatus };
68
+ const redactIdentity = shouldRedactReviewIdentity(actionCtx, access);
69
+ const commentsWithCapabilities = comments.map((comment) => ({
70
+ ...comment,
71
+ canDelete:
72
+ access.role !== "viewer" ||
73
+ Boolean(
74
+ actionCtx?.userEmail && comment.authorEmail === actionCtx.userEmail,
75
+ ),
76
+ }));
77
+ return redactIdentity
78
+ ? {
79
+ comments: commentsWithCapabilities.map(
80
+ redactPublicReviewCommentIdentity,
81
+ ),
82
+ reviewStatus: redactPublicReviewStatusIdentity(reviewStatus),
83
+ summary,
84
+ }
85
+ : { comments: commentsWithCapabilities, reviewStatus, summary };
52
86
  },
53
87
  });
@@ -1,12 +1,13 @@
1
1
  import { z } from "zod";
2
2
 
3
3
  import { defineAction } from "../../action.js";
4
+ import { reviewAuthorNameFromContext } from "../identity.js";
4
5
  import { extractReviewMentions, normalizeReviewMentions } from "../mentions.js";
5
6
  import {
6
7
  assertReviewableResourceAccess,
7
8
  normalizeReviewVisibility,
8
9
  } from "../registry.js";
9
- import { getReviewCommentById, insertReviewComment } from "../store.js";
10
+ import { getReviewCommentById, insertReviewReply } from "../store.js";
10
11
  import type { ReviewActorKind, ReviewResourceContext } from "../types.js";
11
12
 
12
13
  const mentionSchema = z.object({
@@ -51,32 +52,42 @@ export default defineAction({
51
52
  ) {
52
53
  throw new Error("Review comment not found");
53
54
  }
55
+ if (parent.status !== "open") {
56
+ throw new Error("Review thread is not open");
57
+ }
54
58
  const mentions = normalizeReviewMentions([
55
59
  ...normalizeReviewMentions(args.mentions),
56
60
  ...extractReviewMentions(args.body),
57
61
  ]);
58
62
 
59
- return insertReviewComment({
60
- resourceType: args.resourceType,
61
- resourceId: args.resourceId,
62
- threadId: parent.threadId,
63
- parentCommentId: parent.id,
64
- targetId: parent.targetId,
65
- kind: parent.kind,
66
- anchor: parent.anchor,
67
- body: args.body,
68
- authorEmail: actionCtx?.userEmail ?? null,
69
- authorName: args.authorName ?? actionCtx?.userEmail ?? null,
70
- createdBy: actorKindFromContext(actionCtx),
71
- resolutionTarget:
72
- args.resolutionTarget ??
73
- (mentions.length > 0 ? "human" : parent.resolutionTarget),
74
- mentions,
75
- ownerEmail: access.ownerEmail ?? actionCtx?.userEmail ?? null,
76
- orgId: access.orgId ?? actionCtx?.orgId ?? null,
77
- visibility: normalizeReviewVisibility(access.visibility),
78
- metadata: args.metadata,
79
- });
63
+ const routeTarget =
64
+ args.resolutionTarget ?? (mentions.length > 0 ? "human" : null);
65
+ return insertReviewReply(
66
+ {
67
+ resourceType: args.resourceType,
68
+ resourceId: args.resourceId,
69
+ threadId: parent.threadId,
70
+ parentCommentId: parent.id,
71
+ targetId: parent.targetId,
72
+ kind: parent.kind,
73
+ anchor: parent.anchor,
74
+ body: args.body,
75
+ authorEmail: actionCtx?.userEmail ?? null,
76
+ authorName: args.authorName ?? reviewAuthorNameFromContext(actionCtx),
77
+ createdBy: actorKindFromContext(actionCtx),
78
+ resolutionTarget: null,
79
+ mentions,
80
+ ownerEmail: access.ownerEmail ?? actionCtx?.userEmail ?? null,
81
+ orgId: access.orgId ?? actionCtx?.orgId ?? null,
82
+ visibility: normalizeReviewVisibility(access.visibility),
83
+ metadata: args.metadata,
84
+ },
85
+ routeTarget,
86
+ {
87
+ resourceType: args.resourceType,
88
+ resourceId: args.resourceId,
89
+ },
90
+ );
80
91
  },
81
92
  audit: {
82
93
  target: (args, result) => {
@@ -2,7 +2,11 @@ import { z } from "zod";
2
2
 
3
3
  import { defineAction } from "../../action.js";
4
4
  import { assertReviewableResourceAccess } from "../registry.js";
5
- import { getReviewCommentById, resolveReviewThread } from "../store.js";
5
+ import {
6
+ getReviewCommentById,
7
+ getReviewThreadRoot,
8
+ resolveReviewThread,
9
+ } from "../store.js";
6
10
  import type { ReviewResourceContext } from "../types.js";
7
11
 
8
12
  const schema = z.object({
@@ -10,6 +14,7 @@ const schema = z.object({
10
14
  resourceId: z.string().min(1),
11
15
  threadId: z.string().optional(),
12
16
  commentId: z.string().optional(),
17
+ resolutionNote: z.string().trim().min(1).max(2_000).optional(),
13
18
  });
14
19
 
15
20
  export default defineAction({
@@ -52,11 +57,33 @@ export default defineAction({
52
57
  resourceType: args.resourceType,
53
58
  resourceId: args.resourceId,
54
59
  },
60
+ args.resolutionNote,
55
61
  );
56
62
  if (updatedCount < 1) {
57
63
  throw new Error("Review thread not found");
58
64
  }
59
- return { threadId, resolved: true as const, updatedCount };
65
+ const comment = await getReviewThreadRoot(
66
+ threadId,
67
+ {
68
+ resourceType: args.resourceType,
69
+ resourceId: args.resourceId,
70
+ },
71
+ {
72
+ userEmail: actionCtx?.userEmail ?? null,
73
+ orgId: actionCtx?.orgId ?? null,
74
+ },
75
+ { bypassScope: true },
76
+ );
77
+ if (!comment) {
78
+ throw new Error("Resolved review thread could not be verified");
79
+ }
80
+ return {
81
+ threadId,
82
+ resolved: true as const,
83
+ updatedCount,
84
+ resolutionNote: comment.resolutionNote ?? null,
85
+ comment,
86
+ };
60
87
  },
61
88
  audit: {
62
89
  target: (args) => ({
@@ -0,0 +1,62 @@
1
+ import { z } from "zod";
2
+
3
+ import { defineAction } from "../../action.js";
4
+ import { assertReviewableResourceAccess } from "../registry.js";
5
+ import { sendReviewThreadToAgent } from "../store.js";
6
+ import type { ReviewResourceContext } from "../types.js";
7
+
8
+ const schema = z.object({
9
+ resourceType: z.string().min(1),
10
+ resourceId: z.string().min(1),
11
+ threadId: z.string().min(1),
12
+ });
13
+
14
+ export default defineAction({
15
+ description:
16
+ "Send one open review thread to the agent queue without routing other threads.",
17
+ schema,
18
+ run: async (args, ctx) => {
19
+ const actionCtx = ctx as ReviewResourceContext | undefined;
20
+ const access = await assertReviewableResourceAccess(
21
+ args.resourceType,
22
+ args.resourceId,
23
+ actionCtx,
24
+ "editor",
25
+ );
26
+ const updatedCount = await sendReviewThreadToAgent(args.threadId, {
27
+ resourceType: args.resourceType,
28
+ resourceId: args.resourceId,
29
+ });
30
+ if (updatedCount < 1) {
31
+ throw new Error("Open review thread not found");
32
+ }
33
+ return {
34
+ resourceType: args.resourceType,
35
+ resourceId: args.resourceId,
36
+ threadId: args.threadId,
37
+ resolutionTarget: "agent" as const,
38
+ consumedAt: null,
39
+ updatedCount,
40
+ ownerEmail: access.ownerEmail ?? actionCtx?.userEmail ?? null,
41
+ orgId: access.orgId ?? actionCtx?.orgId ?? null,
42
+ visibility: access.visibility ?? "private",
43
+ };
44
+ },
45
+ audit: {
46
+ target: (args, result) => {
47
+ const routed = result as {
48
+ ownerEmail?: string | null;
49
+ orgId?: string | null;
50
+ visibility?: "private" | "org" | "public";
51
+ };
52
+ return {
53
+ type: args.resourceType,
54
+ id: args.resourceId,
55
+ ownerEmail: routed.ownerEmail,
56
+ orgId: routed.orgId,
57
+ visibility: routed.visibility,
58
+ };
59
+ },
60
+ summary: (args) => `Sent review thread ${args.threadId} to the agent`,
61
+ },
62
+ });
@@ -0,0 +1,101 @@
1
+ import type {
2
+ ReviewComment,
3
+ ReviewResourceAccess,
4
+ ReviewResourceContext,
5
+ ReviewStatusEntry,
6
+ } from "./types.js";
7
+
8
+ export function reviewAuthorNameFromContext(
9
+ ctx: ReviewResourceContext | undefined,
10
+ ): string | null {
11
+ const value = ctx?.userName;
12
+ if (typeof value !== "string") return null;
13
+ const name = value.trim();
14
+ if (!name || /^[^\s@]+@[^\s@]+\.[^\s@]+$/.test(name)) return null;
15
+ return name;
16
+ }
17
+
18
+ export function shouldRedactReviewIdentity(
19
+ ctx: ReviewResourceContext | undefined,
20
+ access: Pick<ReviewResourceAccess, "role" | "visibility">,
21
+ ): boolean {
22
+ return (
23
+ !ctx?.userEmail ||
24
+ (access.visibility === "public" && access.role === "viewer")
25
+ );
26
+ }
27
+
28
+ export function redactPublicReviewCommentIdentity(
29
+ comment: ReviewComment,
30
+ ): ReviewComment {
31
+ return {
32
+ ...comment,
33
+ authorEmail: null,
34
+ authorName: safeReviewDisplayName(comment.authorName),
35
+ mentions: comment.mentions.map((mention) => ({
36
+ label: safeReviewDisplayName(mention.label) ?? "Mentioned user",
37
+ })),
38
+ ownerEmail: null,
39
+ orgId: null,
40
+ resolvedBy: null,
41
+ deletedBy: null,
42
+ metadata: redactPublicReviewMetadata(comment.metadata),
43
+ };
44
+ }
45
+
46
+ export function redactPublicReviewStatusIdentity(
47
+ status: ReviewStatusEntry | null,
48
+ ): ReviewStatusEntry | null {
49
+ return status
50
+ ? {
51
+ ...status,
52
+ updatedBy: null,
53
+ ownerEmail: null,
54
+ orgId: null,
55
+ metadata: redactPublicReviewMetadata(status.metadata),
56
+ }
57
+ : null;
58
+ }
59
+
60
+ function safeReviewDisplayName(
61
+ value: string | null | undefined,
62
+ ): string | null {
63
+ const name = value?.trim();
64
+ if (!name || /^[^\s@]+@[^\s@]+\.[^\s@]+$/.test(name)) {
65
+ return null;
66
+ }
67
+ return name;
68
+ }
69
+
70
+ function redactPublicReviewMetadata(
71
+ metadata: Record<string, unknown> | null,
72
+ ): Record<string, unknown> | null {
73
+ if (!metadata) {
74
+ return null;
75
+ }
76
+ return Object.fromEntries(
77
+ Object.entries(metadata).flatMap(([key, value]) =>
78
+ /^(authorEmail|ownerEmail|orgId|updatedBy|resolvedBy|deletedBy|email|userEmail|userId)$/i.test(
79
+ key,
80
+ )
81
+ ? []
82
+ : [[key, redactPublicReviewMetadataValue(value)]],
83
+ ),
84
+ );
85
+ }
86
+
87
+ function redactPublicReviewMetadataValue(value: unknown): unknown {
88
+ if (Array.isArray(value)) {
89
+ return value.map(redactPublicReviewMetadataValue);
90
+ }
91
+ if (typeof value === "object" && value !== null) {
92
+ return redactPublicReviewMetadata(value as Record<string, unknown>);
93
+ }
94
+ if (
95
+ typeof value === "string" &&
96
+ /^[^\s@]+@[^\s@]+\.[^\s@]+$/.test(value.trim())
97
+ ) {
98
+ return null;
99
+ }
100
+ return value;
101
+ }
@@ -13,6 +13,12 @@ export type {
13
13
  ReviewStatusEntry,
14
14
  ReviewableResourceRegistration,
15
15
  } from "./types.js";
16
+ export {
17
+ redactPublicReviewCommentIdentity,
18
+ redactPublicReviewStatusIdentity,
19
+ reviewAuthorNameFromContext,
20
+ shouldRedactReviewIdentity,
21
+ } from "./identity.js";
16
22
  export { extractReviewMentions, normalizeReviewMentions } from "./mentions.js";
17
23
  export {
18
24
  __resetReviewableResourcesForTests,
@@ -27,5 +33,13 @@ export {
27
33
  ensureReviewTables,
28
34
  getReviewCommentById,
29
35
  getReviewStatus,
36
+ getReviewThreadSummary,
37
+ getReviewThreadRoot,
30
38
  queryReviewComments,
39
+ routeReviewThread,
40
+ sendReviewThreadToAgent,
41
+ } from "./store.js";
42
+ export type {
43
+ GetReviewThreadSummaryInput,
44
+ ReviewThreadSummary,
31
45
  } from "./store.js";