@agent-native/core 0.100.2 → 0.101.3

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 (388) hide show
  1. package/corpus/README.md +2 -2
  2. package/corpus/core/CHANGELOG.md +83 -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/analytics.ts +8 -1
  37. package/corpus/core/src/client/chat/markdown-renderer.tsx +54 -8
  38. package/corpus/core/src/client/chat/message-components.tsx +8 -2
  39. package/corpus/core/src/client/clipboard.ts +28 -1
  40. package/corpus/core/src/client/guided-questions.tsx +4 -0
  41. package/corpus/core/src/client/i18n.tsx +2 -1
  42. package/corpus/core/src/client/index.ts +4 -0
  43. package/corpus/core/src/client/review/ReviewCommentComposer.tsx +108 -0
  44. package/corpus/core/src/client/review/ReviewThreadPanel.tsx +482 -150
  45. package/corpus/core/src/client/review/index.ts +8 -0
  46. package/corpus/core/src/client/review/use-review.ts +35 -1
  47. package/corpus/core/src/client/use-agent-chat-context.ts +3 -2
  48. package/corpus/core/src/credentials/index.ts +41 -8
  49. package/corpus/core/src/extensions/fetch-tool.ts +33 -3
  50. package/corpus/core/src/notifications/channels.ts +20 -6
  51. package/corpus/core/src/review/actions/create-review-comment.ts +2 -1
  52. package/corpus/core/src/review/actions/get-review-feedback.ts +6 -11
  53. package/corpus/core/src/review/actions/list-review-comments.ts +38 -4
  54. package/corpus/core/src/review/actions/reply-review-comment.ts +33 -22
  55. package/corpus/core/src/review/actions/resolve-review-thread.ts +29 -2
  56. package/corpus/core/src/review/actions/send-review-thread-to-agent.ts +62 -0
  57. package/corpus/core/src/review/identity.ts +101 -0
  58. package/corpus/core/src/review/index.ts +14 -0
  59. package/corpus/core/src/review/store.ts +315 -8
  60. package/corpus/core/src/review/types.ts +4 -0
  61. package/corpus/core/src/secrets/crypto.ts +26 -10
  62. package/corpus/core/src/secrets/storage.ts +16 -3
  63. package/corpus/core/src/server/action-discovery.ts +4 -0
  64. package/corpus/core/src/server/action-routes.ts +125 -4
  65. package/corpus/core/src/server/agent-chat/plugin-options.ts +16 -0
  66. package/corpus/core/src/server/agent-chat-plugin.ts +61 -7
  67. package/corpus/core/src/server/derived-secret.ts +5 -1
  68. package/corpus/core/src/server/index.ts +8 -0
  69. package/corpus/core/src/vite/action-types-plugin.ts +4 -0
  70. package/corpus/templates/analytics/changelog/2026-07-14-daily-dashboard-email-captures-authenticate-with-a-sessi.md +6 -0
  71. package/corpus/templates/analytics/changelog/2026-07-14-long-running-cross-app-analyses-now-continue-reliably-in-the.md +6 -0
  72. package/corpus/templates/analytics/server/lib/dashboard-report.ts +156 -3
  73. package/corpus/templates/analytics/server/plugins/agent-chat.ts +8 -4
  74. package/corpus/templates/assets/app/components/generation/GenerationResults.tsx +402 -142
  75. package/corpus/templates/assets/app/i18n/zh-TW.ts +1 -0
  76. package/corpus/templates/assets/app/i18n-data.ts +1 -0
  77. package/corpus/templates/assets/app/routes/library.tsx +187 -48
  78. package/corpus/templates/assets/changelog/2026-07-13-merged-the-candidates-panel-into-the-library-as-a-drafts-tab.md +6 -0
  79. package/corpus/templates/chat/app/lib/agent-page.tsx +40 -0
  80. package/corpus/templates/chat/app/routes/agent.tsx +5 -3
  81. package/corpus/templates/chat/changelog/2026-07-14-fixed-chat-template-startup-with-older-core-versions.md +6 -0
  82. package/corpus/templates/clips/.agents/skills/ai-video-tools/SKILL.md +5 -0
  83. package/corpus/templates/clips/AGENTS.md +4 -0
  84. package/corpus/templates/clips/actions/get-feature-flags.ts +30 -0
  85. package/corpus/templates/clips/actions/lib/transcript-preview.ts +48 -0
  86. package/corpus/templates/clips/actions/request-transcript.ts +41 -1
  87. package/corpus/templates/clips/actions/view-screen.ts +5 -9
  88. package/corpus/templates/clips/app/components/library/library-layout.tsx +1 -1
  89. package/corpus/templates/clips/app/components/player/share-dialog.tsx +44 -81
  90. package/corpus/templates/clips/app/components/player/video-player.tsx +39 -1
  91. package/corpus/templates/clips/app/hooks/use-desktop-promo.ts +6 -12
  92. package/corpus/templates/clips/app/hooks/use-mse-video-source.ts +146 -0
  93. package/corpus/templates/clips/app/i18n/ar-SA.ts +0 -8
  94. package/corpus/templates/clips/app/i18n/de-DE.ts +0 -9
  95. package/corpus/templates/clips/app/i18n/en-US.ts +0 -8
  96. package/corpus/templates/clips/app/i18n/es-ES.ts +0 -9
  97. package/corpus/templates/clips/app/i18n/fr-FR.ts +0 -9
  98. package/corpus/templates/clips/app/i18n/hi-IN.ts +0 -8
  99. package/corpus/templates/clips/app/i18n/ja-JP.ts +0 -9
  100. package/corpus/templates/clips/app/i18n/ko-KR.ts +0 -9
  101. package/corpus/templates/clips/app/i18n/pt-BR.ts +0 -9
  102. package/corpus/templates/clips/app/i18n/zh-CN.ts +0 -7
  103. package/corpus/templates/clips/app/i18n/zh-TW.ts +0 -7
  104. package/corpus/templates/clips/app/lib/capture-install-options.ts +21 -0
  105. package/corpus/templates/clips/app/lib/fmp4.ts +271 -0
  106. package/corpus/templates/clips/app/lib/mse-video-loader.ts +585 -0
  107. package/corpus/templates/clips/app/routes/_app.dictate.tsx +0 -4
  108. package/corpus/templates/clips/app/routes/_app.meetings.$meetingId.tsx +5 -13
  109. package/corpus/templates/clips/app/routes/_app.meetings._index.tsx +2 -37
  110. package/corpus/templates/clips/app/routes/download.tsx +3 -2
  111. package/corpus/templates/clips/changelog/2026-07-10-shared-clips-now-start-playing-instantly-instead-of-showing-.md +6 -0
  112. package/corpus/templates/clips/changelog/2026-07-14-clips-now-distinguishes-transcript-previews-from-incomplete-.md +6 -0
  113. package/corpus/templates/clips/changelog/2026-07-14-desktop-app-prompts-stay-hidden-after-you-download-the-insta.md +6 -0
  114. package/corpus/templates/clips/changelog/2026-07-14-share-dialogs-show-separate-links-for-people-and-agents.md +6 -0
  115. package/corpus/templates/clips/desktop/src/lib/recorder.ts +5 -0
  116. package/corpus/templates/clips/desktop/src/overlays/recording-pill.tsx +10 -0
  117. package/corpus/templates/clips/desktop/src-tauri/src/lib.rs +4 -0
  118. package/corpus/templates/clips/desktop/src-tauri/src/native_screen/custom_capture.rs +2518 -0
  119. package/corpus/templates/clips/desktop/src-tauri/src/native_screen/live_upload.rs +353 -0
  120. package/corpus/templates/clips/desktop/src-tauri/src/native_screen.rs +558 -67
  121. package/corpus/templates/clips/desktop/src-tauri/src/recording_indicator.rs +11 -1
  122. package/corpus/templates/clips/desktop/src-tauri/src/remote_flags.rs +188 -0
  123. package/corpus/templates/clips/desktop/src-tauri/src/whisper_speech.rs +1 -1
  124. package/corpus/templates/clips/server/lib/post-finalize-dispatch.ts +1 -0
  125. package/corpus/templates/clips/server/plugins/agent-chat.ts +5 -0
  126. package/corpus/templates/clips/server/routes/api/_agent-native-background/post-finalize-worker.post.ts +5 -1
  127. package/corpus/templates/clips/shared/feature-flags.ts +41 -0
  128. package/corpus/templates/design/.agents/skills/design-generation/SKILL.md +3 -0
  129. package/corpus/templates/design/.agents/skills/design-review-feedback/SKILL.md +42 -0
  130. package/corpus/templates/design/AGENTS.md +6 -0
  131. package/corpus/templates/design/README.md +1 -0
  132. package/corpus/templates/design/actions/navigate.ts +4 -4
  133. package/corpus/templates/design/actions/view-screen.ts +116 -2
  134. package/corpus/templates/design/agent-native.app-skill.json +5 -0
  135. package/corpus/templates/design/app/components/design/DesignCanvas.tsx +52 -59
  136. package/corpus/templates/design/app/components/design/DesignExtensionsPanel.tsx +13 -9
  137. package/corpus/templates/design/app/components/design/EditPanel.tsx +79 -11
  138. package/corpus/templates/design/app/components/design/LayersPanel.tsx +78 -65
  139. package/corpus/templates/design/app/components/design/ReviewCommentsPanel.tsx +161 -0
  140. package/corpus/templates/design/app/components/design/ReviewStatusControl.tsx +96 -0
  141. package/corpus/templates/design/app/components/design/bridge/hit-test.bridge.ts +166 -0
  142. package/corpus/templates/design/app/components/layout/Layout.tsx +1 -0
  143. package/corpus/templates/design/app/components/visual-editor/ReviewCanvasPins.tsx +1077 -0
  144. package/corpus/templates/design/app/components/visual-editor/index.ts +1 -0
  145. package/corpus/templates/design/app/components/visual-editor/review-canvas-state.ts +42 -0
  146. package/corpus/templates/design/app/hooks/use-design-systems.ts +2 -2
  147. package/corpus/templates/design/app/hooks/use-navigation-state.ts +9 -6
  148. package/corpus/templates/design/app/hooks/use-question-flow.ts +7 -1
  149. package/corpus/templates/design/app/i18n/ar-SA.ts +56 -1
  150. package/corpus/templates/design/app/i18n/de-DE.ts +57 -1
  151. package/corpus/templates/design/app/i18n/en-US.ts +56 -1
  152. package/corpus/templates/design/app/i18n/es-ES.ts +56 -1
  153. package/corpus/templates/design/app/i18n/fr-FR.ts +57 -1
  154. package/corpus/templates/design/app/i18n/hi-IN.ts +56 -1
  155. package/corpus/templates/design/app/i18n/ja-JP.ts +56 -1
  156. package/corpus/templates/design/app/i18n/ko-KR.ts +56 -1
  157. package/corpus/templates/design/app/i18n/pt-BR.ts +57 -1
  158. package/corpus/templates/design/app/i18n/zh-CN.ts +56 -1
  159. package/corpus/templates/design/app/i18n/zh-TW.ts +51 -0
  160. package/corpus/templates/design/app/pages/Present.tsx +172 -14
  161. package/corpus/templates/design/app/pages/design-editor/overview-camera.ts +23 -0
  162. package/corpus/templates/design/app/pages/design-editor/tool-state.ts +10 -0
  163. package/corpus/templates/design/app/pages/present-review-state.ts +18 -0
  164. package/corpus/templates/design/app/public-routes.ts +8 -0
  165. package/corpus/templates/design/app/root.tsx +7 -6
  166. package/corpus/templates/design/changelog/2026-07-13-dragged-design-assets-now-appear-at-the-visible-drop-locatio.md +6 -0
  167. package/corpus/templates/design/changelog/2026-07-13-reviewers-can-pin-comments-on-shared-designs-and-apply-verif.md +6 -0
  168. package/corpus/templates/design/server/plugins/agent-chat.ts +10 -0
  169. package/corpus/templates/design/server/plugins/auth.ts +7 -5
  170. package/corpus/templates/design/server/plugins/review.ts +9 -0
  171. package/corpus/templates/design/shared/review-anchor.ts +83 -0
  172. package/corpus/templates/design/shared/review-summary.ts +25 -0
  173. package/corpus/templates/dispatch/changelog/2026-07-14-dispatch-now-distinguishes-connected-agents-from-locally-mou.md +6 -0
  174. package/corpus/templates/forms/.agents/skills/form-publishing/SKILL.md +2 -0
  175. package/corpus/templates/forms/AGENTS.md +4 -0
  176. package/corpus/templates/forms/actions/create-form.ts +2 -1
  177. package/corpus/templates/forms/actions/update-form.ts +5 -2
  178. package/corpus/templates/forms/app/i18n/ar-SA.ts +3 -0
  179. package/corpus/templates/forms/app/i18n/de-DE.ts +3 -0
  180. package/corpus/templates/forms/app/i18n/en-US.ts +3 -0
  181. package/corpus/templates/forms/app/i18n/es-ES.ts +3 -0
  182. package/corpus/templates/forms/app/i18n/fr-FR.ts +3 -0
  183. package/corpus/templates/forms/app/i18n/hi-IN.ts +3 -0
  184. package/corpus/templates/forms/app/i18n/ja-JP.ts +3 -0
  185. package/corpus/templates/forms/app/i18n/ko-KR.ts +3 -0
  186. package/corpus/templates/forms/app/i18n/pt-BR.ts +3 -0
  187. package/corpus/templates/forms/app/i18n/zh-CN.ts +3 -0
  188. package/corpus/templates/forms/app/i18n/zh-TW.ts +3 -0
  189. package/corpus/templates/forms/app/pages/FormBuilderPage.tsx +19 -0
  190. package/corpus/templates/forms/changelog/2026-07-14-fixed-the-ask-forms-loading-input-appearing-above-the-welcom.md +6 -0
  191. package/corpus/templates/forms/changelog/2026-07-14-form-social-previews-now-show-the-form-title-description-and.md +6 -0
  192. package/corpus/templates/forms/changelog/2026-07-14-forms-can-email-the-form-owner-when-new-responses-arrive.md +6 -0
  193. package/corpus/templates/forms/server/handlers/submissions.ts +17 -0
  194. package/corpus/templates/forms/server/lib/form-og-image.ts +64 -6
  195. package/corpus/templates/forms/server/lib/public-form-ssr.ts +6 -2
  196. package/corpus/templates/forms/server/lib/response-email.ts +65 -0
  197. package/corpus/templates/forms/server/plugins/agent-chat.ts +1 -0
  198. package/corpus/templates/forms/server/routes/api/forms/og/[...slug]/og.png.get.ts +184 -0
  199. package/corpus/templates/forms/shared/types.ts +2 -0
  200. package/corpus/templates/plan/.agents/skills/visual-plan/SKILL.md +6 -4
  201. package/corpus/templates/plan/.agents/skills/visual-recap/SKILL.md +7 -1
  202. package/dist/a2a/index.d.ts +2 -1
  203. package/dist/a2a/index.d.ts.map +1 -1
  204. package/dist/a2a/index.js +1 -1
  205. package/dist/a2a/index.js.map +1 -1
  206. package/dist/a2a/server.d.ts +25 -0
  207. package/dist/a2a/server.d.ts.map +1 -1
  208. package/dist/a2a/server.js +30 -6
  209. package/dist/a2a/server.js.map +1 -1
  210. package/dist/agent/production-agent.d.ts +2 -0
  211. package/dist/agent/production-agent.d.ts.map +1 -1
  212. package/dist/agent/production-agent.js +37 -12
  213. package/dist/agent/production-agent.js.map +1 -1
  214. package/dist/cli/create.d.ts +5 -3
  215. package/dist/cli/create.d.ts.map +1 -1
  216. package/dist/cli/create.js +44 -19
  217. package/dist/cli/create.js.map +1 -1
  218. package/dist/cli/pr-visual-recap-workflow.d.ts +2 -2
  219. package/dist/cli/pr-visual-recap-workflow.d.ts.map +1 -1
  220. package/dist/cli/pr-visual-recap-workflow.js +2 -2
  221. package/dist/cli/pr-visual-recap-workflow.js.map +1 -1
  222. package/dist/cli/recap.d.ts +3 -562
  223. package/dist/cli/recap.d.ts.map +1 -1
  224. package/dist/cli/recap.js +3 -3875
  225. package/dist/cli/recap.js.map +1 -1
  226. package/dist/cli/skills-content/visual-plan-skill.d.ts +1 -1
  227. package/dist/cli/skills-content/visual-plan-skill.d.ts.map +1 -1
  228. package/dist/cli/skills-content/visual-plan-skill.js +6 -4
  229. package/dist/cli/skills-content/visual-plan-skill.js.map +1 -1
  230. package/dist/cli/skills-content/visual-recap-skill.d.ts +1 -1
  231. package/dist/cli/skills-content/visual-recap-skill.d.ts.map +1 -1
  232. package/dist/cli/skills-content/visual-recap-skill.js +7 -1
  233. package/dist/cli/skills-content/visual-recap-skill.js.map +1 -1
  234. package/dist/client/AgentPanel.d.ts.map +1 -1
  235. package/dist/client/AgentPanel.js +3 -3
  236. package/dist/client/AgentPanel.js.map +1 -1
  237. package/dist/client/analytics.d.ts +5 -0
  238. package/dist/client/analytics.d.ts.map +1 -1
  239. package/dist/client/analytics.js +3 -1
  240. package/dist/client/analytics.js.map +1 -1
  241. package/dist/client/chat/markdown-renderer.d.ts +1 -0
  242. package/dist/client/chat/markdown-renderer.d.ts.map +1 -1
  243. package/dist/client/chat/markdown-renderer.js +36 -1
  244. package/dist/client/chat/markdown-renderer.js.map +1 -1
  245. package/dist/client/chat/message-components.d.ts.map +1 -1
  246. package/dist/client/chat/message-components.js +5 -2
  247. package/dist/client/chat/message-components.js.map +1 -1
  248. package/dist/client/clipboard.d.ts +3 -1
  249. package/dist/client/clipboard.d.ts.map +1 -1
  250. package/dist/client/clipboard.js +24 -1
  251. package/dist/client/clipboard.js.map +1 -1
  252. package/dist/client/guided-questions.d.ts +3 -1
  253. package/dist/client/guided-questions.d.ts.map +1 -1
  254. package/dist/client/guided-questions.js +2 -1
  255. package/dist/client/guided-questions.js.map +1 -1
  256. package/dist/client/i18n.d.ts.map +1 -1
  257. package/dist/client/i18n.js +3 -1
  258. package/dist/client/i18n.js.map +1 -1
  259. package/dist/client/index.d.ts +1 -1
  260. package/dist/client/index.d.ts.map +1 -1
  261. package/dist/client/index.js +1 -1
  262. package/dist/client/index.js.map +1 -1
  263. package/dist/client/review/ReviewCommentComposer.d.ts +18 -0
  264. package/dist/client/review/ReviewCommentComposer.d.ts.map +1 -0
  265. package/dist/client/review/ReviewCommentComposer.js +30 -0
  266. package/dist/client/review/ReviewCommentComposer.js.map +1 -0
  267. package/dist/client/review/ReviewThreadPanel.d.ts +28 -1
  268. package/dist/client/review/ReviewThreadPanel.d.ts.map +1 -1
  269. package/dist/client/review/ReviewThreadPanel.js +151 -39
  270. package/dist/client/review/ReviewThreadPanel.js.map +1 -1
  271. package/dist/client/review/index.d.ts +3 -2
  272. package/dist/client/review/index.d.ts.map +1 -1
  273. package/dist/client/review/index.js +2 -1
  274. package/dist/client/review/index.js.map +1 -1
  275. package/dist/client/review/use-review.d.ts +23 -0
  276. package/dist/client/review/use-review.d.ts.map +1 -1
  277. package/dist/client/review/use-review.js +3 -0
  278. package/dist/client/review/use-review.js.map +1 -1
  279. package/dist/client/use-agent-chat-context.d.ts +1 -1
  280. package/dist/client/use-agent-chat-context.d.ts.map +1 -1
  281. package/dist/client/use-agent-chat-context.js +4 -2
  282. package/dist/client/use-agent-chat-context.js.map +1 -1
  283. package/dist/collab/awareness.d.ts +2 -2
  284. package/dist/collab/awareness.d.ts.map +1 -1
  285. package/dist/collab/struct-routes.d.ts +1 -1
  286. package/dist/credentials/index.d.ts +12 -7
  287. package/dist/credentials/index.d.ts.map +1 -1
  288. package/dist/credentials/index.js +33 -8
  289. package/dist/credentials/index.js.map +1 -1
  290. package/dist/extensions/fetch-tool.d.ts +13 -1
  291. package/dist/extensions/fetch-tool.d.ts.map +1 -1
  292. package/dist/extensions/fetch-tool.js +9 -2
  293. package/dist/extensions/fetch-tool.js.map +1 -1
  294. package/dist/notifications/channels.js +20 -4
  295. package/dist/notifications/channels.js.map +1 -1
  296. package/dist/observability/routes.d.ts +5 -5
  297. package/dist/progress/routes.d.ts +1 -1
  298. package/dist/provider-api/corpus-jobs.d.ts +2 -2
  299. package/dist/resources/handlers.d.ts +3 -3
  300. package/dist/review/actions/create-review-comment.js +2 -1
  301. package/dist/review/actions/create-review-comment.js.map +1 -1
  302. package/dist/review/actions/get-review-feedback.js +6 -11
  303. package/dist/review/actions/get-review-feedback.js.map +1 -1
  304. package/dist/review/actions/list-review-comments.d.ts +1 -0
  305. package/dist/review/actions/list-review-comments.js +25 -4
  306. package/dist/review/actions/list-review-comments.js.map +1 -1
  307. package/dist/review/actions/reply-review-comment.js +12 -5
  308. package/dist/review/actions/reply-review-comment.js.map +1 -1
  309. package/dist/review/actions/resolve-review-thread.d.ts +3 -0
  310. package/dist/review/actions/resolve-review-thread.js +20 -3
  311. package/dist/review/actions/resolve-review-thread.js.map +1 -1
  312. package/dist/review/actions/send-review-thread-to-agent.d.ts +17 -0
  313. package/dist/review/actions/send-review-thread-to-agent.d.ts.map +1 -0
  314. package/dist/review/actions/send-review-thread-to-agent.js +49 -0
  315. package/dist/review/actions/send-review-thread-to-agent.js.map +1 -0
  316. package/dist/review/identity.d.ts +6 -0
  317. package/dist/review/identity.d.ts.map +1 -0
  318. package/dist/review/identity.js +68 -0
  319. package/dist/review/identity.js.map +1 -0
  320. package/dist/review/index.d.ts +3 -1
  321. package/dist/review/index.d.ts.map +1 -1
  322. package/dist/review/index.js +2 -1
  323. package/dist/review/index.js.map +1 -1
  324. package/dist/review/store.d.ts +36 -0
  325. package/dist/review/store.d.ts.map +1 -1
  326. package/dist/review/store.js +223 -8
  327. package/dist/review/store.js.map +1 -1
  328. package/dist/review/types.d.ts +4 -0
  329. package/dist/review/types.d.ts.map +1 -1
  330. package/dist/review/types.js.map +1 -1
  331. package/dist/secrets/crypto.d.ts +15 -7
  332. package/dist/secrets/crypto.d.ts.map +1 -1
  333. package/dist/secrets/crypto.js +23 -10
  334. package/dist/secrets/crypto.js.map +1 -1
  335. package/dist/secrets/routes.d.ts +9 -9
  336. package/dist/secrets/storage.d.ts.map +1 -1
  337. package/dist/secrets/storage.js +16 -3
  338. package/dist/secrets/storage.js.map +1 -1
  339. package/dist/server/action-discovery.d.ts.map +1 -1
  340. package/dist/server/action-discovery.js +4 -0
  341. package/dist/server/action-discovery.js.map +1 -1
  342. package/dist/server/action-routes.d.ts +45 -0
  343. package/dist/server/action-routes.d.ts.map +1 -1
  344. package/dist/server/action-routes.js +71 -5
  345. package/dist/server/action-routes.js.map +1 -1
  346. package/dist/server/agent-chat/plugin-options.d.ts +16 -0
  347. package/dist/server/agent-chat/plugin-options.d.ts.map +1 -1
  348. package/dist/server/agent-chat/plugin-options.js.map +1 -1
  349. package/dist/server/agent-chat-plugin.d.ts +20 -0
  350. package/dist/server/agent-chat-plugin.d.ts.map +1 -1
  351. package/dist/server/agent-chat-plugin.js +39 -4
  352. package/dist/server/agent-chat-plugin.js.map +1 -1
  353. package/dist/server/derived-secret.d.ts +1 -1
  354. package/dist/server/derived-secret.d.ts.map +1 -1
  355. package/dist/server/derived-secret.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/clips/app/components/sharing/slack-share-hint.tsx +0 -68
  388. 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);
@@ -3,6 +3,7 @@ import {
3
3
  decryptSecretValue,
4
4
  isEncryptedSecretValue,
5
5
  } from "../secrets/crypto.js";
6
+ import { readAppSecret, type SecretRef } from "../secrets/storage.js";
6
7
  import { getSetting, putSetting, deleteSetting } from "../settings/store.js";
7
8
 
8
9
  const SETTING_PREFIX = "credential:";
@@ -41,6 +42,20 @@ async function readCredentialSetting(
41
42
  }
42
43
  }
43
44
 
45
+ async function readScopedAppSecret(
46
+ key: string,
47
+ scope: SecretRef["scope"],
48
+ scopeId: string,
49
+ ): Promise<string | undefined> {
50
+ try {
51
+ return (await readAppSecret({ key, scope, scopeId }))?.value;
52
+ } catch {
53
+ // Older databases may not have app_secrets yet. Keep the legacy
54
+ // credential store available while the table bootstraps.
55
+ return undefined;
56
+ }
57
+ }
58
+
44
59
  /**
45
60
  * Resolve a credential from one explicit legacy SQL credential scope.
46
61
  *
@@ -61,16 +76,21 @@ export async function resolveCredentialForScope(
61
76
  }
62
77
 
63
78
  /**
64
- * Resolve a credential, scoped to the caller's user (and falling back to
65
- * the active org's shared credential, if any).
79
+ * Resolve a credential across the encrypted app_secrets store and the legacy
80
+ * settings-backed credential store. User overrides win, followed by the
81
+ * active org/workspace shared value.
66
82
  *
67
83
  * SECURITY: NEVER reads from process.env. Env vars are global to the
68
- * deployment and would leak across users in a multi-tenant app. The only
69
- * sources are per-user / per-org rows in the SQL `settings` table.
84
+ * deployment and would leak across users in a multi-tenant app.
85
+ *
86
+ * Read order:
87
+ * 1. user-scoped app_secrets
88
+ * 2. user-scoped legacy settings credential
89
+ * 3. org-scoped app_secrets
90
+ * 4. legacy workspace-scoped app_secrets for the org
91
+ * 5. org-scoped legacy settings credential
70
92
  *
71
- * Storage keys (priority order):
72
- * 1. u:<email>:credential:<KEY> — per-user override
73
- * 2. o:<orgId>:credential:<KEY> — per-org shared credential (if orgId given)
93
+ * Without an active org, step 3 is replaced by the solo workspace scope.
74
94
  */
75
95
  export async function resolveCredential(
76
96
  key: string,
@@ -78,6 +98,9 @@ export async function resolveCredential(
78
98
  ): Promise<string | undefined> {
79
99
  if (!ctx?.userEmail) return undefined;
80
100
 
101
+ const userSecret = await readScopedAppSecret(key, "user", ctx.userEmail);
102
+ if (userSecret) return userSecret;
103
+
81
104
  const userSetting = await resolveCredentialForScope(key, {
82
105
  ...ctx,
83
106
  scope: "user",
@@ -85,10 +108,20 @@ export async function resolveCredential(
85
108
  if (userSetting) return userSetting;
86
109
 
87
110
  if (ctx.orgId) {
111
+ const orgSecret = await readScopedAppSecret(key, "org", ctx.orgId);
112
+ if (orgSecret) return orgSecret;
113
+
114
+ const workspaceSecret = await readScopedAppSecret(
115
+ key,
116
+ "workspace",
117
+ ctx.orgId,
118
+ );
119
+ if (workspaceSecret) return workspaceSecret;
120
+
88
121
  return resolveCredentialForScope(key, { ...ctx, scope: "org" });
89
122
  }
90
123
 
91
- return undefined;
124
+ return readScopedAppSecret(key, "workspace", `solo:${ctx.userEmail}`);
92
125
  }
93
126
 
94
127
  /**
@@ -11,6 +11,7 @@
11
11
  */
12
12
 
13
13
  import type { ActionEntry } from "../agent/production-agent.js";
14
+ import type { ResolvedKeyReference } from "../secrets/substitution.js";
14
15
  import {
15
16
  collectSecretValues,
16
17
  MAX_EXTENSION_PROXY_RESPONSE_SIZE,
@@ -77,9 +78,23 @@ export interface FetchToolOptions {
77
78
  resolved: string;
78
79
  usedKeys: string[];
79
80
  secretValues?: string[];
81
+ /**
82
+ * Optional: which scope (user/org/workspace) each used key actually
83
+ * resolved at. Populated by resolvers like
84
+ * `resolveKeyReferencesWithRequestScopes` so `validateUrl` can look up
85
+ * the allowlist at the scope the value came from rather than assuming
86
+ * user scope. Backwards compatible — callers that omit this (or a
87
+ * resolver that doesn't report it) are unaffected.
88
+ */
89
+ resolvedKeys?: ResolvedKeyReference[];
80
90
  }>;
81
91
  /** Validate URL against per-key allowlists. */
82
- validateUrl?: (url: string, usedKeys: string[]) => Promise<boolean>;
92
+ validateUrl?: (
93
+ url: string,
94
+ usedKeys: string[],
95
+ /** Accumulated `resolvedKeys` from every `resolveKeys` call this request made, when the resolver reported them. */
96
+ resolvedKeys?: ResolvedKeyReference[],
97
+ ) => Promise<boolean>;
83
98
  }
84
99
 
85
100
  /**
@@ -207,6 +222,7 @@ export function createFetchToolEntry(
207
222
  let resolvedBody = rawBody;
208
223
  const allUsedKeys: string[] = [];
209
224
  const allSecretValues: string[] = [];
225
+ const allResolvedKeys: ResolvedKeyReference[] = [];
210
226
 
211
227
  if (opts.resolveKeys) {
212
228
  try {
@@ -214,23 +230,29 @@ export function createFetchToolEntry(
214
230
  resolvedUrl = urlResult.resolved;
215
231
  allUsedKeys.push(...urlResult.usedKeys);
216
232
  allSecretValues.push(...(urlResult.secretValues ?? []));
233
+ allResolvedKeys.push(...(urlResult.resolvedKeys ?? []));
217
234
 
218
235
  const headerResult = await opts.resolveKeys(rawHeaders);
219
236
  resolvedHeaders = headerResult.resolved;
220
237
  allUsedKeys.push(...headerResult.usedKeys);
221
238
  allSecretValues.push(...(headerResult.secretValues ?? []));
239
+ allResolvedKeys.push(...(headerResult.resolvedKeys ?? []));
222
240
 
223
241
  if (rawBody) {
224
242
  const bodyResult = await opts.resolveKeys(rawBody);
225
243
  resolvedBody = bodyResult.resolved;
226
244
  allUsedKeys.push(...bodyResult.usedKeys);
227
245
  allSecretValues.push(...(bodyResult.secretValues ?? []));
246
+ allResolvedKeys.push(...(bodyResult.resolvedKeys ?? []));
228
247
  }
229
248
  } catch (err: any) {
230
249
  return `Error resolving key references: ${err?.message ?? err}`;
231
250
  }
232
251
  }
233
252
  const secretValues = collectSecretValues(allSecretValues);
253
+ const resolvedKeys = allResolvedKeys.length
254
+ ? allResolvedKeys
255
+ : undefined;
234
256
 
235
257
  // Block SSRF targets regardless of key usage
236
258
  if (await isBlockedExtensionUrlWithDns(resolvedUrl)) {
@@ -240,7 +262,11 @@ export function createFetchToolEntry(
240
262
  // Validate URL against per-key allowlists
241
263
  if (opts.validateUrl && allUsedKeys.length > 0) {
242
264
  try {
243
- const allowed = await opts.validateUrl(resolvedUrl, allUsedKeys);
265
+ const allowed = await opts.validateUrl(
266
+ resolvedUrl,
267
+ allUsedKeys,
268
+ resolvedKeys,
269
+ );
244
270
  if (!allowed) {
245
271
  return `URL "${rawUrl}" is not in the allowlist for the referenced keys. Check your key settings.`;
246
272
  }
@@ -298,7 +324,11 @@ export function createFetchToolEntry(
298
324
  return "Redirect to private/internal address blocked.";
299
325
  }
300
326
  if (redirectUrl && opts.validateUrl && allUsedKeys.length > 0) {
301
- const allowed = await opts.validateUrl(redirectUrl, allUsedKeys);
327
+ const allowed = await opts.validateUrl(
328
+ redirectUrl,
329
+ allUsedKeys,
330
+ resolvedKeys,
331
+ );
302
332
  if (!allowed) {
303
333
  return "Redirect URL is not in the allowlist for the referenced keys.";
304
334
  }
@@ -29,7 +29,7 @@
29
29
 
30
30
  import { ssrfSafeFetch } from "../extensions/url-safety.js";
31
31
  import {
32
- resolveKeyReferences,
32
+ resolveKeyReferencesWithRequestScopes,
33
33
  validateUrlAllowlist,
34
34
  getKeyAllowlist,
35
35
  } from "../secrets/substitution.js";
@@ -215,21 +215,30 @@ async function resolveWebhookRequest(
215
215
  owner: string,
216
216
  label: string,
217
217
  ): Promise<{ url: string; headers: Record<string, string> }> {
218
- // Resolve `${keys.NAME}` references against the owner's user-scope secrets.
218
+ // Resolve `${keys.NAME}` references through the same request-scope
219
+ // cascade already used by extension fetches (extensions/routes.ts) and
220
+ // automation connector headers (automation/index.ts): user scope first
221
+ // (a personal override always wins), then the active org scope — where
222
+ // the Dispatch vault syncs workspace secrets — then workspace scope.
223
+ // Org/workspace vault rows are write-gated (org-admin + Dispatch vault
224
+ // UI), so reading them here is safe by default; this is unrelated to the
225
+ // opt-in-only user→workspace fallback in resolveKeyReferences (audit 05
226
+ // H2 in secrets/substitution.ts), which stays off. In headless contexts
227
+ // (e.g. a scheduled monitor check) getRequestOrgId() may be unset, in
228
+ // which case the cascade checks user + solo-workspace scopes only — a
229
+ // strict superset of the previous user-scope-only behavior.
219
230
  // Missing keys throw — the error surfaces in logs and the channel is marked
220
231
  // un-delivered, but other channels still run.
221
- const { resolved: url } = await resolveKeyReferences(
232
+ const { resolved: url } = await resolveKeyReferencesWithRequestScopes(
222
233
  urlTemplate,
223
- "user",
224
234
  owner,
225
235
  );
226
236
  const headers: Record<string, string> = {
227
237
  "Content-Type": "application/json",
228
238
  };
229
239
  if (authTemplate) {
230
- const { resolved: auth } = await resolveKeyReferences(
240
+ const { resolved: auth } = await resolveKeyReferencesWithRequestScopes(
231
241
  authTemplate,
232
- "user",
233
242
  owner,
234
243
  );
235
244
  headers.Authorization = auth;
@@ -237,6 +246,11 @@ async function resolveWebhookRequest(
237
246
 
238
247
  // If the user set an allowlist on a referenced key, enforce it here —
239
248
  // origin-level check, same rule the automations fetch-tool applies.
249
+ // NOTE: this still checks the allowlist at user scope only (unlike the
250
+ // fetch tool's validateUrl, which now consults getResolvedKeyAllowlist at
251
+ // the scope the key actually resolved at — see agent-chat-plugin.ts). A
252
+ // key that resolves at org/workspace scope with an allowlist configured
253
+ // on that org/workspace row will not have it enforced here.
240
254
  const keyNames = Array.from(
241
255
  new Set(
242
256
  Array.from(urlTemplate.matchAll(/\$\{keys\.([A-Za-z0-9_-]+)\}/g), (m) =>
@@ -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
+ });