peachsim 0.1.939 → 0.1.1399

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 (396) hide show
  1. package/README.md +28 -22
  2. package/cli/app-catalog.ts +29 -14
  3. package/cli/app-fonts.ts +5 -3
  4. package/cli/bridge-flow-runner.ts +40 -29
  5. package/cli/cloud-client.ts +57 -21
  6. package/cli/cloud-test-tunnel.ts +12 -18
  7. package/cli/commands/agent.ts +1 -1
  8. package/cli/commands/app-fonts.ts +3 -3
  9. package/cli/commands/assert.ts +8 -8
  10. package/cli/commands/auth.ts +8 -3
  11. package/cli/commands/box/bundle-plane.ts +13 -1
  12. package/cli/commands/box.ts +16 -5
  13. package/cli/commands/compat.ts +1 -1
  14. package/cli/commands/config.ts +2 -2
  15. package/cli/commands/control.ts +125 -71
  16. package/cli/commands/cpu-profile.ts +45 -1
  17. package/cli/commands/daemon.ts +131 -33
  18. package/cli/commands/debug.ts +24 -17
  19. package/cli/commands/desktop.ts +7 -1
  20. package/cli/commands/detect.ts +101 -0
  21. package/cli/commands/detox.ts +6 -6
  22. package/cli/commands/device.ts +12 -12
  23. package/cli/commands/electron.ts +32 -14
  24. package/cli/commands/flow.ts +49 -41
  25. package/cli/commands/guest-host.ts +39 -1
  26. package/cli/commands/inspect/core.ts +14 -8
  27. package/cli/commands/inspect/list.ts +1 -1
  28. package/cli/commands/inspect/settle.ts +5 -3
  29. package/cli/commands/inspect/settling.ts +229 -44
  30. package/cli/commands/inspect/wait-idle.ts +3 -2
  31. package/cli/commands/inspect.ts +105 -93
  32. package/cli/commands/install-cli.ts +36 -15
  33. package/cli/commands/install-desktop.ts +68 -195
  34. package/cli/commands/kotlin.ts +6 -5
  35. package/cli/commands/login.ts +5 -5
  36. package/cli/commands/maestro-compare.ts +554 -0
  37. package/cli/commands/maestro-generate.ts +6 -3
  38. package/cli/commands/maestro.ts +22 -0
  39. package/cli/commands/mode.ts +2 -2
  40. package/cli/commands/no-bridge-hint.ts +6 -2
  41. package/cli/commands/platform.ts +35 -6
  42. package/cli/commands/preview.ts +6 -0
  43. package/cli/commands/project-report.ts +10 -12
  44. package/cli/commands/record.ts +37 -37
  45. package/cli/commands/runtime.ts +9 -9
  46. package/cli/commands/screenshot-layers.ts +4 -4
  47. package/cli/commands/screenshot-mode.ts +2 -2
  48. package/cli/commands/screenshot.ts +8 -8
  49. package/cli/commands/screenshots-capture.ts +2 -2
  50. package/cli/commands/serve.ts +9 -12
  51. package/cli/commands/setup.ts +29 -14
  52. package/cli/commands/shell-boolean-mode.ts +2 -2
  53. package/cli/commands/show-touches-mode.ts +2 -2
  54. package/cli/commands/skills.ts +11 -11
  55. package/cli/commands/swift.ts +29 -11
  56. package/cli/commands/telemetry.ts +2 -2
  57. package/cli/commands/test.ts +5 -0
  58. package/cli/commands/three-mode.ts +3 -3
  59. package/cli/commands/timeline.ts +4 -4
  60. package/cli/commands/upgrade.ts +2 -2
  61. package/cli/commands/upload.ts +15 -15
  62. package/cli/commands/what-happened.ts +2 -2
  63. package/cli/current-sim.ts +6 -3
  64. package/cli/desktop-companion.ts +55 -149
  65. package/cli/dev-build-freshness.ts +2 -2
  66. package/cli/drivers/desktop.ts +17 -9
  67. package/cli/drivers/electron.ts +1 -2
  68. package/cli/drivers/playwright-sim-host.ts +11 -2
  69. package/cli/drivers/playwright.ts +35 -2
  70. package/cli/drivers/types.ts +8 -0
  71. package/cli/maestro-compare.ts +670 -0
  72. package/cli/outbound-endpoints.ts +46 -8
  73. package/cli/recording-access.ts +6 -6
  74. package/cli/run-registry.ts +1 -1
  75. package/cli/runtime-compat.ts +5 -1
  76. package/cli/send-to-box.ts +3 -3
  77. package/cli/shell-init.ts +2 -1
  78. package/cli/ws-bridge.ts +9 -5
  79. package/detox/element-types.ts +1 -0
  80. package/detox/gestures.ts +3 -3
  81. package/detox/index.ts +67 -38
  82. package/detox/navigation-lifecycle.ts +9 -6
  83. package/detox/proof-frame.cjs +6 -4
  84. package/dist-lib/agent-daemon-client.cjs +1 -1
  85. package/dist-lib/agent-events.cjs +1 -1
  86. package/dist-lib/attached-projects.cjs +1 -1
  87. package/dist-lib/auth/shared-session.cjs +1 -1
  88. package/dist-lib/backend-origin.cjs +1 -1
  89. package/dist-lib/beta.cjs +1 -1
  90. package/dist-lib/beta.mjs +1 -1
  91. package/dist-lib/bridge-constants.cjs +1 -1
  92. package/dist-lib/bridge-contract-input.cjs +42 -17
  93. package/dist-lib/bridge-contract-input.mjs +41 -16
  94. package/dist-lib/bridge-contract.cjs +1 -4
  95. package/dist-lib/bridge-contract.mjs +1 -3
  96. package/dist-lib/bundle-channel.cjs +2918 -550
  97. package/dist-lib/capture-contract.cjs +65 -24
  98. package/dist-lib/capture-contract.mjs +63 -24
  99. package/dist-lib/cloud-contract.cjs +2 -2
  100. package/dist-lib/cloud-contract.mjs +2 -2
  101. package/dist-lib/cloud-test-args.cjs +1 -1
  102. package/dist-lib/cloud-test-args.mjs +1 -1
  103. package/dist-lib/cloud.cjs +3 -3
  104. package/dist-lib/cloud.mjs +3 -3
  105. package/dist-lib/config.cjs +15 -5
  106. package/dist-lib/config.mjs +154 -0
  107. package/dist-lib/detox/index.cjs +495 -139
  108. package/dist-lib/dev-bundle-resolution.cjs +1 -1
  109. package/dist-lib/expo-swift-bundle.cjs +1168 -238
  110. package/dist-lib/expo-swift-metadata.cjs +34 -23
  111. package/dist-lib/expo-swift-metadata.mjs +32 -23
  112. package/dist-lib/home-paths.cjs +2 -2
  113. package/dist-lib/host/bridge-host.cjs +2938 -654
  114. package/dist-lib/host/fetch-proxy-handler.cjs +14 -1
  115. package/dist-lib/host/fetch-proxy-overrides.cjs +7 -1
  116. package/dist-lib/host/fetch-proxy-overrides.mjs +5 -1
  117. package/dist-lib/host/replacement-module-handler.cjs +2 -2
  118. package/dist-lib/host/websocket-proxy.cjs +1 -1
  119. package/dist-lib/index.cjs +999 -353
  120. package/dist-lib/jump-to-source-babel.cjs +1 -1
  121. package/dist-lib/jump-to-source-native.cjs +1 -1
  122. package/dist-lib/kotlin-host.cjs +332 -19
  123. package/dist-lib/menu.cjs +1 -1
  124. package/dist-lib/menu.mjs +1 -1
  125. package/dist-lib/metro-fingerprint-registry.cjs +1 -1
  126. package/dist-lib/metro-fingerprint-registry.mjs +1 -1
  127. package/dist-lib/metro-production-bundle.cjs +7 -7
  128. package/dist-lib/metro-production-bundle.mjs +5 -5
  129. package/dist-lib/metro.cjs +688 -250
  130. package/dist-lib/native-app-identity-project.cjs +2647 -0
  131. package/dist-lib/native-app-identity-project.mjs +1257 -0
  132. package/dist-lib/native-app-identity.cjs +325 -25
  133. package/dist-lib/native-app-identity.mjs +323 -25
  134. package/dist-lib/native-firebase-metadata.cjs +1 -1
  135. package/dist-lib/native-firebase-metadata.mjs +1 -1
  136. package/dist-lib/plist.cjs +1 -1
  137. package/dist-lib/plist.mjs +1 -1
  138. package/dist-lib/profiles.cjs +1 -1
  139. package/dist-lib/public-brand.cjs +1 -1
  140. package/dist-lib/react-native-host-modules.cjs +5 -1
  141. package/dist-lib/react-native-host-modules.mjs +5 -1
  142. package/dist-lib/scripts/dev-server-scanner.cjs +57 -32
  143. package/dist-lib/sdk.cjs +231 -51
  144. package/dist-lib/sdk.mjs +231 -51
  145. package/dist-lib/skills.cjs +4107 -1374
  146. package/dist-lib/swift-compile.cjs +290 -30
  147. package/dist-lib/swift-compile.mjs +290 -30
  148. package/dist-lib/swift-package.cjs +143 -12
  149. package/dist-lib/swift-package.mjs +137 -11
  150. package/dist-lib/swift-submit.cjs +47 -5
  151. package/dist-lib/swift-submit.mjs +42 -5
  152. package/dist-lib/swift-toolchain.cjs +7 -2
  153. package/dist-lib/swift.cjs +1 -1
  154. package/dist-lib/vite-swift.cjs +1392 -458
  155. package/dist-lib/vite.cjs +13 -17
  156. package/dist-lib/worklet-executable.cjs +248 -33
  157. package/dist-lib/worklet-executable.mjs +248 -33
  158. package/install.sh +10 -1
  159. package/kotlin/{AppSources → AndroidViewSources}/android/content/res/Resources.kt +9 -9
  160. package/kotlin/AndroidViewSources/android/graphics/Canvas.kt +20 -0
  161. package/kotlin/AndroidViewSources/android/view/View.kt +211 -0
  162. package/kotlin/AndroidViewSources/android/widget/FrameLayout.kt +61 -0
  163. package/kotlin/AndroidViewSources/android/widget/LinearLayout.kt +49 -0
  164. package/kotlin/AppSources/android/view/Window.kt +36 -0
  165. package/kotlin/AppSources/android/view/WindowInsets.kt +9 -0
  166. package/kotlin/AppSources/android/view/WindowInsetsController.kt +5 -0
  167. package/kotlin/AppSources/android/window/OnBackInvokedDispatcher.kt +48 -0
  168. package/kotlin/AppSources/androidx/activity/OnBackPressedDispatcher.kt +20 -5
  169. package/kotlin/AppSources/androidx/compose/foundation/layout/WindowInsets.kt +15 -0
  170. package/kotlin/AppSources/androidx/compose/ui/platform/ComposeView.kt +2 -1
  171. package/kotlin/AppSources/dev/peach/app/PeachApp.kt +42 -50
  172. package/kotlin/ComposeSources/PeachComposeHost.kt +200 -84
  173. package/kotlin/ExpoComposeSources/PeachAndroidView.kt +87 -0
  174. package/kotlin/ExpoComposeSources/PeachExpoViewMount.kt +24 -0
  175. package/kotlin/ExpoComposeSources/dev/peach/expo/PeachExpoCompose.kt +28 -0
  176. package/kotlin/ExpoComposeSources/expo/modules/kotlin/views/ExpoComposeView.kt +70 -0
  177. package/kotlin/ExpoSources/dev/peach/expo/PeachExpoRuntime.kt +513 -0
  178. package/kotlin/ExpoSources/dev/peach/expo/PeachExpoTypes.kt +173 -0
  179. package/kotlin/ExpoSources/expo/modules/kotlin/AppContext.kt +20 -0
  180. package/kotlin/ExpoSources/expo/modules/kotlin/Promise.kt +19 -0
  181. package/kotlin/ExpoSources/expo/modules/kotlin/classcomponent/ClassComponentBuilder.kt +198 -0
  182. package/kotlin/ExpoSources/expo/modules/kotlin/exception/CodedException.kt +126 -0
  183. package/kotlin/ExpoSources/expo/modules/kotlin/functions/Functions.kt +132 -0
  184. package/kotlin/ExpoSources/expo/modules/kotlin/jni/JavaScriptTypedArray.kt +81 -0
  185. package/kotlin/ExpoSources/expo/modules/kotlin/modules/Module.kt +98 -0
  186. package/kotlin/ExpoSources/expo/modules/kotlin/objects/ObjectDefinitionBuilder.kt +236 -0
  187. package/kotlin/ExpoSources/expo/modules/kotlin/records/Record.kt +12 -0
  188. package/kotlin/ExpoSources/expo/modules/kotlin/runtime/Runtime.kt +9 -0
  189. package/kotlin/ExpoSources/expo/modules/kotlin/sharedobjects/SharedObject.kt +50 -0
  190. package/kotlin/ExpoSources/expo/modules/kotlin/sharedobjects/SharedObjectRegistry.kt +57 -0
  191. package/kotlin/ExpoSources/expo/modules/kotlin/sharedobjects/SharedRef.kt +19 -0
  192. package/kotlin/ExpoSources/expo/modules/kotlin/typedarray/ConcreteTypedArrays.kt +158 -0
  193. package/kotlin/ExpoSources/expo/modules/kotlin/typedarray/GenericTypedArray.kt +8 -0
  194. package/kotlin/ExpoSources/expo/modules/kotlin/typedarray/TypedArray.kt +29 -0
  195. package/kotlin/ExpoSources/expo/modules/kotlin/typedarray/TypedArrayIterator.kt +9 -0
  196. package/kotlin/ExpoSources/expo/modules/kotlin/types/AnyType.kt +155 -0
  197. package/kotlin/ExpoSources/expo/modules/kotlin/types/Either.kt +91 -0
  198. package/kotlin/ExpoSources/expo/modules/kotlin/types/Enumerable.kt +6 -0
  199. package/kotlin/ExpoSources/expo/modules/kotlin/viewevent/ViewEvent.kt +54 -0
  200. package/kotlin/ExpoSources/expo/modules/kotlin/views/ExpoView.kt +23 -0
  201. package/kotlin/ExpoSources/expo/modules/kotlin/views/ViewDefinitionBuilder.kt +71 -0
  202. package/kotlin/ExpoSources/expo/modules/kotlin/views/ViewProps.kt +35 -0
  203. package/kotlin/README.md +13 -3
  204. package/kotlin/Sources/android/os/Build.kt +17 -0
  205. package/kotlin/Sources/android/os/Handler.kt +35 -0
  206. package/kotlin/Sources/android/os/Looper.kt +17 -0
  207. package/kotlin/Sources/android/os/MessageQueue.kt +56 -0
  208. package/kotlin/Sources/android/os/SystemClock.kt +14 -0
  209. package/kotlin/Sources/android/util/Log.kt +64 -0
  210. package/kotlin/Sources/java/security/MessageDigest.kt +114 -0
  211. package/kotlin/Sources/kotlin/text/StringFormat.kt +9 -0
  212. package/kotlin/Sources/org/json/JSON.kt +44 -0
  213. package/kotlin/fixtures/counter/Counter.d.kt.ts +1 -0
  214. package/kotlin/fixtures/counter/Counter.kt +10 -3
  215. package/kotlin/fixtures/counter/CounterApp.native.tsx +1 -1
  216. package/kotlin/fixtures/counter/vite.config.ts +2 -2
  217. package/kotlin/fixtures/headless-counter/Headless.kt +7 -6
  218. package/kotlin/fixtures/import-animation/Animation.d.kt.ts +7 -0
  219. package/kotlin/fixtures/import-animation/Animation.kt +80 -0
  220. package/kotlin/fixtures/import-animation/ImportAnimation.native.tsx +13 -0
  221. package/kotlin/fixtures/import-animation/README.md +24 -0
  222. package/kotlin/fixtures/import-animation/app/_layout.tsx +4 -0
  223. package/kotlin/fixtures/import-animation/app/index+spa.tsx +1 -0
  224. package/kotlin/fixtures/import-animation/app/routes.d.ts +18 -0
  225. package/kotlin/fixtures/import-animation/package.json +23 -0
  226. package/kotlin/fixtures/import-animation/tsconfig.json +20 -0
  227. package/kotlin/fixtures/import-animation/vite.config.ts +20 -0
  228. package/kotlin/fixtures/import-editor/Editor.d.kt.ts +7 -0
  229. package/kotlin/fixtures/import-editor/Editor.kt +59 -0
  230. package/kotlin/fixtures/import-editor/ImportEditor.native.tsx +23 -0
  231. package/kotlin/fixtures/import-editor/README.md +27 -0
  232. package/kotlin/fixtures/import-editor/app/_layout.tsx +4 -0
  233. package/kotlin/fixtures/import-editor/app/index+spa.tsx +1 -0
  234. package/kotlin/fixtures/import-editor/package.json +23 -0
  235. package/kotlin/fixtures/import-editor/tsconfig.json +20 -0
  236. package/kotlin/fixtures/import-editor/vite.config.ts +20 -0
  237. package/kotlin/fixtures/import-effects/Effects.d.kt.ts +7 -0
  238. package/kotlin/fixtures/import-effects/Effects.kt +87 -0
  239. package/kotlin/fixtures/import-effects/ImportEffects.native.tsx +13 -0
  240. package/kotlin/fixtures/import-effects/README.md +19 -0
  241. package/kotlin/fixtures/import-effects/app/_layout.tsx +4 -0
  242. package/kotlin/fixtures/import-effects/app/index+spa.tsx +1 -0
  243. package/kotlin/fixtures/import-effects/package.json +23 -0
  244. package/kotlin/fixtures/import-effects/tsconfig.json +20 -0
  245. package/kotlin/fixtures/import-effects/vite.config.ts +20 -0
  246. package/kotlin/fixtures/import-layout/ImportLayout.native.tsx +13 -0
  247. package/kotlin/fixtures/import-layout/Layout.d.kt.ts +7 -0
  248. package/kotlin/fixtures/import-layout/Layout.kt +72 -0
  249. package/kotlin/fixtures/import-layout/README.md +24 -0
  250. package/kotlin/fixtures/import-layout/app/_layout.tsx +4 -0
  251. package/kotlin/fixtures/import-layout/app/index+spa.tsx +1 -0
  252. package/kotlin/fixtures/import-layout/package.json +23 -0
  253. package/kotlin/fixtures/import-layout/tsconfig.json +20 -0
  254. package/kotlin/fixtures/import-layout/vite.config.ts +20 -0
  255. package/kotlin/fixtures/import-navigation/ImportNavigation.native.tsx +18 -0
  256. package/kotlin/fixtures/import-navigation/Navigation.d.kt.ts +7 -0
  257. package/kotlin/fixtures/import-navigation/Navigation.kt +104 -0
  258. package/kotlin/fixtures/import-navigation/README.md +31 -0
  259. package/kotlin/fixtures/import-navigation/app/_layout.tsx +4 -0
  260. package/kotlin/fixtures/import-navigation/app/index+spa.tsx +1 -0
  261. package/kotlin/fixtures/import-navigation/package.json +23 -0
  262. package/kotlin/fixtures/import-navigation/tsconfig.json +20 -0
  263. package/kotlin/fixtures/import-navigation/vite.config.ts +20 -0
  264. package/kotlin/fixtures/import-overlays/ImportOverlays.native.tsx +29 -0
  265. package/kotlin/fixtures/import-overlays/Overlays.d.kt.ts +7 -0
  266. package/kotlin/fixtures/import-overlays/Overlays.kt +93 -0
  267. package/kotlin/fixtures/import-overlays/README.md +34 -0
  268. package/kotlin/fixtures/import-overlays/app/_layout.tsx +4 -0
  269. package/kotlin/fixtures/import-overlays/app/index+spa.tsx +1 -0
  270. package/kotlin/fixtures/import-overlays/package.json +23 -0
  271. package/kotlin/fixtures/import-overlays/tsconfig.json +20 -0
  272. package/kotlin/fixtures/import-overlays/vite.config.ts +20 -0
  273. package/kotlin/fixtures/import-scroll/ImportScroll.native.tsx +13 -0
  274. package/kotlin/fixtures/import-scroll/README.md +23 -0
  275. package/kotlin/fixtures/import-scroll/Scroll.d.kt.ts +7 -0
  276. package/kotlin/fixtures/import-scroll/Scroll.kt +91 -0
  277. package/kotlin/fixtures/import-scroll/app/_layout.tsx +4 -0
  278. package/kotlin/fixtures/import-scroll/app/index+spa.tsx +1 -0
  279. package/kotlin/fixtures/import-scroll/package.json +23 -0
  280. package/kotlin/fixtures/import-scroll/tsconfig.json +20 -0
  281. package/kotlin/fixtures/import-scroll/vite.config.ts +20 -0
  282. package/kotlin/fixtures/import-selection/ImportSelection.native.tsx +44 -0
  283. package/kotlin/fixtures/import-selection/README.md +32 -0
  284. package/kotlin/fixtures/import-selection/Selection.d.kt.ts +8 -0
  285. package/kotlin/fixtures/import-selection/Selection.kt +78 -0
  286. package/kotlin/fixtures/import-selection/app/_layout.tsx +4 -0
  287. package/kotlin/fixtures/import-selection/app/index+spa.tsx +1 -0
  288. package/kotlin/fixtures/import-selection/package.json +23 -0
  289. package/kotlin/fixtures/import-selection/tsconfig.json +20 -0
  290. package/kotlin/fixtures/import-selection/vite.config.ts +20 -0
  291. package/kotlin/fixtures/import-surfaces/ImportSurfaces.native.tsx +13 -0
  292. package/kotlin/fixtures/import-surfaces/README.md +22 -0
  293. package/kotlin/fixtures/import-surfaces/Surfaces.d.kt.ts +7 -0
  294. package/kotlin/fixtures/import-surfaces/Surfaces.kt +64 -0
  295. package/kotlin/fixtures/import-surfaces/app/_layout.tsx +4 -0
  296. package/kotlin/fixtures/import-surfaces/app/index+spa.tsx +1 -0
  297. package/kotlin/fixtures/import-surfaces/package.json +23 -0
  298. package/kotlin/fixtures/import-surfaces/tsconfig.json +20 -0
  299. package/kotlin/fixtures/import-surfaces/vite.config.ts +20 -0
  300. package/kotlin/fixtures/import-values/ImportValues.native.tsx +35 -0
  301. package/kotlin/fixtures/import-values/README.md +23 -0
  302. package/kotlin/fixtures/import-values/Values.d.kt.ts +11 -0
  303. package/kotlin/fixtures/import-values/Values.kt +66 -0
  304. package/kotlin/fixtures/import-values/app/_layout.tsx +4 -0
  305. package/kotlin/fixtures/import-values/app/index+spa.tsx +1 -0
  306. package/kotlin/fixtures/import-values/package.json +23 -0
  307. package/kotlin/fixtures/import-values/tsconfig.json +20 -0
  308. package/kotlin/fixtures/import-values/vite.config.ts +20 -0
  309. package/kotlin/fixtures/kotlin-app-variants/BarBehavior.kt +38 -0
  310. package/kotlin/fixtures/kotlin-app-variants/BarVisibility.kt +36 -0
  311. package/kotlin/fixtures/kotlin-app-variants/Ime.kt +3 -1
  312. package/kotlin/fixtures/kotlin-app-variants/TransientInsets.kt +50 -0
  313. package/kotlin/fork/NOTICE +6 -1
  314. package/kotlin/fork/README.md +15 -7
  315. package/kotlin/fork/build.sh +2 -0
  316. package/kotlin/fork/compose-worker-globals.patch +186 -4
  317. package/kotlin/fork/fork.json +2 -2
  318. package/kotlin/fork/skiko-worker-clock.patch +12 -0
  319. package/kotlin/toolchain.json +12 -12
  320. package/kotlin/tools/expo-types.main.kts +115 -0
  321. package/package.json +17 -23
  322. package/scripts/dev-server-scanner.ts +92 -66
  323. package/skills/contrast/SKILL.md +2 -2
  324. package/skills/peach-debug/SKILL.md +1 -1
  325. package/skills/peach-perf/SKILL.md +1 -1
  326. package/skills/peach-setup/SKILL.md +2 -1
  327. package/skills/peach-test/SKILL.md +8 -0
  328. package/src/assetCatalogContract.ts +43 -1
  329. package/src/bridge-contract-input.ts +46 -19
  330. package/src/bridge-contract.ts +0 -1
  331. package/src/bundle-channel.mjs +197 -84
  332. package/src/bundleGlobalFooter.ts +38 -0
  333. package/src/capture-contract.ts +107 -33
  334. package/src/cloud-contract.ts +5 -1
  335. package/src/cloud.ts +5 -2
  336. package/src/config.ts +22 -3
  337. package/src/configured-bundle-producer.ts +1 -1
  338. package/src/desktop-host-delivery.ts +95 -1
  339. package/src/expo-kotlin-bundle.ts +29 -0
  340. package/src/expo-kotlin-host.ts +201 -0
  341. package/src/expo-swift-host.ts +96 -76
  342. package/src/expoKotlinContract.ts +70 -0
  343. package/src/expoSwiftContract.ts +4 -25
  344. package/src/home-paths.ts +7 -4
  345. package/src/host/bridge-host.ts +23 -3
  346. package/src/host/fetch-proxy-handler.ts +13 -0
  347. package/src/host/fetch-proxy-overrides.ts +11 -0
  348. package/src/host/replacement-module-handler.ts +5 -2
  349. package/src/index.ts +3 -1
  350. package/src/kotlin-host.ts +463 -19
  351. package/src/metro-plugin.ts +56 -28
  352. package/src/metro-production-bundle.ts +2 -2
  353. package/src/native-app-identity-project.ts +190 -0
  354. package/src/native-app-identity.ts +398 -34
  355. package/src/native-firebase-config.ts +69 -15
  356. package/src/native-seam-manifest.ts +6 -0
  357. package/src/one-widget-discovery.ts +2 -1
  358. package/src/openstep-plist.ts +107 -0
  359. package/src/react-native-host-modules.ts +4 -0
  360. package/src/runtime-assets.ts +2 -2
  361. package/src/sim-client.ts +2 -2
  362. package/src/swift-binary-modules.ts +3 -1
  363. package/src/swift-compile.ts +286 -38
  364. package/src/swift-distribution-contract.ts +4 -0
  365. package/src/swift-distribution.lock.json +123 -12
  366. package/src/swift-distribution.ts +7 -3
  367. package/src/swift-host.ts +298 -83
  368. package/src/swift-package-manifest.ts +29 -2
  369. package/src/swift-package.ts +180 -10
  370. package/src/swift-packages.ts +4 -0
  371. package/src/swift-standin-emit.ts +4 -1
  372. package/src/swift-standins.ts +274 -15
  373. package/src/swift-submit.ts +62 -7
  374. package/src/swift-toolchain.ts +6 -1
  375. package/src/swiftContract.ts +126 -3
  376. package/src/vite-plugin-one.ts +13 -16
  377. package/src/vite-plugin-swift.ts +4 -5
  378. package/src/vite-plugin.ts +360 -144
  379. package/src/vite.d.ts +1 -1
  380. package/src/worker-system-chunks.ts +221 -0
  381. package/src/worklet-executable.ts +348 -38
  382. package/src/worklets-babel.ts +1 -1
  383. package/src/xcode-project.ts +243 -127
  384. package/dist-lib/agent-identity.cjs +0 -39
  385. package/dist-lib/agent-sessions.cjs +0 -760
  386. package/dist-lib/cli-constants.cjs +0 -32
  387. package/dist-lib/render-mode.cjs +0 -44
  388. package/kotlin/AppSources/android/view/View.kt +0 -74
  389. package/kotlin/AppSources/android/widget/FrameLayout.kt +0 -6
  390. package/src/render-mode.ts +0 -15
  391. /package/kotlin/{AppSources → AndroidViewSources}/android/content/Context.kt +0 -0
  392. /package/kotlin/{AppSources → AndroidViewSources}/android/content/res/Configuration.kt +0 -0
  393. /package/kotlin/{AppSources → AndroidViewSources}/android/graphics/Color.kt +0 -0
  394. /package/kotlin/{AppSources → AndroidViewSources}/android/util/DisplayMetrics.kt +0 -0
  395. /package/kotlin/{AppSources → AndroidViewSources}/dev/peach/app/JavaFormat.kt +0 -0
  396. /package/kotlin/{AppSources → Sources}/java/lang/Runnable.kt +0 -0
@@ -0,0 +1,35 @@
1
+ import { useEffect, useState } from 'react'
2
+ import { Text, View } from 'react-native'
3
+ import { Values } from './Values.kt'
4
+
5
+ const input = JSON.stringify({
6
+ items: [{ name: 'Kotlin' }, ['hello', 7, true, null]],
7
+ metadata: { source: 'One' },
8
+ })
9
+
10
+ export default function Index() {
11
+ const [result, setResult] = useState('running')
12
+ const [error, setError] = useState('')
13
+ useEffect(() => {
14
+ void Promise.all([
15
+ Values.read(input),
16
+ Values.failures(),
17
+ Values.nested({ first: [1, 2], second: [] }),
18
+ Values.nullable(null),
19
+ Values.nullable('hello'),
20
+ Values.nullableList([null, 'one', '', null]),
21
+ Values.nullableList([]),
22
+ Values.nullableMap({ first: [1, null, 3], empty: [] }),
23
+ Values.nullableMap({}),
24
+ ])
25
+ .then((values) => setResult(JSON.stringify(values)))
26
+ .catch((reason: unknown) => setError(String(reason)))
27
+ }, [])
28
+ return (
29
+ <View style={{ flex: 1, backgroundColor: '#fff', padding: 24, paddingTop: 80 }}>
30
+ <Text style={{ fontSize: 24 }}>Kotlin imported values</Text>
31
+ <Text testID="import-values-result">{result}</Text>
32
+ <Text testID="import-values-error">{error}</Text>
33
+ </View>
34
+ )
35
+ }
@@ -0,0 +1,23 @@
1
+ # Imported Kotlin values
2
+
3
+ This fixture exercises a real `OneModule` through the same `.kt` import on
4
+ Android and in Peach. Its visible result contains nested map/list round trips,
5
+ nullable strings and collection elements, 14 JSON reads and 17 expected Android
6
+ JSON errors. The nine results include null elements, empty lists, nested nullable
7
+ map values and an empty map, so declaration errors cannot hide behind a scalar
8
+ call that happens to work.
9
+
10
+ Run One from this directory with `bunx one dev --port 8081`. Open that server in Peach with
11
+ `peach open <port> --device pixel-8`, or generate Android with `bunx one prebuild --platform android` and build
12
+ `android/` with `./gradlew assembleDebug`.
13
+ Use the repository's remote builder for Android compilation. The module uses
14
+ Android's own `org.json` on device and Peach's Kotlin implementation in Wasm.
15
+
16
+ The `import-values-result` node starts as `running`, then contains the complete
17
+ JSON result. `import-values-error` must stay empty. Compare parsed results
18
+ between hosts, including error messages, nulls and empty collections.
19
+
20
+ For Contrast, import these project files with their catalog dependency versions
21
+ materialized. Its Android native bundle producer compiles `Values.kt`, publishes
22
+ the generated Wasm and registers the module contract before calling methods.
23
+ A successful bundle alone does not establish runtime acceptance.
@@ -0,0 +1,11 @@
1
+ // generated by one typegen; edits will be replaced
2
+ export declare const Values: {
3
+ nested(values: Record<string, number[]>): Promise<Record<string, number[]>>
4
+ nullable(value: string | null): Promise<string | null>
5
+ nullableList(values: (string | null)[]): Promise<(string | null)[]>
6
+ nullableMap(
7
+ values: Record<string, (number | null)[]>,
8
+ ): Promise<Record<string, (number | null)[]>>
9
+ read(input: string): Promise<string[]>
10
+ failures(): Promise<string[]>
11
+ }
@@ -0,0 +1,66 @@
1
+ package dev.contrast.kotlinimports
2
+
3
+ import dev.onejs.one.source.OneModule
4
+ import org.json.JSONArray
5
+ import org.json.JSONException
6
+ import org.json.JSONObject
7
+
8
+ object Values : OneModule {
9
+ fun nested(values: Map<String, List<Int>>): Map<String, List<Int>> = values
10
+
11
+ fun nullable(value: String?): String? = value
12
+
13
+ fun nullableList(values: List<String?>): List<String?> = values
14
+
15
+ fun nullableMap(values: Map<String, List<Int?>>): Map<String, List<Int?>> = values
16
+
17
+ fun read(input: String): List<String> {
18
+ val document = JSONObject(input)
19
+ val items = document.getJSONArray("items")
20
+ val child = items.getJSONObject(0)
21
+ val nested = items.getJSONArray(1)
22
+ return listOf(
23
+ child.getString("name"),
24
+ nested.getString(0),
25
+ nested.getString(1),
26
+ nested.getString(2),
27
+ nested.getString(3),
28
+ document.getJSONObject("metadata").getString("source"),
29
+ (document.optJSONArray("items") === items).toString(),
30
+ (items.optJSONObject(0) === child).toString(),
31
+ (items.optJSONArray(1) === nested).toString(),
32
+ (document.optJSONObject("metadata") != null).toString(),
33
+ (document.optJSONObject("items") == null).toString(),
34
+ (document.optJSONArray("missing") == null).toString(),
35
+ (items.optJSONObject(-1) == null).toString(),
36
+ (items.optJSONArray(20) == null).toString(),
37
+ )
38
+ }
39
+
40
+ fun failures(): List<String> {
41
+ val document = JSONObject("""{"text":"hello","number":7,"decimal":1.0,"flag":false,"nothing":null,"items":[],"child":{}}""")
42
+ val values = JSONArray("""["hello",7,1.0,false,null,[],{}]""")
43
+ val reads: List<() -> Any> = listOf(
44
+ { document.getJSONArray("text") },
45
+ { document.getJSONObject("number") },
46
+ { document.getJSONArray("decimal") },
47
+ { document.getJSONObject("flag") },
48
+ { document.getJSONArray("nothing") },
49
+ { document.getJSONObject("items") },
50
+ { document.getJSONArray("child") },
51
+ { document.getJSONObject("missing") },
52
+ { values.getJSONArray(0) },
53
+ { values.getJSONObject(1) },
54
+ { values.getJSONArray(2) },
55
+ { values.getJSONObject(3) },
56
+ { values.getJSONArray(4) },
57
+ { values.getJSONObject(5) },
58
+ { values.getJSONArray(6) },
59
+ { values.getString(20) },
60
+ { JSONArray().put(null).getString(0) },
61
+ )
62
+ return reads.map { read ->
63
+ try { read(); "unexpected success" } catch (error: JSONException) { error.message ?: "missing error message" }
64
+ }
65
+ }
66
+ }
@@ -0,0 +1,4 @@
1
+ import { Slot } from 'one'
2
+ export default function Layout() {
3
+ return <Slot />
4
+ }
@@ -0,0 +1 @@
1
+ export { default } from '../ImportValues.native'
@@ -0,0 +1,23 @@
1
+ {
2
+ "name": "peach-kotlin-import-values-fixture",
3
+ "private": true,
4
+ "type": "module",
5
+ "targets": [
6
+ "native"
7
+ ],
8
+ "dependencies": {
9
+ "@react-navigation/core": "catalog:",
10
+ "@react-navigation/native": "catalog:",
11
+ "one": "catalog:",
12
+ "react": "catalog:",
13
+ "react-native": "catalog:",
14
+ "react-native-reanimated": "catalog:",
15
+ "react-native-screens": "catalog:",
16
+ "react-native-worklets": "catalog:"
17
+ },
18
+ "devDependencies": {
19
+ "@react-native-community/template": "catalog:",
20
+ "peachsim": "workspace:*",
21
+ "vite": "catalog:"
22
+ }
23
+ }
@@ -0,0 +1,20 @@
1
+ {
2
+ "compilerOptions": {
3
+ "paths": {
4
+ "~/*": ["./*"]
5
+ },
6
+ "strict": true,
7
+ "allowArbitraryExtensions": true,
8
+ "rootDir": ".",
9
+ "module": "Preserve",
10
+ // allows react-native style imports without path extensions, for compat with platform-specific files
11
+ "moduleResolution": "Bundler",
12
+ "preserveSymlinks": true,
13
+ "skipLibCheck": true,
14
+ "jsx": "react-jsx",
15
+ "noImplicitAny": false,
16
+ "types": ["node", "react", "vite/client"],
17
+ "lib": ["dom", "esnext"]
18
+ },
19
+ "exclude": ["node_modules", "**/test", "**/dist", "**/types", "**/__tests__"]
20
+ }
@@ -0,0 +1,20 @@
1
+ import { one } from 'one/vite'
2
+ import { peachPlugin } from 'peachsim/vite'
3
+ export default {
4
+ root: import.meta.dirname,
5
+ plugins: [
6
+ one({
7
+ web: { defaultRenderMode: 'spa' },
8
+ native: {
9
+ bundler: 'vite',
10
+ app: {
11
+ name: 'KotlinImports',
12
+ scheme: 'kotlinimports',
13
+ android: { applicationId: 'dev.contrast.kotlinimports' },
14
+ },
15
+ },
16
+ }),
17
+ peachPlugin(),
18
+ ],
19
+ server: { host: '0.0.0.0' },
20
+ }
@@ -0,0 +1,38 @@
1
+ package dev.contrast.kotlinapp
2
+
3
+ import android.view.WindowInsetsController
4
+ import androidx.compose.foundation.background
5
+ import androidx.compose.foundation.layout.Arrangement
6
+ import androidx.compose.foundation.layout.Column
7
+ import androidx.compose.foundation.layout.fillMaxSize
8
+ import androidx.compose.foundation.layout.padding
9
+ import androidx.compose.foundation.layout.safeDrawingPadding
10
+ import androidx.compose.material3.Button
11
+ import androidx.compose.material3.Text
12
+ import androidx.compose.runtime.Composable
13
+ import androidx.compose.runtime.getValue
14
+ import androidx.compose.runtime.mutableIntStateOf
15
+ import androidx.compose.runtime.remember
16
+ import androidx.compose.runtime.setValue
17
+ import androidx.compose.ui.Modifier
18
+ import androidx.compose.ui.graphics.Color
19
+ import androidx.compose.ui.unit.dp
20
+
21
+ @Composable
22
+ internal fun BarBehavior(controller: WindowInsetsController) {
23
+ var behavior by remember { mutableIntStateOf(controller.systemBarsBehavior) }
24
+ Column(
25
+ Modifier.fillMaxSize().background(Color(0xFFE8EEF8)).safeDrawingPadding().padding(16.dp),
26
+ verticalArrangement = Arrangement.spacedBy(12.dp),
27
+ ) {
28
+ Text("Behavior: $behavior")
29
+ Button(onClick = {
30
+ controller.systemBarsBehavior = WindowInsetsController.BEHAVIOR_SHOW_TRANSIENT_BARS_BY_SWIPE
31
+ behavior = controller.systemBarsBehavior
32
+ }) { Text("Transient bars") }
33
+ Button(onClick = {
34
+ controller.systemBarsBehavior = WindowInsetsController.BEHAVIOR_DEFAULT
35
+ behavior = controller.systemBarsBehavior
36
+ }) { Text("Default bars") }
37
+ }
38
+ }
@@ -0,0 +1,36 @@
1
+ package dev.contrast.kotlinapp
2
+
3
+ import android.view.WindowInsetsController
4
+ import androidx.compose.foundation.background
5
+ import androidx.compose.foundation.layout.Arrangement
6
+ import androidx.compose.foundation.layout.Column
7
+ import androidx.compose.foundation.layout.WindowInsets
8
+ import androidx.compose.foundation.layout.fillMaxSize
9
+ import androidx.compose.foundation.layout.navigationBars
10
+ import androidx.compose.foundation.layout.padding
11
+ import androidx.compose.foundation.layout.safeDrawingPadding
12
+ import androidx.compose.foundation.layout.statusBars
13
+ import androidx.compose.material3.Button
14
+ import androidx.compose.material3.Text
15
+ import androidx.compose.runtime.Composable
16
+ import androidx.compose.ui.Modifier
17
+ import androidx.compose.ui.graphics.Color
18
+ import androidx.compose.ui.platform.LocalDensity
19
+ import androidx.compose.ui.unit.dp
20
+
21
+ @Composable
22
+ internal fun BarVisibility(controller: WindowInsetsController) {
23
+ val density = LocalDensity.current
24
+ val status = WindowInsets.statusBars.getTop(density)
25
+ val navigation = WindowInsets.navigationBars.getBottom(density)
26
+ Column(
27
+ Modifier.fillMaxSize().background(Color(0xFFE8EEF8)).safeDrawingPadding().padding(16.dp),
28
+ verticalArrangement = Arrangement.spacedBy(12.dp),
29
+ ) {
30
+ Text("Bars: status $status navigation $navigation")
31
+ Button(onClick = { controller.hide(android.view.WindowInsets.Type.statusBars()) }) { Text("Hide status") }
32
+ Button(onClick = { controller.hide(android.view.WindowInsets.Type.navigationBars()) }) { Text("Hide navigation") }
33
+ Button(onClick = { controller.show(android.view.WindowInsets.Type.statusBars()) }) { Text("Show status") }
34
+ Button(onClick = { controller.show(android.view.WindowInsets.Type.navigationBars()) }) { Text("Show navigation") }
35
+ }
36
+ }
@@ -7,6 +7,7 @@ import androidx.compose.foundation.layout.WindowInsets
7
7
  import androidx.compose.foundation.layout.fillMaxSize
8
8
  import androidx.compose.foundation.layout.fillMaxWidth
9
9
  import androidx.compose.foundation.layout.ime
10
+ import androidx.compose.foundation.layout.isImeVisible
10
11
  import androidx.compose.foundation.layout.padding
11
12
  import androidx.compose.foundation.layout.safeDrawingPadding
12
13
  import androidx.compose.material3.OutlinedTextField
@@ -31,6 +32,7 @@ fun Ime() {
31
32
  var height by remember { mutableStateOf(0) }
32
33
  var tallest by remember { mutableStateOf(0) }
33
34
  val shown = WindowInsets.ime.getBottom(LocalDensity.current) > 0
35
+ val visible = WindowInsets.isImeVisible
34
36
  Column(
35
37
  Modifier.fillMaxSize()
36
38
  .onSizeChanged { height = it.height; tallest = maxOf(tallest, it.height) }
@@ -38,7 +40,7 @@ fun Ime() {
38
40
  .safeDrawingPadding()
39
41
  .padding(16.dp),
40
42
  ) {
41
- Text("Ime: ${if (shown) "shown" else "hidden"} lifted ${height < tallest}")
43
+ Text("Ime: ${if (shown) "shown" else "hidden"} visible $visible lifted ${height < tallest}")
42
44
  OutlinedTextField(
43
45
  value = note,
44
46
  onValueChange = { note = it },
@@ -0,0 +1,50 @@
1
+ package dev.contrast.kotlinapp
2
+
3
+ import android.view.WindowInsetsController
4
+ import androidx.compose.foundation.background
5
+ import androidx.compose.foundation.layout.Arrangement
6
+ import androidx.compose.foundation.layout.Column
7
+ import androidx.compose.foundation.layout.WindowInsets
8
+ import androidx.compose.foundation.layout.fillMaxSize
9
+ import androidx.compose.foundation.layout.padding
10
+ import androidx.compose.foundation.layout.safeDrawingPadding
11
+ import androidx.compose.foundation.layout.statusBars
12
+ import androidx.compose.material3.Button
13
+ import androidx.compose.material3.Text
14
+ import androidx.compose.runtime.Composable
15
+ import androidx.compose.runtime.LaunchedEffect
16
+ import androidx.compose.runtime.getValue
17
+ import androidx.compose.runtime.mutableIntStateOf
18
+ import androidx.compose.runtime.mutableStateOf
19
+ import androidx.compose.runtime.remember
20
+ import androidx.compose.runtime.setValue
21
+ import androidx.compose.runtime.snapshotFlow
22
+ import androidx.compose.ui.Modifier
23
+ import androidx.compose.ui.graphics.Color
24
+ import androidx.compose.ui.platform.LocalDensity
25
+ import androidx.compose.ui.unit.dp
26
+
27
+ @Composable
28
+ internal fun TransientInsets(controller: WindowInsetsController) {
29
+ val density = LocalDensity.current
30
+ val statusBars = WindowInsets.statusBars
31
+ val top = statusBars.getTop(density)
32
+ var armed by remember { mutableStateOf(false) }
33
+ var peak by remember { mutableIntStateOf(0) }
34
+ LaunchedEffect(statusBars, density) {
35
+ controller.systemBarsBehavior = WindowInsetsController.BEHAVIOR_SHOW_TRANSIENT_BARS_BY_SWIPE
36
+ snapshotFlow { statusBars.getTop(density) }.collect { value ->
37
+ if (armed) peak = maxOf(peak, value)
38
+ }
39
+ }
40
+ Column(
41
+ Modifier.fillMaxSize().background(Color(0xFFE8EEF8)).safeDrawingPadding().padding(16.dp),
42
+ verticalArrangement = Arrangement.spacedBy(12.dp),
43
+ ) {
44
+ Text("Status: $top Peak: $peak")
45
+ Button(onClick = {
46
+ controller.hide(android.view.WindowInsets.Type.statusBars())
47
+ armed = true
48
+ }) { Text("Hide status") }
49
+ }
50
+ }
@@ -28,12 +28,17 @@ React Native tenants do not expose. The Compose patch also formats UTC
28
28
  timestamps at UTC, uses the Android
29
29
  DefaultNavTransitions expressions in the web actual, and initializes the
30
30
  Compose paint stroke join to Miter to agree with Skia and Android.
31
- The built klibs are ui-wasm-js, ui-text-wasm-js, ui-skiko-wasm-js and
31
+ The Compose patch also uses Android click and system-defined touch focus, keeping sibling controls from taking an active text field.
32
+ Dialog.skiko.kt and PlatformContext.skiko.kt attach distinct native dialog windows and dispatchers.
33
+ The built klibs are foundation-wasm-js, ui-wasm-js, ui-text-wasm-js, ui-skiko-wasm-js and
32
34
  material3-wasm-js 1.13.0-alpha01, navigation-compose-wasm-js 2.10.0-beta01,
33
35
  and skiko-wasm-js 0.152.0-alpha02 compiled from the patched sources.
34
36
  skiko-wasm-0.152.0-alpha02.jar contains that worker-safe loader and
35
37
  Skiko's own wasm runtime.
36
38
 
39
+ LinkSkikoTask.kt sorts object paths before linking to remove filesystem order
40
+ from the Wasm binary; library order retains upstream symbol resolution.
41
+
37
42
  The Compose patch also selects integer static glyph advances on Android and
38
43
  scales letter spacing to the integer shaping size, retaining fractional Animated
39
44
  text. skia-android-shaping.patch truncates only the measurement-font copy for
@@ -9,6 +9,8 @@ Android behavior for the approved web differences and static text shaping below.
9
9
 
10
10
  | module | file | native host binding |
11
11
  | --- | --- | --- |
12
+ | Compose `foundation` and `ui` | `RequestFocusOnClick.web.kt`, `Focusability.web.kt` | Android click and touch focus policy keeps sibling controls from taking a text field’s focus |
13
+ | Compose `ui` | `Dialog.skiko.kt`, `PlatformContext.skiko.kt` | distinct Dialog window and navigation dispatcher isolate Back from the activity |
12
14
  | Compose `ui` | `Actuals.wasm.kt` | clock reads `globalThis.performance.now()` |
13
15
  | Compose `ui` | `PlatformClipboard.web.kt` | worker-safe secure-context and clipboard reads |
14
16
  | Compose `ui` | `SystemTheme.kt` | `LocalSystemTheme` visible to the host, which provides the device's night mode |
@@ -18,13 +20,14 @@ Android behavior for the approved web differences and static text shaping below.
18
20
  | Skia shaper | `SkShaper_harfbuzz.cpp` | measurement-font copy truncates static shaping size; the painted run font retains the requested size |
19
21
  | Skia raster | `SkFontHost_FreeType.cpp`, `SkFontHost_FreeType_common.cpp`, `SkSurface.cpp` | Android implicit autohinting policy and text gamma 1.4, contrast 0 |
20
22
  | Skia paragraph | `Run.cpp`, `TextLine.cpp`, `TextWrapper.cpp`, `DartTypes.h` | Android inter-glyph spacing, caret boundaries, edge trimming before line fits and integer center origins |
21
- | Compose `ui-skiko` | `SkikoParagraphIntrinsics.nonAndroid.kt`, `SkikoParagraph.nonAndroid.kt`, `SkikoParagraphBuilder.nonAndroid.kt` | Android letter-spacing intrinsic padding, centered line bounds and explicit center alignment |
23
+ | Compose `ui-skiko` | `SkikoParagraphIntrinsics.nonAndroid.kt`, `SkikoParagraph.nonAndroid.kt`, `SkikoParagraphBuilder.nonAndroid.kt` | Android letter-spacing intrinsic padding, centered line bounds, explicit center alignment and fitting BoringLayout line extents |
22
24
  | Skiko paragraph | `Alignment.kt` | transports the Android center ordinal without changing existing alignments |
23
25
  | Compose `material3` | `PlatformDateFormat.web.kt` | timestamp formatting uses UTC, as Android does |
24
26
  | Navigation `navigation-compose` | `DefaultNavTransitions.web.kt` | Android forward fades and predictive pop defaults |
25
27
  | Skiko | `OsArch.web.kt` | explicit `setHostOsProvider`; its default lazily retains upstream OS detection |
26
28
  | Skiko | `Actuals.web.kt` | nanosecond clock reads `globalThis.performance.now()` |
27
29
  | Skiko loader build | `OptimizeSkikoWasmTask.kt` | script directory reads `import.meta.url`, without `self.location` |
30
+ | Skiko linker | `LinkSkikoTask.kt` | object paths sort before linking; library order retains its symbol resolution contract |
28
31
 
29
32
  The Compose host installs the locale provider once before any scene, from the
30
33
  same device locale it passes to `PlatformContext`, and installs `OS.Android`
@@ -38,7 +41,10 @@ Every changed upstream file carries a modification notice. `LICENSE` and
38
41
  runtime jar with the upstream Gradle builds on the Linux builder. The Skia shaping, paragraph and raster
39
42
  units are fetched at their pinned commit, patched, and compiled into Skiko; the linker
40
43
  uses them instead of the same units in the pinned Skia archive. All other Skia
41
- objects retain their upstream build. FreeType headers match the pinned Skia DEPS revision;
44
+ objects retain their upstream build. The linker sorts object paths, so filesystem
45
+ enumeration does not change the Wasm binary. Static archives retain their declared
46
+ order because that order controls symbol resolution. Sorting costs once per link,
47
+ outside app runtime. FreeType headers match the pinned Skia DEPS revision;
42
48
  the FreeType binary remains the archive version. Raster changes add no allocation
43
49
  and retain the existing A8 preblend path. This adds no allocation beyond the existing
44
50
  measurement-font copy, and truncates once per shaped font, outside the glyph loop.
@@ -46,8 +52,10 @@ Paragraph spacing adds constant arithmetic per glyph or cluster; line fits trim
46
52
  the same edge half-spaces as completed lines, without allocation. Android centered
47
53
  lines use the platform integer origin; other platforms retain fractional centering.
48
54
  Intrinsic measurement checks span letter spacing once and adds Android’s 0.5 px
49
- padding; line bounds use the platform floor and ceil. These corrections add no
50
- allocation. Skiko builds before Compose, whose `skiko-wasm-js` dependency resolves
55
+ padding; line bounds use the platform floor and ceil. Fitting Android BoringLayout
56
+ paragraphs expose the ceiled paragraph extent while preserving fractional glyph
57
+ positions, including Animated text. Eligibility is scanned once per intrinsic
58
+ construction. These corrections add no allocation. Skiko builds before Compose, whose `skiko-wasm-js` dependency resolves
51
59
  from this invocation’s Maven directory through `skiko-local.init.gradle`. The init
52
60
  script travels in the immutable build record with the patches.
53
61
 
@@ -83,6 +91,6 @@ fixture. The six original widths, twelve spacing assertions and the 162/164 px
83
91
  wrapping threshold pass their paired Android controls. The body Range probe
84
92
  retains its existing 0.00098 px difference. The original plain Month raster rows pass the strict 16/255 comparison in
85
93
  the actual Kotlin app; the old frame fails the retained raster check. Other
86
- pixel residuals, mixed-font bold
87
- advances, the primary caret at a style boundary and Animated whole-width rounding
88
- remain open in the lane plan. These corrections do not certify full text parity.
94
+ pixel residuals remain open in the lane plan. The original Animated motion widths
95
+ match Android, and the retained mixed-font/caret controls pass after the extent
96
+ correction. These corrections do not certify full text parity.
@@ -155,6 +155,7 @@ checkout 0
155
155
  -Pjetbrains.publication.version.COMPOSE_MATERIAL3=1.13.0-alpha01 \
156
156
  -Pjetbrains.publication.version.NAVIGATION=2.10.0-beta01 \
157
157
  :compose:ui:ui:publishWasmJsPublicationToMavenLocal \
158
+ :compose:foundation:foundation:publishWasmJsPublicationToMavenLocal \
158
159
  :compose:ui:ui-text:publishWasmJsPublicationToMavenLocal \
159
160
  :compose:ui:ui-skiko:publishWasmJsPublicationToMavenLocal \
160
161
  :compose:material3:material3:publishWasmJsPublicationToMavenLocal \
@@ -162,6 +163,7 @@ checkout 0
162
163
  )
163
164
 
164
165
  cp "${M2}/org/jetbrains/compose/ui/ui-wasm-js/1.13.0-alpha01/ui-wasm-js-1.13.0-alpha01.klib" \
166
+ "${M2}/org/jetbrains/compose/foundation/foundation-wasm-js/1.13.0-alpha01/foundation-wasm-js-1.13.0-alpha01.klib" \
165
167
  "${M2}/org/jetbrains/compose/ui/ui-text-wasm-js/1.13.0-alpha01/ui-text-wasm-js-1.13.0-alpha01.klib" \
166
168
  "${M2}/org/jetbrains/compose/ui/ui-skiko-wasm-js/1.13.0-alpha01/ui-skiko-wasm-js-1.13.0-alpha01.klib" \
167
169
  "${M2}/org/jetbrains/compose/material3/material3-wasm-js/1.13.0-alpha01/material3-wasm-js-1.13.0-alpha01.klib" \