Repository navigation
feat(apps): add app control tools and the App tab - #15
Merged
Merged
Conversation
Add MCP tools that list, launch, stop, and install apps, open deep links, change app permissions, and send test push notifications on iOS simulators and Android devices through simctl and adb. Panel-only tools read app icons, Android labels, declared URL schemes, and permission state. Unexpected command failures reach Sentry with a fixed message so command output with bundle IDs, URLs, and serials stays local.
Split the device popover into App and Device tabs. The App tab picks an installed app with its icon, launches it on selection, relaunches or stops it, opens URLs with declared-scheme and recent suggestions, and sets permissions and test pushes. Without a detected foreground app, the picker opens on the newest running app, then the last app picked on that device.
Replace the single AppControl class, which branched on platform in every method, with an AppDriver interface implemented by SimulatorDriver (simctl) and AndroidDriver (adb). The tool layer validates the target once and picks the driver; drivers never branch on platform. simctl failures that the user can fix are declared at each call site instead of through repeated catch, cast, and rethrow blocks. The app list now puts the foreground app first among running apps, and permission changes return the full list on both platforms. AppIcon becomes AppDetails because it also carries the Android label.
Collapse the store's icon, label, and request-tracking structures into one details map, model loading permissions as null instead of a separate flag, and derive running state from the server's running list. One staleness guard replaces five copies, actions share a single path that resolves the selected app, and permissions and link suggestions update together. The App tab component splits into picker, URL, permission, and push sections.
The shadcn inputs used text-base below the md breakpoint to avoid iOS Safari focus zoom. The panel is always narrower than md, so its fields rendered at 16px next to 14px controls.
Codex keeps the resource address of side tabs and saved cards opened before a plugin update. The server only listed addresses up to 0.1.57, so a tab opened on the previous release showed "Couldn't display Mobile Dev" after updating. Resource templates now serve the current panel, workspace, recording, and comparison views for any earlier release.
Relaunch and Stop join the app picker as icon buttons, and the running state moves into its subtitle. Open sits inside the URL field, and recent URLs get a clock chip ahead of the dashed scheme templates. Permissions and the test notification collapse into rows with a summary, and the open one is remembered across panels. Permission rows show every entry with an icon.
The Device tab groups controls under Display, Location and Panel in one right-hand column. Text size becomes a stepper whose middle still opens the full list. Location shows the current place with one-click city chips, and Custom opens the coordinate fields. Tabs gain icons.
lauridskern
added this pull request to stack #16
October 14, 2026 13:03
Inner-class launcher activities such as .Main$Launcher were expanded by the device shell. Expected app-control outcomes now reach server.error.outcome, as docs/telemetry.md describes.
… helpers - Drivers reject permissions their platform cannot set, so the tool layer no longer branches. - One adb runner in commands.ts, shared by installs and the network throttle. - Element-bound stores and measured panel operations use shared helpers.
…ir device - Drivers report the foreground and running apps together, so iOS lists launchctl once. - A permission change that finishes after a device switch no longer marks the new device. - The panel requests icons in batches the server accepts, so large app lists still get icons. - Android SDK discovery is shared, and a missing aapt2 is looked up again later.
# Conflicts: # .codex-plugin/plugin.json # package-lock.json # package.json # src/shared/version.ts
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
Adds app control to Mobile Dev: MCP tools for Codex, and an App tab in the device popover.
simctl) and Android devices (adb). Panel-only tools read app icons, Android labels, declared URL schemes, and permission state.SimulatorDriverandAndroidDriverimplement oneAppDriverinterface, so the tool layer validates the target once and drivers never branch on platform. Each driver also rejects permissions its platform can't set, so the tool layer has no platform checks..Main$Launcherlaunch.elementStoreshelper, and App tab timings usemeasureUiOperationfromsrc/ui/telemetry.ts. Android installs run throughrunAdbincommands.ts, which feat(settings): add clean status bar, network conditions, and per-app language #14's network throttle also uses.Release bumps are separate commits, up to 0.1.151.
Stack: #14 (clean status bar, network conditions, per-app language) builds on this branch.
Conflicts with
main: only the version bump files (package.json,package-lock.json,.codex-plugin/plugin.json,src/shared/version.ts), becausemaingained two fixes after this branch started.Telemetry
simctl,adb,aapt2, orplutilfailures report a fixed message underapp_control.<action>, so bundle IDs, URLs, serials, and paths stay local. Expected outcomes, such as a missing app, count only throughserver.error.outcome, without a report.ui.app_tools.<action>round trips and countsui.app_tools.failure. Results that arrive after a surface or device change are excluded.docs/telemetry.mdis updated.Testing
tests/app-control.test.tscovers simctl and adb parsing, launch/permission/link/icon handling, and command errors.tests/device-settings.test.tsandtests/react-ui.test.tscover the App and Device tabs.npm teston this branch alone: the app control, device settings, and React UI tests pass. In a fresh worktree, 10 Baguette, serve-emu, and agent-device runtime tests fail because the untracked vendored binaries and runtimenode_modulesare missing there. With feat(settings): add clean status bar, network conditions, and per-app language #14 on top, in the main checkout, all 642 tests pass (1 skipped).