@agent-native/core 0.128.4 → 0.129.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 (343) hide show
  1. package/corpus/README.md +2 -2
  2. package/corpus/core/CHANGELOG.md +84 -0
  3. package/corpus/core/docs/content/template-design-collaboration-and-full-apps.mdx +3 -1
  4. package/corpus/core/package.json +6 -3
  5. package/corpus/core/src/a2a/client.ts +18 -4
  6. package/corpus/core/src/a2a/server.ts +19 -3
  7. package/corpus/core/src/a2a/types.ts +7 -0
  8. package/corpus/core/src/action.ts +43 -16
  9. package/corpus/core/src/agent/engine/ai-sdk-engine.ts +14 -10
  10. package/corpus/core/src/agent/production-agent.ts +41 -3
  11. package/corpus/core/src/agent/thread-data-builder.ts +5 -0
  12. package/corpus/core/src/chat-threads/migrations.ts +53 -0
  13. package/corpus/core/src/cli/create.ts +4 -0
  14. package/corpus/core/src/cli/skills-content/design-visual-edit-skill.ts +36 -16
  15. package/corpus/core/src/cli/skills.ts +16 -0
  16. package/corpus/core/src/client/AgentPanel.tsx +9 -5
  17. package/corpus/core/src/client/AssistantChat.tsx +138 -46
  18. package/corpus/core/src/client/MultiTabAssistantChat.tsx +16 -10
  19. package/corpus/core/src/client/agent-chat-adapter.ts +21 -3
  20. package/corpus/core/src/client/analytics.ts +159 -102
  21. package/corpus/core/src/client/chat/message-components.tsx +12 -5
  22. package/corpus/core/src/client/chat/runtime.ts +2 -1
  23. package/corpus/core/src/client/chat/tool-call-display.tsx +25 -2
  24. package/corpus/core/src/client/chat-model-groups.ts +3 -0
  25. package/corpus/core/src/client/client-status-requests.ts +161 -0
  26. package/corpus/core/src/client/settings/VoiceTranscriptionSection.tsx +2 -2
  27. package/corpus/core/src/client/sse-event-processor.ts +15 -3
  28. package/corpus/core/src/client/use-agent-engine-configured.ts +54 -50
  29. package/corpus/core/src/client/use-chat-models.ts +16 -11
  30. package/corpus/core/src/client/use-chat-threads.ts +32 -9
  31. package/corpus/core/src/client/use-session.ts +4 -5
  32. package/corpus/core/src/db/client.ts +83 -8
  33. package/corpus/core/src/db/ensure-additive-columns.ts +31 -20
  34. package/corpus/core/src/db/migrations.ts +22 -2
  35. package/corpus/core/src/mcp/approval-store.ts +99 -0
  36. package/corpus/core/src/mcp/build-server.ts +579 -303
  37. package/corpus/core/src/mcp/embed-app.ts +1 -1
  38. package/corpus/core/src/mcp/oauth-client-metadata.ts +380 -0
  39. package/corpus/core/src/mcp/oauth-route.ts +57 -52
  40. package/corpus/core/src/mcp/screen-memory-stdio.ts +400 -378
  41. package/corpus/core/src/mcp/server.ts +29 -145
  42. package/corpus/core/src/mcp/stdio.ts +72 -80
  43. package/corpus/core/src/mcp-client/manager.ts +6 -10
  44. package/corpus/core/src/mcp-client/oauth-client.ts +127 -36
  45. package/corpus/core/src/mcp-client/oauth-routes.ts +16 -6
  46. package/corpus/core/src/mcp-client/routes.ts +6 -5
  47. package/corpus/core/src/server/agent-capabilities.ts +20 -0
  48. package/corpus/core/src/server/agent-chat/action-filters-a2a.ts +27 -0
  49. package/corpus/core/src/server/agent-chat-plugin.ts +18 -0
  50. package/corpus/core/src/server/transcribe-voice.ts +14 -5
  51. package/corpus/core/src/templates/default/.agents/skills/security/SKILL.md +13 -2
  52. package/corpus/core/src/templates/workspace-core/.agents/skills/authentication/SKILL.md +5 -2
  53. package/corpus/core/src/templates/workspace-core/.agents/skills/external-agents/SKILL.md +18 -0
  54. package/corpus/core/src/templates/workspace-core/.agents/skills/security/SKILL.md +13 -2
  55. package/corpus/templates/analytics/.agents/skills/security/SKILL.md +13 -2
  56. package/corpus/templates/analytics/app/components/dashboard/DashboardPanelSkeleton.tsx +1 -10
  57. package/corpus/templates/analytics/app/global.css +0 -31
  58. package/corpus/templates/analytics/app/lib/sql-query.ts +46 -20
  59. package/corpus/templates/analytics/changelog/2026-07-28-analytics-dashboard-loading-states-now-use-a-simpler-standar.md +6 -0
  60. package/corpus/templates/analytics/changelog/2026-07-28-analytics-dashboards-now-load-first-party-charts-reliably-in.md +6 -0
  61. package/corpus/templates/analytics/server/lib/first-party-analytics-cache.ts +42 -16
  62. package/corpus/templates/analytics/server/lib/first-party-analytics.ts +4 -2
  63. package/corpus/templates/analytics/shared/sql-query-limits.ts +1 -0
  64. package/corpus/templates/assets/.agents/skills/security/SKILL.md +13 -2
  65. package/corpus/templates/brain/.agents/skills/security/SKILL.md +13 -2
  66. package/corpus/templates/calendar/.agents/skills/security/SKILL.md +13 -2
  67. package/corpus/templates/chat/.agents/skills/security/SKILL.md +13 -2
  68. package/corpus/templates/chat/README.md +0 -2
  69. package/corpus/templates/clips/.agents/skills/security/SKILL.md +13 -2
  70. package/corpus/templates/clips/app/components/player/player-controls.tsx +3 -6
  71. package/corpus/templates/clips/app/routes/r.$recordingId.tsx +6 -2
  72. package/corpus/templates/clips/app/routes/share.$shareId.tsx +3 -1
  73. package/corpus/templates/clips/changelog/2026-07-28-copied-share-links-no-longer-leave-an-unnecessary-confirmati.md +6 -0
  74. package/corpus/templates/clips/changelog/2026-07-28-playback-skip-controls-no-longer-show-overlapping-numbers.md +6 -0
  75. package/corpus/templates/clips/changelog/2026-07-28-public-clips-share-buttons-now-use-a-clean-text-only-label.md +6 -0
  76. package/corpus/templates/clips/desktop/src/app.tsx +14 -17
  77. package/corpus/templates/clips/desktop/src/overlays/live-audio-bars.tsx +3 -1
  78. package/corpus/templates/clips/desktop/src/styles.css +13 -10
  79. package/corpus/templates/clips/desktop/src-tauri/src/recording_indicator.rs +2 -2
  80. package/corpus/templates/clips/desktop/src-tauri/src/whisper_speech.rs +36 -0
  81. package/corpus/templates/content/.agents/skills/security/SKILL.md +13 -2
  82. package/corpus/templates/content/actions/_builder-cms-read-client.ts +155 -34
  83. package/corpus/templates/content/actions/_builder-docs-client.ts +151 -30
  84. package/corpus/templates/content/actions/stage-builder-source-bulk-update.ts +5 -2
  85. package/corpus/templates/content/app/root.tsx +35 -14
  86. package/corpus/templates/content/changelog/2026-07-28-builder-backed-files-media-fields-now-accept-direct-file-url.md +6 -0
  87. package/corpus/templates/content/changelog/2026-07-28-builder-content-reads-now-negotiate-the-newest-mcp-protocol-.md +6 -0
  88. package/corpus/templates/content/changelog/2026-07-28-public-content-pages-load-faster-before-the-optional-ask-sid.md +6 -0
  89. package/corpus/templates/design/.agents/skills/security/SKILL.md +13 -2
  90. package/corpus/templates/design/.agents/skills/visual-edit/SKILL.md +36 -16
  91. package/corpus/templates/design/.generated/bridge/editor-chrome.generated.ts +42 -3
  92. package/corpus/templates/design/actions/open-visual-edit.ts +2 -1
  93. package/corpus/templates/design/app/components/design/CanvasContextMenu.tsx +2 -2
  94. package/corpus/templates/design/app/components/design/DesignCanvas.tsx +14 -15
  95. package/corpus/templates/design/app/components/design/ResponsiveInteractBar.tsx +314 -0
  96. package/corpus/templates/design/app/components/design/bridge/editor-chrome.bridge.ts +88 -3
  97. package/corpus/templates/design/app/components/design/keyboard-shortcuts.ts +1 -1
  98. package/corpus/templates/design/app/hooks/useDesignHotkeys.ts +7 -6
  99. package/corpus/templates/design/app/i18n-data.ts +56 -11
  100. package/corpus/templates/design/app/i18n-responsive-interact.ts +183 -0
  101. package/corpus/templates/design/app/lib/agent-chat.ts +60 -0
  102. package/corpus/templates/design/app/pages/design-editor/responsive-interact.ts +89 -0
  103. package/corpus/templates/design/changelog/2026-07-28-design-edits-can-be-applied-through-the-host-coding-agent-fr.md +6 -0
  104. package/corpus/templates/design/changelog/2026-07-28-interact-mode-can-preview-designs-in-responsive-device-sizes.md +6 -0
  105. package/corpus/templates/design/changelog/2026-07-28-interact-mode-now-opens-a-full-screen-responsive-preview-wit.md +6 -0
  106. package/corpus/templates/design/changelog/2026-07-28-show-or-hide-design-editing-chrome-with-cmd-on-apple-devices.md +2 -2
  107. package/corpus/templates/design/changelog/2026-07-28-visual-edit-now-always-shows-the-live-running-app-in-the-can.md +6 -0
  108. package/corpus/templates/dispatch/.agents/skills/security/SKILL.md +13 -2
  109. package/corpus/templates/forms/.agents/skills/security/SKILL.md +13 -2
  110. package/corpus/templates/macros/.agents/skills/security/SKILL.md +13 -2
  111. package/corpus/templates/mail/.agents/skills/security/SKILL.md +13 -2
  112. package/corpus/templates/plan/.agents/skills/security/SKILL.md +13 -2
  113. package/corpus/templates/slides/.agents/skills/security/SKILL.md +13 -2
  114. package/corpus/templates/tasks/.agents/skills/security/SKILL.md +13 -2
  115. package/corpus/toolkit/CHANGELOG.md +13 -0
  116. package/corpus/toolkit/package.json +1 -1
  117. package/corpus/toolkit/src/chat-history.css +1 -2
  118. package/corpus/toolkit/src/composer/TiptapComposer.tsx +45 -0
  119. package/dist/a2a/client.d.ts +7 -0
  120. package/dist/a2a/client.d.ts.map +1 -1
  121. package/dist/a2a/client.js +8 -3
  122. package/dist/a2a/client.js.map +1 -1
  123. package/dist/a2a/server.d.ts.map +1 -1
  124. package/dist/a2a/server.js +18 -3
  125. package/dist/a2a/server.js.map +1 -1
  126. package/dist/a2a/types.d.ts +7 -0
  127. package/dist/a2a/types.d.ts.map +1 -1
  128. package/dist/a2a/types.js.map +1 -1
  129. package/dist/action.d.ts +15 -1
  130. package/dist/action.d.ts.map +1 -1
  131. package/dist/action.js +39 -16
  132. package/dist/action.js.map +1 -1
  133. package/dist/agent/engine/ai-sdk-engine.d.ts.map +1 -1
  134. package/dist/agent/engine/ai-sdk-engine.js +14 -10
  135. package/dist/agent/engine/ai-sdk-engine.js.map +1 -1
  136. package/dist/agent/production-agent.d.ts.map +1 -1
  137. package/dist/agent/production-agent.js +35 -7
  138. package/dist/agent/production-agent.js.map +1 -1
  139. package/dist/agent/thread-data-builder.d.ts +2 -0
  140. package/dist/agent/thread-data-builder.d.ts.map +1 -1
  141. package/dist/agent/thread-data-builder.js +3 -0
  142. package/dist/agent/thread-data-builder.js.map +1 -1
  143. package/dist/chat-threads/migrations.d.ts +21 -0
  144. package/dist/chat-threads/migrations.d.ts.map +1 -0
  145. package/dist/chat-threads/migrations.js +45 -0
  146. package/dist/chat-threads/migrations.js.map +1 -0
  147. package/dist/cli/create.d.ts.map +1 -1
  148. package/dist/cli/create.js +4 -0
  149. package/dist/cli/create.js.map +1 -1
  150. package/dist/cli/skills-content/design-visual-edit-skill.d.ts +1 -1
  151. package/dist/cli/skills-content/design-visual-edit-skill.d.ts.map +1 -1
  152. package/dist/cli/skills-content/design-visual-edit-skill.js +36 -16
  153. package/dist/cli/skills-content/design-visual-edit-skill.js.map +1 -1
  154. package/dist/cli/skills.d.ts.map +1 -1
  155. package/dist/cli/skills.js +15 -0
  156. package/dist/cli/skills.js.map +1 -1
  157. package/dist/client/AgentPanel.d.ts.map +1 -1
  158. package/dist/client/AgentPanel.js +6 -5
  159. package/dist/client/AgentPanel.js.map +1 -1
  160. package/dist/client/AssistantChat.d.ts +37 -0
  161. package/dist/client/AssistantChat.d.ts.map +1 -1
  162. package/dist/client/AssistantChat.js +41 -8
  163. package/dist/client/AssistantChat.js.map +1 -1
  164. package/dist/client/MultiTabAssistantChat.d.ts.map +1 -1
  165. package/dist/client/MultiTabAssistantChat.js +11 -10
  166. package/dist/client/MultiTabAssistantChat.js.map +1 -1
  167. package/dist/client/agent-chat-adapter.d.ts.map +1 -1
  168. package/dist/client/agent-chat-adapter.js +19 -3
  169. package/dist/client/agent-chat-adapter.js.map +1 -1
  170. package/dist/client/analytics.d.ts.map +1 -1
  171. package/dist/client/analytics.js +150 -101
  172. package/dist/client/analytics.js.map +1 -1
  173. package/dist/client/chat/message-components.d.ts +2 -1
  174. package/dist/client/chat/message-components.d.ts.map +1 -1
  175. package/dist/client/chat/message-components.js +11 -4
  176. package/dist/client/chat/message-components.js.map +1 -1
  177. package/dist/client/chat/runtime.d.ts.map +1 -1
  178. package/dist/client/chat/runtime.js +2 -1
  179. package/dist/client/chat/runtime.js.map +1 -1
  180. package/dist/client/chat/tool-call-display.d.ts +4 -1
  181. package/dist/client/chat/tool-call-display.d.ts.map +1 -1
  182. package/dist/client/chat/tool-call-display.js +14 -8
  183. package/dist/client/chat/tool-call-display.js.map +1 -1
  184. package/dist/client/chat-model-groups.d.ts.map +1 -1
  185. package/dist/client/chat-model-groups.js +3 -0
  186. package/dist/client/chat-model-groups.js.map +1 -1
  187. package/dist/client/client-status-requests.d.ts +14 -0
  188. package/dist/client/client-status-requests.d.ts.map +1 -0
  189. package/dist/client/client-status-requests.js +126 -0
  190. package/dist/client/client-status-requests.js.map +1 -0
  191. package/dist/client/settings/VoiceTranscriptionSection.js +1 -1
  192. package/dist/client/settings/VoiceTranscriptionSection.js.map +1 -1
  193. package/dist/client/sse-event-processor.d.ts +7 -0
  194. package/dist/client/sse-event-processor.d.ts.map +1 -1
  195. package/dist/client/sse-event-processor.js +8 -3
  196. package/dist/client/sse-event-processor.js.map +1 -1
  197. package/dist/client/use-agent-engine-configured.d.ts.map +1 -1
  198. package/dist/client/use-agent-engine-configured.js +29 -43
  199. package/dist/client/use-agent-engine-configured.js.map +1 -1
  200. package/dist/client/use-chat-models.d.ts.map +1 -1
  201. package/dist/client/use-chat-models.js +11 -11
  202. package/dist/client/use-chat-models.js.map +1 -1
  203. package/dist/client/use-chat-threads.d.ts.map +1 -1
  204. package/dist/client/use-chat-threads.js +23 -7
  205. package/dist/client/use-chat-threads.js.map +1 -1
  206. package/dist/client/use-session.d.ts.map +1 -1
  207. package/dist/client/use-session.js +4 -4
  208. package/dist/client/use-session.js.map +1 -1
  209. package/dist/collab/awareness.d.ts +2 -2
  210. package/dist/collab/awareness.d.ts.map +1 -1
  211. package/dist/collab/struct-routes.d.ts +1 -1
  212. package/dist/db/client.d.ts.map +1 -1
  213. package/dist/db/client.js +48 -4
  214. package/dist/db/client.js.map +1 -1
  215. package/dist/db/ensure-additive-columns.d.ts.map +1 -1
  216. package/dist/db/ensure-additive-columns.js +32 -21
  217. package/dist/db/ensure-additive-columns.js.map +1 -1
  218. package/dist/db/migrations.d.ts +9 -0
  219. package/dist/db/migrations.d.ts.map +1 -1
  220. package/dist/db/migrations.js +14 -3
  221. package/dist/db/migrations.js.map +1 -1
  222. package/dist/file-upload/actions/upload-image.d.ts +1 -1
  223. package/dist/mcp/approval-store.d.ts +16 -0
  224. package/dist/mcp/approval-store.d.ts.map +1 -0
  225. package/dist/mcp/approval-store.js +85 -0
  226. package/dist/mcp/approval-store.js.map +1 -0
  227. package/dist/mcp/build-server.d.ts +1 -34
  228. package/dist/mcp/build-server.d.ts.map +1 -1
  229. package/dist/mcp/build-server.js +220 -23
  230. package/dist/mcp/build-server.js.map +1 -1
  231. package/dist/mcp/embed-app.js +1 -1
  232. package/dist/mcp/embed-app.js.map +1 -1
  233. package/dist/mcp/oauth-client-metadata.d.ts +15 -0
  234. package/dist/mcp/oauth-client-metadata.d.ts.map +1 -0
  235. package/dist/mcp/oauth-client-metadata.js +297 -0
  236. package/dist/mcp/oauth-client-metadata.js.map +1 -0
  237. package/dist/mcp/oauth-route.d.ts.map +1 -1
  238. package/dist/mcp/oauth-route.js +39 -53
  239. package/dist/mcp/oauth-route.js.map +1 -1
  240. package/dist/mcp/screen-memory-stdio.d.ts.map +1 -1
  241. package/dist/mcp/screen-memory-stdio.js +304 -296
  242. package/dist/mcp/screen-memory-stdio.js.map +1 -1
  243. package/dist/mcp/server.d.ts +12 -25
  244. package/dist/mcp/server.d.ts.map +1 -1
  245. package/dist/mcp/server.js +24 -133
  246. package/dist/mcp/server.js.map +1 -1
  247. package/dist/mcp/stdio.d.ts.map +1 -1
  248. package/dist/mcp/stdio.js +36 -35
  249. package/dist/mcp/stdio.js.map +1 -1
  250. package/dist/mcp-client/manager.d.ts.map +1 -1
  251. package/dist/mcp-client/manager.js +6 -6
  252. package/dist/mcp-client/manager.js.map +1 -1
  253. package/dist/mcp-client/oauth-client.d.ts +13 -17
  254. package/dist/mcp-client/oauth-client.d.ts.map +1 -1
  255. package/dist/mcp-client/oauth-client.js +74 -16
  256. package/dist/mcp-client/oauth-client.js.map +1 -1
  257. package/dist/mcp-client/oauth-routes.d.ts +2 -2
  258. package/dist/mcp-client/oauth-routes.d.ts.map +1 -1
  259. package/dist/mcp-client/oauth-routes.js +16 -6
  260. package/dist/mcp-client/oauth-routes.js.map +1 -1
  261. package/dist/mcp-client/routes.js +5 -5
  262. package/dist/mcp-client/routes.js.map +1 -1
  263. package/dist/notifications/routes.d.ts +1 -1
  264. package/dist/observability/routes.d.ts +3 -3
  265. package/dist/progress/routes.d.ts +1 -1
  266. package/dist/provider-api/actions/custom-provider-registration.d.ts +14 -14
  267. package/dist/provider-api/actions/provider-api.d.ts +8 -8
  268. package/dist/resources/handlers.d.ts +1 -1
  269. package/dist/secrets/routes.d.ts +9 -9
  270. package/dist/server/agent-capabilities.d.ts.map +1 -1
  271. package/dist/server/agent-capabilities.js +21 -0
  272. package/dist/server/agent-capabilities.js.map +1 -1
  273. package/dist/server/agent-chat/action-filters-a2a.d.ts +14 -0
  274. package/dist/server/agent-chat/action-filters-a2a.d.ts.map +1 -1
  275. package/dist/server/agent-chat/action-filters-a2a.js +16 -0
  276. package/dist/server/agent-chat/action-filters-a2a.js.map +1 -1
  277. package/dist/server/agent-chat-plugin.d.ts.map +1 -1
  278. package/dist/server/agent-chat-plugin.js +11 -1
  279. package/dist/server/agent-chat-plugin.js.map +1 -1
  280. package/dist/server/realtime-token.d.ts +1 -1
  281. package/dist/server/transcribe-voice.d.ts +1 -1
  282. package/dist/server/transcribe-voice.js +12 -6
  283. package/dist/server/transcribe-voice.js.map +1 -1
  284. package/dist/templates/chat/.agents/skills/security/SKILL.md +13 -2
  285. package/dist/templates/chat/README.md +0 -2
  286. package/dist/templates/default/.agents/skills/security/SKILL.md +13 -2
  287. package/dist/templates/workspace-core/.agents/skills/authentication/SKILL.md +5 -2
  288. package/dist/templates/workspace-core/.agents/skills/external-agents/SKILL.md +18 -0
  289. package/dist/templates/workspace-core/.agents/skills/security/SKILL.md +13 -2
  290. package/docs/content/template-design-collaboration-and-full-apps.mdx +3 -1
  291. package/package.json +7 -4
  292. package/src/a2a/client.ts +18 -4
  293. package/src/a2a/server.ts +19 -3
  294. package/src/a2a/types.ts +7 -0
  295. package/src/action.ts +43 -16
  296. package/src/agent/engine/ai-sdk-engine.ts +14 -10
  297. package/src/agent/production-agent.ts +41 -3
  298. package/src/agent/thread-data-builder.ts +5 -0
  299. package/src/chat-threads/migrations.ts +53 -0
  300. package/src/cli/create.ts +4 -0
  301. package/src/cli/skills-content/design-visual-edit-skill.ts +36 -16
  302. package/src/cli/skills.ts +16 -0
  303. package/src/client/AgentPanel.tsx +9 -5
  304. package/src/client/AssistantChat.tsx +138 -46
  305. package/src/client/MultiTabAssistantChat.tsx +16 -10
  306. package/src/client/agent-chat-adapter.ts +21 -3
  307. package/src/client/analytics.ts +159 -102
  308. package/src/client/chat/message-components.tsx +12 -5
  309. package/src/client/chat/runtime.ts +2 -1
  310. package/src/client/chat/tool-call-display.tsx +25 -2
  311. package/src/client/chat-model-groups.ts +3 -0
  312. package/src/client/client-status-requests.ts +161 -0
  313. package/src/client/settings/VoiceTranscriptionSection.tsx +2 -2
  314. package/src/client/sse-event-processor.ts +15 -3
  315. package/src/client/use-agent-engine-configured.ts +54 -50
  316. package/src/client/use-chat-models.ts +16 -11
  317. package/src/client/use-chat-threads.ts +32 -9
  318. package/src/client/use-session.ts +4 -5
  319. package/src/db/client.ts +83 -8
  320. package/src/db/ensure-additive-columns.ts +31 -20
  321. package/src/db/migrations.ts +22 -2
  322. package/src/mcp/approval-store.ts +99 -0
  323. package/src/mcp/build-server.ts +579 -303
  324. package/src/mcp/embed-app.ts +1 -1
  325. package/src/mcp/oauth-client-metadata.ts +380 -0
  326. package/src/mcp/oauth-route.ts +57 -52
  327. package/src/mcp/screen-memory-stdio.ts +400 -378
  328. package/src/mcp/server.ts +29 -145
  329. package/src/mcp/stdio.ts +72 -80
  330. package/src/mcp-client/manager.ts +6 -10
  331. package/src/mcp-client/oauth-client.ts +127 -36
  332. package/src/mcp-client/oauth-routes.ts +16 -6
  333. package/src/mcp-client/routes.ts +6 -5
  334. package/src/server/agent-capabilities.ts +20 -0
  335. package/src/server/agent-chat/action-filters-a2a.ts +27 -0
  336. package/src/server/agent-chat-plugin.ts +18 -0
  337. package/src/server/transcribe-voice.ts +14 -5
  338. package/src/templates/chat/.agents/skills/security/SKILL.md +13 -2
  339. package/src/templates/chat/README.md +0 -2
  340. package/src/templates/default/.agents/skills/security/SKILL.md +13 -2
  341. package/src/templates/workspace-core/.agents/skills/authentication/SKILL.md +5 -2
  342. package/src/templates/workspace-core/.agents/skills/external-agents/SKILL.md +18 -0
  343. package/src/templates/workspace-core/.agents/skills/security/SKILL.md +13 -2
@@ -1,5 +1,5 @@
1
- import * as amplitude from "@amplitude/analytics-browser";
2
- import * as Sentry from "@sentry/browser";
1
+ import type * as amplitude from "@amplitude/analytics-browser";
2
+ import type * as Sentry from "@sentry/browser";
3
3
 
4
4
  import {
5
5
  llmConnectionTrackingProperties,
@@ -9,7 +9,10 @@ import {
9
9
  getOrCreateAnalyticsAnonymousId,
10
10
  getOrCreateAnalyticsSessionId,
11
11
  } from "./analytics-session.js";
12
- import { agentNativePath } from "./api-path.js";
12
+ import {
13
+ fetchAgentEngineStatus,
14
+ fetchAuthSessionStatus,
15
+ } from "./client-status-requests.js";
13
16
  import {
14
17
  installErrorCapture,
15
18
  type CapturedExceptionEvent,
@@ -149,7 +152,17 @@ let _getDefaultProps: GetDefaultProps | null = null;
149
152
  let _agentNativeAnalyticsPublicKey: string | null = null;
150
153
  let _agentNativeAnalyticsEndpoint: string | null = null;
151
154
  let _amplitudeInitialized = false;
155
+ let _amplitudeModule: typeof amplitude | null = null;
156
+ let _amplitudeLoadPromise: Promise<typeof amplitude | null> | null = null;
157
+ let _amplitudeApiKey: string | null = null;
158
+ let _pendingAmplitudeEvents: Array<[string, Record<string, unknown>]> = [];
152
159
  let _sentryInitialized = false;
160
+ let _sentryModule: typeof Sentry | null = null;
161
+ let _sentryLoadPromise: Promise<typeof Sentry | null> | null = null;
162
+ let _pendingSentryCaptures: Array<{
163
+ error: unknown;
164
+ context: ClientCaptureContext;
165
+ }> = [];
153
166
  let _llmConnectionStatus: LlmConnectionStatus | null = null;
154
167
  let _llmConnectionRefresh: Promise<void> | null = null;
155
168
  let _llmConnectionRefreshInstalled = false;
@@ -301,20 +314,12 @@ function refreshLlmConnectionStatus(): Promise<void> {
301
314
  return Promise.resolve();
302
315
  }
303
316
  if (_llmConnectionRefresh) return _llmConnectionRefresh;
304
- let request: Promise<Response>;
305
- try {
306
- request = fetch(agentNativePath("/_agent-native/agent-engine/status"));
307
- } catch {
308
- return Promise.resolve();
309
- }
310
- _llmConnectionRefresh = request
311
- .then((res) => (res.ok ? res.json() : null))
312
- .then((data) => {
313
- _llmConnectionStatus = normalizeAgentEngineStatus(data);
314
- cacheLlmConnectionStatus(_llmConnectionStatus);
315
- })
316
- .catch(() => {
317
- if (!_llmConnectionStatus) {
317
+ _llmConnectionRefresh = fetchAgentEngineStatus()
318
+ .then((result) => {
319
+ if (result.state === "available") {
320
+ _llmConnectionStatus = normalizeAgentEngineStatus(result.value);
321
+ cacheLlmConnectionStatus(_llmConnectionStatus);
322
+ } else if (!_llmConnectionStatus) {
318
323
  _llmConnectionStatus = readCachedLlmConnectionStatus();
319
324
  }
320
325
  })
@@ -396,15 +401,11 @@ function refreshTrackingAuthSession(): Promise<void> {
396
401
  return Promise.resolve();
397
402
  }
398
403
  if (_trackingSessionRefresh) return _trackingSessionRefresh;
399
- _trackingSessionRefresh = fetch(
400
- agentNativePath("/_agent-native/auth/session"),
401
- )
402
- .then((res) => (res.ok ? res.json() : null))
403
- .then((data) => {
404
- setTrackingIdentityFromSession(data);
405
- })
406
- .catch(() => {
407
- clearTrackingIdentity();
404
+ _trackingSessionRefresh = fetchAuthSessionStatus()
405
+ .then((result) => {
406
+ if (result.state === "available") {
407
+ setTrackingIdentityFromSession(result.value);
408
+ }
408
409
  })
409
410
  .finally(() => {
410
411
  _trackingIdentityResolved = true;
@@ -616,12 +617,31 @@ function ensureAmplitude(): boolean {
616
617
  const key = (import.meta.env as Record<string, string | undefined>)
617
618
  ?.VITE_AMPLITUDE_API_KEY;
618
619
  if (!key) return false;
619
- // Standard pageviews and explicit events are emitted below. Keep SDK-level
620
- // DOM/network autocapture off so rendered user content is never collected as
621
- // an implicit analytics side effect.
622
- amplitude.init(key, { autocapture: false });
623
- _amplitudeInitialized = true;
624
- return true;
620
+ _amplitudeApiKey = key;
621
+ if (_amplitudeLoadPromise) return false;
622
+
623
+ _amplitudeLoadPromise = import("@amplitude/analytics-browser")
624
+ .then((module) => {
625
+ // Standard pageviews and explicit events are emitted below. Keep SDK-level
626
+ // DOM/network autocapture off so rendered user content is never collected as
627
+ // an implicit analytics side effect.
628
+ module.init(key, { autocapture: false });
629
+ _amplitudeModule = module;
630
+ _amplitudeInitialized = true;
631
+ for (const [name, properties] of _pendingAmplitudeEvents) {
632
+ module.track(name, properties);
633
+ }
634
+ _pendingAmplitudeEvents = [];
635
+ return module;
636
+ })
637
+ .catch(() => {
638
+ _pendingAmplitudeEvents = [];
639
+ return null;
640
+ })
641
+ .finally(() => {
642
+ _amplitudeLoadPromise = null;
643
+ });
644
+ return false;
625
645
  }
626
646
 
627
647
  function hasOnlySourcelessFrames(value: {
@@ -881,58 +901,103 @@ function getClientSentryDsn(): string | undefined {
881
901
  );
882
902
  }
883
903
 
884
- function ensureSentry(): void {
885
- if (_sentryInitialized) return;
886
- const dsn = getClientSentryDsn();
887
- if (!dsn) return;
888
- Sentry.init({
889
- dsn,
890
- environment:
891
- window.__AGENT_NATIVE_CONFIG__?.sentryEnvironment ||
892
- (import.meta.env as Record<string, string | undefined>)?.MODE ||
893
- "production",
894
- beforeSend(event) {
895
- if (shouldDropBrowserSentryNoise(event)) {
896
- return null;
904
+ function captureWithSentry(
905
+ module: typeof Sentry,
906
+ error: unknown,
907
+ context: ClientCaptureContext,
908
+ ): string | undefined {
909
+ return module.withScope((scope) => {
910
+ if (context.tags) {
911
+ for (const [k, v] of Object.entries(context.tags)) {
912
+ if (typeof v === "string") scope.setTag(k, v);
897
913
  }
898
- // Strip sensitive query params from the request URL. React Router
899
- // history can include share tokens, ?signin=1, password reset codes,
900
- // public-share password params (audit F-07), etc.
901
- if (event.request?.url) {
902
- event.request.url = scrubUrl(event.request.url);
914
+ }
915
+ if (context.extra) {
916
+ for (const [k, v] of Object.entries(context.extra)) {
917
+ if (v !== undefined) scope.setExtra(k, v);
903
918
  }
904
- // Clean the same params from breadcrumb URLs (Sentry captures
905
- // history.pushState breadcrumbs by default).
906
- if (Array.isArray(event.breadcrumbs)) {
907
- for (const crumb of event.breadcrumbs) {
908
- if (crumb && typeof crumb === "object" && "data" in crumb) {
909
- const data = crumb.data as Record<string, unknown> | undefined;
910
- if (data && typeof data.url === "string") {
911
- data.url = scrubUrl(data.url);
912
- }
913
- if (data && typeof data.from === "string") {
914
- data.from = scrubUrl(data.from);
915
- }
916
- if (data && typeof data.to === "string") {
917
- data.to = scrubUrl(data.to);
919
+ }
920
+ if (context.contexts) {
921
+ for (const [k, v] of Object.entries(context.contexts)) {
922
+ scope.setContext(k, v);
923
+ }
924
+ }
925
+ return module.captureException(error);
926
+ });
927
+ }
928
+
929
+ function ensureSentry(loadWithoutDsn = false): void {
930
+ if (_sentryInitialized || _sentryLoadPromise) return;
931
+ const dsn = getClientSentryDsn();
932
+ if (!dsn && !loadWithoutDsn) return;
933
+ _sentryLoadPromise = import("@sentry/browser")
934
+ .then((module) => {
935
+ _sentryModule = module;
936
+ if (!dsn) {
937
+ for (const pending of _pendingSentryCaptures) {
938
+ captureWithSentry(module, pending.error, pending.context);
939
+ }
940
+ _pendingSentryCaptures = [];
941
+ return module;
942
+ }
943
+ module.init({
944
+ dsn,
945
+ environment:
946
+ window.__AGENT_NATIVE_CONFIG__?.sentryEnvironment ||
947
+ (import.meta.env as Record<string, string | undefined>)?.MODE ||
948
+ "production",
949
+ beforeSend(event) {
950
+ if (shouldDropBrowserSentryNoise(event)) {
951
+ return null;
952
+ }
953
+ // Strip sensitive query params from the request URL. React Router
954
+ // history can include share tokens, ?signin=1, password reset codes,
955
+ // public-share password params (audit F-07), etc.
956
+ if (event.request?.url) {
957
+ event.request.url = scrubUrl(event.request.url);
958
+ }
959
+ // Clean the same params from breadcrumb URLs (Sentry captures
960
+ // history.pushState breadcrumbs by default).
961
+ if (Array.isArray(event.breadcrumbs)) {
962
+ for (const crumb of event.breadcrumbs) {
963
+ if (crumb && typeof crumb === "object" && "data" in crumb) {
964
+ const data = crumb.data as Record<string, unknown> | undefined;
965
+ if (data && typeof data.url === "string") {
966
+ data.url = scrubUrl(data.url);
967
+ }
968
+ if (data && typeof data.from === "string") {
969
+ data.from = scrubUrl(data.from);
970
+ }
971
+ if (data && typeof data.to === "string") {
972
+ data.to = scrubUrl(data.to);
973
+ }
974
+ }
918
975
  }
919
976
  }
920
- }
977
+ return event;
978
+ },
979
+ });
980
+ module.setTag("runtime", "browser");
981
+ _sentryInitialized = true;
982
+ // Flush any user/tag that was set before init.
983
+ if (_pendingSentryUser !== undefined) {
984
+ module.setUser(_pendingSentryUser);
985
+ _pendingSentryUser = undefined;
921
986
  }
922
- return event;
923
- },
924
- });
925
- Sentry.setTag("runtime", "browser");
926
- _sentryInitialized = true;
927
- // Flush any user/tag that was set before init.
928
- if (_pendingSentryUser !== undefined) {
929
- Sentry.setUser(_pendingSentryUser);
930
- _pendingSentryUser = undefined;
931
- }
932
- if (_pendingSentryOrgId !== undefined) {
933
- Sentry.setTag("orgId", _pendingSentryOrgId);
934
- _pendingSentryOrgId = undefined;
935
- }
987
+ if (_pendingSentryOrgId !== undefined) {
988
+ module.setTag("orgId", _pendingSentryOrgId);
989
+ _pendingSentryOrgId = undefined;
990
+ }
991
+ for (const pending of _pendingSentryCaptures) {
992
+ captureWithSentry(module, pending.error, pending.context);
993
+ }
994
+ _pendingSentryCaptures = [];
995
+ return module;
996
+ })
997
+ .catch(() => null)
998
+ .finally(() => {
999
+ _sentryLoadPromise = null;
1000
+ });
936
1001
  }
937
1002
 
938
1003
  /**
@@ -972,10 +1037,10 @@ export function setSentryUser(
972
1037
  ) {
973
1038
  void startConfiguredSessionReplay(_sessionReplayOptions);
974
1039
  }
975
- if (_sentryInitialized) {
976
- Sentry.setUser(user);
1040
+ if (_sentryInitialized && _sentryModule) {
1041
+ _sentryModule.setUser(user);
977
1042
  if (orgId !== undefined) {
978
- Sentry.setTag("orgId", orgId ?? null);
1043
+ _sentryModule.setTag("orgId", orgId ?? null);
979
1044
  }
980
1045
  return;
981
1046
  }
@@ -1024,25 +1089,12 @@ export function captureClientException(
1024
1089
  ): string | undefined {
1025
1090
  if (typeof window === "undefined") return undefined;
1026
1091
  try {
1027
- ensureSentry();
1028
- return Sentry.withScope((scope) => {
1029
- if (context.tags) {
1030
- for (const [k, v] of Object.entries(context.tags)) {
1031
- if (typeof v === "string") scope.setTag(k, v);
1032
- }
1033
- }
1034
- if (context.extra) {
1035
- for (const [k, v] of Object.entries(context.extra)) {
1036
- if (v !== undefined) scope.setExtra(k, v);
1037
- }
1038
- }
1039
- if (context.contexts) {
1040
- for (const [k, v] of Object.entries(context.contexts)) {
1041
- scope.setContext(k, v);
1042
- }
1043
- }
1044
- return Sentry.captureException(error);
1045
- });
1092
+ ensureSentry(true);
1093
+ if (_sentryModule) return captureWithSentry(_sentryModule, error, context);
1094
+ if (_pendingSentryCaptures.length < 50) {
1095
+ _pendingSentryCaptures.push({ error, context });
1096
+ }
1097
+ return undefined;
1046
1098
  } catch {
1047
1099
  return undefined;
1048
1100
  }
@@ -1647,6 +1699,7 @@ function pageviewProperties(reason: string): Record<string, unknown> {
1647
1699
  }
1648
1700
 
1649
1701
  function emitPageview(reason: string): void {
1702
+ if (typeof window === "undefined") return;
1650
1703
  if (isLocalAnalyticsHostname(window.location.hostname)) return;
1651
1704
  const state = getPageviewTrackingState();
1652
1705
  const key = pageviewKey();
@@ -1767,7 +1820,11 @@ export function trackEvent(
1767
1820
  const props = resolveProps(name, params);
1768
1821
  window.gtag?.("event", name.replace(/\s+/g, "_"), props);
1769
1822
  if (ensureAmplitude()) {
1770
- amplitude.track(name, props);
1823
+ _amplitudeModule?.track(name, props);
1824
+ } else if (_amplitudeApiKey) {
1825
+ if (_pendingAmplitudeEvents.length < 100) {
1826
+ _pendingAmplitudeEvents.push([name, props]);
1827
+ }
1771
1828
  }
1772
1829
  sendAgentNativeAnalytics(name, props);
1773
1830
  }
@@ -948,6 +948,7 @@ export function assistantMessageHasCompletedCustomUi(
948
948
  type?: unknown;
949
949
  result?: unknown;
950
950
  isError?: unknown;
951
+ outcome?: unknown;
951
952
  activity?: unknown;
952
953
  chatUI?: unknown;
953
954
  mcpApp?: unknown;
@@ -956,7 +957,8 @@ export function assistantMessageHasCompletedCustomUi(
956
957
  record.type !== "tool-call" ||
957
958
  record.activity === true ||
958
959
  record.result === undefined ||
959
- record.isError === true
960
+ record.isError === true ||
961
+ record.outcome === "unknown"
960
962
  ) {
961
963
  continue;
962
964
  }
@@ -1085,13 +1087,20 @@ export function shouldShowAssistantWorkSummary({
1085
1087
  isComplete,
1086
1088
  hasCollapsibleWork,
1087
1089
  hasUnresolvedTool,
1090
+ chatRunning,
1088
1091
  }: {
1089
1092
  isLast: boolean;
1090
1093
  isComplete: boolean;
1091
1094
  hasCollapsibleWork: boolean;
1092
1095
  hasUnresolvedTool: boolean;
1096
+ chatRunning: boolean;
1093
1097
  }): boolean {
1094
- if (!hasCollapsibleWork || hasUnresolvedTool) return false;
1098
+ if (!hasCollapsibleWork) return false;
1099
+
1100
+ // An unresolved tool means "still working" only while the turn is actually
1101
+ // running. On a stalled or interrupted turn it used to hide the summary
1102
+ // forever, so the longest turns showed no "Worked for Xm Ys" at all.
1103
+ if (hasUnresolvedTool) return !(isLast && chatRunning);
1095
1104
 
1096
1105
  // Keep completed historical work wrapped while a later turn is running.
1097
1106
  // Removing the wrapper exposes/remounts ReasoningCell and resets its
@@ -1447,6 +1456,7 @@ export function AssistantMessage() {
1447
1456
  isComplete,
1448
1457
  hasCollapsibleWork,
1449
1458
  hasUnresolvedTool,
1459
+ chatRunning,
1450
1460
  });
1451
1461
  if (!showSummary) return <>{children}</>;
1452
1462
  return (
@@ -1510,9 +1520,6 @@ export function AssistantMessage() {
1510
1520
  variant="response"
1511
1521
  />
1512
1522
  )}
1513
- {isLast && hasUnresolvedTool && !chatRunning && (
1514
- <RunningActivityStatus label="Thinking" />
1515
- )}
1516
1523
  </div>
1517
1524
  {isComplete && (
1518
1525
  <div className="mt-1 flex items-center justify-between">
@@ -1656,7 +1656,7 @@ function applyRuntimeEventToContent(
1656
1656
  }
1657
1657
  if (typed.type === "error") {
1658
1658
  const normalized = normalizeChatError(typed.error, typed.code);
1659
- settleInterruptedToolCalls(content);
1659
+ settleInterruptedToolCalls(content, undefined, { includeActivity: true });
1660
1660
  content.push({
1661
1661
  type: "text",
1662
1662
  text: formatChatErrorText(typed.error, undefined, typed.code),
@@ -1677,6 +1677,7 @@ function applyRuntimeEventToContent(
1677
1677
  } as ChatModelRunResult;
1678
1678
  }
1679
1679
  if (typed.type === "done") {
1680
+ settleInterruptedToolCalls(content, undefined, { includeActivity: true });
1680
1681
  return {
1681
1682
  content: [...content],
1682
1683
  status:
@@ -4,6 +4,7 @@
4
4
  import type { ToolCallMessagePartProps } from "@assistant-ui/react";
5
5
  import {
6
6
  IconLoader2,
7
+ IconAlertTriangle,
7
8
  IconCircleX,
8
9
  IconCheck,
9
10
  IconChevronRight,
@@ -583,6 +584,7 @@ export function ToolCallDisplay({
583
584
  mcpApp,
584
585
  chatUI,
585
586
  isRunning,
587
+ outcome,
586
588
  structuredMeta,
587
589
  approval,
588
590
  repeatCount,
@@ -596,6 +598,8 @@ export function ToolCallDisplay({
596
598
  mcpApp?: AgentMcpAppPayload;
597
599
  chatUI?: ActionChatUIConfig;
598
600
  isRunning: boolean;
601
+ /** "unknown": the stream ended mid-flight, so the side effect may have landed. */
602
+ outcome?: "unknown";
599
603
  structuredMeta?: Record<string, unknown>;
600
604
  approval?: { approvalKey: string; dismissed?: boolean };
601
605
  repeatCount?: number;
@@ -661,6 +665,7 @@ export function ToolCallDisplay({
661
665
  mcpApp={mcpApp}
662
666
  chatUI={chatUI}
663
667
  isRunning={isRunning}
668
+ outcome={outcome}
664
669
  isActiveTail={showActiveTail}
665
670
  structuredMeta={structuredMeta}
666
671
  approval={approval}
@@ -677,6 +682,7 @@ function ToolCallDisplayGeneric({
677
682
  mcpApp,
678
683
  chatUI,
679
684
  isRunning,
685
+ outcome,
680
686
  isActiveTail,
681
687
  structuredMeta,
682
688
  approval,
@@ -689,6 +695,7 @@ function ToolCallDisplayGeneric({
689
695
  mcpApp?: AgentMcpAppPayload;
690
696
  chatUI?: ActionChatUIConfig;
691
697
  isRunning: boolean;
698
+ outcome?: "unknown";
692
699
  isActiveTail: boolean;
693
700
  structuredMeta?: Record<string, unknown>;
694
701
  approval?: { approvalKey: string; dismissed?: boolean };
@@ -704,6 +711,7 @@ function ToolCallDisplayGeneric({
704
711
  ? args.agent
705
712
  : null;
706
713
  const isAgentError = isAgentCall && result === "Error calling agent";
714
+ const isUnknownOutcome = !isRunning && outcome === "unknown";
707
715
  const agentStreamText = isRawCallAgent
708
716
  ? (result ?? "")
709
717
  : isAgentCall
@@ -865,6 +873,8 @@ function ToolCallDisplayGeneric({
865
873
  <IconLoader2 className="size-3.5 animate-spin" />
866
874
  ) : isAgentError ? (
867
875
  <IconCircleX className="size-3.5 text-destructive" />
876
+ ) : isUnknownOutcome ? (
877
+ <IconAlertTriangle className="size-3.5 text-muted-foreground" />
868
878
  ) : (
869
879
  <>
870
880
  <ToolIcon
@@ -929,6 +939,12 @@ function ToolCallDisplayGeneric({
929
939
  )}
930
940
  </div>
931
941
  </AnimatedCollapse>
942
+ {isUnknownOutcome && (
943
+ <p role="status" className="ps-5 text-xs text-muted-foreground">
944
+ Interrupted before this finished reporting — it may or may not have
945
+ completed. Check before retrying.
946
+ </p>
947
+ )}
932
948
  {approval && (
933
949
  <ApprovalAffordance toolName={toolName} approval={approval} />
934
950
  )}
@@ -1149,14 +1165,19 @@ export function ToolCallFallback({
1149
1165
  chatUI?: ActionChatUIConfig;
1150
1166
  structuredMeta?: Record<string, unknown>;
1151
1167
  activity?: boolean;
1168
+ outcome?: "unknown";
1152
1169
  approval?: { approvalKey: string; dismissed?: boolean };
1153
1170
  repeatCount?: number;
1154
1171
  isLatestRunning?: boolean;
1155
1172
  isActiveTail?: boolean;
1156
1173
  }) {
1157
1174
  const chatRunning = React.useContext(ChatRunningContext);
1158
- const isRunning =
1159
- result === undefined && (chatRunning || rest.activity === true);
1175
+ // A spinner is a claim that something is running right now, so it needs an
1176
+ // actually-running chat. `chatRunning` already stays true across
1177
+ // auto-continuation gaps and server-active runs (resolveAssistantChatRunningState),
1178
+ // so an activity placeholder alone must never resurrect one on rehydrated
1179
+ // history.
1180
+ const isRunning = result === undefined && chatRunning;
1160
1181
  return (
1161
1182
  <ToolCallDisplay
1162
1183
  toolName={toolName}
@@ -1173,6 +1194,7 @@ export function ToolCallFallback({
1173
1194
  chatUI={rest.chatUI}
1174
1195
  structuredMeta={rest.structuredMeta}
1175
1196
  isRunning={isRunning}
1197
+ outcome={rest.outcome}
1176
1198
  isActiveTail={rest.isActiveTail}
1177
1199
  isLatestRunning={rest.isLatestRunning}
1178
1200
  approval={rest.approval}
@@ -1247,6 +1269,7 @@ export function ReconnectStreamMessage({
1247
1269
  mcpApp={part.mcpApp}
1248
1270
  chatUI={part.chatUI}
1249
1271
  structuredMeta={part.structuredMeta}
1272
+ outcome={part.outcome}
1250
1273
  isRunning={
1251
1274
  part.result === undefined && (chatRunning || part.activity === true)
1252
1275
  }
@@ -40,6 +40,9 @@ function addCurrentModel(
40
40
  return next;
41
41
  }
42
42
 
43
+ // Cheapest → most expensive. The composer mirrors these tokens for the `$`
44
+ // cost labels on picker rows (packages/toolkit/src/composer/TiptapComposer.tsx);
45
+ // the toolkit cannot import core, so a new family must be added in both lists.
43
46
  const MODEL_COST_ORDER = [
44
47
  "luna",
45
48
  "terra",