@legendapp/spark 0.0.1-next.2 → 0.0.1-next.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 (399) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +10 -4
  3. package/ai-codex.ts +1 -0
  4. package/ai.ts +1 -0
  5. package/app-documents.ts +1 -0
  6. package/config-plugin.d.cts +2 -0
  7. package/contracts.ts +2 -0
  8. package/diagnostics.ts +1 -0
  9. package/expo-config.d.cts +1 -0
  10. package/metro.cjs +4 -1
  11. package/metro.d.cts +12 -0
  12. package/native.cjs +3 -1
  13. package/native.d.cts +6 -0
  14. package/package.json +82 -14
  15. package/schema.json +276 -58
  16. package/settings-observable.ts +1 -0
  17. package/settings-window.ts +1 -0
  18. package/shortcuts-commands.ts +1 -0
  19. package/shortcuts-keyboard.ts +3 -0
  20. package/ui-classnames.ts +1 -0
  21. package/ui-glass.ts +1 -0
  22. package/ui-search.ts +1 -0
  23. package/ui-sidebar.ts +1 -0
  24. package/ui-split-view.ts +1 -0
  25. package/ui-symbol.ts +1 -0
  26. package/vendor/node_modules/@legendapp/spark-ai/package.json +19 -0
  27. package/vendor/node_modules/@legendapp/spark-ai/src/availability.ts +17 -0
  28. package/vendor/node_modules/@legendapp/spark-ai/src/index.ts +15 -0
  29. package/vendor/node_modules/@legendapp/spark-ai/src/invocations.ts +34 -0
  30. package/vendor/node_modules/@legendapp/spark-ai/src/output.ts +62 -0
  31. package/vendor/node_modules/@legendapp/spark-ai/src/run.ts +12 -0
  32. package/vendor/node_modules/@legendapp/spark-ai/src/types.ts +16 -0
  33. package/vendor/node_modules/@legendapp/spark-audio/macos/RNSparkAudio.h +2 -1
  34. package/vendor/node_modules/@legendapp/spark-audio/macos/RNSparkAudio.mm +126 -24
  35. package/vendor/node_modules/@legendapp/spark-audio/package.json +5 -2
  36. package/vendor/node_modules/@legendapp/spark-audio/src/NativeSparkAudio.ts +5 -1
  37. package/vendor/node_modules/@legendapp/spark-audio/src/desktop.ts +36 -32
  38. package/vendor/node_modules/@legendapp/spark-audio/src/events.ts +11 -0
  39. package/vendor/node_modules/@legendapp/spark-audio/src/hooks.ts +65 -0
  40. package/vendor/node_modules/@legendapp/spark-audio/src/index.web.ts +92 -33
  41. package/vendor/node_modules/@legendapp/spark-audio/src/media-session-unavailable.ts +6 -4
  42. package/vendor/node_modules/@legendapp/spark-audio/src/media-session.ts +52 -19
  43. package/vendor/node_modules/@legendapp/spark-audio/src/media-session.web.ts +18 -10
  44. package/vendor/node_modules/@legendapp/spark-audio/src/media-types.ts +40 -13
  45. package/vendor/node_modules/@legendapp/spark-audio/src/mobile.ts +40 -32
  46. package/vendor/node_modules/@legendapp/spark-audio/src/player.ts +97 -0
  47. package/vendor/node_modules/@legendapp/spark-audio/src/status-listeners.ts +21 -15
  48. package/vendor/node_modules/@legendapp/spark-audio/src/types.ts +9 -4
  49. package/vendor/node_modules/@legendapp/spark-audio/windows/SparkAudio/SparkAudio.h +67 -20
  50. package/vendor/node_modules/@legendapp/spark-auth-session/package.json +4 -3
  51. package/vendor/node_modules/@legendapp/spark-auth-session/src/core.ts +60 -42
  52. package/vendor/node_modules/@legendapp/spark-auth-session/src/index.ts +28 -12
  53. package/vendor/node_modules/@legendapp/spark-auth-session/src/mobile.ts +97 -41
  54. package/vendor/node_modules/@legendapp/spark-auth-session/src/types.ts +20 -9
  55. package/vendor/node_modules/@legendapp/spark-cli/dist/add-desktop.js +50 -7
  56. package/vendor/node_modules/@legendapp/spark-cli/dist/build-mode.js +1 -1
  57. package/vendor/node_modules/@legendapp/spark-cli/dist/build.js +83 -48
  58. package/vendor/node_modules/@legendapp/spark-cli/dist/cli-arguments.js +60 -0
  59. package/vendor/node_modules/@legendapp/spark-cli/dist/commands.js +7 -2
  60. package/vendor/node_modules/@legendapp/spark-cli/dist/create.js +31 -5
  61. package/vendor/node_modules/@legendapp/spark-cli/dist/credentials.js +69 -23
  62. package/vendor/node_modules/@legendapp/spark-cli/dist/dev-command.js +12 -3
  63. package/vendor/node_modules/@legendapp/spark-cli/dist/dev.js +12 -9
  64. package/vendor/node_modules/@legendapp/spark-cli/dist/examples.js +1 -1
  65. package/vendor/node_modules/@legendapp/spark-cli/dist/expo-dev-patch.cjs +4 -2
  66. package/vendor/node_modules/@legendapp/spark-cli/dist/expo-metro.cjs +1 -1
  67. package/vendor/node_modules/@legendapp/spark-cli/dist/expo-node.js +3 -3
  68. package/vendor/node_modules/@legendapp/spark-cli/dist/index.js +10 -38
  69. package/vendor/node_modules/@legendapp/spark-cli/dist/local.js +1 -1
  70. package/vendor/node_modules/@legendapp/spark-cli/dist/metro.cjs +26 -5
  71. package/vendor/node_modules/@legendapp/spark-cli/dist/native-metadata.js +26 -0
  72. package/vendor/node_modules/@legendapp/spark-cli/dist/native-patch-preflight.js +84 -0
  73. package/vendor/node_modules/@legendapp/spark-cli/dist/native-preparation.js +88 -0
  74. package/vendor/node_modules/@legendapp/spark-cli/dist/notary-profiles.js +75 -0
  75. package/vendor/node_modules/@legendapp/spark-cli/dist/package.js +4 -2
  76. package/vendor/node_modules/@legendapp/spark-cli/dist/platform.js +16 -2
  77. package/vendor/node_modules/@legendapp/spark-cli/dist/project.js +66 -13
  78. package/vendor/node_modules/@legendapp/spark-cli/dist/release.js +84 -4
  79. package/vendor/node_modules/@legendapp/spark-cli/dist/release.json +23 -18
  80. package/vendor/node_modules/@legendapp/spark-cli/dist/runner-install.js +145 -31
  81. package/vendor/node_modules/@legendapp/spark-cli/dist/signing.js +4 -3
  82. package/vendor/node_modules/@legendapp/spark-cli/dist/updates.js +41 -4
  83. package/vendor/node_modules/@legendapp/spark-cli/dist/windows.js +4 -1
  84. package/vendor/node_modules/@legendapp/spark-cli/package.json +7 -6
  85. package/vendor/node_modules/@legendapp/spark-cli/templates/blank-typescript/App.tsx +6 -12
  86. package/vendor/node_modules/@legendapp/spark-cli/templates/blank-typescript/desktop.config.json +5 -3
  87. package/vendor/node_modules/@legendapp/spark-cli/templates/blank-typescript/package.json +11 -9
  88. package/vendor/node_modules/@legendapp/spark-cli/templates/diff-lite/Git.macos.tsx +2 -2
  89. package/vendor/node_modules/@legendapp/spark-cli/templates/document-editor/Integration.macos.tsx +23 -21
  90. package/vendor/node_modules/@legendapp/spark-cli/templates/document-editor/Integration.windows.tsx +23 -21
  91. package/vendor/node_modules/@legendapp/spark-cli/templates/document-editor/io.desktop.ts +11 -8
  92. package/vendor/node_modules/@legendapp/spark-cli/templates/document-editor/io.macos.ts +3 -3
  93. package/vendor/node_modules/@legendapp/spark-cli/templates/example-shared/Lifecycle.desktop.tsx +8 -14
  94. package/vendor/node_modules/@legendapp/spark-cli/templates/example-shared/OpenFiles.desktop.tsx +5 -10
  95. package/vendor/node_modules/@legendapp/spark-cli/templates/example-shared/io.desktop.ts +11 -8
  96. package/vendor/node_modules/@legendapp/spark-cli/templates/example-shared/io.macos.ts +3 -3
  97. package/vendor/node_modules/@legendapp/spark-cli/templates/music-lite/assets.desktop.ts +2 -2
  98. package/vendor/node_modules/@legendapp/spark-cli/templates/notes-lite/Activation.desktop.tsx +2 -2
  99. package/vendor/node_modules/@legendapp/spark-cli/templates/notes-lite/Desktop.desktop.ts +37 -15
  100. package/vendor/node_modules/@legendapp/spark-cli/templates/notes-lite/session.ts +5 -6
  101. package/vendor/node_modules/@legendapp/spark-cli/templates/notes-lite/window-session.ts +5 -4
  102. package/vendor/node_modules/@legendapp/spark-cli/templates/universal/desktop.config.json +5 -3
  103. package/vendor/node_modules/@legendapp/spark-cli/templates/universal/metro.config.js +1 -1
  104. package/vendor/node_modules/@legendapp/spark-cli/templates/universal/package.json +13 -11
  105. package/vendor/node_modules/@legendapp/spark-cli/templates/universal/react-native.config.js +1 -1
  106. package/vendor/node_modules/@legendapp/spark-cli/templates/windows/package.json +13 -11
  107. package/vendor/node_modules/@legendapp/spark-cli/templates/windows/react-native.config.js +1 -1
  108. package/vendor/node_modules/@legendapp/spark-clipboard/macos/RNDesktopClipboard.mm +10 -16
  109. package/vendor/node_modules/@legendapp/spark-clipboard/package.json +2 -2
  110. package/vendor/node_modules/@legendapp/spark-clipboard/src/NativeDesktopClipboard.ts +1 -1
  111. package/vendor/node_modules/@legendapp/spark-clipboard/src/desktop.ts +55 -31
  112. package/vendor/node_modules/@legendapp/spark-clipboard/src/expo.ts +21 -11
  113. package/vendor/node_modules/@legendapp/spark-clipboard/src/options.ts +8 -0
  114. package/vendor/node_modules/@legendapp/spark-clipboard/src/types.ts +10 -0
  115. package/vendor/node_modules/@legendapp/spark-clipboard/windows/SparkClipboard/SparkClipboard.h +38 -15
  116. package/vendor/node_modules/@legendapp/spark-clipboard/windows/SparkClipboard/SparkClipboard.vcxproj +2 -0
  117. package/vendor/node_modules/@legendapp/spark-codex/RNCodex.podspec +22 -0
  118. package/vendor/node_modules/@legendapp/spark-codex/cpp/HybridCodexAppServer.hpp +23 -0
  119. package/vendor/node_modules/@legendapp/spark-codex/cpp/HybridCodexAppServer.mm +1529 -0
  120. package/vendor/node_modules/@legendapp/spark-codex/nitro.json +21 -0
  121. package/vendor/node_modules/@legendapp/spark-codex/nitrogen/generated/.gitattributes +1 -0
  122. package/vendor/node_modules/@legendapp/spark-codex/nitrogen/generated/ios/RNCodex+autolinking.rb +62 -0
  123. package/vendor/node_modules/@legendapp/spark-codex/nitrogen/generated/ios/RNCodex-Swift-Cxx-Bridge.cpp +17 -0
  124. package/vendor/node_modules/@legendapp/spark-codex/nitrogen/generated/ios/RNCodex-Swift-Cxx-Bridge.hpp +27 -0
  125. package/vendor/node_modules/@legendapp/spark-codex/nitrogen/generated/ios/RNCodex-Swift-Cxx-Umbrella.hpp +38 -0
  126. package/vendor/node_modules/@legendapp/spark-codex/nitrogen/generated/ios/RNCodexAutolinking.mm +35 -0
  127. package/vendor/node_modules/@legendapp/spark-codex/nitrogen/generated/ios/RNCodexAutolinking.swift +16 -0
  128. package/vendor/node_modules/@legendapp/spark-codex/nitrogen/generated/shared/c++/CodexAvailability.hpp +95 -0
  129. package/vendor/node_modules/@legendapp/spark-codex/nitrogen/generated/shared/c++/CodexRunResult.hpp +99 -0
  130. package/vendor/node_modules/@legendapp/spark-codex/nitrogen/generated/shared/c++/HybridCodexAppServerSpec.cpp +24 -0
  131. package/vendor/node_modules/@legendapp/spark-codex/nitrogen/generated/shared/c++/HybridCodexAppServerSpec.hpp +71 -0
  132. package/vendor/node_modules/@legendapp/spark-codex/package.json +35 -0
  133. package/vendor/node_modules/@legendapp/spark-codex/react-native.config.js +11 -0
  134. package/vendor/node_modules/@legendapp/spark-codex/src/Codex.nitro.ts +30 -0
  135. package/vendor/node_modules/@legendapp/spark-codex/src/index.ts +65 -0
  136. package/vendor/node_modules/@legendapp/spark-codex/src/native.ts +6 -0
  137. package/vendor/node_modules/@legendapp/spark-commands/package.json +21 -0
  138. package/vendor/node_modules/@legendapp/spark-commands/src/bindings.ts +90 -0
  139. package/vendor/node_modules/@legendapp/spark-commands/src/index.tsx +400 -0
  140. package/vendor/node_modules/@legendapp/spark-commands/src/router.ts +138 -0
  141. package/vendor/node_modules/@legendapp/spark-commands/src/storage.ts +20 -0
  142. package/vendor/node_modules/@legendapp/spark-context-menu/macos/RNContextMenu.mm +7 -8
  143. package/vendor/node_modules/@legendapp/spark-context-menu/package.json +4 -3
  144. package/vendor/node_modules/@legendapp/spark-context-menu/src/NativeContextMenu.ts +1 -1
  145. package/vendor/node_modules/@legendapp/spark-context-menu/src/index.ts +26 -26
  146. package/vendor/node_modules/@legendapp/spark-context-menu/windows/SparkContextMenu/SparkContextMenu.h +3 -2
  147. package/vendor/node_modules/@legendapp/spark-desktop-app/RNDesktopApp.podspec +2 -1
  148. package/vendor/node_modules/@legendapp/spark-desktop-app/cpp/SparkBinaryJSI.hpp +89 -0
  149. package/vendor/node_modules/@legendapp/spark-desktop-app/cpp/SparkBinaryWindows.hpp +22 -0
  150. package/vendor/node_modules/@legendapp/spark-desktop-app/macos/RNDesktopApp.mm +13 -7
  151. package/vendor/node_modules/@legendapp/spark-desktop-app/macos/SparkBinaryJSI.h +48 -0
  152. package/vendor/node_modules/@legendapp/spark-desktop-app/macos/SparkDesktop.h +4 -0
  153. package/vendor/node_modules/@legendapp/spark-desktop-app/macos/SparkDesktop.mm +33 -33
  154. package/vendor/node_modules/@legendapp/spark-desktop-app/macos/SparkDesktopError.h +20 -0
  155. package/vendor/node_modules/@legendapp/spark-desktop-app/macos/SparkLifecycle.h +26 -0
  156. package/vendor/node_modules/@legendapp/spark-desktop-app/macos/SparkLifecycle.mm +49 -0
  157. package/vendor/node_modules/@legendapp/spark-desktop-app/macos/SparkQuitCoordinator.h +9 -0
  158. package/vendor/node_modules/@legendapp/spark-desktop-app/macos/SparkQuitCoordinator.mm +70 -0
  159. package/vendor/node_modules/@legendapp/spark-desktop-app/macos/SparkWindow.mm +9 -6
  160. package/vendor/node_modules/@legendapp/spark-desktop-app/macos/recent-documents/RNRecentDocumentController.mm +55 -0
  161. package/vendor/node_modules/@legendapp/spark-desktop-app/package.json +5 -3
  162. package/vendor/node_modules/@legendapp/spark-desktop-app/src/NativeDesktopApp.ts +1 -1
  163. package/vendor/node_modules/@legendapp/spark-desktop-app/src/api.ts +86 -40
  164. package/vendor/node_modules/@legendapp/spark-desktop-app/src/contracts/accelerator.ts +40 -0
  165. package/vendor/node_modules/@legendapp/spark-desktop-app/src/contracts/index.ts +56 -0
  166. package/vendor/node_modules/@legendapp/spark-desktop-app/src/contracts/menu.ts +114 -0
  167. package/vendor/node_modules/@legendapp/spark-desktop-app/src/contracts/native-buffer.ts +22 -0
  168. package/vendor/node_modules/@legendapp/spark-desktop-app/src/contracts/path.ts +24 -0
  169. package/vendor/node_modules/@legendapp/spark-desktop-app/src/events.ts +75 -0
  170. package/vendor/node_modules/@legendapp/spark-desktop-app/src/index.ts +2 -0
  171. package/vendor/node_modules/@legendapp/spark-desktop-app/src/index.windows.ts +2 -0
  172. package/vendor/node_modules/@legendapp/spark-desktop-app/src/open-requests.ts +43 -0
  173. package/vendor/node_modules/@legendapp/spark-desktop-app/src/restoration.ts +11 -0
  174. package/vendor/node_modules/@legendapp/spark-desktop-app/src/transport.ts +10 -0
  175. package/vendor/node_modules/@legendapp/spark-desktop-config/app.plugin.cjs +10 -5
  176. package/vendor/node_modules/@legendapp/spark-desktop-config/app.plugin.d.cts +3 -0
  177. package/vendor/node_modules/@legendapp/spark-desktop-config/autolinking.cjs +35 -0
  178. package/vendor/node_modules/@legendapp/spark-desktop-config/config.cjs +16 -3
  179. package/vendor/node_modules/@legendapp/spark-desktop-config/config.d.cts +89 -9
  180. package/vendor/node_modules/@legendapp/spark-desktop-config/expo.d.cts +3 -0
  181. package/vendor/node_modules/@legendapp/spark-desktop-config/identity.cjs +3 -2
  182. package/vendor/node_modules/@legendapp/spark-desktop-config/lifecycle.cjs +20 -0
  183. package/vendor/node_modules/@legendapp/spark-desktop-config/package.json +6 -5
  184. package/vendor/node_modules/@legendapp/spark-desktop-config/schema.json +276 -58
  185. package/vendor/node_modules/@legendapp/spark-desktop-config/updates.cjs +1 -0
  186. package/vendor/node_modules/@legendapp/spark-desktop-config/validation.cjs +35 -0
  187. package/vendor/node_modules/@legendapp/spark-desktop-config/windows.plugin.cjs +2 -1
  188. package/vendor/node_modules/@legendapp/spark-desktop-host/AppDelegate.mm +129 -11
  189. package/vendor/node_modules/@legendapp/spark-desktop-host/package.json +2 -2
  190. package/vendor/node_modules/@legendapp/spark-desktop-host/windows/application.inc +277 -121
  191. package/vendor/node_modules/@legendapp/spark-desktop-links/common/AuthLoopback.h +5 -7
  192. package/vendor/node_modules/@legendapp/spark-desktop-links/macos/RNDesktopLinks.mm +10 -9
  193. package/vendor/node_modules/@legendapp/spark-desktop-links/package.json +2 -2
  194. package/vendor/node_modules/@legendapp/spark-desktop-links/src/NativeDesktopLinks.ts +1 -1
  195. package/vendor/node_modules/@legendapp/spark-desktop-links/src/api.ts +27 -33
  196. package/vendor/node_modules/@legendapp/spark-desktop-links/src/expo.ts +3 -4
  197. package/vendor/node_modules/@legendapp/spark-desktop-links/src/native.ts +9 -0
  198. package/vendor/node_modules/@legendapp/spark-desktop-links/windows/SparkLinks/SparkLinks.h +22 -22
  199. package/vendor/node_modules/@legendapp/spark-desktop-shortcuts/RNDesktopShortcuts.podspec +1 -0
  200. package/vendor/node_modules/@legendapp/spark-desktop-shortcuts/macos/RNDesktopShortcuts.mm +1 -1
  201. package/vendor/node_modules/@legendapp/spark-desktop-shortcuts/macos/keyboard-manager/RNKeyboardManager.h +9 -0
  202. package/vendor/node_modules/@legendapp/spark-desktop-shortcuts/macos/keyboard-manager/RNKeyboardManager.mm +307 -0
  203. package/vendor/node_modules/@legendapp/spark-desktop-shortcuts/package.json +8 -5
  204. package/vendor/node_modules/@legendapp/spark-desktop-shortcuts/src/NativeDesktopShortcuts.ts +1 -1
  205. package/vendor/node_modules/@legendapp/spark-desktop-shortcuts/src/api.ts +39 -14
  206. package/vendor/node_modules/@legendapp/spark-desktop-shortcuts/src/keyboard-manager/NativeKeyboardManager.ts +12 -0
  207. package/vendor/node_modules/@legendapp/spark-desktop-shortcuts/src/keyboard-manager/codes.ts +108 -0
  208. package/vendor/node_modules/@legendapp/spark-desktop-shortcuts/src/keyboard-manager/index.ts +99 -0
  209. package/vendor/node_modules/@legendapp/spark-desktop-windows/RNDesktopWindows.podspec +2 -0
  210. package/vendor/node_modules/@legendapp/spark-desktop-windows/macos/RNDesktopWindows.mm +229 -103
  211. package/vendor/node_modules/@legendapp/spark-desktop-windows/macos/SparkWindowGeometry.h +63 -0
  212. package/vendor/node_modules/@legendapp/spark-desktop-windows/macos/window-manager/LegendWindowRegistry.h +20 -0
  213. package/vendor/node_modules/@legendapp/spark-desktop-windows/macos/window-manager/LegendWindowRegistry.mm +27 -0
  214. package/vendor/node_modules/@legendapp/spark-desktop-windows/macos/window-manager/RNWindowManager.h +12 -0
  215. package/vendor/node_modules/@legendapp/spark-desktop-windows/macos/window-manager/RNWindowManager.mm +3130 -0
  216. package/vendor/node_modules/@legendapp/spark-desktop-windows/macos/window-manager/RNWindowManagerStartup.mm +31 -0
  217. package/vendor/node_modules/@legendapp/spark-desktop-windows/macos/window-manager/SidebarStartupFallbacks.mm +14 -0
  218. package/vendor/node_modules/@legendapp/spark-desktop-windows/package.json +10 -6
  219. package/vendor/node_modules/@legendapp/spark-desktop-windows/src/NativeDesktopWindowManager.ts +1 -1
  220. package/vendor/node_modules/@legendapp/spark-desktop-windows/src/api.ts +144 -70
  221. package/vendor/node_modules/@legendapp/spark-desktop-windows/src/diagnostics.ts +17 -0
  222. package/vendor/node_modules/@legendapp/spark-desktop-windows/src/index.ts +3 -1
  223. package/vendor/node_modules/@legendapp/spark-desktop-windows/src/index.windows.ts +3 -1
  224. package/vendor/node_modules/@legendapp/spark-desktop-windows/src/macos-adapter.ts +53 -0
  225. package/vendor/node_modules/@legendapp/spark-desktop-windows/src/macos.ts +51 -0
  226. package/vendor/node_modules/@legendapp/spark-desktop-windows/src/transport.ts +41 -0
  227. package/vendor/node_modules/@legendapp/spark-desktop-windows/src/types.ts +140 -0
  228. package/vendor/node_modules/@legendapp/spark-desktop-windows/src/validation.ts +162 -0
  229. package/vendor/node_modules/@legendapp/spark-desktop-windows/src/window-manager/NativeWindowManager.ts +28 -0
  230. package/vendor/node_modules/@legendapp/spark-desktop-windows/src/windows/WindowProvider.tsx +20 -0
  231. package/vendor/node_modules/@legendapp/spark-desktop-windows/src/windows/createWindowsNavigator.tsx +78 -0
  232. package/vendor/node_modules/@legendapp/spark-desktop-windows/src/windows/index.ts +6 -0
  233. package/vendor/node_modules/@legendapp/spark-desktop-windows/src/windows/primaryWindowLifecycle.ts +34 -0
  234. package/vendor/node_modules/@legendapp/spark-desktop-windows/src/windows/types.ts +11 -0
  235. package/vendor/node_modules/@legendapp/spark-desktop-windows/src/windows/usePrimaryWindowLifecycle.ts +18 -0
  236. package/vendor/node_modules/@legendapp/spark-desktop-windows/src/windows/useWindowFocusEffect.ts +17 -0
  237. package/vendor/node_modules/@legendapp/spark-documents/package.json +22 -0
  238. package/vendor/node_modules/@legendapp/spark-documents/src/controller.ts +97 -0
  239. package/vendor/node_modules/@legendapp/spark-documents/src/documentTransition.ts +13 -0
  240. package/vendor/node_modules/@legendapp/spark-documents/src/hooks.ts +139 -0
  241. package/vendor/node_modules/@legendapp/spark-documents/src/index.tsx +50 -0
  242. package/vendor/node_modules/@legendapp/spark-documents/src/reload.ts +39 -0
  243. package/vendor/node_modules/@legendapp/spark-documents/src/requests.ts +15 -0
  244. package/vendor/node_modules/@legendapp/spark-drag-drop/package.json +4 -3
  245. package/vendor/node_modules/@legendapp/spark-drag-drop/src/DesktopDragViewNativeComponent.ts +1 -1
  246. package/vendor/node_modules/@legendapp/spark-drag-drop/src/contracts.ts +73 -18
  247. package/vendor/node_modules/@legendapp/spark-drag-drop/src/index.tsx +58 -15
  248. package/vendor/node_modules/@legendapp/spark-drag-drop/windows/SparkDragDrop/SparkDragDrop.h +14 -8
  249. package/vendor/node_modules/@legendapp/spark-file-dialog/ios/RNFileDialog.mm +34 -121
  250. package/vendor/node_modules/@legendapp/spark-file-dialog/package.json +12 -5
  251. package/vendor/node_modules/@legendapp/spark-file-dialog/src/NativeFileDialog.ts +1 -5
  252. package/vendor/node_modules/@legendapp/spark-file-dialog/src/index.ts +19 -84
  253. package/vendor/node_modules/@legendapp/spark-file-dialog/src/native.ts +12 -0
  254. package/vendor/node_modules/@legendapp/spark-file-dialog/src/options.ts +34 -14
  255. package/vendor/node_modules/@legendapp/spark-file-dialog/src/types.ts +26 -0
  256. package/vendor/node_modules/@legendapp/spark-file-dialog/windows/SparkFileDialog/SparkFileDialog.h +42 -58
  257. package/vendor/node_modules/@legendapp/spark-file-system/RNDesktopFileSystem.podspec +1 -0
  258. package/vendor/node_modules/@legendapp/spark-file-system/macos/RNDesktopFileSystem.mm +32 -21
  259. package/vendor/node_modules/@legendapp/spark-file-system/macos/SparkFileMutations.h +24 -0
  260. package/vendor/node_modules/@legendapp/spark-file-system/macos/SparkFileMutations.mm +215 -0
  261. package/vendor/node_modules/@legendapp/spark-file-system/macos/file-scanner/RNFileScanner.h +9 -0
  262. package/vendor/node_modules/@legendapp/spark-file-system/macos/file-scanner/RNFileScanner.mm +82 -0
  263. package/vendor/node_modules/@legendapp/spark-file-system/macos/file-scanner/RNFileScannerCore.h +47 -0
  264. package/vendor/node_modules/@legendapp/spark-file-system/macos/file-scanner/RNFileScannerCore.mm +306 -0
  265. package/vendor/node_modules/@legendapp/spark-file-system/package.json +8 -6
  266. package/vendor/node_modules/@legendapp/spark-file-system/src/NativeDesktopFileSystem.ts +1 -1
  267. package/vendor/node_modules/@legendapp/spark-file-system/src/file-scanner/NativeFileScanner.ts +11 -0
  268. package/vendor/node_modules/@legendapp/spark-file-system/src/file-scanner/index.ts +93 -0
  269. package/vendor/node_modules/@legendapp/spark-file-system/src/handles.ts +48 -14
  270. package/vendor/node_modules/@legendapp/spark-file-system/src/index.ts +134 -45
  271. package/vendor/node_modules/@legendapp/spark-file-system/src/path.ts +1 -9
  272. package/vendor/node_modules/@legendapp/spark-file-system/windows/SparkFileSystem/SparkFileSystem.h +102 -26
  273. package/vendor/node_modules/@legendapp/spark-file-system/windows/SparkFileSystem/SparkFileSystem.vcxproj +2 -0
  274. package/vendor/node_modules/@legendapp/spark-global-shortcuts/RNDesktopGlobalShortcuts.podspec +1 -0
  275. package/vendor/node_modules/@legendapp/spark-global-shortcuts/macos/RNDesktopGlobalShortcuts.mm +7 -4
  276. package/vendor/node_modules/@legendapp/spark-global-shortcuts/package.json +4 -3
  277. package/vendor/node_modules/@legendapp/spark-global-shortcuts/src/NativeDesktopGlobalShortcuts.ts +1 -1
  278. package/vendor/node_modules/@legendapp/spark-global-shortcuts/src/index.ts +39 -10
  279. package/vendor/node_modules/@legendapp/spark-global-shortcuts/windows/SparkGlobalShortcuts/SparkGlobalShortcuts.h +5 -4
  280. package/vendor/node_modules/@legendapp/spark-message-dialog/macos/RNDesktopMessageDialog.mm +2 -2
  281. package/vendor/node_modules/@legendapp/spark-message-dialog/package.json +2 -2
  282. package/vendor/node_modules/@legendapp/spark-message-dialog/src/NativeDesktopMessageDialog.ts +1 -1
  283. package/vendor/node_modules/@legendapp/spark-message-dialog/src/index.ts +48 -11
  284. package/vendor/node_modules/@legendapp/spark-native-menu/ios/RNNativeMenu.mm +141 -609
  285. package/vendor/node_modules/@legendapp/spark-native-menu/package.json +9 -4
  286. package/vendor/node_modules/@legendapp/spark-native-menu/src/NativeMenu.ts +2 -7
  287. package/vendor/node_modules/@legendapp/spark-native-menu/src/api.ts +76 -121
  288. package/vendor/node_modules/@legendapp/spark-native-menu/src/hooks.ts +97 -0
  289. package/vendor/node_modules/@legendapp/spark-native-menu/src/windows-menus.ts +43 -37
  290. package/vendor/node_modules/@legendapp/spark-notifications/macos/RNDesktopNotifications.mm +75 -30
  291. package/vendor/node_modules/@legendapp/spark-notifications/package.json +2 -2
  292. package/vendor/node_modules/@legendapp/spark-notifications/src/NativeDesktopNotifications.ts +1 -1
  293. package/vendor/node_modules/@legendapp/spark-notifications/src/index.ts +130 -42
  294. package/vendor/node_modules/@legendapp/spark-notifications/windows/SparkNotifications/SparkNotifications.h +46 -8
  295. package/vendor/node_modules/@legendapp/spark-processes/macos/RNDesktopProcesses.mm +94 -21
  296. package/vendor/node_modules/@legendapp/spark-processes/package.json +4 -3
  297. package/vendor/node_modules/@legendapp/spark-processes/src/NativeDesktopProcesses.ts +1 -1
  298. package/vendor/node_modules/@legendapp/spark-processes/src/index.ts +124 -28
  299. package/vendor/node_modules/@legendapp/spark-processes/src/types.ts +34 -0
  300. package/vendor/node_modules/@legendapp/spark-processes/windows/SparkProcesses/SparkProcesses.h +83 -34
  301. package/vendor/node_modules/@legendapp/spark-processes/windows/SparkProcesses/SparkProcesses.vcxproj +2 -0
  302. package/vendor/node_modules/@legendapp/spark-secure-storage/macos/RNDesktopSecureStorage.mm +49 -40
  303. package/vendor/node_modules/@legendapp/spark-secure-storage/package.json +2 -2
  304. package/vendor/node_modules/@legendapp/spark-secure-storage/src/NativeDesktopSecureStorage.ts +1 -1
  305. package/vendor/node_modules/@legendapp/spark-secure-storage/src/desktop.ts +16 -14
  306. package/vendor/node_modules/@legendapp/spark-secure-storage/src/expo.ts +0 -1
  307. package/vendor/node_modules/@legendapp/spark-secure-storage/src/options.ts +3 -2
  308. package/vendor/node_modules/@legendapp/spark-secure-storage/src/unavailable.ts +6 -3
  309. package/vendor/node_modules/@legendapp/spark-settings/package.json +10 -3
  310. package/vendor/node_modules/@legendapp/spark-settings/src/fileStorage.ts +11 -0
  311. package/vendor/node_modules/@legendapp/spark-settings/src/index.ts +7 -9
  312. package/vendor/node_modules/@legendapp/spark-settings/src/storage/index.ts +142 -0
  313. package/vendor/node_modules/@legendapp/spark-settings/src/store.ts +63 -21
  314. package/vendor/node_modules/@legendapp/spark-settings-ui/package.json +20 -0
  315. package/vendor/node_modules/@legendapp/spark-settings-ui/src/index.tsx +436 -0
  316. package/vendor/node_modules/@legendapp/spark-settings-ui/src/options.ts +10 -0
  317. package/vendor/node_modules/@legendapp/spark-sqlite/package.json +3 -3
  318. package/vendor/node_modules/@legendapp/spark-sqlite/src/database.ts +182 -0
  319. package/vendor/node_modules/@legendapp/spark-sqlite/src/index.ts +19 -6
  320. package/vendor/node_modules/@legendapp/spark-sqlite/src/types.ts +22 -0
  321. package/vendor/node_modules/@legendapp/spark-system/macos/RNDesktopSystem.mm +36 -11
  322. package/vendor/node_modules/@legendapp/spark-system/package.json +2 -2
  323. package/vendor/node_modules/@legendapp/spark-system/src/NativeDesktopSystem.ts +1 -1
  324. package/vendor/node_modules/@legendapp/spark-system/src/index.ts +89 -32
  325. package/vendor/node_modules/@legendapp/spark-system/windows/SparkSystem/SparkSystem.h +8 -4
  326. package/vendor/node_modules/@legendapp/spark-tray/macos/RNDesktopTray.mm +20 -8
  327. package/vendor/node_modules/@legendapp/spark-tray/package.json +2 -2
  328. package/vendor/node_modules/@legendapp/spark-tray/src/NativeDesktopTray.ts +1 -1
  329. package/vendor/node_modules/@legendapp/spark-tray/src/index.ts +91 -34
  330. package/vendor/node_modules/@legendapp/spark-tray/windows/SparkTray/SparkTray.h +45 -15
  331. package/vendor/node_modules/@legendapp/spark-ui/macos/RNSparkButton.mm +2 -1
  332. package/vendor/node_modules/@legendapp/spark-ui/macos/RNSparkTextInput.mm +10 -2
  333. package/vendor/node_modules/@legendapp/spark-ui/macos/appkit-split-view/RNSidebarSplitViewComponent.h +15 -0
  334. package/vendor/node_modules/@legendapp/spark-ui/macos/appkit-split-view/RNSidebarSplitViewComponent.mm +1182 -0
  335. package/vendor/node_modules/@legendapp/spark-ui/macos/glass-effect-view/RNGlassEffectView.mm +72 -0
  336. package/vendor/node_modules/@legendapp/spark-ui/macos/native-select/RNNativeSegmentedControl.h +15 -0
  337. package/vendor/node_modules/@legendapp/spark-ui/macos/native-select/RNNativeSegmentedControl.mm +194 -0
  338. package/vendor/node_modules/@legendapp/spark-ui/macos/native-select/RNNativeSelect.h +15 -0
  339. package/vendor/node_modules/@legendapp/spark-ui/macos/native-select/RNNativeSelect.mm +180 -0
  340. package/vendor/node_modules/@legendapp/spark-ui/macos/sf-symbol/RNSFSymbol.h +15 -0
  341. package/vendor/node_modules/@legendapp/spark-ui/macos/sf-symbol/RNSFSymbol.mm +155 -0
  342. package/vendor/node_modules/@legendapp/spark-ui/macos/sidebar/RNSidebar.h +18 -0
  343. package/vendor/node_modules/@legendapp/spark-ui/macos/sidebar/RNSidebar.mm +645 -0
  344. package/vendor/node_modules/@legendapp/spark-ui/macos/text-input-search/RNTextInputSearch.h +15 -0
  345. package/vendor/node_modules/@legendapp/spark-ui/macos/text-input-search/RNTextInputSearch.mm +164 -0
  346. package/vendor/node_modules/@legendapp/spark-ui/package.json +16 -4
  347. package/vendor/node_modules/@legendapp/spark-ui/src/SparkSelectNativeComponent.ts +3 -1
  348. package/vendor/node_modules/@legendapp/spark-ui/src/SparkTextInputNativeComponent.ts +6 -2
  349. package/vendor/node_modules/@legendapp/spark-ui/src/appkit-split-view/SidebarSplitViewNativeComponent.ts +31 -0
  350. package/vendor/node_modules/@legendapp/spark-ui/src/appkit-split-view/index.tsx +77 -0
  351. package/vendor/node_modules/@legendapp/spark-ui/src/availability.ts +10 -0
  352. package/vendor/node_modules/@legendapp/spark-ui/src/classnames/index.ts +8 -0
  353. package/vendor/node_modules/@legendapp/spark-ui/src/control.ts +42 -0
  354. package/vendor/node_modules/@legendapp/spark-ui/src/desktop.tsx +56 -0
  355. package/vendor/node_modules/@legendapp/spark-ui/src/glass-effect-view/index.tsx +15 -0
  356. package/vendor/node_modules/@legendapp/spark-ui/src/index.android.tsx +35 -21
  357. package/vendor/node_modules/@legendapp/spark-ui/src/index.ios.tsx +55 -26
  358. package/vendor/node_modules/@legendapp/spark-ui/src/index.tsx +1 -27
  359. package/vendor/node_modules/@legendapp/spark-ui/src/index.web.tsx +45 -14
  360. package/vendor/node_modules/@legendapp/spark-ui/src/index.windows.tsx +1 -42
  361. package/vendor/node_modules/@legendapp/spark-ui/src/mobile-input.tsx +11 -0
  362. package/vendor/node_modules/@legendapp/spark-ui/src/native-select/NativeSegmentedControlNativeComponent.ts +17 -0
  363. package/vendor/node_modules/@legendapp/spark-ui/src/native-select/NativeSelectNativeComponent.ts +17 -0
  364. package/vendor/node_modules/@legendapp/spark-ui/src/select.ts +5 -3
  365. package/vendor/node_modules/@legendapp/spark-ui/src/sf-symbol/SFSymbolNativeComponent.ts +13 -0
  366. package/vendor/node_modules/@legendapp/spark-ui/src/sf-symbol/index.tsx +27 -0
  367. package/vendor/node_modules/@legendapp/spark-ui/src/sidebar/SidebarItemNativeComponent.ts +25 -0
  368. package/vendor/node_modules/@legendapp/spark-ui/src/sidebar/SidebarNativeComponent.ts +24 -0
  369. package/vendor/node_modules/@legendapp/spark-ui/src/sidebar/index.tsx +104 -0
  370. package/vendor/node_modules/@legendapp/spark-ui/src/specialized.ts +22 -0
  371. package/vendor/node_modules/@legendapp/spark-ui/src/text-input-search/TextInputSearchNativeComponent.ts +33 -0
  372. package/vendor/node_modules/@legendapp/spark-ui/src/text-input-search/index.tsx +34 -0
  373. package/vendor/node_modules/@legendapp/spark-ui/src/types.ts +30 -19
  374. package/vendor/node_modules/@legendapp/spark-ui/uniwind.ts +3 -1
  375. package/vendor/node_modules/@legendapp/spark-ui/uniwind.web.ts +3 -1
  376. package/vendor/node_modules/@legendapp/spark-ui/windows/SparkUI/SparkUI.h +16 -11
  377. package/vendor/node_modules/@legendapp/spark-updates/macos/RNDesktopUpdates.mm +21 -8
  378. package/vendor/node_modules/@legendapp/spark-updates/package.json +2 -2
  379. package/vendor/node_modules/@legendapp/spark-updates/src/NativeDesktopUpdates.ts +3 -2
  380. package/vendor/node_modules/@legendapp/spark-updates/src/index.ts +71 -15
  381. package/vendor/node_modules/@legendapp/spark-webview/package.json +2 -2
  382. package/vendor/node_modules/@legendapp/spark-webview/src/WebView.tsx +11 -0
  383. package/vendor/node_modules/@legendapp/spark-webview/src/adapter.ts +55 -0
  384. package/vendor/node_modules/@legendapp/spark-webview/src/index.ts +2 -2
  385. package/vendor/node_modules/@legendapp/spark-webview/src/types.ts +32 -0
  386. package/vendor/node_modules/@legendapp/spark-webview/src/view-props.ts +28 -0
  387. package/vendor/node_modules/@legendapp/spark-window-options/index.cjs +51 -14
  388. package/vendor/node_modules/@legendapp/spark-window-options/index.d.ts +21 -8
  389. package/vendor/node_modules/@legendapp/spark-window-options/package.json +1 -1
  390. package/windows-macos.ts +1 -0
  391. package/expo-metro.cjs +0 -1
  392. package/message-dialog.ts +0 -1
  393. package/universal.cjs +0 -1
  394. package/vendor/node_modules/@legendapp/spark-desktop-shortcuts/src/accelerator.ts +0 -22
  395. package/vendor/node_modules/@legendapp/spark-desktop-windows/src/windows-options.ts +0 -11
  396. package/vendor/node_modules/@legendapp/spark-file-dialog/src/index.windows.ts +0 -15
  397. package/vendor/node_modules/@legendapp/spark-global-shortcuts/src/accelerator.ts +0 -22
  398. package/vendor/node_modules/@legendapp/spark-ui/macos/RNSparkSelect.h +0 -4
  399. package/vendor/node_modules/@legendapp/spark-ui/macos/RNSparkSelect.mm +0 -53
@@ -1,10 +1,10 @@
1
1
  import { spawnProcess } from "./process.js";
2
2
  import { readAppConfig } from "./project.js";
3
3
  import { existsSync } from "node:fs";
4
- import path from "node:path";
5
4
  import { createInterface } from "node:readline/promises";
6
5
  import { run } from "./commands.js";
7
6
  import { readJson, stateFile, writeJson } from "./project.js";
7
+ import { listNotaryProfiles } from "./notary-profiles.js";
8
8
  export function parseIdentities(output) {
9
9
  return [...output.matchAll(/\b([A-Fa-f0-9]{40})\s+"(Developer ID Application: [^"\n]+ \(([A-Z0-9]{10})\))"/g)]
10
10
  .map((match) => ({ hash: match[1].toUpperCase(), name: match[2], teamId: match[3] }));
@@ -32,38 +32,84 @@ export async function credentials(root, reset = false, execute = run) {
32
32
  const saved = !reset && existsSync(file) ? readJson(file) : {};
33
33
  const config = readAppConfig(root).expo?.extra?.spark?.signing?.macos ?? {};
34
34
  const keychain = process.env.SPARK_SIGNING_KEYCHAIN ?? saved.keychain;
35
- const identity = process.env.SPARK_DEVELOPER_ID_APPLICATION ?? config.identity ?? saved.hash;
36
- const teamId = process.env.SPARK_TEAM_ID ?? config.teamId ?? saved.teamId;
35
+ const identity = process.env.SPARK_DEVELOPER_ID_APPLICATION ?? config.identity ?? (process.stdin.isTTY ? undefined : saved.hash);
36
+ const teamId = process.env.SPARK_TEAM_ID ?? config.teamId ?? (process.stdin.isTTY ? undefined : saved.teamId);
37
37
  const discovered = parseIdentities(await execute(root, ["security", "find-identity", "-v", "-p", "codesigning", ...(keychain ? [keychain] : [])], { capture: true }));
38
38
  const matches = chooseIdentity(discovered, identity, teamId);
39
- let selected = matches[0];
40
- if (matches.length > 1) {
41
- if (!process.stdin.isTTY)
42
- throw new Error("Multiple signing identities are available. Set SPARK_DEVELOPER_ID_APPLICATION or run spark credentials interactively.");
39
+ const defaultChoice = Math.max(0, matches.findIndex(item => item.hash === saved.hash)) + 1;
40
+ let selected = matches[defaultChoice - 1];
41
+ if (process.stdin.isTTY) {
42
+ console.log("Available Developer ID signing certificates:");
43
43
  console.log(matches.map((item, index) => `${index + 1}. ${item.name} [${item.hash}]`).join("\n"));
44
- const choice = Number(await ask("Signing identity: "));
44
+ const choice = Number(await ask(`Signing certificate [${defaultChoice}]: `) || String(defaultChoice));
45
45
  if (!Number.isInteger(choice) || choice < 1 || choice > matches.length)
46
46
  throw new Error("Invalid signing identity selection.");
47
47
  selected = matches[choice - 1];
48
48
  }
49
+ else if (matches.length > 1) {
50
+ throw new Error("Multiple signing identities are available. Set SPARK_DEVELOPER_ID_APPLICATION or run spark credentials interactively.");
51
+ }
49
52
  let keychainProfile = process.env.SPARK_NOTARY_KEYCHAIN_PROFILE ?? saved.keychainProfile;
50
- if (!keychainProfile) {
51
- if (!process.stdin.isTTY)
52
- throw new Error("Notarization is not configured. Set SPARK_NOTARY_KEYCHAIN_PROFILE or run spark credentials interactively.");
53
- keychainProfile = await ask("Existing notarization Keychain profile (Enter to create one): ");
54
- if (!keychainProfile) {
55
- keychainProfile = `spark-${selected.teamId}`;
56
- console.log(`Apple’s tool will store and validate notarization credentials in Keychain as ${keychainProfile}. Secret input is handled by notarytool and is not recorded by spark.`);
57
- const child = spawnProcess(["xcrun", "notarytool", "store-credentials", keychainProfile, ...(keychain ? ["--keychain", keychain] : [])], {
58
- stdin: "inherit", stdout: "inherit", stderr: "inherit",
59
- });
60
- if (await child.exited)
61
- throw new Error("Notarization credential setup failed. Run spark credentials to retry.");
53
+ let suggestedProfile = keychainProfile || `spark-${selected.teamId}`;
54
+ let result;
55
+ let validated = false;
56
+ let needsSelection = Boolean(process.stdin.isTTY);
57
+ while (!validated) {
58
+ if (needsSelection || !keychainProfile) {
59
+ if (!process.stdin.isTTY)
60
+ throw new Error("Notarization is not configured. Set SPARK_NOTARY_KEYCHAIN_PROFILE or run spark credentials interactively.");
61
+ const profiles = await listNotaryProfiles(root, keychain, execute);
62
+ const manualChoice = profiles.length + 1;
63
+ const createChoice = profiles.length + 2;
64
+ const rememberedChoice = profiles.indexOf(keychainProfile);
65
+ const defaultProfileChoice = rememberedChoice >= 0 ? rememberedChoice + 1 : profiles.length ? 1 : manualChoice;
66
+ console.log(`Available saved notarization Keychain profiles${keychain ? ` in ${keychain}` : ""}:`);
67
+ console.log(profiles.length ? profiles.map((profile, index) => `${index + 1}. ${profile}`).join("\n") : "No saved notarization profiles found.");
68
+ console.log(`${manualChoice}. Enter an existing profile name\n${createChoice}. Create a notarization Keychain profile`);
69
+ const choice = Number(await ask(`Notarization profile [${defaultProfileChoice}]: `) || String(defaultProfileChoice));
70
+ if (Number.isInteger(choice) && choice >= 1 && choice <= profiles.length) {
71
+ keychainProfile = profiles[choice - 1];
72
+ }
73
+ else if (choice === manualChoice) {
74
+ keychainProfile = await ask("Existing notarization Keychain profile: ");
75
+ if (!keychainProfile)
76
+ throw new Error("Enter an existing profile name or select the create option.");
77
+ }
78
+ else if (choice === createChoice) {
79
+ keychainProfile = await ask(`New notarization Keychain profile [${suggestedProfile}]: `) || suggestedProfile;
80
+ console.log(`Apple’s tool will store and validate notarization credentials in Keychain as ${keychainProfile}. Secret input is handled by notarytool and is not recorded by spark.`);
81
+ const child = spawnProcess(["xcrun", "notarytool", "store-credentials", keychainProfile, ...(keychain ? ["--keychain", keychain] : [])], {
82
+ stdin: "inherit", stdout: "inherit", stderr: "inherit",
83
+ });
84
+ if (await child.exited)
85
+ throw new Error("Notarization credential setup failed. Run spark credentials to retry.");
86
+ }
87
+ else {
88
+ throw new Error("Invalid notarization setup selection.");
89
+ }
90
+ needsSelection = false;
91
+ }
92
+ result = { ...selected, keychainProfile, ...(keychain ? { keychain } : {}) };
93
+ // Validate the Keychain profile before native compilation or signing.
94
+ try {
95
+ await execute(root, ["xcrun", "notarytool", "history", ...notaryAuth(result), "--output-format", "json"], { capture: true });
96
+ validated = true;
97
+ }
98
+ catch (error) {
99
+ if (error instanceof Error && error.message.includes("No Keychain password item found for profile:")) {
100
+ const message = `Notarization Keychain profile ${JSON.stringify(keychainProfile)} was not found${keychain ? ` in ${JSON.stringify(keychain)}` : ""}. A signing certificate name does not create a notarization profile.`;
101
+ if (!process.stdin.isTTY)
102
+ throw new Error(`${message} Run spark credentials interactively to select an existing profile or explicitly create one.`, { cause: error });
103
+ console.error(message);
104
+ suggestedProfile = keychainProfile;
105
+ keychainProfile = undefined;
106
+ needsSelection = true;
107
+ }
108
+ else {
109
+ throw error;
110
+ }
62
111
  }
63
112
  }
64
- const result = { ...selected, keychainProfile, ...(keychain ? { keychain } : {}) };
65
- // Validate the Keychain profile before native compilation or signing.
66
- await execute(root, ["xcrun", "notarytool", "history", ...notaryAuth(result), "--output-format", "json"], { capture: true });
67
113
  writeJson(file, result);
68
114
  return result;
69
115
  }
@@ -17,7 +17,16 @@ export function devArguments(args) {
17
17
  throw new Error("--no-open does not take a value");
18
18
  spark.noOpen = true;
19
19
  }
20
- else if (["--project", "--platform", "--runner-binary", "--prebuilt-binary", "--go-binary"].includes(key)) {
20
+ else if (key === "--app-arg") {
21
+ const value = inline.length ? inline.join("=") : args[++i];
22
+ if (value === undefined)
23
+ throw new Error("--app-arg needs a value");
24
+ (spark.appArgs ??= []).push(value);
25
+ }
26
+ else if (["--prebuilt-binary", "--go-binary"].includes(key)) {
27
+ throw new Error(`Unknown Spark option: ${key}; use --runner-binary`);
28
+ }
29
+ else if (["--project", "--platform", "--runner-binary"].includes(key)) {
21
30
  const value = inline.length ? inline.join("=") : args[++i];
22
31
  if (!value || value.startsWith("-"))
23
32
  throw new Error(`${key} needs a value`);
@@ -44,7 +53,7 @@ export async function devCommand(args) {
44
53
  const options = devArguments(args);
45
54
  const start = path.resolve(options.project ?? process.cwd());
46
55
  if (options.expo.includes("--help") || options.expo.includes("-h")) {
47
- console.log("spark dev options:\n --project <directory> Application directory\n --platform <platform> Initial launch target; all declared platforms stay available\n --runner-binary <path> Register and use a Spark Runner\n --no-open Wait for a launch key (explicit Expo launch flags still apply)\n\nAll other options belong to expo start:\n");
56
+ console.log("spark dev options:\n --project <directory> Application directory\n --platform <platform> Initial launch target; all declared platforms stay available\n --runner-binary <path> Register and use a Spark Runner\n --app-arg <value> Pass a desktop launch argument (repeatable)\n --no-open Wait for a launch key (explicit Expo launch flags still apply)\n\nAll other options belong to expo start:\n");
48
57
  const child = spawnProcess(nodeCommand(start, "expo", "expo", ["start", "--help"]), { cwd: start, stdin: "inherit", stdout: "inherit", stderr: "inherit" });
49
58
  process.exitCode = await child.exited;
50
59
  return;
@@ -58,7 +67,7 @@ export async function devCommand(args) {
58
67
  if (!options.noOpen && ["ios", "android", "web"].includes(initial))
59
68
  expo.push(`--${initial}`);
60
69
  if (desktop) {
61
- await dev(root, options.prebuiltBinary, expo, !!options.noOpen || initial !== desktop || (desktop === "windows" ? process.platform !== "win32" : process.platform !== "darwin"));
70
+ await dev(root, options.prebuiltBinary, expo, !!options.noOpen || initial !== desktop || (desktop === "windows" ? process.platform !== "win32" : process.platform !== "darwin"), options.appArgs);
62
71
  }
63
72
  else {
64
73
  if (options.prebuiltBinary)
@@ -2,7 +2,7 @@ import { installedRelease } from "./release.js";
2
2
  import { acquireRunner } from "./runner-install.js";
3
3
  import { spawnProcess } from "./process.js";
4
4
  import { windowsMetroPort, stopWindowsMetro } from "./windows-metro.js";
5
- import { projectPlatform } from "./platform.js";
5
+ import { architecture, projectPlatform } from "./platform.js";
6
6
  import { nodeCommand } from "./windows.js";
7
7
  import { readAppConfig } from "./project.js";
8
8
  import { existsSync, rmSync, watch } from "node:fs";
@@ -13,14 +13,16 @@ import { createRequire } from "node:module";
13
13
  const { preparePatch } = createRequire(import.meta.url)("./expo-dev-patch.cjs");
14
14
  import { findGo, readRuntime, registerRuntime } from "./local.js";
15
15
  import { sessionStatus } from "./session-status.js";
16
+ import { assertNativePatchPreflight } from "./native-patch-preflight.js";
16
17
  import { prepareConfig, dependencyStamp, goConfigurationIssues, incompatible, nativePackages, readJson, projectEnvironment, runtimeFor, stateFile, writeJson, } from "./project.js";
17
18
  export async function launch(root, app, port, options = {}) {
19
+ assertNativePatchPreflight(root);
18
20
  if (readRuntime(app)?.platform === "windows") {
19
21
  if (process.platform !== "win32")
20
22
  throw new Error("Launch the Windows runtime on Windows.");
21
23
  const nativePort = await windowsMetroPort(root, port ?? 8081, options);
22
24
  writeJson(stateFile(root, "windows-connection.json"), { port: nativePort, dev: options.dev ?? true });
23
- return spawnProcess([path.join(app, "MyApp.exe")], { cwd: app, env: { ...process.env, ...projectEnvironment(root), SPARK_METRO_PORT: String(nativePort), SPARK_SESSION_FILE: stateFile(root, "windows-connection.json") }, stdout: "inherit", stderr: "inherit" });
25
+ return spawnProcess([path.join(app, "MyApp.exe"), ...(options.args ?? [])], { cwd: app, env: { ...process.env, ...projectEnvironment(root), SPARK_METRO_PORT: String(nativePort), SPARK_SESSION_FILE: stateFile(root, "windows-connection.json") }, stdout: "inherit", stderr: "inherit" });
24
26
  }
25
27
  const info = await run(root, [
26
28
  "/usr/libexec/PlistBuddy",
@@ -34,7 +36,7 @@ export async function launch(root, app, port, options = {}) {
34
36
  // Direct executable launch retains the exact product path and process ownership.
35
37
  // RN's native packager websocket reads RCT_jsLocation independently of the
36
38
  // JS bundle URL. The process argument domain avoids persistent preference edits.
37
- return spawnProcess([executable, ...(port ? ["-RCT_jsLocation", `127.0.0.1:${port}`] : [])], {
39
+ return spawnProcess([executable, ...(port ? ["-RCT_jsLocation", `127.0.0.1:${port}`] : []), ...(options.args ?? [])], {
38
40
  cwd: root,
39
41
  env: {
40
42
  ...process.env,
@@ -49,7 +51,8 @@ export async function launch(root, app, port, options = {}) {
49
51
  stderr: "inherit",
50
52
  });
51
53
  }
52
- export async function dev(root, goApp, expoArgs = [], noOpen = false) {
54
+ export async function dev(root, goApp, expoArgs = [], noOpen = false, appArgs = []) {
55
+ assertNativePatchPreflight(root);
53
56
  const platform = projectPlatform(root);
54
57
  preparePatch(root);
55
58
  let port;
@@ -201,7 +204,7 @@ export async function dev(root, goApp, expoArgs = [], noOpen = false) {
201
204
  }
202
205
  issues.push(...goConfigurationIssues(readAppConfig(root)));
203
206
  }
204
- const view = sessionStatus(target, !!current, issues, appProcess?.exitCode === null, !!installedRelease()?.runners[`${platform}-${platform === "macos" ? "arm64" : process.arch}`]);
207
+ const view = sessionStatus(target, !!current, issues, appProcess?.exitCode === null, !!installedRelease()?.runners[`${platform}-${architecture(platform)}`]);
205
208
  if (view.compatible && current && appProcess?.exitCode === null &&
206
209
  (launchedRuntime?.app !== current.app || launchedRuntime.fingerprint !== current.runtime.fingerprint)) {
207
210
  // Discovery can find a different compatible binary after a native edit.
@@ -256,7 +259,7 @@ export async function dev(root, goApp, expoArgs = [], noOpen = false) {
256
259
  appProcess.kill();
257
260
  await appProcess.exited;
258
261
  }
259
- appProcess = await launch(root, current.app, port, bundleOptions);
262
+ appProcess = await launch(root, current.app, port, { ...bundleOptions, args: appArgs });
260
263
  if (closing) {
261
264
  appProcess.kill();
262
265
  return;
@@ -278,7 +281,7 @@ export async function dev(root, goApp, expoArgs = [], noOpen = false) {
278
281
  await appProcess.exited;
279
282
  }
280
283
  await open();
281
- writeJson(settingsFile, { target, goApp });
284
+ writeJson(settingsFile, { ...(existsSync(settingsFile) ? readJson(settingsFile) : {}), target, goApp });
282
285
  }
283
286
  else if (name === "build") {
284
287
  if ((await check()) || !canBuild)
@@ -294,7 +297,7 @@ export async function dev(root, goApp, expoArgs = [], noOpen = false) {
294
297
  target = "dev";
295
298
  restartPending = true;
296
299
  await open();
297
- writeJson(settingsFile, { target, goApp });
300
+ writeJson(settingsFile, { ...(existsSync(settingsFile) ? readJson(settingsFile) : {}), target, goApp });
298
301
  }
299
302
  else if (name === "open")
300
303
  await open();
@@ -401,7 +404,7 @@ export async function dev(root, goApp, expoArgs = [], noOpen = false) {
401
404
  finally {
402
405
  busy = false;
403
406
  }
404
- writeJson(settingsFile, { target, goApp });
407
+ writeJson(settingsFile, { ...(existsSync(settingsFile) ? readJson(settingsFile) : {}), target, goApp });
405
408
  await finished;
406
409
  process.off("SIGINT", close);
407
410
  process.off("SIGTERM", close);
@@ -18,7 +18,7 @@ export async function configureExample(root, example) {
18
18
  if (example !== "document-editor")
19
19
  pkg.dependencies["@react-native-async-storage/async-storage"] = "2.2.0";
20
20
  if (example === "music-lite")
21
- pkg.dependencies["expo-audio"] = "1.1.1";
21
+ pkg.dependencies["expo-audio"] = pkg.dependencies["expo-audio"] ?? pkg.overrides?.["expo-audio"] ?? pkg.resolutions?.["expo-audio"] ?? pkg.pnpm?.overrides?.["expo-audio"] ?? "1.1.1";
22
22
  if (example === "diff-lite")
23
23
  pkg.dependencies["diff"] = "8.0.2";
24
24
  writeJson(path.join(root, "package.json"), pkg);
@@ -15,8 +15,10 @@ const patches = [
15
15
  ' const onPressAsync = async (key)=>{',
16
16
  ` const onPressAsync = async (key)=>{\n try {\n if (await require(${extension}).handleKey(key)) return;\n } catch (error) {\n _log.exception(error);\n return;\n }`],
17
17
  ['startAsync.js', '0e062078e63ad6264b1393d403ad56d65a38c6430d30fdac50cd656486cd418b',
18
- ' mcpServer == null ? void 0 : mcpServer.start();',
19
- ` mcpServer == null ? void 0 : mcpServer.start();\n require(${extension}).ready(devServerManager.getNativeDevServerPort(), { dev: options.dev, minify: options.minify, https: options.https });`],
18
+ ' await (0, _profile.profile)(devServerManager.startAsync.bind(devServerManager))(startOptions);',
19
+ // Dependency validation can wait on the network after Metro is listening.
20
+ // Report actual server readiness before those optional startup checks.
21
+ ` await (0, _profile.profile)(devServerManager.startAsync.bind(devServerManager))(startOptions);\n require(${extension}).ready(devServerManager.getNativeDevServerPort(), { dev: options.dev, minify: options.minify, https: options.https });`],
20
22
  ];
21
23
 
22
24
  function preparePatch(root) {
@@ -19,7 +19,7 @@ exports.withSparkMetro = config => {
19
19
  if (config && typeof config.then === 'function') return config.then(exports.withSparkMetro);
20
20
  if (!config || typeof config !== 'object') throw new Error('Spark needs an object or promise from metro.config');
21
21
  const upstream = defaults.get(path.resolve(config.projectRoot || process.cwd()));
22
- if (!upstream) throw new Error('Compose Metro with getDefaultConfig from @legendapp/spark-cli/src/expo-metro.cjs');
22
+ if (!upstream) throw new Error('Compose Metro with getDefaultConfig from @legendapp/spark/metro');
23
23
  const customResolve = config.resolver?.resolveRequest;
24
24
  if (customResolve && customResolve !== upstream.resolveRequest) {
25
25
  const desktopResolve = upstream.resolveRequest;
@@ -2,7 +2,7 @@ import { spawnProcess, which } from "./process.js";
2
2
  import { createRequire } from "node:module";
3
3
  import path from "node:path";
4
4
  import { pathToFileURL } from "node:url";
5
- /** Check the actual Node/Expo pair before handing work to Expo Desktop beta. */
5
+ /** Check the actual Node/Expo pair before handing work to Expo Desktop. */
6
6
  export async function checkExpoDesktopNode(root) {
7
7
  const requireApp = createRequire(path.join(root, "package.json"));
8
8
  const requireDesktop = createRequire(requireApp.resolve("expo-desktop/package.json"));
@@ -10,12 +10,12 @@ export async function checkExpoDesktopNode(root) {
10
10
  const node = which("node");
11
11
  if (!node)
12
12
  throw new Error("Missing node. Install Node 24.19.0 (the version in .nvmrc), then retry.");
13
- // Use the same static named imports as beta.5. Older Node releases cannot
13
+ // Use the static named imports used by Expo Desktop. Older Node releases cannot
14
14
  // discover these exports in Expo's Babel-generated CommonJS modules.
15
15
  const child = spawnProcess([node, "--input-type=module", "-e",
16
16
  `import { AndroidConfig, IOSConfig } from ${JSON.stringify(configPlugins)}; if (!AndroidConfig || !IOSConfig) throw new Error('Missing Expo config exports');`,
17
17
  ], { cwd: root, stdout: "ignore", stderr: "pipe" });
18
18
  const [stderr, code] = await Promise.all([new Response(child.stderr).text(), child.exited]);
19
19
  if (code !== 0)
20
- throw new Error(`Expo Desktop beta could not load its config plugins using ${node}. Use Node 24.19.0 (nvm install && nvm use from the framework checkout), then retry. Node 24.12.0 cannot import these CommonJS named exports.\n${stderr.trim()}`);
20
+ throw new Error(`Expo Desktop could not load its config plugins using ${node}. Use Node 24.19.0 (nvm install && nvm use from the framework checkout), then retry. Node 24.12.0 cannot import these CommonJS named exports.\n${stderr.trim()}`);
21
21
  }
@@ -4,7 +4,7 @@ import { prepareGoProfile } from "./go-profile.js";
4
4
  import { exportSDK, importSDK } from "./sdk-transfer.js";
5
5
  import { hostPlatform } from "./platform.js";
6
6
  import path from "node:path";
7
- import { parseArgs } from "node:util";
7
+ import { cliArguments } from "./cli-arguments.js";
8
8
  import { existsSync, readFileSync, writeFileSync } from "node:fs";
9
9
  import { prepareConfig, readConfig, isExpoProject } from "@legendapp/spark-desktop-config/config.cjs";
10
10
  import { nodeCommand, prepareWindows } from "./windows.js";
@@ -24,33 +24,7 @@ async function main() {
24
24
  const argv = process.argv.slice(2);
25
25
  if (argv[0] === "dev")
26
26
  return devCommand(argv.slice(1));
27
- const { positionals, values } = parseArgs({
28
- args: argv,
29
- allowPositionals: true,
30
- options: {
31
- example: { type: "string" },
32
- "package-manager": { type: "string" },
33
- runtime: { type: "string", multiple: true },
34
- universal: { type: "boolean" },
35
- device: { type: "string" },
36
- project: { type: "string" },
37
- platform: { type: "string" },
38
- packages: { type: "string" },
39
- port: { type: "string" },
40
- runner: { type: "boolean" },
41
- prebuilt: { type: "boolean" },
42
- go: { type: "boolean" }, // Legacy desktop build alias; dev --go belongs to Expo.
43
- dev: { type: "boolean" },
44
- release: { type: "boolean" },
45
- preview: { type: "boolean" },
46
- force: { type: "boolean" },
47
- "no-open": { type: "boolean" },
48
- "submission-id": { type: "string" },
49
- help: { type: "boolean", short: "h" },
50
- },
51
- });
52
- if (values.platform && !["macos", "windows", "ios", "android", "web"].includes(values.platform))
53
- throw new Error("Platform must be macos, windows, ios, android, or web.");
27
+ const { positionals, values } = cliArguments(argv);
54
28
  if (values.platform)
55
29
  process.env.SPARK_PLATFORM = values.platform;
56
30
  const platform = (values.platform ?? hostPlatform());
@@ -58,25 +32,25 @@ async function main() {
58
32
  const start = path.resolve(projectOption ?? process.cwd());
59
33
  const project = () => findProject(start);
60
34
  const port = values.port === undefined ? undefined : Number(values.port);
61
- if (port !== undefined && (!Number.isInteger(port) || port < 1 || port > 65535))
62
- throw new Error("Port must be an integer between 1 and 65535.");
63
35
  const command = positionals[0];
64
36
  if (!values.help && !values.platform && !(command === "open" && positionals[1]) && ["build", "prebuild", "analyze", "package", "open", "updates", "credentials"].includes(command ?? "") && isExpoProject(project())) {
65
37
  process.env.SPARK_PLATFORM = readConfig(project()).expo.platforms[0];
66
38
  }
67
39
  if (values.example && (command !== "create" || !examples.includes(values.example)))
68
40
  throw new Error(`Use create --example ${examples.join(" | ")}`);
69
- if (values.universal && command !== "create")
70
- throw new Error("--universal is a create option.");
71
41
  if (!values.help && ["build", "prebuild"].includes(command ?? "")) {
72
42
  const root = project();
73
43
  const selected = readConfig(root).expo.platforms[0];
44
+ if (!["ios", "android", "web"].includes(selected) && (values.device || values.port))
45
+ throw new Error("--device and --port are mobile build options; use spark dev for desktop launch options.");
74
46
  if (["ios", "android", "web"].includes(selected)) {
47
+ if (values.force)
48
+ throw new Error("--force is a desktop build option.");
75
49
  if (command === "build" && selected === "web")
76
50
  throw new Error("Use expo export --platform web for web production output.");
77
51
  if (command === "prebuild" && selected === "web")
78
52
  throw new Error("Web has no native project to prebuild.");
79
- if (values.runner || values.prebuilt || values.go || values.release || values.preview || (command === "build" && !values.dev))
53
+ if (values.runner || values.release || values.preview || (command === "build" && !values.dev))
80
54
  throw new Error("Mobile builds use --dev in this slice; Expo owns mobile distribution workflows.");
81
55
  prepareConfig(root);
82
56
  const args = command === "prebuild" ? ["prebuild", "--platform", selected, "--no-install"] : [`run:${selected}`, ...(values.device ? ["--device", values.device] : []), ...(port ? ["--port", String(port)] : [])];
@@ -125,7 +99,7 @@ Overrides: --project <directory>, --port <number>, dev --runner-binary <runtime
125
99
  case "create": {
126
100
  if (!positionals[1])
127
101
  throw new Error("Usage: spark create MyApp");
128
- if (!values.universal && !["macos", "windows"].includes(platform))
102
+ if (!(values.universal || values.example) && !["macos", "windows"].includes(platform))
129
103
  throw new Error("Use create --universal for mobile/web targets");
130
104
  await create(path.resolve(positionals[1]), creationManifest(values.packages), platform, !!values.universal || !!values.example, values.example, values["package-manager"]);
131
105
  break;
@@ -169,8 +143,6 @@ Overrides: --project <directory>, --port <number>, dev --runner-binary <runtime
169
143
  process.exitCode = 2;
170
144
  break;
171
145
  }
172
- case "build-go": // Legacy alias; persisted runtime metadata still uses "go".
173
- case "build-prebuilt": // Legacy command alias.
174
146
  case "build-runner": {
175
147
  let root;
176
148
  if (projectOption)
@@ -216,8 +188,8 @@ Overrides: --project <directory>, --port <number>, dev --runner-binary <runtime
216
188
  console.log("Signing credentials configured. Run spark package to prepare a distribution archive.");
217
189
  break;
218
190
  case "package": {
219
- if (process.platform !== "darwin" || process.arch !== "arm64")
220
- throw new Error("Packaging currently supports Apple Silicon macOS only.");
191
+ if (process.platform !== "darwin")
192
+ throw new Error("macOS packaging requires macOS.");
221
193
  const result = await packageApp(project(), { force: !!values.force, submissionId: values["submission-id"] });
222
194
  if (result.pending)
223
195
  process.exitCode = 2;
@@ -35,7 +35,7 @@ export function readRuntime(app) {
35
35
  try {
36
36
  const windows = existsSync(path.join(app, "spark-runtime.json"));
37
37
  const runtime = readJson(path.join(app, windows ? "spark-runtime.json" : "Contents/Resources/spark-runtime.json"));
38
- if (runtime.schema !== 1 || runtime.framework !== VERSION || !["macos", "windows"].includes(runtime.platform) || !(runtime.platform === "windows" ? ["arm64", "x64"] : ["arm64"]).includes(runtime.arch) || !runtime.modules || typeof runtime.modules !== "object" || typeof runtime.fingerprint !== "string")
38
+ if (runtime.schema !== 1 || runtime.framework !== VERSION || !["macos", "windows"].includes(runtime.platform) || !["arm64", "x64"].includes(runtime.arch) || !runtime.modules || typeof runtime.modules !== "object" || typeof runtime.fingerprint !== "string")
39
39
  return undefined;
40
40
  if (!existsSync(path.join(app, windows ? "MyApp.exe" : "Contents/MacOS")) || windows !== (runtime.platform === "windows"))
41
41
  return undefined;
@@ -16,6 +16,11 @@ function runtimePlan(root, env = process.env) {
16
16
  .map(e => e.name).concat(["src"]) };
17
17
  }
18
18
  function withDesktop(config, options = {}) {
19
+ if (!options || typeof options !== "object" || Array.isArray(options)) throw new Error("Expected desktop Metro options");
20
+ for (const [key, value] of Object.entries(options)) {
21
+ if (!["runtimes", "watch"].includes(key)) throw new Error(`Unknown desktop Metro option: ${key}`);
22
+ if (value !== undefined && typeof value !== "boolean") throw new Error(`${key} must be boolean`);
23
+ }
19
24
  // Expo 54 sets the react-native export condition only for iOS/Android.
20
25
  // Desktop must also select native package exports (e.g. Uniwind's runtime).
21
26
  const conditions = { ...config.resolver?.unstable_conditionsByPlatform };
@@ -24,10 +29,26 @@ function withDesktop(config, options = {}) {
24
29
  }
25
30
  config = { ...config, resolver: { ...config.resolver, unstable_conditionsByPlatform: conditions } };
26
31
  const root = path.resolve(config.projectRoot || process.cwd());
27
- // Prebuilt hosts request /index.bundle and /.threaded-runtime/entry.bundle.
28
- // Keep those URLs relative to the app inside a monorepo; Expo still discovers
29
- // workspace watch folders and package dependencies.
30
- config = { ...config, server: { ...config.server, unstable_serverRoot: root } };
32
+ // Keep the configured workspace root so lazy imports outside the app have
33
+ // valid URLs. Only the prebuilt host's fixed entry URLs are app-relative.
34
+ const serverRoot = path.resolve(config.server?.unstable_serverRoot || root);
35
+ const entryPrefix = path.relative(serverRoot, root).split(path.sep).map(encodeURIComponent).join("/");
36
+ if (entryPrefix && (entryPrefix === ".." || entryPrefix.startsWith("../"))) {
37
+ throw new Error("Metro's server root must contain the Spark project");
38
+ }
39
+ const rewrite = config.server?.rewriteRequestUrl;
40
+ config = { ...config, server: { ...config.server, unstable_serverRoot: serverRoot,
41
+ rewriteRequestUrl(value) {
42
+ const url = new URL(value, "http://localhost");
43
+ const platform = url.searchParams.get("platform");
44
+ if (entryPrefix && (!platform || ["macos", "windows"].includes(platform)) &&
45
+ /^\/(index|\.threaded-runtime\/entry)\.(bundle|map|delta)$/.test(url.pathname)) {
46
+ url.pathname = `/${entryPrefix}${url.pathname}`;
47
+ value = value.startsWith("/") ? `${url.pathname}${url.search}${url.hash}` : url.href;
48
+ }
49
+ return rewrite ? rewrite(value) : value;
50
+ },
51
+ } };
31
52
  let core;
32
53
  try { core = require.resolve("@react-native-runtimes/core/metro", { paths: [root] }); } catch {}
33
54
  if (!core || options.runtimes === false) {
@@ -40,7 +61,7 @@ function withDesktop(config, options = {}) {
40
61
  const plan = runtimePlan(root);
41
62
  const generatedEntry = path.join(root, ".threaded-runtime/entry.js");
42
63
  if (plan.enabled) {
43
- config = withThreadedRuntime(config, { ...options, roots: plan.roots, watch: plan.production ? false : options.watch });
64
+ config = withThreadedRuntime(config, { roots: plan.roots, watch: plan.production ? false : options.watch });
44
65
  // Production roots come from Metro's resolved graph, including worker files
45
66
  // shipped by dependencies. Do not register unrelated index.<name>.ts files.
46
67
  if (plan.production) generateThreadedRuntimeEntry({ projectRoot: root, generatedEntry, roots: plan.roots, runtimeEntries: [] });
@@ -0,0 +1,26 @@
1
+ import { existsSync, readdirSync, writeFileSync } from "node:fs";
2
+ import path from "node:path";
3
+ import { run } from "./commands.js";
4
+ import { createRequire } from "node:module";
5
+ const { identity } = createRequire(import.meta.url)("@legendapp/spark-desktop-config/identity.cjs");
6
+ /** Restore app-owned values after Expo Desktop's template string replacement. */
7
+ export async function restoreNativeMetadata(root, config, execute = run) {
8
+ const overrides = { ...config.macos?.infoPlist, ...identity(config) };
9
+ const nativeRoot = path.join(root, "macos");
10
+ const matches = [];
11
+ for (const entry of readdirSync(nativeRoot, { withFileTypes: true })) {
12
+ if (!entry.isDirectory())
13
+ continue;
14
+ const file = path.join(nativeRoot, entry.name, "Info.plist");
15
+ if (!existsSync(file))
16
+ continue;
17
+ const info = JSON.parse(await execute(root, ["plutil", "-convert", "json", "-o", "-", file], { capture: true }));
18
+ if ("SparkProjectIdentifier" in info)
19
+ matches.push({ file, info });
20
+ }
21
+ if (matches.length !== 1)
22
+ throw new Error(`Expected one generated Spark Info.plist, found ${matches.length}`);
23
+ const { file, info } = matches[0];
24
+ writeFileSync(file, JSON.stringify({ ...info, ...overrides }));
25
+ await execute(root, ["plutil", "-convert", "xml1", file], { capture: true });
26
+ }
@@ -0,0 +1,84 @@
1
+ import { createHash } from "node:crypto";
2
+ import { existsSync, readFileSync } from "node:fs";
3
+ import path from "node:path";
4
+ import { findFramework } from "./local.js";
5
+ import { installedPackages, readJson, VERSION } from "./project.js";
6
+ const required = ["@react-native-runtimes/core", "react-native-nitro-modules", "@op-engineering/op-sqlite", "react-native-webview"];
7
+ const optional = ["expo-audio"];
8
+ export function validatePackedNativePatches(packages, requirements, frameworkVersion = VERSION) {
9
+ if (!requirements || requirements.schema !== 1 || requirements.frameworkVersion !== frameworkVersion || !requirements.packages || typeof requirements.packages !== "object")
10
+ return [`The installed @legendapp/spark SDK does not include native patch provenance for ${frameworkVersion}. Run spark add desktop to install the matching SDK packages, then retry.`];
11
+ const installed = new Map(packages.map(pkg => [pkg.name, pkg.json]));
12
+ const errors = [];
13
+ for (const name of required)
14
+ if (!installed.has(name))
15
+ errors.push(`${name} is missing; reinstall the dependencies from this Spark SDK.`);
16
+ for (const name of [...required, ...optional]) {
17
+ const actual = installed.get(name);
18
+ if (!actual)
19
+ continue;
20
+ const expected = requirements.packages[name];
21
+ const spark = actual.spark;
22
+ if (!expected || typeof expected.version !== "string" || !/^[a-f0-9]{64}$/.test(expected.patchHash) ||
23
+ (!expected.upstreamIntegrity && !expected.upstreamRevision) || actual.version !== expected.version || spark?.sdk !== true || spark.patchHash !== expected.patchHash ||
24
+ spark.upstreamIntegrity !== expected.upstreamIntegrity || spark.upstreamRevision !== expected.upstreamRevision) {
25
+ errors.push(`${name}@${actual.version} is not the matching patched Spark SDK package.`);
26
+ }
27
+ }
28
+ return errors;
29
+ }
30
+ export function validateWorkspaceNativePatches(root, packages) {
31
+ const framework = findFramework(root);
32
+ if (!framework)
33
+ return ["The Spark SDK is missing native patch provenance. Run spark add desktop to install matching SDK packages, then retry."];
34
+ const frameworkPackage = readJson(path.join(framework, "package.json"));
35
+ const map = frameworkPackage.sparkWorkspacePatches;
36
+ if (!map)
37
+ return ["The Spark workspace has no install-time patch inventory. Run npm run postinstall in the framework checkout, then retry."];
38
+ const pins = readJson(path.join(framework, "patches/workspace/upstream.json"));
39
+ const installed = new Map(packages.map(pkg => [pkg.name, pkg]));
40
+ const errors = [];
41
+ for (const name of [...required, ...optional]) {
42
+ const pkg = installed.get(name);
43
+ if (!pkg) {
44
+ if (required.includes(name))
45
+ errors.push(`${name} is missing; reinstall the dependencies from this Spark workspace.`);
46
+ continue;
47
+ }
48
+ const entry = Object.entries(map).find(([key]) => key.slice(0, key.lastIndexOf("@")) === name);
49
+ const pin = pins[name];
50
+ if (!entry || !pin || !entry[0].endsWith(`@${pin.version}`) || pkg.json.version !== pin.version) {
51
+ errors.push(`${name}@${pkg.json.version} does not match the Spark workspace patch inventory.`);
52
+ continue;
53
+ }
54
+ const patchFile = path.resolve(framework, entry[1]);
55
+ if (!patchFile.startsWith(framework + path.sep) || !existsSync(patchFile)) {
56
+ errors.push(`${name} has no readable Spark workspace patch. Run npm run postinstall in the framework checkout.`);
57
+ continue;
58
+ }
59
+ const patchHash = createHash("sha256").update(readFileSync(patchFile)).digest("hex");
60
+ const receipt = pkg.json.spark?.workspacePatch;
61
+ const expectedRevision = pin.revision;
62
+ if (!receipt || receipt.schema !== 1 || receipt.version !== pin.version || receipt.patchHash !== patchHash ||
63
+ receipt.upstreamIntegrity !== pin.integrity || (expectedRevision && receipt.upstreamRevision !== expectedRevision)) {
64
+ errors.push(`${name}@${pkg.json.version} has no matching applied workspace patch stamp. Run npm run postinstall in the framework checkout, then retry.`);
65
+ }
66
+ }
67
+ return errors;
68
+ }
69
+ export function assertNativePatchPreflight(root) {
70
+ const packages = installedPackages(root);
71
+ const framework = findFramework(root);
72
+ let errors;
73
+ const spark = packages.find(pkg => pkg.name === "@legendapp/spark");
74
+ const requirements = spark?.json.spark?.nativePatchRequirements;
75
+ if (requirements)
76
+ errors = validatePackedNativePatches(packages, requirements);
77
+ else if (framework)
78
+ errors = validateWorkspaceNativePatches(root, packages);
79
+ else {
80
+ errors = validatePackedNativePatches(packages, requirements);
81
+ }
82
+ if (errors.length)
83
+ throw new Error(`Native preparation stopped before changing project files:\n${errors.map(error => `- ${error}`).join("\n")}`);
84
+ }