swipium 1.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 (387) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +295 -0
  3. package/dist/appMap/automationLink.js +74 -0
  4. package/dist/appMap/automationLink.js.map +1 -0
  5. package/dist/appMap/build.js +193 -0
  6. package/dist/appMap/build.js.map +1 -0
  7. package/dist/appMap/codeIndex.js +73 -0
  8. package/dist/appMap/codeIndex.js.map +1 -0
  9. package/dist/appMap/featureModel.js +83 -0
  10. package/dist/appMap/featureModel.js.map +1 -0
  11. package/dist/appMap/firstRunApply.js +131 -0
  12. package/dist/appMap/firstRunApply.js.map +1 -0
  13. package/dist/appMap/fsWalk.js +75 -0
  14. package/dist/appMap/fsWalk.js.map +1 -0
  15. package/dist/appMap/issues.js +227 -0
  16. package/dist/appMap/issues.js.map +1 -0
  17. package/dist/appMap/migrations.js +87 -0
  18. package/dist/appMap/migrations.js.map +1 -0
  19. package/dist/appMap/prelaunch.js +66 -0
  20. package/dist/appMap/prelaunch.js.map +1 -0
  21. package/dist/appMap/projectRegistry.js +70 -0
  22. package/dist/appMap/projectRegistry.js.map +1 -0
  23. package/dist/appMap/provenance.js +52 -0
  24. package/dist/appMap/provenance.js.map +1 -0
  25. package/dist/appMap/query.js +118 -0
  26. package/dist/appMap/query.js.map +1 -0
  27. package/dist/appMap/runtimeMerge.js +207 -0
  28. package/dist/appMap/runtimeMerge.js.map +1 -0
  29. package/dist/appMap/schema.js +65 -0
  30. package/dist/appMap/schema.js.map +1 -0
  31. package/dist/appMap/screenMatch.js +75 -0
  32. package/dist/appMap/screenMatch.js.map +1 -0
  33. package/dist/appMap/staticScan.js +614 -0
  34. package/dist/appMap/staticScan.js.map +1 -0
  35. package/dist/appMap/store.js +173 -0
  36. package/dist/appMap/store.js.map +1 -0
  37. package/dist/appMap/tsAstScan.js +184 -0
  38. package/dist/appMap/tsAstScan.js.map +1 -0
  39. package/dist/artifacts/bundletool.js +199 -0
  40. package/dist/artifacts/bundletool.js.map +1 -0
  41. package/dist/artifacts/resolve.js +388 -0
  42. package/dist/artifacts/resolve.js.map +1 -0
  43. package/dist/automationGen/appiumModel.js +129 -0
  44. package/dist/automationGen/appiumModel.js.map +1 -0
  45. package/dist/automationGen/ciEmitter.js +80 -0
  46. package/dist/automationGen/ciEmitter.js.map +1 -0
  47. package/dist/automationGen/jsEmitter.js +440 -0
  48. package/dist/automationGen/jsEmitter.js.map +1 -0
  49. package/dist/automationGen/packagePatch.js +56 -0
  50. package/dist/automationGen/packagePatch.js.map +1 -0
  51. package/dist/automationGen/projectProfile.js +317 -0
  52. package/dist/automationGen/projectProfile.js.map +1 -0
  53. package/dist/automationGen/pythonEmitter.js +386 -0
  54. package/dist/automationGen/pythonEmitter.js.map +1 -0
  55. package/dist/automationGen/readmeEmitter.js +66 -0
  56. package/dist/automationGen/readmeEmitter.js.map +1 -0
  57. package/dist/automationGen/suitePlan.js +94 -0
  58. package/dist/automationGen/suitePlan.js.map +1 -0
  59. package/dist/automationGen/validation.js +150 -0
  60. package/dist/automationGen/validation.js.map +1 -0
  61. package/dist/build/parseBuildLog.js +119 -0
  62. package/dist/build/parseBuildLog.js.map +1 -0
  63. package/dist/build/plan.js +150 -0
  64. package/dist/build/plan.js.map +1 -0
  65. package/dist/ci/preflight.js +85 -0
  66. package/dist/ci/preflight.js.map +1 -0
  67. package/dist/cli/init.js +105 -0
  68. package/dist/cli/init.js.map +1 -0
  69. package/dist/cli/scan.js +85 -0
  70. package/dist/cli/scan.js.map +1 -0
  71. package/dist/cli/suite.js +85 -0
  72. package/dist/cli/suite.js.map +1 -0
  73. package/dist/cli/verify.js +62 -0
  74. package/dist/cli/verify.js.map +1 -0
  75. package/dist/consent/consent.js +43 -0
  76. package/dist/consent/consent.js.map +1 -0
  77. package/dist/context/detect.js +156 -0
  78. package/dist/context/detect.js.map +1 -0
  79. package/dist/context/findApps.js +198 -0
  80. package/dist/context/findApps.js.map +1 -0
  81. package/dist/context/projectRoot.js +41 -0
  82. package/dist/context/projectRoot.js.map +1 -0
  83. package/dist/context/scan.js +167 -0
  84. package/dist/context/scan.js.map +1 -0
  85. package/dist/core/target.js +115 -0
  86. package/dist/core/target.js.map +1 -0
  87. package/dist/core/targetPlan.js +140 -0
  88. package/dist/core/targetPlan.js.map +1 -0
  89. package/dist/drivers/DirectDriver.js +228 -0
  90. package/dist/drivers/DirectDriver.js.map +1 -0
  91. package/dist/drivers/Driver.js +4 -0
  92. package/dist/drivers/Driver.js.map +1 -0
  93. package/dist/drivers/SimctlDriver.js +127 -0
  94. package/dist/drivers/SimctlDriver.js.map +1 -0
  95. package/dist/drivers/WdaDriver.js +250 -0
  96. package/dist/drivers/WdaDriver.js.map +1 -0
  97. package/dist/explore/candidates.js +93 -0
  98. package/dist/explore/candidates.js.map +1 -0
  99. package/dist/explore/graph.js +116 -0
  100. package/dist/explore/graph.js.map +1 -0
  101. package/dist/explore/memory.js +35 -0
  102. package/dist/explore/memory.js.map +1 -0
  103. package/dist/explore/planner.js +105 -0
  104. package/dist/explore/planner.js.map +1 -0
  105. package/dist/explore/policy.js +85 -0
  106. package/dist/explore/policy.js.map +1 -0
  107. package/dist/explore/runner.js +475 -0
  108. package/dist/explore/runner.js.map +1 -0
  109. package/dist/explore/signatures.js +35 -0
  110. package/dist/explore/signatures.js.map +1 -0
  111. package/dist/explore/suite.js +55 -0
  112. package/dist/explore/suite.js.map +1 -0
  113. package/dist/featureTesting/executionBootstrap.js +140 -0
  114. package/dist/featureTesting/executionBootstrap.js.map +1 -0
  115. package/dist/firstRun/authStateMachine.js +83 -0
  116. package/dist/firstRun/authStateMachine.js.map +1 -0
  117. package/dist/firstRun/classifyScreen.js +201 -0
  118. package/dist/firstRun/classifyScreen.js.map +1 -0
  119. package/dist/firstRun/firstRunPlanner.js +207 -0
  120. package/dist/firstRun/firstRunPlanner.js.map +1 -0
  121. package/dist/firstRun/firstRunRunner.js +331 -0
  122. package/dist/firstRun/firstRunRunner.js.map +1 -0
  123. package/dist/firstRun/generatedDataPolicy.js +215 -0
  124. package/dist/firstRun/generatedDataPolicy.js.map +1 -0
  125. package/dist/firstRun/inputPlanner.js +67 -0
  126. package/dist/firstRun/inputPlanner.js.map +1 -0
  127. package/dist/firstRun/onboardingStateMachine.js +46 -0
  128. package/dist/firstRun/onboardingStateMachine.js.map +1 -0
  129. package/dist/firstRun/paywallPolicy.js +54 -0
  130. package/dist/firstRun/paywallPolicy.js.map +1 -0
  131. package/dist/firstRun/types.js +7 -0
  132. package/dist/firstRun/types.js.map +1 -0
  133. package/dist/fixtures/catalog.js +131 -0
  134. package/dist/fixtures/catalog.js.map +1 -0
  135. package/dist/flows/discover.js +18 -0
  136. package/dist/flows/discover.js.map +1 -0
  137. package/dist/flows/generate.js +211 -0
  138. package/dist/flows/generate.js.map +1 -0
  139. package/dist/flows/lint.js +97 -0
  140. package/dist/flows/lint.js.map +1 -0
  141. package/dist/flows/pack.js +68 -0
  142. package/dist/flows/pack.js.map +1 -0
  143. package/dist/flows/run.js +738 -0
  144. package/dist/flows/run.js.map +1 -0
  145. package/dist/flows/schema.js +240 -0
  146. package/dist/flows/schema.js.map +1 -0
  147. package/dist/flows/seedExec.js +108 -0
  148. package/dist/flows/seedExec.js.map +1 -0
  149. package/dist/flows/templates.js +155 -0
  150. package/dist/flows/templates.js.map +1 -0
  151. package/dist/flows/waitGuards.js +12 -0
  152. package/dist/flows/waitGuards.js.map +1 -0
  153. package/dist/index.js +33 -0
  154. package/dist/index.js.map +1 -0
  155. package/dist/ios/signing.js +182 -0
  156. package/dist/ios/signing.js.map +1 -0
  157. package/dist/issues/classify.js +186 -0
  158. package/dist/issues/classify.js.map +1 -0
  159. package/dist/issues/fingerprint.js +130 -0
  160. package/dist/issues/fingerprint.js.map +1 -0
  161. package/dist/issues/index.js +240 -0
  162. package/dist/issues/index.js.map +1 -0
  163. package/dist/issues/metrics.js +155 -0
  164. package/dist/issues/metrics.js.map +1 -0
  165. package/dist/issues/recurrence.js +193 -0
  166. package/dist/issues/recurrence.js.map +1 -0
  167. package/dist/issues/report.js +110 -0
  168. package/dist/issues/report.js.map +1 -0
  169. package/dist/issues/reportBridge.js +119 -0
  170. package/dist/issues/reportBridge.js.map +1 -0
  171. package/dist/issues/schema.js +90 -0
  172. package/dist/issues/schema.js.map +1 -0
  173. package/dist/issues/sourceRevision.js +108 -0
  174. package/dist/issues/sourceRevision.js.map +1 -0
  175. package/dist/issues/store.js +155 -0
  176. package/dist/issues/store.js.map +1 -0
  177. package/dist/lib/android.js +278 -0
  178. package/dist/lib/android.js.map +1 -0
  179. package/dist/lib/commandTemplate.js +55 -0
  180. package/dist/lib/commandTemplate.js.map +1 -0
  181. package/dist/lib/coordSpace.js +23 -0
  182. package/dist/lib/coordSpace.js.map +1 -0
  183. package/dist/lib/device.js +87 -0
  184. package/dist/lib/device.js.map +1 -0
  185. package/dist/lib/gitignore.js +22 -0
  186. package/dist/lib/gitignore.js.map +1 -0
  187. package/dist/lib/image.js +97 -0
  188. package/dist/lib/image.js.map +1 -0
  189. package/dist/lib/logger.js +8 -0
  190. package/dist/lib/logger.js.map +1 -0
  191. package/dist/lib/metroState.js +45 -0
  192. package/dist/lib/metroState.js.map +1 -0
  193. package/dist/lib/needsInput.js +201 -0
  194. package/dist/lib/needsInput.js.map +1 -0
  195. package/dist/lib/png.js +103 -0
  196. package/dist/lib/png.js.map +1 -0
  197. package/dist/lib/redact.js +21 -0
  198. package/dist/lib/redact.js.map +1 -0
  199. package/dist/lib/result.js +87 -0
  200. package/dist/lib/result.js.map +1 -0
  201. package/dist/lib/schemaHash.js +65 -0
  202. package/dist/lib/schemaHash.js.map +1 -0
  203. package/dist/lib/sensitive.js +13 -0
  204. package/dist/lib/sensitive.js.map +1 -0
  205. package/dist/lib/simctl.js +149 -0
  206. package/dist/lib/simctl.js.map +1 -0
  207. package/dist/lib/spawn.js +144 -0
  208. package/dist/lib/spawn.js.map +1 -0
  209. package/dist/lib/wda.js +347 -0
  210. package/dist/lib/wda.js.map +1 -0
  211. package/dist/lib/wdaConfig.js +69 -0
  212. package/dist/lib/wdaConfig.js.map +1 -0
  213. package/dist/lib/wdaTune.js +58 -0
  214. package/dist/lib/wdaTune.js.map +1 -0
  215. package/dist/oracle/auth.js +22 -0
  216. package/dist/oracle/auth.js.map +1 -0
  217. package/dist/oracle/failures.js +193 -0
  218. package/dist/oracle/failures.js.map +1 -0
  219. package/dist/oracle/health.js +123 -0
  220. package/dist/oracle/health.js.map +1 -0
  221. package/dist/oracle/record.js +36 -0
  222. package/dist/oracle/record.js.map +1 -0
  223. package/dist/orchestration/envelope.js +52 -0
  224. package/dist/orchestration/envelope.js.map +1 -0
  225. package/dist/orchestration/goal.js +98 -0
  226. package/dist/orchestration/goal.js.map +1 -0
  227. package/dist/plan/plan.js +124 -0
  228. package/dist/plan/plan.js.map +1 -0
  229. package/dist/prompts/index.js +63 -0
  230. package/dist/prompts/index.js.map +1 -0
  231. package/dist/report/artifactManifest.js +44 -0
  232. package/dist/report/artifactManifest.js.map +1 -0
  233. package/dist/report/coverage.js +60 -0
  234. package/dist/report/coverage.js.map +1 -0
  235. package/dist/report/evidence.js +84 -0
  236. package/dist/report/evidence.js.map +1 -0
  237. package/dist/report/export.js +447 -0
  238. package/dist/report/export.js.map +1 -0
  239. package/dist/report/flake.js +61 -0
  240. package/dist/report/flake.js.map +1 -0
  241. package/dist/report/history.js +564 -0
  242. package/dist/report/history.js.map +1 -0
  243. package/dist/report/policy.js +98 -0
  244. package/dist/report/policy.js.map +1 -0
  245. package/dist/report/qaLevel.js +96 -0
  246. package/dist/report/qaLevel.js.map +1 -0
  247. package/dist/report/readiness.js +213 -0
  248. package/dist/report/readiness.js.map +1 -0
  249. package/dist/report/summary.js +42 -0
  250. package/dist/report/summary.js.map +1 -0
  251. package/dist/report/testCatalog.js +93 -0
  252. package/dist/report/testCatalog.js.map +1 -0
  253. package/dist/report/timing.js +37 -0
  254. package/dist/report/timing.js.map +1 -0
  255. package/dist/server.js +180 -0
  256. package/dist/server.js.map +1 -0
  257. package/dist/services/automationGenerate.js +60 -0
  258. package/dist/services/automationGenerate.js.map +1 -0
  259. package/dist/services/build.js +66 -0
  260. package/dist/services/build.js.map +1 -0
  261. package/dist/services/preflight.js +51 -0
  262. package/dist/services/preflight.js.map +1 -0
  263. package/dist/services/prepareAndroid.js +183 -0
  264. package/dist/services/prepareAndroid.js.map +1 -0
  265. package/dist/services/prepareIos.js +162 -0
  266. package/dist/services/prepareIos.js.map +1 -0
  267. package/dist/services/report.js +537 -0
  268. package/dist/services/report.js.map +1 -0
  269. package/dist/services/smoke.js +120 -0
  270. package/dist/services/smoke.js.map +1 -0
  271. package/dist/services/suiteGenerate.js +123 -0
  272. package/dist/services/suiteGenerate.js.map +1 -0
  273. package/dist/services/testSuiteKnowledge.js +150 -0
  274. package/dist/services/testSuiteKnowledge.js.map +1 -0
  275. package/dist/session/attach.js +47 -0
  276. package/dist/session/attach.js.map +1 -0
  277. package/dist/session/progress.js +56 -0
  278. package/dist/session/progress.js.map +1 -0
  279. package/dist/session/store.js +329 -0
  280. package/dist/session/store.js.map +1 -0
  281. package/dist/snapshot/overlays.js +132 -0
  282. package/dist/snapshot/overlays.js.map +1 -0
  283. package/dist/snapshot/parse.js +204 -0
  284. package/dist/snapshot/parse.js.map +1 -0
  285. package/dist/snapshot/present.js +12 -0
  286. package/dist/snapshot/present.js.map +1 -0
  287. package/dist/snapshot/settle.js +36 -0
  288. package/dist/snapshot/settle.js.map +1 -0
  289. package/dist/state/profile.js +318 -0
  290. package/dist/state/profile.js.map +1 -0
  291. package/dist/suite/compile.js +176 -0
  292. package/dist/suite/compile.js.map +1 -0
  293. package/dist/suite/lint.js +45 -0
  294. package/dist/suite/lint.js.map +1 -0
  295. package/dist/suite/pom.js +285 -0
  296. package/dist/suite/pom.js.map +1 -0
  297. package/dist/suite/testcase.js +87 -0
  298. package/dist/suite/testcase.js.map +1 -0
  299. package/dist/testSuite/generator.js +222 -0
  300. package/dist/testSuite/generator.js.map +1 -0
  301. package/dist/testSuite/history.js +44 -0
  302. package/dist/testSuite/history.js.map +1 -0
  303. package/dist/testSuite/issueLinks.js +96 -0
  304. package/dist/testSuite/issueLinks.js.map +1 -0
  305. package/dist/testSuite/merge.js +190 -0
  306. package/dist/testSuite/merge.js.map +1 -0
  307. package/dist/testSuite/schema.js +86 -0
  308. package/dist/testSuite/schema.js.map +1 -0
  309. package/dist/testSuite/store.js +116 -0
  310. package/dist/testSuite/store.js.map +1 -0
  311. package/dist/testSuite/traceability.js +55 -0
  312. package/dist/testSuite/traceability.js.map +1 -0
  313. package/dist/tools/act.js +457 -0
  314. package/dist/tools/act.js.map +1 -0
  315. package/dist/tools/agent.js +225 -0
  316. package/dist/tools/agent.js.map +1 -0
  317. package/dist/tools/appMap.js +317 -0
  318. package/dist/tools/appMap.js.map +1 -0
  319. package/dist/tools/assertVisual.js +74 -0
  320. package/dist/tools/assertVisual.js.map +1 -0
  321. package/dist/tools/automationGenerate.js +394 -0
  322. package/dist/tools/automationGenerate.js.map +1 -0
  323. package/dist/tools/capabilities.js +114 -0
  324. package/dist/tools/capabilities.js.map +1 -0
  325. package/dist/tools/clearOverlay.js +150 -0
  326. package/dist/tools/clearOverlay.js.map +1 -0
  327. package/dist/tools/detectContext.js +41 -0
  328. package/dist/tools/detectContext.js.map +1 -0
  329. package/dist/tools/doctor.js +116 -0
  330. package/dist/tools/doctor.js.map +1 -0
  331. package/dist/tools/explore.js +289 -0
  332. package/dist/tools/explore.js.map +1 -0
  333. package/dist/tools/firstRun.js +136 -0
  334. package/dist/tools/firstRun.js.map +1 -0
  335. package/dist/tools/flow.js +331 -0
  336. package/dist/tools/flow.js.map +1 -0
  337. package/dist/tools/flowGenerate.js +55 -0
  338. package/dist/tools/flowGenerate.js.map +1 -0
  339. package/dist/tools/getArtifact.js +39 -0
  340. package/dist/tools/getArtifact.js.map +1 -0
  341. package/dist/tools/health.js +41 -0
  342. package/dist/tools/health.js.map +1 -0
  343. package/dist/tools/ios.js +492 -0
  344. package/dist/tools/ios.js.map +1 -0
  345. package/dist/tools/jobs.js +20 -0
  346. package/dist/tools/jobs.js.map +1 -0
  347. package/dist/tools/network.js +50 -0
  348. package/dist/tools/network.js.map +1 -0
  349. package/dist/tools/note.js +69 -0
  350. package/dist/tools/note.js.map +1 -0
  351. package/dist/tools/plan.js +49 -0
  352. package/dist/tools/plan.js.map +1 -0
  353. package/dist/tools/prepareIosTarget.js +99 -0
  354. package/dist/tools/prepareIosTarget.js.map +1 -0
  355. package/dist/tools/prepareTarget.js +257 -0
  356. package/dist/tools/prepareTarget.js.map +1 -0
  357. package/dist/tools/report.js +42 -0
  358. package/dist/tools/report.js.map +1 -0
  359. package/dist/tools/screenRecord.js +24 -0
  360. package/dist/tools/screenRecord.js.map +1 -0
  361. package/dist/tools/screenshot.js +63 -0
  362. package/dist/tools/screenshot.js.map +1 -0
  363. package/dist/tools/smoke.js +39 -0
  364. package/dist/tools/smoke.js.map +1 -0
  365. package/dist/tools/snapshot.js +129 -0
  366. package/dist/tools/snapshot.js.map +1 -0
  367. package/dist/tools/startSession.js +169 -0
  368. package/dist/tools/startSession.js.map +1 -0
  369. package/dist/tools/state.js +87 -0
  370. package/dist/tools/state.js.map +1 -0
  371. package/dist/tools/suite.js +412 -0
  372. package/dist/tools/suite.js.map +1 -0
  373. package/dist/tools/testThis.js +774 -0
  374. package/dist/tools/testThis.js.map +1 -0
  375. package/dist/tools/wda.js +477 -0
  376. package/dist/tools/wda.js.map +1 -0
  377. package/dist/version.js +62 -0
  378. package/dist/version.js.map +1 -0
  379. package/dist/visual/ocr.js +72 -0
  380. package/dist/visual/ocr.js.map +1 -0
  381. package/dist/visual/provider.js +75 -0
  382. package/dist/visual/provider.js.map +1 -0
  383. package/docs/README.md +19 -0
  384. package/docs/assets/swipium-lockup-ink-on-light.png +0 -0
  385. package/docs/mcp-server.md +135 -0
  386. package/docs/tools.md +130 -0
  387. package/package.json +70 -0
package/LICENSE ADDED
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2026 swipium contributors
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
package/README.md ADDED
@@ -0,0 +1,295 @@
1
+ <p align="center">
2
+ <img src="docs/assets/swipium-lockup-ink-on-light.png" alt="Swipium" width="420">
3
+ </p>
4
+
5
+ # Swipium
6
+
7
+ MCP server for simulator-based mobile QA agents.
8
+
9
+ [![npm version](https://img.shields.io/npm/v/swipium.svg)](https://www.npmjs.com/package/swipium)
10
+ [![License: MIT](https://img.shields.io/badge/License-MIT-blue.svg)](LICENSE)
11
+ [![Node >= 20](https://img.shields.io/badge/node-%3E%3D20-brightgreen.svg)](https://nodejs.org)
12
+ [![MCP](https://img.shields.io/badge/MCP-server-black.svg)](https://modelcontextprotocol.io)
13
+ [![Platform](https://img.shields.io/badge/platform-Android%20Emulator%20%2B%20iOS%20Simulator-blue.svg)](https://swipium.com)
14
+
15
+ Swipium lets an AI agent run practical mobile QA from a local MCP client: launch an app in an Android Emulator or iOS Simulator, inspect screens, act on the UI, run smoke checks, collect evidence, build an app knowledge map, generate reports, and create reusable test assets.
16
+
17
+ Website: [swipium.com](https://swipium.com)
18
+
19
+ ## About
20
+
21
+ Swipium is a local MCP server for mobile QA workflows. It gives agents a structured tool surface for simulator setup, UI observation, action execution, evidence capture, app-map memory, reporting, and generated test suites.
22
+
23
+ Swipium's mission is to help development teams and indie developers get fast feedback on applications from a usage perspective, not from a code perspective. Earlier usage feedback helps teams iterate quickly and avoid shipping production builds with issues that could have been detected before release.
24
+
25
+ Swipium is intended to be used through an agent. The agent communicates with the MCP server and gets access to a QA-oriented suite of testing tools for exploration, evidence collection, app knowledge, report generation, test assets, and automation.
26
+
27
+ Public v1 scope:
28
+
29
+ - Android Emulator and iOS Simulator.
30
+ - Local MCP stdio server.
31
+ - Evidence stored as local Swipium artifacts.
32
+ - Durable app knowledge map under the tested project.
33
+ - Flow, test-case, suite, and automation generation from observed behavior.
34
+ - Consent gates for mutating actions.
35
+ - Secret redaction for credentials, tokens, OTPs, and generated sensitive values.
36
+
37
+
38
+ ## What is Swipium?
39
+
40
+ Swipium is not a replacement for a test runner. It is an agent-facing QA harness.
41
+
42
+ It helps an agent answer requests like:
43
+
44
+ - "Test it."
45
+ - "Test this e2e flow."
46
+ - "Create test automation for this app."
47
+ - "Smoke test this app."
48
+ - "Explore the login flow."
49
+ - "Generate a report with evidence."
50
+ - "Turn this run into a reusable flow."
51
+ - "Create an automation suite from what you observed."
52
+
53
+ The MCP server keeps the workflow deterministic where possible and explicit where risk exists. Heavy steps such as booting simulators, installing apps, writing files, or generating automation are exposed as tools with structured outputs, blockers, artifacts, and consent prompts.
54
+
55
+ ## QuickStart
56
+
57
+ Run this from the mobile app repository:
58
+
59
+ ```bash
60
+ npx -y swipium verify
61
+ ```
62
+
63
+ Add Swipium to your agent:
64
+
65
+ ```bash
66
+ npm install -g swipium
67
+ swipium init claude --apply --scope project
68
+ ```
69
+
70
+ Then ask the agent:
71
+
72
+ ```text
73
+ Test this app with Swipium. Start with qa_test_this. Use Android Emulator or iOS Simulator only. Generate a report with evidence.
74
+ ```
75
+
76
+ For a direct MCP configuration without a global install:
77
+
78
+ ```jsonc
79
+ {
80
+ "mcpServers": {
81
+ "swipium": {
82
+ "command": "npx",
83
+ "args": ["-y", "swipium"],
84
+ "cwd": "/absolute/path/to/your/mobile-app",
85
+ "timeout": 600000
86
+ }
87
+ }
88
+ }
89
+ ```
90
+
91
+ ## Installation
92
+
93
+ Run without installing:
94
+
95
+ ```bash
96
+ npx -y swipium verify
97
+ ```
98
+
99
+ Install globally:
100
+
101
+ ```bash
102
+ npm install -g swipium
103
+ swipium verify
104
+ ```
105
+
106
+ Install in a project:
107
+
108
+ ```bash
109
+ npm install --save-dev swipium
110
+ npx swipium verify
111
+ ```
112
+
113
+ Requirements:
114
+
115
+ - Node.js 20 or newer.
116
+ - Android Studio for Android Emulator workflows.
117
+ - Xcode for iOS Simulator workflows.
118
+ - A simulator-ready app artifact when testing iOS, such as a simulator `.app`.
119
+ - An APK or buildable Android project when testing Android.
120
+
121
+ ## Usage
122
+
123
+ Start with the autopilot tool:
124
+
125
+ ```text
126
+ qa_test_this {
127
+ "projectRoot": "/absolute/path/to/app",
128
+ "mode": "execute",
129
+ "goal": "smoke"
130
+ }
131
+ ```
132
+
133
+ Common workflow:
134
+
135
+ 1. `qa_doctor` checks local toolchain readiness.
136
+ 2. `qa_test_this` resolves the project, artifact, and simulator target.
137
+ 3. `qa_job_status` polls long-running work.
138
+ 4. `qa_smoke` or `qa_explore` runs the app.
139
+ 5. `qa_report` produces the evidence report.
140
+ 6. `qa_app_map_read` or `qa_app_map_query` reads the durable app map.
141
+ 7. `qa_flow_generate`, `qa_suite_generate`, or `qa_automation_generate` creates reusable QA assets.
142
+
143
+ CLI helpers:
144
+
145
+ ```bash
146
+ swipium verify # starts the server and checks tool injection
147
+ swipium init claude # preview Claude Code registration
148
+ swipium init gemini # preview Gemini registration
149
+ swipium init codex # preview Codex config
150
+ swipium init flows # create starter flow templates
151
+ swipium scan # scan project context
152
+ swipium suite # local suite helper
153
+ ```
154
+
155
+ ## MCP Server
156
+
157
+ Swipium runs as a stdio MCP server. MCP clients launch it as a local process and communicate through JSON-RPC over stdin and stdout.
158
+
159
+ Manual MCP configuration:
160
+
161
+ ```jsonc
162
+ {
163
+ "mcpServers": {
164
+ "swipium": {
165
+ "command": "npx",
166
+ "args": ["-y", "swipium"],
167
+ "cwd": "/absolute/path/to/your/mobile-app",
168
+ "timeout": 600000
169
+ }
170
+ }
171
+ }
172
+ ```
173
+
174
+ Installed binary configuration:
175
+
176
+ ```jsonc
177
+ {
178
+ "mcpServers": {
179
+ "swipium": {
180
+ "command": "swipium",
181
+ "args": [],
182
+ "cwd": "/absolute/path/to/your/mobile-app",
183
+ "timeout": 600000
184
+ }
185
+ }
186
+ }
187
+ ```
188
+
189
+ Important:
190
+
191
+ - Set `cwd` to the mobile app repository.
192
+ - Restart the MCP client after installing or upgrading.
193
+ - Run `qa_doctor` if tools are missing or stale.
194
+ - Use `qa_get_artifact` for report, screenshot, dump, and log artifacts.
195
+
196
+ More detail: [docs/mcp-server.md](docs/mcp-server.md)
197
+
198
+ ## Agent Integration
199
+
200
+ ### Claude Code
201
+
202
+ Global install:
203
+
204
+ ```bash
205
+ npm install -g swipium
206
+ swipium init claude --apply --scope project
207
+ ```
208
+
209
+ No global install:
210
+
211
+ ```bash
212
+ claude mcp add swipium --scope project -- npx -y swipium
213
+ ```
214
+
215
+ ### Gemini CLI
216
+
217
+ Global install:
218
+
219
+ ```bash
220
+ npm install -g swipium
221
+ swipium init gemini --apply
222
+ ```
223
+
224
+ No global install:
225
+
226
+ ```bash
227
+ gemini mcp add swipium npx -y swipium
228
+ ```
229
+
230
+ ### Codex
231
+
232
+ Global install:
233
+
234
+ ```bash
235
+ npm install -g swipium
236
+ swipium init codex --apply
237
+ ```
238
+
239
+ Manual Codex config:
240
+
241
+ ```toml
242
+ [mcp_servers.swipium]
243
+ command = "npx"
244
+ args = ["-y", "swipium"]
245
+ cwd = "/absolute/path/to/your/mobile-app"
246
+ ```
247
+
248
+ After setup, verify that the client lists `qa_test_this`, `qa_capabilities`, and `qa_report`.
249
+
250
+ ## Tool Docs
251
+
252
+ Swipium v1 exposes 42 public MCP tools. Start with `qa_test_this` for low-context requests.
253
+
254
+ Full reference: [docs/tools.md](docs/tools.md)
255
+
256
+ | Group | Tools |
257
+ | --- | --- |
258
+ | Start | `qa_agent_brief`, `qa_capabilities`, `qa_test_this`, `qa_job_status`, `qa_status`, `qa_explain_blocker`, `qa_continue_from_blocker`, `qa_get_artifact` |
259
+ | Setup | `qa_doctor`, `qa_start_session`, `qa_detect_context`, `qa_plan`, `qa_prepare_target`, `qa_prepare_ios_target`, `qa_ios`, `qa_wda` |
260
+ | Drive | `qa_snapshot`, `qa_act`, `qa_clear_overlay`, `qa_check_health`, `qa_screenshot`, `qa_note`, `qa_assert_visual` |
261
+ | Run | `qa_smoke`, `qa_explore`, `qa_report` |
262
+ | App map | `qa_app_map_build`, `qa_app_map_read`, `qa_app_map_query`, `qa_app_map_feature_scope`, `qa_app_map_validate` |
263
+ | Flows and suites | `qa_flow_check`, `qa_flow_run`, `qa_flow_generate`, `qa_suite_generate`, `qa_suite_compile`, `qa_testcase_generate` |
264
+ | First run | `qa_first_run_plan`, `qa_first_run_continue` |
265
+ | Automation | `qa_automation_plan`, `qa_automation_generate`, `qa_automation_validate` |
266
+
267
+ ## Why Swipium?
268
+
269
+ - Agent-native: exposes QA work as MCP tools with structured outputs.
270
+ - Simulator-first: focuses v1 on Android Emulator and iOS Simulator reliability.
271
+ - Evidence-first: screenshots, logs, reports, dumps, and artifacts are stored and linked.
272
+ - App memory: the app map preserves screens, features, test cases, flows, and coverage context.
273
+ - Practical consent: mutating actions are gated instead of hidden behind agent text.
274
+ - Reusable output: exploratory runs can become flows, test cases, suites, and generated automation.
275
+ - Local by default: the server runs on the developer machine and uses local simulators.
276
+
277
+ ## Docs
278
+
279
+ - [MCP Server](docs/mcp-server.md)
280
+ - [Tool Reference](docs/tools.md)
281
+ - [Project Docs Index](docs/README.md)
282
+ - [Security Policy](SECURITY.md)
283
+ - [Contributing](CONTRIBUTING.md)
284
+ - [Support](SUPPORT.md)
285
+ - [Changelog](CHANGELOG.md)
286
+
287
+ ## Topics
288
+
289
+ Recommended GitHub topics:
290
+
291
+ `mcp`, `model-context-protocol`, `mobile-testing`, `qa-automation`, `android-emulator`, `ios-simulator`, `appium`, `ai-agents`, `test-automation`, `e2e-testing`, `react-native-testing`, `flutter-testing`, `app-map`, `test-suites`, `developer-tools`
292
+
293
+ ## License
294
+
295
+ MIT. See [LICENSE](LICENSE).
@@ -0,0 +1,74 @@
1
+ // Vision Gap Fix 7 — write a generated automation suite back into the durable app map. After
2
+ // qa_automation_generate emits an Appium POM suite, the app map should KNOW automation now exists for
3
+ // these screens/features, so future feature/ticket decisions can see which flows are automated. Pure-
4
+ // ish: loads + saves `.swipium/app-map.json`, upserting an AutomationSuiteRef (by path) with the
5
+ // screen/feature ids the suite covers. Best-effort: returns ok:false rather than throwing on no map.
6
+ import { loadAppMap, saveAppMap } from './store.js';
7
+ import { addProvenance, makeProvenance, recomputeConfidence } from './provenance.js';
8
+ import { detectFramework } from './../context/detect.js';
9
+ function fallbackProject(root) {
10
+ const fw = detectFramework(root);
11
+ return { root, gitRemote: null, packageName: null, workspaceTarget: null, framework: fw, platforms: fw === 'native-android' ? ['android'] : fw === 'native-ios' ? ['ios'] : ['android', 'ios'] };
12
+ }
13
+ // Generic page/screen suffixes carry no identity — a POM "LoginPage" and a static "login" route are
14
+ // the same screen. Strip these (on both sides) so the page-name → static-screen match actually fires.
15
+ const SCREEN_NOISE = new Set(['page', 'screen', 'view', 'component', 'tab', 'modal', 'navigator', 'stack', 'drawer', 'route', 'index']);
16
+ /** Split camelCase/PascalCase/snake/kebab into lowercase identity tokens, dropping generic noise. */
17
+ function tokenize(s) {
18
+ return s
19
+ .replace(/([a-z0-9])([A-Z])/g, '$1 $2') // camelCase boundary: LoginPage → Login Page
20
+ .replace(/([A-Z]+)([A-Z][a-z])/g, '$1 $2') // ACRONYMWord boundary
21
+ .toLowerCase()
22
+ .split(/[^a-z0-9]+/)
23
+ .filter((t) => t.length >= 2 && !SCREEN_NOISE.has(t));
24
+ }
25
+ /** Best-effort map of generated POM screen names → app-map static screen ids + their feature ids. */
26
+ export function deriveAutomationLinks(map, screenNames) {
27
+ const screenIds = new Set();
28
+ for (const name of screenNames) {
29
+ const want = new Set(tokenize(name));
30
+ if (!want.size)
31
+ continue;
32
+ let best;
33
+ for (const s of map.staticTopology.screens) {
34
+ // Match against the static screen's name, route, AND id slug (e.g. "screen:login" / "route:login").
35
+ const have = new Set([...tokenize(s.name), ...tokenize(s.route ?? ''), ...tokenize(s.id)]);
36
+ let score = 0;
37
+ for (const t of want)
38
+ if (have.has(t))
39
+ score++;
40
+ if (score > 0 && (!best || score > best.score))
41
+ best = { id: s.id, score };
42
+ }
43
+ if (best)
44
+ screenIds.add(best.id);
45
+ }
46
+ const featureIds = new Set();
47
+ for (const f of map.features) {
48
+ if (f.staticScreens.some((sid) => screenIds.has(sid)))
49
+ featureIds.add(f.id);
50
+ }
51
+ return { screenIds: [...screenIds], featureIds: [...featureIds] };
52
+ }
53
+ /** Upsert (by path) an automation suite record into the durable app map. */
54
+ export function linkAutomationSuite(root, suite, now) {
55
+ const loaded = loadAppMap(root, fallbackProject(root), now);
56
+ if (!loaded.map)
57
+ return { ok: false };
58
+ const map = loaded.map;
59
+ // Enrich screen/feature links from the map when the caller didn't already resolve them.
60
+ if ((!suite.linkedScreenIds || !suite.linkedScreenIds.length) && suite.linkedFeatureIds === undefined) {
61
+ // nothing to enrich
62
+ }
63
+ const existing = map.automation.suites.find((s) => s.path === suite.path);
64
+ if (existing)
65
+ Object.assign(existing, suite);
66
+ else
67
+ map.automation.suites.push(suite);
68
+ addProvenance(map, makeProvenance('test_case', now, `Automation suite ${suite.name} linked (${suite.framework ?? 'appium'})`, { targetType: 'test', refs: [suite.path] }));
69
+ map.updatedAt = now;
70
+ recomputeConfidence(map);
71
+ const save = saveAppMap(root, map);
72
+ return { ok: true, appMapUri: save.resourceUri, suite };
73
+ }
74
+ //# sourceMappingURL=automationLink.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"automationLink.js","sourceRoot":"","sources":["../../src/appMap/automationLink.ts"],"names":[],"mappings":"AAAA,6FAA6F;AAC7F,sGAAsG;AACtG,sGAAsG;AACtG,iGAAiG;AACjG,qGAAqG;AAErG,OAAO,EAAE,UAAU,EAAE,UAAU,EAAqB,MAAM,YAAY,CAAC;AACvE,OAAO,EAAE,aAAa,EAAE,cAAc,EAAE,mBAAmB,EAAE,MAAM,iBAAiB,CAAC;AACrF,OAAO,EAAE,eAAe,EAAE,MAAM,wBAAwB,CAAC;AAGzD,SAAS,eAAe,CAAC,IAAY;IACnC,MAAM,EAAE,GAAG,eAAe,CAAC,IAAI,CAAC,CAAC;IACjC,OAAO,EAAE,IAAI,EAAE,SAAS,EAAE,IAAI,EAAE,WAAW,EAAE,IAAI,EAAE,eAAe,EAAE,IAAI,EAAE,SAAS,EAAE,EAAE,EAAE,SAAS,EAAE,EAAE,KAAK,gBAAgB,CAAC,CAAC,CAAC,CAAC,SAAS,CAAC,CAAC,CAAC,CAAC,EAAE,KAAK,YAAY,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC,SAAS,EAAE,KAAK,CAAC,EAAE,CAAC;AACnM,CAAC;AAED,oGAAoG;AACpG,sGAAsG;AACtG,MAAM,YAAY,GAAG,IAAI,GAAG,CAAC,CAAC,MAAM,EAAE,QAAQ,EAAE,MAAM,EAAE,WAAW,EAAE,KAAK,EAAE,OAAO,EAAE,WAAW,EAAE,OAAO,EAAE,QAAQ,EAAE,OAAO,EAAE,OAAO,CAAC,CAAC,CAAC;AAExI,qGAAqG;AACrG,SAAS,QAAQ,CAAC,CAAS;IACzB,OAAO,CAAC;SACL,OAAO,CAAC,oBAAoB,EAAE,OAAO,CAAC,CAAC,6CAA6C;SACpF,OAAO,CAAC,uBAAuB,EAAE,OAAO,CAAC,CAAC,uBAAuB;SACjE,WAAW,EAAE;SACb,KAAK,CAAC,YAAY,CAAC;SACnB,MAAM,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,MAAM,IAAI,CAAC,IAAI,CAAC,YAAY,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC;AAC1D,CAAC;AAED,qGAAqG;AACrG,MAAM,UAAU,qBAAqB,CAAC,GAAoB,EAAE,WAAqB;IAC/E,MAAM,SAAS,GAAG,IAAI,GAAG,EAAU,CAAC;IACpC,KAAK,MAAM,IAAI,IAAI,WAAW,EAAE,CAAC;QAC/B,MAAM,IAAI,GAAG,IAAI,GAAG,CAAC,QAAQ,CAAC,IAAI,CAAC,CAAC,CAAC;QACrC,IAAI,CAAC,IAAI,CAAC,IAAI;YAAE,SAAS;QACzB,IAAI,IAA+C,CAAC;QACpD,KAAK,MAAM,CAAC,IAAI,GAAG,CAAC,cAAc,CAAC,OAAO,EAAE,CAAC;YAC3C,oGAAoG;YACpG,MAAM,IAAI,GAAG,IAAI,GAAG,CAAC,CAAC,GAAG,QAAQ,CAAC,CAAC,CAAC,IAAI,CAAC,EAAE,GAAG,QAAQ,CAAC,CAAC,CAAC,KAAK,IAAI,EAAE,CAAC,EAAE,GAAG,QAAQ,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC;YAC3F,IAAI,KAAK,GAAG,CAAC,CAAC;YACd,KAAK,MAAM,CAAC,IAAI,IAAI;gBAAE,IAAI,IAAI,CAAC,GAAG,CAAC,CAAC,CAAC;oBAAE,KAAK,EAAE,CAAC;YAC/C,IAAI,KAAK,GAAG,CAAC,IAAI,CAAC,CAAC,IAAI,IAAI,KAAK,GAAG,IAAI,CAAC,KAAK,CAAC;gBAAE,IAAI,GAAG,EAAE,EAAE,EAAE,CAAC,CAAC,EAAE,EAAE,KAAK,EAAE,CAAC;QAC7E,CAAC;QACD,IAAI,IAAI;YAAE,SAAS,CAAC,GAAG,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC;IACnC,CAAC;IACD,MAAM,UAAU,GAAG,IAAI,GAAG,EAAU,CAAC;IACrC,KAAK,MAAM,CAAC,IAAI,GAAG,CAAC,QAAQ,EAAE,CAAC;QAC7B,IAAI,CAAC,CAAC,aAAa,CAAC,IAAI,CAAC,CAAC,GAAG,EAAE,EAAE,CAAC,SAAS,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC;YAAE,UAAU,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC;IAC9E,CAAC;IACD,OAAO,EAAE,SAAS,EAAE,CAAC,GAAG,SAAS,CAAC,EAAE,UAAU,EAAE,CAAC,GAAG,UAAU,CAAC,EAAE,CAAC;AACpE,CAAC;AAQD,4EAA4E;AAC5E,MAAM,UAAU,mBAAmB,CAAC,IAAY,EAAE,KAAyB,EAAE,GAAW;IACtF,MAAM,MAAM,GAAG,UAAU,CAAC,IAAI,EAAE,eAAe,CAAC,IAAI,CAAC,EAAE,GAAG,CAAC,CAAC;IAC5D,IAAI,CAAC,MAAM,CAAC,GAAG;QAAE,OAAO,EAAE,EAAE,EAAE,KAAK,EAAE,CAAC;IACtC,MAAM,GAAG,GAAG,MAAM,CAAC,GAAG,CAAC;IACvB,wFAAwF;IACxF,IAAI,CAAC,CAAC,KAAK,CAAC,eAAe,IAAI,CAAC,KAAK,CAAC,eAAe,CAAC,MAAM,CAAC,IAAI,KAAK,CAAC,gBAAgB,KAAK,SAAS,EAAE,CAAC;QACtG,oBAAoB;IACtB,CAAC;IACD,MAAM,QAAQ,GAAG,GAAG,CAAC,UAAU,CAAC,MAAM,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,IAAI,KAAK,KAAK,CAAC,IAAI,CAAC,CAAC;IAC1E,IAAI,QAAQ;QAAE,MAAM,CAAC,MAAM,CAAC,QAAQ,EAAE,KAAK,CAAC,CAAC;;QACxC,GAAG,CAAC,UAAU,CAAC,MAAM,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC;IACvC,aAAa,CAAC,GAAG,EAAE,cAAc,CAAC,WAAW,EAAE,GAAG,EAAE,oBAAoB,KAAK,CAAC,IAAI,YAAY,KAAK,CAAC,SAAS,IAAI,QAAQ,GAAG,EAAE,EAAE,UAAU,EAAE,MAAM,EAAE,IAAI,EAAE,CAAC,KAAK,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC,CAAC;IAC3K,GAAG,CAAC,SAAS,GAAG,GAAG,CAAC;IACpB,mBAAmB,CAAC,GAAG,CAAC,CAAC;IACzB,MAAM,IAAI,GAAG,UAAU,CAAC,IAAI,EAAE,GAAG,CAAC,CAAC;IACnC,OAAO,EAAE,EAAE,EAAE,IAAI,EAAE,SAAS,EAAE,IAAI,CAAC,WAAW,EAAE,KAAK,EAAE,CAAC;AAC1D,CAAC"}
@@ -0,0 +1,193 @@
1
+ // App map builder (SWIPIUM-REQ-01 qa_app_map_build orchestration). Resolves project identity, runs
2
+ // the framework-aware static scan, loads + migrates any existing map, optionally merges a runtime
3
+ // explore graph, recomputes coverage/confidence, and persists. Additive: a static rescan refreshes
4
+ // the static topology while PRESERVING runtime observations, tickets, the test suite, and automation
5
+ // links. Pure-ish: filesystem I/O is confined to staticScan/codeIndex/store; this composes them.
6
+ import { readFileSync } from 'node:fs';
7
+ import { join } from 'node:path';
8
+ import { detectFramework } from '../context/detect.js';
9
+ import { buildCodeIndex } from './codeIndex.js';
10
+ import { inferFeatures } from './featureModel.js';
11
+ import { addProvenance, makeProvenance, recomputeConfidence } from './provenance.js';
12
+ import { applyIssueSummariesToAppMap } from './issues.js';
13
+ import { mergeRuntimeGraph, computeUnvisitedStaticScreens } from './runtimeMerge.js';
14
+ import { applyFirstRunPatches } from './firstRunApply.js';
15
+ import { emptyAppMap } from './schema.js';
16
+ import { hasFormLibrary, staticScan } from './staticScan.js';
17
+ import { loadAppMap, saveAppMap, saveIndexes } from './store.js';
18
+ import { rememberProject } from './projectRegistry.js';
19
+ function gitRemote(root) {
20
+ try {
21
+ const cfg = readFileSync(join(root, '.git', 'config'), 'utf8');
22
+ const m = cfg.match(/\[remote "origin"\][^[]*url\s*=\s*(.+)/);
23
+ return m ? m[1].trim() : null;
24
+ }
25
+ catch {
26
+ return null;
27
+ }
28
+ }
29
+ function platformsFor(fw) {
30
+ switch (fw) {
31
+ case 'native-android':
32
+ return ['android'];
33
+ case 'native-ios':
34
+ return ['ios'];
35
+ default:
36
+ return ['android', 'ios'];
37
+ }
38
+ }
39
+ function projectIdentity(root, fw, packageName) {
40
+ return {
41
+ root,
42
+ gitRemote: gitRemote(root),
43
+ packageName,
44
+ workspaceTarget: null,
45
+ framework: fw,
46
+ platforms: platformsFor(fw),
47
+ };
48
+ }
49
+ function recomputeCoverage(map) {
50
+ // Recompute unvisited static screens here so it is correct after EVERY build path — including a
51
+ // static-only scan where mergeRuntimeGraph never runs (SWIPIUM-REQ-01 Fix Group 6).
52
+ map.runtimeTopology.unvisitedStaticScreens = computeUnvisitedStaticScreens(map);
53
+ const staticScreens = map.staticTopology.screens.length;
54
+ const runtimeScreens = map.runtimeTopology.screens.length;
55
+ const linkedScreens = map.runtimeTopology.screens.filter((r) => r.linkedStaticScreenId).length;
56
+ const unmapped = map.runtimeTopology.screens.filter((r) => r.unmapped).length;
57
+ const featureCoverage = {};
58
+ for (const f of map.features)
59
+ featureCoverage[f.id] = f.testCoverage;
60
+ const staleTests = map.testSuite.cases.filter((c) => c.stale).length;
61
+ const overallPercent = staticScreens ? Math.round((linkedScreens / staticScreens) * 100) : runtimeScreens ? 100 : 0;
62
+ map.coverage = {
63
+ staticScreens,
64
+ runtimeScreens,
65
+ linkedScreens,
66
+ unvisitedStaticScreens: map.runtimeTopology.unvisitedStaticScreens.length,
67
+ unmappedRuntimeScreens: unmapped,
68
+ featureCoverage,
69
+ staleTests,
70
+ overallPercent,
71
+ };
72
+ }
73
+ /** Replace the static topology + static-derived facts; preserve runtime feature enrichment. */
74
+ function applyStaticScan(map, root, at) {
75
+ const scan = staticScan(root, at);
76
+ map.staticTopology = scan.staticTopology;
77
+ map.appIdentity = {
78
+ androidPackage: scan.appIdentity.androidPackage ?? map.appIdentity.androidPackage,
79
+ iosBundleId: scan.appIdentity.iosBundleId ?? map.appIdentity.iosBundleId,
80
+ appName: scan.appIdentity.appName ?? map.appIdentity.appName,
81
+ version: scan.appIdentity.version ?? map.appIdentity.version,
82
+ artifactHash: map.appIdentity.artifactHash,
83
+ environment: map.appIdentity.environment,
84
+ };
85
+ map.auth = scan.auth;
86
+ map.onboarding = scan.onboarding;
87
+ map.paywalls = scan.paywalls;
88
+ map.inputModels = scan.inputModels;
89
+ map.sourceFingerprint = scan.sourceFingerprint;
90
+ if (scan.packageName)
91
+ map.project.packageName = scan.packageName;
92
+ // Re-infer features, but carry over runtime enrichment (runtimeScreens/testCoverage) by id.
93
+ const fresh = inferFeatures({ topo: scan.staticTopology, auth: scan.auth, onboarding: scan.onboarding, paywalls: scan.paywalls, hasForms: hasFormLibrary(root) });
94
+ const prevById = new Map(map.features.map((f) => [f.id, f]));
95
+ map.features = fresh.map((f) => {
96
+ const prev = prevById.get(f.id);
97
+ if (!prev)
98
+ return f;
99
+ return { ...f, runtimeScreens: prev.runtimeScreens, testCoverage: prev.testCoverage, actions: prev.actions.length ? prev.actions : f.actions };
100
+ });
101
+ addProvenance(map, makeProvenance('code_scan', at, `Static scan: ${scan.staticTopology.screens.length} screen(s), router=${scan.staticTopology.router ?? 'none'}`, { targetType: 'map', refs: scan.staticTopology.parserNotes.slice(0, 3) }));
102
+ if (scan.appIdentity.androidPackage || scan.appIdentity.iosBundleId) {
103
+ addProvenance(map, makeProvenance('app_config', at, `App identity from config: ${scan.appIdentity.androidPackage ?? scan.appIdentity.iosBundleId}`, { targetType: 'identity' }));
104
+ }
105
+ // Code index over the collected files.
106
+ return buildCodeIndex(root, scan.collectedFiles, at);
107
+ }
108
+ /** Build (or incrementally update) the app map. Filesystem-bound but never throws on scan errors. */
109
+ export function buildAppMap(root, opts) {
110
+ const fw = detectFramework(root);
111
+ const fallbackProject = projectIdentity(root, fw, null);
112
+ const loaded = loadAppMap(root, fallbackProject, opts.at);
113
+ let map = loaded.map ?? emptyAppMap(fallbackProject, opts.at);
114
+ // refresh project identity (framework can change as the repo evolves)
115
+ map.project = { ...map.project, ...projectIdentity(root, fw, map.project.packageName) };
116
+ let codeIndex = null;
117
+ const doRescan = opts.mode === 'static_only' || opts.mode === 'full' || !loaded.existed || opts.forceRescan === true;
118
+ let rescanned = false;
119
+ if (doRescan) {
120
+ codeIndex = applyStaticScan(map, root, opts.at);
121
+ rescanned = true;
122
+ }
123
+ let mergeResult;
124
+ if ((opts.mode === 'runtime_merge' || opts.mode === 'full') && opts.exploreGraph) {
125
+ mergeResult = mergeRuntimeGraph(map, opts.exploreGraph, { sessionId: opts.sessionId, at: opts.at });
126
+ addProvenance(map, makeProvenance('runtime', opts.at, `Runtime merge: +${mergeResult.newRuntimeScreens} new, ~${mergeResult.updatedRuntimeScreens} updated, ${mergeResult.linkedScreens} linked`, { targetType: 'map', refs: opts.sessionId ? [opts.sessionId] : [] }));
127
+ }
128
+ let firstRunApply;
129
+ if (opts.firstRunPatches?.length) {
130
+ firstRunApply = applyFirstRunPatches(map, opts.firstRunPatches, opts.at);
131
+ addProvenance(map, makeProvenance('runtime', opts.at, `First-run merge: ${firstRunApply.newScreens} new, ${firstRunApply.updatedScreens} updated runtime screen(s)`, { targetType: 'map', refs: opts.sessionId ? [opts.sessionId] : [] }));
132
+ }
133
+ if (opts.appIdentityHints) {
134
+ map.appIdentity.androidPackage = opts.appIdentityHints.androidPackage ?? map.appIdentity.androidPackage;
135
+ map.appIdentity.iosBundleId = opts.appIdentityHints.iosBundleId ?? map.appIdentity.iosBundleId;
136
+ map.appIdentity.artifactHash = opts.appIdentityHints.artifactHash ?? map.appIdentity.artifactHash;
137
+ map.appIdentity.environment = opts.appIdentityHints.environment ?? map.appIdentity.environment;
138
+ }
139
+ recomputeCoverage(map);
140
+ recomputeConfidence(map);
141
+ // Derived issue summaries from the durable issue ledger (SWIPIUM-REQ-08). Best-effort — the issue
142
+ // ledger is an additive context layer and must never break an app-map build.
143
+ try {
144
+ applyIssueSummariesToAppMap(map, root, opts.at);
145
+ }
146
+ catch {
147
+ /* best-effort */
148
+ }
149
+ map.updatedAt = opts.at;
150
+ if (!map.generatedAt)
151
+ map.generatedAt = opts.at;
152
+ let save;
153
+ if (opts.persist !== false) {
154
+ save = saveAppMap(root, map);
155
+ if (opts.includeCodeIndex !== false)
156
+ saveIndexes(root, codeIndex, map.features);
157
+ // Fix 8: durably remember this project so its app-map resource URI resolves across restarts.
158
+ rememberProject(root, { packageName: map.project.packageName, framework: map.project.framework, at: opts.at });
159
+ }
160
+ return { map, codeIndex, mergeResult, firstRunApply, migration: loaded.migration, save, rescanned };
161
+ }
162
+ /** Read just the coverage counts from an existing map (zeros if none) — for computing a delta. */
163
+ export function quickCoverage(root, at) {
164
+ const fw = detectFramework(root);
165
+ const loaded = loadAppMap(root, projectIdentity(root, fw, null), at);
166
+ const c = loaded.map?.coverage;
167
+ return { overallPercent: c?.overallPercent ?? 0, runtimeScreens: c?.runtimeScreens ?? 0, staticScreens: c?.staticScreens ?? 0 };
168
+ }
169
+ /** Compact, context-friendly summary of a map for tool text + structured results. */
170
+ export function summarizeMap(map) {
171
+ const gaps = [];
172
+ if (map.runtimeTopology.unvisitedStaticScreens.length)
173
+ gaps.push(`${map.runtimeTopology.unvisitedStaticScreens.length} static screen(s) never visited at runtime`);
174
+ const uncovered = map.features.filter((f) => f.testCoverage === 'none');
175
+ if (uncovered.length)
176
+ gaps.push(`${uncovered.length} feature(s) with no coverage: ${uncovered.slice(0, 4).map((f) => f.title).join(', ')}`);
177
+ const hypotheses = map.features.filter((f) => f.status === 'hypothesis');
178
+ if (hypotheses.length)
179
+ gaps.push(`${hypotheses.length} low-confidence feature hypothesis(es)`);
180
+ return {
181
+ framework: map.project.framework,
182
+ router: map.staticTopology.router,
183
+ appIdentity: map.appIdentity,
184
+ staticScreens: map.staticTopology.screens.length,
185
+ runtimeScreens: map.runtimeTopology.screens.length,
186
+ features: map.features.map((f) => ({ id: f.id, title: f.title, status: f.status, testCoverage: f.testCoverage, confidence: f.confidence })),
187
+ coverage: map.coverage,
188
+ confidence: map.confidence.overall,
189
+ topGaps: gaps.slice(0, 6),
190
+ parserNotes: map.staticTopology.parserNotes.slice(0, 4),
191
+ };
192
+ }
193
+ //# sourceMappingURL=build.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"build.js","sourceRoot":"","sources":["../../src/appMap/build.ts"],"names":[],"mappings":"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"}