@agent-native/core 0.197.0-nightly-20260929172956 → 0.197.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 (97) hide show
  1. package/corpus/README.md +1 -1
  2. package/corpus/templates/analytics/CHANGELOG.md +10 -0
  3. package/corpus/templates/assets/CHANGELOG.md +8 -0
  4. package/corpus/templates/calendar/CHANGELOG.md +18 -0
  5. package/corpus/templates/clips/CHANGELOG.md +19 -0
  6. package/corpus/templates/content/CHANGELOG.md +16 -0
  7. package/corpus/templates/content/actions/_database-property-setup.ts +33 -2
  8. package/corpus/templates/content/actions/_database-setup-discovery.ts +4 -4
  9. package/corpus/templates/content/actions/_property-utils.ts +9 -1
  10. package/corpus/templates/content/actions/_relation-values.ts +291 -0
  11. package/corpus/templates/content/actions/configure-document-property.ts +53 -1
  12. package/corpus/templates/content/actions/search-content-database-rows.ts +124 -0
  13. package/corpus/templates/content/actions/set-document-property.ts +21 -1
  14. package/corpus/templates/content/agent-native.config.ts +5 -0
  15. package/corpus/templates/content/app/components/editor/DocumentProperties.tsx +892 -189
  16. package/corpus/templates/content/app/components/editor/database/DatabaseView.tsx +7 -2
  17. package/corpus/templates/content/app/components/editor/database/navigation-state.ts +4 -1
  18. package/corpus/templates/content/app/hooks/use-content-database.ts +16 -2
  19. package/corpus/templates/content/app/hooks/use-document-properties.ts +65 -5
  20. package/corpus/templates/content/app/i18n-data.ts +28 -0
  21. package/corpus/templates/content/changelog/2026-09-28-link-rows-across-collections-with-relation-properties.md +6 -0
  22. package/corpus/templates/content/changelog/2026-09-29-related-pages-can-be-loaded-past-the-first-25-results.md +6 -0
  23. package/corpus/templates/content/parity/matrix.md +1 -1
  24. package/corpus/templates/content/parity/matrix.ts +1 -0
  25. package/corpus/templates/content/shared/api.ts +21 -0
  26. package/corpus/templates/content/shared/properties.ts +19 -0
  27. package/corpus/templates/crm/CHANGELOG.md +8 -0
  28. package/corpus/templates/design/CHANGELOG.md +33 -0
  29. package/corpus/templates/design/actions/clone-creative-context-design-native.ts +12 -3
  30. package/corpus/templates/design/actions/generate-design.ts +2 -29
  31. package/corpus/templates/design/actions/update-design.ts +33 -8
  32. package/corpus/templates/design/app/components/design/design-canvas/LocalNetworkAccessPrompt.tsx +2 -2
  33. package/corpus/templates/design/changelog/2026-09-29-design-tweak-controls-stay-intact-when-an-edit-contains-inva.md +6 -0
  34. package/corpus/templates/design/changelog/2026-09-29-the-chrome-fallback-guide-shows-the-local-network-allow-opti.md +6 -0
  35. package/corpus/templates/design/shared/tweak-definition-schema.ts +30 -0
  36. package/corpus/templates/dispatch/CHANGELOG.md +4 -0
  37. package/corpus/templates/mail/CHANGELOG.md +34 -0
  38. package/corpus/templates/mail/app/components/email/EmailList.tsx +29 -28
  39. package/corpus/templates/mail/app/components/layout/AppLayout.tsx +20 -8
  40. package/corpus/templates/mail/app/pages/InboxPage.tsx +34 -11
  41. package/corpus/templates/mail/changelog/2026-09-29-mail-loading-layout.md +6 -0
  42. package/corpus/templates/mail/changelog/2026-09-29-mail-shows-the-first-messages-sooner-and-keeps-them-visible-.md +6 -0
  43. package/corpus/templates/mail/server/lib/inbox-sync.ts +11 -7
  44. package/corpus/templates/slides/CHANGELOG.md +19 -0
  45. package/dist/cli/create-tui.d.ts +36 -0
  46. package/dist/cli/create-tui.js +604 -0
  47. package/dist/cli/create.d.ts +23 -1
  48. package/dist/cli/create.js +667 -136
  49. package/dist/cli/index.js +26 -5
  50. package/dist/client/AppShellSkeleton.js +97 -54
  51. package/dist/collab/awareness.d.ts +2 -2
  52. package/dist/collab/routes.d.ts +1 -1
  53. package/dist/file-upload/actions/upload-image.d.ts +2 -2
  54. package/dist/localization/core-messages/ar-SA.js +2 -2
  55. package/dist/localization/core-messages/de-DE.js +2 -2
  56. package/dist/localization/core-messages/en-US.d.ts +2 -2
  57. package/dist/localization/core-messages/en-US.js +2 -2
  58. package/dist/localization/core-messages/es-ES.js +2 -2
  59. package/dist/localization/core-messages/fr-FR.js +2 -2
  60. package/dist/localization/core-messages/hi-IN.js +2 -2
  61. package/dist/localization/core-messages/ja-JP.js +2 -2
  62. package/dist/localization/core-messages/ko-KR.js +2 -2
  63. package/dist/localization/core-messages/pt-BR.js +2 -2
  64. package/dist/localization/core-messages/zh-CN.js +2 -2
  65. package/dist/localization/core-messages/zh-TW.js +2 -2
  66. package/dist/localization/core-messages.d.ts +2 -2
  67. package/dist/localization/default-messages.js +2 -2
  68. package/dist/org/index.d.ts +2 -2
  69. package/dist/progress/routes.d.ts +1 -1
  70. package/dist/provider-api/actions/custom-provider-registration.d.ts +4 -4
  71. package/dist/provider-api/actions/provider-api.d.ts +9 -9
  72. package/dist/secrets/routes.d.ts +10 -10
  73. package/dist/server/agent-engine-default-model-route.d.ts +1 -1
  74. package/dist/templates/default/app/i18n/ar-SA.ts +3 -2
  75. package/dist/templates/default/app/i18n/de-DE.ts +3 -2
  76. package/dist/templates/default/app/i18n/en-US.ts +2 -2
  77. package/dist/templates/default/app/i18n/es-ES.ts +3 -2
  78. package/dist/templates/default/app/i18n/fr-FR.ts +3 -2
  79. package/dist/templates/default/app/i18n/hi-IN.ts +2 -3
  80. package/dist/templates/default/app/i18n/ja-JP.ts +2 -2
  81. package/dist/templates/default/app/i18n/ko-KR.ts +2 -2
  82. package/dist/templates/default/app/i18n/pt-BR.ts +2 -2
  83. package/dist/templates/default/app/i18n/zh-CN.ts +2 -2
  84. package/dist/templates/default/app/i18n/zh-TW.ts +2 -2
  85. package/docs/content/versioning-and-stability.mdx +3 -2
  86. package/package.json +7 -6
  87. package/src/templates/default/app/i18n/ar-SA.ts +3 -2
  88. package/src/templates/default/app/i18n/de-DE.ts +3 -2
  89. package/src/templates/default/app/i18n/en-US.ts +2 -2
  90. package/src/templates/default/app/i18n/es-ES.ts +3 -2
  91. package/src/templates/default/app/i18n/fr-FR.ts +3 -2
  92. package/src/templates/default/app/i18n/hi-IN.ts +2 -3
  93. package/src/templates/default/app/i18n/ja-JP.ts +2 -2
  94. package/src/templates/default/app/i18n/ko-KR.ts +2 -2
  95. package/src/templates/default/app/i18n/pt-BR.ts +2 -2
  96. package/src/templates/default/app/i18n/zh-CN.ts +2 -2
  97. package/src/templates/default/app/i18n/zh-TW.ts +2 -2
@@ -0,0 +1,30 @@
1
+ import { z } from "zod";
2
+
3
+ export const tweakDefinitionsSchema = z.array(
4
+ z.object({
5
+ id: z.string(),
6
+ label: z.string(),
7
+ type: z.enum([
8
+ "color-swatch",
9
+ "color-swatches",
10
+ "segment",
11
+ "slider",
12
+ "toggle",
13
+ ]),
14
+ options: z
15
+ .array(
16
+ z.object({
17
+ label: z.string(),
18
+ value: z.string(),
19
+ color: z.string().optional(),
20
+ }),
21
+ )
22
+ .optional(),
23
+ min: z.number().optional(),
24
+ max: z.number().optional(),
25
+ step: z.number().optional(),
26
+ defaultValue: z.union([z.string(), z.number(), z.boolean()]),
27
+ cssVar: z.string().optional(),
28
+ unit: z.string().optional(),
29
+ }),
30
+ );
@@ -5,6 +5,10 @@ time from the command menu (Cmd+K → "What's new").
5
5
 
6
6
  ## 2026-09-28
7
7
 
8
+ ### Improved
9
+
10
+ - Dispatch admin pages now use a consistent settings layout.
11
+
8
12
  ### Fixed
9
13
 
10
14
  - Desktop sign-in now carries over to Mail and other eligible apps.
@@ -3,16 +3,50 @@
3
3
  All notable user-facing changes to Agent-Native Mail are documented here. Open it any
4
4
  time from the command menu (Cmd+K → "What's new") or from Settings.
5
5
 
6
+ ## 2026-09-29
7
+
8
+ ### Improved
9
+
10
+ - Mail loading screens match the current inbox layout.
11
+ - Mail shows the first messages sooner and keeps them visible while background sync finishes.
12
+
13
+ ### Fixed
14
+
15
+ - Existing compose drafts keep their attachments when revised
16
+ - Scheduled email changes refresh the inbox and schedule list
17
+
6
18
  ## 2026-09-28
7
19
 
8
20
  ### Improved
9
21
 
22
+ - AI triage now appears before Automations in Mail settings.
23
+ - The app canvas now meets the right chat sidebar without a dark seam or rounded corner.
24
+ - Google sign-in shows progress while authentication finishes.
25
+ - General and AI triage settings now share a consistent full-width layout.
26
+ - Mail background work stays within its time budget and checks fewer connected accounts per sweep.
27
+ - Mail onboarding saves inbox rules before provider setup and sorts recent mail after connection.
28
+ - Mail syncs large inboxes progressively with shared Gmail quota control and resumable bulk archiving.
29
+ - Settings now opens in the new layout, with Account, Connections, Agent, Organization, and app sections.
10
30
  - Builder credit notices appear above sidebar actions in a full-width layout.
11
31
  - Mail automation rules use a consistent neutral color treatment.
12
32
  - Open the current agent conversation in a full-page view
13
33
 
14
34
  ### Fixed
15
35
 
36
+ - Your inbox now loads without getting stuck on loading placeholders.
37
+ - Inbox category tabs stay in the inbox view
38
+ - Inbox rule sorting now offers a retry when starting fails and reports undo errors.
39
+ - Large archives finish without manual retries
40
+ - Mail actions follow the active inbox tab and ignore rows retained from previous filters
41
+ - Mail automations start from the current inbox point after setup or a sync gap.
42
+ - Mail preserves sorting progress and undo access when a retry is needed
43
+ - Mail retries Gmail status errors and avoids repeating Google sign-in in manual setup.
44
+ - Mail setup keeps saved rules available when browser storage or onboarding completion fails.
45
+ - Mail setup stays recoverable when model settings or sorting status checks fail.
46
+ - Mail updates an existing compose draft in place when you ask for a revision.
47
+ - Rule backfills show why recent mail could not be processed
48
+ - Scheduled Mail jobs recover after interrupted sweeps without duplicating sends
49
+ - Search results no longer trigger a duplicate mailbox fetch
16
50
  - Avoid automatic retries after Gmail quota cooldowns
17
51
 
18
52
  ## 2026-09-27
@@ -196,7 +196,6 @@ interface EmailListProps {
196
196
  emails?: EmailMessage[];
197
197
  isLoading?: boolean;
198
198
  isFetching?: boolean;
199
- isSyncing?: boolean;
200
199
  emailsError?: Error | null;
201
200
  accountErrors?: AccountError[];
202
201
  labels?: Label[];
@@ -351,22 +350,40 @@ function MailLoadingState({
351
350
  return (
352
351
  <div className="flex h-full flex-col" ref={containerRef}>
353
352
  <div className="flex-1 overflow-y-auto">
354
- {Array.from({ length: 12 }).map((_, i) => (
355
- <div
356
- key={i}
357
- className="flex h-[48px] items-center gap-3 px-4 sm:h-[38px]"
358
- >
359
- <div className="h-2 w-2 shrink-0 animate-pulse rounded-full bg-muted" />
360
- <div className="h-3 w-28 animate-pulse rounded bg-muted" />
361
- <div className="h-3 flex-1 animate-pulse rounded bg-muted" />
362
- <div className="h-3 w-12 animate-pulse rounded bg-muted" />
363
- </div>
364
- ))}
353
+ <MailLoadingRows count={12} />
365
354
  </div>
366
355
  </div>
367
356
  );
368
357
  }
369
358
 
359
+ function MailLoadingRows({ count }: { count: number }) {
360
+ return (
361
+ <div aria-hidden="true">
362
+ {Array.from({ length: count }, (_, index) => (
363
+ <div
364
+ key={index}
365
+ className="email-list-row flex h-[48px] items-center px-3 sm:h-[38px]"
366
+ >
367
+ <div className="me-2 flex h-full w-5 shrink-0 items-center justify-center">
368
+ <div className="h-[7px] w-[7px] animate-pulse rounded-full bg-muted" />
369
+ </div>
370
+ <div className="me-3 flex w-[100px] shrink-0 items-center sm:w-[160px]">
371
+ <div className="h-3 w-3/4 animate-pulse rounded bg-muted" />
372
+ </div>
373
+ {index % 2 === 1 && (
374
+ <div className="me-2 h-4 w-14 shrink-0 animate-pulse rounded bg-muted" />
375
+ )}
376
+ <div className="flex min-w-0 flex-1 items-center gap-1.5 overflow-hidden">
377
+ <div className="h-3 w-36 shrink-0 animate-pulse rounded bg-muted" />
378
+ <div className="h-3 min-w-0 flex-1 animate-pulse rounded bg-muted" />
379
+ </div>
380
+ <div className="ms-2 h-3 w-12 shrink-0 animate-pulse rounded bg-muted" />
381
+ </div>
382
+ ))}
383
+ </div>
384
+ );
385
+ }
386
+
370
387
  const RATE_LIMIT_RETRY_MS = 60_000;
371
388
 
372
389
  function getRateLimitRetryMs(error: {
@@ -488,7 +505,6 @@ export function EmailList({
488
505
  emails: emailsProp,
489
506
  isLoading: isLoadingProp,
490
507
  isFetching: isFetchingProp,
491
- isSyncing = false,
492
508
  emailsError: emailsErrorProp,
493
509
  accountErrors: accountErrorsProp,
494
510
  labels: labelsProp,
@@ -2779,21 +2795,6 @@ export function EmailList({
2779
2795
  );
2780
2796
  })}
2781
2797
  </div>
2782
- {isSyncing && (
2783
- <div aria-hidden="true">
2784
- {Array.from({ length: 4 }).map((_, index) => (
2785
- <div
2786
- key={index}
2787
- className="flex h-[48px] items-center gap-3 px-4 sm:h-[38px]"
2788
- >
2789
- <div className="h-2 w-2 shrink-0 animate-pulse rounded-full bg-muted" />
2790
- <div className="h-3 w-28 animate-pulse rounded bg-muted" />
2791
- <div className="h-3 flex-1 animate-pulse rounded bg-muted" />
2792
- <div className="h-3 w-12 animate-pulse rounded bg-muted" />
2793
- </div>
2794
- ))}
2795
- </div>
2796
- )}
2797
2798
  <AlertDialog
2798
2799
  open={retryUncertainJobId !== null}
2799
2800
  onOpenChange={(open) => !open && setRetryUncertainJobId(null)}
@@ -663,7 +663,12 @@ function AppLayoutInner({ children }: AppLayoutProps) {
663
663
  ? (resolvedInboxTab ?? inboxThreads.data?.tabs[0]?.id)
664
664
  : (inboxThreads.data?.activeTabId ?? resolvedInboxTab);
665
665
  const inboxIsFetching = inboxThreads.isFetching;
666
- const inboxSyncing = inboxMetadata?.syncing === true;
666
+ const inboxSyncing =
667
+ inboxMetadata?.syncing === true ||
668
+ inboxMetadata?.accounts.some(
669
+ (account) =>
670
+ account.state === "ready" && account.backfillPending === true,
671
+ );
667
672
  const needsReauthAccount = inboxMetadata?.accounts.find(
668
673
  (account) => account.state === "needs_reauth",
669
674
  );
@@ -1602,11 +1607,11 @@ function AppLayoutInner({ children }: AppLayoutProps) {
1602
1607
  <>
1603
1608
  {tabsLoading ? (
1604
1609
  <nav className="flex w-max shrink-0 items-center gap-2 sm:w-auto sm:flex-1 sm:min-w-0 sm:overflow-x-auto sm:hide-scrollbar">
1605
- {[1, 2, 3].map((i) => (
1610
+ {[96, 128, 98, 72, 84, 62].map((width, index) => (
1606
1611
  <span
1607
- key={i}
1608
- className="h-4 shrink-0 rounded bg-muted animate-pulse"
1609
- style={{ width: `${48 + i * 12}px` }}
1612
+ key={index}
1613
+ className="h-8 shrink-0 rounded-md bg-muted animate-pulse"
1614
+ style={{ width }}
1610
1615
  />
1611
1616
  ))}
1612
1617
  </nav>
@@ -1782,9 +1787,16 @@ function AppLayoutInner({ children }: AppLayoutProps) {
1782
1787
  </>
1783
1788
 
1784
1789
  {inboxSyncing && (
1785
- <span className="hidden shrink-0 items-center gap-1.5 text-[11px] text-muted-foreground sm:flex">
1786
- <IconRefresh className="h-3 w-3 animate-spin" />
1787
- {t("mail.inbox.syncing")}
1790
+ <span
1791
+ className="flex shrink-0 items-center text-muted-foreground"
1792
+ role="status"
1793
+ aria-label={t("mail.inbox.syncing")}
1794
+ title={t("mail.inbox.syncing")}
1795
+ >
1796
+ <IconRefresh
1797
+ aria-hidden="true"
1798
+ className="h-3 w-3 animate-spin"
1799
+ />
1788
1800
  </span>
1789
1801
  )}
1790
1802
 
@@ -14,6 +14,7 @@ import { EmailList, InboxZero } from "@/components/email/EmailList";
14
14
  import { EmailThread } from "@/components/email/EmailThread";
15
15
  import { IntegrationsSidebar } from "@/components/email/IntegrationsSidebar";
16
16
  import { GoogleConnectBanner } from "@/components/GoogleConnectBanner";
17
+ import { Skeleton } from "@/components/ui/skeleton";
17
18
  import { useAccountFilter } from "@/hooks/use-account-filter";
18
19
  import {
19
20
  FOCUS_COMPOSE_DRAFT_EVENT,
@@ -170,6 +171,26 @@ function ContactPanel({
170
171
  );
171
172
  }
172
173
 
174
+ function ContactPanelSkeleton() {
175
+ return (
176
+ <div aria-hidden="true" className="flex h-full flex-col">
177
+ <div className="space-y-1.5 px-4 pt-4 pb-3">
178
+ <Skeleton className="h-4 w-8" />
179
+ <Skeleton className="h-3 w-40 max-w-full" />
180
+ <Skeleton className="h-3 w-28" />
181
+ </div>
182
+ <div className="flex items-center gap-2 px-4 py-2">
183
+ <Skeleton className="size-5 rounded-md" />
184
+ <Skeleton className="h-3 w-14" />
185
+ </div>
186
+ <div className="mx-4 h-px bg-border/30" />
187
+ <div className="px-4 py-2">
188
+ <Skeleton className="h-3 w-20" />
189
+ </div>
190
+ </div>
191
+ );
192
+ }
193
+
173
194
  function formatSidebarSender(thread: ThreadSummary): string {
174
195
  if (thread.messageCount <= 1) {
175
196
  return thread.latestMessage.from.name || thread.latestMessage.from.email;
@@ -1091,7 +1112,6 @@ export function InboxPage() {
1091
1112
  onNavigateThread={handleOptimisticThreadNavigation}
1092
1113
  isLoading={emailListLoading}
1093
1114
  isFetching={isFetching}
1094
- isSyncing={isInboxView && inboxMetadata?.syncing === true}
1095
1115
  emailsError={emailsError}
1096
1116
  accountErrors={accountErrors}
1097
1117
  labels={
@@ -1116,17 +1136,20 @@ export function InboxPage() {
1116
1136
  )}
1117
1137
  </div>
1118
1138
 
1119
- {/* Right contact panel — hidden during initial load or when maximized */}
1120
- {!emailListLoading && !(hasThread && isMaximized) && (
1139
+ {!(hasThread && isMaximized) && (
1121
1140
  <div className="mail-contact-side-panel hidden w-[260px] shrink-0 flex-col border-s border-border/30 bg-muted/50 dark:bg-[var(--mail-sidebar-surface)]">
1122
- <ContactPanel
1123
- emailId={contactEmailId}
1124
- contactEmail={sidebarContactEmail}
1125
- emails={emails}
1126
- allowEmailSearch={
1127
- !isInboxView || (googleStatus.isSuccess && !isGoogleConnected)
1128
- }
1129
- />
1141
+ {emailListLoading ? (
1142
+ <ContactPanelSkeleton />
1143
+ ) : (
1144
+ <ContactPanel
1145
+ emailId={contactEmailId}
1146
+ contactEmail={sidebarContactEmail}
1147
+ emails={emails}
1148
+ allowEmailSearch={
1149
+ !isInboxView || (googleStatus.isSuccess && !isGoogleConnected)
1150
+ }
1151
+ />
1152
+ )}
1130
1153
  </div>
1131
1154
  )}
1132
1155
  </div>
@@ -0,0 +1,6 @@
1
+ ---
2
+ type: improved
3
+ date: 2026-09-29
4
+ ---
5
+
6
+ Mail loading screens match the current inbox layout.
@@ -0,0 +1,6 @@
1
+ ---
2
+ type: improved
3
+ date: 2026-09-29
4
+ ---
5
+
6
+ Mail shows the first messages sooner and keeps them visible while background sync finishes.
@@ -46,9 +46,10 @@ const DEFAULT_BUDGET_MS = 6_000;
46
46
  const CLAIM_TTL_MS = 90_000;
47
47
  const LABELS_TTL_MS = 5 * 60 * 1000;
48
48
  const EAGER_PAGE_SIZE = 50;
49
- // 74 thread reads cost 2,960 units; profile and two list calls bring eager sync to 2,981.
49
+ // Use interactive quota for the 74-thread eager slice so its first backfill page still fits.
50
50
  const EAGER_COMPLETION_SIZE = 24;
51
- const BACKFILL_PAGE_SIZE = 45;
51
+ // 49 reads and one threads.list call use 1,970 of the 2,000-unit backfill budget.
52
+ const BACKFILL_PAGE_SIZE = 49;
52
53
  const RECONCILE_PAGE_SIZE = 500;
53
54
  const RECONCILE_HYDRATE_SIZE = 45;
54
55
  const RECONCILE_MAX_PASSES = 2;
@@ -292,7 +293,7 @@ async function hydrateAndApply(
292
293
  accountEmail: string,
293
294
  connected: Set<string>,
294
295
  claimId: string,
295
- lane: "incremental" | "backfill",
296
+ lane: "interactive" | "incremental" | "backfill",
296
297
  onChanged?: () => void,
297
298
  ): Promise<void> {
298
299
  for (let i = 0; i < ids.length; i += HYDRATE_CHUNK) {
@@ -349,10 +350,14 @@ async function runFullSyncStep(
349
350
  connectedAccountEmails?: readonly string[],
350
351
  onChanged?: () => void,
351
352
  ): Promise<SyncStepResult> {
353
+ const initialSync = row.historyId == null;
352
354
  let fullSyncHistoryId = row.fullSyncHistoryId;
353
355
  let fullSyncStartedAt = row.fullSyncStartedAt;
354
356
  if (fullSyncHistoryId == null) {
355
- const profile = await gmailGetProfile(accessToken, "incremental");
357
+ const profile = await gmailGetProfile(
358
+ accessToken,
359
+ initialSync ? "interactive" : "incremental",
360
+ );
356
361
  fullSyncHistoryId = String(profile.historyId);
357
362
  fullSyncStartedAt = Date.now();
358
363
  await patchProgress(ownerEmail, accountEmail, claimId, {
@@ -368,7 +373,7 @@ async function runFullSyncStep(
368
373
  connectedAccountEmails,
369
374
  );
370
375
  const completingEagerSlice = row.historyId == null && pageToken != null;
371
- const initialSync = row.historyId == null;
376
+ const lane = initialSync ? "interactive" : "backfill";
372
377
  const page = await gmailListThreads(
373
378
  accessToken,
374
379
  {
@@ -380,11 +385,10 @@ async function runFullSyncStep(
380
385
  : BACKFILL_PAGE_SIZE,
381
386
  pageToken,
382
387
  },
383
- initialSync ? "incremental" : "backfill",
388
+ lane,
384
389
  );
385
390
  const ids: string[] = (page.threads ?? []).map((thread: any) => thread.id);
386
391
  if (ids.length > 0) {
387
- const lane = initialSync ? "incremental" : "backfill";
388
392
  await hydrateAndApply(
389
393
  accessToken,
390
394
  ids,
@@ -3,15 +3,34 @@
3
3
  All notable user-facing changes to Agent-Native Slides are documented here. Open it any
4
4
  time from the command menu (Cmd+K → "What's new").
5
5
 
6
+ ## 2026-09-29
7
+
8
+ ### Improved
9
+
10
+ - Settings pages now share the account layout, with dated updates that load in batches.
11
+
6
12
  ## 2026-09-28
7
13
 
8
14
  ### Improved
9
15
 
16
+ - The app canvas now meets the right chat sidebar without a dark seam or rounded corner.
17
+ - Center the home search field and keep prompt submission responsive while AI readiness is checked.
18
+ - Rotation controls are smaller and easier to see.
19
+ - Settings now opens in the new layout, with Account, Connections, Agent, Organization, and app sections.
20
+ - Slides now batch short deck creation and explain when layout measurements are not available.
10
21
  - Starter prompts now sit below the chat composer
11
22
  - The deck list search and import controls stay legible on narrow screens.
12
23
 
13
24
  ### Fixed
14
25
 
26
+ - Canceling reference selection restores the prompt and its attachments.
27
+ - Deck editor waits for sign-in before loading its workspace shell.
28
+ - Existing decks open to Recent, and the home prompt stays interactive while AI readiness is checked.
29
+ - Preserve home prompt state across imports and clarify upload, website, and template search results.
30
+ - Slides preserves backward text selections when editing starts
31
+ - Slides text editing keeps the caret steady through focus changes and input-method composition
32
+ - The home import control no longer clips its label
33
+ - Typing in Slides agent chat keeps every character in order
15
34
  - The model picker shows available models when AI is configured.
16
35
  - Reference attachments stay available when a new deck prompt starts a chat.
17
36
  - Template menus stay available when you hover over a card.
@@ -0,0 +1,36 @@
1
+ import * as React from "react";
2
+ export type CreateStartKind = "chat-workspace" | "standalone" | "headless" | "first-party" | "community" | "workspace-add";
3
+ export interface CreateWizardAnswers {
4
+ kind: CreateStartKind;
5
+ name?: string;
6
+ templates: string[];
7
+ communityTemplate?: string;
8
+ addToWorkspace: boolean;
9
+ }
10
+ export interface CreateWizardOptions {
11
+ cwd?: string;
12
+ initialName?: string;
13
+ initialKind?: CreateStartKind;
14
+ initialTemplates?: string[];
15
+ initialCommunityTemplate?: string;
16
+ installedApps?: string[];
17
+ validateName?: (name: string) => string | undefined;
18
+ validateCommunityTemplate?: (value: string) => string | undefined;
19
+ addToWorkspace?: boolean;
20
+ }
21
+ export declare function createProjectPreview(input: {
22
+ kind?: CreateStartKind;
23
+ name: string;
24
+ templates: string[];
25
+ cwd: string;
26
+ addToWorkspace?: boolean;
27
+ }): string[];
28
+ export declare function CreateWizard({ options, onFinish, }: {
29
+ options: CreateWizardOptions;
30
+ onFinish: (answers: CreateWizardAnswers | null) => void;
31
+ }): React.JSX.Element;
32
+ export declare function runCreateWizard(options: CreateWizardOptions): Promise<CreateWizardAnswers | null>;
33
+ export declare function promptInkChoice(message: string, choices: Array<{
34
+ value: string;
35
+ label: string;
36
+ }>): Promise<string | null>;