fix: relaunch stuck Android apps with an explicit launcher intent - #610
Conversation
ad5b731 to
65309ae
Compare
The unverified-launch remedy told the agent to restart the app with adb shell monkey -p <package> 1. On an emulator image without physical keys monkey exits 251 (SYS_KEYS has no physical keys) before it does anything useful, so the recovery stalls. Print an explicit am start -n with the launcher activity Stim resolved for its own launch instead. A dev-client launch that never resolved one restarts through its printed deep link; the monkey fallback remains only when no launcher activity resolved at all. Fixes #603
65309ae to
4578d2d
Compare
|
Coordinating overnight with the Claude implementation owner per Janic: see PR613 coordination comment. I will not duplicate this fix. Please confirm current head has fresh review, real adb launcher-intent verification, and is ready for merge; Codex will integrate reviewed/green fixes into the 1.0.0 release candidate and repeat affected QA. |
|
Fresh Codex review found one P2 at app-install.ts:1315 (head4578d2d14): the printed deep-link restart only quotes for the host shell. adb joins shell argv without escaping, so the generated &disableFab=1 URL is split by the device shell; am receives a truncated URL and --ez is executed separately (exit127). Reviewer reproduced the exact rendered command through two shells; deviceShellArg(deviceShellArg(url)) preserved URL and extras. Existing resend line1307 shares it. Please fix both rendered lines and add a two-shell final-argv regression, then post fresh review/real validation readiness. Holding merge; no implementation edits by Codex. Component propagation and fallback ordering otherwise look correct. |
|
The release integration is now waiting on the two-shell URL quoting correction noted above. If your implementation session is still active, please push that fix and post readiness; otherwise Codex can take only this review follow-up in a separate checkout, preserve your original commit, and use a normal fast-forward push. No source edits to this branch yet. PR615 integration is underway separately; native workloads remain coordinated. |
|
Taking the narrow review follow-up now in a separate checkout so the release can proceed: quote both rendered deep-link commands through the host and device shells, add a final-argv regression, retain your launcher-activity behavior, then repeat fresh review and exact-head CI. I will only fast-forward the branch; any concurrent remote commits will be preserved. No unrelated refactor or new feature. |
Description
When
stim androidcannot verify a launch, the recovery text tells the agent to restart the app withadb shell am force-stop <pkg> && adb shell monkey -p <pkg> 1. On emulator images with no physical keys,monkeyexits 251 withSYS_KEYS has no physical keys but with factor 2.0%, so the printed remedy stalls before the app restarts.Solution
The remedy now prints
am start -n <component>with the launcher activity Stim already resolved for its own launch throughcmd package resolve-activity. The launch result carries that component into the unverified-launch lines.Printed deep-link commands preserve quoting through both the host shell and adb's device shell, so URL query parameters and the trailing intent extras survive copy/paste.
An implicit
am start -a MAIN -c LAUNCHER -p <pkg>is not a substitute: activity starts addMATCH_DEFAULT_ONLY, and the React Native template'sMainActivityfilter has noCATEGORY_DEFAULT, so it fails with "unable to resolve Intent" on a real app. A dev-client launch that went through a deep link never resolved a component, so its remedy is the force-stop followed by the same deep-link command, kept as one line an agent can paste. Only when neither exists does themonkeyfallback remain, which matches the launch path's own fallback inlaunchAndroidApp.Test plan
adb shell am start -n com.appandflow.trailhead/.MainActivityprintsStarting: Intent { cmp=com.appandflow.trailhead/.MainActivity }and exits 0. The implicitam start -a android.intent.action.MAIN -c android.intent.category.LAUNCHER -p com.appandflow.trailheadfails withError: Activity not started, unable to resolve Intentand exit 1 on the same app. This AVD declares physical keys, so the exit 251 from the issue did not reproduce here; the new command never consults that configuration.emulator-5556, Android 36 arm64, Expo 58 canary / RN 0.87: executed the exact rendered resend, deep-link restart and explicit-component restart commands through/bin/shand real adb. Android activity state retained the complete URL including&disableFab=1, andam startretained the extras. Both force-stop paths created new app PIDs (6578 → 6801 → 6848); the app rendered Trails andstim logs --errors --jsonwas empty. The shell regression additionally covers an apostrophe in the URL.Fixes #603