taphound 0.2.0-dev.1 → 0.2.0-dev.11

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 (447) hide show
  1. package/README.md +49 -149
  2. package/README.zh-CN.md +47 -147
  3. package/assets/skills/taphound-case-suite/SKILL.md +363 -0
  4. package/assets/skills/taphound-case-suite/schemas/base-flow-record.schema.json +22 -0
  5. package/assets/skills/taphound-case-suite/schemas/case-catalog.schema.json +26 -0
  6. package/assets/skills/taphound-case-suite/schemas/case-ledger.schema.json +158 -0
  7. package/assets/skills/taphound-case-suite/schemas/suite-input.schema.json +41 -0
  8. package/assets/skills/taphound-case-suite/schemas/transition.schema.json +61 -0
  9. package/assets/skills/taphound-case-suite/scripts/ledger.mjs +1207 -0
  10. package/assets/skills/taphound-case-suite/templates/base-flow-record.example.json +20 -0
  11. package/assets/skills/taphound-case-suite/templates/suite-input.example.json +27 -0
  12. package/assets/skills/taphound-case-suite/templates/transition.example.json +8 -0
  13. package/assets/skills/taphound-flash/SKILL.md +115 -0
  14. package/assets/skills/taphound-flash/scripts/flash.mjs +585 -0
  15. package/assets/skills/taphound-flash/templates/flash-plan.example.json +15 -0
  16. package/assets/skills/taphound-journey-brief-author/CONTEXT-GUIDE.md +471 -0
  17. package/assets/skills/taphound-journey-brief-author/SKILL.md +494 -0
  18. package/assets/skills/taphound-journey-brief-author/prompts/brief-author-role.md +96 -0
  19. package/assets/skills/taphound-journey-brief-author/prompts/brief-author-role.zh-CN.md +80 -0
  20. package/assets/skills/taphound-journey-brief-author/prompts/context-analyze-project.md +309 -0
  21. package/assets/skills/taphound-journey-brief-author/schemas/context-refresh-result.json +123 -0
  22. package/assets/skills/taphound-journey-brief-author/schemas/project-context-module.json +192 -0
  23. package/assets/skills/taphound-journey-brief-author/schemas/project-context.json +152 -0
  24. package/assets/skills/taphound-journey-brief-author/templates/project-context-module.example.json +58 -0
  25. package/assets/skills/taphound-journey-brief-author/templates/project-context.example.json +51 -0
  26. package/assets/skills/taphound-journey-brief-author/templates/taphound-journey-brief.template.md +63 -0
  27. package/assets/skills/taphound-journey-generator/SKILL.md +500 -0
  28. package/assets/skills/{taphound-ai-journey → taphound-journey-generator}/prompts/check-completion.md +3 -0
  29. package/assets/skills/taphound-journey-generator/prompts/consume-journey-brief.md +52 -0
  30. package/assets/skills/taphound-journey-generator/prompts/generate-step.md +211 -0
  31. package/assets/skills/taphound-journey-generator/prompts/select-flow.md +91 -0
  32. package/assets/skills/taphound-journey-generator/references/bridge.md +35 -0
  33. package/assets/skills/taphound-journey-generator/references/mid-session.md +44 -0
  34. package/assets/skills/taphound-journey-generator/schemas/external-flow.json +37 -0
  35. package/assets/skills/taphound-journey-generator/schemas/flow.json +28 -0
  36. package/assets/skills/taphound-journey-generator/schemas/journey-source.json +25 -0
  37. package/assets/skills/{taphound-ai-journey → taphound-journey-generator}/schemas/observe-output.json +13 -4
  38. package/assets/skills/{taphound-ai-journey → taphound-journey-generator}/schemas/proposed-step-envelope.json +127 -5
  39. package/assets/skills/taphound-journey-generator/scripts/envelope.mjs +561 -0
  40. package/assets/skills/taphound-journey-generator/templates/external-flow.example.json +22 -0
  41. package/assets/skills/taphound-journey-generator/templates/flow.example.json +22 -0
  42. package/assets/skills/taphound-journey-generator/templates/journey-source.example.json +17 -0
  43. package/assets/skills/taphound-journey-generator/templates/taphound-journey-brief.example.md +70 -0
  44. package/assets/skills/taphound-verify-change/SKILL.md +91 -0
  45. package/assets/skills/taphound-verify-change/references/accept.md +38 -0
  46. package/assets/skills/taphound-verify-change/references/preserve.md +349 -0
  47. package/assets/skills/taphound-verify-change/schemas/workflow-manifest.schema.json +295 -0
  48. package/assets/skills/taphound-verify-change/scripts/handoff.mjs +482 -0
  49. package/assets/skills/taphound-verify-change/scripts/ui-refactor.mjs +505 -0
  50. package/dist/adapters/adb/adb-adapter.d.ts +16 -2
  51. package/dist/adapters/adb/adb-adapter.js +199 -0
  52. package/dist/adapters/adb/system-uiautomator-snapshot-provider.d.ts +13 -0
  53. package/dist/adapters/adb/system-uiautomator-snapshot-provider.js +122 -0
  54. package/dist/adapters/adb/ui-automator-parser.d.ts +3 -0
  55. package/dist/adapters/adb/ui-automator-parser.js +160 -0
  56. package/dist/adapters/adb/window-topology-parser.d.ts +2 -0
  57. package/dist/adapters/adb/window-topology-parser.js +101 -0
  58. package/dist/adapters/android-cli/android-cli-adapter.d.ts +16 -8
  59. package/dist/adapters/android-cli/android-cli-adapter.js +137 -15
  60. package/dist/adapters/android-cli/android-cli-snapshot-provider.d.ts +9 -0
  61. package/dist/adapters/android-cli/android-cli-snapshot-provider.js +99 -0
  62. package/dist/adapters/android-cli/layout-parser.js +12 -8
  63. package/dist/adapters/appium/appium-doctor.d.ts +7 -0
  64. package/dist/adapters/appium/appium-doctor.js +128 -0
  65. package/dist/adapters/appium/appium-ui-snapshot-provider.d.ts +34 -0
  66. package/dist/adapters/appium/appium-ui-snapshot-provider.js +240 -0
  67. package/dist/adapters/camera/camera-probe-adapter.d.ts +18 -0
  68. package/dist/adapters/camera/camera-probe-adapter.js +286 -0
  69. package/dist/adapters/filesystem/artifact-store.js +40 -1
  70. package/dist/adapters/filesystem/context-document-writer.d.ts +15 -0
  71. package/dist/adapters/filesystem/context-document-writer.js +112 -0
  72. package/dist/adapters/filesystem/external-flow-registry.d.ts +17 -0
  73. package/dist/adapters/filesystem/external-flow-registry.js +325 -0
  74. package/dist/adapters/filesystem/generation-session-store.d.ts +17 -11
  75. package/dist/adapters/filesystem/generation-session-store.js +281 -855
  76. package/dist/adapters/filesystem/generation-store/session-lock.d.ts +29 -0
  77. package/dist/adapters/filesystem/generation-store/session-lock.js +202 -0
  78. package/dist/adapters/filesystem/generation-store/session-transitions.d.ts +24 -0
  79. package/dist/adapters/filesystem/generation-store/session-transitions.js +340 -0
  80. package/dist/adapters/filesystem/generation-store/store-files.d.ts +50 -0
  81. package/dist/adapters/filesystem/generation-store/store-files.js +363 -0
  82. package/dist/adapters/filesystem/journey-composition-store.d.ts +23 -0
  83. package/dist/adapters/filesystem/journey-composition-store.js +151 -0
  84. package/dist/adapters/filesystem/knowledge-registry.d.ts +12 -0
  85. package/dist/adapters/filesystem/knowledge-registry.js +223 -0
  86. package/dist/adapters/filesystem/project-bound-file.js +3 -5
  87. package/dist/adapters/filesystem/project-file-inspector.d.ts +2 -0
  88. package/dist/adapters/filesystem/project-file-inspector.js +57 -28
  89. package/dist/adapters/filesystem/project-identity-inspector.d.ts +7 -0
  90. package/dist/adapters/filesystem/project-identity-inspector.js +215 -0
  91. package/dist/adapters/filesystem/project-inventory-inspector.d.ts +8 -0
  92. package/dist/adapters/filesystem/project-inventory-inspector.js +93 -0
  93. package/dist/adapters/filesystem/project-module-discoverer.d.ts +6 -0
  94. package/dist/adapters/filesystem/project-module-discoverer.js +158 -0
  95. package/dist/adapters/filesystem/skill-installer.d.ts +7 -2
  96. package/dist/adapters/filesystem/skill-installer.js +40 -11
  97. package/dist/adapters/filesystem/workspace-layout.d.ts +7 -0
  98. package/dist/adapters/filesystem/workspace-layout.js +57 -0
  99. package/dist/adapters/git/node-git-diff.d.ts +17 -0
  100. package/dist/adapters/git/node-git-diff.js +114 -0
  101. package/dist/adapters/process/node-detached-process-launcher.d.ts +6 -0
  102. package/dist/adapters/process/node-detached-process-launcher.js +96 -0
  103. package/dist/adapters/process/node-process-runner.js +11 -2
  104. package/dist/adapters/prompt/inquirer-align-prompt.d.ts +27 -0
  105. package/dist/adapters/prompt/inquirer-align-prompt.js +65 -0
  106. package/dist/adapters/prompt/inquirer-generation-prompt.js +3 -0
  107. package/dist/adapters/prompt/inquirer-recorder-prompt.d.ts +9 -1
  108. package/dist/adapters/prompt/inquirer-recorder-prompt.js +63 -0
  109. package/dist/adapters/runtime/adb-runtime-backend.d.ts +67 -0
  110. package/dist/adapters/runtime/adb-runtime-backend.js +206 -0
  111. package/dist/adapters/runtime/fake-runtime-backend.d.ts +87 -0
  112. package/dist/adapters/runtime/fake-runtime-backend.js +240 -0
  113. package/dist/adapters/runtime/mobile-mcp/mcp-tool-client.d.ts +45 -0
  114. package/dist/adapters/runtime/mobile-mcp/mcp-tool-client.js +153 -0
  115. package/dist/adapters/runtime/mobile-mcp/mobile-mcp-errors.d.ts +23 -0
  116. package/dist/adapters/runtime/mobile-mcp/mobile-mcp-errors.js +39 -0
  117. package/dist/adapters/runtime/mobile-mcp/mobile-mcp-responses.d.ts +20 -0
  118. package/dist/adapters/runtime/mobile-mcp/mobile-mcp-responses.js +180 -0
  119. package/dist/adapters/runtime/mobile-mcp/mobile-mcp-runtime-backend.d.ts +78 -0
  120. package/dist/adapters/runtime/mobile-mcp/mobile-mcp-runtime-backend.js +379 -0
  121. package/dist/adapters/runtime/mobile-mcp/mobile-mcp-tools.d.ts +46 -0
  122. package/dist/adapters/runtime/session-adb-view.d.ts +53 -0
  123. package/dist/adapters/runtime/session-adb-view.js +193 -0
  124. package/dist/adapters/runtime/session-backed-ports.d.ts +21 -0
  125. package/dist/adapters/runtime/session-backed-ports.js +43 -0
  126. package/dist/adapters/runtime/shared-session-runtime-backend.d.ts +12 -0
  127. package/dist/adapters/runtime/shared-session-runtime-backend.js +64 -0
  128. package/dist/adapters/ui/auto-ui-snapshot-provider.d.ts +8 -0
  129. package/dist/adapters/ui/auto-ui-snapshot-provider.js +48 -0
  130. package/dist/adapters/ui/device-layout-temp.d.ts +6 -0
  131. package/dist/adapters/ui/device-layout-temp.js +18 -0
  132. package/dist/adapters/ui/device-ui-environment.d.ts +13 -0
  133. package/dist/adapters/ui/device-ui-environment.js +81 -0
  134. package/dist/adapters/ui/layout-normalization.d.ts +9 -0
  135. package/dist/adapters/ui/layout-normalization.js +44 -0
  136. package/dist/adapters/ui/ui-snapshot-error.d.ts +11 -0
  137. package/dist/adapters/ui/ui-snapshot-error.js +12 -0
  138. package/dist/adapters/ui/ui-snapshot-support.d.ts +15 -0
  139. package/dist/adapters/ui/ui-snapshot-support.js +12 -0
  140. package/dist/application/align/align-service.d.ts +42 -0
  141. package/dist/application/align/align-service.js +106 -0
  142. package/dist/application/assertion/expectation-evaluator.d.ts +18 -5
  143. package/dist/application/assertion/expectation-evaluator.js +156 -18
  144. package/dist/application/assertion/guarded-expectation.d.ts +45 -0
  145. package/dist/application/assertion/guarded-expectation.js +74 -0
  146. package/dist/application/checkpoint/baseline-capturer.d.ts +26 -0
  147. package/dist/application/checkpoint/baseline-capturer.js +163 -0
  148. package/dist/application/checkpoint/baseline-error.d.ts +5 -0
  149. package/dist/application/checkpoint/baseline-error.js +8 -0
  150. package/dist/application/checkpoint/baseline-service.d.ts +31 -0
  151. package/dist/application/checkpoint/baseline-service.js +147 -0
  152. package/dist/application/checkpoint/checkpoint-evaluator.d.ts +35 -0
  153. package/dist/application/checkpoint/checkpoint-evaluator.js +415 -0
  154. package/dist/application/checkpoint/regression-comparator.d.ts +18 -0
  155. package/dist/application/checkpoint/regression-comparator.js +192 -0
  156. package/dist/application/collector/logcat-collector.d.ts +22 -1
  157. package/dist/application/collector/logcat-collector.js +103 -15
  158. package/dist/application/collector/logcat-event.d.ts +8 -0
  159. package/dist/application/collector/logcat-event.js +79 -0
  160. package/dist/application/collector/logcat-stop.d.ts +2 -0
  161. package/dist/application/collector/logcat-stop.js +11 -0
  162. package/dist/application/context/context-generator.d.ts +45 -0
  163. package/dist/application/context/context-generator.js +228 -0
  164. package/dist/application/context/context-loader.d.ts +40 -0
  165. package/dist/application/context/context-loader.js +223 -0
  166. package/dist/application/context/context-refresher.d.ts +59 -0
  167. package/dist/application/context/context-refresher.js +349 -0
  168. package/dist/application/context/context-rehasher.d.ts +36 -0
  169. package/dist/application/context/context-rehasher.js +110 -0
  170. package/dist/application/context/context-validator.d.ts +23 -1
  171. package/dist/application/context/context-validator.js +116 -9
  172. package/dist/application/context/evidence-hash.d.ts +1 -0
  173. package/dist/application/context/evidence-hash.js +125 -0
  174. package/dist/application/context/evidence-match.d.ts +9 -0
  175. package/dist/application/context/evidence-match.js +8 -0
  176. package/dist/application/context/shard-identity.d.ts +2 -0
  177. package/dist/application/context/shard-identity.js +7 -0
  178. package/dist/application/contract/contract-loader.d.ts +25 -0
  179. package/dist/application/contract/contract-loader.js +68 -0
  180. package/dist/application/contract/contract-review.d.ts +25 -0
  181. package/dist/application/contract/contract-review.js +51 -0
  182. package/dist/application/contract/contract-verifier.d.ts +53 -0
  183. package/dist/application/contract/contract-verifier.js +645 -0
  184. package/dist/application/devices/resolve-device-assignments.d.ts +21 -0
  185. package/dist/application/devices/resolve-device-assignments.js +60 -0
  186. package/dist/application/diagnosis/failure-classifier.d.ts +23 -0
  187. package/dist/application/diagnosis/failure-classifier.js +179 -0
  188. package/dist/application/doctor/doctor-service.d.ts +36 -3
  189. package/dist/application/doctor/doctor-service.js +255 -25
  190. package/dist/application/generation/generation-app-preparer.d.ts +20 -0
  191. package/dist/application/generation/generation-app-preparer.js +28 -0
  192. package/dist/application/generation/generation-config-service.d.ts +21 -0
  193. package/dist/application/generation/generation-config-service.js +53 -0
  194. package/dist/application/generation/generation-confirmation-service.d.ts +14 -3
  195. package/dist/application/generation/generation-confirmation-service.js +109 -24
  196. package/dist/application/generation/generation-context-snapshot.d.ts +6 -0
  197. package/dist/application/generation/generation-context-snapshot.js +29 -0
  198. package/dist/application/generation/generation-finalizer.d.ts +15 -9
  199. package/dist/application/generation/generation-finalizer.js +167 -70
  200. package/dist/application/generation/generation-publisher.js +12 -8
  201. package/dist/application/generation/generation-recovery-service.d.ts +35 -0
  202. package/dist/application/generation/generation-recovery-service.js +144 -0
  203. package/dist/application/generation/generation-reopen-service.d.ts +15 -0
  204. package/dist/application/generation/generation-reopen-service.js +37 -0
  205. package/dist/application/generation/generation-replace-service.d.ts +32 -0
  206. package/dist/application/generation/generation-replace-service.js +116 -0
  207. package/dist/application/generation/generation-starter.d.ts +44 -4
  208. package/dist/application/generation/generation-starter.js +175 -8
  209. package/dist/application/generation/generation-step-executor.d.ts +67 -5
  210. package/dist/application/generation/generation-step-executor.js +471 -108
  211. package/dist/application/generation/proposed-step-validator.js +96 -30
  212. package/dist/application/generation/replay-policy-loader.d.ts +16 -0
  213. package/dist/application/generation/replay-policy-loader.js +29 -0
  214. package/dist/application/generation/risk-evaluator.d.ts +4 -1
  215. package/dist/application/generation/risk-evaluator.js +118 -3
  216. package/dist/application/generation/runtime-observer.d.ts +39 -7
  217. package/dist/application/generation/runtime-observer.js +193 -24
  218. package/dist/application/impact/impact-resolver.d.ts +32 -0
  219. package/dist/application/impact/impact-resolver.js +160 -0
  220. package/dist/application/init/init-service.js +26 -13
  221. package/dist/application/interaction/action-executor.d.ts +3 -2
  222. package/dist/application/interaction/action-executor.js +11 -1
  223. package/dist/application/interaction/action-target.d.ts +17 -0
  224. package/dist/application/interaction/action-target.js +40 -0
  225. package/dist/application/interaction/external-step-runner.d.ts +153 -0
  226. package/dist/application/interaction/external-step-runner.js +332 -0
  227. package/dist/application/interaction/fallback-resolver.d.ts +6 -3
  228. package/dist/application/interaction/fallback-resolver.js +7 -5
  229. package/dist/application/interaction/scroll-to-executor.d.ts +17 -3
  230. package/dist/application/interaction/scroll-to-executor.js +118 -36
  231. package/dist/application/journey/external-flow-resolver.d.ts +25 -0
  232. package/dist/application/journey/external-flow-resolver.js +22 -0
  233. package/dist/application/journey/journey-check-service.d.ts +54 -0
  234. package/dist/application/journey/journey-check-service.js +207 -0
  235. package/dist/application/journey/journey-promoter.d.ts +26 -0
  236. package/dist/application/journey/journey-promoter.js +123 -0
  237. package/dist/application/journey/journey-resolver.d.ts +42 -0
  238. package/dist/application/journey/journey-resolver.js +239 -0
  239. package/dist/application/journey/journey-retirer.d.ts +25 -0
  240. package/dist/application/journey/journey-retirer.js +87 -0
  241. package/dist/application/knowledge/anchor-resolver.d.ts +36 -0
  242. package/dist/application/knowledge/anchor-resolver.js +110 -0
  243. package/dist/application/knowledge/knowledge-loader.d.ts +16 -0
  244. package/dist/application/knowledge/knowledge-loader.js +36 -0
  245. package/dist/application/locator/layout-failure-summary.d.ts +2 -0
  246. package/dist/application/locator/layout-failure-summary.js +67 -0
  247. package/dist/application/locator/layout-traversal.d.ts +11 -0
  248. package/dist/application/locator/layout-traversal.js +18 -0
  249. package/dist/application/locator/locator-resolver.d.ts +13 -1
  250. package/dist/application/locator/locator-resolver.js +182 -18
  251. package/dist/application/observe/observe-service.d.ts +20 -0
  252. package/dist/application/observe/observe-service.js +91 -0
  253. package/dist/application/project/project-describer.d.ts +14 -6
  254. package/dist/application/project/project-describer.js +38 -5
  255. package/dist/application/recognition/screen-detector.d.ts +28 -0
  256. package/dist/application/recognition/screen-detector.js +111 -0
  257. package/dist/application/recorder/locator-selector.js +151 -17
  258. package/dist/application/recorder/recorder-service.d.ts +16 -4
  259. package/dist/application/recorder/recorder-service.js +420 -128
  260. package/dist/application/report/report-writer.js +1 -1
  261. package/dist/application/runtime/cold-launch.d.ts +28 -0
  262. package/dist/application/runtime/cold-launch.js +59 -0
  263. package/dist/application/runtime/step-runner.d.ts +49 -4
  264. package/dist/application/runtime/step-runner.js +721 -130
  265. package/dist/application/runtime/verify-runtime.d.ts +57 -7
  266. package/dist/application/runtime/verify-runtime.js +554 -174
  267. package/dist/application/ui/cached-ui-snapshot-provider.d.ts +45 -0
  268. package/dist/application/ui/cached-ui-snapshot-provider.js +111 -0
  269. package/dist/application/ui/ui-snapshot-lifecycle.d.ts +2 -0
  270. package/dist/application/ui/ui-snapshot-lifecycle.js +8 -0
  271. package/dist/application/ui/ui-stability-probe.d.ts +3 -0
  272. package/dist/application/ui/ui-stability-probe.js +8 -0
  273. package/dist/application/wait/idle-advice.d.ts +6 -0
  274. package/dist/application/wait/idle-advice.js +27 -0
  275. package/dist/application/wait/idle-profiles.d.ts +15 -0
  276. package/dist/application/wait/idle-profiles.js +75 -0
  277. package/dist/application/wait/idle-waiter.d.ts +28 -4
  278. package/dist/application/wait/idle-waiter.js +186 -15
  279. package/dist/cli/commands/align.d.ts +3 -0
  280. package/dist/cli/commands/align.js +124 -0
  281. package/dist/cli/commands/baseline.d.ts +3 -0
  282. package/dist/cli/commands/baseline.js +130 -0
  283. package/dist/cli/commands/context.js +300 -27
  284. package/dist/cli/commands/contract.d.ts +3 -0
  285. package/dist/cli/commands/contract.js +120 -0
  286. package/dist/cli/commands/doctor.js +16 -9
  287. package/dist/cli/commands/failure.d.ts +3 -0
  288. package/dist/cli/commands/failure.js +63 -0
  289. package/dist/cli/commands/generation/lifecycle-commands.d.ts +5 -0
  290. package/dist/cli/commands/generation/lifecycle-commands.js +211 -0
  291. package/dist/cli/commands/generation/session-commands.d.ts +11 -0
  292. package/dist/cli/commands/generation/session-commands.js +472 -0
  293. package/dist/cli/commands/generation/shared.d.ts +1414 -0
  294. package/dist/cli/commands/generation/shared.js +291 -0
  295. package/dist/cli/commands/generation/step-commands.d.ts +8 -0
  296. package/dist/cli/commands/generation/step-commands.js +315 -0
  297. package/dist/cli/commands/generation.js +10 -507
  298. package/dist/cli/commands/impact.d.ts +3 -0
  299. package/dist/cli/commands/impact.js +87 -0
  300. package/dist/cli/commands/init.js +13 -6
  301. package/dist/cli/commands/journey.d.ts +3 -0
  302. package/dist/cli/commands/journey.js +382 -0
  303. package/dist/cli/commands/knowledge.d.ts +3 -0
  304. package/dist/cli/commands/knowledge.js +93 -0
  305. package/dist/cli/commands/observe.d.ts +3 -0
  306. package/dist/cli/commands/observe.js +127 -0
  307. package/dist/cli/commands/project.js +2 -1
  308. package/dist/cli/commands/record.js +18 -5
  309. package/dist/cli/commands/verify.js +273 -63
  310. package/dist/cli/dependencies.d.ts +125 -1
  311. package/dist/cli/dependencies.js +450 -51
  312. package/dist/cli/diff-verification.d.ts +41 -0
  313. package/dist/cli/diff-verification.js +192 -0
  314. package/dist/cli/main.js +49 -1
  315. package/dist/cli/output.d.ts +5 -3
  316. package/dist/cli/output.js +12 -0
  317. package/dist/cli/program.js +19 -1
  318. package/dist/cli/project-root.d.ts +1 -0
  319. package/dist/cli/project-root.js +6 -0
  320. package/dist/cli/runtime-selection.d.ts +22 -0
  321. package/dist/cli/runtime-selection.js +92 -0
  322. package/dist/cli/version.d.ts +1 -0
  323. package/dist/cli/version.js +14 -0
  324. package/dist/cli/workspace-guard.d.ts +2 -0
  325. package/dist/cli/workspace-guard.js +3 -0
  326. package/dist/domain/binding-reference.d.ts +4 -0
  327. package/dist/domain/binding-reference.js +23 -0
  328. package/dist/domain/checkpoint.d.ts +404 -0
  329. package/dist/domain/checkpoint.js +297 -0
  330. package/dist/domain/config.d.ts +107 -1
  331. package/dist/domain/config.js +52 -6
  332. package/dist/domain/contract.d.ts +413 -0
  333. package/dist/domain/contract.js +196 -0
  334. package/dist/domain/external-flow.d.ts +493 -0
  335. package/dist/domain/external-flow.js +15 -0
  336. package/dist/domain/failure-classification.d.ts +176 -0
  337. package/dist/domain/failure-classification.js +169 -0
  338. package/dist/domain/failure.d.ts +2 -1
  339. package/dist/domain/failure.js +123 -0
  340. package/dist/domain/generation.d.ts +1671 -132
  341. package/dist/domain/generation.js +202 -13
  342. package/dist/domain/geometry.d.ts +13 -0
  343. package/dist/domain/geometry.js +16 -0
  344. package/dist/domain/impact.d.ts +71 -0
  345. package/dist/domain/impact.js +76 -0
  346. package/dist/domain/init.d.ts +12 -4
  347. package/dist/domain/init.js +24 -18
  348. package/dist/domain/journey-composition.d.ts +2285 -0
  349. package/dist/domain/journey-composition.js +85 -0
  350. package/dist/domain/journey-lifecycle.d.ts +10 -0
  351. package/dist/domain/journey-lifecycle.js +9 -0
  352. package/dist/domain/journey.d.ts +2419 -212
  353. package/dist/domain/journey.js +384 -14
  354. package/dist/domain/knowledge.d.ts +165 -0
  355. package/dist/domain/knowledge.js +188 -0
  356. package/dist/domain/layout.d.ts +34 -5
  357. package/dist/domain/layout.js +64 -6
  358. package/dist/domain/locator-evidence.d.ts +3 -0
  359. package/dist/domain/locator-evidence.js +36 -0
  360. package/dist/domain/logcat-event.d.ts +54 -0
  361. package/dist/domain/logcat-event.js +40 -0
  362. package/dist/domain/observation.d.ts +33 -0
  363. package/dist/domain/observation.js +18 -0
  364. package/dist/domain/project-context.d.ts +219 -1
  365. package/dist/domain/project-context.js +209 -6
  366. package/dist/domain/proposed-step.d.ts +340 -60
  367. package/dist/domain/proposed-step.js +23 -3
  368. package/dist/domain/report.d.ts +1455 -28
  369. package/dist/domain/report.js +211 -14
  370. package/dist/domain/runtime-snapshot.d.ts +58 -1
  371. package/dist/domain/runtime-snapshot.js +14 -3
  372. package/dist/domain/runtime.d.ts +50 -0
  373. package/dist/domain/runtime.js +36 -0
  374. package/dist/domain/system-app-profiles.d.ts +6 -0
  375. package/dist/domain/system-app-profiles.js +43 -0
  376. package/dist/domain/ui-backend.d.ts +28 -0
  377. package/dist/domain/ui-backend.js +33 -0
  378. package/dist/domain/ui-cache.d.ts +11 -0
  379. package/dist/domain/ui-cache.js +10 -0
  380. package/dist/domain/window-hierarchy.d.ts +84 -0
  381. package/dist/domain/window-hierarchy.js +172 -0
  382. package/dist/domain/workflow-manifest.d.ts +77 -0
  383. package/dist/domain/workflow-manifest.js +136 -0
  384. package/dist/domain/workspace.d.ts +28 -0
  385. package/dist/domain/workspace.js +72 -0
  386. package/dist/ports/adb.d.ts +34 -1
  387. package/dist/ports/align-prompt.d.ts +11 -0
  388. package/dist/ports/align-prompt.js +6 -0
  389. package/dist/ports/anchor-resolver.d.ts +30 -0
  390. package/dist/ports/anchor-resolver.js +1 -0
  391. package/dist/ports/annotated-screen-resolver.d.ts +4 -0
  392. package/dist/ports/annotated-screen-resolver.js +1 -0
  393. package/dist/ports/camera-probe.d.ts +23 -0
  394. package/dist/ports/camera-probe.js +8 -0
  395. package/dist/ports/context-document-writer.d.ts +24 -0
  396. package/dist/ports/context-document-writer.js +1 -0
  397. package/dist/ports/detached-process-launcher.d.ts +12 -0
  398. package/dist/ports/detached-process-launcher.js +1 -0
  399. package/dist/ports/external-flow-registry.d.ts +37 -0
  400. package/dist/ports/external-flow-registry.js +1 -0
  401. package/dist/ports/generation-prompt.d.ts +2 -1
  402. package/dist/ports/generation-session-store.d.ts +12 -2
  403. package/dist/ports/git-diff.d.ts +9 -0
  404. package/dist/ports/git-diff.js +1 -0
  405. package/dist/ports/journey-composition-store.d.ts +17 -0
  406. package/dist/ports/journey-composition-store.js +1 -0
  407. package/dist/ports/knowledge-registry.d.ts +20 -0
  408. package/dist/ports/knowledge-registry.js +1 -0
  409. package/dist/ports/process-runner.d.ts +7 -0
  410. package/dist/ports/project-file-inspector.d.ts +1 -0
  411. package/dist/ports/project-identity-inspector.d.ts +24 -0
  412. package/dist/ports/project-identity-inspector.js +1 -0
  413. package/dist/ports/project-inventory-inspector.d.ts +21 -0
  414. package/dist/ports/project-inventory-inspector.js +1 -0
  415. package/dist/ports/project-module-discoverer.d.ts +26 -0
  416. package/dist/ports/project-module-discoverer.js +1 -0
  417. package/dist/ports/recorder-prompt.d.ts +10 -1
  418. package/dist/ports/runtime-backend.d.ts +89 -0
  419. package/dist/ports/runtime-backend.js +13 -0
  420. package/dist/ports/runtime-capability.d.ts +12 -0
  421. package/dist/ports/runtime-capability.js +20 -0
  422. package/dist/ports/runtime-session-ports.d.ts +25 -0
  423. package/dist/ports/runtime-session-ports.js +1 -0
  424. package/dist/ports/screenshot.d.ts +11 -0
  425. package/dist/ports/screenshot.js +1 -0
  426. package/dist/ports/skill-installer.d.ts +2 -2
  427. package/dist/ports/ui-snapshot.d.ts +35 -0
  428. package/dist/ports/ui-snapshot.js +1 -0
  429. package/dist/ports/ui-stability.d.ts +19 -0
  430. package/dist/ports/ui-stability.js +1 -0
  431. package/dist/ports/workspace-layout.d.ts +4 -0
  432. package/dist/ports/workspace-layout.js +1 -0
  433. package/dist/shared/errors.d.ts +2 -0
  434. package/dist/shared/errors.js +22 -0
  435. package/dist/shared/paths.d.ts +2 -0
  436. package/dist/shared/paths.js +24 -0
  437. package/dist/shared/strings.d.ts +2 -0
  438. package/dist/shared/strings.js +16 -0
  439. package/package.json +6 -1
  440. package/assets/skills/taphound-ai-journey/GUIDE.md +0 -862
  441. package/assets/skills/taphound-ai-journey/SKILL.md +0 -377
  442. package/assets/skills/taphound-ai-journey/prompts/analyze-project.md +0 -526
  443. package/assets/skills/taphound-ai-journey/prompts/generate-step.md +0 -109
  444. package/assets/skills/taphound-ai-journey/schemas/project-context.json +0 -81
  445. package/assets/skills/taphound-ai-journey/templates/project-context.example.json +0 -49
  446. package/dist/ports/android-cli.d.ts +0 -21
  447. /package/dist/{ports/android-cli.js → adapters/runtime/mobile-mcp/mobile-mcp-tools.js} +0 -0
@@ -35,6 +35,7 @@ export class NodeProcessRunner {
35
35
  let cancelled = false;
36
36
  let spawnError;
37
37
  let settled = false;
38
+ let terminationRequested = false;
38
39
  let timeout;
39
40
  let forceKillTimeout;
40
41
  let startupTimeout;
@@ -77,11 +78,15 @@ export class NodeProcessRunner {
77
78
  child.stdout.setEncoding("utf8");
78
79
  child.stderr.setEncoding("utf8");
79
80
  child.stdout.on("data", (chunk) => {
80
- stdout += chunk;
81
+ if (handlers.captureStdout !== false) {
82
+ stdout += chunk;
83
+ }
81
84
  consumeLines(stdoutLines, chunk);
82
85
  });
83
86
  child.stderr.on("data", (chunk) => {
84
- stderr += chunk;
87
+ if (handlers.captureStderr !== false) {
88
+ stderr += chunk;
89
+ }
85
90
  consumeLines(stderrLines, chunk);
86
91
  });
87
92
  child.on("spawn", () => {
@@ -137,6 +142,7 @@ export class NodeProcessRunner {
137
142
  durationMs: performance.now() - startedAt,
138
143
  timedOut,
139
144
  cancelled,
145
+ ...(terminationRequested ? { terminationRequested: true } : {}),
140
146
  ...(spawnError === undefined ? {} : { spawnError })
141
147
  };
142
148
  settleStarted(result);
@@ -144,6 +150,9 @@ export class NodeProcessRunner {
144
150
  });
145
151
  });
146
152
  const stop = () => {
153
+ if (!settled) {
154
+ terminationRequested = true;
155
+ }
147
156
  terminate();
148
157
  return completion;
149
158
  };
@@ -0,0 +1,27 @@
1
+ import { confirm } from "@inquirer/prompts";
2
+ import { type AlignPromptPort } from "../../ports/align-prompt.js";
3
+ import type { CameraProbeResult } from "../../ports/camera-probe.js";
4
+ export type AlignInputStream = NodeJS.ReadableStream & {
5
+ isTTY?: boolean | undefined;
6
+ };
7
+ export type AlignDiagnosticStream = NodeJS.WritableStream & {
8
+ isTTY?: boolean | undefined;
9
+ };
10
+ export type AlignPromptContext = NonNullable<Parameters<typeof confirm>[1]>;
11
+ export interface AlignPromptFunctions {
12
+ confirm: (config: {
13
+ message: string;
14
+ default: boolean;
15
+ }, context: AlignPromptContext) => Promise<unknown>;
16
+ }
17
+ export declare class InquirerAlignPrompt implements AlignPromptPort {
18
+ private readonly prompts;
19
+ private readonly promptInput;
20
+ private readonly diagnostics;
21
+ constructor(prompts?: AlignPromptFunctions, promptInput?: AlignInputStream, diagnostics?: AlignDiagnosticStream);
22
+ confirmWrite(input: {
23
+ values: CameraProbeResult;
24
+ targetPath: string;
25
+ }): Promise<boolean>;
26
+ private assertLocalTty;
27
+ }
@@ -0,0 +1,65 @@
1
+ import { confirm } from "@inquirer/prompts";
2
+ import { AlignPromptCancelledError } from "../../ports/align-prompt.js";
3
+ const defaultPrompts = {
4
+ confirm: async (config, context) => confirm(config, context)
5
+ };
6
+ function formatValues(values) {
7
+ const lines = [
8
+ ` Camera package: ${values.packageName}`,
9
+ ` Camera activity: ${values.activityName}`,
10
+ ...(values.confirmActivityName === undefined
11
+ ? []
12
+ : [` Review activity: ${values.confirmActivityName}`]),
13
+ ` Shutter button: ${values.shutterResourceId}${values.shutterContentDescription !== undefined
14
+ ? ` (${values.shutterContentDescription})`
15
+ : ""}`
16
+ ];
17
+ if (values.confirmResourceId !== undefined) {
18
+ lines.push(` Confirm button: ${values.confirmResourceId}${values.confirmContentDescription !== undefined
19
+ ? ` (${values.confirmContentDescription})`
20
+ : ""}`);
21
+ }
22
+ else {
23
+ lines.push(" Confirm button: (none — camera auto-accepts)");
24
+ }
25
+ return lines.join("\n");
26
+ }
27
+ export class InquirerAlignPrompt {
28
+ prompts;
29
+ promptInput;
30
+ diagnostics;
31
+ constructor(prompts = defaultPrompts, promptInput = process.stdin, diagnostics = process.stderr) {
32
+ this.prompts = prompts;
33
+ this.promptInput = promptInput;
34
+ this.diagnostics = diagnostics;
35
+ }
36
+ async confirmWrite(input) {
37
+ this.assertLocalTty();
38
+ const body = formatValues(input.values);
39
+ let answer;
40
+ try {
41
+ answer = await this.prompts.confirm({
42
+ message: `${body}\n\nWrite flow to ${input.targetPath}?`,
43
+ default: true
44
+ }, { input: this.promptInput, output: this.diagnostics });
45
+ }
46
+ catch (error) {
47
+ if (error instanceof Error
48
+ && (error.name === "AbortPromptError"
49
+ || error.name === "ExitPromptError")) {
50
+ throw new AlignPromptCancelledError();
51
+ }
52
+ throw error;
53
+ }
54
+ if (typeof answer !== "boolean") {
55
+ throw new Error("Align confirm prompt returned an invalid answer");
56
+ }
57
+ return answer;
58
+ }
59
+ assertLocalTty() {
60
+ if (this.promptInput.isTTY !== true
61
+ || this.diagnostics.isTTY !== true) {
62
+ throw new Error("Align confirm requires local TTY input and diagnostics");
63
+ }
64
+ }
65
+ }
@@ -58,6 +58,9 @@ export class InquirerGenerationPrompt {
58
58
  throw new Error("Generation confirmation challenge is not pending");
59
59
  }
60
60
  this.diagnostics.write(`TapHound confirmation: ${challenge.actionSummary}\n`);
61
+ if (challenge.reason !== undefined) {
62
+ this.diagnostics.write(`Reason (${challenge.reason.rule}): ${challenge.reason.message}\n`);
63
+ }
61
64
  const answer = await this.ask((context) => this.prompts.confirm({
62
65
  message: `Approve action at step ${String(challenge.stepIndex)}?`,
63
66
  default: false
@@ -1,4 +1,5 @@
1
- import type { RecorderAction, RecorderPromptPort, RecorderTargetChoice, ScrollDecision, SwipeOptions } from "../../ports/recorder-prompt.js";
1
+ import type { BridgeScenario } from "../../domain/journey.js";
2
+ import type { ExternalStepAction, RecorderAction, RecorderPromptPort, RecorderTargetChoice, ScrollDecision, SwipeOptions } from "../../ports/recorder-prompt.js";
2
3
  interface SelectConfig {
3
4
  message: string;
4
5
  choices: readonly {
@@ -43,5 +44,12 @@ export declare class InquirerRecorderPrompt implements RecorderPromptPort {
43
44
  notifyFailure(message: string): Promise<void>;
44
45
  selectScrollContainer(choices: readonly RecorderTargetChoice[]): Promise<string>;
45
46
  scrollTargetDecision(choices: readonly RecorderTargetChoice[]): Promise<ScrollDecision>;
47
+ selectBridgeScenario(): Promise<BridgeScenario>;
48
+ inputBridgeDescription(scenario: BridgeScenario): Promise<string>;
49
+ inputBridgeReturnTimeoutMs(): Promise<number>;
50
+ selectExternalStepAction(): Promise<ExternalStepAction>;
51
+ notifyExternalEscape(escapedPackageName: string): Promise<void>;
52
+ notifyExternalReturn(): Promise<void>;
53
+ notifyBridgeNoEscape(): Promise<void>;
46
54
  }
47
55
  export {};
@@ -19,9 +19,26 @@ const ACTIONS = [
19
19
  "scrollTo",
20
20
  "back",
21
21
  "wait",
22
+ "bridgeTrigger",
22
23
  "finish",
23
24
  "cancel"
24
25
  ];
26
+ const EXTERNAL_STEP_ACTIONS = [
27
+ "click",
28
+ "longClick",
29
+ "inputText",
30
+ "swipe",
31
+ "scrollTo",
32
+ "back",
33
+ "wait",
34
+ "finishExternal"
35
+ ];
36
+ const BRIDGE_SCENARIOS = [
37
+ "photoCapture",
38
+ "pickImage",
39
+ "pickFile",
40
+ "custom"
41
+ ];
25
42
  function selectedString(value, allowed) {
26
43
  if (typeof value !== "string"
27
44
  || (allowed !== undefined && !allowed.includes(value))) {
@@ -154,4 +171,50 @@ export class InquirerRecorderPrompt {
154
171
  }
155
172
  return { kind: "select", id: selected };
156
173
  }
174
+ async selectBridgeScenario() {
175
+ const value = await this.prompts.select({
176
+ message: "Bridge scenario",
177
+ choices: BRIDGE_SCENARIOS.map((scenario) => ({
178
+ name: scenario,
179
+ value: scenario
180
+ }))
181
+ });
182
+ return selectedString(value, BRIDGE_SCENARIOS);
183
+ }
184
+ async inputBridgeDescription(scenario) {
185
+ const value = await this.prompts.input({
186
+ message: `Bridge description${scenario === "custom" ? " (required)" : ""}`,
187
+ validate: (answer) => answer.trim().length > 0 || "Description must not be empty"
188
+ });
189
+ return selectedString(value);
190
+ }
191
+ async inputBridgeReturnTimeoutMs() {
192
+ return selectedNumber(await this.prompts.number({
193
+ message: "Return timeout (ms)",
194
+ default: 30000,
195
+ min: 1
196
+ }), 1);
197
+ }
198
+ async selectExternalStepAction() {
199
+ const value = await this.prompts.select({
200
+ message: "Choose an external App Action",
201
+ choices: EXTERNAL_STEP_ACTIONS.map((action) => ({
202
+ name: action,
203
+ value: action
204
+ }))
205
+ });
206
+ return selectedString(value, EXTERNAL_STEP_ACTIONS);
207
+ }
208
+ notifyExternalEscape(escapedPackageName) {
209
+ this.diagnostics.write(`TapHound: Package escape detected — ${escapedPackageName}\n`);
210
+ return Promise.resolve();
211
+ }
212
+ notifyExternalReturn() {
213
+ this.diagnostics.write("TapHound: Returned to target package\n");
214
+ return Promise.resolve();
215
+ }
216
+ notifyBridgeNoEscape() {
217
+ this.diagnostics.write("TapHound: Trigger did not cause a package escape; bridge step was not recorded\n");
218
+ return Promise.resolve();
219
+ }
157
220
  }
@@ -0,0 +1,67 @@
1
+ import type { AdbPort, DeviceIdentity } from "../../ports/adb.js";
2
+ import type { AnnotatedScreenResolverPort } from "../../ports/annotated-screen-resolver.js";
3
+ import type { CommandResult, RunningCommand } from "../../ports/process-runner.js";
4
+ import type { OpenRuntimeSessionOptions, OpenRuntimeUiSnapshotsOptions, RuntimeAppQuery, RuntimeBackend, RuntimeDumpLogcatOptions, RuntimeIntentOptions, RuntimeLaunchOptions, RuntimeLogcatStreamOptions, RuntimeScreenshotOptions, RuntimeSession } from "../../ports/runtime-backend.js";
5
+ import type { ScreenshotPort } from "../../ports/screenshot.js";
6
+ import type { UiSnapshotProvider, UiSnapshotProviderFactory } from "../../ports/ui-snapshot.js";
7
+ import type { UiStabilityProbe } from "../../ports/ui-stability.js";
8
+ import type { ForegroundComponent } from "../../domain/activity.js";
9
+ import type { AppProcess } from "../../domain/app-process.js";
10
+ import type { Point } from "../../domain/geometry.js";
11
+ import type { DeviceInfo, RuntimeBackendDescriptor, RuntimeCapabilities } from "../../domain/runtime.js";
12
+ import type { WindowTopology } from "../../domain/window-hierarchy.js";
13
+ export declare const ADB_RUNTIME_ADAPTER_VERSION = "adb-runtime-v1";
14
+ export declare const DEFAULT_RUNTIME_UI_SNAPSHOT_TIMEOUT_MS = 5000;
15
+ export declare function adbRuntimeCapabilities(): RuntimeCapabilities;
16
+ export interface AdbRuntimeSessionDependencies {
17
+ adb: AdbPort;
18
+ screenshots: ScreenshotPort;
19
+ annotatedScreens: AnnotatedScreenResolverPort;
20
+ uiStability: UiStabilityProbe;
21
+ uiSnapshotFactory: UiSnapshotProviderFactory;
22
+ deviceSerial: string;
23
+ descriptor: RuntimeBackendDescriptor;
24
+ }
25
+ export declare class AdbRuntimeSession implements RuntimeSession {
26
+ private readonly dependencies;
27
+ private uiSnapshotProvider;
28
+ constructor(dependencies: AdbRuntimeSessionDependencies);
29
+ get descriptor(): RuntimeBackendDescriptor;
30
+ get deviceSerial(): string;
31
+ get deviceIdentity(): ((app: RuntimeAppQuery) => Promise<DeviceIdentity>) | undefined;
32
+ openUiSnapshots(options?: OpenRuntimeUiSnapshotsOptions): Promise<UiSnapshotProvider>;
33
+ get annotatedScreens(): AnnotatedScreenResolverPort;
34
+ get uiStability(): UiStabilityProbe;
35
+ isInstalled(app: RuntimeAppQuery): Promise<boolean>;
36
+ launchApp(options: RuntimeLaunchOptions): Promise<CommandResult>;
37
+ forceStop(app: RuntimeAppQuery): Promise<CommandResult>;
38
+ currentActivity(app: RuntimeAppQuery): Promise<string>;
39
+ foregroundComponent(app: RuntimeAppQuery): Promise<ForegroundComponent>;
40
+ appProcesses(app: RuntimeAppQuery): Promise<readonly AppProcess[]>;
41
+ windowTopology(app: RuntimeAppQuery): Promise<WindowTopology>;
42
+ tap(point: Point, signal?: AbortSignal): Promise<CommandResult>;
43
+ longClick(point: Point, durationMs: number, signal?: AbortSignal): Promise<CommandResult>;
44
+ swipe(from: Point, to: Point, durationMs: number, signal?: AbortSignal): Promise<CommandResult>;
45
+ back(signal?: AbortSignal): Promise<CommandResult>;
46
+ inputText(text: string, signal?: AbortSignal): Promise<CommandResult>;
47
+ startLogcat(options: RuntimeLogcatStreamOptions): RunningCommand;
48
+ dumpLogcat(options: RuntimeDumpLogcatOptions): Promise<CommandResult>;
49
+ captureScreenshot(options: RuntimeScreenshotOptions): Promise<CommandResult>;
50
+ startActivityByIntent(options: RuntimeIntentOptions): Promise<CommandResult>;
51
+ close(): Promise<void>;
52
+ }
53
+ export interface AdbRuntimeBackendDependencies {
54
+ adb: AdbPort;
55
+ screenshots: ScreenshotPort;
56
+ annotatedScreens: AnnotatedScreenResolverPort;
57
+ uiStability: UiStabilityProbe;
58
+ uiSnapshots: UiSnapshotProviderFactory;
59
+ }
60
+ export declare class AdbRuntimeBackend implements RuntimeBackend {
61
+ private readonly dependencies;
62
+ readonly descriptor: RuntimeBackendDescriptor;
63
+ readonly capabilities: RuntimeCapabilities;
64
+ constructor(dependencies: AdbRuntimeBackendDependencies);
65
+ listDevices(signal?: AbortSignal): Promise<readonly DeviceInfo[]>;
66
+ openSession(options: OpenRuntimeSessionOptions): Promise<RuntimeSession>;
67
+ }
@@ -0,0 +1,206 @@
1
+ import { createHash } from "node:crypto";
2
+ export const ADB_RUNTIME_ADAPTER_VERSION = "adb-runtime-v1";
3
+ export const DEFAULT_RUNTIME_UI_SNAPSHOT_TIMEOUT_MS = 5000;
4
+ export function adbRuntimeCapabilities() {
5
+ return {
6
+ layoutSnapshot: true,
7
+ screenshot: true,
8
+ annotatedScreens: true,
9
+ frameStatsIdle: true,
10
+ logs: true,
11
+ processDiscovery: true,
12
+ windowTopology: true,
13
+ intentStart: true,
14
+ foregroundActivity: true
15
+ };
16
+ }
17
+ function appIdentity(query, deviceSerial) {
18
+ return {
19
+ packageName: query.packageName,
20
+ deviceSerial,
21
+ ...(query.signal === undefined ? {} : { signal: query.signal }),
22
+ ...(query.timeoutMs === undefined ? {} : { timeoutMs: query.timeoutMs })
23
+ };
24
+ }
25
+ export class AdbRuntimeSession {
26
+ dependencies;
27
+ uiSnapshotProvider;
28
+ constructor(dependencies) {
29
+ this.dependencies = dependencies;
30
+ }
31
+ get descriptor() {
32
+ return this.dependencies.descriptor;
33
+ }
34
+ get deviceSerial() {
35
+ return this.dependencies.deviceSerial;
36
+ }
37
+ get deviceIdentity() {
38
+ if (this.dependencies.adb.deviceIdentity === undefined) {
39
+ return undefined;
40
+ }
41
+ return (app) => {
42
+ const current = this.dependencies.adb.deviceIdentity;
43
+ if (current === undefined) {
44
+ return Promise.reject(new Error("deviceIdentity is unavailable"));
45
+ }
46
+ return current.call(this.dependencies.adb, appIdentity(app, this.dependencies.deviceSerial));
47
+ };
48
+ }
49
+ openUiSnapshots(options) {
50
+ if (this.uiSnapshotProvider !== undefined) {
51
+ return this.uiSnapshotProvider;
52
+ }
53
+ const opened = this.dependencies.uiSnapshotFactory.open({
54
+ deviceSerial: this.dependencies.deviceSerial,
55
+ timeoutMs: options?.timeoutMs
56
+ ?? DEFAULT_RUNTIME_UI_SNAPSHOT_TIMEOUT_MS,
57
+ ...(options?.backend === undefined
58
+ ? {}
59
+ : { backend: options.backend }),
60
+ ...(options?.cacheEnabled === undefined
61
+ ? {}
62
+ : { cacheEnabled: options.cacheEnabled }),
63
+ ...(options?.signal === undefined ? {} : { signal: options.signal })
64
+ });
65
+ opened.catch(() => {
66
+ if (this.uiSnapshotProvider === opened) {
67
+ this.uiSnapshotProvider = undefined;
68
+ }
69
+ });
70
+ this.uiSnapshotProvider = opened;
71
+ return opened;
72
+ }
73
+ get annotatedScreens() {
74
+ return this.dependencies.annotatedScreens;
75
+ }
76
+ get uiStability() {
77
+ return this.dependencies.uiStability;
78
+ }
79
+ isInstalled(app) {
80
+ return this.dependencies.adb.isInstalled(appIdentity(app, this.dependencies.deviceSerial));
81
+ }
82
+ launchApp(options) {
83
+ return this.dependencies.adb.launchActivity({
84
+ packageName: options.packageName,
85
+ activity: options.activity,
86
+ deviceSerial: this.dependencies.deviceSerial,
87
+ ...(options.signal === undefined ? {} : { signal: options.signal }),
88
+ ...(options.timeoutMs === undefined
89
+ ? {}
90
+ : { timeoutMs: options.timeoutMs })
91
+ });
92
+ }
93
+ forceStop(app) {
94
+ return this.dependencies.adb.forceStop(appIdentity(app, this.dependencies.deviceSerial));
95
+ }
96
+ currentActivity(app) {
97
+ return this.dependencies.adb.currentActivity(appIdentity(app, this.dependencies.deviceSerial));
98
+ }
99
+ foregroundComponent(app) {
100
+ return this.dependencies.adb.foregroundComponent(appIdentity(app, this.dependencies.deviceSerial));
101
+ }
102
+ appProcesses(app) {
103
+ return this.dependencies.adb.appProcesses(appIdentity(app, this.dependencies.deviceSerial));
104
+ }
105
+ windowTopology(app) {
106
+ return this.dependencies.adb.windowTopology(appIdentity(app, this.dependencies.deviceSerial));
107
+ }
108
+ tap(point, signal) {
109
+ return this.dependencies.adb.tap(point, this.dependencies.deviceSerial, signal);
110
+ }
111
+ longClick(point, durationMs, signal) {
112
+ return this.dependencies.adb.longClick(point, durationMs, this.dependencies.deviceSerial, signal);
113
+ }
114
+ swipe(from, to, durationMs, signal) {
115
+ return this.dependencies.adb.swipe(from, to, durationMs, this.dependencies.deviceSerial, signal);
116
+ }
117
+ back(signal) {
118
+ return this.dependencies.adb.back(this.dependencies.deviceSerial, signal);
119
+ }
120
+ inputText(text, signal) {
121
+ return this.dependencies.adb.inputText(text, this.dependencies.deviceSerial, signal);
122
+ }
123
+ startLogcat(options) {
124
+ return this.dependencies.adb.startLogcat({
125
+ deviceSerial: this.dependencies.deviceSerial,
126
+ onStdoutLine: options.onStdoutLine,
127
+ ...(options.onStderrLine === undefined
128
+ ? {}
129
+ : { onStderrLine: options.onStderrLine }),
130
+ ...(options.signal === undefined ? {} : { signal: options.signal })
131
+ });
132
+ }
133
+ dumpLogcat(options) {
134
+ return this.dependencies.adb.dumpLogcat({
135
+ deviceSerial: this.dependencies.deviceSerial,
136
+ maxLines: options.maxLines,
137
+ ...(options.signal === undefined ? {} : { signal: options.signal }),
138
+ ...(options.timeoutMs === undefined
139
+ ? {}
140
+ : { timeoutMs: options.timeoutMs })
141
+ });
142
+ }
143
+ captureScreenshot(options) {
144
+ return this.dependencies.screenshots.capture({
145
+ outputPath: options.outputPath,
146
+ deviceSerial: this.dependencies.deviceSerial,
147
+ ...(options.annotate === undefined ? {} : { annotate: options.annotate }),
148
+ ...(options.signal === undefined ? {} : { signal: options.signal }),
149
+ ...(options.timeoutMs === undefined
150
+ ? {}
151
+ : { timeoutMs: options.timeoutMs })
152
+ });
153
+ }
154
+ startActivityByIntent(options) {
155
+ return this.dependencies.adb.startActivityByIntent({
156
+ action: options.action,
157
+ deviceSerial: this.dependencies.deviceSerial,
158
+ ...(options.signal === undefined ? {} : { signal: options.signal }),
159
+ ...(options.timeoutMs === undefined
160
+ ? {}
161
+ : { timeoutMs: options.timeoutMs })
162
+ });
163
+ }
164
+ close() {
165
+ const provider = this.uiSnapshotProvider;
166
+ if (provider === undefined) {
167
+ return Promise.resolve();
168
+ }
169
+ this.uiSnapshotProvider = undefined;
170
+ return provider.then((snapshotProvider) => snapshotProvider.close(), () => undefined);
171
+ }
172
+ }
173
+ export class AdbRuntimeBackend {
174
+ dependencies;
175
+ descriptor;
176
+ capabilities = adbRuntimeCapabilities();
177
+ constructor(dependencies) {
178
+ this.dependencies = dependencies;
179
+ const capabilities = adbRuntimeCapabilities();
180
+ this.capabilities = capabilities;
181
+ this.descriptor = {
182
+ id: "adb",
183
+ adapterVersion: ADB_RUNTIME_ADAPTER_VERSION,
184
+ configSha256: createHash("sha256").update(JSON.stringify({
185
+ id: "adb",
186
+ adapterVersion: ADB_RUNTIME_ADAPTER_VERSION,
187
+ capabilities
188
+ })).digest("hex"),
189
+ capabilities
190
+ };
191
+ }
192
+ listDevices(signal) {
193
+ return this.dependencies.adb.devices(signal);
194
+ }
195
+ openSession(options) {
196
+ return Promise.resolve(new AdbRuntimeSession({
197
+ adb: this.dependencies.adb,
198
+ screenshots: this.dependencies.screenshots,
199
+ annotatedScreens: this.dependencies.annotatedScreens,
200
+ uiStability: this.dependencies.uiStability,
201
+ uiSnapshotFactory: this.dependencies.uiSnapshots,
202
+ deviceSerial: options.deviceSerial,
203
+ descriptor: this.descriptor
204
+ }));
205
+ }
206
+ }
@@ -0,0 +1,87 @@
1
+ import type { DeviceIdentity } from "../../ports/adb.js";
2
+ import type { AnnotatedScreenResolverPort } from "../../ports/annotated-screen-resolver.js";
3
+ import type { CommandResult, RunningCommand } from "../../ports/process-runner.js";
4
+ import type { OpenRuntimeSessionOptions, OpenRuntimeUiSnapshotsOptions, RuntimeAppQuery, RuntimeBackend, RuntimeDumpLogcatOptions, RuntimeIntentOptions, RuntimeLaunchOptions, RuntimeLogcatStreamOptions, RuntimeScreenshotOptions, RuntimeSession } from "../../ports/runtime-backend.js";
5
+ import type { UiSnapshotProvider } from "../../ports/ui-snapshot.js";
6
+ import type { UiStabilityProbe } from "../../ports/ui-stability.js";
7
+ import type { ForegroundComponent } from "../../domain/activity.js";
8
+ import type { AppProcess } from "../../domain/app-process.js";
9
+ import type { DeviceInfo, RuntimeBackendDescriptor, RuntimeCapabilities } from "../../domain/runtime.js";
10
+ import type { WindowTopology } from "../../domain/window-hierarchy.js";
11
+ export declare const FAKE_RUNTIME_ADAPTER_VERSION = "fake-runtime-v1";
12
+ export declare function fakeRuntimeCapabilities(): RuntimeCapabilities;
13
+ export declare function fakeRuntimeUiSnapshotProvider(provider?: Partial<UiSnapshotProvider>): UiSnapshotProvider;
14
+ export interface FakeRuntimeSessionState {
15
+ installed?: boolean | undefined;
16
+ foreground?: ForegroundComponent | undefined;
17
+ processes?: readonly AppProcess[] | undefined;
18
+ topology?: WindowTopology | undefined;
19
+ currentActivity?: string | undefined;
20
+ dumpLogcatResult?: CommandResult | undefined;
21
+ }
22
+ export declare class FakeRuntimeSession implements RuntimeSession {
23
+ readonly descriptor: RuntimeBackendDescriptor;
24
+ readonly deviceSerial: string;
25
+ readonly uiSnapshotProvider: UiSnapshotProvider;
26
+ readonly capabilities: RuntimeCapabilities;
27
+ readonly currentActivity: ((app: RuntimeAppQuery) => Promise<string>) | undefined;
28
+ readonly deviceIdentity: ((app: RuntimeAppQuery) => Promise<DeviceIdentity>) | undefined;
29
+ readonly foregroundComponent: ((app: RuntimeAppQuery) => Promise<ForegroundComponent>) | undefined;
30
+ readonly appProcesses: ((app: RuntimeAppQuery) => Promise<readonly AppProcess[]>) | undefined;
31
+ readonly windowTopology: ((app: RuntimeAppQuery) => Promise<WindowTopology>) | undefined;
32
+ readonly startLogcat: ((options: RuntimeLogcatStreamOptions) => RunningCommand) | undefined;
33
+ readonly dumpLogcat: ((options: RuntimeDumpLogcatOptions) => Promise<CommandResult>) | undefined;
34
+ annotatedScreens: AnnotatedScreenResolverPort | undefined;
35
+ uiStability: UiStabilityProbe;
36
+ startActivityByIntent: ((options: RuntimeIntentOptions) => Promise<CommandResult>) | undefined;
37
+ state: FakeRuntimeSessionState;
38
+ readonly calls: string[];
39
+ lastUiSnapshotOptions: OpenRuntimeUiSnapshotsOptions | undefined;
40
+ private openedUiSnapshots;
41
+ constructor(input: {
42
+ descriptor: RuntimeBackendDescriptor;
43
+ deviceSerial: string;
44
+ state?: FakeRuntimeSessionState | undefined;
45
+ uiSnapshots?: UiSnapshotProvider | undefined;
46
+ uiStability?: UiStabilityProbe | undefined;
47
+ deviceIdentity?: DeviceIdentity | undefined;
48
+ });
49
+ openUiSnapshots(options?: OpenRuntimeUiSnapshotsOptions): Promise<UiSnapshotProvider>;
50
+ isInstalled(app: RuntimeAppQuery): Promise<boolean>;
51
+ launchApp(options: RuntimeLaunchOptions): Promise<CommandResult>;
52
+ forceStop(app: RuntimeAppQuery): Promise<CommandResult>;
53
+ tap(point: {
54
+ x: number;
55
+ y: number;
56
+ }): Promise<CommandResult>;
57
+ longClick(point: {
58
+ x: number;
59
+ y: number;
60
+ }, durationMs: number): Promise<CommandResult>;
61
+ swipe(from: {
62
+ x: number;
63
+ y: number;
64
+ }, to: {
65
+ x: number;
66
+ y: number;
67
+ }, durationMs: number): Promise<CommandResult>;
68
+ back(): Promise<CommandResult>;
69
+ inputText(text: string): Promise<CommandResult>;
70
+ captureScreenshot(options: RuntimeScreenshotOptions): Promise<CommandResult>;
71
+ close(): Promise<void>;
72
+ }
73
+ export declare class FakeRuntimeBackend implements RuntimeBackend {
74
+ readonly descriptor: RuntimeBackendDescriptor;
75
+ readonly capabilities: RuntimeCapabilities;
76
+ readonly devices: readonly DeviceInfo[];
77
+ readonly openCalls: OpenRuntimeSessionOptions[];
78
+ readonly sessions: FakeRuntimeSession[];
79
+ createSession: (options: OpenRuntimeSessionOptions) => RuntimeSession;
80
+ constructor(options?: {
81
+ capabilities?: RuntimeCapabilities | undefined;
82
+ devices?: readonly DeviceInfo[] | undefined;
83
+ sessions?: ((options: OpenRuntimeSessionOptions) => RuntimeSession) | undefined;
84
+ });
85
+ listDevices(): Promise<readonly DeviceInfo[]>;
86
+ openSession(options: OpenRuntimeSessionOptions): Promise<RuntimeSession>;
87
+ }