@agent-native/core 0.165.3 → 0.167.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 (249) hide show
  1. package/corpus/README.md +1 -1
  2. package/corpus/templates/analytics/.agents/skills/secrets/SKILL.md +5 -1
  3. package/corpus/templates/analytics/.agents/skills/workspace-conventions/SKILL.md +4 -1
  4. package/corpus/templates/analytics/CHANGELOG.md +740 -2
  5. package/corpus/templates/analytics/app/components/layout/Sidebar.tsx +93 -56
  6. package/corpus/templates/analytics/app/i18n-data.ts +23 -20
  7. package/corpus/templates/analytics/app/pages/Settings.tsx +0 -1
  8. package/corpus/templates/analytics/app/pages/adhoc/explorer/index.tsx +0 -1
  9. package/corpus/templates/analytics/app/pages/adhoc/explorer-dashboard/index.tsx +1 -1
  10. package/corpus/templates/analytics/app/pages/adhoc/sql-dashboard/SqlChartCard.tsx +2 -1
  11. package/corpus/templates/analytics/app/pages/sessions/SessionsPage.tsx +0 -1
  12. package/corpus/templates/analytics/server/lib/first-party-analytics-backend.ts +0 -32
  13. package/corpus/templates/analytics/server/lib/session-replay.ts +1 -5
  14. package/corpus/templates/assets/.agents/skills/secrets/SKILL.md +5 -1
  15. package/corpus/templates/assets/.agents/skills/workspace-conventions/SKILL.md +4 -1
  16. package/corpus/templates/assets/CHANGELOG.md +204 -2
  17. package/corpus/templates/assets/actions/navigate.ts +2 -2
  18. package/corpus/templates/assets/actions/save-generated-image.ts +0 -5
  19. package/corpus/templates/assets/app/routes/brand-kits.$id.tsx +2 -262
  20. package/corpus/templates/assets/app/routes/library.tsx +1 -1
  21. package/corpus/templates/assets/app/routes/settings.tsx +0 -3
  22. package/corpus/templates/brain/.agents/skills/secrets/SKILL.md +5 -1
  23. package/corpus/templates/brain/.agents/skills/workspace-conventions/SKILL.md +4 -1
  24. package/corpus/templates/brain/CHANGELOG.md +145 -2
  25. package/corpus/templates/brain/actions/ask-brain.ts +0 -1
  26. package/corpus/templates/brain/actions/navigate.ts +2 -2
  27. package/corpus/templates/brain/app/routes/sources.tsx +0 -4
  28. package/corpus/templates/brain/server/lib/capture-sanitization.ts +0 -11
  29. package/corpus/templates/calendar/.agents/skills/secrets/SKILL.md +5 -1
  30. package/corpus/templates/calendar/.agents/skills/workspace-conventions/SKILL.md +4 -1
  31. package/corpus/templates/calendar/CHANGELOG.md +272 -2
  32. package/corpus/templates/calendar/app/components/calendar/EventDetailPopover.tsx +0 -20
  33. package/corpus/templates/calendar/app/pages/CalendarView.tsx +0 -1
  34. package/corpus/templates/chat/.agents/skills/secrets/SKILL.md +5 -1
  35. package/corpus/templates/chat/.agents/skills/workspace-conventions/SKILL.md +4 -1
  36. package/corpus/templates/chat/CHANGELOG.md +89 -2
  37. package/corpus/templates/chat/actions/navigate.ts +2 -2
  38. package/corpus/templates/clips/.agents/skills/secrets/SKILL.md +5 -1
  39. package/corpus/templates/clips/.agents/skills/workspace-conventions/SKILL.md +4 -1
  40. package/corpus/templates/clips/CHANGELOG.md +865 -2
  41. package/corpus/templates/clips/actions/import-loom-recording.ts +16 -4
  42. package/corpus/templates/clips/actions/navigate.ts +2 -2
  43. package/corpus/templates/clips/app/components/editor/stitch-manager.tsx +0 -1
  44. package/corpus/templates/clips/app/components/library/space-dialogs.tsx +0 -1
  45. package/corpus/templates/clips/app/components/meetings/share-meeting-dialog.tsx +0 -1
  46. package/corpus/templates/clips/app/components/player/clips-share-trigger.tsx +17 -0
  47. package/corpus/templates/clips/app/components/player/delete-recording-menu.tsx +3 -3
  48. package/corpus/templates/clips/app/components/player/video-player.tsx +2 -2
  49. package/corpus/templates/clips/app/components/recorder/recorder-engine.ts +0 -1
  50. package/corpus/templates/clips/app/components/settings/ai-setup-section.tsx +0 -1
  51. package/corpus/templates/clips/app/global.css +31 -0
  52. package/corpus/templates/clips/app/hooks/use-playback-position.ts +0 -2
  53. package/corpus/templates/clips/app/lib/download-release-channel.ts +10 -0
  54. package/corpus/templates/clips/app/routes/_app.meetings.$meetingId.tsx +1 -3
  55. package/corpus/templates/clips/app/routes/download.tsx +67 -44
  56. package/corpus/templates/clips/app/routes/r.$recordingId.tsx +7 -12
  57. package/corpus/templates/clips/app/routes/record.tsx +6 -6
  58. package/corpus/templates/clips/app/routes/share.$shareId.tsx +26 -29
  59. package/corpus/templates/clips/changelog/2026-08-20-clip-viewer-share-actions.md +6 -0
  60. package/corpus/templates/clips/changelog/2026-08-20-preparing-recording-countdown-overlay.md +6 -0
  61. package/corpus/templates/clips/chrome-extension/src/background.ts +0 -13
  62. package/corpus/templates/clips/chrome-extension/src/overlay.ts +0 -1
  63. package/corpus/templates/clips/chrome-extension/src/popup.ts +0 -20
  64. package/corpus/templates/clips/desktop/src/app.tsx +6 -18
  65. package/corpus/templates/clips/desktop/src/hooks/useMediaDevices.ts +0 -1
  66. package/corpus/templates/clips/desktop/src/lib/recorder.ts +0 -8
  67. package/corpus/templates/clips/desktop/src/overlays/preparing.tsx +4 -6
  68. package/corpus/templates/clips/desktop/src/styles.css +18 -20
  69. package/corpus/templates/clips/desktop/src-tauri/src/clips/mod.rs +9 -17
  70. package/corpus/templates/content/.agents/skills/secrets/SKILL.md +5 -1
  71. package/corpus/templates/content/.agents/skills/workspace-conventions/SKILL.md +4 -1
  72. package/corpus/templates/content/CHANGELOG.md +503 -2
  73. package/corpus/templates/content/actions/_database-source-utils.ts +0 -3
  74. package/corpus/templates/content/actions/attach-content-database-source.ts +1 -4
  75. package/corpus/templates/content/actions/navigate.ts +2 -2
  76. package/corpus/templates/content/actions/prepare-builder-source-execution.ts +1 -1
  77. package/corpus/templates/content/app/components/editor/DocumentProperties.tsx +0 -6
  78. package/corpus/templates/content/app/components/editor/database/DatabaseView.tsx +0 -580
  79. package/corpus/templates/content/app/components/editor/database/FormView.tsx +2 -2
  80. package/corpus/templates/content/app/components/editor/database/filter-sort.ts +1 -1
  81. package/corpus/templates/content/app/components/editor/database/settings.tsx +0 -23
  82. package/corpus/templates/content/app/components/editor/database/sidebar.tsx +0 -1
  83. package/corpus/templates/content/app/components/sidebar/DocumentSidebar.tsx +8 -304
  84. package/corpus/templates/content/app/hooks/use-documents.ts +0 -1
  85. package/corpus/templates/content/shared/api.ts +0 -1
  86. package/corpus/templates/content/shared/builder-mdx.ts +0 -1
  87. package/corpus/templates/content/shared/nfm.ts +1 -7
  88. package/corpus/templates/crm/.agents/skills/secrets/SKILL.md +5 -1
  89. package/corpus/templates/crm/.agents/skills/workspace-conventions/SKILL.md +4 -1
  90. package/corpus/templates/crm/CHANGELOG.md +31 -2
  91. package/corpus/templates/crm/actions/merge-crm-records.ts +0 -4
  92. package/corpus/templates/crm/app/components/crm/record/RecordLists.tsx +0 -1
  93. package/corpus/templates/crm/server/crm/hubspot-adapter.ts +0 -1
  94. package/corpus/templates/crm/server/crm/salesforce-adapter.ts +0 -1
  95. package/corpus/templates/crm/server/db/crm-store.ts +1 -1
  96. package/corpus/templates/design/.agents/skills/secrets/SKILL.md +5 -1
  97. package/corpus/templates/design/.agents/skills/workspace-conventions/SKILL.md +4 -1
  98. package/corpus/templates/design/.generated/bridge/editor-chrome.generated.ts +1 -14
  99. package/corpus/templates/design/AGENTS.md +2 -1
  100. package/corpus/templates/design/CHANGELOG.md +870 -2
  101. package/corpus/templates/design/actions/apply-component-prop-edit.ts +1 -5
  102. package/corpus/templates/design/actions/generate-design.ts +0 -1
  103. package/corpus/templates/design/actions/generate-screens.ts +5 -2
  104. package/corpus/templates/design/actions/go-to-main-component.ts +2 -2
  105. package/corpus/templates/design/actions/list-design-systems.ts +10 -0
  106. package/corpus/templates/design/actions/navigate.ts +2 -2
  107. package/corpus/templates/design/actions/open-component-source.ts +4 -4
  108. package/corpus/templates/design/actions/present-design-variants.ts +1 -2
  109. package/corpus/templates/design/actions/run-design-audit.ts +0 -22
  110. package/corpus/templates/design/actions/show-design-questions.ts +5 -2
  111. package/corpus/templates/design/app/components/design/DesignCanvas.tsx +19 -8
  112. package/corpus/templates/design/app/components/design/EditPanel.tsx +11 -183
  113. package/corpus/templates/design/app/components/design/MultiScreenCanvas.tsx +21 -4
  114. package/corpus/templates/design/app/components/design/QuestionFlow.tsx +1 -5
  115. package/corpus/templates/design/app/components/design/bridge/codegen.ts +1 -1
  116. package/corpus/templates/design/app/components/design/bridge/editor-chrome.bridge.ts +10 -19
  117. package/corpus/templates/design/app/components/design/edit-panel/appearance-properties.tsx +1 -1
  118. package/corpus/templates/design/app/components/design/edit-panel/layout-properties.tsx +13 -3
  119. package/corpus/templates/design/app/components/design/edit-panel/panel-primitives.tsx +38 -32
  120. package/corpus/templates/design/app/components/design/edit-panel/position-layout-properties.tsx +1 -4
  121. package/corpus/templates/design/app/components/design/inspector/AlignmentMatrix.tsx +0 -4
  122. package/corpus/templates/design/app/components/design/inspector/AutoLayoutMatrix.tsx +15 -6
  123. package/corpus/templates/design/app/components/design/inspector/DesignColorPicker.tsx +2 -2
  124. package/corpus/templates/design/app/components/visual-editor/NodeRewriteProposal.tsx +0 -1
  125. package/corpus/templates/design/app/components/visual-editor/ReviewCanvasPins.tsx +1 -1
  126. package/corpus/templates/design/app/i18n-data.ts +122 -0
  127. package/corpus/templates/design/app/lib/clipboard-content-lineage.ts +11 -1
  128. package/corpus/templates/design/app/pages/DesignEditor.tsx +50 -254
  129. package/corpus/templates/design/app/pages/DesignSystemSetup.tsx +163 -8
  130. package/corpus/templates/design/app/pages/Index.tsx +17 -0
  131. package/corpus/templates/design/app/pages/design-editor/canvas-primitive-insert.ts +44 -32
  132. package/corpus/templates/design/app/pages/design-editor/canvas-primitives.ts +10 -0
  133. package/corpus/templates/design/app/pages/design-editor/clone-and-pen-edit.ts +49 -3
  134. package/corpus/templates/design/app/pages/design-editor/clone-idrefs.ts +31 -0
  135. package/corpus/templates/design/app/pages/design-editor/code-layer-state.ts +28 -0
  136. package/corpus/templates/design/app/pages/design-editor/commands/add-auto-layout.ts +3 -3
  137. package/corpus/templates/design/app/pages/design-editor/commands/align-selection.ts +44 -14
  138. package/corpus/templates/design/app/pages/design-editor/commands/apply-local-content-update.ts +16 -5
  139. package/corpus/templates/design/app/pages/design-editor/commands/change-selected-z-index.ts +1 -1
  140. package/corpus/templates/design/app/pages/design-editor/commands/frame-selection.ts +1 -1
  141. package/corpus/templates/design/app/pages/design-editor/commands/group-selection.ts +1 -1
  142. package/corpus/templates/design/app/pages/design-editor/commands/nudge-selection.ts +1 -1
  143. package/corpus/templates/design/app/pages/design-editor/commands/paste-selection.ts +142 -17
  144. package/corpus/templates/design/app/pages/design-editor/commands/screen-visual-duplicate-change.ts +1 -0
  145. package/corpus/templates/design/app/pages/design-editor/commands/ungroup-selection.ts +1 -1
  146. package/corpus/templates/design/app/pages/design-editor/commands/visual-duplicate-change.ts +1 -0
  147. package/corpus/templates/design/app/pages/design-editor/cross-screen-text-color.ts +25 -9
  148. package/corpus/templates/design/app/pages/design-editor/editor-state.ts +1 -0
  149. package/corpus/templates/design/app/pages/design-editor/measure-child-rects.ts +83 -0
  150. package/corpus/templates/design/app/pages/design-editor/paste-placement.ts +66 -0
  151. package/corpus/templates/design/server/routes/[...page].get.ts +0 -1
  152. package/corpus/templates/design/shared/code-layer.ts +120 -70
  153. package/corpus/templates/design/shared/design-surface-index.ts +0 -1
  154. package/corpus/templates/design/shared/pen-path.ts +0 -4
  155. package/corpus/templates/dispatch/.agents/skills/secrets/SKILL.md +5 -1
  156. package/corpus/templates/dispatch/.agents/skills/workspace-conventions/SKILL.md +4 -1
  157. package/corpus/templates/dispatch/CHANGELOG.md +196 -2
  158. package/corpus/templates/dispatch/app/routes/integrations.tsx +0 -109
  159. package/corpus/templates/factory/.agents/skills/secrets/SKILL.md +5 -1
  160. package/corpus/templates/factory/.agents/skills/workspace-conventions/SKILL.md +4 -1
  161. package/corpus/templates/factory/CHANGELOG.md +121 -2
  162. package/corpus/templates/factory/actions/navigate.ts +2 -2
  163. package/corpus/templates/factory/app/components/factory/FactoryAuditView.tsx +0 -13
  164. package/corpus/templates/factory/app/routes/factory.tsx +0 -1
  165. package/corpus/templates/factory/server/factory-graph/store.ts +0 -1
  166. package/corpus/templates/forms/.agents/skills/secrets/SKILL.md +5 -1
  167. package/corpus/templates/forms/.agents/skills/workspace-conventions/SKILL.md +4 -1
  168. package/corpus/templates/forms/CHANGELOG.md +166 -2
  169. package/corpus/templates/macros/.agents/skills/secrets/SKILL.md +5 -1
  170. package/corpus/templates/macros/.agents/skills/workspace-conventions/SKILL.md +4 -1
  171. package/corpus/templates/macros/CHANGELOG.md +49 -2
  172. package/corpus/templates/macros/app/components/layout/AppLayout.tsx +0 -1
  173. package/corpus/templates/mail/.agents/skills/secrets/SKILL.md +5 -1
  174. package/corpus/templates/mail/.agents/skills/workspace-conventions/SKILL.md +4 -1
  175. package/corpus/templates/mail/CHANGELOG.md +201 -2
  176. package/corpus/templates/mail/app/components/email/EmailList.tsx +0 -1
  177. package/corpus/templates/mail/app/components/layout/AppLayout.tsx +2 -2
  178. package/corpus/templates/mail/shared/markdown.ts +3 -0
  179. package/corpus/templates/plan/.agents/skills/secrets/SKILL.md +5 -1
  180. package/corpus/templates/plan/.agents/skills/workspace-conventions/SKILL.md +4 -1
  181. package/corpus/templates/plan/CHANGELOG.md +277 -2
  182. package/corpus/templates/slides/.agents/skills/secrets/SKILL.md +5 -1
  183. package/corpus/templates/slides/.agents/skills/workspace-conventions/SKILL.md +4 -1
  184. package/corpus/templates/slides/CHANGELOG.md +437 -2
  185. package/corpus/templates/slides/actions/add-slide.ts +0 -1
  186. package/corpus/templates/slides/actions/list-decks.ts +1 -1
  187. package/corpus/templates/slides/app/components/editor/EditorSidebar.tsx +1 -4
  188. package/corpus/templates/slides/app/components/editor/SlideContextToolbar.tsx +0 -1
  189. package/corpus/templates/slides/app/components/editor/SlideEditor.tsx +1 -1
  190. package/corpus/templates/slides/app/pages/DeckEditor.tsx +1 -6
  191. package/corpus/templates/tasks/.agents/skills/secrets/SKILL.md +5 -1
  192. package/corpus/templates/tasks/.agents/skills/workspace-conventions/SKILL.md +4 -1
  193. package/corpus/templates/tasks/CHANGELOG.md +32 -2
  194. package/corpus/templates/tasks/app/components/layout/Layout.tsx +0 -1
  195. package/corpus/templates/tasks/app/hooks/use-visible-task-fields.ts +1 -4
  196. package/corpus/templates/tasks/server/custom-fields/store.ts +1 -6
  197. package/corpus/templates/tasks/shared/list-screen-snapshot.ts +2 -2
  198. package/dist/agent/engine/registry.js +27 -14
  199. package/dist/agent/index.d.ts +1 -1
  200. package/dist/agent/production-agent.d.ts +19 -6
  201. package/dist/agent/production-agent.js +57 -16
  202. package/dist/agent/types.d.ts +3 -0
  203. package/dist/changelog/parse.d.ts +3 -3
  204. package/dist/changelog/parse.js +35 -16
  205. package/dist/client/EnvironmentBadge.d.ts +1 -0
  206. package/dist/client/EnvironmentBadge.js +7 -0
  207. package/dist/collab/awareness.d.ts +2 -2
  208. package/dist/collab/routes.d.ts +1 -1
  209. package/dist/collab/struct-routes.d.ts +1 -1
  210. package/dist/config.d.ts +11 -0
  211. package/dist/config.js +248 -0
  212. package/dist/deploy/build.js +12 -1
  213. package/dist/index.d.ts +1 -1
  214. package/dist/notifications/routes.d.ts +3 -3
  215. package/dist/observability/routes.d.ts +6 -6
  216. package/dist/resources/handlers.d.ts +2 -2
  217. package/dist/secrets/routes.d.ts +9 -9
  218. package/dist/server/agent-chat/plugin-options.d.ts +3 -2
  219. package/dist/server/agent-chat-plugin.js +5 -2
  220. package/dist/server/index.d.ts +1 -1
  221. package/dist/server/realtime-token.d.ts +1 -1
  222. package/dist/server/transcribe-voice.d.ts +1 -1
  223. package/dist/templates/chat/.agents/skills/secrets/SKILL.md +5 -1
  224. package/dist/templates/chat/.agents/skills/workspace-conventions/SKILL.md +4 -1
  225. package/dist/templates/chat/CHANGELOG.md +89 -2
  226. package/dist/templates/chat/actions/navigate.ts +2 -2
  227. package/dist/templates/default/.agents/skills/secrets/SKILL.md +5 -1
  228. package/dist/templates/default/.agents/skills/workspace-conventions/SKILL.md +4 -1
  229. package/dist/templates/headless/.agents/skills/secrets/SKILL.md +5 -1
  230. package/dist/templates/workspace-core/.agents/skills/secrets/SKILL.md +5 -1
  231. package/dist/templates/workspace-core/.agents/skills/workspace-conventions/SKILL.md +4 -1
  232. package/dist/vite/agent-native-config-loader.d.ts +1 -0
  233. package/dist/vite/agent-native-config-loader.js +3 -3
  234. package/dist/vite/agents-bundle-plugin.d.ts +1 -1
  235. package/dist/vite/agents-bundle-plugin.js +13 -1
  236. package/dist/vite/client.js +14 -14
  237. package/docs/content/agent-native-config.mdx +62 -11
  238. package/docs/content/agent-surfaces.mdx +6 -0
  239. package/docs/content/environment-variables.mdx +5 -2
  240. package/package.json +3 -3
  241. package/src/templates/chat/.agents/skills/secrets/SKILL.md +5 -1
  242. package/src/templates/chat/.agents/skills/workspace-conventions/SKILL.md +4 -1
  243. package/src/templates/chat/CHANGELOG.md +89 -2
  244. package/src/templates/chat/actions/navigate.ts +2 -2
  245. package/src/templates/default/.agents/skills/secrets/SKILL.md +5 -1
  246. package/src/templates/default/.agents/skills/workspace-conventions/SKILL.md +4 -1
  247. package/src/templates/headless/.agents/skills/secrets/SKILL.md +5 -1
  248. package/src/templates/workspace-core/.agents/skills/secrets/SKILL.md +5 -1
  249. package/src/templates/workspace-core/.agents/skills/workspace-conventions/SKILL.md +4 -1
@@ -1,5 +1,8 @@
1
1
  import { defineAction } from "@agent-native/core";
2
- import { writeAppState } from "@agent-native/core/application-state";
2
+ import {
3
+ writeAppState,
4
+ writeAppStateForCurrentTab,
5
+ } from "@agent-native/core/application-state";
3
6
  import { ssrfSafeFetch } from "@agent-native/core/extensions/url-safety";
4
7
  import { uploadFile } from "@agent-native/core/file-upload";
5
8
  import { buildDeepLink } from "@agent-native/core/server";
@@ -315,7 +318,10 @@ export default defineAction({
315
318
  updatedAt: now,
316
319
  });
317
320
  await writeAppState("refresh-signal", { ts: Date.now() });
318
- await writeAppState("navigate", { view: "recording", recordingId: id });
321
+ await writeAppStateForCurrentTab("navigate", {
322
+ view: "recording",
323
+ recordingId: id,
324
+ });
319
325
 
320
326
  return {
321
327
  recordingId: id,
@@ -386,7 +392,10 @@ export default defineAction({
386
392
  updatedAt: now,
387
393
  });
388
394
  await writeAppState("refresh-signal", { ts: Date.now() });
389
- await writeAppState("navigate", { view: "recording", recordingId: id });
395
+ await writeAppStateForCurrentTab("navigate", {
396
+ view: "recording",
397
+ recordingId: id,
398
+ });
390
399
 
391
400
  try {
392
401
  console.log("[import-loom-recording] dispatching loom-import job", {
@@ -540,7 +549,10 @@ export default defineAction({
540
549
  updatedAt: now,
541
550
  });
542
551
  await writeAppState("refresh-signal", { ts: Date.now() });
543
- await writeAppState("navigate", { view: "recording", recordingId: id });
552
+ await writeAppStateForCurrentTab("navigate", {
553
+ view: "recording",
554
+ recordingId: id,
555
+ });
544
556
 
545
557
  return {
546
558
  recordingId: id,
@@ -16,7 +16,7 @@
16
16
  */
17
17
 
18
18
  import { defineAction } from "@agent-native/core";
19
- import { writeAppState } from "@agent-native/core/application-state";
19
+ import { writeAppStateForCurrentTab } from "@agent-native/core/application-state";
20
20
  import { z } from "zod";
21
21
 
22
22
  const Views = [
@@ -91,7 +91,7 @@ export default defineAction({
91
91
  if (args.shareId) nav.shareId = args.shareId;
92
92
  if (args.search) nav.search = args.search;
93
93
  if (args.path) nav.path = args.path;
94
- await writeAppState("navigate", nav);
94
+ await writeAppStateForCurrentTab("navigate", nav);
95
95
  const target =
96
96
  args.path ||
97
97
  [
@@ -1,4 +1,3 @@
1
- import { agentNativePath } from "@agent-native/core/client/api-path";
2
1
  import {
3
2
  useActionMutation,
4
3
  useActionQuery,
@@ -1,6 +1,5 @@
1
1
  import { useActionMutation } from "@agent-native/core/client/hooks";
2
2
  import { useT } from "@agent-native/core/client/i18n";
3
- import { useState } from "react";
4
3
  import { toast } from "sonner";
5
4
 
6
5
  import {
@@ -73,7 +73,6 @@ function ShareMeetingContent({
73
73
  shareTranscript: boolean;
74
74
  transcriptReady: boolean;
75
75
  }) {
76
- const t = useT();
77
76
  const shareUrl = useMemo(
78
77
  () => `${window.location.origin}${appPath(`/share/meeting/${meetingId}`)}`,
79
78
  [meetingId],
@@ -0,0 +1,17 @@
1
+ import {
2
+ ShareTrigger,
3
+ type ShareTriggerProps,
4
+ } from "@agent-native/toolkit/sharing";
5
+
6
+ import { cn } from "@/lib/utils";
7
+
8
+ export function ClipsShareTrigger({ className, ...props }: ShareTriggerProps) {
9
+ return (
10
+ <ShareTrigger
11
+ {...props}
12
+ intent="primary"
13
+ emphasis="solid"
14
+ className={cn("clips-share-trigger shrink-0", className)}
15
+ />
16
+ );
17
+ }
@@ -1,6 +1,6 @@
1
1
  import { useActionMutation } from "@agent-native/core/client/hooks";
2
2
  import { useT } from "@agent-native/core/client/i18n";
3
- import { IconDots, IconDownload, IconTrash } from "@tabler/icons-react";
3
+ import { IconDotsVertical, IconDownload, IconTrash } from "@tabler/icons-react";
4
4
  import { useCallback, useRef, useState } from "react";
5
5
  import { toast } from "sonner";
6
6
 
@@ -93,10 +93,10 @@ export function RecordingOptionsMenu({
93
93
  <Button
94
94
  variant="ghost"
95
95
  size="icon"
96
- className="shrink-0"
96
+ className="-mx-1.5 h-auto w-auto shrink-0 px-0.5 py-1.5"
97
97
  aria-label={t("deleteRecordingMenu.clipOptions")}
98
98
  >
99
- <IconDots className="h-4 w-4" />
99
+ <IconDotsVertical className="h-4 w-4" />
100
100
  </Button>
101
101
  </DropdownMenuTrigger>
102
102
  <DropdownMenuContent align="end" className="w-44">
@@ -399,7 +399,7 @@ export const VideoPlayer = forwardRef<VideoPlayerHandle, VideoPlayerProps>(
399
399
  const [isFullscreen, setIsFullscreen] = useState(false);
400
400
  const nativeFullscreenRef = useRef(false);
401
401
  const [isPip, setIsPip] = useState(false);
402
- const [canPlay, setCanPlay] = useState(false);
402
+ const [, setCanPlay] = useState(false);
403
403
  const [isPlayPending, setIsPlayPending] = useState(false);
404
404
  const [isBuffering, setIsBuffering] = useState(false);
405
405
  const [playError, setPlayError] = useState<string | null>(null);
@@ -467,7 +467,7 @@ export const VideoPlayer = forwardRef<VideoPlayerHandle, VideoPlayerProps>(
467
467
  // first frame of a freshly-finalized clip so the user doesn't see a blank
468
468
  // black rectangle. Hidden on loadeddata / canplay / currentTime > 0, or
469
469
  // after a 10s safety timeout.
470
- const [isPreparing, setIsPreparing] = useState<boolean>(!!videoUrl);
470
+ const [, setIsPreparing] = useState<boolean>(!!videoUrl);
471
471
  const edits = useMemo(() => parseEdits(editsJson), [editsJson]);
472
472
  const hasEditorThumbnail = Boolean(edits.thumbnail);
473
473
  const [shouldRefreshAutoThumbnail, setShouldRefreshAutoThumbnail] =
@@ -11,7 +11,6 @@ import {
11
11
  import {
12
12
  SCREEN_CAPTURE_FRAME_RATE,
13
13
  screenCaptureDisplayOptions,
14
- screenCaptureVideoConstraints,
15
14
  } from "@shared/recording-capture";
16
15
  import {
17
16
  chunkUploadUrl,
@@ -15,7 +15,6 @@ import {
15
15
  IconBolt,
16
16
  IconCheck,
17
17
  IconExternalLink,
18
- IconKey,
19
18
  IconLoader2,
20
19
  } from "@tabler/icons-react";
21
20
  import { useState } from "react";
@@ -73,6 +73,10 @@
73
73
  --highlight-foreground: 0 0% 10%;
74
74
  }
75
75
 
76
+ .dark .clips-share-trigger {
77
+ --primary: 0 0% 100%;
78
+ }
79
+
76
80
  @theme inline {
77
81
  --color-highlight: hsl(var(--highlight));
78
82
  --color-highlight-foreground: hsl(var(--highlight-foreground));
@@ -148,6 +152,33 @@
148
152
  animation: clips-collapsible-up 120ms ease-out;
149
153
  }
150
154
 
155
+ .clips-share-content {
156
+ container: clips-share-content / inline-size;
157
+ }
158
+
159
+ .clips-share-metadata-description {
160
+ order: 2;
161
+ }
162
+
163
+ .clips-share-metadata-actions {
164
+ order: 1;
165
+ }
166
+
167
+ @container clips-share-content (min-width: 860px) {
168
+ .clips-share-metadata {
169
+ align-items: flex-start;
170
+ flex-direction: row;
171
+ }
172
+
173
+ .clips-share-metadata-description {
174
+ order: 1;
175
+ }
176
+
177
+ .clips-share-metadata-actions {
178
+ order: 2;
179
+ }
180
+ }
181
+
151
182
  @media (prefers-reduced-motion: reduce) {
152
183
  .clips-collapsible-content[data-state] {
153
184
  animation-duration: 1ms;
@@ -48,7 +48,6 @@ export function usePlaybackPosition({
48
48
  let restoreApplied = false;
49
49
  let saveInFlight = false;
50
50
  let pendingSave: { positionMs: number; keepalive: boolean } | null = null;
51
- let lastSavedPositionMs = -1;
52
51
  let lastSavedAt = -SAVE_INTERVAL_MS;
53
52
  let removePendingRestoreListeners: (() => void) | null = null;
54
53
 
@@ -80,7 +79,6 @@ export function usePlaybackPosition({
80
79
  }
81
80
 
82
81
  saveInFlight = true;
83
- lastSavedPositionMs = positionMs;
84
82
  lastSavedAt = now;
85
83
  void savePlaybackPosition(recordingId, positionMs, { keepalive })
86
84
  .catch((error) => {
@@ -0,0 +1,10 @@
1
+ export type DownloadReleaseChannel = "production" | "nightly";
2
+
3
+ export const BETA_CLIPS_HOSTNAME = "beta.clips.agent-native.com";
4
+
5
+ export function getDefaultDownloadChannel(
6
+ hostname: string | undefined,
7
+ ): DownloadReleaseChannel {
8
+ const normalized = hostname?.trim().toLowerCase().replace(/\.$/, "");
9
+ return normalized === BETA_CLIPS_HOSTNAME ? "nightly" : "production";
10
+ }
@@ -28,7 +28,6 @@ import { useEffect, useMemo, useRef, useState } from "react";
28
28
  import { NavLink, useNavigate, useParams } from "react-router";
29
29
  import { toast } from "sonner";
30
30
 
31
- import { CaptureInstallButton } from "@/components/capture-install-options";
32
31
  import { PageHeader } from "@/components/library/page-header";
33
32
  import {
34
33
  AttendeeStack,
@@ -69,7 +68,6 @@ import {
69
68
  TooltipContent,
70
69
  TooltipTrigger,
71
70
  } from "@/components/ui/tooltip";
72
- import { useDesktopPromo } from "@/hooks/use-desktop-promo";
73
71
  import enMessages from "@/i18n/en-US";
74
72
  import { cn } from "@/lib/utils";
75
73
 
@@ -499,7 +497,7 @@ export default function MeetingDetailRoute() {
499
497
  const stopMeetingRecording = useActionMutation<any, any>(
500
498
  "stop-meeting-recording",
501
499
  );
502
- const { isDesktopApp } = useDesktopPromo();
500
+
503
501
  const [notesJustArrived, setNotesJustArrived] = useState(false);
504
502
  const [deleteOpen, setDeleteOpen] = useState(false);
505
503
  const [endMeetingOpen, setEndMeetingOpen] = useState(false);
@@ -4,12 +4,20 @@ import {
4
4
  IconBrandChrome,
5
5
  IconBrandApple,
6
6
  IconBrandWindows,
7
+ IconChevronDown,
7
8
  IconDeviceDesktop,
8
9
  IconExternalLink,
9
10
  } from "@tabler/icons-react";
10
11
  import { useEffect, useState } from "react";
11
12
 
12
13
  import { Button } from "@/components/ui/button";
14
+ import {
15
+ DropdownMenu,
16
+ DropdownMenuContent,
17
+ DropdownMenuRadioGroup,
18
+ DropdownMenuRadioItem,
19
+ DropdownMenuTrigger,
20
+ } from "@/components/ui/dropdown-menu";
13
21
  import { Skeleton } from "@/components/ui/skeleton";
14
22
  import enMessages from "@/i18n/en-US";
15
23
  import {
@@ -17,6 +25,10 @@ import {
17
25
  markDesktopAppDownloaded,
18
26
  useClipsChromeExtensionEnabled,
19
27
  } from "@/lib/capture-install-options";
28
+ import {
29
+ getDefaultDownloadChannel,
30
+ type DownloadReleaseChannel,
31
+ } from "@/lib/download-release-channel";
20
32
 
21
33
  export function meta() {
22
34
  return [
@@ -29,7 +41,6 @@ export function meta() {
29
41
  }
30
42
 
31
43
  type PlatformId = "mac" | "windows" | "linux";
32
- type ReleaseChannel = "production" | "nightly";
33
44
 
34
45
  interface PlatformVariant {
35
46
  id: PlatformId;
@@ -204,7 +215,8 @@ function secondaryDownloadButton(
204
215
  export default function DownloadPage() {
205
216
  const chromeExtensionEnabled = useClipsChromeExtensionEnabled();
206
217
  const t = useT();
207
- const [channel, setChannel] = useState<ReleaseChannel>("production");
218
+ const [channel, setChannel] = useState<DownloadReleaseChannel>("production");
219
+ const [hostResolved, setHostResolved] = useState(false);
208
220
  const [manifest, setManifest] = useState<Manifest | null>(null);
209
221
  const [manifestError, setManifestError] = useState(false);
210
222
  const [detected, setDetected] = useState<PlatformId | null>(null);
@@ -215,6 +227,13 @@ export default function DownloadPage() {
215
227
  }, []);
216
228
 
217
229
  useEffect(() => {
230
+ setChannel(getDefaultDownloadChannel(window.location.hostname));
231
+ setHostResolved(true);
232
+ }, []);
233
+
234
+ useEffect(() => {
235
+ if (!hostResolved) return;
236
+
218
237
  let cancelled = false;
219
238
  setManifest(null);
220
239
  setManifestError(false);
@@ -233,13 +252,15 @@ export default function DownloadPage() {
233
252
  return () => {
234
253
  cancelled = true;
235
254
  };
236
- }, [channel, manifestRequest]);
255
+ }, [channel, hostResolved, manifestRequest]);
237
256
 
238
257
  const retryManifest = () => {
239
258
  setManifestRequest((request) => request + 1);
240
259
  };
241
260
 
242
- const handleChannelChange = (nextChannel: ReleaseChannel) => {
261
+ const handleChannelChange = (nextChannel: DownloadReleaseChannel) => {
262
+ if (nextChannel === channel) return;
263
+
243
264
  setManifest(null);
244
265
  setManifestError(false);
245
266
  setChannel(nextChannel);
@@ -335,46 +356,48 @@ export default function DownloadPage() {
335
356
  <>{t("downloadRoute.loadingRelease")}</>
336
357
  )}
337
358
  </div>
338
- <div className="mt-2 flex items-center gap-2 text-xs text-muted-foreground">
339
- <span>{t("downloadRoute.stable")}</span>
340
- <button
341
- type="button"
342
- role="switch"
343
- aria-checked={channel === "nightly"}
344
- aria-label={t(
345
- channel === "nightly"
346
- ? "downloadRoute.switchToStable"
347
- : "downloadRoute.switchToNightly",
348
- )}
349
- onClick={() =>
350
- handleChannelChange(
351
- channel === "nightly" ? "production" : "nightly",
352
- )
353
- }
354
- className={`relative inline-flex h-5 w-9 shrink-0 items-center rounded-full border border-border transition-colors focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-blue-500/50 ${
355
- channel === "nightly"
356
- ? "bg-foreground"
357
- : "bg-muted-foreground/20"
358
- }`}
359
- >
360
- <span
361
- aria-hidden="true"
362
- className={`block size-3.5 rounded-full bg-primary-foreground shadow-sm transition-transform ${
363
- channel === "nightly"
364
- ? "translate-x-[18px]"
365
- : "translate-x-[2px]"
366
- }`}
367
- />
368
- </button>
369
- <span
370
- className={
371
- channel === "nightly"
372
- ? "font-medium text-foreground"
373
- : "text-muted-foreground"
374
- }
375
- >
376
- {t("downloadRoute.nightly")}
377
- </span>
359
+ <div className="mt-2 flex items-center justify-center text-xs text-muted-foreground">
360
+ <DropdownMenu>
361
+ <DropdownMenuTrigger asChild>
362
+ <Button
363
+ type="button"
364
+ variant="ghost"
365
+ size="sm"
366
+ className="h-7 gap-1.5 px-2 font-normal text-muted-foreground hover:bg-muted/50 hover:text-foreground"
367
+ data-release-channel={channel}
368
+ >
369
+ <span
370
+ className={
371
+ channel === "nightly"
372
+ ? "font-medium text-foreground"
373
+ : undefined
374
+ }
375
+ >
376
+ {channel === "nightly"
377
+ ? t("downloadRoute.nightly")
378
+ : t("downloadRoute.stable")}
379
+ </span>
380
+ <IconChevronDown className="size-3.5" aria-hidden="true" />
381
+ </Button>
382
+ </DropdownMenuTrigger>
383
+ <DropdownMenuContent align="center" className="w-44">
384
+ <DropdownMenuRadioGroup
385
+ value={channel}
386
+ onValueChange={(value) => {
387
+ if (value === "production" || value === "nightly") {
388
+ handleChannelChange(value);
389
+ }
390
+ }}
391
+ >
392
+ <DropdownMenuRadioItem value="production">
393
+ {t("downloadRoute.stable")}
394
+ </DropdownMenuRadioItem>
395
+ <DropdownMenuRadioItem value="nightly">
396
+ {t("downloadRoute.nightly")}
397
+ </DropdownMenuRadioItem>
398
+ </DropdownMenuRadioGroup>
399
+ </DropdownMenuContent>
400
+ </DropdownMenu>
378
401
  </div>
379
402
  </div>
380
403
 
@@ -1,5 +1,5 @@
1
1
  import { AgentPanel } from "@agent-native/core/client/agent-chat";
2
- import { appPath, agentNativePath } from "@agent-native/core/client/api-path";
2
+ import { agentNativePath } from "@agent-native/core/client/api-path";
3
3
  import { writeClipboardText } from "@agent-native/core/client/clipboard";
4
4
  import {
5
5
  useActionMutation,
@@ -16,7 +16,7 @@ import {
16
16
  isHumanReadableDocumentTitle,
17
17
  normalizeDocumentTitle,
18
18
  } from "@agent-native/core/shared";
19
- import { ShareCopyRow, ShareTrigger } from "@agent-native/toolkit/sharing";
19
+ import { ShareCopyRow } from "@agent-native/toolkit/sharing";
20
20
  import {
21
21
  BUILDER_CREDITS_UPGRADE_URL,
22
22
  type BuilderCreditsStatus,
@@ -59,6 +59,7 @@ import { toast } from "sonner";
59
59
 
60
60
  import { EditableRecordingTitle } from "@/components/editable-recording-title";
61
61
  import { EditorLayout } from "@/components/editor/editor-layout";
62
+ import { ClipsShareTrigger } from "@/components/player/clips-share-trigger";
62
63
  import { CommentsPanel } from "@/components/player/comments-panel";
63
64
  import { RecordingOptionsMenu } from "@/components/player/delete-recording-menu";
64
65
  import { InsightsPanel } from "@/components/player/insights-panel";
@@ -1051,7 +1052,7 @@ export default function RecordingPage() {
1051
1052
  if (!showRecoveryState) {
1052
1053
  return (
1053
1054
  <div className="flex min-h-screen w-full flex-col bg-background">
1054
- <header className="flex min-w-0 shrink-0 items-center gap-3 border-b border-border px-3 py-2 sm:px-4 sm:py-3">
1055
+ <header className="flex min-w-0 shrink-0 items-center gap-2 border-b border-border px-3 py-2 sm:px-4 sm:py-3">
1055
1056
  <BackToLibraryButton />
1056
1057
  <div className="min-w-0 flex-1">
1057
1058
  <p className="truncate text-sm font-medium">{visibleTitle}</p>
@@ -1070,10 +1071,7 @@ export default function RecordingPage() {
1070
1071
  hasPassword={Boolean(recording.hasPassword)}
1071
1072
  viewerReshareOnly={viewerReshareOnly}
1072
1073
  >
1073
- <ShareTrigger
1074
- label={t("recordingPage.share")}
1075
- className="shrink-0"
1076
- />
1074
+ <ClipsShareTrigger label={t("recordingPage.share")} />
1077
1075
  </ShareRecordingPopover>
1078
1076
  </header>
1079
1077
 
@@ -1370,7 +1368,7 @@ export default function RecordingPage() {
1370
1368
  <div className="flex min-h-screen w-full max-w-full flex-col overflow-x-hidden bg-background xl:h-screen xl:flex-row xl:overflow-hidden">
1371
1369
  {/* Main video column */}
1372
1370
  <div className="flex w-full min-w-0 flex-col xl:flex-1">
1373
- <header className="flex min-w-0 shrink-0 items-center gap-2 border-b border-border px-3 py-2 sm:gap-3 sm:px-4 sm:py-3">
1371
+ <header className="flex min-w-0 shrink-0 items-center gap-2 border-b border-border px-3 py-2 sm:px-4 sm:py-3">
1374
1372
  <BackToLibraryButton />
1375
1373
  <div className="flex-1 min-w-0">
1376
1374
  <EditableRecordingTitle
@@ -1609,10 +1607,7 @@ export default function RecordingPage() {
1609
1607
  hasPassword={Boolean(recording.hasPassword)}
1610
1608
  viewerReshareOnly={viewerReshareOnly}
1611
1609
  >
1612
- <ShareTrigger
1613
- label={t("recordingPage.share")}
1614
- className="shrink-0"
1615
- />
1610
+ <ClipsShareTrigger label={t("recordingPage.share")} />
1616
1611
  </ShareRecordingPopover>
1617
1612
  ) : null}
1618
1613
 
@@ -3,7 +3,7 @@ import {
3
3
  agentNativePath,
4
4
  appBasePath,
5
5
  } from "@agent-native/core/client/api-path";
6
- import { callAction } from "@agent-native/core/client/hooks";
6
+ import { callAction, getBrowserTabId } from "@agent-native/core/client/hooks";
7
7
  import { useT } from "@agent-native/core/client/i18n";
8
8
  import { useLiveTranscription } from "@agent-native/core/client/transcription/use-live-transcription";
9
9
  import type { BrowserDiagnosticsData } from "@shared/browser-diagnostics";
@@ -31,7 +31,7 @@ import {
31
31
  import { useQueryClient } from "@tanstack/react-query";
32
32
  import { useCallback, useEffect, useMemo, useRef, useState } from "react";
33
33
  import { flushSync } from "react-dom";
34
- import { Link, useLocation, useNavigate } from "react-router";
34
+ import { useLocation, useNavigate } from "react-router";
35
35
 
36
36
  import { Skeleton } from "@/components/ui/skeleton";
37
37
  import { useDesktopPromo } from "@/hooks/use-desktop-promo";
@@ -1783,7 +1783,7 @@ export default function RecordRoute() {
1783
1783
  }
1784
1784
  if (reportContext && createdId) {
1785
1785
  const path = bugReportDonePath(createdId, reportContext);
1786
- await writeAppState("navigate", {
1786
+ await writeAppState(`navigate:${getBrowserTabId()}`, {
1787
1787
  view: "bug-report-done",
1788
1788
  recordingId: createdId,
1789
1789
  path,
@@ -1792,7 +1792,7 @@ export default function RecordRoute() {
1792
1792
  navigate(path);
1793
1793
  }, 50);
1794
1794
  } else {
1795
- await writeAppState("navigate", {
1795
+ await writeAppState(`navigate:${getBrowserTabId()}`, {
1796
1796
  view: "recording",
1797
1797
  recordingId: createdId,
1798
1798
  });
@@ -1980,7 +1980,7 @@ export default function RecordRoute() {
1980
1980
 
1981
1981
  if (reportContext) {
1982
1982
  const path = bugReportDonePath(recordingId, reportContext);
1983
- await writeAppState("navigate", {
1983
+ await writeAppState(`navigate:${getBrowserTabId()}`, {
1984
1984
  view: "bug-report-done",
1985
1985
  recordingId,
1986
1986
  path,
@@ -1991,7 +1991,7 @@ export default function RecordRoute() {
1991
1991
  return;
1992
1992
  }
1993
1993
 
1994
- await writeAppState("navigate", {
1994
+ await writeAppState(`navigate:${getBrowserTabId()}`, {
1995
1995
  view: "recording",
1996
1996
  recordingId,
1997
1997
  }).catch(() => {});