@agent-native/core 0.90.1 → 0.90.3

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (714) hide show
  1. package/corpus/README.md +2 -2
  2. package/corpus/core/CHANGELOG.md +26 -0
  3. package/corpus/core/docs/content/agent-native-toolkit.mdx +87 -80
  4. package/corpus/core/docs/content/locales/ar-SA/agent-native-toolkit.mdx +89 -80
  5. package/corpus/core/docs/content/locales/de-DE/agent-native-toolkit.mdx +89 -80
  6. package/corpus/core/docs/content/locales/es-ES/agent-native-toolkit.mdx +89 -80
  7. package/corpus/core/docs/content/locales/fr-FR/agent-native-toolkit.mdx +89 -80
  8. package/corpus/core/docs/content/locales/hi-IN/agent-native-toolkit.mdx +89 -80
  9. package/corpus/core/docs/content/locales/ja-JP/agent-native-toolkit.mdx +89 -80
  10. package/corpus/core/docs/content/locales/ko-KR/agent-native-toolkit.mdx +89 -80
  11. package/corpus/core/docs/content/locales/pt-BR/agent-native-toolkit.mdx +89 -80
  12. package/corpus/core/docs/content/locales/zh-CN/agent-native-toolkit.mdx +89 -80
  13. package/corpus/core/docs/content/locales/zh-TW/agent-native-toolkit.mdx +89 -80
  14. package/corpus/core/docs/content/toolkit-agent-ux.mdx +43 -0
  15. package/corpus/core/docs/content/toolkit-app-adapters.mdx +9 -0
  16. package/corpus/core/docs/content/toolkit-collaboration-ui.mdx +12 -0
  17. package/corpus/core/docs/content/toolkit-collaboration.mdx +74 -0
  18. package/corpus/core/docs/content/toolkit-command-navigation.mdx +106 -0
  19. package/corpus/core/docs/content/toolkit-comments-review.mdx +98 -0
  20. package/corpus/core/docs/content/toolkit-history.mdx +95 -0
  21. package/corpus/core/docs/content/toolkit-observability.mdx +41 -0
  22. package/corpus/core/docs/content/toolkit-org-team.mdx +80 -0
  23. package/corpus/core/docs/content/toolkit-resources.mdx +57 -0
  24. package/corpus/core/docs/content/toolkit-settings.mdx +65 -0
  25. package/corpus/core/docs/content/toolkit-setup-connections.mdx +109 -0
  26. package/corpus/core/docs/content/toolkit-sharing-ui.mdx +18 -6
  27. package/corpus/core/docs/content/toolkit-sharing.mdx +81 -0
  28. package/corpus/core/docs/content/toolkit-shell-hooks.mdx +9 -0
  29. package/corpus/core/docs/content/toolkit-ui.mdx +9 -0
  30. package/corpus/core/package.json +35 -1
  31. package/corpus/core/src/agent/engine/ai-sdk-engine.ts +19 -1
  32. package/corpus/core/src/agent/engine/anthropic-engine.ts +25 -1
  33. package/corpus/core/src/agent/engine/registry.ts +23 -16
  34. package/corpus/core/src/agent/production-agent.ts +37 -6
  35. package/corpus/core/src/client/AgentPanel.tsx +1 -1
  36. package/corpus/core/src/client/command-navigation/index.ts +15 -0
  37. package/corpus/core/src/client/comments-review/index.ts +1 -0
  38. package/corpus/core/src/client/history/VersionHistoryPanel.tsx +145 -0
  39. package/corpus/core/src/client/history/index.ts +18 -0
  40. package/corpus/core/src/client/history/use-history.ts +86 -0
  41. package/corpus/core/src/client/index.ts +76 -9
  42. package/corpus/core/src/client/org/OrgSwitcher.tsx +6 -6
  43. package/corpus/core/src/client/org/RequireActiveOrg.tsx +2 -2
  44. package/corpus/core/src/client/org/TeamPage.tsx +3 -3
  45. package/corpus/core/src/client/org/hooks.ts +32 -0
  46. package/corpus/core/src/client/org/index.ts +30 -1
  47. package/corpus/core/src/client/org-team/index.ts +1 -0
  48. package/corpus/core/src/client/review/ReviewStatusBadge.tsx +39 -0
  49. package/corpus/core/src/client/review/ReviewThreadPanel.tsx +278 -0
  50. package/corpus/core/src/client/review/index.ts +25 -0
  51. package/corpus/core/src/client/review/use-review.ts +114 -0
  52. package/corpus/core/src/client/rich-markdown-editor/useCollabReconcile.ts +11 -6
  53. package/corpus/core/src/client/settings/index.ts +11 -1
  54. package/corpus/core/src/client/setup-connections/BuilderConnectCard.tsx +94 -0
  55. package/corpus/core/src/client/setup-connections/ProviderReadinessBadge.tsx +73 -0
  56. package/corpus/core/src/client/setup-connections/SetupConnectionsPage.tsx +94 -0
  57. package/corpus/core/src/client/setup-connections/index.ts +46 -0
  58. package/corpus/core/src/client/sharing/ShareButton.tsx +20 -14
  59. package/corpus/core/src/client/sharing/ShareDialog.tsx +3 -3
  60. package/corpus/core/src/client/use-action.ts +39 -2
  61. package/corpus/core/src/client/use-db-sync.ts +44 -18
  62. package/corpus/core/src/command-navigation/actions.ts +100 -0
  63. package/corpus/core/src/command-navigation/index.ts +12 -0
  64. package/corpus/core/src/comments-review/index.ts +1 -0
  65. package/corpus/core/src/db/create-get-db.ts +32 -2
  66. package/corpus/core/src/file-upload/builder.ts +24 -3
  67. package/corpus/core/src/file-upload/types.ts +3 -1
  68. package/corpus/core/src/history/actions/create-resource-version.ts +89 -0
  69. package/corpus/core/src/history/actions/get-resource-version.ts +60 -0
  70. package/corpus/core/src/history/actions/list-resource-history.ts +53 -0
  71. package/corpus/core/src/history/actions/list-resource-versions.ts +43 -0
  72. package/corpus/core/src/history/actions/restore-resource-version.ts +96 -0
  73. package/corpus/core/src/history/index.ts +27 -0
  74. package/corpus/core/src/history/registry.ts +99 -0
  75. package/corpus/core/src/history/store.ts +348 -0
  76. package/corpus/core/src/history/types.ts +69 -0
  77. package/corpus/core/src/index.ts +10 -0
  78. package/corpus/core/src/navigation/index.ts +170 -0
  79. package/corpus/core/src/org/index.ts +8 -0
  80. package/corpus/core/src/org/permissions.ts +30 -0
  81. package/corpus/core/src/org-team/index.ts +1 -0
  82. package/corpus/core/src/private-blob/registry.ts +1 -0
  83. package/corpus/core/src/review/actions/consume-review-feedback.ts +38 -0
  84. package/corpus/core/src/review/actions/create-review-comment.ts +107 -0
  85. package/corpus/core/src/review/actions/delete-review-comment.ts +55 -0
  86. package/corpus/core/src/review/actions/get-review-feedback.ts +54 -0
  87. package/corpus/core/src/review/actions/list-review-comments.ts +53 -0
  88. package/corpus/core/src/review/actions/reply-review-comment.ts +107 -0
  89. package/corpus/core/src/review/actions/resolve-review-thread.ts +60 -0
  90. package/corpus/core/src/review/actions/set-review-status.ts +58 -0
  91. package/corpus/core/src/review/index.ts +36 -0
  92. package/corpus/core/src/review/mentions.ts +44 -0
  93. package/corpus/core/src/review/registry.ts +99 -0
  94. package/corpus/core/src/review/store.ts +687 -0
  95. package/corpus/core/src/review/types.ts +97 -0
  96. package/corpus/core/src/server/action-discovery.ts +54 -0
  97. package/corpus/core/src/server/agent-engine-api-key-route.ts +5 -0
  98. package/corpus/core/src/server/credential-provider.ts +108 -0
  99. package/corpus/core/src/server/framework-request-handler.ts +52 -4
  100. package/corpus/core/src/setup-connections/index.ts +89 -0
  101. package/corpus/core/src/setup-connections/onboarding.ts +47 -0
  102. package/corpus/core/src/transcription/builder-transcription.ts +9 -2
  103. package/corpus/core/src/vite/action-types-plugin.ts +52 -0
  104. package/corpus/templates/analytics/app/components/layout/Layout.tsx +2 -1
  105. package/corpus/templates/analytics/app/components/layout/Sidebar.tsx +2 -2
  106. package/corpus/templates/analytics/app/global.css +22 -10
  107. package/corpus/templates/analytics/app/i18n/zh-TW.ts +6 -1
  108. package/corpus/templates/analytics/app/i18n-data.ts +81 -13
  109. package/corpus/templates/analytics/app/pages/adhoc/sql-dashboard/index.tsx +2 -2
  110. package/corpus/templates/analytics/app/pages/analyses/AnalysisDetail.tsx +2 -2
  111. package/corpus/templates/analytics/app/pages/sessions/SessionDetailPage.tsx +528 -108
  112. package/corpus/templates/analytics/app/pages/sessions/SessionDevToolsPanel.tsx +466 -183
  113. package/corpus/templates/analytics/changelog/2026-07-07-session-replays-load-sooner-show-clearer-activity-timelines-.md +6 -0
  114. package/corpus/templates/assets/.agents/skills/asset-generation/SKILL.md +5 -0
  115. package/corpus/templates/assets/.agents/skills/logo-composite/SKILL.md +34 -6
  116. package/corpus/templates/assets/AGENTS.md +23 -4
  117. package/corpus/templates/assets/actions/_generation-preset-settings.ts +48 -0
  118. package/corpus/templates/assets/actions/_helpers.ts +8 -1
  119. package/corpus/templates/assets/actions/_preset-skeleton-validation.ts +64 -0
  120. package/corpus/templates/assets/actions/create-generation-preset.ts +11 -3
  121. package/corpus/templates/assets/actions/generate-image-batch.ts +7 -2
  122. package/corpus/templates/assets/actions/generate-image.ts +342 -25
  123. package/corpus/templates/assets/actions/get-library.ts +4 -3
  124. package/corpus/templates/assets/actions/navigate.ts +2 -1
  125. package/corpus/templates/assets/actions/refresh-generation-run.ts +5 -1
  126. package/corpus/templates/assets/actions/update-asset.ts +1 -0
  127. package/corpus/templates/assets/actions/update-generation-preset.ts +8 -1
  128. package/corpus/templates/assets/actions/view-screen.ts +8 -1
  129. package/corpus/templates/assets/app/components/generation/GenerationResults.tsx +9 -1
  130. package/corpus/templates/assets/app/hooks/use-image-model-menu.ts +1 -0
  131. package/corpus/templates/assets/app/hooks/use-navigation-state.ts +11 -0
  132. package/corpus/templates/assets/app/i18n/zh-TW.ts +64 -0
  133. package/corpus/templates/assets/app/i18n-data.ts +650 -0
  134. package/corpus/templates/assets/app/routes/asset.$id.tsx +2 -1
  135. package/corpus/templates/assets/app/routes/brand-kits.$id.tsx +44 -33
  136. package/corpus/templates/assets/app/routes/brand-kits.$id_.presets.$presetId.tsx +1474 -0
  137. package/corpus/templates/assets/app/routes/library.tsx +43 -1
  138. package/corpus/templates/assets/server/lib/generation.ts +366 -44
  139. package/corpus/templates/assets/server/lib/image-processing.ts +252 -0
  140. package/corpus/templates/assets/server/lib/preset-skeleton.ts +137 -0
  141. package/corpus/templates/assets/shared/api.ts +47 -0
  142. package/corpus/templates/brain/app/routes/settings.tsx +2 -2
  143. package/corpus/templates/calendar/app/components/calendar/AttendeeAutocomplete.tsx +32 -6
  144. package/corpus/templates/calendar/app/components/calendar/EventDetailPopover.tsx +120 -40
  145. package/corpus/templates/calendar/app/hooks/use-people.ts +55 -0
  146. package/corpus/templates/calendar/changelog/2026-07-07-guest-suggestions-now-find-coworkers-from-your-google-worksp.md +6 -0
  147. package/corpus/templates/calendar/changelog/2026-07-07-zoom-stays-selected-after-connecting-it-from-a-draft-event.md +6 -0
  148. package/corpus/templates/clips/actions/create-recording.ts +5 -1
  149. package/corpus/templates/clips/actions/finalize-recording.ts +140 -1
  150. package/corpus/templates/clips/actions/import-loom-recording.ts +1 -0
  151. package/corpus/templates/clips/actions/lib/ensure-seekable-video.ts +1 -0
  152. package/corpus/templates/clips/actions/request-transcript.ts +31 -0
  153. package/corpus/templates/clips/actions/set-thumbnail.ts +2 -0
  154. package/corpus/templates/clips/app/components/library/library-layout.tsx +7 -2
  155. package/corpus/templates/clips/app/components/library/organization-switcher.tsx +2 -2
  156. package/corpus/templates/clips/app/components/library/sort-menu.tsx +1 -1
  157. package/corpus/templates/clips/app/components/player/scrubber-position.ts +9 -0
  158. package/corpus/templates/clips/app/components/player/scrubber.tsx +5 -2
  159. package/corpus/templates/clips/app/components/player/share-dialog.tsx +69 -41
  160. package/corpus/templates/clips/app/components/player/video-player.tsx +38 -1
  161. package/corpus/templates/clips/app/components/recorder/recorder-engine.ts +114 -33
  162. package/corpus/templates/clips/app/components/sharing/share-ui.tsx +3 -3
  163. package/corpus/templates/clips/app/components/sharing/slack-share-hint.tsx +9 -19
  164. package/corpus/templates/clips/app/routes/_app.library._index.tsx +27 -1
  165. package/corpus/templates/clips/app/routes/r.$recordingId.tsx +9 -3
  166. package/corpus/templates/clips/app/routes/record.tsx +178 -80
  167. package/corpus/templates/clips/changelog/2026-07-02-recordings-now-wait-for-storage-media-to-serve-before-finishing.md +6 -0
  168. package/corpus/templates/clips/changelog/2026-07-07-a-pending-app-update-no-longer-blocks-screen-recording-updat.md +6 -0
  169. package/corpus/templates/clips/changelog/2026-07-07-chrome-extension-recordings-keep-audio-after-refreshing-tab.md +6 -0
  170. package/corpus/templates/clips/changelog/2026-07-07-clip-playback-progress-now-starts-and-finishes-at-the-right-times.md +6 -0
  171. package/corpus/templates/clips/changelog/2026-07-07-sharing-public-clips-now-stays-focused-on-the-normal-link-wi.md +6 -0
  172. package/corpus/templates/clips/chrome-extension/src/background.ts +18 -0
  173. package/corpus/templates/clips/chrome-extension/src/offscreen.ts +23 -8
  174. package/corpus/templates/clips/desktop/src/app.tsx +40 -3
  175. package/corpus/templates/clips/desktop/src/hooks/useMediaDevices.ts +19 -7
  176. package/corpus/templates/clips/desktop/src/lib/permissions.ts +2 -0
  177. package/corpus/templates/clips/desktop/src/lib/updater.ts +25 -2
  178. package/corpus/templates/clips/desktop/src-tauri/src/native_screen.rs +7 -0
  179. package/corpus/templates/clips/server/routes/api/recordings/[recordingId]/thumbnail.post.ts +1 -0
  180. package/corpus/templates/clips/server/routes/api/uploads/[recordingId]/abort.post.ts +23 -6
  181. package/corpus/templates/clips/server/routes/api/uploads/[recordingId]/chunk.post.ts +28 -3
  182. package/corpus/templates/clips/server/routes/api/video/[recordingId].get.ts +13 -6
  183. package/corpus/templates/clips/shared/finalize-recovery.ts +35 -3
  184. package/corpus/templates/content/AGENTS.md +52 -52
  185. package/corpus/templates/content/actions/_builder-cms-read-client.ts +188 -8
  186. package/corpus/templates/content/actions/_builder-docs-client.ts +41 -3
  187. package/corpus/templates/content/actions/_database-source-utils.ts +998 -160
  188. package/corpus/templates/content/actions/_database-utils.ts +44 -4
  189. package/corpus/templates/content/actions/_notion-action-utils.ts +6 -2
  190. package/corpus/templates/content/actions/add-content-database-source-field-property.ts +23 -1
  191. package/corpus/templates/content/actions/attach-content-database-source.ts +85 -12
  192. package/corpus/templates/content/actions/change-content-database-source-role.ts +9 -1
  193. package/corpus/templates/content/actions/delete-content-database.ts +1 -0
  194. package/corpus/templates/content/actions/delete-document.ts +337 -52
  195. package/corpus/templates/content/actions/get-document.ts +11 -2
  196. package/corpus/templates/content/actions/list-content-databases.ts +57 -9
  197. package/corpus/templates/content/actions/prepare-builder-source-review.ts +23 -6
  198. package/corpus/templates/content/actions/refresh-content-database-source.ts +26 -3
  199. package/corpus/templates/content/actions/restore-content-database.ts +1 -0
  200. package/corpus/templates/content/actions/update-document.ts +43 -0
  201. package/corpus/templates/content/app/components/editor/BuilderBodySyncingNotice.tsx +21 -0
  202. package/corpus/templates/content/app/components/editor/DocumentDatabase.tsx +0 -1
  203. package/corpus/templates/content/app/components/editor/DocumentEditor.tsx +70 -28
  204. package/corpus/templates/content/app/components/editor/DocumentProperties.tsx +69 -17
  205. package/corpus/templates/content/app/components/editor/VisualEditor.tsx +4 -4
  206. package/corpus/templates/content/app/components/editor/body-hydration.ts +112 -0
  207. package/corpus/templates/content/app/components/editor/builder-body-hydration-pump.ts +52 -0
  208. package/corpus/templates/content/app/components/editor/database/DatabaseView.tsx +9076 -2876
  209. package/corpus/templates/content/app/components/editor/database-sources/BuilderSourceReviewDialog.tsx +41 -1
  210. package/corpus/templates/content/app/components/editor/extensions/ImageBlock.tsx +36 -11
  211. package/corpus/templates/content/app/components/editor/previewDocumentSaveController.ts +21 -1
  212. package/corpus/templates/content/app/components/sidebar/DocumentSidebar.tsx +11 -1
  213. package/corpus/templates/content/app/components/sidebar/DocumentTreeItem.tsx +11 -8
  214. package/corpus/templates/content/app/global.css +41 -0
  215. package/corpus/templates/content/app/hooks/use-content-database.ts +346 -42
  216. package/corpus/templates/content/app/hooks/use-db-sync.ts +9 -0
  217. package/corpus/templates/content/app/hooks/use-documents.ts +47 -0
  218. package/corpus/templates/content/app/hooks/use-notion.ts +12 -10
  219. package/corpus/templates/content/app/i18n/zh-TW.ts +35 -0
  220. package/corpus/templates/content/app/i18n-data.ts +355 -0
  221. package/corpus/templates/content/app/root.tsx +22 -0
  222. package/corpus/templates/content/changelog/2026-07-01-builder-database-sources-keep-loading-rows-in-the-background.md +6 -0
  223. package/corpus/templates/content/changelog/2026-07-01-builder-source-attach-starts-with-usable-rows.md +6 -0
  224. package/corpus/templates/content/changelog/2026-07-01-builder-source-attachment-now-stays-connected-after-large.md +6 -0
  225. package/corpus/templates/content/changelog/2026-07-01-builder-source-refreshes-now-show-progress-for-large-docs-blog.md +6 -0
  226. package/corpus/templates/content/changelog/2026-07-01-database-pages-now-delete-to-trash-without-route-errors.md +6 -0
  227. package/corpus/templates/content/changelog/2026-07-02-builder-source-refreshes-recover-from-stalled-background-row.md +6 -0
  228. package/corpus/templates/content/changelog/2026-07-02-builder-sourced-rows-open-with-sync-protection.md +6 -0
  229. package/corpus/templates/content/changelog/2026-07-02-database-rows-and-pages-open-faster-from-recently-loaded-dat.md +6 -0
  230. package/corpus/templates/content/changelog/2026-07-02-preview-panels-close-reliably-narrow-sidebar-row-actions-sta.md +6 -0
  231. package/corpus/templates/content/changelog/2026-07-06-builder-sync-progress-no-longer-shows-continue.md +6 -0
  232. package/corpus/templates/content/changelog/2026-07-07-permanently-deleting-trashed-databases-now-finishes-reliably.md +6 -0
  233. package/corpus/templates/content/shared/api.ts +13 -0
  234. package/corpus/templates/content/shared/builder-mdx.ts +16 -3
  235. package/corpus/templates/design/.agents/skills/design-generation/SKILL.md +23 -13
  236. package/corpus/templates/design/.agents/skills/responsive-breakpoints/SKILL.md +98 -0
  237. package/corpus/templates/design/.agents/skills/shader-fills/SKILL.md +162 -0
  238. package/corpus/templates/design/AGENTS.md +9 -2
  239. package/corpus/templates/design/actions/add-breakpoint.ts +6 -3
  240. package/corpus/templates/design/actions/apply-a11y-fix.ts +57 -37
  241. package/corpus/templates/design/actions/apply-component-prop-edit.ts +41 -20
  242. package/corpus/templates/design/actions/apply-motion-edit.ts +251 -38
  243. package/corpus/templates/design/actions/apply-shader-fill.ts +90 -66
  244. package/corpus/templates/design/actions/apply-visual-edit.ts +282 -55
  245. package/corpus/templates/design/actions/create-component.ts +29 -60
  246. package/corpus/templates/design/actions/create-file.ts +9 -2
  247. package/corpus/templates/design/actions/duplicate-design.ts +31 -2
  248. package/corpus/templates/design/actions/edit-design.ts +36 -38
  249. package/corpus/templates/design/actions/generate-design-title.ts +87 -0
  250. package/corpus/templates/design/actions/generate-design.ts +53 -18
  251. package/corpus/templates/design/actions/generate-screens.ts +108 -4
  252. package/corpus/templates/design/actions/get-motion-timeline.ts +35 -7
  253. package/corpus/templates/design/actions/insert-asset.ts +34 -29
  254. package/corpus/templates/design/actions/insert-design-native-asset.ts +129 -32
  255. package/corpus/templates/design/actions/insert-figma-library-asset.ts +35 -30
  256. package/corpus/templates/design/actions/present-design-variants.ts +7 -2
  257. package/corpus/templates/design/actions/remove-motion-timeline.ts +31 -36
  258. package/corpus/templates/design/actions/update-file.ts +190 -75
  259. package/corpus/templates/design/app/components/design/BreakpointBar.tsx +403 -0
  260. package/corpus/templates/design/app/components/design/CanvasContextMenu.tsx +469 -222
  261. package/corpus/templates/design/app/components/design/DesignCanvas.tsx +708 -53
  262. package/corpus/templates/design/app/components/design/DesignExtensionsPanel.tsx +83 -3
  263. package/corpus/templates/design/app/components/design/EditPanel.tsx +1091 -6948
  264. package/corpus/templates/design/app/components/design/LayersPanel.tsx +419 -85
  265. package/corpus/templates/design/app/components/design/MotionDock.tsx +1124 -103
  266. package/corpus/templates/design/app/components/design/MultiScreenCanvas.tsx +2610 -1398
  267. package/corpus/templates/design/app/components/design/ReadOnlyDesignBanner.tsx +22 -0
  268. package/corpus/templates/design/app/components/design/bridge/editor-chrome.bridge.ts +2182 -235
  269. package/corpus/templates/design/app/components/design/bridge/motion-preview.bridge.ts +187 -11
  270. package/corpus/templates/design/app/components/design/bridge/shader-fill-preview.bridge.ts +376 -1
  271. package/corpus/templates/design/app/components/design/bridge/shader-runtime.bridge.ts +746 -0
  272. package/corpus/templates/design/app/components/design/canvas-primitive-style.ts +17 -0
  273. package/corpus/templates/design/app/components/design/code-workbench/SideBar.tsx +1 -1
  274. package/corpus/templates/design/app/components/design/code-workbench/explorer/FileTree.tsx +1 -3
  275. package/corpus/templates/design/app/components/design/code-workbench/quickinput/QuickInput.tsx +1 -1
  276. package/corpus/templates/design/app/components/design/edit-panel/appearance-properties.tsx +518 -0
  277. package/corpus/templates/design/app/components/design/edit-panel/code-inspect-helpers.tsx +562 -0
  278. package/corpus/templates/design/app/components/design/edit-panel/component-section.tsx +763 -0
  279. package/corpus/templates/design/app/components/design/edit-panel/document-colors.ts +94 -0
  280. package/corpus/templates/design/app/components/design/edit-panel/effects-properties.tsx +780 -0
  281. package/corpus/templates/design/app/components/design/edit-panel/element-classification.ts +446 -0
  282. package/corpus/templates/design/app/components/design/edit-panel/element-identity.ts +79 -0
  283. package/corpus/templates/design/app/components/design/edit-panel/field-primitives.tsx +315 -0
  284. package/corpus/templates/design/app/components/design/edit-panel/fill-gradient-helpers.ts +344 -0
  285. package/corpus/templates/design/app/components/design/edit-panel/fill-properties.tsx +594 -0
  286. package/corpus/templates/design/app/components/design/edit-panel/frame-presets-panel.tsx +119 -0
  287. package/corpus/templates/design/app/components/design/edit-panel/inspector-controls.tsx +248 -0
  288. package/corpus/templates/design/app/components/design/edit-panel/interaction-state-helpers.ts +45 -0
  289. package/corpus/templates/design/app/components/design/edit-panel/layout-properties.tsx +693 -0
  290. package/corpus/templates/design/app/components/design/edit-panel/panel-primitives.tsx +724 -0
  291. package/corpus/templates/design/app/components/design/edit-panel/position-helpers.ts +207 -0
  292. package/corpus/templates/design/app/components/design/edit-panel/position-layout-properties.tsx +628 -0
  293. package/corpus/templates/design/app/components/design/edit-panel/selection-helpers.ts +91 -0
  294. package/corpus/templates/design/app/components/design/edit-panel/stroke-properties.tsx +649 -0
  295. package/corpus/templates/design/app/components/design/edit-panel/style-change-types.ts +118 -0
  296. package/corpus/templates/design/app/components/design/edit-panel/style-options.ts +88 -0
  297. package/corpus/templates/design/app/components/design/edit-panel/transform-helpers.ts +100 -0
  298. package/corpus/templates/design/app/components/design/edit-panel/typography-helpers.ts +117 -0
  299. package/corpus/templates/design/app/components/design/edit-panel/typography-properties.tsx +501 -0
  300. package/corpus/templates/design/app/components/design/inspector/AutoLayoutMatrix.tsx +91 -40
  301. package/corpus/templates/design/app/components/design/inspector/BreakpointOverrideIndicator.tsx +82 -0
  302. package/corpus/templates/design/app/components/design/inspector/DesignColorPicker.tsx +189 -87
  303. package/corpus/templates/design/app/components/design/inspector/GlslShaderPanel.tsx +1097 -0
  304. package/corpus/templates/design/app/components/design/inspector/GradientEditor.tsx +44 -0
  305. package/corpus/templates/design/app/components/design/inspector/InteractionStatePanel.tsx +258 -0
  306. package/corpus/templates/design/app/components/design/inspector/MotionKeyframeDiamond.tsx +144 -0
  307. package/corpus/templates/design/app/components/design/inspector/ScrubInput.tsx +99 -9
  308. package/corpus/templates/design/app/components/design/inspector/frame-size-presets.ts +116 -0
  309. package/corpus/templates/design/app/components/design/inspector/index.ts +26 -0
  310. package/corpus/templates/design/app/components/design/inspector/scrub-input-utils.ts +29 -0
  311. package/corpus/templates/design/app/components/design/multi-screen/alt-hover-measurement.ts +171 -0
  312. package/corpus/templates/design/app/components/design/multi-screen/board-surface-html.ts +220 -0
  313. package/corpus/templates/design/app/components/design/multi-screen/chrome-transitions.ts +35 -0
  314. package/corpus/templates/design/app/components/design/multi-screen/cross-screen-drop.ts +134 -0
  315. package/corpus/templates/design/app/components/design/multi-screen/culling.ts +185 -0
  316. package/corpus/templates/design/app/components/design/multi-screen/gradient-overlay-geometry.ts +120 -0
  317. package/corpus/templates/design/app/components/design/multi-screen/types.ts +892 -0
  318. package/corpus/templates/design/app/components/design/multi-screen/vector-edit-geometry.ts +21 -0
  319. package/corpus/templates/design/app/components/design/types.ts +15 -0
  320. package/corpus/templates/design/app/components/editor/PromptDialog.tsx +109 -5
  321. package/corpus/templates/design/app/global.css +8 -8
  322. package/corpus/templates/design/app/hooks/useDesignHotkeys.ts +259 -2
  323. package/corpus/templates/design/app/i18n/zh-TW.ts +163 -9
  324. package/corpus/templates/design/app/i18n-breakpoints.ts +205 -0
  325. package/corpus/templates/design/app/i18n-data.ts +1664 -152
  326. package/corpus/templates/design/app/i18n-motion.ts +563 -0
  327. package/corpus/templates/design/app/lib/design-import.ts +73 -0
  328. package/corpus/templates/design/app/pages/Index.tsx +41 -22
  329. package/corpus/templates/design/changelog/2026-06-29-design-inspector-controls-now-match-figmas-softer-dark-chrome.md +1 -1
  330. package/corpus/templates/design/changelog/2026-06-30-design-now-has-a-figma-style-left-rail-for-file-agent-assets.md +1 -1
  331. package/corpus/templates/design/changelog/2026-06-30-design-tools-now-use-a-quieter-figma-style-list-layout.md +1 -1
  332. package/corpus/templates/design/changelog/2026-06-30-multi-select-outlines-now-stay-consistent-across-all-screens.md +1 -1
  333. package/corpus/templates/design/changelog/2026-07-03-canvas-interactions-now-match-figma-rotation-aware-resizing-.md +1 -1
  334. package/corpus/templates/design/changelog/2026-07-03-layers-panel-matches-figma-top-layer-on-top-drag-with-auto-s.md +1 -1
  335. package/corpus/templates/design/changelog/2026-07-05-designs-get-ai-generated-names-from-your-prompt.md +6 -0
  336. package/corpus/templates/design/changelog/2026-07-05-local-code-screens-keep-their-connection-when-duplicated-and.md +6 -0
  337. package/corpus/templates/design/changelog/2026-07-05-press-a-to-draw-screens-on-the-canvas-inside-a-screen-it-dr.md +6 -0
  338. package/corpus/templates/design/changelog/2026-07-06-3d-rotation-and-perspective-controls-on-every-element.md +6 -0
  339. package/corpus/templates/design/changelog/2026-07-06-ai-generated-and-duplicated-screens-now-get-their-editor-sel.md +6 -0
  340. package/corpus/templates/design/changelog/2026-07-06-applying-shaders-and-fills-in-quick-succession-can-no-longer.md +6 -0
  341. package/corpus/templates/design/changelog/2026-07-06-breakpoint-frames-in-the-overview-now-support-click-to-selec.md +6 -0
  342. package/corpus/templates/design/changelog/2026-07-06-breakpoint-segments-in-the-inspector-now-show-a-device-icon-.md +6 -0
  343. package/corpus/templates/design/changelog/2026-07-06-breakpoint-targeting-now-lives-in-one-compact-control-in-the.md +6 -0
  344. package/corpus/templates/design/changelog/2026-07-06-canvas-edits-can-no-longer-be-overwritten-by-stale-collabora.md +6 -0
  345. package/corpus/templates/design/changelog/2026-07-06-canvas-edits-inside-screens-save-reliably-again.md +6 -0
  346. package/corpus/templates/design/changelog/2026-07-06-cleaner-inspector-removed-the-ask-ai-box-from-the-design-tab.md +6 -0
  347. package/corpus/templates/design/changelog/2026-07-06-clicking-empty-canvas-space-now-deselects-an-element-inside-.md +6 -0
  348. package/corpus/templates/design/changelog/2026-07-06-dragging-an-element-onto-a-rectangle-now-nests-it-inside-wit.md +6 -0
  349. package/corpus/templates/design/changelog/2026-07-06-dragging-screens-and-objects-on-the-canvas-is-now-much-smoot.md +6 -0
  350. package/corpus/templates/design/changelog/2026-07-06-drawing-a-shape-or-text-on-the-canvas-no-longer-flashes-away.md +6 -0
  351. package/corpus/templates/design/changelog/2026-07-06-dropping-an-element-between-two-others-inside-a-screen-now-s.md +6 -0
  352. package/corpus/templates/design/changelog/2026-07-06-duplicating-a-screen-now-places-the-copy-exactly-where-you-d.md +6 -0
  353. package/corpus/templates/design/changelog/2026-07-06-edit-gradients-directly-on-elements-inside-screens-scale-str.md +6 -0
  354. package/corpus/templates/design/changelog/2026-07-06-edits-from-collaborators-and-the-agent-now-update-the-canvas.md +6 -0
  355. package/corpus/templates/design/changelog/2026-07-06-fixed-a-bug-where-most-style-position-and-text-edits-briefly.md +6 -0
  356. package/corpus/templates/design/changelog/2026-07-06-fixed-a-confusing-raw-error-message-when-a-file-upload-fails.md +6 -0
  357. package/corpus/templates/design/changelog/2026-07-06-fixed-a-rare-case-where-an-edit-could-be-silently-overwritte.md +6 -0
  358. package/corpus/templates/design/changelog/2026-07-06-fixed-inserted-assets-sometimes-disappearing-reappearing-or-.md +6 -0
  359. package/corpus/templates/design/changelog/2026-07-06-fixed-inspector-value-scrubbing-producing-erratic-numbers-an.md +6 -0
  360. package/corpus/templates/design/changelog/2026-07-06-fixed-padding-gap-and-min-max-size-scrubbing-not-updating-th.md +6 -0
  361. package/corpus/templates/design/changelog/2026-07-06-fixed-text-stroke-color-turning-black-and-glyphs-disappearin.md +6 -0
  362. package/corpus/templates/design/changelog/2026-07-06-fixed-the-collapsed-effects-and-stroke-inspector-sections-sh.md +6 -0
  363. package/corpus/templates/design/changelog/2026-07-06-fixed-the-new-design-dialog-closing-unexpectedly-when-using-.md +6 -0
  364. package/corpus/templates/design/changelog/2026-07-06-fixed-the-typography-section-missing-when-selecting-text-nes.md +6 -0
  365. package/corpus/templates/design/changelog/2026-07-06-full-view-no-longer-flashes-back-to-the-overview-on-entry-no.md +6 -0
  366. package/corpus/templates/design/changelog/2026-07-06-keyframe-animation-timeline-per-property-keyframes-easing-cu.md +6 -0
  367. package/corpus/templates/design/changelog/2026-07-06-moving-restyling-and-scrubbing-values-on-elements-in-ai-gene.md +6 -0
  368. package/corpus/templates/design/changelog/2026-07-06-padding-and-corner-radius-value-scrubbing-now-snaps-to-whole.md +6 -0
  369. package/corpus/templates/design/changelog/2026-07-06-padding-handles-now-only-resize-on-the-handle-line-itself-sh.md +6 -0
  370. package/corpus/templates/design/changelog/2026-07-06-preview-and-edit-hover-focus-and-pressed-states-with-real-cs.md +6 -0
  371. package/corpus/templates/design/changelog/2026-07-06-promoting-an-element-to-a-component-now-works-correctly-for-.md +6 -0
  372. package/corpus/templates/design/changelog/2026-07-06-reduced-url-history-churn-and-selection-overlay-flicker-whil.md +6 -0
  373. package/corpus/templates/design/changelog/2026-07-06-removed-the-decorative-dot-before-screen-names-in-the-overvi.md +6 -0
  374. package/corpus/templates/design/changelog/2026-07-06-responsive-breakpoints-edit-at-any-width-with-cascading-over.md +6 -0
  375. package/corpus/templates/design/changelog/2026-07-06-screen-labels-no-longer-turn-blue-when-you-hover-inside-the-.md +6 -0
  376. package/corpus/templates/design/changelog/2026-07-06-scrolling-a-screen-with-an-element-selected-stays-smooth-on-.md +6 -0
  377. package/corpus/templates/design/changelog/2026-07-06-selecting-multiple-elements-and-dragging-now-moves-the-whole.md +6 -0
  378. package/corpus/templates/design/changelog/2026-07-06-selection-borders-handles-and-value-readouts-now-stay-the-sa.md +6 -0
  379. package/corpus/templates/design/changelog/2026-07-06-selection-handles-and-editing-chrome-now-stay-a-constant-siz.md +6 -0
  380. package/corpus/templates/design/changelog/2026-07-06-shader-fills-and-effects-ai-authored-or-preset-glsl-shaders-.md +6 -0
  381. package/corpus/templates/design/changelog/2026-07-06-text-drawn-on-the-canvas-now-defaults-to-white-and-inter-in-.md +6 -0
  382. package/corpus/templates/design/changelog/2026-07-06-text-dropped-into-a-shape-now-stays-readable-instead-of-disa.md +6 -0
  383. package/corpus/templates/design/changelog/2026-07-06-the-add-tweak-controls-prompt-no-longer-jumps-to-the-corner-.md +6 -0
  384. package/corpus/templates/design/changelog/2026-07-06-the-padding-value-readout-now-stays-visible-while-you-hover-.md +6 -0
  385. package/corpus/templates/design/changelog/2026-07-06-the-selected-element-attachment-now-clears-from-the-chat-com.md +6 -0
  386. package/corpus/templates/design/changelog/2026-07-06-the-zoom-menu-is-more-compact-with-tight-rows-and-right-alig.md +6 -0
  387. package/corpus/templates/design/changelog/2026-07-06-undo-and-redo-no-longer-flash-the-screen-changes-now-apply-i.md +6 -0
  388. package/corpus/templates/design/changelog/2026-07-06-zoom-presets-like-zoom-to-50-now-stay-on-the-focused-screen-.md +6 -0
  389. package/corpus/templates/design/server/lib/import-design-files.ts +11 -2
  390. package/corpus/templates/design/server/source-workspace.ts +139 -59
  391. package/corpus/templates/design/shared/board-file.ts +11 -2
  392. package/corpus/templates/design/shared/breakpoint-media.ts +543 -0
  393. package/corpus/templates/design/shared/canvas-math.ts +354 -35
  394. package/corpus/templates/design/shared/code-layer.ts +277 -8
  395. package/corpus/templates/design/shared/design-state.ts +11 -4
  396. package/corpus/templates/design/shared/interaction-states.ts +548 -0
  397. package/corpus/templates/design/shared/motion-compiler.ts +186 -23
  398. package/corpus/templates/design/shared/motion-easing.ts +294 -0
  399. package/corpus/templates/design/shared/motion-timeline.ts +400 -34
  400. package/corpus/templates/design/shared/prompt-title.ts +95 -0
  401. package/corpus/templates/design/shared/responsive-classes.ts +448 -10
  402. package/corpus/templates/design/shared/screen-annotation.ts +46 -0
  403. package/corpus/templates/design/shared/shader-fills.ts +1009 -0
  404. package/corpus/templates/design/shared/shader-presets.ts +852 -4
  405. package/corpus/templates/slides/app/components/editor/EditorToolbar.tsx +15 -2
  406. package/corpus/templates/slides/app/components/editor/ImportButton.tsx +10 -1
  407. package/corpus/templates/slides/app/lib/upload-response.ts +71 -0
  408. package/corpus/templates/slides/app/pages/DeckEditor.tsx +2 -2
  409. package/dist/agent/engine/ai-sdk-engine.d.ts.map +1 -1
  410. package/dist/agent/engine/ai-sdk-engine.js +15 -1
  411. package/dist/agent/engine/ai-sdk-engine.js.map +1 -1
  412. package/dist/agent/engine/anthropic-engine.d.ts.map +1 -1
  413. package/dist/agent/engine/anthropic-engine.js +20 -1
  414. package/dist/agent/engine/anthropic-engine.js.map +1 -1
  415. package/dist/agent/engine/registry.d.ts.map +1 -1
  416. package/dist/agent/engine/registry.js +22 -14
  417. package/dist/agent/engine/registry.js.map +1 -1
  418. package/dist/agent/production-agent.d.ts.map +1 -1
  419. package/dist/agent/production-agent.js +27 -7
  420. package/dist/agent/production-agent.js.map +1 -1
  421. package/dist/client/AgentPanel.js +1 -1
  422. package/dist/client/AgentPanel.js.map +1 -1
  423. package/dist/client/command-navigation/index.d.ts +4 -0
  424. package/dist/client/command-navigation/index.d.ts.map +1 -0
  425. package/dist/client/command-navigation/index.js +4 -0
  426. package/dist/client/command-navigation/index.js.map +1 -0
  427. package/dist/client/comments-review/index.d.ts +2 -0
  428. package/dist/client/comments-review/index.d.ts.map +1 -0
  429. package/dist/client/comments-review/index.js +2 -0
  430. package/dist/client/comments-review/index.js.map +1 -0
  431. package/dist/client/history/VersionHistoryPanel.d.ts +18 -0
  432. package/dist/client/history/VersionHistoryPanel.d.ts.map +1 -0
  433. package/dist/client/history/VersionHistoryPanel.js +24 -0
  434. package/dist/client/history/VersionHistoryPanel.js.map +1 -0
  435. package/dist/client/history/index.d.ts +3 -0
  436. package/dist/client/history/index.d.ts.map +1 -0
  437. package/dist/client/history/index.js +3 -0
  438. package/dist/client/history/index.js.map +1 -0
  439. package/dist/client/history/use-history.d.ts +46 -0
  440. package/dist/client/history/use-history.d.ts.map +1 -0
  441. package/dist/client/history/use-history.js +18 -0
  442. package/dist/client/history/use-history.js.map +1 -0
  443. package/dist/client/index.d.ts +6 -4
  444. package/dist/client/index.d.ts.map +1 -1
  445. package/dist/client/index.js +6 -4
  446. package/dist/client/index.js.map +1 -1
  447. package/dist/client/org/OrgSwitcher.js +5 -5
  448. package/dist/client/org/OrgSwitcher.js.map +1 -1
  449. package/dist/client/org/RequireActiveOrg.js +2 -2
  450. package/dist/client/org/RequireActiveOrg.js.map +1 -1
  451. package/dist/client/org/TeamPage.js +3 -3
  452. package/dist/client/org/TeamPage.js.map +1 -1
  453. package/dist/client/org/hooks.d.ts +12 -1
  454. package/dist/client/org/hooks.d.ts.map +1 -1
  455. package/dist/client/org/hooks.js +15 -0
  456. package/dist/client/org/hooks.js.map +1 -1
  457. package/dist/client/org/index.d.ts +4 -2
  458. package/dist/client/org/index.d.ts.map +1 -1
  459. package/dist/client/org/index.js +3 -1
  460. package/dist/client/org/index.js.map +1 -1
  461. package/dist/client/org-team/index.d.ts +2 -0
  462. package/dist/client/org-team/index.d.ts.map +1 -0
  463. package/dist/client/org-team/index.js +2 -0
  464. package/dist/client/org-team/index.js.map +1 -0
  465. package/dist/client/review/ReviewStatusBadge.d.ts +7 -0
  466. package/dist/client/review/ReviewStatusBadge.d.ts.map +1 -0
  467. package/dist/client/review/ReviewStatusBadge.js +19 -0
  468. package/dist/client/review/ReviewStatusBadge.js.map +1 -0
  469. package/dist/client/review/ReviewThreadPanel.d.ts +20 -0
  470. package/dist/client/review/ReviewThreadPanel.d.ts.map +1 -0
  471. package/dist/client/review/ReviewThreadPanel.js +84 -0
  472. package/dist/client/review/ReviewThreadPanel.js.map +1 -0
  473. package/dist/client/review/index.d.ts +4 -0
  474. package/dist/client/review/index.d.ts.map +1 -0
  475. package/dist/client/review/index.js +4 -0
  476. package/dist/client/review/index.js.map +1 -0
  477. package/dist/client/review/use-review.d.ts +68 -0
  478. package/dist/client/review/use-review.d.ts.map +1 -0
  479. package/dist/client/review/use-review.js +22 -0
  480. package/dist/client/review/use-review.js.map +1 -0
  481. package/dist/client/rich-markdown-editor/useCollabReconcile.d.ts.map +1 -1
  482. package/dist/client/rich-markdown-editor/useCollabReconcile.js +11 -6
  483. package/dist/client/rich-markdown-editor/useCollabReconcile.js.map +1 -1
  484. package/dist/client/settings/index.d.ts +1 -1
  485. package/dist/client/settings/index.d.ts.map +1 -1
  486. package/dist/client/settings/index.js +1 -1
  487. package/dist/client/settings/index.js.map +1 -1
  488. package/dist/client/setup-connections/BuilderConnectCard.d.ts +9 -0
  489. package/dist/client/setup-connections/BuilderConnectCard.d.ts.map +1 -0
  490. package/dist/client/setup-connections/BuilderConnectCard.js +25 -0
  491. package/dist/client/setup-connections/BuilderConnectCard.js.map +1 -0
  492. package/dist/client/setup-connections/ProviderReadinessBadge.d.ts +8 -0
  493. package/dist/client/setup-connections/ProviderReadinessBadge.d.ts.map +1 -0
  494. package/dist/client/setup-connections/ProviderReadinessBadge.js +32 -0
  495. package/dist/client/setup-connections/ProviderReadinessBadge.js.map +1 -0
  496. package/dist/client/setup-connections/SetupConnectionsPage.d.ts +17 -0
  497. package/dist/client/setup-connections/SetupConnectionsPage.d.ts.map +1 -0
  498. package/dist/client/setup-connections/SetupConnectionsPage.js +10 -0
  499. package/dist/client/setup-connections/SetupConnectionsPage.js.map +1 -0
  500. package/dist/client/setup-connections/index.d.ts +7 -0
  501. package/dist/client/setup-connections/index.d.ts.map +1 -0
  502. package/dist/client/setup-connections/index.js +7 -0
  503. package/dist/client/setup-connections/index.js.map +1 -0
  504. package/dist/client/sharing/ShareButton.d.ts +4 -4
  505. package/dist/client/sharing/ShareButton.d.ts.map +1 -1
  506. package/dist/client/sharing/ShareButton.js +13 -7
  507. package/dist/client/sharing/ShareButton.js.map +1 -1
  508. package/dist/client/sharing/ShareDialog.js +3 -3
  509. package/dist/client/sharing/ShareDialog.js.map +1 -1
  510. package/dist/client/use-action.d.ts +3 -0
  511. package/dist/client/use-action.d.ts.map +1 -1
  512. package/dist/client/use-action.js +34 -3
  513. package/dist/client/use-action.js.map +1 -1
  514. package/dist/client/use-db-sync.d.ts +4 -0
  515. package/dist/client/use-db-sync.d.ts.map +1 -1
  516. package/dist/client/use-db-sync.js +37 -18
  517. package/dist/client/use-db-sync.js.map +1 -1
  518. package/dist/collab/routes.d.ts +1 -1
  519. package/dist/command-navigation/actions.d.ts +25 -0
  520. package/dist/command-navigation/actions.d.ts.map +1 -0
  521. package/dist/command-navigation/actions.js +64 -0
  522. package/dist/command-navigation/actions.js.map +1 -0
  523. package/dist/command-navigation/index.d.ts +4 -0
  524. package/dist/command-navigation/index.d.ts.map +1 -0
  525. package/dist/command-navigation/index.js +4 -0
  526. package/dist/command-navigation/index.js.map +1 -0
  527. package/dist/comments-review/index.d.ts +2 -0
  528. package/dist/comments-review/index.d.ts.map +1 -0
  529. package/dist/comments-review/index.js +2 -0
  530. package/dist/comments-review/index.js.map +1 -0
  531. package/dist/db/create-get-db.d.ts +25 -0
  532. package/dist/db/create-get-db.d.ts.map +1 -1
  533. package/dist/db/create-get-db.js +25 -2
  534. package/dist/db/create-get-db.js.map +1 -1
  535. package/dist/file-upload/builder.d.ts.map +1 -1
  536. package/dist/file-upload/builder.js +18 -2
  537. package/dist/file-upload/builder.js.map +1 -1
  538. package/dist/file-upload/types.d.ts +3 -0
  539. package/dist/file-upload/types.d.ts.map +1 -1
  540. package/dist/file-upload/types.js.map +1 -1
  541. package/dist/history/actions/create-resource-version.d.ts +10 -0
  542. package/dist/history/actions/create-resource-version.d.ts.map +1 -0
  543. package/dist/history/actions/create-resource-version.js +65 -0
  544. package/dist/history/actions/create-resource-version.js.map +1 -0
  545. package/dist/history/actions/get-resource-version.d.ts +10 -0
  546. package/dist/history/actions/get-resource-version.d.ts.map +1 -0
  547. package/dist/history/actions/get-resource-version.js +38 -0
  548. package/dist/history/actions/get-resource-version.js.map +1 -0
  549. package/dist/history/actions/list-resource-history.d.ts +10 -0
  550. package/dist/history/actions/list-resource-history.d.ts.map +1 -0
  551. package/dist/history/actions/list-resource-history.js +45 -0
  552. package/dist/history/actions/list-resource-history.js.map +1 -0
  553. package/dist/history/actions/list-resource-versions.d.ts +10 -0
  554. package/dist/history/actions/list-resource-versions.d.ts.map +1 -0
  555. package/dist/history/actions/list-resource-versions.js +35 -0
  556. package/dist/history/actions/list-resource-versions.js.map +1 -0
  557. package/dist/history/actions/restore-resource-version.d.ts +11 -0
  558. package/dist/history/actions/restore-resource-version.d.ts.map +1 -0
  559. package/dist/history/actions/restore-resource-version.js +59 -0
  560. package/dist/history/actions/restore-resource-version.js.map +1 -0
  561. package/dist/history/index.d.ts +4 -0
  562. package/dist/history/index.d.ts.map +1 -0
  563. package/dist/history/index.js +3 -0
  564. package/dist/history/index.js.map +1 -0
  565. package/dist/history/registry.d.ts +10 -0
  566. package/dist/history/registry.d.ts.map +1 -0
  567. package/dist/history/registry.js +61 -0
  568. package/dist/history/registry.js.map +1 -0
  569. package/dist/history/store.d.ts +34 -0
  570. package/dist/history/store.d.ts.map +1 -0
  571. package/dist/history/store.js +265 -0
  572. package/dist/history/store.js.map +1 -0
  573. package/dist/history/types.d.ts +55 -0
  574. package/dist/history/types.d.ts.map +1 -0
  575. package/dist/history/types.js +2 -0
  576. package/dist/history/types.js.map +1 -0
  577. package/dist/index.d.ts +6 -0
  578. package/dist/index.d.ts.map +1 -1
  579. package/dist/index.js +6 -0
  580. package/dist/index.js.map +1 -1
  581. package/dist/navigation/index.d.ts +53 -0
  582. package/dist/navigation/index.d.ts.map +1 -0
  583. package/dist/navigation/index.js +105 -0
  584. package/dist/navigation/index.js.map +1 -0
  585. package/dist/observability/routes.d.ts +3 -3
  586. package/dist/org/index.d.ts +1 -0
  587. package/dist/org/index.d.ts.map +1 -1
  588. package/dist/org/index.js +1 -0
  589. package/dist/org/index.js.map +1 -1
  590. package/dist/org/permissions.d.ts +7 -0
  591. package/dist/org/permissions.d.ts.map +1 -0
  592. package/dist/org/permissions.js +21 -0
  593. package/dist/org/permissions.js.map +1 -0
  594. package/dist/org-team/index.d.ts +2 -0
  595. package/dist/org-team/index.d.ts.map +1 -0
  596. package/dist/org-team/index.js +2 -0
  597. package/dist/org-team/index.js.map +1 -0
  598. package/dist/private-blob/registry.d.ts.map +1 -1
  599. package/dist/private-blob/registry.js +1 -0
  600. package/dist/private-blob/registry.js.map +1 -1
  601. package/dist/resources/handlers.d.ts +2 -2
  602. package/dist/review/actions/consume-review-feedback.d.ts +9 -0
  603. package/dist/review/actions/consume-review-feedback.d.ts.map +1 -0
  604. package/dist/review/actions/consume-review-feedback.js +29 -0
  605. package/dist/review/actions/consume-review-feedback.js.map +1 -0
  606. package/dist/review/actions/create-review-comment.d.ts +18 -0
  607. package/dist/review/actions/create-review-comment.d.ts.map +1 -0
  608. package/dist/review/actions/create-review-comment.js +81 -0
  609. package/dist/review/actions/create-review-comment.js.map +1 -0
  610. package/dist/review/actions/delete-review-comment.d.ts +10 -0
  611. package/dist/review/actions/delete-review-comment.d.ts.map +1 -0
  612. package/dist/review/actions/delete-review-comment.js +45 -0
  613. package/dist/review/actions/delete-review-comment.js.map +1 -0
  614. package/dist/review/actions/get-review-feedback.d.ts +10 -0
  615. package/dist/review/actions/get-review-feedback.d.ts.map +1 -0
  616. package/dist/review/actions/get-review-feedback.js +45 -0
  617. package/dist/review/actions/get-review-feedback.js.map +1 -0
  618. package/dist/review/actions/list-review-comments.d.ts +13 -0
  619. package/dist/review/actions/list-review-comments.d.ts.map +1 -0
  620. package/dist/review/actions/list-review-comments.js +44 -0
  621. package/dist/review/actions/list-review-comments.js.map +1 -0
  622. package/dist/review/actions/reply-review-comment.d.ts +16 -0
  623. package/dist/review/actions/reply-review-comment.d.ts.map +1 -0
  624. package/dist/review/actions/reply-review-comment.js +84 -0
  625. package/dist/review/actions/reply-review-comment.js.map +1 -0
  626. package/dist/review/actions/resolve-review-thread.d.ts +11 -0
  627. package/dist/review/actions/resolve-review-thread.d.ts.map +1 -0
  628. package/dist/review/actions/resolve-review-thread.js +46 -0
  629. package/dist/review/actions/resolve-review-thread.js.map +1 -0
  630. package/dist/review/actions/set-review-status.d.ts +9 -0
  631. package/dist/review/actions/set-review-status.d.ts.map +1 -0
  632. package/dist/review/actions/set-review-status.js +43 -0
  633. package/dist/review/actions/set-review-status.js.map +1 -0
  634. package/dist/review/index.d.ts +5 -0
  635. package/dist/review/index.d.ts.map +1 -0
  636. package/dist/review/index.js +4 -0
  637. package/dist/review/index.js.map +1 -0
  638. package/dist/review/mentions.d.ts +4 -0
  639. package/dist/review/mentions.d.ts.map +1 -0
  640. package/dist/review/mentions.js +39 -0
  641. package/dist/review/mentions.js.map +1 -0
  642. package/dist/review/registry.d.ts +10 -0
  643. package/dist/review/registry.d.ts.map +1 -0
  644. package/dist/review/registry.js +61 -0
  645. package/dist/review/registry.js.map +1 -0
  646. package/dist/review/store.d.ts +63 -0
  647. package/dist/review/store.d.ts.map +1 -0
  648. package/dist/review/store.js +558 -0
  649. package/dist/review/store.js.map +1 -0
  650. package/dist/review/types.d.ts +77 -0
  651. package/dist/review/types.d.ts.map +1 -0
  652. package/dist/review/types.js +2 -0
  653. package/dist/review/types.js.map +1 -0
  654. package/dist/secrets/routes.d.ts +9 -9
  655. package/dist/server/action-discovery.d.ts.map +1 -1
  656. package/dist/server/action-discovery.js +54 -0
  657. package/dist/server/action-discovery.js.map +1 -1
  658. package/dist/server/agent-engine-api-key-route.d.ts +1 -1
  659. package/dist/server/agent-engine-api-key-route.d.ts.map +1 -1
  660. package/dist/server/agent-engine-api-key-route.js +5 -0
  661. package/dist/server/agent-engine-api-key-route.js.map +1 -1
  662. package/dist/server/credential-provider.d.ts +26 -0
  663. package/dist/server/credential-provider.d.ts.map +1 -1
  664. package/dist/server/credential-provider.js +82 -0
  665. package/dist/server/credential-provider.js.map +1 -1
  666. package/dist/server/framework-request-handler.d.ts.map +1 -1
  667. package/dist/server/framework-request-handler.js +37 -1
  668. package/dist/server/framework-request-handler.js.map +1 -1
  669. package/dist/setup-connections/index.d.ts +6 -0
  670. package/dist/setup-connections/index.d.ts.map +1 -0
  671. package/dist/setup-connections/index.js +6 -0
  672. package/dist/setup-connections/index.js.map +1 -0
  673. package/dist/setup-connections/onboarding.d.ts +14 -0
  674. package/dist/setup-connections/onboarding.d.ts.map +1 -0
  675. package/dist/setup-connections/onboarding.js +23 -0
  676. package/dist/setup-connections/onboarding.js.map +1 -0
  677. package/dist/transcription/builder-transcription.d.ts +1 -0
  678. package/dist/transcription/builder-transcription.d.ts.map +1 -1
  679. package/dist/transcription/builder-transcription.js +5 -2
  680. package/dist/transcription/builder-transcription.js.map +1 -1
  681. package/dist/vite/action-types-plugin.d.ts.map +1 -1
  682. package/dist/vite/action-types-plugin.js +52 -0
  683. package/dist/vite/action-types-plugin.js.map +1 -1
  684. package/docs/content/agent-native-toolkit.mdx +87 -80
  685. package/docs/content/locales/ar-SA/agent-native-toolkit.mdx +89 -80
  686. package/docs/content/locales/de-DE/agent-native-toolkit.mdx +89 -80
  687. package/docs/content/locales/es-ES/agent-native-toolkit.mdx +89 -80
  688. package/docs/content/locales/fr-FR/agent-native-toolkit.mdx +89 -80
  689. package/docs/content/locales/hi-IN/agent-native-toolkit.mdx +89 -80
  690. package/docs/content/locales/ja-JP/agent-native-toolkit.mdx +89 -80
  691. package/docs/content/locales/ko-KR/agent-native-toolkit.mdx +89 -80
  692. package/docs/content/locales/pt-BR/agent-native-toolkit.mdx +89 -80
  693. package/docs/content/locales/zh-CN/agent-native-toolkit.mdx +89 -80
  694. package/docs/content/locales/zh-TW/agent-native-toolkit.mdx +89 -80
  695. package/docs/content/toolkit-agent-ux.mdx +43 -0
  696. package/docs/content/toolkit-app-adapters.mdx +9 -0
  697. package/docs/content/toolkit-collaboration-ui.mdx +12 -0
  698. package/docs/content/toolkit-collaboration.mdx +74 -0
  699. package/docs/content/toolkit-command-navigation.mdx +106 -0
  700. package/docs/content/toolkit-comments-review.mdx +98 -0
  701. package/docs/content/toolkit-history.mdx +95 -0
  702. package/docs/content/toolkit-observability.mdx +41 -0
  703. package/docs/content/toolkit-org-team.mdx +80 -0
  704. package/docs/content/toolkit-resources.mdx +57 -0
  705. package/docs/content/toolkit-settings.mdx +65 -0
  706. package/docs/content/toolkit-setup-connections.mdx +109 -0
  707. package/docs/content/toolkit-sharing-ui.mdx +18 -6
  708. package/docs/content/toolkit-sharing.mdx +81 -0
  709. package/docs/content/toolkit-shell-hooks.mdx +9 -0
  710. package/docs/content/toolkit-ui.mdx +9 -0
  711. package/package.json +36 -2
  712. package/corpus/templates/design/app/components/design/inspector/InspectorAiActions.tsx +0 -153
  713. package/corpus/templates/design/app/hooks/useAgentEditRequest.ts +0 -133
  714. package/corpus/templates/design/app/pages/DesignEditor.tsx +0 -22924
@@ -1,8 +1,8 @@
1
1
  import {
2
+ AgentToggleButton,
2
3
  appApiPath,
3
4
  PromptComposer,
4
5
  useActionMutation,
5
- useActionQuery,
6
6
  useSendToAgentChat,
7
7
  useT,
8
8
  } from "@agent-native/core/client";
@@ -10,6 +10,7 @@ import { SESSION_REPLAY_AGENT_ACCESS_PARAM } from "@shared/session-replay-agent-
10
10
  import {
11
11
  IconArrowLeft,
12
12
  IconCheck,
13
+ IconChevronRight,
13
14
  IconCopy,
14
15
  IconExclamationCircle,
15
16
  IconKeyboard,
@@ -24,7 +25,6 @@ import {
24
25
  IconTerminal2,
25
26
  IconTimelineEvent,
26
27
  } from "@tabler/icons-react";
27
- import { useQuery } from "@tanstack/react-query";
28
28
  import {
29
29
  type ReactNode,
30
30
  useCallback,
@@ -113,6 +113,11 @@ type SessionReplayPlaybackResponse = {
113
113
  eventCount: number;
114
114
  truncated: boolean;
115
115
  unavailableChunks: number;
116
+ loadedChunks: number;
117
+ totalChunks: number;
118
+ loadedBytes: number;
119
+ totalBytes: number;
120
+ isComplete: boolean;
116
121
  };
117
122
 
118
123
  type AnyReplayEvent = Record<string, any>;
@@ -124,9 +129,11 @@ type ReplayMarker = {
124
129
  id: string;
125
130
  offsetMs: number;
126
131
  timestamp: number;
127
- kind: "navigation" | "input" | "click" | "custom";
132
+ kind: "navigation" | "input" | "click" | "console" | "custom";
128
133
  label: string;
129
134
  detail?: string;
135
+ severity?: "info" | "warn" | "error";
136
+ fields?: Array<{ label: string; value: string }>;
130
137
  };
131
138
 
132
139
  type SkipRange = {
@@ -148,6 +155,17 @@ const MIN_IDLE_SKIP_MS = 8000;
148
155
  const IDLE_EDGE_PAD_MS = 1200;
149
156
  const REPLAY_CHUNK_FETCH_CONCURRENCY = 6;
150
157
  const REPLAY_CHUNK_UNAVAILABLE_MESSAGE = "Session replay chunk is unavailable";
158
+ const DEFAULT_DEVTOOLS_HEIGHT = 280;
159
+ const SCRUBBER_MARKER_LIMIT = 500;
160
+ const SESSION_REPLAY_CONSOLE_EVENT_TAG = "agent-native.console";
161
+ const SESSION_REPLAY_NETWORK_EVENT_TAG = "agent-native.network";
162
+
163
+ const EMPTY_DIAGNOSTICS: ReturnType<typeof extractReplayDiagnostics> = {
164
+ console: [],
165
+ network: [],
166
+ consoleErrorCount: 0,
167
+ networkFailedCount: 0,
168
+ };
151
169
 
152
170
  const RRWEB_EVENT_TYPE = {
153
171
  FullSnapshot: 2,
@@ -211,10 +229,13 @@ export default function SessionDetailPage() {
211
229
  ) : null}
212
230
  </div>
213
231
  {recording ? (
214
- <div className="flex shrink-0 items-center gap-2">
215
- <CopySessionForAgentButton recordingId={recording.id} />
216
- <AskSessionPopover recording={recording} />
217
- </div>
232
+ <TooltipProvider>
233
+ <div className="flex shrink-0 items-center gap-2">
234
+ <CopySessionForAgentButton recordingId={recording.id} />
235
+ <AskSessionPopover recording={recording} />
236
+ <AgentToggleButton />
237
+ </div>
238
+ </TooltipProvider>
218
239
  ) : null}
219
240
  </div>
220
241
 
@@ -257,19 +278,24 @@ function CopySessionForAgentButton({ recordingId }: { recordingId: string }) {
257
278
  }
258
279
 
259
280
  return (
260
- <Button
261
- type="button"
262
- variant="outline"
263
- onClick={() => void handleCopy()}
264
- disabled={createLink.isPending}
265
- >
266
- {copied ? (
267
- <IconCheck className="h-4 w-4" />
268
- ) : (
269
- <IconCopy className="h-4 w-4" />
270
- )}
271
- {copied ? t("sessions.copiedForAgent") : t("sessions.copyForAgent")}
272
- </Button>
281
+ <Tooltip>
282
+ <TooltipTrigger asChild>
283
+ <Button
284
+ type="button"
285
+ variant="outline"
286
+ onClick={() => void handleCopy()}
287
+ disabled={createLink.isPending}
288
+ >
289
+ {copied ? (
290
+ <IconCheck className="h-4 w-4" />
291
+ ) : (
292
+ <IconCopy className="h-4 w-4" />
293
+ )}
294
+ {copied ? t("sessions.copiedForAgent") : t("sessions.copyForAgent")}
295
+ </Button>
296
+ </TooltipTrigger>
297
+ <TooltipContent>{t("sessions.copyForAgentTooltip")}</TooltipContent>
298
+ </Tooltip>
273
299
  );
274
300
  }
275
301
 
@@ -298,12 +324,17 @@ function AskSessionPopover({
298
324
 
299
325
  return (
300
326
  <Popover open={open} onOpenChange={setOpen}>
301
- <PopoverTrigger asChild>
302
- <Button type="button" variant="outline" disabled={isGenerating}>
303
- <IconMessageCircle className="h-4 w-4" />
304
- {t("sessions.askAgent")}
305
- </Button>
306
- </PopoverTrigger>
327
+ <Tooltip>
328
+ <TooltipTrigger asChild>
329
+ <PopoverTrigger asChild>
330
+ <Button type="button" variant="outline" disabled={isGenerating}>
331
+ <IconMessageCircle className="h-4 w-4" />
332
+ {t("sessions.askAgent")}
333
+ </Button>
334
+ </PopoverTrigger>
335
+ </TooltipTrigger>
336
+ <TooltipContent>{t("sessions.askAgentTooltip")}</TooltipContent>
337
+ </Tooltip>
307
338
  <PopoverContent
308
339
  className="w-[calc(100vw-2rem)] p-3 sm:w-[460px]"
309
340
  align="end"
@@ -398,6 +429,7 @@ function ReplayPlayer({
398
429
  const [speed, setSpeed] = useState(DEFAULT_SPEED);
399
430
  const [skipInactive, setSkipInactive] = useState(true);
400
431
  const [devToolsOpen, setDevToolsOpen] = useState(false);
432
+ const [devToolsHeight, setDevToolsHeight] = useState(DEFAULT_DEVTOOLS_HEIGHT);
401
433
  const [streamedDims, setStreamedDims] = useState<{
402
434
  width: number;
403
435
  height: number;
@@ -414,14 +446,25 @@ function ReplayPlayer({
414
446
  const skipInactiveRef = useLiveRef(skipInactive);
415
447
  const currentTimeRef = useLiveRef(currentTime);
416
448
  const playingRef = useLiveRef(playing);
449
+ const speedRef = useLiveRef(speed);
417
450
 
418
451
  const currentUrl = useMemo(
419
452
  () => currentUrlAt(events, currentTime),
420
453
  [events, currentTime],
421
454
  );
422
- const diagnostics = useMemo(() => extractReplayDiagnostics(events), [events]);
423
- const devToolsIssueCount =
424
- diagnostics.consoleErrorCount + diagnostics.networkFailedCount;
455
+ const diagnostics = useMemo(
456
+ () => (devToolsOpen ? extractReplayDiagnostics(events) : EMPTY_DIAGNOSTICS),
457
+ [devToolsOpen, events],
458
+ );
459
+ const devToolsIssueCount = devToolsOpen
460
+ ? diagnostics.consoleErrorCount + diagnostics.networkFailedCount
461
+ : response.recording.errorCount;
462
+ const loadingPercent =
463
+ response.totalChunks > 0
464
+ ? clamp(response.loadedChunks / response.totalChunks, 0, 1)
465
+ : response.isComplete
466
+ ? 1
467
+ : 0;
425
468
 
426
469
  useEffect(() => {
427
470
  const el = stageAreaRef.current;
@@ -479,6 +522,13 @@ function ReplayPlayer({
479
522
  let localReplayer: any = null;
480
523
 
481
524
  async function loadReplay() {
525
+ const hasPlayableEvents = hasPlayableReplayEvents(events);
526
+ if (!hasPlayableEvents && !response.isComplete) {
527
+ setStatus("loading");
528
+ setError(null);
529
+ setPlaying(false);
530
+ return;
531
+ }
482
532
  if (events.length < 2) {
483
533
  throw new Error(t("sessions.noReplayEvents"));
484
534
  }
@@ -497,7 +547,7 @@ function ReplayPlayer({
497
547
  setStreamedDims(initialDims);
498
548
  localReplayer = new Replayer(events as any[], {
499
549
  root: stageRootRef.current,
500
- speed: DEFAULT_SPEED,
550
+ speed: speedRef.current,
501
551
  skipInactive: false,
502
552
  showWarning: false,
503
553
  showDebug: false,
@@ -518,6 +568,11 @@ function ReplayPlayer({
518
568
  const meta = localReplayer.getMetaData?.();
519
569
  const total = Number(meta?.totalTime ?? replayDuration(events));
520
570
  setTotalTime(Number.isFinite(total) ? total : 0);
571
+ const startAt = clamp(
572
+ currentTimeRef.current,
573
+ 0,
574
+ Number.isFinite(total) ? total : 0,
575
+ );
521
576
  applyReplayFrameDimensions(localReplayer, initialDims);
522
577
  localReplayer.on?.("finish", () => {
523
578
  setPlaying(false);
@@ -540,15 +595,15 @@ function ReplayPlayer({
540
595
  );
541
596
  revealReplayFrame(localReplayer);
542
597
  });
543
- updateTime(0);
598
+ updateTime(startAt);
544
599
  setStatus("ready");
545
600
  try {
546
- localReplayer.play?.(0);
601
+ localReplayer.play?.(startAt);
547
602
  setPlaying(true);
548
603
  } catch (autoplayError) {
549
604
  console.warn("[session-replay] autoplay failed", autoplayError);
550
605
  try {
551
- localReplayer.pause?.(0);
606
+ localReplayer.pause?.(startAt);
552
607
  } catch {
553
608
  // Some rrweb versions only render after play; the first click still works.
554
609
  }
@@ -584,7 +639,15 @@ function ReplayPlayer({
584
639
  replayerRef.current = null;
585
640
  if (stageRootRef.current) stageRootRef.current.innerHTML = "";
586
641
  };
587
- }, [events, initialDims, t, updateTime]);
642
+ }, [
643
+ currentTimeRef,
644
+ events,
645
+ initialDims,
646
+ response.isComplete,
647
+ speedRef,
648
+ t,
649
+ updateTime,
650
+ ]);
588
651
 
589
652
  useEffect(() => {
590
653
  if (!playing || status !== "ready") {
@@ -711,8 +774,26 @@ function ReplayPlayer({
711
774
  onClick={togglePlay}
712
775
  />
713
776
  {status === "loading" ? (
714
- <div className="absolute inset-0 z-30 grid place-items-center bg-background/70 text-sm text-muted-foreground">
715
- {t("sessions.replayLoading")}
777
+ <div className="absolute inset-0 z-30 grid place-items-center bg-background/70 p-6 text-center text-sm text-muted-foreground">
778
+ <div className="w-full max-w-sm">
779
+ <p>{t("sessions.replayLoading")}</p>
780
+ <div className="mt-3 h-1.5 overflow-hidden rounded-full bg-muted">
781
+ <div
782
+ className="h-full rounded-full bg-primary transition-[width]"
783
+ style={{
784
+ width: `${Math.round(loadingPercent * 100)}%`,
785
+ }}
786
+ />
787
+ </div>
788
+ {response.totalChunks > 0 ? (
789
+ <p className="mt-2 font-mono text-[11px]">
790
+ {t("sessions.replayLoadingProgress", {
791
+ loaded: String(response.loadedChunks),
792
+ total: String(response.totalChunks),
793
+ })}
794
+ </p>
795
+ ) : null}
796
+ </div>
716
797
  </div>
717
798
  ) : null}
718
799
  {status === "error" && error ? (
@@ -845,6 +926,8 @@ function ReplayPlayer({
845
926
  <SessionDevToolsPanel
846
927
  diagnostics={diagnostics}
847
928
  currentTime={currentTime}
929
+ height={devToolsHeight}
930
+ onHeightChange={setDevToolsHeight}
848
931
  onSeek={(ms) => seek(ms, true)}
849
932
  />
850
933
  ) : null}
@@ -880,6 +963,10 @@ function ReplayScrubber({
880
963
  onSeek: (ms: number) => void;
881
964
  }) {
882
965
  const t = useT();
966
+ const scrubberMarkers = useMemo(
967
+ () => visibleScrubberMarkers(markers, totalTime),
968
+ [markers, totalTime],
969
+ );
883
970
  return (
884
971
  <div className="relative min-h-8 min-w-[180px] flex-1">
885
972
  <input
@@ -904,8 +991,8 @@ function ReplayScrubber({
904
991
  <span
905
992
  key={`${range.startMs}-${range.endMs}`}
906
993
  className={cn(
907
- "absolute top-0 h-full rounded-full bg-muted-foreground transition-opacity",
908
- skipInactive ? "opacity-30" : "opacity-10",
994
+ "absolute top-0 h-full rounded-full bg-amber-400 transition-opacity",
995
+ skipInactive ? "opacity-50" : "opacity-20",
909
996
  )}
910
997
  style={{ left: `${left}%`, width: `${width}%` }}
911
998
  />
@@ -913,7 +1000,7 @@ function ReplayScrubber({
913
1000
  })}
914
1001
  </div>
915
1002
  <div className="pointer-events-none absolute inset-x-0 top-1/2 z-30 h-5 -translate-y-1/2">
916
- {markers.slice(0, 200).map((marker) => {
1003
+ {scrubberMarkers.map((marker) => {
917
1004
  const left = totalTime > 0 ? (marker.offsetMs / totalTime) * 100 : 0;
918
1005
  return (
919
1006
  <span
@@ -926,7 +1013,13 @@ function ReplayScrubber({
926
1013
  ? "bg-emerald-500"
927
1014
  : marker.kind === "click"
928
1015
  ? "bg-sky-500"
929
- : "bg-violet-500",
1016
+ : marker.kind === "console"
1017
+ ? marker.severity === "error"
1018
+ ? "bg-red-500"
1019
+ : marker.severity === "warn"
1020
+ ? "bg-amber-500"
1021
+ : "bg-slate-400"
1022
+ : "bg-violet-500",
930
1023
  )}
931
1024
  style={{ left: `${left}%` }}
932
1025
  />
@@ -978,7 +1071,8 @@ function ReplayTimeline({
978
1071
  onSeek: (ms: number) => void;
979
1072
  }) {
980
1073
  const t = useT();
981
- const visibleMarkers = markers.slice(0, 120);
1074
+ const [expandedMarkerId, setExpandedMarkerId] = useState<string | null>(null);
1075
+ const visibleMarkers = markers.slice(0, 300);
982
1076
  return (
983
1077
  <Card className="analytics-session-detail-timeline min-h-0 overflow-hidden">
984
1078
  <CardContent className="flex min-h-0 flex-1 flex-col p-0">
@@ -991,6 +1085,7 @@ function ReplayTimeline({
991
1085
  {visibleMarkers.length
992
1086
  ? t("sessions.timelineDescription", {
993
1087
  count: String(visibleMarkers.length),
1088
+ total: String(markers.length),
994
1089
  })
995
1090
  : t("sessions.noTimelineEvents")}
996
1091
  </p>
@@ -998,48 +1093,71 @@ function ReplayTimeline({
998
1093
  <div className="min-h-0 flex-1 overflow-auto">
999
1094
  {visibleMarkers.length ? (
1000
1095
  <div className="divide-y">
1001
- {visibleMarkers.map((marker) => (
1002
- <button
1003
- key={marker.id}
1004
- type="button"
1005
- className={cn(
1006
- "flex w-full gap-2.5 px-3 py-2.5 text-left transition-colors hover:bg-muted/50",
1007
- marker.id === activeMarkerId && "bg-muted",
1008
- )}
1009
- onClick={() => onSeek(marker.offsetMs)}
1010
- >
1011
- <span
1012
- className={cn(
1013
- "mt-0.5 flex h-7 w-7 shrink-0 items-center justify-center rounded-md border",
1014
- marker.kind === "navigation" &&
1015
- "border-amber-500/35 bg-amber-500/10 text-amber-500",
1016
- marker.kind === "input" &&
1017
- "border-emerald-500/35 bg-emerald-500/10 text-emerald-500",
1018
- marker.kind === "click" &&
1019
- "border-sky-500/35 bg-sky-500/10 text-sky-500",
1020
- marker.kind === "custom" &&
1021
- "border-violet-500/35 bg-violet-500/10 text-violet-500",
1022
- )}
1096
+ {visibleMarkers.map((marker) => {
1097
+ const expanded = marker.id === expandedMarkerId;
1098
+ return (
1099
+ <div
1100
+ key={marker.id}
1101
+ className={cn(marker.id === activeMarkerId && "bg-muted")}
1023
1102
  >
1024
- <MarkerIcon kind={marker.kind} />
1025
- </span>
1026
- <span className="min-w-0 flex-1">
1027
- <span className="flex items-center justify-between gap-3">
1028
- <span className="truncate text-sm font-medium">
1029
- {marker.label}
1103
+ <button
1104
+ type="button"
1105
+ className="flex w-full gap-2.5 px-3 py-2.5 text-left transition-colors hover:bg-muted/50"
1106
+ aria-expanded={expanded}
1107
+ onClick={() => {
1108
+ onSeek(marker.offsetMs);
1109
+ setExpandedMarkerId((current) =>
1110
+ current === marker.id ? null : marker.id,
1111
+ );
1112
+ }}
1113
+ >
1114
+ <span
1115
+ className={cn(
1116
+ "mt-0.5 flex h-7 w-7 shrink-0 items-center justify-center rounded-md border",
1117
+ marker.kind === "navigation" &&
1118
+ "border-amber-500/35 bg-amber-500/10 text-amber-500",
1119
+ marker.kind === "input" &&
1120
+ "border-emerald-500/35 bg-emerald-500/10 text-emerald-500",
1121
+ marker.kind === "click" &&
1122
+ "border-sky-500/35 bg-sky-500/10 text-sky-500",
1123
+ marker.kind === "console" &&
1124
+ marker.severity !== "error" &&
1125
+ "border-slate-500/35 bg-slate-500/10 text-slate-400",
1126
+ marker.kind === "console" &&
1127
+ marker.severity === "error" &&
1128
+ "border-red-500/35 bg-red-500/10 text-red-500",
1129
+ marker.kind === "custom" &&
1130
+ "border-violet-500/35 bg-violet-500/10 text-violet-500",
1131
+ )}
1132
+ >
1133
+ <MarkerIcon kind={marker.kind} />
1030
1134
  </span>
1031
- <span className="font-mono text-xs text-muted-foreground">
1032
- {formatClock(marker.offsetMs)}
1135
+ <span className="min-w-0 flex-1">
1136
+ <span className="flex items-center justify-between gap-3">
1137
+ <span className="truncate text-sm font-medium">
1138
+ {marker.label}
1139
+ </span>
1140
+ <span className="font-mono text-xs text-muted-foreground">
1141
+ {formatClock(marker.offsetMs)}
1142
+ </span>
1143
+ </span>
1144
+ {marker.detail ? (
1145
+ <span className="mt-1 block truncate text-xs text-muted-foreground">
1146
+ {marker.detail}
1147
+ </span>
1148
+ ) : null}
1033
1149
  </span>
1034
- </span>
1035
- {marker.detail ? (
1036
- <span className="mt-1 block truncate text-xs text-muted-foreground">
1037
- {marker.detail}
1038
- </span>
1039
- ) : null}
1040
- </span>
1041
- </button>
1042
- ))}
1150
+ <IconChevronRight
1151
+ className={cn(
1152
+ "mt-1 h-3.5 w-3.5 shrink-0 text-muted-foreground transition-transform rtl:-scale-x-100",
1153
+ expanded && "rotate-90 rtl:scale-x-100",
1154
+ )}
1155
+ />
1156
+ </button>
1157
+ {expanded ? <MarkerDetail marker={marker} /> : null}
1158
+ </div>
1159
+ );
1160
+ })}
1043
1161
  </div>
1044
1162
  ) : (
1045
1163
  <div className="p-4 text-sm text-muted-foreground">
@@ -1056,9 +1174,36 @@ function MarkerIcon({ kind }: { kind: ReplayMarker["kind"] }) {
1056
1174
  if (kind === "navigation") return <IconRoute className="h-4 w-4" />;
1057
1175
  if (kind === "input") return <IconKeyboard className="h-4 w-4" />;
1058
1176
  if (kind === "click") return <IconMouse className="h-4 w-4" />;
1177
+ if (kind === "console") return <IconTerminal2 className="h-4 w-4" />;
1059
1178
  return <IconTimelineEvent className="h-4 w-4" />;
1060
1179
  }
1061
1180
 
1181
+ function MarkerDetail({ marker }: { marker: ReplayMarker }) {
1182
+ return (
1183
+ <div className="space-y-2 border-t bg-muted/25 px-3 py-2 ps-12">
1184
+ {marker.detail ? (
1185
+ <p className="break-words text-xs text-muted-foreground">
1186
+ {marker.detail}
1187
+ </p>
1188
+ ) : null}
1189
+ {marker.fields?.length ? (
1190
+ <dl className="grid gap-2 text-xs">
1191
+ {marker.fields.map((field) => (
1192
+ <div key={`${marker.id}-${field.label}`} className="min-w-0">
1193
+ <dt className="text-[10px] font-semibold uppercase tracking-wide text-muted-foreground">
1194
+ {field.label}
1195
+ </dt>
1196
+ <dd className="mt-0.5 break-all font-mono text-[11px] text-foreground/80">
1197
+ {field.value}
1198
+ </dd>
1199
+ </div>
1200
+ ))}
1201
+ </dl>
1202
+ ) : null}
1203
+ </div>
1204
+ );
1205
+ }
1206
+
1062
1207
  function DetailSkeleton() {
1063
1208
  return (
1064
1209
  <div className="analytics-session-detail-workbench grid min-h-0 flex-1 gap-3">
@@ -1070,14 +1215,136 @@ function DetailSkeleton() {
1070
1215
 
1071
1216
  function useSessionReplayPlayback(recordingId: string) {
1072
1217
  const agentAccessToken = currentSessionReplayAgentAccessToken();
1073
- return useQuery({
1074
- queryKey: ["session-replay-playback", recordingId, agentAccessToken],
1075
- enabled: Boolean(recordingId),
1076
- staleTime: 30_000,
1077
- gcTime: 60_000,
1078
- queryFn: () =>
1079
- fetchSessionReplayPlayback(recordingId, { agentAccessToken }),
1218
+ const [state, setState] = useState<{
1219
+ data: SessionReplayPlaybackResponse | null;
1220
+ isLoading: boolean;
1221
+ error: Error | null;
1222
+ }>({
1223
+ data: null,
1224
+ isLoading: Boolean(recordingId),
1225
+ error: null,
1080
1226
  });
1227
+
1228
+ useEffect(() => {
1229
+ if (!recordingId) {
1230
+ setState({ data: null, isLoading: false, error: null });
1231
+ return;
1232
+ }
1233
+
1234
+ let cancelled = false;
1235
+ setState({ data: null, isLoading: true, error: null });
1236
+
1237
+ async function loadProgressively() {
1238
+ try {
1239
+ const manifest = await fetchReplayManifest(recordingId, {
1240
+ agentAccessToken,
1241
+ });
1242
+ if (cancelled) return;
1243
+
1244
+ const loadedChunks = new Array<ReplayChunkEvents | undefined>(
1245
+ manifest.chunks.length,
1246
+ );
1247
+ let loadedCount = 0;
1248
+ let loadedBytes = 0;
1249
+ let unavailableChunks = 0;
1250
+ let nextIndex = 0;
1251
+ let firstPlayablePublished = false;
1252
+
1253
+ const publish = (force = false) => {
1254
+ const complete = loadedCount >= manifest.chunks.length;
1255
+ const chunks = loadedChunks.filter(
1256
+ (chunk): chunk is ReplayChunkEvents => Boolean(chunk),
1257
+ );
1258
+ const shouldPublishEvents =
1259
+ force ||
1260
+ complete ||
1261
+ (!firstPlayablePublished &&
1262
+ hasPlayableReplayEvents(chunks.flatMap((chunk) => chunk.events)));
1263
+
1264
+ if (shouldPublishEvents) {
1265
+ firstPlayablePublished = true;
1266
+ setState({
1267
+ data: playbackResponseFromChunks(manifest, chunks, {
1268
+ isComplete: complete,
1269
+ loadedChunks: loadedCount,
1270
+ loadedBytes,
1271
+ unavailableChunks,
1272
+ }),
1273
+ isLoading: false,
1274
+ error: null,
1275
+ });
1276
+ return;
1277
+ }
1278
+
1279
+ setState((current) => ({
1280
+ data: current.data
1281
+ ? {
1282
+ ...current.data,
1283
+ loadedChunks: loadedCount,
1284
+ loadedBytes,
1285
+ unavailableChunks,
1286
+ }
1287
+ : playbackResponseFromChunks(manifest, [], {
1288
+ isComplete: complete,
1289
+ loadedChunks: loadedCount,
1290
+ loadedBytes,
1291
+ unavailableChunks,
1292
+ }),
1293
+ isLoading: false,
1294
+ error: null,
1295
+ }));
1296
+ };
1297
+
1298
+ publish();
1299
+
1300
+ async function worker() {
1301
+ while (!cancelled && nextIndex < manifest.chunks.length) {
1302
+ const index = nextIndex;
1303
+ nextIndex += 1;
1304
+ const chunk = await fetchReplayChunk(manifest.chunks[index], {
1305
+ agentAccessToken,
1306
+ });
1307
+ loadedChunks[index] = chunk;
1308
+ loadedCount += 1;
1309
+ loadedBytes += manifest.chunks[index].byteLength;
1310
+ if (chunk.unavailable) unavailableChunks += 1;
1311
+ if (!cancelled) publish();
1312
+ }
1313
+ }
1314
+
1315
+ await Promise.all(
1316
+ Array.from(
1317
+ {
1318
+ length: Math.min(
1319
+ REPLAY_CHUNK_FETCH_CONCURRENCY,
1320
+ manifest.chunks.length,
1321
+ ),
1322
+ },
1323
+ worker,
1324
+ ),
1325
+ );
1326
+ if (!cancelled) publish(true);
1327
+ } catch (loadError) {
1328
+ if (cancelled) return;
1329
+ cancelled = true;
1330
+ setState({
1331
+ data: null,
1332
+ isLoading: false,
1333
+ error:
1334
+ loadError instanceof Error
1335
+ ? loadError
1336
+ : new Error(String(loadError)),
1337
+ });
1338
+ }
1339
+ }
1340
+
1341
+ void loadProgressively();
1342
+ return () => {
1343
+ cancelled = true;
1344
+ };
1345
+ }, [agentAccessToken, recordingId]);
1346
+
1347
+ return state;
1081
1348
  }
1082
1349
 
1083
1350
  interface FetchSessionReplayPlaybackOptions {
@@ -1091,16 +1358,47 @@ export async function fetchSessionReplayPlayback(
1091
1358
  const manifest = await fetchReplayManifest(recordingId, options);
1092
1359
  const chunks = await fetchReplayChunks(manifest.chunks, options);
1093
1360
  const unavailableChunks = chunks.filter((chunk) => chunk.unavailable).length;
1361
+ const loadedBytes = manifest.chunks.reduce(
1362
+ (sum, chunk) => sum + chunk.byteLength,
1363
+ 0,
1364
+ );
1365
+ return playbackResponseFromChunks(manifest, chunks, {
1366
+ isComplete: true,
1367
+ loadedChunks: chunks.length,
1368
+ loadedBytes,
1369
+ unavailableChunks,
1370
+ });
1371
+ }
1372
+
1373
+ function playbackResponseFromChunks(
1374
+ manifest: SessionReplayManifestResponse,
1375
+ chunks: ReplayChunkEvents[],
1376
+ progress: {
1377
+ isComplete: boolean;
1378
+ loadedChunks: number;
1379
+ loadedBytes: number;
1380
+ unavailableChunks: number;
1381
+ },
1382
+ ): SessionReplayPlaybackResponse {
1094
1383
  const eventCount = chunks.reduce(
1095
1384
  (sum, chunk) => sum + chunk.events.length,
1096
1385
  0,
1097
1386
  );
1387
+ const totalBytes = manifest.chunks.reduce(
1388
+ (sum, chunk) => sum + chunk.byteLength,
1389
+ 0,
1390
+ );
1098
1391
  return {
1099
1392
  recording: manifest.recording,
1100
1393
  chunks,
1101
1394
  eventCount,
1102
1395
  truncated: false,
1103
- unavailableChunks,
1396
+ unavailableChunks: progress.unavailableChunks,
1397
+ loadedChunks: progress.loadedChunks,
1398
+ totalChunks: manifest.chunks.length,
1399
+ loadedBytes: progress.loadedBytes,
1400
+ totalBytes,
1401
+ isComplete: progress.isComplete,
1104
1402
  };
1105
1403
  }
1106
1404
 
@@ -1436,7 +1734,7 @@ function isScriptLikeLink(attributes: unknown): boolean {
1436
1734
  );
1437
1735
  }
1438
1736
 
1439
- function buildReplayMarkers(events: AnyReplayEvent[]): ReplayMarker[] {
1737
+ export function buildReplayMarkers(events: AnyReplayEvent[]): ReplayMarker[] {
1440
1738
  const startedAt = replayStartedAt(events);
1441
1739
  const markers: ReplayMarker[] = [];
1442
1740
  for (const event of events) {
@@ -1452,19 +1750,26 @@ function buildReplayMarkers(events: AnyReplayEvent[]): ReplayMarker[] {
1452
1750
  timestamp,
1453
1751
  offsetMs: Math.max(0, timestamp - startedAt),
1454
1752
  kind: "navigation",
1455
- label: pathLabel(href),
1753
+ label: "Navigate",
1456
1754
  detail: href,
1755
+ fields: [{ label: "URL", value: href }],
1457
1756
  });
1458
1757
  } else if (
1459
1758
  event.type === RRWEB_EVENT_TYPE.IncrementalSnapshot &&
1460
1759
  event.data?.source === INCREMENTAL_SOURCE.Input
1461
1760
  ) {
1761
+ const inputValue = replayInputValue(event.data);
1462
1762
  markers.push({
1463
1763
  id: `input-${timestamp}-${markers.length}`,
1464
1764
  timestamp,
1465
1765
  offsetMs: Math.max(0, timestamp - startedAt),
1466
1766
  kind: "input",
1467
- label: "Input",
1767
+ label: inputValue ? "Input changed" : "Input",
1768
+ detail: inputValue,
1769
+ fields: markerFields([
1770
+ ["Element id", event.data?.id],
1771
+ ["Value", inputValue],
1772
+ ]),
1468
1773
  });
1469
1774
  } else if (
1470
1775
  event.type === RRWEB_EVENT_TYPE.IncrementalSnapshot &&
@@ -1478,25 +1783,75 @@ function buildReplayMarkers(events: AnyReplayEvent[]): ReplayMarker[] {
1478
1783
  timestamp,
1479
1784
  offsetMs: Math.max(0, timestamp - startedAt),
1480
1785
  kind: "click",
1481
- label: event.data?.type === MOUSE_INTERACTION.Focus ? "Focus" : "Click",
1786
+ label: mouseInteractionLabel(event.data?.type),
1787
+ detail: pointerDetail(event.data),
1788
+ fields: markerFields([
1789
+ ["Element id", event.data?.id],
1790
+ ["X", event.data?.x],
1791
+ ["Y", event.data?.y],
1792
+ ]),
1482
1793
  });
1483
1794
  } else if (event.type === RRWEB_EVENT_TYPE.Custom) {
1484
- markers.push({
1485
- id: `custom-${timestamp}-${markers.length}`,
1795
+ const marker = customReplayMarker(
1796
+ event,
1486
1797
  timestamp,
1487
- offsetMs: Math.max(0, timestamp - startedAt),
1488
- kind: "custom",
1489
- label: String(event.data?.tag ?? "Custom event"),
1490
- detail:
1491
- typeof event.data?.payload?.message === "string"
1492
- ? event.data.payload.message
1493
- : undefined,
1494
- });
1798
+ startedAt,
1799
+ markers.length,
1800
+ );
1801
+ if (marker) markers.push(marker);
1495
1802
  }
1496
1803
  }
1497
1804
  return markers.sort((a, b) => a.offsetMs - b.offsetMs);
1498
1805
  }
1499
1806
 
1807
+ function customReplayMarker(
1808
+ event: AnyReplayEvent,
1809
+ timestamp: number,
1810
+ startedAt: number,
1811
+ index: number,
1812
+ ): ReplayMarker | null {
1813
+ const tag = String(event.data?.tag ?? "Custom event");
1814
+ const payload = isRecord(event.data?.payload) ? event.data.payload : {};
1815
+ const offsetMs = Math.max(0, timestamp - startedAt);
1816
+
1817
+ if (tag === SESSION_REPLAY_CONSOLE_EVENT_TAG) {
1818
+ const level = typeof payload.level === "string" ? payload.level : "log";
1819
+ if (level !== "error" && level !== "warn") return null;
1820
+ const message =
1821
+ typeof payload.message === "string" ? payload.message : undefined;
1822
+ return {
1823
+ id: `console-${timestamp}-${index}`,
1824
+ timestamp,
1825
+ offsetMs,
1826
+ kind: "console",
1827
+ label: level === "error" ? "Console error" : `Console ${level}`,
1828
+ detail: message,
1829
+ severity:
1830
+ level === "error" ? "error" : level === "warn" ? "warn" : "info",
1831
+ fields: markerFields([
1832
+ ["Level", level],
1833
+ ["Source", payload.source],
1834
+ ["Message", message],
1835
+ ["URL", payload.url],
1836
+ ["Stack", payload.stack],
1837
+ ]),
1838
+ };
1839
+ }
1840
+
1841
+ if (tag === SESSION_REPLAY_NETWORK_EVENT_TAG) {
1842
+ return null;
1843
+ }
1844
+
1845
+ return {
1846
+ id: `custom-${timestamp}-${index}`,
1847
+ timestamp,
1848
+ offsetMs,
1849
+ kind: "custom",
1850
+ label: tag,
1851
+ detail: typeof payload.message === "string" ? payload.message : undefined,
1852
+ };
1853
+ }
1854
+
1500
1855
  function buildIdleSkipRanges(events: AnyReplayEvent[]): SkipRange[] {
1501
1856
  const startedAt = replayStartedAt(events);
1502
1857
  const interactions: number[] = [];
@@ -1563,6 +1918,18 @@ function currentUrlAt(events: AnyReplayEvent[], currentTime: number): string {
1563
1918
  return current;
1564
1919
  }
1565
1920
 
1921
+ function hasPlayableReplayEvents(events: unknown[]): boolean {
1922
+ let hasFullSnapshot = false;
1923
+ let hasMeta = false;
1924
+ for (const event of events) {
1925
+ if (!isRecord(event)) continue;
1926
+ if (event.type === RRWEB_EVENT_TYPE.FullSnapshot) hasFullSnapshot = true;
1927
+ if (event.type === RRWEB_EVENT_TYPE.Meta) hasMeta = true;
1928
+ if (hasFullSnapshot && hasMeta) return true;
1929
+ }
1930
+ return false;
1931
+ }
1932
+
1566
1933
  export function replayViewportDimensions(
1567
1934
  events: AnyReplayEvent[],
1568
1935
  ): ReplayViewportDimensions | null {
@@ -1639,13 +2006,66 @@ function replayDuration(events: AnyReplayEvent[]): number {
1639
2006
  return Math.max(0, endedAt - startedAt);
1640
2007
  }
1641
2008
 
1642
- function pathLabel(href: string): string {
1643
- try {
1644
- const url = new URL(href);
1645
- return `${url.pathname}${url.search}`;
1646
- } catch {
1647
- return href;
2009
+ function replayInputValue(data: AnyRecord): string | undefined {
2010
+ if (typeof data.text === "string" && data.text) return data.text;
2011
+ if (typeof data.value === "string" && data.value) return data.value;
2012
+ if (typeof data.isChecked === "boolean") {
2013
+ return data.isChecked ? "Checked" : "Unchecked";
1648
2014
  }
2015
+ return undefined;
2016
+ }
2017
+
2018
+ function mouseInteractionLabel(type: unknown): string {
2019
+ if (type === MOUSE_INTERACTION.DblClick) return "Double click";
2020
+ if (type === MOUSE_INTERACTION.Focus) return "Focus";
2021
+ return "Click";
2022
+ }
2023
+
2024
+ function pointerDetail(data: AnyRecord): string | undefined {
2025
+ const x = Number(data.x);
2026
+ const y = Number(data.y);
2027
+ if (Number.isFinite(x) && Number.isFinite(y)) {
2028
+ return `x ${Math.round(x)}, y ${Math.round(y)}`;
2029
+ }
2030
+ return undefined;
2031
+ }
2032
+
2033
+ function markerFields(
2034
+ entries: Array<[string, unknown]>,
2035
+ ): Array<{ label: string; value: string }> | undefined {
2036
+ const fields = entries.flatMap(([label, value]) => {
2037
+ if (value === undefined || value === null || value === "") return [];
2038
+ return [{ label, value: String(value) }];
2039
+ });
2040
+ return fields.length ? fields : undefined;
2041
+ }
2042
+
2043
+ function visibleScrubberMarkers(
2044
+ markers: ReplayMarker[],
2045
+ totalTime: number,
2046
+ ): ReplayMarker[] {
2047
+ if (markers.length <= SCRUBBER_MARKER_LIMIT || totalTime <= 0) return markers;
2048
+ const bucketMs = Math.max(1, totalTime / SCRUBBER_MARKER_LIMIT);
2049
+ const buckets = new Map<number, ReplayMarker>();
2050
+
2051
+ for (const marker of markers) {
2052
+ const bucket = Math.floor(marker.offsetMs / bucketMs);
2053
+ const current = buckets.get(bucket);
2054
+ if (!current || markerPriority(marker) > markerPriority(current)) {
2055
+ buckets.set(bucket, marker);
2056
+ }
2057
+ }
2058
+
2059
+ return Array.from(buckets.values()).sort((a, b) => a.offsetMs - b.offsetMs);
2060
+ }
2061
+
2062
+ function markerPriority(marker: ReplayMarker): number {
2063
+ if (marker.severity === "error") return 6;
2064
+ if (marker.kind === "navigation") return 5;
2065
+ if (marker.kind === "click") return 4;
2066
+ if (marker.severity === "warn") return 3;
2067
+ if (marker.kind === "input") return 2;
2068
+ return 1;
1649
2069
  }
1650
2070
 
1651
2071
  function visitorLabel(