@agent-native/core 0.149.2 → 0.149.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 (345) hide show
  1. package/corpus/README.md +1 -1
  2. package/corpus/templates/analytics/.agents/skills/actions/SKILL.md +54 -488
  3. package/corpus/templates/analytics/.agents/skills/actions/references/action-fields.md +136 -0
  4. package/corpus/templates/analytics/.agents/skills/actions/references/examples.md +94 -0
  5. package/corpus/templates/analytics/.agents/skills/actions/references/provider-apis.md +95 -0
  6. package/corpus/templates/analytics/.agents/skills/create-skill/SKILL.md +9 -35
  7. package/corpus/templates/analytics/.agents/skills/creative-context/SKILL.md +4 -2
  8. package/corpus/templates/analytics/.agents/skills/frontend-design/SKILL.md +4 -5
  9. package/corpus/templates/analytics/.agents/skills/turn-into-app/SKILL.md +18 -31
  10. package/corpus/templates/analytics/AGENTS.md +25 -32
  11. package/corpus/templates/analytics/app/global.css +1 -1
  12. package/corpus/templates/analytics/changelog/2026-08-11-full-page-chat-composers-stay-at-a-focused-750px-width.md +6 -0
  13. package/corpus/templates/assets/.agents/skills/actions/SKILL.md +54 -488
  14. package/corpus/templates/assets/.agents/skills/actions/references/action-fields.md +136 -0
  15. package/corpus/templates/assets/.agents/skills/actions/references/examples.md +94 -0
  16. package/corpus/templates/assets/.agents/skills/actions/references/provider-apis.md +95 -0
  17. package/corpus/templates/assets/.agents/skills/create-skill/SKILL.md +9 -35
  18. package/corpus/templates/assets/.agents/skills/creative-context/SKILL.md +4 -2
  19. package/corpus/templates/assets/.agents/skills/frontend-design/SKILL.md +4 -5
  20. package/corpus/templates/assets/.agents/skills/turn-into-app/SKILL.md +18 -31
  21. package/corpus/templates/assets/AGENTS.md +6 -9
  22. package/corpus/templates/assets/app/global.css +1 -1
  23. package/corpus/templates/assets/changelog/2026-08-11-full-page-chat-composers-stay-at-a-focused-750px-width.md +6 -0
  24. package/corpus/templates/brain/.agents/skills/actions/SKILL.md +54 -488
  25. package/corpus/templates/brain/.agents/skills/actions/references/action-fields.md +136 -0
  26. package/corpus/templates/brain/.agents/skills/actions/references/examples.md +94 -0
  27. package/corpus/templates/brain/.agents/skills/actions/references/provider-apis.md +95 -0
  28. package/corpus/templates/brain/.agents/skills/create-skill/SKILL.md +9 -35
  29. package/corpus/templates/brain/.agents/skills/frontend-design/SKILL.md +4 -5
  30. package/corpus/templates/brain/.agents/skills/turn-into-app/SKILL.md +18 -31
  31. package/corpus/templates/brain/AGENTS.md +5 -12
  32. package/corpus/templates/brain/app/global.css +1 -1
  33. package/corpus/templates/brain/changelog/2026-08-11-full-page-chat-composers-stay-at-a-focused-750px-width.md +6 -0
  34. package/corpus/templates/calendar/.agents/skills/actions/SKILL.md +54 -488
  35. package/corpus/templates/calendar/.agents/skills/actions/references/action-fields.md +136 -0
  36. package/corpus/templates/calendar/.agents/skills/actions/references/examples.md +94 -0
  37. package/corpus/templates/calendar/.agents/skills/actions/references/provider-apis.md +95 -0
  38. package/corpus/templates/calendar/.agents/skills/create-skill/SKILL.md +9 -35
  39. package/corpus/templates/calendar/.agents/skills/frontend-design/SKILL.md +4 -5
  40. package/corpus/templates/calendar/.agents/skills/turn-into-app/SKILL.md +18 -31
  41. package/corpus/templates/calendar/AGENTS.md +8 -9
  42. package/corpus/templates/chat/.agents/skills/actions/SKILL.md +54 -488
  43. package/corpus/templates/chat/.agents/skills/actions/references/action-fields.md +136 -0
  44. package/corpus/templates/chat/.agents/skills/actions/references/examples.md +94 -0
  45. package/corpus/templates/chat/.agents/skills/actions/references/provider-apis.md +95 -0
  46. package/corpus/templates/chat/.agents/skills/create-skill/SKILL.md +9 -35
  47. package/corpus/templates/chat/.agents/skills/frontend-design/SKILL.md +4 -5
  48. package/corpus/templates/chat/.agents/skills/turn-into-app/SKILL.md +18 -31
  49. package/corpus/templates/chat/AGENTS.md +32 -80
  50. package/corpus/templates/clips/.agents/skills/actions/SKILL.md +54 -488
  51. package/corpus/templates/clips/.agents/skills/actions/references/action-fields.md +136 -0
  52. package/corpus/templates/clips/.agents/skills/actions/references/examples.md +94 -0
  53. package/corpus/templates/clips/.agents/skills/actions/references/provider-apis.md +95 -0
  54. package/corpus/templates/clips/.agents/skills/create-skill/SKILL.md +9 -35
  55. package/corpus/templates/clips/.agents/skills/frontend-design/SKILL.md +4 -5
  56. package/corpus/templates/clips/.agents/skills/turn-into-app/SKILL.md +18 -31
  57. package/corpus/templates/clips/AGENTS.md +25 -31
  58. package/corpus/templates/content/.agents/skills/actions/SKILL.md +54 -488
  59. package/corpus/templates/content/.agents/skills/actions/references/action-fields.md +136 -0
  60. package/corpus/templates/content/.agents/skills/actions/references/examples.md +94 -0
  61. package/corpus/templates/content/.agents/skills/actions/references/provider-apis.md +95 -0
  62. package/corpus/templates/content/.agents/skills/create-skill/SKILL.md +9 -35
  63. package/corpus/templates/content/.agents/skills/creative-context/SKILL.md +4 -2
  64. package/corpus/templates/content/.agents/skills/frontend-design/SKILL.md +4 -5
  65. package/corpus/templates/content/.agents/skills/turn-into-app/SKILL.md +18 -31
  66. package/corpus/templates/content/AGENTS.md +5 -9
  67. package/corpus/templates/crm/.agents/skills/turn-into-app/SKILL.md +18 -31
  68. package/corpus/templates/crm/AGENTS.md +7 -11
  69. package/corpus/templates/crm/app/global.css +1 -1
  70. package/corpus/templates/crm/changelog/2026-08-11-full-page-chat-composers-stay-at-a-focused-750px-width.md +6 -0
  71. package/corpus/templates/design/.agents/skills/actions/SKILL.md +54 -488
  72. package/corpus/templates/design/.agents/skills/actions/references/action-fields.md +136 -0
  73. package/corpus/templates/design/.agents/skills/actions/references/examples.md +94 -0
  74. package/corpus/templates/design/.agents/skills/actions/references/provider-apis.md +95 -0
  75. package/corpus/templates/design/.agents/skills/create-skill/SKILL.md +9 -35
  76. package/corpus/templates/design/.agents/skills/creative-context/SKILL.md +4 -2
  77. package/corpus/templates/design/.agents/skills/frontend-design/SKILL.md +4 -5
  78. package/corpus/templates/design/.agents/skills/turn-into-app/SKILL.md +18 -31
  79. package/corpus/templates/design/.generated/bridge/editor-chrome.generated.ts +70 -3
  80. package/corpus/templates/design/AGENTS.md +13 -21
  81. package/corpus/templates/design/app/components/design/DesignCanvas.tsx +12 -0
  82. package/corpus/templates/design/app/components/design/LayersPanel.tsx +19 -2
  83. package/corpus/templates/design/app/components/design/MultiScreenCanvas.tsx +115 -7
  84. package/corpus/templates/design/app/components/design/bridge/editor-chrome.bridge.ts +82 -7
  85. package/corpus/templates/design/app/components/design/design-trace.ts +120 -0
  86. package/corpus/templates/design/app/components/design/dnd-debug.ts +2 -1
  87. package/corpus/templates/design/app/components/design/edit-panel/position-layout-properties.tsx +40 -26
  88. package/corpus/templates/design/app/components/design/multi-screen/board-surface-html.ts +4 -1
  89. package/corpus/templates/design/app/components/design/multi-screen/frame-geometry.ts +12 -3
  90. package/corpus/templates/design/app/components/design/multi-screen/screen-content-cache.ts +4 -0
  91. package/corpus/templates/design/app/components/design/multi-screen/types.ts +7 -0
  92. package/corpus/templates/design/app/components/editor/PromptDialog.tsx +3 -2
  93. package/corpus/templates/design/app/components/layout/Sidebar.tsx +2 -2
  94. package/corpus/templates/design/app/hooks/useDesignHotkeys.ts +3 -0
  95. package/corpus/templates/design/app/i18n-data.ts +1 -0
  96. package/corpus/templates/design/app/pages/DesignSystemSetup.tsx +5 -5
  97. package/corpus/templates/design/app/pages/DesignSystems.tsx +3 -2
  98. package/corpus/templates/design/app/pages/design-editor/canvas-primitive-insert.ts +100 -13
  99. package/corpus/templates/design/app/pages/design-editor/cross-screen-text-color.ts +1 -1
  100. package/corpus/templates/design/app/pages/design-editor/data-operations.ts +14 -0
  101. package/corpus/templates/design/changelog/2026-08-10-marquee-selecting-layers-far-down-a-tall-screen-now-selects-.md +6 -0
  102. package/corpus/templates/design/changelog/2026-08-10-the-frame-tool-draws-a-plain-frame-by-default-with-screen-av.md +6 -0
  103. package/corpus/templates/design/e2e/global-setup.ts +27 -32
  104. package/corpus/templates/design/playwright.config.ts +3 -5
  105. package/corpus/templates/design/shared/breakpoint-media.ts +9 -2
  106. package/corpus/templates/dispatch/.agents/skills/actions/SKILL.md +54 -488
  107. package/corpus/templates/dispatch/.agents/skills/actions/references/action-fields.md +136 -0
  108. package/corpus/templates/dispatch/.agents/skills/actions/references/examples.md +94 -0
  109. package/corpus/templates/dispatch/.agents/skills/actions/references/provider-apis.md +95 -0
  110. package/corpus/templates/dispatch/.agents/skills/create-skill/SKILL.md +9 -35
  111. package/corpus/templates/dispatch/.agents/skills/frontend-design/SKILL.md +4 -5
  112. package/corpus/templates/dispatch/.agents/skills/turn-into-app/SKILL.md +18 -31
  113. package/corpus/templates/dispatch/AGENTS.md +9 -16
  114. package/corpus/templates/factory/.agents/skills/actions/SKILL.md +54 -488
  115. package/corpus/templates/factory/.agents/skills/actions/references/action-fields.md +136 -0
  116. package/corpus/templates/factory/.agents/skills/actions/references/examples.md +94 -0
  117. package/corpus/templates/factory/.agents/skills/actions/references/provider-apis.md +95 -0
  118. package/corpus/templates/factory/.agents/skills/create-skill/SKILL.md +9 -35
  119. package/corpus/templates/factory/.agents/skills/frontend-design/SKILL.md +4 -5
  120. package/corpus/templates/factory/.agents/skills/turn-into-app/SKILL.md +18 -31
  121. package/corpus/templates/factory/AGENTS.md +10 -24
  122. package/corpus/templates/forms/.agents/skills/actions/SKILL.md +54 -488
  123. package/corpus/templates/forms/.agents/skills/actions/references/action-fields.md +136 -0
  124. package/corpus/templates/forms/.agents/skills/actions/references/examples.md +94 -0
  125. package/corpus/templates/forms/.agents/skills/actions/references/provider-apis.md +95 -0
  126. package/corpus/templates/forms/.agents/skills/create-skill/SKILL.md +9 -35
  127. package/corpus/templates/forms/.agents/skills/frontend-design/SKILL.md +4 -5
  128. package/corpus/templates/forms/.agents/skills/turn-into-app/SKILL.md +18 -31
  129. package/corpus/templates/forms/AGENTS.md +11 -17
  130. package/corpus/templates/forms/app/global.css +1 -0
  131. package/corpus/templates/forms/changelog/2026-08-11-full-page-chat-composers-stay-at-a-focused-750px-width.md +6 -0
  132. package/corpus/templates/macros/.agents/skills/frontend-design/SKILL.md +4 -5
  133. package/corpus/templates/macros/.agents/skills/turn-into-app/SKILL.md +18 -31
  134. package/corpus/templates/macros/AGENTS.md +8 -8
  135. package/corpus/templates/mail/.agents/skills/actions/SKILL.md +54 -488
  136. package/corpus/templates/mail/.agents/skills/actions/references/action-fields.md +136 -0
  137. package/corpus/templates/mail/.agents/skills/actions/references/examples.md +94 -0
  138. package/corpus/templates/mail/.agents/skills/actions/references/provider-apis.md +95 -0
  139. package/corpus/templates/mail/.agents/skills/create-skill/SKILL.md +9 -35
  140. package/corpus/templates/mail/.agents/skills/frontend-design/SKILL.md +4 -5
  141. package/corpus/templates/mail/.agents/skills/turn-into-app/SKILL.md +18 -31
  142. package/corpus/templates/mail/AGENTS.md +5 -6
  143. package/corpus/templates/plan/.agents/skills/actions/SKILL.md +54 -488
  144. package/corpus/templates/plan/.agents/skills/actions/references/action-fields.md +136 -0
  145. package/corpus/templates/plan/.agents/skills/actions/references/examples.md +94 -0
  146. package/corpus/templates/plan/.agents/skills/actions/references/provider-apis.md +95 -0
  147. package/corpus/templates/plan/.agents/skills/create-skill/SKILL.md +9 -35
  148. package/corpus/templates/plan/.agents/skills/frontend-design/SKILL.md +4 -5
  149. package/corpus/templates/plan/.agents/skills/turn-into-app/SKILL.md +18 -31
  150. package/corpus/templates/plan/AGENTS.md +5 -14
  151. package/corpus/templates/plan/changelog/2026-08-11-plan-no-longer-reloads-when-runtime-state-changes.md +6 -0
  152. package/corpus/templates/plan/vite.config.ts +5 -0
  153. package/corpus/templates/slides/.agents/skills/actions/SKILL.md +54 -488
  154. package/corpus/templates/slides/.agents/skills/actions/references/action-fields.md +136 -0
  155. package/corpus/templates/slides/.agents/skills/actions/references/examples.md +94 -0
  156. package/corpus/templates/slides/.agents/skills/actions/references/provider-apis.md +95 -0
  157. package/corpus/templates/slides/.agents/skills/create-deck/SKILL.md +2 -2
  158. package/corpus/templates/slides/.agents/skills/create-skill/SKILL.md +9 -35
  159. package/corpus/templates/slides/.agents/skills/creative-context/SKILL.md +6 -3
  160. package/corpus/templates/slides/.agents/skills/deck-management/SKILL.md +6 -1
  161. package/corpus/templates/slides/.agents/skills/frontend-design/SKILL.md +4 -5
  162. package/corpus/templates/slides/.agents/skills/image-generation-via-a2a/SKILL.md +3 -2
  163. package/corpus/templates/slides/.agents/skills/slide-editing/SKILL.md +3 -0
  164. package/corpus/templates/slides/.agents/skills/slide-images/SKILL.md +3 -3
  165. package/corpus/templates/slides/.agents/skills/turn-into-app/SKILL.md +18 -31
  166. package/corpus/templates/slides/AGENTS.md +22 -25
  167. package/corpus/templates/slides/actions/get-deck-reference-context.ts +2 -2
  168. package/corpus/templates/slides/actions/get-deck.ts +57 -9
  169. package/corpus/templates/slides/actions/import-file.ts +2 -1
  170. package/corpus/templates/slides/actions/patch-deck.ts +45 -2
  171. package/corpus/templates/slides/actions/update-slide.ts +1 -1
  172. package/corpus/templates/slides/app/components/comments/SlideCommentsPanel.tsx +2 -2
  173. package/corpus/templates/slides/app/components/deck/DeckCard.tsx +1 -23
  174. package/corpus/templates/slides/app/components/design-system/DesignSystemCard.tsx +2 -2
  175. package/corpus/templates/slides/app/components/design-system/DesignSystemSetup.tsx +6 -6
  176. package/corpus/templates/slides/app/components/editor/AnimationsPanel.tsx +3 -3
  177. package/corpus/templates/slides/app/components/editor/DeckEditorSkeleton.tsx +4 -4
  178. package/corpus/templates/slides/app/components/editor/EditorSidebar.tsx +1 -1
  179. package/corpus/templates/slides/app/components/editor/EditorToolbar.tsx +428 -180
  180. package/corpus/templates/slides/app/components/editor/ExportMenu.tsx +294 -266
  181. package/corpus/templates/slides/app/components/editor/PromptDialog.tsx +7 -5
  182. package/corpus/templates/slides/app/components/editor/SlideContextToolbar.tsx +1 -1
  183. package/corpus/templates/slides/app/components/editor/SlideEditor.tsx +40 -12
  184. package/corpus/templates/slides/app/components/editor/SpeakerNotesPanel.tsx +6 -12
  185. package/corpus/templates/slides/app/components/editor/editor-command-model.ts +35 -0
  186. package/corpus/templates/slides/app/components/layout/Sidebar.tsx +8 -10
  187. package/corpus/templates/slides/app/context/DeckContext.tsx +2 -1
  188. package/corpus/templates/slides/app/global.css +76 -1
  189. package/corpus/templates/slides/app/i18n/en-US.ts +1 -0
  190. package/corpus/templates/slides/app/lib/create-deck-generation.ts +51 -23
  191. package/corpus/templates/slides/app/lib/slide-animation-elements.ts +68 -5
  192. package/corpus/templates/slides/app/pages/DeckEditor.tsx +13 -6
  193. package/corpus/templates/slides/app/pages/DesignSystems.tsx +2 -2
  194. package/corpus/templates/slides/app/pages/Index.tsx +87 -74
  195. package/corpus/templates/slides/app/root.tsx +43 -0
  196. package/corpus/templates/slides/changelog/2026-08-11-faster-slides-chat-deck-reads.md +6 -0
  197. package/corpus/templates/slides/changelog/2026-08-11-slides-chat-can-read-one-slide-without-loading-the-full-deck.md +6 -0
  198. package/corpus/templates/slides/changelog/2026-08-11-slides-clearly-indicate-when-an-ai-agent-is-editing-alongsid.md +6 -0
  199. package/corpus/templates/slides/package.json +1 -0
  200. package/corpus/templates/slides/server/lib/validate-slide-animations.ts +163 -0
  201. package/corpus/templates/slides/server/plugins/agent-chat.ts +4 -3
  202. package/corpus/templates/slides/shared/api.ts +46 -15
  203. package/corpus/templates/tasks/.agents/skills/actions/SKILL.md +54 -488
  204. package/corpus/templates/tasks/.agents/skills/actions/references/action-fields.md +136 -0
  205. package/corpus/templates/tasks/.agents/skills/actions/references/examples.md +94 -0
  206. package/corpus/templates/tasks/.agents/skills/actions/references/provider-apis.md +95 -0
  207. package/corpus/templates/tasks/.agents/skills/agent-watchdog/SKILL.md +1 -0
  208. package/corpus/templates/tasks/.agents/skills/create-skill/SKILL.md +9 -35
  209. package/corpus/templates/tasks/.agents/skills/efficient-fable/SKILL.md +1 -0
  210. package/corpus/templates/tasks/.agents/skills/efficient-frontier/SKILL.md +1 -0
  211. package/corpus/templates/tasks/.agents/skills/frontend-design/SKILL.md +4 -5
  212. package/corpus/templates/tasks/.agents/skills/plan-arbiter/SKILL.md +1 -0
  213. package/corpus/templates/tasks/.agents/skills/plow-ahead/SKILL.md +1 -0
  214. package/corpus/templates/tasks/.agents/skills/quick-recap/SKILL.md +1 -0
  215. package/corpus/templates/tasks/.agents/skills/read-the-damn-docs/SKILL.md +1 -0
  216. package/corpus/templates/tasks/.agents/skills/stay-within-limits/SKILL.md +1 -0
  217. package/corpus/templates/tasks/.agents/skills/turn-into-app/SKILL.md +18 -31
  218. package/corpus/templates/tasks/AGENTS.md +5 -20
  219. package/dist/agent/production-agent.js +376 -345
  220. package/dist/agent/run-manager.js +156 -14
  221. package/dist/agent/run-store.d.ts +11 -10
  222. package/dist/agent/run-store.js +17 -13
  223. package/dist/client/AssistantChat.d.ts +6 -2
  224. package/dist/client/AssistantChat.js +216 -131
  225. package/dist/client/active-run-state.d.ts +9 -1
  226. package/dist/client/active-run-state.js +34 -3
  227. package/dist/client/agent-chat-adapter.d.ts +8 -0
  228. package/dist/client/agent-chat-adapter.js +114 -28
  229. package/dist/client/chat/message-components.d.ts +7 -1
  230. package/dist/client/chat/message-components.js +32 -5
  231. package/dist/client/chat/run-recovery.d.ts +1 -0
  232. package/dist/client/chat/run-recovery.js +8 -0
  233. package/dist/client/chat/tool-call-display.d.ts +2 -0
  234. package/dist/client/chat/tool-call-display.js +2 -0
  235. package/dist/client/chat-first/apps-rail.js +1 -1
  236. package/dist/client/chat-first/chat-history.d.ts +1 -1
  237. package/dist/client/chat-first/chat-history.js +5 -2
  238. package/dist/client/sse-event-processor.d.ts +4 -2
  239. package/dist/client/sse-event-processor.js +36 -6
  240. package/dist/client/use-run-stuck-detection.d.ts +2 -0
  241. package/dist/client/use-run-stuck-detection.js +85 -9
  242. package/dist/collab/awareness.d.ts +2 -2
  243. package/dist/collab/routes.d.ts +1 -1
  244. package/dist/integrations/adapters/slack.d.ts +0 -4
  245. package/dist/integrations/adapters/slack.js +6 -30
  246. package/dist/integrations/catalog.js +1 -1
  247. package/dist/integrations/pending-tasks-store.d.ts +0 -8
  248. package/dist/integrations/pending-tasks-store.js +0 -21
  249. package/dist/integrations/slack-manifest.d.ts +2 -2
  250. package/dist/integrations/slack-manifest.js +0 -3
  251. package/dist/mcp/screen-memory-stdio.d.ts +7 -7
  252. package/dist/observability/routes.d.ts +3 -3
  253. package/dist/provider-api/actions/custom-provider-registration.d.ts +4 -4
  254. package/dist/provider-api/actions/provider-api.d.ts +8 -8
  255. package/dist/resources/handlers.d.ts +1 -1
  256. package/dist/scripts/docs/source-search.js +2 -2
  257. package/dist/secrets/routes.d.ts +9 -9
  258. package/dist/server/agent-chat/framework-prompts.js +7 -2
  259. package/dist/server/agent-chat/prompt-resources.js +2 -2
  260. package/dist/server/agent-chat/skill-frontmatter.d.ts +31 -2
  261. package/dist/server/agent-chat/skill-frontmatter.js +41 -15
  262. package/dist/server/agent-chat-plugin.js +3 -3
  263. package/dist/server/agent-engine-api-key-route.d.ts +1 -1
  264. package/dist/server/agents-bundle.d.ts +16 -19
  265. package/dist/server/agents-bundle.js +19 -35
  266. package/dist/server/better-auth-instance.d.ts +1 -0
  267. package/dist/server/better-auth-instance.js +17 -2
  268. package/dist/server/prompts/framework-core-compact.d.ts +6 -1
  269. package/dist/server/prompts/framework-core-compact.js +12 -9
  270. package/dist/server/prompts/framework-core.d.ts +6 -1
  271. package/dist/server/prompts/framework-core.js +11 -9
  272. package/dist/server/prompts/index.d.ts +1 -1
  273. package/dist/server/prompts/index.js +1 -1
  274. package/dist/server/prompts/shared-rules.d.ts +15 -11
  275. package/dist/server/prompts/shared-rules.js +17 -13
  276. package/dist/server/realtime-token.d.ts +1 -1
  277. package/dist/server/transcribe-voice.d.ts +1 -1
  278. package/dist/templates/chat/.agents/skills/actions/SKILL.md +54 -488
  279. package/dist/templates/chat/.agents/skills/actions/references/action-fields.md +136 -0
  280. package/dist/templates/chat/.agents/skills/actions/references/examples.md +94 -0
  281. package/dist/templates/chat/.agents/skills/actions/references/provider-apis.md +95 -0
  282. package/dist/templates/chat/.agents/skills/create-skill/SKILL.md +9 -35
  283. package/dist/templates/chat/.agents/skills/frontend-design/SKILL.md +4 -5
  284. package/dist/templates/chat/.agents/skills/turn-into-app/SKILL.md +18 -31
  285. package/dist/templates/chat/AGENTS.md +32 -80
  286. package/dist/templates/default/.agents/skills/actions/SKILL.md +54 -488
  287. package/dist/templates/default/.agents/skills/actions/references/action-fields.md +136 -0
  288. package/dist/templates/default/.agents/skills/actions/references/examples.md +94 -0
  289. package/dist/templates/default/.agents/skills/actions/references/provider-apis.md +95 -0
  290. package/dist/templates/default/.agents/skills/create-skill/SKILL.md +9 -35
  291. package/dist/templates/default/.agents/skills/frontend-design/SKILL.md +4 -5
  292. package/dist/templates/default/.agents/skills/turn-into-app/SKILL.md +18 -31
  293. package/dist/templates/headless/.agents/skills/actions/SKILL.md +54 -488
  294. package/dist/templates/headless/.agents/skills/actions/references/action-fields.md +136 -0
  295. package/dist/templates/headless/.agents/skills/actions/references/examples.md +94 -0
  296. package/dist/templates/headless/.agents/skills/actions/references/provider-apis.md +95 -0
  297. package/dist/templates/headless/.agents/skills/turn-into-app/SKILL.md +18 -31
  298. package/dist/templates/workspace-core/.agents/skills/actions/SKILL.md +54 -488
  299. package/dist/templates/workspace-core/.agents/skills/actions/references/action-fields.md +136 -0
  300. package/dist/templates/workspace-core/.agents/skills/actions/references/examples.md +94 -0
  301. package/dist/templates/workspace-core/.agents/skills/actions/references/provider-apis.md +95 -0
  302. package/dist/templates/workspace-core/.agents/skills/adding-workspace-apps/SKILL.md +1 -0
  303. package/dist/templates/workspace-core/.agents/skills/agent-page/SKILL.md +1 -0
  304. package/dist/templates/workspace-core/.agents/skills/create-skill/SKILL.md +9 -35
  305. package/dist/templates/workspace-core/.agents/skills/frontend-design/SKILL.md +4 -5
  306. package/dist/templates/workspace-core/.agents/skills/recurring-jobs/SKILL.md +21 -29
  307. package/dist/templates/workspace-core/.agents/skills/turn-into-app/SKILL.md +18 -31
  308. package/dist/templates/workspace-core/.agents/skills/workspace-conventions/SKILL.md +7 -17
  309. package/dist/templates/workspace-core/.agents/skills/writing-agent-instructions/SKILL.md +3 -3
  310. package/dist/templates/workspace-core/AGENTS.md +7 -16
  311. package/docs/content/messaging.mdx +6 -7
  312. package/package.json +1 -1
  313. package/src/templates/chat/.agents/skills/actions/SKILL.md +54 -488
  314. package/src/templates/chat/.agents/skills/actions/references/action-fields.md +136 -0
  315. package/src/templates/chat/.agents/skills/actions/references/examples.md +94 -0
  316. package/src/templates/chat/.agents/skills/actions/references/provider-apis.md +95 -0
  317. package/src/templates/chat/.agents/skills/create-skill/SKILL.md +9 -35
  318. package/src/templates/chat/.agents/skills/frontend-design/SKILL.md +4 -5
  319. package/src/templates/chat/.agents/skills/turn-into-app/SKILL.md +18 -31
  320. package/src/templates/chat/AGENTS.md +32 -80
  321. package/src/templates/default/.agents/skills/actions/SKILL.md +54 -488
  322. package/src/templates/default/.agents/skills/actions/references/action-fields.md +136 -0
  323. package/src/templates/default/.agents/skills/actions/references/examples.md +94 -0
  324. package/src/templates/default/.agents/skills/actions/references/provider-apis.md +95 -0
  325. package/src/templates/default/.agents/skills/create-skill/SKILL.md +9 -35
  326. package/src/templates/default/.agents/skills/frontend-design/SKILL.md +4 -5
  327. package/src/templates/default/.agents/skills/turn-into-app/SKILL.md +18 -31
  328. package/src/templates/headless/.agents/skills/actions/SKILL.md +54 -488
  329. package/src/templates/headless/.agents/skills/actions/references/action-fields.md +136 -0
  330. package/src/templates/headless/.agents/skills/actions/references/examples.md +94 -0
  331. package/src/templates/headless/.agents/skills/actions/references/provider-apis.md +95 -0
  332. package/src/templates/headless/.agents/skills/turn-into-app/SKILL.md +18 -31
  333. package/src/templates/workspace-core/.agents/skills/actions/SKILL.md +54 -488
  334. package/src/templates/workspace-core/.agents/skills/actions/references/action-fields.md +136 -0
  335. package/src/templates/workspace-core/.agents/skills/actions/references/examples.md +94 -0
  336. package/src/templates/workspace-core/.agents/skills/actions/references/provider-apis.md +95 -0
  337. package/src/templates/workspace-core/.agents/skills/adding-workspace-apps/SKILL.md +1 -0
  338. package/src/templates/workspace-core/.agents/skills/agent-page/SKILL.md +1 -0
  339. package/src/templates/workspace-core/.agents/skills/create-skill/SKILL.md +9 -35
  340. package/src/templates/workspace-core/.agents/skills/frontend-design/SKILL.md +4 -5
  341. package/src/templates/workspace-core/.agents/skills/recurring-jobs/SKILL.md +21 -29
  342. package/src/templates/workspace-core/.agents/skills/turn-into-app/SKILL.md +18 -31
  343. package/src/templates/workspace-core/.agents/skills/workspace-conventions/SKILL.md +7 -17
  344. package/src/templates/workspace-core/.agents/skills/writing-agent-instructions/SKILL.md +3 -3
  345. package/src/templates/workspace-core/AGENTS.md +7 -16
@@ -99,5 +99,5 @@ export const ChatFirstAppsRail = memo(function ChatFirstAppsRail({ apps, activeA
99
99
  ? "bg-sidebar-accent text-sidebar-accent-foreground"
100
100
  : "text-sidebar-foreground/70 hover:bg-sidebar-accent hover:text-sidebar-accent-foreground"), onClick: () => onOpenApp(app), "aria-label": copy("openApp", { name: app.name }), title: app.name, children: renderIcon(app) }, app.id))), onOpenAllApps ? (_jsx("button", { type: "button", "data-chat-first-all-apps": true, className: "flex size-9 items-center justify-center rounded-md text-sidebar-foreground/70 hover:bg-sidebar-accent hover:text-sidebar-accent-foreground", onClick: onOpenAllApps, "aria-label": copy("allApps"), title: copy("allApps"), children: _jsx(IconApps, { size: 16, "aria-hidden": "true" }) })) : null, error ? (_jsx("span", { className: "size-1.5 rounded-full bg-destructive", title: error, "aria-label": error })) : null] }));
101
101
  }
102
- return (_jsxs("section", { "data-chat-first-apps-rail": true, className: "mt-3 px-0 pb-2 pt-2", "aria-label": copy("workspaceApps"), children: [_jsxs("div", { className: "mb-1 flex items-center gap-1.5 px-2 text-[11px] font-medium text-sidebar-foreground/50", children: [_jsx("span", { children: copy("workspaceApps") }), _jsx("span", { className: "ml-auto", children: createTrigger })] }), loading && apps.length === 0 ? (_jsx("div", { className: "space-y-0.5 px-2", children: [0, 1, 2].map((index) => (_jsx(Skeleton, { className: "h-8 w-full rounded-md" }, index))) })) : apps.length === 0 ? (_jsxs("div", { className: "px-2", children: [_jsx("p", { className: "text-xs text-sidebar-foreground/55", children: copy("noWorkspaceApps") }), createAppTrigger ? (createTrigger) : onCreateApp ? (_jsxs("button", { type: "button", className: "mt-1 inline-flex h-6 items-center gap-1.5 rounded-md border border-sidebar-border px-2 text-xs text-sidebar-foreground/75 hover:bg-sidebar-accent hover:text-sidebar-foreground", onClick: onCreateApp, children: [_jsx(IconPlus, { size: 13, "aria-hidden": "true" }), copy("createApp")] })) : (createTrigger)] })) : (_jsx(AppRows, { apps: visibleApps, activeAppId: activeAppId, layout: layout, onDragStart: setDraggedAppId, onDrop: reorderApps, onDragEnd: () => setDraggedAppId(null), onOpenApp: onOpenApp, onTogglePinned: togglePinned, onMove: moveApp, renderIcon: renderIcon, copy: copy })), hasMoreApps || showAllApps ? (_jsxs("button", { type: "button", className: "mt-0.5 flex h-8 w-full items-center gap-2 rounded-md px-2 text-xs text-sidebar-foreground/50 hover:bg-sidebar-accent hover:text-sidebar-foreground", onClick: () => setShowAllApps((value) => !value), children: [showAllApps ? (_jsx(IconChevronUp, { size: 14, "aria-hidden": "true" })) : (_jsx(IconChevronDown, { size: 14, "aria-hidden": "true" })), showAllApps ? copy("showLess") : copy("showMore")] })) : null, onOpenAllApps ? (_jsx("div", { className: "mt-1 border-t border-sidebar-border/60 pt-1", children: _jsxs("button", { type: "button", "data-chat-first-all-apps": true, className: "flex h-8 w-full items-center gap-2 rounded-md px-2 text-xs text-sidebar-foreground/55 hover:bg-sidebar-accent hover:text-sidebar-foreground", onClick: onOpenAllApps, children: [_jsx(IconApps, { size: 14, "aria-hidden": "true" }), _jsx("span", { children: copy("allApps") })] }) })) : null, error ? (_jsxs(Tooltip, { children: [_jsx(TooltipTrigger, { asChild: true, children: _jsxs("button", { type: "button", className: "mt-1 flex items-center gap-1 px-2 text-[10px] text-destructive/80", onClick: onRetry, "aria-label": error, children: [_jsx("span", { className: "size-1.5 rounded-full bg-destructive" }), onRetry ? copy("retry") : copy("appsLoadError")] }) }), _jsx(TooltipContent, { side: "right", children: error })] })) : null] }));
102
+ return (_jsxs("section", { "data-chat-first-apps-rail": true, className: "mt-3 px-2 pb-2 pt-2", "aria-label": copy("workspaceApps"), children: [_jsxs("div", { className: "mb-1 flex items-center gap-1.5 px-2 text-[11px] font-medium text-sidebar-foreground/50", children: [_jsx("span", { children: copy("workspaceApps") }), _jsx("span", { className: "ml-auto", children: createTrigger })] }), loading && apps.length === 0 ? (_jsx("div", { className: "space-y-0.5 px-2", children: [0, 1, 2].map((index) => (_jsx(Skeleton, { className: "h-8 w-full rounded-md" }, index))) })) : apps.length === 0 ? (_jsxs("div", { className: "px-2", children: [_jsx("p", { className: "text-xs text-sidebar-foreground/55", children: copy("noWorkspaceApps") }), createAppTrigger ? (createTrigger) : onCreateApp ? (_jsxs("button", { type: "button", className: "mt-1 inline-flex h-6 items-center gap-1.5 rounded-md border border-sidebar-border px-2 text-xs text-sidebar-foreground/75 hover:bg-sidebar-accent hover:text-sidebar-foreground", onClick: onCreateApp, children: [_jsx(IconPlus, { size: 13, "aria-hidden": "true" }), copy("createApp")] })) : (createTrigger)] })) : (_jsx(AppRows, { apps: visibleApps, activeAppId: activeAppId, layout: layout, onDragStart: setDraggedAppId, onDrop: reorderApps, onDragEnd: () => setDraggedAppId(null), onOpenApp: onOpenApp, onTogglePinned: togglePinned, onMove: moveApp, renderIcon: renderIcon, copy: copy })), hasMoreApps || showAllApps ? (_jsxs("button", { type: "button", className: "mt-0.5 flex h-8 w-full items-center gap-2 rounded-md px-2 text-xs text-sidebar-foreground/50 hover:bg-sidebar-accent hover:text-sidebar-foreground", onClick: () => setShowAllApps((value) => !value), children: [showAllApps ? (_jsx(IconChevronUp, { size: 14, "aria-hidden": "true" })) : (_jsx(IconChevronDown, { size: 14, "aria-hidden": "true" })), showAllApps ? copy("showLess") : copy("showMore")] })) : null, onOpenAllApps ? (_jsx("div", { className: "mt-1 border-t border-sidebar-border/60 pt-1", children: _jsxs("button", { type: "button", "data-chat-first-all-apps": true, className: "flex h-8 w-full items-center gap-2 rounded-md px-2 text-xs text-sidebar-foreground/55 hover:bg-sidebar-accent hover:text-sidebar-foreground", onClick: onOpenAllApps, children: [_jsx(IconApps, { size: 14, "aria-hidden": "true" }), _jsx("span", { children: copy("allApps") })] }) })) : null, error ? (_jsxs(Tooltip, { children: [_jsx(TooltipTrigger, { asChild: true, children: _jsxs("button", { type: "button", className: "mt-1 flex items-center gap-1 px-2 text-[10px] text-destructive/80", onClick: onRetry, "aria-label": error, children: [_jsx("span", { className: "size-1.5 rounded-full bg-destructive" }), onRetry ? copy("retry") : copy("appsLoadError")] }) }), _jsx(TooltipContent, { side: "right", children: error })] })) : null] }));
103
103
  });
@@ -11,4 +11,4 @@ export interface ChatFirstChatHistoryProps extends Omit<ChatHistoryListProps, "i
11
11
  * host. Hosts still own thread fetching and actions, but row rhythm and the
12
12
  * Chats section treatment stay identical.
13
13
  */
14
- export declare function ChatFirstChatHistory({ items, label, headerAction, className, ...props }: ChatFirstChatHistoryProps): import("react").JSX.Element | null;
14
+ export declare function ChatFirstChatHistory({ items, label, headerAction, className, ...props }: ChatFirstChatHistoryProps): import("react").JSX.Element;
@@ -6,7 +6,10 @@ import { ChatHistoryList, } from "../chat/ChatHistoryList.js";
6
6
  * Chats section treatment stay identical.
7
7
  */
8
8
  export function ChatFirstChatHistory({ items, label = "Chats", headerAction, className, ...props }) {
9
- if (items.length === 0)
10
- return null;
9
+ if (items.length === 0) {
10
+ return (_jsx("section", { "data-chat-first-chat-history": true, className: ["min-h-0 min-w-0 flex-1", className]
11
+ .filter(Boolean)
12
+ .join(" ") }));
13
+ }
11
14
  return (_jsxs("section", { "data-chat-first-chat-history": true, className: ["min-h-0 min-w-0", className].filter(Boolean).join(" "), children: [_jsxs("div", { "data-chat-first-chat-history-header": true, className: "group mb-1 flex min-h-6 items-center justify-between gap-2 px-2", children: [_jsx("p", { className: "min-w-0 text-[11px] font-medium text-sidebar-foreground/50", children: label }), headerAction ? (_jsx("div", { className: "shrink-0 opacity-0 transition-opacity duration-100 group-hover:opacity-100 group-focus-within:opacity-100", children: headerAction })) : null] }), _jsx(ChatHistoryList, { ...props, items: items, variant: "rail", className: "min-w-0" })] }));
12
15
  }
@@ -196,6 +196,8 @@ export interface SSEStreamOptions {
196
196
  noProgressTimeoutMs?: number;
197
197
  /** Reader-local counterpart to `noProgressTimeoutMs` for action preparation. */
198
198
  actionPreparationStallTimeoutMs?: number;
199
+ /** Mark the adapter's final `done` snapshot terminal before it is yielded. */
200
+ markTerminalResults?: boolean;
199
201
  /**
200
202
  * Optional caller-owned preparation watchdog state. Passing the same object
201
203
  * across reconnect reads keeps a stuck action preparation from getting a
@@ -261,7 +263,7 @@ export declare function processEvent(ev: SSEEvent, content: ContentPart[], toolC
261
263
  */
262
264
  export declare function readSSEStream(body: ReadableStream<Uint8Array>, content: ContentPart[], toolCallCounter: {
263
265
  value: number;
264
- }, tabId: string | undefined, onSeq?: (seq: number) => void, runId?: string | null, options?: SSEStreamOptions): AsyncGenerator<ChatModelRunResult>;
266
+ }, tabId: string | undefined, onSeq?: (seq: number, isProgress?: boolean) => void, runId?: string | null, options?: SSEStreamOptions): AsyncGenerator<ChatModelRunResult>;
265
267
  /**
266
268
  * Read raw SSE events from a ReadableStream and process them into ContentPart[].
267
269
  * Unlike readSSEStream, this doesn't yield ChatModelRunResult — it updates the
@@ -270,5 +272,5 @@ export declare function readSSEStream(body: ReadableStream<Uint8Array>, content:
270
272
  */
271
273
  export declare function readSSEStreamRaw(body: ReadableStream<Uint8Array>, content: ContentPart[], toolCallCounter: {
272
274
  value: number;
273
- }, tabId: string | undefined, onUpdate: (content: ContentPart[]) => void, onSeq?: (seq: number) => void, options?: SSEStreamOptions): Promise<void>;
275
+ }, tabId: string | undefined, onUpdate: (content: ContentPart[]) => void, onSeq?: (seq: number, isProgress?: boolean) => void, options?: SSEStreamOptions): Promise<void>;
274
276
  export {};
@@ -154,6 +154,20 @@ function isMeaningfulProgressEvent(ev, actionPreparationProgress, options) {
154
154
  }
155
155
  return true;
156
156
  }
157
+ /**
158
+ * The browser's durable liveness cursor must mirror the server's
159
+ * `last_progress_at` predicate. The stream watchdog intentionally has a
160
+ * broader background policy, so it cannot be reused for this cursor: raw
161
+ * keepalives and repeated zero-byte preparation are not proof of real work.
162
+ */
163
+ function isDurableProgressEvent(ev, actionPreparationProgress) {
164
+ if (ev.type === "stream_keepalive" || ev.type === "clear")
165
+ return false;
166
+ if (ev.type === "activity" && isPreparingActionActivity(ev)) {
167
+ return actionPreparationProgress === true;
168
+ }
169
+ return true;
170
+ }
157
171
  function baseActivityLabel(ev, tool) {
158
172
  return humanizeToolLabelText(ev.label ?? "Working", tool);
159
173
  }
@@ -1603,13 +1617,15 @@ export async function* readSSEStream(body, content, toolCallCounter, tabId, onSe
1603
1617
  const now = Date.now();
1604
1618
  inFlightWork = Math.max(0, inFlightWork + sseInFlightWorkDelta(ev));
1605
1619
  const actionPreparationProgress = updatePreparingActionState(preparingActionState, ev, now);
1606
- if (isMeaningfulProgressEvent(ev, actionPreparationProgress, options)) {
1620
+ const meaningfulProgress = isMeaningfulProgressEvent(ev, actionPreparationProgress, options);
1621
+ const durableProgress = isDurableProgressEvent(ev, actionPreparationProgress);
1622
+ if (meaningfulProgress) {
1607
1623
  sawProgressEvent = true;
1608
1624
  lastMeaningfulEventAt = now;
1609
1625
  }
1610
1626
  // Track sequence number for reconnection
1611
1627
  if (ev.seq !== undefined && onSeq) {
1612
- onSeq(ev.seq);
1628
+ onSeq(ev.seq, durableProgress);
1613
1629
  }
1614
1630
  if (ev.type === "clear") {
1615
1631
  activityTrail.length = 0;
@@ -1637,9 +1653,21 @@ export async function* readSSEStream(body, content, toolCallCounter, tabId, onSe
1637
1653
  }
1638
1654
  }
1639
1655
  const { action, result, autoContinue } = processEvent(ev, content, toolCallCounter, tabId, processEventState);
1640
- if (result) {
1656
+ const terminalResult = result &&
1657
+ options?.markTerminalResults === true &&
1658
+ action === "done" &&
1659
+ result.status == null
1660
+ ? {
1661
+ ...result,
1662
+ status: {
1663
+ type: "complete",
1664
+ reason: "stop",
1665
+ },
1666
+ }
1667
+ : result;
1668
+ if (terminalResult) {
1641
1669
  await paceRenderUpdate();
1642
- yield withStreamMetadata(result);
1670
+ yield withStreamMetadata(terminalResult);
1643
1671
  }
1644
1672
  if (hasStalledPreparingAction(preparingActionState, Date.now(), preparationStallTimeoutMs)) {
1645
1673
  throw new AgentAutoContinueSignal({
@@ -1757,12 +1785,14 @@ export async function readSSEStreamRaw(body, content, toolCallCounter, tabId, on
1757
1785
  const now = Date.now();
1758
1786
  inFlightWork = Math.max(0, inFlightWork + sseInFlightWorkDelta(ev));
1759
1787
  const actionPreparationProgress = updatePreparingActionState(preparingActionState, ev, now);
1760
- if (isMeaningfulProgressEvent(ev, actionPreparationProgress, options)) {
1788
+ const meaningfulProgress = isMeaningfulProgressEvent(ev, actionPreparationProgress, options);
1789
+ const durableProgress = isDurableProgressEvent(ev, actionPreparationProgress);
1790
+ if (meaningfulProgress) {
1761
1791
  sawProgressEvent = true;
1762
1792
  lastMeaningfulEventAt = now;
1763
1793
  }
1764
1794
  if (ev.seq !== undefined && onSeq) {
1765
- onSeq(ev.seq);
1795
+ onSeq(ev.seq, durableProgress);
1766
1796
  }
1767
1797
  if (ev.type === "clear") {
1768
1798
  activityTrail.length = 0;
@@ -18,6 +18,8 @@ export interface RunStuckState {
18
18
  lastProgressAt: number | null;
19
19
  /** Milliseconds since `lastProgressAt`, or null. */
20
20
  stuckSinceMs: number | null;
21
+ /** Last browser SSE sequence classified as real work progress, or null. */
22
+ lastProgressSeq: number | null;
21
23
  /** Server timestamp (ms) of the last process-alive heartbeat. */
22
24
  heartbeatAt: number | null;
23
25
  /** Milliseconds since `heartbeatAt`, computed against the server clock. */
@@ -1,5 +1,6 @@
1
1
  import { useEffect, useState, useCallback } from "react";
2
2
  import { createPollEngine } from "../shared/poll-engine.js";
3
+ import { ACTIVE_RUN_STATE_EVENT, getActiveRun, } from "./active-run-state.js";
3
4
  import { agentNativePath } from "./api-path.js";
4
5
  const DEFAULT_STUCK_THRESHOLD_MS = 90_000;
5
6
  export const DEFAULT_BACKGROUND_STUCK_THRESHOLD_MS = 180_000;
@@ -20,6 +21,7 @@ const EMPTY_STATE = {
20
21
  status: null,
21
22
  lastProgressAt: null,
22
23
  stuckSinceMs: null,
24
+ lastProgressSeq: null,
23
25
  heartbeatAt: null,
24
26
  heartbeatSinceMs: null,
25
27
  dispatchMode: null,
@@ -37,6 +39,8 @@ export function useRunStuckDetection({ threadId, enabled = true, stuckThresholdM
37
39
  let cancelled = false;
38
40
  let snapshotTransitionTimer = null;
39
41
  let snapshotVersion = 0;
42
+ let lastObservedLocalProgressAt = null;
43
+ let lastObservedLocalProgressSeq = null;
40
44
  let consecutivePollFailures = 0;
41
45
  // The engine's own cadence varies per tick (idle backoff, error backoff),
42
46
  // which is why intervalMs below reads from this ref instead of a fixed
@@ -86,8 +90,14 @@ export function useRunStuckDetection({ threadId, enabled = true, stuckThresholdM
86
90
  const currentStuckSinceMs = snapshot.stuckSinceMs == null
87
91
  ? null
88
92
  : snapshot.stuckSinceMs + currentElapsedMs;
93
+ const currentLocalProgressSinceMs = snapshot.localProgressObservedAt == null
94
+ ? null
95
+ : Math.max(0, Date.now() - snapshot.localProgressObservedAt);
89
96
  const effectiveThresholdMs = effectiveThresholdFor(snapshot.dispatchMode, currentHeartbeatSinceMs);
90
- const currentlyStuck = Boolean(currentStuckSinceMs != null &&
97
+ const localProgressFresh = Boolean(currentLocalProgressSinceMs != null &&
98
+ currentLocalProgressSinceMs <= effectiveThresholdMs);
99
+ const currentlyStuck = Boolean(!localProgressFresh &&
100
+ currentStuckSinceMs != null &&
91
101
  currentStuckSinceMs > effectiveThresholdMs);
92
102
  const transitionDelaysMs = [];
93
103
  if (currentHeartbeatSinceMs != null &&
@@ -95,9 +105,14 @@ export function useRunStuckDetection({ threadId, enabled = true, stuckThresholdM
95
105
  currentHeartbeatSinceMs < FRESH_BACKGROUND_HEARTBEAT_MS) {
96
106
  transitionDelaysMs.push(FRESH_BACKGROUND_HEARTBEAT_MS - currentHeartbeatSinceMs + 1);
97
107
  }
98
- if (currentStuckSinceMs != null && !currentlyStuck) {
108
+ if (!localProgressFresh &&
109
+ currentStuckSinceMs != null &&
110
+ !currentlyStuck) {
99
111
  transitionDelaysMs.push(Math.max(1, effectiveThresholdMs - currentStuckSinceMs + 1));
100
112
  }
113
+ if (localProgressFresh && currentLocalProgressSinceMs != null) {
114
+ transitionDelaysMs.push(Math.max(1, effectiveThresholdMs - currentLocalProgressSinceMs + 1));
115
+ }
101
116
  if (transitionDelaysMs.length === 0)
102
117
  return;
103
118
  // Both ages originate from the server clock. Advance those snapshots by
@@ -116,26 +131,66 @@ export function useRunStuckDetection({ threadId, enabled = true, stuckThresholdM
116
131
  const nextStuckSinceMs = snapshot.stuckSinceMs == null
117
132
  ? null
118
133
  : snapshot.stuckSinceMs + elapsedSinceObservationMs;
134
+ const nextLocalProgressSinceMs = snapshot.localProgressObservedAt == null
135
+ ? null
136
+ : Math.max(0, Date.now() - snapshot.localProgressObservedAt);
119
137
  const nextEffectiveThresholdMs = effectiveThresholdFor(snapshot.dispatchMode, nextHeartbeatSinceMs);
120
- const nextIsStuck = Boolean(nextStuckSinceMs != null &&
138
+ const nextLocalProgressFresh = Boolean(nextLocalProgressSinceMs != null &&
139
+ nextLocalProgressSinceMs <= nextEffectiveThresholdMs);
140
+ const nextIsStuck = Boolean(!nextLocalProgressFresh &&
141
+ nextStuckSinceMs != null &&
121
142
  nextStuckSinceMs > nextEffectiveThresholdMs);
122
143
  setState((current) => {
123
144
  if (version !== snapshotVersion ||
124
145
  current.runId !== snapshot.runId ||
125
146
  current.lastProgressAt !== snapshot.lastProgressAt ||
126
- current.heartbeatAt !== snapshot.heartbeatAt) {
147
+ current.heartbeatAt !== snapshot.heartbeatAt ||
148
+ current.lastProgressSeq !== snapshot.lastProgressSeq) {
127
149
  return current;
128
150
  }
129
151
  return {
130
152
  ...current,
131
153
  isStuck: nextIsStuck,
132
- stuckSinceMs: nextStuckSinceMs,
154
+ stuckSinceMs: nextLocalProgressFresh ? null : nextStuckSinceMs,
133
155
  heartbeatSinceMs: nextHeartbeatSinceMs,
134
156
  };
135
157
  });
136
158
  scheduleSnapshotTransition(snapshot, observedAtMs, version);
137
159
  }, delayMs);
138
160
  };
161
+ // A healthy SSE stream is a stronger local proof of progress than a
162
+ // delayed SQL timestamp. Listen only to the real-progress cursor - raw
163
+ // keepalives still advance the reconnect cursor but must not suppress the
164
+ // stuck detector forever.
165
+ const onActiveRunStateChange = (event) => {
166
+ const activeRun = (event.detail?.state ?? getActiveRun());
167
+ const progressSeq = activeRun?.lastProgressSeq ?? null;
168
+ const hasNewerProgress = typeof activeRun?.lastProgressObservedAt === "number" &&
169
+ (activeRun.lastProgressObservedAt >
170
+ (lastObservedLocalProgressAt ?? -1) ||
171
+ (activeRun.lastProgressObservedAt === lastObservedLocalProgressAt &&
172
+ progressSeq != null &&
173
+ progressSeq > (lastObservedLocalProgressSeq ?? -1)));
174
+ if (!activeRun ||
175
+ activeRun.threadId !== threadId ||
176
+ typeof activeRun.lastProgressObservedAt !== "number" ||
177
+ !hasNewerProgress) {
178
+ return;
179
+ }
180
+ lastObservedLocalProgressAt = activeRun.lastProgressObservedAt;
181
+ lastObservedLocalProgressSeq = progressSeq;
182
+ snapshotVersion += 1;
183
+ if (snapshotTransitionTimer)
184
+ clearTimeout(snapshotTransitionTimer);
185
+ snapshotTransitionTimer = null;
186
+ setState((current) => {
187
+ if (current.runId !== activeRun.runId || !current.isStuck) {
188
+ return current;
189
+ }
190
+ return { ...current, isStuck: false, stuckSinceMs: null };
191
+ });
192
+ };
193
+ window.addEventListener(ACTIVE_RUN_STATE_EVENT, onActiveRunStateChange);
139
194
  const attempt = async (signal) => {
140
195
  let nextDelay = pollIntervalMs;
141
196
  try {
@@ -156,6 +211,14 @@ export function useRunStuckDetection({ threadId, enabled = true, stuckThresholdM
156
211
  const heartbeatAt = data.heartbeatAt ?? null;
157
212
  const heartbeatSinceMs = heartbeatAt != null ? nowMs - heartbeatAt : null;
158
213
  const dispatchMode = typeof data.dispatchMode === "string" ? data.dispatchMode : null;
214
+ const runId = data.runId ?? null;
215
+ const activeRun = getActiveRun();
216
+ const localProgressObservedAt = activeRun?.threadId === threadId && activeRun.runId === runId
217
+ ? (activeRun.lastProgressObservedAt ?? null)
218
+ : null;
219
+ const localProgressSinceMs = localProgressObservedAt == null
220
+ ? null
221
+ : Math.max(0, Date.now() - localProgressObservedAt);
159
222
  // A claimed durable worker with a fresh heartbeat can legitimately
160
223
  // be waiting on a bounded long-running tool/sub-agent call. Still
161
224
  // surface informational status at the normal background threshold;
@@ -166,25 +229,37 @@ export function useRunStuckDetection({ threadId, enabled = true, stuckThresholdM
166
229
  const isStuck = Boolean(data.active &&
167
230
  data.status === "running" &&
168
231
  stuckSinceMs != null &&
169
- stuckSinceMs > effectiveThresholdMs);
232
+ stuckSinceMs > effectiveThresholdMs &&
233
+ (localProgressSinceMs == null ||
234
+ localProgressSinceMs > effectiveThresholdMs));
170
235
  const observedAtMs = Date.now();
171
236
  const version = ++snapshotVersion;
172
237
  scheduleSnapshotTransition({
173
238
  active: data.active,
174
- runId: data.runId ?? null,
239
+ runId,
175
240
  status: data.status ?? null,
176
241
  lastProgressAt,
177
242
  stuckSinceMs,
243
+ localProgressObservedAt,
244
+ lastProgressSeq: activeRun?.threadId === threadId && activeRun.runId === runId
245
+ ? (activeRun.lastProgressSeq ?? null)
246
+ : null,
178
247
  heartbeatAt,
179
248
  heartbeatSinceMs,
180
249
  dispatchMode,
181
250
  }, observedAtMs, version);
182
251
  setState({
183
252
  isStuck,
184
- runId: data.runId ?? null,
253
+ runId,
185
254
  status: data.status ?? null,
186
255
  lastProgressAt,
187
- stuckSinceMs,
256
+ stuckSinceMs: localProgressSinceMs != null &&
257
+ localProgressSinceMs <= effectiveThresholdMs
258
+ ? null
259
+ : stuckSinceMs,
260
+ lastProgressSeq: activeRun?.threadId === threadId && activeRun.runId === runId
261
+ ? (activeRun.lastProgressSeq ?? null)
262
+ : null,
188
263
  heartbeatAt,
189
264
  heartbeatSinceMs,
190
265
  dispatchMode,
@@ -245,6 +320,7 @@ export function useRunStuckDetection({ threadId, enabled = true, stuckThresholdM
245
320
  engine.stop();
246
321
  if (snapshotTransitionTimer)
247
322
  clearTimeout(snapshotTransitionTimer);
323
+ window.removeEventListener(ACTIVE_RUN_STATE_EVENT, onActiveRunStateChange);
248
324
  document.removeEventListener("visibilitychange", onVisibilityChange);
249
325
  };
250
326
  }, [
@@ -62,11 +62,11 @@ export declare const postAwareness: import("h3").EventHandlerWithFetch<import("h
62
62
  error: string;
63
63
  states?: undefined;
64
64
  } | {
65
+ error?: undefined;
65
66
  states: {
66
67
  clientId: number;
67
68
  state: string;
68
69
  }[];
69
- error?: undefined;
70
70
  }>>;
71
71
  /**
72
72
  * GET /_agent-native/collab/:docId/users
@@ -77,9 +77,9 @@ export declare const getActiveUsers: import("h3").EventHandlerWithFetch<import("
77
77
  error: string;
78
78
  users?: undefined;
79
79
  } | {
80
+ error?: undefined;
80
81
  users: {
81
82
  clientId: number;
82
83
  lastSeen: number;
83
84
  }[];
84
- error?: undefined;
85
85
  }>>;
@@ -26,8 +26,8 @@ export declare const getCollabState: import("h3").EventHandlerWithFetch<import("
26
26
  * Body: { update: string (base64), requestSource?: string }
27
27
  */
28
28
  export declare const postCollabUpdate: import("h3").EventHandlerWithFetch<import("h3").EventHandlerRequest, Promise<{
29
- ok?: undefined;
30
29
  error: string;
30
+ ok?: undefined;
31
31
  } | {
32
32
  error?: undefined;
33
33
  ok: boolean;
@@ -2,10 +2,6 @@ import type { PlatformAdapter, IncomingMessage } from "../types.js";
2
2
  export interface SlackAdapterOptions {
3
3
  /** Resolve the bot token for the exact Slack installation. */
4
4
  resolveBotToken?: (incoming: IncomingMessage) => Promise<string | undefined>;
5
- /** Override active-thread detection for hosted adapters/tests. */
6
- isThreadActive?: (incoming: IncomingMessage) => Promise<boolean>;
7
- /** Override one-shot clarification-window consumption for tests. */
8
- consumeAwaitingInput?: (incoming: IncomingMessage) => Promise<boolean>;
9
5
  }
10
6
  /**
11
7
  * Create a Slack platform adapter.
@@ -3,10 +3,8 @@ import { createError, getHeader, readRawBody } from "h3";
3
3
  import { resolveSecret } from "../../server/credential-provider.js";
4
4
  import { getRequestContext } from "../../server/request-context.js";
5
5
  import { getIntegrationRequestContext } from "../../server/request-context.js";
6
- import { consumeIntegrationAwaitingInput } from "../awaiting-input-store.js";
7
6
  import { createIntegrationControl } from "../controls-store.js";
8
7
  import { getActiveIntegrationInstallationByKey, listActiveIntegrationInstallationsForTenant, listIntegrationInstallations, resolveIntegrationTokenBundle, } from "../installations-store.js";
9
- import { hasActivePendingTask } from "../pending-tasks-store.js";
10
8
  import { slackInstallationKey } from "../slack-oauth.js";
11
9
  /** Slack's max message length */
12
10
  const SLACK_MAX_LENGTH = 4000;
@@ -195,10 +193,10 @@ export function slackAdapter(options = {}) {
195
193
  // Ignore message edits and deletes
196
194
  if (e.subtype === "message_changed" || e.subtype === "message_deleted")
197
195
  return null;
198
- // Handle DMs and explicit mentions. Ordinary channel replies are only
199
- // accepted while this exact workspace-qualified thread has queued or
200
- // executing work; broad message subscriptions must never invoke the
201
- // agent for general channel chatter.
196
+ // Handle DMs and explicit mentions only. A channel thread can contain
197
+ // many human replies after an agent mention; each new agent turn must
198
+ // opt in with another explicit mention instead of inheriting the
199
+ // parent message's invocation.
202
200
  const text = e.text?.trim();
203
201
  if (!text)
204
202
  return null;
@@ -211,8 +209,7 @@ export function slackAdapter(options = {}) {
211
209
  ? e.channel_type === "im"
212
210
  : typeof e.channel === "string" && e.channel.startsWith("D");
213
211
  const isMention = e.type === "app_mention";
214
- const isThreadReply = !isDm && !isMention && !!e.thread_ts;
215
- if (!isDm && !isMention && !isThreadReply)
212
+ if (!isDm && !isMention)
216
213
  return null;
217
214
  // Remove bot mention from text (e.g., "<@U123> do something" → "do something")
218
215
  const cleanText = text.replace(/<@[A-Z0-9]+>/g, "").trim();
@@ -227,7 +224,7 @@ export function slackAdapter(options = {}) {
227
224
  text: cleanText,
228
225
  senderName: e.user,
229
226
  senderId: e.user,
230
- triggerKind: isDm ? "dm" : isMention ? "mention" : "thread_reply",
227
+ triggerKind: isDm ? "dm" : "mention",
231
228
  conversationType: isDm ? "dm" : "unknown",
232
229
  tenantId: teamId,
233
230
  // The signed Slack envelope authenticates the workspace, not the
@@ -256,27 +253,6 @@ export function slackAdapter(options = {}) {
256
253
  replyRef: e.ts,
257
254
  timestamp: Math.floor(parseFloat(e.ts) * 1000),
258
255
  };
259
- if (isThreadReply) {
260
- // An ordinary thread reply is narrowly admitted when either work is
261
- // still queued or the same Slack user is answering a fresh
262
- // integration-originated clarification. Consuming the latter is a
263
- // conditional SQL delete, so concurrent replies cannot both reopen
264
- // the agent and unrelated channel messages remain ignored.
265
- const answeredClarification = options.consumeAwaitingInput
266
- ? await options.consumeAwaitingInput(partialIncoming)
267
- : options.isThreadActive
268
- ? false
269
- : await consumeIntegrationAwaitingInput({
270
- platform: "slack",
271
- externalThreadId,
272
- requesterId: e.user,
273
- });
274
- const active = options.isThreadActive
275
- ? await options.isThreadActive(partialIncoming)
276
- : await hasActivePendingTask("slack", externalThreadId);
277
- if (!active && !answeredClarification)
278
- return null;
279
- }
280
256
  const token = await resolveBotToken(partialIncoming);
281
257
  const threadPermalink = await resolveSlackThreadPermalink(e.channel, threadTs, token);
282
258
  return {
@@ -36,7 +36,7 @@ const BUILT_IN_CHANNEL_CATALOG = [
36
36
  "Apply the Agent Native Slack manifest to enable Agent View and writable direct messages.",
37
37
  "Configure the OAuth client id, client secret, and signing secret.",
38
38
  "Enable Event Subscriptions and Interactivity with the documented URLs.",
39
- "Subscribe to app_home_opened, app_context_changed, app_mention, and message.im/channels/groups, then use Add to Slack.",
39
+ "Subscribe to app_home_opened, app_context_changed, app_mention, and message.im, then use Add to Slack.",
40
40
  ],
41
41
  },
42
42
  credentialRequirements: [
@@ -20,14 +20,6 @@ export interface PendingTask {
20
20
  updatedAt: number;
21
21
  completedAt: number | null;
22
22
  }
23
- /**
24
- * Whether a provider thread currently has queued or executing work.
25
- *
26
- * Messaging adapters use this to accept unmentioned replies only while an
27
- * agent task is active. This prevents broad message subscriptions from turning
28
- * every channel message into an agent invocation.
29
- */
30
- export declare function hasActivePendingTask(platform: string, externalThreadId: string): Promise<boolean>;
31
23
  /**
32
24
  * Insert a new pending task. Returns the generated task id.
33
25
  *
@@ -110,27 +110,6 @@ async function ensureDispatchColumns(client) {
110
110
  }
111
111
  }
112
112
  }
113
- /**
114
- * Whether a provider thread currently has queued or executing work.
115
- *
116
- * Messaging adapters use this to accept unmentioned replies only while an
117
- * agent task is active. This prevents broad message subscriptions from turning
118
- * every channel message into an agent invocation.
119
- */
120
- export async function hasActivePendingTask(platform, externalThreadId) {
121
- await ensureTable();
122
- const client = getDbExec();
123
- const { rows } = await client.execute({
124
- sql: `SELECT 1 AS active
125
- FROM integration_pending_tasks
126
- WHERE platform = ?
127
- AND external_thread_id = ?
128
- AND status IN ('pending', 'processing')
129
- LIMIT 1`,
130
- args: [platform, externalThreadId],
131
- });
132
- return rows.length > 0;
133
- }
134
113
  function rowToTask(row) {
135
114
  return {
136
115
  id: row.id,
@@ -1,4 +1,4 @@
1
- export declare const SLACK_AGENT_BOT_EVENTS: readonly ["app_home_opened", "app_context_changed", "app_mention", "message.channels", "message.groups", "message.im", "message.mpim"];
1
+ export declare const SLACK_AGENT_BOT_EVENTS: readonly ["app_home_opened", "app_context_changed", "app_mention", "message.im"];
2
2
  export interface SlackAgentManifestUrls {
3
3
  oauthRedirectUrl: string;
4
4
  eventsRequestUrl: string;
@@ -52,7 +52,7 @@ export declare function buildSlackAgentManifest(urls: SlackAgentManifestUrls): {
52
52
  readonly settings: {
53
53
  readonly event_subscriptions: {
54
54
  readonly request_url: string;
55
- readonly bot_events: readonly ["app_home_opened", "app_context_changed", "app_mention", "message.channels", "message.groups", "message.im", "message.mpim"];
55
+ readonly bot_events: readonly ["app_home_opened", "app_context_changed", "app_mention", "message.im"];
56
56
  };
57
57
  readonly interactivity: {
58
58
  readonly is_enabled: true;
@@ -3,10 +3,7 @@ export const SLACK_AGENT_BOT_EVENTS = [
3
3
  "app_home_opened",
4
4
  "app_context_changed",
5
5
  "app_mention",
6
- "message.channels",
7
- "message.groups",
8
6
  "message.im",
9
- "message.mpim",
10
7
  ];
11
8
  /**
12
9
  * Build the canonical Slack app manifest for Agent Native.