@agent-native/core 0.153.10 → 0.154.1

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 (149) hide show
  1. package/corpus/README.md +1 -1
  2. package/corpus/templates/analytics/AGENTS.md +20 -30
  3. package/corpus/templates/analytics/actions/search-dashboard-references.ts +58 -0
  4. package/corpus/templates/analytics/app/components/layout/Sidebar.tsx +1 -1
  5. package/corpus/templates/analytics/app/lib/utils.ts +1 -1
  6. package/corpus/templates/analytics/app/pages/adhoc/sql-dashboard/ViewSqlPopover.tsx +1 -1
  7. package/corpus/templates/analytics/server/lib/agent-chat-plan-mode.ts +2 -0
  8. package/corpus/templates/analytics/server/lib/dashboards-store.ts +366 -3
  9. package/corpus/templates/analytics/server/lib/real-data-actions.ts +3 -1
  10. package/corpus/templates/analytics/server/plugins/agent-chat.ts +6 -2
  11. package/corpus/templates/calendar/app/components/calendar/EventDialog.tsx +1 -1
  12. package/corpus/templates/calendar/app/lib/utils.ts +1 -1
  13. package/corpus/templates/clips/app/components/recorder/recorder-engine.ts +32 -5
  14. package/corpus/templates/clips/app/components/sharing/share-ui.tsx +15 -15
  15. package/corpus/templates/clips/app/i18n/en-US.ts +3 -3
  16. package/corpus/templates/clips/app/lib/utils.ts +5 -6
  17. package/corpus/templates/clips/chrome-extension/src/offscreen.ts +43 -8
  18. package/corpus/templates/clips/desktop/src/app.tsx +26 -12
  19. package/corpus/templates/clips/desktop/src/lib/recorder.ts +23 -9
  20. package/corpus/templates/clips/desktop/src-tauri/src/native_screen/custom_capture.rs +261 -11
  21. package/corpus/templates/clips/desktop/src-tauri/src/native_screen.rs +21 -3
  22. package/corpus/templates/clips/shared/mic-audio-cleanup.ts +350 -0
  23. package/corpus/templates/content/actions/resolve-content-landing.ts +162 -32
  24. package/corpus/templates/content/app/i18n-data.ts +10 -10
  25. package/corpus/templates/content/scripts/check-native-deps.mjs +181 -15
  26. package/corpus/templates/content/shared/content-landing.ts +5 -0
  27. package/corpus/templates/design/.agents/skills/design-generation/SKILL.md +79 -7
  28. package/corpus/templates/design/.agents/skills/design-systems/SKILL.md +14 -2
  29. package/corpus/templates/design/.agents/skills/visual-edit/SKILL.md +2 -2
  30. package/corpus/templates/design/.generated/bridge/editor-chrome.generated.ts +35 -11
  31. package/corpus/templates/design/actions/get-design-system.ts +103 -3
  32. package/corpus/templates/design/actions/import-design-tokens.ts +37 -8
  33. package/corpus/templates/design/actions/import-github.ts +32 -138
  34. package/corpus/templates/design/actions/index-design-system-with-builder.ts +49 -16
  35. package/corpus/templates/design/actions/present-design-variants.ts +93 -4
  36. package/corpus/templates/design/actions/run-design-audit.ts +229 -0
  37. package/corpus/templates/design/actions/sync-design-system-with-builder.ts +64 -0
  38. package/corpus/templates/design/app/components/design/code-workbench/commands.ts +2 -2
  39. package/corpus/templates/design/app/components/design/inspector/DesignColorPicker.tsx +17 -4
  40. package/corpus/templates/design/app/components/design/inspector/GradientEditor.tsx +5 -1
  41. package/corpus/templates/design/app/components/design/inspector/ImageFillControls.tsx +5 -1
  42. package/corpus/templates/design/app/hooks/use-question-flow.ts +81 -5
  43. package/corpus/templates/design/app/i18n/en-US.ts +1 -1
  44. package/corpus/templates/design/app/i18n-data.ts +32 -1
  45. package/corpus/templates/design/app/i18n-keyboard-shortcuts.ts +10 -10
  46. package/corpus/templates/design/app/pages/DesignSystemSetup.tsx +83 -11
  47. package/corpus/templates/design/app/pages/DesignSystems.tsx +14 -0
  48. package/corpus/templates/design/app/pages/design-editor/generation-prompt-directives.ts +22 -0
  49. package/corpus/templates/design/changelog/2026-08-13-a-screen-that-would-render-behind-an-invisible-alpine-overla.md +6 -0
  50. package/corpus/templates/design/changelog/2026-08-13-attach-a-ui-screenshot-and-the-design-is-reproduced-not-rein.md +6 -0
  51. package/corpus/templates/design/changelog/2026-08-13-linking-a-design-system-means-you-never-get-generic-directio.md +6 -0
  52. package/corpus/templates/design/changelog/2026-08-13-the-design-audit-now-reports-when-a-screen-ignores-its-linke.md +6 -0
  53. package/corpus/templates/design/changelog/2026-08-13-the-design-system-preview-now-shows-how-many-named-tokens-we.md +6 -0
  54. package/corpus/templates/design/changelog/2026-08-13-your-design-system-prompt-and-reference-screenshots-now-reac.md +6 -0
  55. package/corpus/templates/design/server/lib/builder-design-system-proxy.ts +18 -2
  56. package/corpus/templates/design/shared/design-review.ts +1 -0
  57. package/corpus/templates/design/shared/html-integrity.ts +171 -0
  58. package/corpus/templates/mail/app/lib/utils.ts +1 -1
  59. package/corpus/templates/slides/.agents/skills/design-systems/SKILL.md +10 -6
  60. package/corpus/templates/slides/actions/index-design-system-with-builder.ts +41 -3
  61. package/corpus/templates/slides/actions/patch-deck.ts +12 -3
  62. package/corpus/templates/slides/actions/sync-design-system-with-builder.ts +64 -0
  63. package/corpus/templates/slides/app/components/deck/DeckCard.tsx +1 -1
  64. package/corpus/templates/slides/app/components/design-system/DesignSystemSetup.tsx +193 -20
  65. package/corpus/templates/slides/app/components/editor/EditorActionCluster.tsx +73 -1
  66. package/corpus/templates/slides/app/components/editor/EditorSidebar.tsx +64 -34
  67. package/corpus/templates/slides/app/components/editor/EditorToolbar.tsx +34 -41
  68. package/corpus/templates/slides/app/components/editor/ExportMenu.tsx +119 -91
  69. package/corpus/templates/slides/app/components/editor/ImageOverlay.tsx +16 -0
  70. package/corpus/templates/slides/app/components/editor/NewDeckReferenceStep.tsx +15 -0
  71. package/corpus/templates/slides/app/components/editor/SlideEditor.tsx +158 -31
  72. package/corpus/templates/slides/app/components/editor/SlideOverflowWarning.tsx +30 -14
  73. package/corpus/templates/slides/app/components/editor/SpeakerNotesPanel.tsx +2 -2
  74. package/corpus/templates/slides/app/components/editor/canvas-interactions/slides-canvas-adapter.ts +4 -1
  75. package/corpus/templates/slides/app/components/editor/rich-text-selection.ts +14 -0
  76. package/corpus/templates/slides/app/components/editor/slide-text-targets.ts +24 -0
  77. package/corpus/templates/slides/app/context/DeckContext.tsx +19 -31
  78. package/corpus/templates/slides/app/global.css +24 -0
  79. package/corpus/templates/slides/app/hooks/use-navigation-state.ts +20 -17
  80. package/corpus/templates/slides/app/i18n/en-US.ts +19 -10
  81. package/corpus/templates/slides/app/lib/deck-filter.ts +47 -0
  82. package/corpus/templates/slides/app/lib/export-google-slides-client.ts +15 -4
  83. package/corpus/templates/slides/app/lib/export-pptx-client.ts +637 -1
  84. package/corpus/templates/slides/app/lib/image-download.ts +84 -0
  85. package/corpus/templates/slides/app/lib/utils.ts +1 -1
  86. package/corpus/templates/slides/app/pages/DeckEditor.tsx +9 -0
  87. package/corpus/templates/slides/app/pages/Index.tsx +25 -9
  88. package/corpus/templates/slides/changelog/2026-08-13-clicking-a-slide-thumbnail-now-focuses-it-so-the-slide-shortc.md +6 -0
  89. package/corpus/templates/slides/changelog/2026-08-13-duplicating-or-restoring-a-slide-now-keeps-its-transition-ani.md +6 -0
  90. package/corpus/templates/slides/changelog/2026-08-13-opening-presentation-mode-from-the-agent-now-starts-on-the-re.md +6 -0
  91. package/corpus/templates/slides/changelog/2026-08-13-slide-transitions-can-be-set-from-a-visible-control-in-the-sl.md +6 -0
  92. package/corpus/templates/slides/netlify.toml +1 -0
  93. package/corpus/templates/slides/server/lib/builder-design-system-proxy.ts +14 -2
  94. package/dist/a2a/audience.d.ts +2 -0
  95. package/dist/a2a/audience.js +23 -0
  96. package/dist/a2a/client.d.ts +4 -0
  97. package/dist/a2a/client.js +32 -14
  98. package/dist/a2a/server.d.ts +9 -4
  99. package/dist/a2a/server.js +52 -25
  100. package/dist/a2a/types.d.ts +4 -4
  101. package/dist/agent/production-agent.js +1 -1
  102. package/dist/brand-kit/types.d.ts +10 -2
  103. package/dist/cli/code.js +1 -1
  104. package/dist/cli/index.js +30 -1
  105. package/dist/cli/native-dependencies.d.ts +24 -0
  106. package/dist/cli/native-dependencies.js +264 -0
  107. package/dist/cli/plan-local.js +1 -1
  108. package/dist/cli/skills-content/design-visual-edit-skill.d.ts +1 -1
  109. package/dist/cli/skills-content/design-visual-edit-skill.js +2 -2
  110. package/dist/cli/visualize-repo.js +1 -1
  111. package/dist/client/FeedbackButton.js +12 -12
  112. package/dist/client/agent-chat-adapter.js +3 -4
  113. package/dist/client/assistant-ui-recovery.d.ts +1 -1
  114. package/dist/client/assistant-ui-recovery.js +4 -0
  115. package/dist/client/chat/message-components.d.ts +11 -3
  116. package/dist/client/chat/message-components.js +31 -5
  117. package/dist/client/chat/tool-call-display.d.ts +2 -1
  118. package/dist/client/chat/tool-call-display.js +33 -15
  119. package/dist/client/db-admin/SqlEditor.js +1 -1
  120. package/dist/client/dev-overlay/DevOverlay.js +2 -2
  121. package/dist/client/extensions/portable-extension.js +4 -0
  122. package/dist/client/guided-questions.d.ts +8 -0
  123. package/dist/client/guided-questions.js +12 -3
  124. package/dist/client/sharing/ShareButton.js +16 -24
  125. package/dist/client/sse-event-processor.js +35 -15
  126. package/dist/client/tool-display.d.ts +9 -0
  127. package/dist/client/tool-display.js +39 -0
  128. package/dist/client/vite-dev-recovery-script.js +1 -1
  129. package/dist/collab/awareness.d.ts +2 -2
  130. package/dist/collab/routes.d.ts +1 -1
  131. package/dist/collab/struct-routes.d.ts +1 -1
  132. package/dist/extensions/html-shell.js +5 -0
  133. package/dist/notifications/routes.d.ts +1 -1
  134. package/dist/observability/routes.d.ts +3 -3
  135. package/dist/provider-api/actions/custom-provider-registration.d.ts +2 -2
  136. package/dist/server/agent-capabilities.js +0 -0
  137. package/dist/server/agent-chat/action-filters-a2a.d.ts +14 -13
  138. package/dist/server/agent-chat/action-filters-a2a.js +59 -23
  139. package/dist/server/agent-chat/prompt-resources.js +17 -16
  140. package/dist/server/agent-chat-plugin.d.ts +9 -0
  141. package/dist/server/agent-chat-plugin.js +29 -7
  142. package/dist/server/agent-engine-api-key-route.d.ts +1 -1
  143. package/dist/server/builder-design-systems.d.ts +33 -1
  144. package/dist/server/builder-design-systems.js +293 -11
  145. package/dist/server/design-token-utils.d.ts +11 -0
  146. package/dist/server/design-token-utils.js +68 -16
  147. package/dist/server/index.d.ts +1 -1
  148. package/dist/server/index.js +1 -1
  149. package/package.json +2 -2
@@ -32,6 +32,8 @@ export type DesignHtmlIntegrityIssue =
32
32
  | "close-tag-orphaned"
33
33
  | "content-truncated"
34
34
  | "runtime-missing"
35
+ | "runtime-alpine-missing"
36
+ | "runtime-cloak-missing"
35
37
  | "url-backed-screen-replaced";
36
38
 
37
39
  /**
@@ -86,6 +88,10 @@ const DOCUMENT_SHAPE_MESSAGES: Partial<
86
88
  "an editor-managed <style>/<script> block appears more than once; there must be exactly one of each",
87
89
  "url-backed-screen-replaced":
88
90
  "this screen's content is its live route URL, and the write would replace it with document markup — that permanently unbinds the screen from the running app. Edit the app's own source instead",
91
+ "runtime-cloak-missing":
92
+ "this document uses x-cloak without the CSS rule that keeps Alpine-controlled content hidden before Alpine starts",
93
+ "runtime-alpine-missing":
94
+ "this document uses x-cloak but does not load Alpine.js, so the hidden state can never be removed",
89
95
  };
90
96
 
91
97
  export function describeDesignHtmlIntegrityIssue(
@@ -141,6 +147,19 @@ export function describeDesignHtmlIntegrityIssue(
141
147
  `<script src="…@tailwindcss/browser@4"> or a <style type="text/tailwindcss">). ` +
142
148
  `Utility classes will not apply and the design renders unstyled.`
143
149
  );
150
+ case "runtime-alpine-missing":
151
+ return (
152
+ `the document uses x-cloak on <${detail.tag ?? "element"}> at ${at}, ` +
153
+ `but no script source contains Alpine.js. The element will remain ` +
154
+ `hidden forever; load Alpine.js before relying on x-cloak.`
155
+ );
156
+ case "runtime-cloak-missing":
157
+ return (
158
+ `the document uses x-cloak on <${detail.tag ?? "element"}> at ${at}, ` +
159
+ `but no style block defines [x-cloak] { display: none !important; }. ` +
160
+ `Alpine-controlled overlays can flash or cover the entire screen before ` +
161
+ `Alpine starts. Add that exact hiding rule to the document.`
162
+ );
144
163
  default:
145
164
  return `the document structure is invalid (${detail.issue}) at ${at}.`;
146
165
  }
@@ -1077,6 +1096,85 @@ function collectManagedMarkerIssue(
1077
1096
  return null;
1078
1097
  }
1079
1098
 
1099
+ /**
1100
+ * The selector may sit anywhere in a comma-separated list, and any of the three
1101
+ * hidings below is a correct pre-Alpine hide. Matching only
1102
+ * `[x-cloak] { display: none }` rejects documents that render perfectly.
1103
+ */
1104
+ const X_CLOAK_RULE =
1105
+ /\[x-cloak\][^{}]*\{[^}]*(?:display\s*:\s*none|visibility\s*:\s*hidden|@apply[^;}]*\bhidden\b)/i;
1106
+ const ALPINE_RUNTIME = /\balpinejs\b/i;
1107
+ const INLINE_PRE_HIDE = /(?:display\s*:\s*none|visibility\s*:\s*hidden)/i;
1108
+
1109
+ /**
1110
+ * `x-cloak` is an Alpine convention, not a runtime feature: it only works
1111
+ * when the authored document also supplies the CSS rule that hides the node
1112
+ * before Alpine initializes. A missing rule is especially dangerous for
1113
+ * fixed overlays, which can make a correct screen look completely replaced.
1114
+ */
1115
+ function collectInteractiveRuntimeIssues(
1116
+ parsed: ParsedDocument,
1117
+ locate: Locator,
1118
+ ): DesignHtmlIntegrityIssueDetail[] {
1119
+ const cloaked = parsed.elements.find((element) =>
1120
+ element.attrs.some(
1121
+ (attribute) => attribute.name.toLowerCase() === "x-cloak",
1122
+ ),
1123
+ );
1124
+ if (!cloaked) return [];
1125
+
1126
+ const hasAlpineRuntime = parsed.elements.some(
1127
+ (element) =>
1128
+ element.tagName === "script" &&
1129
+ ALPINE_RUNTIME.test(attributeOf(element, "src") ?? ""),
1130
+ );
1131
+
1132
+ // A linked stylesheet is content this parser cannot read, so its rules are
1133
+ // unknown — not missing. Reporting "no rule defined" here would be the
1134
+ // coercion this whole module exists to prevent.
1135
+ const hasUnreadableStylesheet = parsed.elements.some(
1136
+ (element) =>
1137
+ element.tagName === "link" &&
1138
+ /\bstylesheet\b/i.test(attributeOf(element, "rel") ?? "") &&
1139
+ (attributeOf(element, "href") ?? "").trim().length > 0,
1140
+ );
1141
+
1142
+ const hasCloakRule =
1143
+ hasUnreadableStylesheet ||
1144
+ INLINE_PRE_HIDE.test(attributeOf(cloaked, "style") ?? "") ||
1145
+ parsed.elements.some((element) => {
1146
+ if (element.tagName !== "style") return false;
1147
+ const css = childrenOf(element)
1148
+ .filter((node) => node.nodeName === "#text")
1149
+ .map((node) => (node as DefaultTreeAdapterTypes.TextNode).value)
1150
+ .join("\n");
1151
+ return X_CLOAK_RULE.test(css);
1152
+ });
1153
+
1154
+ const attribute = cloaked.attrs.find(
1155
+ (entry) => entry.name.toLowerCase() === "x-cloak",
1156
+ );
1157
+ const offset =
1158
+ locationOf(cloaked)?.attrs?.[attribute?.name ?? ""]?.startOffset ??
1159
+ locationOf(cloaked)?.startOffset ??
1160
+ 0;
1161
+ const detail = {
1162
+ line: locate(offset).line,
1163
+ column: locate(offset).column,
1164
+ excerpt: locate(offset).excerpt,
1165
+ tag: cloaked.tagName,
1166
+ attribute: "x-cloak",
1167
+ };
1168
+ return [
1169
+ ...(hasAlpineRuntime
1170
+ ? []
1171
+ : [{ issue: "runtime-alpine-missing" as const, ...detail }]),
1172
+ ...(hasCloakRule
1173
+ ? []
1174
+ : [{ issue: "runtime-cloak-missing" as const, ...detail }]),
1175
+ ];
1176
+ }
1177
+
1080
1178
  /**
1081
1179
  * Reported, never enforced: legitimate fragments and token-only screens carry no
1082
1180
  * runtime of their own, so blocking here would reject valid work.
@@ -1142,10 +1240,45 @@ export function inspectDesignHtmlDocumentIntegrity(
1142
1240
  const marker = collectManagedMarkerIssue(parsed);
1143
1241
  if (marker) return { valid: false, issue: marker };
1144
1242
 
1243
+ const interactiveRuntime = collectInteractiveRuntimeIssues(parsed, locate);
1244
+ if (interactiveRuntime.length > 0) {
1245
+ return {
1246
+ valid: false,
1247
+ issue: interactiveRuntime[0]!.issue,
1248
+ detail: interactiveRuntime,
1249
+ };
1250
+ }
1251
+
1145
1252
  const advisory = collectAdvisoryIssues(parsed, locate);
1146
1253
  return advisory.length > 0 ? { valid: true, advisory } : { valid: true };
1147
1254
  }
1148
1255
 
1256
+ const RUNTIME_ISSUES: ReadonlySet<DesignHtmlIntegrityIssue> = new Set([
1257
+ "runtime-alpine-missing",
1258
+ "runtime-cloak-missing",
1259
+ ]);
1260
+
1261
+ /**
1262
+ * The runtime issues are the one class an edit may carry forward. A screen
1263
+ * saved before these checks existed still renders, and the person dragging on
1264
+ * the canvas did not author its markup and cannot add a CSS rule — refusing
1265
+ * their unrelated edit strands the screen. Block what the edit introduces;
1266
+ * the create path still refuses to author the defect in the first place.
1267
+ */
1268
+ function introducedRuntimeIssues(
1269
+ next: DesignHtmlIntegrityIssueDetail[],
1270
+ previousContent: string,
1271
+ ): DesignHtmlIntegrityIssueDetail[] {
1272
+ if (next.length === 0 || !previousContent.trim()) return next;
1273
+ const inherited = new Set(
1274
+ collectInteractiveRuntimeIssues(
1275
+ parseDocument(previousContent),
1276
+ createLocator(previousContent),
1277
+ ).map((entry) => entry.issue),
1278
+ );
1279
+ return next.filter((entry) => !inherited.has(entry.issue));
1280
+ }
1281
+
1149
1282
  /**
1150
1283
  * Fail closed only for document edits. Standalone Alpine fragments remain
1151
1284
  * supported. Existing malformed documents can still be repaired: a candidate
@@ -1186,6 +1319,19 @@ export function assertDesignHtmlEditIntegrity(args: {
1186
1319
  detail: structural,
1187
1320
  });
1188
1321
  }
1322
+ const interactiveRuntime = introducedRuntimeIssues(
1323
+ collectInteractiveRuntimeIssues(
1324
+ parseDocument(args.nextContent),
1325
+ createLocator(args.nextContent),
1326
+ ),
1327
+ args.previousContent,
1328
+ );
1329
+ if (interactiveRuntime.length > 0) {
1330
+ throw new DesignHtmlIntegrityError(interactiveRuntime[0]!.issue, {
1331
+ filename: args.filename,
1332
+ detail: interactiveRuntime,
1333
+ });
1334
+ }
1189
1335
  return;
1190
1336
  }
1191
1337
  if (previousIsDocument && !nextIsDocument) {
@@ -1195,6 +1341,17 @@ export function assertDesignHtmlEditIntegrity(args: {
1195
1341
  }
1196
1342
  const result = inspectDesignHtmlDocumentIntegrity(args.nextContent);
1197
1343
  if (!result.valid) {
1344
+ if (result.issue && RUNTIME_ISSUES.has(result.issue)) {
1345
+ const introduced = introducedRuntimeIssues(
1346
+ result.detail ?? [],
1347
+ args.previousContent,
1348
+ );
1349
+ if (introduced.length === 0) return;
1350
+ throw new DesignHtmlIntegrityError(introduced[0]!.issue, {
1351
+ filename: args.filename,
1352
+ detail: introduced,
1353
+ });
1354
+ }
1198
1355
  throw new DesignHtmlIntegrityError(result.issue ?? "document-root", {
1199
1356
  filename: args.filename,
1200
1357
  detail: result.detail,
@@ -1227,6 +1384,20 @@ export function assertDesignHtmlWellFormed(args: {
1227
1384
  detail: structural,
1228
1385
  });
1229
1386
  }
1387
+ // Fragments are checked too, unlike the document-shape rules above: a screen
1388
+ // is rendered as its own `srcdoc`, so nothing injects Alpine or a `[x-cloak]`
1389
+ // rule around it. A sketch that omits them is broken exactly as a full
1390
+ // document would be.
1391
+ const interactiveRuntime = collectInteractiveRuntimeIssues(
1392
+ parseDocument(args.content),
1393
+ createLocator(args.content),
1394
+ );
1395
+ if (interactiveRuntime.length > 0) {
1396
+ throw new DesignHtmlIntegrityError(interactiveRuntime[0]!.issue, {
1397
+ filename: args.filename,
1398
+ detail: interactiveRuntime,
1399
+ });
1400
+ }
1230
1401
  }
1231
1402
 
1232
1403
  export function assertDesignHtmlCreateIntegrity(args: {
@@ -194,5 +194,5 @@ export function formatShortcut(key: string): string {
194
194
  if (lower === "space") return "Space";
195
195
  return token.length === 1 ? token.toUpperCase() : token;
196
196
  })
197
- .join("+");
197
+ .join(" ");
198
198
  }
@@ -72,12 +72,16 @@ Builder indexing flow.
72
72
 
73
73
  ### Source: connected code, GitHub, or `design.md`
74
74
 
75
- For any other reusable source — connected code, a GitHub repo, local
76
- code/design files, or an optional `design.md` — use Builder-backed DSI
77
- indexing through `index-design-system-with-builder`. Pass readable `design.md`
78
- content as `designMd`, and use the returned local design system id in the rest
79
- of the Slides flow. Call `get-design-system` before generation so Builder docs
80
- and tokens are hydrated when available.
75
+ For any other reusable source - connected code, a GitHub repo, local
76
+ code/design files, or an optional `design.md` - use Builder-backed DSI
77
+ indexing through `index-design-system-with-builder`. Pass GitHub sources as one
78
+ `githubSources` array; each source may pin a branch/tag/commit and include
79
+ repository-relative files or folders. Pass readable `design.md` content as
80
+ `designMd`, and use the returned local design system id in the rest of the
81
+ Slides flow. Call `get-design-system` before generation so Builder docs and
82
+ tokens are hydrated when available. For a saved GitHub-backed system, call
83
+ `sync-design-system-with-builder --id <localDesignSystemId>` to replay its
84
+ persisted source scope after upstream changes.
81
85
 
82
86
  Never create a duplicate local design system from raw Figma or code sources.
83
87
  Builder owns the indexed brand kit; a second local copy drifts from it and
@@ -32,6 +32,30 @@ const codeFileSchema = z.object({
32
32
  ),
33
33
  });
34
34
 
35
+ const githubSourceSchema = z.object({
36
+ repoUrl: z.string().trim().min(1).describe("GitHub repository URL"),
37
+ ref: z
38
+ .string()
39
+ .trim()
40
+ .min(1)
41
+ .optional()
42
+ .describe("Optional branch, tag, or commit"),
43
+ include: z
44
+ .array(z.string().trim().min(1))
45
+ .optional()
46
+ .describe("Optional repository-relative files or folders to include"),
47
+ exclude: z
48
+ .array(z.string().trim().min(1))
49
+ .optional()
50
+ .describe("Optional repository-relative files or folders to exclude"),
51
+ instructions: z
52
+ .string()
53
+ .trim()
54
+ .min(1)
55
+ .optional()
56
+ .describe("Optional indexing guidance for this repository"),
57
+ });
58
+
35
59
  export default defineAction({
36
60
  description:
37
61
  "Start Builder DSI design-system indexing from connected code, a GitHub repository, code/design files, and optional design.md guidance. " +
@@ -49,7 +73,15 @@ export default defineAction({
49
73
  githubRepoUrl: z
50
74
  .string()
51
75
  .optional()
52
- .describe("GitHub repository URL to index with Builder"),
76
+ .describe("Legacy single GitHub repository URL to index with Builder"),
77
+ githubSources: z
78
+ .array(githubSourceSchema)
79
+ .min(1)
80
+ .max(20)
81
+ .optional()
82
+ .describe(
83
+ "GitHub repositories to index in one design system. Each source may specify a branch/tag/commit and repository-relative files or folders.",
84
+ ),
53
85
  connectedProjectId: z
54
86
  .string()
55
87
  .optional()
@@ -69,6 +101,7 @@ export default defineAction({
69
101
  projectName,
70
102
  description,
71
103
  githubRepoUrl,
104
+ githubSources,
72
105
  connectedProjectId,
73
106
  codeFiles,
74
107
  designMd,
@@ -81,6 +114,7 @@ export default defineAction({
81
114
  projectName,
82
115
  description,
83
116
  githubRepoUrl,
117
+ githubRepos: githubSources,
84
118
  connectedProjectId,
85
119
  files,
86
120
  });
@@ -93,10 +127,13 @@ export default defineAction({
93
127
  orgId: getRequestOrgId(),
94
128
  projectName,
95
129
  description,
130
+ githubSources:
131
+ githubSources ?? (githubRepoUrl ? [{ repoUrl: githubRepoUrl }] : []),
96
132
  sourceKind:
97
- githubRepoUrl && (codeFiles?.length || designMd)
133
+ (githubSources?.length || githubRepoUrl) &&
134
+ (codeFiles?.length || designMd)
98
135
  ? "mixed"
99
- : githubRepoUrl
136
+ : githubSources?.length || githubRepoUrl
100
137
  ? "github"
101
138
  : codeFiles?.length || designMd
102
139
  ? "code"
@@ -107,6 +144,7 @@ export default defineAction({
107
144
  ...result,
108
145
  ...proxy,
109
146
  uploadedFileCount: files.length,
147
+ githubSourceCount: githubSources?.length ?? (githubRepoUrl ? 1 : 0),
110
148
  };
111
149
  },
112
150
  });
@@ -157,6 +157,14 @@ const AddSlideOp = z.object({
157
157
  notes: z.string().optional(),
158
158
  layout: z.string().optional(),
159
159
  background: z.string().optional(),
160
+ imageUrl: z.string().optional(),
161
+ imagePrompt: z.string().optional(),
162
+ excalidrawData: z.string().optional(),
163
+ transition: z
164
+ .enum(["instant", "none", "fade", "slide", "zoom"])
165
+ .optional(),
166
+ animations: z.array(z.unknown()).optional(),
167
+ splitByParagraph: z.boolean().optional(),
160
168
  })
161
169
  .passthrough(),
162
170
  });
@@ -382,7 +390,10 @@ export function applyOperation(deck: any, op: Operation): void {
382
390
  // Idempotency: if the slide already exists (duplicate delivery), skip.
383
391
  if (slides.some((s: { id: string }) => s.id === slideId)) return;
384
392
  // eslint-disable-next-line @typescript-eslint/no-explicit-any
393
+ // Copy every provided field: a duplicated or undo-restored slide has to
394
+ // keep its transition, animations, and image data, not just its text.
385
395
  const newSlide: any = {
396
+ ...fields,
386
397
  id: slideId,
387
398
  content:
388
399
  typeof fields.content === "string"
@@ -391,9 +402,7 @@ export function applyOperation(deck: any, op: Operation): void {
391
402
  notes: fields.notes ?? "",
392
403
  layout: fields.layout ?? "content",
393
404
  };
394
- if (fields.background !== undefined) {
395
- newSlide.background = fields.background;
396
- }
405
+ delete newSlide.imageLoading;
397
406
  const insertAfterIdx = afterSlideId
398
407
  ? slides.findIndex((s: { id: string }) => s.id === afterSlideId)
399
408
  : -1;
@@ -0,0 +1,64 @@
1
+ import { defineAction } from "@agent-native/core";
2
+ import {
3
+ parseBuilderDesignSystemProxyReference,
4
+ startBuilderDesignSystemIndex,
5
+ } from "@agent-native/core/server";
6
+ import { getRequestUserEmail } from "@agent-native/core/server/request-context";
7
+ import { assertAccess, resolveAccess } from "@agent-native/core/sharing";
8
+ import { z } from "zod";
9
+
10
+ import "../server/db/index.js";
11
+ import { upsertBuilderProxyDesignSystem } from "../server/lib/builder-design-system-proxy.js";
12
+
13
+ export default defineAction({
14
+ description:
15
+ "Re-index a Builder-backed GitHub design system using its persisted repository, ref, and file/folder scope. Requires editor access.",
16
+ schema: z.object({
17
+ id: z.string().min(1).describe("Local design system id"),
18
+ }),
19
+ run: async ({ id }) => {
20
+ await assertAccess("design-system", id, "editor");
21
+ const access = await resolveAccess("design-system", id);
22
+ if (!access) throw new Error("Design system not found");
23
+
24
+ const reference = parseBuilderDesignSystemProxyReference(
25
+ access.resource.data,
26
+ );
27
+ if (!reference?.githubSources?.length) {
28
+ throw new Error(
29
+ "This design system has no persisted GitHub source scope to sync.",
30
+ );
31
+ }
32
+ if (reference.sourceKind === "mixed") {
33
+ throw new Error(
34
+ "This design system combines GitHub with non-replayable sources. Re-import all sources before syncing it.",
35
+ );
36
+ }
37
+
38
+ const result = await startBuilderDesignSystemIndex({
39
+ projectName: access.resource.title,
40
+ description: access.resource.description ?? undefined,
41
+ githubRepos: reference.githubSources,
42
+ });
43
+ const ownerEmail = getRequestUserEmail();
44
+ if (!ownerEmail) throw new Error("no authenticated user");
45
+
46
+ const proxy = await upsertBuilderProxyDesignSystem({
47
+ result,
48
+ ownerEmail: access.resource.ownerEmail,
49
+ orgId: access.resource.orgId,
50
+ projectName: access.resource.title,
51
+ description: access.resource.description ?? undefined,
52
+ sourceKind: reference.sourceKind,
53
+ githubSources: reference.githubSources,
54
+ localDesignSystemId: id,
55
+ });
56
+
57
+ return {
58
+ ...result,
59
+ ...proxy,
60
+ synced: true,
61
+ githubSourceCount: reference.githubSources.length,
62
+ };
63
+ },
64
+ });
@@ -189,7 +189,7 @@ export default function DeckCard({
189
189
  </DropdownMenuTrigger>
190
190
  <DropdownMenuContent
191
191
  align="end"
192
- className="w-40"
192
+ className="w-56"
193
193
  onCloseAutoFocus={(e) => {
194
194
  if (pendingRenameRef.current) {
195
195
  e.preventDefault();