@adminide-stack/yantra-mobile 12.0.142 → 12.0.145-alpha.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 (118) hide show
  1. package/lib/features/attachments/displayUserMessageText.js +2 -2
  2. package/lib/features/attachments/displayUserMessageText.js.map +1 -1
  3. package/lib/features/devices/readings.js.map +1 -1
  4. package/lib/features/devices/session.js +2 -22
  5. package/lib/features/devices/session.js.map +1 -1
  6. package/lib/features/notion/NotionAgentPanel.js +987 -0
  7. package/lib/features/notion/NotionAgentPanel.js.map +1 -0
  8. package/lib/features/notion/NotionAskAiSheet.js +362 -0
  9. package/lib/features/notion/NotionAskAiSheet.js.map +1 -0
  10. package/lib/features/notion/NotionBlockView.js +4 -3
  11. package/lib/features/notion/NotionBlockView.js.map +1 -1
  12. package/lib/features/notion/NotionConnectionsSheet.js +47 -13
  13. package/lib/features/notion/NotionConnectionsSheet.js.map +1 -1
  14. package/lib/features/notion/NotionPageView.js +68 -8
  15. package/lib/features/notion/NotionPageView.js.map +1 -1
  16. package/lib/features/notion/NotionSidebarSections.js +1 -1
  17. package/lib/features/notion/NotionSidebarSections.js.map +1 -1
  18. package/lib/features/notion/NotionWorkspaceView.js +14 -9
  19. package/lib/features/notion/NotionWorkspaceView.js.map +1 -1
  20. package/lib/features/notion/database/DatabaseCells.js +3 -1
  21. package/lib/features/notion/database/DatabaseCells.js.map +1 -1
  22. package/lib/features/notion/database/DatabaseDateLayouts.js +1 -1
  23. package/lib/features/notion/database/DatabaseDateLayouts.js.map +1 -1
  24. package/lib/features/notion/database/NotionDatabaseView.js +1 -1
  25. package/lib/features/notion/database/NotionDatabaseView.js.map +1 -1
  26. package/lib/features/notion/notionAgentRunStatus.js +2 -2
  27. package/lib/features/notion/notionAgentRunStatus.js.map +1 -1
  28. package/lib/features/notion/notionAgentRuns.js +57 -0
  29. package/lib/features/notion/notionAgentRuns.js.map +1 -0
  30. package/lib/features/notion/notionAiContext.js +91 -0
  31. package/lib/features/notion/notionAiContext.js.map +1 -0
  32. package/lib/features/notion/notionConnections.js +42 -4
  33. package/lib/features/notion/notionConnections.js.map +1 -1
  34. package/lib/features/notion/notionDocuments.js +61 -1
  35. package/lib/features/notion/notionDocuments.js.map +1 -1
  36. package/lib/features/notion/notionNotesAgent.js +173 -3
  37. package/lib/features/notion/notionNotesAgent.js.map +1 -1
  38. package/lib/features/notion/notionPageKinds.js +1 -1
  39. package/lib/features/webbuilder/WebBuilderExperience.js +229 -97
  40. package/lib/features/webbuilder/WebBuilderExperience.js.map +1 -1
  41. package/lib/features/webbuilder/buildFragments.js +33 -7
  42. package/lib/features/webbuilder/buildFragments.js.map +1 -1
  43. package/lib/features/webbuilder/buildJob.js +2 -2
  44. package/lib/features/webbuilder/buildJob.js.map +1 -1
  45. package/lib/features/webbuilder/codeFiles.js +18 -1
  46. package/lib/features/webbuilder/codeFiles.js.map +1 -1
  47. package/lib/features/webbuilder/components/BottomTabs.js.map +1 -1
  48. package/lib/features/webbuilder/components/CodeView.js +134 -56
  49. package/lib/features/webbuilder/components/CodeView.js.map +1 -1
  50. package/lib/features/webbuilder/components/Composer.js +2 -2
  51. package/lib/features/webbuilder/components/Composer.js.map +1 -1
  52. package/lib/features/webbuilder/components/PreviewFrame.js +19 -3
  53. package/lib/features/webbuilder/components/PreviewFrame.js.map +1 -1
  54. package/lib/features/webbuilder/components/PreviewScreen.js +310 -46
  55. package/lib/features/webbuilder/components/PreviewScreen.js.map +1 -1
  56. package/lib/features/webbuilder/components/ProjectChat.js +141 -12
  57. package/lib/features/webbuilder/components/ProjectChat.js.map +1 -1
  58. package/lib/features/webbuilder/components/ProjectSheets.js +792 -0
  59. package/lib/features/webbuilder/components/ProjectSheets.js.map +1 -0
  60. package/lib/features/webbuilder/components/ProjectsScreen.js +14 -2
  61. package/lib/features/webbuilder/components/ProjectsScreen.js.map +1 -1
  62. package/lib/features/webbuilder/components/PublishSheet.js +914 -58
  63. package/lib/features/webbuilder/components/PublishSheet.js.map +1 -1
  64. package/lib/features/webbuilder/components/TemplateCard.js +9 -6
  65. package/lib/features/webbuilder/components/TemplateCard.js.map +1 -1
  66. package/lib/features/webbuilder/components/TemplatesSheet.js +5 -17
  67. package/lib/features/webbuilder/components/TemplatesSheet.js.map +1 -1
  68. package/lib/features/webbuilder/connectorTemplates.js +171 -0
  69. package/lib/features/webbuilder/connectorTemplates.js.map +1 -0
  70. package/lib/features/webbuilder/fileTree.js +163 -0
  71. package/lib/features/webbuilder/fileTree.js.map +1 -0
  72. package/lib/features/webbuilder/followUps.js +67 -0
  73. package/lib/features/webbuilder/followUps.js.map +1 -0
  74. package/lib/features/webbuilder/previewProbe.js +49 -0
  75. package/lib/features/webbuilder/previewProbe.js.map +1 -0
  76. package/lib/features/webbuilder/previewRoutes.js +156 -0
  77. package/lib/features/webbuilder/previewRoutes.js.map +1 -0
  78. package/lib/features/webbuilder/projectTools.js +341 -0
  79. package/lib/features/webbuilder/projectTools.js.map +1 -0
  80. package/lib/features/webbuilder/publishTools.js +475 -0
  81. package/lib/features/webbuilder/publishTools.js.map +1 -0
  82. package/lib/features/webbuilder/sleepNotice.js +13 -0
  83. package/lib/features/webbuilder/sleepNotice.js.map +1 -0
  84. package/lib/features/webbuilder/stepLabels.js +37 -7
  85. package/lib/features/webbuilder/stepLabels.js.map +1 -1
  86. package/lib/features/webbuilder/studioCatalog.js +5 -1
  87. package/lib/features/webbuilder/studioCatalog.js.map +1 -1
  88. package/lib/features/webbuilder/templateCatalog.js +140 -0
  89. package/lib/features/webbuilder/templateCatalog.js.map +1 -0
  90. package/lib/features/webbuilder/webbuilderPrompts.js +31 -5
  91. package/lib/features/webbuilder/webbuilderPrompts.js.map +1 -1
  92. package/lib/features/webbuilder/workflow.js +8 -4
  93. package/lib/features/webbuilder/workflow.js.map +1 -1
  94. package/lib/screens/Devices/index.js +3 -205
  95. package/lib/screens/Devices/index.js.map +1 -1
  96. package/lib/screens/WebBuilderNative/codeWorkspaceApi.js +9 -6
  97. package/lib/screens/WebBuilderNative/codeWorkspaceApi.js.map +1 -1
  98. package/lib/screens/WebBuilderNative/index.js +1 -1
  99. package/lib/screens/WebBuilderNative/index.js.map +1 -1
  100. package/lib/screens/WebBuilderNative/keepAlive.js +53 -3
  101. package/lib/screens/WebBuilderNative/keepAlive.js.map +1 -1
  102. package/lib/screens/WebBuilderNative/unreachableRetry.js +23 -0
  103. package/lib/screens/WebBuilderNative/unreachableRetry.js.map +1 -0
  104. package/lib/screens/WebBuilderNative/useConnectorTemplates.js +37 -0
  105. package/lib/screens/WebBuilderNative/useConnectorTemplates.js.map +1 -0
  106. package/lib/screens/WebBuilderNative/useSandboxKeepAlive.js +6 -0
  107. package/lib/screens/WebBuilderNative/useSandboxKeepAlive.js.map +1 -1
  108. package/lib/screens/WebBuilderNative/useWebBuilderHost.js +302 -40
  109. package/lib/screens/WebBuilderNative/useWebBuilderHost.js.map +1 -1
  110. package/lib/screens/WebBuilderNative/useWebBuilderJobs.js +2 -2
  111. package/lib/screens/WebBuilderNative/useWebBuilderJobs.js.map +1 -1
  112. package/lib/screens/WebBuilderNative/versionUndo.js +1 -1
  113. package/lib/screens/WebBuilderNative/versionUndo.js.map +1 -1
  114. package/lib/screens/WebBuilderNative/webbuilderTransport.js +147 -77
  115. package/lib/screens/WebBuilderNative/webbuilderTransport.js.map +1 -1
  116. package/package.json +4 -4
  117. package/lib/features/devices/bodyComposition.js +0 -116
  118. package/lib/features/devices/bodyComposition.js.map +0 -1
@@ -1,4 +1,4 @@
1
- import {jsxs,jsx,Fragment}from'react/jsx-runtime';import {useMemo,useState,useCallback,useRef,useEffect}from'react';import {StyleSheet,Keyboard,BackHandler,View,Text,Share,Platform,ActionSheetIOS,Linking,Alert}from'react-native';import {MaterialCommunityIcons}from'@expo/vector-icons';import {GestureHandlerRootView}from'react-native-gesture-handler';import {useSafeInsets}from'../canvas/withRemoteSafeArea.js';import {useAppTheme}from'../../theme/AppThemeProvider.js';import {Tap,DIM}from'../inbox/components/Tap.js';import {isBareSeed,studioTurnText,brandBriefBlock,siteScoreTurn}from'./studioCatalog.js';import {titleFromPrompt}from'./buildFragments.js';import {useBrandKit}from'./brandKitStorage.js';import {parseToolActivity}from'../chat/toolActivity.js';import {wakePreviewPrompt}from'./webbuilderPrompts.js';import {webbuilderTheme}from'./webbuilderTheme.js';import {BrandKitSheet}from'./components/BrandKitSheet.js';import {CodeView}from'./components/CodeView.js';import {ProjectChat}from'./components/ProjectChat.js';import {PreviewScreen,ViewPicker}from'./components/PreviewScreen.js';import {PublishSheet}from'./components/PublishSheet.js';import {BOTTOM_TABS_SPACE,BottomTabs}from'./components/BottomTabs.js';import {SiteScoreSheet}from'./components/SiteScoreSheet.js';import {ProjectsScreen}from'./components/ProjectsScreen.js';import {TemplatesSheet}from'./components/TemplatesSheet.js';import {StudioHome}from'./components/StudioHome.js';import {VersionsSheet}from'./components/VersionsSheet.js';import {IconButton,Sheet,Toast}from'./components/ui.js';import {exportMessage,EXPORT_TARGETS,exportTurn}from'./exportCode.js';import {demoVideoSource,webbuilderDemoHandoff,encodeCodezenHandoff}from'./codezenHandoff.js';var __defProp = Object.defineProperty;
1
+ import {jsxs,jsx,Fragment}from'react/jsx-runtime';import {useMemo,useState,useCallback,useRef,useEffect}from'react';import {StyleSheet,Keyboard,BackHandler,View,Text,Share,Linking,Alert}from'react-native';import {MaterialCommunityIcons}from'@expo/vector-icons';import {GestureHandlerRootView}from'react-native-gesture-handler';import {useSafeInsets}from'../canvas/withRemoteSafeArea.js';import {useAppTheme}from'../../theme/AppThemeProvider.js';import {Tap,DIM}from'../inbox/components/Tap.js';import {isBareSeed,studioTurnText,brandKitNote,siteScoreTurn}from'./studioCatalog.js';import {titleFromPrompt}from'./buildFragments.js';import {useBrandKit}from'./brandKitStorage.js';import {parseToolActivity}from'../chat/toolActivity.js';import {friendlySteps,firstContentLanded}from'./stepLabels.js';import {restoreTurnNote}from'./webbuilderPrompts.js';import {webbuilderTheme}from'./webbuilderTheme.js';import {BrandKitSheet}from'./components/BrandKitSheet.js';import {CodeView}from'./components/CodeView.js';import {ProjectChat}from'./components/ProjectChat.js';import {ViewportToggle,PreviewScreen,ViewPicker}from'./components/PreviewScreen.js';import {PublishSheet}from'./components/PublishSheet.js';import {BOTTOM_TABS_SPACE,BottomTabs}from'./components/BottomTabs.js';import {SiteScoreSheet}from'./components/SiteScoreSheet.js';import {ProjectsScreen}from'./components/ProjectsScreen.js';import {TemplatesSheet}from'./components/TemplatesSheet.js';import {StudioHome}from'./components/StudioHome.js';import {VersionsSheet}from'./components/VersionsSheet.js';import {IconButton,Sheet,Toast}from'./components/ui.js';import {exportTurn,exportMessage}from'./exportCode.js';import {ownCloudflareTurn}from'./publishTools.js';import {ProjectMenuSheet,ProjectSettingsSheet,GithubPushSheet,IntegrationsSheet,ImportProjectSheet}from'./components/ProjectSheets.js';import {demoVideoSource,webbuilderDemoHandoff,encodeCodezenHandoff}from'./codezenHandoff.js';var __defProp = Object.defineProperty;
2
2
  var __getOwnPropSymbols = Object.getOwnPropertySymbols;
3
3
  var __hasOwnProp = Object.prototype.hasOwnProperty;
4
4
  var __propIsEnum = Object.prototype.propertyIsEnumerable;
@@ -43,14 +43,18 @@ function WebBuilderExperience({
43
43
  hostChat,
44
44
  onPublish,
45
45
  onResumePreview,
46
+ onRestorePreview,
47
+ goneSandboxIds,
46
48
  onOpenCodezen,
47
49
  onUndo,
48
50
  onRedo,
49
51
  onDownloadCode,
52
+ publishTools,
53
+ projectTools,
50
54
  code,
51
55
  initialAgentSeed = null
52
56
  }) {
53
- var _a, _b, _c, _d, _e, _f, _g, _h, _i, _j, _k, _l, _m;
57
+ var _a, _b, _c, _d, _e, _f, _g, _h, _i, _j, _k, _l, _m, _n, _o;
54
58
  const appTheme = useAppTheme();
55
59
  const isDark = hostIsDark != null ? hostIsDark : appTheme.isDark;
56
60
  const theme = useMemo(() => webbuilderTheme(isDark), [isDark]);
@@ -81,7 +85,7 @@ function WebBuilderExperience({
81
85
  onStartProject(__spreadValues(__spreadValues({
82
86
  text: studioTurnText({
83
87
  brief,
84
- brandBlock: brandBriefBlock(brand),
88
+ brandBlock: brandKitNote(brand),
85
89
  referenceUrl: start.referenceUrl
86
90
  }),
87
91
  template: start.template
@@ -156,21 +160,88 @@ function WebBuilderExperience({
156
160
  setMode("chat");
157
161
  }, []);
158
162
  const [waking, setWaking] = useState(false);
163
+ const [trouble, setTrouble] = useState(null);
159
164
  const wokenFor = useRef(null);
160
165
  useEffect(() => {
161
166
  wokenFor.current = null;
162
167
  }, [build == null ? void 0 : build.key]);
163
- const wakePreview = useCallback(() => {
164
- if (!build || waking || wokenFor.current === build.key) return;
168
+ const goneNow = Boolean((build == null ? void 0 : build.sandboxId) && (goneSandboxIds == null ? void 0 : goneSandboxIds.has(build.sandboxId)));
169
+ let previewTrouble = null;
170
+ if (trouble && build && trouble.key === build.key) previewTrouble = trouble;
171
+ else if (goneNow && build) previewTrouble = {
172
+ key: build.key,
173
+ kind: "gone"
174
+ };
175
+ const wakePreview = useCallback((asked = false) => {
176
+ if (!build || waking) return;
177
+ if (!asked && wokenFor.current === build.key) return;
165
178
  if (building || (hostChat == null ? void 0 : hostChat.busy)) return;
166
179
  wokenFor.current = build.key;
180
+ if (!onResumePreview) {
181
+ setTrouble({
182
+ key: build.key,
183
+ kind: "failed"
184
+ });
185
+ return;
186
+ }
187
+ const target = build;
167
188
  setWaking(true);
168
- const resume = onResumePreview ? onResumePreview(build) : Promise.resolve("failed");
169
- resume.catch(() => "failed").then((outcome) => {
170
- if (outcome === "ok") setPreviewNonce((n) => n + 1);
171
- else if (hostChat && !hostChat.busy) hostChat.send(wakePreviewPrompt(), void 0, build);
189
+ setTrouble(null);
190
+ onResumePreview(target, {
191
+ asked
192
+ }).catch(() => "failed").then((outcome) => {
193
+ if (outcome === "ok") {
194
+ setPreviewNonce((n) => n + 1);
195
+ return;
196
+ }
197
+ setTrouble({
198
+ key: target.key,
199
+ kind: outcome === "gone" ? "gone" : "failed"
200
+ });
172
201
  }).finally(() => setWaking(false));
173
202
  }, [build, waking, building, onResumePreview, hostChat]);
203
+ const askAiToRestore = useCallback((reason, snapshotId) => {
204
+ if (!build || !hostChat || hostChat.busy) return;
205
+ const name = siteTitle || build.title || "my site";
206
+ hostChat.send(`Restore "${name}" from its saved copy in a new sandbox and send me the preview link.
207
+
208
+ ${restoreTurnNote({
209
+ snapshotId: snapshotId != null ? snapshotId : build.snapshotId,
210
+ templateId: build.templateId,
211
+ restoreError: reason
212
+ })}`, void 0, build);
213
+ setTrouble(null);
214
+ setMode("chat");
215
+ }, [build, hostChat, siteTitle]);
216
+ const restoreFromSavedCopy = useCallback(() => {
217
+ if (!build || (previewTrouble == null ? void 0 : previewTrouble.kind) === "restoring") return;
218
+ if (!onRestorePreview) {
219
+ askAiToRestore();
220
+ return;
221
+ }
222
+ const target = build;
223
+ setTrouble({
224
+ key: target.key,
225
+ kind: "restoring"
226
+ });
227
+ onRestorePreview(target).catch(() => ({
228
+ ok: false,
229
+ reason: "The saved copy could not be opened."
230
+ })).then((result) => {
231
+ if (result.ok) {
232
+ setTrouble(null);
233
+ setPreviewNonce((n) => n + 1);
234
+ showToast("Your site is back");
235
+ return;
236
+ }
237
+ setTrouble({
238
+ key: target.key,
239
+ kind: "restoreFailed",
240
+ reason: result.reason,
241
+ snapshotId: result.snapshotId
242
+ });
243
+ });
244
+ }, [build, previewTrouble == null ? void 0 : previewTrouble.kind, onRestorePreview, askAiToRestore, showToast]);
174
245
  const [publishOpen, setPublishOpen] = useState(false);
175
246
  const [versionsOpen, setVersionsOpen] = useState(false);
176
247
  const [publishStarted, setPublishStarted] = useState(null);
@@ -184,12 +255,12 @@ function WebBuilderExperience({
184
255
  }
185
256
  }, [builds, publishStarted, showToast]);
186
257
  const publishing = publishingOnChat || Boolean(publishStarted && Date.now() - publishStarted.at < PUBLISH_WATCH_MS);
187
- const publish = useCallback(async (target, projectName) => {
258
+ const publish = useCallback(async (target, projectName, customDomain) => {
188
259
  if (!onPublish) return {
189
260
  ok: false,
190
261
  message: "Publishing is not available here."
191
262
  };
192
- const result = await onPublish(target, projectName);
263
+ const result = await onPublish(target, projectName, customDomain);
193
264
  if (result.ok) {
194
265
  setPublishStarted({
195
266
  key: target.key,
@@ -241,6 +312,18 @@ function WebBuilderExperience({
241
312
  shadowColor: theme.isDark ? "#000" : "#1c1917"
242
313
  };
243
314
  const liveSteps = (hostChat == null ? void 0 : hostChat.busy) && hostChat.streaming ? parseToolActivity(hostChat.streaming, true).steps : [];
315
+ const turnBusy = Boolean(hostChat == null ? void 0 : hostChat.busy);
316
+ const hadBuildsAtTurnStart = useRef(true);
317
+ const wasTurnBusy = useRef(false);
318
+ if (turnBusy !== wasTurnBusy.current) {
319
+ wasTurnBusy.current = turnBusy;
320
+ if (turnBusy) hadBuildsAtTurnStart.current = builds.length > 0;
321
+ }
322
+ const coverSteps = friendlySteps(liveSteps);
323
+ const buildingCover = turnBusy && build && !hadBuildsAtTurnStart.current && !firstContentLanded(liveSteps) ? {
324
+ title: siteTitle || build.title,
325
+ step: (_f = (_e = coverSteps[coverSteps.length - 1]) == null ? void 0 : _e.label) != null ? _f : null
326
+ } : null;
244
327
  let publishLabel = "Publish";
245
328
  if (publishing) publishLabel = "Publishing\u2026";
246
329
  const shareUrl = live || (build == null ? void 0 : build.previewUrl) || null;
@@ -279,25 +362,6 @@ function WebBuilderExperience({
279
362
  }).catch(() => showToast("Couldn't undo that change.")).finally(() => setUndoing(false));
280
363
  };
281
364
  const [menu, setMenu] = useState(null);
282
- const showMenu = (title, actions) => {
283
- if (!actions.length) return;
284
- if (Platform.OS === "ios") {
285
- ActionSheetIOS.showActionSheetWithOptions({
286
- title,
287
- options: [...actions.map((a) => a.label), "Cancel"],
288
- cancelButtonIndex: actions.length,
289
- destructiveButtonIndex: actions.findIndex((a) => a.destructive)
290
- }, (index) => {
291
- var _a2;
292
- return (_a2 = actions[index]) == null ? void 0 : _a2.run();
293
- });
294
- return;
295
- }
296
- setMenu({
297
- title,
298
- actions
299
- });
300
- };
301
365
  const chooseMenu = (action) => {
302
366
  setMenu(null);
303
367
  setTimeout(action.run, 250);
@@ -324,91 +388,135 @@ function WebBuilderExperience({
324
388
  }).catch(() => askAgent(exportMessage(title, "zip")));
325
389
  };
326
390
  const exportTo = (target) => askAgent(exportTurn(siteTitle || (build == null ? void 0 : build.title) || "", target));
327
- const pickExport = () => showMenu("Export or deploy", EXPORT_TARGETS.map((t) => ({
328
- label: t.label,
329
- run: () => exportTo(t.target)
330
- })));
331
391
  const canShowCode = Boolean((build == null ? void 0 : build.files) || code && ((build == null ? void 0 : build.sandboxId) || (build == null ? void 0 : build.liveUrl)));
332
- const openMore = () => {
333
- const actions = [];
334
- if (mode !== "chat") actions.push({
392
+ const [projectMenuOpen, setProjectMenuOpen] = useState(false);
393
+ const [settingsMode, setSettingsMode] = useState(null);
394
+ const [githubOpen, setGithubOpen] = useState(false);
395
+ const [integrationsOpen, setIntegrationsOpen] = useState(false);
396
+ const [importOpen, setImportOpen] = useState(false);
397
+ const filmDemo = () => {
398
+ const demo = build && !building ? demoVideoSource(live, build.previewUrl) : null;
399
+ if (!demo || !onOpenCodezen) return;
400
+ const film = () => {
401
+ try {
402
+ const handoff = webbuilderDemoHandoff(siteTitle || (build == null ? void 0 : build.title) || "", demo);
403
+ onOpenCodezen(encodeCodezenHandoff(handoff), handoff);
404
+ } catch (err) {
405
+ showToast(err instanceof Error ? err.message : "Couldn't open Codezen.");
406
+ }
407
+ };
408
+ if (demo.stable) {
409
+ film();
410
+ return;
411
+ }
412
+ Alert.alert("Publish first for a link that stays up", "Codezen will film the live preview, which sleeps about an hour after the last change.", [{
413
+ text: "Cancel",
414
+ style: "cancel"
415
+ }, {
416
+ text: "Film the preview",
417
+ onPress: film
418
+ }]);
419
+ };
420
+ const projectMenu = () => {
421
+ const view = [];
422
+ if (mode !== "chat") view.push({
423
+ key: "chat",
424
+ icon: "message-outline",
335
425
  label: "Back to the chat",
336
426
  run: () => setMode("chat")
337
427
  });
338
428
  if ((build == null ? void 0 : build.previewUrl) && mode !== "preview") {
339
- actions.push({
429
+ view.push({
430
+ key: "preview",
431
+ icon: "television-play",
340
432
  label: "Open preview",
341
433
  run: () => setMode("preview")
342
434
  });
343
435
  }
344
- if (canShowCode && mode !== "code") {
345
- actions.push({
346
- label: "View code",
347
- run: () => setMode("code")
348
- });
349
- }
350
- if ((build == null ? void 0 : build.sandboxId) && onUndo && !building && !undoing) {
351
- actions.push({
352
- label: "Undo last change",
353
- run: undoLast
354
- });
355
- }
356
- if (builds.length > 1) actions.push({
357
- label: "Versions",
358
- run: () => setVersionsOpen(true)
359
- });
360
- if (build == null ? void 0 : build.sandboxId) {
361
- actions.push({
362
- label: live ? "Publish an update" : "Publish",
363
- run: () => setPublishOpen(true)
436
+ if (builds.length > 1) {
437
+ view.push({
438
+ key: "versions",
439
+ icon: "history",
440
+ label: "Versions",
441
+ run: () => setVersionsOpen(true)
364
442
  });
365
443
  }
366
444
  if (build == null ? void 0 : build.previewUrl) {
367
445
  const url = live || build.previewUrl;
368
- actions.push({
446
+ view.push({
447
+ key: "browser",
448
+ icon: "open-in-new",
369
449
  label: "Open in browser",
370
- run: () => Linking.openURL(url).catch(() => void 0)
450
+ run: () => {
451
+ Linking.openURL(url).catch(() => void 0);
452
+ }
371
453
  });
372
454
  }
373
- if ((build == null ? void 0 : build.sandboxId) && !building) {
374
- actions.push({
375
- label: "Download code",
376
- run: downloadCode
455
+ const project2 = projectTools ? [{
456
+ key: "settings",
457
+ icon: "tune-variant",
458
+ label: "Project settings",
459
+ hint: "Name, instructions for the AI, delete",
460
+ run: () => setSettingsMode("settings")
461
+ }, {
462
+ key: "rename",
463
+ icon: "pencil-outline",
464
+ label: "Rename",
465
+ run: () => setSettingsMode("rename")
466
+ }] : [];
467
+ const tools = [];
468
+ if (projectTools && hostChat) {
469
+ tools.push({
470
+ key: "integrations",
471
+ icon: "power-plug-outline",
472
+ label: "Integrations",
473
+ hint: "Stripe, email, Slack, AI\u2026",
474
+ run: () => setIntegrationsOpen(true)
377
475
  });
378
- if (hostChat) actions.push({
379
- label: "Export or deploy\u2026",
380
- run: pickExport
476
+ }
477
+ if (projectTools && (build == null ? void 0 : build.sandboxId)) {
478
+ tools.push({
479
+ key: "github",
480
+ icon: "github",
481
+ label: "GitHub",
482
+ run: () => void 0,
483
+ children: [{
484
+ key: "github-push",
485
+ icon: "github",
486
+ label: "Push to my GitHub",
487
+ hint: "Create or update a repo with this code",
488
+ run: () => setGithubOpen(true)
489
+ }]
381
490
  });
382
491
  }
383
492
  const demo = build && !building ? demoVideoSource(live, build.previewUrl) : null;
384
493
  if (demo && onOpenCodezen) {
385
- actions.push({
494
+ tools.push({
495
+ key: "demo",
496
+ icon: "movie-open-outline",
386
497
  label: "Demo video",
387
- run: () => {
388
- const film = () => {
389
- try {
390
- const handoff = webbuilderDemoHandoff(siteTitle || (build == null ? void 0 : build.title) || "", demo);
391
- onOpenCodezen(encodeCodezenHandoff(handoff), handoff);
392
- } catch (err) {
393
- showToast(err instanceof Error ? err.message : "Couldn't open Codezen.");
394
- }
395
- };
396
- if (demo.stable) {
397
- film();
398
- return;
399
- }
400
- Alert.alert("Publish first for a link that stays up", "Codezen will film the live preview, which sleeps about an hour after the last change.", [{
401
- text: "Cancel",
402
- style: "cancel"
403
- }, {
404
- text: "Film the preview",
405
- onPress: film
406
- }]);
407
- }
498
+ hint: demo.stable ? "Film the published site" : "Publish first for a link that stays up",
499
+ run: filmDemo
408
500
  });
409
501
  }
410
- showMenu(siteTitle || "Project", actions);
502
+ const more = [{
503
+ key: "import",
504
+ icon: "github",
505
+ label: "Import a project",
506
+ hint: "GitHub",
507
+ run: () => setImportOpen(true)
508
+ }];
509
+ return [{
510
+ items: [...project2, ...view]
511
+ }, {
512
+ title: "TOOLS",
513
+ items: tools
514
+ }, {
515
+ items: more
516
+ }];
411
517
  };
518
+ const openMore = () => setProjectMenuOpen(true);
519
+ const canUndo = Boolean((build == null ? void 0 : build.sandboxId) && onUndo && !building);
412
520
  return /* @__PURE__ */ jsxs(GestureHandlerRootView, { style: [styles.fill, {
413
521
  backgroundColor: theme.screen
414
522
  }], children: [
@@ -428,6 +536,7 @@ function WebBuilderExperience({
428
536
  ] }),
429
537
  /* @__PURE__ */ jsx(View, { style: styles.headSpacer }),
430
538
  /* @__PURE__ */ jsxs(View, { style: [styles.actionPill, floating], children: [
539
+ canUndo ? /* @__PURE__ */ jsx(Tap, { onPress: undoLast, disabled: undoing, accessibilityRole: "button", accessibilityLabel: "Undo the last change", style: [styles.pillBtn, undoing && styles.disabled], pressedStyle: DIM, testID: "webbuilder-undo", children: /* @__PURE__ */ jsx(MaterialCommunityIcons, { name: "undo-variant", size: 24, color: theme.ink }) }) : null,
431
540
  /* @__PURE__ */ jsx(Tap, { onPress: shareSite, disabled: !shareUrl, accessibilityRole: "button", accessibilityLabel: "Share", style: [styles.pillBtn, !shareUrl && styles.disabled], pressedStyle: DIM, children: /* @__PURE__ */ jsx(MaterialCommunityIcons, { name: "share-outline", size: 24, color: theme.ink }) }),
432
541
  /* @__PURE__ */ jsx(Tap, { onPress: openMore, accessibilityRole: "button", accessibilityLabel: "More", style: styles.pillBtn, pressedStyle: DIM, testID: "webbuilder-more", children: /* @__PURE__ */ jsx(MaterialCommunityIcons, { name: "dots-horizontal", size: 24, color: theme.ink }) })
433
542
  ] })
@@ -436,13 +545,15 @@ function WebBuilderExperience({
436
545
  color: theme.ink
437
546
  }], numberOfLines: 1, children: mode === "code" ? "Code" : siteTitle || "Preview" }),
438
547
  /* @__PURE__ */ jsxs(View, { style: [styles.actionPill, floating], children: [
548
+ mode === "preview" ? /* @__PURE__ */ jsx(ViewportToggle, { viewport, onViewport: setViewport, disabled: !(build == null ? void 0 : build.previewUrl), theme, style: styles.pillBtn }) : null,
549
+ canUndo ? /* @__PURE__ */ jsx(Tap, { onPress: undoLast, disabled: undoing, accessibilityRole: "button", accessibilityLabel: "Undo the last change", style: [styles.pillBtn, undoing && styles.disabled], pressedStyle: DIM, testID: "webbuilder-undo", children: /* @__PURE__ */ jsx(MaterialCommunityIcons, { name: "undo-variant", size: 24, color: theme.ink }) }) : null,
439
550
  /* @__PURE__ */ jsx(Tap, { onPress: shareSite, disabled: !shareUrl, accessibilityRole: "button", accessibilityLabel: "Share", style: [styles.pillBtn, !shareUrl && styles.disabled], pressedStyle: DIM, children: /* @__PURE__ */ jsx(MaterialCommunityIcons, { name: "share-outline", size: 24, color: theme.ink }) }),
440
551
  /* @__PURE__ */ jsx(Tap, { onPress: openMore, accessibilityRole: "button", accessibilityLabel: "More", style: styles.pillBtn, pressedStyle: DIM, children: /* @__PURE__ */ jsx(MaterialCommunityIcons, { name: "dots-horizontal", size: 24, color: theme.ink }) })
441
552
  ] })
442
553
  ] })
443
554
  ] }),
444
- mode === "chat" ? /* @__PURE__ */ jsx(ProjectChat, { messages: (_e = hostChat == null ? void 0 : hostChat.messages) != null ? _e : [], streaming: (_f = hostChat == null ? void 0 : hostChat.streaming) != null ? _f : null, busy: Boolean(hostChat == null ? void 0 : hostChat.busy), error: (_g = hostChat == null ? void 0 : hostChat.error) != null ? _g : null, connected: Boolean(hostChat == null ? void 0 : hostChat.connected), building, build, siteTitle: siteTitle || "Your site", onSend: (text) => sendToAgent(text), onOpenPreview: () => setMode("preview"), onPublish: () => setPublishOpen(true), onPreviewAsleep: wakePreview, ask: (_h = hostChat == null ? void 0 : hostChat.ask) != null ? _h : null, onAnswerAsk: (formatted) => hostChat == null ? void 0 : hostChat.send(formatted), theme, bottomInset: insets.bottom }) : null,
445
- mode === "preview" ? /* @__PURE__ */ jsx(PreviewScreen, { build, building, loading: buildsLoading, previewNonce, onReload: () => setPreviewNonce((n) => n + 1), onHome: () => setPreviewNonce((n) => n + 1), onWake: wakePreview, waking, steps: liveSteps, onPublish: () => setPublishOpen(true), publishLabel, error: (_i = hostChat == null ? void 0 : hostChat.error) != null ? _i : null, theme, bottomInset: insets.bottom, viewport, onViewport: setViewport, onShowCode: canShowCode ? () => setMode("code") : void 0 }) : null,
555
+ mode === "chat" ? /* @__PURE__ */ jsx(ProjectChat, { messages: (_g = hostChat == null ? void 0 : hostChat.messages) != null ? _g : [], streaming: (_h = hostChat == null ? void 0 : hostChat.streaming) != null ? _h : null, busy: Boolean(hostChat == null ? void 0 : hostChat.busy), error: (_i = hostChat == null ? void 0 : hostChat.error) != null ? _i : null, connected: Boolean(hostChat == null ? void 0 : hostChat.connected), building, build, siteTitle: siteTitle || "Your site", onSend: (text) => sendToAgent(text), onOpenPreview: () => setMode("preview"), onPublish: () => setPublishOpen(true), onPreviewAsleep: () => wakePreview(), previewDown: Boolean(previewTrouble && previewTrouble.kind !== "restoring"), ask: (_j = hostChat == null ? void 0 : hostChat.ask) != null ? _j : null, onAnswerAsk: (formatted) => hostChat == null ? void 0 : hostChat.send(formatted), theme, bottomInset: insets.bottom }) : null,
556
+ mode === "preview" ? /* @__PURE__ */ jsx(PreviewScreen, { build, building, loading: buildsLoading, previewNonce, onReload: () => setPreviewNonce((n) => n + 1), onWake: () => wakePreview(), waking, trouble: previewTrouble, onRetry: () => wakePreview(true), onRestore: restoreFromSavedCopy, onAskAiRestore: hostChat ? askAiToRestore : void 0, agentBusy: Boolean(building) || Boolean(hostChat == null ? void 0 : hostChat.busy), steps: liveSteps, onPublish: () => setPublishOpen(true), publishLabel, error: (_k = hostChat == null ? void 0 : hostChat.error) != null ? _k : null, theme, bottomInset: insets.bottom, viewport, unpublished: Boolean(build == null ? void 0 : build.sandboxId) && !(build == null ? void 0 : build.liveUrl), onShowCode: canShowCode ? () => setMode("code") : void 0, buildingCover }) : null,
446
557
  mode === "code" ? /* @__PURE__ */ jsxs(View, { style: [styles.fill, {
447
558
  backgroundColor: theme.card,
448
559
  paddingBottom: insets.bottom
@@ -457,7 +568,7 @@ function WebBuilderExperience({
457
568
  color: theme.ink
458
569
  }], numberOfLines: 1, children: "Code" })
459
570
  ] }),
460
- /* @__PURE__ */ jsx(CodeView, { files: (_j = build == null ? void 0 : build.files) != null ? _j : null, build, code, busy: Boolean(building) || Boolean(hostChat == null ? void 0 : hostChat.busy), onWake: build && onResumePreview ? () => onResumePreview(build).then((outcome) => {
571
+ /* @__PURE__ */ jsx(CodeView, { files: (_l = build == null ? void 0 : build.files) != null ? _l : null, build, code, busy: Boolean(building) || Boolean(hostChat == null ? void 0 : hostChat.busy), onWake: build && onResumePreview ? () => onResumePreview(build).then((outcome) => {
461
572
  if (outcome === "ok") setPreviewNonce((n) => n + 1);
462
573
  return outcome;
463
574
  }) : void 0, theme, onAsk: openChat })
@@ -470,7 +581,7 @@ function WebBuilderExperience({
470
581
  /* @__PURE__ */ jsx(View, { style: styles.fill, children: homeTab === "create" ? /* @__PURE__ */ jsx(StudioHome, { draft, onDraft: setDraft, template, onClearTemplate: () => setTemplate(null), onBrowseTemplates: () => setTemplatesOpen(true), brand, onBrand: () => setBrandOpen(true), onSiteScore: () => setScoreOpen(true), onStart: startSite, connecting: startBlocked, startNotice, theme, bottomInset: BOTTOM_TABS_SPACE + insets.bottom }) : /* @__PURE__ */ jsx(ProjectsScreen, { projects, loading: projectsLoading, error: projectsError, hasMore: projectsHasMore, onRefresh: onRefreshProjects, onLoadMore: onLoadMoreProjects, onOpen: (p) => onOpenProject(p.channelId), onNewProject: () => setHomeTab("create"), topInset: insets.top + 12, bottomInset: BOTTOM_TABS_SPACE + insets.bottom, theme }) }),
471
582
  /* @__PURE__ */ jsx(BottomTabs, { tab: homeTab, onTab: setHomeTab, theme, bottomInset: insets.bottom })
472
583
  ] }),
473
- /* @__PURE__ */ jsx(TemplatesSheet, { visible: templatesOpen, onClose: () => setTemplatesOpen(false), templates, loading: templatesLoading, error: templatesError, onReload: onReloadTemplates, selectedId: (_k = template == null ? void 0 : template.id) != null ? _k : null, onPick: pickTemplate, theme }),
584
+ /* @__PURE__ */ jsx(TemplatesSheet, { visible: templatesOpen, onClose: () => setTemplatesOpen(false), templates, loading: templatesLoading, error: templatesError, onReload: onReloadTemplates, selectedId: (_m = template == null ? void 0 : template.id) != null ? _m : null, onPick: pickTemplate, theme }),
474
585
  /* @__PURE__ */ jsx(SiteScoreSheet, { visible: scoreOpen, onClose: () => setScoreOpen(false), blocked: startBlocked, onCheck: (url) => {
475
586
  setScoreOpen(false);
476
587
  onStartProject({
@@ -480,14 +591,35 @@ function WebBuilderExperience({
480
591
  });
481
592
  }, theme }),
482
593
  /* @__PURE__ */ jsx(BrandKitSheet, { visible: brandOpen, brand, onSave: saveBrand, onClose: () => setBrandOpen(false), theme }),
483
- /* @__PURE__ */ jsx(PublishSheet, { visible: publishOpen, build, publishing, onPublish: onPublish ? publish : void 0, onClose: () => setPublishOpen(false), theme }),
594
+ /* @__PURE__ */ jsx(ProjectMenuSheet, { visible: projectMenuOpen, title: siteTitle || "Project", sections: projectMenuOpen ? projectMenu() : [], onClose: () => setProjectMenuOpen(false), theme }),
595
+ projectTools ? /* @__PURE__ */ jsxs(Fragment, { children: [
596
+ /* @__PURE__ */ jsx(ProjectSettingsSheet, { visible: settingsMode !== null, mode: settingsMode != null ? settingsMode : "settings", channelId: activeChannelId, title: siteTitle || "New app", tools: projectTools, aiBusy: Boolean(building) || Boolean(hostChat == null ? void 0 : hostChat.busy), onSaved: () => showToast("Saved"), onDeleted: () => {
597
+ showToast("Project deleted");
598
+ onCloseProject();
599
+ setHomeTab("projects");
600
+ onRefreshProjects == null ? void 0 : onRefreshProjects();
601
+ }, onClose: () => setSettingsMode(null), theme }),
602
+ /* @__PURE__ */ jsx(GithubPushSheet, { visible: githubOpen, build, channelId: activeChannelId, title: siteTitle || (build == null ? void 0 : build.title) || "", tools: projectTools, onStarted: (message) => {
603
+ showToast(message);
604
+ setMode("chat");
605
+ }, onClose: () => setGithubOpen(false), theme }),
606
+ /* @__PURE__ */ jsx(IntegrationsSheet, { visible: integrationsOpen, channelId: activeChannelId, tools: projectTools, aiBusy: Boolean(building) || Boolean(hostChat == null ? void 0 : hostChat.busy), onRequest: (text) => askAgent(text), onClose: () => setIntegrationsOpen(false), theme })
607
+ ] }) : null,
608
+ /* @__PURE__ */ jsx(ImportProjectSheet, { visible: importOpen, onImport: (turn) => {
609
+ onStartProject({
610
+ text: turn,
611
+ template: null,
612
+ agent: true
613
+ });
614
+ }, onClose: () => setImportOpen(false), theme }),
615
+ /* @__PURE__ */ jsx(PublishSheet, { visible: publishOpen, build, publishing, onPublish: onPublish ? publish : void 0, onClose: () => setPublishOpen(false), theme, liveUrl: live, aiBusy: Boolean(building) || Boolean(hostChat == null ? void 0 : hostChat.busy), tools: publishTools, onDownloadCode: (build == null ? void 0 : build.sandboxId) && !building ? downloadCode : void 0, onExport: hostChat && !building ? exportTo : void 0, onOwnCloudflare: hostChat && !building ? () => askAgent(ownCloudflareTurn(siteTitle || (build == null ? void 0 : build.title) || "")) : void 0, onFixWithAi: hostChat ? (text) => askAgent(text) : void 0, onUnpublished: () => showToast("The site is offline now.") }),
484
616
  /* @__PURE__ */ jsx(VersionsSheet, { visible: versionsOpen, builds, selectedKey, onSelect: (picked) => {
485
617
  setSelectedKey(picked.key === (latest == null ? void 0 : latest.key) ? null : picked.key);
486
618
  setVersionsOpen(false);
487
619
  }, onClose: () => setVersionsOpen(false), theme }),
488
- /* @__PURE__ */ jsx(Sheet, { visible: menu !== null, title: (_l = menu == null ? void 0 : menu.title) != null ? _l : "", onClose: () => setMenu(null), theme, children: /* @__PURE__ */ jsx(View, { style: [styles.menuList, {
620
+ /* @__PURE__ */ jsx(Sheet, { visible: menu !== null, title: (_n = menu == null ? void 0 : menu.title) != null ? _n : "", onClose: () => setMenu(null), theme, children: /* @__PURE__ */ jsx(View, { style: [styles.menuList, {
489
621
  paddingBottom: insets.bottom + 8
490
- }], children: ((_m = menu == null ? void 0 : menu.actions) != null ? _m : []).map((action) => /* @__PURE__ */ jsx(Tap, { onPress: () => chooseMenu(action), accessibilityRole: "button", style: [styles.menuRow, {
622
+ }], children: ((_o = menu == null ? void 0 : menu.actions) != null ? _o : []).map((action) => /* @__PURE__ */ jsx(Tap, { onPress: () => chooseMenu(action), accessibilityRole: "button", style: [styles.menuRow, {
491
623
  borderBottomColor: theme.border
492
624
  }], pressedStyle: DIM, children: /* @__PURE__ */ jsx(Text, { style: [styles.menuLabel, {
493
625
  color: action.destructive ? theme.crit : theme.ink