@agent-native/core 0.83.0 → 0.84.1

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 (508) hide show
  1. package/README.md +2 -2
  2. package/corpus/README.md +1 -1
  3. package/corpus/core/CHANGELOG.md +34 -0
  4. package/corpus/core/README.md +2 -2
  5. package/corpus/core/docs/content/cloneable-saas.mdx +2 -2
  6. package/corpus/core/docs/content/evals.mdx +34 -12
  7. package/corpus/core/docs/content/faq.mdx +1 -1
  8. package/corpus/core/docs/content/locales/ar-SA/cloneable-saas.mdx +2 -2
  9. package/corpus/core/docs/content/locales/ar-SA/evals.mdx +7 -0
  10. package/corpus/core/docs/content/locales/ar-SA/faq.mdx +1 -1
  11. package/corpus/core/docs/content/locales/ar-SA/template-chat.mdx +1 -1
  12. package/corpus/core/docs/content/locales/de-DE/cloneable-saas.mdx +2 -2
  13. package/corpus/core/docs/content/locales/de-DE/evals.mdx +8 -0
  14. package/corpus/core/docs/content/locales/de-DE/faq.mdx +1 -1
  15. package/corpus/core/docs/content/locales/de-DE/template-chat.mdx +1 -1
  16. package/corpus/core/docs/content/locales/es-ES/cloneable-saas.mdx +2 -2
  17. package/corpus/core/docs/content/locales/es-ES/evals.mdx +8 -0
  18. package/corpus/core/docs/content/locales/es-ES/faq.mdx +1 -1
  19. package/corpus/core/docs/content/locales/es-ES/template-chat.mdx +1 -1
  20. package/corpus/core/docs/content/locales/fr-FR/cloneable-saas.mdx +2 -2
  21. package/corpus/core/docs/content/locales/fr-FR/evals.mdx +8 -0
  22. package/corpus/core/docs/content/locales/fr-FR/faq.mdx +1 -1
  23. package/corpus/core/docs/content/locales/fr-FR/template-chat.mdx +1 -1
  24. package/corpus/core/docs/content/locales/hi-IN/cloneable-saas.mdx +2 -2
  25. package/corpus/core/docs/content/locales/hi-IN/evals.mdx +8 -0
  26. package/corpus/core/docs/content/locales/hi-IN/faq.mdx +1 -1
  27. package/corpus/core/docs/content/locales/hi-IN/template-chat.mdx +1 -1
  28. package/corpus/core/docs/content/locales/ja-JP/cloneable-saas.mdx +2 -2
  29. package/corpus/core/docs/content/locales/ja-JP/evals.mdx +7 -0
  30. package/corpus/core/docs/content/locales/ja-JP/faq.mdx +1 -1
  31. package/corpus/core/docs/content/locales/ja-JP/template-chat.mdx +1 -1
  32. package/corpus/core/docs/content/locales/ko-KR/cloneable-saas.mdx +2 -2
  33. package/corpus/core/docs/content/locales/ko-KR/evals.mdx +7 -0
  34. package/corpus/core/docs/content/locales/ko-KR/faq.mdx +1 -1
  35. package/corpus/core/docs/content/locales/ko-KR/template-chat.mdx +1 -1
  36. package/corpus/core/docs/content/locales/pt-BR/cloneable-saas.mdx +2 -2
  37. package/corpus/core/docs/content/locales/pt-BR/evals.mdx +8 -0
  38. package/corpus/core/docs/content/locales/pt-BR/faq.mdx +1 -1
  39. package/corpus/core/docs/content/locales/pt-BR/template-chat.mdx +1 -1
  40. package/corpus/core/docs/content/locales/zh-CN/cloneable-saas.mdx +2 -2
  41. package/corpus/core/docs/content/locales/zh-CN/evals.mdx +7 -0
  42. package/corpus/core/docs/content/locales/zh-CN/faq.mdx +1 -1
  43. package/corpus/core/docs/content/locales/zh-CN/template-chat.mdx +1 -1
  44. package/corpus/core/docs/content/locales/zh-TW/cloneable-saas.mdx +2 -2
  45. package/corpus/core/docs/content/locales/zh-TW/evals.mdx +7 -0
  46. package/corpus/core/docs/content/locales/zh-TW/faq.mdx +1 -1
  47. package/corpus/core/docs/content/locales/zh-TW/template-chat.mdx +1 -1
  48. package/corpus/core/docs/content/template-chat.mdx +1 -1
  49. package/corpus/core/package.json +1 -1
  50. package/corpus/core/src/agent/engine/builtin.ts +1 -1
  51. package/corpus/core/src/agent/engine/output-tokens.ts +1 -1
  52. package/corpus/core/src/agent/harness/acp-adapter.ts +28 -4
  53. package/corpus/core/src/agent/harness/ai-sdk-adapter.ts +3 -0
  54. package/corpus/core/src/agent/harness/translate.ts +3 -0
  55. package/corpus/core/src/agent/harness/types.ts +1 -0
  56. package/corpus/core/src/agent/model-config.ts +34 -13
  57. package/corpus/core/src/agent/production-agent.ts +87 -10
  58. package/corpus/core/src/agent/thread-data-builder.ts +29 -4
  59. package/corpus/core/src/agent/tool-call-journal.ts +109 -48
  60. package/corpus/core/src/agent/types.ts +6 -1
  61. package/corpus/core/src/cli/design-connect.ts +106 -0
  62. package/corpus/core/src/cli/gateway-helpers.ts +17 -0
  63. package/corpus/core/src/cli/recap.ts +0 -2
  64. package/corpus/core/src/cli/skills.ts +54 -16
  65. package/corpus/core/src/cli/workspace-dev.ts +29 -5
  66. package/corpus/core/src/client/AssistantChat.tsx +89 -42
  67. package/corpus/core/src/client/DefaultSpinner.tsx +8 -1
  68. package/corpus/core/src/client/chat/message-components.tsx +49 -1
  69. package/corpus/core/src/client/chat/repo-helpers.ts +71 -0
  70. package/corpus/core/src/client/chat/run-recovery.tsx +15 -5
  71. package/corpus/core/src/client/components/ApiKeySettings.tsx +8 -8
  72. package/corpus/core/src/client/components/CodeRequiredDialog.tsx +26 -15
  73. package/corpus/core/src/client/components/MissingKeyCard.tsx +13 -6
  74. package/corpus/core/src/client/composer/TiptapComposer.tsx +4 -3
  75. package/corpus/core/src/client/extensions/ExtensionsSidebarSection.tsx +0 -1
  76. package/corpus/core/src/client/guided-questions.tsx +21 -27
  77. package/corpus/core/src/client/integrations/IntegrationCard.tsx +1 -1
  78. package/corpus/core/src/client/integrations/IntegrationsPanel.tsx +1 -1
  79. package/corpus/core/src/client/onboarding/OnboardingBanner.tsx +2 -2
  80. package/corpus/core/src/client/onboarding/OnboardingPanel.tsx +23 -19
  81. package/corpus/core/src/client/resources/ResourceEditor.tsx +18 -10
  82. package/corpus/core/src/client/resources/ResourcesPanel.tsx +5 -1
  83. package/corpus/core/src/client/settings/SettingsPanel.tsx +8 -3
  84. package/corpus/core/src/client/settings/useBuilderStatus.ts +8 -41
  85. package/corpus/core/src/client/useProductionAgent.ts +6 -2
  86. package/corpus/core/src/deploy/build.ts +1 -1
  87. package/corpus/core/src/eval/define-eval.ts +4 -1
  88. package/corpus/core/src/eval/report.ts +23 -8
  89. package/corpus/core/src/eval/runner.ts +41 -6
  90. package/corpus/core/src/eval/types.ts +11 -0
  91. package/corpus/core/src/observability/traces.ts +3 -3
  92. package/corpus/core/src/onboarding/default-steps.ts +1 -1
  93. package/corpus/core/src/scripts/agent-engines/manage-agent-engine.ts +1 -1
  94. package/corpus/core/src/scripts/agent-engines/set-agent-engine.ts +1 -1
  95. package/corpus/core/src/server/agent-chat-plugin.ts +177 -81
  96. package/corpus/core/src/server/core-routes-plugin.ts +7 -1
  97. package/corpus/core/src/server/open-route.ts +59 -40
  98. package/corpus/core/src/shared/reasoning-effort.ts +2 -0
  99. package/corpus/core/src/sharing/access.ts +22 -2
  100. package/corpus/core/src/sharing/registry.ts +18 -0
  101. package/corpus/core/src/styles/agent-native.css +104 -20
  102. package/corpus/core/src/styles/rich-markdown-editor.css +11 -10
  103. package/corpus/templates/analytics/app/components/dashboard/CumulativeNetChart.tsx +10 -10
  104. package/corpus/templates/analytics/app/components/dashboard/RevenueChart.tsx +10 -10
  105. package/corpus/templates/analytics/app/components/dashboard/RevenueComparisonChart.tsx +6 -5
  106. package/corpus/templates/analytics/app/components/dashboard/TimeSeriesChart.tsx +9 -9
  107. package/corpus/templates/analytics/app/global.css +4 -0
  108. package/corpus/templates/analytics/app/lib/chart-theme.ts +13 -0
  109. package/corpus/templates/analytics/app/pages/adhoc/_shared/KpiChart.tsx +22 -24
  110. package/corpus/templates/analytics/changelog/2026-06-30-dashboard-charts-now-use-theme-aware-tooltip-and-grid-colors.md +6 -0
  111. package/corpus/templates/analytics/changelog/2026-06-30-fixed-ask-composer-spacing-so-the-chat-field-has-a-comfortab.md +6 -0
  112. package/corpus/templates/calendar/AGENTS.md +4 -0
  113. package/corpus/templates/calendar/actions/connect-google-calendar.ts +80 -0
  114. package/corpus/templates/calendar/changelog/2026-06-30-calendar-now-gives-the-agent-a-safe-google-connection-link-i.md +6 -0
  115. package/corpus/templates/calendar/server/plugins/agent-chat.ts +4 -0
  116. package/corpus/templates/content/AGENTS.md +9 -2
  117. package/corpus/templates/content/actions/_database-row-batch.ts +230 -0
  118. package/corpus/templates/content/actions/_database-utils.ts +17 -9
  119. package/corpus/templates/content/actions/_notion-action-utils.ts +26 -0
  120. package/corpus/templates/content/actions/connect-notion-status.ts +13 -4
  121. package/corpus/templates/content/actions/create-and-link-notion-page.ts +23 -0
  122. package/corpus/templates/content/actions/delete-database-items.ts +55 -0
  123. package/corpus/templates/content/actions/delete-document.ts +4 -4
  124. package/corpus/templates/content/actions/disconnect-notion.ts +16 -0
  125. package/corpus/templates/content/actions/duplicate-database-item.ts +1 -1
  126. package/corpus/templates/content/actions/duplicate-database-items.ts +191 -0
  127. package/corpus/templates/content/actions/link-notion-page.ts +10 -7
  128. package/corpus/templates/content/actions/list-notion-links.ts +3 -4
  129. package/corpus/templates/content/actions/pull-notion-page.ts +7 -9
  130. package/corpus/templates/content/actions/push-notion-page.ts +7 -9
  131. package/corpus/templates/content/actions/refresh-notion-sync-status.ts +24 -0
  132. package/corpus/templates/content/actions/resolve-notion-sync-conflict.ts +23 -0
  133. package/corpus/templates/content/actions/search-notion-pages.ts +67 -0
  134. package/corpus/templates/content/actions/unlink-notion-page.ts +23 -0
  135. package/corpus/templates/content/app/components/editor/BubbleToolbar.tsx +5 -5
  136. package/corpus/templates/content/app/components/editor/DocumentDatabase.tsx +27 -34
  137. package/corpus/templates/content/app/components/editor/DocumentEditor.tsx +16 -13
  138. package/corpus/templates/content/app/components/editor/DocumentToolbar.tsx +10 -10
  139. package/corpus/templates/content/app/components/editor/NotionConflictBanner.tsx +1 -1
  140. package/corpus/templates/content/app/components/editor/NotionSyncBar.tsx +18 -9
  141. package/corpus/templates/content/app/components/editor/database/DatabaseView.tsx +27 -34
  142. package/corpus/templates/content/app/components/editor/database/navigation-state.ts +10 -4
  143. package/corpus/templates/content/app/components/sidebar/NotionButton.tsx +32 -17
  144. package/corpus/templates/content/app/global.css +6 -5
  145. package/corpus/templates/content/app/hooks/use-content-database.ts +35 -0
  146. package/corpus/templates/content/app/hooks/use-notion.ts +108 -99
  147. package/corpus/templates/content/changelog/2026-06-30-editor-floating-toolbars-now-use-theme-aware-colors-in-light.md +6 -0
  148. package/corpus/templates/content/package.json +3 -0
  149. package/corpus/templates/content/parity/README.md +69 -0
  150. package/corpus/templates/content/parity/eval-scenarios.ts +118 -0
  151. package/corpus/templates/content/parity/exceptions.allowlist.ts +17 -0
  152. package/corpus/templates/content/parity/matrix.md +28 -0
  153. package/corpus/templates/content/parity/matrix.ts +606 -0
  154. package/corpus/templates/content/parity/matrix.types.ts +42 -0
  155. package/corpus/templates/content/parity/parity-evals.eval.ts +4 -0
  156. package/corpus/templates/content/parity/render-matrix.ts +90 -0
  157. package/corpus/templates/content/parity/scenario-to-eval.ts +57 -0
  158. package/corpus/templates/content/shared/api.ts +11 -0
  159. package/corpus/templates/design/.agents/skills/visual-edit/SKILL.md +6 -1
  160. package/corpus/templates/design/actions/add-localhost-screens.ts +63 -8
  161. package/corpus/templates/design/actions/apply-motion-edit.ts +12 -46
  162. package/corpus/templates/design/actions/list-design-native-assets.ts +2 -1
  163. package/corpus/templates/design/actions/migrate-board-objects-to-file.ts +49 -1
  164. package/corpus/templates/design/actions/navigate.ts +3 -12
  165. package/corpus/templates/design/actions/open-visual-edit.ts +341 -0
  166. package/corpus/templates/design/actions/view-screen.ts +1 -1
  167. package/corpus/templates/design/app/components/design/CanvasContextMenu.tsx +1 -1
  168. package/corpus/templates/design/app/components/design/DesignCanvas.tsx +345 -14
  169. package/corpus/templates/design/app/components/design/DesignEditorSkeleton.tsx +71 -91
  170. package/corpus/templates/design/app/components/design/DesignExtensionsPanel.tsx +25 -27
  171. package/corpus/templates/design/app/components/design/DeviceFrame.tsx +1 -1
  172. package/corpus/templates/design/app/components/design/DrawOverlay.tsx +2 -2
  173. package/corpus/templates/design/app/components/design/EditPanel.tsx +1111 -570
  174. package/corpus/templates/design/app/components/design/LayersPanel.tsx +162 -32
  175. package/corpus/templates/design/app/components/design/MotionDock.tsx +268 -240
  176. package/corpus/templates/design/app/components/design/MultiScreenCanvas.tsx +1038 -150
  177. package/corpus/templates/design/app/components/design/QuestionFlow.tsx +1 -1
  178. package/corpus/templates/design/app/components/design/ReviewPanel.tsx +81 -102
  179. package/corpus/templates/design/app/components/design/StatesPanel.tsx +6 -6
  180. package/corpus/templates/design/app/components/design/TokensPanel.tsx +11 -11
  181. package/corpus/templates/design/app/components/design/TweaksPanel.tsx +9 -7
  182. package/corpus/templates/design/app/components/design/bridge/editor-chrome.bridge.ts +1129 -155
  183. package/corpus/templates/design/app/components/design/bridge/hit-test.bridge.ts +130 -37
  184. package/corpus/templates/design/app/components/design/canvas-primitive-style.ts +24 -11
  185. package/corpus/templates/design/app/components/design/inspector/AutoLayoutMatrix.tsx +184 -162
  186. package/corpus/templates/design/app/components/design/inspector/ConstraintsWidget.tsx +137 -79
  187. package/corpus/templates/design/app/components/design/inspector/DesignColorPicker.tsx +13 -13
  188. package/corpus/templates/design/app/components/design/inspector/ExportSettingsPanel.tsx +8 -8
  189. package/corpus/templates/design/app/components/design/inspector/GradientEditor.tsx +2 -2
  190. package/corpus/templates/design/app/components/design/inspector/ImageFillControls.tsx +4 -4
  191. package/corpus/templates/design/app/components/design/inspector/InspectorAiActions.tsx +3 -3
  192. package/corpus/templates/design/app/components/design/inspector/ScrubInput.tsx +13 -7
  193. package/corpus/templates/design/app/components/design/inspector/ShaderControls.tsx +14 -11
  194. package/corpus/templates/design/app/components/design/inspector/ShaderFillsPanel.tsx +4 -4
  195. package/corpus/templates/design/app/components/design/inspector/index.ts +2 -0
  196. package/corpus/templates/design/app/components/design/types.ts +19 -0
  197. package/corpus/templates/design/app/components/editor/PromptDialog.tsx +61 -78
  198. package/corpus/templates/design/app/components/layout/Header.tsx +0 -1
  199. package/corpus/templates/design/app/components/layout/Layout.tsx +3 -2
  200. package/corpus/templates/design/app/components/layout/Sidebar.tsx +0 -2
  201. package/corpus/templates/design/app/components/visual-editor/CanvasCommentPins.tsx +5 -4
  202. package/corpus/templates/design/app/components/visual-editor/DrawOverlay.tsx +1 -1
  203. package/corpus/templates/design/app/components/visual-editor/SaveStatusIndicator.tsx +2 -2
  204. package/corpus/templates/design/app/global.css +56 -0
  205. package/corpus/templates/design/app/hooks/use-agent-generating.ts +4 -5
  206. package/corpus/templates/design/app/hooks/use-navigation-state.ts +6 -7
  207. package/corpus/templates/design/app/hooks/use-question-flow.ts +3 -2
  208. package/corpus/templates/design/app/hooks/useAgentEditRequest.ts +6 -4
  209. package/corpus/templates/design/app/i18n/zh-TW.ts +5 -14
  210. package/corpus/templates/design/app/i18n-data.ts +63 -188
  211. package/corpus/templates/design/app/lib/agent-chat.ts +13 -0
  212. package/corpus/templates/design/app/pages/DesignEditor.tsx +1428 -384
  213. package/corpus/templates/design/app/pages/DesignSystemSetup.tsx +9 -5
  214. package/corpus/templates/design/app/pages/DesignSystems.tsx +2 -2
  215. package/corpus/templates/design/app/pages/Index.tsx +49 -26
  216. package/corpus/templates/design/app/pages/NotFound.tsx +25 -8
  217. package/corpus/templates/design/app/pages/VisualEdit.tsx +17 -5
  218. package/corpus/templates/design/app/routes/examples.tsx +1 -7
  219. package/corpus/templates/design/app/routes/templates.tsx +7 -4
  220. package/corpus/templates/design/changelog/2026-06-30-board-shapes-and-auto-layout-controls-are-clearer.md +6 -0
  221. package/corpus/templates/design/changelog/2026-06-30-component-selections-now-use-purple-component-chrome-and-sho.md +6 -0
  222. package/corpus/templates/design/changelog/2026-06-30-constraints-now-stay-tucked-into-a-compact-inspector-preview.md +6 -0
  223. package/corpus/templates/design/changelog/2026-06-30-creating-a-component-now-opens-in-a-compact-inspector-popove.md +6 -0
  224. package/corpus/templates/design/changelog/2026-06-30-design-cards-no-longer-show-legacy-project-type-badges.md +6 -0
  225. package/corpus/templates/design/changelog/2026-06-30-design-chat-now-keeps-new-turns-in-the-visible-design-agent-.md +6 -0
  226. package/corpus/templates/design/changelog/2026-06-30-design-editor-panels-now-keep-their-compact-text-sizing-cons.md +6 -0
  227. package/corpus/templates/design/changelog/2026-06-30-design-no-longer-shows-the-connected-local-code-warning-bann.md +6 -0
  228. package/corpus/templates/design/changelog/2026-06-30-design-now-opens-to-the-files-panel-unless-a-generation-is-a.md +6 -0
  229. package/corpus/templates/design/changelog/2026-06-30-design-opens-with-a-cleaner-empty-canvas-and-loading-preview.md +6 -0
  230. package/corpus/templates/design/changelog/2026-06-30-design-tools-use-simpler-less-decorative-icons.md +6 -0
  231. package/corpus/templates/design/changelog/2026-06-30-dragging-absolute-elements-no-longer-shows-coordinate-labels.md +6 -0
  232. package/corpus/templates/design/changelog/2026-06-30-fixed-all-screens-opening-too-zoomed-in-by-default.md +6 -0
  233. package/corpus/templates/design/changelog/2026-06-30-fixed-the-public-design-assets-sidebar-so-native-components-.md +6 -0
  234. package/corpus/templates/design/changelog/2026-06-30-fixed-the-screen-overview-board-so-empty-board-space-no-long.md +6 -0
  235. package/corpus/templates/design/changelog/2026-06-30-full-view-screens-can-now-scroll-while-remaining-editable.md +6 -0
  236. package/corpus/templates/design/changelog/2026-06-30-inspector-element-headers-show-the-selected-html-tag-and-the.md +6 -0
  237. package/corpus/templates/design/changelog/2026-06-30-inspector-inputs-stay-compact-across-desktop-breakpoints.md +6 -0
  238. package/corpus/templates/design/changelog/2026-06-30-layers-can-be-multi-selected-from-the-canvas-and-edited-toge.md +6 -0
  239. package/corpus/templates/design/changelog/2026-06-30-local-visual-edit-links-can-edit-localhost-frames-without-si.md +6 -0
  240. package/corpus/templates/design/changelog/2026-06-30-localhost-visual-edit-frames-can-now-be-selected-and-edited.md +6 -0
  241. package/corpus/templates/design/changelog/2026-06-30-marquee-selection-now-works-inside-screens-multi-selected-la.md +6 -0
  242. package/corpus/templates/design/changelog/2026-06-30-motion-is-now-available-from-the-persistent-left-rail-and-th.md +6 -0
  243. package/corpus/templates/design/changelog/2026-06-30-motion-timeline-collapse-and-reopen-animations-feel-smoother.md +6 -0
  244. package/corpus/templates/design/changelog/2026-06-30-multi-select-outlines-now-stay-consistent-across-all-screens.md +6 -0
  245. package/corpus/templates/design/changelog/2026-06-30-new-board-shapes-now-start-with-neutral-gray-styling.md +6 -0
  246. package/corpus/templates/design/changelog/2026-06-30-new-designs-open-into-a-steadier-loading-state-before-the-ed.md +6 -0
  247. package/corpus/templates/design/changelog/2026-06-30-new-designs-show-a-loading-state-during-handoff-and-keep-edi.md +6 -0
  248. package/corpus/templates/design/changelog/2026-06-30-public-visual-edit-design-links-now-open-directly-instead-of.md +6 -0
  249. package/corpus/templates/design/changelog/2026-06-30-removed-the-confusing-states-section-from-the-design-editor-.md +6 -0
  250. package/corpus/templates/design/changelog/2026-06-30-removed-the-templates-gallery-from-design-navigation.md +6 -0
  251. package/corpus/templates/design/changelog/2026-06-30-share-stays-visible-as-soon-as-editable-designs-load.md +6 -0
  252. package/corpus/templates/design/changelog/2026-06-30-signed-out-save-and-share-controls-use-simpler-labels-and-op.md +6 -0
  253. package/corpus/templates/design/changelog/2026-06-30-text-added-on-the-canvas-now-focuses-cleanly-with-the-right-.md +6 -0
  254. package/corpus/templates/design/changelog/2026-06-30-the-design-editor-loading-skeleton-is-simpler-and-its-bottom.md +6 -0
  255. package/corpus/templates/design/changelog/2026-06-30-the-design-editor-loading-skeleton-now-follows-the-current-t.md +6 -0
  256. package/corpus/templates/design/changelog/2026-06-30-the-design-inspector-no-longer-shows-child-layout-controls-o.md +6 -0
  257. package/corpus/templates/design/changelog/2026-06-30-the-design-inspector-no-longer-shows-the-ask-ai-section-abov.md +6 -0
  258. package/corpus/templates/design/changelog/2026-06-30-the-design-review-panel-no-longer-shows-a-separate-inline-au.md +6 -0
  259. package/corpus/templates/design/changelog/2026-06-30-the-empty-designs-page-now-focuses-on-a-single-primary-new-d.md +6 -0
  260. package/corpus/templates/design/changelog/2026-06-30-the-layers-panel-header-stays-as-layers-while-multiple-items.md +6 -0
  261. package/corpus/templates/design/changelog/2026-06-30-the-missing-design-screen-now-uses-a-neutral-back-button.md +6 -0
  262. package/corpus/templates/design/changelog/2026-06-30-the-motion-timeline-now-closes-without-squeezing-the-canvas-.md +6 -0
  263. package/corpus/templates/design/changelog/2026-06-30-the-new-design-connect-ai-setup-now-lines-up-with-the-compos.md +6 -0
  264. package/corpus/templates/design/changelog/2026-06-30-the-screen-overview-board-now-blends-into-the-canvas-and-new.md +6 -0
  265. package/corpus/templates/design/changelog/2026-06-30-top-level-canvas-drops-now-show-screen-guides.md +6 -0
  266. package/corpus/templates/design/changelog/2026-06-30-top-level-canvas-layers-now-keep-a-transparent-backdrop-and-.md +6 -0
  267. package/corpus/templates/design/changelog/2026-06-30-top-level-canvas-layers-now-select-reliably-from-all-screens.md +6 -0
  268. package/corpus/templates/design/changelog/2026-06-30-visual-edit-can-open-and-refresh-localhost-screens-in-one-au.md +6 -0
  269. package/corpus/templates/design/e2e/helpers.ts +15 -4
  270. package/corpus/templates/design/server/db/index.ts +52 -0
  271. package/corpus/templates/design/server/plugins/agent-chat.ts +5 -0
  272. package/corpus/templates/design/server/plugins/auth.ts +1 -0
  273. package/corpus/templates/design/server/plugins/core-routes.ts +4 -0
  274. package/corpus/templates/design/shared/board-file.ts +380 -5
  275. package/corpus/templates/design/shared/board-objects.ts +2 -2
  276. package/corpus/templates/design/shared/code-layer.ts +50 -6
  277. package/corpus/templates/design/shared/motion-compiler.ts +27 -0
  278. package/corpus/templates/macros/app/components/DailyProgress.tsx +41 -37
  279. package/corpus/templates/macros/app/components/ExerciseCard.tsx +2 -2
  280. package/corpus/templates/macros/app/components/MealCard.tsx +2 -2
  281. package/corpus/templates/macros/app/components/VoiceDictation.tsx +1 -1
  282. package/corpus/templates/macros/app/components/WeeklyCaloriesChart.tsx +1 -1
  283. package/corpus/templates/macros/app/components/WeightCard.tsx +2 -2
  284. package/corpus/templates/macros/app/components/WeightTracker.tsx +1 -1
  285. package/corpus/templates/macros/app/components/layout/AppLayout.tsx +1 -1
  286. package/corpus/templates/macros/app/routes/_index.tsx +5 -5
  287. package/corpus/templates/macros/app/routes/analytics.tsx +1 -1
  288. package/corpus/templates/macros/changelog/2026-06-30-dashboard-loading-and-chart-surfaces-now-use-theme-aware-col.md +6 -0
  289. package/corpus/templates/mail/app/components/email/ComposeBubbleToolbar.tsx +14 -11
  290. package/corpus/templates/mail/app/global.css +3 -2
  291. package/corpus/templates/mail/changelog/2026-06-30-compose-floating-toolbars-now-use-theme-aware-colors-in-ligh.md +6 -0
  292. package/corpus/templates/plan/app/pages/PlansPage.tsx +2 -2
  293. package/corpus/templates/slides/app/components/deck/DeckCard.tsx +3 -3
  294. package/corpus/templates/slides/app/global.css +10 -0
  295. package/corpus/templates/slides/app/pages/Index.tsx +55 -51
  296. package/corpus/templates/slides/changelog/2026-06-30-deck-thumbnails-collapse-cleanly-to-one-column-when-the-chat.md +6 -0
  297. package/dist/agent/engine/anthropic-engine.d.ts +2 -2
  298. package/dist/agent/engine/anthropic-engine.d.ts.map +1 -1
  299. package/dist/agent/engine/builder-engine.d.ts +2 -2
  300. package/dist/agent/engine/builder-engine.d.ts.map +1 -1
  301. package/dist/agent/engine/builtin.js +1 -1
  302. package/dist/agent/engine/builtin.js.map +1 -1
  303. package/dist/agent/engine/output-tokens.js +1 -1
  304. package/dist/agent/engine/output-tokens.js.map +1 -1
  305. package/dist/agent/harness/acp-adapter.d.ts +4 -1
  306. package/dist/agent/harness/acp-adapter.d.ts.map +1 -1
  307. package/dist/agent/harness/acp-adapter.js +19 -2
  308. package/dist/agent/harness/acp-adapter.js.map +1 -1
  309. package/dist/agent/harness/ai-sdk-adapter.d.ts.map +1 -1
  310. package/dist/agent/harness/ai-sdk-adapter.js +3 -0
  311. package/dist/agent/harness/ai-sdk-adapter.js.map +1 -1
  312. package/dist/agent/harness/translate.d.ts.map +1 -1
  313. package/dist/agent/harness/translate.js +3 -0
  314. package/dist/agent/harness/translate.js.map +1 -1
  315. package/dist/agent/harness/types.d.ts +1 -0
  316. package/dist/agent/harness/types.d.ts.map +1 -1
  317. package/dist/agent/harness/types.js.map +1 -1
  318. package/dist/agent/model-config.d.ts +21 -20
  319. package/dist/agent/model-config.d.ts.map +1 -1
  320. package/dist/agent/model-config.js +31 -13
  321. package/dist/agent/model-config.js.map +1 -1
  322. package/dist/agent/production-agent.d.ts.map +1 -1
  323. package/dist/agent/production-agent.js +85 -10
  324. package/dist/agent/production-agent.js.map +1 -1
  325. package/dist/agent/thread-data-builder.d.ts.map +1 -1
  326. package/dist/agent/thread-data-builder.js +27 -6
  327. package/dist/agent/thread-data-builder.js.map +1 -1
  328. package/dist/agent/tool-call-journal.d.ts +11 -9
  329. package/dist/agent/tool-call-journal.d.ts.map +1 -1
  330. package/dist/agent/tool-call-journal.js +92 -40
  331. package/dist/agent/tool-call-journal.js.map +1 -1
  332. package/dist/agent/types.d.ts +5 -1
  333. package/dist/agent/types.d.ts.map +1 -1
  334. package/dist/agent/types.js.map +1 -1
  335. package/dist/cli/design-connect.d.ts.map +1 -1
  336. package/dist/cli/design-connect.js +84 -0
  337. package/dist/cli/design-connect.js.map +1 -1
  338. package/dist/cli/gateway-helpers.d.ts +4 -0
  339. package/dist/cli/gateway-helpers.d.ts.map +1 -1
  340. package/dist/cli/gateway-helpers.js +9 -0
  341. package/dist/cli/gateway-helpers.js.map +1 -1
  342. package/dist/cli/recap.d.ts.map +1 -1
  343. package/dist/cli/recap.js +0 -2
  344. package/dist/cli/recap.js.map +1 -1
  345. package/dist/cli/skills.d.ts.map +1 -1
  346. package/dist/cli/skills.js +54 -16
  347. package/dist/cli/skills.js.map +1 -1
  348. package/dist/cli/workspace-dev.d.ts.map +1 -1
  349. package/dist/cli/workspace-dev.js +33 -6
  350. package/dist/cli/workspace-dev.js.map +1 -1
  351. package/dist/client/AssistantChat.d.ts.map +1 -1
  352. package/dist/client/AssistantChat.js +72 -26
  353. package/dist/client/AssistantChat.js.map +1 -1
  354. package/dist/client/DefaultSpinner.d.ts.map +1 -1
  355. package/dist/client/DefaultSpinner.js +8 -1
  356. package/dist/client/DefaultSpinner.js.map +1 -1
  357. package/dist/client/chat/message-components.d.ts +7 -1
  358. package/dist/client/chat/message-components.d.ts.map +1 -1
  359. package/dist/client/chat/message-components.js +37 -1
  360. package/dist/client/chat/message-components.js.map +1 -1
  361. package/dist/client/chat/repo-helpers.d.ts +1 -0
  362. package/dist/client/chat/repo-helpers.d.ts.map +1 -1
  363. package/dist/client/chat/repo-helpers.js +59 -0
  364. package/dist/client/chat/repo-helpers.js.map +1 -1
  365. package/dist/client/chat/run-recovery.d.ts.map +1 -1
  366. package/dist/client/chat/run-recovery.js +4 -4
  367. package/dist/client/chat/run-recovery.js.map +1 -1
  368. package/dist/client/components/ApiKeySettings.js +8 -8
  369. package/dist/client/components/ApiKeySettings.js.map +1 -1
  370. package/dist/client/components/CodeRequiredDialog.d.ts.map +1 -1
  371. package/dist/client/components/CodeRequiredDialog.js +24 -15
  372. package/dist/client/components/CodeRequiredDialog.js.map +1 -1
  373. package/dist/client/components/MissingKeyCard.d.ts.map +1 -1
  374. package/dist/client/components/MissingKeyCard.js +11 -6
  375. package/dist/client/components/MissingKeyCard.js.map +1 -1
  376. package/dist/client/composer/TiptapComposer.d.ts.map +1 -1
  377. package/dist/client/composer/TiptapComposer.js +4 -3
  378. package/dist/client/composer/TiptapComposer.js.map +1 -1
  379. package/dist/client/extensions/ExtensionsSidebarSection.d.ts.map +1 -1
  380. package/dist/client/extensions/ExtensionsSidebarSection.js +1 -1
  381. package/dist/client/extensions/ExtensionsSidebarSection.js.map +1 -1
  382. package/dist/client/guided-questions.d.ts.map +1 -1
  383. package/dist/client/guided-questions.js +6 -6
  384. package/dist/client/guided-questions.js.map +1 -1
  385. package/dist/client/integrations/IntegrationCard.js +1 -1
  386. package/dist/client/integrations/IntegrationCard.js.map +1 -1
  387. package/dist/client/integrations/IntegrationsPanel.js +1 -1
  388. package/dist/client/integrations/IntegrationsPanel.js.map +1 -1
  389. package/dist/client/onboarding/OnboardingBanner.js +2 -2
  390. package/dist/client/onboarding/OnboardingBanner.js.map +1 -1
  391. package/dist/client/onboarding/OnboardingPanel.js +23 -19
  392. package/dist/client/onboarding/OnboardingPanel.js.map +1 -1
  393. package/dist/client/resources/ResourceEditor.d.ts.map +1 -1
  394. package/dist/client/resources/ResourceEditor.js +13 -10
  395. package/dist/client/resources/ResourceEditor.js.map +1 -1
  396. package/dist/client/resources/ResourcesPanel.d.ts.map +1 -1
  397. package/dist/client/resources/ResourcesPanel.js +2 -1
  398. package/dist/client/resources/ResourcesPanel.js.map +1 -1
  399. package/dist/client/settings/SettingsPanel.d.ts.map +1 -1
  400. package/dist/client/settings/SettingsPanel.js +8 -3
  401. package/dist/client/settings/SettingsPanel.js.map +1 -1
  402. package/dist/client/settings/useBuilderStatus.d.ts.map +1 -1
  403. package/dist/client/settings/useBuilderStatus.js +6 -38
  404. package/dist/client/settings/useBuilderStatus.js.map +1 -1
  405. package/dist/client/useProductionAgent.d.ts +2 -1
  406. package/dist/client/useProductionAgent.d.ts.map +1 -1
  407. package/dist/client/useProductionAgent.js.map +1 -1
  408. package/dist/collab/awareness.d.ts +2 -2
  409. package/dist/collab/awareness.d.ts.map +1 -1
  410. package/dist/collab/routes.d.ts +1 -1
  411. package/dist/deploy/build.js +1 -1
  412. package/dist/deploy/build.js.map +1 -1
  413. package/dist/eval/define-eval.d.ts.map +1 -1
  414. package/dist/eval/define-eval.js +2 -1
  415. package/dist/eval/define-eval.js.map +1 -1
  416. package/dist/eval/report.d.ts.map +1 -1
  417. package/dist/eval/report.js +19 -4
  418. package/dist/eval/report.js.map +1 -1
  419. package/dist/eval/runner.d.ts.map +1 -1
  420. package/dist/eval/runner.js +38 -6
  421. package/dist/eval/runner.js.map +1 -1
  422. package/dist/eval/types.d.ts +11 -0
  423. package/dist/eval/types.d.ts.map +1 -1
  424. package/dist/eval/types.js.map +1 -1
  425. package/dist/file-upload/actions/upload-image.d.ts +2 -2
  426. package/dist/notifications/routes.d.ts +3 -3
  427. package/dist/observability/routes.d.ts +5 -5
  428. package/dist/observability/traces.d.ts.map +1 -1
  429. package/dist/observability/traces.js.map +1 -1
  430. package/dist/onboarding/default-steps.js +1 -1
  431. package/dist/onboarding/default-steps.js.map +1 -1
  432. package/dist/progress/routes.d.ts +1 -1
  433. package/dist/resources/handlers.d.ts +1 -1
  434. package/dist/scripts/agent-engines/manage-agent-engine.js +1 -1
  435. package/dist/scripts/agent-engines/manage-agent-engine.js.map +1 -1
  436. package/dist/scripts/agent-engines/set-agent-engine.js +1 -1
  437. package/dist/scripts/agent-engines/set-agent-engine.js.map +1 -1
  438. package/dist/server/agent-chat-plugin.d.ts +3 -0
  439. package/dist/server/agent-chat-plugin.d.ts.map +1 -1
  440. package/dist/server/agent-chat-plugin.js +134 -72
  441. package/dist/server/agent-chat-plugin.js.map +1 -1
  442. package/dist/server/core-routes-plugin.d.ts +3 -0
  443. package/dist/server/core-routes-plugin.d.ts.map +1 -1
  444. package/dist/server/core-routes-plugin.js +4 -1
  445. package/dist/server/core-routes-plugin.js.map +1 -1
  446. package/dist/server/open-route.d.ts +9 -0
  447. package/dist/server/open-route.d.ts.map +1 -1
  448. package/dist/server/open-route.js +48 -38
  449. package/dist/server/open-route.js.map +1 -1
  450. package/dist/shared/reasoning-effort.js +3 -0
  451. package/dist/shared/reasoning-effort.js.map +1 -1
  452. package/dist/sharing/access.d.ts.map +1 -1
  453. package/dist/sharing/access.js +18 -2
  454. package/dist/sharing/access.js.map +1 -1
  455. package/dist/sharing/registry.d.ts +10 -0
  456. package/dist/sharing/registry.d.ts.map +1 -1
  457. package/dist/sharing/registry.js.map +1 -1
  458. package/dist/styles/agent-native.css +104 -20
  459. package/dist/styles/rich-markdown-editor.css +11 -10
  460. package/docs/content/cloneable-saas.mdx +2 -2
  461. package/docs/content/evals.mdx +34 -12
  462. package/docs/content/faq.mdx +1 -1
  463. package/docs/content/locales/ar-SA/cloneable-saas.mdx +2 -2
  464. package/docs/content/locales/ar-SA/evals.mdx +7 -0
  465. package/docs/content/locales/ar-SA/faq.mdx +1 -1
  466. package/docs/content/locales/ar-SA/template-chat.mdx +1 -1
  467. package/docs/content/locales/de-DE/cloneable-saas.mdx +2 -2
  468. package/docs/content/locales/de-DE/evals.mdx +8 -0
  469. package/docs/content/locales/de-DE/faq.mdx +1 -1
  470. package/docs/content/locales/de-DE/template-chat.mdx +1 -1
  471. package/docs/content/locales/es-ES/cloneable-saas.mdx +2 -2
  472. package/docs/content/locales/es-ES/evals.mdx +8 -0
  473. package/docs/content/locales/es-ES/faq.mdx +1 -1
  474. package/docs/content/locales/es-ES/template-chat.mdx +1 -1
  475. package/docs/content/locales/fr-FR/cloneable-saas.mdx +2 -2
  476. package/docs/content/locales/fr-FR/evals.mdx +8 -0
  477. package/docs/content/locales/fr-FR/faq.mdx +1 -1
  478. package/docs/content/locales/fr-FR/template-chat.mdx +1 -1
  479. package/docs/content/locales/hi-IN/cloneable-saas.mdx +2 -2
  480. package/docs/content/locales/hi-IN/evals.mdx +8 -0
  481. package/docs/content/locales/hi-IN/faq.mdx +1 -1
  482. package/docs/content/locales/hi-IN/template-chat.mdx +1 -1
  483. package/docs/content/locales/ja-JP/cloneable-saas.mdx +2 -2
  484. package/docs/content/locales/ja-JP/evals.mdx +7 -0
  485. package/docs/content/locales/ja-JP/faq.mdx +1 -1
  486. package/docs/content/locales/ja-JP/template-chat.mdx +1 -1
  487. package/docs/content/locales/ko-KR/cloneable-saas.mdx +2 -2
  488. package/docs/content/locales/ko-KR/evals.mdx +7 -0
  489. package/docs/content/locales/ko-KR/faq.mdx +1 -1
  490. package/docs/content/locales/ko-KR/template-chat.mdx +1 -1
  491. package/docs/content/locales/pt-BR/cloneable-saas.mdx +2 -2
  492. package/docs/content/locales/pt-BR/evals.mdx +8 -0
  493. package/docs/content/locales/pt-BR/faq.mdx +1 -1
  494. package/docs/content/locales/pt-BR/template-chat.mdx +1 -1
  495. package/docs/content/locales/zh-CN/cloneable-saas.mdx +2 -2
  496. package/docs/content/locales/zh-CN/evals.mdx +7 -0
  497. package/docs/content/locales/zh-CN/faq.mdx +1 -1
  498. package/docs/content/locales/zh-CN/template-chat.mdx +1 -1
  499. package/docs/content/locales/zh-TW/cloneable-saas.mdx +2 -2
  500. package/docs/content/locales/zh-TW/evals.mdx +7 -0
  501. package/docs/content/locales/zh-TW/faq.mdx +1 -1
  502. package/docs/content/locales/zh-TW/template-chat.mdx +1 -1
  503. package/docs/content/template-chat.mdx +1 -1
  504. package/package.json +1 -1
  505. package/corpus/templates/content/server/routes/api/notion/disconnect.post.ts +0 -12
  506. package/corpus/templates/design/app/components/design/LocalSourceEditBanner.tsx +0 -157
  507. package/corpus/templates/design/app/lib/design-templates.ts +0 -1305
  508. package/corpus/templates/design/app/pages/Templates.tsx +0 -279
@@ -91,6 +91,7 @@ import {
91
91
  getRepoMessage,
92
92
  shouldImportServerThreadData,
93
93
  dedupeRepoMessagesById,
94
+ dropEmptyAssistantMessages,
94
95
  } from "./chat/repo-helpers.js";
95
96
  import {
96
97
  BuilderSetupCard,
@@ -885,7 +886,7 @@ function ensureMessageMetadata(repo: any): any {
885
886
  // throws "performOp/link: A message with the same id already exists in the
886
887
  // parent tree" (Sentry AGENT-NATIVE-BROWSER-2Q) when fed repeated ids. No-op
887
888
  // for the normal no-duplicate case. See dedupeRepoMessagesById.
888
- repo = dedupeRepoMessagesById(repo);
889
+ repo = dropEmptyAssistantMessages(dedupeRepoMessagesById(repo));
889
890
  if (!repo?.messages || !Array.isArray(repo.messages)) return repo;
890
891
  for (const entry of repo.messages) {
891
892
  // Handle both wrapped ({ message: { ... } }) and flat ({ role, ... }) formats
@@ -1347,6 +1348,7 @@ const AssistantChatInner = forwardRef<
1347
1348
  // True during the 250ms continuation window and startup of the next chunk
1348
1349
  // (adapter's auto-continue delay before POSTing the next chunk).
1349
1350
  const [isAutoResuming, setIsAutoResuming] = useState(false);
1351
+ const [optimisticRunning, setOptimisticRunning] = useState(false);
1350
1352
  const [runningActivityLabel, setRunningActivityLabel] = useState<
1351
1353
  string | null
1352
1354
  >(null);
@@ -1379,7 +1381,8 @@ const AssistantChatInner = forwardRef<
1379
1381
  // Real running state — drives submission/queue gating. Treat reconnecting
1380
1382
  // to an active run the same as running, UNLESS the user has explicitly
1381
1383
  // clicked stop (forceStopped).
1382
- const isRunning = !forceStopped && (isRuntimeRunning || isReconnecting);
1384
+ const isRunning =
1385
+ !forceStopped && (isRuntimeRunning || isReconnecting || optimisticRunning);
1383
1386
  const textStreaming = isRunning || externalStreaming;
1384
1387
  // UI-only running state — drives the stop button and thinking indicator.
1385
1388
  const showRunningInUI = isRunning;
@@ -1402,6 +1405,16 @@ const AssistantChatInner = forwardRef<
1402
1405
  // a running turn without adding many unstable closure deps to its dep list.
1403
1406
  const stopActiveRunRef = useRef<() => void>(() => {});
1404
1407
 
1408
+ const markOptimisticRunning = useCallback(() => {
1409
+ setOptimisticRunning(true);
1410
+ if (typeof window === "undefined") return;
1411
+ window.dispatchEvent(
1412
+ new CustomEvent("agentNative.chatRunning", {
1413
+ detail: { isRunning: true, tabId: tabId || threadId },
1414
+ }),
1415
+ );
1416
+ }, [tabId, threadId]);
1417
+
1405
1418
  useEffect(() => {
1406
1419
  if (lastBroadcastRunningRef.current === isRunning) return;
1407
1420
  lastBroadcastRunningRef.current = isRunning;
@@ -1412,6 +1425,20 @@ const AssistantChatInner = forwardRef<
1412
1425
  );
1413
1426
  }, [isRunning, tabId, threadId]);
1414
1427
 
1428
+ useEffect(() => {
1429
+ if (!optimisticRunning) return;
1430
+ if (!forceStopped && !isRuntimeRunning && !isReconnecting) return;
1431
+ setOptimisticRunning(false);
1432
+ }, [forceStopped, isReconnecting, isRuntimeRunning, optimisticRunning]);
1433
+
1434
+ useEffect(() => {
1435
+ if (!optimisticRunning) return;
1436
+ const timer = window.setTimeout(() => {
1437
+ setOptimisticRunning(false);
1438
+ }, 15_000);
1439
+ return () => window.clearTimeout(timer);
1440
+ }, [optimisticRunning]);
1441
+
1415
1442
  // ─── Chat persistence ──────────────────────────────────────────────
1416
1443
  const hasRestoredRef = useRef(false);
1417
1444
  const [initialCachedThreadSnapshot] = useState(() =>
@@ -1468,6 +1495,7 @@ const AssistantChatInner = forwardRef<
1468
1495
  // re-evaluates against the runtime exactly as before instead of
1469
1496
  // short-circuiting to the rejected repo.
1470
1497
  let settled = true;
1498
+ let settledRepo = repo;
1471
1499
  if (repo?.messages?.length > 0) {
1472
1500
  let shouldImport = true;
1473
1501
  try {
@@ -1482,7 +1510,9 @@ const AssistantChatInner = forwardRef<
1482
1510
  if (options?.markTitleGenerated) {
1483
1511
  titleGeneratedRef.current = true;
1484
1512
  }
1485
- threadRuntime.import(ensureMessageMetadata(repo));
1513
+ const importRepo = ensureMessageMetadata(repo);
1514
+ threadRuntime.import(importRepo);
1515
+ settledRepo = importRepo;
1486
1516
  } else {
1487
1517
  settled = false;
1488
1518
  }
@@ -1503,7 +1533,7 @@ const AssistantChatInner = forwardRef<
1503
1533
  }
1504
1534
  if (settled && signature !== null) {
1505
1535
  lastImportedSignatureRef.current = signature;
1506
- lastImportedRepoRef.current = repo;
1536
+ lastImportedRepoRef.current = settledRepo;
1507
1537
  }
1508
1538
  return repo;
1509
1539
  },
@@ -2594,6 +2624,7 @@ const AssistantChatInner = forwardRef<
2594
2624
  // all the stop-related state in its own dep array.
2595
2625
  const stopActiveRun = useCallback(() => {
2596
2626
  setForceStopped(true);
2627
+ setOptimisticRunning(false);
2597
2628
  const activeRun = getActiveRun();
2598
2629
  const runIdToAbort = reconnectRunIdRef.current ?? activeRun?.runId;
2599
2630
  userStoppedRunRef.current = {
@@ -2834,19 +2865,25 @@ const AssistantChatInner = forwardRef<
2834
2865
  },
2835
2866
  ]);
2836
2867
  } else {
2837
- appendThreadMessage({
2838
- role: "user",
2839
- content: [{ type: "text", text: submittedText }],
2840
- ...(messageAttachments.length > 0
2841
- ? { attachments: messageAttachments }
2842
- : {}),
2843
- ...createUserMessageRunConfig(
2844
- references,
2845
- effectiveRequestMode,
2846
- recoveryAction,
2847
- trackInRunsTray,
2848
- ),
2849
- } as Parameters<typeof threadRuntime.append>[0]);
2868
+ markOptimisticRunning();
2869
+ try {
2870
+ appendThreadMessage({
2871
+ role: "user",
2872
+ content: [{ type: "text", text: submittedText }],
2873
+ ...(messageAttachments.length > 0
2874
+ ? { attachments: messageAttachments }
2875
+ : {}),
2876
+ ...createUserMessageRunConfig(
2877
+ references,
2878
+ effectiveRequestMode,
2879
+ recoveryAction,
2880
+ trackInRunsTray,
2881
+ ),
2882
+ } as Parameters<typeof threadRuntime.append>[0]);
2883
+ } catch (error) {
2884
+ setOptimisticRunning(false);
2885
+ throw error;
2886
+ }
2850
2887
  }
2851
2888
  if (submitted.includesContext) {
2852
2889
  updateComposerContextItems(() => []);
@@ -2859,6 +2896,7 @@ const AssistantChatInner = forwardRef<
2859
2896
  execMode,
2860
2897
  isRunning,
2861
2898
  materializeFrozenReconnectContent,
2899
+ markOptimisticRunning,
2862
2900
  appendThreadMessage,
2863
2901
  updateComposerContextItems,
2864
2902
  ],
@@ -2918,7 +2956,7 @@ const AssistantChatInner = forwardRef<
2918
2956
  addToQueue(text, images);
2919
2957
  },
2920
2958
  isRunning() {
2921
- return thread.isRunning;
2959
+ return isRunning;
2922
2960
  },
2923
2961
  focusComposer() {
2924
2962
  tiptapRef.current?.focus();
@@ -2938,9 +2976,9 @@ const AssistantChatInner = forwardRef<
2938
2976
  [
2939
2977
  addToQueue,
2940
2978
  exportCleanThreadRepo,
2979
+ isRunning,
2941
2980
  messages.length,
2942
2981
  stageComposerContextItem,
2943
- thread.isRunning,
2944
2982
  ],
2945
2983
  );
2946
2984
 
@@ -3110,6 +3148,12 @@ const AssistantChatInner = forwardRef<
3110
3148
  centeredEmptyState && !isRestoring && hasThreadFooterSlot;
3111
3149
  const showComposerSlot =
3112
3150
  Boolean(composerSlot) && (!centerComposerWhenEmpty || centeredEmptyState);
3151
+ const compactMissingKeyEmptyState =
3152
+ missingApiKeySetupAboveComposer &&
3153
+ missingApiKey &&
3154
+ !authError &&
3155
+ showEmptyState &&
3156
+ !isRestoring;
3113
3157
 
3114
3158
  // Clarifying-question surface: the `ask-question` action writes a
3115
3159
  // GuidedQuestionPayload to application_state under "guided-questions". The
@@ -3137,6 +3181,7 @@ const AssistantChatInner = forwardRef<
3137
3181
  const approvalCtx = useMemo<ApprovalContextValue>(
3138
3182
  () => ({
3139
3183
  onApprove: (approvalKey: string) => {
3184
+ markOptimisticRunning();
3140
3185
  appendThreadMessage({
3141
3186
  role: "user",
3142
3187
  content: [
@@ -3159,7 +3204,7 @@ const AssistantChatInner = forwardRef<
3159
3204
  } as Parameters<typeof threadRuntime.append>[0]);
3160
3205
  },
3161
3206
  }),
3162
- [appendThreadMessage, execMode],
3207
+ [appendThreadMessage, execMode, markOptimisticRunning],
3163
3208
  );
3164
3209
 
3165
3210
  return (
@@ -3170,7 +3215,11 @@ const AssistantChatInner = forwardRef<
3170
3215
  <TextStreamingContext.Provider value={textStreaming}>
3171
3216
  <div
3172
3217
  data-agent-empty-state={
3173
- centeredEmptyState ? "centered" : undefined
3218
+ centeredEmptyState
3219
+ ? "centered"
3220
+ : compactMissingKeyEmptyState
3221
+ ? "compact-setup"
3222
+ : undefined
3174
3223
  }
3175
3224
  className={cn(
3176
3225
  "relative flex flex-1 flex-col h-full min-h-0 text-foreground",
@@ -3515,27 +3564,25 @@ const AssistantChatInner = forwardRef<
3515
3564
  </div>
3516
3565
  ) : null}
3517
3566
  {guidedQuestions && guidedQuestions.length > 0 && (
3518
- <div className="shrink-0 px-3 pb-2 pt-1">
3519
- <div className="rounded-lg border border-border bg-card/60 shadow-sm">
3520
- <GuidedQuestionFlow
3521
- questions={guidedQuestions}
3522
- onSubmit={handleGuidedQuestionsSubmit}
3523
- onSkip={handleGuidedQuestionsSkip}
3524
- {...(guidedQuestionsTitle
3525
- ? { title: guidedQuestionsTitle }
3526
- : {})}
3527
- {...(guidedQuestionsDescription
3528
- ? { description: guidedQuestionsDescription }
3529
- : {})}
3530
- {...(guidedQuestionsSkipLabel
3531
- ? { skipLabel: guidedQuestionsSkipLabel }
3532
- : {})}
3533
- {...(guidedQuestionsSubmitLabel
3534
- ? { submitLabel: guidedQuestionsSubmitLabel }
3535
- : {})}
3536
- className="h-auto items-stretch justify-stretch bg-transparent"
3537
- />
3538
- </div>
3567
+ <div className="shrink-0 px-3 pb-2">
3568
+ <GuidedQuestionFlow
3569
+ questions={guidedQuestions}
3570
+ onSubmit={handleGuidedQuestionsSubmit}
3571
+ onSkip={handleGuidedQuestionsSkip}
3572
+ {...(guidedQuestionsTitle
3573
+ ? { title: guidedQuestionsTitle }
3574
+ : {})}
3575
+ {...(guidedQuestionsDescription
3576
+ ? { description: guidedQuestionsDescription }
3577
+ : {})}
3578
+ {...(guidedQuestionsSkipLabel
3579
+ ? { skipLabel: guidedQuestionsSkipLabel }
3580
+ : {})}
3581
+ {...(guidedQuestionsSubmitLabel
3582
+ ? { submitLabel: guidedQuestionsSubmitLabel }
3583
+ : {})}
3584
+ className="h-auto items-stretch justify-stretch bg-transparent"
3585
+ />
3539
3586
  </div>
3540
3587
  )}
3541
3588
  {showPlanModeCallout && (
@@ -31,8 +31,15 @@ export function DefaultSpinner() {
31
31
  </svg>
32
32
  <style>{`
33
33
  @keyframes an-spin { to { transform: rotate(360deg) } }
34
+ html {
35
+ background: hsl(var(--background, 0 0% 100%));
36
+ color: hsl(var(--foreground, 240 10% 3.9%));
37
+ }
34
38
  @media (prefers-color-scheme: dark) {
35
- html { background: #09090b; color: #fafafa }
39
+ html {
40
+ background: hsl(var(--background, 240 10% 3.9%));
41
+ color: hsl(var(--foreground, 0 0% 98%));
42
+ }
36
43
  }
37
44
  `}</style>
38
45
  </div>
@@ -760,6 +760,46 @@ export function UserMessage() {
760
760
 
761
761
  // ─── AssistantMessage ─────────────────────────────────────────────────────────
762
762
 
763
+ function assistantMessageHasRenderableContent(message: {
764
+ content?: unknown;
765
+ }): boolean {
766
+ const content = message.content;
767
+ if (typeof content === "string") return content.trim().length > 0;
768
+ if (!Array.isArray(content)) return false;
769
+ return content.some((part) => {
770
+ if (!part || typeof part !== "object") return false;
771
+ const type = (part as { type?: unknown }).type;
772
+ if (type === "text") {
773
+ const text = (part as { text?: unknown }).text;
774
+ return typeof text === "string" && text.trim().length > 0;
775
+ }
776
+ return true;
777
+ });
778
+ }
779
+
780
+ function assistantMessageStatusIsTerminal(message: {
781
+ status?: { type?: unknown };
782
+ }): boolean {
783
+ const statusType = message.status?.type;
784
+ return statusType === "complete" || statusType === "incomplete";
785
+ }
786
+
787
+ export function shouldShowAssistantMessageFooter({
788
+ isLast,
789
+ chatRunning,
790
+ hasRenderableContent,
791
+ statusIsTerminal,
792
+ }: {
793
+ isLast: boolean;
794
+ chatRunning: boolean;
795
+ hasRenderableContent: boolean;
796
+ statusIsTerminal: boolean;
797
+ }): boolean {
798
+ if (!hasRenderableContent) return false;
799
+ if (!isLast) return true;
800
+ return !chatRunning && statusIsTerminal;
801
+ }
802
+
763
803
  export function AssistantMessage() {
764
804
  const [restoreState, setRestoreState] = useState<
765
805
  "idle" | "confirming" | "restoring"
@@ -772,7 +812,13 @@ export function AssistantMessage() {
772
812
  const isLast =
773
813
  thread.messages.length > 0 &&
774
814
  thread.messages[thread.messages.length - 1].id === msg.id;
775
- const isComplete = !isLast || !chatRunning;
815
+ const hasRenderableContent = assistantMessageHasRenderableContent(msg);
816
+ const isComplete = shouldShowAssistantMessageFooter({
817
+ isLast,
818
+ chatRunning,
819
+ hasRenderableContent,
820
+ statusIsTerminal: assistantMessageStatusIsTerminal(msg),
821
+ });
776
822
  const cpCtx = React.useContext(CheckpointContext);
777
823
 
778
824
  const handleRestore = useCallback(async () => {
@@ -842,6 +888,8 @@ export function AssistantMessage() {
842
888
  p.structuredMeta.toolKind === "write"),
843
889
  );
844
890
 
891
+ if (!hasRenderableContent) return null;
892
+
845
893
  return (
846
894
  <div
847
895
  className="group relative"
@@ -94,6 +94,77 @@ export function dedupeRepoMessagesById<T extends NormalizedRepo>(
94
94
  return { ...repo, messages: deduped };
95
95
  }
96
96
 
97
+ function repoMessageContentIsEmpty(content: unknown): boolean {
98
+ if (typeof content === "string") return content.trim().length === 0;
99
+ if (!Array.isArray(content)) return true;
100
+ return !content.some((part) => {
101
+ if (!part || typeof part !== "object") return false;
102
+ const type = (part as { type?: unknown }).type;
103
+ if (type === "text") {
104
+ const text = (part as { text?: unknown }).text;
105
+ return typeof text === "string" && text.trim().length > 0;
106
+ }
107
+ return true;
108
+ });
109
+ }
110
+
111
+ function entryWithParentId(
112
+ entry: RepoEntry,
113
+ parentId: string | null,
114
+ ): RepoEntry {
115
+ return { ...entry, parentId };
116
+ }
117
+
118
+ function repairRepoLinks<T extends NormalizedRepo>(
119
+ repo: T,
120
+ entries: RepoEntry[],
121
+ ): T {
122
+ const seenIds = new Set<string>();
123
+ let previousId: string | null = null;
124
+ const repaired: RepoEntry[] = [];
125
+
126
+ for (const entry of entries) {
127
+ const id = getRepoMessage(entry)?.id;
128
+ if (typeof id !== "string" || !id) continue;
129
+ const requestedParentId = entry.parentId;
130
+ const parentId =
131
+ requestedParentId === null
132
+ ? null
133
+ : typeof requestedParentId === "string" &&
134
+ seenIds.has(requestedParentId)
135
+ ? requestedParentId
136
+ : previousId;
137
+ repaired.push(entryWithParentId(entry, parentId));
138
+ seenIds.add(id);
139
+ previousId = id;
140
+ }
141
+
142
+ const headId =
143
+ typeof repo.headId === "string" && seenIds.has(repo.headId)
144
+ ? repo.headId
145
+ : previousId;
146
+ return { ...repo, messages: repaired, headId: headId ?? undefined };
147
+ }
148
+
149
+ export function dropEmptyAssistantMessages<T extends NormalizedRepo>(
150
+ repo: T | null | undefined,
151
+ ): T | null | undefined {
152
+ if (!repo || !Array.isArray(repo.messages)) return repo;
153
+
154
+ let changed = false;
155
+ const messages = repo.messages.filter((entry) => {
156
+ const message = getRepoMessage(entry);
157
+ const drop =
158
+ message?.role === "assistant" &&
159
+ repoMessageContentIsEmpty(message.content);
160
+ if (drop) changed = true;
161
+ return !drop;
162
+ });
163
+
164
+ if (!changed) return repo;
165
+ return repairRepoLinks(repo, messages);
166
+ }
167
+
97
168
  export function isAssistantMessageTerminal(
98
169
  message: RepoMessage | null,
99
170
  ): boolean {
@@ -436,14 +436,24 @@ export function BuilderSetupCard({
436
436
  "agent-builder-setup-card",
437
437
  sidebarLayout && "agent-builder-setup-card--sidebar",
438
438
  fullWidth
439
- ? "w-full pb-2"
439
+ ? "w-full px-3 pb-2"
440
440
  : sidebarLayout
441
441
  ? "mx-auto w-full max-w-[42rem] px-3 pb-2"
442
442
  : "mx-auto w-full max-w-[42rem] px-3 pb-2 sm:w-fit",
443
443
  )}
444
444
  >
445
- <div className="rounded-lg border border-border/80 bg-background/80 p-3 shadow-sm backdrop-blur">
446
- <div className="agent-builder-setup-card__content flex flex-col gap-3 sm:flex-row sm:items-center sm:justify-between">
445
+ <div
446
+ className={cn(
447
+ "agent-builder-setup-card__panel rounded-lg border border-border/80 bg-background/80 shadow-sm backdrop-blur",
448
+ sidebarLayout ? "p-2.5" : "p-3",
449
+ )}
450
+ >
451
+ <div
452
+ className={cn(
453
+ "agent-builder-setup-card__content flex flex-col sm:flex-row sm:items-center sm:justify-between",
454
+ sidebarLayout ? "gap-2" : "gap-3",
455
+ )}
456
+ >
447
457
  <div className="agent-builder-setup-card__copy min-w-0">
448
458
  <h3 className="text-[13px] font-medium text-foreground">
449
459
  Connect AI
@@ -456,7 +466,7 @@ export function BuilderSetupCard({
456
466
  className={cn(
457
467
  "agent-builder-setup-card__actions flex shrink-0",
458
468
  sidebarLayout
459
- ? "flex-col items-start gap-0 sm:items-center"
469
+ ? "flex-col items-start gap-1 sm:items-center"
460
470
  : "flex-nowrap items-center gap-2",
461
471
  )}
462
472
  >
@@ -472,7 +482,7 @@ export function BuilderSetupCard({
472
482
  )}
473
483
  aria-expanded={keyOpen}
474
484
  >
475
- {sidebarLayout ? "Or, use API key" : "Use API key"}
485
+ Use API key
476
486
  </button>
477
487
  </div>
478
488
  </div>
@@ -228,7 +228,7 @@ const styles: Record<string, React.CSSProperties> = {
228
228
  marginTop: "8px",
229
229
  padding: "6px 12px",
230
230
  fontSize: "13px",
231
- border: "1px solid rgba(255,255,255,0.15)",
231
+ border: "1px solid hsl(var(--border))",
232
232
  borderRadius: "6px",
233
233
  background: "transparent",
234
234
  color: "inherit",
@@ -242,8 +242,8 @@ const styles: Record<string, React.CSSProperties> = {
242
242
  keyCard: {
243
243
  padding: "10px 12px",
244
244
  borderRadius: "8px",
245
- border: "1px solid rgba(255,255,255,0.08)",
246
- background: "rgba(255,255,255,0.03)",
245
+ border: "1px solid hsl(var(--border))",
246
+ background: "hsl(var(--card))",
247
247
  },
248
248
  keyHeader: {
249
249
  display: "flex",
@@ -268,7 +268,7 @@ const styles: Record<string, React.CSSProperties> = {
268
268
  fontSize: "14px",
269
269
  },
270
270
  unconfiguredDot: {
271
- color: "rgba(255,255,255,0.25)",
271
+ color: "hsl(var(--muted-foreground) / 0.55)",
272
272
  fontSize: "8px",
273
273
  },
274
274
  requiredBadge: {
@@ -285,8 +285,8 @@ const styles: Record<string, React.CSSProperties> = {
285
285
  padding: "7px 10px",
286
286
  fontSize: "13px",
287
287
  borderRadius: "6px",
288
- border: "1px solid rgba(255,255,255,0.12)",
289
- background: "rgba(0,0,0,0.2)",
288
+ border: "1px solid hsl(var(--input))",
289
+ background: "hsl(var(--background))",
290
290
  color: "inherit",
291
291
  outline: "none",
292
292
  boxSizing: "border-box" as const,
@@ -302,8 +302,8 @@ const styles: Record<string, React.CSSProperties> = {
302
302
  fontWeight: 500,
303
303
  borderRadius: "6px",
304
304
  border: "none",
305
- background: "#3b82f6",
306
- color: "#fff",
305
+ background: "hsl(var(--primary))",
306
+ color: "hsl(var(--primary-foreground))",
307
307
  cursor: "pointer",
308
308
  },
309
309
  };
@@ -162,7 +162,9 @@ export function CodeRequiredDialog({
162
162
  Object.assign(e.currentTarget.style, s.optionCardHover)
163
163
  }
164
164
  onMouseLeave={(e) =>
165
- Object.assign(e.currentTarget.style, { borderColor: "#e5e7eb" })
165
+ Object.assign(e.currentTarget.style, {
166
+ borderColor: "hsl(var(--border))",
167
+ })
166
168
  }
167
169
  >
168
170
  <div style={s.optionIcon}>
@@ -190,7 +192,9 @@ export function CodeRequiredDialog({
190
192
  Object.assign(e.currentTarget.style, s.optionCardHover)
191
193
  }
192
194
  onMouseLeave={(e) =>
193
- Object.assign(e.currentTarget.style, { borderColor: "#e5e7eb" })
195
+ Object.assign(e.currentTarget.style, {
196
+ borderColor: "hsl(var(--border))",
197
+ })
194
198
  }
195
199
  onClick={handleBuilderAgent}
196
200
  >
@@ -254,7 +258,7 @@ export function CodeRequiredDialog({
254
258
  }
255
259
  onMouseLeave={(e) =>
256
260
  Object.assign(e.currentTarget.style, {
257
- borderColor: "#e5e7eb",
261
+ borderColor: "hsl(var(--border))",
258
262
  })
259
263
  }
260
264
  >
@@ -294,7 +298,13 @@ export function CodeRequiredDialog({
294
298
  )}
295
299
 
296
300
  {error && (
297
- <p style={{ color: "#ef4444", fontSize: 12, marginTop: 12 }}>
301
+ <p
302
+ style={{
303
+ color: "hsl(var(--destructive))",
304
+ fontSize: 12,
305
+ marginTop: 12,
306
+ }}
307
+ >
298
308
  {error}
299
309
  </p>
300
310
  )}
@@ -326,8 +336,9 @@ const s: Record<string, React.CSSProperties> = {
326
336
  },
327
337
  dialog: {
328
338
  position: "relative",
329
- background: "#fff",
339
+ background: "hsl(var(--popover))",
330
340
  borderRadius: "12px",
341
+ border: "1px solid hsl(var(--border))",
331
342
  maxWidth: "460px",
332
343
  width: "100%",
333
344
  padding: "24px",
@@ -335,7 +346,7 @@ const s: Record<string, React.CSSProperties> = {
335
346
  "0 20px 25px -5px rgba(0,0,0,.1), 0 8px 10px -6px rgba(0,0,0,.1)",
336
347
  fontFamily:
337
348
  '-apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, sans-serif',
338
- color: "#111827",
349
+ color: "hsl(var(--popover-foreground))",
339
350
  },
340
351
  header: {
341
352
  display: "flex",
@@ -348,11 +359,11 @@ const s: Record<string, React.CSSProperties> = {
348
359
  width: "40px",
349
360
  height: "40px",
350
361
  borderRadius: "10px",
351
- background: "#f3f4f6",
362
+ background: "hsl(var(--muted))",
352
363
  display: "flex",
353
364
  alignItems: "center",
354
365
  justifyContent: "center",
355
- color: "#6b7280",
366
+ color: "hsl(var(--muted-foreground))",
356
367
  },
357
368
  title: {
358
369
  margin: 0,
@@ -363,7 +374,7 @@ const s: Record<string, React.CSSProperties> = {
363
374
  subtitle: {
364
375
  margin: "4px 0 0",
365
376
  fontSize: "13px",
366
- color: "#6b7280",
377
+ color: "hsl(var(--muted-foreground))",
367
378
  lineHeight: "1.5",
368
379
  },
369
380
  options: {
@@ -377,7 +388,7 @@ const s: Record<string, React.CSSProperties> = {
377
388
  alignItems: "flex-start",
378
389
  gap: "14px",
379
390
  padding: "14px",
380
- border: "1px solid #e5e7eb",
391
+ border: "1px solid hsl(var(--border))",
381
392
  borderRadius: "10px",
382
393
  background: "transparent",
383
394
  cursor: "pointer",
@@ -388,7 +399,7 @@ const s: Record<string, React.CSSProperties> = {
388
399
  color: "inherit",
389
400
  },
390
401
  optionCardHover: {
391
- borderColor: "#a5b4fc",
402
+ borderColor: "hsl(var(--ring))",
392
403
  },
393
404
  optionLink: {
394
405
  textDecoration: "none",
@@ -410,7 +421,7 @@ const s: Record<string, React.CSSProperties> = {
410
421
  },
411
422
  optionDesc: {
412
423
  fontSize: "12px",
413
- color: "#6b7280",
424
+ color: "hsl(var(--muted-foreground))",
414
425
  lineHeight: "1.5",
415
426
  },
416
427
  badge: {
@@ -420,7 +431,7 @@ const s: Record<string, React.CSSProperties> = {
420
431
  fontSize: "10px",
421
432
  fontWeight: 600,
422
433
  color: "#00B5FF",
423
- background: "#e0f2fe",
434
+ background: "hsl(var(--primary) / 0.08)",
424
435
  padding: "2px 8px",
425
436
  borderRadius: "99px",
426
437
  textTransform: "uppercase",
@@ -435,7 +446,7 @@ const s: Record<string, React.CSSProperties> = {
435
446
  cursor: "pointer",
436
447
  padding: "6px",
437
448
  borderRadius: "6px",
438
- color: "#9ca3af",
449
+ color: "hsl(var(--muted-foreground))",
439
450
  display: "flex",
440
451
  alignItems: "center",
441
452
  justifyContent: "center",
@@ -445,7 +456,7 @@ const s: Record<string, React.CSSProperties> = {
445
456
  padding: "12px",
446
457
  borderRadius: "8px",
447
458
  border: "1px solid #22c55e40",
448
- background: "#f0fdf4",
459
+ background: "rgba(34,197,94,0.08)",
449
460
  display: "flex",
450
461
  flexDirection: "column",
451
462
  gap: "4px",