taphound 0.2.0-dev.1

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 (176) hide show
  1. package/LICENSE +202 -0
  2. package/README.md +200 -0
  3. package/README.zh-CN.md +200 -0
  4. package/assets/brand/taphound-mark.svg +9 -0
  5. package/assets/skills/taphound-ai-journey/GUIDE.md +862 -0
  6. package/assets/skills/taphound-ai-journey/SKILL.md +377 -0
  7. package/assets/skills/taphound-ai-journey/prompts/analyze-project.md +526 -0
  8. package/assets/skills/taphound-ai-journey/prompts/check-completion.md +52 -0
  9. package/assets/skills/taphound-ai-journey/prompts/generate-step.md +109 -0
  10. package/assets/skills/taphound-ai-journey/schemas/observe-output.json +42 -0
  11. package/assets/skills/taphound-ai-journey/schemas/project-context.json +81 -0
  12. package/assets/skills/taphound-ai-journey/schemas/proposed-step-envelope.json +267 -0
  13. package/assets/skills/taphound-ai-journey/templates/project-context.example.json +49 -0
  14. package/dist/adapters/adb/adb-adapter.d.ts +23 -0
  15. package/dist/adapters/adb/adb-adapter.js +218 -0
  16. package/dist/adapters/android-cli/android-cli-adapter.d.ts +11 -0
  17. package/dist/adapters/android-cli/android-cli-adapter.js +64 -0
  18. package/dist/adapters/android-cli/layout-parser.d.ts +3 -0
  19. package/dist/adapters/android-cli/layout-parser.js +174 -0
  20. package/dist/adapters/clock/system-clock.d.ts +5 -0
  21. package/dist/adapters/clock/system-clock.js +13 -0
  22. package/dist/adapters/filesystem/artifact-store.d.ts +4 -0
  23. package/dist/adapters/filesystem/artifact-store.js +73 -0
  24. package/dist/adapters/filesystem/generation-meta-writer.d.ts +16 -0
  25. package/dist/adapters/filesystem/generation-meta-writer.js +34 -0
  26. package/dist/adapters/filesystem/generation-session-store.d.ts +68 -0
  27. package/dist/adapters/filesystem/generation-session-store.js +1603 -0
  28. package/dist/adapters/filesystem/journey-writer.d.ts +16 -0
  29. package/dist/adapters/filesystem/journey-writer.js +34 -0
  30. package/dist/adapters/filesystem/project-bound-file.d.ts +6 -0
  31. package/dist/adapters/filesystem/project-bound-file.js +240 -0
  32. package/dist/adapters/filesystem/project-file-inspector.d.ts +8 -0
  33. package/dist/adapters/filesystem/project-file-inspector.js +198 -0
  34. package/dist/adapters/filesystem/skill-installer.d.ts +10 -0
  35. package/dist/adapters/filesystem/skill-installer.js +39 -0
  36. package/dist/adapters/process/node-process-runner.d.ts +8 -0
  37. package/dist/adapters/process/node-process-runner.js +155 -0
  38. package/dist/adapters/prompt/inquirer-generation-prompt.d.ts +55 -0
  39. package/dist/adapters/prompt/inquirer-generation-prompt.js +213 -0
  40. package/dist/adapters/prompt/inquirer-init-prompt.d.ts +32 -0
  41. package/dist/adapters/prompt/inquirer-init-prompt.js +55 -0
  42. package/dist/adapters/prompt/inquirer-recorder-prompt.d.ts +47 -0
  43. package/dist/adapters/prompt/inquirer-recorder-prompt.js +157 -0
  44. package/dist/application/assertion/expectation-evaluator.d.ts +61 -0
  45. package/dist/application/assertion/expectation-evaluator.js +207 -0
  46. package/dist/application/collector/logcat-collector.d.ts +39 -0
  47. package/dist/application/collector/logcat-collector.js +107 -0
  48. package/dist/application/context/context-validator.d.ts +27 -0
  49. package/dist/application/context/context-validator.js +120 -0
  50. package/dist/application/doctor/doctor-service.d.ts +35 -0
  51. package/dist/application/doctor/doctor-service.js +178 -0
  52. package/dist/application/generation/focused-input.d.ts +2 -0
  53. package/dist/application/generation/focused-input.js +9 -0
  54. package/dist/application/generation/generation-confirmation-service.d.ts +76 -0
  55. package/dist/application/generation/generation-confirmation-service.js +383 -0
  56. package/dist/application/generation/generation-finalizer.d.ts +67 -0
  57. package/dist/application/generation/generation-finalizer.js +646 -0
  58. package/dist/application/generation/generation-publisher.d.ts +46 -0
  59. package/dist/application/generation/generation-publisher.js +178 -0
  60. package/dist/application/generation/generation-starter.d.ts +31 -0
  61. package/dist/application/generation/generation-starter.js +102 -0
  62. package/dist/application/generation/generation-step-executor.d.ts +52 -0
  63. package/dist/application/generation/generation-step-executor.js +668 -0
  64. package/dist/application/generation/proposed-step-validator.d.ts +11 -0
  65. package/dist/application/generation/proposed-step-validator.js +88 -0
  66. package/dist/application/generation/risk-evaluator.d.ts +9 -0
  67. package/dist/application/generation/risk-evaluator.js +14 -0
  68. package/dist/application/generation/runtime-observer.d.ts +39 -0
  69. package/dist/application/generation/runtime-observer.js +157 -0
  70. package/dist/application/init/init-service.d.ts +17 -0
  71. package/dist/application/init/init-service.js +44 -0
  72. package/dist/application/interaction/action-executor.d.ts +25 -0
  73. package/dist/application/interaction/action-executor.js +103 -0
  74. package/dist/application/interaction/fallback-resolver.d.ts +24 -0
  75. package/dist/application/interaction/fallback-resolver.js +48 -0
  76. package/dist/application/interaction/scroll-to-executor.d.ts +40 -0
  77. package/dist/application/interaction/scroll-to-executor.js +191 -0
  78. package/dist/application/locator/locator-resolver.d.ts +20 -0
  79. package/dist/application/locator/locator-resolver.js +89 -0
  80. package/dist/application/project/project-describer.d.ts +14 -0
  81. package/dist/application/project/project-describer.js +8 -0
  82. package/dist/application/recorder/locator-selector.d.ts +10 -0
  83. package/dist/application/recorder/locator-selector.js +80 -0
  84. package/dist/application/recorder/recorder-service.d.ts +41 -0
  85. package/dist/application/recorder/recorder-service.js +331 -0
  86. package/dist/application/report/report-writer.d.ts +10 -0
  87. package/dist/application/report/report-writer.js +39 -0
  88. package/dist/application/runtime/activity-waiter.d.ts +33 -0
  89. package/dist/application/runtime/activity-waiter.js +73 -0
  90. package/dist/application/runtime/launch-failure.d.ts +2 -0
  91. package/dist/application/runtime/launch-failure.js +20 -0
  92. package/dist/application/runtime/process-waiter.d.ts +27 -0
  93. package/dist/application/runtime/process-waiter.js +73 -0
  94. package/dist/application/runtime/step-runner.d.ts +50 -0
  95. package/dist/application/runtime/step-runner.js +429 -0
  96. package/dist/application/runtime/verify-runtime.d.ts +44 -0
  97. package/dist/application/runtime/verify-runtime.js +350 -0
  98. package/dist/application/wait/idle-waiter.d.ts +30 -0
  99. package/dist/application/wait/idle-waiter.js +90 -0
  100. package/dist/cli/commands/context.d.ts +3 -0
  101. package/dist/cli/commands/context.js +94 -0
  102. package/dist/cli/commands/doctor.d.ts +3 -0
  103. package/dist/cli/commands/doctor.js +51 -0
  104. package/dist/cli/commands/generation.d.ts +3 -0
  105. package/dist/cli/commands/generation.js +518 -0
  106. package/dist/cli/commands/init.d.ts +3 -0
  107. package/dist/cli/commands/init.js +104 -0
  108. package/dist/cli/commands/project.d.ts +3 -0
  109. package/dist/cli/commands/project.js +58 -0
  110. package/dist/cli/commands/record.d.ts +3 -0
  111. package/dist/cli/commands/record.js +88 -0
  112. package/dist/cli/commands/verify.d.ts +3 -0
  113. package/dist/cli/commands/verify.js +106 -0
  114. package/dist/cli/dependencies.d.ts +66 -0
  115. package/dist/cli/dependencies.js +204 -0
  116. package/dist/cli/main.d.ts +8 -0
  117. package/dist/cli/main.js +73 -0
  118. package/dist/cli/output.d.ts +16 -0
  119. package/dist/cli/output.js +22 -0
  120. package/dist/cli/program.d.ts +3 -0
  121. package/dist/cli/program.js +43 -0
  122. package/dist/domain/activity.d.ts +7 -0
  123. package/dist/domain/activity.js +65 -0
  124. package/dist/domain/app-process.d.ts +7 -0
  125. package/dist/domain/app-process.js +10 -0
  126. package/dist/domain/config.d.ts +15 -0
  127. package/dist/domain/config.js +17 -0
  128. package/dist/domain/failure.d.ts +4 -0
  129. package/dist/domain/failure.js +43 -0
  130. package/dist/domain/generation.d.ts +912 -0
  131. package/dist/domain/generation.js +342 -0
  132. package/dist/domain/init.d.ts +42 -0
  133. package/dist/domain/init.js +114 -0
  134. package/dist/domain/journey.d.ts +673 -0
  135. package/dist/domain/journey.js +109 -0
  136. package/dist/domain/layout.d.ts +35 -0
  137. package/dist/domain/layout.js +33 -0
  138. package/dist/domain/locator.d.ts +8 -0
  139. package/dist/domain/locator.js +5 -0
  140. package/dist/domain/project-context.d.ts +101 -0
  141. package/dist/domain/project-context.js +64 -0
  142. package/dist/domain/proposed-step.d.ts +341 -0
  143. package/dist/domain/proposed-step.js +87 -0
  144. package/dist/domain/report.d.ts +349 -0
  145. package/dist/domain/report.js +135 -0
  146. package/dist/domain/runtime-snapshot.d.ts +16 -0
  147. package/dist/domain/runtime-snapshot.js +46 -0
  148. package/dist/ports/adb.d.ts +42 -0
  149. package/dist/ports/adb.js +1 -0
  150. package/dist/ports/android-cli.d.ts +21 -0
  151. package/dist/ports/android-cli.js +1 -0
  152. package/dist/ports/artifact-store.d.ts +12 -0
  153. package/dist/ports/artifact-store.js +1 -0
  154. package/dist/ports/clock.d.ts +4 -0
  155. package/dist/ports/clock.js +1 -0
  156. package/dist/ports/generation-meta-writer.d.ts +10 -0
  157. package/dist/ports/generation-meta-writer.js +1 -0
  158. package/dist/ports/generation-prompt.d.ts +19 -0
  159. package/dist/ports/generation-prompt.js +6 -0
  160. package/dist/ports/generation-session-store.d.ts +32 -0
  161. package/dist/ports/generation-session-store.js +26 -0
  162. package/dist/ports/init-prompt.d.ts +8 -0
  163. package/dist/ports/init-prompt.js +6 -0
  164. package/dist/ports/journey-writer.d.ts +10 -0
  165. package/dist/ports/journey-writer.js +1 -0
  166. package/dist/ports/process-runner.d.ts +32 -0
  167. package/dist/ports/process-runner.js +1 -0
  168. package/dist/ports/project-bound-file.d.ts +8 -0
  169. package/dist/ports/project-bound-file.js +1 -0
  170. package/dist/ports/project-file-inspector.d.ts +33 -0
  171. package/dist/ports/project-file-inspector.js +1 -0
  172. package/dist/ports/recorder-prompt.d.ts +29 -0
  173. package/dist/ports/recorder-prompt.js +1 -0
  174. package/dist/ports/skill-installer.d.ts +8 -0
  175. package/dist/ports/skill-installer.js +1 -0
  176. package/package.json +64 -0
@@ -0,0 +1,349 @@
1
+ import { z } from "zod";
2
+ export declare const ReportFailureSchema: z.ZodObject<{
3
+ code: z.ZodEnum<{
4
+ CONFIG_INVALID: "CONFIG_INVALID";
5
+ APP_CRASHED: "APP_CRASHED";
6
+ ENVIRONMENT_MISSING_TOOL: "ENVIRONMENT_MISSING_TOOL";
7
+ DEVICE_UNAVAILABLE: "DEVICE_UNAVAILABLE";
8
+ APP_NOT_INSTALLED: "APP_NOT_INSTALLED";
9
+ APP_LAUNCH_FAILED: "APP_LAUNCH_FAILED";
10
+ LOCATOR_NOT_FOUND: "LOCATOR_NOT_FOUND";
11
+ LOCATOR_AMBIGUOUS: "LOCATOR_AMBIGUOUS";
12
+ SCROLL_TARGET_NOT_FOUND: "SCROLL_TARGET_NOT_FOUND";
13
+ ACTION_FAILED: "ACTION_FAILED";
14
+ IDLE_TIMEOUT: "IDLE_TIMEOUT";
15
+ ACTIVITY_BEFORE_MISMATCH: "ACTIVITY_BEFORE_MISMATCH";
16
+ ACTIVITY_AFTER_MISMATCH: "ACTIVITY_AFTER_MISMATCH";
17
+ EXPECT_ACTIVITY_FAILED: "EXPECT_ACTIVITY_FAILED";
18
+ EXPECT_ELEMENT_FAILED: "EXPECT_ELEMENT_FAILED";
19
+ EXPECT_LOGCAT_FAILED: "EXPECT_LOGCAT_FAILED";
20
+ COLLECTION_FAILED: "COLLECTION_FAILED";
21
+ INTERNAL_ERROR: "INTERNAL_ERROR";
22
+ }>;
23
+ message: z.ZodString;
24
+ phase: z.ZodString;
25
+ stepIndex: z.ZodOptional<z.ZodNumber>;
26
+ }, z.core.$strict>;
27
+ export declare const StepReportSchema: z.ZodObject<{
28
+ index: z.ZodNumber;
29
+ action: z.ZodEnum<{
30
+ swipe: "swipe";
31
+ click: "click";
32
+ longClick: "longClick";
33
+ inputText: "inputText";
34
+ scrollTo: "scrollTo";
35
+ back: "back";
36
+ wait: "wait";
37
+ }>;
38
+ status: z.ZodEnum<{
39
+ notRun: "notRun";
40
+ passed: "passed";
41
+ failed: "failed";
42
+ }>;
43
+ startedAtMs: z.ZodNumber;
44
+ finishedAtMs: z.ZodNumber;
45
+ durationMs: z.ZodNumber;
46
+ locator: z.ZodOptional<z.ZodObject<{
47
+ status: z.ZodEnum<{
48
+ notRun: "notRun";
49
+ failed: "failed";
50
+ found: "found";
51
+ }>;
52
+ matchedBy: z.ZodOptional<z.ZodEnum<{
53
+ resourceId: "resourceId";
54
+ text: "text";
55
+ contentDescription: "contentDescription";
56
+ }>>;
57
+ fallbackUsed: z.ZodBoolean;
58
+ fallbackLabel: z.ZodOptional<z.ZodString>;
59
+ annotatedScreenshotPath: z.ZodOptional<z.ZodString>;
60
+ message: z.ZodOptional<z.ZodString>;
61
+ }, z.core.$strict>>;
62
+ idle: z.ZodOptional<z.ZodObject<{
63
+ status: z.ZodEnum<{
64
+ cancelled: "cancelled";
65
+ notRun: "notRun";
66
+ stable: "stable";
67
+ timeout: "timeout";
68
+ }>;
69
+ polls: z.ZodNumber;
70
+ lastDiff: z.ZodOptional<z.ZodArray<z.ZodUnknown>>;
71
+ }, z.core.$strict>>;
72
+ scroll: z.ZodOptional<z.ZodObject<{
73
+ swipesUsed: z.ZodNumber;
74
+ maxSwipes: z.ZodNumber;
75
+ }, z.core.$strict>>;
76
+ activity: z.ZodOptional<z.ZodObject<{
77
+ before: z.ZodObject<{
78
+ status: z.ZodEnum<{
79
+ notRun: "notRun";
80
+ passed: "passed";
81
+ failed: "failed";
82
+ }>;
83
+ expected: z.ZodString;
84
+ actual: z.ZodOptional<z.ZodString>;
85
+ }, z.core.$strict>;
86
+ after: z.ZodObject<{
87
+ status: z.ZodEnum<{
88
+ notRun: "notRun";
89
+ passed: "passed";
90
+ failed: "failed";
91
+ }>;
92
+ expected: z.ZodString;
93
+ actual: z.ZodOptional<z.ZodString>;
94
+ }, z.core.$strict>;
95
+ }, z.core.$strict>>;
96
+ expectation: z.ZodOptional<z.ZodObject<{
97
+ type: z.ZodEnum<{
98
+ activity: "activity";
99
+ logcat: "logcat";
100
+ element: "element";
101
+ }>;
102
+ status: z.ZodEnum<{
103
+ notRun: "notRun";
104
+ passed: "passed";
105
+ failed: "failed";
106
+ }>;
107
+ code: z.ZodOptional<z.ZodEnum<{
108
+ CONFIG_INVALID: "CONFIG_INVALID";
109
+ APP_CRASHED: "APP_CRASHED";
110
+ ENVIRONMENT_MISSING_TOOL: "ENVIRONMENT_MISSING_TOOL";
111
+ DEVICE_UNAVAILABLE: "DEVICE_UNAVAILABLE";
112
+ APP_NOT_INSTALLED: "APP_NOT_INSTALLED";
113
+ APP_LAUNCH_FAILED: "APP_LAUNCH_FAILED";
114
+ LOCATOR_NOT_FOUND: "LOCATOR_NOT_FOUND";
115
+ LOCATOR_AMBIGUOUS: "LOCATOR_AMBIGUOUS";
116
+ SCROLL_TARGET_NOT_FOUND: "SCROLL_TARGET_NOT_FOUND";
117
+ ACTION_FAILED: "ACTION_FAILED";
118
+ IDLE_TIMEOUT: "IDLE_TIMEOUT";
119
+ ACTIVITY_BEFORE_MISMATCH: "ACTIVITY_BEFORE_MISMATCH";
120
+ ACTIVITY_AFTER_MISMATCH: "ACTIVITY_AFTER_MISMATCH";
121
+ EXPECT_ACTIVITY_FAILED: "EXPECT_ACTIVITY_FAILED";
122
+ EXPECT_ELEMENT_FAILED: "EXPECT_ELEMENT_FAILED";
123
+ EXPECT_LOGCAT_FAILED: "EXPECT_LOGCAT_FAILED";
124
+ COLLECTION_FAILED: "COLLECTION_FAILED";
125
+ INTERNAL_ERROR: "INTERNAL_ERROR";
126
+ }>>;
127
+ message: z.ZodOptional<z.ZodString>;
128
+ }, z.core.$strict>>;
129
+ logcatPath: z.ZodOptional<z.ZodString>;
130
+ }, z.core.$strict>;
131
+ export declare const TapHoundReportSchema: z.ZodObject<{
132
+ schemaVersion: z.ZodLiteral<2>;
133
+ runId: z.ZodString;
134
+ status: z.ZodEnum<{
135
+ error: "error";
136
+ passed: "passed";
137
+ failed: "failed";
138
+ }>;
139
+ startedAt: z.ZodString;
140
+ finishedAt: z.ZodString;
141
+ durationMs: z.ZodNumber;
142
+ project: z.ZodObject<{
143
+ root: z.ZodString;
144
+ packageName: z.ZodString;
145
+ launchActivity: z.ZodString;
146
+ }, z.core.$strict>;
147
+ journey: z.ZodObject<{
148
+ name: z.ZodString;
149
+ sha256: z.ZodString;
150
+ }, z.core.$strict>;
151
+ environment: z.ZodObject<{
152
+ deviceSerial: z.ZodString;
153
+ tools: z.ZodRecord<z.ZodString, z.ZodString>;
154
+ }, z.core.$strict>;
155
+ layers: z.ZodObject<{
156
+ run: z.ZodEnum<{
157
+ notRun: "notRun";
158
+ passed: "passed";
159
+ failed: "failed";
160
+ }>;
161
+ structural: z.ZodEnum<{
162
+ notRun: "notRun";
163
+ passed: "passed";
164
+ failed: "failed";
165
+ }>;
166
+ activityCheckpoint: z.ZodEnum<{
167
+ notRun: "notRun";
168
+ passed: "passed";
169
+ failed: "failed";
170
+ }>;
171
+ explicitExpect: z.ZodEnum<{
172
+ notRun: "notRun";
173
+ passed: "passed";
174
+ failed: "failed";
175
+ }>;
176
+ collection: z.ZodEnum<{
177
+ notRun: "notRun";
178
+ passed: "passed";
179
+ failed: "failed";
180
+ }>;
181
+ }, z.core.$strict>;
182
+ steps: z.ZodArray<z.ZodObject<{
183
+ index: z.ZodNumber;
184
+ action: z.ZodEnum<{
185
+ swipe: "swipe";
186
+ click: "click";
187
+ longClick: "longClick";
188
+ inputText: "inputText";
189
+ scrollTo: "scrollTo";
190
+ back: "back";
191
+ wait: "wait";
192
+ }>;
193
+ status: z.ZodEnum<{
194
+ notRun: "notRun";
195
+ passed: "passed";
196
+ failed: "failed";
197
+ }>;
198
+ startedAtMs: z.ZodNumber;
199
+ finishedAtMs: z.ZodNumber;
200
+ durationMs: z.ZodNumber;
201
+ locator: z.ZodOptional<z.ZodObject<{
202
+ status: z.ZodEnum<{
203
+ notRun: "notRun";
204
+ failed: "failed";
205
+ found: "found";
206
+ }>;
207
+ matchedBy: z.ZodOptional<z.ZodEnum<{
208
+ resourceId: "resourceId";
209
+ text: "text";
210
+ contentDescription: "contentDescription";
211
+ }>>;
212
+ fallbackUsed: z.ZodBoolean;
213
+ fallbackLabel: z.ZodOptional<z.ZodString>;
214
+ annotatedScreenshotPath: z.ZodOptional<z.ZodString>;
215
+ message: z.ZodOptional<z.ZodString>;
216
+ }, z.core.$strict>>;
217
+ idle: z.ZodOptional<z.ZodObject<{
218
+ status: z.ZodEnum<{
219
+ cancelled: "cancelled";
220
+ notRun: "notRun";
221
+ stable: "stable";
222
+ timeout: "timeout";
223
+ }>;
224
+ polls: z.ZodNumber;
225
+ lastDiff: z.ZodOptional<z.ZodArray<z.ZodUnknown>>;
226
+ }, z.core.$strict>>;
227
+ scroll: z.ZodOptional<z.ZodObject<{
228
+ swipesUsed: z.ZodNumber;
229
+ maxSwipes: z.ZodNumber;
230
+ }, z.core.$strict>>;
231
+ activity: z.ZodOptional<z.ZodObject<{
232
+ before: z.ZodObject<{
233
+ status: z.ZodEnum<{
234
+ notRun: "notRun";
235
+ passed: "passed";
236
+ failed: "failed";
237
+ }>;
238
+ expected: z.ZodString;
239
+ actual: z.ZodOptional<z.ZodString>;
240
+ }, z.core.$strict>;
241
+ after: z.ZodObject<{
242
+ status: z.ZodEnum<{
243
+ notRun: "notRun";
244
+ passed: "passed";
245
+ failed: "failed";
246
+ }>;
247
+ expected: z.ZodString;
248
+ actual: z.ZodOptional<z.ZodString>;
249
+ }, z.core.$strict>;
250
+ }, z.core.$strict>>;
251
+ expectation: z.ZodOptional<z.ZodObject<{
252
+ type: z.ZodEnum<{
253
+ activity: "activity";
254
+ logcat: "logcat";
255
+ element: "element";
256
+ }>;
257
+ status: z.ZodEnum<{
258
+ notRun: "notRun";
259
+ passed: "passed";
260
+ failed: "failed";
261
+ }>;
262
+ code: z.ZodOptional<z.ZodEnum<{
263
+ CONFIG_INVALID: "CONFIG_INVALID";
264
+ APP_CRASHED: "APP_CRASHED";
265
+ ENVIRONMENT_MISSING_TOOL: "ENVIRONMENT_MISSING_TOOL";
266
+ DEVICE_UNAVAILABLE: "DEVICE_UNAVAILABLE";
267
+ APP_NOT_INSTALLED: "APP_NOT_INSTALLED";
268
+ APP_LAUNCH_FAILED: "APP_LAUNCH_FAILED";
269
+ LOCATOR_NOT_FOUND: "LOCATOR_NOT_FOUND";
270
+ LOCATOR_AMBIGUOUS: "LOCATOR_AMBIGUOUS";
271
+ SCROLL_TARGET_NOT_FOUND: "SCROLL_TARGET_NOT_FOUND";
272
+ ACTION_FAILED: "ACTION_FAILED";
273
+ IDLE_TIMEOUT: "IDLE_TIMEOUT";
274
+ ACTIVITY_BEFORE_MISMATCH: "ACTIVITY_BEFORE_MISMATCH";
275
+ ACTIVITY_AFTER_MISMATCH: "ACTIVITY_AFTER_MISMATCH";
276
+ EXPECT_ACTIVITY_FAILED: "EXPECT_ACTIVITY_FAILED";
277
+ EXPECT_ELEMENT_FAILED: "EXPECT_ELEMENT_FAILED";
278
+ EXPECT_LOGCAT_FAILED: "EXPECT_LOGCAT_FAILED";
279
+ COLLECTION_FAILED: "COLLECTION_FAILED";
280
+ INTERNAL_ERROR: "INTERNAL_ERROR";
281
+ }>>;
282
+ message: z.ZodOptional<z.ZodString>;
283
+ }, z.core.$strict>>;
284
+ logcatPath: z.ZodOptional<z.ZodString>;
285
+ }, z.core.$strict>>;
286
+ artifacts: z.ZodObject<{
287
+ directory: z.ZodString;
288
+ report: z.ZodString;
289
+ summary: z.ZodString;
290
+ screenshot: z.ZodOptional<z.ZodString>;
291
+ logcat: z.ZodOptional<z.ZodString>;
292
+ stepLogs: z.ZodArray<z.ZodString>;
293
+ }, z.core.$strict>;
294
+ primaryFailure: z.ZodOptional<z.ZodObject<{
295
+ code: z.ZodEnum<{
296
+ CONFIG_INVALID: "CONFIG_INVALID";
297
+ APP_CRASHED: "APP_CRASHED";
298
+ ENVIRONMENT_MISSING_TOOL: "ENVIRONMENT_MISSING_TOOL";
299
+ DEVICE_UNAVAILABLE: "DEVICE_UNAVAILABLE";
300
+ APP_NOT_INSTALLED: "APP_NOT_INSTALLED";
301
+ APP_LAUNCH_FAILED: "APP_LAUNCH_FAILED";
302
+ LOCATOR_NOT_FOUND: "LOCATOR_NOT_FOUND";
303
+ LOCATOR_AMBIGUOUS: "LOCATOR_AMBIGUOUS";
304
+ SCROLL_TARGET_NOT_FOUND: "SCROLL_TARGET_NOT_FOUND";
305
+ ACTION_FAILED: "ACTION_FAILED";
306
+ IDLE_TIMEOUT: "IDLE_TIMEOUT";
307
+ ACTIVITY_BEFORE_MISMATCH: "ACTIVITY_BEFORE_MISMATCH";
308
+ ACTIVITY_AFTER_MISMATCH: "ACTIVITY_AFTER_MISMATCH";
309
+ EXPECT_ACTIVITY_FAILED: "EXPECT_ACTIVITY_FAILED";
310
+ EXPECT_ELEMENT_FAILED: "EXPECT_ELEMENT_FAILED";
311
+ EXPECT_LOGCAT_FAILED: "EXPECT_LOGCAT_FAILED";
312
+ COLLECTION_FAILED: "COLLECTION_FAILED";
313
+ INTERNAL_ERROR: "INTERNAL_ERROR";
314
+ }>;
315
+ message: z.ZodString;
316
+ phase: z.ZodString;
317
+ stepIndex: z.ZodOptional<z.ZodNumber>;
318
+ }, z.core.$strict>>;
319
+ secondaryErrors: z.ZodArray<z.ZodObject<{
320
+ code: z.ZodEnum<{
321
+ CONFIG_INVALID: "CONFIG_INVALID";
322
+ APP_CRASHED: "APP_CRASHED";
323
+ ENVIRONMENT_MISSING_TOOL: "ENVIRONMENT_MISSING_TOOL";
324
+ DEVICE_UNAVAILABLE: "DEVICE_UNAVAILABLE";
325
+ APP_NOT_INSTALLED: "APP_NOT_INSTALLED";
326
+ APP_LAUNCH_FAILED: "APP_LAUNCH_FAILED";
327
+ LOCATOR_NOT_FOUND: "LOCATOR_NOT_FOUND";
328
+ LOCATOR_AMBIGUOUS: "LOCATOR_AMBIGUOUS";
329
+ SCROLL_TARGET_NOT_FOUND: "SCROLL_TARGET_NOT_FOUND";
330
+ ACTION_FAILED: "ACTION_FAILED";
331
+ IDLE_TIMEOUT: "IDLE_TIMEOUT";
332
+ ACTIVITY_BEFORE_MISMATCH: "ACTIVITY_BEFORE_MISMATCH";
333
+ ACTIVITY_AFTER_MISMATCH: "ACTIVITY_AFTER_MISMATCH";
334
+ EXPECT_ACTIVITY_FAILED: "EXPECT_ACTIVITY_FAILED";
335
+ EXPECT_ELEMENT_FAILED: "EXPECT_ELEMENT_FAILED";
336
+ EXPECT_LOGCAT_FAILED: "EXPECT_LOGCAT_FAILED";
337
+ COLLECTION_FAILED: "COLLECTION_FAILED";
338
+ INTERNAL_ERROR: "INTERNAL_ERROR";
339
+ }>;
340
+ message: z.ZodString;
341
+ phase: z.ZodString;
342
+ stepIndex: z.ZodOptional<z.ZodNumber>;
343
+ }, z.core.$strict>>;
344
+ fallbackUsed: z.ZodBoolean;
345
+ }, z.core.$strict>;
346
+ export type ReportFailure = z.infer<typeof ReportFailureSchema>;
347
+ export type StepReport = z.infer<typeof StepReportSchema>;
348
+ export type TapHoundReport = z.infer<typeof TapHoundReportSchema>;
349
+ export declare function hashJourney(journey: unknown): string;
@@ -0,0 +1,135 @@
1
+ import { createHash } from "node:crypto";
2
+ import { z } from "zod";
3
+ import { FAILURE_CODES } from "./failure.js";
4
+ const ResultStatusSchema = z.enum(["passed", "failed", "notRun"]);
5
+ const RunStatusSchema = z.enum(["passed", "failed", "error"]);
6
+ export const ReportFailureSchema = z.strictObject({
7
+ code: z.enum(FAILURE_CODES),
8
+ message: z.string().min(1),
9
+ phase: z.string().min(1),
10
+ stepIndex: z.number().int().nonnegative().optional()
11
+ });
12
+ const LocatorReportSchema = z.strictObject({
13
+ status: z.enum(["found", "failed", "notRun"]),
14
+ matchedBy: z.enum([
15
+ "resourceId",
16
+ "text",
17
+ "contentDescription"
18
+ ]).optional(),
19
+ fallbackUsed: z.boolean(),
20
+ fallbackLabel: z.string().regex(/^#\d+$/).optional(),
21
+ annotatedScreenshotPath: z.string().min(1).optional(),
22
+ message: z.string().min(1).optional()
23
+ }).superRefine((locator, context) => {
24
+ if (locator.fallbackUsed
25
+ && (locator.fallbackLabel === undefined
26
+ || locator.annotatedScreenshotPath === undefined)) {
27
+ context.addIssue({
28
+ code: "custom",
29
+ message: "Fallback evidence requires label and annotated screenshot"
30
+ });
31
+ }
32
+ });
33
+ const IdleReportSchema = z.strictObject({
34
+ status: z.enum(["stable", "timeout", "cancelled", "notRun"]),
35
+ polls: z.number().int().nonnegative(),
36
+ lastDiff: z.array(z.unknown()).optional()
37
+ });
38
+ const ActivityCheckSchema = z.strictObject({
39
+ status: ResultStatusSchema,
40
+ expected: z.string().min(1),
41
+ actual: z.string().min(1).optional()
42
+ });
43
+ const StepExpectationSchema = z.strictObject({
44
+ type: z.enum(["activity", "element", "logcat"]),
45
+ status: ResultStatusSchema,
46
+ code: z.enum(FAILURE_CODES).optional(),
47
+ message: z.string().min(1).optional()
48
+ });
49
+ export const StepReportSchema = z.strictObject({
50
+ index: z.number().int().nonnegative(),
51
+ action: z.enum([
52
+ "click",
53
+ "longClick",
54
+ "inputText",
55
+ "swipe",
56
+ "scrollTo",
57
+ "back",
58
+ "wait"
59
+ ]),
60
+ status: ResultStatusSchema,
61
+ startedAtMs: z.number().nonnegative(),
62
+ finishedAtMs: z.number().nonnegative(),
63
+ durationMs: z.number().nonnegative(),
64
+ locator: LocatorReportSchema.optional(),
65
+ idle: IdleReportSchema.optional(),
66
+ scroll: z.strictObject({
67
+ swipesUsed: z.number().int().nonnegative(),
68
+ maxSwipes: z.number().int().positive()
69
+ }).optional(),
70
+ activity: z.strictObject({
71
+ before: ActivityCheckSchema,
72
+ after: ActivityCheckSchema
73
+ }).optional(),
74
+ expectation: StepExpectationSchema.optional(),
75
+ logcatPath: z.string().min(1).optional()
76
+ });
77
+ const LayersSchema = z.strictObject({
78
+ run: ResultStatusSchema,
79
+ structural: ResultStatusSchema,
80
+ activityCheckpoint: ResultStatusSchema,
81
+ explicitExpect: ResultStatusSchema,
82
+ collection: ResultStatusSchema
83
+ });
84
+ const ArtifactsSchema = z.strictObject({
85
+ directory: z.string().min(1),
86
+ report: z.string().min(1),
87
+ summary: z.string().min(1),
88
+ screenshot: z.string().min(1).optional(),
89
+ logcat: z.string().min(1).optional(),
90
+ stepLogs: z.array(z.string().min(1))
91
+ });
92
+ export const TapHoundReportSchema = z.strictObject({
93
+ schemaVersion: z.literal(2),
94
+ runId: z.string().min(1),
95
+ status: RunStatusSchema,
96
+ startedAt: z.string().min(1),
97
+ finishedAt: z.string().min(1),
98
+ durationMs: z.number().nonnegative(),
99
+ project: z.strictObject({
100
+ root: z.string().min(1),
101
+ packageName: z.string().min(1),
102
+ launchActivity: z.string().min(1)
103
+ }),
104
+ journey: z.strictObject({
105
+ name: z.string().min(1),
106
+ sha256: z.string().regex(/^[a-f\d]{64}$/)
107
+ }),
108
+ environment: z.strictObject({
109
+ deviceSerial: z.string().min(1),
110
+ tools: z.record(z.string(), z.string())
111
+ }),
112
+ layers: LayersSchema,
113
+ steps: z.array(StepReportSchema),
114
+ artifacts: ArtifactsSchema,
115
+ primaryFailure: ReportFailureSchema.optional(),
116
+ secondaryErrors: z.array(ReportFailureSchema),
117
+ fallbackUsed: z.boolean()
118
+ });
119
+ function canonicalize(value) {
120
+ if (Array.isArray(value)) {
121
+ return value.map(canonicalize);
122
+ }
123
+ if (value !== null && typeof value === "object") {
124
+ return Object.fromEntries(Object.entries(value)
125
+ .filter(([, item]) => item !== undefined)
126
+ .sort(([left], [right]) => left.localeCompare(right))
127
+ .map(([key, item]) => [key, canonicalize(item)]));
128
+ }
129
+ return value;
130
+ }
131
+ export function hashJourney(journey) {
132
+ return createHash("sha256")
133
+ .update(JSON.stringify(canonicalize(journey)))
134
+ .digest("hex");
135
+ }
@@ -0,0 +1,16 @@
1
+ import { z } from "zod";
2
+ export declare const RuntimeSnapshotSchema: z.ZodObject<{
3
+ version: z.ZodLiteral<1>;
4
+ generationId: z.ZodString;
5
+ baseRevision: z.ZodNumber;
6
+ deviceSerial: z.ZodString;
7
+ expectedPackageName: z.ZodString;
8
+ foregroundPackageName: z.ZodString;
9
+ activity: z.ZodString;
10
+ pid: z.ZodNullable<z.ZodNumber>;
11
+ capturedAt: z.ZodISODateTime;
12
+ screenshotPath: z.ZodOptional<z.ZodString>;
13
+ layout: z.ZodArray<z.ZodType<import("./layout.js").LayoutElement, unknown, z.core.$ZodTypeInternals<import("./layout.js").LayoutElement, unknown>>>;
14
+ }, z.core.$strict>;
15
+ export type RuntimeSnapshot = z.infer<typeof RuntimeSnapshotSchema>;
16
+ export declare function hashRuntimeSnapshot(snapshot: unknown): string;
@@ -0,0 +1,46 @@
1
+ import { createHash } from "node:crypto";
2
+ import { z } from "zod";
3
+ import { LayoutElementSchema } from "./layout.js";
4
+ const QualifiedNameSchema = z.string().regex(/^(?:[A-Za-z_$][\w$]*\.)+[A-Za-z_$][\w$]*$/, "Value must be fully qualified");
5
+ export const RuntimeSnapshotSchema = z.strictObject({
6
+ version: z.literal(1),
7
+ generationId: z.string().trim().min(1),
8
+ baseRevision: z.number().int().positive().max(Number.MAX_SAFE_INTEGER),
9
+ deviceSerial: z.string().trim().min(1),
10
+ expectedPackageName: QualifiedNameSchema,
11
+ foregroundPackageName: QualifiedNameSchema,
12
+ activity: QualifiedNameSchema,
13
+ pid: z.number().int().positive().max(Number.MAX_SAFE_INTEGER).nullable(),
14
+ capturedAt: z.iso.datetime(),
15
+ screenshotPath: z.string().trim().min(1).optional(),
16
+ layout: z.array(LayoutElementSchema)
17
+ });
18
+ function canonicalize(value) {
19
+ if (Array.isArray(value)) {
20
+ return value.map(canonicalize);
21
+ }
22
+ if (value !== null && typeof value === "object") {
23
+ return Object.fromEntries(Object.entries(value)
24
+ .filter(([, item]) => item !== undefined)
25
+ .sort(([left], [right]) => left.localeCompare(right))
26
+ .map(([key, item]) => [key, canonicalize(item)]));
27
+ }
28
+ return value;
29
+ }
30
+ export function hashRuntimeSnapshot(snapshot) {
31
+ const parsed = RuntimeSnapshotSchema.parse(snapshot);
32
+ const content = {
33
+ version: parsed.version,
34
+ generationId: parsed.generationId,
35
+ baseRevision: parsed.baseRevision,
36
+ deviceSerial: parsed.deviceSerial,
37
+ expectedPackageName: parsed.expectedPackageName,
38
+ foregroundPackageName: parsed.foregroundPackageName,
39
+ activity: parsed.activity,
40
+ pid: parsed.pid,
41
+ layout: parsed.layout
42
+ };
43
+ return createHash("sha256")
44
+ .update(JSON.stringify(canonicalize(content)))
45
+ .digest("hex");
46
+ }
@@ -0,0 +1,42 @@
1
+ import type { Point } from "./android-cli.js";
2
+ import type { ForegroundComponent } from "../domain/activity.js";
3
+ import type { AppProcess } from "../domain/app-process.js";
4
+ import type { CommandResult, RunningCommand } from "./process-runner.js";
5
+ export interface DeviceInfo {
6
+ serial: string;
7
+ status: string;
8
+ }
9
+ export interface AppIdentity {
10
+ packageName: string;
11
+ deviceSerial: string;
12
+ signal?: AbortSignal | undefined;
13
+ timeoutMs?: number | undefined;
14
+ }
15
+ export interface LaunchActivityOptions {
16
+ packageName: string;
17
+ activity: string;
18
+ deviceSerial: string;
19
+ signal?: AbortSignal | undefined;
20
+ timeoutMs?: number | undefined;
21
+ }
22
+ export interface LogcatOptions {
23
+ deviceSerial: string;
24
+ onStdoutLine: (line: string) => void;
25
+ onStderrLine?: ((line: string) => void) | undefined;
26
+ signal?: AbortSignal | undefined;
27
+ }
28
+ export interface AdbPort {
29
+ devices: (signal?: AbortSignal) => Promise<readonly DeviceInfo[]>;
30
+ foregroundComponent: (identity: AppIdentity) => Promise<ForegroundComponent>;
31
+ currentActivity: (identity: AppIdentity) => Promise<string>;
32
+ isInstalled: (identity: AppIdentity) => Promise<boolean>;
33
+ launchActivity: (options: LaunchActivityOptions) => Promise<CommandResult>;
34
+ forceStop: (identity: AppIdentity) => Promise<CommandResult>;
35
+ appProcesses: (identity: AppIdentity) => Promise<readonly AppProcess[]>;
36
+ tap: (point: Point, deviceSerial: string, signal?: AbortSignal) => Promise<CommandResult>;
37
+ longClick: (point: Point, durationMs: number, deviceSerial: string, signal?: AbortSignal) => Promise<CommandResult>;
38
+ swipe: (from: Point, to: Point, durationMs: number, deviceSerial: string, signal?: AbortSignal) => Promise<CommandResult>;
39
+ back: (deviceSerial: string, signal?: AbortSignal) => Promise<CommandResult>;
40
+ inputText: (text: string, deviceSerial: string, signal?: AbortSignal) => Promise<CommandResult>;
41
+ startLogcat: (options: LogcatOptions) => RunningCommand;
42
+ }
@@ -0,0 +1 @@
1
+ export {};
@@ -0,0 +1,21 @@
1
+ import type { LayoutElement } from "../domain/layout.js";
2
+ import type { CommandResult } from "./process-runner.js";
3
+ export interface Point {
4
+ x: number;
5
+ y: number;
6
+ }
7
+ export interface DeviceCommandOptions {
8
+ deviceSerial: string;
9
+ signal?: AbortSignal | undefined;
10
+ timeoutMs?: number | undefined;
11
+ }
12
+ export interface CaptureScreenOptions extends DeviceCommandOptions {
13
+ outputPath: string;
14
+ annotate?: boolean | undefined;
15
+ }
16
+ export interface AndroidCliPort {
17
+ layout: (options: DeviceCommandOptions) => Promise<readonly LayoutElement[]>;
18
+ layoutDiff: (options: DeviceCommandOptions) => Promise<readonly unknown[]>;
19
+ captureScreen: (options: CaptureScreenOptions) => Promise<CommandResult>;
20
+ resolveScreen: (screenshotPath: string, label: string, signal?: AbortSignal) => Promise<Point>;
21
+ }
@@ -0,0 +1 @@
1
+ export {};
@@ -0,0 +1,12 @@
1
+ export interface ArtifactSession {
2
+ readonly temporaryDirectory: string;
3
+ readonly finalDirectory: string;
4
+ path: (relativePath: string) => string;
5
+ writeText: (relativePath: string, content: string) => Promise<void>;
6
+ writeJson: (relativePath: string, value: unknown) => Promise<void>;
7
+ publish: () => Promise<string>;
8
+ discard: () => Promise<void>;
9
+ }
10
+ export interface ArtifactStore {
11
+ begin: (baseDirectory: string, runDirectoryName: string) => Promise<ArtifactSession>;
12
+ }
@@ -0,0 +1 @@
1
+ export {};
@@ -0,0 +1,4 @@
1
+ export interface Clock {
2
+ now: () => number;
3
+ sleep: (durationMs: number, signal?: AbortSignal) => Promise<void>;
4
+ }
@@ -0,0 +1 @@
1
+ export {};
@@ -0,0 +1,10 @@
1
+ import type { GenerationMeta } from "../domain/generation.js";
2
+ import type { ProjectBoundFileReader, ProjectBoundPath } from "./project-bound-file.js";
3
+ export interface GenerationMetaWriterPort {
4
+ write: (outputPath: string, meta: GenerationMeta) => Promise<void>;
5
+ }
6
+ export interface ProjectBoundGenerationMetaWriterPort extends GenerationMetaWriterPort, ProjectBoundFileReader {
7
+ writeProjectBound: (path: ProjectBoundPath & {
8
+ meta: GenerationMeta;
9
+ }) => Promise<void>;
10
+ }
@@ -0,0 +1 @@
1
+ export {};
@@ -0,0 +1,19 @@
1
+ import type { PendingConfirmation } from "../domain/generation.js";
2
+ import type { Expectation } from "../domain/journey.js";
3
+ import type { LayoutElement } from "../domain/layout.js";
4
+ import type { ProposalBinding, ProposedStep } from "../domain/proposed-step.js";
5
+ export interface ManualProposalInput {
6
+ action: ProposedStep["action"];
7
+ binding: ProposalBinding;
8
+ before: string;
9
+ expect?: Expectation | undefined;
10
+ layout: readonly LayoutElement[];
11
+ }
12
+ export interface GenerationPromptPort {
13
+ confirm: (challenge: PendingConfirmation, signal?: AbortSignal) => Promise<boolean>;
14
+ buildManualProposal: (input: ManualProposalInput, signal?: AbortSignal) => Promise<ProposedStep>;
15
+ }
16
+ export declare class GenerationPromptCancelledError extends Error {
17
+ readonly name = "GenerationPromptCancelledError";
18
+ constructor();
19
+ }