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,112 @@
1
+ import { createHash, randomUUID } from "node:crypto";
2
+ import { mkdir, realpath, rename, rm, writeFile } from "node:fs/promises";
3
+ import { basename, dirname, join, resolve } from "node:path";
4
+ import { isContained } from "../../shared/paths.js";
5
+ function errorMessage(error) {
6
+ return error instanceof Error ? error.message : "Unknown write failure";
7
+ }
8
+ export class FileSystemContextDocumentWriter {
9
+ writeContextDocument = async (input) => {
10
+ const normalizedPath = input.relativePath.replaceAll("\\", "/");
11
+ if (normalizedPath.length === 0
12
+ || normalizedPath.startsWith("/")
13
+ || /^[A-Za-z]:/.test(normalizedPath)
14
+ || normalizedPath.split("/").includes("..")) {
15
+ return { status: "escape" };
16
+ }
17
+ let canonicalRoot;
18
+ try {
19
+ canonicalRoot = await realpath(input.projectRoot);
20
+ }
21
+ catch (error) {
22
+ return { status: "unwritable", message: errorMessage(error) };
23
+ }
24
+ const target = resolve(canonicalRoot, normalizedPath);
25
+ if (!isContained(canonicalRoot, target)) {
26
+ return { status: "escape" };
27
+ }
28
+ const bytes = `${JSON.stringify(input.document, null, 2)}\n`;
29
+ const directory = dirname(target);
30
+ const temporaryPath = join(directory, `.${basename(target)}.${randomUUID()}.tmp`);
31
+ try {
32
+ await mkdir(directory, { recursive: true });
33
+ await writeFile(temporaryPath, bytes, "utf8");
34
+ await rename(temporaryPath, target);
35
+ }
36
+ catch (error) {
37
+ await rm(temporaryPath, { force: true }).catch(() => undefined);
38
+ return { status: "unwritable", message: errorMessage(error) };
39
+ }
40
+ return {
41
+ status: "written",
42
+ sha256: createHash("sha256").update(bytes).digest("hex")
43
+ };
44
+ };
45
+ writeContextDocumentBatch = async (input) => {
46
+ let canonicalRoot;
47
+ try {
48
+ canonicalRoot = await realpath(input.projectRoot);
49
+ }
50
+ catch (error) {
51
+ const failure = {
52
+ status: "unwritable",
53
+ message: errorMessage(error)
54
+ };
55
+ return input.documents.map(() => failure);
56
+ }
57
+ const prepared = [];
58
+ for (const doc of input.documents) {
59
+ const normalizedPath = doc.relativePath.replaceAll("\\", "/");
60
+ if (normalizedPath.length === 0
61
+ || normalizedPath.startsWith("/")
62
+ || /^[A-Za-z]:/.test(normalizedPath)
63
+ || normalizedPath.split("/").includes("..")) {
64
+ for (const item of prepared) {
65
+ await rm(item.tempPath, { force: true }).catch(() => undefined);
66
+ }
67
+ const failure = { status: "escape" };
68
+ return input.documents.map(() => failure);
69
+ }
70
+ const target = resolve(canonicalRoot, normalizedPath);
71
+ if (!isContained(canonicalRoot, target)) {
72
+ for (const item of prepared) {
73
+ await rm(item.tempPath, { force: true }).catch(() => undefined);
74
+ }
75
+ const failure = { status: "escape" };
76
+ return input.documents.map(() => failure);
77
+ }
78
+ const bytes = `${JSON.stringify(doc.document, null, 2)}\n`;
79
+ const directory = dirname(target);
80
+ const tempPath = join(directory, `.${basename(target)}.${randomUUID()}.tmp`);
81
+ prepared.push({
82
+ target,
83
+ tempPath,
84
+ bytes,
85
+ sha256: createHash("sha256").update(bytes).digest("hex")
86
+ });
87
+ }
88
+ try {
89
+ for (const item of prepared) {
90
+ await mkdir(dirname(item.target), { recursive: true });
91
+ await writeFile(item.tempPath, item.bytes, "utf8");
92
+ }
93
+ for (const item of prepared) {
94
+ await rename(item.tempPath, item.target);
95
+ }
96
+ }
97
+ catch (error) {
98
+ for (const item of prepared) {
99
+ await rm(item.tempPath, { force: true }).catch(() => undefined);
100
+ }
101
+ const failure = {
102
+ status: "unwritable",
103
+ message: errorMessage(error)
104
+ };
105
+ return input.documents.map(() => failure);
106
+ }
107
+ return prepared.map((item) => ({
108
+ status: "written",
109
+ sha256: item.sha256
110
+ }));
111
+ };
112
+ }
@@ -0,0 +1,17 @@
1
+ import type { ExternalFlowCatalogEntry, ExternalFlowRecord, ExternalFlowRegistry, WriteExternalFlowInput, WriteExternalFlowResult } from "../../ports/external-flow-registry.js";
2
+ export declare class FileSystemExternalFlowRegistry implements ExternalFlowRegistry {
3
+ private readonly builtinFlowsRoot;
4
+ constructor(builtinFlowsRoot: string);
5
+ readonly read: (input: {
6
+ projectRoot: string;
7
+ name: string;
8
+ }) => Promise<ExternalFlowRecord>;
9
+ readonly list: (projectRoot: string) => Promise<readonly ExternalFlowCatalogEntry[]>;
10
+ readonly write: (input: WriteExternalFlowInput) => Promise<WriteExternalFlowResult>;
11
+ private readonly loadFlow;
12
+ private readonly resolveProjectFlowPath;
13
+ private readonly resolveBuiltinFlowPath;
14
+ private readonly readFlowFile;
15
+ private readonly listBuiltinFlows;
16
+ private readonly listProjectFlows;
17
+ }
@@ -0,0 +1,325 @@
1
+ import { lstat, mkdir, readdir, readFile, realpath, rename, writeFile } from "node:fs/promises";
2
+ import { isAbsolute, join, relative, resolve, sep } from "node:path";
3
+ import { ExternalFlowSchema } from "../../domain/external-flow.js";
4
+ import { EXTERNAL_FLOWS_DIR } from "../../domain/workspace.js";
5
+ const MAX_EXTERNAL_FLOW_BYTES = 1024 * 1024;
6
+ function contained(root, candidate) {
7
+ const fromRoot = relative(root, candidate);
8
+ return fromRoot === ""
9
+ || (fromRoot !== ".."
10
+ && !fromRoot.startsWith(`..${sep}`)
11
+ && !isAbsolute(fromRoot));
12
+ }
13
+ function flowFileName(name) {
14
+ return `${name}.json`;
15
+ }
16
+ function errorDetails(error) {
17
+ if (error instanceof Error) {
18
+ return {
19
+ code: "EXTERNAL_FLOW_INVALID",
20
+ message: error.message
21
+ };
22
+ }
23
+ return {
24
+ code: "EXTERNAL_FLOW_INVALID",
25
+ message: String(error)
26
+ };
27
+ }
28
+ export class FileSystemExternalFlowRegistry {
29
+ builtinFlowsRoot;
30
+ constructor(builtinFlowsRoot) {
31
+ this.builtinFlowsRoot = builtinFlowsRoot;
32
+ }
33
+ read = async (input) => {
34
+ const loaded = await this.loadFlow(input.projectRoot, input.name);
35
+ return {
36
+ bytes: loaded.bytes,
37
+ flow: loaded.flow,
38
+ source: loaded.source,
39
+ path: loaded.path
40
+ };
41
+ };
42
+ list = async (projectRoot) => {
43
+ const builtinEntries = await this.listBuiltinFlows();
44
+ const projectEntries = await this.listProjectFlows(projectRoot);
45
+ const projectNames = new Set(projectEntries.map((entry) => entry.name));
46
+ const entries = [
47
+ ...projectEntries,
48
+ ...builtinEntries.filter((entry) => !projectNames.has(entry.name))
49
+ ];
50
+ return entries.sort((left, right) => left.name.localeCompare(right.name));
51
+ };
52
+ write = async (input) => {
53
+ const { projectRoot, name, flow, force } = input;
54
+ const canonicalRoot = await realpath(projectRoot);
55
+ const externalRoot = resolve(canonicalRoot, EXTERNAL_FLOWS_DIR);
56
+ const targetPath = join(externalRoot, flowFileName(name));
57
+ const canonicalExternalRoot = await realpath(externalRoot).catch((error) => {
58
+ if (error instanceof Error
59
+ && "code" in error
60
+ && error.code === "ENOENT") {
61
+ return undefined;
62
+ }
63
+ throw error;
64
+ });
65
+ if (canonicalExternalRoot !== undefined
66
+ && !contained(canonicalRoot, canonicalExternalRoot)) {
67
+ throw new Error("External Flow directory escapes the project root");
68
+ }
69
+ const rootStats = await lstat(externalRoot).catch((error) => {
70
+ if (error instanceof Error
71
+ && "code" in error
72
+ && error.code === "ENOENT") {
73
+ return undefined;
74
+ }
75
+ throw error;
76
+ });
77
+ if (rootStats !== undefined && rootStats.isSymbolicLink()) {
78
+ throw new Error("External Flow directory is a symlink");
79
+ }
80
+ const validated = ExternalFlowSchema.parse(flow);
81
+ if (validated.name !== name) {
82
+ throw new Error(`External Flow declares name "${validated.name}", expected "${name}"`);
83
+ }
84
+ let overwritten = false;
85
+ const existingStats = await lstat(targetPath).catch((error) => {
86
+ if (error instanceof Error
87
+ && "code" in error
88
+ && error.code === "ENOENT") {
89
+ return undefined;
90
+ }
91
+ throw error;
92
+ });
93
+ if (existingStats !== undefined) {
94
+ if (existingStats.isSymbolicLink()) {
95
+ throw new Error(`External Flow target is a symlink: ${targetPath}`);
96
+ }
97
+ if (!force) {
98
+ throw new Error(`External Flow already exists: ${name}`);
99
+ }
100
+ overwritten = true;
101
+ }
102
+ const parentDir = name.includes("/")
103
+ ? join(externalRoot, name.split("/").slice(0, -1).join("/"))
104
+ : externalRoot;
105
+ await mkdir(parentDir, { recursive: true });
106
+ const tempPath = `${targetPath}.tmp`;
107
+ await writeFile(tempPath, `${JSON.stringify(validated, null, 2)}\n`);
108
+ await rename(tempPath, targetPath);
109
+ const relativePath = relative(canonicalRoot, targetPath).replaceAll("\\", "/");
110
+ return { path: relativePath, overwritten };
111
+ };
112
+ loadFlow = async (projectRoot, name) => {
113
+ const projectPath = await this.resolveProjectFlowPath(projectRoot, name);
114
+ if (projectPath !== undefined) {
115
+ return this.readFlowFile(projectPath, name, "project");
116
+ }
117
+ const builtinPath = await this.resolveBuiltinFlowPath(name);
118
+ if (builtinPath !== undefined) {
119
+ return this.readFlowFile(builtinPath, name, "builtin");
120
+ }
121
+ throw new Error(`External Flow not found: ${name}`);
122
+ };
123
+ resolveProjectFlowPath = async (projectRoot, name) => {
124
+ const canonicalRoot = await realpath(projectRoot);
125
+ const externalRoot = resolve(canonicalRoot, EXTERNAL_FLOWS_DIR);
126
+ try {
127
+ const canonicalExternalRoot = await realpath(externalRoot);
128
+ if (!contained(canonicalRoot, canonicalExternalRoot)) {
129
+ throw new Error("External Flow directory escapes the project root");
130
+ }
131
+ const rootStats = await lstat(externalRoot);
132
+ if (!rootStats.isDirectory() || rootStats.isSymbolicLink()) {
133
+ return undefined;
134
+ }
135
+ }
136
+ catch (error) {
137
+ if (error instanceof Error
138
+ && "code" in error
139
+ && error.code === "ENOENT") {
140
+ return undefined;
141
+ }
142
+ throw error;
143
+ }
144
+ const filePath = join(externalRoot, flowFileName(name));
145
+ try {
146
+ const stats = await lstat(filePath);
147
+ if (!stats.isFile() || stats.isSymbolicLink()) {
148
+ return undefined;
149
+ }
150
+ return filePath;
151
+ }
152
+ catch (error) {
153
+ if (error instanceof Error
154
+ && "code" in error
155
+ && error.code === "ENOENT") {
156
+ return undefined;
157
+ }
158
+ throw error;
159
+ }
160
+ };
161
+ resolveBuiltinFlowPath = async (name) => {
162
+ const filePath = join(this.builtinFlowsRoot, flowFileName(name));
163
+ try {
164
+ const stats = await lstat(filePath);
165
+ if (!stats.isFile() || stats.isSymbolicLink()) {
166
+ return undefined;
167
+ }
168
+ return filePath;
169
+ }
170
+ catch (error) {
171
+ if (error instanceof Error
172
+ && "code" in error
173
+ && error.code === "ENOENT") {
174
+ return undefined;
175
+ }
176
+ throw error;
177
+ }
178
+ };
179
+ readFlowFile = async (filePath, expectedName, source) => {
180
+ const bytes = await readFile(filePath);
181
+ if (bytes.byteLength > MAX_EXTERNAL_FLOW_BYTES) {
182
+ throw new Error(`External Flow exceeds ${String(MAX_EXTERNAL_FLOW_BYTES)} bytes: ${filePath}`);
183
+ }
184
+ let parsed;
185
+ try {
186
+ parsed = JSON.parse(bytes.toString("utf8"));
187
+ }
188
+ catch (error) {
189
+ throw new Error(`External Flow is not valid JSON: ${filePath}`, { cause: error });
190
+ }
191
+ const flow = ExternalFlowSchema.parse(parsed);
192
+ if (flow.name !== expectedName) {
193
+ throw new Error(`External Flow at ${filePath} declares name "${flow.name}", expected "${expectedName}"`);
194
+ }
195
+ return { bytes, flow, path: filePath, source };
196
+ };
197
+ listBuiltinFlows = async () => {
198
+ let rootStats;
199
+ try {
200
+ rootStats = await lstat(this.builtinFlowsRoot);
201
+ }
202
+ catch (error) {
203
+ if (error instanceof Error
204
+ && "code" in error
205
+ && error.code === "ENOENT") {
206
+ return [];
207
+ }
208
+ throw error;
209
+ }
210
+ if (!rootStats.isDirectory() || rootStats.isSymbolicLink()) {
211
+ return [];
212
+ }
213
+ const paths = [];
214
+ const visit = async (directory) => {
215
+ const entries = await readdir(directory, { withFileTypes: true });
216
+ for (const entry of entries) {
217
+ const path = join(directory, entry.name);
218
+ if (entry.isSymbolicLink()) {
219
+ throw new Error(`Built-in External Flow catalog cannot contain symlinks: ${path}`);
220
+ }
221
+ if (entry.isDirectory()) {
222
+ await visit(path);
223
+ }
224
+ else if (entry.isFile() && entry.name.endsWith(".json")) {
225
+ paths.push(path);
226
+ }
227
+ }
228
+ };
229
+ await visit(this.builtinFlowsRoot);
230
+ paths.sort();
231
+ const results = [];
232
+ for (const filePath of paths) {
233
+ const relativePath = relative(this.builtinFlowsRoot, filePath).replaceAll("\\", "/");
234
+ const name = relativePath.slice(0, -".json".length);
235
+ try {
236
+ const loaded = await this.readFlowFile(filePath, name, "builtin");
237
+ results.push({
238
+ name,
239
+ source: "builtin",
240
+ path: filePath,
241
+ status: "valid",
242
+ escapedPackageName: loaded.flow.escapedPackageName,
243
+ stepCount: loaded.flow.steps.length
244
+ });
245
+ }
246
+ catch (error) {
247
+ results.push({
248
+ name,
249
+ source: "builtin",
250
+ path: filePath,
251
+ status: "invalid",
252
+ failure: errorDetails(error)
253
+ });
254
+ }
255
+ }
256
+ return results;
257
+ };
258
+ listProjectFlows = async (projectRoot) => {
259
+ const canonicalRoot = await realpath(projectRoot);
260
+ const externalRoot = resolve(canonicalRoot, EXTERNAL_FLOWS_DIR);
261
+ try {
262
+ const canonicalExternalRoot = await realpath(externalRoot);
263
+ if (!contained(canonicalRoot, canonicalExternalRoot)) {
264
+ throw new Error("External Flow directory escapes the project root");
265
+ }
266
+ const rootStats = await lstat(externalRoot);
267
+ if (!rootStats.isDirectory() || rootStats.isSymbolicLink()) {
268
+ return [];
269
+ }
270
+ }
271
+ catch (error) {
272
+ if (error instanceof Error
273
+ && "code" in error
274
+ && error.code === "ENOENT") {
275
+ return [];
276
+ }
277
+ throw error;
278
+ }
279
+ const paths = [];
280
+ const visit = async (directory) => {
281
+ const entries = await readdir(directory, { withFileTypes: true });
282
+ for (const entry of entries) {
283
+ const path = join(directory, entry.name);
284
+ if (entry.isSymbolicLink()) {
285
+ throw new Error(`External Flow catalog cannot contain symlinks: ${path}`);
286
+ }
287
+ if (entry.isDirectory()) {
288
+ await visit(path);
289
+ }
290
+ else if (entry.isFile() && entry.name.endsWith(".json")) {
291
+ paths.push(path);
292
+ }
293
+ }
294
+ };
295
+ await visit(externalRoot);
296
+ paths.sort();
297
+ const results = [];
298
+ for (const filePath of paths) {
299
+ const relativePath = relative(canonicalRoot, filePath).replaceAll("\\", "/");
300
+ const name = relativePath
301
+ .slice(`${EXTERNAL_FLOWS_DIR}/`.length, -".json".length);
302
+ try {
303
+ const loaded = await this.readFlowFile(filePath, name, "project");
304
+ results.push({
305
+ name,
306
+ source: "project",
307
+ path: relativePath,
308
+ status: "valid",
309
+ escapedPackageName: loaded.flow.escapedPackageName,
310
+ stepCount: loaded.flow.steps.length
311
+ });
312
+ }
313
+ catch (error) {
314
+ results.push({
315
+ name,
316
+ source: "project",
317
+ path: relativePath,
318
+ status: "invalid",
319
+ failure: errorDetails(error)
320
+ });
321
+ }
322
+ }
323
+ return results;
324
+ };
325
+ }
@@ -1,10 +1,11 @@
1
- import { type GenerationInFlight, type GenerationSession, type PendingConfirmation } from "../../domain/generation.js";
1
+ import { type GenerationInFlight, type GenerationSession, type PendingConfirmation, type VerificationPhase } from "../../domain/generation.js";
2
2
  import { type GenerationSessionStore } from "../../ports/generation-session-store.js";
3
3
  export interface FileSystemGenerationSessionStoreOptions {
4
4
  lockTimeoutMs?: number;
5
5
  lockRetryMs?: number;
6
6
  now?: (() => Date) | undefined;
7
7
  hooks?: FileSystemGenerationSessionStoreHooks;
8
+ generationRoot?: string | undefined;
8
9
  }
9
10
  export interface FileSystemGenerationSessionStoreHooks {
10
11
  beforeLockStagingWrite?: () => Promise<void> | void;
@@ -27,6 +28,8 @@ export declare class FileSystemGenerationSessionStore implements GenerationSessi
27
28
  private readonly options;
28
29
  private readonly now;
29
30
  private readonly hooks;
31
+ private readonly customGenerationRoot;
32
+ private readonly lock;
30
33
  constructor(projectRoot: string, options?: FileSystemGenerationSessionStoreOptions);
31
34
  readonly create: (input: GenerationSession) => Promise<void>;
32
35
  readonly read: (id: string) => Promise<GenerationSession>;
@@ -36,14 +39,24 @@ export declare class FileSystemGenerationSessionStore implements GenerationSessi
36
39
  readonly beginStep: (id: string, expectedRevision: number, inFlightInput: GenerationInFlight, approvedConfirmationInput?: PendingConfirmation) => Promise<GenerationSession>;
37
40
  readonly completeStep: (id: string, expectedRevision: number, expectedInFlightInput: GenerationInFlight, input: GenerationSession) => Promise<void>;
38
41
  readonly recover: (id: string, expectedRevision: number, input: GenerationSession) => Promise<void>;
39
- readonly beginVerification: (id: string, expectedRevision: number, attemptId: string) => Promise<GenerationSession>;
42
+ readonly beginVerification: (id: string, expectedRevision: number, attemptId: string, owner?: {
43
+ pid: number;
44
+ startedAt: string;
45
+ }) => Promise<GenerationSession>;
46
+ readonly updateVerificationPhase: (id: string, attemptId: string, phase: VerificationPhase) => Promise<void>;
47
+ readonly abortVerification: (id: string, expectedRevision: number) => Promise<GenerationSession>;
40
48
  readonly completeVerification: (id: string, expectedRevision: number, input: GenerationSession) => Promise<void>;
41
49
  readonly failVerification: (id: string, expectedRevision: number, input: GenerationSession) => Promise<void>;
50
+ readonly recoverVerification: (id: string, expectedRevision: number, input: GenerationSession) => Promise<void>;
51
+ readonly reopenVerification: (id: string, expectedRevision: number, input: GenerationSession) => Promise<void>;
42
52
  readonly markBundlePublishable: (id: string, expectedRevision: number, input: GenerationSession) => Promise<void>;
53
+ readonly archive: (id: string, expectedRevision: number, input: GenerationSession) => Promise<void>;
54
+ readonly list: () => Promise<readonly GenerationSession[]>;
43
55
  readonly writeEvidence: (id: string, relativePath: string, value: unknown) => Promise<void>;
44
56
  readonly writeTextEvidence: (id: string, relativePath: string, value: string) => Promise<void>;
45
57
  readonly produceEvidence: (id: string, relativePath: string, produce: (temporaryPath: string) => Promise<void>) => Promise<void>;
46
58
  readonly readEvidence: (id: string, relativePath: string) => Promise<Buffer>;
59
+ readonly evidenceReference: (id: string, relativePath: string) => Promise<string>;
47
60
  readonly listEvidence: (id: string) => Promise<readonly {
48
61
  path: string;
49
62
  contentBase64: string;
@@ -54,15 +67,8 @@ export declare class FileSystemGenerationSessionStore implements GenerationSessi
54
67
  private readonly writeVerificationTransition;
55
68
  private readonly activeDirectory;
56
69
  private readonly finalDirectory;
57
- private readonly lockPath;
58
- private readonly syncDirectory;
70
+ private readonly withVerifiedEvidence;
59
71
  private readonly withLock;
60
- private readonly acquireLock;
61
- private readonly tryInstallLock;
62
- private readonly reapDeadOwnerLock;
63
- private readonly releaseLock;
64
- private readonly readLockOwner;
65
- private readonly fileIdentity;
66
- private readonly isProcessAlive;
72
+ private readonly syncDirectory;
67
73
  private assertPublishable;
68
74
  }