@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
@@ -49,6 +49,12 @@ const PILL_LABEL: &str = "recording-pill";
49
49
  /// it through every command.
50
50
  static PILL_DETACHED: AtomicBool = AtomicBool::new(false);
51
51
  static PILL_RIGHT_SIDE: AtomicBool = AtomicBool::new(false);
52
+ /// Mirrors the renderer's `expanded` React state so a re-show of an already
53
+ /// open pill (e.g. after the tray icon toggles the popover) resizes the
54
+ /// native window to match what's actually rendered instead of snapping it
55
+ /// back to the collapsed size while the webview still renders the expanded
56
+ /// layout.
57
+ static PILL_EXPANDED: AtomicBool = AtomicBool::new(false);
52
58
 
53
59
  /// Hover-tracking loop control. macOS only feeds mouse-moved / hover events to
54
60
  /// the *key* window, so the background pill's CSS `:hover` never fires while
@@ -360,7 +366,8 @@ pub async fn recording_pill_show(
360
366
  (Some(p), Some(s)) => Some((p.x, p.y, s.width, s.height)),
361
367
  _ => None,
362
368
  };
363
- let (w, h, x, y) = anchored_rect(&app, false, previous);
369
+ let expanded = PILL_EXPANDED.load(Ordering::Relaxed);
370
+ let (w, h, x, y) = anchored_rect(&app, expanded, previous);
364
371
  let _ = existing.set_size(tauri::Size::Physical(PhysicalSize::new(w, h)));
365
372
  let _ = existing.set_position(PhysicalPosition::new(x, y));
366
373
  use tauri::Emitter;
@@ -377,6 +384,7 @@ pub async fn recording_pill_show(
377
384
  return Ok(());
378
385
  }
379
386
 
387
+ PILL_EXPANDED.store(false, Ordering::SeqCst);
380
388
  let (w, h, x, y) = anchored_rect(&app, false, None);
381
389
 
382
390
  let url = build_overlay_url("recording-pill");
@@ -465,6 +473,7 @@ fn stop_pill_hover_tracking() {
465
473
 
466
474
  #[tauri::command]
467
475
  pub async fn recording_pill_expand(app: AppHandle, expanded: bool) -> Result<(), String> {
476
+ PILL_EXPANDED.store(expanded, Ordering::SeqCst);
468
477
  let Some(window) = app.get_webview_window(PILL_LABEL) else {
469
478
  return Ok(());
470
479
  };
@@ -534,6 +543,7 @@ pub async fn recording_pill_set_detached(app: AppHandle, detached: bool) -> Resu
534
543
  // by the time we hit `anchored_rect` below, the new flag has
535
544
  // already taken effect and we get the right size + position for
536
545
  // the destination mode. (The atomic was flipped above.)
546
+ PILL_EXPANDED.store(false, Ordering::SeqCst);
537
547
  let (w, h, x, y) = anchored_rect(&app, false, None);
538
548
  let _ = window.set_size(tauri::Size::Physical(PhysicalSize::new(w, h)));
539
549
  let _ = window.set_position(PhysicalPosition::new(x, y));
@@ -0,0 +1,188 @@
1
+ //! Server-controlled feature flags for the desktop capture pipeline
2
+ //! (`useCustomSCKPipeline`, `customSCKPipelineLiveUploadEnabled`) — flipping
3
+ //! either requires no desktop rebuild. This module fetches the flags from the
4
+ //! backend's `get-feature-flags` action and caches them in memory so
5
+ //! backend-selection stays a synchronous, zero-latency read.
6
+ //!
7
+ //! `spawn_watcher` runs its own periodic poll (independent of the meetings
8
+ //! watcher's tick, though it reuses the same session credentials via
9
+ //! `MeetingsWatcherState::session_snapshot()` rather than tracking its own);
10
+ //! recording start also kicks off a best-effort (non-blocking) refresh so the
11
+ //! cache stays warm without ever delaying a recording start. A fetch failure
12
+ //! (offline, no session yet, 401) just leaves the last-known-good value in
13
+ //! place — the cache never resets to defaults once a real value has been
14
+ //! fetched.
15
+
16
+ use std::sync::{Mutex, OnceLock};
17
+ use std::time::Duration;
18
+
19
+ use serde::Deserialize;
20
+ use tauri::{AppHandle, Manager};
21
+
22
+ use crate::meetings_watcher::MeetingsWatcherState;
23
+
24
+ /// How often the background watcher polls `get-feature-flags` once it has
25
+ /// fetched successfully at least once.
26
+ const REMOTE_FLAGS_POLL_SECS: u64 = 60;
27
+ /// How often it retries before the first successful fetch (e.g. while
28
+ /// waiting for the renderer to push session credentials after app launch).
29
+ const REMOTE_FLAGS_FAST_POLL_SECS: u64 = 5;
30
+
31
+ fn default_false() -> bool {
32
+ false
33
+ }
34
+
35
+ // Explicit `rename`s (not `rename_all = "camelCase"`) because serde's
36
+ // case conversion would turn `sck` into `Sck`, not `SCK` — these must match
37
+ // the JSON keys from the `get-feature-flags` action exactly.
38
+ #[derive(Debug, Clone, Copy, Deserialize)]
39
+ pub(crate) struct RemoteFeatureFlags {
40
+ #[serde(rename = "useCustomSCKPipeline", default = "default_false")]
41
+ pub(crate) use_custom_sck_pipeline: bool,
42
+ #[serde(
43
+ rename = "customSCKPipelineLiveUploadEnabled",
44
+ default = "default_false"
45
+ )]
46
+ pub(crate) custom_sck_pipeline_live_upload_enabled: bool,
47
+ }
48
+
49
+ impl Default for RemoteFeatureFlags {
50
+ fn default() -> Self {
51
+ Self {
52
+ use_custom_sck_pipeline: false,
53
+ custom_sck_pipeline_live_upload_enabled: false,
54
+ }
55
+ }
56
+ }
57
+
58
+ fn cache() -> &'static Mutex<RemoteFeatureFlags> {
59
+ static CACHE: OnceLock<Mutex<RemoteFeatureFlags>> = OnceLock::new();
60
+ CACHE.get_or_init(|| Mutex::new(RemoteFeatureFlags::default()))
61
+ }
62
+
63
+ /// Last-known-good flags. Synchronous — safe to call from the non-async
64
+ /// backend-selection code paths that choose the capture pipeline.
65
+ pub(crate) fn current() -> RemoteFeatureFlags {
66
+ *cache().lock().unwrap_or_else(|e| e.into_inner())
67
+ }
68
+
69
+ /// Fetch `get-feature-flags` from the backend and update the in-memory cache
70
+ /// on success. Best-effort: any failure just leaves the cache untouched.
71
+ pub(crate) async fn refresh(
72
+ client: &reqwest::Client,
73
+ server_url: &str,
74
+ cookie: Option<&str>,
75
+ auth_token: Option<&str>,
76
+ ) -> Result<(), String> {
77
+ let url = format!("{server_url}/_agent-native/actions/get-feature-flags");
78
+ let mut req = client.get(&url).header("X-Request-Source", "clips-desktop");
79
+ if let Some(c) = cookie {
80
+ req = req.header("Cookie", c);
81
+ }
82
+ if let Some(token) = auth_token {
83
+ req = req.bearer_auth(token);
84
+ }
85
+ let resp = req
86
+ .send()
87
+ .await
88
+ .map_err(|e| format!("fetch feature flags: {e}"))?;
89
+ if !resp.status().is_success() {
90
+ return Err(format!("fetch feature flags: HTTP {}", resp.status()));
91
+ }
92
+ let flags: RemoteFeatureFlags = resp
93
+ .json()
94
+ .await
95
+ .map_err(|e| format!("parse feature flags: {e}"))?;
96
+ *cache().lock().unwrap_or_else(|e| e.into_inner()) = flags;
97
+ Ok(())
98
+ }
99
+
100
+ /// Fire a best-effort refresh in the background without blocking the caller
101
+ /// (e.g. recording start). No-ops silently without a server URL.
102
+ pub(crate) fn spawn_refresh(
103
+ server_url: Option<String>,
104
+ cookie: Option<String>,
105
+ auth_token: Option<String>,
106
+ ) {
107
+ let Some(server_url) = server_url.filter(|s| !s.trim().is_empty()) else {
108
+ return;
109
+ };
110
+ tauri::async_runtime::spawn(async move {
111
+ let client = match reqwest::Client::builder()
112
+ .timeout(Duration::from_secs(5))
113
+ .build()
114
+ {
115
+ Ok(c) => c,
116
+ Err(err) => {
117
+ eprintln!("[feature-flags] reqwest build failed: {err}");
118
+ return;
119
+ }
120
+ };
121
+ if let Err(err) = refresh(
122
+ &client,
123
+ &server_url,
124
+ cookie.as_deref(),
125
+ auth_token.as_deref(),
126
+ )
127
+ .await
128
+ {
129
+ eprintln!("[feature-flags] refresh failed: {err}");
130
+ }
131
+ });
132
+ }
133
+
134
+ /// Spawn the long-running feature-flags poller. Idempotent — gated on a
135
+ /// static `OnceLock` so a double-call from setup is safe. Runs on its own
136
+ /// loop, entirely separate from the meetings watcher's tick; it only reads
137
+ /// that watcher's already-live session credentials (server URL / cookie /
138
+ /// auth token) via `session_snapshot()` instead of tracking a second copy.
139
+ ///
140
+ /// Starts immediately (no initial delay) and retries every
141
+ /// `REMOTE_FLAGS_FAST_POLL_SECS` until the first successful fetch — session
142
+ /// credentials aren't pushed by the renderer until sign-in completes, so this
143
+ /// closes that gap without the app needing to notify this loop. Once a fetch
144
+ /// succeeds it settles into the slower `REMOTE_FLAGS_POLL_SECS` keep-warm
145
+ /// cadence.
146
+ pub(crate) fn spawn_watcher(app: AppHandle) {
147
+ static STARTED: OnceLock<()> = OnceLock::new();
148
+ if STARTED.set(()).is_err() {
149
+ return;
150
+ }
151
+ tauri::async_runtime::spawn(async move {
152
+ let client = match reqwest::Client::builder()
153
+ .timeout(Duration::from_secs(10))
154
+ .build()
155
+ {
156
+ Ok(c) => c,
157
+ Err(err) => {
158
+ eprintln!("[feature-flags] request build failed: {err}");
159
+ return;
160
+ }
161
+ };
162
+ let mut fetched_once = false;
163
+ loop {
164
+ if let Some(state) = app.try_state::<MeetingsWatcherState>() {
165
+ let snapshot = state.session_snapshot();
166
+ if let Some(server_url) = snapshot.server_url {
167
+ match refresh(
168
+ &client,
169
+ &server_url,
170
+ snapshot.session_cookie.as_deref(),
171
+ snapshot.auth_token.as_deref(),
172
+ )
173
+ .await
174
+ {
175
+ Ok(()) => fetched_once = true,
176
+ Err(err) => eprintln!("[feature-flags] watcher refresh failed: {err}"),
177
+ }
178
+ }
179
+ }
180
+ let wait_secs = if fetched_once {
181
+ REMOTE_FLAGS_POLL_SECS
182
+ } else {
183
+ REMOTE_FLAGS_FAST_POLL_SECS
184
+ };
185
+ tokio::time::sleep(Duration::from_secs(wait_secs)).await;
186
+ }
187
+ });
188
+ }
@@ -480,7 +480,7 @@ mod macos {
480
480
  language: Option<&str>,
481
481
  ) -> Vec<(i64, i64, String)> {
482
482
  let mut params = FullParams::new(SamplingStrategy::Greedy { best_of: 1 });
483
- params.set_n_threads(4);
483
+ params.set_n_threads(2);
484
484
  params.set_language(language);
485
485
  params.set_translate(false);
486
486
  params.set_no_context(true);
@@ -46,6 +46,7 @@ export async function dispatchPostFinalizeJob(args: {
46
46
  kind: PostFinalizeJobKind;
47
47
  delayMs?: number;
48
48
  retryAttempt?: number;
49
+ regenerate?: boolean;
49
50
  }): Promise<void> {
50
51
  const token = signScopedAgentAccessToken({
51
52
  resourceKind: POST_FINALIZE_JOB_TOKEN_KIND,
@@ -18,6 +18,7 @@ const INITIAL_TOOL_NAMES = [
18
18
  "list-recordings",
19
19
  "search-recordings",
20
20
  "get-recording-player-data",
21
+ "request-transcript",
21
22
  "create-recording",
22
23
  "import-loom-recording",
23
24
  "update-recording",
@@ -38,5 +39,9 @@ export default createAgentChatPlugin({
38
39
  appId: "clips",
39
40
  actions: loadActionsFromStaticRegistry(actionsRegistry),
40
41
  initialToolNames: INITIAL_TOOL_NAMES,
42
+ extraContext: async () =>
43
+ `<clips-transcript-guidance>
44
+ The transcript in view-screen is a bounded preview. When previewTruncated is true, its text is expected to end mid-sentence and is never evidence that transcription stopped early. Call get-recording-player-data before judging transcript completeness or quoting the full transcript. For a failed or pending transcript, use request-transcript with force=true. For an explicit fresh retry of an existing ready transcript, also pass regenerate=true. Agent-triggered retries are queued for the durable worker and return pending while processing.
45
+ </clips-transcript-guidance>`,
41
46
  resolveOrgId: async (event) => (await getOrgContext(event)).orgId,
42
47
  });
@@ -26,6 +26,7 @@ const bodySchema = z.object({
26
26
  token: z.string().min(1),
27
27
  delayMs: z.number().int().min(0).max(30_000).optional(),
28
28
  retryAttempt: z.number().int().min(1).max(10).optional(),
29
+ regenerate: z.boolean().optional(),
29
30
  });
30
31
 
31
32
  export default defineEventHandler(async (event: H3Event) => {
@@ -35,7 +36,8 @@ export default defineEventHandler(async (event: H3Event) => {
35
36
  return { ok: false, error: "Invalid post-finalize job" };
36
37
  }
37
38
 
38
- const { recordingId, kind, token, delayMs, retryAttempt } = parsed.data;
39
+ const { recordingId, kind, token, delayMs, retryAttempt, regenerate } =
40
+ parsed.data;
39
41
  const verified = verifyScopedAgentAccessToken(token, {
40
42
  resourceKind: POST_FINALIZE_JOB_TOKEN_KIND,
41
43
  resourceId: postFinalizeJobResourceId(recordingId, kind),
@@ -81,6 +83,7 @@ export default defineEventHandler(async (event: H3Event) => {
81
83
  recordingId,
82
84
  kind,
83
85
  retryAttempt,
86
+ regenerate,
84
87
  });
85
88
  return {
86
89
  ok: true,
@@ -102,6 +105,7 @@ export default defineEventHandler(async (event: H3Event) => {
102
105
  recordingId,
103
106
  force: true,
104
107
  retryAttempt,
108
+ regenerate,
105
109
  });
106
110
  return { ok: true, kind, result };
107
111
  },
@@ -0,0 +1,41 @@
1
+ /**
2
+ * Server-controlled feature flags, readable from the action surface so
3
+ * behavior can change without a redeploy. Stored under one global `settings`
4
+ * key (not per-user/org) — these gate app-wide rollout decisions, not
5
+ * individual preferences.
6
+ *
7
+ * Add new flags here as they're needed; `get-feature-flags` stays generic
8
+ * and doesn't need to change.
9
+ */
10
+
11
+ export const FEATURE_FLAGS_KEY = "feature-flags";
12
+
13
+ export type FeatureFlags = {
14
+ /**
15
+ * Desktop app: use the custom ScreenCaptureKit (SCK) capture pipeline
16
+ * (fragmented MP4 writer + live audio mixer) instead of Apple's stock
17
+ * `SCRecordingOutput`. See `desktop/src-tauri/src/native_screen/custom_capture.rs`.
18
+ */
19
+ useCustomSCKPipeline?: boolean;
20
+ /**
21
+ * Desktop app: stream the recording to the server in chunks while it is
22
+ * being recorded, instead of uploading the whole file after Stop. Only
23
+ * effective when `useCustomSCKPipeline` is also on. See
24
+ * `desktop/src-tauri/src/native_screen/live_upload.rs`.
25
+ */
26
+ customSCKPipelineLiveUploadEnabled?: boolean;
27
+ };
28
+
29
+ export const FEATURE_FLAG_DEFAULTS: Required<FeatureFlags> = {
30
+ useCustomSCKPipeline: false,
31
+ customSCKPipelineLiveUploadEnabled: false,
32
+ };
33
+
34
+ export function withFeatureFlagDefaults(
35
+ flags: FeatureFlags | Record<string, unknown> | null | undefined,
36
+ ): Required<FeatureFlags> {
37
+ return {
38
+ ...FEATURE_FLAG_DEFAULTS,
39
+ ...(flags as FeatureFlags | undefined),
40
+ };
41
+ }
@@ -661,6 +661,9 @@ regeneration is slow, expensive, and regresses unrelated parts.
661
661
 
662
662
  1. **Read before you edit.** Pull the current file with `get-design-snapshot`
663
663
  (or `get-design`) so you edit the live content, not a stale memory of it.
664
+ If the design has persisted review comments, fetch the open queue with
665
+ `get-review-feedback` and use `.agents/skills/design-review-feedback` to
666
+ apply and verify one anchored thread at a time.
664
667
  2. **Prefer `edit-design` for small changes.** It applies one or more
665
668
  search/replace blocks to a file's HTML — surgical, cheap, and it preserves
666
669
  everything you didn't touch (Alpine state, scroll, other screens):
@@ -0,0 +1,42 @@
1
+ ---
2
+ name: design-review-feedback
3
+ description: >-
4
+ Work through persisted, element-anchored review comments on shared Design
5
+ prototypes and close the loop with verified edits.
6
+ ---
7
+
8
+ # Design Review Feedback
9
+
10
+ Use the shared review actions for design feedback:
11
+
12
+ 1. Call `view-screen` first so the active design, screen, inspector tab, and
13
+ review queue are current.
14
+ 2. Call `get-review-feedback` for the open queue and work on one root thread at
15
+ a time. Keep the thread id, target screen id, anchor node id, and nearby
16
+ context together while editing.
17
+ 3. For element-anchored feedback, prefer the stable
18
+ `data-agent-native-node-id` from the anchor. Use the stored percentage point
19
+ only as a visual fallback when the node cannot be resolved.
20
+ 4. Read the affected file with `get-design-snapshot`, make the smallest
21
+ persisted edit with `edit-design` or the appropriate design action, then
22
+ verify the saved result with `get-design-snapshot` and a screenshot or audit
23
+ when the change is visual.
24
+ 5. Resolve the thread with `resolve-review-thread` only after the edit is
25
+ persisted and verified, and pass `resolutionNote` with a one-line description
26
+ of the persisted change. If the user needs to decide something, reply with
27
+ `reply-review-comment` and set `resolutionTarget: "human"`; do not silently
28
+ resolve it.
29
+ 6. After applying a thread, call `consume-review-feedback` for the applied
30
+ agent-targeted root comment so the queue does not repeatedly resurface the
31
+ same work.
32
+
33
+ Reviewers can leave a human-only comment or choose **Send to agent** when
34
+ composing. Editors can selectively route an existing open thread with
35
+ `send-review-thread-to-agent`; that action only changes the selected thread.
36
+ When a thread is sent from the Design UI, the agent chat handoff includes its
37
+ thread id and instructs the agent not to apply other queued feedback.
38
+
39
+ Use `create-review-comment` for agent-authored follow-up notes when a durable
40
+ record is more useful than a chat-only explanation. Keep review comments
41
+ scoped to the design resource and the target screen; never copy large HTML,
42
+ screenshots, or provider payloads into a comment.
@@ -33,6 +33,12 @@ patterns live in `.agents/skills/`.
33
33
  tool. The action schema is the source of truth for parameters.
34
34
  - Call `view-screen` before editing a specific design if the current design or
35
35
  selected file is not already clear from context.
36
+ - For shared prototype feedback, use the persisted review actions
37
+ (`list-review-comments`, `get-review-feedback`, `create-review-comment`,
38
+ `reply-review-comment`, `resolve-review-thread`, `consume-review-feedback`,
39
+ `send-review-thread-to-agent`, and `set-review-status`). Work one thread at a time, prefer its stable node
40
+ anchor, verify saved edits before resolving, and read
41
+ `.agents/skills/design-review-feedback/SKILL.md` for the full loop.
36
42
  - Generated files must be complete, standalone HTML unless the user asks for a
37
43
  different export format. They should render in the iframe without a build step.
38
44
  - For design generation, ground the work in a concrete audience, primary job,
@@ -18,6 +18,7 @@ prompts and visual tweak controls.
18
18
  - Save and reuse design-system preferences to stay on-brand.
19
19
  - Import existing HTML or reference material as context.
20
20
  - Export real files: HTML, ZIP, or PDF.
21
+ - Share prototypes with element-anchored review comments and apply verified feedback through the agent.
21
22
 
22
23
  ## Develop locally
23
24
 
@@ -18,7 +18,7 @@
18
18
  * --view View name (list, editor, design-systems, present, settings)
19
19
  * --designId Design ID (for editor/present views)
20
20
  * --editorView Editor mode for designs: single or overview
21
- * --inspectorTab Inspector tab for designs: design or tweaks (extensions opens Tools for compatibility)
21
+ * --inspectorTab Inspector tab for designs: design, comments, or tweaks (extensions opens Tools for compatibility)
22
22
  * --leftPanel Left editor panel: file, agent, assets, import, tools, tokens, or code
23
23
  * --fileId Screen/file id to focus in the design editor
24
24
  * --filename Screen filename to focus in the design editor
@@ -61,7 +61,7 @@ const designLeftPanelSchema = z.enum([
61
61
 
62
62
  export default defineAction({
63
63
  description:
64
- "Navigate the UI to a specific view or path. Views: list, templates, editor, design-systems, present, settings. Use --templateId with templates, --designId with editor/present views, and --designSystemId with design-systems. For designs, use editorView=overview to show the infinite screens canvas, or editorView=single with fileId/filename/screen to focus a screen. Use leftPanel=file|agent|assets|import|tools|tokens|code to focus the left rail, including Import and the wide Code workspace. Legacy inspectorTab=extensions opens Tools. Use tool to activate a design editor tool.",
64
+ "Navigate the UI to a specific view or path. Views: list, templates, editor, design-systems, present, settings. Use --templateId with templates, --designId with editor/present views, and --designSystemId with design-systems. For designs, use editorView=overview to show the infinite screens canvas, or editorView=single with fileId/filename/screen to focus a screen. Use inspectorTab=design|comments|tweaks to focus the inspector, or leftPanel=file|agent|assets|import|tools|tokens|code to focus the left rail, including Import and the wide Code workspace. Legacy inspectorTab=extensions opens Tools. Use tool to activate a design editor tool.",
65
65
  schema: z
66
66
  .object({
67
67
  view: z
@@ -87,11 +87,11 @@ export default defineAction({
87
87
  .optional()
88
88
  .describe("Alias for editorView"),
89
89
  inspectorTab: z
90
- .enum(["design", "tweaks", "extensions"])
90
+ .enum(["design", "comments", "tweaks", "extensions"])
91
91
  .optional()
92
92
  .describe("Design editor inspector tab to focus"),
93
93
  inspector: z
94
- .enum(["design", "tweaks", "extensions"])
94
+ .enum(["design", "comments", "tweaks", "extensions"])
95
95
  .optional()
96
96
  .describe("Alias for inspectorTab"),
97
97
  leftPanel: designLeftPanelSchema
@@ -12,6 +12,16 @@ import {
12
12
  readAppState,
13
13
  readAppStateForCurrentTab,
14
14
  } from "@agent-native/core/application-state";
15
+ import {
16
+ getReviewStatus,
17
+ queryReviewComments,
18
+ redactPublicReviewCommentIdentity,
19
+ redactPublicReviewStatusIdentity,
20
+ shouldRedactReviewIdentity,
21
+ type ReviewComment,
22
+ type ReviewResourceContext,
23
+ } from "@agent-native/core/review";
24
+ import * as reviewRuntime from "@agent-native/core/review";
15
25
  import { resolveAccess } from "@agent-native/core/sharing";
16
26
  import { eq } from "drizzle-orm";
17
27
  import { z } from "zod";
@@ -21,6 +31,22 @@ import { parseCanvasFrameGeometryById } from "../shared/canvas-frames.js";
21
31
  import { getDesignTemplatePreset } from "../shared/design-template-presets.js";
22
32
  import { designGenerationSessionKey } from "../shared/generation-session.js";
23
33
 
34
+ interface ReviewThreadSummary {
35
+ openCount: number;
36
+ agentQueueCount: number;
37
+ }
38
+
39
+ const getReviewThreadSummary = (
40
+ reviewRuntime as unknown as {
41
+ getReviewThreadSummary?: (input: {
42
+ resourceType: string;
43
+ resourceId: string;
44
+ scope: { userEmail?: string | null; orgId?: string | null };
45
+ bypassScope?: boolean;
46
+ }) => Promise<ReviewThreadSummary>;
47
+ }
48
+ ).getReviewThreadSummary;
49
+
24
50
  function stringProp(value: unknown, key: string): string | undefined {
25
51
  if (!value || typeof value !== "object") return undefined;
26
52
  const candidate = (value as Record<string, unknown>)[key];
@@ -135,12 +161,57 @@ function resolveActiveCodeFile(
135
161
  };
136
162
  }
137
163
 
164
+ function reviewAnchorNodeId(anchor: unknown): string | null {
165
+ if (!anchor || typeof anchor !== "object") return null;
166
+ const nodeId = (anchor as Record<string, unknown>).nodeId;
167
+ return typeof nodeId === "string" && nodeId.trim() ? nodeId : null;
168
+ }
169
+
170
+ function buildReviewSummary(
171
+ comments: ReviewComment[],
172
+ status: Awaited<ReturnType<typeof getReviewStatus>>,
173
+ activeScreenId: string | undefined,
174
+ summary?: ReviewThreadSummary,
175
+ ) {
176
+ const openRoots = new Map<string, ReviewComment>();
177
+ for (const comment of comments) {
178
+ if (comment.status !== "open") continue;
179
+ if (!comment.parentCommentId && !openRoots.has(comment.threadId)) {
180
+ openRoots.set(comment.threadId, comment);
181
+ }
182
+ }
183
+ const agentQueueThreads = new Set(
184
+ Array.from(openRoots.values())
185
+ .filter(
186
+ (comment) =>
187
+ comment.resolutionTarget !== "human" && !comment.consumedAt,
188
+ )
189
+ .map((comment) => comment.threadId),
190
+ );
191
+ const activeScreenThreads = Array.from(openRoots.values())
192
+ .filter((comment) => comment.targetId === activeScreenId)
193
+ .map((comment) => ({
194
+ id: comment.id,
195
+ threadId: comment.threadId,
196
+ body: comment.body.slice(0, 180),
197
+ nodeId: reviewAnchorNodeId(comment.anchor),
198
+ author: comment.authorName ?? comment.authorEmail ?? comment.createdBy,
199
+ }));
200
+
201
+ return {
202
+ status: status?.status ?? "draft",
203
+ openCount: summary?.openCount ?? openRoots.size,
204
+ agentQueueCount: summary?.agentQueueCount ?? agentQueueThreads.size,
205
+ activeScreenThreads,
206
+ };
207
+ }
208
+
138
209
  export default defineAction({
139
210
  description:
140
- "See what the user is currently looking at on screen. Returns the current navigation state including which design or template is open, which view they are on (list, templates, editor, design-systems, present, settings), active/focused design screen, selected element, active inspector tab (design or tweaks), active left rail panel (file, agent, assets, import, tools, tokens, or code), active code file metadata, overview canvas state, plus any pending question overlay. Always call this first before taking any action.",
211
+ "See what the user is currently looking at on screen. Returns the current navigation state including which design or template is open, which view they are on (list, templates, editor, design-systems, present, settings), active/focused design screen, selected element, active inspector tab (design, comments, or tweaks), active left rail panel (file, agent, assets, import, tools, tokens, or code), active code file metadata, overview canvas state, review status and feedback queue summary, plus any pending question overlay. Always call this first before taking any action.",
141
212
  schema: z.object({}),
142
213
  http: false,
143
- run: async () => {
214
+ run: async (_, ctx) => {
144
215
  const [navigation, designSelection] = await Promise.all([
145
216
  readAppStateForCurrentTab("navigation"),
146
217
  readAppStateForCurrentTab("design-selection"),
@@ -233,6 +304,49 @@ export default defineAction({
233
304
  activeCodeFile: resolveActiveCodeFile(files, designSelection),
234
305
  canvasFrames: parseCanvasFrameGeometryById(data.canvasFrames),
235
306
  };
307
+ const reviewContext = ctx as ReviewResourceContext | undefined;
308
+ const reviewScope = {
309
+ userEmail: reviewContext?.userEmail ?? null,
310
+ orgId: reviewContext?.orgId ?? null,
311
+ };
312
+ const [reviewComments, reviewStatus, reviewSummary] = await Promise.all(
313
+ [
314
+ queryReviewComments({
315
+ resourceType: "design",
316
+ resourceId: designId,
317
+ scope: reviewScope,
318
+ bypassScope: true,
319
+ includeResolved: false,
320
+ includeDeleted: false,
321
+ limit: 500,
322
+ }),
323
+ getReviewStatus("design", designId, reviewScope, {
324
+ bypassScope: true,
325
+ }),
326
+ getReviewThreadSummary
327
+ ? getReviewThreadSummary({
328
+ resourceType: "design",
329
+ resourceId: designId,
330
+ scope: reviewScope,
331
+ bypassScope: true,
332
+ })
333
+ : Promise.resolve(undefined),
334
+ ],
335
+ );
336
+ const redactReviewIdentity = shouldRedactReviewIdentity(reviewContext, {
337
+ role: access.role,
338
+ visibility: access.resource.visibility,
339
+ });
340
+ (screen.design as Record<string, unknown>).review = buildReviewSummary(
341
+ redactReviewIdentity
342
+ ? reviewComments.map(redactPublicReviewCommentIdentity)
343
+ : reviewComments,
344
+ redactReviewIdentity
345
+ ? redactPublicReviewStatusIdentity(reviewStatus)
346
+ : reviewStatus,
347
+ resolveActiveScreen(files, navigation, designSelection)?.id,
348
+ reviewSummary,
349
+ );
236
350
  }
237
351
  }
238
352
  if (showQuestions) {
@@ -46,6 +46,11 @@
46
46
  "path": ".agents/skills/visual-edit",
47
47
  "visibility": "both",
48
48
  "exportAs": "visual-edit"
49
+ },
50
+ {
51
+ "path": ".agents/skills/design-review-feedback",
52
+ "visibility": "both",
53
+ "exportAs": "design-review-feedback"
49
54
  }
50
55
  ],
51
56
  "hostAdapters": [