swipium 1.4.0 → 2.0.0

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 (541) hide show
  1. package/CHANGELOG.md +313 -0
  2. package/README.md +175 -219
  3. package/THREAT_MODEL.md +223 -47
  4. package/dist/appMap/automationLink.js +39 -26
  5. package/dist/appMap/automationLink.js.map +1 -1
  6. package/dist/appMap/build.js +68 -20
  7. package/dist/appMap/build.js.map +1 -1
  8. package/dist/appMap/codeIndex.js +31 -5
  9. package/dist/appMap/codeIndex.js.map +1 -1
  10. package/dist/appMap/featureIndex.js +23 -5
  11. package/dist/appMap/featureIndex.js.map +1 -1
  12. package/dist/appMap/featureModel.js +44 -8
  13. package/dist/appMap/featureModel.js.map +1 -1
  14. package/dist/appMap/firstRunApply.js +24 -6
  15. package/dist/appMap/firstRunApply.js.map +1 -1
  16. package/dist/appMap/fsWalk.js +19 -2
  17. package/dist/appMap/fsWalk.js.map +1 -1
  18. package/dist/appMap/issues.js +10 -30
  19. package/dist/appMap/issues.js.map +1 -1
  20. package/dist/appMap/migrations.js +6 -6
  21. package/dist/appMap/migrations.js.map +1 -1
  22. package/dist/appMap/prelaunch.js +2 -2
  23. package/dist/appMap/prelaunch.js.map +1 -1
  24. package/dist/appMap/projectRegistry.js +83 -11
  25. package/dist/appMap/projectRegistry.js.map +1 -1
  26. package/dist/appMap/provenance.js +2 -2
  27. package/dist/appMap/provenance.js.map +1 -1
  28. package/dist/appMap/query.js +21 -5
  29. package/dist/appMap/query.js.map +1 -1
  30. package/dist/appMap/runtimeMerge.js +12 -5
  31. package/dist/appMap/runtimeMerge.js.map +1 -1
  32. package/dist/appMap/schema.js +1 -1
  33. package/dist/appMap/schema.js.map +1 -1
  34. package/dist/appMap/screenMatch.js +6 -2
  35. package/dist/appMap/screenMatch.js.map +1 -1
  36. package/dist/appMap/staticScan.js +151 -39
  37. package/dist/appMap/staticScan.js.map +1 -1
  38. package/dist/appMap/store.js +58 -85
  39. package/dist/appMap/store.js.map +1 -1
  40. package/dist/appMap/tsAstScan.js +34 -12
  41. package/dist/appMap/tsAstScan.js.map +1 -1
  42. package/dist/artifacts/bundletool.js +49 -12
  43. package/dist/artifacts/bundletool.js.map +1 -1
  44. package/dist/artifacts/resolve.js +41 -14
  45. package/dist/artifacts/resolve.js.map +1 -1
  46. package/dist/automation/capabilities.js +112 -30
  47. package/dist/automation/capabilities.js.map +1 -1
  48. package/dist/automation/gestures.js +6 -2
  49. package/dist/automation/gestures.js.map +1 -1
  50. package/dist/automation/plan.js +71 -23
  51. package/dist/automation/plan.js.map +1 -1
  52. package/dist/automation/report.js +15 -5
  53. package/dist/automation/report.js.map +1 -1
  54. package/dist/automation/selectors.js +22 -28
  55. package/dist/automation/selectors.js.map +1 -1
  56. package/dist/automation/types.js +1 -1
  57. package/dist/automation/types.js.map +1 -1
  58. package/dist/automation/waits.js +14 -8
  59. package/dist/automation/waits.js.map +1 -1
  60. package/dist/automation/webview.js +9 -3
  61. package/dist/automation/webview.js.map +1 -1
  62. package/dist/automationGen/appiumModel.js +16 -8
  63. package/dist/automationGen/appiumModel.js.map +1 -1
  64. package/dist/automationGen/ciEmitter.js +6 -6
  65. package/dist/automationGen/ciEmitter.js.map +1 -1
  66. package/dist/automationGen/identifiers.js +224 -0
  67. package/dist/automationGen/identifiers.js.map +1 -0
  68. package/dist/automationGen/jsEmitter.js +288 -121
  69. package/dist/automationGen/jsEmitter.js.map +1 -1
  70. package/dist/automationGen/packagePatch.js +2 -2
  71. package/dist/automationGen/packagePatch.js.map +1 -1
  72. package/dist/automationGen/platformResolve.js +36 -0
  73. package/dist/automationGen/platformResolve.js.map +1 -0
  74. package/dist/automationGen/projectProfile.js +76 -27
  75. package/dist/automationGen/projectProfile.js.map +1 -1
  76. package/dist/automationGen/pythonEmitter.js +278 -107
  77. package/dist/automationGen/pythonEmitter.js.map +1 -1
  78. package/dist/automationGen/readmeEmitter.js +7 -6
  79. package/dist/automationGen/readmeEmitter.js.map +1 -1
  80. package/dist/automationGen/run.js +388 -0
  81. package/dist/automationGen/run.js.map +1 -0
  82. package/dist/automationGen/suitePlan.js +17 -10
  83. package/dist/automationGen/suitePlan.js.map +1 -1
  84. package/dist/automationGen/validation.js +52 -12
  85. package/dist/automationGen/validation.js.map +1 -1
  86. package/dist/build/parseBuildLog.js +235 -31
  87. package/dist/build/parseBuildLog.js.map +1 -1
  88. package/dist/build/plan.js +39 -18
  89. package/dist/build/plan.js.map +1 -1
  90. package/dist/ci/preflight.js +13 -4
  91. package/dist/ci/preflight.js.map +1 -1
  92. package/dist/cli/gc.js +74 -0
  93. package/dist/cli/gc.js.map +1 -0
  94. package/dist/cli/init.js +217 -26
  95. package/dist/cli/init.js.map +1 -1
  96. package/dist/cli/main.js +50 -0
  97. package/dist/cli/main.js.map +1 -0
  98. package/dist/cli/report.js +218 -0
  99. package/dist/cli/report.js.map +1 -0
  100. package/dist/cli/scan.js +36 -15
  101. package/dist/cli/scan.js.map +1 -1
  102. package/dist/cli/suite.js +7 -7
  103. package/dist/cli/suite.js.map +1 -1
  104. package/dist/cli/verify.js +7 -7
  105. package/dist/cli/verify.js.map +1 -1
  106. package/dist/consent/consent.js +162 -5
  107. package/dist/consent/consent.js.map +1 -1
  108. package/dist/context/detect.js +55 -18
  109. package/dist/context/detect.js.map +1 -1
  110. package/dist/context/findApps.js +22 -8
  111. package/dist/context/findApps.js.map +1 -1
  112. package/dist/context/projectRoot.js +174 -19
  113. package/dist/context/projectRoot.js.map +1 -1
  114. package/dist/context/scan.js +1 -1
  115. package/dist/context/scan.js.map +1 -1
  116. package/dist/core/capabilityGroups.js +90 -0
  117. package/dist/core/capabilityGroups.js.map +1 -0
  118. package/dist/core/target.js +10 -8
  119. package/dist/core/target.js.map +1 -1
  120. package/dist/core/targetPlan.js +160 -39
  121. package/dist/core/targetPlan.js.map +1 -1
  122. package/dist/drivers/DirectDriver.js +317 -43
  123. package/dist/drivers/DirectDriver.js.map +1 -1
  124. package/dist/drivers/SimctlDriver.js +124 -8
  125. package/dist/drivers/SimctlDriver.js.map +1 -1
  126. package/dist/drivers/WdaDriver.js +365 -55
  127. package/dist/drivers/WdaDriver.js.map +1 -1
  128. package/dist/explore/candidates.js +7 -3
  129. package/dist/explore/candidates.js.map +1 -1
  130. package/dist/explore/graph.js +15 -6
  131. package/dist/explore/graph.js.map +1 -1
  132. package/dist/explore/memory.js +4 -1
  133. package/dist/explore/memory.js.map +1 -1
  134. package/dist/explore/planner.js +54 -9
  135. package/dist/explore/planner.js.map +1 -1
  136. package/dist/explore/policy.js +11 -6
  137. package/dist/explore/policy.js.map +1 -1
  138. package/dist/explore/runner.js +363 -190
  139. package/dist/explore/runner.js.map +1 -1
  140. package/dist/explore/signatures.js +4 -2
  141. package/dist/explore/signatures.js.map +1 -1
  142. package/dist/explore/suite.js +3 -1
  143. package/dist/explore/suite.js.map +1 -1
  144. package/dist/featureTesting/executionBootstrap.js +137 -29
  145. package/dist/featureTesting/executionBootstrap.js.map +1 -1
  146. package/dist/featureTesting/featureMap.js +6 -3
  147. package/dist/featureTesting/featureMap.js.map +1 -1
  148. package/dist/featureTesting/featureScope.js +101 -20
  149. package/dist/featureTesting/featureScope.js.map +1 -1
  150. package/dist/featureTesting/mapFeatureScope.js +44 -15
  151. package/dist/featureTesting/mapFeatureScope.js.map +1 -1
  152. package/dist/featureTesting/objectiveModel.js +15 -11
  153. package/dist/featureTesting/objectiveModel.js.map +1 -1
  154. package/dist/featureTesting/resultMerge.js +16 -8
  155. package/dist/featureTesting/resultMerge.js.map +1 -1
  156. package/dist/featureTesting/sources.js +8 -5
  157. package/dist/featureTesting/sources.js.map +1 -1
  158. package/dist/featureTesting/suiteBridge.js +8 -2
  159. package/dist/featureTesting/suiteBridge.js.map +1 -1
  160. package/dist/featureTesting/synonyms.js +32 -4
  161. package/dist/featureTesting/synonyms.js.map +1 -1
  162. package/dist/featureTesting/testCaseFactory.js +27 -15
  163. package/dist/featureTesting/testCaseFactory.js.map +1 -1
  164. package/dist/featureTesting/testPlan.js +34 -12
  165. package/dist/featureTesting/testPlan.js.map +1 -1
  166. package/dist/firstRun/authStateMachine.js +1 -1
  167. package/dist/firstRun/authStateMachine.js.map +1 -1
  168. package/dist/firstRun/classifyScreen.js +9 -6
  169. package/dist/firstRun/classifyScreen.js.map +1 -1
  170. package/dist/firstRun/firstRunPlanner.js +16 -13
  171. package/dist/firstRun/firstRunPlanner.js.map +1 -1
  172. package/dist/firstRun/firstRunRunner.js +92 -31
  173. package/dist/firstRun/firstRunRunner.js.map +1 -1
  174. package/dist/firstRun/generatedDataPolicy.js +25 -15
  175. package/dist/firstRun/generatedDataPolicy.js.map +1 -1
  176. package/dist/firstRun/inputPlanner.js +45 -11
  177. package/dist/firstRun/inputPlanner.js.map +1 -1
  178. package/dist/firstRun/onboardingStateMachine.js +1 -1
  179. package/dist/firstRun/onboardingStateMachine.js.map +1 -1
  180. package/dist/firstRun/paywallPolicy.js +3 -3
  181. package/dist/firstRun/paywallPolicy.js.map +1 -1
  182. package/dist/firstRun/types.js +1 -1
  183. package/dist/firstRun/types.js.map +1 -1
  184. package/dist/fixtures/catalog.js +72 -9
  185. package/dist/fixtures/catalog.js.map +1 -1
  186. package/dist/fixtures/load.js +50 -0
  187. package/dist/fixtures/load.js.map +1 -0
  188. package/dist/flows/discover.js +2 -2
  189. package/dist/flows/discover.js.map +1 -1
  190. package/dist/flows/generate.js +68 -17
  191. package/dist/flows/generate.js.map +1 -1
  192. package/dist/flows/lint.js +88 -14
  193. package/dist/flows/lint.js.map +1 -1
  194. package/dist/flows/pack.js +21 -5
  195. package/dist/flows/pack.js.map +1 -1
  196. package/dist/flows/paths.js +57 -0
  197. package/dist/flows/paths.js.map +1 -0
  198. package/dist/flows/repair.js +176 -37
  199. package/dist/flows/repair.js.map +1 -1
  200. package/dist/flows/run.js +308 -99
  201. package/dist/flows/run.js.map +1 -1
  202. package/dist/flows/schema.js +107 -25
  203. package/dist/flows/schema.js.map +1 -1
  204. package/dist/flows/seedExec.js +8 -4
  205. package/dist/flows/seedExec.js.map +1 -1
  206. package/dist/flows/templates.js +5 -5
  207. package/dist/index.js +50 -8
  208. package/dist/index.js.map +1 -1
  209. package/dist/ios/signing.js +32 -3
  210. package/dist/ios/signing.js.map +1 -1
  211. package/dist/issues/classify.js +28 -20
  212. package/dist/issues/classify.js.map +1 -1
  213. package/dist/issues/fingerprint.js +35 -9
  214. package/dist/issues/fingerprint.js.map +1 -1
  215. package/dist/issues/index.js +93 -46
  216. package/dist/issues/index.js.map +1 -1
  217. package/dist/issues/metrics.js +6 -5
  218. package/dist/issues/metrics.js.map +1 -1
  219. package/dist/issues/recurrence.js +35 -8
  220. package/dist/issues/recurrence.js.map +1 -1
  221. package/dist/issues/report.js +12 -8
  222. package/dist/issues/report.js.map +1 -1
  223. package/dist/issues/reportBridge.js +40 -9
  224. package/dist/issues/reportBridge.js.map +1 -1
  225. package/dist/issues/schema.js +2 -2
  226. package/dist/issues/schema.js.map +1 -1
  227. package/dist/issues/sourceRevision.js +2 -2
  228. package/dist/issues/sourceRevision.js.map +1 -1
  229. package/dist/issues/store.js +110 -32
  230. package/dist/issues/store.js.map +1 -1
  231. package/dist/lib/abortScope.js +48 -0
  232. package/dist/lib/abortScope.js.map +1 -0
  233. package/dist/lib/android.js +84 -8
  234. package/dist/lib/android.js.map +1 -1
  235. package/dist/lib/coordSpace.js +1 -1
  236. package/dist/lib/coordSpace.js.map +1 -1
  237. package/dist/lib/device.js +53 -12
  238. package/dist/lib/device.js.map +1 -1
  239. package/dist/lib/gestures.js +141 -0
  240. package/dist/lib/gestures.js.map +1 -0
  241. package/dist/lib/gitignore.js +4 -3
  242. package/dist/lib/gitignore.js.map +1 -1
  243. package/dist/lib/image.js +12 -3
  244. package/dist/lib/image.js.map +1 -1
  245. package/dist/lib/lockfile.js +399 -0
  246. package/dist/lib/lockfile.js.map +1 -0
  247. package/dist/lib/needsInput.js +9 -6
  248. package/dist/lib/needsInput.js.map +1 -1
  249. package/dist/lib/png.js +4 -3
  250. package/dist/lib/png.js.map +1 -1
  251. package/dist/lib/redact.js +170 -9
  252. package/dist/lib/redact.js.map +1 -1
  253. package/dist/lib/result.js +94 -10
  254. package/dist/lib/result.js.map +1 -1
  255. package/dist/lib/schemaHash.js +7 -5
  256. package/dist/lib/schemaHash.js.map +1 -1
  257. package/dist/lib/sensitive.js +6 -3
  258. package/dist/lib/sensitive.js.map +1 -1
  259. package/dist/lib/simctl.js +3 -3
  260. package/dist/lib/simctl.js.map +1 -1
  261. package/dist/lib/spawn.js +78 -17
  262. package/dist/lib/spawn.js.map +1 -1
  263. package/dist/lib/toolAnnotations.js +114 -0
  264. package/dist/lib/toolAnnotations.js.map +1 -0
  265. package/dist/lib/wda.js +321 -25
  266. package/dist/lib/wda.js.map +1 -1
  267. package/dist/lib/wdaConfig.js +12 -5
  268. package/dist/lib/wdaConfig.js.map +1 -1
  269. package/dist/lib/wdaTune.js +52 -23
  270. package/dist/lib/wdaTune.js.map +1 -1
  271. package/dist/mobileAudit/checks.js +150 -28
  272. package/dist/mobileAudit/checks.js.map +1 -1
  273. package/dist/mobileAudit/evidence.js +4 -4
  274. package/dist/mobileAudit/evidence.js.map +1 -1
  275. package/dist/mobileAudit/profiles.js +121 -20
  276. package/dist/mobileAudit/profiles.js.map +1 -1
  277. package/dist/mobileAudit/results.js +9 -4
  278. package/dist/mobileAudit/results.js.map +1 -1
  279. package/dist/mobileAudit/runner.js +214 -35
  280. package/dist/mobileAudit/runner.js.map +1 -1
  281. package/dist/oracle/auth.js +1 -1
  282. package/dist/oracle/auth.js.map +1 -1
  283. package/dist/oracle/failures.js +1085 -145
  284. package/dist/oracle/failures.js.map +1 -1
  285. package/dist/oracle/health.js +148 -26
  286. package/dist/oracle/health.js.map +1 -1
  287. package/dist/oracle/locator.js +148 -19
  288. package/dist/oracle/locator.js.map +1 -1
  289. package/dist/oracle/record.js +3 -3
  290. package/dist/oracle/record.js.map +1 -1
  291. package/dist/orchestration/envelope.js +2 -2
  292. package/dist/orchestration/envelope.js.map +1 -1
  293. package/dist/orchestration/goal.js +7 -13
  294. package/dist/orchestration/goal.js.map +1 -1
  295. package/dist/orchestration/testThis/execute.js +167 -0
  296. package/dist/orchestration/testThis/execute.js.map +1 -0
  297. package/dist/orchestration/testThis/pipeline.js +413 -0
  298. package/dist/orchestration/testThis/pipeline.js.map +1 -0
  299. package/dist/orchestration/testThis/plan.js +519 -0
  300. package/dist/orchestration/testThis/plan.js.map +1 -0
  301. package/dist/orchestration/testThis/sessionIntent.js +72 -0
  302. package/dist/orchestration/testThis/sessionIntent.js.map +1 -0
  303. package/dist/orchestration/testThis/terminal.js +136 -0
  304. package/dist/orchestration/testThis/terminal.js.map +1 -0
  305. package/dist/orchestration/testThis/types.js +12 -0
  306. package/dist/orchestration/testThis/types.js.map +1 -0
  307. package/dist/plan/plan.js +9 -9
  308. package/dist/plan/plan.js.map +1 -1
  309. package/dist/prompts/index.js +24 -24
  310. package/dist/prompts/index.js.map +1 -1
  311. package/dist/report/coverage.js +0 -1
  312. package/dist/report/coverage.js.map +1 -1
  313. package/dist/report/evidence.js.map +1 -1
  314. package/dist/report/export.js +449 -72
  315. package/dist/report/export.js.map +1 -1
  316. package/dist/report/findingsDedupe.js +41 -0
  317. package/dist/report/findingsDedupe.js.map +1 -0
  318. package/dist/report/flake.js +13 -14
  319. package/dist/report/flake.js.map +1 -1
  320. package/dist/report/history.js +72 -38
  321. package/dist/report/history.js.map +1 -1
  322. package/dist/report/policy.js +18 -7
  323. package/dist/report/policy.js.map +1 -1
  324. package/dist/report/qaLevel.js +10 -16
  325. package/dist/report/qaLevel.js.map +1 -1
  326. package/dist/report/readiness.js +42 -12
  327. package/dist/report/readiness.js.map +1 -1
  328. package/dist/report/sarifSources.js +160 -0
  329. package/dist/report/sarifSources.js.map +1 -0
  330. package/dist/report/summary.js +2 -2
  331. package/dist/report/summary.js.map +1 -1
  332. package/dist/report/testCatalog.js +4 -4
  333. package/dist/report/testCatalog.js.map +1 -1
  334. package/dist/report/timing.js +23 -23
  335. package/dist/report/timing.js.map +1 -1
  336. package/dist/report/toolHealth.js +124 -0
  337. package/dist/report/toolHealth.js.map +1 -0
  338. package/dist/server.js +501 -69
  339. package/dist/server.js.map +1 -1
  340. package/dist/services/automationGenerate.js +8 -2
  341. package/dist/services/automationGenerate.js.map +1 -1
  342. package/dist/services/build.js +10 -4
  343. package/dist/services/build.js.map +1 -1
  344. package/dist/services/flowGenerate.js +75 -0
  345. package/dist/services/flowGenerate.js.map +1 -0
  346. package/dist/services/preflight.js +40 -8
  347. package/dist/services/preflight.js.map +1 -1
  348. package/dist/services/prepareAndroid.js +92 -18
  349. package/dist/services/prepareAndroid.js.map +1 -1
  350. package/dist/services/prepareIos.js +94 -17
  351. package/dist/services/prepareIos.js.map +1 -1
  352. package/dist/services/report.js +271 -80
  353. package/dist/services/report.js.map +1 -1
  354. package/dist/services/smoke.js +68 -22
  355. package/dist/services/smoke.js.map +1 -1
  356. package/dist/services/suiteGenerate.js +43 -6
  357. package/dist/services/suiteGenerate.js.map +1 -1
  358. package/dist/services/testSuiteKnowledge.js +78 -33
  359. package/dist/services/testSuiteKnowledge.js.map +1 -1
  360. package/dist/session/attach.js +284 -4
  361. package/dist/session/attach.js.map +1 -1
  362. package/dist/session/processRegistry.js +433 -0
  363. package/dist/session/processRegistry.js.map +1 -0
  364. package/dist/session/progress.js +1 -1
  365. package/dist/session/progress.js.map +1 -1
  366. package/dist/session/retention.js +201 -0
  367. package/dist/session/retention.js.map +1 -0
  368. package/dist/session/store.js +459 -59
  369. package/dist/session/store.js.map +1 -1
  370. package/dist/snapshot/overlays.js +60 -10
  371. package/dist/snapshot/overlays.js.map +1 -1
  372. package/dist/snapshot/parse.js +30 -12
  373. package/dist/snapshot/parse.js.map +1 -1
  374. package/dist/snapshot/present.js +36 -6
  375. package/dist/snapshot/present.js.map +1 -1
  376. package/dist/snapshot/settle.js +39 -9
  377. package/dist/snapshot/settle.js.map +1 -1
  378. package/dist/state/consent.js +99 -0
  379. package/dist/state/consent.js.map +1 -0
  380. package/dist/state/profile.js +82 -11
  381. package/dist/state/profile.js.map +1 -1
  382. package/dist/suite/compile.js +15 -6
  383. package/dist/suite/compile.js.map +1 -1
  384. package/dist/suite/lint.js +22 -4
  385. package/dist/suite/lint.js.map +1 -1
  386. package/dist/suite/pom.js +75 -44
  387. package/dist/suite/pom.js.map +1 -1
  388. package/dist/suite/secretGuard.js +266 -0
  389. package/dist/suite/secretGuard.js.map +1 -0
  390. package/dist/suite/testcase.js +15 -11
  391. package/dist/suite/testcase.js.map +1 -1
  392. package/dist/testSuite/exporter.js +7 -3
  393. package/dist/testSuite/exporter.js.map +1 -1
  394. package/dist/testSuite/generator.js +43 -14
  395. package/dist/testSuite/generator.js.map +1 -1
  396. package/dist/testSuite/history.js +1 -1
  397. package/dist/testSuite/history.js.map +1 -1
  398. package/dist/testSuite/issueLinks.js +3 -3
  399. package/dist/testSuite/issueLinks.js.map +1 -1
  400. package/dist/testSuite/lint.js +4 -4
  401. package/dist/testSuite/lint.js.map +1 -1
  402. package/dist/testSuite/merge.js +13 -7
  403. package/dist/testSuite/merge.js.map +1 -1
  404. package/dist/testSuite/schema.js +21 -16
  405. package/dist/testSuite/schema.js.map +1 -1
  406. package/dist/testSuite/store.js +12 -4
  407. package/dist/testSuite/store.js.map +1 -1
  408. package/dist/testSuite/traceability.js +2 -2
  409. package/dist/testSuite/traceability.js.map +1 -1
  410. package/dist/tools/act.js +868 -174
  411. package/dist/tools/act.js.map +1 -1
  412. package/dist/tools/agent.js +521 -112
  413. package/dist/tools/agent.js.map +1 -1
  414. package/dist/tools/appControl.js +82 -19
  415. package/dist/tools/appControl.js.map +1 -1
  416. package/dist/tools/appMap.js +393 -189
  417. package/dist/tools/appMap.js.map +1 -1
  418. package/dist/tools/build.js +92 -51
  419. package/dist/tools/build.js.map +1 -1
  420. package/dist/tools/bundletool.js +141 -40
  421. package/dist/tools/bundletool.js.map +1 -1
  422. package/dist/tools/clearOverlay.js +98 -18
  423. package/dist/tools/clearOverlay.js.map +1 -1
  424. package/dist/tools/device.js +108 -19
  425. package/dist/tools/device.js.map +1 -1
  426. package/dist/tools/doctor.js +98 -35
  427. package/dist/tools/doctor.js.map +1 -1
  428. package/dist/tools/explore.js +110 -42
  429. package/dist/tools/explore.js.map +1 -1
  430. package/dist/tools/featureTesting.js +152 -130
  431. package/dist/tools/featureTesting.js.map +1 -1
  432. package/dist/tools/firstRun.js +94 -66
  433. package/dist/tools/firstRun.js.map +1 -1
  434. package/dist/tools/flow.js +347 -132
  435. package/dist/tools/flow.js.map +1 -1
  436. package/dist/tools/flowRepair.js +42 -10
  437. package/dist/tools/flowRepair.js.map +1 -1
  438. package/dist/tools/generate.js +199 -0
  439. package/dist/tools/generate.js.map +1 -0
  440. package/dist/tools/getArtifact.js +37 -8
  441. package/dist/tools/getArtifact.js.map +1 -1
  442. package/dist/tools/health.js +17 -12
  443. package/dist/tools/health.js.map +1 -1
  444. package/dist/tools/ios.js +148 -194
  445. package/dist/tools/ios.js.map +1 -1
  446. package/dist/tools/issues.js +256 -171
  447. package/dist/tools/issues.js.map +1 -1
  448. package/dist/tools/jobs.js +55 -11
  449. package/dist/tools/jobs.js.map +1 -1
  450. package/dist/tools/metro.js +84 -38
  451. package/dist/tools/metro.js.map +1 -1
  452. package/dist/tools/mobileAudit.js +83 -26
  453. package/dist/tools/mobileAudit.js.map +1 -1
  454. package/dist/tools/network.js +36 -14
  455. package/dist/tools/network.js.map +1 -1
  456. package/dist/tools/note.js +31 -17
  457. package/dist/tools/note.js.map +1 -1
  458. package/dist/tools/prepareIosTarget.js +31 -14
  459. package/dist/tools/prepareIosTarget.js.map +1 -1
  460. package/dist/tools/prepareTarget.js +193 -47
  461. package/dist/tools/prepareTarget.js.map +1 -1
  462. package/dist/tools/report.js +16 -8
  463. package/dist/tools/report.js.map +1 -1
  464. package/dist/tools/resolveArtifact.js +12 -12
  465. package/dist/tools/resolveArtifact.js.map +1 -1
  466. package/dist/tools/resolveTarget.js +81 -18
  467. package/dist/tools/resolveTarget.js.map +1 -1
  468. package/dist/tools/screenRecord.js +85 -20
  469. package/dist/tools/screenRecord.js.map +1 -1
  470. package/dist/tools/screenshot.js +42 -18
  471. package/dist/tools/screenshot.js.map +1 -1
  472. package/dist/tools/smoke.js +29 -12
  473. package/dist/tools/smoke.js.map +1 -1
  474. package/dist/tools/snapshot.js +157 -107
  475. package/dist/tools/snapshot.js.map +1 -1
  476. package/dist/tools/startSession.js +117 -84
  477. package/dist/tools/startSession.js.map +1 -1
  478. package/dist/tools/suite.js +391 -310
  479. package/dist/tools/suite.js.map +1 -1
  480. package/dist/tools/testSuite.js +112 -36
  481. package/dist/tools/testSuite.js.map +1 -1
  482. package/dist/tools/testThis.js +35 -802
  483. package/dist/tools/testThis.js.map +1 -1
  484. package/dist/tools/visual.js +698 -116
  485. package/dist/tools/visual.js.map +1 -1
  486. package/dist/tools/wait.js +9 -23
  487. package/dist/tools/wait.js.map +1 -1
  488. package/dist/tools/wda.js +312 -54
  489. package/dist/tools/wda.js.map +1 -1
  490. package/dist/version.js +37 -64
  491. package/dist/version.js.map +1 -1
  492. package/dist/visual/ocr.js +65 -8
  493. package/dist/visual/ocr.js.map +1 -1
  494. package/dist/visual/provider.js +87 -15
  495. package/dist/visual/provider.js.map +1 -1
  496. package/docs/README.md +24 -10
  497. package/docs/ci-reports.md +328 -0
  498. package/docs/concepts.md +227 -0
  499. package/docs/flows.md +153 -0
  500. package/docs/mcp-server.md +210 -104
  501. package/docs/physical-devices.md +84 -0
  502. package/docs/tools.md +808 -217
  503. package/package.json +16 -6
  504. package/dist/appMap/diff.js +0 -60
  505. package/dist/appMap/diff.js.map +0 -1
  506. package/dist/automation/maestroIr.js +0 -282
  507. package/dist/automation/maestroIr.js.map +0 -1
  508. package/dist/interop/maestro.js +0 -151
  509. package/dist/interop/maestro.js.map +0 -1
  510. package/dist/tools/assertVisual.js +0 -74
  511. package/dist/tools/assertVisual.js.map +0 -1
  512. package/dist/tools/automationGenerate.js +0 -394
  513. package/dist/tools/automationGenerate.js.map +0 -1
  514. package/dist/tools/capabilities.js +0 -209
  515. package/dist/tools/capabilities.js.map +0 -1
  516. package/dist/tools/detectContext.js +0 -41
  517. package/dist/tools/detectContext.js.map +0 -1
  518. package/dist/tools/flowGenerate.js +0 -55
  519. package/dist/tools/flowGenerate.js.map +0 -1
  520. package/dist/tools/history.js +0 -56
  521. package/dist/tools/history.js.map +0 -1
  522. package/dist/tools/idling.js +0 -104
  523. package/dist/tools/idling.js.map +0 -1
  524. package/dist/tools/inputCapabilities.js +0 -30
  525. package/dist/tools/inputCapabilities.js.map +0 -1
  526. package/dist/tools/locator.js +0 -57
  527. package/dist/tools/locator.js.map +0 -1
  528. package/dist/tools/maestro.js +0 -78
  529. package/dist/tools/maestro.js.map +0 -1
  530. package/dist/tools/permissions.js +0 -149
  531. package/dist/tools/permissions.js.map +0 -1
  532. package/dist/tools/plan.js +0 -49
  533. package/dist/tools/plan.js.map +0 -1
  534. package/dist/tools/screenInfo.js +0 -70
  535. package/dist/tools/screenInfo.js.map +0 -1
  536. package/dist/tools/seed.js +0 -101
  537. package/dist/tools/seed.js.map +0 -1
  538. package/dist/tools/state.js +0 -170
  539. package/dist/tools/state.js.map +0 -1
  540. package/dist/tools/visualText.js +0 -61
  541. package/dist/tools/visualText.js.map +0 -1
@@ -1,57 +0,0 @@
1
- // qa_locator_suggest (NEXT-PLAN: Locator And Maintainability) — for the current screen, recommend
2
- // the most durable locator for each element + score it, and grade the screen's "automation
3
- // readiness" (how much of the interactive UI has a durable testID/accessibility handle). This
4
- // tells a developer exactly which controls need testIDs to make flows non-brittle.
5
- import { z } from 'zod';
6
- import { qaOk, qaError } from '../lib/result.js';
7
- import { parseSnapshot, signature } from '../snapshot/parse.js';
8
- import { suggestLocator, automationReadiness, locatorReadinessIssues } from '../oracle/locator.js';
9
- import { getDriver } from '../session/attach.js';
10
- export function registerLocator(server, sessions) {
11
- server.registerTool('qa_locator_suggest', {
12
- title: 'Suggest durable locators',
13
- description: 'For the current screen, recommend the most durable locator for each element (priority: accessibility/content-desc > resource-id/testID > visible text > structure > coordinate) with a durability score, and grade the screen\'s automation readiness — listing exactly which interactive controls need a testID. Use this to make generated flows non-brittle and to hand developers an actionable testID to-do list. Needs a structured UI tree (not the iOS simulator / visual-fallback).',
14
- inputSchema: {
15
- sessionId: z.string(),
16
- interactiveOnly: z.boolean().optional().describe('Only score clickable elements (default false → all addressable elements).'),
17
- },
18
- }, async ({ sessionId, interactiveOnly }) => {
19
- const session = sessions.get(sessionId);
20
- const { driver } = session ? await getDriver(session) : { driver: undefined };
21
- if (!session || !driver) {
22
- return qaError({ what: 'No device attached to this session', changedState: false, retrySafe: true, nextSteps: ['Call qa_prepare_target first.'] });
23
- }
24
- if (driver.kind === 'simulator' || session.mode === 'visual-fallback') {
25
- return qaError({
26
- what: 'Locator suggestions need a structured UI tree, which this backend/screen lacks',
27
- changedState: false,
28
- retrySafe: false,
29
- failureCode: 'BACKEND_UNSUPPORTED',
30
- nextSteps: ['On the iOS simulator or a visual-only screen there is no a11y tree to score. Use qa_visual / qa_assert_visual instead.'],
31
- });
32
- }
33
- let xml;
34
- try {
35
- xml = await driver.dumpXml();
36
- }
37
- catch (e) {
38
- return qaError({ what: `Could not read the UI tree: ${String(e)}`, changedState: false, retrySafe: true, failureCode: 'SNAPSHOT_FAILED', nextSteps: ['Retry on a settled screen.'] });
39
- }
40
- const parsed = parseSnapshot(xml, { interactiveOnly: interactiveOnly ?? false });
41
- session.lastSnapshot = { fullByRef: parsed.fullByRef, signatures: new Set(parsed.elements.map(signature)), allNodes: parsed.allNodes };
42
- const platform = driver.kind === 'wda' ? 'ios' : driver.kind === 'direct' || driver.kind === 'remote' ? 'android' : 'generic';
43
- const suggestions = parsed.elements.map((el) => suggestLocator(el, { platform }));
44
- const readiness = automationReadiness(suggestions, parsed.elements, { platform });
45
- const issues = locatorReadinessIssues(suggestions, parsed.elements, { platform });
46
- const tierTally = suggestions.reduce((a, s) => ((a[s.tier] = (a[s.tier] ?? 0) + 1), a), {});
47
- const summary = `automation readiness: ${readiness.grade} (${readiness.durablePct}% of ${readiness.interactiveCount} interactive controls have a durable ${platform === 'ios' ? 'accessibilityIdentifier' : 'testID/a11y'} handle)\n` +
48
- `platform: ${platform}\n` +
49
- `locator tiers: ${Object.entries(tierTally).map(([t, n]) => `${t}=${n}`).join(' ')}\n` +
50
- (issues.length ? `issues:\n${issues.slice(0, 8).map((i) => ` - ${i.code}: ${i.message}`).join('\n')}\n` : '') +
51
- (readiness.needTestIds.length
52
- ? `needs a testID (${readiness.needTestIds.length}):\n` + readiness.needTestIds.slice(0, 15).map((n) => ` - ${n.ref} [${n.role}] — ${n.hint}${n.suggestedTestId ? `; suggested ${platform === 'ios' ? 'accessibilityIdentifier' : 'testID'}: ${n.suggestedTestId}` : ''}`).join('\n')
53
- : 'every interactive control already has a durable locator ✅');
54
- return qaOk({ platform, readiness, suggestions, tierTally, issues }, summary);
55
- });
56
- }
57
- //# sourceMappingURL=locator.js.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"locator.js","sourceRoot":"","sources":["../../src/tools/locator.ts"],"names":[],"mappings":"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"}
@@ -1,78 +0,0 @@
1
- import { readFileSync } from 'node:fs';
2
- import { z } from 'zod';
3
- import { qaError, qaOk } from '../lib/result.js';
4
- import { importMaestro } from '../interop/maestro.js';
5
- import { importMaestroActions, exportMaestroActions } from '../automation/maestroIr.js';
6
- import { compileActions } from '../automation/plan.js';
7
- import { parseFlow } from '../flows/schema.js';
8
- function rootFor(sessions, sessionId, projectRoot) {
9
- return sessionId ? sessions.get(sessionId)?.root : projectRoot;
10
- }
11
- export function registerMaestro(server, sessions) {
12
- server.registerTool('qa_maestro_import', {
13
- title: 'Import Maestro YAML',
14
- description: 'Import Maestro commands into the Automation Kernel V2 Action IR (`actionIr`), preserving explicit tapOn retryTapIfNoChange/repeat/settle, longPressOn, full scrollUntilVisible options, waitForAnimationToEnd, assertNotVisible, and eraseText. `unsupported` + `grades` are the authoritative semantic view (a command is unsupported only if it cannot be automated at all — e.g. clearState, repeat loops). Also emits `flowYaml` (the narrower Flow V2 subset for a saved .swipium/flows artifact) and `flowYamlUnsupported` (commands the IR supports but the Flow V2 YAML cannot yet express, e.g. longPressOn/assertNotVisible).',
15
- inputSchema: {
16
- sessionId: z.string().optional(),
17
- projectRoot: z.string().optional(),
18
- maestroYaml: z.string().optional(),
19
- path: z.string().optional(),
20
- name: z.string().optional(),
21
- appId: z.string().optional(),
22
- },
23
- }, async ({ sessionId, projectRoot, maestroYaml, path, name, appId }) => {
24
- const root = rootFor(sessions, sessionId, projectRoot);
25
- if (!maestroYaml && !path)
26
- return qaError({ what: 'Pass maestroYaml or path', changedState: false, retrySafe: true, nextSteps: ['Provide the Maestro YAML content or file path.'] });
27
- try {
28
- const text = maestroYaml ?? readFileSync(path, 'utf8');
29
- const legacy = importMaestro(text, { name, appId });
30
- const ir = importMaestroActions(text);
31
- const session = sessionId ? sessions.get(sessionId) : undefined;
32
- const uri = session ? sessions.saveArtifact(session, 'flow', `maestro-import-${Date.now()}.yaml`, legacy.flowYaml, 'text/yaml', 'Maestro import as Swipium Flow V2') : undefined;
33
- return qaOk({
34
- // V2 Action IR is authoritative: longPressOn/assertNotVisible/etc are supported here and
35
- // are NOT counted as unsupported (which was the contradiction the legacy importer caused).
36
- actionIr: ir.actions,
37
- grades: ir.grades,
38
- unsupported: ir.unsupported,
39
- // Flow V2 YAML (for a saved artifact) + the commands it cannot yet express even though the IR can.
40
- flowYaml: legacy.flowYaml,
41
- flowYamlUnsupported: legacy.unsupported,
42
- artifactUri: uri ?? null,
43
- root: root ?? null,
44
- }, `imported Maestro → ${ir.actions.length} Action IR step(s), ${ir.unsupported.length} unsupported${legacy.unsupported.length ? `, ${legacy.unsupported.length} not expressible in Flow V2 YAML` : ''}${uri ? `\nflow: ${uri}` : ''}`);
45
- }
46
- catch (e) {
47
- return qaError({ what: `Could not import Maestro YAML: ${String(e.message ?? e)}`, changedState: false, retrySafe: true, nextSteps: ['Check the YAML syntax and supported command subset.'] });
48
- }
49
- });
50
- server.registerTool('qa_maestro_export', {
51
- title: 'Export Swipium Flow to Maestro',
52
- description: 'Export a Swipium Flow V2 YAML to Maestro YAML via the Automation Kernel V2 IR exporter. Native selectors map to Maestro selector blocks (never XPath). Steps with no portable Maestro form — iOS predicate/class-chain selectors, visual/OCR/diff, and other Swipium/Appium/WDA-only steps — are emitted as explicit `manualReview` entries graded manual_review_required, never silently downgraded.',
53
- inputSchema: {
54
- sessionId: z.string().optional(),
55
- flowYaml: z.string().optional(),
56
- path: z.string().optional(),
57
- },
58
- }, async ({ sessionId, flowYaml, path }) => {
59
- if (!flowYaml && !path)
60
- return qaError({ what: 'Pass flowYaml or path', changedState: false, retrySafe: true, nextSteps: ['Provide Swipium flow YAML content or a path.'] });
61
- try {
62
- const text = flowYaml ?? readFileSync(path, 'utf8');
63
- const { flow: parsed, errors } = parseFlow(text);
64
- if (errors.length || !parsed) {
65
- return qaError({ what: `Flow is invalid (${errors.length} error${errors.length === 1 ? '' : 's'}) — run qa_flow_check`, changedState: false, retrySafe: true, nextSteps: ['Fix the flow YAML and re-export.'] }, { errors });
66
- }
67
- const result = exportMaestroActions(compileActions(parsed));
68
- const session = sessionId ? sessions.get(sessionId) : undefined;
69
- const uri = session ? sessions.saveArtifact(session, 'maestro', `maestro-export-${Date.now()}.yaml`, result.maestroYaml, 'text/yaml', 'Swipium Flow exported to Maestro') : undefined;
70
- const portable = result.grades.filter((g) => g.grade === 'portable' || g.grade === 'maestro_supported').length;
71
- return qaOk({ maestroYaml: result.maestroYaml, grades: result.grades, unsupported: result.unsupported, artifactUri: uri ?? null }, `exported Maestro YAML: ${portable}/${result.grades.length} portable, ${result.unsupported.length} need manual review${uri ? `\nartifact: ${uri}` : ''}`);
72
- }
73
- catch (e) {
74
- return qaError({ what: `Could not export Maestro YAML: ${String(e.message ?? e)}`, changedState: false, retrySafe: true, nextSteps: ['Check the Swipium Flow YAML.'] });
75
- }
76
- });
77
- }
78
- //# sourceMappingURL=maestro.js.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"maestro.js","sourceRoot":"","sources":["../../src/tools/maestro.ts"],"names":[],"mappings":"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"}
@@ -1,149 +0,0 @@
1
- // qa_permissions (PHASE3-PLAN §4.2) — list / grant / revoke Android runtime permissions without
2
- // raw adb. grant is low-risk (commonly used to pre-approve and skip a dialog) and only logged;
3
- // revoke can break app state, so it is consent-gated. Every mutation is recorded as an
4
- // environment change for qa_report.
5
- import { z } from 'zod';
6
- import { qaOk, qaError } from '../lib/result.js';
7
- import { requireConsent, consumeConsent } from '../consent/consent.js';
8
- import { getDriver } from '../session/attach.js';
9
- import { listRuntimePermissions, grantPermission, revokePermission } from '../lib/device.js';
10
- export function registerPermissions(server, sessions) {
11
- server.registerTool('qa_permissions', {
12
- title: 'App permissions',
13
- description: 'Inspect or change a package\'s Android runtime permissions. action: list (granted/denied), grant (pre-approve to skip a dialog — logged), revoke (consent-gated, can break app state — logged). `package` defaults to the session\'s appId; `permission` is a full android.permission.* name (e.g. android.permission.ACCESS_FINE_LOCATION).',
14
- inputSchema: {
15
- sessionId: z.string(),
16
- action: z.enum(['list', 'grant', 'revoke']),
17
- package: z.string().optional().describe('Target package (default: the session appId).'),
18
- permission: z.string().optional().describe('Full permission name, required for grant/revoke.'),
19
- consentId: z.string().optional(),
20
- approve: z.boolean().optional(),
21
- },
22
- }, async ({ sessionId, action, package: pkgArg, permission, consentId, approve }) => {
23
- const session = sessions.get(sessionId);
24
- const { driver } = session ? await getDriver(session) : { driver: undefined };
25
- const serial = driver?.currentDevice();
26
- if (!session || !driver || !serial) {
27
- return qaError({ what: 'No device attached to this session', changedState: false, retrySafe: true, nextSteps: ['Call qa_prepare_target first.'] });
28
- }
29
- const pkg = pkgArg ?? session.appId;
30
- if (!pkg) {
31
- return qaError({ what: 'No package given and the session has no appId', changedState: false, retrySafe: true, nextSteps: ['Pass package, or qa_prepare_target to set the appId.'] });
32
- }
33
- if (action === 'list') {
34
- const perms = await listRuntimePermissions(serial, pkg);
35
- return qaOk({ package: pkg, ...perms }, `${pkg}: ${perms.granted.length} granted, ${perms.denied.length} denied\n granted: ${perms.granted.join(', ') || '—'}\n denied: ${perms.denied.join(', ') || '—'}`);
36
- }
37
- if (!permission) {
38
- return qaError({ what: `${action} requires a permission name`, changedState: false, retrySafe: true, nextSteps: ['Pass permission="android.permission.…" (qa_permissions list to see them).'] });
39
- }
40
- if (action === 'revoke') {
41
- // Revoking can crash/break the app — gate behind consent.
42
- const gate = consumeConsent(consentId, approve, { action: 'permission_revoke', affects: { package: pkg, permission } });
43
- if (!gate.approved) {
44
- sessions.recordMutation(session, {
45
- tool: 'qa_permissions',
46
- action: 'permission_revoke',
47
- risk: 'medium',
48
- target: { package: pkg, permission },
49
- consent: { required: true, approved: false },
50
- status: 'requested',
51
- });
52
- return requireConsent({
53
- action: 'permission_revoke',
54
- risk: 'medium',
55
- exactCommand: `adb -s ${serial} shell pm revoke ${pkg} ${permission}`,
56
- affects: { package: pkg, permission },
57
- explain: `Revoke ${permission} from ${pkg}? This can change app behavior or crash a poorly-guarded app.`,
58
- });
59
- }
60
- sessions.recordMutation(session, {
61
- tool: 'qa_permissions',
62
- action: 'permission_revoke',
63
- risk: 'medium',
64
- target: { package: pkg, permission },
65
- consent: { required: true, consentId, approved: true },
66
- status: 'approved',
67
- });
68
- try {
69
- await revokePermission(serial, pkg, permission);
70
- }
71
- catch (e) {
72
- sessions.recordMutation(session, {
73
- tool: 'qa_permissions',
74
- action: 'permission_revoke',
75
- risk: 'medium',
76
- target: { package: pkg, permission },
77
- consent: { required: true, consentId, approved: true },
78
- status: 'blocked',
79
- detail: String(e),
80
- });
81
- return qaError({ what: `revoke failed: ${String(e)}`, changedState: false, retrySafe: true, nextSteps: ['Check the permission name; some are not revocable.'] });
82
- }
83
- sessions.addEnvChange(session, `permission revoke ${permission} from ${pkg}`);
84
- sessions.recordMutation(session, {
85
- tool: 'qa_permissions',
86
- action: 'permission_revoke',
87
- risk: 'medium',
88
- target: { package: pkg, permission },
89
- consent: { required: true, consentId, approved: true },
90
- status: 'executed',
91
- });
92
- return qaOk({ package: pkg, permission, action }, `revoked ${permission} from ${pkg}`);
93
- }
94
- // grant — low risk, but still a state mutation (it can hide a permission-dialog bug), so
95
- // it is consent-gated (low) and always reported, never silent.
96
- const grantGate = consumeConsent(consentId, approve, { action: 'permission_grant', affects: { package: pkg, permission } });
97
- if (!grantGate.approved) {
98
- sessions.recordMutation(session, {
99
- tool: 'qa_permissions',
100
- action: 'permission_grant',
101
- risk: 'low',
102
- target: { package: pkg, permission },
103
- consent: { required: true, approved: false },
104
- status: 'requested',
105
- });
106
- return requireConsent({
107
- action: 'permission_grant',
108
- risk: 'low',
109
- exactCommand: `adb -s ${serial} shell pm grant ${pkg} ${permission}`,
110
- affects: { package: pkg, permission },
111
- explain: `Pre-grant ${permission} to ${pkg}? This skips the runtime permission dialog — convenient, but it can mask a permission-prompt bug.`,
112
- });
113
- }
114
- sessions.recordMutation(session, {
115
- tool: 'qa_permissions',
116
- action: 'permission_grant',
117
- risk: 'low',
118
- target: { package: pkg, permission },
119
- consent: { required: true, consentId, approved: true },
120
- status: 'approved',
121
- });
122
- try {
123
- await grantPermission(serial, pkg, permission);
124
- }
125
- catch (e) {
126
- sessions.recordMutation(session, {
127
- tool: 'qa_permissions',
128
- action: 'permission_grant',
129
- risk: 'low',
130
- target: { package: pkg, permission },
131
- consent: { required: true, consentId, approved: true },
132
- status: 'blocked',
133
- detail: String(e),
134
- });
135
- return qaError({ what: `grant failed: ${String(e)}`, changedState: false, retrySafe: true, nextSteps: ['Check the permission name; only runtime permissions are grantable.'] });
136
- }
137
- sessions.addEnvChange(session, `permission grant ${permission} to ${pkg}`);
138
- sessions.recordMutation(session, {
139
- tool: 'qa_permissions',
140
- action: 'permission_grant',
141
- risk: 'low',
142
- target: { package: pkg, permission },
143
- consent: { required: true, consentId, approved: true },
144
- status: 'executed',
145
- });
146
- return qaOk({ package: pkg, permission, action }, `granted ${permission} to ${pkg}`);
147
- });
148
- }
149
- //# sourceMappingURL=permissions.js.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"permissions.js","sourceRoot":"","sources":["../../src/tools/permissions.ts"],"names":[],"mappings":"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"}
@@ -1,49 +0,0 @@
1
- // qa_plan (PHASE3-PLAN §3.2) — propose a safe test plan instead of making the agent guess.
2
- // Synthesizes detectContext() + the session's declared fixtures / observed auth / prepared
3
- // appId into READY / BLOCKED / UNSAFE workflows. Pure planning logic lives in src/plan/plan.ts.
4
- import { z } from 'zod';
5
- import { qaOk, qaError } from '../lib/result.js';
6
- import { detectContext } from '../context/detect.js';
7
- import { buildPlan } from '../plan/plan.js';
8
- import { listFlowFiles } from '../flows/discover.js';
9
- export function registerPlan(server, sessions) {
10
- server.registerTool('qa_plan', {
11
- title: 'Plan what to test',
12
- description: 'Propose a safe test plan for the current session instead of guessing. Returns READY workflows (with budget profile + satisfied preconditions), BLOCKED workflows (with a category — missing_device/missing_artifact/missing_test_data/missing_toolchain — required state, and how to unblock), and UNSAFE workflows (with a reason, e.g. bundle_cache_loss for fresh_start on a debug RN/Expo build). Call this first to decide what to run. Reads detected context + declared fixtures + observed auth; does not touch the device.',
13
- inputSchema: {
14
- sessionId: z.string().describe('A session from qa_start_session (its fixtures/auth/root inform the plan).'),
15
- },
16
- }, async ({ sessionId }) => {
17
- const session = sessions.get(sessionId);
18
- if (!session) {
19
- return qaError({
20
- what: 'No such session',
21
- changedState: false,
22
- retrySafe: true,
23
- nextSteps: ['Call qa_start_session first, then qa_plan with its sessionId.'],
24
- });
25
- }
26
- const ctx = await detectContext(session.root);
27
- const plan = buildPlan({
28
- framework: ctx.framework,
29
- hasDevice: ctx.devices.androidOnline.length > 0 || ctx.devices.avds.length > 0,
30
- hasApk: ctx.artifacts.apks.length > 0 || ctx.artifacts.ipas.length > 0 || ctx.artifacts.appBundles.length > 0,
31
- appPrepared: !!session.appId,
32
- fixtures: session.fixtures,
33
- auth: session.auth,
34
- blockers: ctx.blockers,
35
- flows: listFlowFiles(session.root).map((f) => f.name),
36
- });
37
- const line = (s) => ` - ${s}`;
38
- const summary = `Plan for session ${session.id} (framework=${ctx.framework})\n` +
39
- `READY (${plan.ready.length}):\n` +
40
- (plan.ready.map((w) => line(`${w.workflow} [${w.budgetProfile}]${w.requires.length ? ` needs ${w.requires.join(', ')}` : ''}`)).join('\n') || ' (none)') +
41
- `\nBLOCKED (${plan.blocked.length}):\n` +
42
- (plan.blocked.map((w) => line(`${w.workflow}: ${w.category} — ${w.requiredState} → ${w.recommendedSetup}`)).join('\n') || ' (none)') +
43
- `\nUNSAFE (${plan.unsafe.length}):\n` +
44
- (plan.unsafe.map((w) => line(`${w.workflow}: ${w.reason} — ${w.detail}`)).join('\n') || ' (none)') +
45
- (plan.notes.length ? `\nnotes:\n` + plan.notes.map(line).join('\n') : '');
46
- return qaOk({ ...plan, framework: ctx.framework }, summary);
47
- });
48
- }
49
- //# sourceMappingURL=plan.js.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"plan.js","sourceRoot":"","sources":["../../src/tools/plan.ts"],"names":[],"mappings":"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"}
@@ -1,70 +0,0 @@
1
- // qa_screen_info — device + screen metadata for coordinate-driven (visual-fallback) work,
2
- // so the agent doesn't shell out to `adb shell wm size/density` or measure screenshots.
3
- import { z } from 'zod';
4
- import { qaOk, qaError } from '../lib/result.js';
5
- import { getOrientation } from '../lib/device.js';
6
- import { getDriver } from '../session/attach.js';
7
- export function registerScreenInfo(server, sessions) {
8
- server.registerTool('qa_screen_info', {
9
- title: 'Screen info',
10
- description: 'Device + screen metadata for coordinate work: width/height (px), density (dpi), session mode (structured | visual-fallback), the latest screenshot URI, and budget counters. Use this in visual-fallback mode to place coordinate taps instead of shelling out to wm size/density.',
11
- inputSchema: { sessionId: z.string() },
12
- }, async ({ sessionId }) => {
13
- const session = sessions.get(sessionId);
14
- const { driver } = session ? await getDriver(session) : { driver: undefined };
15
- if (!session || !driver) {
16
- return qaError({
17
- what: 'No device attached to this session',
18
- changedState: false,
19
- retrySafe: true,
20
- nextSteps: ['Call qa_prepare_target first.'],
21
- });
22
- }
23
- const serial = driver.currentDevice();
24
- const [size, density, orient] = await Promise.all([driver.screenSize(), driver.screenDensity(), serial ? getOrientation(serial).catch(() => null) : Promise.resolve(null)]);
25
- const orientation = orient ? (orient.rotation === 1 || orient.rotation === 3 ? 'landscape' : 'portrait') : 'unknown';
26
- const lastShot = [...session.artifacts].reverse().find((a) => a.kind === 'screenshot');
27
- // Coordinate landmarks (P1.7) for visual-fallback taps — so the agent places taps from
28
- // named anchors instead of guessing pixels off a screenshot.
29
- let landmarks;
30
- let bands;
31
- if (size) {
32
- const w = size.width;
33
- const h = size.height;
34
- const X = (fx) => Math.round(w * fx);
35
- const Y = (fy) => Math.round(h * fy);
36
- landmarks = {
37
- topNavCenter: [X(0.5), Y(0.06)],
38
- bottomNavCenter: [X(0.5), Y(0.96)],
39
- center: [X(0.5), Y(0.5)],
40
- topLeft: [X(0.08), Y(0.06)],
41
- topRight: [X(0.92), Y(0.06)],
42
- bottomLeft: [X(0.08), Y(0.96)],
43
- bottomRight: [X(0.92), Y(0.96)],
44
- primaryCtaArea: [X(0.5), Y(0.88)], // most apps put the main CTA in the bottom band
45
- };
46
- bands = {
47
- topNav: { yFrom: 0, yTo: Y(0.12) },
48
- content: { yFrom: Y(0.12), yTo: Y(0.85) },
49
- bottomNav: { yFrom: Y(0.9), yTo: h },
50
- ctaBand: { yFrom: Y(0.78), yTo: Y(0.95) },
51
- };
52
- }
53
- return qaOk({
54
- device: session.device ?? null,
55
- screen: size ? { width: size.width, height: size.height, density } : null,
56
- orientation,
57
- coordinateNote: 'landmarks/bands are DEVICE pixels (origin top-left) — pass directly as qa_act {x,y}. For screenshot-space hits (qa_visual find_image) convert with coordinateSpace.scale.',
58
- mode: session.mode,
59
- headless: session.headless ?? null,
60
- latestScreenshot: lastShot?.uri ?? null,
61
- landmarks,
62
- bands,
63
- counters: session.counters,
64
- budget: session.budget,
65
- }, `device=${session.device} screen=${size ? `${size.width}x${size.height}@${density ?? '?'}dpi` : 'unknown'} mode=${session.mode}` +
66
- (landmarks ? `\nlandmarks: center=${landmarks.center} bottomNav=${landmarks.bottomNavCenter} cta=${landmarks.primaryCtaArea}` : '') +
67
- (lastShot ? `\nlatest screenshot: ${lastShot.uri}` : '\n(no screenshot yet — call qa_screenshot)'));
68
- });
69
- }
70
- //# sourceMappingURL=screenInfo.js.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"screenInfo.js","sourceRoot":"","sources":["../../src/tools/screenInfo.ts"],"names":[],"mappings":"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"}
@@ -1,101 +0,0 @@
1
- // qa_seed (PHASE3-PLAN §4.4 / roadmap §9) — turn a declared precondition into one Swipium can
2
- // actually create, OPT-IN and consent-gated. A fixture may carry a `seed` spec: a deep link, a
3
- // project-root script, or an API call. Every seed is a mutation → explicit consent, exact action
4
- // shown. The raw execution lives in src/flows/seedExec.ts (shared with the flow `seed` step). If
5
- // seeding fails it is reported as a SETUP failure (environment bucket), never an app bug.
6
- import { z } from 'zod';
7
- import { qaOk, qaError } from '../lib/result.js';
8
- import { qaFail } from '../oracle/failures.js';
9
- import { requireConsent, consumeConsent } from '../consent/consent.js';
10
- import { executeSeed, seedExactCommand, seedGitScopeViolation } from '../flows/seedExec.js';
11
- import { getDriver } from '../session/attach.js';
12
- export function registerSeed(server, sessions) {
13
- server.registerTool('qa_seed', {
14
- title: 'Seed a precondition',
15
- description: 'Create a declared precondition (opt-in, consent-gated) so a blocked workflow can run. The named fixture must declare a `seed`: deeplink (open a setup deep link), script (argv array run under the project root), or api (HTTP call). Every seed is a mutation and requires consent showing the exact action. If seeding fails it is reported as a SETUP failure, not an app bug.',
16
- inputSchema: {
17
- sessionId: z.string(),
18
- fixture: z.string().describe('Name of a declared fixture that has a `seed` spec.'),
19
- consentId: z.string().optional(),
20
- approve: z.boolean().optional(),
21
- },
22
- }, async ({ sessionId, fixture: fixtureName, consentId, approve }) => {
23
- const session = sessions.get(sessionId);
24
- if (!session) {
25
- return qaError({ what: `Unknown sessionId ${sessionId}`, changedState: false, retrySafe: true, nextSteps: ['Call qa_start_session first.'] });
26
- }
27
- const fixture = session.fixtures.find((f) => f.name === fixtureName);
28
- if (!fixture) {
29
- return qaError({ what: `No declared fixture "${fixtureName}"`, changedState: false, retrySafe: true, nextSteps: ['Declare it in .swipium/fixtures.json or qa_start_session { fixtures }.'] });
30
- }
31
- const seed = fixture.seed;
32
- if (!seed) {
33
- return qaError({ what: `Fixture "${fixtureName}" has no seed spec`, changedState: false, retrySafe: true, nextSteps: ['Add a seed: { type: "deeplink"|"script"|"api", … } to the fixture to make it creatable.'] });
34
- }
35
- const git = seedGitScopeViolation(seed);
36
- if (git) {
37
- return qaFail('GIT_SCOPE_FORBIDDEN', {
38
- what: `Fixture "${fixtureName}" seed command is refused because Git is outside Swipium's QA scope: ${git}`,
39
- changedState: false,
40
- extra: { fixture: fixtureName, command: git },
41
- });
42
- }
43
- // Consent — exact action shown, scoped to this fixture + seed type.
44
- const affects = { fixture: fixtureName, type: seed.type };
45
- const risk = seed.type === 'script' ? 'high' : seed.type === 'api' ? 'medium' : 'low';
46
- const gate = consumeConsent(consentId, approve, { action: 'seed_state', affects });
47
- if (!gate.approved) {
48
- sessions.recordMutation(session, {
49
- tool: 'qa_seed',
50
- action: 'seed_state',
51
- risk,
52
- target: affects,
53
- consent: { required: true, approved: false },
54
- status: 'requested',
55
- });
56
- return requireConsent({
57
- action: 'seed_state',
58
- risk,
59
- exactCommand: seedExactCommand(seed),
60
- affects,
61
- explain: `Seed precondition "${fixtureName}" via ${seed.type}? This mutates state${seed.type === 'script' ? ' by running a command under the project root' : seed.type === 'api' ? ' by calling an external API' : ' by opening a deep link'}.`,
62
- });
63
- }
64
- sessions.recordMutation(session, {
65
- tool: 'qa_seed',
66
- action: 'seed_state',
67
- risk,
68
- target: affects,
69
- consent: { required: true, consentId, approved: true },
70
- status: 'approved',
71
- });
72
- const { driver } = await getDriver(session);
73
- const result = await executeSeed(sessions, session, driver, fixtureName, seed);
74
- if (!result.ok) {
75
- // Record as a SETUP failure (not an app bug) so the report can't mislabel it.
76
- sessions.addNote(session, { at: Date.now(), workflow: `seed:${fixtureName}`, outcome: 'blocked', category: 'missing_test_data', reason: `seed failed: ${result.detail}`, requiredState: fixture.requiredState, recommendedSetup: fixture.recommendedSetup });
77
- sessions.recordMutation(session, {
78
- tool: 'qa_seed',
79
- action: 'seed_state',
80
- risk,
81
- target: affects,
82
- consent: { required: true, consentId, approved: true },
83
- status: 'blocked',
84
- detail: result.detail,
85
- });
86
- return qaFail('SEED_FAILED', { what: `Seeding "${fixtureName}" failed: ${result.detail}`, changedState: true, extra: { fixture: fixtureName, type: seed.type } });
87
- }
88
- sessions.addNote(session, { at: Date.now(), workflow: `seed:${fixtureName}`, outcome: 'pass', reason: `precondition created via ${seed.type}` });
89
- sessions.recordMutation(session, {
90
- tool: 'qa_seed',
91
- action: 'seed_state',
92
- risk,
93
- target: affects,
94
- consent: { required: true, consentId, approved: true },
95
- status: 'executed',
96
- detail: result.warnings.join(' ') || undefined,
97
- });
98
- return qaOk({ fixture: fixtureName, type: seed.type, seeded: true, warnings: result.warnings }, `✅ seeded "${fixtureName}" via ${seed.type} — the precondition should now be met. Re-run the workflow.${result.warnings.length ? `\n⚠ ${result.warnings.join(' ')}` : ''}`);
99
- });
100
- }
101
- //# sourceMappingURL=seed.js.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"seed.js","sourceRoot":"","sources":["../../src/tools/seed.ts"],"names":[],"mappings":"AAAA,8FAA8F;AAC9F,+FAA+F;AAC/F,iGAAiG;AACjG,iGAAiG;AACjG,0FAA0F;AAE1F,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AAExB,OAAO,EAAE,IAAI,EAAE,OAAO,EAAE,MAAM,kBAAkB,CAAC;AACjD,OAAO,EAAE,MAAM,EAAE,MAAM,uBAAuB,CAAC;AAC/C,OAAO,EAAE,cAAc,EAAE,cAAc,EAAE,MAAM,uBAAuB,CAAC;AACvE,OAAO,EAAE,WAAW,EAAE,gBAAgB,EAAE,qBAAqB,EAAE,MAAM,sBAAsB,CAAC;AAC5F,OAAO,EAAE,SAAS,EAAE,MAAM,sBAAsB,CAAC;AAGjD,MAAM,UAAU,YAAY,CAAC,MAAiB,EAAE,QAAsB;IACpE,MAAM,CAAC,YAAY,CACjB,SAAS,EACT;QACE,KAAK,EAAE,qBAAqB;QAC5B,WAAW,EACT,mXAAmX;QACrX,WAAW,EAAE;YACX,SAAS,EAAE,CAAC,CAAC,MAAM,EAAE;YACrB,OAAO,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,QAAQ,CAAC,oDAAoD,CAAC;YAClF,SAAS,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,QAAQ,EAAE;YAChC,OAAO,EAAE,CAAC,CAAC,OAAO,EAAE,CAAC,QAAQ,EAAE;SAChC;KACF,EACD,KAAK,EAAE,EAAE,SAAS,EAAE,OAAO,EAAE,WAAW,EAAE,SAAS,EAAE,OAAO,EAAE,EAAE,EAAE;QAChE,MAAM,OAAO,GAAG,QAAQ,CAAC,GAAG,CAAC,SAAS,CAAC,CAAC;QACxC,IAAI,CAAC,OAAO,EAAE,CAAC;YACb,OAAO,OAAO,CAAC,EAAE,IAAI,EAAE,qBAAqB,SAAS,EAAE,EAAE,YAAY,EAAE,KAAK,EAAE,SAAS,EAAE,IAAI,EAAE,SAAS,EAAE,CAAC,8BAA8B,CAAC,EAAE,CAAC,CAAC;QAChJ,CAAC;QACD,MAAM,OAAO,GAAG,OAAO,CAAC,QAAQ,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,IAAI,KAAK,WAAW,CAAC,CAAC;QACrE,IAAI,CAAC,OAAO,EAAE,CAAC;YACb,OAAO,OAAO,CAAC,EAAE,IAAI,EAAE,wBAAwB,WAAW,GAAG,EAAE,YAAY,EAAE,KAAK,EAAE,SAAS,EAAE,IAAI,EAAE,SAAS,EAAE,CAAC,wEAAwE,CAAC,EAAE,CAAC,CAAC;QAChM,CAAC;QACD,MAAM,IAAI,GAAG,OAAO,CAAC,IAAI,CAAC;QAC1B,IAAI,CAAC,IAAI,EAAE,CAAC;YACV,OAAO,OAAO,CAAC,EAAE,IAAI,EAAE,YAAY,WAAW,oBAAoB,EAAE,YAAY,EAAE,KAAK,EAAE,SAAS,EAAE,IAAI,EAAE,SAAS,EAAE,CAAC,yFAAyF,CAAC,EAAE,CAAC,CAAC;QACtN,CAAC;QACD,MAAM,GAAG,GAAG,qBAAqB,CAAC,IAAI,CAAC,CAAC;QACxC,IAAI,GAAG,EAAE,CAAC;YACR,OAAO,MAAM,CAAC,qBAAqB,EAAE;gBACnC,IAAI,EAAE,YAAY,WAAW,wEAAwE,GAAG,EAAE;gBAC1G,YAAY,EAAE,KAAK;gBACnB,KAAK,EAAE,EAAE,OAAO,EAAE,WAAW,EAAE,OAAO,EAAE,GAAG,EAAE;aAC9C,CAAC,CAAC;QACL,CAAC;QAED,oEAAoE;QACpE,MAAM,OAAO,GAAG,EAAE,OAAO,EAAE,WAAW,EAAE,IAAI,EAAE,IAAI,CAAC,IAAI,EAAE,CAAC;QAC1D,MAAM,IAAI,GAAG,IAAI,CAAC,IAAI,KAAK,QAAQ,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,IAAI,CAAC,IAAI,KAAK,KAAK,CAAC,CAAC,CAAC,QAAQ,CAAC,CAAC,CAAC,KAAK,CAAC;QACtF,MAAM,IAAI,GAAG,cAAc,CAAC,SAAS,EAAE,OAAO,EAAE,EAAE,MAAM,EAAE,YAAY,EAAE,OAAO,EAAE,CAAC,CAAC;QACnF,IAAI,CAAC,IAAI,CAAC,QAAQ,EAAE,CAAC;YACnB,QAAQ,CAAC,cAAc,CAAC,OAAO,EAAE;gBAC/B,IAAI,EAAE,SAAS;gBACf,MAAM,EAAE,YAAY;gBACpB,IAAI;gBACJ,MAAM,EAAE,OAAO;gBACf,OAAO,EAAE,EAAE,QAAQ,EAAE,IAAI,EAAE,QAAQ,EAAE,KAAK,EAAE;gBAC5C,MAAM,EAAE,WAAW;aACpB,CAAC,CAAC;YACH,OAAO,cAAc,CAAC;gBACpB,MAAM,EAAE,YAAY;gBACpB,IAAI;gBACJ,YAAY,EAAE,gBAAgB,CAAC,IAAI,CAAC;gBACpC,OAAO;gBACP,OAAO,EAAE,sBAAsB,WAAW,SAAS,IAAI,CAAC,IAAI,uBAAuB,IAAI,CAAC,IAAI,KAAK,QAAQ,CAAC,CAAC,CAAC,8CAA8C,CAAC,CAAC,CAAC,IAAI,CAAC,IAAI,KAAK,KAAK,CAAC,CAAC,CAAC,6BAA6B,CAAC,CAAC,CAAC,yBAAyB,GAAG;aAChP,CAAC,CAAC;QACL,CAAC;QACD,QAAQ,CAAC,cAAc,CAAC,OAAO,EAAE;YAC/B,IAAI,EAAE,SAAS;YACf,MAAM,EAAE,YAAY;YACpB,IAAI;YACJ,MAAM,EAAE,OAAO;YACf,OAAO,EAAE,EAAE,QAAQ,EAAE,IAAI,EAAE,SAAS,EAAE,QAAQ,EAAE,IAAI,EAAE;YACtD,MAAM,EAAE,UAAU;SACnB,CAAC,CAAC;QAEH,MAAM,EAAE,MAAM,EAAE,GAAG,MAAM,SAAS,CAAC,OAAO,CAAC,CAAC;QAC5C,MAAM,MAAM,GAAG,MAAM,WAAW,CAAC,QAAQ,EAAE,OAAO,EAAE,MAAM,EAAE,WAAW,EAAE,IAAI,CAAC,CAAC;QAC/E,IAAI,CAAC,MAAM,CAAC,EAAE,EAAE,CAAC;YACf,8EAA8E;YAC9E,QAAQ,CAAC,OAAO,CAAC,OAAO,EAAE,EAAE,EAAE,EAAE,IAAI,CAAC,GAAG,EAAE,EAAE,QAAQ,EAAE,QAAQ,WAAW,EAAE,EAAE,OAAO,EAAE,SAAS,EAAE,QAAQ,EAAE,mBAAmB,EAAE,MAAM,EAAE,gBAAgB,MAAM,CAAC,MAAM,EAAE,EAAE,aAAa,EAAE,OAAO,CAAC,aAAa,EAAE,gBAAgB,EAAE,OAAO,CAAC,gBAAgB,EAAE,CAAC,CAAC;YAC7P,QAAQ,CAAC,cAAc,CAAC,OAAO,EAAE;gBAC/B,IAAI,EAAE,SAAS;gBACf,MAAM,EAAE,YAAY;gBACpB,IAAI;gBACJ,MAAM,EAAE,OAAO;gBACf,OAAO,EAAE,EAAE,QAAQ,EAAE,IAAI,EAAE,SAAS,EAAE,QAAQ,EAAE,IAAI,EAAE;gBACtD,MAAM,EAAE,SAAS;gBACjB,MAAM,EAAE,MAAM,CAAC,MAAM;aACtB,CAAC,CAAC;YACH,OAAO,MAAM,CAAC,aAAa,EAAE,EAAE,IAAI,EAAE,YAAY,WAAW,aAAa,MAAM,CAAC,MAAM,EAAE,EAAE,YAAY,EAAE,IAAI,EAAE,KAAK,EAAE,EAAE,OAAO,EAAE,WAAW,EAAE,IAAI,EAAE,IAAI,CAAC,IAAI,EAAE,EAAE,CAAC,CAAC;QACpK,CAAC;QACD,QAAQ,CAAC,OAAO,CAAC,OAAO,EAAE,EAAE,EAAE,EAAE,IAAI,CAAC,GAAG,EAAE,EAAE,QAAQ,EAAE,QAAQ,WAAW,EAAE,EAAE,OAAO,EAAE,MAAM,EAAE,MAAM,EAAE,4BAA4B,IAAI,CAAC,IAAI,EAAE,EAAE,CAAC,CAAC;QACjJ,QAAQ,CAAC,cAAc,CAAC,OAAO,EAAE;YAC/B,IAAI,EAAE,SAAS;YACf,MAAM,EAAE,YAAY;YACpB,IAAI;YACJ,MAAM,EAAE,OAAO;YACf,OAAO,EAAE,EAAE,QAAQ,EAAE,IAAI,EAAE,SAAS,EAAE,QAAQ,EAAE,IAAI,EAAE;YACtD,MAAM,EAAE,UAAU;YAClB,MAAM,EAAE,MAAM,CAAC,QAAQ,CAAC,IAAI,CAAC,GAAG,CAAC,IAAI,SAAS;SAC/C,CAAC,CAAC;QACH,OAAO,IAAI,CACT,EAAE,OAAO,EAAE,WAAW,EAAE,IAAI,EAAE,IAAI,CAAC,IAAI,EAAE,MAAM,EAAE,IAAI,EAAE,QAAQ,EAAE,MAAM,CAAC,QAAQ,EAAE,EAClF,aAAa,WAAW,SAAS,IAAI,CAAC,IAAI,8DAA8D,MAAM,CAAC,QAAQ,CAAC,MAAM,CAAC,CAAC,CAAC,OAAO,MAAM,CAAC,QAAQ,CAAC,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,EAAE,CAC3K,CAAC;IACJ,CAAC,CACF,CAAC;AACJ,CAAC"}