android-midscene-automation 0.2.3 → 1.1.0

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 (525) hide show
  1. package/CHANGELOG.md +11 -1
  2. package/README.md +63 -1
  3. package/artemis-main/.dockerignore +15 -0
  4. package/artemis-main/.env.example +34 -0
  5. package/artemis-main/CONTRIBUTING.md +35 -0
  6. package/artemis-main/Dockerfile +68 -0
  7. package/artemis-main/LICENSE +202 -0
  8. package/artemis-main/Makefile +115 -0
  9. package/artemis-main/README.md +322 -0
  10. package/artemis-main/README_CN.md +320 -0
  11. package/artemis-main/apps/__init__.py +15 -0
  12. package/artemis-main/apps/admin_console/__init__.py +19 -0
  13. package/artemis-main/apps/admin_console/core/__init__.py +13 -0
  14. package/artemis-main/apps/admin_console/core/config.py +43 -0
  15. package/artemis-main/apps/admin_console/core/security.py +178 -0
  16. package/artemis-main/apps/admin_console/core/state.py +243 -0
  17. package/artemis-main/apps/admin_console/database/__init__.py +13 -0
  18. package/artemis-main/apps/admin_console/database/connection.py +60 -0
  19. package/artemis-main/apps/admin_console/database/repositories/__init__.py +13 -0
  20. package/artemis-main/apps/admin_console/database/repositories/session_repository.py +564 -0
  21. package/artemis-main/apps/admin_console/database/repositories/step_repository.py +512 -0
  22. package/artemis-main/apps/admin_console/database/repositories/trace_repository.py +133 -0
  23. package/artemis-main/apps/admin_console/index.html +3787 -0
  24. package/artemis-main/apps/admin_console/replay_manager.py +2585 -0
  25. package/artemis-main/apps/admin_console/routers/__init__.py +13 -0
  26. package/artemis-main/apps/admin_console/routers/media.py +198 -0
  27. package/artemis-main/apps/admin_console/routers/replay.py +91 -0
  28. package/artemis-main/apps/admin_console/routers/sessions.py +239 -0
  29. package/artemis-main/apps/admin_console/routers/steps.py +109 -0
  30. package/artemis-main/apps/admin_console/routers/stream.py +56 -0
  31. package/artemis-main/apps/admin_console/routers/system.py +761 -0
  32. package/artemis-main/apps/admin_console/routers/tasks.py +517 -0
  33. package/artemis-main/apps/admin_console/schemas/__init__.py +13 -0
  34. package/artemis-main/apps/admin_console/schemas/task_schema.py +47 -0
  35. package/artemis-main/apps/admin_console/server.py +508 -0
  36. package/artemis-main/apps/admin_console/services/__init__.py +13 -0
  37. package/artemis-main/apps/admin_console/services/device_stream_service.py +137 -0
  38. package/artemis-main/apps/admin_console/services/ipc_service.py +262 -0
  39. package/artemis-main/apps/admin_console/services/media_service.py +623 -0
  40. package/artemis-main/apps/admin_console/services/model_service.py +148 -0
  41. package/artemis-main/apps/admin_console/services/task_preset_catalog.py +514 -0
  42. package/artemis-main/apps/admin_console/services/task_queue_service.py +1719 -0
  43. package/artemis-main/apps/admin_console/services/worker_process_io.py +144 -0
  44. package/artemis-main/apps/showcase_ui/README.md +31 -0
  45. package/artemis-main/apps/showcase_ui/angular.json +132 -0
  46. package/artemis-main/apps/showcase_ui/package-lock.json +9472 -0
  47. package/artemis-main/apps/showcase_ui/package.json +39 -0
  48. package/artemis-main/apps/showcase_ui/proxy.conf.json +23 -0
  49. package/artemis-main/apps/showcase_ui/public/favicon.ico +0 -0
  50. package/artemis-main/apps/showcase_ui/public/logo.png +0 -0
  51. package/artemis-main/apps/showcase_ui/public/logo.svg +56 -0
  52. package/artemis-main/apps/showcase_ui/src/app/app.component.html +24 -0
  53. package/artemis-main/apps/showcase_ui/src/app/app.component.scss +49 -0
  54. package/artemis-main/apps/showcase_ui/src/app/app.component.spec.ts +42 -0
  55. package/artemis-main/apps/showcase_ui/src/app/app.component.ts +32 -0
  56. package/artemis-main/apps/showcase_ui/src/app/app.config.ts +29 -0
  57. package/artemis-main/apps/showcase_ui/src/app/app.routes.ts +27 -0
  58. package/artemis-main/apps/showcase_ui/src/app/components/agent-stream/agent-stream-startup.spec.ts +108 -0
  59. package/artemis-main/apps/showcase_ui/src/app/components/agent-stream/agent-stream.component.html +1436 -0
  60. package/artemis-main/apps/showcase_ui/src/app/components/agent-stream/agent-stream.component.scss +3973 -0
  61. package/artemis-main/apps/showcase_ui/src/app/components/agent-stream/agent-stream.component.ts +2235 -0
  62. package/artemis-main/apps/showcase_ui/src/app/components/chat-interface/chat-interface.component.html +380 -0
  63. package/artemis-main/apps/showcase_ui/src/app/components/chat-interface/chat-interface.component.scss +1171 -0
  64. package/artemis-main/apps/showcase_ui/src/app/components/chat-interface/chat-interface.component.ts +270 -0
  65. package/artemis-main/apps/showcase_ui/src/app/components/floating-video-player/floating-video-player.component.html +433 -0
  66. package/artemis-main/apps/showcase_ui/src/app/components/floating-video-player/floating-video-player.component.scss +987 -0
  67. package/artemis-main/apps/showcase_ui/src/app/components/floating-video-player/floating-video-player.component.ts +632 -0
  68. package/artemis-main/apps/showcase_ui/src/app/components/legacy-agent-stream/legacy-agent-stream.component.html +130 -0
  69. package/artemis-main/apps/showcase_ui/src/app/components/legacy-agent-stream/legacy-agent-stream.component.scss +406 -0
  70. package/artemis-main/apps/showcase_ui/src/app/components/legacy-agent-stream/legacy-agent-stream.component.ts +74 -0
  71. package/artemis-main/apps/showcase_ui/src/app/components/nav-switcher/nav-switcher.component.scss +115 -0
  72. package/artemis-main/apps/showcase_ui/src/app/components/nav-switcher/nav-switcher.component.ts +52 -0
  73. package/artemis-main/apps/showcase_ui/src/app/core/data/smart-tasks.data.ts +334 -0
  74. package/artemis-main/apps/showcase_ui/src/app/core/i18n/language.service.spec.ts +55 -0
  75. package/artemis-main/apps/showcase_ui/src/app/core/i18n/language.service.ts +61 -0
  76. package/artemis-main/apps/showcase_ui/src/app/core/i18n/translate.pipe.ts +11 -0
  77. package/artemis-main/apps/showcase_ui/src/app/core/i18n/zh-cn.ts +651 -0
  78. package/artemis-main/apps/showcase_ui/src/app/core/models/markdown.model.ts +43 -0
  79. package/artemis-main/apps/showcase_ui/src/app/core/models/pro-tuning.model.spec.ts +47 -0
  80. package/artemis-main/apps/showcase_ui/src/app/core/models/pro-tuning.model.ts +165 -0
  81. package/artemis-main/apps/showcase_ui/src/app/core/models/session.model.ts +85 -0
  82. package/artemis-main/apps/showcase_ui/src/app/core/models/stream.model.ts +246 -0
  83. package/artemis-main/apps/showcase_ui/src/app/core/models/system.model.ts +118 -0
  84. package/artemis-main/apps/showcase_ui/src/app/core/services/task-recommendation.service.ts +111 -0
  85. package/artemis-main/apps/showcase_ui/src/app/pages/home/home.component.html +2130 -0
  86. package/artemis-main/apps/showcase_ui/src/app/pages/home/home.component.scss +5204 -0
  87. package/artemis-main/apps/showcase_ui/src/app/pages/home/home.component.ts +1189 -0
  88. package/artemis-main/apps/showcase_ui/src/app/pages/legacy-workspace/legacy-workspace.component.html +39 -0
  89. package/artemis-main/apps/showcase_ui/src/app/pages/legacy-workspace/legacy-workspace.component.scss +151 -0
  90. package/artemis-main/apps/showcase_ui/src/app/pages/legacy-workspace/legacy-workspace.component.ts +58 -0
  91. package/artemis-main/apps/showcase_ui/src/app/pages/workspace/workspace.component.html +201 -0
  92. package/artemis-main/apps/showcase_ui/src/app/pages/workspace/workspace.component.scss +886 -0
  93. package/artemis-main/apps/showcase_ui/src/app/pages/workspace/workspace.component.ts +324 -0
  94. package/artemis-main/apps/showcase_ui/src/app/services/agent.service.spec.ts +418 -0
  95. package/artemis-main/apps/showcase_ui/src/app/services/agent.service.ts +2012 -0
  96. package/artemis-main/apps/showcase_ui/src/app/services/system.service.spec.ts +173 -0
  97. package/artemis-main/apps/showcase_ui/src/app/services/system.service.ts +620 -0
  98. package/artemis-main/apps/showcase_ui/src/app/utils/action-formatter.util.spec.ts +513 -0
  99. package/artemis-main/apps/showcase_ui/src/app/utils/action-formatter.util.ts +1015 -0
  100. package/artemis-main/apps/showcase_ui/src/app/utils/image-overlay.util.spec.ts +85 -0
  101. package/artemis-main/apps/showcase_ui/src/app/utils/image-overlay.util.ts +662 -0
  102. package/artemis-main/apps/showcase_ui/src/app/utils/markdown-parser.util.spec.ts +70 -0
  103. package/artemis-main/apps/showcase_ui/src/app/utils/markdown-parser.util.ts +383 -0
  104. package/artemis-main/apps/showcase_ui/src/app/utils/recording-timeline.util.spec.ts +107 -0
  105. package/artemis-main/apps/showcase_ui/src/app/utils/recording-timeline.util.ts +123 -0
  106. package/artemis-main/apps/showcase_ui/src/app/utils/run-info.util.spec.ts +92 -0
  107. package/artemis-main/apps/showcase_ui/src/app/utils/run-info.util.ts +116 -0
  108. package/artemis-main/apps/showcase_ui/src/app/utils/stream-aggregator.util.spec.ts +640 -0
  109. package/artemis-main/apps/showcase_ui/src/app/utils/stream-aggregator.util.ts +1021 -0
  110. package/artemis-main/apps/showcase_ui/src/app/utils/tool-formatter.util.spec.ts +375 -0
  111. package/artemis-main/apps/showcase_ui/src/app/utils/tool-formatter.util.ts +1419 -0
  112. package/artemis-main/apps/showcase_ui/src/index.html +37 -0
  113. package/artemis-main/apps/showcase_ui/src/main.ts +22 -0
  114. package/artemis-main/apps/showcase_ui/src/styles.scss +60 -0
  115. package/artemis-main/apps/showcase_ui/tsconfig.app.json +23 -0
  116. package/artemis-main/apps/showcase_ui/tsconfig.json +27 -0
  117. package/artemis-main/apps/showcase_ui/tsconfig.spec.json +23 -0
  118. package/artemis-main/artemis/__init__.py +44 -0
  119. package/artemis-main/artemis/__main__.py +18 -0
  120. package/artemis-main/artemis/_legacy_imports.py +94 -0
  121. package/artemis-main/artemis/_version.py +30 -0
  122. package/artemis-main/artemis/agents/__init__.py +17 -0
  123. package/artemis-main/artemis/agents/checker/checker.json +9 -0
  124. package/artemis-main/artemis/agents/checker/checker.py +859 -0
  125. package/artemis-main/artemis/agents/diagnoser/diagnoser.json +23 -0
  126. package/artemis-main/artemis/agents/diagnoser/diagnoser.py +608 -0
  127. package/artemis-main/artemis/agents/explorer/constants.py +52 -0
  128. package/artemis-main/artemis/agents/explorer/explorer.json +57 -0
  129. package/artemis-main/artemis/agents/explorer/explorer.py +473 -0
  130. package/artemis-main/artemis/agents/explorer/geometry.py +73 -0
  131. package/artemis-main/artemis/agents/explorer/native_runner.py +878 -0
  132. package/artemis-main/artemis/agents/explorer/perception_tools.py +632 -0
  133. package/artemis-main/artemis/agents/explorer/run_setup.py +403 -0
  134. package/artemis-main/artemis/agents/explorer/screen_index.py +266 -0
  135. package/artemis-main/artemis/agents/explorer/tiers.py +110 -0
  136. package/artemis-main/artemis/agents/explorer/tool_declarations.py +394 -0
  137. package/artemis-main/artemis/agents/explorer/universal_runner.py +317 -0
  138. package/artemis-main/artemis/agents/flash/context_compressor.py +452 -0
  139. package/artemis-main/artemis/agents/flash/flash_runner.md +51 -0
  140. package/artemis-main/artemis/agents/flash/flash_summarizer.md +53 -0
  141. package/artemis-main/artemis/agents/flash/flash_summarizer_single.md +54 -0
  142. package/artemis-main/artemis/agents/flash/runner.py +1167 -0
  143. package/artemis-main/artemis/agents/flash/summarizer.py +511 -0
  144. package/artemis-main/artemis/agents/history_analyzer/history_analyzer.md +8 -0
  145. package/artemis-main/artemis/agents/history_analyzer/history_analyzer.py +182 -0
  146. package/artemis-main/artemis/agents/image_processor/image_processor.md +74 -0
  147. package/artemis-main/artemis/agents/image_processor/image_processor.py +322 -0
  148. package/artemis-main/artemis/agents/log_analyzer/log_analyzer.md +15 -0
  149. package/artemis-main/artemis/agents/log_analyzer/log_analyzer.py +403 -0
  150. package/artemis-main/artemis/agents/log_analyzer/log_reader_sub_agent.md +8 -0
  151. package/artemis-main/artemis/agents/log_analyzer/output_analyzer.md +11 -0
  152. package/artemis-main/artemis/agents/log_analyzer/output_analyzer.py +163 -0
  153. package/artemis-main/artemis/agents/object_detector/object_detector.json +9 -0
  154. package/artemis-main/artemis/agents/object_detector/object_detector.py +211 -0
  155. package/artemis-main/artemis/agents/operator/operator.json +3 -0
  156. package/artemis-main/artemis/agents/operator/operator.py +1394 -0
  157. package/artemis-main/artemis/agents/operator/prompts.py +1064 -0
  158. package/artemis-main/artemis/agents/outputter/outputter.md +36 -0
  159. package/artemis-main/artemis/agents/outputter/outputter.py +552 -0
  160. package/artemis-main/artemis/agents/planner/planner.json +32 -0
  161. package/artemis-main/artemis/agents/planner/planner.py +436 -0
  162. package/artemis-main/artemis/agents/prompt_assembly.py +79 -0
  163. package/artemis-main/artemis/agents/summarizer/summarizer.py +190 -0
  164. package/artemis-main/artemis/agents/validator/action_execution.py +98 -0
  165. package/artemis-main/artemis/agents/validator/categories.py +33 -0
  166. package/artemis-main/artemis/agents/validator/execution_loop.py +488 -0
  167. package/artemis-main/artemis/agents/validator/incidents.py +120 -0
  168. package/artemis-main/artemis/agents/validator/pixel_safety_net.md +15 -0
  169. package/artemis-main/artemis/agents/validator/precondition_pixel.py +320 -0
  170. package/artemis-main/artemis/agents/validator/precondition_xml.py +672 -0
  171. package/artemis-main/artemis/agents/validator/tool_declarations.py +332 -0
  172. package/artemis-main/artemis/agents/validator/validator.py +188 -0
  173. package/artemis-main/artemis/agents/video_analyzer/__init__.py +15 -0
  174. package/artemis-main/artemis/agents/video_analyzer/audio_native.py +543 -0
  175. package/artemis-main/artemis/agents/video_analyzer/blackboard.py +821 -0
  176. package/artemis-main/artemis/agents/video_analyzer/chunk_agentic.py +455 -0
  177. package/artemis-main/artemis/agents/video_analyzer/chunk_conversation.py +491 -0
  178. package/artemis-main/artemis/agents/video_analyzer/chunk_native.py +437 -0
  179. package/artemis-main/artemis/agents/video_analyzer/conflict_resolution.py +137 -0
  180. package/artemis-main/artemis/agents/video_analyzer/gemini_files.py +162 -0
  181. package/artemis-main/artemis/agents/video_analyzer/native_coordinator.py +541 -0
  182. package/artemis-main/artemis/agents/video_analyzer/reliability.py +128 -0
  183. package/artemis-main/artemis/agents/video_analyzer/universal_engine.py +487 -0
  184. package/artemis-main/artemis/agents/video_analyzer/universal_tools.py +323 -0
  185. package/artemis-main/artemis/agents/video_analyzer/video_analyzer.md +51 -0
  186. package/artemis-main/artemis/agents/video_analyzer/video_analyzer.py +875 -0
  187. package/artemis-main/artemis/agents/video_analyzer/video_sub_agent.md +15 -0
  188. package/artemis-main/artemis/agents/video_analyzer/video_sub_agent_audio.md +12 -0
  189. package/artemis-main/artemis/clients/accessibility_client.py +438 -0
  190. package/artemis-main/artemis/clients/screen_client_factory.py +403 -0
  191. package/artemis-main/artemis/config/__init__.py +309 -0
  192. package/artemis-main/artemis/config/agent.py +1098 -0
  193. package/artemis-main/artemis/config/constants.py +151 -0
  194. package/artemis-main/artemis/config/core/__init__.py +24 -0
  195. package/artemis-main/artemis/config/core/engine.py +118 -0
  196. package/artemis-main/artemis/config/core/interpolator.py +78 -0
  197. package/artemis-main/artemis/config/llm.py +267 -0
  198. package/artemis-main/artemis/config/paths.py +244 -0
  199. package/artemis-main/artemis/config/runtime.py +197 -0
  200. package/artemis-main/artemis/config/settings.py +315 -0
  201. package/artemis-main/artemis/constants.py +47 -0
  202. package/artemis-main/artemis/context.py +289 -0
  203. package/artemis-main/artemis/controllers/__init__.py +41 -0
  204. package/artemis-main/artemis/controllers/controller_factory.py +41 -0
  205. package/artemis-main/artemis/controllers/device_controller.py +29 -0
  206. package/artemis-main/artemis/controllers/types.py +37 -0
  207. package/artemis-main/artemis/controllers/unified_controller.py +649 -0
  208. package/artemis-main/artemis/core/__init__.py +21 -0
  209. package/artemis-main/artemis/core/diagnostics/__init__.py +90 -0
  210. package/artemis-main/artemis/core/diagnostics/adb_keys.py +270 -0
  211. package/artemis-main/artemis/core/diagnostics/adb_server_connection.py +330 -0
  212. package/artemis-main/artemis/core/diagnostics/device_smoke.py +364 -0
  213. package/artemis-main/artemis/core/diagnostics/emulator_manager.py +501 -0
  214. package/artemis-main/artemis/core/diagnostics/engine.py +438 -0
  215. package/artemis-main/artemis/core/diagnostics/hierarchy_parity.py +216 -0
  216. package/artemis-main/artemis/core/diagnostics/probes/adb_probe.py +887 -0
  217. package/artemis-main/artemis/core/diagnostics/probes/base.py +45 -0
  218. package/artemis-main/artemis/core/diagnostics/probes/credentials_probe.py +296 -0
  219. package/artemis-main/artemis/core/diagnostics/probes/host_probe.py +427 -0
  220. package/artemis-main/artemis/core/diagnostics/probes/runtime_probe.py +169 -0
  221. package/artemis-main/artemis/core/diagnostics/probes/toolchain_probe.py +139 -0
  222. package/artemis-main/artemis/core/diagnostics/readiness.py +83 -0
  223. package/artemis-main/artemis/core/diagnostics/schema.py +118 -0
  224. package/artemis-main/artemis/core/tool_declaration.py +43 -0
  225. package/artemis-main/artemis/core/tool_failure.py +56 -0
  226. package/artemis-main/artemis/data_engine/context_vars.py +24 -0
  227. package/artemis-main/artemis/data_engine/engine.py +1615 -0
  228. package/artemis-main/artemis/data_engine/history_reader.py +142 -0
  229. package/artemis-main/artemis/data_engine/models.py +131 -0
  230. package/artemis-main/artemis/data_engine/storage.py +1245 -0
  231. package/artemis-main/artemis/data_engine/trace.py +727 -0
  232. package/artemis-main/artemis/drivers/__init__.py +48 -0
  233. package/artemis-main/artemis/drivers/android/adb_driver.py +507 -0
  234. package/artemis-main/artemis/drivers/android/hierarchy.py +64 -0
  235. package/artemis-main/artemis/drivers/android/input_ime.py +120 -0
  236. package/artemis-main/artemis/drivers/android/recorder.py +57 -0
  237. package/artemis-main/artemis/drivers/base.py +290 -0
  238. package/artemis-main/artemis/drivers/cloud/cloud_driver.py +117 -0
  239. package/artemis-main/artemis/drivers/factory.py +80 -0
  240. package/artemis-main/artemis/drivers/mock/mock_driver.py +198 -0
  241. package/artemis-main/artemis/drivers/types.py +67 -0
  242. package/artemis-main/artemis/graph/checkpoints.py +1243 -0
  243. package/artemis-main/artemis/graph/graph.py +1055 -0
  244. package/artemis-main/artemis/graph/perception.py +234 -0
  245. package/artemis-main/artemis/graph/state.py +151 -0
  246. package/artemis-main/artemis/graph/visibility.py +238 -0
  247. package/artemis-main/artemis/interfaces/cli/__init__.py +19 -0
  248. package/artemis-main/artemis/interfaces/cli/commands/__init__.py +15 -0
  249. package/artemis-main/artemis/interfaces/cli/commands/batch.py +278 -0
  250. package/artemis-main/artemis/interfaces/cli/commands/doctor.py +468 -0
  251. package/artemis-main/artemis/interfaces/cli/commands/helper.py +226 -0
  252. package/artemis-main/artemis/interfaces/cli/commands/init.py +193 -0
  253. package/artemis-main/artemis/interfaces/cli/commands/mcp.py +862 -0
  254. package/artemis-main/artemis/interfaces/cli/commands/run.py +463 -0
  255. package/artemis-main/artemis/interfaces/cli/commands/server.py +151 -0
  256. package/artemis-main/artemis/interfaces/cli/commands/server_lifecycle.py +328 -0
  257. package/artemis-main/artemis/interfaces/cli/commands/trace.py +111 -0
  258. package/artemis-main/artemis/interfaces/cli/commands/ui.py +404 -0
  259. package/artemis-main/artemis/interfaces/cli/main.py +109 -0
  260. package/artemis-main/artemis/interfaces/sdk/__init__.py +31 -0
  261. package/artemis-main/artemis/interfaces/sdk/client.py +19 -0
  262. package/artemis-main/artemis/interfaces/sdk/task.py +72 -0
  263. package/artemis-main/artemis/llm/__init__.py +25 -0
  264. package/artemis-main/artemis/llm/fake_model.py +179 -0
  265. package/artemis-main/artemis/llm/google/__init__.py +57 -0
  266. package/artemis-main/artemis/llm/google/provider.py +185 -0
  267. package/artemis-main/artemis/llm/google/usage.py +148 -0
  268. package/artemis-main/artemis/llm/parser.py +32 -0
  269. package/artemis-main/artemis/llm/reliability.py +267 -0
  270. package/artemis-main/artemis/llm/router.py +389 -0
  271. package/artemis-main/artemis/llm/schemas.py +36 -0
  272. package/artemis-main/artemis/llm/structured.py +196 -0
  273. package/artemis-main/artemis/main.py +58 -0
  274. package/artemis-main/artemis/mcp/__init__.py +20 -0
  275. package/artemis-main/artemis/mcp/action_executor.py +760 -0
  276. package/artemis-main/artemis/mcp/action_manifest.py +320 -0
  277. package/artemis-main/artemis/mcp/action_names.py +172 -0
  278. package/artemis-main/artemis/mcp/action_server.py +202 -0
  279. package/artemis-main/artemis/mcp/action_session.py +245 -0
  280. package/artemis-main/artemis/mcp/action_specs.py +868 -0
  281. package/artemis-main/artemis/mcp/action_types.py +86 -0
  282. package/artemis-main/artemis/mcp/actuators/__init__.py +21 -0
  283. package/artemis-main/artemis/mcp/actuators/adb.py +414 -0
  284. package/artemis-main/artemis/mcp/actuators/base.py +113 -0
  285. package/artemis-main/artemis/mcp/actuators/mock.py +70 -0
  286. package/artemis-main/artemis/mcp/adb_server.py +490 -0
  287. package/artemis-main/artemis/mcp/observation.py +133 -0
  288. package/artemis-main/artemis/mcp/xml_search_server.py +297 -0
  289. package/artemis-main/artemis/memory/__init__.py +90 -0
  290. package/artemis-main/artemis/memory/chunking.py +1843 -0
  291. package/artemis-main/artemis/memory/context_policy.py +226 -0
  292. package/artemis-main/artemis/memory/step_capsule.md +73 -0
  293. package/artemis-main/artemis/memory/step_memory.py +281 -0
  294. package/artemis-main/artemis/memory/transcript.py +798 -0
  295. package/artemis-main/artemis/platform/__init__.py +61 -0
  296. package/artemis-main/artemis/platform/base.py +104 -0
  297. package/artemis-main/artemis/platform/darwin.py +184 -0
  298. package/artemis-main/artemis/platform/linux.py +207 -0
  299. package/artemis-main/artemis/platform/windows.py +193 -0
  300. package/artemis-main/artemis/resources/__init__.py +46 -0
  301. package/artemis-main/artemis/runtime/__init__.py +108 -0
  302. package/artemis-main/artemis/runtime/adb_endpoint.py +173 -0
  303. package/artemis-main/artemis/runtime/awake_lease.py +283 -0
  304. package/artemis-main/artemis/runtime/awake_service.py +343 -0
  305. package/artemis-main/artemis/runtime/cancel_requests.py +254 -0
  306. package/artemis-main/artemis/runtime/daemon_client.py +422 -0
  307. package/artemis-main/artemis/runtime/device_lock.py +1013 -0
  308. package/artemis-main/artemis/runtime/device_pool.py +478 -0
  309. package/artemis-main/artemis/runtime/helper_manager.py +1030 -0
  310. package/artemis-main/artemis/runtime/process_probe.py +98 -0
  311. package/artemis-main/artemis/runtime/server_lifecycle.py +435 -0
  312. package/artemis-main/artemis/runtime/supervisor.py +121 -0
  313. package/artemis-main/artemis/runtime/trace_store.py +375 -0
  314. package/artemis-main/artemis/sdk/__init__.py +26 -0
  315. package/artemis-main/artemis/sdk/agent.py +485 -0
  316. package/artemis-main/artemis/sdk/builders/__init__.py +29 -0
  317. package/artemis-main/artemis/sdk/builders/agent_config_builder.py +474 -0
  318. package/artemis-main/artemis/sdk/constants.py +15 -0
  319. package/artemis-main/artemis/sdk/run_outcome.py +58 -0
  320. package/artemis-main/artemis/sdk/types/__init__.py +61 -0
  321. package/artemis-main/artemis/sdk/types/agent.py +89 -0
  322. package/artemis-main/artemis/sdk/utils.py +28 -0
  323. package/artemis-main/artemis/services/llm.py +1040 -0
  324. package/artemis-main/artemis/services/token_meter.py +267 -0
  325. package/artemis-main/artemis/telemetry/__init__.py +35 -0
  326. package/artemis-main/artemis/telemetry/models.py +64 -0
  327. package/artemis-main/artemis/telemetry/replay.py +34 -0
  328. package/artemis-main/artemis/telemetry/storage/json_storage.py +47 -0
  329. package/artemis-main/artemis/telemetry/tracer.py +85 -0
  330. package/artemis-main/artemis/toolchain/__init__.py +52 -0
  331. package/artemis-main/artemis/toolchain/descriptors.py +92 -0
  332. package/artemis-main/artemis/toolchain/resolver.py +185 -0
  333. package/artemis-main/artemis/tools/base.py +232 -0
  334. package/artemis-main/artemis/tools/command_tool.py +1240 -0
  335. package/artemis-main/artemis/tools/committee_prompts.json +5 -0
  336. package/artemis-main/artemis/tools/committee_tool.py +422 -0
  337. package/artemis-main/artemis/tools/diagnoser_submit_answer_tool.py +87 -0
  338. package/artemis-main/artemis/tools/diagnostic_tool.py +120 -0
  339. package/artemis-main/artemis/tools/explorer_tool.py +581 -0
  340. package/artemis-main/artemis/tools/history/__init__.py +398 -0
  341. package/artemis-main/artemis/tools/history/replay.py +120 -0
  342. package/artemis-main/artemis/tools/history/screenshot.py +139 -0
  343. package/artemis-main/artemis/tools/history/search.py +563 -0
  344. package/artemis-main/artemis/tools/image_processor_tool.py +124 -0
  345. package/artemis-main/artemis/tools/index.py +47 -0
  346. package/artemis-main/artemis/tools/log_tool.py +108 -0
  347. package/artemis-main/artemis/tools/mobile/launch_app.py +132 -0
  348. package/artemis-main/artemis/tools/mobile/log_utils.py +138 -0
  349. package/artemis-main/artemis/tools/mobile/ocr.py +202 -0
  350. package/artemis-main/artemis/tools/mobile/read_hierarchy.py +108 -0
  351. package/artemis-main/artemis/tools/mobile/read_logs.py +116 -0
  352. package/artemis-main/artemis/tools/mobile/search_logs.py +260 -0
  353. package/artemis-main/artemis/tools/object_detection_tool.py +244 -0
  354. package/artemis-main/artemis/tools/scratchpad.py +819 -0
  355. package/artemis-main/artemis/tools/system/adb_shell.py +31 -0
  356. package/artemis-main/artemis/tools/tool_wrapper.py +270 -0
  357. package/artemis-main/artemis/tools/video_tool.py +261 -0
  358. package/artemis-main/artemis/tools/wait_tool.py +97 -0
  359. package/artemis-main/artemis/utils/app_launch_utils.py +207 -0
  360. package/artemis-main/artemis/utils/coordinates.py +606 -0
  361. package/artemis-main/artemis/utils/credentials_validator.py +201 -0
  362. package/artemis-main/artemis/utils/cv_canvas.py +189 -0
  363. package/artemis-main/artemis/utils/cython_compat.py +45 -0
  364. package/artemis-main/artemis/utils/element_hit_test.py +80 -0
  365. package/artemis-main/artemis/utils/image_diff.py +335 -0
  366. package/artemis-main/artemis/utils/image_hash.py +80 -0
  367. package/artemis-main/artemis/utils/notes.py +470 -0
  368. package/artemis-main/artemis/utils/ocr_api.py +105 -0
  369. package/artemis-main/artemis/utils/ocr_xml_fusion.py +318 -0
  370. package/artemis-main/artemis/utils/plan_grammar.py +513 -0
  371. package/artemis-main/artemis/utils/python_executor.py +213 -0
  372. package/artemis-main/artemis/utils/startup_progress.py +60 -0
  373. package/artemis-main/artemis/utils/task_tree.py +1174 -0
  374. package/artemis-main/artemis/utils/text.py +37 -0
  375. package/artemis-main/artemis/utils/ui_filter.py +651 -0
  376. package/artemis-main/artemis/utils/video.py +685 -0
  377. package/artemis-main/artemis/utils/visualization.py +802 -0
  378. package/artemis-main/config/artemis.example.jsonc +12 -0
  379. package/artemis-main/mcp_server/README.md +111 -0
  380. package/artemis-main/mcp_server/__init__.py +21 -0
  381. package/artemis-main/mcp_server/__main__.py +20 -0
  382. package/artemis-main/mcp_server/background/__init__.py +15 -0
  383. package/artemis-main/mcp_server/background/task_runner.py +453 -0
  384. package/artemis-main/mcp_server/base.py +49 -0
  385. package/artemis-main/mcp_server/notifiers/__init__.py +74 -0
  386. package/artemis-main/mcp_server/notifiers/agentapi.py +289 -0
  387. package/artemis-main/mcp_server/notifiers/base.py +45 -0
  388. package/artemis-main/mcp_server/notifiers/composite.py +87 -0
  389. package/artemis-main/mcp_server/notifiers/desktop.py +108 -0
  390. package/artemis-main/mcp_server/notifiers/file.py +69 -0
  391. package/artemis-main/mcp_server/notifiers/script.py +90 -0
  392. package/artemis-main/mcp_server/notifiers/webhook.py +87 -0
  393. package/artemis-main/mcp_server/rules.md +68 -0
  394. package/artemis-main/mcp_server/server.py +106 -0
  395. package/artemis-main/mcp_server/tools/__init__.py +29 -0
  396. package/artemis-main/mcp_server/tools/device_state.py +107 -0
  397. package/artemis-main/mcp_server/tools/diagnose.py +1249 -0
  398. package/artemis-main/mcp_server/tools/inspect_trace.py +394 -0
  399. package/artemis-main/mcp_server/tools/task_manager.py +627 -0
  400. package/artemis-main/mcp_server/tools/task_runner.py +548 -0
  401. package/artemis-main/mcp_server/utils/__init__.py +15 -0
  402. package/artemis-main/mcp_server/utils/device_utils.py +180 -0
  403. package/artemis-main/mcp_server/utils/env_utils.py +65 -0
  404. package/artemis-main/packages/artemis-accessibility-helper/ArtemisAccessibilityHelper.apk +0 -0
  405. package/artemis-main/packages/artemis-accessibility-helper/app/build.gradle.kts +35 -0
  406. package/artemis-main/packages/artemis-accessibility-helper/app/src/main/AndroidManifest.xml +49 -0
  407. package/artemis-main/packages/artemis-accessibility-helper/app/src/main/java/com/artemis/helper/A11yNode.java +274 -0
  408. package/artemis-main/packages/artemis-accessibility-helper/app/src/main/java/com/artemis/helper/ArtemisAccessibilityService.java +227 -0
  409. package/artemis-main/packages/artemis-accessibility-helper/app/src/main/java/com/artemis/helper/CommandServer.java +463 -0
  410. package/artemis-main/packages/artemis-accessibility-helper/app/src/main/java/com/artemis/helper/DisplayUtils.java +111 -0
  411. package/artemis-main/packages/artemis-accessibility-helper/app/src/main/java/com/artemis/helper/GestureController.java +232 -0
  412. package/artemis-main/packages/artemis-accessibility-helper/app/src/main/java/com/artemis/helper/HierarchyDumper.java +832 -0
  413. package/artemis-main/packages/artemis-accessibility-helper/app/src/main/java/com/artemis/helper/TokenReceiver.java +36 -0
  414. package/artemis-main/packages/artemis-accessibility-helper/app/src/main/java/com/artemis/helper/TokenStore.java +38 -0
  415. package/artemis-main/packages/artemis-accessibility-helper/app/src/main/java/com/artemis/helper/XmlUtils.java +102 -0
  416. package/artemis-main/packages/artemis-accessibility-helper/app/src/main/res/values/strings.xml +4 -0
  417. package/artemis-main/packages/artemis-accessibility-helper/app/src/main/res/xml/accessibility_service_config.xml +10 -0
  418. package/artemis-main/packages/artemis-accessibility-helper/build.gradle.kts +3 -0
  419. package/artemis-main/packages/artemis-accessibility-helper/build_apk.sh +215 -0
  420. package/artemis-main/packages/artemis-accessibility-helper/debug.keystore +0 -0
  421. package/artemis-main/packages/artemis-accessibility-helper/gradle.properties +2 -0
  422. package/artemis-main/packages/artemis-accessibility-helper/helper_manifest.json +7 -0
  423. package/artemis-main/packages/artemis-accessibility-helper/settings.gradle.kts +17 -0
  424. package/artemis-main/packages/artemis-client/DESIGN.md +89 -0
  425. package/artemis-main/packages/artemis-client/README.md +112 -0
  426. package/artemis-main/packages/artemis-client/examples/basic.py +30 -0
  427. package/artemis-main/packages/artemis-client/pyproject.toml +36 -0
  428. package/artemis-main/packages/artemis-client/src/artemis_client/__init__.py +45 -0
  429. package/artemis-main/packages/artemis-client/src/artemis_client/client.py +401 -0
  430. package/artemis-main/packages/artemis-client/src/artemis_client/errors.py +66 -0
  431. package/artemis-main/packages/artemis-client/src/artemis_client/models.py +212 -0
  432. package/artemis-main/packages/artemis-client/src/artemis_client/py.typed +1 -0
  433. package/artemis-main/packages/artemis-client/src/artemis_client/transport.py +134 -0
  434. package/artemis-main/packages/artemis-client/tests/test_client.py +289 -0
  435. package/artemis-main/packages/artemis-client/tests/test_transport.py +85 -0
  436. package/artemis-main/pyproject.toml +259 -0
  437. package/artemis-main/pyright-core.json +17 -0
  438. package/artemis-main/scripts/check_dependency_sources.py +68 -0
  439. package/artemis-main/scripts/install_deps.ps1 +520 -0
  440. package/artemis-main/scripts/install_deps.sh +533 -0
  441. package/artemis-main/scripts/quality_ratchet.py +97 -0
  442. package/artemis-main/scripts/real_device_video_acceptance.py +483 -0
  443. package/artemis-main/scripts/run_edge_case_part.py +327 -0
  444. package/artemis-main/scripts/run_ui.py +242 -0
  445. package/artemis-main/scripts/start.ps1 +500 -0
  446. package/artemis-main/scripts/test_all_edge_cases.py +269 -0
  447. package/artemis-main/scripts/verify_concurrency_and_devices.py +385 -0
  448. package/artemis-main/setup.py +164 -0
  449. package/artemis-main/start.bat +35 -0
  450. package/artemis-main/start.sh +423 -0
  451. package/artemis-main/third_party/mobile_use/LICENSE +190 -0
  452. package/artemis-main/third_party/mobile_use/METADATA +27 -0
  453. package/artemis-main/third_party/mobile_use/NOTICE +12 -0
  454. package/artemis-main/third_party/mobile_use/__init__.py +19 -0
  455. package/artemis-main/third_party/mobile_use/agents/__init__.py +13 -0
  456. package/artemis-main/third_party/mobile_use/agents/hopper/__init__.py +13 -0
  457. package/artemis-main/third_party/mobile_use/agents/hopper/hopper.md +22 -0
  458. package/artemis-main/third_party/mobile_use/agents/hopper/hopper.py +80 -0
  459. package/artemis-main/third_party/mobile_use/clients/__init__.py +13 -0
  460. package/artemis-main/third_party/mobile_use/clients/ui_automator_client.py +482 -0
  461. package/artemis-main/third_party/mobile_use/config/__init__.py +13 -0
  462. package/artemis-main/third_party/mobile_use/config/llm.py +183 -0
  463. package/artemis-main/third_party/mobile_use/config/output.py +184 -0
  464. package/artemis-main/third_party/mobile_use/context.py +119 -0
  465. package/artemis-main/third_party/mobile_use/controllers/__init__.py +13 -0
  466. package/artemis-main/third_party/mobile_use/controllers/platform_specific_commands_controller.py +151 -0
  467. package/artemis-main/third_party/mobile_use/controllers/types.py +92 -0
  468. package/artemis-main/third_party/mobile_use/controllers/unified_controller.py +183 -0
  469. package/artemis-main/third_party/mobile_use/graph.py +54 -0
  470. package/artemis-main/third_party/mobile_use/llm_service.py +193 -0
  471. package/artemis-main/third_party/mobile_use/main.py +130 -0
  472. package/artemis-main/third_party/mobile_use/sdk/__init__.py +13 -0
  473. package/artemis-main/third_party/mobile_use/sdk/agent.py +1060 -0
  474. package/artemis-main/third_party/mobile_use/sdk/builders/__init__.py +13 -0
  475. package/artemis-main/third_party/mobile_use/sdk/builders/agent_config_builder.py +225 -0
  476. package/artemis-main/third_party/mobile_use/sdk/builders/index.py +33 -0
  477. package/artemis-main/third_party/mobile_use/sdk/builders/task_request_builder.py +243 -0
  478. package/artemis-main/third_party/mobile_use/sdk/types/__init__.py +13 -0
  479. package/artemis-main/third_party/mobile_use/sdk/types/agent.py +98 -0
  480. package/artemis-main/third_party/mobile_use/sdk/types/exceptions.py +109 -0
  481. package/artemis-main/third_party/mobile_use/sdk/types/task.py +234 -0
  482. package/artemis-main/third_party/mobile_use/testing.py +59 -0
  483. package/artemis-main/third_party/mobile_use/tools/__init__.py +13 -0
  484. package/artemis-main/third_party/mobile_use/tools/index.py +44 -0
  485. package/artemis-main/third_party/mobile_use/tools/mobile/__init__.py +13 -0
  486. package/artemis-main/third_party/mobile_use/tools/mobile/launch_app.py +89 -0
  487. package/artemis-main/third_party/mobile_use/tools/tool_wrapper.py +52 -0
  488. package/artemis-main/third_party/mobile_use/utils/__init__.py +13 -0
  489. package/artemis-main/third_party/mobile_use/utils/app_launch_utils.py +217 -0
  490. package/artemis-main/third_party/mobile_use/utils/cli_helpers.py +60 -0
  491. package/artemis-main/third_party/mobile_use/utils/decorators.py +158 -0
  492. package/artemis-main/third_party/mobile_use/utils/file.py +31 -0
  493. package/artemis-main/third_party/mobile_use/utils/logger.py +216 -0
  494. package/artemis-main/third_party/mobile_use/utils/media.py +213 -0
  495. package/artemis-main/third_party/mobile_use/utils/shell_utils.py +39 -0
  496. package/artemis-main/third_party/mobile_use/utils/video.py +398 -0
  497. package/artemis-main/uv.lock +4908 -0
  498. package/bin/android-midscene-automation.js +1 -5
  499. package/bin/artemis-config.mjs +15 -0
  500. package/bin/artemis-embedded.py +56 -0
  501. package/bin/start-artemis.mjs +30 -0
  502. package/bin/start-dev.mjs +112 -0
  503. package/bin/test_artemis_embedded.py +44 -0
  504. package/package.json +10 -8
  505. package/server/artemis.ts +34 -0
  506. package/server/http-api.ts +13 -1
  507. package/src/App.vue +72 -23
  508. package/src/api.ts +5 -0
  509. package/src/appium-recorder/AppiumPage.vue +1 -1
  510. package/src/appium-recorder/components/ComponentInspector.vue +1 -1
  511. package/src/appium-recorder/components/FlowNodeSearch.vue +3 -3
  512. package/src/appium-recorder/components/ImageCheckDialog.vue +3 -3
  513. package/src/appium-recorder/components/RecorderWorkspace.vue +4 -4
  514. package/src/appium-recorder/flow-appearance.ts +4 -4
  515. package/src/components/AppSidebar.vue +8 -7
  516. package/src/components/MidsceneMaintenanceNotice.vue +17 -0
  517. package/src/components/analytics/AnalysisCharts.vue +4 -4
  518. package/src/components/analytics/ReportAnalysis.vue +1 -1
  519. package/src/components/generator/TestCaseFileUpload.vue +1 -1
  520. package/src/components/help/HelpCenter.vue +56 -37
  521. package/src/pages/AiGeneratorPage.vue +1 -1
  522. package/src/pages/ArtemisPage.vue +72 -0
  523. package/src/pages/ConfigPage.vue +18 -19
  524. package/src/style.css +369 -186
  525. package/src/types.ts +1 -1
@@ -0,0 +1,520 @@
1
+ # Copyright 2026 Google LLC
2
+ #
3
+ # Licensed under the Apache License, Version 2.0 (the "License");
4
+ # you may not use this file except in compliance with the License.
5
+ # You may obtain a copy of the License at
6
+ #
7
+ # http://www.apache.org/licenses/LICENSE-2.0
8
+ #
9
+ # Unless required by applicable law or agreed to in writing, software
10
+ # distributed under the License is distributed on an "AS IS" BASIS,
11
+ # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12
+ # See the License for the specific language governing permissions and
13
+ # limitations under the License.
14
+
15
+ <#
16
+ .SYNOPSIS
17
+ Artemis Smart Multi-Platform Dependency Installer for Windows (PowerShell).
18
+ #>
19
+
20
+ [CmdletBinding()]
21
+ param(
22
+ [switch]$Launch = $false,
23
+ [switch]$Open = $false
24
+ )
25
+
26
+ $ErrorActionPreference = "Continue"
27
+ [Console]::OutputEncoding = [System.Text.Encoding]::UTF8
28
+
29
+ # Ensure modern TLS protocols are enabled for downloads (GitHub releases, nodejs.org, Google repositories)
30
+ try {
31
+ [System.Net.ServicePointManager]::SecurityProtocol = [System.Net.ServicePointManager]::SecurityProtocol -bor [System.Net.SecurityProtocolType]::Tls12
32
+ } catch {}
33
+
34
+ Write-Host "======================================================" -ForegroundColor Cyan
35
+ Write-Host " Artemis - Windows Smart Installer " -ForegroundColor Cyan
36
+ Write-Host "======================================================" -ForegroundColor Cyan
37
+ Write-Host ""
38
+
39
+ $ScriptDir = Split-Path -Parent $MyInvocation.MyCommand.Definition
40
+ $RootDir = Split-Path -Parent $ScriptDir
41
+ Set-Location $RootDir
42
+
43
+ function Update-EnvironmentPath {
44
+ $standardDirs = @(
45
+ "$env:LOCALAPPDATA\Microsoft\WinGet\Links",
46
+ "$env:LOCALAPPDATA\Programs\node",
47
+ "$env:USERPROFILE\.local\share\node",
48
+ "$env:LOCALAPPDATA\Programs\scrcpy",
49
+ "$env:USERPROFILE\.local\share\scrcpy",
50
+ "$env:LOCALAPPDATA\Programs\platform-tools",
51
+ "$env:USERPROFILE\.local\share\platform-tools",
52
+ "$env:LOCALAPPDATA\Programs\uv",
53
+ "$env:LOCALAPPDATA\uv",
54
+ "$env:APPDATA\uv",
55
+ "$env:USERPROFILE\.cargo\bin",
56
+ "$env:USERPROFILE\.local\bin",
57
+ "$env:USERPROFILE\scoop\shims",
58
+ "C:\ProgramData\chocolatey\bin",
59
+ "$env:LOCALAPPDATA\Android\Sdk\platform-tools",
60
+ "$env:LOCALAPPDATA\Android\android-sdk\platform-tools",
61
+ "$env:ProgramFiles\Android\platform-tools",
62
+ "${env:ProgramFiles(x86)}\Android\android-sdk\platform-tools",
63
+ "$env:ProgramFiles\nodejs",
64
+ "${env:ProgramFiles(x86)}\nodejs",
65
+ "$env:APPDATA\npm"
66
+ )
67
+ if ($env:CARGO_HOME) { $standardDirs = @("$env:CARGO_HOME\bin") + $standardDirs }
68
+ if ($env:ANDROID_HOME) { $standardDirs += "$env:ANDROID_HOME\platform-tools" }
69
+ if ($env:ANDROID_SDK_ROOT) { $standardDirs += "$env:ANDROID_SDK_ROOT\platform-tools" }
70
+ if ($env:NVM_SYMLINK) { $standardDirs = @($env:NVM_SYMLINK) + $standardDirs }
71
+ if ($env:NVM_HOME) { $standardDirs = @($env:NVM_HOME) + $standardDirs }
72
+
73
+ $regPath = [Environment]::GetEnvironmentVariable("Path", "User") + ";" + [Environment]::GetEnvironmentVariable("Path", "Machine")
74
+ $currentPaths = ($env:PATH -split ";") + ($regPath -split ";") + $standardDirs | Where-Object { [string]::IsNullOrWhiteSpace($_) -eq $false -and (Test-Path $_) } | Select-Object -Unique
75
+ $env:PATH = $currentPaths -join ";"
76
+
77
+ # Ensure user-space portable tools take absolute priority over system-level outdated versions
78
+ $portableNode = "$env:LOCALAPPDATA\Programs\node"
79
+ if (Test-Path "$portableNode\node.exe") {
80
+ $env:PATH = "$portableNode;$env:PATH"
81
+ }
82
+ $portableScrcpy = "$env:LOCALAPPDATA\Programs\scrcpy"
83
+ if (Test-Path "$portableScrcpy\scrcpy.exe") {
84
+ $env:PATH = "$portableScrcpy;$env:PATH"
85
+ }
86
+ $portablePt = "$env:LOCALAPPDATA\Programs\platform-tools"
87
+ if (Test-Path "$portablePt\adb.exe") {
88
+ $env:PATH = "$portablePt;$env:PATH"
89
+ }
90
+ }
91
+
92
+ function Start-LocalAdbServer {
93
+ if (Test-CommandExists "adb") {
94
+ try {
95
+ $origSocket = $env:ADB_SERVER_SOCKET
96
+ Remove-Item Env:\ADB_SERVER_SOCKET -ErrorAction SilentlyContinue
97
+ & adb start-server 2>$null | Out-Null
98
+ if ($origSocket) { $env:ADB_SERVER_SOCKET = $origSocket }
99
+ } catch {}
100
+ }
101
+ }
102
+
103
+ function Test-CommandExists {
104
+ param([string]$Command)
105
+ $res = Get-Command $Command -ErrorAction SilentlyContinue
106
+ return ($null -ne $res)
107
+ }
108
+
109
+ function Invoke-DownloadFile {
110
+ param(
111
+ [Parameter(Mandatory=$true)][string]$Uri,
112
+ [Parameter(Mandatory=$true)][string]$OutFile,
113
+ [int]$TimeoutSec = 45
114
+ )
115
+ if (Test-Path $OutFile) {
116
+ Remove-Item -Path $OutFile -Force -ErrorAction SilentlyContinue
117
+ }
118
+
119
+ # 1. Try Windows built-in curl.exe first (available in Win 10 1803+ and Win 11)
120
+ if (Test-CommandExists "curl.exe") {
121
+ try {
122
+ & curl.exe -f -sSL --connect-timeout 5 --max-time $TimeoutSec "$Uri" -o "$OutFile" 2>$null
123
+ if ($LASTEXITCODE -eq 0 -and (Test-Path $OutFile) -and ((Get-Item $OutFile).Length -gt 0)) {
124
+ return $true
125
+ }
126
+ } catch {}
127
+ if (Test-Path $OutFile) {
128
+ Remove-Item -Path $OutFile -Force -ErrorAction SilentlyContinue
129
+ }
130
+ }
131
+
132
+ # 2. Fallback to Invoke-WebRequest (suppressing progress bar to eliminate PowerShell buffer hangs)
133
+ try {
134
+ $prevProgress = $ProgressPreference
135
+ $ProgressPreference = 'SilentlyContinue'
136
+ Invoke-WebRequest -Uri $Uri -OutFile $OutFile -TimeoutSec $TimeoutSec -UseBasicParsing -ErrorAction Stop
137
+ $ProgressPreference = $prevProgress
138
+ if ((Test-Path $OutFile) -and ((Get-Item $OutFile).Length -gt 0)) {
139
+ return $true
140
+ }
141
+ } catch {
142
+ $ProgressPreference = $prevProgress
143
+ }
144
+
145
+ if (Test-Path $OutFile) {
146
+ Remove-Item -Path $OutFile -Force -ErrorAction SilentlyContinue
147
+ }
148
+ return $false
149
+ }
150
+
151
+ function Install-PortablePlatformTools {
152
+ $ptDir = "$env:LOCALAPPDATA\Programs\platform-tools"
153
+ if (Test-Path "$ptDir\adb.exe") {
154
+ $env:PATH = "$ptDir;$env:PATH"
155
+ return $true
156
+ }
157
+ Write-Host " [INFO] Installing Android platform-tools (adb) in user space..." -ForegroundColor Cyan
158
+ try {
159
+ $zipPath = "$env:TEMP\platform-tools-windows.zip"
160
+ if (Invoke-DownloadFile -Uri "https://dl.google.com/android/repository/platform-tools-latest-windows.zip" -OutFile $zipPath -TimeoutSec 60) {
161
+ New-Item -ItemType Directory -Path "$env:LOCALAPPDATA\Programs" -Force | Out-Null
162
+ Expand-Archive -Path $zipPath -DestinationPath "$env:LOCALAPPDATA\Programs" -Force
163
+ Remove-Item $zipPath -Force -ErrorAction SilentlyContinue
164
+ if (Test-Path "$ptDir\adb.exe") {
165
+ $env:PATH = "$ptDir;$env:PATH"
166
+ Write-Host " [OK] adb installed in user space." -ForegroundColor Green
167
+ return $true
168
+ }
169
+ }
170
+ } catch {
171
+ Write-Host " [WARN] Failed to install portable platform-tools: $_" -ForegroundColor DarkYellow
172
+ }
173
+ return $false
174
+ }
175
+
176
+ function Install-PortableScrcpy {
177
+ $scrcpyDir = "$env:LOCALAPPDATA\Programs\scrcpy"
178
+ if (Test-Path "$scrcpyDir\scrcpy.exe") {
179
+ $env:PATH = "$scrcpyDir;$env:PATH"
180
+ return $true
181
+ }
182
+ # Check if nested from an earlier run and heal
183
+ $nested = Get-ChildItem -Path $scrcpyDir -Directory -Filter "scrcpy*" -ErrorAction SilentlyContinue | Select-Object -First 1
184
+ if ($nested -and (Test-Path "$($nested.FullName)\scrcpy.exe")) {
185
+ Copy-Item -Path "$($nested.FullName)\*" -Destination $scrcpyDir -Recurse -Force
186
+ Remove-Item -Path $nested.FullName -Recurse -Force -ErrorAction SilentlyContinue
187
+ if (Test-Path "$scrcpyDir\scrcpy.exe") {
188
+ $env:PATH = "$scrcpyDir;$env:PATH"
189
+ return $true
190
+ }
191
+ }
192
+
193
+ Write-Host " [INFO] Installing portable scrcpy in user space..." -ForegroundColor Cyan
194
+ try {
195
+ $zipPath = "$env:TEMP\scrcpy-win64.zip"
196
+ if (Invoke-DownloadFile -Uri "https://github.com/Genymobile/scrcpy/releases/download/v4.1/scrcpy-win64-v4.1.zip" -OutFile $zipPath -TimeoutSec 60) {
197
+ $extractDir = "$env:TEMP\scrcpy_extract"
198
+ if (Test-Path $extractDir) { Remove-Item $extractDir -Recurse -Force -ErrorAction SilentlyContinue }
199
+ New-Item -ItemType Directory -Path $extractDir -Force | Out-Null
200
+ Expand-Archive -Path $zipPath -DestinationPath $extractDir -Force
201
+ $extractedFolder = Get-ChildItem -Path $extractDir -Directory | Select-Object -First 1
202
+ if ($extractedFolder) {
203
+ if (-not (Test-Path $scrcpyDir)) {
204
+ New-Item -ItemType Directory -Path $scrcpyDir -Force | Out-Null
205
+ }
206
+ Copy-Item -Path "$($extractedFolder.FullName)\*" -Destination $scrcpyDir -Recurse -Force
207
+ }
208
+ Remove-Item $zipPath -Force -ErrorAction SilentlyContinue
209
+ Remove-Item $extractDir -Recurse -Force -ErrorAction SilentlyContinue
210
+ if (Test-Path "$scrcpyDir\scrcpy.exe") {
211
+ $env:PATH = "$scrcpyDir;$env:PATH"
212
+ Write-Host " [OK] Portable scrcpy installed in user space." -ForegroundColor Green
213
+ return $true
214
+ }
215
+ }
216
+ } catch {
217
+ Write-Host " [WARN] Failed to install portable scrcpy: $_" -ForegroundColor DarkYellow
218
+ }
219
+ return $false
220
+ }
221
+
222
+ function Test-NodeCompatible {
223
+ if (-not (Test-CommandExists "node") -or (-not (Test-CommandExists "npm") -and -not (Test-CommandExists "npm.cmd"))) { return $false }
224
+ try {
225
+ $verRaw = (& node -v 2>$null)
226
+ if (-not $verRaw) { return $false }
227
+ $verStr = $verRaw.ToString().Trim().TrimStart('v')
228
+ $parts = $verStr.Split('.')
229
+ if ($parts.Count -ge 2) {
230
+ $major = [int]$parts[0]
231
+ $minor = [int]$parts[1]
232
+ if ($major -ge 26) { return $true }
233
+ if ($major -eq 24 -and $minor -ge 15) { return $true }
234
+ if ($major -eq 22 -and $minor -ge 22) { return $true }
235
+ }
236
+ } catch {
237
+ return $false
238
+ }
239
+ return $false
240
+ }
241
+
242
+ function Install-PortableNode {
243
+ $nodeDir = "$env:LOCALAPPDATA\Programs\node"
244
+ if (Test-Path "$nodeDir\node.exe") {
245
+ $env:PATH = "$nodeDir;$env:PATH"
246
+ if (Test-NodeCompatible) {
247
+ return $true
248
+ }
249
+ }
250
+ # Check if nested from an earlier run and heal
251
+ $nested = Get-ChildItem -Path $nodeDir -Directory -Filter "node-*" -ErrorAction SilentlyContinue | Select-Object -First 1
252
+ if ($nested -and (Test-Path "$($nested.FullName)\node.exe")) {
253
+ Copy-Item -Path "$($nested.FullName)\*" -Destination $nodeDir -Recurse -Force
254
+ Remove-Item -Path $nested.FullName -Recurse -Force -ErrorAction SilentlyContinue
255
+ if (Test-Path "$nodeDir\node.exe") {
256
+ $env:PATH = "$nodeDir;$env:PATH"
257
+ if (Test-NodeCompatible) {
258
+ return $true
259
+ }
260
+ }
261
+ }
262
+
263
+ Write-Host " [INFO] Installing portable Node.js LTS (v22.23.2) in user space..." -ForegroundColor Cyan
264
+ try {
265
+ $nodeVer = "v22.23.2"
266
+ $arch = if ([System.Environment]::Is64BitOperatingSystem) {
267
+ if ($env:PROCESSOR_ARCHITECTURE -match "ARM64") { "arm64" } else { "x64" }
268
+ } else { "x64" }
269
+ $zipPath = "$env:TEMP\node-$nodeVer-win-$arch.zip"
270
+ if (Invoke-DownloadFile -Uri "https://nodejs.org/dist/$nodeVer/node-$nodeVer-win-$arch.zip" -OutFile $zipPath -TimeoutSec 60) {
271
+ $extractDir = "$env:TEMP\node_extract"
272
+ if (Test-Path $extractDir) { Remove-Item $extractDir -Recurse -Force -ErrorAction SilentlyContinue }
273
+ New-Item -ItemType Directory -Path $extractDir -Force | Out-Null
274
+ Expand-Archive -Path $zipPath -DestinationPath $extractDir -Force
275
+ $extractedFolder = Get-ChildItem -Path $extractDir -Directory | Select-Object -First 1
276
+ if ($extractedFolder) {
277
+ if (-not (Test-Path $nodeDir)) {
278
+ New-Item -ItemType Directory -Path $nodeDir -Force | Out-Null
279
+ }
280
+ Copy-Item -Path "$($extractedFolder.FullName)\*" -Destination $nodeDir -Recurse -Force
281
+ }
282
+ Remove-Item $zipPath -Force -ErrorAction SilentlyContinue
283
+ Remove-Item $extractDir -Recurse -Force -ErrorAction SilentlyContinue
284
+ if (Test-Path "$nodeDir\node.exe") {
285
+ $env:PATH = "$nodeDir;$env:PATH"
286
+ Write-Host " [OK] Portable Node.js $nodeVer installed in user space." -ForegroundColor Green
287
+ return $true
288
+ }
289
+ }
290
+ } catch {
291
+ Write-Host " [WARN] Failed to install portable Node.js: $_" -ForegroundColor DarkYellow
292
+ }
293
+ return $false
294
+ }
295
+
296
+ # 0. Initial PATH refresh
297
+ Update-EnvironmentPath
298
+
299
+ # 1. Check System Dependencies (ADB, FFmpeg, scrcpy)
300
+ Write-Host "1. Checking System Toolchains (ADB, FFmpeg, scrcpy)..." -ForegroundColor Yellow
301
+ $missingTools = @()
302
+
303
+ if (-not (Test-CommandExists "adb")) { $missingTools += "adb" }
304
+ if (-not (Test-CommandExists "ffmpeg")) { $missingTools += "ffmpeg" }
305
+ if (-not (Test-CommandExists "scrcpy")) { $missingTools += "scrcpy" }
306
+
307
+ if ($missingTools.Count -eq 0) {
308
+ Write-Host " [OK] All system toolchains are already installed (ADB, FFmpeg, scrcpy)." -ForegroundColor Green
309
+ Start-LocalAdbServer
310
+ } else {
311
+ Write-Host " ! Missing toolchains: $($missingTools -join ', ')" -ForegroundColor DarkYellow
312
+ $useWinGet = $false
313
+ if (Test-CommandExists "winget") {
314
+ if ([Console]::IsInputRedirected -eq $false) {
315
+ $ans = Read-Host " Install system packages via WinGet? [Y/n]"
316
+ if ($ans -eq "" -or $ans -match "^[Yy]") {
317
+ $useWinGet = $true
318
+ }
319
+ } else {
320
+ $useWinGet = $true
321
+ }
322
+ }
323
+
324
+ if ($useWinGet) {
325
+ Write-Host " Detected WinGet. Installing packages..." -ForegroundColor Cyan
326
+ if ($missingTools -contains "adb") {
327
+ Write-Host " [INFO] Installing Google.PlatformTools (ADB)..." -ForegroundColor Cyan
328
+ winget install --id Google.PlatformTools -e --accept-source-agreements --accept-package-agreements --silent 2>$null | Out-Null
329
+ }
330
+ if ($missingTools -contains "ffmpeg") {
331
+ Write-Host " [INFO] Installing Gyan.FFmpeg..." -ForegroundColor Cyan
332
+ winget install --id Gyan.FFmpeg -e --accept-source-agreements --accept-package-agreements --silent 2>$null | Out-Null
333
+ }
334
+ if ($missingTools -contains "scrcpy") {
335
+ Write-Host " [INFO] Installing Genymobile.scrcpy..." -ForegroundColor Cyan
336
+ winget install --id Genymobile.scrcpy -e --accept-source-agreements --accept-package-agreements --silent 2>$null | Out-Null
337
+ }
338
+ Update-EnvironmentPath
339
+ } elseif (Test-CommandExists "choco") {
340
+ Write-Host " Detected Chocolatey. Installing packages..." -ForegroundColor Cyan
341
+ choco install ($missingTools -join " ") -y | Out-Null
342
+ Update-EnvironmentPath
343
+ } elseif (Test-CommandExists "scoop") {
344
+ Write-Host " Detected Scoop. Installing packages..." -ForegroundColor Cyan
345
+ scoop install ($missingTools -join " ") | Out-Null
346
+ Update-EnvironmentPath
347
+ }
348
+
349
+ # Zero-admin user-space fallback for adb and scrcpy if still missing
350
+ if (-not (Test-CommandExists "adb")) {
351
+ Install-PortablePlatformTools
352
+ }
353
+ if (-not (Test-CommandExists "scrcpy")) {
354
+ Install-PortableScrcpy
355
+ }
356
+
357
+ # Ensure local ADB daemon is warm & listening
358
+ Start-LocalAdbServer
359
+ }
360
+
361
+ # 2. Check and Install uv (Fast Python Package Manager)
362
+ Write-Host "`n2. Checking Python Package Manager (uv)..." -ForegroundColor Yellow
363
+ if (-not (Test-CommandExists "uv")) {
364
+ Write-Host " uv not found. Installing Astral uv..." -ForegroundColor Cyan
365
+ powershell -ExecutionPolicy ByPass -c "irm https://astral.sh/uv/install.ps1 | iex"
366
+ Update-EnvironmentPath
367
+ }
368
+
369
+ if (Test-CommandExists "uv") {
370
+ $uvVer = uv --version
371
+ Write-Host " [OK] uv is ready ($uvVer)" -ForegroundColor Green
372
+ } else {
373
+ Write-Host " [FAIL] Failed to detect uv in PATH." -ForegroundColor Red
374
+ Exit 1
375
+ }
376
+
377
+ # 3. Setup Python Runtime & Sync Dependencies
378
+ Write-Host "`n3. Configuring Python Runtime & Syncing Dependencies..." -ForegroundColor Yellow
379
+ Write-Host " [INFO] Running uv sync (auto-provisioning Python >=3.12 & dependencies)..." -ForegroundColor Cyan
380
+ uv sync
381
+ Write-Host " [OK] Dependencies synced successfully." -ForegroundColor Green
382
+
383
+ # 4. Check .env Configuration
384
+ Write-Host "`n4. Checking Environment Configuration (.env)..." -ForegroundColor Yellow
385
+ if (-not (Test-Path ".env")) {
386
+ if (Test-Path ".env.example") {
387
+ Copy-Item ".env.example" ".env"
388
+ Write-Host " [OK] Created .env template from .env.example." -ForegroundColor Green
389
+ } else {
390
+ New-Item -ItemType File -Path ".env" | Out-Null
391
+ Write-Host " [OK] Created empty .env file." -ForegroundColor Green
392
+ }
393
+ } else {
394
+ Write-Host " [OK] .env configuration file exists." -ForegroundColor Green
395
+ }
396
+
397
+ # 5. Check and Build Showcase UI (Angular)
398
+ Write-Host "`n5. Checking Showcase UI Build (Angular)..." -ForegroundColor Yellow
399
+ $ShowcaseIndex = "$RootDir\apps\showcase_ui\dist\frontend\browser\index.html"
400
+ $ShowcaseIndexAlt1 = "$RootDir\apps\showcase_ui\dist\browser\index.html"
401
+ $ShowcaseIndexAlt2 = "$RootDir\apps\showcase_ui\dist\index.html"
402
+ if ((-not (Test-Path $ShowcaseIndex)) -and (-not (Test-Path $ShowcaseIndexAlt1)) -and (-not (Test-Path $ShowcaseIndexAlt2))) {
403
+ if (-not (Test-NodeCompatible)) {
404
+ if (Test-CommandExists "node") {
405
+ $curVer = (& node -v 2>$null)
406
+ Write-Host " [WARN] Detected Node.js $curVer, but Angular CLI requires Node.js >= v22.22.0." -ForegroundColor Yellow
407
+ } else {
408
+ Write-Host " [WARN] Node.js/npm not found (required for Showcase UI)." -ForegroundColor Cyan
409
+ }
410
+
411
+ # 1. Try nvm if available on Windows
412
+ if (Test-CommandExists "nvm") {
413
+ Write-Host " [INFO] Installing Node.js 22 LTS via nvm..." -ForegroundColor Cyan
414
+ & nvm install 22.23.2 | Out-Null
415
+ & nvm use 22.23.2 | Out-Null
416
+ Update-EnvironmentPath
417
+ }
418
+
419
+ # 2. Try WinGet
420
+ if (-not (Test-NodeCompatible)) {
421
+ $useWinGetNode = $false
422
+ if (Test-CommandExists "winget") {
423
+ if ([Console]::IsInputRedirected -eq $false) {
424
+ $ans = Read-Host " Install/Upgrade Node.js via WinGet (may require Administrator)? [Y/n]"
425
+ if ($ans -eq "" -or $ans -match "^[Yy]") {
426
+ $useWinGetNode = $true
427
+ }
428
+ } else {
429
+ $useWinGetNode = $true
430
+ }
431
+ }
432
+
433
+ if ($useWinGetNode) {
434
+ Write-Host " [INFO] Installing/Upgrading Node.js LTS via WinGet..." -ForegroundColor Cyan
435
+ winget install --id OpenJS.NodeJS.LTS -e --accept-source-agreements --accept-package-agreements --silent 2>$null | Out-Null
436
+ Update-EnvironmentPath
437
+ }
438
+ }
439
+
440
+ # 3. Zero-admin user-space fallback for Node.js if still not compatible
441
+ if (-not (Test-NodeCompatible)) {
442
+ Install-PortableNode
443
+ }
444
+ }
445
+
446
+ if (Test-NodeCompatible) {
447
+ $nodeVer = (& node -v 2>$null)
448
+ Write-Host " [OK] Node.js $nodeVer is ready." -ForegroundColor Green
449
+ Write-Host " [INFO] Compiling Angular Showcase UI..." -ForegroundColor Cyan
450
+ Push-Location "$RootDir\apps\showcase_ui"
451
+ try {
452
+ $npmExec = if (Test-CommandExists "npm.cmd") { "npm.cmd" } else { "npm" }
453
+ Write-Host " [INFO] Installing frontend npm dependencies..." -ForegroundColor Cyan
454
+ & $npmExec install --no-audit --no-fund --loglevel=error
455
+ if ($LASTEXITCODE -ne 0) {
456
+ Write-Host " [WARN] npm install returned exit code $LASTEXITCODE. Trying silent install..." -ForegroundColor DarkYellow
457
+ & $npmExec install --silent
458
+ }
459
+ $cliNodeVersion = "$RootDir\apps\showcase_ui\node_modules\@angular\cli\src\utilities\node-version.js"
460
+ if (Test-Path $cliNodeVersion) {
461
+ (Get-Content $cliNodeVersion) -replace '22\.22\.3', '22.22.0' | Set-Content $cliNodeVersion
462
+ }
463
+ Write-Host " [INFO] Building Angular frontend application..." -ForegroundColor Cyan
464
+ & $npmExec run build
465
+ if (Test-Path $ShowcaseIndex) {
466
+ Write-Host " [OK] Showcase UI compiled successfully." -ForegroundColor Green
467
+ } elseif (Test-Path $ShowcaseIndexAlt1) {
468
+ Write-Host " [OK] Showcase UI compiled successfully." -ForegroundColor Green
469
+ } else {
470
+ Write-Host " [WARN] Showcase UI build finished but index.html was not found in expected dist directory." -ForegroundColor DarkYellow
471
+ }
472
+ } catch {
473
+ Write-Host " [WARN] Failed to build Showcase UI: $_" -ForegroundColor DarkYellow
474
+ } finally {
475
+ Pop-Location
476
+ }
477
+ } else {
478
+ Write-Host " [WARN] Could not configure compatible Node.js (>= 22.22.0). Showcase UI will show fallback notice on launch." -ForegroundColor DarkYellow
479
+ }
480
+ } else {
481
+ Write-Host " [OK] Showcase UI build already exists." -ForegroundColor Green
482
+ }
483
+
484
+ # 6. Toolchain Readiness Summary
485
+ Write-Host "`n6. Toolchain Readiness Summary:" -ForegroundColor Yellow
486
+ $tools = @("adb", "ffmpeg", "scrcpy", "uv", "npm")
487
+ foreach ($t in $tools) {
488
+ $hasCmd = Test-CommandExists $t
489
+ if (-not $hasCmd -and $t -eq "npm") {
490
+ $hasCmd = Test-CommandExists "npm.cmd"
491
+ }
492
+ if ($hasCmd) {
493
+ $targetName = if ($t -eq "npm" -and -not (Test-CommandExists "npm") -and (Test-CommandExists "npm.cmd")) { "npm.cmd" } else { $t }
494
+ $p = (Get-Command $targetName).Source
495
+ if ($t -eq "npm" -and (Test-CommandExists "node")) {
496
+ $nVer = (& node -v 2>$null)
497
+ Write-Host " [OK] $t ($nVer) -> $p" -ForegroundColor Green
498
+ } else {
499
+ Write-Host " [OK] $t -> $p" -ForegroundColor Green
500
+ }
501
+ } else {
502
+ Write-Host " [--] $t -> Not found in PATH (Fallbacks active)" -ForegroundColor DarkYellow
503
+ }
504
+ }
505
+
506
+ Write-Host ""
507
+ Write-Host "======================================================" -ForegroundColor Cyan
508
+ Write-Host " Artemis Environment Ready! " -ForegroundColor Green
509
+ Write-Host "======================================================" -ForegroundColor Cyan
510
+
511
+ if ($Launch -or $Open) {
512
+ Start-LocalAdbServer
513
+ Write-Host "[INFO] Launching Showcase UI..." -ForegroundColor Green
514
+ uv run python -m artemis ui --open
515
+ } else {
516
+ Write-Host "To start the Showcase UI and interactive onboarding:" -ForegroundColor White
517
+ Write-Host " -> .\start.bat (or: uv run python -m artemis ui)" -ForegroundColor Cyan
518
+ Write-Host ""
519
+ }
520
+