ReviewOS

also looking at this

craft-native/craft

fix(native): retain keyed controls and correct map and tab chrome

#368
Merged chris wants to merge codex/native-repeated-selector-identity into main
32 files +449 -100

Review threads live on the whole diff, not on one commit, so none are shown here - a thread's line means something in the branch's final form, and painting it into an intermediate step would put it on code it is not about.

packages/android/README.mdmodified+2-1
Changes to packages/android/README.md
@@ -111,7 +111,8 @@ API 35 image took 943,520 ms in the retained diagnostic run
111111[39113277828](https://github.com/craft-native/craft/actions/runs/39113277828).
112112This is OS provisioning before app installation; app and performance budgets
113113are unchanged. Both modes require a readable event-log stream, SettingsProvider,
114the package manager and System UI to be ready. Logs record the budget, actual
114the package manager and System UI to be ready, with HOME resolved beyond the
115automatic Android SDK setup activity. Logs record the budget, actual
115116boot duration, host CPU interval, selected image, acceleration
116117probe, process identity and boot result. Disposal reaps only the owned process
117118and deletes only its disposable AVD; the managed SDK and other devices remain
packages/android/src/emulator.tsmodified+8-0
Changes to packages/android/src/emulator.ts
@@ -153,8 +153,16 @@ export async function createAndroidEmulator(options: AndroidEmulatorOptions): Pr
153153 // launching any app. boot_completed/System UI can precede logd's ADB
154154 // event stream; declaring readiness then loses that first health check.
155155 const events = await run([adb, '-s', serial, 'logcat', '-b', 'events', '-d', '-t', '1'], undefined, probeTimeout(), true)
156 // AOSP's first boot can report all those services ready while its
157 // automatic SDK setup activity still owns HOME. Launching HOME then
158 // opens that transient activity; after it finishes UI automation has
159 // no foreground root. Wait for the real HOME destination instead of
160 // modifying device setup or relaxing native acceptance.
161 const home = await run([adb, '-s', serial, 'shell', 'cmd', 'package', 'resolve-activity', '--brief', '-a', 'android.intent.action.MAIN', '-c', 'android.intent.category.HOME'], undefined, probeTimeout(), true)
162 const homeActivity = home.stdout.trim().split(/\r?\n/).at(-1) ?? ''
156163 booted = settings.code === 0 && packages.code === 0 && systemUi.code === 0 && events.code === 0
157164 && /^package:\/\S+/m.test(packages.stdout) && /^\d+(?:\s+\d+)*$/.test(systemUi.stdout.trim())
165 && home.code === 0 && /^[\w.]+\/[\w.$]+$/.test(homeActivity) && !homeActivity.startsWith('com.android.sdksetup/')
158166 }
159167 }
160168 const checkedAt = Date.now()