@agent-native/core 0.82.0 → 0.84.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (474) 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/faq.mdx +1 -1
  7. package/corpus/core/docs/content/locales/ar-SA/cloneable-saas.mdx +2 -2
  8. package/corpus/core/docs/content/locales/ar-SA/faq.mdx +1 -1
  9. package/corpus/core/docs/content/locales/ar-SA/template-chat.mdx +1 -1
  10. package/corpus/core/docs/content/locales/de-DE/cloneable-saas.mdx +2 -2
  11. package/corpus/core/docs/content/locales/de-DE/faq.mdx +1 -1
  12. package/corpus/core/docs/content/locales/de-DE/template-chat.mdx +1 -1
  13. package/corpus/core/docs/content/locales/es-ES/cloneable-saas.mdx +2 -2
  14. package/corpus/core/docs/content/locales/es-ES/faq.mdx +1 -1
  15. package/corpus/core/docs/content/locales/es-ES/template-chat.mdx +1 -1
  16. package/corpus/core/docs/content/locales/fr-FR/cloneable-saas.mdx +2 -2
  17. package/corpus/core/docs/content/locales/fr-FR/faq.mdx +1 -1
  18. package/corpus/core/docs/content/locales/fr-FR/template-chat.mdx +1 -1
  19. package/corpus/core/docs/content/locales/hi-IN/cloneable-saas.mdx +2 -2
  20. package/corpus/core/docs/content/locales/hi-IN/faq.mdx +1 -1
  21. package/corpus/core/docs/content/locales/hi-IN/template-chat.mdx +1 -1
  22. package/corpus/core/docs/content/locales/ja-JP/cloneable-saas.mdx +2 -2
  23. package/corpus/core/docs/content/locales/ja-JP/faq.mdx +1 -1
  24. package/corpus/core/docs/content/locales/ja-JP/template-chat.mdx +1 -1
  25. package/corpus/core/docs/content/locales/ko-KR/cloneable-saas.mdx +2 -2
  26. package/corpus/core/docs/content/locales/ko-KR/faq.mdx +1 -1
  27. package/corpus/core/docs/content/locales/ko-KR/template-chat.mdx +1 -1
  28. package/corpus/core/docs/content/locales/pt-BR/cloneable-saas.mdx +2 -2
  29. package/corpus/core/docs/content/locales/pt-BR/faq.mdx +1 -1
  30. package/corpus/core/docs/content/locales/pt-BR/template-chat.mdx +1 -1
  31. package/corpus/core/docs/content/locales/zh-CN/cloneable-saas.mdx +2 -2
  32. package/corpus/core/docs/content/locales/zh-CN/faq.mdx +1 -1
  33. package/corpus/core/docs/content/locales/zh-CN/template-chat.mdx +1 -1
  34. package/corpus/core/docs/content/locales/zh-TW/cloneable-saas.mdx +2 -2
  35. package/corpus/core/docs/content/locales/zh-TW/faq.mdx +1 -1
  36. package/corpus/core/docs/content/locales/zh-TW/template-chat.mdx +1 -1
  37. package/corpus/core/docs/content/template-chat.mdx +1 -1
  38. package/corpus/core/package.json +1 -1
  39. package/corpus/core/src/agent/engine/builtin.ts +1 -1
  40. package/corpus/core/src/agent/engine/output-tokens.ts +1 -1
  41. package/corpus/core/src/agent/harness/acp-adapter.ts +28 -4
  42. package/corpus/core/src/agent/harness/ai-sdk-adapter.ts +3 -0
  43. package/corpus/core/src/agent/harness/translate.ts +3 -0
  44. package/corpus/core/src/agent/harness/types.ts +1 -0
  45. package/corpus/core/src/agent/model-config.ts +34 -13
  46. package/corpus/core/src/agent/production-agent.ts +87 -10
  47. package/corpus/core/src/agent/thread-data-builder.ts +29 -4
  48. package/corpus/core/src/agent/tool-call-journal.ts +109 -48
  49. package/corpus/core/src/agent/types.ts +6 -1
  50. package/corpus/core/src/cli/design-connect.ts +106 -0
  51. package/corpus/core/src/cli/gateway-helpers.ts +17 -0
  52. package/corpus/core/src/cli/recap.ts +0 -2
  53. package/corpus/core/src/cli/skills.ts +54 -16
  54. package/corpus/core/src/cli/workspace-dev.ts +29 -5
  55. package/corpus/core/src/client/AssistantChat.tsx +89 -42
  56. package/corpus/core/src/client/CommandMenu.tsx +34 -12
  57. package/corpus/core/src/client/DefaultSpinner.tsx +8 -1
  58. package/corpus/core/src/client/chat/message-components.tsx +49 -1
  59. package/corpus/core/src/client/chat/repo-helpers.ts +71 -0
  60. package/corpus/core/src/client/chat/run-recovery.tsx +15 -5
  61. package/corpus/core/src/client/components/ApiKeySettings.tsx +8 -8
  62. package/corpus/core/src/client/components/CodeRequiredDialog.tsx +26 -15
  63. package/corpus/core/src/client/components/MissingKeyCard.tsx +13 -6
  64. package/corpus/core/src/client/composer/TiptapComposer.tsx +4 -3
  65. package/corpus/core/src/client/extensions/ExtensionsSidebarSection.tsx +0 -1
  66. package/corpus/core/src/client/guided-questions.tsx +21 -27
  67. package/corpus/core/src/client/integrations/IntegrationCard.tsx +1 -1
  68. package/corpus/core/src/client/integrations/IntegrationsPanel.tsx +1 -1
  69. package/corpus/core/src/client/onboarding/OnboardingBanner.tsx +2 -2
  70. package/corpus/core/src/client/onboarding/OnboardingPanel.tsx +23 -19
  71. package/corpus/core/src/client/resources/ResourceEditor.tsx +18 -10
  72. package/corpus/core/src/client/resources/ResourcesPanel.tsx +5 -1
  73. package/corpus/core/src/client/settings/SettingsPanel.tsx +8 -3
  74. package/corpus/core/src/client/settings/useBuilderStatus.ts +8 -41
  75. package/corpus/core/src/client/useProductionAgent.ts +6 -2
  76. package/corpus/core/src/deploy/build.ts +1 -1
  77. package/corpus/core/src/observability/traces.ts +3 -3
  78. package/corpus/core/src/onboarding/default-steps.ts +1 -1
  79. package/corpus/core/src/scripts/agent-engines/manage-agent-engine.ts +1 -1
  80. package/corpus/core/src/scripts/agent-engines/set-agent-engine.ts +1 -1
  81. package/corpus/core/src/server/agent-chat-plugin.ts +177 -81
  82. package/corpus/core/src/server/core-routes-plugin.ts +7 -1
  83. package/corpus/core/src/server/open-route.ts +59 -40
  84. package/corpus/core/src/shared/reasoning-effort.ts +2 -0
  85. package/corpus/core/src/sharing/access.ts +22 -2
  86. package/corpus/core/src/sharing/registry.ts +18 -0
  87. package/corpus/core/src/styles/agent-native.css +104 -20
  88. package/corpus/core/src/styles/rich-markdown-editor.css +11 -10
  89. package/corpus/templates/analytics/actions/hubspot-deals.ts +64 -4
  90. package/corpus/templates/analytics/app/components/dashboard/CumulativeNetChart.tsx +10 -10
  91. package/corpus/templates/analytics/app/components/dashboard/RevenueChart.tsx +10 -10
  92. package/corpus/templates/analytics/app/components/dashboard/RevenueComparisonChart.tsx +6 -5
  93. package/corpus/templates/analytics/app/components/dashboard/TimeSeriesChart.tsx +9 -9
  94. package/corpus/templates/analytics/app/global.css +4 -0
  95. package/corpus/templates/analytics/app/lib/chart-theme.ts +13 -0
  96. package/corpus/templates/analytics/app/pages/adhoc/_shared/KpiChart.tsx +22 -24
  97. package/corpus/templates/analytics/changelog/2026-06-30-dashboard-charts-now-use-theme-aware-tooltip-and-grid-colors.md +6 -0
  98. package/corpus/templates/analytics/changelog/2026-06-30-fixed-ask-composer-spacing-so-the-chat-field-has-a-comfortab.md +6 -0
  99. package/corpus/templates/calendar/AGENTS.md +4 -0
  100. package/corpus/templates/calendar/actions/connect-google-calendar.ts +80 -0
  101. package/corpus/templates/calendar/changelog/2026-06-30-calendar-now-gives-the-agent-a-safe-google-connection-link-i.md +6 -0
  102. package/corpus/templates/calendar/server/plugins/agent-chat.ts +4 -0
  103. package/corpus/templates/content/.env.local.example +6 -0
  104. package/corpus/templates/content/AGENTS.md +10 -1
  105. package/corpus/templates/content/actions/_builder-cms-read-client.ts +14 -1
  106. package/corpus/templates/content/actions/_builder-cms-source-adapter.ts +43 -0
  107. package/corpus/templates/content/actions/_builder-cms-write-adapter.ts +79 -7
  108. package/corpus/templates/content/actions/_database-source-utils.ts +987 -22
  109. package/corpus/templates/content/actions/_database-utils.ts +41 -0
  110. package/corpus/templates/content/actions/_local-file-documents.ts +74 -1
  111. package/corpus/templates/content/actions/attach-content-database-source.ts +33 -8
  112. package/corpus/templates/content/actions/change-content-database-source-role.ts +14 -0
  113. package/corpus/templates/content/actions/disconnect-content-database-source.ts +3 -0
  114. package/corpus/templates/content/actions/execute-builder-source-execution.ts +71 -3
  115. package/corpus/templates/content/actions/list-content-databases.ts +41 -33
  116. package/corpus/templates/content/actions/process-builder-body-hydration.ts +47 -0
  117. package/corpus/templates/content/actions/update-document.ts +93 -0
  118. package/corpus/templates/content/app/blocks/SourceComponentBlock.tsx +277 -0
  119. package/corpus/templates/content/app/blocks/contentBlockRegistry.tsx +2 -0
  120. package/corpus/templates/content/app/components/editor/BubbleToolbar.tsx +5 -5
  121. package/corpus/templates/content/app/components/editor/DocumentEditor.tsx +45 -4
  122. package/corpus/templates/content/app/components/editor/VisualEditor.tsx +5 -1
  123. package/corpus/templates/content/app/components/editor/database/DatabaseView.tsx +92 -0
  124. package/corpus/templates/content/app/components/editor/database-sources/BuilderSourceReviewDialog.tsx +5 -3
  125. package/corpus/templates/content/app/components/editor/extensions/registryBlocks.ts +41 -0
  126. package/corpus/templates/content/app/components/editor/registrySlashItems.ts +4 -0
  127. package/corpus/templates/content/app/global.css +16 -8
  128. package/corpus/templates/content/app/hooks/use-content-database.ts +24 -0
  129. package/corpus/templates/content/app/i18n/zh-TW.ts +24 -0
  130. package/corpus/templates/content/app/i18n-data.ts +212 -0
  131. package/corpus/templates/content/app/lib/content-command-search.ts +64 -0
  132. package/corpus/templates/content/app/root.tsx +236 -8
  133. package/corpus/templates/content/changelog/2026-06-29-builder-cms-sources-now-sync-article-bodies-through-content.md +6 -0
  134. package/corpus/templates/content/changelog/2026-06-30-builder-article-media-now-render-as-images-and-embeds-when-r.md +6 -0
  135. package/corpus/templates/content/changelog/2026-06-30-builder-source-components-now-render-as-preserved-preview-bl.md +6 -0
  136. package/corpus/templates/content/changelog/2026-06-30-cmd-k-search-now-opens-from-the-editor-and-finds-real-content.md +6 -0
  137. package/corpus/templates/content/changelog/2026-06-30-editor-floating-toolbars-now-use-theme-aware-colors-in-light.md +6 -0
  138. package/corpus/templates/content/package.json +3 -1
  139. package/corpus/templates/content/scripts/check-native-deps.mjs +57 -0
  140. package/corpus/templates/content/scripts/dev-database.mjs +83 -0
  141. package/corpus/templates/content/scripts/seed-demo-user.mjs +107 -0
  142. package/corpus/templates/content/server/db/schema.ts +27 -0
  143. package/corpus/templates/content/server/plugins/db.ts +33 -0
  144. package/corpus/templates/content/shared/api.ts +45 -0
  145. package/corpus/templates/content/shared/builder-mdx.ts +905 -5
  146. package/corpus/templates/content/shared/nfm-registry.ts +2 -0
  147. package/corpus/templates/content/shared/source-component-block.ts +141 -0
  148. package/corpus/templates/design/.agents/skills/visual-edit/SKILL.md +6 -1
  149. package/corpus/templates/design/actions/add-localhost-screens.ts +63 -8
  150. package/corpus/templates/design/actions/apply-motion-edit.ts +12 -46
  151. package/corpus/templates/design/actions/list-design-native-assets.ts +2 -1
  152. package/corpus/templates/design/actions/migrate-board-objects-to-file.ts +49 -1
  153. package/corpus/templates/design/actions/navigate.ts +3 -12
  154. package/corpus/templates/design/actions/open-visual-edit.ts +341 -0
  155. package/corpus/templates/design/actions/view-screen.ts +1 -1
  156. package/corpus/templates/design/app/components/design/CanvasContextMenu.tsx +1 -1
  157. package/corpus/templates/design/app/components/design/DesignCanvas.tsx +350 -15
  158. package/corpus/templates/design/app/components/design/DesignEditorSkeleton.tsx +71 -91
  159. package/corpus/templates/design/app/components/design/DesignExtensionsPanel.tsx +25 -27
  160. package/corpus/templates/design/app/components/design/DeviceFrame.tsx +1 -1
  161. package/corpus/templates/design/app/components/design/DrawOverlay.tsx +2 -2
  162. package/corpus/templates/design/app/components/design/EditPanel.tsx +1111 -570
  163. package/corpus/templates/design/app/components/design/LayersPanel.tsx +162 -32
  164. package/corpus/templates/design/app/components/design/MotionDock.tsx +268 -240
  165. package/corpus/templates/design/app/components/design/MultiScreenCanvas.tsx +1193 -207
  166. package/corpus/templates/design/app/components/design/QuestionFlow.tsx +1 -1
  167. package/corpus/templates/design/app/components/design/ReviewPanel.tsx +81 -102
  168. package/corpus/templates/design/app/components/design/StatesPanel.tsx +6 -6
  169. package/corpus/templates/design/app/components/design/TokensPanel.tsx +11 -11
  170. package/corpus/templates/design/app/components/design/TweaksPanel.tsx +9 -7
  171. package/corpus/templates/design/app/components/design/bridge/editor-chrome.bridge.ts +1225 -154
  172. package/corpus/templates/design/app/components/design/bridge/hit-test.bridge.ts +130 -37
  173. package/corpus/templates/design/app/components/design/canvas-primitive-style.ts +24 -11
  174. package/corpus/templates/design/app/components/design/inspector/AutoLayoutMatrix.tsx +184 -162
  175. package/corpus/templates/design/app/components/design/inspector/ConstraintsWidget.tsx +137 -79
  176. package/corpus/templates/design/app/components/design/inspector/DesignColorPicker.tsx +13 -13
  177. package/corpus/templates/design/app/components/design/inspector/ExportSettingsPanel.tsx +8 -8
  178. package/corpus/templates/design/app/components/design/inspector/GradientEditor.tsx +2 -2
  179. package/corpus/templates/design/app/components/design/inspector/ImageFillControls.tsx +4 -4
  180. package/corpus/templates/design/app/components/design/inspector/InspectorAiActions.tsx +3 -3
  181. package/corpus/templates/design/app/components/design/inspector/ScrubInput.tsx +13 -7
  182. package/corpus/templates/design/app/components/design/inspector/ShaderControls.tsx +14 -11
  183. package/corpus/templates/design/app/components/design/inspector/ShaderFillsPanel.tsx +4 -4
  184. package/corpus/templates/design/app/components/design/inspector/index.ts +2 -0
  185. package/corpus/templates/design/app/components/design/types.ts +19 -0
  186. package/corpus/templates/design/app/components/editor/PromptDialog.tsx +61 -78
  187. package/corpus/templates/design/app/components/layout/Header.tsx +0 -1
  188. package/corpus/templates/design/app/components/layout/Layout.tsx +3 -2
  189. package/corpus/templates/design/app/components/layout/Sidebar.tsx +0 -2
  190. package/corpus/templates/design/app/components/visual-editor/CanvasCommentPins.tsx +5 -4
  191. package/corpus/templates/design/app/components/visual-editor/DrawOverlay.tsx +1 -1
  192. package/corpus/templates/design/app/components/visual-editor/SaveStatusIndicator.tsx +2 -2
  193. package/corpus/templates/design/app/global.css +56 -0
  194. package/corpus/templates/design/app/hooks/use-agent-generating.ts +4 -5
  195. package/corpus/templates/design/app/hooks/use-navigation-state.ts +6 -7
  196. package/corpus/templates/design/app/hooks/use-question-flow.ts +3 -2
  197. package/corpus/templates/design/app/hooks/useAgentEditRequest.ts +6 -4
  198. package/corpus/templates/design/app/hooks/useDesignHotkeys.ts +6 -3
  199. package/corpus/templates/design/app/i18n/zh-TW.ts +5 -14
  200. package/corpus/templates/design/app/i18n-data.ts +63 -188
  201. package/corpus/templates/design/app/lib/agent-chat.ts +13 -0
  202. package/corpus/templates/design/app/pages/DesignEditor.tsx +1755 -401
  203. package/corpus/templates/design/app/pages/DesignSystemSetup.tsx +9 -5
  204. package/corpus/templates/design/app/pages/DesignSystems.tsx +2 -2
  205. package/corpus/templates/design/app/pages/Index.tsx +49 -26
  206. package/corpus/templates/design/app/pages/NotFound.tsx +25 -8
  207. package/corpus/templates/design/app/pages/VisualEdit.tsx +17 -5
  208. package/corpus/templates/design/app/routes/examples.tsx +1 -7
  209. package/corpus/templates/design/app/routes/templates.tsx +7 -4
  210. package/corpus/templates/design/changelog/2026-06-30-board-shapes-and-auto-layout-controls-are-clearer.md +6 -0
  211. package/corpus/templates/design/changelog/2026-06-30-canvas-editing-now-keeps-undo-redo-and-cross-screen-layer-mo.md +6 -0
  212. package/corpus/templates/design/changelog/2026-06-30-component-selections-now-use-purple-component-chrome-and-sho.md +6 -0
  213. package/corpus/templates/design/changelog/2026-06-30-constraints-now-stay-tucked-into-a-compact-inspector-preview.md +6 -0
  214. package/corpus/templates/design/changelog/2026-06-30-creating-a-component-now-opens-in-a-compact-inspector-popove.md +6 -0
  215. package/corpus/templates/design/changelog/2026-06-30-design-cards-no-longer-show-legacy-project-type-badges.md +6 -0
  216. package/corpus/templates/design/changelog/2026-06-30-design-chat-now-keeps-new-turns-in-the-visible-design-agent-.md +6 -0
  217. package/corpus/templates/design/changelog/2026-06-30-design-editor-panels-now-keep-their-compact-text-sizing-cons.md +6 -0
  218. package/corpus/templates/design/changelog/2026-06-30-design-no-longer-shows-the-connected-local-code-warning-bann.md +6 -0
  219. package/corpus/templates/design/changelog/2026-06-30-design-now-opens-to-the-files-panel-unless-a-generation-is-a.md +6 -0
  220. package/corpus/templates/design/changelog/2026-06-30-design-opens-with-a-cleaner-empty-canvas-and-loading-preview.md +6 -0
  221. package/corpus/templates/design/changelog/2026-06-30-design-tools-use-simpler-less-decorative-icons.md +6 -0
  222. package/corpus/templates/design/changelog/2026-06-30-dragging-absolute-elements-no-longer-shows-coordinate-labels.md +6 -0
  223. package/corpus/templates/design/changelog/2026-06-30-fixed-all-screens-opening-too-zoomed-in-by-default.md +6 -0
  224. package/corpus/templates/design/changelog/2026-06-30-fixed-the-public-design-assets-sidebar-so-native-components-.md +6 -0
  225. package/corpus/templates/design/changelog/2026-06-30-fixed-the-screen-overview-board-so-empty-board-space-no-long.md +6 -0
  226. package/corpus/templates/design/changelog/2026-06-30-full-view-screens-can-now-scroll-while-remaining-editable.md +6 -0
  227. package/corpus/templates/design/changelog/2026-06-30-inspector-element-headers-show-the-selected-html-tag-and-the.md +6 -0
  228. package/corpus/templates/design/changelog/2026-06-30-inspector-inputs-stay-compact-across-desktop-breakpoints.md +6 -0
  229. package/corpus/templates/design/changelog/2026-06-30-layers-can-be-multi-selected-from-the-canvas-and-edited-toge.md +6 -0
  230. package/corpus/templates/design/changelog/2026-06-30-local-visual-edit-links-can-edit-localhost-frames-without-si.md +6 -0
  231. package/corpus/templates/design/changelog/2026-06-30-localhost-visual-edit-frames-can-now-be-selected-and-edited.md +6 -0
  232. package/corpus/templates/design/changelog/2026-06-30-marquee-selection-now-works-inside-screens-multi-selected-la.md +6 -0
  233. package/corpus/templates/design/changelog/2026-06-30-motion-is-now-available-from-the-persistent-left-rail-and-th.md +6 -0
  234. package/corpus/templates/design/changelog/2026-06-30-motion-timeline-collapse-and-reopen-animations-feel-smoother.md +6 -0
  235. package/corpus/templates/design/changelog/2026-06-30-multi-select-outlines-now-stay-consistent-across-all-screens.md +6 -0
  236. package/corpus/templates/design/changelog/2026-06-30-new-board-shapes-now-start-with-neutral-gray-styling.md +6 -0
  237. package/corpus/templates/design/changelog/2026-06-30-new-designs-open-into-a-steadier-loading-state-before-the-ed.md +6 -0
  238. package/corpus/templates/design/changelog/2026-06-30-new-designs-show-a-loading-state-during-handoff-and-keep-edi.md +6 -0
  239. package/corpus/templates/design/changelog/2026-06-30-public-visual-edit-design-links-now-open-directly-instead-of.md +6 -0
  240. package/corpus/templates/design/changelog/2026-06-30-removed-the-confusing-states-section-from-the-design-editor-.md +6 -0
  241. package/corpus/templates/design/changelog/2026-06-30-removed-the-templates-gallery-from-design-navigation.md +6 -0
  242. package/corpus/templates/design/changelog/2026-06-30-share-stays-visible-as-soon-as-editable-designs-load.md +6 -0
  243. package/corpus/templates/design/changelog/2026-06-30-signed-out-save-and-share-controls-use-simpler-labels-and-op.md +6 -0
  244. package/corpus/templates/design/changelog/2026-06-30-text-added-on-the-canvas-now-focuses-cleanly-with-the-right-.md +6 -0
  245. package/corpus/templates/design/changelog/2026-06-30-the-design-editor-loading-skeleton-is-simpler-and-its-bottom.md +6 -0
  246. package/corpus/templates/design/changelog/2026-06-30-the-design-editor-loading-skeleton-now-follows-the-current-t.md +6 -0
  247. package/corpus/templates/design/changelog/2026-06-30-the-design-inspector-no-longer-shows-child-layout-controls-o.md +6 -0
  248. package/corpus/templates/design/changelog/2026-06-30-the-design-inspector-no-longer-shows-the-ask-ai-section-abov.md +6 -0
  249. package/corpus/templates/design/changelog/2026-06-30-the-design-review-panel-no-longer-shows-a-separate-inline-au.md +6 -0
  250. package/corpus/templates/design/changelog/2026-06-30-the-empty-designs-page-now-focuses-on-a-single-primary-new-d.md +6 -0
  251. package/corpus/templates/design/changelog/2026-06-30-the-layers-panel-header-stays-as-layers-while-multiple-items.md +6 -0
  252. package/corpus/templates/design/changelog/2026-06-30-the-missing-design-screen-now-uses-a-neutral-back-button.md +6 -0
  253. package/corpus/templates/design/changelog/2026-06-30-the-motion-timeline-now-closes-without-squeezing-the-canvas-.md +6 -0
  254. package/corpus/templates/design/changelog/2026-06-30-the-new-design-connect-ai-setup-now-lines-up-with-the-compos.md +6 -0
  255. package/corpus/templates/design/changelog/2026-06-30-the-screen-overview-board-now-blends-into-the-canvas-and-new.md +6 -0
  256. package/corpus/templates/design/changelog/2026-06-30-top-level-canvas-drops-now-show-screen-guides.md +6 -0
  257. package/corpus/templates/design/changelog/2026-06-30-top-level-canvas-layers-now-keep-a-transparent-backdrop-and-.md +6 -0
  258. package/corpus/templates/design/changelog/2026-06-30-top-level-canvas-layers-now-select-reliably-from-all-screens.md +6 -0
  259. package/corpus/templates/design/changelog/2026-06-30-visual-edit-can-open-and-refresh-localhost-screens-in-one-au.md +6 -0
  260. package/corpus/templates/design/e2e/helpers.ts +15 -4
  261. package/corpus/templates/design/server/db/index.ts +52 -0
  262. package/corpus/templates/design/server/plugins/agent-chat.ts +5 -0
  263. package/corpus/templates/design/server/plugins/auth.ts +1 -0
  264. package/corpus/templates/design/server/plugins/core-routes.ts +4 -0
  265. package/corpus/templates/design/shared/board-file.ts +380 -5
  266. package/corpus/templates/design/shared/board-objects.ts +2 -2
  267. package/corpus/templates/design/shared/code-layer.ts +50 -6
  268. package/corpus/templates/design/shared/motion-compiler.ts +27 -0
  269. package/corpus/templates/macros/app/components/DailyProgress.tsx +41 -37
  270. package/corpus/templates/macros/app/components/ExerciseCard.tsx +2 -2
  271. package/corpus/templates/macros/app/components/MealCard.tsx +2 -2
  272. package/corpus/templates/macros/app/components/VoiceDictation.tsx +1 -1
  273. package/corpus/templates/macros/app/components/WeeklyCaloriesChart.tsx +1 -1
  274. package/corpus/templates/macros/app/components/WeightCard.tsx +2 -2
  275. package/corpus/templates/macros/app/components/WeightTracker.tsx +1 -1
  276. package/corpus/templates/macros/app/components/layout/AppLayout.tsx +1 -1
  277. package/corpus/templates/macros/app/routes/_index.tsx +5 -5
  278. package/corpus/templates/macros/app/routes/analytics.tsx +1 -1
  279. package/corpus/templates/macros/changelog/2026-06-30-dashboard-loading-and-chart-surfaces-now-use-theme-aware-col.md +6 -0
  280. package/corpus/templates/mail/app/components/email/ComposeBubbleToolbar.tsx +14 -11
  281. package/corpus/templates/mail/app/global.css +3 -2
  282. package/corpus/templates/mail/changelog/2026-06-30-compose-floating-toolbars-now-use-theme-aware-colors-in-ligh.md +6 -0
  283. package/corpus/templates/plan/app/pages/PlansPage.tsx +2 -2
  284. package/corpus/templates/slides/app/components/deck/DeckCard.tsx +3 -3
  285. package/corpus/templates/slides/app/global.css +10 -0
  286. package/corpus/templates/slides/app/pages/Index.tsx +55 -51
  287. package/corpus/templates/slides/changelog/2026-06-30-deck-thumbnails-collapse-cleanly-to-one-column-when-the-chat.md +6 -0
  288. package/dist/agent/engine/anthropic-engine.d.ts +2 -2
  289. package/dist/agent/engine/anthropic-engine.d.ts.map +1 -1
  290. package/dist/agent/engine/builder-engine.d.ts +2 -2
  291. package/dist/agent/engine/builder-engine.d.ts.map +1 -1
  292. package/dist/agent/engine/builtin.js +1 -1
  293. package/dist/agent/engine/builtin.js.map +1 -1
  294. package/dist/agent/engine/output-tokens.js +1 -1
  295. package/dist/agent/engine/output-tokens.js.map +1 -1
  296. package/dist/agent/harness/acp-adapter.d.ts +4 -1
  297. package/dist/agent/harness/acp-adapter.d.ts.map +1 -1
  298. package/dist/agent/harness/acp-adapter.js +19 -2
  299. package/dist/agent/harness/acp-adapter.js.map +1 -1
  300. package/dist/agent/harness/ai-sdk-adapter.d.ts.map +1 -1
  301. package/dist/agent/harness/ai-sdk-adapter.js +3 -0
  302. package/dist/agent/harness/ai-sdk-adapter.js.map +1 -1
  303. package/dist/agent/harness/translate.d.ts.map +1 -1
  304. package/dist/agent/harness/translate.js +3 -0
  305. package/dist/agent/harness/translate.js.map +1 -1
  306. package/dist/agent/harness/types.d.ts +1 -0
  307. package/dist/agent/harness/types.d.ts.map +1 -1
  308. package/dist/agent/harness/types.js.map +1 -1
  309. package/dist/agent/model-config.d.ts +21 -20
  310. package/dist/agent/model-config.d.ts.map +1 -1
  311. package/dist/agent/model-config.js +31 -13
  312. package/dist/agent/model-config.js.map +1 -1
  313. package/dist/agent/production-agent.d.ts.map +1 -1
  314. package/dist/agent/production-agent.js +85 -10
  315. package/dist/agent/production-agent.js.map +1 -1
  316. package/dist/agent/thread-data-builder.d.ts.map +1 -1
  317. package/dist/agent/thread-data-builder.js +27 -6
  318. package/dist/agent/thread-data-builder.js.map +1 -1
  319. package/dist/agent/tool-call-journal.d.ts +11 -9
  320. package/dist/agent/tool-call-journal.d.ts.map +1 -1
  321. package/dist/agent/tool-call-journal.js +92 -40
  322. package/dist/agent/tool-call-journal.js.map +1 -1
  323. package/dist/agent/types.d.ts +5 -1
  324. package/dist/agent/types.d.ts.map +1 -1
  325. package/dist/agent/types.js.map +1 -1
  326. package/dist/cli/design-connect.d.ts.map +1 -1
  327. package/dist/cli/design-connect.js +84 -0
  328. package/dist/cli/design-connect.js.map +1 -1
  329. package/dist/cli/gateway-helpers.d.ts +4 -0
  330. package/dist/cli/gateway-helpers.d.ts.map +1 -1
  331. package/dist/cli/gateway-helpers.js +9 -0
  332. package/dist/cli/gateway-helpers.js.map +1 -1
  333. package/dist/cli/recap.d.ts.map +1 -1
  334. package/dist/cli/recap.js +0 -2
  335. package/dist/cli/recap.js.map +1 -1
  336. package/dist/cli/skills.d.ts.map +1 -1
  337. package/dist/cli/skills.js +54 -16
  338. package/dist/cli/skills.js.map +1 -1
  339. package/dist/cli/workspace-dev.d.ts.map +1 -1
  340. package/dist/cli/workspace-dev.js +33 -6
  341. package/dist/cli/workspace-dev.js.map +1 -1
  342. package/dist/client/AssistantChat.d.ts.map +1 -1
  343. package/dist/client/AssistantChat.js +72 -26
  344. package/dist/client/AssistantChat.js.map +1 -1
  345. package/dist/client/CommandMenu.d.ts +6 -2
  346. package/dist/client/CommandMenu.d.ts.map +1 -1
  347. package/dist/client/CommandMenu.js +25 -14
  348. package/dist/client/CommandMenu.js.map +1 -1
  349. package/dist/client/DefaultSpinner.d.ts.map +1 -1
  350. package/dist/client/DefaultSpinner.js +8 -1
  351. package/dist/client/DefaultSpinner.js.map +1 -1
  352. package/dist/client/chat/message-components.d.ts +7 -1
  353. package/dist/client/chat/message-components.d.ts.map +1 -1
  354. package/dist/client/chat/message-components.js +37 -1
  355. package/dist/client/chat/message-components.js.map +1 -1
  356. package/dist/client/chat/repo-helpers.d.ts +1 -0
  357. package/dist/client/chat/repo-helpers.d.ts.map +1 -1
  358. package/dist/client/chat/repo-helpers.js +59 -0
  359. package/dist/client/chat/repo-helpers.js.map +1 -1
  360. package/dist/client/chat/run-recovery.d.ts.map +1 -1
  361. package/dist/client/chat/run-recovery.js +4 -4
  362. package/dist/client/chat/run-recovery.js.map +1 -1
  363. package/dist/client/components/ApiKeySettings.js +8 -8
  364. package/dist/client/components/ApiKeySettings.js.map +1 -1
  365. package/dist/client/components/CodeRequiredDialog.d.ts.map +1 -1
  366. package/dist/client/components/CodeRequiredDialog.js +24 -15
  367. package/dist/client/components/CodeRequiredDialog.js.map +1 -1
  368. package/dist/client/components/MissingKeyCard.d.ts.map +1 -1
  369. package/dist/client/components/MissingKeyCard.js +11 -6
  370. package/dist/client/components/MissingKeyCard.js.map +1 -1
  371. package/dist/client/composer/TiptapComposer.d.ts.map +1 -1
  372. package/dist/client/composer/TiptapComposer.js +4 -3
  373. package/dist/client/composer/TiptapComposer.js.map +1 -1
  374. package/dist/client/extensions/ExtensionsSidebarSection.d.ts.map +1 -1
  375. package/dist/client/extensions/ExtensionsSidebarSection.js +1 -1
  376. package/dist/client/extensions/ExtensionsSidebarSection.js.map +1 -1
  377. package/dist/client/guided-questions.d.ts.map +1 -1
  378. package/dist/client/guided-questions.js +6 -6
  379. package/dist/client/guided-questions.js.map +1 -1
  380. package/dist/client/integrations/IntegrationCard.js +1 -1
  381. package/dist/client/integrations/IntegrationCard.js.map +1 -1
  382. package/dist/client/integrations/IntegrationsPanel.js +1 -1
  383. package/dist/client/integrations/IntegrationsPanel.js.map +1 -1
  384. package/dist/client/onboarding/OnboardingBanner.js +2 -2
  385. package/dist/client/onboarding/OnboardingBanner.js.map +1 -1
  386. package/dist/client/onboarding/OnboardingPanel.js +23 -19
  387. package/dist/client/onboarding/OnboardingPanel.js.map +1 -1
  388. package/dist/client/resources/ResourceEditor.d.ts.map +1 -1
  389. package/dist/client/resources/ResourceEditor.js +13 -10
  390. package/dist/client/resources/ResourceEditor.js.map +1 -1
  391. package/dist/client/resources/ResourcesPanel.d.ts.map +1 -1
  392. package/dist/client/resources/ResourcesPanel.js +2 -1
  393. package/dist/client/resources/ResourcesPanel.js.map +1 -1
  394. package/dist/client/settings/SettingsPanel.d.ts.map +1 -1
  395. package/dist/client/settings/SettingsPanel.js +8 -3
  396. package/dist/client/settings/SettingsPanel.js.map +1 -1
  397. package/dist/client/settings/useBuilderStatus.d.ts.map +1 -1
  398. package/dist/client/settings/useBuilderStatus.js +6 -38
  399. package/dist/client/settings/useBuilderStatus.js.map +1 -1
  400. package/dist/client/useProductionAgent.d.ts +2 -1
  401. package/dist/client/useProductionAgent.d.ts.map +1 -1
  402. package/dist/client/useProductionAgent.js.map +1 -1
  403. package/dist/deploy/build.js +1 -1
  404. package/dist/deploy/build.js.map +1 -1
  405. package/dist/notifications/routes.d.ts +3 -3
  406. package/dist/observability/routes.d.ts +3 -3
  407. package/dist/observability/traces.d.ts.map +1 -1
  408. package/dist/observability/traces.js.map +1 -1
  409. package/dist/onboarding/default-steps.js +1 -1
  410. package/dist/onboarding/default-steps.js.map +1 -1
  411. package/dist/scripts/agent-engines/manage-agent-engine.js +1 -1
  412. package/dist/scripts/agent-engines/manage-agent-engine.js.map +1 -1
  413. package/dist/scripts/agent-engines/set-agent-engine.js +1 -1
  414. package/dist/scripts/agent-engines/set-agent-engine.js.map +1 -1
  415. package/dist/server/agent-chat-plugin.d.ts +3 -0
  416. package/dist/server/agent-chat-plugin.d.ts.map +1 -1
  417. package/dist/server/agent-chat-plugin.js +134 -72
  418. package/dist/server/agent-chat-plugin.js.map +1 -1
  419. package/dist/server/agent-engine-api-key-route.d.ts +1 -1
  420. package/dist/server/core-routes-plugin.d.ts +3 -0
  421. package/dist/server/core-routes-plugin.d.ts.map +1 -1
  422. package/dist/server/core-routes-plugin.js +4 -1
  423. package/dist/server/core-routes-plugin.js.map +1 -1
  424. package/dist/server/open-route.d.ts +9 -0
  425. package/dist/server/open-route.d.ts.map +1 -1
  426. package/dist/server/open-route.js +48 -38
  427. package/dist/server/open-route.js.map +1 -1
  428. package/dist/shared/reasoning-effort.js +3 -0
  429. package/dist/shared/reasoning-effort.js.map +1 -1
  430. package/dist/sharing/access.d.ts.map +1 -1
  431. package/dist/sharing/access.js +18 -2
  432. package/dist/sharing/access.js.map +1 -1
  433. package/dist/sharing/registry.d.ts +10 -0
  434. package/dist/sharing/registry.d.ts.map +1 -1
  435. package/dist/sharing/registry.js.map +1 -1
  436. package/dist/styles/agent-native.css +104 -20
  437. package/dist/styles/rich-markdown-editor.css +11 -10
  438. package/docs/content/cloneable-saas.mdx +2 -2
  439. package/docs/content/faq.mdx +1 -1
  440. package/docs/content/locales/ar-SA/cloneable-saas.mdx +2 -2
  441. package/docs/content/locales/ar-SA/faq.mdx +1 -1
  442. package/docs/content/locales/ar-SA/template-chat.mdx +1 -1
  443. package/docs/content/locales/de-DE/cloneable-saas.mdx +2 -2
  444. package/docs/content/locales/de-DE/faq.mdx +1 -1
  445. package/docs/content/locales/de-DE/template-chat.mdx +1 -1
  446. package/docs/content/locales/es-ES/cloneable-saas.mdx +2 -2
  447. package/docs/content/locales/es-ES/faq.mdx +1 -1
  448. package/docs/content/locales/es-ES/template-chat.mdx +1 -1
  449. package/docs/content/locales/fr-FR/cloneable-saas.mdx +2 -2
  450. package/docs/content/locales/fr-FR/faq.mdx +1 -1
  451. package/docs/content/locales/fr-FR/template-chat.mdx +1 -1
  452. package/docs/content/locales/hi-IN/cloneable-saas.mdx +2 -2
  453. package/docs/content/locales/hi-IN/faq.mdx +1 -1
  454. package/docs/content/locales/hi-IN/template-chat.mdx +1 -1
  455. package/docs/content/locales/ja-JP/cloneable-saas.mdx +2 -2
  456. package/docs/content/locales/ja-JP/faq.mdx +1 -1
  457. package/docs/content/locales/ja-JP/template-chat.mdx +1 -1
  458. package/docs/content/locales/ko-KR/cloneable-saas.mdx +2 -2
  459. package/docs/content/locales/ko-KR/faq.mdx +1 -1
  460. package/docs/content/locales/ko-KR/template-chat.mdx +1 -1
  461. package/docs/content/locales/pt-BR/cloneable-saas.mdx +2 -2
  462. package/docs/content/locales/pt-BR/faq.mdx +1 -1
  463. package/docs/content/locales/pt-BR/template-chat.mdx +1 -1
  464. package/docs/content/locales/zh-CN/cloneable-saas.mdx +2 -2
  465. package/docs/content/locales/zh-CN/faq.mdx +1 -1
  466. package/docs/content/locales/zh-CN/template-chat.mdx +1 -1
  467. package/docs/content/locales/zh-TW/cloneable-saas.mdx +2 -2
  468. package/docs/content/locales/zh-TW/faq.mdx +1 -1
  469. package/docs/content/locales/zh-TW/template-chat.mdx +1 -1
  470. package/docs/content/template-chat.mdx +1 -1
  471. package/package.json +1 -1
  472. package/corpus/templates/design/app/components/design/LocalSourceEditBanner.tsx +0 -157
  473. package/corpus/templates/design/app/lib/design-templates.ts +0 -1305
  474. 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 && (
@@ -261,6 +261,8 @@ export interface CommandMenuProps {
261
261
  open: boolean;
262
262
  onOpenChange: (open: boolean) => void;
263
263
  children: ReactNode;
264
+ /** Render app-specific dynamic results from the current search value. */
265
+ renderResults?: (search: string) => ReactNode;
264
266
  /** Placeholder text for the search input */
265
267
  placeholder?: string;
266
268
  /** Text shown when no results match (before showing agent fallback) */
@@ -291,6 +293,7 @@ export function CommandMenu({
291
293
  open,
292
294
  onOpenChange,
293
295
  children,
296
+ renderResults,
294
297
  placeholder = "Type a command or ask AI...",
295
298
  emptyText: _emptyText = "No commands found.",
296
299
  showAgentFallback = true,
@@ -325,8 +328,15 @@ export function CommandMenu({
325
328
  setTimeout(() => setChangelogOpen(true), 50);
326
329
  }, [onOpenChange, markChangelogSeen]);
327
330
 
328
- // Focus input when opening
331
+ // Focus input when opening; clear search while closed so reopen never renders
332
+ // dynamic results for the previous query.
329
333
  useEffect(() => {
334
+ if (!open) {
335
+ setSearch("");
336
+ setSelectedIndex(0);
337
+ return;
338
+ }
339
+
330
340
  if (open) {
331
341
  setSearch("");
332
342
  setSelectedIndex(0);
@@ -497,6 +507,8 @@ export function CommandMenu({
497
507
  React.isValidElement(child) &&
498
508
  (child.type === CommandGroup || child.type === CommandDocsGroup),
499
509
  );
510
+ const dynamicResults = open ? renderResults?.(search) : null;
511
+ const hasDynamicResults = Boolean(dynamicResults);
500
512
 
501
513
  return (
502
514
  <>
@@ -528,6 +540,7 @@ export function CommandMenu({
528
540
 
529
541
  {/* Command list */}
530
542
  <div className="max-h-[300px] overflow-y-auto overflow-x-hidden">
543
+ {dynamicResults}
531
544
  {hasResults && filteredChildren}
532
545
 
533
546
  {/* What's new — built-in changelog entry */}
@@ -567,7 +580,9 @@ export function CommandMenu({
567
580
  {/* Ask AI — always visible at the bottom */}
568
581
  {showAgentFallback && (
569
582
  <>
570
- {(hasResults || showChangelogRow) && <CommandSeparator />}
583
+ {(hasResults || showChangelogRow || hasDynamicResults) && (
584
+ <CommandSeparator />
585
+ )}
571
586
  <div className="p-1">
572
587
  <div
573
588
  className="relative flex cursor-pointer select-none items-center gap-2 rounded-sm px-2 py-2 text-sm outline-none"
@@ -658,16 +673,21 @@ CommandMenu.Separator = CommandSeparator;
658
673
  /**
659
674
  * Hook to handle Cmd+K (or Ctrl+K) to open the command menu
660
675
  */
661
- export function useCommandMenuShortcut(onOpen: () => void) {
676
+ export function useCommandMenuShortcut(
677
+ onOpen: () => void,
678
+ options: { allowContentEditable?: boolean } = {},
679
+ ) {
662
680
  useEffect(() => {
663
681
  const handleKeyDown = (e: KeyboardEvent) => {
664
- if ((e.metaKey || e.ctrlKey) && e.key === "k") {
665
- // Don't trigger if user is typing in an input/textarea
666
- const target = e.target as HTMLElement;
682
+ if ((e.metaKey || e.ctrlKey) && e.key.toLowerCase() === "k") {
683
+ // Don't trigger if user is typing in a native form control.
684
+ const target = e.target instanceof HTMLElement ? e.target : null;
685
+ const isContentEditable = target?.isContentEditable;
667
686
  if (
668
- target.tagName === "INPUT" ||
669
- target.tagName === "TEXTAREA" ||
670
- target.isContentEditable
687
+ target?.tagName === "INPUT" ||
688
+ target?.tagName === "TEXTAREA" ||
689
+ target?.tagName === "SELECT" ||
690
+ (!options.allowContentEditable && isContentEditable)
671
691
  ) {
672
692
  return;
673
693
  }
@@ -675,9 +695,11 @@ export function useCommandMenuShortcut(onOpen: () => void) {
675
695
  onOpen();
676
696
  }
677
697
  };
678
- document.addEventListener("keydown", handleKeyDown);
679
- return () => document.removeEventListener("keydown", handleKeyDown);
680
- }, [onOpen]);
698
+ const useCapture = Boolean(options.allowContentEditable);
699
+ document.addEventListener("keydown", handleKeyDown, useCapture);
700
+ return () =>
701
+ document.removeEventListener("keydown", handleKeyDown, useCapture);
702
+ }, [onOpen, options.allowContentEditable]);
681
703
  }
682
704
 
683
705
  export type {
@@ -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
  };