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,4 +1,4 @@
1
- // SWIPIUM Issue Log — report integration bridge (SWIPIUM-REQ-07 "Integration Points → Reports").
1
+ // SWIPIUM Issue Log: report integration bridge.
2
2
  //
3
3
  // Converts a finished run's health findings + structured test outcomes into normalized issue
4
4
  // observations, records them in the durable ledger (so recurrence works across runs), and returns
@@ -10,7 +10,7 @@
10
10
  import { recordObservation } from './index.js';
11
11
  import { getIndex } from './store.js';
12
12
  import { buildReportIssuesSection } from './report.js';
13
- import { isIssueCategory } from './schema.js';
13
+ import { isIssueCategory, } from './schema.js';
14
14
  const BILLING_HINTS = [
15
15
  ['revenuecat', /revenuecat/i],
16
16
  ['storekit', /storekit/i],
@@ -47,7 +47,7 @@ function inferScreenPurpose(n) {
47
47
  function noteToObservation(n) {
48
48
  const subsystem = detectSubsystem(`${n.workflow} ${n.reason ?? ''}`);
49
49
  return {
50
- title: `${n.workflow} → ${n.outcome}`,
50
+ title: `${n.workflow} > ${n.outcome}`,
51
51
  summary: n.reason ? n.reason.slice(0, 200) : `${n.workflow} ${n.outcome}`,
52
52
  failureCode: n.failureCode,
53
53
  workflow: n.workflow,
@@ -56,7 +56,7 @@ function noteToObservation(n) {
56
56
  subsystem,
57
57
  };
58
58
  }
59
- // A blocked/failed note in any of these categories is a real REQ-07 issue-ledger entry (not just
59
+ // A blocked/failed note in any of these categories is a real issue-ledger entry (not just
60
60
  // app bugs): hard gates, store-compliance/privacy gaps, readiness improvements, missing data, etc.
61
61
  // Intentional skips and not-applicable / passing outcomes are NOT recorded.
62
62
  const RECORDED_NOTE_CATEGORIES = new Set([
@@ -77,7 +77,7 @@ function shouldRecordNote(n) {
77
77
  if (n.category === 'intentionally_skipped')
78
78
  return false;
79
79
  // Record when it carries a recognized category, a failure code, or is an uncategorized failure
80
- // (an uncategorized fail/blocked is still worth remembering — the classifier triages it).
80
+ // (an uncategorized fail/blocked is still worth remembering; the classifier triages it).
81
81
  return !n.category || RECORDED_NOTE_CATEGORIES.has(n.category) || Boolean(n.failureCode);
82
82
  }
83
83
  /**
@@ -94,9 +94,24 @@ verifiedFixedIssueIds) {
94
94
  for (const f of findings) {
95
95
  if (f.severity === 'info')
96
96
  continue; // info findings are not issues
97
- const res = recordObservation(root, findingToObservation(f), now, { environment: meta.environment }, { appId: meta.appId, appName: meta.appName, platform: meta.platform, environment: meta.environment, sourceRevision: meta.sourceRevision, run });
97
+ const res = recordObservation(root, findingToObservation(f), now, { environment: meta.environment }, {
98
+ appId: meta.appId,
99
+ appName: meta.appName,
100
+ platform: meta.platform,
101
+ environment: meta.environment,
102
+ sourceRevision: meta.sourceRevision,
103
+ run,
104
+ });
98
105
  recordedIssueIds.push(res.issueId);
99
- recorded.push({ issueId: res.issueId, fingerprint: res.fingerprint, source: 'finding', category: res.record.category, severity: res.record.severity, state: res.record.state, reopened: res.reopened });
106
+ recorded.push({
107
+ issueId: res.issueId,
108
+ fingerprint: res.fingerprint,
109
+ source: 'finding',
110
+ category: res.record.category,
111
+ severity: res.record.severity,
112
+ state: res.record.state,
113
+ reopened: res.reopened,
114
+ });
100
115
  if (res.recurrenceMessage)
101
116
  recurrences.push(res.recurrenceMessage);
102
117
  }
@@ -106,9 +121,25 @@ verifiedFixedIssueIds) {
106
121
  // Trust an explicit, valid issue-category note as a classifier fallback (the text rules still
107
122
  // win when they detect a stronger signal, e.g. an actual RedBox mentioned in the reason).
108
123
  const categoryHint = n.category && isIssueCategory(n.category) ? n.category : undefined;
109
- const res = recordObservation(root, noteToObservation(n), now, { environment: meta.environment, categoryHint }, { appId: meta.appId, appName: meta.appName, platform: meta.platform, environment: meta.environment, sourceRevision: meta.sourceRevision, run: { ...run, testCaseId: n.workflow } });
124
+ const res = recordObservation(root, noteToObservation(n), now, { environment: meta.environment, categoryHint }, {
125
+ appId: meta.appId,
126
+ appName: meta.appName,
127
+ platform: meta.platform,
128
+ environment: meta.environment,
129
+ sourceRevision: meta.sourceRevision,
130
+ run: { ...run, testCaseId: n.workflow },
131
+ });
110
132
  recordedIssueIds.push(res.issueId);
111
- recorded.push({ issueId: res.issueId, fingerprint: res.fingerprint, source: 'note', workflow: n.workflow, category: res.record.category, severity: res.record.severity, state: res.record.state, reopened: res.reopened });
133
+ recorded.push({
134
+ issueId: res.issueId,
135
+ fingerprint: res.fingerprint,
136
+ source: 'note',
137
+ workflow: n.workflow,
138
+ category: res.record.category,
139
+ severity: res.record.severity,
140
+ state: res.record.state,
141
+ reopened: res.reopened,
142
+ });
112
143
  if (res.recurrenceMessage)
113
144
  recurrences.push(res.recurrenceMessage);
114
145
  }
@@ -1 +1 @@
1
- {"version":3,"file":"reportBridge.js","sourceRoot":"","sources":["../../src/issues/reportBridge.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"reportBridge.js","sourceRoot":"","sources":["../../src/issues/reportBridge.ts"],"names":[],"mappings":"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"}
@@ -1,9 +1,9 @@
1
- // SWIPIUM Issue Log / Error Tracking (SWIPIUM-REQ-07). Type definitions, enums, and validation
1
+ // SWIPIUM Issue Log / Error Tracking. Type definitions, enums, and validation
2
2
  // helpers for the durable, project-level issue ledger.
3
3
  //
4
4
  // The ledger is Swipium's mobile-QA memory: an append-only event log (`.swipium/issues-log.jsonl`)
5
5
  // plus a derived index (`.swipium/issues/index.json`). Events are compact and never hold full
6
- // screenshots / logs / stack traces / report JSON — only references to artifacts (Developer Notes).
6
+ // screenshots / logs / stack traces / report JSON. Only references to artifacts (Developer Notes).
7
7
  // Every lifecycle mutation is append-only so a developer can audit WHY an issue is currently
8
8
  // considered fixed / reopened / suppressed.
9
9
  //
@@ -1 +1 @@
1
- {"version":3,"file":"schema.js","sourceRoot":"","sources":["../../src/issues/schema.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"schema.js","sourceRoot":"","sources":["../../src/issues/schema.ts"],"names":[],"mappings":"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"}
@@ -1,8 +1,8 @@
1
- // SWIPIUM Issue Log — source revision resolution (SWIPIUM-REQ-07 "Source revision").
1
+ // SWIPIUM Issue Log: source revision resolution.
2
2
  //
3
3
  // Fix attribution is strongest when issues link to a commit/release. But Swipium intentionally does
4
4
  // NOT execute Git in spawned providers. So we resolve a SourceRevision in priority order WITHOUT
5
- // running Git: explicit input → CI environment variables → app build metadata → optional read-only
5
+ // running Git: explicit input > CI environment variables > app build metadata > optional read-only
6
6
  // `.git/HEAD` (only when policy sets allowGitMetadataRead). `unknown` is always an acceptable result.
7
7
  //
8
8
  // PURE w.r.t. process state except the optional read-only git read, which only touches `.git/HEAD`
@@ -1 +1 @@
1
- {"version":3,"file":"sourceRevision.js","sourceRoot":"","sources":["../../src/issues/sourceRevision.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"sourceRevision.js","sourceRoot":"","sources":["../../src/issues/sourceRevision.ts"],"names":[],"mappings":"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"}
@@ -1,18 +1,24 @@
1
- // SWIPIUM Issue Log — persistence (SWIPIUM-REQ-07 "New storage").
1
+ // SWIPIUM Issue Log: persistence.
2
2
  //
3
- // `.swipium/issues-log.jsonl` — canonical, append-only event ledger. NEVER pruned by default.
4
- // `.swipium/issues/index.json` — derived cache, rebuildable from the log if deleted/corrupt.
5
- // `.swipium/issues/policy.json` — classifier + retention + source-revision policy.
6
- // `.swipium/issues/artifacts/` — large evidence files (may follow normal retention).
3
+ // `.swipium/issues-log.jsonl` : canonical, append-only event ledger. NEVER pruned by default.
4
+ // `.swipium/issues/index.json` : derived cache, rebuildable from the log if deleted/corrupt.
5
+ // `.swipium/issues/policy.json` : classifier + retention + source-revision policy.
6
+ // `.swipium/issues/artifacts/` : large evidence files (may follow normal retention).
7
7
  //
8
8
  // The log is the source of truth: the index is always recomputable via rebuildRecords(). Writes are
9
- // append-only for events and atomic (temp + rename) for the index. Best-effort I/O — corrupt files
10
- // degrade to a rebuild, never throw on read.
11
- import { createHash } from 'node:crypto';
12
- import { appendFileSync, existsSync, mkdirSync, readFileSync, renameSync, writeFileSync } from 'node:fs';
9
+ // append-only for events and atomic (unique temp + rename) for the index. Best-effort I/O: corrupt
10
+ // files degrade to a rebuild, never throw on read.
11
+ //
12
+ // Concurrency: several MCP server instances (and the CI CLI) can share one project. Every
13
+ // read-modify-write of the ledger runs under withLedgerLock(), and the cached index records the
14
+ // log's size/mtime it was derived from. A cache whose stamp no longer matches the log (another
15
+ // process appended) is rebuilt instead of trusted.
16
+ import { randomUUID } from 'node:crypto';
17
+ import { appendFileSync, existsSync, mkdirSync, readdirSync, readFileSync, renameSync, rmSync, statSync, writeFileSync } from 'node:fs';
13
18
  import { join } from 'node:path';
14
19
  import { ensureGitignored } from '../lib/gitignore.js';
15
- import { rebuildRecords } from './recurrence.js';
20
+ import { withFileLock } from '../lib/lockfile.js';
21
+ import { liftSuppression, rebuildRecords, suppressionExpired } from './recurrence.js';
16
22
  import { ISSUE_SCHEMA_VERSION, emptyIndex, validateEvent } from './schema.js';
17
23
  const SWIPIUM = '.swipium';
18
24
  export function issuesLogPath(root) {
@@ -30,18 +36,12 @@ export function issuesPolicyPath(root) {
30
36
  export function issuesArtifactsDir(root) {
31
37
  return join(issuesDir(root), 'artifacts');
32
38
  }
33
- export function issuesProjectId(root) {
34
- return createHash('sha256').update(root).digest('hex').slice(0, 16);
35
- }
36
- export function issuesResourceUri(root) {
37
- return `swipium://project/${issuesProjectId(root)}/issues`;
38
- }
39
39
  export const DEFAULT_POLICY = {
40
40
  schemaVersion: 1,
41
41
  allowGitMetadataRead: false,
42
42
  retention: { keepIssueEvents: 'forever', pruneEvidenceAfterDays: 90 },
43
43
  };
44
- /** Load the policy file, merged over defaults. Best-effort — corrupt file → defaults. */
44
+ /** Load the policy file, merged over defaults. Best-effort: corrupt file > defaults. */
45
45
  export function loadPolicy(root) {
46
46
  try {
47
47
  const path = issuesPolicyPath(root);
@@ -77,7 +77,7 @@ export function readEvents(root) {
77
77
  out.push(ev);
78
78
  }
79
79
  catch {
80
- /* skip a corrupt line — the log stays usable */
80
+ /* skip a corrupt line; the log stays usable */
81
81
  }
82
82
  }
83
83
  return out;
@@ -91,19 +91,85 @@ export function appendEvents(root, events) {
91
91
  const path = issuesLogPath(root);
92
92
  const payload = events.map((e) => JSON.stringify(e)).join('\n') + '\n';
93
93
  appendFileSync(path, payload);
94
+ // Retention (policy.retention.pruneEvidenceAfterDays, default 90): large evidence files under
95
+ // .swipium/issues/artifacts/ older than N days are pruned on ledger write. The append-only event
96
+ // log itself is never pruned here (keepIssueEvents).
97
+ pruneEvidence(root, loadPolicy(root).retention?.pruneEvidenceAfterDays);
94
98
  return { path, count: events.length };
95
99
  }
96
- /** Atomically write the derived index (temp + rename). */
97
- export function saveIndex(root, index) {
100
+ /** Delete evidence files under `.swipium/issues/artifacts/` whose mtime is older than `days`
101
+ * (recursively; emptied sub-dirs removed). `days` ≤ 0 / non-finite = disabled. Best-effort: returns
102
+ * the number of files deleted and never throws. */
103
+ export function pruneEvidence(root, days, now = Date.now()) {
104
+ if (typeof days !== 'number' || !Number.isFinite(days) || days <= 0)
105
+ return 0;
106
+ const cutoff = now - days * 24 * 60 * 60 * 1000;
107
+ let deleted = 0;
108
+ const walk = (dir) => {
109
+ let entries;
110
+ try {
111
+ entries = readdirSync(dir, { withFileTypes: true });
112
+ }
113
+ catch {
114
+ return false;
115
+ }
116
+ let remaining = entries.length;
117
+ for (const e of entries) {
118
+ const p = join(dir, e.name);
119
+ try {
120
+ if (e.isDirectory()) {
121
+ if (walk(p)) {
122
+ rmSync(p, { recursive: true, force: true });
123
+ remaining--;
124
+ }
125
+ }
126
+ else if (statSync(p).mtimeMs < cutoff) {
127
+ rmSync(p, { force: true });
128
+ deleted++;
129
+ remaining--;
130
+ }
131
+ }
132
+ catch {
133
+ /* vanished / unreadable, skip */
134
+ }
135
+ }
136
+ return remaining === 0; // caller may remove an emptied sub-dir
137
+ };
138
+ walk(issuesArtifactsDir(root));
139
+ return deleted;
140
+ }
141
+ /**
142
+ * Run a ledger read-modify-write under the project's cross-process issue lock
143
+ * (`.swipium/issues/.lock`). NOT re-entrant: call it once at the outermost mutation.
144
+ */
145
+ export function withLedgerLock(root, fn) {
146
+ mkdirSync(issuesDir(root), { recursive: true });
147
+ return withFileLock(join(issuesDir(root), '.lock'), fn);
148
+ }
149
+ /** Size + mtime of the canonical log, or null when absent. */
150
+ function logStamp(root) {
151
+ try {
152
+ const st = statSync(issuesLogPath(root));
153
+ return { logSize: st.size, logMtimeMs: st.mtimeMs };
154
+ }
155
+ catch {
156
+ return null;
157
+ }
158
+ }
159
+ /** Atomically write the derived index (unique temp + rename), stamped with the log's size/mtime. */
160
+ export function saveIndex(root, index, stamp = logStamp(root)) {
98
161
  mkdirSync(issuesDir(root), { recursive: true });
99
162
  ensureGitignored(root);
100
163
  const path = issuesIndexPath(root);
101
- const tmp = `${path}.tmp`;
164
+ if (stamp)
165
+ Object.assign(index, stamp);
166
+ // Unique per writer: two processes sharing `index.json.tmp` could rename each other's half-file.
167
+ const tmp = `${path}.${process.pid}.${randomUUID().slice(0, 8)}.tmp`;
102
168
  writeFileSync(tmp, JSON.stringify(index, null, 2));
103
169
  renameSync(tmp, path);
104
- return { path, resourceUri: issuesResourceUri(root) };
170
+ return { path };
105
171
  }
106
- /** Load the index from disk; null when absent/corrupt (caller should rebuild). */
172
+ /** Load the index from disk; null when absent/corrupt/stale versus the log (caller should rebuild). */
107
173
  export function loadIndex(root) {
108
174
  try {
109
175
  const path = issuesIndexPath(root);
@@ -112,6 +178,10 @@ export function loadIndex(root) {
112
178
  const raw = JSON.parse(readFileSync(path, 'utf8'));
113
179
  if (raw.schemaVersion !== ISSUE_SCHEMA_VERSION || !Array.isArray(raw.records))
114
180
  return null;
181
+ // Stale check: another process appended since this cache was written (or it predates stamps).
182
+ const stamp = logStamp(root);
183
+ if (stamp && (raw.logSize !== stamp.logSize || raw.logMtimeMs !== stamp.logMtimeMs))
184
+ return null;
115
185
  return raw;
116
186
  }
117
187
  catch {
@@ -120,22 +190,30 @@ export function loadIndex(root) {
120
190
  }
121
191
  /** Rebuild the index from the canonical log and persist it. The log is always authoritative. */
122
192
  export function rebuildIndex(root, now, appId) {
193
+ // Stamp BEFORE reading: this may run outside the ledger lock (read paths), and a stamp taken after
194
+ // a concurrent append would bless records that don't include it. An early stamp only ever makes
195
+ // the cache look stale (one extra rebuild), never fresher than it is.
196
+ const stamp = logStamp(root);
123
197
  const events = readEvents(root);
124
198
  const records = rebuildRecords(events);
125
199
  const index = { schemaVersion: ISSUE_SCHEMA_VERSION, updatedAt: now, appId, records };
126
- if (events.length > 0)
127
- saveIndex(root, index);
200
+ if (events.length > 0) {
201
+ try {
202
+ saveIndex(root, index, stamp);
203
+ }
204
+ catch {
205
+ /* cache write is best-effort; the log stays authoritative */
206
+ }
207
+ }
128
208
  return index;
129
209
  }
130
210
  /** Get the current index, rebuilding from the log when the cache is missing/stale/corrupt. */
131
211
  export function getIndex(root, now, appId) {
132
- const cached = loadIndex(root);
133
- if (cached)
134
- return cached;
135
- const events = readEvents(root);
136
- if (events.length === 0)
137
- return emptyIndex(now, appId);
138
- return rebuildIndex(root, now, appId);
212
+ const index = loadIndex(root) ?? (readEvents(root).length === 0 ? emptyIndex(now, appId) : rebuildIndex(root, now, appId));
213
+ // Enforce `suppressedUntil`: an expired suppression is shown in its pre-suppression lane from
214
+ // `now` on (the next event on the issue makes that durable in the log, see foldEvent).
215
+ index.records = index.records.map((r) => (suppressionExpired(r, now) ? liftSuppression(r) : r));
216
+ return index;
139
217
  }
140
218
  /**
141
219
  * Count events already in the log for an issue. Used to allocate a monotonic per-issue sequence so
@@ -1 +1 @@
1
- {"version":3,"file":"store.js","sourceRoot":"","sources":["../../src/issues/store.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"store.js","sourceRoot":"","sources":["../../src/issues/store.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,48 @@
1
+ // Per-call cancellation scope. The session driver is shared between a background job and the
2
+ // interactive tool calls made while it runs, so a cancellation signal must travel with the CALL,
3
+ // not live in a mutable slot on the driver: AsyncLocalStorage carries it through every await.
4
+ // Jobs run their work inside runWithSignal(jobSignal); interactive tools inside
5
+ // runWithSignal(extra.signal). Drivers read currentSignal() when they spawn adb or fetch WDA.
6
+ import { AsyncLocalStorage } from 'node:async_hooks';
7
+ const scope = new AsyncLocalStorage();
8
+ /** Run `fn` with `signal` as the current cancellation signal (replacing any outer one: a job's
9
+ * signal never leaks into an interactive call made from its context, and vice versa). */
10
+ export function runWithSignal(signal, fn) {
11
+ return scope.run(signal, fn);
12
+ }
13
+ /** The cancellation signal of the call currently executing, if any. */
14
+ export function currentSignal() {
15
+ return scope.getStore();
16
+ }
17
+ /**
18
+ * Is `e` the result of a CANCELLATION rather than a real failure? True when the error (or any
19
+ * error in its `cause` chain) is an AbortError / has code ABORT_ERR, or when the current call's
20
+ * cancellation signal (abortScope) has fired. Drivers wrap aborted adb/WDA calls in their own
21
+ * messages ("uiautomator dump failed … AbortError", "WDA GET /source aborted (cancelled)"), so the
22
+ * signal is the authoritative check.
23
+ *
24
+ * Every place that converts an error into a finding, toolError, snapshotFailure, health verdict or
25
+ * mode switch must check this first and return a CANCELLED result instead: cancelled work is not
26
+ * evidence about the app or the tool.
27
+ */
28
+ export function isAbortError(e, signal = currentSignal()) {
29
+ if (signal?.aborted)
30
+ return true;
31
+ let cur = e;
32
+ for (let depth = 0; cur && depth < 6; depth++) {
33
+ const err = cur;
34
+ if (err.name === 'AbortError' || err.name === 'CancelledError' || err.code === 'ABORT_ERR')
35
+ return true;
36
+ cur = err.cause;
37
+ }
38
+ return false;
39
+ }
40
+ /** Thrown by long-running work (e.g. the explore runner) to unwind a cancelled step without
41
+ * recording it as a failure. */
42
+ export class CancelledError extends Error {
43
+ constructor(message = 'cancelled') {
44
+ super(message);
45
+ this.name = 'CancelledError';
46
+ }
47
+ }
48
+ //# sourceMappingURL=abortScope.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"abortScope.js","sourceRoot":"","sources":["../../src/lib/abortScope.ts"],"names":[],"mappings":"AAAA,6FAA6F;AAC7F,iGAAiG;AACjG,8FAA8F;AAC9F,gFAAgF;AAChF,8FAA8F;AAE9F,OAAO,EAAE,iBAAiB,EAAE,MAAM,kBAAkB,CAAC;AAErD,MAAM,KAAK,GAAG,IAAI,iBAAiB,EAA2B,CAAC;AAE/D;0FAC0F;AAC1F,MAAM,UAAU,aAAa,CAAI,MAA+B,EAAE,EAAW;IAC3E,OAAO,KAAK,CAAC,GAAG,CAAC,MAAM,EAAE,EAAE,CAAC,CAAC;AAC/B,CAAC;AAED,uEAAuE;AACvE,MAAM,UAAU,aAAa;IAC3B,OAAO,KAAK,CAAC,QAAQ,EAAE,CAAC;AAC1B,CAAC;AAED;;;;;;;;;;GAUG;AACH,MAAM,UAAU,YAAY,CAAC,CAAU,EAAE,SAAkC,aAAa,EAAE;IACxF,IAAI,MAAM,EAAE,OAAO;QAAE,OAAO,IAAI,CAAC;IACjC,IAAI,GAAG,GAAY,CAAC,CAAC;IACrB,KAAK,IAAI,KAAK,GAAG,CAAC,EAAE,GAAG,IAAI,KAAK,GAAG,CAAC,EAAE,KAAK,EAAE,EAAE,CAAC;QAC9C,MAAM,GAAG,GAAG,GAA0D,CAAC;QACvE,IAAI,GAAG,CAAC,IAAI,KAAK,YAAY,IAAI,GAAG,CAAC,IAAI,KAAK,gBAAgB,IAAI,GAAG,CAAC,IAAI,KAAK,WAAW;YAAE,OAAO,IAAI,CAAC;QACxG,GAAG,GAAG,GAAG,CAAC,KAAK,CAAC;IAClB,CAAC;IACD,OAAO,KAAK,CAAC;AACf,CAAC;AAED;iCACiC;AACjC,MAAM,OAAO,cAAe,SAAQ,KAAK;IACvC,YAAY,OAAO,GAAG,WAAW;QAC/B,KAAK,CAAC,OAAO,CAAC,CAAC;QACf,IAAI,CAAC,IAAI,GAAG,gBAAgB,CAAC;IAC/B,CAAC;CACF"}
@@ -2,11 +2,80 @@
2
2
  import { spawn } from 'node:child_process';
3
3
  import { existsSync, readdirSync, statSync } from 'node:fs';
4
4
  import { homedir } from 'node:os';
5
- import { join } from 'node:path';
5
+ import { delimiter, join } from 'node:path';
6
6
  import { run } from './spawn.js';
7
+ import { registerManagedProcess } from '../session/processRegistry.js';
7
8
  const MIN_APK_BYTES = 1024 * 1024;
9
+ /** Android Studio's default SDK location for a host OS (used when no env var points at an SDK). */
10
+ export function defaultAndroidSdkDir(platform = process.platform, home = homedir(), env = process.env) {
11
+ if (platform === 'darwin')
12
+ return join(home, 'Library', 'Android', 'sdk');
13
+ if (platform === 'win32')
14
+ return join(env.LOCALAPPDATA || join(home, 'AppData', 'Local'), 'Android', 'Sdk');
15
+ return join(home, 'Android', 'Sdk'); // Linux and other unixes
16
+ }
17
+ /** Candidate SDK roots in priority order: $ANDROID_HOME, $ANDROID_SDK_ROOT, then the OS default. */
18
+ export function androidSdkCandidates(env = process.env, platform = process.platform, home = homedir()) {
19
+ const out = [];
20
+ for (const p of [env.ANDROID_HOME, env.ANDROID_SDK_ROOT, defaultAndroidSdkDir(platform, home, env)]) {
21
+ if (p && p.trim() && !out.includes(p.trim()))
22
+ out.push(p.trim());
23
+ }
24
+ return out;
25
+ }
8
26
  export function androidHome() {
9
- return process.env.ANDROID_HOME || process.env.ANDROID_SDK_ROOT || join(homedir(), 'Library/Android/sdk');
27
+ const candidates = androidSdkCandidates();
28
+ return candidates.find((d) => existsSync(d)) ?? candidates[0];
29
+ }
30
+ /**
31
+ * Resolve an Android SDK tool (`adb` > platform-tools/adb, `emulator` > emulator/emulator)
32
+ * from the SDK candidates BEFORE falling back to PATH. GUI MCP clients (Claude Desktop,
33
+ * Cursor launched from the Dock) don't inherit the shell PATH, so a bare `adb` often fails
34
+ * there even though Android Studio installed it. Returns the absolute path, or the bare name
35
+ * (PATH lookup) when no SDK copy exists.
36
+ */
37
+ export function resolveAndroidTool(tool, env = process.env, platform = process.platform, home = homedir(), exists = existsSync) {
38
+ const sub = tool === 'adb' ? 'platform-tools' : 'emulator';
39
+ const file = platform === 'win32' ? `${tool}.exe` : tool;
40
+ for (const sdk of androidSdkCandidates(env, platform, home)) {
41
+ const p = join(sdk, sub, file);
42
+ if (exists(p))
43
+ return p;
44
+ }
45
+ return tool;
46
+ }
47
+ /** Whether an executable named `file` exists in one of the PATH `dirs`. */
48
+ function onPath(file, dirs, exists) {
49
+ return dirs.some((d) => exists(join(d, file)));
50
+ }
51
+ /**
52
+ * APPEND existing SDK tool dirs (platform-tools, emulator) to this process's PATH (only for a
53
+ * tool that is NOT already resolvable on PATH), so every `run('adb', …)` /
54
+ * `spawn('emulator', …)` call site, and `which`, can find the SDK copy in GUI clients whose
55
+ * PATH lacks it, without ever shadowing the user's own adb/emulator (a different adb version
56
+ * than the one the user's adb server runs would kill that server). Idempotent. Returns the dirs
57
+ * added. Called once at CLI/server startup (src/index.ts, src/server.ts).
58
+ */
59
+ export function ensureAndroidToolsOnPath(env = process.env, platform = process.platform, home = homedir(), exists = existsSync) {
60
+ const sep = platform === 'win32' ? ';' : platform === process.platform ? delimiter : ':';
61
+ // Windows env keys are case-insensitive but Node exposes the original casing (often "Path").
62
+ const key = Object.keys(env).find((k) => k.toUpperCase() === 'PATH') ?? 'PATH';
63
+ const current = (env[key] ?? '').split(sep).filter(Boolean);
64
+ const add = [];
65
+ for (const tool of ['adb', 'emulator']) {
66
+ const file = platform === 'win32' ? `${tool}.exe` : tool;
67
+ if (onPath(file, current, exists))
68
+ continue; // the user's own copy wins
69
+ const resolved = resolveAndroidTool(tool, env, platform, home, exists);
70
+ if (resolved === tool)
71
+ continue;
72
+ const dir = join(resolved, '..');
73
+ if (!current.includes(dir) && !add.includes(dir))
74
+ add.push(dir);
75
+ }
76
+ if (add.length)
77
+ env[key] = [...current, ...add].join(sep);
78
+ return add;
10
79
  }
11
80
  export function findAapt2() {
12
81
  const bt = join(androidHome(), 'build-tools');
@@ -60,7 +129,7 @@ export function resolveApk(projectRoot, explicit) {
60
129
  /**
61
130
  * Boot an AVD headless. Returns the ChildProcess so the caller can `kill()` it on cancel.
62
131
  * We `unref()` it so a running emulator does NOT keep the MCP process alive after the
63
- * client disconnects (unref does not prevent kill — the caller still holds the handle).
132
+ * client disconnects (unref does not prevent kill; the caller still holds the handle).
64
133
  * `detached:true` + `stdio:'ignore'` so it survives an intentional server exit as an
65
134
  * orphan rather than being torn down mid-run. NOTE: deliberate session/shutdown teardown
66
135
  * (track + kill booted emulators on session-close) is a follow-up lifecycle pass.
@@ -69,8 +138,11 @@ export function bootEmulator(avd, headless = true) {
69
138
  const args = ['-avd', avd, '-no-audio', '-no-snapshot', '-no-boot-anim', '-gpu', 'swiftshader_indirect'];
70
139
  if (headless)
71
140
  args.push('-no-window'); // omit for a visible window (local supervised QA)
72
- const child = spawn('emulator', args, { detached: true, stdio: 'ignore' });
141
+ const child = spawn(resolveAndroidTool('emulator'), args, { detached: true, stdio: 'ignore' });
73
142
  child.unref();
143
+ // Tracked for crash visibility only: the orphan reaper ADOPTS emulators (never kills them),
144
+ // since an orphaned emulator stays booted and remains usable via adb for the next run.
145
+ registerManagedProcess(child.pid, 'emulator');
74
146
  return child;
75
147
  }
76
148
  /** Free bytes on the device /data partition (parsed from `df`), or null. */
@@ -80,7 +152,7 @@ export async function deviceFreeDataBytes(serial) {
80
152
  const lines = r.stdout.trim().split('\n').filter(Boolean);
81
153
  const data = lines[lines.length - 1]; // the mount row
82
154
  const cols = data.trim().split(/\s+/);
83
- // Filesystem 1K-blocks Used Available Use% Mounted → Available is index 3
155
+ // Filesystem 1K-blocks Used Available Use% Mounted > Available is index 3
84
156
  const availKb = Number(cols[3]);
85
157
  return Number.isFinite(availKb) ? availKb * 1024 : null;
86
158
  }
@@ -92,7 +164,11 @@ export async function deviceFreeDataBytes(serial) {
92
164
  export async function deviceAbis(serial) {
93
165
  try {
94
166
  const r = await run('adb', ['-s', serial, 'shell', 'getprop', 'ro.product.cpu.abilist'], { timeoutMs: 5000 });
95
- return r.stdout.trim().split(',').map((s) => s.trim()).filter(Boolean);
167
+ return r.stdout
168
+ .trim()
169
+ .split(',')
170
+ .map((s) => s.trim())
171
+ .filter(Boolean);
96
172
  }
97
173
  catch {
98
174
  return [];
@@ -152,7 +228,7 @@ export async function deviceSdk(serial) {
152
228
  return null;
153
229
  }
154
230
  }
155
- /** PURE: is an APK's minSdk satisfied by a device API level? Unknown values → compatible (don't block on missing info). */
231
+ /** PURE: is an APK's minSdk satisfied by a device API level? Unknown values > compatible (don't block on missing info). */
156
232
  export function minSdkCompatible(apkMinSdk, deviceApiLevel) {
157
233
  if (apkMinSdk == null || deviceApiLevel == null)
158
234
  return true;
@@ -175,7 +251,7 @@ export function classifyAndroidInstallError(message) {
175
251
  return 'INSTALL_FAILED';
176
252
  return 'INSTALL_FAILED';
177
253
  }
178
- /** Native ABIs an APK ships (empty = pure/no native code → installs on any ABI). */
254
+ /** Native ABIs an APK ships (empty = pure/no native code > installs on any ABI). */
179
255
  export async function apkNativeAbis(apk) {
180
256
  const aapt2 = findAapt2();
181
257
  if (!aapt2)