@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
@@ -63,6 +63,8 @@ export interface CommandMenuProps {
63
63
  open: boolean;
64
64
  onOpenChange: (open: boolean) => void;
65
65
  children: ReactNode;
66
+ /** Render app-specific dynamic results from the current search value. */
67
+ renderResults?: (search: string) => ReactNode;
66
68
  /** Placeholder text for the search input */
67
69
  placeholder?: string;
68
70
  /** Text shown when no results match (before showing agent fallback) */
@@ -88,7 +90,7 @@ export interface CommandMenuProps {
88
90
  */
89
91
  changelogKey?: string;
90
92
  }
91
- export declare function CommandMenu({ open, onOpenChange, children, placeholder, emptyText: _emptyText, showAgentFallback, className, changelog, changelogLabel, changelogKey, }: CommandMenuProps): React.JSX.Element;
93
+ export declare function CommandMenu({ open, onOpenChange, children, renderResults, placeholder, emptyText: _emptyText, showAgentFallback, className, changelog, changelogLabel, changelogKey, }: CommandMenuProps): React.JSX.Element;
92
94
  export declare namespace CommandMenu {
93
95
  export { CommandGroup as Group };
94
96
  export { CommandItem as Item };
@@ -99,6 +101,8 @@ export declare namespace CommandMenu {
99
101
  /**
100
102
  * Hook to handle Cmd+K (or Ctrl+K) to open the command menu
101
103
  */
102
- export declare function useCommandMenuShortcut(onOpen: () => void): void;
104
+ export declare function useCommandMenuShortcut(onOpen: () => void, options?: {
105
+ allowContentEditable?: boolean;
106
+ }): void;
103
107
  export type { CommandDocsGroupProps, CommandGroupProps, CommandItemProps, CommandShortcutProps, };
104
108
  //# sourceMappingURL=CommandMenu.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"CommandMenu.d.ts","sourceRoot":"","sources":["../../src/client/CommandMenu.tsx"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"CommandMenu.d.ts","sourceRoot":"","sources":["../../src/client/CommandMenu.tsx"],"names":[],"mappings":"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"}
@@ -113,7 +113,7 @@ function CommandDocsGroup({ docs, heading = "Docs" }) {
113
113
  return null;
114
114
  return (_jsx(CommandGroup, { heading: heading, children: docs.map((doc) => (_jsxs(CommandItem, { onSelect: () => openDocsHref(doc.href), keywords: [doc.title, doc.description ?? "", ...(doc.keywords ?? [])], deferSelect: false, className: "items-start py-2", children: [_jsx(IconBook2, { className: "mt-0.5 h-4 w-4 shrink-0 text-muted-foreground" }), _jsxs("span", { className: "min-w-0 flex-1", children: [_jsx("span", { className: "block truncate font-medium", children: doc.title }), doc.description ? (_jsx("span", { className: "mt-0.5 block line-clamp-2 text-xs leading-snug text-muted-foreground", children: doc.description })) : null] }), _jsx(IconExternalLink, { className: "mt-0.5 h-3.5 w-3.5 shrink-0 text-muted-foreground" })] }, doc.href))) }));
115
115
  }
116
- export function CommandMenu({ open, onOpenChange, children, placeholder = "Type a command or ask AI...", emptyText: _emptyText = "No commands found.", showAgentFallback = true, className, changelog, changelogLabel = "What's new", changelogKey, }) {
116
+ export function CommandMenu({ open, onOpenChange, children, renderResults, placeholder = "Type a command or ask AI...", emptyText: _emptyText = "No commands found.", showAgentFallback = true, className, changelog, changelogLabel = "What's new", changelogKey, }) {
117
117
  const [search, setSearch] = useState("");
118
118
  const [selectedIndex, setSelectedIndex] = useState(0);
119
119
  const inputRef = useRef(null);
@@ -132,8 +132,14 @@ export function CommandMenu({ open, onOpenChange, children, placeholder = "Type
132
132
  // Let the menu close before the dialog opens (avoids overlay flicker).
133
133
  setTimeout(() => setChangelogOpen(true), 50);
134
134
  }, [onOpenChange, markChangelogSeen]);
135
- // Focus input when opening
135
+ // Focus input when opening; clear search while closed so reopen never renders
136
+ // dynamic results for the previous query.
136
137
  useEffect(() => {
138
+ if (!open) {
139
+ setSearch("");
140
+ setSelectedIndex(0);
141
+ return;
142
+ }
137
143
  if (open) {
138
144
  setSearch("");
139
145
  setSelectedIndex(0);
@@ -292,14 +298,16 @@ export function CommandMenu({ open, onOpenChange, children, placeholder = "Type
292
298
  const filteredChildren = filterChildren(children);
293
299
  const hasResults = React.Children.toArray(filteredChildren).some((child) => React.isValidElement(child) &&
294
300
  (child.type === CommandGroup || child.type === CommandDocsGroup));
295
- return (_jsxs(_Fragment, { children: [open && (_jsx("div", { className: "fixed inset-0 z-50 bg-black/50", children: _jsx("div", { ref: containerRef, className: cn("fixed left-1/2 top-[15vh] -translate-x-1/2 w-full max-w-lg", "rounded-lg border border-border bg-popover text-popover-foreground shadow-lg", className), children: _jsxs(CommandMenuContext.Provider, { value: { search, onOpenChange, containerRef, setSelectedIndex }, children: [_jsxs("div", { className: "flex items-center border-b px-3", children: [_jsx(IconSearch, { className: "me-2 h-4 w-4 shrink-0 opacity-50" }), _jsx("input", { ref: inputRef, value: search, onChange: (e) => setSearch(e.target.value), onKeyDown: handleKeyDown, placeholder: placeholder, className: "flex h-11 w-full rounded-md bg-transparent py-3 text-sm outline-none placeholder:text-muted-foreground disabled:cursor-not-allowed disabled:opacity-50" })] }), _jsxs("div", { className: "max-h-[300px] overflow-y-auto overflow-x-hidden", children: [hasResults && filteredChildren, showChangelogRow && (_jsxs(_Fragment, { children: [hasResults && _jsx(CommandSeparator, {}), _jsx("div", { className: "p-1", children: _jsxs("div", { className: "relative flex cursor-pointer select-none items-center gap-2 rounded-sm px-2 py-2 text-sm outline-none", onClick: openChangelog, onMouseEnter: (e) => {
301
+ const dynamicResults = open ? renderResults?.(search) : null;
302
+ const hasDynamicResults = Boolean(dynamicResults);
303
+ return (_jsxs(_Fragment, { children: [open && (_jsx("div", { className: "fixed inset-0 z-50 bg-black/50", children: _jsx("div", { ref: containerRef, className: cn("fixed left-1/2 top-[15vh] -translate-x-1/2 w-full max-w-lg", "rounded-lg border border-border bg-popover text-popover-foreground shadow-lg", className), children: _jsxs(CommandMenuContext.Provider, { value: { search, onOpenChange, containerRef, setSelectedIndex }, children: [_jsxs("div", { className: "flex items-center border-b px-3", children: [_jsx(IconSearch, { className: "me-2 h-4 w-4 shrink-0 opacity-50" }), _jsx("input", { ref: inputRef, value: search, onChange: (e) => setSearch(e.target.value), onKeyDown: handleKeyDown, placeholder: placeholder, className: "flex h-11 w-full rounded-md bg-transparent py-3 text-sm outline-none placeholder:text-muted-foreground disabled:cursor-not-allowed disabled:opacity-50" })] }), _jsxs("div", { className: "max-h-[300px] overflow-y-auto overflow-x-hidden", children: [dynamicResults, hasResults && filteredChildren, showChangelogRow && (_jsxs(_Fragment, { children: [hasResults && _jsx(CommandSeparator, {}), _jsx("div", { className: "p-1", children: _jsxs("div", { className: "relative flex cursor-pointer select-none items-center gap-2 rounded-sm px-2 py-2 text-sm outline-none", onClick: openChangelog, onMouseEnter: (e) => {
296
304
  const items = containerRef.current?.querySelectorAll('[role="option"]');
297
305
  if (!items)
298
306
  return;
299
307
  const index = Array.from(items).indexOf(e.currentTarget);
300
308
  if (index >= 0)
301
309
  setSelectedIndex(index);
302
- }, role: "option", children: [_jsx(IconHistory, { className: "h-4 w-4 text-muted-foreground" }), _jsx("span", { children: changelogLabel }), changelogUnseen && (_jsx("span", { className: "ms-auto h-2 w-2 rounded-full bg-primary", "aria-label": "New updates available" }))] }) })] })), showAgentFallback && (_jsxs(_Fragment, { children: [(hasResults || showChangelogRow) && _jsx(CommandSeparator, {}), _jsx("div", { className: "p-1", children: _jsxs("div", { className: "relative flex cursor-pointer select-none items-center gap-2 rounded-sm px-2 py-2 text-sm outline-none", onClick: handleSubmitToAgent, onMouseEnter: (e) => {
310
+ }, role: "option", children: [_jsx(IconHistory, { className: "h-4 w-4 text-muted-foreground" }), _jsx("span", { children: changelogLabel }), changelogUnseen && (_jsx("span", { className: "ms-auto h-2 w-2 rounded-full bg-primary", "aria-label": "New updates available" }))] }) })] })), showAgentFallback && (_jsxs(_Fragment, { children: [(hasResults || showChangelogRow || hasDynamicResults) && (_jsx(CommandSeparator, {})), _jsx("div", { className: "p-1", children: _jsxs("div", { className: "relative flex cursor-pointer select-none items-center gap-2 rounded-sm px-2 py-2 text-sm outline-none", onClick: handleSubmitToAgent, onMouseEnter: (e) => {
303
311
  const items = containerRef.current?.querySelectorAll('[role="option"]');
304
312
  if (!items)
305
313
  return;
@@ -335,23 +343,26 @@ CommandMenu.Separator = CommandSeparator;
335
343
  /**
336
344
  * Hook to handle Cmd+K (or Ctrl+K) to open the command menu
337
345
  */
338
- export function useCommandMenuShortcut(onOpen) {
346
+ export function useCommandMenuShortcut(onOpen, options = {}) {
339
347
  useEffect(() => {
340
348
  const handleKeyDown = (e) => {
341
- if ((e.metaKey || e.ctrlKey) && e.key === "k") {
342
- // Don't trigger if user is typing in an input/textarea
343
- const target = e.target;
344
- if (target.tagName === "INPUT" ||
345
- target.tagName === "TEXTAREA" ||
346
- target.isContentEditable) {
349
+ if ((e.metaKey || e.ctrlKey) && e.key.toLowerCase() === "k") {
350
+ // Don't trigger if user is typing in a native form control.
351
+ const target = e.target instanceof HTMLElement ? e.target : null;
352
+ const isContentEditable = target?.isContentEditable;
353
+ if (target?.tagName === "INPUT" ||
354
+ target?.tagName === "TEXTAREA" ||
355
+ target?.tagName === "SELECT" ||
356
+ (!options.allowContentEditable && isContentEditable)) {
347
357
  return;
348
358
  }
349
359
  e.preventDefault();
350
360
  onOpen();
351
361
  }
352
362
  };
353
- document.addEventListener("keydown", handleKeyDown);
354
- return () => document.removeEventListener("keydown", handleKeyDown);
355
- }, [onOpen]);
363
+ const useCapture = Boolean(options.allowContentEditable);
364
+ document.addEventListener("keydown", handleKeyDown, useCapture);
365
+ return () => document.removeEventListener("keydown", handleKeyDown, useCapture);
366
+ }, [onOpen, options.allowContentEditable]);
356
367
  }
357
368
  //# sourceMappingURL=CommandMenu.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"CommandMenu.js","sourceRoot":"","sources":["../../src/client/CommandMenu.tsx"],"names":[],"mappings":"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","sourcesContent":["/**\n * CommandMenu — reusable command palette with agent chat fallback.\n *\n * Features:\n * - Anchored to top of viewport (not centered)\n * - Falls back to agent chat when no command matches\n * - Opens agent sidebar automatically when sending prompts\n * - Customizable commands via children\n *\n * Usage:\n * <CommandMenu open={open} onOpenChange={setOpen}>\n * <CommandMenu.Group heading=\"Actions\">\n * <CommandMenu.Item onSelect={() => doThing()}>Do thing</CommandMenu.Item>\n * </CommandMenu.Group>\n * </CommandMenu>\n */\n\nimport {\n IconBook2,\n IconExternalLink,\n IconSearch,\n IconMessage,\n IconHistory,\n} from \"@tabler/icons-react\";\nimport React, {\n createContext,\n useCallback,\n useContext,\n useEffect,\n useMemo,\n useRef,\n useState,\n type ReactNode,\n} from \"react\";\n\nimport { parseChangelog } from \"../changelog/parse.js\";\nimport { sendToAgentChat } from \"./agent-chat.js\";\nimport { ChangelogDialog, useChangelogSeen } from \"./changelog/Changelog.js\";\nimport { cn } from \"./utils.js\";\n\n// ─── Context ────────────────────────────────────────────────────────────────\n\ninterface CommandMenuContextValue {\n search: string;\n onOpenChange: (open: boolean) => void;\n containerRef: React.RefObject<HTMLDivElement | null>;\n setSelectedIndex: (index: number) => void;\n}\n\nconst CommandMenuContext = createContext<CommandMenuContextValue | null>(null);\n\nfunction useCommandMenuContext() {\n const ctx = useContext(CommandMenuContext);\n if (!ctx) throw new Error(\"CommandMenu.* must be used inside <CommandMenu>\");\n return ctx;\n}\n\n// ─── Hooks ──────────────────────────────────────────────────────────────────\n\n/**\n * Opens the agent sidebar (dispatches event that AgentSidebar listens for)\n */\nexport function openAgentSidebar() {\n window.dispatchEvent(new Event(\"agent-panel:open\"));\n}\n\nexport function openAgentSettings(\n section?: string | { section?: string | null },\n) {\n if (typeof window === \"undefined\") return;\n\n const normalizedSection =\n typeof section === \"string\" ? section : section?.section;\n\n openAgentSidebar();\n window.dispatchEvent(\n new CustomEvent(\"agent-panel:open-settings\", {\n detail: normalizedSection ? { section: normalizedSection } : undefined,\n }),\n );\n}\n\nexport function focusAgentChat() {\n window.dispatchEvent(\n new CustomEvent(\"agent-panel:set-mode\", {\n detail: { mode: \"chat\" },\n }),\n );\n openAgentSidebar();\n}\n\n/**\n * Sends a prompt to the agent and opens the sidebar\n */\nexport function submitToAgent(message: string) {\n focusAgentChat();\n sendToAgentChat({ message, submit: true });\n}\n\n// ─── Sub-components ─────────────────────────────────────────────────────────\n\ninterface CommandGroupProps {\n heading?: string;\n children: ReactNode;\n}\n\nfunction CommandGroup({ heading, children }: CommandGroupProps) {\n return (\n <div className=\"overflow-hidden p-1 text-foreground\">\n {heading && (\n <div className=\"px-2 py-1.5 text-xs font-medium text-muted-foreground\">\n {heading}\n </div>\n )}\n {children}\n </div>\n );\n}\n\ninterface CommandItemProps {\n onSelect: () => void;\n children: ReactNode;\n keywords?: string[];\n className?: string;\n deferSelect?: boolean;\n}\n\nfunction CommandItem({\n onSelect,\n children,\n keywords: _keywords,\n className,\n deferSelect = true,\n}: CommandItemProps) {\n const { onOpenChange, containerRef, setSelectedIndex } =\n useCommandMenuContext();\n const itemRef = useRef<HTMLDivElement>(null);\n\n const handleSelect = () => {\n if (!deferSelect) {\n onSelect();\n onOpenChange(false);\n return;\n }\n\n onOpenChange(false);\n // Small delay to let dialog close animation start\n setTimeout(onSelect, 50);\n };\n\n const handleMouseEnter = () => {\n if (!containerRef.current || !itemRef.current) return;\n const items = containerRef.current.querySelectorAll('[role=\"option\"]');\n const index = Array.from(items).indexOf(itemRef.current);\n if (index >= 0) setSelectedIndex(index);\n };\n\n return (\n <div\n ref={itemRef}\n className={cn(\n \"relative flex cursor-pointer select-none items-center gap-2 rounded-sm px-2 py-1.5 text-sm outline-none\",\n className,\n )}\n onClick={handleSelect}\n onMouseEnter={handleMouseEnter}\n role=\"option\"\n >\n {children}\n </div>\n );\n}\n\ninterface CommandShortcutProps {\n children: ReactNode;\n className?: string;\n}\n\nfunction CommandShortcut({ children, className }: CommandShortcutProps) {\n return (\n <span\n className={cn(\n \"ms-auto text-xs tracking-widest text-muted-foreground\",\n className,\n )}\n >\n {children}\n </span>\n );\n}\n\nfunction CommandSeparator({ className }: { className?: string }) {\n return <div className={cn(\"-mx-1 my-1 h-px bg-border\", className)} />;\n}\n\nexport interface CommandMenuDoc {\n title: string;\n href: string;\n description?: string;\n keywords?: string[];\n}\n\ninterface CommandDocsGroupProps {\n docs: CommandMenuDoc[];\n heading?: string;\n}\n\nfunction commandDocSearchText(doc: CommandMenuDoc): string {\n return [doc.title, doc.description, ...(doc.keywords ?? [])]\n .filter(Boolean)\n .join(\" \")\n .toLowerCase();\n}\n\nfunction filterCommandDocs(docs: CommandMenuDoc[], search: string) {\n const searchLower = search.trim().toLowerCase();\n if (!searchLower) return docs;\n return docs.filter((doc) => commandDocSearchText(doc).includes(searchLower));\n}\n\nfunction openDocsHref(href: string) {\n if (/^https?:\\/\\//i.test(href)) {\n window.open(href, \"_blank\", \"noopener,noreferrer\");\n return;\n }\n window.location.assign(href);\n}\n\nfunction CommandDocsGroup({ docs, heading = \"Docs\" }: CommandDocsGroupProps) {\n if (docs.length === 0) return null;\n\n return (\n <CommandGroup heading={heading}>\n {docs.map((doc) => (\n <CommandItem\n key={doc.href}\n onSelect={() => openDocsHref(doc.href)}\n keywords={[doc.title, doc.description ?? \"\", ...(doc.keywords ?? [])]}\n deferSelect={false}\n className=\"items-start py-2\"\n >\n <IconBook2 className=\"mt-0.5 h-4 w-4 shrink-0 text-muted-foreground\" />\n <span className=\"min-w-0 flex-1\">\n <span className=\"block truncate font-medium\">{doc.title}</span>\n {doc.description ? (\n <span className=\"mt-0.5 block line-clamp-2 text-xs leading-snug text-muted-foreground\">\n {doc.description}\n </span>\n ) : null}\n </span>\n <IconExternalLink className=\"mt-0.5 h-3.5 w-3.5 shrink-0 text-muted-foreground\" />\n </CommandItem>\n ))}\n </CommandGroup>\n );\n}\n\n// ─── Main Component ─────────────────────────────────────────────────────────\n\nexport interface CommandMenuProps {\n open: boolean;\n onOpenChange: (open: boolean) => void;\n children: ReactNode;\n /** Placeholder text for the search input */\n placeholder?: string;\n /** Text shown when no results match (before showing agent fallback) */\n emptyText?: string;\n /** Whether to show the \"Ask AI\" fallback when no commands match. Default: true */\n showAgentFallback?: boolean;\n /** Custom class for the dialog content */\n className?: string;\n /**\n * Raw CHANGELOG.md contents. When provided, the menu shows a built-in\n * \"What's new\" entry that opens an in-app changelog dialog (with an unseen\n * dot for new releases). Pass your app's own file:\n * import changelog from \"../CHANGELOG.md?raw\";\n * <CommandMenu ... changelog={changelog} />\n */\n changelog?: string;\n /** Label for the built-in changelog entry. Default: \"What's new\". */\n changelogLabel?: string;\n /**\n * Stable key used to remember which release a user has already seen (for the\n * unseen dot). Defaults to the document title's host app; set explicitly when\n * multiple apps share an origin.\n */\n changelogKey?: string;\n}\n\nexport function CommandMenu({\n open,\n onOpenChange,\n children,\n placeholder = \"Type a command or ask AI...\",\n emptyText: _emptyText = \"No commands found.\",\n showAgentFallback = true,\n className,\n changelog,\n changelogLabel = \"What's new\",\n changelogKey,\n}: CommandMenuProps) {\n const [search, setSearch] = useState(\"\");\n const [selectedIndex, setSelectedIndex] = useState(0);\n const inputRef = useRef<HTMLInputElement>(null);\n const containerRef = useRef<HTMLDivElement>(null);\n\n // Built-in \"What's new\" changelog surface (only active when `changelog` is\n // passed). The dialog is rendered alongside the menu so it survives the menu\n // closing; the unseen dot persists per browser via localStorage.\n const [changelogOpen, setChangelogOpen] = useState(false);\n const hasChangelog =\n typeof changelog === \"string\" && changelog.trim().length > 0;\n const changelogEntries = useMemo(\n () => (hasChangelog ? parseChangelog(changelog as string) : []),\n [hasChangelog, changelog],\n );\n const latestChangelogId = changelogEntries[0]?.id;\n const { unseen: changelogUnseen, markSeen: markChangelogSeen } =\n useChangelogSeen(changelogKey ?? \"app\", latestChangelogId);\n\n const openChangelog = useCallback(() => {\n onOpenChange(false);\n markChangelogSeen();\n // Let the menu close before the dialog opens (avoids overlay flicker).\n setTimeout(() => setChangelogOpen(true), 50);\n }, [onOpenChange, markChangelogSeen]);\n\n // Focus input when opening\n useEffect(() => {\n if (open) {\n setSearch(\"\");\n setSelectedIndex(0);\n // Wait for render then focus\n requestAnimationFrame(() => {\n inputRef.current?.focus();\n });\n }\n }, [open]);\n\n // Reset selection when search changes\n useEffect(() => {\n setSelectedIndex(0);\n }, [search]);\n\n // Keep selected item scrolled into view\n useEffect(() => {\n const items = containerRef.current?.querySelectorAll('[role=\"option\"]');\n if (items && items[selectedIndex]) {\n items[selectedIndex].scrollIntoView({ block: \"nearest\" });\n }\n }, [selectedIndex]);\n\n // Apply selected styling directly (can't rely on Tailwind scanning core package)\n useEffect(() => {\n const items = containerRef.current?.querySelectorAll('[role=\"option\"]');\n if (!items) return;\n items.forEach((item, i) => {\n const el = item as HTMLElement;\n if (i === selectedIndex) {\n el.style.backgroundColor = \"hsl(var(--accent))\";\n el.style.color = \"hsl(var(--accent-foreground))\";\n } else {\n el.style.backgroundColor = \"\";\n el.style.color = \"\";\n }\n });\n });\n\n // Close on escape\n useEffect(() => {\n if (!open) return;\n const handleKeyDown = (e: KeyboardEvent) => {\n if (e.key === \"Escape\") {\n e.preventDefault();\n onOpenChange(false);\n }\n };\n document.addEventListener(\"keydown\", handleKeyDown);\n return () => document.removeEventListener(\"keydown\", handleKeyDown);\n }, [open, onOpenChange]);\n\n // Close on click outside\n useEffect(() => {\n if (!open) return;\n const handleClick = (e: MouseEvent) => {\n if (\n containerRef.current &&\n !containerRef.current.contains(e.target as Node)\n ) {\n onOpenChange(false);\n }\n };\n // Use capture to handle clicks before they bubble\n document.addEventListener(\"mousedown\", handleClick, true);\n return () => document.removeEventListener(\"mousedown\", handleClick, true);\n }, [open, onOpenChange]);\n\n const handleSubmitToAgent = useCallback(() => {\n onOpenChange(false);\n if (!search.trim()) {\n focusAgentChat();\n return;\n }\n submitToAgent(search.trim());\n }, [search, onOpenChange]);\n\n const handleKeyDown = (e: React.KeyboardEvent) => {\n const items = containerRef.current?.querySelectorAll('[role=\"option\"]');\n const itemCount = items?.length ?? 0;\n\n if (e.key === \"ArrowDown\") {\n e.preventDefault();\n setSelectedIndex((prev) => (prev + 1) % itemCount || 0);\n } else if (e.key === \"ArrowUp\") {\n e.preventDefault();\n setSelectedIndex((prev) => (prev - 1 + itemCount) % itemCount || 0);\n } else if (e.key === \"Enter\") {\n e.preventDefault();\n if (items && items[selectedIndex]) {\n (items[selectedIndex] as HTMLElement).click();\n }\n }\n };\n\n // The built-in \"What's new\" row matches changelog-ish search terms.\n const changelogRowMatches =\n !search ||\n [\n changelogLabel,\n \"changelog\",\n \"what's new\",\n \"whats new\",\n \"updates\",\n \"release notes\",\n \"changes\",\n ]\n .join(\" \")\n .toLowerCase()\n .includes(search.toLowerCase());\n const showChangelogRow = hasChangelog && changelogRowMatches;\n\n // Filter children based on search\n const filterChildren = (nodes: ReactNode): ReactNode => {\n return React.Children.map(nodes, (child) => {\n if (!React.isValidElement(child)) return child;\n const props = child.props as Record<string, unknown>;\n\n // If it's a CommandGroup, filter its children\n if (child.type === CommandGroup) {\n const groupChildren = filterChildren(props.children as ReactNode);\n const hasChildren = React.Children.count(groupChildren) > 0;\n if (!hasChildren) return null;\n return React.cloneElement(child, {\n ...props,\n children: groupChildren,\n } as Record<string, unknown>);\n }\n\n if (child.type === CommandDocsGroup) {\n const docs = Array.isArray(props.docs)\n ? (props.docs as CommandMenuDoc[])\n : [];\n const filteredDocs = filterCommandDocs(docs, search);\n if (filteredDocs.length === 0) return null;\n return React.cloneElement(child, {\n ...props,\n docs: filteredDocs,\n } as Record<string, unknown>);\n }\n\n // If it's a CommandItem, check if it matches search\n if (child.type === CommandItem) {\n if (!search) return child;\n const text = getTextContent(props.children as ReactNode).toLowerCase();\n const keywords = ((props.keywords as string[]) || [])\n .join(\" \")\n .toLowerCase();\n const searchLower = search.toLowerCase();\n if (text.includes(searchLower) || keywords.includes(searchLower)) {\n return child;\n }\n return null;\n }\n\n // If it's a separator, keep it (will be cleaned up later if needed)\n if (child.type === CommandSeparator) {\n return search ? null : child; // Hide separators when searching\n }\n\n return child;\n });\n };\n\n const filteredChildren = filterChildren(children);\n const hasResults = React.Children.toArray(filteredChildren).some(\n (child) =>\n React.isValidElement(child) &&\n (child.type === CommandGroup || child.type === CommandDocsGroup),\n );\n\n return (\n <>\n {open && (\n <div className=\"fixed inset-0 z-50 bg-black/50\">\n <div\n ref={containerRef}\n className={cn(\n \"fixed left-1/2 top-[15vh] -translate-x-1/2 w-full max-w-lg\",\n \"rounded-lg border border-border bg-popover text-popover-foreground shadow-lg\",\n className,\n )}\n >\n <CommandMenuContext.Provider\n value={{ search, onOpenChange, containerRef, setSelectedIndex }}\n >\n {/* Search input */}\n <div className=\"flex items-center border-b px-3\">\n <IconSearch className=\"me-2 h-4 w-4 shrink-0 opacity-50\" />\n <input\n ref={inputRef}\n value={search}\n onChange={(e) => setSearch(e.target.value)}\n onKeyDown={handleKeyDown}\n placeholder={placeholder}\n className=\"flex h-11 w-full rounded-md bg-transparent py-3 text-sm outline-none placeholder:text-muted-foreground disabled:cursor-not-allowed disabled:opacity-50\"\n />\n </div>\n\n {/* Command list */}\n <div className=\"max-h-[300px] overflow-y-auto overflow-x-hidden\">\n {hasResults && filteredChildren}\n\n {/* What's new — built-in changelog entry */}\n {showChangelogRow && (\n <>\n {hasResults && <CommandSeparator />}\n <div className=\"p-1\">\n <div\n className=\"relative flex cursor-pointer select-none items-center gap-2 rounded-sm px-2 py-2 text-sm outline-none\"\n onClick={openChangelog}\n onMouseEnter={(e) => {\n const items =\n containerRef.current?.querySelectorAll(\n '[role=\"option\"]',\n );\n if (!items) return;\n const index = Array.from(items).indexOf(\n e.currentTarget,\n );\n if (index >= 0) setSelectedIndex(index);\n }}\n role=\"option\"\n >\n <IconHistory className=\"h-4 w-4 text-muted-foreground\" />\n <span>{changelogLabel}</span>\n {changelogUnseen && (\n <span\n className=\"ms-auto h-2 w-2 rounded-full bg-primary\"\n aria-label=\"New updates available\"\n />\n )}\n </div>\n </div>\n </>\n )}\n\n {/* Ask AI — always visible at the bottom */}\n {showAgentFallback && (\n <>\n {(hasResults || showChangelogRow) && <CommandSeparator />}\n <div className=\"p-1\">\n <div\n className=\"relative flex cursor-pointer select-none items-center gap-2 rounded-sm px-2 py-2 text-sm outline-none\"\n onClick={handleSubmitToAgent}\n onMouseEnter={(e) => {\n const items =\n containerRef.current?.querySelectorAll(\n '[role=\"option\"]',\n );\n if (!items) return;\n const index = Array.from(items).indexOf(\n e.currentTarget,\n );\n if (index >= 0) setSelectedIndex(index);\n }}\n role=\"option\"\n >\n <IconMessage className=\"h-4 w-4 text-muted-foreground\" />\n <span>\n {search.trim() ? (\n <>\n Ask AI:{\" \"}\n <span className=\"text-muted-foreground\">\n \"{search}\"\n </span>\n </>\n ) : (\n <span className=\"text-muted-foreground\">\n Ask AI anything...\n </span>\n )}\n </span>\n {search.trim() && (\n <span className=\"ms-auto text-xs text-muted-foreground\">\n ↵\n </span>\n )}\n </div>\n </div>\n </>\n )}\n </div>\n </CommandMenuContext.Provider>\n </div>\n </div>\n )}\n\n {hasChangelog && (\n <ChangelogDialog\n open={changelogOpen}\n onOpenChange={setChangelogOpen}\n markdown={changelog as string}\n title={changelogLabel}\n />\n )}\n </>\n );\n}\n\n// Helper to extract text content from React children\nfunction getTextContent(children: ReactNode): string {\n if (typeof children === \"string\") return children;\n if (typeof children === \"number\") return String(children);\n if (!children) return \"\";\n if (Array.isArray(children)) {\n return children.map(getTextContent).join(\" \");\n }\n if (\n React.isValidElement(children) &&\n (children.props as Record<string, unknown>).children\n ) {\n return getTextContent(\n (children.props as Record<string, unknown>).children as ReactNode,\n );\n }\n return \"\";\n}\n\n// Attach sub-components\nCommandMenu.Group = CommandGroup;\nCommandMenu.Item = CommandItem;\nCommandMenu.DocsGroup = CommandDocsGroup;\nCommandMenu.Shortcut = CommandShortcut;\nCommandMenu.Separator = CommandSeparator;\n\n// ─── Keyboard Hook ──────────────────────────────────────────────────────────\n\n/**\n * Hook to handle Cmd+K (or Ctrl+K) to open the command menu\n */\nexport function useCommandMenuShortcut(onOpen: () => void) {\n useEffect(() => {\n const handleKeyDown = (e: KeyboardEvent) => {\n if ((e.metaKey || e.ctrlKey) && e.key === \"k\") {\n // Don't trigger if user is typing in an input/textarea\n const target = e.target as HTMLElement;\n if (\n target.tagName === \"INPUT\" ||\n target.tagName === \"TEXTAREA\" ||\n target.isContentEditable\n ) {\n return;\n }\n e.preventDefault();\n onOpen();\n }\n };\n document.addEventListener(\"keydown\", handleKeyDown);\n return () => document.removeEventListener(\"keydown\", handleKeyDown);\n }, [onOpen]);\n}\n\nexport type {\n CommandDocsGroupProps,\n CommandGroupProps,\n CommandItemProps,\n CommandShortcutProps,\n};\n"]}
1
+ {"version":3,"file":"CommandMenu.js","sourceRoot":"","sources":["../../src/client/CommandMenu.tsx"],"names":[],"mappings":"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","sourcesContent":["/**\n * CommandMenu — reusable command palette with agent chat fallback.\n *\n * Features:\n * - Anchored to top of viewport (not centered)\n * - Falls back to agent chat when no command matches\n * - Opens agent sidebar automatically when sending prompts\n * - Customizable commands via children\n *\n * Usage:\n * <CommandMenu open={open} onOpenChange={setOpen}>\n * <CommandMenu.Group heading=\"Actions\">\n * <CommandMenu.Item onSelect={() => doThing()}>Do thing</CommandMenu.Item>\n * </CommandMenu.Group>\n * </CommandMenu>\n */\n\nimport {\n IconBook2,\n IconExternalLink,\n IconSearch,\n IconMessage,\n IconHistory,\n} from \"@tabler/icons-react\";\nimport React, {\n createContext,\n useCallback,\n useContext,\n useEffect,\n useMemo,\n useRef,\n useState,\n type ReactNode,\n} from \"react\";\n\nimport { parseChangelog } from \"../changelog/parse.js\";\nimport { sendToAgentChat } from \"./agent-chat.js\";\nimport { ChangelogDialog, useChangelogSeen } from \"./changelog/Changelog.js\";\nimport { cn } from \"./utils.js\";\n\n// ─── Context ────────────────────────────────────────────────────────────────\n\ninterface CommandMenuContextValue {\n search: string;\n onOpenChange: (open: boolean) => void;\n containerRef: React.RefObject<HTMLDivElement | null>;\n setSelectedIndex: (index: number) => void;\n}\n\nconst CommandMenuContext = createContext<CommandMenuContextValue | null>(null);\n\nfunction useCommandMenuContext() {\n const ctx = useContext(CommandMenuContext);\n if (!ctx) throw new Error(\"CommandMenu.* must be used inside <CommandMenu>\");\n return ctx;\n}\n\n// ─── Hooks ──────────────────────────────────────────────────────────────────\n\n/**\n * Opens the agent sidebar (dispatches event that AgentSidebar listens for)\n */\nexport function openAgentSidebar() {\n window.dispatchEvent(new Event(\"agent-panel:open\"));\n}\n\nexport function openAgentSettings(\n section?: string | { section?: string | null },\n) {\n if (typeof window === \"undefined\") return;\n\n const normalizedSection =\n typeof section === \"string\" ? section : section?.section;\n\n openAgentSidebar();\n window.dispatchEvent(\n new CustomEvent(\"agent-panel:open-settings\", {\n detail: normalizedSection ? { section: normalizedSection } : undefined,\n }),\n );\n}\n\nexport function focusAgentChat() {\n window.dispatchEvent(\n new CustomEvent(\"agent-panel:set-mode\", {\n detail: { mode: \"chat\" },\n }),\n );\n openAgentSidebar();\n}\n\n/**\n * Sends a prompt to the agent and opens the sidebar\n */\nexport function submitToAgent(message: string) {\n focusAgentChat();\n sendToAgentChat({ message, submit: true });\n}\n\n// ─── Sub-components ─────────────────────────────────────────────────────────\n\ninterface CommandGroupProps {\n heading?: string;\n children: ReactNode;\n}\n\nfunction CommandGroup({ heading, children }: CommandGroupProps) {\n return (\n <div className=\"overflow-hidden p-1 text-foreground\">\n {heading && (\n <div className=\"px-2 py-1.5 text-xs font-medium text-muted-foreground\">\n {heading}\n </div>\n )}\n {children}\n </div>\n );\n}\n\ninterface CommandItemProps {\n onSelect: () => void;\n children: ReactNode;\n keywords?: string[];\n className?: string;\n deferSelect?: boolean;\n}\n\nfunction CommandItem({\n onSelect,\n children,\n keywords: _keywords,\n className,\n deferSelect = true,\n}: CommandItemProps) {\n const { onOpenChange, containerRef, setSelectedIndex } =\n useCommandMenuContext();\n const itemRef = useRef<HTMLDivElement>(null);\n\n const handleSelect = () => {\n if (!deferSelect) {\n onSelect();\n onOpenChange(false);\n return;\n }\n\n onOpenChange(false);\n // Small delay to let dialog close animation start\n setTimeout(onSelect, 50);\n };\n\n const handleMouseEnter = () => {\n if (!containerRef.current || !itemRef.current) return;\n const items = containerRef.current.querySelectorAll('[role=\"option\"]');\n const index = Array.from(items).indexOf(itemRef.current);\n if (index >= 0) setSelectedIndex(index);\n };\n\n return (\n <div\n ref={itemRef}\n className={cn(\n \"relative flex cursor-pointer select-none items-center gap-2 rounded-sm px-2 py-1.5 text-sm outline-none\",\n className,\n )}\n onClick={handleSelect}\n onMouseEnter={handleMouseEnter}\n role=\"option\"\n >\n {children}\n </div>\n );\n}\n\ninterface CommandShortcutProps {\n children: ReactNode;\n className?: string;\n}\n\nfunction CommandShortcut({ children, className }: CommandShortcutProps) {\n return (\n <span\n className={cn(\n \"ms-auto text-xs tracking-widest text-muted-foreground\",\n className,\n )}\n >\n {children}\n </span>\n );\n}\n\nfunction CommandSeparator({ className }: { className?: string }) {\n return <div className={cn(\"-mx-1 my-1 h-px bg-border\", className)} />;\n}\n\nexport interface CommandMenuDoc {\n title: string;\n href: string;\n description?: string;\n keywords?: string[];\n}\n\ninterface CommandDocsGroupProps {\n docs: CommandMenuDoc[];\n heading?: string;\n}\n\nfunction commandDocSearchText(doc: CommandMenuDoc): string {\n return [doc.title, doc.description, ...(doc.keywords ?? [])]\n .filter(Boolean)\n .join(\" \")\n .toLowerCase();\n}\n\nfunction filterCommandDocs(docs: CommandMenuDoc[], search: string) {\n const searchLower = search.trim().toLowerCase();\n if (!searchLower) return docs;\n return docs.filter((doc) => commandDocSearchText(doc).includes(searchLower));\n}\n\nfunction openDocsHref(href: string) {\n if (/^https?:\\/\\//i.test(href)) {\n window.open(href, \"_blank\", \"noopener,noreferrer\");\n return;\n }\n window.location.assign(href);\n}\n\nfunction CommandDocsGroup({ docs, heading = \"Docs\" }: CommandDocsGroupProps) {\n if (docs.length === 0) return null;\n\n return (\n <CommandGroup heading={heading}>\n {docs.map((doc) => (\n <CommandItem\n key={doc.href}\n onSelect={() => openDocsHref(doc.href)}\n keywords={[doc.title, doc.description ?? \"\", ...(doc.keywords ?? [])]}\n deferSelect={false}\n className=\"items-start py-2\"\n >\n <IconBook2 className=\"mt-0.5 h-4 w-4 shrink-0 text-muted-foreground\" />\n <span className=\"min-w-0 flex-1\">\n <span className=\"block truncate font-medium\">{doc.title}</span>\n {doc.description ? (\n <span className=\"mt-0.5 block line-clamp-2 text-xs leading-snug text-muted-foreground\">\n {doc.description}\n </span>\n ) : null}\n </span>\n <IconExternalLink className=\"mt-0.5 h-3.5 w-3.5 shrink-0 text-muted-foreground\" />\n </CommandItem>\n ))}\n </CommandGroup>\n );\n}\n\n// ─── Main Component ─────────────────────────────────────────────────────────\n\nexport interface CommandMenuProps {\n open: boolean;\n onOpenChange: (open: boolean) => void;\n children: ReactNode;\n /** Render app-specific dynamic results from the current search value. */\n renderResults?: (search: string) => ReactNode;\n /** Placeholder text for the search input */\n placeholder?: string;\n /** Text shown when no results match (before showing agent fallback) */\n emptyText?: string;\n /** Whether to show the \"Ask AI\" fallback when no commands match. Default: true */\n showAgentFallback?: boolean;\n /** Custom class for the dialog content */\n className?: string;\n /**\n * Raw CHANGELOG.md contents. When provided, the menu shows a built-in\n * \"What's new\" entry that opens an in-app changelog dialog (with an unseen\n * dot for new releases). Pass your app's own file:\n * import changelog from \"../CHANGELOG.md?raw\";\n * <CommandMenu ... changelog={changelog} />\n */\n changelog?: string;\n /** Label for the built-in changelog entry. Default: \"What's new\". */\n changelogLabel?: string;\n /**\n * Stable key used to remember which release a user has already seen (for the\n * unseen dot). Defaults to the document title's host app; set explicitly when\n * multiple apps share an origin.\n */\n changelogKey?: string;\n}\n\nexport function CommandMenu({\n open,\n onOpenChange,\n children,\n renderResults,\n placeholder = \"Type a command or ask AI...\",\n emptyText: _emptyText = \"No commands found.\",\n showAgentFallback = true,\n className,\n changelog,\n changelogLabel = \"What's new\",\n changelogKey,\n}: CommandMenuProps) {\n const [search, setSearch] = useState(\"\");\n const [selectedIndex, setSelectedIndex] = useState(0);\n const inputRef = useRef<HTMLInputElement>(null);\n const containerRef = useRef<HTMLDivElement>(null);\n\n // Built-in \"What's new\" changelog surface (only active when `changelog` is\n // passed). The dialog is rendered alongside the menu so it survives the menu\n // closing; the unseen dot persists per browser via localStorage.\n const [changelogOpen, setChangelogOpen] = useState(false);\n const hasChangelog =\n typeof changelog === \"string\" && changelog.trim().length > 0;\n const changelogEntries = useMemo(\n () => (hasChangelog ? parseChangelog(changelog as string) : []),\n [hasChangelog, changelog],\n );\n const latestChangelogId = changelogEntries[0]?.id;\n const { unseen: changelogUnseen, markSeen: markChangelogSeen } =\n useChangelogSeen(changelogKey ?? \"app\", latestChangelogId);\n\n const openChangelog = useCallback(() => {\n onOpenChange(false);\n markChangelogSeen();\n // Let the menu close before the dialog opens (avoids overlay flicker).\n setTimeout(() => setChangelogOpen(true), 50);\n }, [onOpenChange, markChangelogSeen]);\n\n // Focus input when opening; clear search while closed so reopen never renders\n // dynamic results for the previous query.\n useEffect(() => {\n if (!open) {\n setSearch(\"\");\n setSelectedIndex(0);\n return;\n }\n\n if (open) {\n setSearch(\"\");\n setSelectedIndex(0);\n // Wait for render then focus\n requestAnimationFrame(() => {\n inputRef.current?.focus();\n });\n }\n }, [open]);\n\n // Reset selection when search changes\n useEffect(() => {\n setSelectedIndex(0);\n }, [search]);\n\n // Keep selected item scrolled into view\n useEffect(() => {\n const items = containerRef.current?.querySelectorAll('[role=\"option\"]');\n if (items && items[selectedIndex]) {\n items[selectedIndex].scrollIntoView({ block: \"nearest\" });\n }\n }, [selectedIndex]);\n\n // Apply selected styling directly (can't rely on Tailwind scanning core package)\n useEffect(() => {\n const items = containerRef.current?.querySelectorAll('[role=\"option\"]');\n if (!items) return;\n items.forEach((item, i) => {\n const el = item as HTMLElement;\n if (i === selectedIndex) {\n el.style.backgroundColor = \"hsl(var(--accent))\";\n el.style.color = \"hsl(var(--accent-foreground))\";\n } else {\n el.style.backgroundColor = \"\";\n el.style.color = \"\";\n }\n });\n });\n\n // Close on escape\n useEffect(() => {\n if (!open) return;\n const handleKeyDown = (e: KeyboardEvent) => {\n if (e.key === \"Escape\") {\n e.preventDefault();\n onOpenChange(false);\n }\n };\n document.addEventListener(\"keydown\", handleKeyDown);\n return () => document.removeEventListener(\"keydown\", handleKeyDown);\n }, [open, onOpenChange]);\n\n // Close on click outside\n useEffect(() => {\n if (!open) return;\n const handleClick = (e: MouseEvent) => {\n if (\n containerRef.current &&\n !containerRef.current.contains(e.target as Node)\n ) {\n onOpenChange(false);\n }\n };\n // Use capture to handle clicks before they bubble\n document.addEventListener(\"mousedown\", handleClick, true);\n return () => document.removeEventListener(\"mousedown\", handleClick, true);\n }, [open, onOpenChange]);\n\n const handleSubmitToAgent = useCallback(() => {\n onOpenChange(false);\n if (!search.trim()) {\n focusAgentChat();\n return;\n }\n submitToAgent(search.trim());\n }, [search, onOpenChange]);\n\n const handleKeyDown = (e: React.KeyboardEvent) => {\n const items = containerRef.current?.querySelectorAll('[role=\"option\"]');\n const itemCount = items?.length ?? 0;\n\n if (e.key === \"ArrowDown\") {\n e.preventDefault();\n setSelectedIndex((prev) => (prev + 1) % itemCount || 0);\n } else if (e.key === \"ArrowUp\") {\n e.preventDefault();\n setSelectedIndex((prev) => (prev - 1 + itemCount) % itemCount || 0);\n } else if (e.key === \"Enter\") {\n e.preventDefault();\n if (items && items[selectedIndex]) {\n (items[selectedIndex] as HTMLElement).click();\n }\n }\n };\n\n // The built-in \"What's new\" row matches changelog-ish search terms.\n const changelogRowMatches =\n !search ||\n [\n changelogLabel,\n \"changelog\",\n \"what's new\",\n \"whats new\",\n \"updates\",\n \"release notes\",\n \"changes\",\n ]\n .join(\" \")\n .toLowerCase()\n .includes(search.toLowerCase());\n const showChangelogRow = hasChangelog && changelogRowMatches;\n\n // Filter children based on search\n const filterChildren = (nodes: ReactNode): ReactNode => {\n return React.Children.map(nodes, (child) => {\n if (!React.isValidElement(child)) return child;\n const props = child.props as Record<string, unknown>;\n\n // If it's a CommandGroup, filter its children\n if (child.type === CommandGroup) {\n const groupChildren = filterChildren(props.children as ReactNode);\n const hasChildren = React.Children.count(groupChildren) > 0;\n if (!hasChildren) return null;\n return React.cloneElement(child, {\n ...props,\n children: groupChildren,\n } as Record<string, unknown>);\n }\n\n if (child.type === CommandDocsGroup) {\n const docs = Array.isArray(props.docs)\n ? (props.docs as CommandMenuDoc[])\n : [];\n const filteredDocs = filterCommandDocs(docs, search);\n if (filteredDocs.length === 0) return null;\n return React.cloneElement(child, {\n ...props,\n docs: filteredDocs,\n } as Record<string, unknown>);\n }\n\n // If it's a CommandItem, check if it matches search\n if (child.type === CommandItem) {\n if (!search) return child;\n const text = getTextContent(props.children as ReactNode).toLowerCase();\n const keywords = ((props.keywords as string[]) || [])\n .join(\" \")\n .toLowerCase();\n const searchLower = search.toLowerCase();\n if (text.includes(searchLower) || keywords.includes(searchLower)) {\n return child;\n }\n return null;\n }\n\n // If it's a separator, keep it (will be cleaned up later if needed)\n if (child.type === CommandSeparator) {\n return search ? null : child; // Hide separators when searching\n }\n\n return child;\n });\n };\n\n const filteredChildren = filterChildren(children);\n const hasResults = React.Children.toArray(filteredChildren).some(\n (child) =>\n React.isValidElement(child) &&\n (child.type === CommandGroup || child.type === CommandDocsGroup),\n );\n const dynamicResults = open ? renderResults?.(search) : null;\n const hasDynamicResults = Boolean(dynamicResults);\n\n return (\n <>\n {open && (\n <div className=\"fixed inset-0 z-50 bg-black/50\">\n <div\n ref={containerRef}\n className={cn(\n \"fixed left-1/2 top-[15vh] -translate-x-1/2 w-full max-w-lg\",\n \"rounded-lg border border-border bg-popover text-popover-foreground shadow-lg\",\n className,\n )}\n >\n <CommandMenuContext.Provider\n value={{ search, onOpenChange, containerRef, setSelectedIndex }}\n >\n {/* Search input */}\n <div className=\"flex items-center border-b px-3\">\n <IconSearch className=\"me-2 h-4 w-4 shrink-0 opacity-50\" />\n <input\n ref={inputRef}\n value={search}\n onChange={(e) => setSearch(e.target.value)}\n onKeyDown={handleKeyDown}\n placeholder={placeholder}\n className=\"flex h-11 w-full rounded-md bg-transparent py-3 text-sm outline-none placeholder:text-muted-foreground disabled:cursor-not-allowed disabled:opacity-50\"\n />\n </div>\n\n {/* Command list */}\n <div className=\"max-h-[300px] overflow-y-auto overflow-x-hidden\">\n {dynamicResults}\n {hasResults && filteredChildren}\n\n {/* What's new — built-in changelog entry */}\n {showChangelogRow && (\n <>\n {hasResults && <CommandSeparator />}\n <div className=\"p-1\">\n <div\n className=\"relative flex cursor-pointer select-none items-center gap-2 rounded-sm px-2 py-2 text-sm outline-none\"\n onClick={openChangelog}\n onMouseEnter={(e) => {\n const items =\n containerRef.current?.querySelectorAll(\n '[role=\"option\"]',\n );\n if (!items) return;\n const index = Array.from(items).indexOf(\n e.currentTarget,\n );\n if (index >= 0) setSelectedIndex(index);\n }}\n role=\"option\"\n >\n <IconHistory className=\"h-4 w-4 text-muted-foreground\" />\n <span>{changelogLabel}</span>\n {changelogUnseen && (\n <span\n className=\"ms-auto h-2 w-2 rounded-full bg-primary\"\n aria-label=\"New updates available\"\n />\n )}\n </div>\n </div>\n </>\n )}\n\n {/* Ask AI — always visible at the bottom */}\n {showAgentFallback && (\n <>\n {(hasResults || showChangelogRow || hasDynamicResults) && (\n <CommandSeparator />\n )}\n <div className=\"p-1\">\n <div\n className=\"relative flex cursor-pointer select-none items-center gap-2 rounded-sm px-2 py-2 text-sm outline-none\"\n onClick={handleSubmitToAgent}\n onMouseEnter={(e) => {\n const items =\n containerRef.current?.querySelectorAll(\n '[role=\"option\"]',\n );\n if (!items) return;\n const index = Array.from(items).indexOf(\n e.currentTarget,\n );\n if (index >= 0) setSelectedIndex(index);\n }}\n role=\"option\"\n >\n <IconMessage className=\"h-4 w-4 text-muted-foreground\" />\n <span>\n {search.trim() ? (\n <>\n Ask AI:{\" \"}\n <span className=\"text-muted-foreground\">\n \"{search}\"\n </span>\n </>\n ) : (\n <span className=\"text-muted-foreground\">\n Ask AI anything...\n </span>\n )}\n </span>\n {search.trim() && (\n <span className=\"ms-auto text-xs text-muted-foreground\">\n ↵\n </span>\n )}\n </div>\n </div>\n </>\n )}\n </div>\n </CommandMenuContext.Provider>\n </div>\n </div>\n )}\n\n {hasChangelog && (\n <ChangelogDialog\n open={changelogOpen}\n onOpenChange={setChangelogOpen}\n markdown={changelog as string}\n title={changelogLabel}\n />\n )}\n </>\n );\n}\n\n// Helper to extract text content from React children\nfunction getTextContent(children: ReactNode): string {\n if (typeof children === \"string\") return children;\n if (typeof children === \"number\") return String(children);\n if (!children) return \"\";\n if (Array.isArray(children)) {\n return children.map(getTextContent).join(\" \");\n }\n if (\n React.isValidElement(children) &&\n (children.props as Record<string, unknown>).children\n ) {\n return getTextContent(\n (children.props as Record<string, unknown>).children as ReactNode,\n );\n }\n return \"\";\n}\n\n// Attach sub-components\nCommandMenu.Group = CommandGroup;\nCommandMenu.Item = CommandItem;\nCommandMenu.DocsGroup = CommandDocsGroup;\nCommandMenu.Shortcut = CommandShortcut;\nCommandMenu.Separator = CommandSeparator;\n\n// ─── Keyboard Hook ──────────────────────────────────────────────────────────\n\n/**\n * Hook to handle Cmd+K (or Ctrl+K) to open the command menu\n */\nexport function useCommandMenuShortcut(\n onOpen: () => void,\n options: { allowContentEditable?: boolean } = {},\n) {\n useEffect(() => {\n const handleKeyDown = (e: KeyboardEvent) => {\n if ((e.metaKey || e.ctrlKey) && e.key.toLowerCase() === \"k\") {\n // Don't trigger if user is typing in a native form control.\n const target = e.target instanceof HTMLElement ? e.target : null;\n const isContentEditable = target?.isContentEditable;\n if (\n target?.tagName === \"INPUT\" ||\n target?.tagName === \"TEXTAREA\" ||\n target?.tagName === \"SELECT\" ||\n (!options.allowContentEditable && isContentEditable)\n ) {\n return;\n }\n e.preventDefault();\n onOpen();\n }\n };\n const useCapture = Boolean(options.allowContentEditable);\n document.addEventListener(\"keydown\", handleKeyDown, useCapture);\n return () =>\n document.removeEventListener(\"keydown\", handleKeyDown, useCapture);\n }, [onOpen, options.allowContentEditable]);\n}\n\nexport type {\n CommandDocsGroupProps,\n CommandGroupProps,\n CommandItemProps,\n CommandShortcutProps,\n};\n"]}
@@ -1 +1 @@
1
- {"version":3,"file":"DefaultSpinner.d.ts","sourceRoot":"","sources":["../../src/client/DefaultSpinner.tsx"],"names":[],"mappings":"AAAA;;;;GAIG;AACH,wBAAgB,cAAc,gCAkC7B"}
1
+ {"version":3,"file":"DefaultSpinner.d.ts","sourceRoot":"","sources":["../../src/client/DefaultSpinner.tsx"],"names":[],"mappings":"AAAA;;;;GAIG;AACH,wBAAgB,cAAc,gCAyC7B"}
@@ -13,8 +13,15 @@ export function DefaultSpinner() {
13
13
  width: "100%",
14
14
  }, children: [_jsx("svg", { role: "status", "aria-label": "Loading", width: 24, height: 24, viewBox: "0 0 24 24", fill: "none", stroke: "currentColor", strokeWidth: 2, strokeLinecap: "round", strokeLinejoin: "round", style: { animation: "an-spin 1s linear infinite", opacity: 0.7 }, children: _jsx("path", { d: "M21 12a9 9 0 1 1-6.219-8.56" }) }), _jsx("style", { children: `
15
15
  @keyframes an-spin { to { transform: rotate(360deg) } }
16
+ html {
17
+ background: hsl(var(--background, 0 0% 100%));
18
+ color: hsl(var(--foreground, 240 10% 3.9%));
19
+ }
16
20
  @media (prefers-color-scheme: dark) {
17
- html { background: #09090b; color: #fafafa }
21
+ html {
22
+ background: hsl(var(--background, 240 10% 3.9%));
23
+ color: hsl(var(--foreground, 0 0% 98%));
24
+ }
18
25
  }
19
26
  ` })] }));
20
27
  }
@@ -1 +1 @@
1
- {"version":3,"file":"DefaultSpinner.js","sourceRoot":"","sources":["../../src/client/DefaultSpinner.tsx"],"names":[],"mappings":";AAAA;;;;GAIG;AACH,MAAM,UAAU,cAAc;IAC5B,OAAO,CACL,eACE,KAAK,EAAE;YACL,OAAO,EAAE,MAAM;YACf,UAAU,EAAE,QAAQ;YACpB,cAAc,EAAE,QAAQ;YACxB,MAAM,EAAE,OAAO;YACf,KAAK,EAAE,MAAM;SACd,aAED,cACE,IAAI,EAAC,QAAQ,gBACF,SAAS,EACpB,KAAK,EAAE,EAAE,EACT,MAAM,EAAE,EAAE,EACV,OAAO,EAAC,WAAW,EACnB,IAAI,EAAC,MAAM,EACX,MAAM,EAAC,cAAc,EACrB,WAAW,EAAE,CAAC,EACd,aAAa,EAAC,OAAO,EACrB,cAAc,EAAC,OAAO,EACtB,KAAK,EAAE,EAAE,SAAS,EAAE,4BAA4B,EAAE,OAAO,EAAE,GAAG,EAAE,YAEhE,eAAM,CAAC,EAAC,6BAA6B,GAAG,GACpC,EACN,0BAAQ;;;;;OAKP,GAAS,IACN,CACP,CAAC;AACJ,CAAC","sourcesContent":["/**\n * Full-screen loading spinner rendered during SSR and initial hydration.\n * Uses inline SVG + styles because Tailwind may not be loaded yet on the server.\n * Respects the user's OS color scheme so dark-mode users don't get a white flash.\n */\nexport function DefaultSpinner() {\n return (\n <div\n style={{\n display: \"flex\",\n alignItems: \"center\",\n justifyContent: \"center\",\n height: \"100vh\",\n width: \"100%\",\n }}\n >\n <svg\n role=\"status\"\n aria-label=\"Loading\"\n width={24}\n height={24}\n viewBox=\"0 0 24 24\"\n fill=\"none\"\n stroke=\"currentColor\"\n strokeWidth={2}\n strokeLinecap=\"round\"\n strokeLinejoin=\"round\"\n style={{ animation: \"an-spin 1s linear infinite\", opacity: 0.7 }}\n >\n <path d=\"M21 12a9 9 0 1 1-6.219-8.56\" />\n </svg>\n <style>{`\n @keyframes an-spin { to { transform: rotate(360deg) } }\n @media (prefers-color-scheme: dark) {\n html { background: #09090b; color: #fafafa }\n }\n `}</style>\n </div>\n );\n}\n"]}
1
+ {"version":3,"file":"DefaultSpinner.js","sourceRoot":"","sources":["../../src/client/DefaultSpinner.tsx"],"names":[],"mappings":";AAAA;;;;GAIG;AACH,MAAM,UAAU,cAAc;IAC5B,OAAO,CACL,eACE,KAAK,EAAE;YACL,OAAO,EAAE,MAAM;YACf,UAAU,EAAE,QAAQ;YACpB,cAAc,EAAE,QAAQ;YACxB,MAAM,EAAE,OAAO;YACf,KAAK,EAAE,MAAM;SACd,aAED,cACE,IAAI,EAAC,QAAQ,gBACF,SAAS,EACpB,KAAK,EAAE,EAAE,EACT,MAAM,EAAE,EAAE,EACV,OAAO,EAAC,WAAW,EACnB,IAAI,EAAC,MAAM,EACX,MAAM,EAAC,cAAc,EACrB,WAAW,EAAE,CAAC,EACd,aAAa,EAAC,OAAO,EACrB,cAAc,EAAC,OAAO,EACtB,KAAK,EAAE,EAAE,SAAS,EAAE,4BAA4B,EAAE,OAAO,EAAE,GAAG,EAAE,YAEhE,eAAM,CAAC,EAAC,6BAA6B,GAAG,GACpC,EACN,0BAAQ;;;;;;;;;;;;OAYP,GAAS,IACN,CACP,CAAC;AACJ,CAAC","sourcesContent":["/**\n * Full-screen loading spinner rendered during SSR and initial hydration.\n * Uses inline SVG + styles because Tailwind may not be loaded yet on the server.\n * Respects the user's OS color scheme so dark-mode users don't get a white flash.\n */\nexport function DefaultSpinner() {\n return (\n <div\n style={{\n display: \"flex\",\n alignItems: \"center\",\n justifyContent: \"center\",\n height: \"100vh\",\n width: \"100%\",\n }}\n >\n <svg\n role=\"status\"\n aria-label=\"Loading\"\n width={24}\n height={24}\n viewBox=\"0 0 24 24\"\n fill=\"none\"\n stroke=\"currentColor\"\n strokeWidth={2}\n strokeLinecap=\"round\"\n strokeLinejoin=\"round\"\n style={{ animation: \"an-spin 1s linear infinite\", opacity: 0.7 }}\n >\n <path d=\"M21 12a9 9 0 1 1-6.219-8.56\" />\n </svg>\n <style>{`\n @keyframes an-spin { to { transform: rotate(360deg) } }\n html {\n background: hsl(var(--background, 0 0% 100%));\n color: hsl(var(--foreground, 240 10% 3.9%));\n }\n @media (prefers-color-scheme: dark) {\n html {\n background: hsl(var(--background, 240 10% 3.9%));\n color: hsl(var(--foreground, 0 0% 98%));\n }\n }\n `}</style>\n </div>\n );\n}\n"]}
@@ -24,7 +24,13 @@ export declare function MessageActionsMenu({ showRevert, onRevert, }?: {
24
24
  onRevert?: () => void;
25
25
  }): React.JSX.Element;
26
26
  export declare function UserMessage(): React.JSX.Element;
27
- export declare function AssistantMessage(): React.JSX.Element;
27
+ export declare function shouldShowAssistantMessageFooter({ isLast, chatRunning, hasRenderableContent, statusIsTerminal, }: {
28
+ isLast: boolean;
29
+ chatRunning: boolean;
30
+ hasRenderableContent: boolean;
31
+ statusIsTerminal: boolean;
32
+ }): boolean;
33
+ export declare function AssistantMessage(): React.JSX.Element | null;
28
34
  export declare function RunningActivityStatus({ label }: {
29
35
  label: string;
30
36
  }): React.JSX.Element;
@@ -1 +1 @@
1
- {"version":3,"file":"message-components.d.ts","sourceRoot":"","sources":["../../../src/client/chat/message-components.tsx"],"names":[],"mappings":"AAuCA,OAAO,KAAmD,MAAM,OAAO,CAAC;AAqCxE,wBAAgB,0BAA0B,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM,CAE/D;AAID,UAAU,yBAAyB;IACjC,KAAK,EAAE,MAAM,CAAC;IACd,IAAI,EAAE,MAAM,CAAC;CACd;AAqBD,wBAAgB,sBAAsB,CACpC,KAAK,EAAE,OAAO,GACb,yBAAyB,GAAG,IAAI,CAyClC;AAED,wBAAgB,gBAAgB,CAAC,EAC/B,SAAS,EACT,SAAS,GACV,EAAE;IACD,SAAS,EAAE,yBAAyB,CAAC;IACrC,SAAS,CAAC,EAAE,MAAM,CAAC;CACpB,qBAYA;AAID,wBAAgB,qBAAqB,6BAgEpC;AAID,eAAO,MAAM,iBAAiB;YACpB,MAAM;aACL,OAAO;eACL,MAAM;SACJ,CAAC;AAEhB,eAAO,MAAM,qBAAqB;iBACnB,MAAM,IAAI,GAAG,OAAO,GAAG,OAAO,CAAC,IAAI,GAAG,OAAO,CAAC;SAC9C,CAAC;AAIhB,wBAAgB,mBAAmB,sBA+BlC;AAwMD,wBAAgB,kBAAkB,CAAC,EACjC,UAAU,EACV,QAAQ,GACT,GAAE;IACD,UAAU,CAAC,EAAE,OAAO,CAAC;IACrB,QAAQ,CAAC,EAAE,MAAM,IAAI,CAAC;CAClB,qBAiIL;AAID,wBAAgB,WAAW,sBAuI1B;AAID,wBAAgB,gBAAgB,sBAiL/B;AAID,wBAAgB,qBAAqB,CAAC,EAAE,KAAK,EAAE,EAAE;IAAE,KAAK,EAAE,MAAM,CAAA;CAAE,qBAMjE;AAED,wBAAgB,iBAAiB,CAAC,EAChC,KAAkB,GACnB,GAAE;IAAE,KAAK,CAAC,EAAE,MAAM,CAAA;CAAO,qBAWzB"}
1
+ {"version":3,"file":"message-components.d.ts","sourceRoot":"","sources":["../../../src/client/chat/message-components.tsx"],"names":[],"mappings":"AAuCA,OAAO,KAAmD,MAAM,OAAO,CAAC;AAqCxE,wBAAgB,0BAA0B,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM,CAE/D;AAID,UAAU,yBAAyB;IACjC,KAAK,EAAE,MAAM,CAAC;IACd,IAAI,EAAE,MAAM,CAAC;CACd;AAqBD,wBAAgB,sBAAsB,CACpC,KAAK,EAAE,OAAO,GACb,yBAAyB,GAAG,IAAI,CAyClC;AAED,wBAAgB,gBAAgB,CAAC,EAC/B,SAAS,EACT,SAAS,GACV,EAAE;IACD,SAAS,EAAE,yBAAyB,CAAC;IACrC,SAAS,CAAC,EAAE,MAAM,CAAC;CACpB,qBAYA;AAID,wBAAgB,qBAAqB,6BAgEpC;AAID,eAAO,MAAM,iBAAiB;YACpB,MAAM;aACL,OAAO;eACL,MAAM;SACJ,CAAC;AAEhB,eAAO,MAAM,qBAAqB;iBACnB,MAAM,IAAI,GAAG,OAAO,GAAG,OAAO,CAAC,IAAI,GAAG,OAAO,CAAC;SAC9C,CAAC;AAIhB,wBAAgB,mBAAmB,sBA+BlC;AAwMD,wBAAgB,kBAAkB,CAAC,EACjC,UAAU,EACV,QAAQ,GACT,GAAE;IACD,UAAU,CAAC,EAAE,OAAO,CAAC;IACrB,QAAQ,CAAC,EAAE,MAAM,IAAI,CAAC;CAClB,qBAiIL;AAID,wBAAgB,WAAW,sBAuI1B;AA4BD,wBAAgB,gCAAgC,CAAC,EAC/C,MAAM,EACN,WAAW,EACX,oBAAoB,EACpB,gBAAgB,GACjB,EAAE;IACD,MAAM,EAAE,OAAO,CAAC;IAChB,WAAW,EAAE,OAAO,CAAC;IACrB,oBAAoB,EAAE,OAAO,CAAC;IAC9B,gBAAgB,EAAE,OAAO,CAAC;CAC3B,GAAG,OAAO,CAIV;AAED,wBAAgB,gBAAgB,6BAyL/B;AAID,wBAAgB,qBAAqB,CAAC,EAAE,KAAK,EAAE,EAAE;IAAE,KAAK,EAAE,MAAM,CAAA;CAAE,qBAMjE;AAED,wBAAgB,iBAAiB,CAAC,EAChC,KAAkB,GACnB,GAAE;IAAE,KAAK,CAAC,EAAE,MAAM,CAAA;CAAO,qBAWzB"}
@@ -356,6 +356,34 @@ export function UserMessage() {
356
356
  } }) }), !expanded && isExpandable && (_jsx("div", { className: "pointer-events-none absolute inset-x-0 bottom-0 h-14 rounded-b-lg bg-gradient-to-t from-accent via-accent/90 to-transparent" })), !chatRunning && hasDisplayableText && (_jsx(TooltipProvider, { delayDuration: 400, children: _jsxs(Tooltip, { children: [_jsx(TooltipTrigger, { asChild: true, children: _jsx(ActionBarPrimitive.Edit, { asChild: true, children: _jsx("button", { type: "button", "aria-label": "Edit message", className: "absolute -left-8 top-1 flex h-6 w-6 cursor-pointer items-center justify-center rounded-md text-muted-foreground/0 transition-colors duration-150 group-hover:text-muted-foreground/70 group-hover:hover:bg-accent group-hover:hover:text-foreground", children: _jsx(IconPencil, { className: "h-3.5 w-3.5" }) }) }) }), _jsx(TooltipContent, { side: "left", className: "text-xs", children: "Edit message" })] }) }))] })), hasDisplayableText && isExpandable && (_jsxs("button", { type: "button", onClick: () => setExpanded((prev) => !prev), className: "mt-1 inline-flex items-center gap-1 rounded-md px-1.5 py-1 text-[11px] font-medium text-muted-foreground hover:text-foreground", children: [_jsx(IconChevronDown, { className: cn("h-3.5 w-3.5 transition-transform", expanded && "rotate-180") }), expanded ? "Collapse" : "Expand"] })), _jsxs("div", { className: "mt-1 flex items-center justify-end gap-1", children: [_jsx(MessageBranchPicker, {}), timestamp && (_jsx(MessageTimestamp, { timestamp: timestamp, className: "opacity-0 transition-opacity duration-150 group-hover:opacity-100 group-focus-within:opacity-100" }))] })] }) }));
357
357
  }
358
358
  // ─── AssistantMessage ─────────────────────────────────────────────────────────
359
+ function assistantMessageHasRenderableContent(message) {
360
+ const content = message.content;
361
+ if (typeof content === "string")
362
+ return content.trim().length > 0;
363
+ if (!Array.isArray(content))
364
+ return false;
365
+ return content.some((part) => {
366
+ if (!part || typeof part !== "object")
367
+ return false;
368
+ const type = part.type;
369
+ if (type === "text") {
370
+ const text = part.text;
371
+ return typeof text === "string" && text.trim().length > 0;
372
+ }
373
+ return true;
374
+ });
375
+ }
376
+ function assistantMessageStatusIsTerminal(message) {
377
+ const statusType = message.status?.type;
378
+ return statusType === "complete" || statusType === "incomplete";
379
+ }
380
+ export function shouldShowAssistantMessageFooter({ isLast, chatRunning, hasRenderableContent, statusIsTerminal, }) {
381
+ if (!hasRenderableContent)
382
+ return false;
383
+ if (!isLast)
384
+ return true;
385
+ return !chatRunning && statusIsTerminal;
386
+ }
359
387
  export function AssistantMessage() {
360
388
  const [restoreState, setRestoreState] = useState("idle");
361
389
  const messageRuntime = useMessageRuntime();
@@ -365,7 +393,13 @@ export function AssistantMessage() {
365
393
  const timestamp = formatMessageTimestamp(msg.createdAt);
366
394
  const isLast = thread.messages.length > 0 &&
367
395
  thread.messages[thread.messages.length - 1].id === msg.id;
368
- const isComplete = !isLast || !chatRunning;
396
+ const hasRenderableContent = assistantMessageHasRenderableContent(msg);
397
+ const isComplete = shouldShowAssistantMessageFooter({
398
+ isLast,
399
+ chatRunning,
400
+ hasRenderableContent,
401
+ statusIsTerminal: assistantMessageStatusIsTerminal(msg),
402
+ });
369
403
  const cpCtx = React.useContext(CheckpointContext);
370
404
  const handleRestore = useCallback(async () => {
371
405
  if (restoreState === "idle") {
@@ -422,6 +456,8 @@ export function AssistantMessage() {
422
456
  p.structuredMeta &&
423
457
  (p.structuredMeta.toolKind === "edit" ||
424
458
  p.structuredMeta.toolKind === "write"));
459
+ if (!hasRenderableContent)
460
+ return null;
425
461
  return (_jsxs("div", { className: "group relative", style: { contentVisibility: isComplete ? "auto" : "visible" }, children: [_jsxs("div", { className: "max-w-[95%] text-sm leading-relaxed text-foreground", children: [_jsx(MessagePrimitive.Parts, { components: {
426
462
  Text: MarkdownText,
427
463
  tools: {