taphound 0.2.0-dev.1 → 0.2.0-dev.12

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 (467) 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 +507 -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 +578 -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 +357 -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 +42 -0
  66. package/dist/adapters/appium/appium-ui-snapshot-provider.js +309 -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/diagnostics-journal.d.ts +17 -0
  73. package/dist/adapters/filesystem/diagnostics-journal.js +130 -0
  74. package/dist/adapters/filesystem/external-flow-registry.d.ts +17 -0
  75. package/dist/adapters/filesystem/external-flow-registry.js +325 -0
  76. package/dist/adapters/filesystem/generation-session-store.d.ts +17 -11
  77. package/dist/adapters/filesystem/generation-session-store.js +281 -855
  78. package/dist/adapters/filesystem/generation-store/session-lock.d.ts +29 -0
  79. package/dist/adapters/filesystem/generation-store/session-lock.js +202 -0
  80. package/dist/adapters/filesystem/generation-store/session-transitions.d.ts +24 -0
  81. package/dist/adapters/filesystem/generation-store/session-transitions.js +340 -0
  82. package/dist/adapters/filesystem/generation-store/store-files.d.ts +50 -0
  83. package/dist/adapters/filesystem/generation-store/store-files.js +363 -0
  84. package/dist/adapters/filesystem/journey-composition-store.d.ts +23 -0
  85. package/dist/adapters/filesystem/journey-composition-store.js +151 -0
  86. package/dist/adapters/filesystem/knowledge-registry.d.ts +12 -0
  87. package/dist/adapters/filesystem/knowledge-registry.js +223 -0
  88. package/dist/adapters/filesystem/project-bound-file.js +3 -5
  89. package/dist/adapters/filesystem/project-file-inspector.d.ts +2 -0
  90. package/dist/adapters/filesystem/project-file-inspector.js +57 -28
  91. package/dist/adapters/filesystem/project-identity-inspector.d.ts +7 -0
  92. package/dist/adapters/filesystem/project-identity-inspector.js +215 -0
  93. package/dist/adapters/filesystem/project-inventory-inspector.d.ts +8 -0
  94. package/dist/adapters/filesystem/project-inventory-inspector.js +93 -0
  95. package/dist/adapters/filesystem/project-module-discoverer.d.ts +6 -0
  96. package/dist/adapters/filesystem/project-module-discoverer.js +158 -0
  97. package/dist/adapters/filesystem/skill-installer.d.ts +7 -2
  98. package/dist/adapters/filesystem/skill-installer.js +40 -11
  99. package/dist/adapters/filesystem/workspace-layout.d.ts +7 -0
  100. package/dist/adapters/filesystem/workspace-layout.js +57 -0
  101. package/dist/adapters/git/node-git-diff.d.ts +17 -0
  102. package/dist/adapters/git/node-git-diff.js +114 -0
  103. package/dist/adapters/process/node-detached-process-launcher.d.ts +6 -0
  104. package/dist/adapters/process/node-detached-process-launcher.js +96 -0
  105. package/dist/adapters/process/node-process-runner.js +11 -2
  106. package/dist/adapters/prompt/inquirer-align-prompt.d.ts +27 -0
  107. package/dist/adapters/prompt/inquirer-align-prompt.js +65 -0
  108. package/dist/adapters/prompt/inquirer-generation-prompt.js +3 -0
  109. package/dist/adapters/prompt/inquirer-recorder-prompt.d.ts +9 -1
  110. package/dist/adapters/prompt/inquirer-recorder-prompt.js +63 -0
  111. package/dist/adapters/runtime/adb-runtime-backend.d.ts +67 -0
  112. package/dist/adapters/runtime/adb-runtime-backend.js +206 -0
  113. package/dist/adapters/runtime/fake-runtime-backend.d.ts +87 -0
  114. package/dist/adapters/runtime/fake-runtime-backend.js +240 -0
  115. package/dist/adapters/runtime/mobile-mcp/mcp-tool-client.d.ts +45 -0
  116. package/dist/adapters/runtime/mobile-mcp/mcp-tool-client.js +153 -0
  117. package/dist/adapters/runtime/mobile-mcp/mobile-mcp-errors.d.ts +23 -0
  118. package/dist/adapters/runtime/mobile-mcp/mobile-mcp-errors.js +39 -0
  119. package/dist/adapters/runtime/mobile-mcp/mobile-mcp-responses.d.ts +20 -0
  120. package/dist/adapters/runtime/mobile-mcp/mobile-mcp-responses.js +180 -0
  121. package/dist/adapters/runtime/mobile-mcp/mobile-mcp-runtime-backend.d.ts +78 -0
  122. package/dist/adapters/runtime/mobile-mcp/mobile-mcp-runtime-backend.js +379 -0
  123. package/dist/adapters/runtime/mobile-mcp/mobile-mcp-tools.d.ts +46 -0
  124. package/dist/adapters/runtime/session-adb-view.d.ts +53 -0
  125. package/dist/adapters/runtime/session-adb-view.js +193 -0
  126. package/dist/adapters/runtime/session-backed-ports.d.ts +21 -0
  127. package/dist/adapters/runtime/session-backed-ports.js +43 -0
  128. package/dist/adapters/runtime/shared-session-runtime-backend.d.ts +12 -0
  129. package/dist/adapters/runtime/shared-session-runtime-backend.js +64 -0
  130. package/dist/adapters/ui/auto-ui-snapshot-provider.d.ts +8 -0
  131. package/dist/adapters/ui/auto-ui-snapshot-provider.js +48 -0
  132. package/dist/adapters/ui/device-layout-temp.d.ts +6 -0
  133. package/dist/adapters/ui/device-layout-temp.js +18 -0
  134. package/dist/adapters/ui/device-ui-environment.d.ts +13 -0
  135. package/dist/adapters/ui/device-ui-environment.js +81 -0
  136. package/dist/adapters/ui/layout-normalization.d.ts +9 -0
  137. package/dist/adapters/ui/layout-normalization.js +44 -0
  138. package/dist/adapters/ui/ui-snapshot-error.d.ts +11 -0
  139. package/dist/adapters/ui/ui-snapshot-error.js +12 -0
  140. package/dist/adapters/ui/ui-snapshot-support.d.ts +15 -0
  141. package/dist/adapters/ui/ui-snapshot-support.js +12 -0
  142. package/dist/application/align/align-service.d.ts +42 -0
  143. package/dist/application/align/align-service.js +106 -0
  144. package/dist/application/assertion/expectation-evaluator.d.ts +18 -5
  145. package/dist/application/assertion/expectation-evaluator.js +156 -18
  146. package/dist/application/assertion/guarded-expectation.d.ts +45 -0
  147. package/dist/application/assertion/guarded-expectation.js +74 -0
  148. package/dist/application/checkpoint/baseline-capturer.d.ts +26 -0
  149. package/dist/application/checkpoint/baseline-capturer.js +163 -0
  150. package/dist/application/checkpoint/baseline-error.d.ts +5 -0
  151. package/dist/application/checkpoint/baseline-error.js +8 -0
  152. package/dist/application/checkpoint/baseline-service.d.ts +31 -0
  153. package/dist/application/checkpoint/baseline-service.js +147 -0
  154. package/dist/application/checkpoint/checkpoint-evaluator.d.ts +35 -0
  155. package/dist/application/checkpoint/checkpoint-evaluator.js +415 -0
  156. package/dist/application/checkpoint/regression-comparator.d.ts +18 -0
  157. package/dist/application/checkpoint/regression-comparator.js +192 -0
  158. package/dist/application/collector/logcat-collector.d.ts +22 -1
  159. package/dist/application/collector/logcat-collector.js +103 -15
  160. package/dist/application/collector/logcat-event.d.ts +8 -0
  161. package/dist/application/collector/logcat-event.js +79 -0
  162. package/dist/application/collector/logcat-stop.d.ts +2 -0
  163. package/dist/application/collector/logcat-stop.js +11 -0
  164. package/dist/application/context/context-generator.d.ts +45 -0
  165. package/dist/application/context/context-generator.js +228 -0
  166. package/dist/application/context/context-loader.d.ts +40 -0
  167. package/dist/application/context/context-loader.js +223 -0
  168. package/dist/application/context/context-refresher.d.ts +59 -0
  169. package/dist/application/context/context-refresher.js +349 -0
  170. package/dist/application/context/context-rehasher.d.ts +36 -0
  171. package/dist/application/context/context-rehasher.js +110 -0
  172. package/dist/application/context/context-validator.d.ts +23 -1
  173. package/dist/application/context/context-validator.js +116 -9
  174. package/dist/application/context/evidence-hash.d.ts +1 -0
  175. package/dist/application/context/evidence-hash.js +125 -0
  176. package/dist/application/context/evidence-match.d.ts +9 -0
  177. package/dist/application/context/evidence-match.js +8 -0
  178. package/dist/application/context/shard-identity.d.ts +2 -0
  179. package/dist/application/context/shard-identity.js +7 -0
  180. package/dist/application/contract/contract-loader.d.ts +25 -0
  181. package/dist/application/contract/contract-loader.js +68 -0
  182. package/dist/application/contract/contract-review.d.ts +25 -0
  183. package/dist/application/contract/contract-review.js +51 -0
  184. package/dist/application/contract/contract-verifier.d.ts +53 -0
  185. package/dist/application/contract/contract-verifier.js +645 -0
  186. package/dist/application/devices/resolve-device-assignments.d.ts +21 -0
  187. package/dist/application/devices/resolve-device-assignments.js +60 -0
  188. package/dist/application/diagnosis/failure-classifier.d.ts +23 -0
  189. package/dist/application/diagnosis/failure-classifier.js +179 -0
  190. package/dist/application/diagnostics/diagnostics-exporter.d.ts +29 -0
  191. package/dist/application/diagnostics/diagnostics-exporter.js +283 -0
  192. package/dist/application/diagnostics/ui-capture-telemetry.d.ts +16 -0
  193. package/dist/application/diagnostics/ui-capture-telemetry.js +81 -0
  194. package/dist/application/doctor/doctor-service.d.ts +36 -3
  195. package/dist/application/doctor/doctor-service.js +255 -25
  196. package/dist/application/generation/generation-app-preparer.d.ts +20 -0
  197. package/dist/application/generation/generation-app-preparer.js +28 -0
  198. package/dist/application/generation/generation-config-service.d.ts +21 -0
  199. package/dist/application/generation/generation-config-service.js +53 -0
  200. package/dist/application/generation/generation-confirmation-service.d.ts +14 -3
  201. package/dist/application/generation/generation-confirmation-service.js +109 -24
  202. package/dist/application/generation/generation-context-snapshot.d.ts +6 -0
  203. package/dist/application/generation/generation-context-snapshot.js +29 -0
  204. package/dist/application/generation/generation-finalizer.d.ts +15 -9
  205. package/dist/application/generation/generation-finalizer.js +167 -70
  206. package/dist/application/generation/generation-publisher.js +12 -8
  207. package/dist/application/generation/generation-recovery-service.d.ts +35 -0
  208. package/dist/application/generation/generation-recovery-service.js +144 -0
  209. package/dist/application/generation/generation-reopen-service.d.ts +15 -0
  210. package/dist/application/generation/generation-reopen-service.js +37 -0
  211. package/dist/application/generation/generation-replace-service.d.ts +32 -0
  212. package/dist/application/generation/generation-replace-service.js +116 -0
  213. package/dist/application/generation/generation-starter.d.ts +44 -4
  214. package/dist/application/generation/generation-starter.js +175 -8
  215. package/dist/application/generation/generation-step-executor.d.ts +67 -5
  216. package/dist/application/generation/generation-step-executor.js +471 -108
  217. package/dist/application/generation/proposed-step-validator.js +96 -30
  218. package/dist/application/generation/replay-policy-loader.d.ts +16 -0
  219. package/dist/application/generation/replay-policy-loader.js +29 -0
  220. package/dist/application/generation/risk-evaluator.d.ts +4 -1
  221. package/dist/application/generation/risk-evaluator.js +118 -3
  222. package/dist/application/generation/runtime-observer.d.ts +39 -7
  223. package/dist/application/generation/runtime-observer.js +193 -24
  224. package/dist/application/impact/impact-resolver.d.ts +32 -0
  225. package/dist/application/impact/impact-resolver.js +160 -0
  226. package/dist/application/init/init-service.js +26 -13
  227. package/dist/application/interaction/action-executor.d.ts +3 -2
  228. package/dist/application/interaction/action-executor.js +11 -1
  229. package/dist/application/interaction/action-target.d.ts +17 -0
  230. package/dist/application/interaction/action-target.js +40 -0
  231. package/dist/application/interaction/external-step-runner.d.ts +153 -0
  232. package/dist/application/interaction/external-step-runner.js +332 -0
  233. package/dist/application/interaction/fallback-resolver.d.ts +6 -3
  234. package/dist/application/interaction/fallback-resolver.js +7 -5
  235. package/dist/application/interaction/scroll-to-executor.d.ts +17 -3
  236. package/dist/application/interaction/scroll-to-executor.js +118 -36
  237. package/dist/application/journey/external-flow-resolver.d.ts +25 -0
  238. package/dist/application/journey/external-flow-resolver.js +22 -0
  239. package/dist/application/journey/journey-check-service.d.ts +54 -0
  240. package/dist/application/journey/journey-check-service.js +207 -0
  241. package/dist/application/journey/journey-promoter.d.ts +26 -0
  242. package/dist/application/journey/journey-promoter.js +123 -0
  243. package/dist/application/journey/journey-resolver.d.ts +42 -0
  244. package/dist/application/journey/journey-resolver.js +239 -0
  245. package/dist/application/journey/journey-retirer.d.ts +25 -0
  246. package/dist/application/journey/journey-retirer.js +87 -0
  247. package/dist/application/knowledge/anchor-resolver.d.ts +36 -0
  248. package/dist/application/knowledge/anchor-resolver.js +110 -0
  249. package/dist/application/knowledge/knowledge-loader.d.ts +16 -0
  250. package/dist/application/knowledge/knowledge-loader.js +36 -0
  251. package/dist/application/locator/layout-failure-summary.d.ts +2 -0
  252. package/dist/application/locator/layout-failure-summary.js +67 -0
  253. package/dist/application/locator/layout-traversal.d.ts +11 -0
  254. package/dist/application/locator/layout-traversal.js +18 -0
  255. package/dist/application/locator/locator-resolver.d.ts +13 -1
  256. package/dist/application/locator/locator-resolver.js +182 -18
  257. package/dist/application/observe/observe-service.d.ts +20 -0
  258. package/dist/application/observe/observe-service.js +91 -0
  259. package/dist/application/project/project-describer.d.ts +14 -6
  260. package/dist/application/project/project-describer.js +38 -5
  261. package/dist/application/recognition/screen-detector.d.ts +28 -0
  262. package/dist/application/recognition/screen-detector.js +111 -0
  263. package/dist/application/recorder/locator-selector.js +151 -17
  264. package/dist/application/recorder/recorder-service.d.ts +16 -4
  265. package/dist/application/recorder/recorder-service.js +420 -128
  266. package/dist/application/report/report-writer.d.ts +5 -0
  267. package/dist/application/report/report-writer.js +17 -1
  268. package/dist/application/runtime/cold-launch.d.ts +28 -0
  269. package/dist/application/runtime/cold-launch.js +59 -0
  270. package/dist/application/runtime/step-runner.d.ts +49 -4
  271. package/dist/application/runtime/step-runner.js +721 -130
  272. package/dist/application/runtime/verify-runtime.d.ts +57 -7
  273. package/dist/application/runtime/verify-runtime.js +577 -175
  274. package/dist/application/ui/cached-ui-snapshot-provider.d.ts +45 -0
  275. package/dist/application/ui/cached-ui-snapshot-provider.js +111 -0
  276. package/dist/application/ui/observed-ui-snapshot-provider.d.ts +15 -0
  277. package/dist/application/ui/observed-ui-snapshot-provider.js +66 -0
  278. package/dist/application/ui/ui-snapshot-lifecycle.d.ts +2 -0
  279. package/dist/application/ui/ui-snapshot-lifecycle.js +8 -0
  280. package/dist/application/ui/ui-stability-probe.d.ts +9 -0
  281. package/dist/application/ui/ui-stability-probe.js +24 -0
  282. package/dist/application/wait/idle-advice.d.ts +6 -0
  283. package/dist/application/wait/idle-advice.js +27 -0
  284. package/dist/application/wait/idle-profiles.d.ts +15 -0
  285. package/dist/application/wait/idle-profiles.js +75 -0
  286. package/dist/application/wait/idle-waiter.d.ts +28 -4
  287. package/dist/application/wait/idle-waiter.js +201 -15
  288. package/dist/cli/commands/align.d.ts +3 -0
  289. package/dist/cli/commands/align.js +124 -0
  290. package/dist/cli/commands/baseline.d.ts +3 -0
  291. package/dist/cli/commands/baseline.js +130 -0
  292. package/dist/cli/commands/context.js +300 -27
  293. package/dist/cli/commands/contract.d.ts +3 -0
  294. package/dist/cli/commands/contract.js +120 -0
  295. package/dist/cli/commands/diagnose.d.ts +3 -0
  296. package/dist/cli/commands/diagnose.js +84 -0
  297. package/dist/cli/commands/doctor.js +16 -9
  298. package/dist/cli/commands/failure.d.ts +3 -0
  299. package/dist/cli/commands/failure.js +63 -0
  300. package/dist/cli/commands/generation/lifecycle-commands.d.ts +5 -0
  301. package/dist/cli/commands/generation/lifecycle-commands.js +211 -0
  302. package/dist/cli/commands/generation/session-commands.d.ts +11 -0
  303. package/dist/cli/commands/generation/session-commands.js +472 -0
  304. package/dist/cli/commands/generation/shared.d.ts +1414 -0
  305. package/dist/cli/commands/generation/shared.js +291 -0
  306. package/dist/cli/commands/generation/step-commands.d.ts +8 -0
  307. package/dist/cli/commands/generation/step-commands.js +315 -0
  308. package/dist/cli/commands/generation.js +10 -507
  309. package/dist/cli/commands/impact.d.ts +3 -0
  310. package/dist/cli/commands/impact.js +87 -0
  311. package/dist/cli/commands/init.js +13 -6
  312. package/dist/cli/commands/journey.d.ts +3 -0
  313. package/dist/cli/commands/journey.js +382 -0
  314. package/dist/cli/commands/knowledge.d.ts +3 -0
  315. package/dist/cli/commands/knowledge.js +93 -0
  316. package/dist/cli/commands/observe.d.ts +3 -0
  317. package/dist/cli/commands/observe.js +127 -0
  318. package/dist/cli/commands/project.js +2 -1
  319. package/dist/cli/commands/record.js +18 -5
  320. package/dist/cli/commands/verify.js +326 -64
  321. package/dist/cli/dependencies.d.ts +136 -1
  322. package/dist/cli/dependencies.js +504 -52
  323. package/dist/cli/diagnostics-recorder.d.ts +31 -0
  324. package/dist/cli/diagnostics-recorder.js +82 -0
  325. package/dist/cli/diff-verification.d.ts +41 -0
  326. package/dist/cli/diff-verification.js +192 -0
  327. package/dist/cli/main.d.ts +1 -1
  328. package/dist/cli/main.js +107 -2
  329. package/dist/cli/output.d.ts +5 -3
  330. package/dist/cli/output.js +12 -0
  331. package/dist/cli/program.js +21 -1
  332. package/dist/cli/project-root.d.ts +1 -0
  333. package/dist/cli/project-root.js +6 -0
  334. package/dist/cli/runtime-selection.d.ts +22 -0
  335. package/dist/cli/runtime-selection.js +92 -0
  336. package/dist/cli/version.d.ts +1 -0
  337. package/dist/cli/version.js +14 -0
  338. package/dist/cli/workspace-guard.d.ts +2 -0
  339. package/dist/cli/workspace-guard.js +3 -0
  340. package/dist/domain/binding-reference.d.ts +4 -0
  341. package/dist/domain/binding-reference.js +23 -0
  342. package/dist/domain/checkpoint.d.ts +404 -0
  343. package/dist/domain/checkpoint.js +297 -0
  344. package/dist/domain/config.d.ts +107 -1
  345. package/dist/domain/config.js +52 -6
  346. package/dist/domain/contract.d.ts +413 -0
  347. package/dist/domain/contract.js +196 -0
  348. package/dist/domain/diagnostics.d.ts +1396 -0
  349. package/dist/domain/diagnostics.js +193 -0
  350. package/dist/domain/external-flow.d.ts +493 -0
  351. package/dist/domain/external-flow.js +15 -0
  352. package/dist/domain/failure-classification.d.ts +176 -0
  353. package/dist/domain/failure-classification.js +169 -0
  354. package/dist/domain/failure.d.ts +2 -1
  355. package/dist/domain/failure.js +123 -0
  356. package/dist/domain/generation.d.ts +1671 -132
  357. package/dist/domain/generation.js +202 -13
  358. package/dist/domain/geometry.d.ts +13 -0
  359. package/dist/domain/geometry.js +16 -0
  360. package/dist/domain/impact.d.ts +71 -0
  361. package/dist/domain/impact.js +76 -0
  362. package/dist/domain/init.d.ts +12 -4
  363. package/dist/domain/init.js +24 -18
  364. package/dist/domain/journey-composition.d.ts +2285 -0
  365. package/dist/domain/journey-composition.js +85 -0
  366. package/dist/domain/journey-lifecycle.d.ts +10 -0
  367. package/dist/domain/journey-lifecycle.js +9 -0
  368. package/dist/domain/journey.d.ts +2419 -212
  369. package/dist/domain/journey.js +384 -14
  370. package/dist/domain/knowledge.d.ts +165 -0
  371. package/dist/domain/knowledge.js +188 -0
  372. package/dist/domain/layout.d.ts +34 -5
  373. package/dist/domain/layout.js +64 -6
  374. package/dist/domain/locator-evidence.d.ts +3 -0
  375. package/dist/domain/locator-evidence.js +36 -0
  376. package/dist/domain/logcat-event.d.ts +54 -0
  377. package/dist/domain/logcat-event.js +40 -0
  378. package/dist/domain/observation.d.ts +33 -0
  379. package/dist/domain/observation.js +18 -0
  380. package/dist/domain/project-context.d.ts +219 -1
  381. package/dist/domain/project-context.js +209 -6
  382. package/dist/domain/proposed-step.d.ts +340 -60
  383. package/dist/domain/proposed-step.js +23 -3
  384. package/dist/domain/report.d.ts +1455 -28
  385. package/dist/domain/report.js +211 -14
  386. package/dist/domain/runtime-snapshot.d.ts +58 -1
  387. package/dist/domain/runtime-snapshot.js +14 -3
  388. package/dist/domain/runtime.d.ts +50 -0
  389. package/dist/domain/runtime.js +36 -0
  390. package/dist/domain/system-app-profiles.d.ts +6 -0
  391. package/dist/domain/system-app-profiles.js +43 -0
  392. package/dist/domain/ui-backend.d.ts +28 -0
  393. package/dist/domain/ui-backend.js +33 -0
  394. package/dist/domain/ui-cache.d.ts +11 -0
  395. package/dist/domain/ui-cache.js +10 -0
  396. package/dist/domain/verify-receipt.d.ts +17 -0
  397. package/dist/domain/verify-receipt.js +17 -0
  398. package/dist/domain/window-hierarchy.d.ts +84 -0
  399. package/dist/domain/window-hierarchy.js +172 -0
  400. package/dist/domain/workflow-manifest.d.ts +77 -0
  401. package/dist/domain/workflow-manifest.js +136 -0
  402. package/dist/domain/workspace.d.ts +30 -0
  403. package/dist/domain/workspace.js +74 -0
  404. package/dist/ports/adb.d.ts +34 -1
  405. package/dist/ports/align-prompt.d.ts +11 -0
  406. package/dist/ports/align-prompt.js +6 -0
  407. package/dist/ports/anchor-resolver.d.ts +30 -0
  408. package/dist/ports/anchor-resolver.js +1 -0
  409. package/dist/ports/annotated-screen-resolver.d.ts +4 -0
  410. package/dist/ports/annotated-screen-resolver.js +1 -0
  411. package/dist/ports/camera-probe.d.ts +23 -0
  412. package/dist/ports/camera-probe.js +8 -0
  413. package/dist/ports/context-document-writer.d.ts +24 -0
  414. package/dist/ports/context-document-writer.js +1 -0
  415. package/dist/ports/detached-process-launcher.d.ts +12 -0
  416. package/dist/ports/detached-process-launcher.js +1 -0
  417. package/dist/ports/diagnostics.d.ts +15 -0
  418. package/dist/ports/diagnostics.js +1 -0
  419. package/dist/ports/external-flow-registry.d.ts +37 -0
  420. package/dist/ports/external-flow-registry.js +1 -0
  421. package/dist/ports/generation-prompt.d.ts +2 -1
  422. package/dist/ports/generation-session-store.d.ts +12 -2
  423. package/dist/ports/git-diff.d.ts +9 -0
  424. package/dist/ports/git-diff.js +1 -0
  425. package/dist/ports/journey-composition-store.d.ts +17 -0
  426. package/dist/ports/journey-composition-store.js +1 -0
  427. package/dist/ports/knowledge-registry.d.ts +20 -0
  428. package/dist/ports/knowledge-registry.js +1 -0
  429. package/dist/ports/process-runner.d.ts +7 -0
  430. package/dist/ports/project-file-inspector.d.ts +1 -0
  431. package/dist/ports/project-identity-inspector.d.ts +24 -0
  432. package/dist/ports/project-identity-inspector.js +1 -0
  433. package/dist/ports/project-inventory-inspector.d.ts +21 -0
  434. package/dist/ports/project-inventory-inspector.js +1 -0
  435. package/dist/ports/project-module-discoverer.d.ts +26 -0
  436. package/dist/ports/project-module-discoverer.js +1 -0
  437. package/dist/ports/recorder-prompt.d.ts +10 -1
  438. package/dist/ports/runtime-backend.d.ts +89 -0
  439. package/dist/ports/runtime-backend.js +13 -0
  440. package/dist/ports/runtime-capability.d.ts +12 -0
  441. package/dist/ports/runtime-capability.js +20 -0
  442. package/dist/ports/runtime-session-ports.d.ts +25 -0
  443. package/dist/ports/runtime-session-ports.js +1 -0
  444. package/dist/ports/screenshot.d.ts +11 -0
  445. package/dist/ports/screenshot.js +1 -0
  446. package/dist/ports/skill-installer.d.ts +2 -2
  447. package/dist/ports/ui-snapshot.d.ts +35 -0
  448. package/dist/ports/ui-snapshot.js +1 -0
  449. package/dist/ports/ui-stability.d.ts +19 -0
  450. package/dist/ports/ui-stability.js +1 -0
  451. package/dist/ports/workspace-layout.d.ts +4 -0
  452. package/dist/ports/workspace-layout.js +1 -0
  453. package/dist/shared/errors.d.ts +2 -0
  454. package/dist/shared/errors.js +22 -0
  455. package/dist/shared/paths.d.ts +2 -0
  456. package/dist/shared/paths.js +24 -0
  457. package/dist/shared/strings.d.ts +2 -0
  458. package/dist/shared/strings.js +16 -0
  459. package/package.json +7 -2
  460. package/assets/skills/taphound-ai-journey/GUIDE.md +0 -862
  461. package/assets/skills/taphound-ai-journey/SKILL.md +0 -377
  462. package/assets/skills/taphound-ai-journey/prompts/analyze-project.md +0 -526
  463. package/assets/skills/taphound-ai-journey/prompts/generate-step.md +0 -109
  464. package/assets/skills/taphound-ai-journey/schemas/project-context.json +0 -81
  465. package/assets/skills/taphound-ai-journey/templates/project-context.example.json +0 -49
  466. package/dist/ports/android-cli.d.ts +0 -21
  467. /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
+ }