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
@@ -0,0 +1,84 @@
1
+ import { z } from "zod";
2
+ import { type LayoutElement } from "./layout.js";
3
+ export declare const AppWindowSchema: z.ZodObject<{
4
+ id: z.ZodString;
5
+ title: z.ZodString;
6
+ packageName: z.ZodString;
7
+ type: z.ZodOptional<z.ZodString>;
8
+ layer: z.ZodOptional<z.ZodNumber>;
9
+ bounds: z.ZodOptional<z.ZodObject<{
10
+ left: z.ZodNumber;
11
+ top: z.ZodNumber;
12
+ right: z.ZodNumber;
13
+ bottom: z.ZodNumber;
14
+ }, z.core.$strict>>;
15
+ touchable: z.ZodBoolean;
16
+ focusable: z.ZodOptional<z.ZodBoolean>;
17
+ focused: z.ZodOptional<z.ZodBoolean>;
18
+ }, z.core.$strict>;
19
+ export type AppWindow = z.infer<typeof AppWindowSchema>;
20
+ export declare const WindowTopologySchema: z.ZodObject<{
21
+ version: z.ZodLiteral<1>;
22
+ status: z.ZodEnum<{
23
+ observed: "observed";
24
+ unavailable: "unavailable";
25
+ }>;
26
+ windows: z.ZodArray<z.ZodObject<{
27
+ id: z.ZodString;
28
+ title: z.ZodString;
29
+ packageName: z.ZodString;
30
+ type: z.ZodOptional<z.ZodString>;
31
+ layer: z.ZodOptional<z.ZodNumber>;
32
+ bounds: z.ZodOptional<z.ZodObject<{
33
+ left: z.ZodNumber;
34
+ top: z.ZodNumber;
35
+ right: z.ZodNumber;
36
+ bottom: z.ZodNumber;
37
+ }, z.core.$strict>>;
38
+ touchable: z.ZodBoolean;
39
+ focusable: z.ZodOptional<z.ZodBoolean>;
40
+ focused: z.ZodOptional<z.ZodBoolean>;
41
+ }, z.core.$strict>>;
42
+ diagnostic: z.ZodOptional<z.ZodString>;
43
+ }, z.core.$strict>;
44
+ export type WindowTopology = z.infer<typeof WindowTopologySchema>;
45
+ export declare const WindowHierarchySchema: z.ZodObject<{
46
+ status: z.ZodEnum<{
47
+ unknown: "unknown";
48
+ complete: "complete";
49
+ incomplete: "incomplete";
50
+ }>;
51
+ appWindows: z.ZodArray<z.ZodObject<{
52
+ id: z.ZodString;
53
+ title: z.ZodString;
54
+ packageName: z.ZodString;
55
+ type: z.ZodOptional<z.ZodString>;
56
+ layer: z.ZodOptional<z.ZodNumber>;
57
+ bounds: z.ZodOptional<z.ZodObject<{
58
+ left: z.ZodNumber;
59
+ top: z.ZodNumber;
60
+ right: z.ZodNumber;
61
+ bottom: z.ZodNumber;
62
+ }, z.core.$strict>>;
63
+ touchable: z.ZodBoolean;
64
+ focusable: z.ZodOptional<z.ZodBoolean>;
65
+ focused: z.ZodOptional<z.ZodBoolean>;
66
+ }, z.core.$strict>>;
67
+ semanticWindowIds: z.ZodArray<z.ZodString>;
68
+ diagnostics: z.ZodArray<z.ZodObject<{
69
+ code: z.ZodEnum<{
70
+ WINDOW_TOPOLOGY_UNAVAILABLE: "WINDOW_TOPOLOGY_UNAVAILABLE";
71
+ SEMANTIC_WINDOW_IDS_UNAVAILABLE: "SEMANTIC_WINDOW_IDS_UNAVAILABLE";
72
+ APP_WINDOW_WITHOUT_SEMANTIC_ROOT: "APP_WINDOW_WITHOUT_SEMANTIC_ROOT";
73
+ APP_WINDOW_NOT_ACCESSIBILITY_READABLE: "APP_WINDOW_NOT_ACCESSIBILITY_READABLE";
74
+ }>;
75
+ message: z.ZodString;
76
+ }, z.core.$strict>>;
77
+ recovery: z.ZodArray<z.ZodEnum<{
78
+ REOBSERVE: "REOBSERVE";
79
+ LAYOUT_INSPECTOR: "LAYOUT_INSPECTOR";
80
+ DEBUG_WINDOW_INSPECTOR: "DEBUG_WINDOW_INSPECTOR";
81
+ }>>;
82
+ }, z.core.$strict>;
83
+ export type WindowHierarchy = z.infer<typeof WindowHierarchySchema>;
84
+ export declare function assessWindowHierarchy(topology: WindowTopology, layout: readonly LayoutElement[]): WindowHierarchy;
@@ -0,0 +1,172 @@
1
+ import { z } from "zod";
2
+ import { BoundsSchema } from "./layout.js";
3
+ export const AppWindowSchema = z.strictObject({
4
+ id: z.string().trim().min(1),
5
+ title: z.string().trim().min(1),
6
+ packageName: z.string().trim().min(1),
7
+ type: z.string().trim().min(1).optional(),
8
+ layer: z.number().int().nonnegative().optional(),
9
+ bounds: BoundsSchema.optional(),
10
+ touchable: z.boolean(),
11
+ focusable: z.boolean().optional(),
12
+ focused: z.boolean().optional()
13
+ });
14
+ export const WindowTopologySchema = z.strictObject({
15
+ version: z.literal(1),
16
+ status: z.enum(["observed", "unavailable"]),
17
+ windows: z.array(AppWindowSchema),
18
+ diagnostic: z.string().trim().min(1).optional()
19
+ }).superRefine((topology, context) => {
20
+ if (topology.status === "observed"
21
+ && topology.diagnostic !== undefined) {
22
+ context.addIssue({
23
+ code: "custom",
24
+ path: ["diagnostic"],
25
+ message: "Observed window topology cannot include an unavailable diagnostic"
26
+ });
27
+ }
28
+ if (topology.status === "unavailable" && topology.windows.length > 0) {
29
+ context.addIssue({
30
+ code: "custom",
31
+ path: ["windows"],
32
+ message: "Unavailable window topology cannot include windows"
33
+ });
34
+ }
35
+ });
36
+ const HierarchyDiagnosticSchema = z.strictObject({
37
+ code: z.enum([
38
+ "WINDOW_TOPOLOGY_UNAVAILABLE",
39
+ "SEMANTIC_WINDOW_IDS_UNAVAILABLE",
40
+ "APP_WINDOW_WITHOUT_SEMANTIC_ROOT",
41
+ "APP_WINDOW_NOT_ACCESSIBILITY_READABLE"
42
+ ]),
43
+ message: z.string().trim().min(1)
44
+ });
45
+ export const WindowHierarchySchema = z.strictObject({
46
+ status: z.enum(["complete", "incomplete", "unknown"]),
47
+ appWindows: z.array(AppWindowSchema),
48
+ semanticWindowIds: z.array(z.string().trim().min(1)),
49
+ diagnostics: z.array(HierarchyDiagnosticSchema),
50
+ recovery: z.array(z.enum([
51
+ "REOBSERVE",
52
+ "LAYOUT_INSPECTOR",
53
+ "DEBUG_WINDOW_INSPECTOR"
54
+ ]))
55
+ });
56
+ function windowIds(elements) {
57
+ return [...new Set(elements.flatMap((element) => [
58
+ ...(element.windowId === undefined ? [] : [element.windowId]),
59
+ ...windowIds(element.children)
60
+ ]))].sort((left, right) => left.localeCompare(right));
61
+ }
62
+ function hasActionableElement(elements) {
63
+ return elements.some((element) => ((element.enabled
64
+ && (element.clickable === true
65
+ || element.longClickable === true
66
+ || element.focusable === true))
67
+ || hasActionableElement(element.children)));
68
+ }
69
+ /**
70
+ * Android accessibility serializes the active (focused) window. A visible
71
+ * touchable window that cannot take focus therefore never reaches the layout,
72
+ * no matter which acquisition backend is used. Sub panels are excluded because
73
+ * they carry decorations such as text-selection handles rather than controls.
74
+ */
75
+ function unreadableWindows(windows) {
76
+ return windows.filter((window) => (window.focusable === false
77
+ && window.type !== "BASE_APPLICATION"
78
+ && window.type !== "APPLICATION_SUB_PANEL"));
79
+ }
80
+ export function assessWindowHierarchy(topology, layout) {
81
+ const parsedTopology = WindowTopologySchema.parse(topology);
82
+ const semanticWindowIds = windowIds(layout);
83
+ const unreadable = unreadableWindows(parsedTopology.windows);
84
+ if (unreadable.length > 0) {
85
+ return WindowHierarchySchema.parse({
86
+ status: "incomplete",
87
+ appWindows: parsedTopology.windows,
88
+ semanticWindowIds,
89
+ diagnostics: unreadable.map((window) => ({
90
+ code: "APP_WINDOW_NOT_ACCESSIBILITY_READABLE",
91
+ message: `Visible app window ${window.title}${window.type === undefined ? "" : ` (${window.type})`} cannot take focus, so accessibility never exposes its content`
92
+ })),
93
+ recovery: [
94
+ "REOBSERVE",
95
+ "LAYOUT_INSPECTOR",
96
+ "DEBUG_WINDOW_INSPECTOR"
97
+ ]
98
+ });
99
+ }
100
+ if (parsedTopology.status === "unavailable") {
101
+ return WindowHierarchySchema.parse({
102
+ status: "unknown",
103
+ appWindows: [],
104
+ semanticWindowIds,
105
+ diagnostics: [{
106
+ code: "WINDOW_TOPOLOGY_UNAVAILABLE",
107
+ message: parsedTopology.diagnostic
108
+ ?? "ADB window topology is unavailable"
109
+ }],
110
+ recovery: ["REOBSERVE"]
111
+ });
112
+ }
113
+ if (semanticWindowIds.length === 0) {
114
+ return WindowHierarchySchema.parse({
115
+ status: "unknown",
116
+ appWindows: parsedTopology.windows,
117
+ semanticWindowIds,
118
+ diagnostics: [{
119
+ code: "SEMANTIC_WINDOW_IDS_UNAVAILABLE",
120
+ message: "Android layout did not expose semantic window identifiers"
121
+ }],
122
+ recovery: ["REOBSERVE"]
123
+ });
124
+ }
125
+ if (parsedTopology.windows.length === 0) {
126
+ return WindowHierarchySchema.parse({
127
+ status: "unknown",
128
+ appWindows: [],
129
+ semanticWindowIds,
130
+ diagnostics: [{
131
+ code: "WINDOW_TOPOLOGY_UNAVAILABLE",
132
+ message: "ADB window topology contained no visible touchable target-app windows"
133
+ }],
134
+ recovery: ["REOBSERVE"]
135
+ });
136
+ }
137
+ if (parsedTopology.windows.length > semanticWindowIds.length) {
138
+ const nonPanelWindows = parsedTopology.windows.filter((window) => window.type !== "APPLICATION_PANEL");
139
+ if (parsedTopology.windows.some((window) => window.type === "APPLICATION_PANEL")
140
+ && nonPanelWindows.length <= semanticWindowIds.length
141
+ && hasActionableElement(layout)) {
142
+ return WindowHierarchySchema.parse({
143
+ status: "complete",
144
+ appWindows: parsedTopology.windows,
145
+ semanticWindowIds,
146
+ diagnostics: [],
147
+ recovery: []
148
+ });
149
+ }
150
+ return WindowHierarchySchema.parse({
151
+ status: "incomplete",
152
+ appWindows: parsedTopology.windows,
153
+ semanticWindowIds,
154
+ diagnostics: [{
155
+ code: "APP_WINDOW_WITHOUT_SEMANTIC_ROOT",
156
+ message: `ADB observed ${String(parsedTopology.windows.length)} visible touchable app windows, but Android layout exposed ${String(semanticWindowIds.length)} semantic window roots`
157
+ }],
158
+ recovery: [
159
+ "REOBSERVE",
160
+ "LAYOUT_INSPECTOR",
161
+ "DEBUG_WINDOW_INSPECTOR"
162
+ ]
163
+ });
164
+ }
165
+ return WindowHierarchySchema.parse({
166
+ status: "complete",
167
+ appWindows: parsedTopology.windows,
168
+ semanticWindowIds,
169
+ diagnostics: [],
170
+ recovery: []
171
+ });
172
+ }
@@ -0,0 +1,77 @@
1
+ import { z } from "zod";
2
+ export declare const WorkflowManifestSchema: z.ZodObject<{
3
+ version: z.ZodLiteral<1>;
4
+ case: z.ZodObject<{
5
+ id: z.ZodString;
6
+ path: z.ZodEnum<{
7
+ accept: "accept";
8
+ preserve: "preserve";
9
+ }>;
10
+ requirement: z.ZodObject<{
11
+ sourceRef: z.ZodString;
12
+ summarySha256: z.ZodString;
13
+ }, z.core.$strict>;
14
+ }, z.core.$strict>;
15
+ diffs: z.ZodObject<{
16
+ implementation: z.ZodObject<{
17
+ path: z.ZodString;
18
+ sha256: z.ZodString;
19
+ }, z.core.$strict>;
20
+ verificationAssets: z.ZodObject<{
21
+ path: z.ZodString;
22
+ sha256: z.ZodString;
23
+ }, z.core.$strict>;
24
+ }, z.core.$strict>;
25
+ bindings: z.ZodObject<{
26
+ journeySha256: z.ZodString;
27
+ contractSha256: z.ZodOptional<z.ZodString>;
28
+ knowledgeHash: z.ZodOptional<z.ZodString>;
29
+ replayPolicy: z.ZodOptional<z.ZodObject<{
30
+ metaPath: z.ZodString;
31
+ sha256: z.ZodString;
32
+ strict: z.ZodBoolean;
33
+ }, z.core.$strict>>;
34
+ diffScope: z.ZodObject<{
35
+ used: z.ZodBoolean;
36
+ base: z.ZodOptional<z.ZodString>;
37
+ head: z.ZodOptional<z.ZodString>;
38
+ tiers: z.ZodArray<z.ZodEnum<{
39
+ p0: "p0";
40
+ p1: "p1";
41
+ p2: "p2";
42
+ }>>;
43
+ }, z.core.$strict>;
44
+ }, z.core.$strict>;
45
+ commands: z.ZodArray<z.ZodObject<{
46
+ argv: z.ZodArray<z.ZodString>;
47
+ exitCode: z.ZodNumber;
48
+ jsonResultPath: z.ZodString;
49
+ }, z.core.$strict>>;
50
+ evidence: z.ZodObject<{
51
+ beforeReportPath: z.ZodOptional<z.ZodString>;
52
+ reportPath: z.ZodOptional<z.ZodString>;
53
+ verdictPath: z.ZodOptional<z.ZodString>;
54
+ baselinePath: z.ZodOptional<z.ZodString>;
55
+ compareResultPath: z.ZodOptional<z.ZodString>;
56
+ }, z.core.$strict>;
57
+ outcome: z.ZodDiscriminatedUnion<[z.ZodObject<{
58
+ path: z.ZodLiteral<"accept">;
59
+ verdict: z.ZodOptional<z.ZodEnum<{
60
+ invalid: "invalid";
61
+ pass: "pass";
62
+ fail: "fail";
63
+ inconclusive: "inconclusive";
64
+ needsReview: "needsReview";
65
+ }>>;
66
+ }, z.core.$strict>, z.ZodObject<{
67
+ path: z.ZodLiteral<"preserve">;
68
+ equivalent: z.ZodOptional<z.ZodBoolean>;
69
+ }, z.core.$strict>], "path">;
70
+ status: z.ZodEnum<{
71
+ PASS: "PASS";
72
+ FAIL: "FAIL";
73
+ PAUSED: "PAUSED";
74
+ }>;
75
+ pauseReason: z.ZodOptional<z.ZodString>;
76
+ }, z.core.$strict>;
77
+ export type WorkflowManifest = z.infer<typeof WorkflowManifestSchema>;
@@ -0,0 +1,136 @@
1
+ import { z } from "zod";
2
+ import { posix } from "node:path";
3
+ import { WORKFLOWS_DIR } from "./workspace.js";
4
+ const DigestSchema = z.string().regex(/^[a-f\d]{64}$/);
5
+ const ArtifactRefSchema = z.string().trim().min(1);
6
+ const DiffReferenceSchema = z.strictObject({
7
+ path: ArtifactRefSchema,
8
+ sha256: DigestSchema
9
+ });
10
+ export const WorkflowManifestSchema = z.strictObject({
11
+ version: z.literal(1),
12
+ case: z.strictObject({
13
+ id: z.string().regex(/^[a-z][a-z0-9-]{0,63}$/),
14
+ path: z.enum(["accept", "preserve"]),
15
+ requirement: z.strictObject({
16
+ sourceRef: ArtifactRefSchema,
17
+ summarySha256: DigestSchema
18
+ })
19
+ }),
20
+ diffs: z.strictObject({
21
+ implementation: DiffReferenceSchema,
22
+ verificationAssets: DiffReferenceSchema
23
+ }),
24
+ bindings: z.strictObject({
25
+ journeySha256: DigestSchema,
26
+ contractSha256: DigestSchema.optional(),
27
+ knowledgeHash: DigestSchema.optional(),
28
+ replayPolicy: z.strictObject({
29
+ metaPath: ArtifactRefSchema,
30
+ sha256: DigestSchema,
31
+ strict: z.boolean()
32
+ }).optional(),
33
+ diffScope: z.strictObject({
34
+ used: z.boolean(),
35
+ base: z.string().trim().min(1).optional(),
36
+ head: z.string().trim().min(1).optional(),
37
+ tiers: z.array(z.enum(["p0", "p1", "p2"]))
38
+ }).superRefine((scope, context) => {
39
+ if (scope.used && (scope.base === undefined || scope.tiers.length === 0)) {
40
+ context.addIssue({
41
+ code: "custom", message: "Used diff scope requires base and selected tiers"
42
+ });
43
+ }
44
+ })
45
+ }),
46
+ commands: z.array(z.strictObject({
47
+ argv: z.array(z.string().min(1)).min(1),
48
+ exitCode: z.number().int().nonnegative(),
49
+ jsonResultPath: ArtifactRefSchema
50
+ })),
51
+ evidence: z.strictObject({
52
+ beforeReportPath: ArtifactRefSchema.optional(),
53
+ reportPath: ArtifactRefSchema.optional(),
54
+ verdictPath: ArtifactRefSchema.optional(),
55
+ baselinePath: ArtifactRefSchema.optional(),
56
+ compareResultPath: ArtifactRefSchema.optional()
57
+ }),
58
+ outcome: z.discriminatedUnion("path", [
59
+ z.strictObject({
60
+ path: z.literal("accept"),
61
+ verdict: z.enum(["pass", "fail", "inconclusive", "needsReview", "invalid"])
62
+ .optional()
63
+ }),
64
+ z.strictObject({
65
+ path: z.literal("preserve"),
66
+ equivalent: z.boolean().optional()
67
+ })
68
+ ]),
69
+ status: z.enum(["PASS", "FAIL", "PAUSED"]),
70
+ pauseReason: z.string().trim().min(1).optional()
71
+ }).superRefine((manifest, context) => {
72
+ const caseDir = `${WORKFLOWS_DIR}/${manifest.case.id}/`;
73
+ const insideCase = (path) => path.startsWith(caseDir)
74
+ && !path.includes("\\")
75
+ && !path.startsWith("/")
76
+ && posix.normalize(path) === path;
77
+ for (const [index, command] of manifest.commands.entries()) {
78
+ if (!insideCase(command.jsonResultPath)) {
79
+ context.addIssue({
80
+ code: "custom", path: ["commands", index, "jsonResultPath"],
81
+ message: "Command JSON must stay in the Case build directory"
82
+ });
83
+ }
84
+ }
85
+ for (const kind of ["implementation", "verificationAssets"]) {
86
+ if (!insideCase(manifest.diffs[kind].path)) {
87
+ context.addIssue({
88
+ code: "custom", path: ["diffs", kind, "path"],
89
+ message: "Diff evidence must stay in the Case build directory"
90
+ });
91
+ }
92
+ }
93
+ if (manifest.case.path !== manifest.outcome.path) {
94
+ context.addIssue({ code: "custom", path: ["outcome"], message: "Outcome path must match Case" });
95
+ }
96
+ if (manifest.status === "PAUSED" && manifest.pauseReason === undefined) {
97
+ context.addIssue({ code: "custom", path: ["pauseReason"], message: "Paused Case needs a reason" });
98
+ }
99
+ if (manifest.status !== "PASS")
100
+ return;
101
+ if (manifest.evidence.reportPath === undefined
102
+ || manifest.commands.length === 0
103
+ || manifest.commands.some((command) => command.exitCode !== 0)) {
104
+ context.addIssue({
105
+ code: "custom", path: ["status"],
106
+ message: "PASS needs a report and successful recorded commands"
107
+ });
108
+ }
109
+ if (manifest.bindings.replayPolicy?.strict !== true) {
110
+ context.addIssue({
111
+ code: "custom", path: ["bindings", "replayPolicy"],
112
+ message: "PASS requires a bound strict Replay policy"
113
+ });
114
+ }
115
+ if (manifest.case.path === "accept") {
116
+ if (manifest.outcome.path !== "accept"
117
+ || manifest.outcome.verdict !== "pass"
118
+ || manifest.evidence.verdictPath === undefined
119
+ || manifest.bindings.contractSha256 === undefined) {
120
+ context.addIssue({
121
+ code: "custom", path: ["status"],
122
+ message: "Accept PASS needs a bound passing Contract Verdict"
123
+ });
124
+ }
125
+ }
126
+ else if (manifest.outcome.path !== "preserve"
127
+ || manifest.outcome.equivalent !== true
128
+ || manifest.evidence.beforeReportPath === undefined
129
+ || manifest.evidence.baselinePath === undefined
130
+ || manifest.evidence.compareResultPath === undefined) {
131
+ context.addIssue({
132
+ code: "custom", path: ["status"],
133
+ message: "Preserve PASS needs a Baseline and equivalent comparison"
134
+ });
135
+ }
136
+ });
@@ -0,0 +1,28 @@
1
+ export declare const TAPHOUND_DIR = ".taphound";
2
+ export declare const CONFIG_PATH = ".taphound/config.json";
3
+ export declare const CONTEXT_DIR = ".taphound/context";
4
+ export declare const CONTEXT_INDEX_PATH = ".taphound/context/project-context.json";
5
+ export declare const KNOWLEDGE_DIR = ".taphound/knowledge";
6
+ export declare const KNOWLEDGE_INDEX_PATH = ".taphound/knowledge/index.json";
7
+ export declare const KNOWLEDGE_ANCHORS_DIR = ".taphound/knowledge/anchors";
8
+ export declare const KNOWLEDGE_SCREENS_DIR = ".taphound/knowledge/screens";
9
+ export declare const FLOWS_DIR = ".taphound/flows";
10
+ export declare const EXTERNAL_FLOWS_DIR = ".taphound/flows/external";
11
+ export declare const JOURNEY_SOURCES_DIR = ".taphound/sources";
12
+ export declare const JOURNEYS_DIR = ".taphound/journeys";
13
+ export declare const CONTRACTS_DIR = ".taphound/contracts";
14
+ export declare const BASELINES_DIR = ".taphound/baselines";
15
+ export declare const BUILD_DIR = ".taphound/build";
16
+ export declare const GENERATIONS_DIR = ".taphound/build/generations";
17
+ export declare const JOBS_DIR = ".taphound/build/jobs";
18
+ export declare const DEFAULT_ARTIFACTS_DIR = ".taphound/build/runs";
19
+ export declare const WORKFLOWS_DIR = ".taphound/build/workflows";
20
+ export declare function workflowManifestPath(caseId: string): string;
21
+ export declare const BUILD_IGNORE_FILE = ".taphound/.gitignore";
22
+ export declare const BUILD_IGNORE_CONTENT = "build/\n";
23
+ export declare const GENERATION_CONTEXT_SNAPSHOT_PATH = "context/resolved.json";
24
+ export declare function assertArtifactDirectory(projectRoot: string, artifactsDir: string, relativeAuthorityRoot?: string): void;
25
+ export declare function isInvalidRelativeArtifactDirectory(path: string): boolean;
26
+ export declare function assertProjectPathUnder(projectRoot: string, outputPath: string, relativeRoot: string, label: string): string;
27
+ export declare function activeGenerationBundleName(id: string): string;
28
+ export declare function parseSnapshotEvidenceReference(reference: string, generationId: string): string | null;
@@ -0,0 +1,72 @@
1
+ import { isAbsolute, relative, resolve } from "node:path";
2
+ import { posix } from "node:path";
3
+ export const TAPHOUND_DIR = ".taphound";
4
+ export const CONFIG_PATH = `${TAPHOUND_DIR}/config.json`;
5
+ export const CONTEXT_DIR = `${TAPHOUND_DIR}/context`;
6
+ export const CONTEXT_INDEX_PATH = `${CONTEXT_DIR}/project-context.json`;
7
+ export const KNOWLEDGE_DIR = `${TAPHOUND_DIR}/knowledge`;
8
+ export const KNOWLEDGE_INDEX_PATH = `${KNOWLEDGE_DIR}/index.json`;
9
+ export const KNOWLEDGE_ANCHORS_DIR = `${KNOWLEDGE_DIR}/anchors`;
10
+ export const KNOWLEDGE_SCREENS_DIR = `${KNOWLEDGE_DIR}/screens`;
11
+ export const FLOWS_DIR = `${TAPHOUND_DIR}/flows`;
12
+ export const EXTERNAL_FLOWS_DIR = `${FLOWS_DIR}/external`;
13
+ export const JOURNEY_SOURCES_DIR = `${TAPHOUND_DIR}/sources`;
14
+ export const JOURNEYS_DIR = `${TAPHOUND_DIR}/journeys`;
15
+ export const CONTRACTS_DIR = `${TAPHOUND_DIR}/contracts`;
16
+ export const BASELINES_DIR = `${TAPHOUND_DIR}/baselines`;
17
+ export const BUILD_DIR = `${TAPHOUND_DIR}/build`;
18
+ export const GENERATIONS_DIR = `${BUILD_DIR}/generations`;
19
+ export const JOBS_DIR = `${BUILD_DIR}/jobs`;
20
+ export const DEFAULT_ARTIFACTS_DIR = `${BUILD_DIR}/runs`;
21
+ export const WORKFLOWS_DIR = `${BUILD_DIR}/workflows`;
22
+ export function workflowManifestPath(caseId) {
23
+ if (!/^[a-z][a-z0-9-]{0,63}$/.test(caseId)) {
24
+ throw new Error("Workflow Case id must be a safe lowercase path component");
25
+ }
26
+ return `${WORKFLOWS_DIR}/${caseId}/manifest.json`;
27
+ }
28
+ export const BUILD_IGNORE_FILE = `${TAPHOUND_DIR}/.gitignore`;
29
+ export const BUILD_IGNORE_CONTENT = "build/\n";
30
+ export const GENERATION_CONTEXT_SNAPSHOT_PATH = "context/resolved.json";
31
+ function isSameOrDescendant(parent, candidate) {
32
+ const fromParent = relative(parent, candidate);
33
+ return fromParent.length === 0
34
+ || (!fromParent.startsWith("..") && !isAbsolute(fromParent));
35
+ }
36
+ export function assertArtifactDirectory(projectRoot, artifactsDir, relativeAuthorityRoot = BUILD_DIR) {
37
+ const build = resolve(projectRoot, relativeAuthorityRoot);
38
+ const candidate = resolve(projectRoot, artifactsDir);
39
+ if (!isSameOrDescendant(build, candidate)) {
40
+ throw new Error(`Artifact output must stay under ${BUILD_DIR}/: ${artifactsDir}`);
41
+ }
42
+ }
43
+ export function isInvalidRelativeArtifactDirectory(path) {
44
+ const normalized = posix.normalize(path.replaceAll("\\", "/"));
45
+ return !posix.isAbsolute(normalized)
46
+ && normalized !== BUILD_DIR
47
+ && !normalized.startsWith(`${BUILD_DIR}/`);
48
+ }
49
+ export function assertProjectPathUnder(projectRoot, outputPath, relativeRoot, label) {
50
+ const root = resolve(projectRoot, relativeRoot);
51
+ const candidate = resolve(projectRoot, outputPath);
52
+ if (!isSameOrDescendant(root, candidate)) {
53
+ throw new Error(`${label} must stay under ${relativeRoot}/: ${outputPath}`);
54
+ }
55
+ return candidate;
56
+ }
57
+ const SNAPSHOT_EVIDENCE_REFERENCE_PATTERN = new RegExp(`^${GENERATIONS_DIR.replace(/[.*+?^${}()|[\]\\]/g, "\\$&")}/([^/]+)/(evidence/snapshots/revision-\\d+/[^/]+/snapshot\\.json)$`);
58
+ export function activeGenerationBundleName(id) {
59
+ return `.${id}.work`;
60
+ }
61
+ export function parseSnapshotEvidenceReference(reference, generationId) {
62
+ const match = SNAPSHOT_EVIDENCE_REFERENCE_PATTERN.exec(reference);
63
+ if (match === null) {
64
+ return null;
65
+ }
66
+ const bundleName = match[1] ?? "";
67
+ if (bundleName !== generationId
68
+ && bundleName !== activeGenerationBundleName(generationId)) {
69
+ return null;
70
+ }
71
+ return match[2] ?? null;
72
+ }
@@ -1,6 +1,7 @@
1
- import type { Point } from "./android-cli.js";
1
+ import type { Point } from "../domain/geometry.js";
2
2
  import type { ForegroundComponent } from "../domain/activity.js";
3
3
  import type { AppProcess } from "../domain/app-process.js";
4
+ import type { WindowTopology } from "../domain/window-hierarchy.js";
4
5
  import type { CommandResult, RunningCommand } from "./process-runner.js";
5
6
  export interface DeviceInfo {
6
7
  serial: string;
@@ -19,24 +20,56 @@ export interface LaunchActivityOptions {
19
20
  signal?: AbortSignal | undefined;
20
21
  timeoutMs?: number | undefined;
21
22
  }
23
+ export interface StartActivityByIntentOptions {
24
+ action: string;
25
+ deviceSerial: string;
26
+ signal?: AbortSignal | undefined;
27
+ timeoutMs?: number | undefined;
28
+ }
29
+ export interface ResolveLauncherActivityOptions {
30
+ packageName: string;
31
+ deviceSerial: string;
32
+ signal?: AbortSignal | undefined;
33
+ timeoutMs?: number | undefined;
34
+ }
35
+ export interface ResolvedActivity {
36
+ packageName: string;
37
+ activity: string;
38
+ }
22
39
  export interface LogcatOptions {
23
40
  deviceSerial: string;
24
41
  onStdoutLine: (line: string) => void;
25
42
  onStderrLine?: ((line: string) => void) | undefined;
26
43
  signal?: AbortSignal | undefined;
27
44
  }
45
+ export interface DumpLogcatOptions {
46
+ deviceSerial: string;
47
+ maxLines: number;
48
+ signal?: AbortSignal | undefined;
49
+ timeoutMs?: number | undefined;
50
+ }
51
+ export interface DeviceIdentity {
52
+ manufacturer: string;
53
+ model: string;
54
+ sdkLevel: number;
55
+ }
28
56
  export interface AdbPort {
29
57
  devices: (signal?: AbortSignal) => Promise<readonly DeviceInfo[]>;
58
+ deviceIdentity?: (identity: AppIdentity) => Promise<DeviceIdentity>;
30
59
  foregroundComponent: (identity: AppIdentity) => Promise<ForegroundComponent>;
31
60
  currentActivity: (identity: AppIdentity) => Promise<string>;
32
61
  isInstalled: (identity: AppIdentity) => Promise<boolean>;
33
62
  launchActivity: (options: LaunchActivityOptions) => Promise<CommandResult>;
63
+ startActivityByIntent: (options: StartActivityByIntentOptions) => Promise<CommandResult>;
64
+ resolveLauncherActivity: (options: ResolveLauncherActivityOptions) => Promise<ResolvedActivity | undefined>;
34
65
  forceStop: (identity: AppIdentity) => Promise<CommandResult>;
35
66
  appProcesses: (identity: AppIdentity) => Promise<readonly AppProcess[]>;
67
+ windowTopology: (identity: AppIdentity) => Promise<WindowTopology>;
36
68
  tap: (point: Point, deviceSerial: string, signal?: AbortSignal) => Promise<CommandResult>;
37
69
  longClick: (point: Point, durationMs: number, deviceSerial: string, signal?: AbortSignal) => Promise<CommandResult>;
38
70
  swipe: (from: Point, to: Point, durationMs: number, deviceSerial: string, signal?: AbortSignal) => Promise<CommandResult>;
39
71
  back: (deviceSerial: string, signal?: AbortSignal) => Promise<CommandResult>;
40
72
  inputText: (text: string, deviceSerial: string, signal?: AbortSignal) => Promise<CommandResult>;
41
73
  startLogcat: (options: LogcatOptions) => RunningCommand;
74
+ dumpLogcat: (options: DumpLogcatOptions) => Promise<CommandResult>;
42
75
  }
@@ -0,0 +1,11 @@
1
+ import type { CameraProbeResult } from "./camera-probe.js";
2
+ export declare class AlignPromptCancelledError extends Error {
3
+ readonly name = "AlignPromptCancelledError";
4
+ constructor();
5
+ }
6
+ export interface AlignPromptPort {
7
+ confirmWrite: (input: {
8
+ values: CameraProbeResult;
9
+ targetPath: string;
10
+ }) => Promise<boolean>;
11
+ }
@@ -0,0 +1,6 @@
1
+ export class AlignPromptCancelledError extends Error {
2
+ name = "AlignPromptCancelledError";
3
+ constructor() {
4
+ super("Align prompt was cancelled");
5
+ }
6
+ }