@agent-native/core 0.192.0-nightly-20260926081002 → 0.192.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 (139) hide show
  1. package/corpus/README.md +1 -1
  2. package/corpus/templates/analytics/CHANGELOG.md +17 -0
  3. package/corpus/templates/analytics/actions/get-sql-dashboard.ts +27 -3
  4. package/corpus/templates/analytics/app/components/AnalyticsReviewArtifactPreview.tsx +8 -2
  5. package/corpus/templates/analytics/app/components/dashboard/SqlChart.tsx +14 -10
  6. package/corpus/templates/analytics/app/root.tsx +2 -4
  7. package/corpus/templates/analytics/app/routes/_index.tsx +1 -36
  8. package/corpus/templates/analytics/app/routes/home.tsx +1 -1
  9. package/corpus/templates/analytics/changelog/2026-09-25-human-review-previews-show-same-organization-dashboard-chart.md +6 -0
  10. package/corpus/templates/analytics/changelog/2026-09-25-human-review-skips-saved-bigquery-queries-in-previews.md +6 -0
  11. package/corpus/templates/analytics/changelog/2026-09-26-the-app-entry-now-opens-the-shared-sign-in-and-sign-up-scree.md +6 -0
  12. package/corpus/templates/analytics/server/lib/dashboards-store.ts +14 -0
  13. package/corpus/templates/analytics/server/plugins/auth.ts +0 -3
  14. package/corpus/templates/assets/CHANGELOG.md +16 -0
  15. package/corpus/templates/assets/app/root.tsx +2 -7
  16. package/corpus/templates/assets/app/routes/_index.tsx +1 -36
  17. package/corpus/templates/assets/changelog/2026-09-26-the-app-entry-now-opens-the-shared-sign-in-and-sign-up-scree.md +6 -0
  18. package/corpus/templates/assets/server/plugins/auth.ts +0 -3
  19. package/corpus/templates/brain/app/root.tsx +2 -13
  20. package/corpus/templates/brain/app/routes/_index.tsx +1 -35
  21. package/corpus/templates/brain/app/routes/home.tsx +1 -1
  22. package/corpus/templates/calendar/CHANGELOG.md +15 -0
  23. package/corpus/templates/calendar/app/root.tsx +2 -10
  24. package/corpus/templates/calendar/app/routes/_index.tsx +1 -34
  25. package/corpus/templates/calendar/changelog/2026-09-26-the-app-entry-now-opens-the-shared-sign-in-and-sign-up-scree.md +6 -0
  26. package/corpus/templates/calendar/server/plugins/auth.ts +0 -3
  27. package/corpus/templates/chat/AGENTS.md +3 -3
  28. package/corpus/templates/chat/app/root.tsx +3 -15
  29. package/corpus/templates/chat/app/routes/_index.tsx +1 -37
  30. package/corpus/templates/chat/server/plugins/auth.ts +0 -3
  31. package/corpus/templates/clips/CHANGELOG.md +10 -0
  32. package/corpus/templates/clips/app/root.tsx +2 -10
  33. package/corpus/templates/clips/app/routes/_index.tsx +1 -33
  34. package/corpus/templates/clips/app/routes/share.$shareId.tsx +2 -3
  35. package/corpus/templates/clips/changelog/2026-09-26-the-app-entry-now-opens-the-shared-sign-in-and-sign-up-scree.md +6 -0
  36. package/corpus/templates/clips/server/plugins/auth.ts +0 -3
  37. package/corpus/templates/content/app/root.tsx +2 -3
  38. package/corpus/templates/content/app/routes/_index.tsx +1 -33
  39. package/corpus/templates/content/server/plugins/auth.ts +0 -3
  40. package/corpus/templates/crm/app/root.tsx +3 -16
  41. package/corpus/templates/crm/app/routes/_index.tsx +1 -36
  42. package/corpus/templates/crm/app/routes/home.tsx +1 -1
  43. package/corpus/templates/design/.generated/bridge/editor-chrome.generated.ts +30 -17
  44. package/corpus/templates/design/CHANGELOG.md +31 -0
  45. package/corpus/templates/design/actions/connect-localhost.ts +98 -37
  46. package/corpus/templates/design/actions/get-design.schema.ts +10 -0
  47. package/corpus/templates/design/actions/get-design.ts +25 -6
  48. package/corpus/templates/design/actions/publish-visual-edit-pending.ts +4 -59
  49. package/corpus/templates/design/app/components/design/DesignCanvas.tsx +108 -49
  50. package/corpus/templates/design/app/components/design/MultiScreenCanvas.tsx +63 -21
  51. package/corpus/templates/design/app/components/design/types.ts +2 -0
  52. package/corpus/templates/design/app/pages/design-editor/commands/cross-screen-element-drop.ts +98 -9
  53. package/corpus/templates/design/app/pages/design-editor/commands/cross-screen-insert-timeout.ts +61 -6
  54. package/corpus/templates/design/app/pages/design-editor/commands/mode-change.ts +6 -5
  55. package/corpus/templates/design/app/pages/design-editor/commands/publish-visual-edit-pending.ts +21 -3
  56. package/corpus/templates/design/app/pages/design-editor/pending-edits.ts +4 -7
  57. package/corpus/templates/design/app/root.tsx +2 -20
  58. package/corpus/templates/design/app/routes/_index.tsx +1 -34
  59. package/corpus/templates/design/changelog/2026-09-25-fix-live-visual-edit-recovery-handoff-and-interaction-workfl.md +6 -0
  60. package/corpus/templates/design/changelog/2026-09-25-human-review-previews-show-the-actual-design-when-you-have-o.md +6 -0
  61. package/corpus/templates/design/changelog/2026-09-25-live-screens-recover-safely-from-interrupted-cross-screen-mo.md +6 -0
  62. package/corpus/templates/design/changelog/2026-09-26-canvas-focus-stays-on-toolbar-controls-when-a-live-preview-f.md +6 -0
  63. package/corpus/templates/design/changelog/2026-09-26-the-app-entry-now-opens-the-shared-sign-in-and-sign-up-scree.md +6 -0
  64. package/corpus/templates/design/server/plugins/auth.ts +0 -3
  65. package/corpus/templates/dispatch/app/root.tsx +2 -11
  66. package/corpus/templates/dispatch/app/routes/_index.tsx +1 -34
  67. package/corpus/templates/dispatch/server/plugins/setup-dispatch.ts +0 -3
  68. package/corpus/templates/factory/app/root.tsx +3 -15
  69. package/corpus/templates/factory/app/routes/_index.tsx +1 -34
  70. package/corpus/templates/factory/app/routes/home.tsx +1 -1
  71. package/corpus/templates/forms/AGENTS.md +1 -1
  72. package/corpus/templates/forms/app/root.tsx +2 -4
  73. package/corpus/templates/forms/app/routes/_index.tsx +1 -34
  74. package/corpus/templates/forms/server/plugins/auth.ts +0 -3
  75. package/corpus/templates/mail/CHANGELOG.md +8 -0
  76. package/corpus/templates/mail/app/root.tsx +2 -6
  77. package/corpus/templates/mail/app/routes/_index.tsx +1 -36
  78. package/corpus/templates/mail/app/routes/home.tsx +1 -1
  79. package/corpus/templates/mail/changelog/2026-09-26-the-app-entry-now-opens-the-shared-sign-in-and-sign-up-scree.md +6 -0
  80. package/corpus/templates/mail/server/plugins/auth.ts +0 -3
  81. package/corpus/templates/plan/app/root.tsx +7 -13
  82. package/corpus/templates/plan/app/routes/_index.tsx +1 -35
  83. package/corpus/templates/plan/app/routes/home.tsx +1 -1
  84. package/corpus/templates/plan/server/plugins/auth.ts +0 -3
  85. package/corpus/templates/slides/CHANGELOG.md +21 -0
  86. package/corpus/templates/slides/actions/get-deck.ts +49 -12
  87. package/corpus/templates/slides/app/root.tsx +1 -3
  88. package/corpus/templates/slides/app/routes/_index.tsx +1 -36
  89. package/corpus/templates/slides/app/routes/home.tsx +1 -1
  90. package/corpus/templates/slides/changelog/2026-09-25-human-review-previews-show-same-organization-slides-for-orga.md +6 -0
  91. package/corpus/templates/slides/changelog/2026-09-26-the-app-entry-now-opens-the-shared-sign-in-and-sign-up-scree.md +6 -0
  92. package/corpus/templates/slides/server/plugins/auth.ts +0 -3
  93. package/corpus/templates/tasks/AGENTS.md +1 -1
  94. package/corpus/templates/tasks/README.md +1 -1
  95. package/corpus/templates/tasks/app/root.tsx +2 -11
  96. package/corpus/templates/tasks/app/routes/_index.tsx +1 -37
  97. package/corpus/templates/tasks/app/routes/home.tsx +1 -1
  98. package/dist/cli/design-connect.d.ts +1 -0
  99. package/dist/cli/design-connect.js +94 -32
  100. package/dist/client/auth/AuthPage.d.ts +1 -17
  101. package/dist/client/auth/AuthPage.js +7 -49
  102. package/dist/client/observability/OutputPreview.js +8 -2
  103. package/dist/client/sign-in-landing.d.ts +1 -0
  104. package/dist/client/sign-in-landing.js +8 -0
  105. package/dist/collab/awareness.d.ts +2 -2
  106. package/dist/deploy/workspace-deploy.js +32 -8
  107. package/dist/file-upload/actions/upload-image.d.ts +1 -1
  108. package/dist/provider-api/actions/custom-provider-registration.d.ts +7 -7
  109. package/dist/provider-api/actions/provider-api.d.ts +3 -3
  110. package/dist/server/auth-marketing.d.ts +0 -7
  111. package/dist/server/auth-marketing.js +0 -36
  112. package/dist/server/auth.d.ts +1 -10
  113. package/dist/server/index.d.ts +1 -1
  114. package/dist/server/index.js +1 -1
  115. package/dist/server/onboarding-html.d.ts +1 -12
  116. package/dist/server/onboarding-html.js +4 -817
  117. package/dist/shared/ssr-auth-redirect.d.ts +3 -3
  118. package/dist/shared/ssr-auth-redirect.js +4 -4
  119. package/dist/templates/chat/AGENTS.md +3 -3
  120. package/dist/templates/chat/app/root.tsx +3 -15
  121. package/dist/templates/chat/app/routes/_index.tsx +1 -37
  122. package/dist/templates/chat/server/plugins/auth.ts +0 -3
  123. package/dist/templates/default/AGENTS.md +2 -4
  124. package/dist/templates/default/DEVELOPING.md +3 -5
  125. package/dist/templates/default/app/root.tsx +2 -9
  126. package/dist/templates/default/app/routes/_index.tsx +8 -15
  127. package/package.json +5 -4
  128. package/src/templates/chat/AGENTS.md +3 -3
  129. package/src/templates/chat/app/root.tsx +3 -15
  130. package/src/templates/chat/app/routes/_index.tsx +1 -37
  131. package/src/templates/chat/server/plugins/auth.ts +0 -3
  132. package/src/templates/default/AGENTS.md +2 -4
  133. package/src/templates/default/DEVELOPING.md +3 -5
  134. package/src/templates/default/app/root.tsx +2 -9
  135. package/src/templates/default/app/routes/_index.tsx +8 -15
  136. package/dist/server/auth-marketing-locales.d.ts +0 -9
  137. package/dist/server/auth-marketing-locales.js +0 -1322
  138. package/dist/templates/chat/public/auth-marketing/chat.webp +0 -0
  139. package/src/templates/chat/public/auth-marketing/chat.webp +0 -0
@@ -1,37 +1 @@
1
- import { appPath } from "@agent-native/core/client/api-path";
2
- import { MarketingHome } from "@agent-native/toolkit/marketing";
3
-
4
- import { APP_TITLE } from "@/lib/app-config";
5
-
6
- const SEO_TITLE = APP_TITLE + " - Open Source AI app starter with actions";
7
- const SEO_DESCRIPTION =
8
- "Open Source starter for agent-native apps with durable chat, shared actions, UI state, tools, and a backend your agent can extend.";
9
-
10
- export function meta() {
11
- return [
12
- { title: SEO_TITLE },
13
- { name: "description", content: SEO_DESCRIPTION },
14
- { property: "og:title", content: SEO_TITLE },
15
- { property: "og:description", content: SEO_DESCRIPTION },
16
- { name: "twitter:card", content: "summary" },
17
- { name: "twitter:title", content: SEO_TITLE },
18
- { name: "twitter:description", content: SEO_DESCRIPTION },
19
- ];
20
- }
21
-
22
- export default function MarketingHomeRoute() {
23
- return (
24
- <MarketingHome
25
- appName={APP_TITLE}
26
- tagline="Start from a chat-first agent-native app and add actions, screens, and workflows as you grow."
27
- description={SEO_DESCRIPTION}
28
- valueProps={[
29
- "Full-page chat with durable threads and tool call history",
30
- "Use shared actions from chat, UI, HTTP, MCP, A2A, and CLI",
31
- "Plug in your own agent runtime or use the included app-agent loop",
32
- ]}
33
- primaryActionHref={appPath("/home")}
34
- secondaryActionHref={appPath("/sign-in")}
35
- />
36
- );
37
- }
1
+ export { signInLandingLoader as loader } from "@agent-native/core/client/sign-in-landing";
@@ -7,9 +7,6 @@ export default createAuthPlugin({
7
7
  workspaceAppPublicPaths: ["/"],
8
8
  marketing: {
9
9
  appName: appTitle,
10
- screenshotPath: "/auth-marketing/chat.webp",
11
- screenshotWidth: 914,
12
- screenshotHeight: 818,
13
10
  learnMoreUrl: "https://agent-native.com/apps/chat",
14
11
  tagline:
15
12
  "Start from a chat-first agent-native app and add actions, screens, and workflows as you grow.",
@@ -3,15 +3,25 @@
3
3
  All notable user-facing changes to Clips are documented here. Open it any time
4
4
  from the command menu (Cmd+K → "What's new") or from Settings.
5
5
 
6
+ ## 2026-09-26
7
+
8
+ ### Changed
9
+
10
+ - The app entry now opens the shared sign-in and sign-up screen instead of a separate marketing page.
11
+
6
12
  ## 2026-09-25
7
13
 
8
14
  ### Improved
9
15
 
16
+ - Connect Builder storage by creating an account in one click.
17
+ - Public clip embeds and meeting notes show richer link previews.
10
18
  - The no-comments sidebar gives viewers a concise reason to try Clips and a clear path to sign up.
11
19
  - Shared clips remember your sidebar choice and help new viewers understand why to sign up.
12
20
 
13
21
  ### Fixed
14
22
 
23
+ - Clips desktop sign-in now accepts authenticator codes when two-step verification is enabled.
24
+ - Keep Builder login state after blocked popups and show feedback while retrying storage connection checks
15
25
  - Clips clears a stale recording overlay after an interrupted save
16
26
  - Concurrent workflow requests no longer replace an active generation.
17
27
  - Generated workflows stay tied to the request that created them.
@@ -382,12 +382,6 @@ function ClipsExtensionAuthBridge() {
382
382
  );
383
383
  }
384
384
 
385
- function AppContent() {
386
- const location = useLocation();
387
- if (location.pathname === "/") return <Outlet />;
388
- return <PrivateAppContent />;
389
- }
390
-
391
385
  function PrivateAppContent() {
392
386
  const location = useLocation();
393
387
  const { status: sessionStatus } = useSession();
@@ -429,9 +423,7 @@ export default function Root() {
429
423
  const location = useLocation();
430
424
  const loaderData = useLoaderData<typeof loader>();
431
425
  const [queryClient] = useState(() => createAgentNativeQueryClient());
432
- const isMarketingHome = location.pathname === "/";
433
- const isPublicPath =
434
- isMarketingHome || isStandalonePublicPath(location.pathname);
426
+ const isPublicPath = isStandalonePublicPath(location.pathname);
435
427
  const legacyRecordingPath = isLegacyRecordingPath(location.pathname);
436
428
  const publicSharePath = location.pathname.startsWith("/share/");
437
429
  return (
@@ -461,7 +453,7 @@ export default function Root() {
461
453
  persistPreference: !isPublicPath,
462
454
  }}
463
455
  >
464
- <AppContent />
456
+ <PrivateAppContent />
465
457
  </AppProviders>
466
458
  </AppToolkitProvider>
467
459
  );
@@ -1,33 +1 @@
1
- import { appPath } from "@agent-native/core/client/api-path";
2
- import { MarketingHome } from "@agent-native/toolkit/marketing";
3
-
4
- const SEO_TITLE = "Clips - Open Source screen recorder";
5
- const SEO_DESCRIPTION =
6
- "Open Source screen recorder and meeting-notes app with AI transcripts, summaries, search, dictation, and agent-readable share links.";
7
-
8
- export function meta() {
9
- return [
10
- { title: SEO_TITLE },
11
- {
12
- name: "description",
13
- content: SEO_DESCRIPTION,
14
- },
15
- { property: "og:title", content: SEO_TITLE },
16
- { property: "og:description", content: SEO_DESCRIPTION },
17
- { name: "twitter:card", content: "summary" },
18
- { name: "twitter:title", content: SEO_TITLE },
19
- { name: "twitter:description", content: SEO_DESCRIPTION },
20
- ];
21
- }
22
-
23
- export default function MarketingHomeRoute() {
24
- return (
25
- <MarketingHome
26
- appName="Clips"
27
- tagline={SEO_TITLE}
28
- description={SEO_DESCRIPTION}
29
- primaryActionHref={appPath("/home")}
30
- secondaryActionHref={appPath("/sign-in")}
31
- />
32
- );
33
- }
1
+ export { signInLandingLoader as loader } from "@agent-native/core/client/sign-in-landing";
@@ -533,9 +533,8 @@ export default function ShareRoute() {
533
533
  status: sessionStatus,
534
534
  retry: retrySession,
535
535
  } = useSession();
536
- // appPath("/") always renders the public marketing shell (root.tsx's
537
- // isMarketingHome), even for a signed-in viewer - never use it as a
538
- // signed-in destination.
536
+ // The root entry is public, even for signed-in viewers; keep private
537
+ // destinations on the app's home route.
539
538
  const homeHref = session ? appPath("/home") : appPath("/");
540
539
  const retriedUnavailableSessionRef = useRef(false);
541
540
  const requestAccess = useActionMutation<
@@ -0,0 +1,6 @@
1
+ ---
2
+ type: changed
3
+ date: 2026-09-26
4
+ ---
5
+
6
+ The app entry now opens the shared sign-in and sign-up screen instead of a separate marketing page.
@@ -14,9 +14,6 @@ export default createAuthPlugin({
14
14
  mountGoogleOAuthRoutes: false,
15
15
  marketing: {
16
16
  appName: "Clips",
17
- screenshotPath: "/auth-marketing/clips.webp",
18
- screenshotWidth: 914,
19
- screenshotHeight: 818,
20
17
  learnMoreUrl: "https://agent-native.com/apps/clips",
21
18
  tagline:
22
19
  "Your AI agent transcribes, summarizes, and searches everything you record alongside you.",
@@ -417,7 +417,6 @@ export default function Root() {
417
417
  // Public document paths (/p/*) SSR real content without the ClientOnly gate
418
418
  // so crawlers and unauthenticated visitors receive full markup on first visit.
419
419
  const isPublicPath = location.pathname.startsWith("/p/");
420
- const isMarketingHome = location.pathname === "/";
421
420
 
422
421
  // Content's 3-way theme cycle (system/light/dark) animates the transition;
423
422
  // pass disableThemeTransitions={false} to restore that behaviour.
@@ -426,12 +425,12 @@ export default function Root() {
426
425
  // a different toasting system.
427
426
  const contentToaster = <Sonner closeButton position="bottom-left" />;
428
427
 
429
- if (isPublicPath || isMarketingHome) {
428
+ if (isPublicPath) {
430
429
  return (
431
430
  <AppToolkitProvider>
432
431
  <AppProviders
433
432
  queryClient={queryClient}
434
- isPublicPath={isPublicPath || isMarketingHome}
433
+ isPublicPath={isPublicPath}
435
434
  disableThemeTransitions={false}
436
435
  toaster={contentToaster}
437
436
  i18n={{
@@ -1,33 +1 @@
1
- import { appPath } from "@agent-native/core/client/api-path";
2
- import { MarketingHome } from "@agent-native/toolkit/marketing";
3
-
4
- const SEO_TITLE = "Content - Open Source, agent-friendly Obsidian alternative";
5
- const SEO_DESCRIPTION =
6
- "Open Source MDX editor for local docs, knowledge bases, and content systems, with custom blocks and agent-assisted editing.";
7
-
8
- export function meta() {
9
- return [
10
- { title: SEO_TITLE },
11
- {
12
- name: "description",
13
- content: SEO_DESCRIPTION,
14
- },
15
- { property: "og:title", content: SEO_TITLE },
16
- { property: "og:description", content: SEO_DESCRIPTION },
17
- { name: "twitter:card", content: "summary" },
18
- { name: "twitter:title", content: SEO_TITLE },
19
- { name: "twitter:description", content: SEO_DESCRIPTION },
20
- ];
21
- }
22
-
23
- export default function MarketingHomeRoute() {
24
- return (
25
- <MarketingHome
26
- appName="Content"
27
- tagline={SEO_TITLE}
28
- description={SEO_DESCRIPTION}
29
- primaryActionHref={appPath("/home")}
30
- secondaryActionHref={appPath("/sign-in")}
31
- />
32
- );
33
- }
1
+ export { signInLandingLoader as loader } from "@agent-native/core/client/sign-in-landing";
@@ -6,9 +6,6 @@ export default createAuthPlugin({
6
6
  workspaceAppPublicPaths: ["/"],
7
7
  marketing: {
8
8
  appName: "Content",
9
- screenshotPath: "/auth-marketing/content.webp",
10
- screenshotWidth: 914,
11
- screenshotHeight: 818,
12
9
  learnMoreUrl: "https://agent-native.com/apps/content",
13
10
  tagline:
14
11
  "Open-source Obsidian for MDX: your AI agent edits local docs, creates custom blocks, and organizes everything alongside you.",
@@ -9,14 +9,7 @@ import { getLocaleInitScript } from "@agent-native/core/client/i18n";
9
9
  import { getThemeInitScript } from "@agent-native/core/client/ui";
10
10
  import { useQueryClient } from "@tanstack/react-query";
11
11
  import { useState } from "react";
12
- import {
13
- Links,
14
- Meta,
15
- Outlet,
16
- Scripts,
17
- ScrollRestoration,
18
- useLocation,
19
- } from "react-router";
12
+ import { Links, Meta, Outlet, Scripts, ScrollRestoration } from "react-router";
20
13
  import type { LinksFunction } from "react-router";
21
14
 
22
15
  import { CrmCommandMenu } from "@/components/layout/CrmCommandMenu";
@@ -95,16 +88,10 @@ function AppContent() {
95
88
 
96
89
  export default function Root() {
97
90
  const [queryClient] = useState(() => createAgentNativeQueryClient());
98
- const location = useLocation();
99
- const isMarketingPath = location.pathname === "/";
100
91
  return (
101
92
  <AppToolkitProvider>
102
- <AppProviders
103
- queryClient={queryClient}
104
- isPublicPath={isMarketingPath}
105
- i18n={{ catalog: i18nCatalog }}
106
- >
107
- {isMarketingPath ? <Outlet /> : <AppContent />}
93
+ <AppProviders queryClient={queryClient} i18n={{ catalog: i18nCatalog }}>
94
+ <AppContent />
108
95
  </AppProviders>
109
96
  </AppToolkitProvider>
110
97
  );
@@ -1,36 +1 @@
1
- import { appPath } from "@agent-native/core/client/api-path";
2
- import { MarketingHome } from "@agent-native/toolkit/marketing";
3
-
4
- const SEO_TITLE =
5
- "CRM - Open Source agent-native customer relationship manager";
6
- const SEO_DESCRIPTION =
7
- "Open Source CRM for accounts, people, opportunities, tasks, and connected customer data, with safe actions your agent can use.";
8
-
9
- export function meta() {
10
- return [
11
- { title: SEO_TITLE },
12
- { name: "description", content: SEO_DESCRIPTION },
13
- { property: "og:title", content: SEO_TITLE },
14
- { property: "og:description", content: SEO_DESCRIPTION },
15
- { name: "twitter:card", content: "summary" },
16
- { name: "twitter:title", content: SEO_TITLE },
17
- { name: "twitter:description", content: SEO_DESCRIPTION },
18
- ];
19
- }
20
-
21
- export default function MarketingHomeRoute() {
22
- return (
23
- <MarketingHome
24
- appName="CRM"
25
- tagline="A complete Native SQL CRM or a connected companion grounded in its source system."
26
- description={SEO_DESCRIPTION}
27
- valueProps={[
28
- "Run accounts, people, opportunities, tasks, and cadence on Native SQL",
29
- "Connect scoped HubSpot or Salesforce records without copying credentials",
30
- "Use the same safe actions from the UI or your CRM agent",
31
- ]}
32
- primaryActionHref={appPath("/home")}
33
- secondaryActionHref={appPath("/sign-in")}
34
- />
35
- );
36
- }
1
+ export { signInLandingLoader as loader } from "@agent-native/core/client/sign-in-landing";
@@ -8,7 +8,7 @@ export function meta() {
8
8
  return [{ title: "My work · CRM" }];
9
9
  }
10
10
 
11
- // Private app entry retained at /home; / serves the public marketing page.
11
+ // Private app entry retained at /home; / redirects to shared sign-in/signup.
12
12
  export default function WorkRoute() {
13
13
  const overview = useActionQuery<CrmOverview>(
14
14
  "get-crm-overview" as never,
@@ -15967,7 +15967,6 @@ export const editorChromeBridgeScript: string = `"use strict";
15967
15967
  if (!dragEl) return;
15968
15968
  var outsideOnDrop = ev ? isOutsideIframeViewport(ev.clientX, ev.clientY) || crossScreenClaimedByHost : false;
15969
15969
  if (ev && !isGroupDrag && (outsideOnDrop || designCanvasBoardSurface)) {
15970
- var sourceDeleteRequestId = activeCrossScreenDeleteRequestId;
15971
15970
  postCrossScreenDrag("end", dragEl, ev, {
15972
15971
  duplicate: duplicatedForDrag,
15973
15972
  modifiers: {
@@ -15986,21 +15985,6 @@ export const editorChromeBridgeScript: string = `"use strict";
15986
15985
  postElementSelect(selectedEl);
15987
15986
  } else {
15988
15987
  restoreSourceDragPosition();
15989
- if (crossScreenClaimedByHost && sourceDeleteRequestId) {
15990
- var selector = getSelector(dragEl);
15991
- var sourceId = getSourceId(dragEl);
15992
- var selectorCandidates = [selector];
15993
- if (sourceId) {
15994
- selectorCandidates.push(
15995
- '[data-agent-native-node-id="' + CSS.escape(sourceId) + '"]'
15996
- );
15997
- }
15998
- concealPendingRuntimeDelete(
15999
- selector,
16000
- selectorCandidates,
16001
- sourceDeleteRequestId
16002
- );
16003
- }
16004
15988
  }
16005
15989
  return;
16006
15990
  }
@@ -19667,8 +19651,31 @@ export const editorChromeBridgeScript: string = `"use strict";
19667
19651
  requestId: e.data.requestId,
19668
19652
  applied: Boolean(e.data.applied)
19669
19653
  });
19654
+ var cancelRuntimeStructureDelete = e.data.cancelRuntimeStructureDelete;
19655
+ var postRuntimeStructureDeleteCancellationResult = function(sourcePresentOverride) {
19656
+ if (!cancelRuntimeStructureDelete || typeof cancelRuntimeStructureDelete.transactionId !== "string") {
19657
+ return;
19658
+ }
19659
+ var restoredSource = findRuntimeTarget(
19660
+ String(cancelRuntimeStructureDelete.selector || ""),
19661
+ Array.isArray(cancelRuntimeStructureDelete.selectorCandidates) ? cancelRuntimeStructureDelete.selectorCandidates : []
19662
+ );
19663
+ window.parent.postMessage(
19664
+ {
19665
+ type: "runtime-structure-delete-cancelled",
19666
+ requestId: String(e.data.requestId || ""),
19667
+ transactionId: cancelRuntimeStructureDelete.transactionId,
19668
+ routePath: window.location.pathname + window.location.search,
19669
+ sourcePresent: typeof sourcePresentOverride === "boolean" ? sourcePresentOverride : Boolean(restoredSource)
19670
+ },
19671
+ "*"
19672
+ );
19673
+ };
19670
19674
  var move = pendingStructureMoves[e.data.requestId];
19671
- if (!move) return;
19675
+ if (!move) {
19676
+ postRuntimeStructureDeleteCancellationResult();
19677
+ return;
19678
+ }
19672
19679
  delete pendingStructureMoves[e.data.requestId];
19673
19680
  var moveWasInsert = Boolean(move.origin && "inserted" in move.origin);
19674
19681
  var moveWasRemoval = Boolean(move.origin && "removed" in move.origin);
@@ -19689,6 +19696,7 @@ export const editorChromeBridgeScript: string = `"use strict";
19689
19696
  }
19690
19697
  }
19691
19698
  refreshOverlays();
19699
+ postRuntimeStructureDeleteCancellationResult();
19692
19700
  return;
19693
19701
  }
19694
19702
  if (moveWasRemoval) {
@@ -19706,6 +19714,9 @@ export const editorChromeBridgeScript: string = `"use strict";
19706
19714
  }
19707
19715
  }
19708
19716
  refreshOverlays();
19717
+ postRuntimeStructureDeleteCancellationResult(
19718
+ Boolean(move.el && move.el.isConnected)
19719
+ );
19709
19720
  return;
19710
19721
  }
19711
19722
  if (e.data.applied) {
@@ -19730,6 +19741,7 @@ export const editorChromeBridgeScript: string = `"use strict";
19730
19741
  }
19731
19742
  if (hoveredEl === move.el) hoveredEl = null;
19732
19743
  refreshOverlays();
19744
+ postRuntimeStructureDeleteCancellationResult();
19733
19745
  return;
19734
19746
  }
19735
19747
  if (move.el && move.el.isConnected && move.origin && "prevParent" in move.origin && move.origin.prevParent && move.origin.prevParent.isConnected) {
@@ -19752,6 +19764,7 @@ export const editorChromeBridgeScript: string = `"use strict";
19752
19764
  postElementSelect(selectedEl);
19753
19765
  }
19754
19766
  }
19767
+ postRuntimeStructureDeleteCancellationResult();
19755
19768
  return;
19756
19769
  }
19757
19770
  if (e.data.type === "replace-document-content") {
@@ -3,19 +3,49 @@
3
3
  All notable user-facing changes to Design are documented here. Open it any time
4
4
  from the command menu (Cmd+K → "What's new") or from Settings.
5
5
 
6
+ ## 2026-09-26
7
+
8
+ ### Fixed
9
+
10
+ - Canvas focus stays on toolbar controls when a live preview finishes loading
11
+
12
+ ### Changed
13
+
14
+ - The app entry now opens the shared sign-in and sign-up screen instead of a separate marketing page.
15
+
6
16
  ## 2026-09-25
7
17
 
8
18
  ### Added
9
19
 
20
+ - Design home quick actions now adapt to your onboarding role and appear only when an AI provider is ready.
10
21
  - Chat messages can be reverted to their autosaved version, including a shortcut to restore the start of a chat.
11
22
 
12
23
  ### Improved
13
24
 
25
+ - Attach Figma frames and websites from focused dialogs while keeping prompt drafts and uploaded design.md files intact.
26
+ - Recent designs now use the same consistent library card layout as templates.
27
+ - Start designs from a focused prompt with editable suggestions, template previews, and a searchable recent-design library.
28
+ - Open an editable template with one click, or use its menu to preview interactive screens without changing your draft.
29
+ - Run Design template HTML as an interactive live preview, including working controls and safe navigation between local template files.
30
+ - Browse design systems and references from the shared context menu, create a design system from its empty state, and manage uploaded files directly inside the prompt.
31
+ - Shared designs, systems, and templates show their titles and descriptions in previews.
32
+ - Start designs in one click, attach design, slide, and Figma references in the home composer, or open Figma imports directly from the toolbar.
33
+ - Import Figma files directly from the toolbar and find design references in a simpler context menu.
34
+ - Use templates directly from full preview
35
+ - Use text-first menus for import and template actions
36
+ - Welcome new creators with a more encouraging first-design prompt.
14
37
  - Design-system empty states show one creation action
15
38
  - Live preview snapshots stay private until an editor signs in and enables collaboration.
16
39
 
17
40
  ### Fixed
18
41
 
42
+ - Failed Figma imports no longer leave empty designs behind, and malformed preview links stay safely on the current screen.
43
+ - Fix live visual-edit recovery, handoff, and interaction workflows.
44
+ - Human Review previews show the actual design when you have organization admin access.
45
+ - Live screens recover safely from interrupted cross-screen moves and keep pending edits accessible before switching to Interact.
46
+ - Searching shared designs stays visible even when you have no designs of your own.
47
+ - Shared-only work now opens in the Recent library without requiring a manual filter change, and template copies can safely retry.
48
+ - Template retries now start a fresh copy when the request changes while preserving safe retries for the same request.
19
49
  - Builder design-system failures preserve readable JSON errors behind Cloudflare.
20
50
  - Standalone HTML exports with multiple screens now show each screen in its own
21
51
  viewport instead of overlapping.
@@ -24,6 +54,7 @@ from the command menu (Cmd+K → "What's new") or from Settings.
24
54
  - Live canvas sharing requires an account, with a sign-up path for signed-out owners.
25
55
  - Cross-screen moves preserve Flex and Grid sizing through undo and redo.
26
56
  - Moving a layer from one live app screen into another now lands it instead of failing with "Could not move that layer", and a failed move no longer leaves the layer stuck to the cursor.
57
+ - Timed-out live move rollbacks retry before another move is admitted.
27
58
 
28
59
  ## 2026-09-24
29
60
 
@@ -212,7 +212,7 @@ export default defineAction({
212
212
  ? normalizeBridgeUrl(args.bridgeUrl)
213
213
  : undefined;
214
214
  const rootPath = args.routeManifest?.rootPath ?? args.rootPath;
215
- const id =
215
+ let id =
216
216
  args.id ?? stableConnectionId(devServerUrl, rootPath, ownerEmail, orgId);
217
217
  const rawRoutes = args.routeManifest?.routes ?? args.routes ?? [];
218
218
  const routes = rawRoutes.map((route) => ({
@@ -253,10 +253,13 @@ export default defineAction({
253
253
  // from devServerUrl + rootPath without user scoping, so two users on the
254
254
  // same devcontainer image collide). Detect that up front and fail with a
255
255
  // clear error instead of crashing on the primary-key insert below.
256
- const existing = await db
256
+ let existing = await db
257
257
  .select({
258
+ id: schema.designLocalhostConnections.id,
258
259
  ownerEmail: schema.designLocalhostConnections.ownerEmail,
259
260
  orgId: schema.designLocalhostConnections.orgId,
261
+ devServerUrl: schema.designLocalhostConnections.devServerUrl,
262
+ rootPath: schema.designLocalhostConnections.rootPath,
260
263
  bridgeUrl: schema.designLocalhostConnections.bridgeUrl,
261
264
  previewToken: schema.designLocalhostConnections.previewToken,
262
265
  bridgeToken: schema.designLocalhostConnections.bridgeToken,
@@ -265,6 +268,55 @@ export default defineAction({
265
268
  .where(eq(schema.designLocalhostConnections.id, id))
266
269
  .limit(1);
267
270
 
271
+ // Older CLI versions used a non-user-scoped connection ID. Reuse that
272
+ // credential only when this owner/org has one unambiguous row for the
273
+ // exact app URL and root; otherwise a new row could mint a token that an
274
+ // already-running bridge does not have.
275
+ if (!args.id && !existing[0] && rootPath) {
276
+ const priorConnections = await db
277
+ .select({
278
+ id: schema.designLocalhostConnections.id,
279
+ ownerEmail: schema.designLocalhostConnections.ownerEmail,
280
+ orgId: schema.designLocalhostConnections.orgId,
281
+ devServerUrl: schema.designLocalhostConnections.devServerUrl,
282
+ rootPath: schema.designLocalhostConnections.rootPath,
283
+ bridgeUrl: schema.designLocalhostConnections.bridgeUrl,
284
+ previewToken: schema.designLocalhostConnections.previewToken,
285
+ bridgeToken: schema.designLocalhostConnections.bridgeToken,
286
+ })
287
+ .from(schema.designLocalhostConnections)
288
+ .where(
289
+ and(
290
+ ownerOrgScope,
291
+ eq(schema.designLocalhostConnections.devServerUrl, devServerUrl),
292
+ eq(schema.designLocalhostConnections.rootPath, rootPath),
293
+ ...(requestedBridgeUrl
294
+ ? [
295
+ eq(
296
+ schema.designLocalhostConnections.bridgeUrl,
297
+ requestedBridgeUrl,
298
+ ),
299
+ ]
300
+ : []),
301
+ ),
302
+ )
303
+ .limit(2);
304
+ if (priorConnections.length > 1) {
305
+ throw new Error(
306
+ "Multiple existing localhost connections match this app. Pass the connection ID to choose which bridge to reuse.",
307
+ );
308
+ }
309
+ const prior = priorConnections[0];
310
+ if (
311
+ prior &&
312
+ prior.ownerEmail === ownerEmail &&
313
+ (prior.orgId ?? null) === orgId
314
+ ) {
315
+ id = prior.id;
316
+ existing = [prior];
317
+ }
318
+ }
319
+
268
320
  if (
269
321
  existing[0] &&
270
322
  (existing[0].ownerEmail !== ownerEmail ||
@@ -317,44 +369,53 @@ export default defineAction({
317
369
  updatedAt: now,
318
370
  };
319
371
 
320
- // Keep the read-only credential paired with the bridge credential on every
321
- // reconnect. A legacy row may contain an unrelated preview token from
322
- // before the deterministic pairing contract; preserving it makes the
323
- // next daemon restart fail again. setWhere keeps a cross-user conflict a
324
- // no-op, and the read-back below returns the winning row after a race.
325
- await db
326
- .insert(schema.designLocalhostConnections)
327
- .values({
328
- ...baseValues,
329
- previewToken: nextPreviewToken,
330
- bridgeToken: nextBridgeToken,
331
- createdAt: now,
332
- })
333
- .onConflictDoUpdate({
334
- target: schema.designLocalhostConnections.id,
335
- set: {
372
+ // The conflict update can keep a concurrently inserted bridge token.
373
+ // Derive and persist its preview token under the same row lock so the pair
374
+ // is committed atomically, including for legacy rows with a stale preview.
375
+ const {
376
+ bridgeToken: effectiveBridgeToken,
377
+ previewToken: effectivePreviewToken,
378
+ } = await db.transaction(async (tx) => {
379
+ const [stored] = await tx
380
+ .insert(schema.designLocalhostConnections)
381
+ .values({
336
382
  ...baseValues,
337
- bridgeToken: explicitToken
338
- ? nextBridgeToken
339
- : sql`coalesce(${schema.designLocalhostConnections.bridgeToken}, excluded.bridge_token)`,
340
383
  previewToken: nextPreviewToken,
341
- },
342
- setWhere: ownerOrgScope,
343
- });
384
+ bridgeToken: nextBridgeToken,
385
+ createdAt: now,
386
+ })
387
+ .onConflictDoUpdate({
388
+ target: schema.designLocalhostConnections.id,
389
+ set: {
390
+ ...baseValues,
391
+ bridgeToken: explicitToken
392
+ ? nextBridgeToken
393
+ : sql`coalesce(${schema.designLocalhostConnections.bridgeToken}, excluded.bridge_token)`,
394
+ previewToken: nextPreviewToken,
395
+ },
396
+ setWhere: ownerOrgScope,
397
+ })
398
+ .returning({
399
+ bridgeToken: schema.designLocalhostConnections.bridgeToken,
400
+ });
401
+ if (!stored?.bridgeToken) {
402
+ throw Object.assign(
403
+ new Error(
404
+ "The localhost connection could not be confirmed for this account. Refresh the connection and retry.",
405
+ ),
406
+ { errorCode: "localhost_connection_conflict" },
407
+ );
408
+ }
344
409
 
345
- // Return the token the row actually holds (owner-scoped, so a cross-user
346
- // no-op never leaks another user's token), not the one we minted — so
347
- // concurrent callers converge on the winner (no 401 on a lost race).
348
- const [stored] = await db
349
- .select({
350
- bridgeToken: schema.designLocalhostConnections.bridgeToken,
351
- previewToken: schema.designLocalhostConnections.previewToken,
352
- })
353
- .from(schema.designLocalhostConnections)
354
- .where(and(eq(schema.designLocalhostConnections.id, id), ownerOrgScope))
355
- .limit(1);
356
- const effectiveBridgeToken = stored?.bridgeToken ?? nextBridgeToken;
357
- const effectivePreviewToken = derivePreviewToken(effectiveBridgeToken);
410
+ const previewToken = derivePreviewToken(stored.bridgeToken);
411
+ await tx
412
+ .update(schema.designLocalhostConnections)
413
+ .set({ previewToken })
414
+ .where(
415
+ and(eq(schema.designLocalhostConnections.id, id), ownerOrgScope),
416
+ );
417
+ return { bridgeToken: stored.bridgeToken, previewToken };
418
+ });
358
419
 
359
420
  return {
360
421
  id,