@agent-native/toolkit 0.228.0-nightly-20261111212500 → 0.228.0

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 (361) hide show
  1. package/agent-native.eject.json +2 -0
  2. package/dist/app/agentkit/react/approval-card.d.ts.map +1 -1
  3. package/dist/app/agentkit/react/approval-card.js +5 -3
  4. package/dist/app/agentkit/react/approval-card.js.map +1 -1
  5. package/dist/app/agentkit/react/code-block.d.ts +32 -0
  6. package/dist/app/agentkit/react/code-block.d.ts.map +1 -0
  7. package/dist/app/agentkit/react/code-block.js +125 -0
  8. package/dist/app/agentkit/react/code-block.js.map +1 -0
  9. package/dist/app/agentkit/react/components.d.ts +33 -14
  10. package/dist/app/agentkit/react/components.d.ts.map +1 -1
  11. package/dist/app/agentkit/react/components.js +843 -168
  12. package/dist/app/agentkit/react/components.js.map +1 -1
  13. package/dist/app/agentkit/react/context-usage.d.ts +45 -0
  14. package/dist/app/agentkit/react/context-usage.d.ts.map +1 -0
  15. package/dist/app/agentkit/react/context-usage.js +93 -0
  16. package/dist/app/agentkit/react/context-usage.js.map +1 -0
  17. package/dist/app/agentkit/react/context.d.ts +42 -3
  18. package/dist/app/agentkit/react/context.d.ts.map +1 -1
  19. package/dist/app/agentkit/react/context.js +46 -1
  20. package/dist/app/agentkit/react/context.js.map +1 -1
  21. package/dist/app/agentkit/react/disclosure-content.d.ts +12 -0
  22. package/dist/app/agentkit/react/disclosure-content.d.ts.map +1 -0
  23. package/dist/app/agentkit/react/disclosure-content.js +33 -0
  24. package/dist/app/agentkit/react/disclosure-content.js.map +1 -0
  25. package/dist/app/agentkit/react/duration.d.ts +6 -0
  26. package/dist/app/agentkit/react/duration.d.ts.map +1 -0
  27. package/dist/app/agentkit/react/duration.js +21 -0
  28. package/dist/app/agentkit/react/duration.js.map +1 -0
  29. package/dist/app/agentkit/react/file-change.d.ts +33 -0
  30. package/dist/app/agentkit/react/file-change.d.ts.map +1 -0
  31. package/dist/app/agentkit/react/file-change.js +83 -0
  32. package/dist/app/agentkit/react/file-change.js.map +1 -0
  33. package/dist/app/agentkit/react/file-diff.d.ts +17 -0
  34. package/dist/app/agentkit/react/file-diff.d.ts.map +1 -0
  35. package/dist/app/agentkit/react/file-diff.js +94 -0
  36. package/dist/app/agentkit/react/file-diff.js.map +1 -0
  37. package/dist/app/agentkit/react/index.d.ts +7 -0
  38. package/dist/app/agentkit/react/index.d.ts.map +1 -1
  39. package/dist/app/agentkit/react/index.js +7 -0
  40. package/dist/app/agentkit/react/index.js.map +1 -1
  41. package/dist/app/agentkit/react/question-card.d.ts +67 -0
  42. package/dist/app/agentkit/react/question-card.d.ts.map +1 -0
  43. package/dist/app/agentkit/react/question-card.js +198 -0
  44. package/dist/app/agentkit/react/question-card.js.map +1 -0
  45. package/dist/app/agentkit/react/root.d.ts +3 -2
  46. package/dist/app/agentkit/react/root.d.ts.map +1 -1
  47. package/dist/app/agentkit/react/root.js +2 -2
  48. package/dist/app/agentkit/react/root.js.map +1 -1
  49. package/dist/app/agentkit/react/roving-focus.d.ts +4 -0
  50. package/dist/app/agentkit/react/roving-focus.d.ts.map +1 -0
  51. package/dist/app/agentkit/react/roving-focus.js +75 -0
  52. package/dist/app/agentkit/react/roving-focus.js.map +1 -0
  53. package/dist/app/agentkit/react/stack-trace.d.ts +34 -0
  54. package/dist/app/agentkit/react/stack-trace.d.ts.map +1 -0
  55. package/dist/app/agentkit/react/stack-trace.js +121 -0
  56. package/dist/app/agentkit/react/stack-trace.js.map +1 -0
  57. package/dist/app/agentkit/react/stop-button.d.ts.map +1 -1
  58. package/dist/app/agentkit/react/stop-button.js +22 -6
  59. package/dist/app/agentkit/react/stop-button.js.map +1 -1
  60. package/dist/app/agentkit/react/styles.css +1306 -395
  61. package/dist/app/agentkit/react/terminal.d.ts +28 -0
  62. package/dist/app/agentkit/react/terminal.d.ts.map +1 -0
  63. package/dist/app/agentkit/react/terminal.js +84 -0
  64. package/dist/app/agentkit/react/terminal.js.map +1 -0
  65. package/dist/app/agentkit/react/trace.d.ts +31 -0
  66. package/dist/app/agentkit/react/trace.d.ts.map +1 -0
  67. package/dist/app/agentkit/react/trace.js +73 -0
  68. package/dist/app/agentkit/react/trace.js.map +1 -0
  69. package/dist/app/blocks/library/HighlightedCode.d.ts +2 -1
  70. package/dist/app/blocks/library/HighlightedCode.d.ts.map +1 -1
  71. package/dist/app/blocks/library/HighlightedCode.js +8 -111
  72. package/dist/app/blocks/library/HighlightedCode.js.map +1 -1
  73. package/dist/app/chat/AgentKitAssistantChat.d.ts.map +1 -1
  74. package/dist/app/chat/AgentKitAssistantChat.js +23 -245
  75. package/dist/app/chat/AgentKitAssistantChat.js.map +1 -1
  76. package/dist/app/chat/agentkit-chat/guided-questions.d.ts +15 -1
  77. package/dist/app/chat/agentkit-chat/guided-questions.d.ts.map +1 -1
  78. package/dist/app/chat/agentkit-chat/guided-questions.js +142 -2
  79. package/dist/app/chat/agentkit-chat/guided-questions.js.map +1 -1
  80. package/dist/app/chat/agentkit-chat/history.js +1 -1
  81. package/dist/app/chat/agentkit-chat/history.js.map +1 -1
  82. package/dist/app/chat/agentkit-chat/index.d.ts +1 -1
  83. package/dist/app/chat/agentkit-chat/index.d.ts.map +1 -1
  84. package/dist/app/chat/agentkit-chat/index.js +1 -1
  85. package/dist/app/chat/agentkit-chat/index.js.map +1 -1
  86. package/dist/app/chat/agentkit-chat/labels.d.ts +5 -0
  87. package/dist/app/chat/agentkit-chat/labels.d.ts.map +1 -0
  88. package/dist/app/chat/agentkit-chat/labels.js +245 -0
  89. package/dist/app/chat/agentkit-chat/labels.js.map +1 -0
  90. package/dist/app/chat/agentkit-chat/questions.d.ts +1 -1
  91. package/dist/app/chat/agentkit-chat/questions.d.ts.map +1 -1
  92. package/dist/app/chat/agentkit-chat/questions.js +1 -1
  93. package/dist/app/chat/agentkit-chat/questions.js.map +1 -1
  94. package/dist/app/chat/agentkit-chat/root.d.ts.map +1 -1
  95. package/dist/app/chat/agentkit-chat/root.js +5 -64
  96. package/dist/app/chat/agentkit-chat/root.js.map +1 -1
  97. package/dist/app/chat/agentkit-chat/work-step-labels.d.ts +2 -0
  98. package/dist/app/chat/agentkit-chat/work-step-labels.d.ts.map +1 -1
  99. package/dist/app/chat/agentkit-chat/work-step-labels.js +31 -0
  100. package/dist/app/chat/agentkit-chat/work-step-labels.js.map +1 -1
  101. package/dist/app/chat/chat/markdown-renderer.d.ts +2 -12
  102. package/dist/app/chat/chat/markdown-renderer.d.ts.map +1 -1
  103. package/dist/app/chat/chat/markdown-renderer.js +2 -41
  104. package/dist/app/chat/chat/markdown-renderer.js.map +1 -1
  105. package/dist/app/chat/chat/tool-call-display.d.ts.map +1 -1
  106. package/dist/app/chat/chat/tool-call-display.js +2 -2
  107. package/dist/app/chat/chat/tool-call-display.js.map +1 -1
  108. package/dist/app/chat/conversation/AgentConversation.d.ts.map +1 -1
  109. package/dist/app/chat/conversation/AgentConversation.js +2 -37
  110. package/dist/app/chat/conversation/AgentConversation.js.map +1 -1
  111. package/dist/app/chat/tool-cells/BashCell.d.ts +3 -1
  112. package/dist/app/chat/tool-cells/BashCell.d.ts.map +1 -1
  113. package/dist/app/chat/tool-cells/BashCell.js +4 -40
  114. package/dist/app/chat/tool-cells/BashCell.js.map +1 -1
  115. package/dist/app/chat/tool-cells/EditCell.d.ts.map +1 -1
  116. package/dist/app/chat/tool-cells/EditCell.js +5 -108
  117. package/dist/app/chat/tool-cells/EditCell.js.map +1 -1
  118. package/dist/app/chat/tool-cells/FilesChangedSummary.d.ts.map +1 -1
  119. package/dist/app/chat/tool-cells/FilesChangedSummary.js +23 -81
  120. package/dist/app/chat/tool-cells/FilesChangedSummary.js.map +1 -1
  121. package/dist/app/chat/tool-cells/WriteCell.d.ts.map +1 -1
  122. package/dist/app/chat/tool-cells/WriteCell.js +5 -24
  123. package/dist/app/chat/tool-cells/WriteCell.js.map +1 -1
  124. package/dist/app/code-highlighter.d.ts +11 -0
  125. package/dist/app/code-highlighter.d.ts.map +1 -0
  126. package/dist/app/code-highlighter.js +122 -0
  127. package/dist/app/code-highlighter.js.map +1 -0
  128. package/dist/app/context-xray/ThreadContextRing.js +3 -3
  129. package/dist/app/context-xray/ThreadContextRing.js.map +1 -1
  130. package/dist/app/i18n/catalogs/ar-SA.d.ts.map +1 -1
  131. package/dist/app/i18n/catalogs/ar-SA.js +22 -0
  132. package/dist/app/i18n/catalogs/ar-SA.js.map +1 -1
  133. package/dist/app/i18n/catalogs/de-DE.d.ts.map +1 -1
  134. package/dist/app/i18n/catalogs/de-DE.js +22 -0
  135. package/dist/app/i18n/catalogs/de-DE.js.map +1 -1
  136. package/dist/app/i18n/catalogs/en-US.d.ts +22 -0
  137. package/dist/app/i18n/catalogs/en-US.d.ts.map +1 -1
  138. package/dist/app/i18n/catalogs/en-US.js +22 -0
  139. package/dist/app/i18n/catalogs/en-US.js.map +1 -1
  140. package/dist/app/i18n/catalogs/es-ES.d.ts.map +1 -1
  141. package/dist/app/i18n/catalogs/es-ES.js +22 -0
  142. package/dist/app/i18n/catalogs/es-ES.js.map +1 -1
  143. package/dist/app/i18n/catalogs/fr-FR.d.ts.map +1 -1
  144. package/dist/app/i18n/catalogs/fr-FR.js +22 -0
  145. package/dist/app/i18n/catalogs/fr-FR.js.map +1 -1
  146. package/dist/app/i18n/catalogs/hi-IN.d.ts.map +1 -1
  147. package/dist/app/i18n/catalogs/hi-IN.js +22 -0
  148. package/dist/app/i18n/catalogs/hi-IN.js.map +1 -1
  149. package/dist/app/i18n/catalogs/ja-JP.d.ts.map +1 -1
  150. package/dist/app/i18n/catalogs/ja-JP.js +22 -0
  151. package/dist/app/i18n/catalogs/ja-JP.js.map +1 -1
  152. package/dist/app/i18n/catalogs/ko-KR.d.ts.map +1 -1
  153. package/dist/app/i18n/catalogs/ko-KR.js +22 -0
  154. package/dist/app/i18n/catalogs/ko-KR.js.map +1 -1
  155. package/dist/app/i18n/catalogs/pt-BR.d.ts.map +1 -1
  156. package/dist/app/i18n/catalogs/pt-BR.js +22 -0
  157. package/dist/app/i18n/catalogs/pt-BR.js.map +1 -1
  158. package/dist/app/i18n/catalogs/zh-CN.d.ts.map +1 -1
  159. package/dist/app/i18n/catalogs/zh-CN.js +22 -0
  160. package/dist/app/i18n/catalogs/zh-CN.js.map +1 -1
  161. package/dist/app/i18n/catalogs/zh-TW.d.ts.map +1 -1
  162. package/dist/app/i18n/catalogs/zh-TW.js +22 -0
  163. package/dist/app/i18n/catalogs/zh-TW.js.map +1 -1
  164. package/dist/app/onboarding/first-run-first-paint.d.ts +10 -0
  165. package/dist/app/onboarding/first-run-first-paint.d.ts.map +1 -0
  166. package/dist/app/onboarding/first-run-first-paint.js +22 -0
  167. package/dist/app/onboarding/first-run-first-paint.js.map +1 -0
  168. package/dist/app/onboarding/first-run-startup-gate.d.ts +3 -1
  169. package/dist/app/onboarding/first-run-startup-gate.d.ts.map +1 -1
  170. package/dist/app/onboarding/first-run-startup-gate.js +30 -6
  171. package/dist/app/onboarding/first-run-startup-gate.js.map +1 -1
  172. package/dist/app/providers/AppProviders.d.ts.map +1 -1
  173. package/dist/app/providers/AppProviders.js +9 -2
  174. package/dist/app/providers/AppProviders.js.map +1 -1
  175. package/dist/app/providers/BuilderSignupActivation.d.ts +2 -1
  176. package/dist/app/providers/BuilderSignupActivation.d.ts.map +1 -1
  177. package/dist/app/providers/BuilderSignupActivation.js +6 -3
  178. package/dist/app/providers/BuilderSignupActivation.js.map +1 -1
  179. package/dist/app/shared/AppShellSkeleton.d.ts.map +1 -1
  180. package/dist/app/shared/AppShellSkeleton.js +11 -1
  181. package/dist/app/shared/AppShellSkeleton.js.map +1 -1
  182. package/dist/app/styles/agent-native.css +2 -2
  183. package/dist/app/styles/tokens/agent-kit.css +20 -3
  184. package/dist/composer/AgentSuggestionBar.d.ts.map +1 -1
  185. package/dist/composer/AgentSuggestionBar.js +2 -2
  186. package/dist/composer/AgentSuggestionBar.js.map +1 -1
  187. package/dist/composer/ComposerContextMenu.js +4 -4
  188. package/dist/composer/ComposerContextMenu.js.map +1 -1
  189. package/dist/composer/ComposerContextPicker.d.ts.map +1 -1
  190. package/dist/composer/ComposerContextPicker.js +2 -2
  191. package/dist/composer/ComposerContextPicker.js.map +1 -1
  192. package/dist/composer/ComposerContextPickerDialog.d.ts.map +1 -1
  193. package/dist/composer/ComposerContextPickerDialog.js +2 -2
  194. package/dist/composer/ComposerContextPickerDialog.js.map +1 -1
  195. package/dist/composer/ComposerModePicker.d.ts.map +1 -1
  196. package/dist/composer/ComposerModePicker.js +2 -1
  197. package/dist/composer/ComposerModePicker.js.map +1 -1
  198. package/dist/composer/ComposerPlusMenu.js +1 -1
  199. package/dist/composer/ComposerPlusMenu.js.map +1 -1
  200. package/dist/composer/MentionChip.js +1 -1
  201. package/dist/composer/MentionChip.js.map +1 -1
  202. package/dist/composer/MentionPopover.d.ts +3 -0
  203. package/dist/composer/MentionPopover.d.ts.map +1 -1
  204. package/dist/composer/MentionPopover.js +34 -15
  205. package/dist/composer/MentionPopover.js.map +1 -1
  206. package/dist/composer/MessageQueueDrawer.d.ts.map +1 -1
  207. package/dist/composer/MessageQueueDrawer.js +14 -9
  208. package/dist/composer/MessageQueueDrawer.js.map +1 -1
  209. package/dist/composer/PastedTextChip.d.ts.map +1 -1
  210. package/dist/composer/PastedTextChip.js +14 -18
  211. package/dist/composer/PastedTextChip.js.map +1 -1
  212. package/dist/composer/PromptBar.js +1 -1
  213. package/dist/composer/PromptBar.js.map +1 -1
  214. package/dist/composer/PromptComposer.d.ts.map +1 -1
  215. package/dist/composer/PromptComposer.js +11 -9
  216. package/dist/composer/PromptComposer.js.map +1 -1
  217. package/dist/composer/RealtimeVoiceMode.js +2 -2
  218. package/dist/composer/RealtimeVoiceMode.js.map +1 -1
  219. package/dist/composer/TiptapComposer.d.ts.map +1 -1
  220. package/dist/composer/TiptapComposer.js +52 -89
  221. package/dist/composer/TiptapComposer.js.map +1 -1
  222. package/dist/composer/VoiceButton.d.ts +3 -1
  223. package/dist/composer/VoiceButton.d.ts.map +1 -1
  224. package/dist/composer/VoiceButton.js +10 -8
  225. package/dist/composer/VoiceButton.js.map +1 -1
  226. package/dist/composer/composer-notice.js +3 -3
  227. package/dist/composer/composer-notice.js.map +1 -1
  228. package/dist/composer/extensions/FileReference.js +1 -1
  229. package/dist/composer/extensions/FileReference.js.map +1 -1
  230. package/dist/composer/extensions/SkillReference.js +1 -1
  231. package/dist/composer/extensions/SkillReference.js.map +1 -1
  232. package/dist/composer/popover-surface.d.ts +1 -1
  233. package/dist/composer/popover-surface.d.ts.map +1 -1
  234. package/dist/composer/popover-surface.js +1 -1
  235. package/dist/composer/popover-surface.js.map +1 -1
  236. package/dist/context-ui/ContextUsageRing.d.ts +1 -45
  237. package/dist/context-ui/ContextUsageRing.d.ts.map +1 -1
  238. package/dist/context-ui/ContextUsageRing.js +2 -87
  239. package/dist/context-ui/ContextUsageRing.js.map +1 -1
  240. package/dist/context-ui/index.d.ts +2 -2
  241. package/dist/context-ui/index.d.ts.map +1 -1
  242. package/dist/context-ui/index.js +2 -2
  243. package/dist/context-ui/index.js.map +1 -1
  244. package/package.json +4 -4
  245. package/src/app/agentkit/react/approval-card.tsx +14 -2
  246. package/src/app/agentkit/react/code-block.spec.tsx +154 -0
  247. package/src/app/agentkit/react/code-block.tsx +317 -0
  248. package/src/app/agentkit/react/components.interaction.spec.tsx +7 -0
  249. package/src/app/agentkit/react/components.papercuts.spec.tsx +143 -2
  250. package/src/app/agentkit/react/components.spec.tsx +40 -47
  251. package/src/app/agentkit/react/components.tsx +1533 -413
  252. package/src/app/agentkit/react/composer-context.spec.tsx +35 -0
  253. package/src/app/agentkit/react/context-usage.tsx +353 -0
  254. package/src/app/agentkit/react/context.tsx +93 -1
  255. package/src/app/agentkit/react/disclosure-content.ts +42 -0
  256. package/src/app/agentkit/react/disclosures.spec.tsx +62 -4
  257. package/src/app/agentkit/react/duration.ts +22 -0
  258. package/src/app/agentkit/react/file-change.spec.tsx +124 -0
  259. package/src/app/agentkit/react/file-change.tsx +228 -0
  260. package/src/app/agentkit/react/file-diff.ts +110 -0
  261. package/src/app/agentkit/react/index.ts +7 -0
  262. package/src/app/agentkit/react/lifecycle.spec.tsx +565 -20
  263. package/src/app/agentkit/react/markdown.spec.tsx +18 -8
  264. package/src/app/agentkit/react/message-actions.spec.tsx +55 -1
  265. package/src/app/agentkit/react/notices.spec.tsx +4 -4
  266. package/src/app/agentkit/react/optimistic-send.spec.tsx +43 -0
  267. package/src/app/agentkit/react/question-card.spec.tsx +276 -0
  268. package/src/app/agentkit/react/question-card.tsx +533 -0
  269. package/src/app/agentkit/react/root.tsx +4 -0
  270. package/src/app/agentkit/react/roving-focus.spec.tsx +114 -0
  271. package/src/app/agentkit/react/roving-focus.ts +82 -0
  272. package/src/app/agentkit/react/stack-trace.spec.tsx +177 -0
  273. package/src/app/agentkit/react/stack-trace.tsx +281 -0
  274. package/src/app/agentkit/react/stop-button.spec.tsx +40 -0
  275. package/src/app/agentkit/react/stop-button.tsx +22 -5
  276. package/src/app/agentkit/react/styles.css +1306 -395
  277. package/src/app/agentkit/react/subagent-step.spec.tsx +554 -0
  278. package/src/app/agentkit/react/terminal.spec.tsx +228 -0
  279. package/src/app/agentkit/react/terminal.tsx +228 -0
  280. package/src/app/agentkit/react/trace.spec.tsx +120 -0
  281. package/src/app/agentkit/react/trace.tsx +239 -0
  282. package/src/app/blocks/library/HighlightedCode.tsx +14 -126
  283. package/src/app/chat/AgentKitAssistantChat.spec.tsx +28 -12
  284. package/src/app/chat/AgentKitAssistantChat.tsx +27 -253
  285. package/src/app/chat/agentkit-chat/approval-card.spec.tsx +1 -0
  286. package/src/app/chat/agentkit-chat/guided-questions.flow.spec.tsx +381 -0
  287. package/src/app/chat/agentkit-chat/guided-questions.tsx +236 -3
  288. package/src/app/chat/agentkit-chat/history.tsx +1 -1
  289. package/src/app/chat/agentkit-chat/index.ts +2 -0
  290. package/src/app/chat/agentkit-chat/labels.ts +259 -0
  291. package/src/app/chat/agentkit-chat/questions.ts +2 -0
  292. package/src/app/chat/agentkit-chat/root.spec.tsx +18 -0
  293. package/src/app/chat/agentkit-chat/root.tsx +5 -64
  294. package/src/app/chat/agentkit-chat/work-step-labels.ts +42 -0
  295. package/src/app/chat/chat/markdown-renderer.tsx +2 -59
  296. package/src/app/chat/chat/tool-call-display.spec.tsx +26 -14
  297. package/src/app/chat/chat/tool-call-display.tsx +2 -1
  298. package/src/app/chat/conversation/AgentConversation.tsx +2 -50
  299. package/src/app/chat/tool-cells/BashCell.tsx +14 -136
  300. package/src/app/chat/tool-cells/EditCell.tsx +11 -248
  301. package/src/app/chat/tool-cells/FilesChangedSummary.spec.tsx +62 -5
  302. package/src/app/chat/tool-cells/FilesChangedSummary.tsx +31 -162
  303. package/src/app/chat/tool-cells/WriteCell.tsx +11 -121
  304. package/src/app/code-highlighter.ts +131 -0
  305. package/src/app/context-xray/ThreadContextRing.tsx +7 -7
  306. package/src/app/i18n/catalogs/ar-SA.ts +22 -0
  307. package/src/app/i18n/catalogs/de-DE.ts +22 -0
  308. package/src/app/i18n/catalogs/en-US.ts +22 -0
  309. package/src/app/i18n/catalogs/es-ES.ts +22 -0
  310. package/src/app/i18n/catalogs/fr-FR.ts +22 -0
  311. package/src/app/i18n/catalogs/hi-IN.ts +22 -0
  312. package/src/app/i18n/catalogs/ja-JP.ts +22 -0
  313. package/src/app/i18n/catalogs/ko-KR.ts +22 -0
  314. package/src/app/i18n/catalogs/pt-BR.ts +22 -0
  315. package/src/app/i18n/catalogs/zh-CN.ts +22 -0
  316. package/src/app/i18n/catalogs/zh-TW.ts +22 -0
  317. package/src/app/onboarding/first-run-first-paint.spec.ts +39 -0
  318. package/src/app/onboarding/first-run-first-paint.ts +24 -0
  319. package/src/app/onboarding/first-run-startup-gate.spec.tsx +125 -13
  320. package/src/app/onboarding/first-run-startup-gate.tsx +48 -5
  321. package/src/app/providers/AppProviders.tsx +18 -0
  322. package/src/app/providers/BuilderSignupActivation.tsx +8 -2
  323. package/src/app/shared/AppShellSkeleton.spec.tsx +60 -1
  324. package/src/app/shared/AppShellSkeleton.tsx +31 -1
  325. package/src/app/styles/agent-native.css +2 -2
  326. package/src/app/styles/agent-native.spec.ts +2 -2
  327. package/src/app/styles/tokens/agent-kit.css +20 -3
  328. package/src/composer/AgentSuggestionBar.spec.tsx +3 -1
  329. package/src/composer/AgentSuggestionBar.tsx +5 -2
  330. package/src/composer/ComposerContextMenu.tsx +4 -4
  331. package/src/composer/ComposerContextPicker.tsx +8 -2
  332. package/src/composer/ComposerContextPickerDialog.tsx +5 -2
  333. package/src/composer/ComposerModePicker.tsx +2 -1
  334. package/src/composer/ComposerPlusMenu.tsx +1 -1
  335. package/src/composer/MentionChip.tsx +1 -1
  336. package/src/composer/MentionPopover.spec.tsx +108 -2
  337. package/src/composer/MentionPopover.tsx +93 -17
  338. package/src/composer/MessageQueueDrawer.spec.tsx +5 -5
  339. package/src/composer/MessageQueueDrawer.tsx +19 -12
  340. package/src/composer/PastedTextChip.spec.tsx +36 -0
  341. package/src/composer/PastedTextChip.tsx +52 -58
  342. package/src/composer/PromptBar.tsx +1 -1
  343. package/src/composer/PromptComposer.context.spec.tsx +2 -2
  344. package/src/composer/PromptComposer.submission.spec.tsx +27 -0
  345. package/src/composer/PromptComposer.tsx +17 -9
  346. package/src/composer/RealtimeVoiceMode.tsx +2 -2
  347. package/src/composer/TiptapComposer.model-picker.spec.tsx +23 -82
  348. package/src/composer/TiptapComposer.tsx +68 -145
  349. package/src/composer/VoiceButton.tsx +12 -7
  350. package/src/composer/composer-notice.tsx +3 -3
  351. package/src/composer/extensions/FileReference.tsx +1 -1
  352. package/src/composer/extensions/SkillReference.tsx +1 -1
  353. package/src/composer/popover-surface.ts +1 -1
  354. package/src/context-ui/ContextUsageRing.spec.tsx +33 -8
  355. package/src/context-ui/ContextUsageRing.tsx +13 -348
  356. package/src/context-ui/index.ts +7 -1
  357. package/dist/composer/ModelPickerParts.d.ts +0 -20
  358. package/dist/composer/ModelPickerParts.d.ts.map +0 -1
  359. package/dist/composer/ModelPickerParts.js +0 -77
  360. package/dist/composer/ModelPickerParts.js.map +0 -1
  361. package/src/composer/ModelPickerParts.tsx +0 -188
@@ -12,6 +12,7 @@ import React, {
12
12
  useState,
13
13
  useEffect,
14
14
  useRef,
15
+ useId,
15
16
  useImperativeHandle,
16
17
  forwardRef,
17
18
  } from "react";
@@ -66,6 +67,9 @@ interface MentionPopoverProps {
66
67
  * otherwise jump to the top.
67
68
  */
68
69
  keepSectionOrder?: boolean;
70
+ /** The editor keeps focus and points here with aria-controls and aria-activedescendant. */
71
+ listboxId?: string;
72
+ onActiveOptionChange?: (optionId: string | undefined) => void;
69
73
  }
70
74
 
71
75
  const iconProps = { size: 16, className: "shrink-0 text-muted-foreground" };
@@ -149,7 +153,10 @@ function LoadingSkeleton() {
149
153
 
150
154
  function LoadingSkeletonRow() {
151
155
  return (
152
- <div className="flex items-center gap-2 rounded px-2 py-1.5">
156
+ <div
157
+ aria-hidden="true"
158
+ className="flex items-center gap-2 rounded px-2 py-1.5"
159
+ >
153
160
  <div className="h-3.5 w-3.5 rounded bg-muted animate-pulse" />
154
161
  <div className="h-3 w-24 rounded bg-muted animate-pulse" />
155
162
  </div>
@@ -200,7 +207,13 @@ export const MentionPopover = forwardRef<
200
207
  onClose,
201
208
  density = "default",
202
209
  keepSectionOrder = false,
210
+ listboxId: listboxIdProp,
211
+ onActiveOptionChange,
203
212
  } = props;
213
+ const generatedListboxId = useId();
214
+ const listboxId = listboxIdProp ?? generatedListboxId;
215
+ const optionId = (index: number) =>
216
+ index === -1 ? `${listboxId}-retry` : `${listboxId}-option-${index}`;
204
217
  const stacked = density === "stacked";
205
218
 
206
219
  const [selectedIndex, setSelectedIndex] = useState(0);
@@ -226,7 +239,8 @@ export const MentionPopover = forwardRef<
226
239
  defaultValue: "Other",
227
240
  });
228
241
  default:
229
- return section;
242
+ // A provider label is usually an app catalog key; a plain one comes back as itself.
243
+ return t(section, { defaultValue: section });
230
244
  }
231
245
  };
232
246
 
@@ -305,6 +319,18 @@ export const MentionPopover = forwardRef<
305
319
  }
306
320
  }, [selectedIndex]);
307
321
 
322
+ const activeOptionId =
323
+ position && (selectedIndex === -1 ? retryable : selectedIndex < itemCount)
324
+ ? optionId(selectedIndex)
325
+ : undefined;
326
+ useEffect(() => {
327
+ onActiveOptionChange?.(activeOptionId);
328
+ }, [activeOptionId, onActiveOptionChange]);
329
+ useEffect(
330
+ () => () => onActiveOptionChange?.(undefined),
331
+ [onActiveOptionChange],
332
+ );
333
+
308
334
  useImperativeHandle(ref, () => ({
309
335
  moveUp: () => {
310
336
  setSelectedIndex((prev) =>
@@ -367,7 +393,7 @@ export const MentionPopover = forwardRef<
367
393
  event.stopPropagation();
368
394
  onClose();
369
395
  }}
370
- className={`overflow-y-auto rounded-lg border-border/80 p-1 shadow-2xl ${COMPOSER_POPOVER_SURFACE_CLASS}`}
396
+ className={`overflow-y-auto p-1 ${COMPOSER_POPOVER_SURFACE_CLASS}`}
371
397
  style={{
372
398
  width: Math.min(
373
399
  position.width ?? 640,
@@ -379,14 +405,16 @@ export const MentionPopover = forwardRef<
379
405
  {type === "@" && error && (
380
406
  <div
381
407
  role="alert"
382
- className="flex items-center justify-between gap-2 px-3 py-2 text-xs text-destructive"
408
+ className="flex items-center justify-between gap-2 px-3 py-2 text-xs agent-kit-tone-warning"
383
409
  >
384
410
  <span>{error}</span>
385
411
  {onRetry && (
386
412
  <button
387
413
  type="button"
414
+ id={optionId(-1)}
415
+ tabIndex={-1}
388
416
  data-mention-index={-1}
389
- className={`shrink-0 rounded px-1.5 py-0.5 font-medium text-foreground ${
417
+ className={`shrink-0 rounded-[var(--agent-kit-radius-xs,0.25rem)] px-1.5 py-0.5 font-medium text-foreground ${
390
418
  selectedIndex === -1 ? "bg-muted" : "hover:bg-accent"
391
419
  }`}
392
420
  onMouseEnter={() => setSelectedIndex(-1)}
@@ -424,18 +452,35 @@ export const MentionPopover = forwardRef<
424
452
  )}
425
453
  </div>
426
454
  ) : (
427
- <div>
455
+ <div
456
+ role="listbox"
457
+ id={listboxId}
458
+ aria-label={
459
+ type === "@"
460
+ ? t("agentChat.composer.addContext", {
461
+ defaultValue: "Add context",
462
+ })
463
+ : t("agentChat.mentions.commands", {
464
+ defaultValue: "Commands",
465
+ })
466
+ }
467
+ >
428
468
  {isLoading && <LoadingSkeletonRow />}
429
469
  {type === "@"
430
470
  ? (() => {
431
471
  let flatIndex = 0;
432
- return groupedMentions.map((group) => (
433
- <div key={group.section}>
472
+ return groupedMentions.map((group, groupIndex) => (
473
+ <div
474
+ key={group.section}
475
+ role="group"
476
+ aria-labelledby={`${listboxId}-group-${groupIndex}`}
477
+ >
434
478
  <div
479
+ id={`${listboxId}-group-${groupIndex}`}
435
480
  className={
436
481
  stacked
437
- ? "px-2.5 pb-1 pt-2 agent-kit-caption-copy font-medium uppercase tracking-wide text-muted-foreground/70"
438
- : "px-3 pb-2 pt-2 text-xs font-medium uppercase tracking-wide text-muted-foreground/70"
482
+ ? "px-2.5 pb-1 pt-2 agent-kit-caption-copy font-medium uppercase tracking-wide text-muted-foreground"
483
+ : "px-3 pb-2 pt-2 text-xs font-medium uppercase tracking-wide text-muted-foreground"
439
484
  }
440
485
  >
441
486
  {sectionLabel(group.section)}
@@ -445,9 +490,14 @@ export const MentionPopover = forwardRef<
445
490
  return (
446
491
  <button
447
492
  key={item.id}
493
+ type="button"
494
+ role="option"
495
+ id={optionId(idx)}
496
+ aria-selected={idx === selectedIndex}
497
+ tabIndex={-1}
448
498
  data-mention-index={idx}
449
499
  data-mention-density={density}
450
- className={`flex min-h-8 w-full min-w-0 cursor-pointer items-center gap-2 rounded-md px-2 py-1 text-start ${
500
+ className={`flex min-h-8 w-full min-w-0 cursor-pointer items-center gap-2 rounded-[var(--agent-kit-radius-xs,0.25rem)] px-2 py-1 text-start ${
451
501
  idx === selectedIndex
452
502
  ? "bg-muted text-foreground"
453
503
  : "hover:bg-accent/50"
@@ -498,8 +548,14 @@ export const MentionPopover = forwardRef<
498
548
  return (
499
549
  <>
500
550
  {commands.length > 0 && (
501
- <div>
502
- <div className="px-2 pb-1 pt-1 agent-kit-micro-copy font-medium uppercase tracking-wide text-muted-foreground/70">
551
+ <div
552
+ role="group"
553
+ aria-labelledby={`${listboxId}-group-commands`}
554
+ >
555
+ <div
556
+ id={`${listboxId}-group-commands`}
557
+ className="px-2 pb-1 pt-1 agent-kit-micro-copy font-medium uppercase tracking-wide text-muted-foreground"
558
+ >
503
559
  {t("agentChat.mentions.commands", {
504
560
  defaultValue: "Commands",
505
561
  })}
@@ -509,8 +565,13 @@ export const MentionPopover = forwardRef<
509
565
  return (
510
566
  <button
511
567
  key={cmd.name}
568
+ type="button"
569
+ role="option"
570
+ id={optionId(i)}
571
+ aria-selected={i === selectedIndex}
572
+ tabIndex={-1}
512
573
  data-mention-index={i}
513
- className={`flex min-h-8 w-full min-w-0 cursor-pointer items-center gap-2 rounded-md px-2 py-1 text-start ${
574
+ className={`flex min-h-8 w-full min-w-0 cursor-pointer items-center gap-2 rounded-[var(--agent-kit-radius-xs,0.25rem)] px-2 py-1 text-start ${
514
575
  i === selectedIndex
515
576
  ? "bg-muted text-foreground"
516
577
  : "hover:bg-accent/50"
@@ -536,9 +597,19 @@ export const MentionPopover = forwardRef<
536
597
  </div>
537
598
  )}
538
599
  {skills.length > 0 && (
539
- <div>
600
+ <div
601
+ role={commands.length > 0 ? "group" : undefined}
602
+ aria-labelledby={
603
+ commands.length > 0
604
+ ? `${listboxId}-group-skills`
605
+ : undefined
606
+ }
607
+ >
540
608
  {commands.length > 0 && (
541
- <div className="px-2 pb-1 pt-1.5 agent-kit-micro-copy font-medium uppercase tracking-wide text-muted-foreground/70">
609
+ <div
610
+ id={`${listboxId}-group-skills`}
611
+ className="px-2 pb-1 pt-1.5 agent-kit-micro-copy font-medium uppercase tracking-wide text-muted-foreground"
612
+ >
542
613
  {t("agentChat.mentions.skills", {
543
614
  defaultValue: "Skills",
544
615
  })}
@@ -553,8 +624,13 @@ export const MentionPopover = forwardRef<
553
624
  description={skill.description}
554
625
  >
555
626
  <button
627
+ type="button"
628
+ role="option"
629
+ id={optionId(i)}
630
+ aria-selected={i === selectedIndex}
631
+ tabIndex={-1}
556
632
  data-mention-index={i}
557
- className={`flex min-h-8 w-full min-w-0 cursor-pointer items-center gap-2 rounded-md px-2 py-1 text-start ${
633
+ className={`flex min-h-8 w-full min-w-0 cursor-pointer items-center gap-2 rounded-[var(--agent-kit-radius-xs,0.25rem)] px-2 py-1 text-start ${
558
634
  i === selectedIndex
559
635
  ? "bg-muted text-foreground"
560
636
  : "hover:bg-accent/50"
@@ -367,7 +367,7 @@ describe("MessageQueueDrawer", () => {
367
367
  ),
368
368
  ).toBeNull();
369
369
  expect(drawer?.style.getPropertyValue("--agent-message-queue-height")).toBe(
370
- "min(44px, 10rem)",
370
+ "min(48px, 10rem)",
371
371
  );
372
372
 
373
373
  act(() => {
@@ -439,7 +439,7 @@ describe("MessageQueueDrawer", () => {
439
439
  ),
440
440
  ).toBe(true);
441
441
  });
442
- it("keeps rows a fixed 36px with concentric corners from the composer radius", () => {
442
+ it("keeps rows a fixed 32px with concentric corners from the composer radius", () => {
443
443
  act(() => {
444
444
  root.render(
445
445
  <MessageQueueDrawer
@@ -458,13 +458,13 @@ describe("MessageQueueDrawer", () => {
458
458
  "var(--agentkit-composer-radius, var(--radius-xl, 0.75rem))",
459
459
  );
460
460
  expect(drawer.style.getPropertyValue("--agent-message-queue-inset")).toBe(
461
- "0.25rem",
461
+ "0.5rem",
462
462
  );
463
463
  expect(drawer.className).toContain(
464
464
  "rounded-t-[var(--agent-message-queue-radius)]",
465
465
  );
466
466
  expect(drawer.className).toContain("p-[var(--agent-message-queue-inset)]");
467
- // 32 + 32 + 64 rows plus the 4px inset above and below.
467
+ // 32 + 32 + 64 rows, two 4px gaps and the 8px inset above and below.
468
468
  expect(drawer.style.getPropertyValue("--agent-message-queue-height")).toBe(
469
469
  "min(152px, 10rem)",
470
470
  );
@@ -478,7 +478,7 @@ describe("MessageQueueDrawer", () => {
478
478
  // Rows fade in; a slide would fight the drawer's height transition.
479
479
  expect(row.className).not.toContain("slide-in");
480
480
  }
481
- expect(rows[0]!.className).toContain("h-9");
481
+ expect(rows[0]!.className).toContain("h-8");
482
482
  expect(rows[2]!.className).toContain("h-16");
483
483
  expect(container.querySelector("ul")?.className).toContain(
484
484
  "overflow-y-hidden",
@@ -30,6 +30,7 @@ import {
30
30
  } from "../ui/tooltip.js";
31
31
  import { cn } from "../utils.js";
32
32
  import { ComposerNotice } from "./composer-notice.js";
33
+ import { COMPOSER_POPOVER_SURFACE_CLASS } from "./popover-surface.js";
33
34
  import { useComposerRuntimeAdapters } from "./runtime-adapters.js";
34
35
 
35
36
  export interface MessageQueueItem {
@@ -102,12 +103,13 @@ export interface MessageQueueDrawerProps {
102
103
  }
103
104
 
104
105
  // Row heights and the gap between rows are fixed so the recessed drawer can
105
- // animate to an exact block size; change them together with the h-9 / h-16
106
- // row classes and the list's gap-1.
107
- const QUEUE_ROW_PX = 36;
106
+ // animate to an exact block size; change them together with the h-8 / h-16
107
+ // row classes and the list's gap-1. The 8px inset keeps the 8px row radius
108
+ // concentric with the composer's 16px corner.
109
+ const QUEUE_ROW_PX = 32;
108
110
  const QUEUE_IMAGE_ROW_PX = 64;
109
111
  const QUEUE_ROW_GAP_PX = 4;
110
- const QUEUE_INSET_PX = 4;
112
+ const QUEUE_INSET_PX = 8;
111
113
  const RECESSED_QUEUE_MAX_PX = 160;
112
114
 
113
115
  function queueRowHeight(item: MessageQueueItem): number {
@@ -191,6 +193,9 @@ export function MessageQueueDrawer({
191
193
  const dragToReorder =
192
194
  labels.dragToReorder ??
193
195
  t("agentChat.queue.dragToReorder", { defaultValue: "Drag to reorder" });
196
+ const attachedImageLabel = t("agentChat.queue.attachedImage", {
197
+ defaultValue: "Attached image",
198
+ });
194
199
  const moveUpLabel =
195
200
  labels.moveUp ?? t("agentChat.queue.moveUp", { defaultValue: "Move up" });
196
201
  const moveDownLabel =
@@ -480,7 +485,7 @@ export function MessageQueueDrawer({
480
485
  "p-[var(--agent-message-queue-inset)] data-[empty=true]:p-0",
481
486
  recessed
482
487
  ? "rounded-t-[var(--agent-message-queue-radius)] rounded-b-none"
483
- : "w-full overflow-hidden rounded-[var(--agent-message-queue-radius)] border border-border/80 bg-background shadow-sm animate-in fade-in-0 duration-200 motion-reduce:animate-none",
488
+ : "w-full overflow-hidden rounded-[var(--agent-message-queue-radius)] border border-border bg-background shadow-sm animate-in fade-in-0 duration-200 motion-reduce:animate-none",
484
489
  className,
485
490
  )}
486
491
  >
@@ -514,7 +519,7 @@ export function MessageQueueDrawer({
514
519
  "group relative flex min-h-0 min-w-0 shrink-0 gap-1 rounded-[calc(var(--agent-message-queue-radius)-var(--agent-message-queue-inset))] px-1 text-sm leading-5 animate-in fade-in-0 duration-150 motion-reduce:animate-none",
515
520
  hasImages
516
521
  ? "h-16 items-start pt-1 pb-0"
517
- : "h-9 items-center py-0",
522
+ : "h-8 items-center py-0",
518
523
  dragging
519
524
  ? "z-10 bg-accent shadow-sm"
520
525
  : "transition-[transform,background-color] duration-150 ease-out hover:bg-accent/50 motion-reduce:transition-none",
@@ -547,7 +552,7 @@ export function MessageQueueDrawer({
547
552
  onPointerUp={() => endDrag(true)}
548
553
  onPointerCancel={() => endDrag(false)}
549
554
  className={cn(
550
- "absolute inset-0 flex touch-none items-center justify-center rounded-md text-muted-foreground opacity-0 transition-opacity duration-150 hover:text-foreground focus-visible:opacity-100 focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-inset focus-visible:ring-ring group-hover:opacity-100 group-focus-within:opacity-100 group-data-[dragging=true]:opacity-100 disabled:hidden motion-reduce:transition-none",
555
+ "absolute inset-0 flex touch-none items-center justify-center rounded-[var(--agent-kit-radius-sm,0.5rem)] text-muted-foreground opacity-0 transition-opacity duration-150 hover:text-foreground focus-visible:opacity-100 focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-inset focus-visible:ring-ring group-hover:opacity-100 group-focus-within:opacity-100 group-data-[dragging=true]:opacity-100 disabled:hidden motion-reduce:transition-none",
551
556
  dragging ? "cursor-grabbing" : "cursor-grab",
552
557
  )}
553
558
  >
@@ -568,9 +573,10 @@ export function MessageQueueDrawer({
568
573
  >
569
574
  <div
570
575
  data-agent-message-queue-text="true"
571
- className="flex h-6 min-w-0 items-center text-sm leading-5 text-foreground"
576
+ className="flex min-h-6 min-w-0 items-center text-sm leading-5 text-foreground"
572
577
  >
573
- <span className="min-w-0 truncate">
578
+ {/* Keyboard focus has no hover, so focus expands the message. */}
579
+ <span className="min-w-0 truncate group-focus-within:whitespace-normal group-focus-within:[overflow-wrap:anywhere]">
574
580
  {renderText ? renderText(item) : item.text}
575
581
  </span>
576
582
  </div>
@@ -583,8 +589,8 @@ export function MessageQueueDrawer({
583
589
  <img
584
590
  key={`${item.id}-image-${imageIndex}`}
585
591
  src={src}
586
- alt=""
587
- className="size-8 shrink-0 rounded-md border border-border/60 object-cover"
592
+ alt={attachedImageLabel}
593
+ className="size-8 shrink-0 rounded-[var(--agent-kit-radius-sm,0.5rem)] border border-border object-cover"
588
594
  />
589
595
  ))}
590
596
  </div>
@@ -676,6 +682,7 @@ export function MessageQueueDrawer({
676
682
  align="end"
677
683
  side="top"
678
684
  sideOffset={4}
685
+ className={COMPOSER_POPOVER_SURFACE_CLASS}
679
686
  >
680
687
  {actions.map((action) => {
681
688
  const menuItem = (
@@ -685,7 +692,7 @@ export function MessageQueueDrawer({
685
692
  onSelect={() => action.onSelect(item)}
686
693
  className={cn(
687
694
  action.destructive &&
688
- "text-destructive focus:text-destructive",
695
+ "text-[color:var(--agent-kit-danger-text)] focus:text-[color:var(--agent-kit-danger-text)]",
689
696
  )}
690
697
  >
691
698
  {action.label}
@@ -55,4 +55,40 @@ describe("PastedTextChip", () => {
55
55
  expect(container.textContent).toContain("12.345 lines");
56
56
  });
57
57
  });
58
+
59
+ it("makes Remove its own button beside the preview trigger", async () => {
60
+ const onRemove = vi.fn();
61
+ const attachment = {
62
+ id: "pasted-2",
63
+ type: "file",
64
+ name: "pasted-text-2.txt",
65
+ content: [{ type: "text", text: "hello" }],
66
+ } as Attachment;
67
+
68
+ await act(async () => {
69
+ root.render(
70
+ <ComposerRuntimeAdaptersProvider
71
+ adapters={{
72
+ formatNumber: (value) => String(value),
73
+ translate: (key, options) => String(options?.defaultValue ?? key),
74
+ }}
75
+ >
76
+ <PastedTextChip attachment={attachment} onRemove={onRemove} />
77
+ </ComposerRuntimeAdaptersProvider>,
78
+ );
79
+ });
80
+
81
+ const remove = container.querySelector<HTMLButtonElement>(
82
+ 'button[aria-label="Remove pasted text"]',
83
+ );
84
+ const preview = container.querySelector<HTMLButtonElement>(
85
+ 'button[aria-label="Preview pasted text"]',
86
+ );
87
+ expect(remove?.tabIndex).toBe(0);
88
+ expect(preview?.contains(remove ?? null)).toBe(false);
89
+
90
+ await act(async () => remove?.click());
91
+ expect(onRemove).toHaveBeenCalledWith("pasted-2");
92
+ expect(preview?.getAttribute("aria-expanded")).toBe("false");
93
+ });
58
94
  });
@@ -1,7 +1,7 @@
1
1
  import type { Attachment } from "@assistant-ui/react";
2
2
  import * as PopoverPrimitive from "@radix-ui/react-popover";
3
3
  import { IconClipboardText, IconX } from "@tabler/icons-react";
4
- import { useCallback, useEffect, useState } from "react";
4
+ import { useEffect, useState } from "react";
5
5
 
6
6
  import { cn } from "../utils.js";
7
7
  import { countLines, unwrapAttachmentEnvelope } from "./pasted-text.js";
@@ -62,14 +62,6 @@ export function PastedTextChip({
62
62
  const t = adapters.translate!;
63
63
  const formatNumber = adapters.formatNumber!;
64
64
 
65
- const handleRemove = useCallback(
66
- (event: React.MouseEvent) => {
67
- event.stopPropagation();
68
- onRemove?.(attachment.id);
69
- },
70
- [attachment.id, onRemove],
71
- );
72
-
73
65
  const lineSummary = t("agentChat.pastedText.lines", {
74
66
  count: lines,
75
67
  formattedCount: formatNumber(lines),
@@ -84,68 +76,70 @@ export function PastedTextChip({
84
76
 
85
77
  return (
86
78
  <PopoverPrimitive.Root open={open} onOpenChange={setOpen}>
87
- <PopoverPrimitive.Trigger asChild>
88
- <button
89
- type="button"
90
- className={cn(
91
- "group relative inline-flex items-center gap-2 rounded-md border border-border/70 bg-muted/50 text-start text-foreground hover:bg-muted/70 cursor-pointer",
92
- compact
93
- ? "max-w-[220px] px-2 py-1.5 text-xs"
94
- : "max-w-[260px] px-2.5 py-2 text-xs",
95
- onRemove && !compact && "pe-7",
96
- )}
97
- aria-label={t("agentChat.pastedText.preview", {
98
- defaultValue: "Preview pasted text",
99
- })}
100
- >
101
- <span
79
+ {/* Remove stays outside the trigger: a control in a button is unreachable. */}
80
+ <span className="relative inline-flex">
81
+ <PopoverPrimitive.Trigger asChild>
82
+ <button
83
+ type="button"
102
84
  className={cn(
103
- "flex shrink-0 items-center justify-center rounded bg-background text-muted-foreground",
104
- compact ? "h-6 w-6" : "h-8 w-8",
85
+ "group relative inline-flex items-center gap-2 rounded-[var(--agent-kit-radius-sm,0.5rem)] border border-border bg-muted/50 text-start text-foreground hover:bg-muted/70 cursor-pointer",
86
+ compact
87
+ ? "max-w-[220px] px-2 py-1.5 text-xs"
88
+ : "max-w-[260px] px-2.5 py-2 text-xs",
89
+ onRemove && "pe-7",
105
90
  )}
91
+ aria-label={t("agentChat.pastedText.preview", {
92
+ defaultValue: "Preview pasted text",
93
+ })}
106
94
  >
107
- <IconClipboardText
108
- className={compact ? "h-3.5 w-3.5" : "h-4 w-4"}
109
- />
110
- </span>
111
- <span className="min-w-0 flex-1">
112
- <span className="block truncate font-medium">
113
- {t("agentChat.pastedText.title", {
114
- defaultValue: "Pasted text",
115
- })}
116
- </span>
117
- <span className="block agent-kit-caption-copy text-muted-foreground">
118
- {summary}
119
- </span>
120
- </span>
121
- {onRemove && (
122
95
  <span
123
- role="button"
124
- tabIndex={-1}
125
- data-agent-composer-slot="attachment-remove"
126
- onClick={handleRemove}
127
- aria-label={t("agentChat.pastedText.remove", {
128
- defaultValue: "Remove pasted text",
129
- })}
130
96
  className={cn(
131
- // The 20px glyph box keeps the chip's geometry; the pseudo
132
- // element extends the hit target to 24px.
133
- "flex h-5 w-5 shrink-0 cursor-pointer items-center justify-center rounded text-muted-foreground hover:text-foreground after:absolute after:-inset-0.5 after:content-['']",
134
- compact ? "relative" : "absolute end-1.5 top-1.5",
97
+ "flex shrink-0 items-center justify-center rounded-[var(--agent-kit-radius-xs,0.25rem)] bg-background text-muted-foreground",
98
+ compact ? "h-6 w-6" : "h-8 w-8",
135
99
  )}
136
100
  >
137
- <IconX className="h-3 w-3" />
101
+ <IconClipboardText
102
+ className={compact ? "h-3.5 w-3.5" : "h-4 w-4"}
103
+ />
104
+ </span>
105
+ <span className="min-w-0 flex-1">
106
+ <span className="block truncate font-medium">
107
+ {t("agentChat.pastedText.title", {
108
+ defaultValue: "Pasted text",
109
+ })}
110
+ </span>
111
+ <span className="block agent-kit-caption-copy text-muted-foreground">
112
+ {summary}
113
+ </span>
138
114
  </span>
139
- )}
140
- </button>
141
- </PopoverPrimitive.Trigger>
115
+ </button>
116
+ </PopoverPrimitive.Trigger>
117
+ {onRemove && (
118
+ <button
119
+ type="button"
120
+ data-agent-composer-slot="attachment-remove"
121
+ onClick={() => onRemove(attachment.id)}
122
+ aria-label={t("agentChat.pastedText.remove", {
123
+ defaultValue: "Remove pasted text",
124
+ })}
125
+ className={cn(
126
+ // The 20px glyph box keeps the chip's geometry; the pseudo
127
+ // element extends the hit target to 24px.
128
+ "absolute end-1.5 flex h-5 w-5 shrink-0 cursor-pointer items-center justify-center rounded-[var(--agent-kit-radius-xs,0.25rem)] text-muted-foreground hover:text-foreground after:absolute after:-inset-0.5 after:content-['']",
129
+ compact ? "top-1/2 -translate-y-1/2" : "top-1.5",
130
+ )}
131
+ >
132
+ <IconX className="h-3 w-3" />
133
+ </button>
134
+ )}
135
+ </span>
142
136
  <PopoverPrimitive.Portal>
143
137
  <PopoverPrimitive.Content
144
138
  side="top"
145
139
  align="start"
146
140
  sideOffset={6}
147
141
  collisionPadding={12}
148
- className="z-50 w-[min(560px,calc(100vw-32px))] rounded-lg border border-border bg-popover text-popover-foreground shadow-lg origin-[var(--radix-popover-content-transform-origin)] data-[state=open]:animate-in data-[state=closed]:animate-out data-[state=open]:fade-in-0 data-[state=closed]:fade-out-0 data-[state=open]:zoom-in-95 data-[state=closed]:zoom-out-95"
142
+ className="z-50 w-[min(560px,calc(100vw-32px))] rounded-[var(--agent-kit-radius-sm,0.5rem)] border border-border bg-popover text-popover-foreground shadow-lg origin-[var(--radix-popover-content-transform-origin)] data-[state=open]:animate-in data-[state=closed]:animate-out data-[state=open]:fade-in-0 data-[state=closed]:fade-out-0 data-[state=open]:zoom-in-95 data-[state=closed]:zoom-out-95"
149
143
  >
150
144
  <div className="flex items-center justify-between gap-2 border-b border-border px-3 py-2">
151
145
  <div className="flex items-center gap-2 min-w-0">
@@ -165,7 +159,7 @@ export function PastedTextChip({
165
159
  aria-label={t("agentChat.composer.closePreview", {
166
160
  defaultValue: "Close preview",
167
161
  })}
168
- className="flex h-6 w-6 shrink-0 cursor-pointer items-center justify-center rounded text-muted-foreground hover:text-foreground"
162
+ className="flex h-6 w-6 shrink-0 cursor-pointer items-center justify-center rounded-[var(--agent-kit-radius-xs,0.25rem)] text-muted-foreground hover:text-foreground"
169
163
  >
170
164
  <IconX className="h-3.5 w-3.5" />
171
165
  </button>
@@ -114,7 +114,7 @@ export function PromptBar({
114
114
  >
115
115
  <div className="flex flex-col gap-2">
116
116
  {hasMenuContent ? (
117
- <div className="max-h-[min(360px,45vh)] overflow-y-auto rounded-xl border border-border/80 bg-popover p-2 shadow-lg">
117
+ <div className="max-h-[min(360px,45vh)] overflow-y-auto rounded-[var(--agent-kit-radius-sm,0.5rem)] border border-border bg-popover p-2 shadow-lg">
118
118
  {visibleSections.map((section) => (
119
119
  <div
120
120
  key={section.id}
@@ -2468,7 +2468,7 @@ describe("controlled composer context", () => {
2468
2468
  await pressEnter();
2469
2469
  expect(onSubmit).not.toHaveBeenCalled();
2470
2470
  const contextRow = container.querySelector('[data-context-key="brief"]')!;
2471
- expect(contextRow.className).toContain("py-0.5");
2471
+ expect(contextRow.className).toContain("h-5");
2472
2472
  expect(contextRow.querySelector("span")?.textContent).toBe("Brief");
2473
2473
  expect(contextRow.querySelectorAll("button")).toHaveLength(1);
2474
2474
  expect(
@@ -2532,7 +2532,7 @@ describe("controlled composer context", () => {
2532
2532
  expect(
2533
2533
  contextChip.querySelector('button[aria-label="Remove Brief context"]'),
2534
2534
  ).not.toBeNull();
2535
- expect(contextChip.className).toContain("py-0.5");
2535
+ expect(contextChip.className).toContain("h-5");
2536
2536
  await act(async () => contextChip.click());
2537
2537
  expect(onInspectContextItem).not.toHaveBeenCalled();
2538
2538
  });
@@ -468,6 +468,33 @@ describe("composer submission ownership", () => {
468
468
  ]);
469
469
  });
470
470
 
471
+ it("submits a custom agent mention as a custom-agent reference without null fields", async () => {
472
+ const onSubmit = vi.fn();
473
+ await render({ onSubmit });
474
+ await act(async () =>
475
+ composerRef.current!.insertReference({
476
+ refType: "custom-agent",
477
+ refId: "researcher",
478
+ label: "Researcher",
479
+ refPath: "agents/researcher.md",
480
+ source: "agent:custom",
481
+ icon: "agent",
482
+ }),
483
+ );
484
+ await act(async () => send());
485
+ expect(onSubmit).toHaveBeenCalledOnce();
486
+ expect(onSubmit.mock.calls[0]?.[2]).toStrictEqual([
487
+ {
488
+ type: "custom-agent",
489
+ path: "agents/researcher.md",
490
+ name: "Researcher",
491
+ source: "agent:custom",
492
+ refType: "custom-agent",
493
+ refId: "researcher",
494
+ },
495
+ ]);
496
+ });
497
+
471
498
  it("keeps a standalone popup's recovery draft intact through preprocessing, unmount, and rejection", async () => {
472
499
  const transport = deferred();
473
500
  let observedDraft = "Original draft";