Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
27 commits
Select commit Hold shift + click to select a range
ebb60f2
feat: add app-flow
hurali97 Oct 14, 2026
d5878ca
fix: folder picker
hurali97 Oct 14, 2026
cb6ae7b
fix: launch and start recording
hurali97 Oct 14, 2026
e1ef776
fix: image display
hurali97 Oct 14, 2026
0ff6916
fix: cumulative time duration and graph update
hurali97 Oct 15, 2026
363ee0a
feat: port runtime based flow
hurali97 Oct 15, 2026
d04e3eb
fix: ui prompts
hurali97 Oct 16, 2026
2a91f59
fix: bugs and parity with runtime route
hurali97 Oct 16, 2026
8e67c47
fix: model calls
hurali97 Oct 16, 2026
f924706
feat: add UI states opt-in
hurali97 Oct 16, 2026
546536c
fix: bugs
hurali97 Oct 16, 2026
3613a63
fix: ui states capture
hurali97 Oct 19, 2026
1f11915
revert: ui states
hurali97 Oct 19, 2026
7918a9c
feat: add ui state capture
hurali97 Oct 19, 2026
d56bf12
feat: capture UI states as part of explore
hurali97 Oct 19, 2026
a8a1038
feat: working UI states
hurali97 Oct 20, 2026
5eaa6d9
feat: add jump-to drop down
hurali97 Oct 20, 2026
9e3b408
feat: improve UI
hurali97 Oct 20, 2026
c14fc59
fix: record path bugs
hurali97 Oct 20, 2026
a00cc81
feat: allow fast path to be replayed
hurali97 Oct 21, 2026
5532b1e
feat: disable uncaptured path replays
hurali97 Oct 21, 2026
e51ee4c
feat: make fast codex hop free
hurali97 Oct 21, 2026
5035e5e
feat: add opt-in codex hop
hurali97 Oct 21, 2026
e7270c8
feat: add filter and confirmation
hurali97 Oct 21, 2026
de75e00
Merge remote-tracking branch 'origin/main' into hur/add-app-flow
hurali97 Oct 21, 2026
74a686b
refactor: code review
hurali97 Oct 21, 2026
1a7b307
feat(app-flow): default MCP exploration mode to fast
hurali97 Oct 21, 2026
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
19 changes: 19 additions & 0 deletions docs/mcp-tools.md
Original file line number Diff line number Diff line change
Expand Up @@ -41,5 +41,24 @@
| `mobile_read_display_fps` | Read FPS intervals and connection status |
| `mobile_read_performance_frames` | Read Android jank/pacing statistics and page through exact display frames |
| `mobile_display_fps_close` | Stop FPS collection and release the tracing connection |
| `mobile_appflow_start` | Start a non-blocking structure build or screen sweep; Fast (the default) uses the deterministic runtime, Auto tries Deep Link → Fast, and Thorough tries Deep Link → Exploration |
| `mobile_appflow_status` | Read current or persisted App Flow status |
| `mobile_appflow_result` | Read the current or persisted screen graph |
| `mobile_appflow_events` | Poll buffered progress and manual-recording events past a sequence cursor (app only) |
| `mobile_appflow_pause` | Pause a running sweep at a safe boundary (app only) |
| `mobile_appflow_cancel` | Cancel a run and any parked agent decision |
| `mobile_appflow_launch_app` | Launch the selected project without starting a sweep (app only) |
| `mobile_appflow_resolve_prompt` | Resolve a human-action gate after the user acts (app only) |
| `mobile_appflow_projects` | List the project folders App Flow can open (app only) |
| `mobile_appflow_choose_project` | Select a listed project or open the system folder picker (app only) |
| `mobile_appflow_manual_start` | Start recording a path to one screen (app only) |
| `mobile_appflow_manual_act` | Perform and record one manual path action (app only) |
| `mobile_appflow_manual_stop` | Save the active manual path recording (app only) |
| `mobile_appflow_manual_cancel` | Discard the active manual path recording (app only) |
| `mobile_appflow_manual_replay` | Replay a saved path to one screen (app only) |
| `mobile_appflow_runtime_replay` | Navigate to one screen through the running app's navigator, no recording needed (app only) |
| `mobile_appflow_next_decision` | Long-poll for the next active-agent sweep decision (model only) |
| `mobile_appflow_submit_decision` | Submit one role-valid JSON decision and wait briefly for the next (model only) |
| `mobile_appflow_screenshot` | Read an authorized App Flow PNG (app only) |

When reactivated, the `agent-device` MCP server exposes the pinned runtime's official operations through compact, validated schemas, including `open`, `snapshot`, `press`, `fill`, `type`, `scroll`, `wait`, `find`, `get`, `is`, `close`, and debugging tools. Their input schemas describe each command. The source [control skill](../skills/agent-device/SKILL.md), currently excluded from the package, explains session ordering and links to the version-matched guide.
55 changes: 54 additions & 1 deletion docs/telemetry.md

Large diffs are not rendered by default.

177 changes: 177 additions & 0 deletions package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

1 change: 1 addition & 0 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -55,6 +55,7 @@
"@openai/mcp-extensions": "0.1.0",
"@sentry/node": "11.2.0",
"@sentry/react": "11.2.0",
"@xyflow/react": "^12.12.0",
"ajv": "8.20.0",
"class-variance-authority": "^0.7.1",
"clsx": "^2.1.1",
Expand Down
2 changes: 1 addition & 1 deletion scripts/build.mjs
Original file line number Diff line number Diff line change
Expand Up @@ -138,7 +138,7 @@ const server = await build({
format: "esm", platform: "node", target: "node22", minify: false, legalComments: "eof", metafile: true,
sourcemap: "external",
plugins: [sentryEsbuildPlugin({ project: "codex-mobile-dev-server", telemetry: false, sourcemaps: { disable: true }, release: { inject: false, create: false, finalize: false } })],
banner: { js: "import { createRequire as mobileDevBundleRequire } from 'node:module'; const require = mobileDevBundleRequire(import.meta.url);" },
banner: { js: "import { createRequire as mobileDevBundleRequire } from 'node:module'; import { fileURLToPath as mobileDevFileURLToPath } from 'node:url'; import { dirname as mobileDevDirname } from 'node:path'; const require = mobileDevBundleRequire(import.meta.url); const __filename = mobileDevFileURLToPath(import.meta.url); const __dirname = mobileDevDirname(__filename);" },
});
await mkdir(".sentry/server", { recursive: true });
for (const name of ["server.mjs", "agent-device-server.mjs", "ios-mirror-service.mjs"]) {
Expand Down
15 changes: 15 additions & 0 deletions skills/mobile-dev/SKILL.md
Original file line number Diff line number Diff line change
Expand Up @@ -86,6 +86,21 @@ Selecting a log and clicking Attach to chat puts its message, stack, source, lev

The host needs an Apple Silicon Mac and Xcode 26 or later with an iOS simulator runtime. The plugin uses Codex's bundled Node runtime. If the backend fails, read its error before retrying `mobile_start_baguette`. Keep logs on stderr because stdout carries MCP messages.

### App Flow

Use App Flow to map an Expo Router or React Navigation project. `mobile_appflow_start` is non-blocking. Pass the project folder and either `structure-only` for an unattended route graph or `screen-ui-and-structure` for a simulator sweep with captures and runtime navigation evidence.

For `screen-ui-and-structure`, keep servicing the same run until it reaches a terminal or human-action state:

1. Call `mobile_appflow_next_decision` with the returned `runId`. A `waiting` result means local build or device work is still progressing; poll again.
2. For a `pending` request, follow its role instructions and history, inspect its inline screenshot when present, and return exactly one strict JSON object through `mobile_appflow_submit_decision` with the same `runId` and `requestId`.
3. A successful submit may contain the next request. Continue directly from it; call `next_decision` again only when the submit reports `waiting`.
4. Stop when status is completed, failed, cancelled, or suspended, or when the run reports `needs-user-action`.

Decision JSON is role-specific. Auth classification uses `{ "verdict": "auth" | "clear" | "uncertain", "reason": string }`; arrival and navigation requests must follow their supplied schema; runtime-screen classification uses `{ "distinct": boolean, "key"?: string, "info"?: string }`; state-trigger planning returns actions, a state name, destination locator, and nullable note. Do not wrap the object in Markdown.

An auth/review prompt is deliberately separate from the agent's screenshot classification. When the run needs user action, tell the user to log in or review the simulator and stop the decision loop. Never claim that the human action happened and never call `mobile_appflow_resolve_prompt` on the user's behalf. The App Flow panel owns Stop, Continue anyway, and Continue controls. A paused or inactivity-suspended sweep can be resumed by starting the same project again; its checkpoint preserves completed screens.

### TraceSift profile investigations

When the user provides a local CPU profile or React DevTools profiling export and asks for a root cause, call `mobile_analyze_profile` with its path. Leave `profileType` as `auto` unless the user or file format makes `cpu` or `react` explicit. The plugin reuses a compatible local TraceSift service or starts `tracesift start --no-open`; if setup is missing, report the returned `tracesift init`, installation, version, or platform guidance rather than substituting a different analyzer.
Expand Down
Loading
Loading