mobilerun 0.6.0__tar.gz

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 (237) hide show
  1. mobilerun-0.6.0/.dockerignore +5 -0
  2. mobilerun-0.6.0/.github/workflows/black.yml +19 -0
  3. mobilerun-0.6.0/.github/workflows/bounty.yml +134 -0
  4. mobilerun-0.6.0/.github/workflows/claude-code-review.yml +57 -0
  5. mobilerun-0.6.0/.github/workflows/claude.yml +50 -0
  6. mobilerun-0.6.0/.github/workflows/docker.yml +54 -0
  7. mobilerun-0.6.0/.github/workflows/publish.yml +109 -0
  8. mobilerun-0.6.0/.gitignore +43 -0
  9. mobilerun-0.6.0/.python-version +1 -0
  10. mobilerun-0.6.0/CONTRIBUTING.md +113 -0
  11. mobilerun-0.6.0/Dockerfile +27 -0
  12. mobilerun-0.6.0/LICENSE +21 -0
  13. mobilerun-0.6.0/MANIFEST.in +7 -0
  14. mobilerun-0.6.0/PKG-INFO +300 -0
  15. mobilerun-0.6.0/README.md +234 -0
  16. mobilerun-0.6.0/SKILL.md +85 -0
  17. mobilerun-0.6.0/compat/droidrun/__init__.py +131 -0
  18. mobilerun-0.6.0/compat/droidrun/__main__.py +12 -0
  19. mobilerun-0.6.0/compat/droidrun/cli_shim.py +14 -0
  20. mobilerun-0.6.0/compat/droidrun/macro/__init__.py +17 -0
  21. mobilerun-0.6.0/compat/droidrun/macro/__main__.py +12 -0
  22. mobilerun-0.6.0/compat/pyproject.toml +22 -0
  23. mobilerun-0.6.0/docs/ favicon.svg +5 -0
  24. mobilerun-0.6.0/docs/concepts/architecture.mdx +122 -0
  25. mobilerun-0.6.0/docs/concepts/events-and-workflows.mdx +355 -0
  26. mobilerun-0.6.0/docs/concepts/prompts.mdx +320 -0
  27. mobilerun-0.6.0/docs/concepts/shared-state.mdx +62 -0
  28. mobilerun-0.6.0/docs/custom.css +74 -0
  29. mobilerun-0.6.0/docs/docs.json +119 -0
  30. mobilerun-0.6.0/docs/favicon-dark.png +0 -0
  31. mobilerun-0.6.0/docs/favicon.png +0 -0
  32. mobilerun-0.6.0/docs/features/app-cards.mdx +288 -0
  33. mobilerun-0.6.0/docs/features/credentials.mdx +249 -0
  34. mobilerun-0.6.0/docs/features/custom-tools.mdx +397 -0
  35. mobilerun-0.6.0/docs/features/custom-variables.mdx +201 -0
  36. mobilerun-0.6.0/docs/features/structured-output.mdx +274 -0
  37. mobilerun-0.6.0/docs/features/telemetry.mdx +45 -0
  38. mobilerun-0.6.0/docs/features/tracing.mdx +243 -0
  39. mobilerun-0.6.0/docs/guides/cli.mdx +534 -0
  40. mobilerun-0.6.0/docs/guides/device-setup.mdx +578 -0
  41. mobilerun-0.6.0/docs/guides/docker.mdx +141 -0
  42. mobilerun-0.6.0/docs/guides/overview.mdx +47 -0
  43. mobilerun-0.6.0/docs/logo/dark.png +0 -0
  44. mobilerun-0.6.0/docs/logo/light.png +0 -0
  45. mobilerun-0.6.0/docs/overview.mdx +52 -0
  46. mobilerun-0.6.0/docs/quickstart.mdx +172 -0
  47. mobilerun-0.6.0/docs/sdk/adb-tools.mdx +475 -0
  48. mobilerun-0.6.0/docs/sdk/base-tools.mdx +346 -0
  49. mobilerun-0.6.0/docs/sdk/configuration.mdx +627 -0
  50. mobilerun-0.6.0/docs/sdk/droid-agent.mdx +462 -0
  51. mobilerun-0.6.0/docs/sdk/ios-tools.mdx +431 -0
  52. mobilerun-0.6.0/docs/sdk/reference.mdx +49 -0
  53. mobilerun-0.6.0/gen-docs-sdk-ref.sh +19 -0
  54. mobilerun-0.6.0/mobilerun/__init__.py +102 -0
  55. mobilerun-0.6.0/mobilerun/__main__.py +8 -0
  56. mobilerun-0.6.0/mobilerun/agent/__init__.py +3 -0
  57. mobilerun-0.6.0/mobilerun/agent/action_context.py +41 -0
  58. mobilerun-0.6.0/mobilerun/agent/action_result.py +16 -0
  59. mobilerun-0.6.0/mobilerun/agent/common/__init__.py +0 -0
  60. mobilerun-0.6.0/mobilerun/agent/common/constants.py +3 -0
  61. mobilerun-0.6.0/mobilerun/agent/common/events.py +20 -0
  62. mobilerun-0.6.0/mobilerun/agent/droid/__init__.py +30 -0
  63. mobilerun-0.6.0/mobilerun/agent/droid/droid_agent.py +1058 -0
  64. mobilerun-0.6.0/mobilerun/agent/droid/events.py +108 -0
  65. mobilerun-0.6.0/mobilerun/agent/droid/state.py +199 -0
  66. mobilerun-0.6.0/mobilerun/agent/executor/__init__.py +22 -0
  67. mobilerun-0.6.0/mobilerun/agent/executor/events.py +45 -0
  68. mobilerun-0.6.0/mobilerun/agent/executor/executor_agent.py +288 -0
  69. mobilerun-0.6.0/mobilerun/agent/executor/prompts.py +51 -0
  70. mobilerun-0.6.0/mobilerun/agent/external/README.md +131 -0
  71. mobilerun-0.6.0/mobilerun/agent/external/__init__.py +91 -0
  72. mobilerun-0.6.0/mobilerun/agent/fast_agent/__init__.py +3 -0
  73. mobilerun-0.6.0/mobilerun/agent/fast_agent/events.py +45 -0
  74. mobilerun-0.6.0/mobilerun/agent/fast_agent/fast_agent.py +568 -0
  75. mobilerun-0.6.0/mobilerun/agent/fast_agent/xml_parser.py +258 -0
  76. mobilerun-0.6.0/mobilerun/agent/manager/__init__.py +28 -0
  77. mobilerun-0.6.0/mobilerun/agent/manager/events.py +38 -0
  78. mobilerun-0.6.0/mobilerun/agent/manager/manager_agent.py +570 -0
  79. mobilerun-0.6.0/mobilerun/agent/manager/prompts.py +114 -0
  80. mobilerun-0.6.0/mobilerun/agent/manager/stateless_manager_agent.py +306 -0
  81. mobilerun-0.6.0/mobilerun/agent/oneflows/__init__.py +0 -0
  82. mobilerun-0.6.0/mobilerun/agent/oneflows/app_starter_workflow.py +141 -0
  83. mobilerun-0.6.0/mobilerun/agent/oneflows/structured_output_agent.py +80 -0
  84. mobilerun-0.6.0/mobilerun/agent/providers/__init__.py +23 -0
  85. mobilerun-0.6.0/mobilerun/agent/providers/registry.py +268 -0
  86. mobilerun-0.6.0/mobilerun/agent/providers/setup_service.py +215 -0
  87. mobilerun-0.6.0/mobilerun/agent/providers/types.py +29 -0
  88. mobilerun-0.6.0/mobilerun/agent/tool_registry.py +267 -0
  89. mobilerun-0.6.0/mobilerun/agent/trajectory/__init__.py +3 -0
  90. mobilerun-0.6.0/mobilerun/agent/trajectory/writer.py +454 -0
  91. mobilerun-0.6.0/mobilerun/agent/usage.py +254 -0
  92. mobilerun-0.6.0/mobilerun/agent/utils/__init__.py +27 -0
  93. mobilerun-0.6.0/mobilerun/agent/utils/actions.py +523 -0
  94. mobilerun-0.6.0/mobilerun/agent/utils/chat_utils.py +90 -0
  95. mobilerun-0.6.0/mobilerun/agent/utils/inference.py +276 -0
  96. mobilerun-0.6.0/mobilerun/agent/utils/llm_loader.py +256 -0
  97. mobilerun-0.6.0/mobilerun/agent/utils/llm_picker.py +267 -0
  98. mobilerun-0.6.0/mobilerun/agent/utils/oauth/anthropic_oauth_llm.py +805 -0
  99. mobilerun-0.6.0/mobilerun/agent/utils/oauth/gemini_oauth_code_assist_llm.py +1032 -0
  100. mobilerun-0.6.0/mobilerun/agent/utils/oauth/openai_oauth_llm.py +1091 -0
  101. mobilerun-0.6.0/mobilerun/agent/utils/prompt_resolver.py +66 -0
  102. mobilerun-0.6.0/mobilerun/agent/utils/signatures.py +323 -0
  103. mobilerun-0.6.0/mobilerun/agent/utils/tracing_setup.py +290 -0
  104. mobilerun-0.6.0/mobilerun/agent/utils/trajectory.py +373 -0
  105. mobilerun-0.6.0/mobilerun/app_cards/__init__.py +0 -0
  106. mobilerun-0.6.0/mobilerun/app_cards/app_card_provider.py +26 -0
  107. mobilerun-0.6.0/mobilerun/app_cards/providers/__init__.py +7 -0
  108. mobilerun-0.6.0/mobilerun/app_cards/providers/composite_provider.py +101 -0
  109. mobilerun-0.6.0/mobilerun/app_cards/providers/local_provider.py +114 -0
  110. mobilerun-0.6.0/mobilerun/app_cards/providers/server_provider.py +120 -0
  111. mobilerun-0.6.0/mobilerun/cli/__init__.py +9 -0
  112. mobilerun-0.6.0/mobilerun/cli/configure_prompts.py +77 -0
  113. mobilerun-0.6.0/mobilerun/cli/configure_wizard.py +652 -0
  114. mobilerun-0.6.0/mobilerun/cli/device_commands.py +283 -0
  115. mobilerun-0.6.0/mobilerun/cli/doctor.py +795 -0
  116. mobilerun-0.6.0/mobilerun/cli/event_handler.py +178 -0
  117. mobilerun-0.6.0/mobilerun/cli/logs.py +9 -0
  118. mobilerun-0.6.0/mobilerun/cli/main.py +1259 -0
  119. mobilerun-0.6.0/mobilerun/cli/oauth_actions.py +119 -0
  120. mobilerun-0.6.0/mobilerun/cli/tui/__init__.py +12 -0
  121. mobilerun-0.6.0/mobilerun/cli/tui/app.py +931 -0
  122. mobilerun-0.6.0/mobilerun/cli/tui/commands.py +71 -0
  123. mobilerun-0.6.0/mobilerun/cli/tui/css/advanced_tab.tcss +3 -0
  124. mobilerun-0.6.0/mobilerun/cli/tui/css/app.tcss +306 -0
  125. mobilerun-0.6.0/mobilerun/cli/tui/css/models_tab.tcss +44 -0
  126. mobilerun-0.6.0/mobilerun/cli/tui/css/settings_screen.tcss +56 -0
  127. mobilerun-0.6.0/mobilerun/cli/tui/settings/__init__.py +6 -0
  128. mobilerun-0.6.0/mobilerun/cli/tui/settings/advanced_tab.py +168 -0
  129. mobilerun-0.6.0/mobilerun/cli/tui/settings/agent_tab.py +70 -0
  130. mobilerun-0.6.0/mobilerun/cli/tui/settings/data.py +286 -0
  131. mobilerun-0.6.0/mobilerun/cli/tui/settings/models_tab.py +281 -0
  132. mobilerun-0.6.0/mobilerun/cli/tui/settings/section.py +49 -0
  133. mobilerun-0.6.0/mobilerun/cli/tui/settings/settings_screen.py +86 -0
  134. mobilerun-0.6.0/mobilerun/cli/tui/widgets/__init__.py +7 -0
  135. mobilerun-0.6.0/mobilerun/cli/tui/widgets/command_dropdown.py +79 -0
  136. mobilerun-0.6.0/mobilerun/cli/tui/widgets/device_picker.py +218 -0
  137. mobilerun-0.6.0/mobilerun/cli/tui/widgets/input_bar.py +138 -0
  138. mobilerun-0.6.0/mobilerun/cli/tui/widgets/log_view.py +47 -0
  139. mobilerun-0.6.0/mobilerun/cli/tui/widgets/status_bar.py +56 -0
  140. mobilerun-0.6.0/mobilerun/config/app_cards/README.md +159 -0
  141. mobilerun-0.6.0/mobilerun/config/app_cards/app_cards.json +3 -0
  142. mobilerun-0.6.0/mobilerun/config/app_cards/gmail.md +35 -0
  143. mobilerun-0.6.0/mobilerun/config/credentials_example.yaml +106 -0
  144. mobilerun-0.6.0/mobilerun/config/prompts/executor/rev1.jinja2 +78 -0
  145. mobilerun-0.6.0/mobilerun/config/prompts/executor/system.jinja2 +109 -0
  146. mobilerun-0.6.0/mobilerun/config/prompts/fast_agent/system.jinja2 +163 -0
  147. mobilerun-0.6.0/mobilerun/config/prompts/fast_agent/user.jinja2 +5 -0
  148. mobilerun-0.6.0/mobilerun/config/prompts/manager/rev1.jinja2 +131 -0
  149. mobilerun-0.6.0/mobilerun/config/prompts/manager/stateless.jinja2 +125 -0
  150. mobilerun-0.6.0/mobilerun/config/prompts/manager/system.jinja2 +138 -0
  151. mobilerun-0.6.0/mobilerun/config/prompts/manager/trained.jinja2 +50 -0
  152. mobilerun-0.6.0/mobilerun/config_example.yaml +237 -0
  153. mobilerun-0.6.0/mobilerun/config_manager/__init__.py +40 -0
  154. mobilerun-0.6.0/mobilerun/config_manager/config_manager.py +394 -0
  155. mobilerun-0.6.0/mobilerun/config_manager/credential_paths.py +17 -0
  156. mobilerun-0.6.0/mobilerun/config_manager/env_keys.py +133 -0
  157. mobilerun-0.6.0/mobilerun/config_manager/loader.py +110 -0
  158. mobilerun-0.6.0/mobilerun/config_manager/migrations/__init__.py +39 -0
  159. mobilerun-0.6.0/mobilerun/config_manager/migrations/v002_add_code_exec.py +43 -0
  160. mobilerun-0.6.0/mobilerun/config_manager/migrations/v003_add_auto_setup.py +12 -0
  161. mobilerun-0.6.0/mobilerun/config_manager/migrations/v004_remove_deprecated_agents.py +41 -0
  162. mobilerun-0.6.0/mobilerun/config_manager/migrations/v005_remove_external_agents.py +15 -0
  163. mobilerun-0.6.0/mobilerun/config_manager/migrations/v006_disabled_tools_default_sentinel.py +33 -0
  164. mobilerun-0.6.0/mobilerun/config_manager/path_resolver.py +112 -0
  165. mobilerun-0.6.0/mobilerun/config_manager/prompt_loader.py +94 -0
  166. mobilerun-0.6.0/mobilerun/credential_manager/__init__.py +13 -0
  167. mobilerun-0.6.0/mobilerun/credential_manager/credential_manager.py +38 -0
  168. mobilerun-0.6.0/mobilerun/credential_manager/file_credential_manager.py +137 -0
  169. mobilerun-0.6.0/mobilerun/log_handlers.py +88 -0
  170. mobilerun-0.6.0/mobilerun/macro/__init__.py +11 -0
  171. mobilerun-0.6.0/mobilerun/macro/__main__.py +10 -0
  172. mobilerun-0.6.0/mobilerun/macro/cli.py +398 -0
  173. mobilerun-0.6.0/mobilerun/macro/handoff.py +30 -0
  174. mobilerun-0.6.0/mobilerun/macro/matcher.py +67 -0
  175. mobilerun-0.6.0/mobilerun/macro/recorder.py +51 -0
  176. mobilerun-0.6.0/mobilerun/macro/replay.py +502 -0
  177. mobilerun-0.6.0/mobilerun/macro/state.py +209 -0
  178. mobilerun-0.6.0/mobilerun/mcp/__init__.py +13 -0
  179. mobilerun-0.6.0/mobilerun/mcp/adapter.py +76 -0
  180. mobilerun-0.6.0/mobilerun/mcp/client.py +162 -0
  181. mobilerun-0.6.0/mobilerun/mcp/config.py +25 -0
  182. mobilerun-0.6.0/mobilerun/portal.py +798 -0
  183. mobilerun-0.6.0/mobilerun/telemetry/__init__.py +19 -0
  184. mobilerun-0.6.0/mobilerun/telemetry/events.py +58 -0
  185. mobilerun-0.6.0/mobilerun/telemetry/langfuse_processor.py +795 -0
  186. mobilerun-0.6.0/mobilerun/telemetry/phoenix.py +223 -0
  187. mobilerun-0.6.0/mobilerun/telemetry/tracker.py +155 -0
  188. mobilerun-0.6.0/mobilerun/tools/__init__.py +17 -0
  189. mobilerun-0.6.0/mobilerun/tools/android/__init__.py +5 -0
  190. mobilerun-0.6.0/mobilerun/tools/android/portal_client.py +744 -0
  191. mobilerun-0.6.0/mobilerun/tools/driver/__init__.py +20 -0
  192. mobilerun-0.6.0/mobilerun/tools/driver/android.py +194 -0
  193. mobilerun-0.6.0/mobilerun/tools/driver/base.py +140 -0
  194. mobilerun-0.6.0/mobilerun/tools/driver/cloud.py +274 -0
  195. mobilerun-0.6.0/mobilerun/tools/driver/ios.py +322 -0
  196. mobilerun-0.6.0/mobilerun/tools/driver/recording.py +106 -0
  197. mobilerun-0.6.0/mobilerun/tools/driver/stealth.py +180 -0
  198. mobilerun-0.6.0/mobilerun/tools/driver/visual_remote.py +294 -0
  199. mobilerun-0.6.0/mobilerun/tools/filters/__init__.py +22 -0
  200. mobilerun-0.6.0/mobilerun/tools/filters/base.py +20 -0
  201. mobilerun-0.6.0/mobilerun/tools/filters/concise_filter.py +68 -0
  202. mobilerun-0.6.0/mobilerun/tools/filters/detailed_filter.py +160 -0
  203. mobilerun-0.6.0/mobilerun/tools/formatters/__init__.py +6 -0
  204. mobilerun-0.6.0/mobilerun/tools/formatters/base.py +27 -0
  205. mobilerun-0.6.0/mobilerun/tools/formatters/indexed_formatter.py +202 -0
  206. mobilerun-0.6.0/mobilerun/tools/helpers/__init__.py +20 -0
  207. mobilerun-0.6.0/mobilerun/tools/helpers/coordinate.py +25 -0
  208. mobilerun-0.6.0/mobilerun/tools/helpers/element_search.py +635 -0
  209. mobilerun-0.6.0/mobilerun/tools/helpers/geometry.py +49 -0
  210. mobilerun-0.6.0/mobilerun/tools/helpers/images.py +196 -0
  211. mobilerun-0.6.0/mobilerun/tools/ios/__init__.py +5 -0
  212. mobilerun-0.6.0/mobilerun/tools/ui/__init__.py +16 -0
  213. mobilerun-0.6.0/mobilerun/tools/ui/ios_provider.py +269 -0
  214. mobilerun-0.6.0/mobilerun/tools/ui/provider.py +252 -0
  215. mobilerun-0.6.0/mobilerun/tools/ui/screenshot_provider.py +71 -0
  216. mobilerun-0.6.0/mobilerun/tools/ui/state.py +175 -0
  217. mobilerun-0.6.0/mobilerun/tools/ui/stealth_state.py +104 -0
  218. mobilerun-0.6.0/pyproject.toml +179 -0
  219. mobilerun-0.6.0/setup.py +8 -0
  220. mobilerun-0.6.0/static/demo-apartment-search.gif +0 -0
  221. mobilerun-0.6.0/static/demo-duolingo-streak.gif +0 -0
  222. mobilerun-0.6.0/static/demo-reddit-trends.gif +0 -0
  223. mobilerun-0.6.0/static/mobilerun-dark.png +0 -0
  224. mobilerun-0.6.0/static/mobilerun-demo.gif +0 -0
  225. mobilerun-0.6.0/static/mobilerun.png +0 -0
  226. mobilerun-0.6.0/tests/test_app_cards.py +95 -0
  227. mobilerun-0.6.0/tests/test_cloud_driver_sdk.py +65 -0
  228. mobilerun-0.6.0/tests/test_fast_agent_xml_parser.py +200 -0
  229. mobilerun-0.6.0/tests/test_macro_guarded_replay.py +255 -0
  230. mobilerun-0.6.0/tests/test_macro_recording_actions.py +240 -0
  231. mobilerun-0.6.0/tests/test_macro_state_matcher.py +47 -0
  232. mobilerun-0.6.0/tests/test_macro_v2_schema.py +68 -0
  233. mobilerun-0.6.0/tests/test_portal_asset_selection.py +320 -0
  234. mobilerun-0.6.0/tests/test_type_action.py +88 -0
  235. mobilerun-0.6.0/tests/test_vision_only_run_cli.py +232 -0
  236. mobilerun-0.6.0/tests/test_visual_remote_connection.py +617 -0
  237. mobilerun-0.6.0/uv.lock +4027 -0
@@ -0,0 +1,5 @@
1
+ *
2
+
3
+ !droidrun
4
+ !pyproject.toml
5
+ !README.md
@@ -0,0 +1,19 @@
1
+ name: Lint
2
+
3
+ on: [push, pull_request]
4
+
5
+ jobs:
6
+ lint:
7
+ runs-on: ubuntu-latest
8
+ steps:
9
+ - uses: actions/checkout@v4
10
+
11
+ - uses: actions/setup-python@v5
12
+ with:
13
+ python-version: "3.13"
14
+
15
+ - uses: psf/black@stable
16
+ with:
17
+ options: "--check --diff --verbose"
18
+ src: "."
19
+ version: "25.9.0"
@@ -0,0 +1,134 @@
1
+ name: "Project V2: Status ← issue label"
2
+
3
+ on:
4
+ issues:
5
+ types: [labeled]
6
+
7
+ env:
8
+ ORG: droidrun
9
+ PROJECT_NUMBER: 2
10
+ PROJECT_TOKEN: ${{ secrets.BOUNTY_SECRET }}
11
+
12
+ jobs:
13
+ update_status:
14
+ runs-on: ubuntu-latest
15
+ steps:
16
+
17
+ - name: Fetch project & field metadata
18
+ id: metadata
19
+ env:
20
+ GH_TOKEN: ${{ env.PROJECT_TOKEN }}
21
+ run: |
22
+ # 1) Query projectV2 ID and the Status field + its options
23
+ gh api graphql -f query='
24
+ query($org:String!,$num:Int!){
25
+ organization(login:$org){
26
+ projectV2(number:$num){
27
+ id
28
+ fields(first:20){
29
+ nodes{
30
+ ... on ProjectV2SingleSelectField{
31
+ id
32
+ name
33
+ options { id name }
34
+ }
35
+ }
36
+ }
37
+ }
38
+ }
39
+ }' \
40
+ -f org="${ORG}" -F num=${PROJECT_NUMBER} \
41
+ --jq '
42
+ .data.organization.projectV2 as $p |
43
+ ($p.id) as $projId |
44
+ ($p.fields.nodes[] | select(.name=="Status")) as $f |
45
+ {
46
+ projectId: $projId,
47
+ statusFieldId: $f.id,
48
+ options: ($f.options | map({(.name): .id}) | add)
49
+ }
50
+ ' > meta.json
51
+
52
+ # expose to GH env
53
+ echo "PROJECT_ID=$(jq -r .projectId meta.json)" >> $GITHUB_ENV
54
+ echo "STATUS_FIELD_ID=$(jq -r .statusFieldId meta.json)" >> $GITHUB_ENV
55
+ # options is an object like {"Eligible":"ID1","Bounty Posted":"ID2",...}
56
+ echo "STATUS_OPTIONS=$(jq -c .options meta.json)" >> $GITHUB_ENV
57
+
58
+ - name: Determine target option ID
59
+ id: pick
60
+ run: |
61
+ LABEL="${{ github.event.label.name }}"
62
+ # map label→ field option name
63
+ case "$LABEL" in
64
+ eligible) OPT_NAME="📝 Eligible" ;;
65
+ bounty-official) OPT_NAME="💰 Bounty" ;;
66
+ claimed) OPT_NAME="🛠️ In Progress" ;;
67
+ *) echo "No matching status for $LABEL"; exit 78 ;;
68
+ esac
69
+
70
+ # extract from JSON map
71
+ OPT_ID=$(echo "$STATUS_OPTIONS" | jq -r --arg name "$OPT_NAME" '.[$name]')
72
+ echo "OPTION_ID=$OPT_ID" >> $GITHUB_ENV
73
+
74
+ - name: Ensure issue is in the project
75
+ id: add_if_missing
76
+ env:
77
+ GH_TOKEN: ${{ env.PROJECT_TOKEN }}
78
+ run: |
79
+ ISSUE_NODE_ID=$(gh api graphql -f query='
80
+ query($owner:String!,$repo:String!,$number:Int!){
81
+ repository(owner:$owner, name:$repo){
82
+ issue(number:$number){
83
+ id
84
+ projectItems(first:1){
85
+ nodes{ id }
86
+ }
87
+ }
88
+ }
89
+ }' \
90
+ -f owner="droidrun" \
91
+ -f repo="mobilerun" \
92
+ -F number=104 \
93
+ --jq '.data.repository.issue as $i |
94
+ { issueId: $i.id,
95
+ itemId: ($i.projectItems.nodes[0]?.id // "") }' )
96
+
97
+ # Save to file
98
+ echo "$ISSUE_NODE_ID" > issue.json
99
+ ISSUE_ID=$(jq -r .issueId issue.json)
100
+ ITEM_ID=$(jq -r .itemId issue.json)
101
+
102
+ if [ -z "$ITEM_ID" ]; then
103
+ ITEM_ID=$(gh api graphql -f query='
104
+ mutation($proj:ID!,$content:ID!){
105
+ addProjectV2ItemById(input:{projectId:$proj, contentId:$content}){
106
+ item { id }
107
+ }
108
+ }' \
109
+ -f proj="${PROJECT_ID}" -f content="$ISSUE_ID" \
110
+ --jq '.data.addProjectV2ItemById.item.id')
111
+ fi
112
+ echo "ITEM_ID=$ITEM_ID" >> $GITHUB_ENV
113
+
114
+ - name: Update Status field
115
+ env:
116
+ GH_TOKEN: ${{ env.PROJECT_TOKEN }}
117
+ run: |
118
+ gh api graphql -f query='
119
+ mutation($proj:ID!,$item:ID!,$field:ID!,$opt:String!){
120
+ updateProjectV2ItemFieldValue(input:{
121
+ projectId: $proj,
122
+ itemId: $item,
123
+ fieldId: $field,
124
+ value: {
125
+ singleSelectOptionId: $opt
126
+ }
127
+ }) {
128
+ projectV2Item { id }
129
+ }
130
+ }' \
131
+ -f proj="${PROJECT_ID}" \
132
+ -f item="${ITEM_ID}" \
133
+ -f field="${STATUS_FIELD_ID}" \
134
+ -f opt="${OPTION_ID}"
@@ -0,0 +1,57 @@
1
+ name: Claude Code Review
2
+
3
+ on:
4
+ pull_request:
5
+ types: [opened, synchronize]
6
+ # Optional: Only run on specific file changes
7
+ # paths:
8
+ # - "src/**/*.ts"
9
+ # - "src/**/*.tsx"
10
+ # - "src/**/*.js"
11
+ # - "src/**/*.jsx"
12
+
13
+ jobs:
14
+ claude-review:
15
+ # Optional: Filter by PR author
16
+ # if: |
17
+ # github.event.pull_request.user.login == 'external-contributor' ||
18
+ # github.event.pull_request.user.login == 'new-developer' ||
19
+ # github.event.pull_request.author_association == 'FIRST_TIME_CONTRIBUTOR'
20
+
21
+ runs-on: ubuntu-latest
22
+ permissions:
23
+ contents: read
24
+ pull-requests: write
25
+ issues: read
26
+ id-token: write
27
+
28
+ steps:
29
+ - name: Checkout repository
30
+ uses: actions/checkout@v4
31
+ with:
32
+ fetch-depth: 1
33
+
34
+ - name: Run Claude Code Review
35
+ id: claude-review
36
+ uses: anthropics/claude-code-action@v1
37
+ with:
38
+ claude_code_oauth_token: ${{ secrets.CLAUDE_CODE_OAUTH_TOKEN }}
39
+ github_token: ${{ secrets.GITHUB_TOKEN }}
40
+ prompt: |
41
+ REPO: ${{ github.repository }}
42
+ PR NUMBER: ${{ github.event.pull_request.number }}
43
+
44
+ Please review this pull request and provide feedback on:
45
+ - Code quality and best practices
46
+ - Potential bugs or issues
47
+ - Performance considerations
48
+ - Security concerns
49
+ - Test coverage
50
+
51
+ Use the repository's CLAUDE.md for guidance on style and conventions. Be constructive and helpful in your feedback.
52
+
53
+ Use `gh pr comment` with your Bash tool to leave your review as a comment on the PR.
54
+
55
+ # See https://github.com/anthropics/claude-code-action/blob/main/docs/usage.md
56
+ # or https://docs.claude.com/en/docs/claude-code/cli-reference for available options
57
+ claude_args: '--allowed-tools "Bash(gh issue view:*),Bash(gh search:*),Bash(gh issue list:*),Bash(gh pr comment:*),Bash(gh pr diff:*),Bash(gh pr view:*),Bash(gh pr list:*)"'
@@ -0,0 +1,50 @@
1
+ name: Claude Code
2
+
3
+ on:
4
+ issue_comment:
5
+ types: [created]
6
+ pull_request_review_comment:
7
+ types: [created]
8
+ issues:
9
+ types: [opened, assigned]
10
+ pull_request_review:
11
+ types: [submitted]
12
+
13
+ jobs:
14
+ claude:
15
+ if: |
16
+ (github.event_name == 'issue_comment' && contains(github.event.comment.body, '@claude')) ||
17
+ (github.event_name == 'pull_request_review_comment' && contains(github.event.comment.body, '@claude')) ||
18
+ (github.event_name == 'pull_request_review' && contains(github.event.review.body, '@claude')) ||
19
+ (github.event_name == 'issues' && (contains(github.event.issue.body, '@claude') || contains(github.event.issue.title, '@claude')))
20
+ runs-on: ubuntu-latest
21
+ permissions:
22
+ contents: read
23
+ pull-requests: read
24
+ issues: read
25
+ id-token: write
26
+ actions: read # Required for Claude to read CI results on PRs
27
+ steps:
28
+ - name: Checkout repository
29
+ uses: actions/checkout@v4
30
+ with:
31
+ fetch-depth: 1
32
+
33
+ - name: Run Claude Code
34
+ id: claude
35
+ uses: anthropics/claude-code-action@v1
36
+ with:
37
+ claude_code_oauth_token: ${{ secrets.CLAUDE_CODE_OAUTH_TOKEN }}
38
+
39
+ # This is an optional setting that allows Claude to read CI results on PRs
40
+ additional_permissions: |
41
+ actions: read
42
+
43
+ # Optional: Give a custom prompt to Claude. If this is not specified, Claude will perform the instructions specified in the comment that tagged it.
44
+ # prompt: 'Update the pull request description to include a summary of changes.'
45
+
46
+ # Optional: Add claude_args to customize behavior and configuration
47
+ # See https://github.com/anthropics/claude-code-action/blob/main/docs/usage.md
48
+ # or https://docs.claude.com/en/docs/claude-code/cli-reference for available options
49
+ # claude_args: '--allowed-tools Bash(gh pr:*)'
50
+
@@ -0,0 +1,54 @@
1
+ name: Publish Docker Image 🐳
2
+
3
+ on:
4
+ push:
5
+ tags:
6
+ - "v*"
7
+
8
+ env:
9
+ REGISTRY: ghcr.io
10
+ IMAGE_NAME: ${{ github.repository }}
11
+
12
+ jobs:
13
+ push-image:
14
+ runs-on: ubuntu-latest
15
+
16
+ permissions:
17
+ contents: read
18
+ packages: write
19
+ attestations: write
20
+ id-token: write
21
+
22
+ steps:
23
+ - name: Checkout repository
24
+ uses: actions/checkout@v5
25
+
26
+ - name: Set up QEMU
27
+ uses: docker/setup-qemu-action@v3
28
+ with:
29
+ platforms: all
30
+
31
+ - name: Set up Docker Buildx
32
+ uses: docker/setup-buildx-action@v3
33
+
34
+ - name: Log in to the Container registry
35
+ uses: docker/login-action@v3
36
+ with:
37
+ registry: ${{ env.REGISTRY }}
38
+ username: ${{ github.actor }}
39
+ password: ${{ secrets.GITHUB_TOKEN }}
40
+
41
+ - name: Extract metadata (tags, labels) for Docker
42
+ id: meta
43
+ uses: docker/metadata-action@v5
44
+ with:
45
+ images: ${{ env.REGISTRY }}/${{ env.IMAGE_NAME }}
46
+
47
+ - name: Build and push multi-arch Docker image
48
+ uses: docker/build-push-action@v6
49
+ with:
50
+ context: .
51
+ push: true
52
+ platforms: linux/amd64,linux/arm64
53
+ tags: ${{ steps.meta.outputs.tags }}
54
+ labels: ${{ steps.meta.outputs.labels }}
@@ -0,0 +1,109 @@
1
+ name: Publish Python 🐍 distribution 📦 to PyPI and TestPyPI
2
+ on: push
3
+
4
+ jobs:
5
+ version-check:
6
+ name: Check version matches tag and compat shim
7
+ if: startsWith(github.ref, 'refs/tags/v')
8
+ runs-on: ubuntu-latest
9
+ steps:
10
+ - uses: actions/checkout@v4
11
+ - name: Compare tag to root and compat versions, verify dependency pin
12
+ run: |
13
+ TAG="${GITHUB_REF#refs/tags/v}"
14
+ ROOT_VERSION=$(sed -n 's/^version = "\(.*\)"/\1/p' pyproject.toml)
15
+ COMPAT_VERSION=$(sed -n 's/^version = "\(.*\)"/\1/p' compat/pyproject.toml)
16
+
17
+ if [ "$TAG" != "$ROOT_VERSION" ]; then
18
+ echo "::error::Tag v$TAG does not match pyproject.toml version $ROOT_VERSION"
19
+ exit 1
20
+ fi
21
+ if [ "$ROOT_VERSION" != "$COMPAT_VERSION" ]; then
22
+ echo "::error::Version mismatch: root=$ROOT_VERSION compat=$COMPAT_VERSION"
23
+ exit 1
24
+ fi
25
+ if ! grep -q "mobilerun==$ROOT_VERSION" compat/pyproject.toml; then
26
+ echo "::error::compat/pyproject.toml does not pin mobilerun==$ROOT_VERSION"
27
+ exit 1
28
+ fi
29
+ echo "Version check passed: v$ROOT_VERSION (root + compat aligned)"
30
+
31
+ build:
32
+ name: Build mobilerun + droidrun shim 📦
33
+ needs:
34
+ - version-check
35
+ if: startsWith(github.ref, 'refs/tags/v')
36
+ runs-on: ubuntu-latest
37
+ steps:
38
+ - uses: actions/checkout@v4
39
+ with:
40
+ persist-credentials: false
41
+ - name: Set up Python
42
+ uses: actions/setup-python@v5
43
+ with:
44
+ python-version: "3.x"
45
+ - name: Install pypa/build
46
+ run: python3 -m pip install build --user
47
+ - name: Build mobilerun (root package)
48
+ run: python3 -m build
49
+ - name: Build droidrun (compat shim)
50
+ run: python3 -m build compat/
51
+ - name: Merge compat artifacts into dist/
52
+ run: cp compat/dist/* dist/
53
+ - name: Verify both packages built
54
+ run: |
55
+ ls dist/mobilerun-*.whl dist/mobilerun-*.tar.gz
56
+ ls dist/droidrun-*.whl dist/droidrun-*.tar.gz
57
+ - name: Store the distribution packages
58
+ uses: actions/upload-artifact@v4
59
+ with:
60
+ name: python-package-distributions
61
+ path: dist/
62
+
63
+ publish-to-testpypi:
64
+ name: Publish mobilerun + droidrun shim to TestPyPI
65
+ if: startsWith(github.ref, 'refs/tags/v')
66
+ needs:
67
+ - build
68
+ runs-on: ubuntu-latest
69
+ environment:
70
+ name: testpypi
71
+ url: https://test.pypi.org/p/mobilerun
72
+ permissions:
73
+ id-token: write
74
+ steps:
75
+ - name: Download all the dists
76
+ uses: actions/download-artifact@v4
77
+ with:
78
+ name: python-package-distributions
79
+ path: dist/
80
+ - name: Publish both packages to TestPyPI
81
+ # Each wheel is routed to its matching PyPI project via OIDC.
82
+ # Both 'mobilerun' and 'droidrun' projects on TestPyPI must have this
83
+ # workflow configured as a trusted publisher (environment: testpypi).
84
+ uses: pypa/gh-action-pypi-publish@release/v1
85
+ with:
86
+ repository-url: https://test.pypi.org/legacy/
87
+
88
+ publish-to-pypi:
89
+ name: Publish mobilerun + droidrun shim to PyPI
90
+ if: startsWith(github.ref, 'refs/tags/v')
91
+ needs:
92
+ - publish-to-testpypi
93
+ runs-on: ubuntu-latest
94
+ environment:
95
+ name: pypi
96
+ url: https://pypi.org/p/mobilerun
97
+ permissions:
98
+ id-token: write
99
+ steps:
100
+ - name: Download all the dists
101
+ uses: actions/download-artifact@v4
102
+ with:
103
+ name: python-package-distributions
104
+ path: dist/
105
+ - name: Publish both packages to PyPI
106
+ # Each wheel is routed to its matching PyPI project via OIDC.
107
+ # Both 'mobilerun' and 'droidrun' projects on PyPI must have this
108
+ # workflow configured as a trusted publisher (environment: pypi).
109
+ uses: pypa/gh-action-pypi-publish@release/v1
@@ -0,0 +1,43 @@
1
+ dist/
2
+ build/
3
+ # Python bytecode files
4
+ __pycache__/
5
+ *.py[cod]
6
+ *$py.class
7
+ trajectories/
8
+ *.class
9
+
10
+ test.py
11
+ test.ipynb
12
+ *.log
13
+
14
+ messages_log.json
15
+
16
+ .idea
17
+ .vscode
18
+ .vscode-test
19
+ .vscode-test-*
20
+ .idea/*
21
+ .vscode/*
22
+ patch_apis.py
23
+ .git
24
+ .arize-phoenix
25
+
26
+ todo.txt
27
+
28
+ config.yaml
29
+
30
+ credentials.yaml
31
+ **/credentials.yaml
32
+ !**/credentials_example.yaml
33
+
34
+ .*/
35
+ !.gitignore
36
+ !.github/
37
+
38
+ backend/
39
+ frontend/
40
+
41
+ reddit_python_posts.json
42
+
43
+ test/
@@ -0,0 +1 @@
1
+ 3.13
@@ -0,0 +1,113 @@
1
+ # Contributing to Mobilerun
2
+
3
+ Thank you for your interest in contributing to Mobilerun! This document provides guidelines and instructions for contributing to the project.
4
+
5
+ ## Getting Started
6
+
7
+ 1. Fork the repository on GitHub
8
+ 2. Clone your fork:
9
+ ```bash
10
+ git clone https://github.com/YOUR_USERNAME/mobilerun.git
11
+ cd mobilerun
12
+ ```
13
+ 3. Set up your development environment as described below
14
+
15
+ ## Development Setup
16
+
17
+ 1. Create and activate a virtual environment:
18
+ ```bash
19
+ python -m venv .venv
20
+ source .venv/bin/activate # On Windows: .venv\Scripts\activate
21
+ ```
22
+
23
+ 2. Install development dependencies:
24
+ ```bash
25
+ pip install -e ".[dev]"
26
+ ```
27
+
28
+ ## Making Contributions
29
+
30
+ 1. Create a new branch for your feature:
31
+ ```bash
32
+ git checkout -b feature/your-feature-name
33
+ ```
34
+
35
+ 2. Make your changes following our coding standards:
36
+ - Use type hints for Python functions
37
+ - Follow PEP 8 style guidelines
38
+ - Write descriptive commit messages
39
+ - Update documentation as needed
40
+
41
+ 3. Commit your changes:
42
+ ```bash
43
+ git add .
44
+ git commit -m "feat: add your feature description"
45
+ ```
46
+
47
+ 4. Push to your fork:
48
+ ```bash
49
+ git push origin feature/your-feature-name
50
+ ```
51
+
52
+ 5. Open a Pull Request
53
+
54
+ ## Documentation
55
+
56
+ - Update the README.md if you change functionality
57
+ - Add docstrings to new functions and classes
58
+ - Update the documentation in the `docs/` directory
59
+
60
+ ## Community
61
+
62
+ - Join our [Discord server](https://discord.gg/ZZbKEZZkwK) for discussions
63
+ - Follow us on [Twitter/X](https://x.com/mobilerun_ai)
64
+ - Check our [Documentation](https://docs.mobilerun.ai)
65
+ - Report bugs and request features through [GitHub Issues](https://github.com/droidrun/mobilerun/issues)
66
+
67
+ ## Security Checks
68
+
69
+ To ensure the security of the codebase, we have integrated security checks using `bandit` and `safety`. These tools help identify potential security issues in the code and dependencies.
70
+
71
+ ### Running Security Checks
72
+
73
+ Before submitting any code, please run the following security checks:
74
+
75
+ 1. **Bandit**: A tool to find common security issues in Python code.
76
+ ```bash
77
+ bandit -r mobilerun
78
+ ```
79
+
80
+ 2. **Safety**: A tool to check your installed dependencies for known security vulnerabilities.
81
+ ```bash
82
+ safety scan
83
+ ```
84
+
85
+ ## Pull Request Process
86
+
87
+ 1. Update documentation for any modified functionality
88
+ 2. Update the changelog if applicable
89
+ 3. Get at least one code review from a maintainer
90
+ 4. Once approved, a maintainer will merge your PR
91
+
92
+ ## Release Process
93
+
94
+ Releases are handled by the maintainers. Version numbers follow [Semantic Versioning](https://semver.org/).
95
+
96
+ ## Questions?
97
+
98
+ If you have questions about contributing:
99
+ 1. Check existing GitHub issues
100
+ 2. Ask in our Discord server
101
+ 3. Open a new GitHub issue for complex questions
102
+
103
+ Thank you for contributing to Mobilerun! 🚀
104
+
105
+ ## Language
106
+
107
+ English is the preferred language for all contributions, including:
108
+ - Code comments
109
+ - Documentation
110
+ - Commit messages
111
+ - Pull requests
112
+ - Issue reports
113
+ - Community discussions
@@ -0,0 +1,27 @@
1
+ FROM python:3.12-slim
2
+
3
+ RUN groupadd -g 1000 mobilerun \
4
+ && useradd -m -u 1000 -g 1000 -s /bin/bash mobilerun
5
+
6
+ RUN apt-get update && \
7
+ apt-get install -y --no-install-recommends \
8
+ curl \
9
+ android-tools-adb \
10
+ && rm -rf /var/lib/apt/lists/*
11
+
12
+ USER mobilerun
13
+
14
+ WORKDIR /mobilerun
15
+
16
+ RUN curl -LsSf https://astral.sh/uv/install.sh | sh
17
+
18
+ ENV PATH="/home/mobilerun/.local/bin:${PATH}"
19
+
20
+ COPY . .
21
+
22
+ RUN uv venv && \
23
+ uv pip --no-cache-dir install .[google,anthropic,openai,deepseek,ollama,openrouter]
24
+
25
+ ENTRYPOINT [".venv/bin/mobilerun"]
26
+
27
+ CMD ["setup"]
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2025 Niels Schmidt
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
@@ -0,0 +1,7 @@
1
+ include LICENSE
2
+ include README.md
3
+ include pyproject.toml
4
+
5
+ recursive-include mobilerun *
6
+ recursive-exclude * __pycache__
7
+ recursive-exclude * *.py[cod]