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
@@ -0,0 +1,225 @@
1
+ // Agent-efficiency layer. Compact, deterministic helpers so an MCP client spends fewer turns:
2
+ // a one-glance session status, a blocker explainer, and a resume-from-blocker entry that consumes
3
+ // user-provided input safely.
4
+ import { z } from 'zod';
5
+ import { qaOk, qaError } from '../lib/result.js';
6
+ import { FAILURES, failureOwner, isSelfFixable } from '../oracle/failures.js';
7
+ import { progressLine } from '../session/progress.js';
8
+ import { readinessForSession } from '../report/readiness.js';
9
+ import { SWIPIUM_VERSION, TOOL_COUNT, PROMPT_COUNT } from '../version.js';
10
+ import { TEST_GOALS } from '../orchestration/goal.js';
11
+ function budgetRemaining(s) {
12
+ const elapsedMin = (Date.now() - s.createdAt) / 60000;
13
+ return {
14
+ minutes: Math.max(0, Math.round((s.budget.maxMinutes - elapsedMin) * 10) / 10),
15
+ actions: Math.max(0, s.budget.maxActions - s.counters.actions),
16
+ screenshots: Math.max(0, s.budget.maxScreenshots - s.counters.screenshots),
17
+ };
18
+ }
19
+ /** Deterministic "what next" given the session's observed state (optionally goal-aware). */
20
+ function nextBestAction(s, goal) {
21
+ const sid = s.id;
22
+ const lastJob = [...s.jobs.values()].sort((a, b) => b.startedAt - a.startedAt)[0];
23
+ if (lastJob?.status === 'running')
24
+ return { tool: 'qa_job_status', why: `job ${lastJob.jobId} (${lastJob.kind}) is still running`, args: { sessionId: sid, jobId: lastJob.jobId } };
25
+ if (!s.device)
26
+ return { tool: 'qa_test_this', why: goal ? `no device/app prepared yet — run the autopilot for goal "${goal}"` : 'no device/app prepared yet — orchestrate setup', args: { sessionId: sid, mode: 'execute', ...(goal ? { goal } : {}) } };
27
+ if (!s.appId)
28
+ return { tool: 'qa_prepare_target', why: 'device bound but no app launched', args: { sessionId: sid } };
29
+ if (s.recordedActions.length === 0)
30
+ return { tool: 'qa_smoke', why: 'app is up but nothing exercised yet — run a smoke pass', args: { sessionId: sid } };
31
+ if (s.findings.length > 0)
32
+ return { tool: 'qa_report', why: `${s.findings.length} finding(s) recorded — summarize with evidence`, args: { sessionId: sid } };
33
+ if (s.recordedActions.length > 0)
34
+ return { tool: 'qa_suite_generate', why: 'actions recorded — turn the run into a durable POM suite', args: { sessionId: sid } };
35
+ return { tool: 'qa_report', why: 'wrap up and report', args: { sessionId: sid } };
36
+ }
37
+ /** The compact, current-version instruction set for coding agents (Milestone A). Pure + deterministic
38
+ * so it is snapshot-testable; it references the live SWIPIUM_VERSION / tool / prompt counts. */
39
+ export function agentBrief() {
40
+ return {
41
+ version: SWIPIUM_VERSION,
42
+ tools: TOOL_COUNT,
43
+ prompts: PROMPT_COUNT,
44
+ purpose: 'Turn a coding agent into a mobile QA tester. For a zero-context "test this" request, call the macro tool first.',
45
+ firstCall: {
46
+ tool: 'qa_test_this',
47
+ args: { mode: 'execute' },
48
+ note: 'Pass projectRoot if the client did not expose a workspace root. mode:"execute" runs the whole path as a background job.',
49
+ },
50
+ polling: {
51
+ tool: 'qa_job_status',
52
+ args: { sessionId: '<from firstCall>', jobId: '<from firstCall>' },
53
+ terminalStates: ['completed', 'blocked', 'unsafe', 'needs_input'],
54
+ },
55
+ report: {
56
+ tool: 'qa_get_artifact',
57
+ args: { uri: '<reportUri from the terminal result>' },
58
+ rule: 'Fetch reportUri instead of calling more tools, unless nextRecommendedAction says otherwise.',
59
+ },
60
+ goals: TEST_GOALS,
61
+ needsInputRule: 'Relay exactly the one returned question (with its fields/secret flags). Do not invent extra questions. Resume with the response\'s `resume` call.',
62
+ blockerRule: 'Relay failureCode, owner, what Swipium tried (attempted/workaroundsAttempted), and how to fix it. A build failure is not a test failure.',
63
+ stopRule: 'Stop and ask the user only on a needs_input state (credentials, monorepo target, destructive approval, signing, external service). Otherwise continue without user input.',
64
+ continueRule: 'For completed/blocked/unsafe states, summarize from the structured envelope and the report — no extra Swipium calls are required.',
65
+ mapRule: 'Before feature-focused testing, consult the durable App Knowledge Map: qa_app_map_read, qa_app_map_query, or qa_app_map_feature_scope to reuse what Swipium already learned instead of rediscovering the app. qa_test_this and qa_explore update the map automatically.',
66
+ macroTools: ['qa_test_this', 'qa_smoke', 'qa_explore', 'qa_report', 'qa_app_map_read'],
67
+ escapeHatches: ['qa_doctor', 'qa_start_session', 'qa_detect_context', 'qa_plan', 'qa_prepare_target', 'qa_prepare_ios_target', 'qa_ios', 'qa_wda', 'qa_act', 'qa_snapshot'],
68
+ };
69
+ }
70
+ export function registerAgentTools(server, sessions) {
71
+ // ---- qa_agent_brief ----
72
+ server.registerTool('qa_agent_brief', {
73
+ title: 'Agent brief (how to drive Swipium)',
74
+ description: 'Read-only, cheap, deterministic. Returns the current-version instruction set for coding agents: the first call for low-context QA (qa_test_this), the polling + report-fetch flow, the NeedsInput/blocker rules, when to stop vs. continue, and which tools are macros vs. low-level escape hatches. Call this once at the start instead of inspecting the source tree.',
75
+ inputSchema: {},
76
+ }, async () => {
77
+ const b = agentBrief();
78
+ const summary = `Swipium v${b.version} (${b.tools} tools, ${b.prompts} prompts) — agent brief\n` +
79
+ `1. ${b.firstCall.tool} ${JSON.stringify(b.firstCall.args)}\n` +
80
+ `2. ${b.polling.tool} until state ∈ {${b.polling.terminalStates.join(', ')}}\n` +
81
+ `3. ${b.report.tool} { uri: reportUri }\n` +
82
+ 'needs_input -> ask the one returned question; otherwise continue.';
83
+ return qaOk(b, summary);
84
+ });
85
+ // ---- qa_status ----
86
+ server.registerTool('qa_status', {
87
+ title: 'Session status (compact)',
88
+ description: 'A concise snapshot of a session for an agent: project root/framework, bound device + app, budget remaining, counters, recorded actions, findings/notes, last job, and the safe fallbacks taken (workarounds). Read-only, cheap — call between steps instead of re-deriving state.',
89
+ inputSchema: { sessionId: z.string() },
90
+ }, async ({ sessionId }) => {
91
+ const s = sessions.get(sessionId);
92
+ if (!s)
93
+ return qaError({ what: `Unknown sessionId ${sessionId}`, changedState: false, retrySafe: true, nextSteps: ['Call qa_start_session first.'] });
94
+ const remaining = budgetRemaining(s);
95
+ const lastJob = [...s.jobs.values()].sort((a, b) => b.startedAt - a.startedAt)[0];
96
+ const next = nextBestAction(s);
97
+ const status = {
98
+ sessionId: s.id, root: s.root, device: s.device ?? null, appId: s.appId ?? null, mode: s.mode,
99
+ budgetRemaining: remaining, counters: s.counters,
100
+ recordedActions: s.recordedActions.length, findings: s.findings.length, notes: s.notes.length,
101
+ workarounds: s.workarounds, inputsProvided: s.inputs.map((i) => i.varName),
102
+ readiness: readinessForSession(s),
103
+ lastJob: lastJob ? { jobId: lastJob.jobId, kind: lastJob.kind, status: lastJob.status, progress: lastJob.progress, progressDetail: lastJob.progressDetail ?? null } : null,
104
+ nextBestAction: next,
105
+ };
106
+ const progLine = progressLine(lastJob?.progressDetail);
107
+ const summary = `session ${s.id} — ${s.device ?? 'no device'}${s.appId ? ` / ${s.appId}` : ''} (mode=${s.mode})\n` +
108
+ `budget left: ${remaining.minutes}m / ${remaining.actions} actions / ${remaining.screenshots} shots\n` +
109
+ `recorded=${s.recordedActions.length} findings=${s.findings.length} notes=${s.notes.length}` +
110
+ (lastJob ? `\nlast job: ${lastJob.kind} [${lastJob.status}]${progLine ? `\n ${progLine}` : lastJob.progress ? ` ${lastJob.progress}` : ''}` : '') +
111
+ (s.workarounds.length ? `\nworkarounds: ${s.workarounds.length}` : '') +
112
+ `\n→ next: ${next.tool} — ${next.why}`;
113
+ return qaOk(status, summary);
114
+ });
115
+ // ---- qa_explain_blocker ----
116
+ server.registerTool('qa_explain_blocker', {
117
+ title: 'Explain a blocker',
118
+ description: 'Turn a typed failure code (e.g. AAB_NEEDS_BUNDLETOOL, WDA_SIGNING_FAILED, NO_BUILD_ARTIFACT) into a user-friendly explanation: what it means, who owns the fix (app / environment / Swipium / user), whether it is retry-safe, whether Swipium can fix it itself, and the exact recovery step. Use to relay a blocker to the user in plain language.',
119
+ inputSchema: {
120
+ failureCode: z.string().describe('A Swipium failure code (from a tool that returned isError with failureCode).'),
121
+ context: z.string().optional(),
122
+ },
123
+ }, async ({ failureCode, context }) => {
124
+ const code = failureCode;
125
+ const info = FAILURES[code];
126
+ if (!info) {
127
+ return qaError({ what: `Unknown failure code "${failureCode}"`, changedState: false, retrySafe: true, nextSteps: ['Pass a code surfaced by a Swipium tool (the `failureCode` field of an error).'] });
128
+ }
129
+ const owner = failureOwner(code);
130
+ const ownerText = {
131
+ app: 'the app developer (fix the app)',
132
+ environment: 'the dev environment (toolchain/device/build setup)',
133
+ swipium: 'Swipium (it can often handle this automatically)',
134
+ user: 'you (provide input/approval/test data)',
135
+ };
136
+ const explanation = {
137
+ failureCode: code, bucket: info.bucket, owner, severity: info.severity,
138
+ retrySafe: info.retrySafe, canSwipiumFix: isSelfFixable(code),
139
+ whatItMeans: info.summary, whoFixesIt: ownerText[owner], howToFix: info.recovery,
140
+ context: context ?? null,
141
+ };
142
+ const summary = `${code} — ${info.summary}\n` +
143
+ `owner: ${ownerText[owner]}; retry-safe: ${info.retrySafe}; Swipium can fix: ${isSelfFixable(code)}\n` +
144
+ `fix: ${info.recovery}`;
145
+ return qaOk(explanation, summary);
146
+ });
147
+ // ---- qa_continue_from_blocker ----
148
+ server.registerTool('qa_continue_from_blocker', {
149
+ title: 'Resume after providing input',
150
+ description: 'Consume user-provided input for a NeedsInput question and return the next action. Secret values (passwords/OTP/tokens) are added to the session redaction set immediately (never stored in plaintext, never logged). Non-secret choices (platform, allowOutsideRoot, target) are echoed back as the args to re-invoke qa_test_this / qa_prepare_target with.',
151
+ inputSchema: {
152
+ sessionId: z.string(),
153
+ kind: z.string().describe('The NeedsInput kind being answered (e.g. credentials, preferred_platform, artifact_outside_root).'),
154
+ values: z.record(z.union([z.string(), z.boolean()])).optional().describe('Field name → value. Secret fields are redacted on receipt.'),
155
+ secretFields: z.array(z.string()).optional().describe('Which value keys are secret (default: password/otp/token-like names).'),
156
+ },
157
+ }, async ({ sessionId, kind, values, secretFields }) => {
158
+ const s = sessions.get(sessionId);
159
+ if (!s)
160
+ return qaError({ what: `Unknown sessionId ${sessionId}`, changedState: false, retrySafe: true, nextSteps: ['Call qa_start_session first.'] });
161
+ const vals = values ?? {};
162
+ const secretRe = /pass|secret|token|otp|pin|cvv|key/i;
163
+ const isSecret = (k) => (secretFields?.includes(k)) || secretRe.test(k);
164
+ // Register inputs into the SECURE STORE (P0.5): each maps to a flow variable; secret values
165
+ // join the redaction set and are NEVER echoed back. Generated flows reference the var name.
166
+ const accepted = [];
167
+ const storedVars = [];
168
+ const reInvokeArgs = { sessionId: s.id };
169
+ for (const [k, v] of Object.entries(vals)) {
170
+ const secret = isSecret(k);
171
+ if (typeof v === 'string' && (secret || /email|user|account|otp|code|token|pin/i.test(k))) {
172
+ const varName = inputVarName(k);
173
+ sessions.setInput(s, varName, v, secret, `needs_input:${kind}`);
174
+ storedVars.push(varName);
175
+ accepted.push(`${k} → \${${varName}}${secret ? ' (redacted)' : ''}`);
176
+ }
177
+ else {
178
+ accepted.push(`${k}=${v}`);
179
+ if (k === 'platform')
180
+ reInvokeArgs.platform = v;
181
+ if (k === 'allowOutsideRoot')
182
+ reInvokeArgs.allowOutsideRoot = v;
183
+ if (k === 'target' || k === 'device')
184
+ reInvokeArgs.device = v;
185
+ if (k === 'developmentTeam' || k === 'provisioningProfile' || k === 'serviceEndpoint')
186
+ reInvokeArgs[k] = v;
187
+ }
188
+ }
189
+ sessions.persist(s);
190
+ sessions.addWorkaround(s, `resumed from "${kind}" blocker with: ${accepted.join(', ') || '(no values)'}`);
191
+ // Decide the resume action by kind.
192
+ const reInvokeKinds = new Set([
193
+ 'artifact_outside_root', 'preferred_platform', 'monorepo_target',
194
+ 'signing_team',
195
+ 'destructive_exploration_approval', 'external_service_required',
196
+ ]);
197
+ // Every resume is a DIRECTLY executable call. Credentials/OTP are now registered as secure
198
+ // inputs, so re-invoking the autopilot drives the authenticated flows with them (the macro
199
+ // tool resolves the already-prepared session/device and continues) — no bare qa_act guess.
200
+ const resume = kind === 'credentials' || kind === 'otp_or_manual_verification'
201
+ ? { tool: 'qa_test_this', why: 'credentials registered (redacted) — re-run the autopilot to drive authenticated flows with them', args: { sessionId: s.id, mode: 'execute', stopOnNeedsInput: false } }
202
+ : reInvokeKinds.has(kind)
203
+ ? { tool: 'qa_test_this', why: 're-run orchestration with your choice applied', args: { mode: 'execute', ...reInvokeArgs } }
204
+ : { tool: 'qa_test_this', why: 'resume orchestration', args: { mode: 'execute', ...reInvokeArgs } };
205
+ return qaOk({ kind, accepted, storedVariables: storedVars, nextAction: resume, secretsRegistered: accepted.filter((a) => a.includes('redacted')).length }, `Accepted ${accepted.length} field(s)${accepted.some((a) => a.includes('redacted')) ? ' (secrets redacted)' : ''}.` +
206
+ (storedVars.length ? `\nstored for replay: ${storedVars.join(', ')}` : '') +
207
+ `\n→ next: ${resume.tool} ${JSON.stringify(resume.args)} — ${resume.why}`);
208
+ });
209
+ }
210
+ /** Map a NeedsInput field name to its canonical Swipium flow variable (P0.5). */
211
+ function inputVarName(field) {
212
+ const f = field.toLowerCase();
213
+ if (/pass/.test(f))
214
+ return 'SWIPIUM_TEST_PASSWORD';
215
+ if (/email|user|account/.test(f))
216
+ return 'SWIPIUM_TEST_EMAIL';
217
+ if (/otp|code|2fa|mfa/.test(f))
218
+ return 'SWIPIUM_TEST_OTP';
219
+ if (/token|api[_-]?key/.test(f))
220
+ return 'SWIPIUM_TEST_TOKEN';
221
+ if (/pin/.test(f))
222
+ return 'SWIPIUM_TEST_PIN';
223
+ return `SWIPIUM_${field.toUpperCase().replace(/[^A-Z0-9]+/g, '_')}`;
224
+ }
225
+ //# sourceMappingURL=agent.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"agent.js","sourceRoot":"","sources":["../../src/tools/agent.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,317 @@
1
+ // App Knowledge Map MCP tools. Public v1 reads, builds, queries, scopes, and validates the
2
+ // durable `.swipium/app-map.json`. Large map data is returned by RESOURCE
3
+ // URI (swipium://project/<id>/app-map…) rather than flooded into the text channel; compact,
4
+ // structured data is returned inline. All heavy logic lives in src/appMap/*; these are thin.
5
+ import { existsSync, readFileSync } from 'node:fs';
6
+ import { z } from 'zod';
7
+ import { qaOk, qaError } from '../lib/result.js';
8
+ import { resolveProjectRoot } from '../context/projectRoot.js';
9
+ import { buildAppMap, summarizeMap } from '../appMap/build.js';
10
+ import { queryAppMap } from '../appMap/query.js';
11
+ import { loadAppMap, loadCodeIndex, validateAppMap, appMapResourceUri, appMapPath, projectId } from '../appMap/store.js';
12
+ import { rememberProject, lookupRoot } from '../appMap/projectRegistry.js';
13
+ import { detectFramework } from '../context/detect.js';
14
+ // projectId(root) is a one-way hash, so resource reads need a reverse lookup. We remember every root
15
+ // touched this session (in-memory) AND in a DURABLE registry (~/.swipium/projects.json, Fix 8) so a
16
+ // resource URI stays resolvable across server restarts. The resource handler also falls back to live
17
+ // sessions for roots that predate the durable registry.
18
+ const projectRegistry = new Map();
19
+ function remember(root) {
20
+ projectRegistry.set(projectId(root), root);
21
+ rememberProject(root, { framework: detectFramework(root) });
22
+ }
23
+ export function resolveAppMapRoot(id, sessions) {
24
+ const known = projectRegistry.get(id);
25
+ if (known)
26
+ return known;
27
+ // Durable registry survives restarts (Fix 8).
28
+ const durable = lookupRoot(id);
29
+ if (durable && existsSync(appMapPath(durable.root)))
30
+ return durable.root;
31
+ for (const s of sessions.list()) {
32
+ if (projectId(s.root) === id)
33
+ return s.root;
34
+ }
35
+ return durable?.root;
36
+ }
37
+ function nowIso() {
38
+ return new Date().toISOString();
39
+ }
40
+ /** Resolve a project root from an explicit arg or a session. */
41
+ async function rootFor(server, sessions, args) {
42
+ if (args.sessionId) {
43
+ const s = sessions.get(args.sessionId);
44
+ if (!s)
45
+ return { hint: `Unknown sessionId ${args.sessionId}` };
46
+ return { root: s.root, session: s };
47
+ }
48
+ const resolved = await resolveProjectRoot(server, args.projectRoot);
49
+ if (!resolved.root)
50
+ return { hint: resolved.hint };
51
+ return { root: resolved.root };
52
+ }
53
+ function fallbackProject(root) {
54
+ const fw = detectFramework(root);
55
+ return { root, gitRemote: null, packageName: null, workspaceTarget: null, framework: fw, platforms: fw === 'native-android' ? ['android'] : fw === 'native-ios' ? ['ios'] : ['android', 'ios'] };
56
+ }
57
+ /** Read an existing map WITHOUT rescanning. Returns null when no map file exists yet. */
58
+ function readExistingMap(root) {
59
+ return loadAppMap(root, fallbackProject(root), nowIso()).map;
60
+ }
61
+ /** Pull the latest serialized explore graph for a session (for runtime_merge). */
62
+ function latestExploreGraph(sessions, session) {
63
+ if (!session?.exploration?.graphUri)
64
+ return null;
65
+ const found = sessions.findArtifact(session.exploration.graphUri);
66
+ if (!found)
67
+ return null;
68
+ try {
69
+ return JSON.parse(readFileSync(found.rec.path, 'utf8'));
70
+ }
71
+ catch {
72
+ return null;
73
+ }
74
+ }
75
+ export function registerAppMap(server, sessions) {
76
+ // ------------------------------------------------------------------ build
77
+ server.registerTool('qa_app_map_build', {
78
+ title: 'Build / update the app knowledge map',
79
+ description: 'Build or incrementally update the durable App Knowledge Map at .swipium/app-map.json. Runs the framework-aware STATIC scan (Expo Router / React Navigation / native Android manifest / SwiftUI+UIKit / Flutter routes), loads + migrates any existing map, and (with a sessionId in runtime_merge/full mode) MERGES the latest exploration screen graph into runtime topology — linking runtime screens to static screens. Returns a compact summary + the map resource URI; the full map is read via qa_app_map_read or the resource. Does NOT commit the file.',
80
+ inputSchema: {
81
+ projectRoot: z.string().optional().describe('Absolute project root. Omit to use a session root or the MCP workspace root.'),
82
+ sessionId: z.string().optional().describe('Reuse a session (its root + latest exploration graph).'),
83
+ mode: z.enum(['static_only', 'runtime_merge', 'full']).optional().describe('static_only: code scan only; runtime_merge: merge the session exploration graph only; full (default): both.'),
84
+ includeCodeIndex: z.boolean().optional().describe('Persist a code symbol index for queries (default true).'),
85
+ forceRescan: z.boolean().optional().describe('Re-run the static scan even if an up-to-date map exists (default false).'),
86
+ },
87
+ outputSchema: { ok: z.boolean(), appMapUri: z.string().optional(), staticScreens: z.number().optional(), runtimeScreens: z.number().optional() },
88
+ }, async ({ projectRoot, sessionId, mode, includeCodeIndex, forceRescan }) => {
89
+ const { root, session, hint } = await rootFor(server, sessions, { projectRoot, sessionId });
90
+ if (!root)
91
+ return qaError({ what: 'Could not resolve a project root', changedState: false, retrySafe: true, nextSteps: ['Pass projectRoot="/abs/path" or a valid sessionId.'], clientHint: hint });
92
+ remember(root);
93
+ const m = (mode ?? 'full');
94
+ const exploreGraph = m === 'static_only' ? null : latestExploreGraph(sessions, session);
95
+ try {
96
+ const res = buildAppMap(root, { mode: m, at: nowIso(), includeCodeIndex, forceRescan, sessionId, exploreGraph, persist: true });
97
+ const summary = summarizeMap(res.map);
98
+ const merge = res.mergeResult;
99
+ const text = `🗺️ app map built (${m}) for ${root}\n` +
100
+ `framework=${res.map.project.framework} router=${res.map.staticTopology.router ?? 'none'} · static screens=${res.map.staticTopology.screens.length} · runtime screens=${res.map.runtimeTopology.screens.length}\n` +
101
+ (merge ? `merge: +${merge.newRuntimeScreens} new, ~${merge.updatedRuntimeScreens} updated, ${merge.linkedScreens} linked, ${merge.unmappedRuntimeScreens} unmapped\n` : '') +
102
+ `confidence=${res.map.confidence.overall} · features=${res.map.features.length}\n` +
103
+ (Array.isArray(summary.topGaps) && summary.topGaps.length ? `gaps: ${summary.topGaps.join('; ')}\n` : '') +
104
+ `appMapUri: ${res.save?.resourceUri}`;
105
+ return qaOk({
106
+ appMapUri: res.save?.resourceUri,
107
+ appMapPath: res.save?.path,
108
+ mode: m,
109
+ rescanned: res.rescanned,
110
+ staticScreens: res.map.staticTopology.screens.length,
111
+ runtimeScreens: res.map.runtimeTopology.screens.length,
112
+ mergeResult: merge ?? null,
113
+ migration: res.migration ? { migratedFrom: res.migration.migratedFrom, applied: res.migration.applied } : null,
114
+ summary,
115
+ }, text);
116
+ }
117
+ catch (e) {
118
+ return qaError({ what: `App map build failed: ${String(e)}`, changedState: false, retrySafe: true, nextSteps: ['Check the project root is a supported mobile project.'] });
119
+ }
120
+ });
121
+ // ------------------------------------------------------------------- read
122
+ server.registerTool('qa_app_map_read', {
123
+ title: 'Read the app knowledge map',
124
+ description: 'Return a COMPACT section of the app map (default summary). Sections: summary | screens | features | auth | automation | testSuite | full. Pass featureId or screenId to drill into one node. The full map and large sections are returned by resource URI to protect context — fetch it with qa_get_artifact / the resource when you need everything.',
125
+ inputSchema: {
126
+ projectRoot: z.string().optional(),
127
+ sessionId: z.string().optional(),
128
+ section: z.enum(['summary', 'screens', 'features', 'auth', 'automation', 'testSuite', 'full']).optional(),
129
+ featureId: z.string().optional(),
130
+ screenId: z.string().optional(),
131
+ },
132
+ outputSchema: { ok: z.boolean(), appMapUri: z.string().optional(), section: z.string().optional() },
133
+ }, async ({ projectRoot, sessionId, section, featureId, screenId }) => {
134
+ const { root, hint } = await rootFor(server, sessions, { projectRoot, sessionId });
135
+ if (!root)
136
+ return qaError({ what: 'Could not resolve a project root', changedState: false, retrySafe: true, nextSteps: ['Pass projectRoot or sessionId.'], clientHint: hint });
137
+ remember(root);
138
+ const map = readExistingMap(root);
139
+ if (!map)
140
+ return qaError({ what: 'No app map yet', changedState: false, retrySafe: true, nextSteps: ['Run qa_app_map_build first.'], failureCode: 'NO_APP_MAP' });
141
+ const uri = appMapResourceUri(root);
142
+ const sec = section ?? 'summary';
143
+ if (featureId) {
144
+ const f = map.features.find((x) => x.id === featureId);
145
+ if (!f)
146
+ return qaError({ what: `Unknown featureId ${featureId}`, changedState: false, retrySafe: true, nextSteps: ['Call qa_app_map_read { section:"features" } to list ids.'] });
147
+ return qaOk({ appMapUri: uri, section: 'feature', feature: f, featureResourceUri: `${uri}/feature/${featureId}` }, `feature ${f.title} — ${f.testCoverage} coverage, ${f.status}, confidence ${f.confidence}`);
148
+ }
149
+ if (screenId) {
150
+ const s = map.staticTopology.screens.find((x) => x.id === screenId);
151
+ const r = map.runtimeTopology.screens.find((x) => x.id === screenId);
152
+ if (!s && !r)
153
+ return qaError({ what: `Unknown screenId ${screenId}`, changedState: false, retrySafe: true, nextSteps: ['Call qa_app_map_read { section:"screens" } to list ids.'] });
154
+ return qaOk({ appMapUri: uri, section: 'screen', staticScreen: s ?? null, runtimeScreen: r ?? null, screenResourceUri: `${uri}/screen/${screenId}` }, `screen ${screenId}`);
155
+ }
156
+ switch (sec) {
157
+ case 'summary':
158
+ return qaOk({ appMapUri: uri, section: sec, summary: summarizeMap(map) }, `app map summary (${map.staticTopology.screens.length} static / ${map.runtimeTopology.screens.length} runtime screens). Full map: ${uri}`);
159
+ case 'screens':
160
+ return qaOk({
161
+ appMapUri: uri,
162
+ section: sec,
163
+ staticScreens: map.staticTopology.screens.map((s) => ({ id: s.id, name: s.name, route: s.route, kind: s.kind, confidence: s.confidence })),
164
+ runtimeScreens: map.runtimeTopology.screens.map((r) => ({ id: r.id, title: r.title, visits: r.visits, linkedStaticScreenId: r.linkedStaticScreenId, unmapped: r.unmapped, locatorReadiness: r.locatorReadiness })),
165
+ unvisitedStaticScreens: map.runtimeTopology.unvisitedStaticScreens,
166
+ }, `${map.staticTopology.screens.length} static / ${map.runtimeTopology.screens.length} runtime screens; ${map.runtimeTopology.unvisitedStaticScreens.length} unvisited`);
167
+ case 'features':
168
+ return qaOk({ appMapUri: uri, section: sec, features: map.features }, `${map.features.length} features`);
169
+ case 'auth':
170
+ return qaOk({ appMapUri: uri, section: sec, auth: map.auth, onboarding: map.onboarding, paywalls: map.paywalls }, `auth=${map.auth.hasAuth} onboarding=${!!map.onboarding} paywalls=${map.paywalls.length}`);
171
+ case 'automation':
172
+ return qaOk({ appMapUri: uri, section: sec, automation: map.automation }, `${map.automation.suites.length} suite(s), ${map.automation.flows.length} flow(s)`);
173
+ case 'testSuite':
174
+ return qaOk({ appMapUri: uri, section: sec, testSuite: map.testSuite }, `${map.testSuite.cases.length} test case(s)`);
175
+ case 'full':
176
+ default:
177
+ // Protect context: point at the resource instead of inlining the whole map.
178
+ return qaOk({ appMapUri: uri, section: 'full', summary: summarizeMap(map), note: 'Full map omitted from text to protect context — read the appMapUri resource for everything.' }, `Full map at resource: ${uri}`);
179
+ }
180
+ });
181
+ // ------------------------------------------------------------------ query
182
+ server.registerTool('qa_app_map_query', {
183
+ title: 'Query the app knowledge map',
184
+ description: 'Search the feature index, static topology, runtime graph, and tests for a natural-language query (e.g. "checkout flow"). Returns ranked results with provenance, confidence, source files, screens, and the recommended next Swipium tool call for each. Pass intent to bias the search.',
185
+ inputSchema: {
186
+ query: z.string(),
187
+ projectRoot: z.string().optional(),
188
+ sessionId: z.string().optional(),
189
+ intent: z.enum(['feature', 'screen', 'code', 'test', 'freeform']).optional(),
190
+ limit: z.number().optional(),
191
+ },
192
+ outputSchema: { ok: z.boolean(), total: z.number().optional() },
193
+ }, async ({ query, projectRoot, sessionId, intent, limit }) => {
194
+ const { root, hint } = await rootFor(server, sessions, { projectRoot, sessionId });
195
+ if (!root)
196
+ return qaError({ what: 'Could not resolve a project root', changedState: false, retrySafe: true, nextSteps: ['Pass projectRoot or sessionId.'], clientHint: hint });
197
+ remember(root);
198
+ const map = readExistingMap(root);
199
+ if (!map)
200
+ return qaError({ what: 'No app map yet', changedState: false, retrySafe: true, nextSteps: ['Run qa_app_map_build first.'], failureCode: 'NO_APP_MAP' });
201
+ const codeIndex = loadCodeIndex(root);
202
+ const out = queryAppMap(map, codeIndex, { query, intent, limit });
203
+ const top = out.results.slice(0, 5).map((r, i) => ` ${i + 1}. [${r.type}] ${r.title} (score ${r.score}${r.confidence !== undefined ? `, conf ${r.confidence}` : ''}) → ${r.recommendedNextTool.tool}`).join('\n');
204
+ return qaOk({ ...out, appMapUri: appMapResourceUri(root) }, `🔎 "${query}" — ${out.total} result(s)\n${top || ' (no matches)'}`);
205
+ });
206
+ // ----------------------------------------------------------- feature_scope
207
+ server.registerTool('qa_app_map_feature_scope', {
208
+ title: 'Scope testing to a feature',
209
+ description: 'Resolve a feature (by featureId or free-text query) to a focused test scope: its source files, static + runtime screens, current coverage, blockers, and a recommended Swipium plan.',
210
+ inputSchema: {
211
+ projectRoot: z.string().optional(),
212
+ sessionId: z.string().optional(),
213
+ featureId: z.string().optional(),
214
+ query: z.string().optional().describe('Free-text feature description, e.g. "checkout flow".'),
215
+ },
216
+ outputSchema: { ok: z.boolean(), featureId: z.string().optional() },
217
+ }, async ({ projectRoot, sessionId, featureId, query }) => {
218
+ const { root, hint } = await rootFor(server, sessions, { projectRoot, sessionId });
219
+ if (!root)
220
+ return qaError({ what: 'Could not resolve a project root', changedState: false, retrySafe: true, nextSteps: ['Pass projectRoot or sessionId.'], clientHint: hint });
221
+ remember(root);
222
+ const map = readExistingMap(root);
223
+ if (!map)
224
+ return qaError({ what: 'No app map yet', changedState: false, retrySafe: true, nextSteps: ['Run qa_app_map_build first.'], failureCode: 'NO_APP_MAP' });
225
+ let features = map.features;
226
+ if (featureId) {
227
+ features = map.features.filter((f) => f.id === featureId);
228
+ if (!features.length)
229
+ return qaError({ what: `Unknown featureId ${featureId}`, changedState: false, retrySafe: true, nextSteps: ['List ids with qa_app_map_read { section:"features" }.'] });
230
+ }
231
+ else if (query) {
232
+ const out = queryAppMap(map, loadCodeIndex(root), { query, intent: 'feature', limit: 5 });
233
+ const ids = new Set(out.results.filter((r) => r.type === 'feature').map((r) => r.id));
234
+ features = map.features.filter((f) => ids.has(f.id));
235
+ if (!features.length)
236
+ return qaError({ what: `No feature matched "${query}"`, changedState: false, retrySafe: true, nextSteps: ['Try qa_app_map_query for broader matches, or qa_app_map_build to refresh.'] });
237
+ }
238
+ else {
239
+ return qaError({ what: 'Provide one of: featureId or query', changedState: false, retrySafe: true, nextSteps: ['e.g. qa_app_map_feature_scope { query:"login" }'] });
240
+ }
241
+ const scope = features.map((f) => {
242
+ const staticScreens = f.staticScreens.map((id) => map.staticTopology.screens.find((s) => s.id === id)).filter(Boolean).map((s) => ({ id: s.id, name: s.name, route: s.route, sourceFiles: s.sourceFiles }));
243
+ const needsCreds = f.id === 'feature:auth' || f.blockers.some((b) => /credential/i.test(b));
244
+ const recommendedGoal = f.id === 'feature:auth' ? 'test_login' : 'reproduce_bug';
245
+ return {
246
+ featureId: f.id,
247
+ title: f.title,
248
+ objective: f.objective,
249
+ status: f.status,
250
+ confidence: f.confidence,
251
+ riskLevel: f.riskLevel,
252
+ testCoverage: f.testCoverage,
253
+ sourceFiles: f.sourceFiles.slice(0, 12),
254
+ staticScreens,
255
+ runtimeScreens: f.runtimeScreens,
256
+ blockers: f.blockers,
257
+ recommendedPlan: {
258
+ tool: 'qa_test_this',
259
+ args: { mode: 'execute', goal: recommendedGoal, goalText: f.title, explore: true, ...(needsCreds ? { stopOnNeedsInput: true } : {}) },
260
+ why: needsCreds ? `Drive "${f.title}"; will stop for test credentials (fixture) — ${f.testCoverage} coverage today` : `Drive "${f.title}" with focused exploration — ${f.testCoverage} coverage today`,
261
+ },
262
+ };
263
+ });
264
+ const text = `scope: ${scope.length} feature(s)\n` +
265
+ scope.map((s) => ` • ${s.title} [${s.testCoverage}] — ${s.staticScreens.length} screen(s), ${s.sourceFiles.length} file(s)${s.blockers.length ? ` · blockers: ${s.blockers.join(', ')}` : ''}\n → ${s.recommendedPlan.tool} ${JSON.stringify(s.recommendedPlan.args)}`).join('\n');
266
+ return qaOk({ appMapUri: appMapResourceUri(root), featureId: scope[0]?.featureId, scope }, text);
267
+ });
268
+ // --------------------------------------------------------------- validate
269
+ server.registerTool('qa_app_map_validate', {
270
+ title: 'Validate the app knowledge map',
271
+ description: 'Validate the app map: schema version, provenance completeness, missing/dangling links, duplicate ids, impossible states (e.g. covered-without-runtime), and (optionally) stale source fingerprints. Returns errors + warnings with codes. Use before trusting an old map for feature-focused testing.',
272
+ inputSchema: {
273
+ projectRoot: z.string().optional(),
274
+ sessionId: z.string().optional(),
275
+ checkFingerprint: z.boolean().optional().describe('Also re-hash fingerprinted source files to detect a stale map (default false).'),
276
+ },
277
+ outputSchema: { ok: z.boolean(), valid: z.boolean().optional(), errors: z.number().optional(), warnings: z.number().optional() },
278
+ }, async ({ projectRoot, sessionId, checkFingerprint }) => {
279
+ const { root, hint } = await rootFor(server, sessions, { projectRoot, sessionId });
280
+ if (!root)
281
+ return qaError({ what: 'Could not resolve a project root', changedState: false, retrySafe: true, nextSteps: ['Pass projectRoot or sessionId.'], clientHint: hint });
282
+ remember(root);
283
+ const map = readExistingMap(root);
284
+ if (!map)
285
+ return qaError({ what: 'No app map yet', changedState: false, retrySafe: true, nextSteps: ['Run qa_app_map_build first.'], failureCode: 'NO_APP_MAP' });
286
+ const v = validateAppMap(map, { checkFingerprint, root });
287
+ const text = `${v.ok ? '✅' : '❌'} app map ${v.ok ? 'valid' : 'INVALID'} — ${v.errors} error(s), ${v.warnings} warning(s)\n` +
288
+ v.issues.slice(0, 12).map((i) => ` ${i.severity === 'error' ? '✗' : '⚠'} ${i.code}: ${i.detail}`).join('\n');
289
+ return qaOk({ valid: v.ok, errors: v.errors, warnings: v.warnings, issues: v.issues, appMapUri: appMapResourceUri(root) }, text);
290
+ });
291
+ }
292
+ /** Resolve a feature/screen/test-suite/full app-map resource read for the MCP resource handler.
293
+ * Routes through loadAppMap() so an older on-disk shape is MIGRATED before it is served (Fix 8). */
294
+ export function readAppMapResource(root, sub) {
295
+ const path = appMapPath(root);
296
+ if (!existsSync(path))
297
+ return null;
298
+ const loaded = loadAppMap(root, fallbackProject(root), nowIso());
299
+ const map = loaded.map;
300
+ if (!map)
301
+ return null;
302
+ if (!sub.kind)
303
+ return { mimeType: 'application/json', text: JSON.stringify(map, null, 2) };
304
+ if (sub.kind === 'feature') {
305
+ const f = map.features.find((x) => x.id === sub.id || x.id === `feature:${sub.id}`);
306
+ return f ? { mimeType: 'application/json', text: JSON.stringify(f, null, 2) } : null;
307
+ }
308
+ if (sub.kind === 'screen') {
309
+ const s = map.staticTopology.screens.find((x) => x.id === sub.id) ?? map.runtimeTopology.screens.find((x) => x.id === sub.id);
310
+ return s ? { mimeType: 'application/json', text: JSON.stringify(s, null, 2) } : null;
311
+ }
312
+ if (sub.kind === 'test-suite') {
313
+ return { mimeType: 'application/json', text: JSON.stringify(map.testSuite, null, 2) };
314
+ }
315
+ return null;
316
+ }
317
+ //# sourceMappingURL=appMap.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"appMap.js","sourceRoot":"","sources":["../../src/tools/appMap.ts"],"names":[],"mappings":"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"}