@agent-native/core 0.185.0-nightly-20260923150956 → 0.185.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 (43) hide show
  1. package/corpus/templates/analytics/CHANGELOG.md +6 -0
  2. package/corpus/templates/brain/CHANGELOG.md +6 -0
  3. package/corpus/templates/calendar/CHANGELOG.md +11 -0
  4. package/corpus/templates/clips/CHANGELOG.md +37 -0
  5. package/corpus/templates/content/CHANGELOG.md +6 -0
  6. package/corpus/templates/design/CHANGELOG.md +9 -0
  7. package/corpus/templates/design/actions/get-design-system-index-status.ts +2 -5
  8. package/corpus/templates/design/actions/get-design-system.ts +6 -3
  9. package/corpus/templates/design/actions/list-design-systems.ts +53 -1
  10. package/corpus/templates/design/app/components/editor/design-start-pickers.tsx +10 -0
  11. package/corpus/templates/design/app/i18n-data.ts +10 -0
  12. package/corpus/templates/design/app/lib/design-system-data.ts +13 -10
  13. package/corpus/templates/design/app/pages/DesignSystems.tsx +11 -8
  14. package/corpus/templates/design/app/pages/Templates.tsx +6 -1
  15. package/corpus/templates/design/changelog/2026-09-22-fixed-the-design-system-picker-showing-a-still-indexing-buil.md +6 -0
  16. package/corpus/templates/design/server/lib/builder-design-system-proxy.ts +11 -30
  17. package/corpus/templates/mail/CHANGELOG.md +5 -0
  18. package/corpus/templates/slides/CHANGELOG.md +13 -0
  19. package/corpus/templates/slides/actions/apply-design-system.ts +2 -22
  20. package/corpus/templates/slides/actions/create-deck.ts +4 -54
  21. package/corpus/templates/slides/actions/get-design-system.ts +40 -3
  22. package/corpus/templates/slides/actions/list-design-systems.ts +26 -11
  23. package/corpus/templates/slides/app/components/design-system/DesignSystemSetup.tsx +16 -23
  24. package/corpus/templates/slides/app/components/editor/NewDeckReferenceStep.tsx +14 -51
  25. package/corpus/templates/slides/app/hooks/use-design-systems.ts +1 -191
  26. package/corpus/templates/slides/app/i18n/en-US.ts +0 -4
  27. package/corpus/templates/slides/app/lib/design-system-selection.ts +4 -19
  28. package/corpus/templates/slides/app/pages/Index.tsx +3 -16
  29. package/corpus/templates/slides/shared/design-system-validation.ts +16 -18
  30. package/dist/automation/index.d.ts +1 -1
  31. package/dist/collab/routes.d.ts +1 -1
  32. package/dist/collab/struct-routes.d.ts +1 -1
  33. package/dist/secrets/routes.d.ts +3 -3
  34. package/dist/server/agent-engine-api-key-route.d.ts +1 -1
  35. package/dist/server/builder-design-systems.d.ts +23 -1
  36. package/dist/server/builder-design-systems.js +58 -17
  37. package/dist/server/index.d.ts +1 -1
  38. package/dist/server/index.js +1 -1
  39. package/dist/server/realtime-token.d.ts +1 -1
  40. package/dist/server/transcribe-voice.d.ts +1 -1
  41. package/docs/content/toolkit-settings.mdx +32 -0
  42. package/package.json +4 -4
  43. package/corpus/templates/slides/actions/refresh-design-system-indexing-status.ts +0 -120
@@ -5,8 +5,14 @@ time from the command menu (Cmd+K → "What's new") or from Settings.
5
5
 
6
6
  ## 2026-09-22
7
7
 
8
+ ### Added
9
+
10
+ - Action success rate and action reliability metrics now weight sampled events correctly and leave cancelled requests out of the failure rate.
11
+
8
12
  ### Improved
9
13
 
14
+ - Analytics data reaches reports sooner, temporary event copies clear from Postgres after delivery or a limited recovery window, and out-of-range client clocks use the server receive time.
15
+ - Apps start with an app-shaped skeleton while session data loads immediately.
10
16
  - Daily chart tooltips show the weekday alongside the date
11
17
 
12
18
  ### Fixed
@@ -3,6 +3,12 @@
3
3
  All notable user-facing changes to Agent-Native Brain 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-22
7
+
8
+ ### Added
9
+
10
+ - Captures are now screened by Jev, which returns a calibrated probability per sensitivity category, and Settings lets you pick between Jev, a custom model, and deterministic-only screening.
11
+
6
12
  ## 2026-08-22
7
13
 
8
14
  ### Fixed
@@ -3,6 +3,17 @@
3
3
  All notable user-facing changes to Agent-Native Calendar 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-22
7
+
8
+ ### Improved
9
+
10
+ - Apps start with an app-shaped skeleton while session data loads immediately.
11
+ - Calendar shows an app-shaped skeleton while the calendar workspace loads.
12
+
13
+ ### Fixed
14
+
15
+ - Opening Calendar signed out inside an embedded tab now shows sign-in instead of a page whose actions all fail.
16
+
6
17
  ## 2026-09-18
7
18
 
8
19
  ### Fixed
@@ -3,8 +3,45 @@
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-22
7
+
8
+ ### Added
9
+
10
+ - Clips can import Loom links in a dialog and upload videos by dropping them into the library.
11
+
12
+ ### Improved
13
+
14
+ - Apps start with an app-shaped skeleton while session data loads immediately.
15
+ - Refine empty-state copy across Shared with me, Spaces, and Meetings.
16
+ - Member lists and mentions load faster in large workspaces.
17
+ - Dictation lists focus on the transcript, with time and duration available from a compact info popover in the expanded toolbar.
18
+
19
+ ### Fixed
20
+
21
+ - Clips keeps uploaded videos visible while the library refreshes and localizes Loom import failures.
22
+ - Clips recovers dropped uploads after a lost finalization response and clears saving feedback after successful saves.
23
+ - The desktop app stops re-checking flags and meetings every few seconds after your session expires, and resumes when you sign in again.
24
+ - Dictation capture stays controllable in every supported environment.
25
+ - Dictation cleanup keeps its recognizable button after processing, with a green success state and an accessible “AI cleaned” tooltip.
26
+ - Dictionary stays available before your first dictation so you can add preferred spellings before recording.
27
+ - Dictation cards expand from a single-line preview to the full transcript with aligned action controls, keeping the expand control in place without flashing duplicate text when collapsing.
28
+ - Rewind keeps its rolling screen history within a smaller default storage limit.
29
+ - Shared recordings play reliably when the player seeks through the video.
30
+
6
31
  ## 2026-09-21
7
32
 
33
+ ### Improved
34
+
35
+ - Dictate makes it clearer how to start and what happens to your notes afterward.
36
+ - The Dictate empty state now centers within the page content area and keeps its primary action text-only.
37
+ - Dictate starts with a clear empty state and a single New Dictation action.
38
+ - Dictate history now uses meeting-style day sections with individual list cards, in-place progressive disclosure, compact source badges, AI-cleaned status badges, and explicit cleanup success or error feedback.
39
+ - Dictation cards now toggle from the card itself and collapse when you click outside.
40
+ - The empty Dictate view now keeps duplicate toolbar actions out of the way until there is dictation history.
41
+ - Empty states now share a responsive layout with outcome-led titles, non-repetitive descriptions, comfortable text wrapping, and direct calls to action.
42
+ - Empty Library, Spaces, and Dictate views now keep the toolbar focused on navigation while the empty state owns the primary action.
43
+ - Clips empty states now explain what belongs in each view and surface the most relevant next action without adding unnecessary controls.
44
+
8
45
  ### Fixed
9
46
 
10
47
  - Clips keeps the menu-bar popover open, restarts cleanly after updates, and waits for Google sign-in without a loading indicator.
@@ -3,6 +3,12 @@
3
3
  All notable user-facing changes to Agent-Native Content are documented here. Open it any
4
4
  time from the command menu (Cmd+K → "What's new").
5
5
 
6
+ ## 2026-09-21
7
+
8
+ ### Improved
9
+
10
+ - Search now ranks exact and partial title matches above incidental matches in document bodies.
11
+
6
12
  ## 2026-09-16
7
13
 
8
14
  ### Fixed
@@ -5,8 +5,17 @@ from the command menu (Cmd+K → "What's new") or from Settings.
5
5
 
6
6
  ## 2026-09-22
7
7
 
8
+ ### Improved
9
+
10
+ - Apps start with an app-shaped skeleton while session data loads immediately.
11
+ - Canvas saves are faster because version checkpoints are taken at most every few minutes while you edit.
12
+ - Large Figma files with hundreds of frames now import in seconds without freezing the editor, keep their Figma canvas layout, and render component slots and instance overrides much more faithfully.
13
+
8
14
  ### Fixed
9
15
 
16
+ - Blocks can be selected with one click inside screens
17
+ - Canvas edits on large designs now save even when version history can't be stored, with a one-time notice instead of a lost change.
18
+ - Opening Design signed out inside an embedded tab now shows sign-in instead of a page whose actions all fail.
10
19
  - Live resize handles keep working at overview zoom
11
20
  - Live visual edits can now move layers onto an empty canvas and keep them editable.
12
21
 
@@ -1,6 +1,7 @@
1
1
  import { defineAction } from "@agent-native/core/action";
2
2
  import {
3
3
  hydrateBuilderDesignSystemReference,
4
+ isBuilderDesignSystemReadyByCount,
4
5
  parseBuilderDesignSystemProxyReference,
5
6
  } from "@agent-native/core/server";
6
7
  import { resolveAccess } from "@agent-native/core/sharing";
@@ -43,11 +44,7 @@ export default defineAction({
43
44
  builderJobId: reference.builderJobId,
44
45
  status:
45
46
  hydrated.builderStatus ?? reference.builderStatus ?? "in-progress",
46
- ready:
47
- hydrated.builderStatus === "ready" ||
48
- hydrated.builderStatus === "complete" ||
49
- hydrated.builderStatus === "completed" ||
50
- hydrated.completionConfirmed === true,
47
+ ready: isBuilderDesignSystemReadyByCount(hydrated.docCount),
51
48
  docCount: hydrated.docCount,
52
49
  tokenCount: Object.keys(hydrated.tokenValues).length,
53
50
  };
@@ -1,6 +1,7 @@
1
1
  import { defineAction } from "@agent-native/core/action";
2
2
  import {
3
3
  hydrateBuilderDesignSystemReference,
4
+ isBuilderDesignSystemReadyByCount,
4
5
  parseBuilderDesignSystemProxyReference,
5
6
  } from "@agent-native/core/server";
6
7
  import { resolveAccess } from "@agent-native/core/sharing";
@@ -41,7 +42,8 @@ interface BuilderGenerationContext {
41
42
  tokenValues?: Record<string, string>;
42
43
  }>;
43
44
  tokenValues: Record<string, string>;
44
- docCount: number;
45
+ /** null when Builder could not be read at all; 0 means "still indexing". */
46
+ docCount: number | null;
45
47
  warning?: string;
46
48
  }
47
49
 
@@ -199,7 +201,8 @@ function buildDesignSystemAgentContext({
199
201
  // than presenting placeholder proxy values as if they were the user's brand.
200
202
  const builderUsable = Boolean(
201
203
  builder &&
202
- (builder.docCount > 0 || Object.keys(builder.tokenValues).length > 0),
204
+ typeof builder.docCount === "number" &&
205
+ isBuilderDesignSystemReadyByCount(builder.docCount),
203
206
  );
204
207
  if (builder && !builderUsable) {
205
208
  lines.push(
@@ -363,7 +366,7 @@ export default defineAction({
363
366
  ...builderReference,
364
367
  docs: [],
365
368
  tokenValues: {},
366
- docCount: 0,
369
+ docCount: null,
367
370
  warning:
368
371
  error instanceof Error
369
372
  ? error.message
@@ -1,4 +1,8 @@
1
1
  import { defineAction } from "@agent-native/core/action";
2
+ import {
3
+ fetchBuilderDesignSystemDocumentCount,
4
+ parseBuilderDesignSystemProxyReference,
5
+ } from "@agent-native/core/server";
2
6
  import {
3
7
  getRequestOrgId,
4
8
  getRequestUserEmail,
@@ -27,6 +31,15 @@ function strongerRole(current: ShareRole | null, next: ShareRole): ShareRole {
27
31
  return current;
28
32
  }
29
33
 
34
+ function withLiveDocCount(data: string, docCount: number): string {
35
+ const parsed = JSON.parse(data) as Record<string, unknown>;
36
+ return JSON.stringify({
37
+ ...parsed,
38
+ docCount,
39
+ builderStatus: docCount > 0 ? "ready" : "in-progress",
40
+ });
41
+ }
42
+
30
43
  export default defineAction({
31
44
  description:
32
45
  "List all design systems accessible to the current user. Returns title, " +
@@ -70,6 +83,41 @@ export default defineAction({
70
83
  return { count: 0, designSystems: [] };
71
84
  }
72
85
 
86
+ // docCount is never stored in SQL and never read from a cached value on
87
+ // the row: it always comes from Builder's own document-count endpoint,
88
+ // fetched fresh for every Builder-backed row on every list call, in
89
+ // parallel so N Builder-backed systems cost one round trip, not N.
90
+ const builderRows = rows
91
+ .map((row) => ({
92
+ row,
93
+ reference: parseBuilderDesignSystemProxyReference(row.data),
94
+ }))
95
+ .filter(
96
+ (
97
+ entry,
98
+ ): entry is {
99
+ row: (typeof rows)[number];
100
+ reference: NonNullable<typeof entry.reference>;
101
+ } => entry.reference !== null,
102
+ );
103
+ const liveDocCounts = new Map<string, number>();
104
+ const liveRowData = new Map<string, string>();
105
+ if (builderRows.length > 0) {
106
+ const results = await Promise.all(
107
+ builderRows.map(async ({ row, reference }) => {
108
+ const result = await fetchBuilderDesignSystemDocumentCount(
109
+ reference.builderDesignSystemId,
110
+ );
111
+ return { row, result };
112
+ }),
113
+ );
114
+ for (const { row, result } of results) {
115
+ if (!result.ok) continue;
116
+ liveDocCounts.set(row.id, result.docCount);
117
+ liveRowData.set(row.id, withLiveDocCount(row.data, result.docCount));
118
+ }
119
+ }
120
+
73
121
  // The row-level isDefault column is per-owner, so a shared system owned by
74
122
  // someone else can carry isDefault: true for them. Compute the caller's
75
123
  // own effective default once and report that instead of the raw column.
@@ -133,6 +181,8 @@ export default defineAction({
133
181
  role = "owner";
134
182
  }
135
183
  const canManage = canManageDesignSystemRole(role);
184
+ const data = liveRowData.get(row.id) ?? row.data;
185
+ const docCount = liveDocCounts.get(row.id);
136
186
  if (args.compact === "true") {
137
187
  return {
138
188
  id: row.id,
@@ -140,13 +190,15 @@ export default defineAction({
140
190
  isDefault: row.id === effectiveDefaultId,
141
191
  accessRole: role,
142
192
  canManage,
193
+ docCount,
143
194
  };
144
195
  }
145
196
  return {
146
197
  id: row.id,
147
198
  title: row.title,
148
199
  description: row.description,
149
- data: row.data,
200
+ data,
201
+ docCount,
150
202
  assets: row.assets,
151
203
  customInstructions: row.customInstructions ?? "",
152
204
  isDefault: row.id === effectiveDefaultId,
@@ -30,6 +30,7 @@ import {
30
30
  SelectTrigger,
31
31
  } from "@/components/ui/select";
32
32
  import { Skeleton } from "@/components/ui/skeleton";
33
+ import { isDesignSystemUsableForGeneration } from "@/lib/design-system-data";
33
34
  import { cn } from "@/lib/utils";
34
35
 
35
36
  export interface PromptTemplateOption {
@@ -52,6 +53,8 @@ export interface PromptDesignSystemOption {
52
53
  /** The system's own palette, so the row can be picked by colour rather than
53
54
  * by reading a list of near-identical names. */
54
55
  colors?: string[];
56
+ /** False while a Builder-backed system has no indexed docCount yet. */
57
+ ready: boolean;
55
58
  }
56
59
 
57
60
  export function TemplatePickerControl({
@@ -259,6 +262,7 @@ export function DesignSystemPickerControl({
259
262
  <SelectItem
260
263
  key={system.id}
261
264
  value={system.id}
265
+ disabled={!system.ready}
262
266
  className="py-2 text-xs"
263
267
  >
264
268
  <span className="flex min-w-0 items-center gap-2.5">
@@ -277,6 +281,11 @@ export function DesignSystemPickerControl({
277
281
  </span>
278
282
  ) : null}
279
283
  <span className="min-w-0 truncate">{system.title}</span>
284
+ {!system.ready ? (
285
+ <span className="shrink-0 text-muted-foreground">
286
+ {t("promptDialog.designSystemIndexing")}
287
+ </span>
288
+ ) : null}
280
289
  </span>
281
290
  </SelectItem>
282
291
  ))}
@@ -325,6 +334,7 @@ export function designSystemPickerOptions(
325
334
  description: system.description,
326
335
  isDefault: system.isDefault,
327
336
  colors,
337
+ ready: isDesignSystemUsableForGeneration(system.data),
328
338
  };
329
339
  });
330
340
  }
@@ -1375,6 +1375,7 @@ const enUS = {
1375
1375
  startBlankCanvasHint: "Draw it yourself with frames, shapes and text.",
1376
1376
  designSystem: "Design system",
1377
1377
  noDesignSystem: "No design system",
1378
+ designSystemIndexing: "Indexing…",
1378
1379
  newDesignSystem: "New",
1379
1380
  createDesignSystem: "Create design system",
1380
1381
  template: "Template",
@@ -6311,6 +6312,7 @@ const designRawLiteralOverrides = {
6311
6312
  "这些附件太大。上传总大小上限为 {{max}} MB — 请减少文件数量或使用更小的文件。",
6312
6313
  designSystem: "Design系统",
6313
6314
  noDesignSystem: "没有设计系统",
6315
+ designSystemIndexing: "正在索引…",
6314
6316
  newDesignSystem: "新",
6315
6317
  addAttachment: "添加",
6316
6318
  removeAttachment: "删除{{name}}",
@@ -6474,6 +6476,7 @@ const designRawLiteralOverrides = {
6474
6476
  "Esos adjuntos son demasiado grandes. Las subidas están limitadas a {{max}} MB en total: adjunta menos archivos o más pequeños.",
6475
6477
  designSystem: "sistema Design",
6476
6478
  noDesignSystem: "Sin sistema de diseño",
6479
+ designSystemIndexing: "Indexando…",
6477
6480
  newDesignSystem: "Nuevo",
6478
6481
  addAttachment: "Añadir",
6479
6482
  removeAttachment: "Eliminar {{name}}",
@@ -6641,6 +6644,7 @@ const designRawLiteralOverrides = {
6641
6644
  "Ces pièces jointes sont trop volumineuses. Les téléversements sont limités à {{max}} Mo au total : joignez moins de fichiers ou des fichiers plus petits.",
6642
6645
  designSystem: "Système Design",
6643
6646
  noDesignSystem: "Aucun système de conception",
6647
+ designSystemIndexing: "Indexation…",
6644
6648
  newDesignSystem: "Nouveau",
6645
6649
  addAttachment: "Ajouter",
6646
6650
  removeAttachment: "Supprimer {{name}}",
@@ -6808,6 +6812,7 @@ const designRawLiteralOverrides = {
6808
6812
  "Diese Anhänge sind zu groß. Uploads sind auf insgesamt {{max}} MB begrenzt – hänge weniger oder kleinere Dateien an.",
6809
6813
  designSystem: "Design-System",
6810
6814
  noDesignSystem: "Kein Designsystem",
6815
+ designSystemIndexing: "Wird indiziert…",
6811
6816
  newDesignSystem: "Neu",
6812
6817
  addAttachment: "Hinzufügen",
6813
6818
  removeAttachment: "Entfernen Sie {{name}}",
@@ -6975,6 +6980,7 @@ const designRawLiteralOverrides = {
6975
6980
  "添付ファイルが大きすぎます。アップロードは合計 {{max}} MB までです。ファイル数を減らすか、より小さいファイルを添付してください。",
6976
6981
  designSystem: "Designシステム",
6977
6982
  noDesignSystem: "デザインシステムがない",
6983
+ designSystemIndexing: "インデックス作成中…",
6978
6984
  newDesignSystem: "新しい",
6979
6985
  addAttachment: "追加",
6980
6986
  removeAttachment: "{{name}} を削除",
@@ -7137,6 +7143,7 @@ const designRawLiteralOverrides = {
7137
7143
  "첨부 파일이 너무 큽니다. 업로드는 총 {{max}}MB까지 지원됩니다. 파일 수를 줄이거나 더 작은 파일을 첨부하세요.",
7138
7144
  designSystem: "Design 시스템",
7139
7145
  noDesignSystem: "디자인 시스템 없음",
7146
+ designSystemIndexing: "색인 생성 중…",
7140
7147
  newDesignSystem: "새로운",
7141
7148
  addAttachment: "추가",
7142
7149
  removeAttachment: "{{name}} 제거",
@@ -7301,6 +7308,7 @@ const designRawLiteralOverrides = {
7301
7308
  "Esses anexos são grandes demais. Os envios são limitados a {{max}} MB no total — anexe menos arquivos ou arquivos menores.",
7302
7309
  designSystem: "Sistema Design",
7303
7310
  noDesignSystem: "Nenhum sistema de design",
7311
+ designSystemIndexing: "Indexando…",
7304
7312
  newDesignSystem: "Novo",
7305
7313
  addAttachment: "Adicionar",
7306
7314
  removeAttachment: "Remover {{name}}",
@@ -7466,6 +7474,7 @@ const designRawLiteralOverrides = {
7466
7474
  "ये attachments बहुत बड़े हैं। Uploads की कुल सीमा {{max}} MB है — कम या छोटी files attach करें।",
7467
7475
  designSystem: "Design प्रणाली",
7468
7476
  noDesignSystem: "कोई डिज़ाइन प्रणाली नहीं",
7477
+ designSystemIndexing: "इंडेक्स हो रहा है…",
7469
7478
  newDesignSystem: "नया",
7470
7479
  addAttachment: "जोड़ें",
7471
7480
  removeAttachment: "{{name}} हटाएँ",
@@ -7628,6 +7637,7 @@ const designRawLiteralOverrides = {
7628
7637
  "المرفقات كبيرة جدًا. الحد الأقصى للرفع هو {{max}} ميغابايت إجمالًا — أرفق ملفات أقل أو أصغر.",
7629
7638
  designSystem: "نظام Design",
7630
7639
  noDesignSystem: "لا يوجد نظام التصميم",
7640
+ designSystemIndexing: "جارٍ الفهرسة…",
7631
7641
  newDesignSystem: "جديد",
7632
7642
  addAttachment: "أضف",
7633
7643
  removeAttachment: "إزالة {{name}}",
@@ -5,6 +5,8 @@ export interface DesignSystemData {
5
5
  builderBranchName?: string;
6
6
  builderUrl?: string;
7
7
  builderStatus?: string;
8
+ /** Builder-reported indexed document count; readiness, unlike builderStatus. */
9
+ docCount?: number;
8
10
  builderSyncedAt?: string;
9
11
  colors?: {
10
12
  primary?: unknown;
@@ -45,6 +47,15 @@ export function parseDesignSystemData(
45
47
  }
46
48
  }
47
49
 
50
+ /**
51
+ * docCount is the only readiness signal: not builderStatus, not a sync
52
+ * timestamp, not document types. A Builder-backed row with no recorded
53
+ * docCount has not been measured yet, which is not ready.
54
+ */
55
+ function isBuilderKitIndexed(parsed: DesignSystemData): boolean {
56
+ return typeof parsed.docCount === "number" && parsed.docCount > 0;
57
+ }
58
+
48
59
  export function shouldRefreshBuilderDesignSystem(
49
60
  system: Pick<{ accessRole?: string; data: string }, "accessRole" | "data">,
50
61
  ): boolean {
@@ -54,11 +65,7 @@ export function shouldRefreshBuilderDesignSystem(
54
65
  system.accessRole === "admin" ||
55
66
  system.accessRole === "editor") &&
56
67
  parsed?.source === "builder" &&
57
- (parsed.builderStatus === "in-progress" ||
58
- ((parsed.builderStatus === "ready" ||
59
- parsed.builderStatus === "complete" ||
60
- parsed.builderStatus === "completed") &&
61
- typeof parsed.builderSyncedAt !== "string"))
68
+ (!isBuilderKitIndexed(parsed) || typeof parsed.builderSyncedAt !== "string")
62
69
  );
63
70
  }
64
71
 
@@ -66,11 +73,7 @@ export function isDesignSystemUsableForGeneration(data: string): boolean {
66
73
  const parsed = parseDesignSystemData(data);
67
74
  if (!parsed) return false;
68
75
  if (parsed.source !== "builder") return true;
69
- return (
70
- parsed.builderStatus === "ready" ||
71
- parsed.builderStatus === "complete" ||
72
- parsed.builderStatus === "completed"
73
- );
76
+ return isBuilderKitIndexed(parsed);
74
77
  }
75
78
 
76
79
  export function builderRefreshKey(system: {
@@ -108,17 +108,20 @@ interface DesignSystem {
108
108
  type BuilderRefreshResult = {
109
109
  synced: boolean;
110
110
  status?: string;
111
+ docCount?: number;
111
112
  rejectedTokenCount?: number;
112
113
  };
113
114
 
114
- function isTerminalBuilderStatus(status?: string): boolean {
115
+ /**
116
+ * Builder's status string lags the real index state, so polling only stops on
117
+ * a positive document count or on a status that reports outright failure.
118
+ */
119
+ function isSettledBuilderRefresh(result: BuilderRefreshResult): boolean {
120
+ if (typeof result.docCount === "number" && result.docCount > 0) return true;
115
121
  return (
116
- status === "ready" ||
117
- status === "complete" ||
118
- status === "completed" ||
119
- status === "error" ||
120
- status === "failed" ||
121
- status === "cancelled"
122
+ result.status === "error" ||
123
+ result.status === "failed" ||
124
+ result.status === "cancelled"
122
125
  );
123
126
  }
124
127
 
@@ -463,7 +466,7 @@ export default function DesignSystems() {
463
466
  stoppedBuilderRefreshesRef.current.add(entry.key);
464
467
  return;
465
468
  }
466
- if (isTerminalBuilderStatus(result.status)) {
469
+ if (isSettledBuilderRefresh(result)) {
467
470
  activeBuilderRefreshesRef.current.delete(entry.key);
468
471
  settledBuilderRefreshesRef.current.add(entry.key);
469
472
  return;
@@ -22,6 +22,7 @@ import { type ReactNode, useEffect, useMemo, useRef, useState } from "react";
22
22
  import { useNavigate, useSearchParams } from "react-router";
23
23
  import { toast } from "sonner";
24
24
 
25
+ import { designSystemPickerOptions } from "@/components/editor/design-start-pickers";
25
26
  import PromptPopover from "@/components/editor/PromptDialog";
26
27
  import type { UploadedFile } from "@/components/editor/PromptDialog";
27
28
  import { QueryErrorState } from "@/components/QueryErrorState";
@@ -106,6 +107,10 @@ export default function Templates() {
106
107
  defaultSystem,
107
108
  isLoading: designSystemsLoading,
108
109
  } = useDesignSystems();
110
+ const designSystemOptions = useMemo(
111
+ () => designSystemPickerOptions(designSystems),
112
+ [designSystems],
113
+ );
109
114
 
110
115
  const templates = useMemo(() => data?.templates ?? [], [data?.templates]);
111
116
  const linkedTemplateId = searchParams.get("templateId");
@@ -387,7 +392,7 @@ export default function Templates() {
387
392
  onSubmit={handleSubmit}
388
393
  anchorRef={anchorRef}
389
394
  loading={creating}
390
- designSystems={designSystems}
395
+ designSystems={designSystemOptions}
391
396
  designSystemsLoading={designSystemsLoading}
392
397
  selectedDesignSystemId={selectedDesignSystemId ?? null}
393
398
  onDesignSystemChange={setSelectedDesignSystemId}
@@ -0,0 +1,6 @@
1
+ ---
2
+ type: fixed
3
+ date: 2026-09-22
4
+ ---
5
+
6
+ Fixed the design system picker showing a still-indexing Builder design system as ready to use
@@ -6,13 +6,14 @@ import {
6
6
  } from "@agent-native/core/brand-kit";
7
7
  import {
8
8
  createBuilderDesignSystemProxyFields,
9
+ isBuilderDesignSystemReadyByCount,
9
10
  localBuilderDesignSystemId,
10
11
  type BuilderDesignSystemHydratedReference,
11
12
  type BuilderDesignSystemIndexResult,
12
13
  type BuilderDesignSystemGitHubSource,
13
14
  type BuilderDesignSystemSourceKind,
14
15
  } from "@agent-native/core/server";
15
- import { and, eq, isNull } from "drizzle-orm";
16
+ import { eq } from "drizzle-orm";
16
17
  import { nanoid } from "nanoid";
17
18
 
18
19
  import { getDb, schema } from "../db/index.js";
@@ -32,12 +33,6 @@ type HydratedBuilderDesignSystemReference =
32
33
  completionConfirmed?: boolean;
33
34
  };
34
35
 
35
- export function isBuilderDesignSystemReady(
36
- status: string | undefined,
37
- ): boolean {
38
- return status === "ready" || status === "complete" || status === "completed";
39
- }
40
-
41
36
  export interface BuilderProxyReconciliation {
42
37
  data: string;
43
38
  tokenCount: number;
@@ -182,11 +177,9 @@ export function reconcileBuilderProxyData(
182
177
  source: "Builder DSI",
183
178
  })),
184
179
  );
185
- const completionConfirmed =
186
- hydrated.completionConfirmed === true ||
187
- hydrated.builderStatus === "ready" ||
188
- hydrated.builderStatus === "complete" ||
189
- hydrated.builderStatus === "completed";
180
+ const completionConfirmed = isBuilderDesignSystemReadyByCount(
181
+ hydrated.docCount,
182
+ );
190
183
  if (extracted.tokens.length === 0) {
191
184
  if (extracted.rejected.length > 0) {
192
185
  return {
@@ -201,6 +194,7 @@ export function reconcileBuilderProxyData(
201
194
  data: JSON.stringify({
202
195
  ...parsed,
203
196
  builderStatus: "ready",
197
+ docCount: hydrated.docCount,
204
198
  builderSyncedAt: syncedAt,
205
199
  }),
206
200
  tokenCount: 0,
@@ -313,6 +307,7 @@ export function reconcileBuilderProxyData(
313
307
  data: JSON.stringify({
314
308
  ...parsed,
315
309
  builderStatus: completionConfirmed ? "ready" : "in-progress",
310
+ docCount: hydrated.docCount,
316
311
  ...(completionConfirmed ? { builderSyncedAt: syncedAt } : {}),
317
312
  colors: nextColors,
318
313
  typography: nextTypography,
@@ -394,21 +389,6 @@ export async function upsertBuilderProxyDesignSystem({
394
389
  })
395
390
  .where(eq(schema.designSystems.id, existing.id));
396
391
  } else {
397
- const [ownedSystem] = await db
398
- .select({ id: schema.designSystems.id })
399
- .from(schema.designSystems)
400
- .where(
401
- orgId
402
- ? and(
403
- eq(schema.designSystems.ownerEmail, ownerEmail),
404
- eq(schema.designSystems.orgId, orgId),
405
- )
406
- : and(
407
- eq(schema.designSystems.ownerEmail, ownerEmail),
408
- isNull(schema.designSystems.orgId),
409
- ),
410
- )
411
- .limit(1);
412
392
  await db.insert(schema.designSystems).values({
413
393
  id: localDesignSystemId,
414
394
  title: proxyFields.title,
@@ -416,9 +396,10 @@ export async function upsertBuilderProxyDesignSystem({
416
396
  data: proxyFields.data,
417
397
  assets: "[]",
418
398
  customInstructions: proxyFields.customInstructions,
419
- // An indexing proxy has placeholders until Builder confirms completion;
420
- // making it the default here lets new designs consume an unusable kit.
421
- isDefault: !ownedSystem && isBuilderDesignSystemReady(result.status),
399
+ // A proxy created at index start has no indexed documents, so it is
400
+ // never usable yet; the refresh that sees a positive Builder doc count
401
+ // is what promotes it to default.
402
+ isDefault: false,
422
403
  ownerEmail,
423
404
  orgId: orgId ?? null,
424
405
  visibility: orgId ? "org" : "private",
@@ -5,8 +5,13 @@ time from the command menu (Cmd+K → "What's new") or from Settings.
5
5
 
6
6
  ## 2026-09-22
7
7
 
8
+ ### Improved
9
+
10
+ - Apps start with an app-shaped skeleton while session data loads immediately.
11
+
8
12
  ### Fixed
9
13
 
14
+ - Signed-out desktop tabs now show sign-in instead of retrying the inbox every 20 seconds.
10
15
  - Mail keeps cached messages visible when an account refresh fails
11
16
 
12
17
  ## 2026-09-19
@@ -3,6 +3,19 @@
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-22
7
+
8
+ ### Improved
9
+
10
+ - Apps start with an app-shaped skeleton while session data loads immediately.
11
+ - Design system indexing checks now back off instead of polling every few seconds indefinitely.
12
+ - Moving and resizing slide content now works like Google Slides: boxes drag from anywhere on them, a second click edits their text, containers outline on hover, and resizing AI-generated text works even while editing.
13
+ - An open deck no longer reloads every deck your teammates change.
14
+
15
+ ### Fixed
16
+
17
+ - AI-generated bullets keep their markers when you add, indent, or undo bullet rows.
18
+
6
19
  ## 2026-09-21
7
20
 
8
21
  ### Fixed