@agent-native/core 0.149.1 → 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 (422) 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/dashboard-management/SKILL.md +2 -0
  9. package/corpus/templates/analytics/.agents/skills/frontend-design/SKILL.md +4 -5
  10. package/corpus/templates/analytics/.agents/skills/turn-into-app/SKILL.md +18 -31
  11. package/corpus/templates/analytics/AGENTS.md +25 -32
  12. package/corpus/templates/analytics/app/components/dashboard/SqlChart.tsx +150 -46
  13. package/corpus/templates/analytics/app/global.css +1 -1
  14. package/corpus/templates/analytics/app/i18n-data.ts +37 -0
  15. package/corpus/templates/analytics/app/pages/adhoc/sql-dashboard/PanelEditorDialog.tsx +1 -1
  16. package/corpus/templates/analytics/app/pages/adhoc/sql-dashboard/SqlChartCard.tsx +32 -0
  17. package/corpus/templates/analytics/app/pages/adhoc/sql-dashboard/types.ts +2 -0
  18. package/corpus/templates/analytics/changelog/2026-08-10-dashboard-tables-can-be-copied-and-sorted-by-multiple-column.md +6 -0
  19. package/corpus/templates/analytics/changelog/2026-08-10-full-page-chat-now-uses-the-available-width-up-to-1000px-for.md +6 -0
  20. package/corpus/templates/analytics/changelog/2026-08-11-full-page-chat-composers-stay-at-a-focused-750px-width.md +6 -0
  21. package/corpus/templates/assets/.agents/skills/actions/SKILL.md +54 -488
  22. package/corpus/templates/assets/.agents/skills/actions/references/action-fields.md +136 -0
  23. package/corpus/templates/assets/.agents/skills/actions/references/examples.md +94 -0
  24. package/corpus/templates/assets/.agents/skills/actions/references/provider-apis.md +95 -0
  25. package/corpus/templates/assets/.agents/skills/create-skill/SKILL.md +9 -35
  26. package/corpus/templates/assets/.agents/skills/creative-context/SKILL.md +4 -2
  27. package/corpus/templates/assets/.agents/skills/frontend-design/SKILL.md +4 -5
  28. package/corpus/templates/assets/.agents/skills/turn-into-app/SKILL.md +18 -31
  29. package/corpus/templates/assets/AGENTS.md +6 -9
  30. package/corpus/templates/assets/app/global.css +1 -1
  31. package/corpus/templates/assets/changelog/2026-08-10-full-page-chat-now-uses-the-available-width-up-to-1000px-for.md +6 -0
  32. package/corpus/templates/assets/changelog/2026-08-11-full-page-chat-composers-stay-at-a-focused-750px-width.md +6 -0
  33. package/corpus/templates/brain/.agents/skills/actions/SKILL.md +54 -488
  34. package/corpus/templates/brain/.agents/skills/actions/references/action-fields.md +136 -0
  35. package/corpus/templates/brain/.agents/skills/actions/references/examples.md +94 -0
  36. package/corpus/templates/brain/.agents/skills/actions/references/provider-apis.md +95 -0
  37. package/corpus/templates/brain/.agents/skills/create-skill/SKILL.md +9 -35
  38. package/corpus/templates/brain/.agents/skills/frontend-design/SKILL.md +4 -5
  39. package/corpus/templates/brain/.agents/skills/turn-into-app/SKILL.md +18 -31
  40. package/corpus/templates/brain/AGENTS.md +5 -12
  41. package/corpus/templates/brain/app/global.css +1 -1
  42. package/corpus/templates/brain/changelog/2026-08-10-full-page-chat-now-uses-the-available-width-up-to-1000px-for.md +6 -0
  43. package/corpus/templates/brain/changelog/2026-08-11-full-page-chat-composers-stay-at-a-focused-750px-width.md +6 -0
  44. package/corpus/templates/calendar/.agents/skills/actions/SKILL.md +54 -488
  45. package/corpus/templates/calendar/.agents/skills/actions/references/action-fields.md +136 -0
  46. package/corpus/templates/calendar/.agents/skills/actions/references/examples.md +94 -0
  47. package/corpus/templates/calendar/.agents/skills/actions/references/provider-apis.md +95 -0
  48. package/corpus/templates/calendar/.agents/skills/create-skill/SKILL.md +9 -35
  49. package/corpus/templates/calendar/.agents/skills/frontend-design/SKILL.md +4 -5
  50. package/corpus/templates/calendar/.agents/skills/turn-into-app/SKILL.md +18 -31
  51. package/corpus/templates/calendar/AGENTS.md +8 -9
  52. package/corpus/templates/chat/.agents/skills/actions/SKILL.md +54 -488
  53. package/corpus/templates/chat/.agents/skills/actions/references/action-fields.md +136 -0
  54. package/corpus/templates/chat/.agents/skills/actions/references/examples.md +94 -0
  55. package/corpus/templates/chat/.agents/skills/actions/references/provider-apis.md +95 -0
  56. package/corpus/templates/chat/.agents/skills/create-skill/SKILL.md +9 -35
  57. package/corpus/templates/chat/.agents/skills/frontend-design/SKILL.md +4 -5
  58. package/corpus/templates/chat/.agents/skills/turn-into-app/SKILL.md +18 -31
  59. package/corpus/templates/chat/AGENTS.md +32 -80
  60. package/corpus/templates/chat/changelog/2026-08-10-full-page-chat-now-uses-the-available-width-up-to-1000px-for.md +6 -0
  61. package/corpus/templates/clips/.agents/skills/actions/SKILL.md +54 -488
  62. package/corpus/templates/clips/.agents/skills/actions/references/action-fields.md +136 -0
  63. package/corpus/templates/clips/.agents/skills/actions/references/examples.md +94 -0
  64. package/corpus/templates/clips/.agents/skills/actions/references/provider-apis.md +95 -0
  65. package/corpus/templates/clips/.agents/skills/create-skill/SKILL.md +9 -35
  66. package/corpus/templates/clips/.agents/skills/frontend-design/SKILL.md +4 -5
  67. package/corpus/templates/clips/.agents/skills/turn-into-app/SKILL.md +18 -31
  68. package/corpus/templates/clips/AGENTS.md +25 -31
  69. package/corpus/templates/clips/changelog/2026-08-10-clips-desktop-sign-in-now-starts-with-magic-links-and-google.md +6 -0
  70. package/corpus/templates/clips/chrome-extension/src/overlay.css +1 -0
  71. package/corpus/templates/clips/desktop/src/app.tsx +274 -137
  72. package/corpus/templates/clips/desktop/src/styles.css +35 -0
  73. package/corpus/templates/content/.agents/skills/actions/SKILL.md +54 -488
  74. package/corpus/templates/content/.agents/skills/actions/references/action-fields.md +136 -0
  75. package/corpus/templates/content/.agents/skills/actions/references/examples.md +94 -0
  76. package/corpus/templates/content/.agents/skills/actions/references/provider-apis.md +95 -0
  77. package/corpus/templates/content/.agents/skills/create-skill/SKILL.md +9 -35
  78. package/corpus/templates/content/.agents/skills/creative-context/SKILL.md +4 -2
  79. package/corpus/templates/content/.agents/skills/frontend-design/SKILL.md +4 -5
  80. package/corpus/templates/content/.agents/skills/turn-into-app/SKILL.md +18 -31
  81. package/corpus/templates/content/AGENTS.md +5 -9
  82. package/corpus/templates/content/app/global.css +1 -0
  83. package/corpus/templates/crm/.agents/skills/turn-into-app/SKILL.md +18 -31
  84. package/corpus/templates/crm/AGENTS.md +7 -11
  85. package/corpus/templates/crm/app/global.css +1 -1
  86. package/corpus/templates/crm/changelog/2026-08-10-full-page-chat-now-uses-the-available-width-up-to-1000px-for.md +6 -0
  87. package/corpus/templates/crm/changelog/2026-08-11-full-page-chat-composers-stay-at-a-focused-750px-width.md +6 -0
  88. package/corpus/templates/design/.agents/skills/actions/SKILL.md +54 -488
  89. package/corpus/templates/design/.agents/skills/actions/references/action-fields.md +136 -0
  90. package/corpus/templates/design/.agents/skills/actions/references/examples.md +94 -0
  91. package/corpus/templates/design/.agents/skills/actions/references/provider-apis.md +95 -0
  92. package/corpus/templates/design/.agents/skills/create-skill/SKILL.md +9 -35
  93. package/corpus/templates/design/.agents/skills/creative-context/SKILL.md +4 -2
  94. package/corpus/templates/design/.agents/skills/frontend-design/SKILL.md +4 -5
  95. package/corpus/templates/design/.agents/skills/turn-into-app/SKILL.md +18 -31
  96. package/corpus/templates/design/.generated/bridge/editor-chrome.generated.ts +70 -3
  97. package/corpus/templates/design/AGENTS.md +13 -21
  98. package/corpus/templates/design/app/components/design/DesignCanvas.tsx +12 -0
  99. package/corpus/templates/design/app/components/design/LayersPanel.tsx +19 -2
  100. package/corpus/templates/design/app/components/design/MultiScreenCanvas.tsx +115 -7
  101. package/corpus/templates/design/app/components/design/bridge/editor-chrome.bridge.ts +82 -7
  102. package/corpus/templates/design/app/components/design/design-trace.ts +120 -0
  103. package/corpus/templates/design/app/components/design/dnd-debug.ts +2 -1
  104. package/corpus/templates/design/app/components/design/edit-panel/position-layout-properties.tsx +40 -26
  105. package/corpus/templates/design/app/components/design/multi-screen/board-surface-html.ts +4 -1
  106. package/corpus/templates/design/app/components/design/multi-screen/frame-geometry.ts +12 -3
  107. package/corpus/templates/design/app/components/design/multi-screen/screen-content-cache.ts +4 -0
  108. package/corpus/templates/design/app/components/design/multi-screen/types.ts +7 -0
  109. package/corpus/templates/design/app/components/editor/PromptDialog.tsx +3 -2
  110. package/corpus/templates/design/app/components/layout/Sidebar.tsx +2 -2
  111. package/corpus/templates/design/app/hooks/useDesignHotkeys.ts +3 -0
  112. package/corpus/templates/design/app/i18n-data.ts +1 -0
  113. package/corpus/templates/design/app/pages/DesignSystemSetup.tsx +5 -5
  114. package/corpus/templates/design/app/pages/DesignSystems.tsx +3 -2
  115. package/corpus/templates/design/app/pages/design-editor/canvas-primitive-insert.ts +100 -13
  116. package/corpus/templates/design/app/pages/design-editor/cross-screen-text-color.ts +1 -1
  117. package/corpus/templates/design/app/pages/design-editor/data-operations.ts +14 -0
  118. package/corpus/templates/design/changelog/2026-08-10-marquee-selecting-layers-far-down-a-tall-screen-now-selects-.md +6 -0
  119. package/corpus/templates/design/changelog/2026-08-10-the-frame-tool-draws-a-plain-frame-by-default-with-screen-av.md +6 -0
  120. package/corpus/templates/design/e2e/global-setup.ts +27 -32
  121. package/corpus/templates/design/playwright.config.ts +3 -5
  122. package/corpus/templates/design/shared/breakpoint-media.ts +9 -2
  123. package/corpus/templates/dispatch/.agents/skills/actions/SKILL.md +54 -488
  124. package/corpus/templates/dispatch/.agents/skills/actions/references/action-fields.md +136 -0
  125. package/corpus/templates/dispatch/.agents/skills/actions/references/examples.md +94 -0
  126. package/corpus/templates/dispatch/.agents/skills/actions/references/provider-apis.md +95 -0
  127. package/corpus/templates/dispatch/.agents/skills/create-skill/SKILL.md +9 -35
  128. package/corpus/templates/dispatch/.agents/skills/frontend-design/SKILL.md +4 -5
  129. package/corpus/templates/dispatch/.agents/skills/turn-into-app/SKILL.md +18 -31
  130. package/corpus/templates/dispatch/AGENTS.md +9 -16
  131. package/corpus/templates/dispatch/changelog/2026-08-10-full-page-chat-now-uses-the-available-width-up-to-1000px-for.md +6 -0
  132. package/corpus/templates/factory/.agents/skills/actions/SKILL.md +54 -488
  133. package/corpus/templates/factory/.agents/skills/actions/references/action-fields.md +136 -0
  134. package/corpus/templates/factory/.agents/skills/actions/references/examples.md +94 -0
  135. package/corpus/templates/factory/.agents/skills/actions/references/provider-apis.md +95 -0
  136. package/corpus/templates/factory/.agents/skills/create-skill/SKILL.md +9 -35
  137. package/corpus/templates/factory/.agents/skills/frontend-design/SKILL.md +4 -5
  138. package/corpus/templates/factory/.agents/skills/turn-into-app/SKILL.md +18 -31
  139. package/corpus/templates/factory/AGENTS.md +10 -24
  140. package/corpus/templates/factory/changelog/2026-08-10-full-page-chat-now-uses-the-available-width-up-to-1000px-for.md +6 -0
  141. package/corpus/templates/forms/.agents/skills/actions/SKILL.md +54 -488
  142. package/corpus/templates/forms/.agents/skills/actions/references/action-fields.md +136 -0
  143. package/corpus/templates/forms/.agents/skills/actions/references/examples.md +94 -0
  144. package/corpus/templates/forms/.agents/skills/actions/references/provider-apis.md +95 -0
  145. package/corpus/templates/forms/.agents/skills/create-skill/SKILL.md +9 -35
  146. package/corpus/templates/forms/.agents/skills/frontend-design/SKILL.md +4 -5
  147. package/corpus/templates/forms/.agents/skills/turn-into-app/SKILL.md +18 -31
  148. package/corpus/templates/forms/AGENTS.md +11 -17
  149. package/corpus/templates/forms/app/global.css +1 -0
  150. package/corpus/templates/forms/changelog/2026-08-10-full-page-chat-now-uses-the-available-width-up-to-1000px-for.md +6 -0
  151. package/corpus/templates/forms/changelog/2026-08-11-full-page-chat-composers-stay-at-a-focused-750px-width.md +6 -0
  152. package/corpus/templates/macros/.agents/skills/frontend-design/SKILL.md +4 -5
  153. package/corpus/templates/macros/.agents/skills/turn-into-app/SKILL.md +18 -31
  154. package/corpus/templates/macros/AGENTS.md +8 -8
  155. package/corpus/templates/mail/.agents/skills/actions/SKILL.md +54 -488
  156. package/corpus/templates/mail/.agents/skills/actions/references/action-fields.md +136 -0
  157. package/corpus/templates/mail/.agents/skills/actions/references/examples.md +94 -0
  158. package/corpus/templates/mail/.agents/skills/actions/references/provider-apis.md +95 -0
  159. package/corpus/templates/mail/.agents/skills/create-skill/SKILL.md +9 -35
  160. package/corpus/templates/mail/.agents/skills/frontend-design/SKILL.md +4 -5
  161. package/corpus/templates/mail/.agents/skills/turn-into-app/SKILL.md +18 -31
  162. package/corpus/templates/mail/AGENTS.md +5 -6
  163. package/corpus/templates/plan/.agents/skills/actions/SKILL.md +54 -488
  164. package/corpus/templates/plan/.agents/skills/actions/references/action-fields.md +136 -0
  165. package/corpus/templates/plan/.agents/skills/actions/references/examples.md +94 -0
  166. package/corpus/templates/plan/.agents/skills/actions/references/provider-apis.md +95 -0
  167. package/corpus/templates/plan/.agents/skills/create-skill/SKILL.md +9 -35
  168. package/corpus/templates/plan/.agents/skills/frontend-design/SKILL.md +4 -5
  169. package/corpus/templates/plan/.agents/skills/turn-into-app/SKILL.md +18 -31
  170. package/corpus/templates/plan/AGENTS.md +5 -14
  171. package/corpus/templates/plan/app/global.css +1 -0
  172. package/corpus/templates/plan/changelog/2026-08-10-full-page-chat-now-uses-the-available-width-up-to-1000px-for.md +6 -0
  173. package/corpus/templates/plan/changelog/2026-08-11-plan-no-longer-reloads-when-runtime-state-changes.md +6 -0
  174. package/corpus/templates/plan/server/ui-plan-html.ts +4 -1
  175. package/corpus/templates/plan/vite.config.ts +5 -0
  176. package/corpus/templates/slides/.agents/skills/actions/SKILL.md +54 -488
  177. package/corpus/templates/slides/.agents/skills/actions/references/action-fields.md +136 -0
  178. package/corpus/templates/slides/.agents/skills/actions/references/examples.md +94 -0
  179. package/corpus/templates/slides/.agents/skills/actions/references/provider-apis.md +95 -0
  180. package/corpus/templates/slides/.agents/skills/create-deck/SKILL.md +2 -2
  181. package/corpus/templates/slides/.agents/skills/create-skill/SKILL.md +9 -35
  182. package/corpus/templates/slides/.agents/skills/creative-context/SKILL.md +6 -3
  183. package/corpus/templates/slides/.agents/skills/deck-management/SKILL.md +6 -1
  184. package/corpus/templates/slides/.agents/skills/frontend-design/SKILL.md +4 -5
  185. package/corpus/templates/slides/.agents/skills/image-generation-via-a2a/SKILL.md +3 -2
  186. package/corpus/templates/slides/.agents/skills/slide-editing/SKILL.md +3 -0
  187. package/corpus/templates/slides/.agents/skills/slide-images/SKILL.md +3 -3
  188. package/corpus/templates/slides/.agents/skills/turn-into-app/SKILL.md +18 -31
  189. package/corpus/templates/slides/AGENTS.md +33 -35
  190. package/corpus/templates/slides/actions/add-deck.ts +2 -0
  191. package/corpus/templates/slides/actions/add-slide.ts +15 -1
  192. package/corpus/templates/slides/actions/create-deck.ts +18 -6
  193. package/corpus/templates/slides/actions/get-deck-reference-context.ts +2 -2
  194. package/corpus/templates/slides/actions/get-deck.ts +83 -7
  195. package/corpus/templates/slides/actions/import-file.ts +2 -1
  196. package/corpus/templates/slides/actions/patch-deck.ts +165 -9
  197. package/corpus/templates/slides/actions/save-deck.ts +24 -1
  198. package/corpus/templates/slides/actions/update-slide.ts +1 -1
  199. package/corpus/templates/slides/app/components/comments/SlideCommentsPanel.tsx +2 -2
  200. package/corpus/templates/slides/app/components/deck/DeckCard.tsx +1 -23
  201. package/corpus/templates/slides/app/components/design-system/DesignSystemCard.tsx +2 -2
  202. package/corpus/templates/slides/app/components/design-system/DesignSystemSetup.tsx +6 -6
  203. package/corpus/templates/slides/app/components/editor/AnimationsPanel.tsx +3 -3
  204. package/corpus/templates/slides/app/components/editor/DeckEditorSkeleton.tsx +4 -4
  205. package/corpus/templates/slides/app/components/editor/EditorSidebar.tsx +1 -1
  206. package/corpus/templates/slides/app/components/editor/EditorToolbar.tsx +432 -668
  207. package/corpus/templates/slides/app/components/editor/ExportMenu.tsx +296 -259
  208. package/corpus/templates/slides/app/components/editor/GeneratingSlidePreview.tsx +1 -1
  209. package/corpus/templates/slides/app/components/editor/GoogleDriveConnectionCta.tsx +13 -1
  210. package/corpus/templates/slides/app/components/editor/NewDeckReferenceStep.tsx +56 -174
  211. package/corpus/templates/slides/app/components/editor/PromptDialog.tsx +241 -116
  212. package/corpus/templates/slides/app/components/editor/SlideContextToolbar.tsx +1 -1
  213. package/corpus/templates/slides/app/components/editor/SlideEditor.tsx +42 -14
  214. package/corpus/templates/slides/app/components/editor/SpeakerNotesPanel.tsx +6 -12
  215. package/corpus/templates/slides/app/components/editor/editor-command-model.ts +35 -0
  216. package/corpus/templates/slides/app/components/layout/AgentWorkIndicator.tsx +1 -1
  217. package/corpus/templates/slides/app/components/layout/Layout.tsx +34 -35
  218. package/corpus/templates/slides/app/components/layout/Sidebar.tsx +8 -10
  219. package/corpus/templates/slides/app/components/layout/layout-route-policy.ts +2 -5
  220. package/corpus/templates/slides/app/components/onboarding/FirstDeckOnboardingFlow.tsx +45 -40
  221. package/corpus/templates/slides/app/components/presentation/PresentationView.tsx +63 -16
  222. package/corpus/templates/slides/app/context/DeckContext.tsx +2 -1
  223. package/corpus/templates/slides/app/global.css +76 -1
  224. package/corpus/templates/slides/app/hooks/use-generating-slide-preview.ts +25 -3
  225. package/corpus/templates/slides/app/i18n/en-US.ts +2 -0
  226. package/corpus/templates/slides/app/lib/create-deck-generation.ts +52 -23
  227. package/corpus/templates/slides/app/lib/recent-references.ts +23 -1
  228. package/corpus/templates/slides/app/lib/slide-animation-elements.ts +104 -3
  229. package/corpus/templates/slides/app/pages/DeckEditor.tsx +17 -33
  230. package/corpus/templates/slides/app/pages/DesignSystems.tsx +2 -2
  231. package/corpus/templates/slides/app/pages/Index.tsx +315 -151
  232. package/corpus/templates/slides/app/root.tsx +43 -0
  233. package/corpus/templates/slides/changelog/2026-08-10-ai-editing-avatar-badge.md +6 -0
  234. package/corpus/templates/slides/changelog/2026-08-10-generated-decks-keep-a-clear-human-readable-title.md +6 -0
  235. package/corpus/templates/slides/changelog/2026-08-10-new-deck-creation-now-shows-progress-opens-the-editor-direct.md +6 -0
  236. package/corpus/templates/slides/changelog/2026-08-10-presentation-reveals-now-follow-valid-targets.md +6 -0
  237. package/corpus/templates/slides/changelog/2026-08-10-slides-editing-controls-are-consolidated-into-one-focused-me.md +6 -0
  238. package/corpus/templates/slides/changelog/2026-08-10-slides-now-verify-and-restyle-every-imported-slide-in-one-pa.md +6 -0
  239. package/corpus/templates/slides/changelog/2026-08-10-slides-only-suggests-a-google-connection-for-relevant-reques.md +6 -0
  240. package/corpus/templates/slides/changelog/2026-08-10-the-google-slides-import-option-is-now-labeled-slides.md +6 -0
  241. package/corpus/templates/slides/changelog/2026-08-11-faster-slides-chat-deck-reads.md +6 -0
  242. package/corpus/templates/slides/changelog/2026-08-11-slides-chat-can-read-one-slide-without-loading-the-full-deck.md +6 -0
  243. package/corpus/templates/slides/changelog/2026-08-11-slides-clearly-indicate-when-an-ai-agent-is-editing-alongsid.md +6 -0
  244. package/corpus/templates/slides/package.json +1 -0
  245. package/corpus/templates/slides/server/lib/chat-attachments.ts +1 -1
  246. package/corpus/templates/slides/server/lib/validate-slide-animations.ts +163 -0
  247. package/corpus/templates/slides/server/plugins/agent-chat.ts +8 -5
  248. package/corpus/templates/slides/shared/api.ts +47 -15
  249. package/corpus/templates/slides/shared/deck-title.ts +135 -0
  250. package/corpus/templates/tasks/.agents/skills/actions/SKILL.md +54 -488
  251. package/corpus/templates/tasks/.agents/skills/actions/references/action-fields.md +136 -0
  252. package/corpus/templates/tasks/.agents/skills/actions/references/examples.md +94 -0
  253. package/corpus/templates/tasks/.agents/skills/actions/references/provider-apis.md +95 -0
  254. package/corpus/templates/tasks/.agents/skills/agent-watchdog/SKILL.md +1 -0
  255. package/corpus/templates/tasks/.agents/skills/create-skill/SKILL.md +9 -35
  256. package/corpus/templates/tasks/.agents/skills/efficient-fable/SKILL.md +1 -0
  257. package/corpus/templates/tasks/.agents/skills/efficient-frontier/SKILL.md +1 -0
  258. package/corpus/templates/tasks/.agents/skills/frontend-design/SKILL.md +4 -5
  259. package/corpus/templates/tasks/.agents/skills/plan-arbiter/SKILL.md +1 -0
  260. package/corpus/templates/tasks/.agents/skills/plow-ahead/SKILL.md +1 -0
  261. package/corpus/templates/tasks/.agents/skills/quick-recap/SKILL.md +1 -0
  262. package/corpus/templates/tasks/.agents/skills/read-the-damn-docs/SKILL.md +1 -0
  263. package/corpus/templates/tasks/.agents/skills/stay-within-limits/SKILL.md +1 -0
  264. package/corpus/templates/tasks/.agents/skills/turn-into-app/SKILL.md +18 -31
  265. package/corpus/templates/tasks/AGENTS.md +5 -20
  266. package/corpus/templates/tasks/app/components/tasks/TaskListRow.tsx +4 -1
  267. package/dist/agent/engine/ai-sdk-engine.js +1 -1
  268. package/dist/agent/production-agent.d.ts +21 -1
  269. package/dist/agent/production-agent.js +505 -355
  270. package/dist/agent/run-manager.js +156 -14
  271. package/dist/agent/run-store.d.ts +11 -10
  272. package/dist/agent/run-store.js +17 -13
  273. package/dist/agent/tool-approval-store.d.ts +18 -0
  274. package/dist/agent/tool-approval-store.js +122 -0
  275. package/dist/agent/types.d.ts +1 -1
  276. package/dist/cli/code-agent-executor.js +11 -2
  277. package/dist/client/AgentPanel.js +31 -6
  278. package/dist/client/AssistantChat.d.ts +9 -4
  279. package/dist/client/AssistantChat.js +221 -149
  280. package/dist/client/active-run-state.d.ts +9 -1
  281. package/dist/client/active-run-state.js +34 -3
  282. package/dist/client/agent-chat/index.d.ts +1 -1
  283. package/dist/client/agent-chat-adapter.d.ts +8 -0
  284. package/dist/client/agent-chat-adapter.js +125 -28
  285. package/dist/client/agent-chat.d.ts +1 -1
  286. package/dist/client/chat/markdown-renderer.js +14 -2
  287. package/dist/client/chat/message-components.d.ts +13 -3
  288. package/dist/client/chat/message-components.js +57 -52
  289. package/dist/client/chat/run-recovery.d.ts +1 -0
  290. package/dist/client/chat/run-recovery.js +8 -0
  291. package/dist/client/chat/tool-call-display.d.ts +5 -5
  292. package/dist/client/chat/tool-call-display.js +9 -212
  293. package/dist/client/chat-first/apps-rail.js +3 -3
  294. package/dist/client/chat-first/browser-pane.js +4 -1
  295. package/dist/client/chat-first/chat-history.d.ts +3 -1
  296. package/dist/client/chat-first/chat-history.js +7 -4
  297. package/dist/client/chat-first/surface-tabs.d.ts +1 -1
  298. package/dist/client/chat-first/surface-tabs.js +52 -41
  299. package/dist/client/chat-first/types.d.ts +3 -0
  300. package/dist/client/chat-first.d.ts +10 -0
  301. package/dist/client/chat-first.js +37 -2
  302. package/dist/client/components/ui/message-scroller.js +4 -1
  303. package/dist/client/i18n.js +3 -1
  304. package/dist/client/resources/McpConnectionSuggestion.js +9 -1
  305. package/dist/client/sse-event-processor.d.ts +4 -2
  306. package/dist/client/sse-event-processor.js +46 -6
  307. package/dist/client/use-chat-models.js +156 -80
  308. package/dist/client/use-run-stuck-detection.d.ts +2 -0
  309. package/dist/client/use-run-stuck-detection.js +85 -9
  310. package/dist/collab/awareness.d.ts +2 -2
  311. package/dist/collab/routes.d.ts +1 -1
  312. package/dist/collab/struct-routes.d.ts +1 -1
  313. package/dist/integrations/adapters/slack.d.ts +0 -4
  314. package/dist/integrations/adapters/slack.js +6 -30
  315. package/dist/integrations/catalog.js +1 -1
  316. package/dist/integrations/pending-tasks-store.d.ts +0 -8
  317. package/dist/integrations/pending-tasks-store.js +0 -21
  318. package/dist/integrations/slack-manifest.d.ts +2 -2
  319. package/dist/integrations/slack-manifest.js +0 -3
  320. package/dist/integrations/webhook-handler.js +1 -1
  321. package/dist/mcp/screen-memory-stdio.d.ts +7 -7
  322. package/dist/observability/routes.d.ts +3 -3
  323. package/dist/provider-api/actions/custom-provider-registration.d.ts +4 -4
  324. package/dist/provider-api/actions/provider-api.d.ts +8 -8
  325. package/dist/scripts/docs/source-search.js +2 -2
  326. package/dist/server/agent-chat/framework-prompts.js +7 -2
  327. package/dist/server/agent-chat/prompt-resources.js +2 -2
  328. package/dist/server/agent-chat/skill-frontmatter.d.ts +31 -2
  329. package/dist/server/agent-chat/skill-frontmatter.js +41 -15
  330. package/dist/server/agent-chat-plugin.js +3 -3
  331. package/dist/server/agent-engine-api-key-route.d.ts +1 -1
  332. package/dist/server/agents-bundle.d.ts +16 -19
  333. package/dist/server/agents-bundle.js +19 -35
  334. package/dist/server/auth.js +262 -31
  335. package/dist/server/better-auth-instance.d.ts +1 -0
  336. package/dist/server/better-auth-instance.js +17 -2
  337. package/dist/server/onboarding-html.js +56 -9
  338. package/dist/server/prompts/framework-core-compact.d.ts +6 -1
  339. package/dist/server/prompts/framework-core-compact.js +12 -9
  340. package/dist/server/prompts/framework-core.d.ts +6 -1
  341. package/dist/server/prompts/framework-core.js +11 -9
  342. package/dist/server/prompts/index.d.ts +1 -1
  343. package/dist/server/prompts/index.js +1 -1
  344. package/dist/server/prompts/shared-rules.d.ts +15 -11
  345. package/dist/server/prompts/shared-rules.js +17 -13
  346. package/dist/server/realtime-token.d.ts +1 -1
  347. package/dist/server/transcribe-voice.d.ts +1 -1
  348. package/dist/shared/reasoning-effort.d.ts +8 -8
  349. package/dist/shared/reasoning-effort.js +10 -10
  350. package/dist/shared/streaming-text-smoothing.js +41 -11
  351. package/dist/styles/agent-native.css +19 -32
  352. package/dist/templates/chat/.agents/skills/actions/SKILL.md +54 -488
  353. package/dist/templates/chat/.agents/skills/actions/references/action-fields.md +136 -0
  354. package/dist/templates/chat/.agents/skills/actions/references/examples.md +94 -0
  355. package/dist/templates/chat/.agents/skills/actions/references/provider-apis.md +95 -0
  356. package/dist/templates/chat/.agents/skills/create-skill/SKILL.md +9 -35
  357. package/dist/templates/chat/.agents/skills/frontend-design/SKILL.md +4 -5
  358. package/dist/templates/chat/.agents/skills/turn-into-app/SKILL.md +18 -31
  359. package/dist/templates/chat/AGENTS.md +32 -80
  360. package/dist/templates/chat/changelog/2026-08-10-full-page-chat-now-uses-the-available-width-up-to-1000px-for.md +6 -0
  361. package/dist/templates/default/.agents/skills/actions/SKILL.md +54 -488
  362. package/dist/templates/default/.agents/skills/actions/references/action-fields.md +136 -0
  363. package/dist/templates/default/.agents/skills/actions/references/examples.md +94 -0
  364. package/dist/templates/default/.agents/skills/actions/references/provider-apis.md +95 -0
  365. package/dist/templates/default/.agents/skills/create-skill/SKILL.md +9 -35
  366. package/dist/templates/default/.agents/skills/frontend-design/SKILL.md +4 -5
  367. package/dist/templates/default/.agents/skills/turn-into-app/SKILL.md +18 -31
  368. package/dist/templates/headless/.agents/skills/actions/SKILL.md +54 -488
  369. package/dist/templates/headless/.agents/skills/actions/references/action-fields.md +136 -0
  370. package/dist/templates/headless/.agents/skills/actions/references/examples.md +94 -0
  371. package/dist/templates/headless/.agents/skills/actions/references/provider-apis.md +95 -0
  372. package/dist/templates/headless/.agents/skills/turn-into-app/SKILL.md +18 -31
  373. package/dist/templates/workspace-core/.agents/skills/actions/SKILL.md +54 -488
  374. package/dist/templates/workspace-core/.agents/skills/actions/references/action-fields.md +136 -0
  375. package/dist/templates/workspace-core/.agents/skills/actions/references/examples.md +94 -0
  376. package/dist/templates/workspace-core/.agents/skills/actions/references/provider-apis.md +95 -0
  377. package/dist/templates/workspace-core/.agents/skills/adding-workspace-apps/SKILL.md +1 -0
  378. package/dist/templates/workspace-core/.agents/skills/agent-page/SKILL.md +1 -0
  379. package/dist/templates/workspace-core/.agents/skills/create-skill/SKILL.md +9 -35
  380. package/dist/templates/workspace-core/.agents/skills/frontend-design/SKILL.md +4 -5
  381. package/dist/templates/workspace-core/.agents/skills/recurring-jobs/SKILL.md +21 -29
  382. package/dist/templates/workspace-core/.agents/skills/turn-into-app/SKILL.md +18 -31
  383. package/dist/templates/workspace-core/.agents/skills/workspace-conventions/SKILL.md +7 -17
  384. package/dist/templates/workspace-core/.agents/skills/writing-agent-instructions/SKILL.md +3 -3
  385. package/dist/templates/workspace-core/AGENTS.md +7 -16
  386. package/docs/content/messaging.mdx +6 -7
  387. package/docs/content/template-chat.mdx +1 -1
  388. package/package.json +2 -2
  389. package/src/templates/chat/.agents/skills/actions/SKILL.md +54 -488
  390. package/src/templates/chat/.agents/skills/actions/references/action-fields.md +136 -0
  391. package/src/templates/chat/.agents/skills/actions/references/examples.md +94 -0
  392. package/src/templates/chat/.agents/skills/actions/references/provider-apis.md +95 -0
  393. package/src/templates/chat/.agents/skills/create-skill/SKILL.md +9 -35
  394. package/src/templates/chat/.agents/skills/frontend-design/SKILL.md +4 -5
  395. package/src/templates/chat/.agents/skills/turn-into-app/SKILL.md +18 -31
  396. package/src/templates/chat/AGENTS.md +32 -80
  397. package/src/templates/chat/changelog/2026-08-10-full-page-chat-now-uses-the-available-width-up-to-1000px-for.md +6 -0
  398. package/src/templates/default/.agents/skills/actions/SKILL.md +54 -488
  399. package/src/templates/default/.agents/skills/actions/references/action-fields.md +136 -0
  400. package/src/templates/default/.agents/skills/actions/references/examples.md +94 -0
  401. package/src/templates/default/.agents/skills/actions/references/provider-apis.md +95 -0
  402. package/src/templates/default/.agents/skills/create-skill/SKILL.md +9 -35
  403. package/src/templates/default/.agents/skills/frontend-design/SKILL.md +4 -5
  404. package/src/templates/default/.agents/skills/turn-into-app/SKILL.md +18 -31
  405. package/src/templates/headless/.agents/skills/actions/SKILL.md +54 -488
  406. package/src/templates/headless/.agents/skills/actions/references/action-fields.md +136 -0
  407. package/src/templates/headless/.agents/skills/actions/references/examples.md +94 -0
  408. package/src/templates/headless/.agents/skills/actions/references/provider-apis.md +95 -0
  409. package/src/templates/headless/.agents/skills/turn-into-app/SKILL.md +18 -31
  410. package/src/templates/workspace-core/.agents/skills/actions/SKILL.md +54 -488
  411. package/src/templates/workspace-core/.agents/skills/actions/references/action-fields.md +136 -0
  412. package/src/templates/workspace-core/.agents/skills/actions/references/examples.md +94 -0
  413. package/src/templates/workspace-core/.agents/skills/actions/references/provider-apis.md +95 -0
  414. package/src/templates/workspace-core/.agents/skills/adding-workspace-apps/SKILL.md +1 -0
  415. package/src/templates/workspace-core/.agents/skills/agent-page/SKILL.md +1 -0
  416. package/src/templates/workspace-core/.agents/skills/create-skill/SKILL.md +9 -35
  417. package/src/templates/workspace-core/.agents/skills/frontend-design/SKILL.md +4 -5
  418. package/src/templates/workspace-core/.agents/skills/recurring-jobs/SKILL.md +21 -29
  419. package/src/templates/workspace-core/.agents/skills/turn-into-app/SKILL.md +18 -31
  420. package/src/templates/workspace-core/.agents/skills/workspace-conventions/SKILL.md +7 -17
  421. package/src/templates/workspace-core/.agents/skills/writing-agent-instructions/SKILL.md +3 -3
  422. package/src/templates/workspace-core/AGENTS.md +7 -16
@@ -499,10 +499,24 @@ function abortInMemoryRun(run, reason = "user") {
499
499
  threadToRun.delete(run.threadId);
500
500
  }
501
501
  run.abort.abort(reason);
502
- const terminalEvent = terminalEventForAbortReason(reason);
502
+ // Keep the abort terminal in the replay buffer as well as sending it to
503
+ // current subscribers. A reconnect can arrive after the live subscriber
504
+ // was removed but while this run is still warm in memory; closing that
505
+ // replay with no terminal frame makes the client manufacture a false
506
+ // frozen response and retry against a run that is already done.
507
+ const existingTerminalEvent = [...run.events]
508
+ .reverse()
509
+ .find((event) => isTerminalRunEvent(event.event));
510
+ const terminalRunEvent = existingTerminalEvent ?? {
511
+ seq: run.events.length,
512
+ event: terminalEventForAbortReason(reason),
513
+ };
514
+ if (!existingTerminalEvent) {
515
+ run.events.push(terminalRunEvent);
516
+ }
503
517
  for (const subscriber of run.subscribers) {
504
518
  try {
505
- subscriber({ seq: run.events.length, event: terminalEvent });
519
+ subscriber(terminalRunEvent);
506
520
  }
507
521
  catch {
508
522
  // ignore — subscriber is being removed below
@@ -596,18 +610,116 @@ export function startRun(runId, threadId, runFn, onComplete, options) {
596
610
  // Throttle the durable progress timestamp to at most once per second so
597
611
  // a chatty token-by-token stream doesn't translate into one DB write per
598
612
  // chunk. The stuck-detector threshold is on the order of tens of seconds,
599
- // so 1s resolution is plenty.
613
+ // so 1s resolution is plenty. Keep one write in flight and coalesce a
614
+ // trailing request: overlapping progress updates can exhaust a pooler and
615
+ // starve the heartbeat that is supposed to prove this run is alive.
616
+ const PROGRESS_BUMP_INTERVAL_MS = 1_000;
600
617
  let lastProgressBumpAt = 0;
618
+ let progressWriteInFlight = null;
619
+ let progressWriteTimer = null;
620
+ let progressWritePending = false;
621
+ let progressWriteAttempts = 0;
622
+ let progressWriteFailures = 0;
623
+ let consecutiveProgressWriteFailures = 0;
601
624
  const preparingActivityBytes = new Map();
602
625
  const preparingActivityTools = new Map();
603
626
  const preparingActivityRestartHighWater = new Map();
604
627
  let eventPersistenceErrorCaptured = false;
605
- const bumpProgressIfDue = () => {
606
- const now = Date.now();
607
- if (now - lastProgressBumpAt < 1000)
628
+ const recordProgressWriteFailure = (error, kind) => {
629
+ progressWriteFailures += 1;
630
+ consecutiveProgressWriteFailures += 1;
631
+ // Keep every failure counted and retried, but sample the error capture so
632
+ // a database outage does not turn one long streamed input into hundreds of
633
+ // identical reports. The run id and event count make the sampled report
634
+ // useful for correlating the durable clock with the event ledger.
635
+ if (progressWriteFailures === 1 || progressWriteFailures % 10 === 0) {
636
+ const capturedError = error instanceof Error ? error : new Error(String(error));
637
+ console.error(`[run-manager] durable progress write ${kind} failed`, runId, {
638
+ attempts: progressWriteAttempts,
639
+ failures: progressWriteFailures,
640
+ consecutiveFailures: consecutiveProgressWriteFailures,
641
+ eventCount: run.events.length,
642
+ }, capturedError);
643
+ captureError(capturedError, {
644
+ route: "/_agent-native/agent-chat",
645
+ tags: {
646
+ source: "agent-run-manager",
647
+ phase: "progress",
648
+ kind,
649
+ consecutiveFailures: String(consecutiveProgressWriteFailures),
650
+ },
651
+ aiTraceId: runId,
652
+ extra: {
653
+ runId,
654
+ threadId,
655
+ attempts: progressWriteAttempts,
656
+ failures: progressWriteFailures,
657
+ eventCount: run.events.length,
658
+ },
659
+ });
660
+ }
661
+ };
662
+ const writeProgress = async () => {
663
+ let updated = await bumpRunProgress(runId);
664
+ if (updated === false) {
665
+ // The initial run insert is intentionally asynchronous so the fast SSE
666
+ // path does not wait on SQL. If this first UPDATE wins the race, retry
667
+ // after that insert commits instead of permanently losing the first
668
+ // durable progress signal.
669
+ await insertRunPromise;
670
+ updated = await bumpRunProgress(runId);
671
+ }
672
+ if (updated === false) {
673
+ if (run.status !== "running")
674
+ return;
675
+ recordProgressWriteFailure(new Error("Durable progress update affected no running run row"), "no-row");
676
+ progressWritePending = true;
608
677
  return;
609
- lastProgressBumpAt = now;
610
- bumpRunProgress(runId).catch(() => { });
678
+ }
679
+ consecutiveProgressWriteFailures = 0;
680
+ };
681
+ function startProgressWrite() {
682
+ if (!progressWritePending ||
683
+ progressWriteInFlight ||
684
+ run.status !== "running") {
685
+ return;
686
+ }
687
+ progressWritePending = false;
688
+ lastProgressBumpAt = Date.now();
689
+ progressWriteAttempts += 1;
690
+ const write = writeProgress()
691
+ .catch((error) => {
692
+ recordProgressWriteFailure(error, "error");
693
+ // Retry even if no later event arrives. A transient failure must not
694
+ // freeze the durable clock until the next user-visible event.
695
+ progressWritePending = true;
696
+ })
697
+ .finally(() => {
698
+ progressWriteInFlight = null;
699
+ scheduleProgressWrite();
700
+ });
701
+ progressWriteInFlight = write;
702
+ }
703
+ function scheduleProgressWrite() {
704
+ if (!progressWritePending ||
705
+ progressWriteInFlight ||
706
+ progressWriteTimer ||
707
+ run.status !== "running") {
708
+ return;
709
+ }
710
+ const delayMs = Math.max(0, lastProgressBumpAt + PROGRESS_BUMP_INTERVAL_MS - Date.now());
711
+ if (delayMs === 0) {
712
+ startProgressWrite();
713
+ return;
714
+ }
715
+ progressWriteTimer = setTimeout(() => {
716
+ progressWriteTimer = null;
717
+ startProgressWrite();
718
+ }, delayMs);
719
+ }
720
+ const bumpProgressIfDue = () => {
721
+ progressWritePending = true;
722
+ scheduleProgressWrite();
611
723
  };
612
724
  const shouldBumpProgressForEvent = (event) => {
613
725
  if (event.type === "stream_keepalive")
@@ -683,6 +795,25 @@ export function startRun(runId, threadId, runFn, onComplete, options) {
683
795
  // emits nothing for minutes and carries its own 12-min timeout.
684
796
  let lastRealProgressAt = Date.now();
685
797
  let inFlightWorkCount = 0;
798
+ let inFlightMarkerSince = null;
799
+ let inFlightMarkerWrite = Promise.resolve();
800
+ const mirrorInFlightMarker = (inFlight) => {
801
+ const markerSince = inFlight ? Date.now() : inFlightMarkerSince;
802
+ if (inFlight) {
803
+ inFlightMarkerSince = markerSince;
804
+ }
805
+ else {
806
+ inFlightMarkerSince = null;
807
+ }
808
+ // Preserve transition order: a delayed clear must not erase the marker
809
+ // written for the next tool that starts before the clear reaches SQL.
810
+ inFlightMarkerWrite = inFlightMarkerWrite
811
+ .catch(() => undefined)
812
+ .then(() => setRunInFlightMarker(runId, inFlight, markerSince ?? undefined))
813
+ .catch((error) => {
814
+ console.error(`[run-manager] failed to mirror in-flight marker (${inFlight ? "set" : "clear"})`, runId, error instanceof Error ? error.message : error);
815
+ });
816
+ };
686
817
  const trackInFlightWork = (event) => {
687
818
  const wasIdle = inFlightWorkCount === 0;
688
819
  if (event.type === "tool_start") {
@@ -708,15 +839,15 @@ export function startRun(runId, threadId, runFn, onComplete, options) {
708
839
  // grant this demonstrably-alive run a bounded grace even when THIS
709
840
  // isolate's own heartbeat write is failing (e.g. Neon pooler saturation)
710
841
  // — `inFlightWorkCount` itself is in-memory and invisible to those other
711
- // isolates. Fire-and-forget: never block event emission on this write,
712
- // and a write failure here is no worse than today's behavior (the row
713
- // just gets no grace). See `setRunInFlightMarker` / `IN_FLIGHT_RUN_STALE_GRACE_MS`
714
- // in run-store.ts for the full reasoning and the bounded-grace derivation.
842
+ // isolates. Fire-and-forget: never block event emission on this write, but
843
+ // keep failures observable and preserve transition order. See
844
+ // `setRunInFlightMarker` / `IN_FLIGHT_RUN_STALE_GRACE_MS` in run-store.ts
845
+ // for the full reasoning and bounded-grace derivation.
715
846
  if (wasIdle && inFlightWorkCount > 0) {
716
- setRunInFlightMarker(runId, true).catch(() => { });
847
+ mirrorInFlightMarker(true);
717
848
  }
718
849
  else if (!wasIdle && inFlightWorkCount === 0) {
719
- setRunInFlightMarker(runId, false).catch(() => { });
850
+ mirrorInFlightMarker(false);
720
851
  }
721
852
  };
722
853
  // Make a chunk boundary durable at the instant it is decided. The terminal
@@ -1171,6 +1302,17 @@ export function startRun(runId, threadId, runFn, onComplete, options) {
1171
1302
  clearInterval(heartbeatTimer);
1172
1303
  if (softTimeoutTimer)
1173
1304
  clearTimeout(softTimeoutTimer);
1305
+ if (progressWriteTimer)
1306
+ clearTimeout(progressWriteTimer);
1307
+ progressWriteTimer = null;
1308
+ progressWritePending = false;
1309
+ // A tool can throw before its matching event is emitted, or the process
1310
+ // can reach terminal cleanup with an in-flight call still open. Do not
1311
+ // leave the SQL grace marker attached to a terminal run.
1312
+ if (inFlightWorkCount > 0 || inFlightMarkerSince !== null) {
1313
+ inFlightWorkCount = 0;
1314
+ mirrorInFlightMarker(false);
1315
+ }
1174
1316
  // 5. Persist final status to SQL. Use the conditional write so a zombie
1175
1317
  // run (reaped or displaced while executing) cannot clobber the newer
1176
1318
  // status written by the reaper or a replacement run.
@@ -457,7 +457,7 @@ export declare function updateRunHeartbeat(runId: string): Promise<void>;
457
457
  * stuck-detector can tell "process alive but nothing happening" from
458
458
  * "process dead." Callers should throttle (run-manager debounces to ~1/s).
459
459
  */
460
- export declare function bumpRunProgress(runId: string): Promise<void>;
460
+ export declare function bumpRunProgress(runId: string): Promise<boolean>;
461
461
  /**
462
462
  * Mirror run-manager's in-memory `inFlightWorkCount` 0<->N transitions into
463
463
  * SQL so a stale reaper running in a DIFFERENT isolate can tell a
@@ -469,17 +469,18 @@ export declare function bumpRunProgress(runId: string): Promise<void>;
469
469
  * depth belt-and-suspenders against a nested 1->2 transition clobbering the
470
470
  * ORIGINAL start time with a later one (the caller's own counter already
471
471
  * dedupes 0->1 transitions; this WHERE just makes the write itself
472
- * idempotent/order-independent too). `inFlight: false` always clears
473
- * unconditionally — if it races a fresh 0->1 write from a *different* tool
474
- * finishing/starting back to back, worst case is losing a few seconds of
475
- * grace, never gaining an incorrect one.
472
+ * idempotent/order-independent too). When `markerSince` is supplied for a
473
+ * clear, the UPDATE is conditional on the marker still having that value. The
474
+ * run manager serializes marker writes and supplies this token so a delayed
475
+ * clear from one tool cannot erase a newer tool's marker.
476
476
  *
477
- * Best-effort: callers fire-and-forget (`.catch(() => {})`) so a write
478
- * failure here never blocks event emission or aborts the run. If this write
479
- * itself fails (the same DB pressure that could be starving the heartbeat),
480
- * the row simply gets no grace — never worse than today's behavior.
477
+ * Best-effort: callers fire-and-forget so a write failure here never blocks
478
+ * event emission or aborts the run. The run manager logs marker-write failures
479
+ * while preserving transition order. If this write itself fails (the same DB
480
+ * pressure that could be starving the heartbeat), the row simply gets no grace
481
+ * - never worse than today's behavior.
481
482
  */
482
- export declare function setRunInFlightMarker(runId: string, inFlight: boolean): Promise<void>;
483
+ export declare function setRunInFlightMarker(runId: string, inFlight: boolean, markerSince?: number): Promise<void>;
483
484
  /**
484
485
  * If the given run is marked "running" in SQL but its heartbeat is stale
485
486
  * (producer likely crashed), flip it to "errored" so watchers stop waiting.
@@ -1351,7 +1351,7 @@ export async function bumpRunProgress(runId) {
1351
1351
  await ensureRunTables();
1352
1352
  const client = getDbExec();
1353
1353
  const now = Date.now();
1354
- await client.execute({
1354
+ const { rowsAffected } = await client.execute({
1355
1355
  // Multiple event-persistence paths and serverless isolates can bump the
1356
1356
  // same run concurrently. A slower, older write must never land after a
1357
1357
  // newer one and move the user-visible no-progress clock backwards.
@@ -1359,6 +1359,7 @@ export async function bumpRunProgress(runId) {
1359
1359
  sql: `UPDATE agent_runs SET last_progress_at = CASE WHEN last_progress_at IS NULL OR last_progress_at < ? THEN ? ELSE last_progress_at END WHERE id = ? AND status = 'running'`,
1360
1360
  args: [now, now, runId],
1361
1361
  });
1362
+ return (rowsAffected ?? 0) > 0;
1362
1363
  }
1363
1364
  /**
1364
1365
  * Mirror run-manager's in-memory `inFlightWorkCount` 0<->N transitions into
@@ -1371,29 +1372,32 @@ export async function bumpRunProgress(runId) {
1371
1372
  * depth belt-and-suspenders against a nested 1->2 transition clobbering the
1372
1373
  * ORIGINAL start time with a later one (the caller's own counter already
1373
1374
  * dedupes 0->1 transitions; this WHERE just makes the write itself
1374
- * idempotent/order-independent too). `inFlight: false` always clears
1375
- * unconditionally — if it races a fresh 0->1 write from a *different* tool
1376
- * finishing/starting back to back, worst case is losing a few seconds of
1377
- * grace, never gaining an incorrect one.
1375
+ * idempotent/order-independent too). When `markerSince` is supplied for a
1376
+ * clear, the UPDATE is conditional on the marker still having that value. The
1377
+ * run manager serializes marker writes and supplies this token so a delayed
1378
+ * clear from one tool cannot erase a newer tool's marker.
1378
1379
  *
1379
- * Best-effort: callers fire-and-forget (`.catch(() => {})`) so a write
1380
- * failure here never blocks event emission or aborts the run. If this write
1381
- * itself fails (the same DB pressure that could be starving the heartbeat),
1382
- * the row simply gets no grace — never worse than today's behavior.
1380
+ * Best-effort: callers fire-and-forget so a write failure here never blocks
1381
+ * event emission or aborts the run. The run manager logs marker-write failures
1382
+ * while preserving transition order. If this write itself fails (the same DB
1383
+ * pressure that could be starving the heartbeat), the row simply gets no grace
1384
+ * - never worse than today's behavior.
1383
1385
  */
1384
- export async function setRunInFlightMarker(runId, inFlight) {
1386
+ export async function setRunInFlightMarker(runId, inFlight, markerSince) {
1385
1387
  await ensureRunTables();
1386
1388
  const client = getDbExec();
1387
1389
  if (inFlight) {
1388
1390
  await client.execute({
1389
1391
  sql: `UPDATE agent_runs SET in_flight_since = ? WHERE id = ? AND status = 'running' AND in_flight_since IS NULL`,
1390
- args: [Date.now(), runId],
1392
+ args: [markerSince ?? Date.now(), runId],
1391
1393
  });
1392
1394
  }
1393
1395
  else {
1394
1396
  await client.execute({
1395
- sql: `UPDATE agent_runs SET in_flight_since = NULL WHERE id = ?`,
1396
- args: [runId],
1397
+ sql: markerSince == null
1398
+ ? `UPDATE agent_runs SET in_flight_since = NULL WHERE id = ?`
1399
+ : `UPDATE agent_runs SET in_flight_since = NULL WHERE id = ? AND in_flight_since = ?`,
1400
+ args: markerSince == null ? [runId] : [runId, markerSince],
1397
1401
  });
1398
1402
  }
1399
1403
  }
@@ -0,0 +1,18 @@
1
+ export interface AgentToolApprovalBinding {
2
+ ownerEmail: string;
3
+ orgId?: string | null;
4
+ threadId?: string | null;
5
+ turnId?: string | null;
6
+ toolName: string;
7
+ callId: string;
8
+ approvalKey: string;
9
+ expiresAt?: number;
10
+ }
11
+ export declare function hashAgentToolApprovalKey(approvalKey: string): string;
12
+ export declare function createAgentToolApproval(binding: AgentToolApprovalBinding): Promise<void>;
13
+ /**
14
+ * Atomically consume the server-created approval for one exact tool call.
15
+ * Client history and approval keys are only lookup input; the pending row is
16
+ * the authorization boundary and cannot be manufactured by the client.
17
+ */
18
+ export declare function consumeAgentToolApproval(binding: AgentToolApprovalBinding): Promise<boolean>;
@@ -0,0 +1,122 @@
1
+ import { createHash, randomUUID } from "node:crypto";
2
+ import { getDbExec, intType, isPostgres, retryOnDdlRace, } from "../db/client.js";
3
+ import { ensureIndexExists, ensureTableExists } from "../db/ddl-guard.js";
4
+ const APPROVAL_TTL_MS = 15 * 60_000;
5
+ const APPROVAL_CLEANUP_AGE_MS = 24 * 60 * 60_000;
6
+ let initPromise;
7
+ async function ensureAgentToolApprovalTable() {
8
+ if (!initPromise) {
9
+ initPromise = (async () => {
10
+ const createSql = `CREATE TABLE IF NOT EXISTS agent_tool_approvals (
11
+ id TEXT PRIMARY KEY,
12
+ owner_email TEXT NOT NULL,
13
+ org_id TEXT,
14
+ thread_id TEXT,
15
+ turn_id TEXT,
16
+ tool_name TEXT NOT NULL,
17
+ call_id TEXT NOT NULL,
18
+ approval_key_hash TEXT NOT NULL,
19
+ status TEXT NOT NULL,
20
+ expires_at ${intType()} NOT NULL,
21
+ consumed_at ${intType()},
22
+ created_at ${intType()} NOT NULL,
23
+ updated_at ${intType()} NOT NULL
24
+ )`;
25
+ const indexSql = `CREATE INDEX IF NOT EXISTS idx_agent_tool_approvals_binding
26
+ ON agent_tool_approvals(owner_email, org_id, thread_id, tool_name, call_id, status)`;
27
+ if (isPostgres()) {
28
+ await ensureTableExists("agent_tool_approvals", createSql);
29
+ await ensureIndexExists("idx_agent_tool_approvals_binding", indexSql);
30
+ return;
31
+ }
32
+ const client = getDbExec();
33
+ await retryOnDdlRace(() => client.execute(createSql));
34
+ await retryOnDdlRace(() => client.execute(indexSql));
35
+ })().catch((error) => {
36
+ initPromise = undefined;
37
+ throw error;
38
+ });
39
+ }
40
+ return initPromise;
41
+ }
42
+ export function hashAgentToolApprovalKey(approvalKey) {
43
+ return createHash("sha256").update(approvalKey).digest("hex");
44
+ }
45
+ export async function createAgentToolApproval(binding) {
46
+ await ensureAgentToolApprovalTable();
47
+ const now = Date.now();
48
+ const expiresAt = binding.expiresAt ?? now + APPROVAL_TTL_MS;
49
+ await getDbExec().execute({
50
+ sql: `INSERT INTO agent_tool_approvals
51
+ (id, owner_email, org_id, thread_id, turn_id, tool_name, call_id,
52
+ approval_key_hash, status, expires_at, consumed_at, created_at, updated_at)
53
+ VALUES (?, ?, ?, ?, ?, ?, ?, ?, 'pending', ?, NULL, ?, ?)`,
54
+ args: [
55
+ `agent-tool-approval-${randomUUID()}`,
56
+ binding.ownerEmail,
57
+ binding.orgId ?? null,
58
+ binding.threadId ?? null,
59
+ binding.turnId ?? null,
60
+ binding.toolName,
61
+ binding.callId,
62
+ hashAgentToolApprovalKey(binding.approvalKey),
63
+ expiresAt,
64
+ now,
65
+ now,
66
+ ],
67
+ });
68
+ // Cleanup is hygiene only. Expired rows remain unusable because consume uses
69
+ // an atomic status and expiry predicate, so cleanup failures must not affect
70
+ // the approval that was just recorded.
71
+ try {
72
+ await getDbExec().execute({
73
+ sql: `DELETE FROM agent_tool_approvals
74
+ WHERE expires_at < ? AND status <> 'pending'`,
75
+ args: [now - APPROVAL_CLEANUP_AGE_MS],
76
+ });
77
+ }
78
+ catch (error) {
79
+ console.warn("[agent] Could not clean expired tool approval records", error);
80
+ }
81
+ }
82
+ /**
83
+ * Atomically consume the server-created approval for one exact tool call.
84
+ * Client history and approval keys are only lookup input; the pending row is
85
+ * the authorization boundary and cannot be manufactured by the client.
86
+ */
87
+ export async function consumeAgentToolApproval(binding) {
88
+ await ensureAgentToolApprovalTable();
89
+ const now = Date.now();
90
+ const result = await getDbExec().execute({
91
+ sql: `UPDATE agent_tool_approvals
92
+ SET status = 'consumed', consumed_at = ?, updated_at = ?
93
+ WHERE id = (
94
+ SELECT id FROM agent_tool_approvals
95
+ WHERE owner_email = ?
96
+ AND ((org_id IS NULL AND CAST(? AS TEXT) IS NULL) OR org_id = ?)
97
+ AND ((thread_id IS NULL AND CAST(? AS TEXT) IS NULL) OR thread_id = ?)
98
+ AND tool_name = ?
99
+ AND call_id = ?
100
+ AND approval_key_hash = ?
101
+ AND status = 'pending'
102
+ AND expires_at > ?
103
+ ORDER BY created_at DESC
104
+ LIMIT 1
105
+ )
106
+ AND status = 'pending'`,
107
+ args: [
108
+ now,
109
+ now,
110
+ binding.ownerEmail,
111
+ binding.orgId ?? null,
112
+ binding.orgId ?? null,
113
+ binding.threadId ?? null,
114
+ binding.threadId ?? null,
115
+ binding.toolName,
116
+ binding.callId,
117
+ hashAgentToolApprovalKey(binding.approvalKey),
118
+ now,
119
+ ],
120
+ });
121
+ return result.rowsAffected === 1;
122
+ }
@@ -189,7 +189,7 @@ export interface AgentChatRequest {
189
189
  model?: string;
190
190
  /** Per-request engine override (sent alongside model for cross-provider switches). */
191
191
  engine?: string;
192
- /** Per-request reasoning effort override (ephemeral, from the composer picker). */
192
+ /** Per-request effort override (ephemeral, from the composer picker). */
193
193
  effort?: ReasoningEffort;
194
194
  /** Usage-tracking label for this call (e.g. "chat", "summarize"). Default: "chat". */
195
195
  usageLabel?: string;
@@ -471,7 +471,14 @@ async function executeClaudeCliRun(options) {
471
471
  });
472
472
  try {
473
473
  const result = await runClaudeCodeParticipant({
474
- role: options.permissionMode === "full-auto" ? "driver" : "watchdog",
474
+ // Claude's driver uses acceptEdits, which is the closest available
475
+ // mapping for auto-edit and full-auto. Keep ask-before-edit on the
476
+ // read-only watchdog path because this non-interactive runner has no
477
+ // approval channel to honor an edit prompt safely.
478
+ role: options.permissionMode === "auto-edit" ||
479
+ options.permissionMode === "full-auto"
480
+ ? "driver"
481
+ : "watchdog",
475
482
  prompt: buildClaudeCliPrompt(options.run, options.prompt),
476
483
  cwd,
477
484
  model,
@@ -604,7 +611,9 @@ async function executeClaudeCliRun(options) {
604
611
  }
605
612
  function buildClaudeCliPrompt(run, prompt) {
606
613
  const permissionMode = run.permissionMode ?? "full-auto";
607
- const mode = permissionMode === "full-auto" ? "Auto" : "Plan";
614
+ const mode = permissionMode === "auto-edit" || permissionMode === "full-auto"
615
+ ? "Auto"
616
+ : "Plan";
608
617
  const modeInstruction = mode === "Plan"
609
618
  ? "Inspect and explain only. Do not edit files or run mutating commands."
610
619
  : "Edit and verify as needed. Do not create, switch, reset, rebase, or stash git branches.";
@@ -24,6 +24,7 @@ import { Fragment as _Fragment, jsx as _jsx, jsxs as _jsxs } from "react/jsx-run
24
24
  import { Tooltip as DesignSystemTooltip } from "@agent-native/toolkit/design-system";
25
25
  import { IconMessageCircle, IconMessageDots, IconTerminal2, IconSettings, IconLayoutSidebarRightCollapse, IconLayoutGrid, IconCheck, IconPlus, IconX, IconDotsVertical, IconHistory, IconArrowsHorizontal, IconArrowsMaximize, IconExternalLink, } from "@tabler/icons-react";
26
26
  import React, { useState, useEffect, useRef, useCallback, useMemo, lazy, Suspense, startTransition, } from "react";
27
+ import { flushSync } from "react-dom";
27
28
  import { DropdownMenu, DropdownMenuContent, DropdownMenuItem, DropdownMenuSeparator, DropdownMenuShortcut, DropdownMenuTrigger, } from "./components/ui/dropdown-menu.js";
28
29
  import { normalizeTooltipText } from "./components/ui/tooltip.js";
29
30
  import { ErrorReportActions } from "./ErrorReportActions.js";
@@ -1700,6 +1701,26 @@ export function AgentSidebar({ children, emptyStateText = "How can I help you?",
1700
1701
  return next;
1701
1702
  });
1702
1703
  }, []);
1704
+ // `view-transition-name` is only legal to carry while a transition is
1705
+ // actually capturing. Left on permanently it makes the panel its own
1706
+ // stacking context and the containing block for every fixed/absolute
1707
+ // descendant, and enlists it as a captured group in unrelated transitions
1708
+ // (any React Router `viewTransition` navigation), which is how overlays end
1709
+ // up painted at stale offsets. Apply it only around the drawer morph, and
1710
+ // flush it into the DOM first: `startViewTransition` captures the old state
1711
+ // before it invokes the callback, so a name applied in a normal React commit
1712
+ // would land too late to be captured.
1713
+ const [drawerMorphing, setDrawerMorphing] = useState(false);
1714
+ const runDrawerMorph = useCallback((apply) => {
1715
+ flushSync(() => setDrawerMorphing(true));
1716
+ const settle = () => setDrawerMorphing(false);
1717
+ const transition = startAgentChatViewTransition(apply);
1718
+ if (!transition) {
1719
+ settle();
1720
+ return;
1721
+ }
1722
+ transition.finished.then(settle, settle);
1723
+ }, []);
1703
1724
  const snapTo75Percent = useCallback(() => {
1704
1725
  if (drawerExitTimerRef.current !== null) {
1705
1726
  clearTimeout(drawerExitTimerRef.current);
@@ -1719,8 +1740,8 @@ export function AgentSidebar({ children, emptyStateText = "How can I help you?",
1719
1740
  }
1720
1741
  catch { }
1721
1742
  };
1722
- startAgentChatViewTransition(apply);
1723
- }, [drawerPlaceholderWidth, isWideDrawer, width]);
1743
+ runDrawerMorph(apply);
1744
+ }, [runDrawerMorph, drawerPlaceholderWidth, isWideDrawer, width]);
1724
1745
  const exitWideDrawer = useCallback(() => {
1725
1746
  if (!isWideDrawer || drawerExitTimerRef.current !== null)
1726
1747
  return;
@@ -1738,8 +1759,8 @@ export function AgentSidebar({ children, emptyStateText = "How can I help you?",
1738
1759
  setIsWideDrawer(false);
1739
1760
  }, SIDEBAR_ANIMATION_MS + 32);
1740
1761
  };
1741
- startAgentChatViewTransition(apply);
1742
- }, [drawerPlaceholderWidth, isWideDrawer]);
1762
+ runDrawerMorph(apply);
1763
+ }, [runDrawerMorph, drawerPlaceholderWidth, isWideDrawer]);
1743
1764
  const handleResizeStart = useCallback(() => setIsResizing(true), []);
1744
1765
  const handleResizeEnd = useCallback(() => setIsResizing(false), []);
1745
1766
  const isLeft = position === "left";
@@ -1820,7 +1841,9 @@ export function AgentSidebar({ children, emptyStateText = "How can I help you?",
1820
1841
  borderLeft: isLeft ? "none" : "1px solid hsl(var(--border))",
1821
1842
  borderRight: isLeft ? "1px solid hsl(var(--border))" : "none",
1822
1843
  display: "flex",
1823
- viewTransitionName: SIDEBAR_DRAWER_VIEW_TRANSITION_NAME,
1844
+ ...(drawerMorphing
1845
+ ? { viewTransitionName: SIDEBAR_DRAWER_VIEW_TRANSITION_NAME }
1846
+ : null),
1824
1847
  };
1825
1848
  }
1826
1849
  else {
@@ -1841,7 +1864,9 @@ export function AgentSidebar({ children, emptyStateText = "How can I help you?",
1841
1864
  display: desktopAnimationEnabled || panelOpen ? "flex" : "none",
1842
1865
  minWidth: desktopAnimationEnabled ? 0 : undefined,
1843
1866
  pointerEvents: desktopAnimationEnabled && !panelOpen ? "none" : undefined,
1844
- viewTransitionName: SIDEBAR_DRAWER_VIEW_TRANSITION_NAME,
1867
+ ...(drawerMorphing
1868
+ ? { viewTransitionName: SIDEBAR_DRAWER_VIEW_TRANSITION_NAME }
1869
+ : null),
1845
1870
  };
1846
1871
  }
1847
1872
  // Mount the live chat surface only while visible or actively needed. Keeping
@@ -34,7 +34,7 @@ export declare function createUserMessageRunConfig(references?: Reference[], req
34
34
  model?: string;
35
35
  engine?: string;
36
36
  effort?: ReasoningEffort;
37
- }): {
37
+ }, turnId?: string): {
38
38
  runConfig?: {
39
39
  custom: {
40
40
  references?: Reference[];
@@ -45,6 +45,7 @@ export declare function createUserMessageRunConfig(references?: Reference[], req
45
45
  model?: string;
46
46
  engine?: string;
47
47
  effort?: ReasoningEffort;
48
+ turnId?: string;
48
49
  };
49
50
  };
50
51
  metadata?: {
@@ -98,13 +99,14 @@ export declare function resolveAssistantChatSubmitIntent({ isRunning, requestedI
98
99
  isRunning: boolean;
99
100
  requestedIntent?: ComposerSubmitIntent;
100
101
  }): ComposerSubmitIntent;
101
- export declare function resolveAssistantChatRunningState({ forceStopped, isRuntimeRunning, isReconnecting, optimisticRunning, isAutoResuming, hasActiveServerRun, }: {
102
+ export declare function resolveAssistantChatRunningState({ forceStopped, isRuntimeRunning, isReconnecting, optimisticRunning, isAutoResuming, hasActiveServerRun, hasTerminalRunError, }: {
102
103
  forceStopped: boolean;
103
104
  isRuntimeRunning: boolean;
104
105
  isReconnecting: boolean;
105
106
  optimisticRunning: boolean;
106
107
  isAutoResuming: boolean;
107
108
  hasActiveServerRun?: boolean;
109
+ hasTerminalRunError?: boolean;
108
110
  }): {
109
111
  isRunning: boolean;
110
112
  showRunningInUI: boolean;
@@ -136,6 +138,9 @@ type QueuedMessage = {
136
138
  recoveryAction?: AgentRecoveryAction;
137
139
  trackInRunsTray?: boolean;
138
140
  hideUserMessage?: boolean;
141
+ approvedToolCalls?: string[];
142
+ /** Preserve the logical turn when a hidden reconnect recovery is re-issued. */
143
+ turnId?: string;
139
144
  /**
140
145
  * Model/engine/effort snapshotted at enqueue time, for the same reason
141
146
  * `requestMode` is: the picker is global and live, so a queue that flushes
@@ -306,7 +311,7 @@ export interface AssistantChatProps {
306
311
  defaultModel?: string;
307
312
  /** Selected engine override for this conversation */
308
313
  selectedEngine?: string;
309
- /** Selected reasoning effort override for this conversation */
314
+ /** Selected effort override for this conversation */
310
315
  selectedEffort?: ReasoningEffort;
311
316
  /** Available engine/model list for the model picker */
312
317
  availableModels?: Array<{
@@ -319,7 +324,7 @@ export interface AssistantChatProps {
319
324
  modelListLoading?: boolean;
320
325
  /** Callback when user picks a model from the picker */
321
326
  onModelChange?: (model: string, engine: string) => void;
322
- /** Callback when user picks a reasoning effort from the picker */
327
+ /** Callback when user picks an effort from the picker */
323
328
  onEffortChange?: (effort: ReasoningEffort) => void;
324
329
  /**
325
330
  * Optional secondary model menu (e.g. an image-generation model) shown inside