@agent-native/core 0.163.4 → 0.164.3

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 (228) hide show
  1. package/corpus/README.md +1 -1
  2. package/corpus/templates/analytics/app/components/agents/FeatureFlagsFleetPanel.tsx +78 -19
  3. package/corpus/templates/analytics/app/hooks/use-dashboard-chat-context.ts +29 -0
  4. package/corpus/templates/analytics/app/lib/use-auto-focus-select.ts +4 -4
  5. package/corpus/templates/analytics/app/pages/adhoc/explorer-dashboard/index.tsx +3 -0
  6. package/corpus/templates/analytics/app/pages/adhoc/sql-dashboard/index.tsx +6 -0
  7. package/corpus/templates/analytics/app/pages/sessions/SessionsPage.tsx +1 -2
  8. package/corpus/templates/analytics/app/routes/_index.tsx +3 -2
  9. package/corpus/templates/analytics/app/routes/adhoc.$id.tsx +7 -2
  10. package/corpus/templates/analytics/app/routes/dashboard.tsx +3 -2
  11. package/corpus/templates/analytics/app/routes/overview.tsx +3 -2
  12. package/corpus/templates/analytics/app/routes/traffic.tsx +3 -2
  13. package/corpus/templates/analytics/changelog/2026-08-18-verify-cross-app-feature-flag-changes.md +6 -0
  14. package/corpus/templates/analytics/netlify.toml +2 -0
  15. package/corpus/templates/analytics/server/lib/workspace-feature-flags.ts +196 -48
  16. package/corpus/templates/analytics/server/plugins/feature-flags.ts +5 -0
  17. package/corpus/templates/analytics/shared/feature-flags.ts +10 -0
  18. package/corpus/templates/assets/app/routes/brand-kits.$id.tsx +5 -1
  19. package/corpus/templates/assets/app/routes/brand-kits._index.tsx +4 -1
  20. package/corpus/templates/assets/app/routes/libraries.tsx +4 -1
  21. package/corpus/templates/assets/app/routes/picker.tsx +4 -1
  22. package/corpus/templates/assets/netlify.toml +2 -0
  23. package/corpus/templates/brain/netlify.toml +2 -0
  24. package/corpus/templates/calendar/app/components/calendar/DayView.tsx +2 -1
  25. package/corpus/templates/calendar/changelog/2026-08-19-calendar-page-loads-stay-fast-after-idle-periods.md +6 -0
  26. package/corpus/templates/calendar/netlify.toml +2 -0
  27. package/corpus/templates/chat/netlify.toml +2 -0
  28. package/corpus/templates/clips/app/components/player/player-controls.tsx +3 -3
  29. package/corpus/templates/clips/app/components/player/reaction-emojis.ts +12 -0
  30. package/corpus/templates/clips/app/components/player/reactions-tray.tsx +90 -9
  31. package/corpus/templates/clips/app/components/player/scrubber.tsx +43 -10
  32. package/corpus/templates/clips/app/components/player/video-player.tsx +105 -15
  33. package/corpus/templates/clips/app/routes/_app.settings._index.tsx +1 -2
  34. package/corpus/templates/clips/app/routes/_app.wispr.tsx +2 -1
  35. package/corpus/templates/clips/app/routes/_index.tsx +7 -3
  36. package/corpus/templates/clips/app/routes/r.$recordingId.tsx +13 -8
  37. package/corpus/templates/clips/app/routes/share.$shareId.tsx +15 -8
  38. package/corpus/templates/clips/netlify.toml +2 -0
  39. package/corpus/templates/clips/server/routes/[...page].head.ts +5 -0
  40. package/corpus/templates/content/netlify.toml +2 -0
  41. package/corpus/templates/design/.agents/skills/design-editor-architecture/SKILL.md +103 -0
  42. package/corpus/templates/design/.agents/skills/design-generation/SKILL.md +2 -1
  43. package/corpus/templates/design/AGENTS.md +3 -1
  44. package/corpus/templates/design/app/components/design/bridge/editor-chrome.bridge.ts +3 -2
  45. package/corpus/templates/design/app/components/design/editor/AgentNativeMenuMark.tsx +25 -0
  46. package/corpus/templates/design/app/components/design/editor/DesignBottomToolbar.tsx +411 -0
  47. package/corpus/templates/design/app/components/design/editor/DesignCollaborators.tsx +153 -0
  48. package/corpus/templates/design/app/components/design/editor/DesignWorkspaceRail.tsx +231 -0
  49. package/corpus/templates/design/app/components/design/editor/MakeRealDialog.tsx +223 -0
  50. package/corpus/templates/design/app/components/design/editor/PendingScreenDeletionDialog.tsx +58 -0
  51. package/corpus/templates/design/app/components/design/editor/PendingVisualStyleWarningDialog.tsx +56 -0
  52. package/corpus/templates/design/app/components/design/editor/ReadOnlyEditorPanel.tsx +23 -0
  53. package/corpus/templates/design/app/components/design/editor/SaveTemplateDialog.tsx +161 -0
  54. package/corpus/templates/design/app/components/design/editor/toolbar-controls.tsx +185 -0
  55. package/corpus/templates/design/app/pages/DesignEditor.tsx +20913 -0
  56. package/corpus/templates/design/app/pages/design-editor/command-types.ts +120 -0
  57. package/corpus/templates/design/app/pages/design-editor/commands/README.md +193 -0
  58. package/corpus/templates/design/app/pages/design-editor/commands/add-auto-layout.ts +416 -0
  59. package/corpus/templates/design/app/pages/design-editor/commands/add-screen.ts +112 -0
  60. package/corpus/templates/design/app/pages/design-editor/commands/align-selection.ts +183 -0
  61. package/corpus/templates/design/app/pages/design-editor/commands/apply-design-editor-command.ts +243 -0
  62. package/corpus/templates/design/app/pages/design-editor/commands/apply-file-content-update.ts +236 -0
  63. package/corpus/templates/design/app/pages/design-editor/commands/apply-local-content-update.ts +304 -0
  64. package/corpus/templates/design/app/pages/design-editor/commands/apply-pending-visual-styles-with-agent.ts +376 -0
  65. package/corpus/templates/design/app/pages/design-editor/commands/apply-to-source.ts +132 -0
  66. package/corpus/templates/design/app/pages/design-editor/commands/can-move-layer.ts +117 -0
  67. package/corpus/templates/design/app/pages/design-editor/commands/change-selected-z-index.ts +212 -0
  68. package/corpus/templates/design/app/pages/design-editor/commands/commit-relative-style-delta-to-selected-layers.ts +176 -0
  69. package/corpus/templates/design/app/pages/design-editor/commands/commit-styles-to-selected-layers.ts +175 -0
  70. package/corpus/templates/design/app/pages/design-editor/commands/commit-visual-styles.ts +710 -0
  71. package/corpus/templates/design/app/pages/design-editor/commands/confirm-make-real.ts +99 -0
  72. package/corpus/templates/design/app/pages/design-editor/commands/copy-as-figma-svg.ts +95 -0
  73. package/corpus/templates/design/app/pages/design-editor/commands/copy-selection.ts +156 -0
  74. package/corpus/templates/design/app/pages/design-editor/commands/create-primitive.ts +291 -0
  75. package/corpus/templates/design/app/pages/design-editor/commands/create-screen-frame.ts +131 -0
  76. package/corpus/templates/design/app/pages/design-editor/commands/cross-screen-element-drop.ts +577 -0
  77. package/corpus/templates/design/app/pages/design-editor/commands/delete-files.ts +364 -0
  78. package/corpus/templates/design/app/pages/design-editor/commands/delete-selection.ts +521 -0
  79. package/corpus/templates/design/app/pages/design-editor/commands/detach-instance-menu-action.ts +88 -0
  80. package/corpus/templates/design/app/pages/design-editor/commands/distribute-selection.ts +114 -0
  81. package/corpus/templates/design/app/pages/design-editor/commands/download-all-screens-pdf.ts +116 -0
  82. package/corpus/templates/design/app/pages/design-editor/commands/download-pdf.ts +103 -0
  83. package/corpus/templates/design/app/pages/design-editor/commands/download-svg.ts +159 -0
  84. package/corpus/templates/design/app/pages/design-editor/commands/duplicate-screen.ts +201 -0
  85. package/corpus/templates/design/app/pages/design-editor/commands/duplicate-selection.ts +279 -0
  86. package/corpus/templates/design/app/pages/design-editor/commands/editor-paste.ts +81 -0
  87. package/corpus/templates/design/app/pages/design-editor/commands/enter-hotkey.ts +155 -0
  88. package/corpus/templates/design/app/pages/design-editor/commands/enter-single-screen.ts +168 -0
  89. package/corpus/templates/design/app/pages/design-editor/commands/escape-hotkey.ts +212 -0
  90. package/corpus/templates/design/app/pages/design-editor/commands/frame-selection.ts +119 -0
  91. package/corpus/templates/design/app/pages/design-editor/commands/geometry-commit.ts +169 -0
  92. package/corpus/templates/design/app/pages/design-editor/commands/get-selected-layer-snapshots.ts +177 -0
  93. package/corpus/templates/design/app/pages/design-editor/commands/group-selection.ts +127 -0
  94. package/corpus/templates/design/app/pages/design-editor/commands/iframe-context-menu.ts +121 -0
  95. package/corpus/templates/design/app/pages/design-editor/commands/import-figma-clipboard-into-design.ts +119 -0
  96. package/corpus/templates/design/app/pages/design-editor/commands/layer-marquee-selection-change.ts +163 -0
  97. package/corpus/templates/design/app/pages/design-editor/commands/layer-move-to-screen.ts +331 -0
  98. package/corpus/templates/design/app/pages/design-editor/commands/layer-move.ts +517 -0
  99. package/corpus/templates/design/app/pages/design-editor/commands/layer-rename.ts +247 -0
  100. package/corpus/templates/design/app/pages/design-editor/commands/layer-selection-change.ts +161 -0
  101. package/corpus/templates/design/app/pages/design-editor/commands/mode-change.ts +122 -0
  102. package/corpus/templates/design/app/pages/design-editor/commands/nudge-selection.ts +213 -0
  103. package/corpus/templates/design/app/pages/design-editor/commands/overview-primitive-reparent.ts +318 -0
  104. package/corpus/templates/design/app/pages/design-editor/commands/paste-copied-screens.ts +114 -0
  105. package/corpus/templates/design/app/pages/design-editor/commands/paste-over-selection.ts +70 -0
  106. package/corpus/templates/design/app/pages/design-editor/commands/paste-selection.ts +436 -0
  107. package/corpus/templates/design/app/pages/design-editor/commands/paste-to-replace.ts +135 -0
  108. package/corpus/templates/design/app/pages/design-editor/commands/pasted-image-files.ts +209 -0
  109. package/corpus/templates/design/app/pages/design-editor/commands/persist-frame-geometry-save.ts +113 -0
  110. package/corpus/templates/design/app/pages/design-editor/commands/persist-tweak-save.ts +160 -0
  111. package/corpus/templates/design/app/pages/design-editor/commands/primitive-created.ts +168 -0
  112. package/corpus/templates/design/app/pages/design-editor/commands/record-pending-live-layer-state-edit.ts +149 -0
  113. package/corpus/templates/design/app/pages/design-editor/commands/record-pending-live-structure-edit.ts +200 -0
  114. package/corpus/templates/design/app/pages/design-editor/commands/record-pending-live-text-edit.ts +152 -0
  115. package/corpus/templates/design/app/pages/design-editor/commands/record-pending-visual-style-edit.ts +247 -0
  116. package/corpus/templates/design/app/pages/design-editor/commands/redo.ts +1086 -0
  117. package/corpus/templates/design/app/pages/design-editor/commands/render-png-blob.ts +200 -0
  118. package/corpus/templates/design/app/pages/design-editor/commands/save-file-content.ts +207 -0
  119. package/corpus/templates/design/app/pages/design-editor/commands/screen-element-select.ts +262 -0
  120. package/corpus/templates/design/app/pages/design-editor/commands/screen-text-content-change.ts +216 -0
  121. package/corpus/templates/design/app/pages/design-editor/commands/screen-visual-duplicate-change.ts +108 -0
  122. package/corpus/templates/design/app/pages/design-editor/commands/screen-visual-structure-change.ts +280 -0
  123. package/corpus/templates/design/app/pages/design-editor/commands/screen-visual-style-change.ts +151 -0
  124. package/corpus/templates/design/app/pages/design-editor/commands/send-overview-annotations.ts +88 -0
  125. package/corpus/templates/design/app/pages/design-editor/commands/send-runtime-layer-move-semantic-handoff.ts +122 -0
  126. package/corpus/templates/design/app/pages/design-editor/commands/send-runtime-layer-semantic-handoff.ts +143 -0
  127. package/corpus/templates/design/app/pages/design-editor/commands/send-runtime-layer-state-semantic-handoff.ts +115 -0
  128. package/corpus/templates/design/app/pages/design-editor/commands/start-retry-generation.ts +152 -0
  129. package/corpus/templates/design/app/pages/design-editor/commands/start-sidebar-resize.ts +99 -0
  130. package/corpus/templates/design/app/pages/design-editor/commands/style-change.ts +152 -0
  131. package/corpus/templates/design/app/pages/design-editor/commands/styles-change.ts +155 -0
  132. package/corpus/templates/design/app/pages/design-editor/commands/suggest-auto-layout.ts +125 -0
  133. package/corpus/templates/design/app/pages/design-editor/commands/text-content-change.ts +201 -0
  134. package/corpus/templates/design/app/pages/design-editor/commands/tidy-up.ts +123 -0
  135. package/corpus/templates/design/app/pages/design-editor/commands/toggle-layer-hidden.ts +167 -0
  136. package/corpus/templates/design/app/pages/design-editor/commands/toggle-layer-locked.ts +175 -0
  137. package/corpus/templates/design/app/pages/design-editor/commands/toggle-motion-keyframe.ts +99 -0
  138. package/corpus/templates/design/app/pages/design-editor/commands/tweak-prompt-submit.ts +84 -0
  139. package/corpus/templates/design/app/pages/design-editor/commands/undo.ts +906 -0
  140. package/corpus/templates/design/app/pages/design-editor/commands/ungroup-selection.ts +170 -0
  141. package/corpus/templates/design/app/pages/design-editor/commands/visual-duplicate-change.ts +119 -0
  142. package/corpus/templates/design/app/pages/design-editor/commands/visual-structure-change.ts +274 -0
  143. package/corpus/templates/design/app/pages/design-editor/commands/write-frame-geometry-snapshot.ts +99 -0
  144. package/corpus/templates/design/app/pages/design-editor/derive/design-breakpoints.ts +56 -0
  145. package/corpus/templates/design/app/pages/design-editor/derive/overview-screens.ts +146 -0
  146. package/corpus/templates/design/app/pages/design-editor/domains/use-tweaks.ts +326 -0
  147. package/corpus/templates/design/app/pages/design-editor/editor-constants.ts +54 -0
  148. package/corpus/templates/design/app/pages/design-editor/editor-helpers.ts +183 -0
  149. package/corpus/templates/design/app/pages/design-editor/effects/adopt-db-file-content.ts +270 -0
  150. package/corpus/templates/design/app/pages/design-editor/effects/mirror-selection-to-agent-chat.ts +134 -0
  151. package/corpus/templates/design/app/pages/design-editor/effects/motion-autosave.ts +335 -0
  152. package/corpus/templates/design/app/pages/design-editor/effects/observe-collab-text.ts +183 -0
  153. package/corpus/templates/design/app/pages/design-editor/effects/publish-agent-selection-context.ts +252 -0
  154. package/corpus/templates/design/app/pages/design-editor/effects/resume-pending-generation.ts +178 -0
  155. package/corpus/templates/design/app/pages/design-editor/effects/seed-collab-content.ts +157 -0
  156. package/corpus/templates/design/app/pages/design-editor/preview-html.ts +19 -0
  157. package/corpus/templates/design/app/routes/examples.tsx +2 -1
  158. package/corpus/templates/design/netlify.toml +2 -0
  159. package/corpus/templates/design/shared/board-file.ts +2 -1
  160. package/corpus/templates/dispatch/netlify.toml +2 -0
  161. package/corpus/templates/forms/app/routes/_index.tsx +3 -2
  162. package/corpus/templates/forms/netlify.toml +2 -0
  163. package/corpus/templates/mail/app/routes/_index.tsx +3 -2
  164. package/corpus/templates/mail/netlify.toml +2 -0
  165. package/corpus/templates/plan/netlify.toml +2 -0
  166. package/corpus/templates/slides/netlify.toml +2 -0
  167. package/corpus/templates/tasks/app/routes/_index.tsx +2 -1
  168. package/dist/agent/engine/builder-engine.d.ts +6 -4
  169. package/dist/agent/engine/builder-engine.js +91 -26
  170. package/dist/agent/engine/registry.js +16 -0
  171. package/dist/cli/code-agent-agent-tools.d.ts +2 -0
  172. package/dist/cli/code-agent-agent-tools.js +188 -0
  173. package/dist/cli/code-agent-collaboration.d.ts +34 -0
  174. package/dist/cli/code-agent-collaboration.js +104 -0
  175. package/dist/cli/code-agent-executor.js +6 -0
  176. package/dist/cli/code-agent-schedules.d.ts +54 -0
  177. package/dist/cli/code-agent-schedules.js +198 -0
  178. package/dist/client/AgentPanel.js +1 -1
  179. package/dist/client/ConnectBuilderCard.js +5 -2
  180. package/dist/client/EnvironmentBadge.js +6 -5
  181. package/dist/client/chat/run-recovery.js +3 -2
  182. package/dist/client/chat/tool-call-display.js +2 -3
  183. package/dist/client/components/CodeRequiredDialog.js +4 -2
  184. package/dist/client/i18n.js +5 -4
  185. package/dist/client/settings/SettingsPanel.js +1 -1
  186. package/dist/client/settings/VoiceTranscriptionSection.js +1 -1
  187. package/dist/client/settings/useBuilderStatus.d.ts +6 -1
  188. package/dist/client/settings/useBuilderStatus.js +22 -33
  189. package/dist/client/transcription/BuilderTranscriptionCta.js +1 -1
  190. package/dist/code-agents/index.d.ts +2 -0
  191. package/dist/code-agents/index.js +2 -0
  192. package/dist/collab/awareness.d.ts +2 -2
  193. package/dist/collab/routes.d.ts +1 -1
  194. package/dist/deploy/build.js +10 -4
  195. package/dist/localization/shared.d.ts +2 -0
  196. package/dist/localization/shared.js +5 -0
  197. package/dist/mcp-client/oauth-client.d.ts +1 -0
  198. package/dist/mcp-client/oauth-client.js +50 -1
  199. package/dist/notifications/routes.d.ts +3 -3
  200. package/dist/observability/routes.d.ts +1 -1
  201. package/dist/provider-api/actions/provider-api.d.ts +2 -2
  202. package/dist/server/auth-marketing-locales.d.ts +7 -0
  203. package/dist/server/auth-marketing-locales.js +1322 -0
  204. package/dist/server/auth-marketing.d.ts +1 -0
  205. package/dist/server/auth-marketing.js +35 -6
  206. package/dist/server/auth.js +4 -17
  207. package/dist/server/builder-browser.d.ts +22 -0
  208. package/dist/server/builder-browser.js +77 -1
  209. package/dist/server/builder-oauth.d.ts +50 -0
  210. package/dist/server/builder-oauth.js +263 -0
  211. package/dist/server/core-routes-plugin.d.ts +11 -0
  212. package/dist/server/core-routes-plugin.js +291 -415
  213. package/dist/server/credential-provider.d.ts +1 -1
  214. package/dist/server/credential-provider.js +1 -1
  215. package/dist/server/csrf.js +2 -2
  216. package/dist/server/onboarding-html.js +52 -120
  217. package/dist/server/ssr-handler.js +13 -4
  218. package/dist/settings/store.d.ts +9 -0
  219. package/dist/settings/store.js +19 -0
  220. package/dist/shared/cache-control.d.ts +22 -0
  221. package/dist/shared/cache-control.js +25 -0
  222. package/dist/shared/index.d.ts +1 -0
  223. package/dist/shared/index.js +1 -0
  224. package/dist/templates/chat/netlify.toml +2 -0
  225. package/docs/content/deployment.mdx +2 -0
  226. package/docs/content/multi-app-workspace.mdx +1 -1
  227. package/package.json +2 -2
  228. package/src/templates/chat/netlify.toml +2 -0
@@ -0,0 +1,231 @@
1
+ import { useT } from "@agent-native/core/client/i18n";
2
+ import {
3
+ IconAssembly,
4
+ IconChevronDown,
5
+ IconChevronUp,
6
+ IconCode,
7
+ IconFile,
8
+ IconFileImport,
9
+ IconMessage,
10
+ IconPhoto,
11
+ IconPuzzle,
12
+ } from "@tabler/icons-react";
13
+ import type { ReactNode } from "react";
14
+
15
+ import { preloadCodeWorkbench } from "@/components/design/code-workbench/CodeWorkbenchLoader";
16
+ import {
17
+ Tooltip,
18
+ TooltipContent,
19
+ TooltipTrigger,
20
+ } from "@/components/ui/tooltip";
21
+ import { cn } from "@/lib/utils";
22
+ import {
23
+ SHOW_DESIGN_CODE_LEFT_PANEL,
24
+ SHOW_DESIGN_SECONDARY_LEFT_PANELS,
25
+ type DesignLeftPanel,
26
+ } from "@/pages/design-editor/types";
27
+
28
+ export const INITIAL_GENERATION_DISABLED_LEFT_PANELS = new Set<DesignLeftPanel>(
29
+ ["file", "assets", "tools", "tokens", "import", "code"],
30
+ );
31
+
32
+ export function DesignWorkspaceRail({
33
+ activePanel,
34
+ disabledPanels,
35
+ hiddenPanels,
36
+ motionOpen,
37
+ motionDisabled,
38
+ projectMenu,
39
+ onMotionToggle,
40
+ onPanelChange,
41
+ }: {
42
+ activePanel: DesignLeftPanel;
43
+ disabledPanels?: ReadonlySet<DesignLeftPanel>;
44
+ hiddenPanels?: ReadonlySet<DesignLeftPanel>;
45
+ motionOpen?: boolean;
46
+ motionDisabled?: boolean;
47
+ projectMenu: ReactNode;
48
+ onMotionToggle?: () => void;
49
+ onPanelChange: (panel: DesignLeftPanel) => void;
50
+ }) {
51
+ const t = useT();
52
+ const items: Array<{
53
+ panel: DesignLeftPanel;
54
+ label: string;
55
+ icon: ReactNode;
56
+ separatorBefore?: boolean;
57
+ }> = [
58
+ {
59
+ panel: "file",
60
+ label: t("designEditor.leftRail.file"),
61
+ icon: <IconFile className="size-[15px]" />,
62
+ },
63
+ {
64
+ panel: "agent",
65
+ label: t("designEditor.leftRail.agent"),
66
+ icon: <IconMessage className="size-[15px]" />,
67
+ },
68
+ ...(SHOW_DESIGN_SECONDARY_LEFT_PANELS
69
+ ? [
70
+ {
71
+ panel: "assets" as const,
72
+ label: t("designEditor.leftRail.assets"),
73
+ icon: <IconPhoto className="size-[15px]" />,
74
+ },
75
+ ]
76
+ : []),
77
+ {
78
+ panel: "import",
79
+ label: t("designEditor.leftRail.import"),
80
+ icon: <IconFileImport className="size-[15px]" />,
81
+ },
82
+ ...(SHOW_DESIGN_SECONDARY_LEFT_PANELS
83
+ ? [
84
+ {
85
+ panel: "tools" as const,
86
+ label: t("designEditor.leftRail.tools"),
87
+ icon: <IconPuzzle className="size-[15px]" />,
88
+ },
89
+ {
90
+ panel: "tokens" as const,
91
+ label: t("designEditor.leftRail.tokens"),
92
+ icon: <IconAssembly className="size-[15px]" />,
93
+ },
94
+ ]
95
+ : []),
96
+ ...(SHOW_DESIGN_CODE_LEFT_PANEL
97
+ ? [
98
+ {
99
+ panel: "code" as const,
100
+ label: "Code" /* i18n-ignore */,
101
+ icon: <IconCode className="size-[15px]" />,
102
+ separatorBefore: true,
103
+ },
104
+ ]
105
+ : []),
106
+ ];
107
+
108
+ return (
109
+ <nav
110
+ aria-label={t("designEditor.leftRail.label")}
111
+ className="flex min-h-0 w-[57px] shrink-0 flex-col items-center overflow-y-auto overscroll-contain border-r border-[var(--design-editor-panel-divider-color)] bg-[var(--design-editor-panel-bg)] py-3"
112
+ >
113
+ <div className="mb-3 flex h-8 items-center justify-center">
114
+ {projectMenu}
115
+ </div>
116
+ <div className="mb-5 h-px w-8 bg-border/70" />
117
+ <div className="flex min-h-0 flex-1 flex-col items-center gap-4">
118
+ {items.map((item) => {
119
+ if (hiddenPanels?.has(item.panel)) return null;
120
+ const active = item.panel === activePanel;
121
+ const disabled = disabledPanels?.has(item.panel) ?? false;
122
+ return (
123
+ <div key={item.panel} className="flex w-full flex-col items-center">
124
+ {item.separatorBefore ? (
125
+ <div className="-mt-1 mb-3 h-px w-8 bg-border/70" />
126
+ ) : null}
127
+ <Tooltip>
128
+ <TooltipTrigger asChild>
129
+ <button
130
+ type="button"
131
+ aria-label={item.label}
132
+ aria-disabled={disabled || undefined}
133
+ aria-current={active ? "page" : undefined}
134
+ tabIndex={disabled ? -1 : undefined}
135
+ onClick={(event) => {
136
+ if (disabled) {
137
+ event.preventDefault();
138
+ return;
139
+ }
140
+ onPanelChange(item.panel);
141
+ }}
142
+ onPointerEnter={() => {
143
+ if (item.panel === "code") preloadCodeWorkbench();
144
+ }}
145
+ onFocus={() => {
146
+ if (item.panel === "code") preloadCodeWorkbench();
147
+ }}
148
+ className={cn(
149
+ "group flex w-12 cursor-pointer flex-col items-center justify-start gap-1 rounded-none text-[10px] font-[450] leading-none text-muted-foreground outline-none transition-colors hover:text-foreground focus-visible:ring-1 focus-visible:ring-[var(--design-editor-accent-color)]",
150
+ disabled &&
151
+ "cursor-default opacity-35 hover:text-muted-foreground",
152
+ active && "text-foreground",
153
+ )}
154
+ >
155
+ <span
156
+ className={cn(
157
+ "flex size-8 items-center justify-center rounded-lg transition-colors",
158
+ active
159
+ ? "bg-[var(--design-editor-selection-color)] text-[var(--design-editor-accent-color)]"
160
+ : "text-muted-foreground group-hover:bg-[var(--design-editor-layer-hover-color)] group-hover:text-foreground",
161
+ disabled &&
162
+ "group-hover:bg-transparent group-hover:text-muted-foreground",
163
+ )}
164
+ >
165
+ {item.icon}
166
+ </span>
167
+ <span className="max-w-full truncate leading-none">
168
+ {item.label}
169
+ </span>
170
+ </button>
171
+ </TooltipTrigger>
172
+ <TooltipContent side="right">{item.label}</TooltipContent>
173
+ </Tooltip>
174
+ </div>
175
+ );
176
+ })}
177
+ </div>
178
+ {onMotionToggle ? (
179
+ <div className="mt-4 flex w-full flex-col items-center border-t border-border/70 pt-3">
180
+ <Tooltip>
181
+ <TooltipTrigger asChild>
182
+ <button
183
+ type="button"
184
+ aria-label={"Motion" /* i18n-ignore */}
185
+ aria-disabled={motionDisabled || undefined}
186
+ aria-pressed={motionOpen || undefined}
187
+ tabIndex={motionDisabled ? -1 : undefined}
188
+ onClick={(event) => {
189
+ if (motionDisabled) {
190
+ event.preventDefault();
191
+ return;
192
+ }
193
+ onMotionToggle();
194
+ }}
195
+ className={cn(
196
+ "group flex w-12 cursor-pointer flex-col items-center justify-start gap-1 rounded-none !text-[10px] font-[450] leading-none text-muted-foreground outline-none transition-colors hover:text-foreground focus-visible:ring-1 focus-visible:ring-[var(--design-editor-accent-color)]",
197
+ motionDisabled &&
198
+ "cursor-default opacity-35 hover:text-muted-foreground",
199
+ motionOpen && "text-foreground",
200
+ )}
201
+ >
202
+ <span
203
+ className={cn(
204
+ "flex size-8 items-center justify-center rounded-lg transition-colors",
205
+ motionOpen
206
+ ? "bg-[var(--design-editor-selection-color)] text-[var(--design-editor-accent-color)]"
207
+ : "text-muted-foreground group-hover:bg-[var(--design-editor-layer-hover-color)] group-hover:text-foreground",
208
+ motionDisabled &&
209
+ "group-hover:bg-transparent group-hover:text-muted-foreground",
210
+ )}
211
+ >
212
+ {motionOpen ? (
213
+ <IconChevronDown className="size-[15px]" />
214
+ ) : (
215
+ <IconChevronUp className="size-[15px]" />
216
+ )}
217
+ </span>
218
+ <span className="max-w-full truncate leading-none">
219
+ {"Motion" /* i18n-ignore */}
220
+ </span>
221
+ </button>
222
+ </TooltipTrigger>
223
+ <TooltipContent side="right">
224
+ {"Motion" /* i18n-ignore */}
225
+ </TooltipContent>
226
+ </Tooltip>
227
+ </div>
228
+ ) : null}
229
+ </nav>
230
+ );
231
+ }
@@ -0,0 +1,223 @@
1
+ import { withBuilderUtmTrackingParams } from "@agent-native/core/shared";
2
+ import {
3
+ IconCircleCheck,
4
+ IconExternalLink,
5
+ IconRocket,
6
+ } from "@tabler/icons-react";
7
+
8
+ import { Button } from "@/components/ui/button";
9
+ import {
10
+ Dialog,
11
+ DialogContent,
12
+ DialogDescription,
13
+ DialogFooter,
14
+ DialogHeader,
15
+ DialogTitle,
16
+ } from "@/components/ui/dialog";
17
+ import { Spinner } from "@/components/ui/spinner";
18
+
19
+ /** Result of `migrate-inline-design-to-app`, including the not-configured CTA. */
20
+ export interface DesignMigrationResult {
21
+ branchName?: string;
22
+ url?: string;
23
+ versionId?: string;
24
+ seedFileCount?: number;
25
+ status?: string;
26
+ projectId?: string;
27
+ cta?: {
28
+ kind: string;
29
+ label: string;
30
+ description?: string;
31
+ connectUrl?: string;
32
+ primaryAction: string;
33
+ };
34
+ }
35
+
36
+ export function MakeRealDialog({
37
+ open,
38
+ onOpenChange,
39
+ result,
40
+ pending,
41
+ onConfirm,
42
+ }: {
43
+ open: boolean;
44
+ onOpenChange: (open: boolean) => void;
45
+ result: DesignMigrationResult | null;
46
+ pending: boolean;
47
+ onConfirm: () => void;
48
+ }) {
49
+ return (
50
+ <Dialog
51
+ open={open}
52
+ onOpenChange={(next) => {
53
+ if (!pending) onOpenChange(next);
54
+ }}
55
+ >
56
+ <DialogContent className="sm:max-w-md">
57
+ {/* Not-configured: Builder not connected or no project ID */}
58
+ {result?.status === "not-configured" && result.cta ? (
59
+ <>
60
+ <DialogHeader>
61
+ <DialogTitle className="flex items-center gap-2">
62
+ <IconRocket className="size-5 text-muted-foreground" />
63
+ {result.cta.label}
64
+ </DialogTitle>
65
+ {result.cta.description ? (
66
+ <DialogDescription>{result.cta.description}</DialogDescription>
67
+ ) : null}
68
+ </DialogHeader>
69
+ <DialogFooter className="flex-col gap-2 sm:flex-row">
70
+ <Button
71
+ variant="outline"
72
+ onClick={() => onOpenChange(false)}
73
+ className="cursor-pointer"
74
+ >
75
+ Cancel
76
+ </Button>
77
+ {result.cta.connectUrl ? (
78
+ <Button asChild className="cursor-pointer">
79
+ <a
80
+ href={result.cta.connectUrl}
81
+ target="_blank"
82
+ rel="noopener noreferrer"
83
+ >
84
+ {result.cta.primaryAction}
85
+ <IconExternalLink className="ml-1.5 size-3.5" />
86
+ </a>
87
+ </Button>
88
+ ) : null}
89
+ </DialogFooter>
90
+ </>
91
+ ) : result?.status === "processing" ? (
92
+ /* Success: Builder accepted the migration job */
93
+ <>
94
+ <DialogHeader>
95
+ <DialogTitle className="flex items-center gap-2">
96
+ {/* guard:allow-raw-color - success checkmark; no success token exists in app/global.css */}
97
+ <IconCircleCheck className="size-5 text-green-500" />
98
+ {"Migration started" /* i18n-ignore */}
99
+ </DialogTitle>
100
+ <DialogDescription>
101
+ {
102
+ "Builder is generating a React app branch from your design. The original inline design is preserved and recoverable." /* i18n-ignore */
103
+ }
104
+ </DialogDescription>
105
+ </DialogHeader>
106
+ <div className="space-y-3 py-2">
107
+ {result.branchName && (
108
+ <div className="rounded-md border border-border bg-muted/40 px-3 py-2 text-sm">
109
+ <span className="text-muted-foreground">
110
+ {"Branch: " /* i18n-ignore */}
111
+ </span>
112
+ <span className="font-mono font-medium">
113
+ {result.branchName}
114
+ </span>
115
+ </div>
116
+ )}
117
+ {result.url && (
118
+ <a
119
+ href={withBuilderUtmTrackingParams(result.url, {
120
+ campaign: "product",
121
+ content: "design_migration",
122
+ })}
123
+ target="_blank"
124
+ rel="noopener noreferrer"
125
+ className="flex items-center gap-1.5 text-sm text-[var(--design-editor-accent-color)] hover:underline"
126
+ >
127
+ {"Open in Builder" /* i18n-ignore */}
128
+ <IconExternalLink className="size-3.5" />
129
+ </a>
130
+ )}
131
+ {result.seedFileCount !== undefined && (
132
+ <p className="text-xs text-muted-foreground">
133
+ {
134
+ `${result.seedFileCount} design file${result.seedFileCount === 1 ? "" : "s"} included in migration seed.` /* i18n-ignore */
135
+ }
136
+ </p>
137
+ )}
138
+ </div>
139
+ <DialogFooter>
140
+ <Button
141
+ onClick={() => onOpenChange(false)}
142
+ className="cursor-pointer"
143
+ >
144
+ {"Done" /* i18n-ignore */}
145
+ </Button>
146
+ </DialogFooter>
147
+ </>
148
+ ) : (
149
+ /* Idle or migrating */
150
+ <>
151
+ <DialogHeader>
152
+ <DialogTitle className="flex items-center gap-2">
153
+ <IconRocket className="size-5" />
154
+ {"Make this a real app" /* i18n-ignore */}
155
+ </DialogTitle>
156
+ <DialogDescription>
157
+ {
158
+ "Connect Builder.io (free tier available) to convert this design into a React + Tailwind app with real components, props, branches, and deploys. Your current inline design is preserved as a snapshot you can restore at any time." /* i18n-ignore */
159
+ }
160
+ </DialogDescription>
161
+ </DialogHeader>
162
+ <div className="space-y-2 py-1 text-sm text-muted-foreground">
163
+ <p>{"What happens:" /* i18n-ignore */}</p>
164
+ <ul className="list-disc pl-4 space-y-1">
165
+ <li>
166
+ {
167
+ "Your design HTML and tokens are sent to the Builder cloud agent" /* i18n-ignore */
168
+ }
169
+ </li>
170
+ <li>
171
+ {
172
+ "A React + Tailwind branch is generated in Builder" /* i18n-ignore */
173
+ }
174
+ </li>
175
+ <li>
176
+ {
177
+ "The editor switches to fusion source mode — gated panels light up" /* i18n-ignore */
178
+ }
179
+ </li>
180
+ <li>
181
+ {
182
+ "The original inline design is saved as a restorable snapshot" /* i18n-ignore */
183
+ }
184
+ </li>
185
+ </ul>
186
+ <p className="pt-1 text-xs">
187
+ {
188
+ "Requires Builder.io to be connected (free tier available) with a branch project configured." /* i18n-ignore */
189
+ }
190
+ </p>
191
+ </div>
192
+ <DialogFooter className="flex-col gap-2 sm:flex-row">
193
+ <Button
194
+ variant="outline"
195
+ onClick={() => onOpenChange(false)}
196
+ disabled={pending}
197
+ className="cursor-pointer"
198
+ >
199
+ Cancel
200
+ </Button>
201
+ <Button
202
+ onClick={() => void onConfirm()}
203
+ disabled={pending}
204
+ className="cursor-pointer"
205
+ >
206
+ {
207
+ pending ? (
208
+ <>
209
+ <Spinner className="mr-2 size-3.5" />
210
+ {"Starting migration…" /* i18n-ignore */}
211
+ </>
212
+ ) : (
213
+ "Start migration"
214
+ ) /* i18n-ignore */
215
+ }
216
+ </Button>
217
+ </DialogFooter>
218
+ </>
219
+ )}
220
+ </DialogContent>
221
+ </Dialog>
222
+ );
223
+ }
@@ -0,0 +1,58 @@
1
+ import { useT } from "@agent-native/core/client/i18n";
2
+
3
+ import {
4
+ AlertDialog,
5
+ AlertDialogAction,
6
+ AlertDialogCancel,
7
+ AlertDialogContent,
8
+ AlertDialogDescription,
9
+ AlertDialogFooter,
10
+ AlertDialogHeader,
11
+ AlertDialogTitle,
12
+ } from "@/components/ui/alert-dialog";
13
+ import type { DesignFile } from "@/pages/design-editor/types";
14
+
15
+ export function PendingScreenDeletionDialog({
16
+ pendingScreenDeletion,
17
+ onCancel,
18
+ onConfirm,
19
+ }: {
20
+ pendingScreenDeletion: { files: DesignFile[] } | null;
21
+ onCancel: () => void;
22
+ onConfirm: () => void;
23
+ }) {
24
+ const t = useT();
25
+ return (
26
+ <AlertDialog open={pendingScreenDeletion !== null}>
27
+ <AlertDialogContent>
28
+ <AlertDialogHeader>
29
+ <AlertDialogTitle>
30
+ {pendingScreenDeletion?.files.length === 1
31
+ ? t("designEditor.screenDeletion.titleOne")
32
+ : t("designEditor.screenDeletion.titleMany", {
33
+ count: pendingScreenDeletion?.files.length ?? 0,
34
+ })}
35
+ </AlertDialogTitle>
36
+ <AlertDialogDescription>
37
+ {pendingScreenDeletion?.files.length === 1
38
+ ? t("designEditor.screenDeletion.descriptionOne", {
39
+ filename: pendingScreenDeletion.files[0]?.filename ?? "",
40
+ })
41
+ : t("designEditor.screenDeletion.descriptionMany")}
42
+ </AlertDialogDescription>
43
+ </AlertDialogHeader>
44
+ <AlertDialogFooter>
45
+ <AlertDialogCancel onClick={onCancel}>
46
+ {t("designEditor.screenDeletion.cancel")}
47
+ </AlertDialogCancel>
48
+ <AlertDialogAction
49
+ className="bg-destructive text-destructive-foreground hover:bg-destructive/90"
50
+ onClick={onConfirm}
51
+ >
52
+ {t("designEditor.screenDeletion.confirm")}
53
+ </AlertDialogAction>
54
+ </AlertDialogFooter>
55
+ </AlertDialogContent>
56
+ </AlertDialog>
57
+ );
58
+ }
@@ -0,0 +1,56 @@
1
+ import { useT } from "@agent-native/core/client/i18n";
2
+
3
+ import {
4
+ AlertDialog,
5
+ AlertDialogAction,
6
+ AlertDialogCancel,
7
+ AlertDialogContent,
8
+ AlertDialogDescription,
9
+ AlertDialogFooter,
10
+ AlertDialogHeader,
11
+ AlertDialogTitle,
12
+ } from "@/components/ui/alert-dialog";
13
+
14
+ export function PendingVisualStyleWarningDialog({
15
+ open,
16
+ pendingVisualEditCount,
17
+ onStay,
18
+ onDiscardAndNavigate,
19
+ }: {
20
+ open: boolean;
21
+ pendingVisualEditCount: number;
22
+ onStay: () => void;
23
+ onDiscardAndNavigate: () => void;
24
+ }) {
25
+ const t = useT();
26
+ return (
27
+ <AlertDialog open={open}>
28
+ <AlertDialogContent>
29
+ <AlertDialogHeader>
30
+ <AlertDialogTitle>
31
+ {t("designEditor.pendingVisualStyles.leaveTitle")}
32
+ </AlertDialogTitle>
33
+ <AlertDialogDescription>
34
+ {t(
35
+ pendingVisualEditCount === 1
36
+ ? "designEditor.pendingVisualStyles.leaveDescriptionOne"
37
+ : "designEditor.pendingVisualStyles.leaveDescriptionOther",
38
+ { count: pendingVisualEditCount },
39
+ )}
40
+ </AlertDialogDescription>
41
+ </AlertDialogHeader>
42
+ <AlertDialogFooter>
43
+ <AlertDialogCancel onClick={onStay}>
44
+ {t("designEditor.pendingVisualStyles.stay")}
45
+ </AlertDialogCancel>
46
+ <AlertDialogAction
47
+ className="bg-destructive text-destructive-foreground hover:bg-destructive/90"
48
+ onClick={onDiscardAndNavigate}
49
+ >
50
+ {t("designEditor.pendingVisualStyles.leave")}
51
+ </AlertDialogAction>
52
+ </AlertDialogFooter>
53
+ </AlertDialogContent>
54
+ </AlertDialog>
55
+ );
56
+ }
@@ -0,0 +1,23 @@
1
+ import { IconLock } from "@tabler/icons-react";
2
+
3
+ export function ReadOnlyEditorPanel({
4
+ title,
5
+ description,
6
+ }: {
7
+ title: string;
8
+ description?: string;
9
+ }) {
10
+ return (
11
+ <div className="flex min-h-0 flex-1 flex-col items-center justify-center px-5 text-center">
12
+ <div className="mb-3 flex size-10 items-center justify-center rounded-lg bg-muted text-muted-foreground">
13
+ <IconLock className="size-5" />
14
+ </div>
15
+ <p className="text-sm font-medium text-foreground">{title}</p>
16
+ {description ? (
17
+ <p className="mt-1 max-w-56 text-xs leading-5 text-muted-foreground">
18
+ {description}
19
+ </p>
20
+ ) : null}
21
+ </div>
22
+ );
23
+ }