swipium 1.4.0 → 2.0.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +313 -0
- package/README.md +175 -219
- package/THREAT_MODEL.md +223 -47
- package/dist/appMap/automationLink.js +39 -26
- package/dist/appMap/automationLink.js.map +1 -1
- package/dist/appMap/build.js +68 -20
- package/dist/appMap/build.js.map +1 -1
- package/dist/appMap/codeIndex.js +31 -5
- package/dist/appMap/codeIndex.js.map +1 -1
- package/dist/appMap/featureIndex.js +23 -5
- package/dist/appMap/featureIndex.js.map +1 -1
- package/dist/appMap/featureModel.js +44 -8
- package/dist/appMap/featureModel.js.map +1 -1
- package/dist/appMap/firstRunApply.js +24 -6
- package/dist/appMap/firstRunApply.js.map +1 -1
- package/dist/appMap/fsWalk.js +19 -2
- package/dist/appMap/fsWalk.js.map +1 -1
- package/dist/appMap/issues.js +10 -30
- package/dist/appMap/issues.js.map +1 -1
- package/dist/appMap/migrations.js +6 -6
- package/dist/appMap/migrations.js.map +1 -1
- package/dist/appMap/prelaunch.js +2 -2
- package/dist/appMap/prelaunch.js.map +1 -1
- package/dist/appMap/projectRegistry.js +83 -11
- package/dist/appMap/projectRegistry.js.map +1 -1
- package/dist/appMap/provenance.js +2 -2
- package/dist/appMap/provenance.js.map +1 -1
- package/dist/appMap/query.js +21 -5
- package/dist/appMap/query.js.map +1 -1
- package/dist/appMap/runtimeMerge.js +12 -5
- package/dist/appMap/runtimeMerge.js.map +1 -1
- package/dist/appMap/schema.js +1 -1
- package/dist/appMap/schema.js.map +1 -1
- package/dist/appMap/screenMatch.js +6 -2
- package/dist/appMap/screenMatch.js.map +1 -1
- package/dist/appMap/staticScan.js +151 -39
- package/dist/appMap/staticScan.js.map +1 -1
- package/dist/appMap/store.js +58 -85
- package/dist/appMap/store.js.map +1 -1
- package/dist/appMap/tsAstScan.js +34 -12
- package/dist/appMap/tsAstScan.js.map +1 -1
- package/dist/artifacts/bundletool.js +49 -12
- package/dist/artifacts/bundletool.js.map +1 -1
- package/dist/artifacts/resolve.js +41 -14
- package/dist/artifacts/resolve.js.map +1 -1
- package/dist/automation/capabilities.js +112 -30
- package/dist/automation/capabilities.js.map +1 -1
- package/dist/automation/gestures.js +6 -2
- package/dist/automation/gestures.js.map +1 -1
- package/dist/automation/plan.js +71 -23
- package/dist/automation/plan.js.map +1 -1
- package/dist/automation/report.js +15 -5
- package/dist/automation/report.js.map +1 -1
- package/dist/automation/selectors.js +22 -28
- package/dist/automation/selectors.js.map +1 -1
- package/dist/automation/types.js +1 -1
- package/dist/automation/types.js.map +1 -1
- package/dist/automation/waits.js +14 -8
- package/dist/automation/waits.js.map +1 -1
- package/dist/automation/webview.js +9 -3
- package/dist/automation/webview.js.map +1 -1
- package/dist/automationGen/appiumModel.js +16 -8
- package/dist/automationGen/appiumModel.js.map +1 -1
- package/dist/automationGen/ciEmitter.js +6 -6
- package/dist/automationGen/ciEmitter.js.map +1 -1
- package/dist/automationGen/identifiers.js +224 -0
- package/dist/automationGen/identifiers.js.map +1 -0
- package/dist/automationGen/jsEmitter.js +288 -121
- package/dist/automationGen/jsEmitter.js.map +1 -1
- package/dist/automationGen/packagePatch.js +2 -2
- package/dist/automationGen/packagePatch.js.map +1 -1
- package/dist/automationGen/platformResolve.js +36 -0
- package/dist/automationGen/platformResolve.js.map +1 -0
- package/dist/automationGen/projectProfile.js +76 -27
- package/dist/automationGen/projectProfile.js.map +1 -1
- package/dist/automationGen/pythonEmitter.js +278 -107
- package/dist/automationGen/pythonEmitter.js.map +1 -1
- package/dist/automationGen/readmeEmitter.js +7 -6
- package/dist/automationGen/readmeEmitter.js.map +1 -1
- package/dist/automationGen/run.js +388 -0
- package/dist/automationGen/run.js.map +1 -0
- package/dist/automationGen/suitePlan.js +17 -10
- package/dist/automationGen/suitePlan.js.map +1 -1
- package/dist/automationGen/validation.js +52 -12
- package/dist/automationGen/validation.js.map +1 -1
- package/dist/build/parseBuildLog.js +235 -31
- package/dist/build/parseBuildLog.js.map +1 -1
- package/dist/build/plan.js +39 -18
- package/dist/build/plan.js.map +1 -1
- package/dist/ci/preflight.js +13 -4
- package/dist/ci/preflight.js.map +1 -1
- package/dist/cli/gc.js +74 -0
- package/dist/cli/gc.js.map +1 -0
- package/dist/cli/init.js +217 -26
- package/dist/cli/init.js.map +1 -1
- package/dist/cli/main.js +50 -0
- package/dist/cli/main.js.map +1 -0
- package/dist/cli/report.js +218 -0
- package/dist/cli/report.js.map +1 -0
- package/dist/cli/scan.js +36 -15
- package/dist/cli/scan.js.map +1 -1
- package/dist/cli/suite.js +7 -7
- package/dist/cli/suite.js.map +1 -1
- package/dist/cli/verify.js +7 -7
- package/dist/cli/verify.js.map +1 -1
- package/dist/consent/consent.js +162 -5
- package/dist/consent/consent.js.map +1 -1
- package/dist/context/detect.js +55 -18
- package/dist/context/detect.js.map +1 -1
- package/dist/context/findApps.js +22 -8
- package/dist/context/findApps.js.map +1 -1
- package/dist/context/projectRoot.js +174 -19
- package/dist/context/projectRoot.js.map +1 -1
- package/dist/context/scan.js +1 -1
- package/dist/context/scan.js.map +1 -1
- package/dist/core/capabilityGroups.js +90 -0
- package/dist/core/capabilityGroups.js.map +1 -0
- package/dist/core/target.js +10 -8
- package/dist/core/target.js.map +1 -1
- package/dist/core/targetPlan.js +160 -39
- package/dist/core/targetPlan.js.map +1 -1
- package/dist/drivers/DirectDriver.js +317 -43
- package/dist/drivers/DirectDriver.js.map +1 -1
- package/dist/drivers/SimctlDriver.js +124 -8
- package/dist/drivers/SimctlDriver.js.map +1 -1
- package/dist/drivers/WdaDriver.js +365 -55
- package/dist/drivers/WdaDriver.js.map +1 -1
- package/dist/explore/candidates.js +7 -3
- package/dist/explore/candidates.js.map +1 -1
- package/dist/explore/graph.js +15 -6
- package/dist/explore/graph.js.map +1 -1
- package/dist/explore/memory.js +4 -1
- package/dist/explore/memory.js.map +1 -1
- package/dist/explore/planner.js +54 -9
- package/dist/explore/planner.js.map +1 -1
- package/dist/explore/policy.js +11 -6
- package/dist/explore/policy.js.map +1 -1
- package/dist/explore/runner.js +363 -190
- package/dist/explore/runner.js.map +1 -1
- package/dist/explore/signatures.js +4 -2
- package/dist/explore/signatures.js.map +1 -1
- package/dist/explore/suite.js +3 -1
- package/dist/explore/suite.js.map +1 -1
- package/dist/featureTesting/executionBootstrap.js +137 -29
- package/dist/featureTesting/executionBootstrap.js.map +1 -1
- package/dist/featureTesting/featureMap.js +6 -3
- package/dist/featureTesting/featureMap.js.map +1 -1
- package/dist/featureTesting/featureScope.js +101 -20
- package/dist/featureTesting/featureScope.js.map +1 -1
- package/dist/featureTesting/mapFeatureScope.js +44 -15
- package/dist/featureTesting/mapFeatureScope.js.map +1 -1
- package/dist/featureTesting/objectiveModel.js +15 -11
- package/dist/featureTesting/objectiveModel.js.map +1 -1
- package/dist/featureTesting/resultMerge.js +16 -8
- package/dist/featureTesting/resultMerge.js.map +1 -1
- package/dist/featureTesting/sources.js +8 -5
- package/dist/featureTesting/sources.js.map +1 -1
- package/dist/featureTesting/suiteBridge.js +8 -2
- package/dist/featureTesting/suiteBridge.js.map +1 -1
- package/dist/featureTesting/synonyms.js +32 -4
- package/dist/featureTesting/synonyms.js.map +1 -1
- package/dist/featureTesting/testCaseFactory.js +27 -15
- package/dist/featureTesting/testCaseFactory.js.map +1 -1
- package/dist/featureTesting/testPlan.js +34 -12
- package/dist/featureTesting/testPlan.js.map +1 -1
- package/dist/firstRun/authStateMachine.js +1 -1
- package/dist/firstRun/authStateMachine.js.map +1 -1
- package/dist/firstRun/classifyScreen.js +9 -6
- package/dist/firstRun/classifyScreen.js.map +1 -1
- package/dist/firstRun/firstRunPlanner.js +16 -13
- package/dist/firstRun/firstRunPlanner.js.map +1 -1
- package/dist/firstRun/firstRunRunner.js +92 -31
- package/dist/firstRun/firstRunRunner.js.map +1 -1
- package/dist/firstRun/generatedDataPolicy.js +25 -15
- package/dist/firstRun/generatedDataPolicy.js.map +1 -1
- package/dist/firstRun/inputPlanner.js +45 -11
- package/dist/firstRun/inputPlanner.js.map +1 -1
- package/dist/firstRun/onboardingStateMachine.js +1 -1
- package/dist/firstRun/onboardingStateMachine.js.map +1 -1
- package/dist/firstRun/paywallPolicy.js +3 -3
- package/dist/firstRun/paywallPolicy.js.map +1 -1
- package/dist/firstRun/types.js +1 -1
- package/dist/firstRun/types.js.map +1 -1
- package/dist/fixtures/catalog.js +72 -9
- package/dist/fixtures/catalog.js.map +1 -1
- package/dist/fixtures/load.js +50 -0
- package/dist/fixtures/load.js.map +1 -0
- package/dist/flows/discover.js +2 -2
- package/dist/flows/discover.js.map +1 -1
- package/dist/flows/generate.js +68 -17
- package/dist/flows/generate.js.map +1 -1
- package/dist/flows/lint.js +88 -14
- package/dist/flows/lint.js.map +1 -1
- package/dist/flows/pack.js +21 -5
- package/dist/flows/pack.js.map +1 -1
- package/dist/flows/paths.js +57 -0
- package/dist/flows/paths.js.map +1 -0
- package/dist/flows/repair.js +176 -37
- package/dist/flows/repair.js.map +1 -1
- package/dist/flows/run.js +308 -99
- package/dist/flows/run.js.map +1 -1
- package/dist/flows/schema.js +107 -25
- package/dist/flows/schema.js.map +1 -1
- package/dist/flows/seedExec.js +8 -4
- package/dist/flows/seedExec.js.map +1 -1
- package/dist/flows/templates.js +5 -5
- package/dist/index.js +50 -8
- package/dist/index.js.map +1 -1
- package/dist/ios/signing.js +32 -3
- package/dist/ios/signing.js.map +1 -1
- package/dist/issues/classify.js +28 -20
- package/dist/issues/classify.js.map +1 -1
- package/dist/issues/fingerprint.js +35 -9
- package/dist/issues/fingerprint.js.map +1 -1
- package/dist/issues/index.js +93 -46
- package/dist/issues/index.js.map +1 -1
- package/dist/issues/metrics.js +6 -5
- package/dist/issues/metrics.js.map +1 -1
- package/dist/issues/recurrence.js +35 -8
- package/dist/issues/recurrence.js.map +1 -1
- package/dist/issues/report.js +12 -8
- package/dist/issues/report.js.map +1 -1
- package/dist/issues/reportBridge.js +40 -9
- package/dist/issues/reportBridge.js.map +1 -1
- package/dist/issues/schema.js +2 -2
- package/dist/issues/schema.js.map +1 -1
- package/dist/issues/sourceRevision.js +2 -2
- package/dist/issues/sourceRevision.js.map +1 -1
- package/dist/issues/store.js +110 -32
- package/dist/issues/store.js.map +1 -1
- package/dist/lib/abortScope.js +48 -0
- package/dist/lib/abortScope.js.map +1 -0
- package/dist/lib/android.js +84 -8
- package/dist/lib/android.js.map +1 -1
- package/dist/lib/coordSpace.js +1 -1
- package/dist/lib/coordSpace.js.map +1 -1
- package/dist/lib/device.js +53 -12
- package/dist/lib/device.js.map +1 -1
- package/dist/lib/gestures.js +141 -0
- package/dist/lib/gestures.js.map +1 -0
- package/dist/lib/gitignore.js +4 -3
- package/dist/lib/gitignore.js.map +1 -1
- package/dist/lib/image.js +12 -3
- package/dist/lib/image.js.map +1 -1
- package/dist/lib/lockfile.js +399 -0
- package/dist/lib/lockfile.js.map +1 -0
- package/dist/lib/needsInput.js +9 -6
- package/dist/lib/needsInput.js.map +1 -1
- package/dist/lib/png.js +4 -3
- package/dist/lib/png.js.map +1 -1
- package/dist/lib/redact.js +170 -9
- package/dist/lib/redact.js.map +1 -1
- package/dist/lib/result.js +94 -10
- package/dist/lib/result.js.map +1 -1
- package/dist/lib/schemaHash.js +7 -5
- package/dist/lib/schemaHash.js.map +1 -1
- package/dist/lib/sensitive.js +6 -3
- package/dist/lib/sensitive.js.map +1 -1
- package/dist/lib/simctl.js +3 -3
- package/dist/lib/simctl.js.map +1 -1
- package/dist/lib/spawn.js +78 -17
- package/dist/lib/spawn.js.map +1 -1
- package/dist/lib/toolAnnotations.js +114 -0
- package/dist/lib/toolAnnotations.js.map +1 -0
- package/dist/lib/wda.js +321 -25
- package/dist/lib/wda.js.map +1 -1
- package/dist/lib/wdaConfig.js +12 -5
- package/dist/lib/wdaConfig.js.map +1 -1
- package/dist/lib/wdaTune.js +52 -23
- package/dist/lib/wdaTune.js.map +1 -1
- package/dist/mobileAudit/checks.js +150 -28
- package/dist/mobileAudit/checks.js.map +1 -1
- package/dist/mobileAudit/evidence.js +4 -4
- package/dist/mobileAudit/evidence.js.map +1 -1
- package/dist/mobileAudit/profiles.js +121 -20
- package/dist/mobileAudit/profiles.js.map +1 -1
- package/dist/mobileAudit/results.js +9 -4
- package/dist/mobileAudit/results.js.map +1 -1
- package/dist/mobileAudit/runner.js +214 -35
- package/dist/mobileAudit/runner.js.map +1 -1
- package/dist/oracle/auth.js +1 -1
- package/dist/oracle/auth.js.map +1 -1
- package/dist/oracle/failures.js +1085 -145
- package/dist/oracle/failures.js.map +1 -1
- package/dist/oracle/health.js +148 -26
- package/dist/oracle/health.js.map +1 -1
- package/dist/oracle/locator.js +148 -19
- package/dist/oracle/locator.js.map +1 -1
- package/dist/oracle/record.js +3 -3
- package/dist/oracle/record.js.map +1 -1
- package/dist/orchestration/envelope.js +2 -2
- package/dist/orchestration/envelope.js.map +1 -1
- package/dist/orchestration/goal.js +7 -13
- package/dist/orchestration/goal.js.map +1 -1
- package/dist/orchestration/testThis/execute.js +167 -0
- package/dist/orchestration/testThis/execute.js.map +1 -0
- package/dist/orchestration/testThis/pipeline.js +413 -0
- package/dist/orchestration/testThis/pipeline.js.map +1 -0
- package/dist/orchestration/testThis/plan.js +519 -0
- package/dist/orchestration/testThis/plan.js.map +1 -0
- package/dist/orchestration/testThis/sessionIntent.js +72 -0
- package/dist/orchestration/testThis/sessionIntent.js.map +1 -0
- package/dist/orchestration/testThis/terminal.js +136 -0
- package/dist/orchestration/testThis/terminal.js.map +1 -0
- package/dist/orchestration/testThis/types.js +12 -0
- package/dist/orchestration/testThis/types.js.map +1 -0
- package/dist/plan/plan.js +9 -9
- package/dist/plan/plan.js.map +1 -1
- package/dist/prompts/index.js +24 -24
- package/dist/prompts/index.js.map +1 -1
- package/dist/report/coverage.js +0 -1
- package/dist/report/coverage.js.map +1 -1
- package/dist/report/evidence.js.map +1 -1
- package/dist/report/export.js +449 -72
- package/dist/report/export.js.map +1 -1
- package/dist/report/findingsDedupe.js +41 -0
- package/dist/report/findingsDedupe.js.map +1 -0
- package/dist/report/flake.js +13 -14
- package/dist/report/flake.js.map +1 -1
- package/dist/report/history.js +72 -38
- package/dist/report/history.js.map +1 -1
- package/dist/report/policy.js +18 -7
- package/dist/report/policy.js.map +1 -1
- package/dist/report/qaLevel.js +10 -16
- package/dist/report/qaLevel.js.map +1 -1
- package/dist/report/readiness.js +42 -12
- package/dist/report/readiness.js.map +1 -1
- package/dist/report/sarifSources.js +160 -0
- package/dist/report/sarifSources.js.map +1 -0
- package/dist/report/summary.js +2 -2
- package/dist/report/summary.js.map +1 -1
- package/dist/report/testCatalog.js +4 -4
- package/dist/report/testCatalog.js.map +1 -1
- package/dist/report/timing.js +23 -23
- package/dist/report/timing.js.map +1 -1
- package/dist/report/toolHealth.js +124 -0
- package/dist/report/toolHealth.js.map +1 -0
- package/dist/server.js +501 -69
- package/dist/server.js.map +1 -1
- package/dist/services/automationGenerate.js +8 -2
- package/dist/services/automationGenerate.js.map +1 -1
- package/dist/services/build.js +10 -4
- package/dist/services/build.js.map +1 -1
- package/dist/services/flowGenerate.js +75 -0
- package/dist/services/flowGenerate.js.map +1 -0
- package/dist/services/preflight.js +40 -8
- package/dist/services/preflight.js.map +1 -1
- package/dist/services/prepareAndroid.js +92 -18
- package/dist/services/prepareAndroid.js.map +1 -1
- package/dist/services/prepareIos.js +94 -17
- package/dist/services/prepareIos.js.map +1 -1
- package/dist/services/report.js +271 -80
- package/dist/services/report.js.map +1 -1
- package/dist/services/smoke.js +68 -22
- package/dist/services/smoke.js.map +1 -1
- package/dist/services/suiteGenerate.js +43 -6
- package/dist/services/suiteGenerate.js.map +1 -1
- package/dist/services/testSuiteKnowledge.js +78 -33
- package/dist/services/testSuiteKnowledge.js.map +1 -1
- package/dist/session/attach.js +284 -4
- package/dist/session/attach.js.map +1 -1
- package/dist/session/processRegistry.js +433 -0
- package/dist/session/processRegistry.js.map +1 -0
- package/dist/session/progress.js +1 -1
- package/dist/session/progress.js.map +1 -1
- package/dist/session/retention.js +201 -0
- package/dist/session/retention.js.map +1 -0
- package/dist/session/store.js +459 -59
- package/dist/session/store.js.map +1 -1
- package/dist/snapshot/overlays.js +60 -10
- package/dist/snapshot/overlays.js.map +1 -1
- package/dist/snapshot/parse.js +30 -12
- package/dist/snapshot/parse.js.map +1 -1
- package/dist/snapshot/present.js +36 -6
- package/dist/snapshot/present.js.map +1 -1
- package/dist/snapshot/settle.js +39 -9
- package/dist/snapshot/settle.js.map +1 -1
- package/dist/state/consent.js +99 -0
- package/dist/state/consent.js.map +1 -0
- package/dist/state/profile.js +82 -11
- package/dist/state/profile.js.map +1 -1
- package/dist/suite/compile.js +15 -6
- package/dist/suite/compile.js.map +1 -1
- package/dist/suite/lint.js +22 -4
- package/dist/suite/lint.js.map +1 -1
- package/dist/suite/pom.js +75 -44
- package/dist/suite/pom.js.map +1 -1
- package/dist/suite/secretGuard.js +266 -0
- package/dist/suite/secretGuard.js.map +1 -0
- package/dist/suite/testcase.js +15 -11
- package/dist/suite/testcase.js.map +1 -1
- package/dist/testSuite/exporter.js +7 -3
- package/dist/testSuite/exporter.js.map +1 -1
- package/dist/testSuite/generator.js +43 -14
- package/dist/testSuite/generator.js.map +1 -1
- package/dist/testSuite/history.js +1 -1
- package/dist/testSuite/history.js.map +1 -1
- package/dist/testSuite/issueLinks.js +3 -3
- package/dist/testSuite/issueLinks.js.map +1 -1
- package/dist/testSuite/lint.js +4 -4
- package/dist/testSuite/lint.js.map +1 -1
- package/dist/testSuite/merge.js +13 -7
- package/dist/testSuite/merge.js.map +1 -1
- package/dist/testSuite/schema.js +21 -16
- package/dist/testSuite/schema.js.map +1 -1
- package/dist/testSuite/store.js +12 -4
- package/dist/testSuite/store.js.map +1 -1
- package/dist/testSuite/traceability.js +2 -2
- package/dist/testSuite/traceability.js.map +1 -1
- package/dist/tools/act.js +868 -174
- package/dist/tools/act.js.map +1 -1
- package/dist/tools/agent.js +521 -112
- package/dist/tools/agent.js.map +1 -1
- package/dist/tools/appControl.js +82 -19
- package/dist/tools/appControl.js.map +1 -1
- package/dist/tools/appMap.js +393 -189
- package/dist/tools/appMap.js.map +1 -1
- package/dist/tools/build.js +92 -51
- package/dist/tools/build.js.map +1 -1
- package/dist/tools/bundletool.js +141 -40
- package/dist/tools/bundletool.js.map +1 -1
- package/dist/tools/clearOverlay.js +98 -18
- package/dist/tools/clearOverlay.js.map +1 -1
- package/dist/tools/device.js +108 -19
- package/dist/tools/device.js.map +1 -1
- package/dist/tools/doctor.js +98 -35
- package/dist/tools/doctor.js.map +1 -1
- package/dist/tools/explore.js +110 -42
- package/dist/tools/explore.js.map +1 -1
- package/dist/tools/featureTesting.js +152 -130
- package/dist/tools/featureTesting.js.map +1 -1
- package/dist/tools/firstRun.js +94 -66
- package/dist/tools/firstRun.js.map +1 -1
- package/dist/tools/flow.js +347 -132
- package/dist/tools/flow.js.map +1 -1
- package/dist/tools/flowRepair.js +42 -10
- package/dist/tools/flowRepair.js.map +1 -1
- package/dist/tools/generate.js +199 -0
- package/dist/tools/generate.js.map +1 -0
- package/dist/tools/getArtifact.js +37 -8
- package/dist/tools/getArtifact.js.map +1 -1
- package/dist/tools/health.js +17 -12
- package/dist/tools/health.js.map +1 -1
- package/dist/tools/ios.js +148 -194
- package/dist/tools/ios.js.map +1 -1
- package/dist/tools/issues.js +256 -171
- package/dist/tools/issues.js.map +1 -1
- package/dist/tools/jobs.js +55 -11
- package/dist/tools/jobs.js.map +1 -1
- package/dist/tools/metro.js +84 -38
- package/dist/tools/metro.js.map +1 -1
- package/dist/tools/mobileAudit.js +83 -26
- package/dist/tools/mobileAudit.js.map +1 -1
- package/dist/tools/network.js +36 -14
- package/dist/tools/network.js.map +1 -1
- package/dist/tools/note.js +31 -17
- package/dist/tools/note.js.map +1 -1
- package/dist/tools/prepareIosTarget.js +31 -14
- package/dist/tools/prepareIosTarget.js.map +1 -1
- package/dist/tools/prepareTarget.js +193 -47
- package/dist/tools/prepareTarget.js.map +1 -1
- package/dist/tools/report.js +16 -8
- package/dist/tools/report.js.map +1 -1
- package/dist/tools/resolveArtifact.js +12 -12
- package/dist/tools/resolveArtifact.js.map +1 -1
- package/dist/tools/resolveTarget.js +81 -18
- package/dist/tools/resolveTarget.js.map +1 -1
- package/dist/tools/screenRecord.js +85 -20
- package/dist/tools/screenRecord.js.map +1 -1
- package/dist/tools/screenshot.js +42 -18
- package/dist/tools/screenshot.js.map +1 -1
- package/dist/tools/smoke.js +29 -12
- package/dist/tools/smoke.js.map +1 -1
- package/dist/tools/snapshot.js +157 -107
- package/dist/tools/snapshot.js.map +1 -1
- package/dist/tools/startSession.js +117 -84
- package/dist/tools/startSession.js.map +1 -1
- package/dist/tools/suite.js +391 -310
- package/dist/tools/suite.js.map +1 -1
- package/dist/tools/testSuite.js +112 -36
- package/dist/tools/testSuite.js.map +1 -1
- package/dist/tools/testThis.js +35 -802
- package/dist/tools/testThis.js.map +1 -1
- package/dist/tools/visual.js +698 -116
- package/dist/tools/visual.js.map +1 -1
- package/dist/tools/wait.js +9 -23
- package/dist/tools/wait.js.map +1 -1
- package/dist/tools/wda.js +312 -54
- package/dist/tools/wda.js.map +1 -1
- package/dist/version.js +37 -64
- package/dist/version.js.map +1 -1
- package/dist/visual/ocr.js +65 -8
- package/dist/visual/ocr.js.map +1 -1
- package/dist/visual/provider.js +87 -15
- package/dist/visual/provider.js.map +1 -1
- package/docs/README.md +24 -10
- package/docs/ci-reports.md +328 -0
- package/docs/concepts.md +227 -0
- package/docs/flows.md +153 -0
- package/docs/mcp-server.md +210 -104
- package/docs/physical-devices.md +84 -0
- package/docs/tools.md +808 -217
- package/package.json +16 -6
- package/dist/appMap/diff.js +0 -60
- package/dist/appMap/diff.js.map +0 -1
- package/dist/automation/maestroIr.js +0 -282
- package/dist/automation/maestroIr.js.map +0 -1
- package/dist/interop/maestro.js +0 -151
- package/dist/interop/maestro.js.map +0 -1
- package/dist/tools/assertVisual.js +0 -74
- package/dist/tools/assertVisual.js.map +0 -1
- package/dist/tools/automationGenerate.js +0 -394
- package/dist/tools/automationGenerate.js.map +0 -1
- package/dist/tools/capabilities.js +0 -209
- package/dist/tools/capabilities.js.map +0 -1
- package/dist/tools/detectContext.js +0 -41
- package/dist/tools/detectContext.js.map +0 -1
- package/dist/tools/flowGenerate.js +0 -55
- package/dist/tools/flowGenerate.js.map +0 -1
- package/dist/tools/history.js +0 -56
- package/dist/tools/history.js.map +0 -1
- package/dist/tools/idling.js +0 -104
- package/dist/tools/idling.js.map +0 -1
- package/dist/tools/inputCapabilities.js +0 -30
- package/dist/tools/inputCapabilities.js.map +0 -1
- package/dist/tools/locator.js +0 -57
- package/dist/tools/locator.js.map +0 -1
- package/dist/tools/maestro.js +0 -78
- package/dist/tools/maestro.js.map +0 -1
- package/dist/tools/permissions.js +0 -149
- package/dist/tools/permissions.js.map +0 -1
- package/dist/tools/plan.js +0 -49
- package/dist/tools/plan.js.map +0 -1
- package/dist/tools/screenInfo.js +0 -70
- package/dist/tools/screenInfo.js.map +0 -1
- package/dist/tools/seed.js +0 -101
- package/dist/tools/seed.js.map +0 -1
- package/dist/tools/state.js +0 -170
- package/dist/tools/state.js.map +0 -1
- package/dist/tools/visualText.js +0 -61
- package/dist/tools/visualText.js.map +0 -1
|
@@ -1,209 +0,0 @@
|
|
|
1
|
-
import { z } from 'zod';
|
|
2
|
-
import { qaOk } from '../lib/result.js';
|
|
3
|
-
import { SWIPIUM_VERSION, TOOL_COUNT } from '../version.js';
|
|
4
|
-
export const CAPABILITY_GROUPS = [
|
|
5
|
-
{
|
|
6
|
-
group: 'start',
|
|
7
|
-
purpose: 'Start a simulator QA run and recover from blockers.',
|
|
8
|
-
tools: [
|
|
9
|
-
{ name: 'qa_agent_brief', summary: 'Brief for agent orchestration: first call, polling, report fetch, and blocker rules.' },
|
|
10
|
-
{ name: 'qa_capabilities', summary: 'Grouped overview of the public tool surface.' },
|
|
11
|
-
{ name: 'qa_test_this', summary: 'Autopilot for "test it": resolve, prepare, smoke, explore, report, and optional suite output.' },
|
|
12
|
-
{ name: 'qa_job_status', summary: 'Poll long-running jobs started by macro tools.' },
|
|
13
|
-
{ name: 'qa_job_cancel', summary: 'Cancel a running job; aborts spawned children.' },
|
|
14
|
-
{ name: 'qa_status', summary: 'Compact session status and current next action.' },
|
|
15
|
-
{ name: 'qa_explain_blocker', summary: 'Explain a typed blocker and the owner of the fix.' },
|
|
16
|
-
{ name: 'qa_continue_from_blocker', summary: 'Resume after user input, with secret redaction.' },
|
|
17
|
-
{ name: 'qa_next_best_action', summary: 'Deterministic recommendation of the single best next tool to call, and why.' },
|
|
18
|
-
{ name: 'qa_get_artifact', summary: 'Fetch Swipium artifact metadata or contents by URI.' },
|
|
19
|
-
],
|
|
20
|
-
},
|
|
21
|
-
{
|
|
22
|
-
group: 'setup',
|
|
23
|
-
purpose: 'Resolve the project, create a session, and prepare Android Emulator or iOS Simulator targets.',
|
|
24
|
-
tools: [
|
|
25
|
-
{ name: 'qa_doctor', summary: 'Check local toolchain readiness.' },
|
|
26
|
-
{ name: 'qa_start_session', summary: 'Open a project session with budget and response mode.' },
|
|
27
|
-
{ name: 'qa_detect_context', summary: 'Detect project framework, artifacts, devices, and blockers.' },
|
|
28
|
-
{ name: 'qa_plan', summary: 'Propose safe workflows before acting.' },
|
|
29
|
-
{ name: 'qa_prepare_target', summary: 'Prepare Android Emulator target and launch an APK.' },
|
|
30
|
-
{ name: 'qa_prepare_ios_target', summary: 'Prepare iOS Simulator target and launch a simulator .app.' },
|
|
31
|
-
{ name: 'qa_ios', summary: 'iOS Simulator operations: boot, install, launch, screenshot, logs, and reset.' },
|
|
32
|
-
{ name: 'qa_wda', summary: 'WebDriverAgent attach/build/start for structured iOS Simulator automation.' },
|
|
33
|
-
],
|
|
34
|
-
},
|
|
35
|
-
{
|
|
36
|
-
group: 'build',
|
|
37
|
-
purpose: 'Resolve a device and an installable artifact, or build one from source locally.',
|
|
38
|
-
tools: [
|
|
39
|
-
{ name: 'qa_resolve_target', summary: 'Pick the best device/simulator (online > boot; honors platform/device).' },
|
|
40
|
-
{ name: 'qa_resolve_artifact', summary: 'Find the best installable .apk/.aab/.ipa/.app and explain where it looked.' },
|
|
41
|
-
{ name: 'qa_build_plan', summary: 'Propose exact build commands per framework/platform (side-effect free).' },
|
|
42
|
-
{ name: 'qa_build', summary: 'Build from source (consent-gated job); captures a log and re-resolves the artifact.' },
|
|
43
|
-
{ name: 'qa_bundletool', summary: 'Convert an .aab to an installable APK (universal or device-specific set).' },
|
|
44
|
-
],
|
|
45
|
-
},
|
|
46
|
-
{
|
|
47
|
-
group: 'device',
|
|
48
|
-
purpose: 'Inspect and control the device/app environment without raw adb or simctl.',
|
|
49
|
-
tools: [
|
|
50
|
-
{ name: 'qa_device_info', summary: 'Model/SDK/ABIs/locale/screen/orientation + installed apps (read-only).' },
|
|
51
|
-
{ name: 'qa_permissions', summary: 'list / grant / revoke runtime permissions (revoke consent-gated).' },
|
|
52
|
-
{ name: 'qa_orientation', summary: 'Set portrait / landscape / auto (logged).' },
|
|
53
|
-
{ name: 'qa_geolocation', summary: 'Spoof GPS location (emulator; consent-gated) for map/location apps.' },
|
|
54
|
-
{ name: 'qa_network', summary: 'airplane-mode status/offline/online/restore (consent-gated; auto-restored).' },
|
|
55
|
-
{ name: 'qa_metro', summary: 'RN/Expo Metro status/start/stop/diagnose (RedBox detection + logcat).' },
|
|
56
|
-
{ name: 'qa_app_control', summary: 'launch/foreground/background/force_stop/restart/clear_data/fresh_start.' },
|
|
57
|
-
{ name: 'qa_screen_info', summary: 'Screen w/h/density, orientation, mode, counters, coordinate landmarks.' },
|
|
58
|
-
{ name: 'qa_screen_record', summary: 'Record a screen video to an mp4 artifact (start/stop; consent-gated).' },
|
|
59
|
-
],
|
|
60
|
-
},
|
|
61
|
-
{
|
|
62
|
-
group: 'drive',
|
|
63
|
-
purpose: 'Observe, act, and make deterministic health assertions.',
|
|
64
|
-
tools: [
|
|
65
|
-
{ name: 'qa_snapshot', summary: 'Capture compact structured UI elements.' },
|
|
66
|
-
{ name: 'qa_inspect', summary: 'Return the full attributes of a single @eN element from the latest snapshot.' },
|
|
67
|
-
{ name: 'qa_act', summary: 'Tap, type, clear, swipe, scroll, press, open URL, or wait, then observe.' },
|
|
68
|
-
{ name: 'qa_clear_overlay', summary: 'Dismiss common overlays blocking a target.' },
|
|
69
|
-
{ name: 'qa_check_health', summary: 'Detect crash, ANR, error boundaries, and foreground health.' },
|
|
70
|
-
{ name: 'qa_screenshot', summary: 'Capture a screenshot artifact.' },
|
|
71
|
-
{ name: 'qa_note', summary: 'Record a structured QA outcome.' },
|
|
72
|
-
{ name: 'qa_assert_visual', summary: 'Capture a visual assertion with evidence.' },
|
|
73
|
-
{ name: 'qa_visual', summary: 'Local visual ops: baseline / diff (regression) / find_image (tappable coords) / ocr (optional).' },
|
|
74
|
-
{ name: 'qa_visual_find_text', summary: 'OCR text locator with structured regions + coordinate-space conversion.' },
|
|
75
|
-
{ name: 'qa_locator_suggest', summary: "Score each element's locator durability and grade automation readiness (which controls need testIDs)." },
|
|
76
|
-
{ name: 'qa_input_capabilities', summary: 'Backend text-entry limits: ASCII, Unicode, clipboard, WDA typing frequency.' },
|
|
77
|
-
{ name: 'qa_wait', summary: 'Non-shell wait for device_online / metro_ready / job_done.' },
|
|
78
|
-
{ name: 'qa_idling_status', summary: 'Read app-declared idling hooks or label-heuristic settling before automation.' },
|
|
79
|
-
],
|
|
80
|
-
},
|
|
81
|
-
{
|
|
82
|
-
group: 'state',
|
|
83
|
-
purpose: 'Create and verify reproducible preconditions instead of reporting them as missing.',
|
|
84
|
-
tools: [
|
|
85
|
-
{ name: 'qa_seed', summary: 'Create a declared precondition via a fixture seed (deeplink/script/api; consent-gated).' },
|
|
86
|
-
{ name: 'qa_state_prepare', summary: 'Prepare a reproducible state profile: reset, launch, seed, verify ledger.' },
|
|
87
|
-
{ name: 'qa_state_verify', summary: 'Verify a state profile without treating setup drift as an app bug.' },
|
|
88
|
-
{ name: 'qa_state_teardown', summary: 'Run state-profile teardown and restore declared environment state.' },
|
|
89
|
-
],
|
|
90
|
-
},
|
|
91
|
-
{
|
|
92
|
-
group: 'run',
|
|
93
|
-
purpose: 'Run smoke checks, exploration, and reports.',
|
|
94
|
-
tools: [
|
|
95
|
-
{ name: 'qa_smoke', summary: 'Run launch smoke and saved flows.' },
|
|
96
|
-
{ name: 'qa_explore', summary: 'Guided simulator exploration with evidence and graph output.' },
|
|
97
|
-
{ name: 'qa_report', summary: 'Summarize findings, blockers, evidence, and next actions.' },
|
|
98
|
-
{ name: 'qa_report_compare', summary: 'Compare current report.json against a baseline report.json.' },
|
|
99
|
-
{ name: 'qa_run_history', summary: 'Summarize local run history, pass rate, failures, flaky flows, and confidence calibration.' },
|
|
100
|
-
],
|
|
101
|
-
},
|
|
102
|
-
{
|
|
103
|
-
group: 'app-map',
|
|
104
|
-
purpose: 'Maintain the app knowledge map used as Swipium project memory.',
|
|
105
|
-
tools: [
|
|
106
|
-
{ name: 'qa_app_map_build', summary: 'Build or update the app map from static analysis and exploration.' },
|
|
107
|
-
{ name: 'qa_app_map_read', summary: 'Read compact app map sections.' },
|
|
108
|
-
{ name: 'qa_app_map_query', summary: 'Search screens, features, tests, and code links.' },
|
|
109
|
-
{ name: 'qa_app_map_feature_scope', summary: 'Resolve a feature query to a focused test scope.' },
|
|
110
|
-
{ name: 'qa_app_map_update', summary: 'Targeted provenance-tracked map updates: note, test cases, automation suite, environment, coverage.' },
|
|
111
|
-
{ name: 'qa_app_map_diff', summary: 'Diff two app-map snapshots: screen/coverage/locator/test changes and new untested code.' },
|
|
112
|
-
{ name: 'qa_app_map_validate', summary: 'Validate schema, provenance, and map links.' },
|
|
113
|
-
],
|
|
114
|
-
},
|
|
115
|
-
{
|
|
116
|
-
group: 'feature',
|
|
117
|
-
purpose: 'Test a specific feature by name, backed by the app knowledge map.',
|
|
118
|
-
tools: [
|
|
119
|
-
{ name: 'qa_feature_scope', summary: 'Map a natural-language feature to code/screens/routes/runtime/tests + objective + strategy (read-only).' },
|
|
120
|
-
{ name: 'qa_feature_test_plan', summary: 'Feature test plan: scope + objective + generated cases + fixtures + automation readiness (read-only).' },
|
|
121
|
-
{ name: 'qa_test_feature', summary: 'Focused feature test: scope, targeted exploration toward the feature, record cases, update the map and report.' },
|
|
122
|
-
],
|
|
123
|
-
},
|
|
124
|
-
{
|
|
125
|
-
group: 'flows',
|
|
126
|
-
purpose: 'Create, plan, run, and repair durable simulator flows and POM suites.',
|
|
127
|
-
tools: [
|
|
128
|
-
{ name: 'qa_flow_check', summary: 'Parse and statically validate a Swipium flow.' },
|
|
129
|
-
{ name: 'qa_flow_plan', summary: 'Plan a flow against backend capabilities without executing it.' },
|
|
130
|
-
{ name: 'qa_flow_run', summary: 'Execute a flow against a prepared simulator session.' },
|
|
131
|
-
{ name: 'qa_flow_generate', summary: 'Generate a flow from recorded actions.' },
|
|
132
|
-
{ name: 'qa_flow_repair', summary: 'Suggest or patch a stronger locator for a failed flow step from the current screen.' },
|
|
133
|
-
{ name: 'qa_suite_generate', summary: 'Generate a POM-style suite from recorded actions.' },
|
|
134
|
-
{ name: 'qa_suite_compile', summary: 'Compile a generated suite into runnable flows.' },
|
|
135
|
-
{ name: 'qa_suite_lint', summary: 'Lint generated page objects for brittle/coordinate-only/dynamic locators.' },
|
|
136
|
-
{ name: 'qa_pom_generate', summary: 'Generate page objects and a locator audit from recorded actions.' },
|
|
137
|
-
{ name: 'qa_testcase_generate', summary: 'Generate test case documentation from recorded behavior.' },
|
|
138
|
-
],
|
|
139
|
-
},
|
|
140
|
-
{
|
|
141
|
-
group: 'test-suite',
|
|
142
|
-
purpose: 'Grow and maintain a canonical, persistent test suite across runs (.swipium/test-suite.json).',
|
|
143
|
-
tools: [
|
|
144
|
-
{ name: 'qa_test_suite_read', summary: 'Read the canonical suite: filter by functionality/status; summary/json/markdown.' },
|
|
145
|
-
{ name: 'qa_test_suite_update', summary: 'Merge cases into the persistent suite (dedupe by feature+objective+steps).' },
|
|
146
|
-
{ name: 'qa_test_suite_generate', summary: 'Generate or refresh canonical cases from a recorded run and exploration.' },
|
|
147
|
-
{ name: 'qa_test_suite_export', summary: 'Export the persistent suite to markdown, yaml dir, json, or junit.' },
|
|
148
|
-
{ name: 'qa_test_suite_lint', summary: 'Validate the suite: missing expected/actual, stale map links, duplicate ids.' },
|
|
149
|
-
],
|
|
150
|
-
},
|
|
151
|
-
{
|
|
152
|
-
group: 'interop',
|
|
153
|
-
purpose: 'Exchange flows with the Maestro ecosystem.',
|
|
154
|
-
tools: [
|
|
155
|
-
{ name: 'qa_maestro_import', summary: 'Import supported Maestro YAML commands into Swipium Flow V2.' },
|
|
156
|
-
{ name: 'qa_maestro_export', summary: 'Export Swipium Flow V2 to Maestro YAML with portability grades.' },
|
|
157
|
-
],
|
|
158
|
-
},
|
|
159
|
-
{
|
|
160
|
-
group: 'issues',
|
|
161
|
-
purpose: 'Durable issue memory and executable mobile-QA audit profiles.',
|
|
162
|
-
tools: [
|
|
163
|
-
{ name: 'qa_issue_log', summary: 'List the durable project issue ledger: records, counts, recurrence, linked evidence.' },
|
|
164
|
-
{ name: 'qa_issue_history', summary: 'Append-only event trail for one issue.' },
|
|
165
|
-
{ name: 'qa_issue_mark_fixed', summary: 'Record a fix so future runs detect regressions via the same fingerprint.' },
|
|
166
|
-
{ name: 'qa_issue_triage', summary: "Change an issue's category/severity/owner or add a note (append-only)." },
|
|
167
|
-
{ name: 'qa_issue_suppress', summary: 'Suppress known noise with a reason/expiration; stays visible under known-noise.' },
|
|
168
|
-
{ name: 'qa_issue_verify_fixed', summary: 'Link passing evidence to a FIXED issue so reports can claim it was verified.' },
|
|
169
|
-
{ name: 'qa_issue_metrics', summary: 'Issue quality trends: opened/fixed/reopened/verified, aging, reopen rate.' },
|
|
170
|
-
{ name: 'qa_mobile_audit', summary: 'Plan or execute a named mobile-QA profile (smoke / account_cycle / store_compliance / resilience / release_gate).' },
|
|
171
|
-
],
|
|
172
|
-
},
|
|
173
|
-
{
|
|
174
|
-
group: 'first-run',
|
|
175
|
-
purpose: 'Handle login, account creation, onboarding, and paywall first-run screens safely.',
|
|
176
|
-
tools: [
|
|
177
|
-
{ name: 'qa_first_run_plan', summary: 'Classify the current first-run screen and produce a safe plan.' },
|
|
178
|
-
{ name: 'qa_first_run_continue', summary: 'Execute bounded first-run steps with safe generated test data when allowed.' },
|
|
179
|
-
],
|
|
180
|
-
},
|
|
181
|
-
{
|
|
182
|
-
group: 'automation',
|
|
183
|
-
purpose: 'Generate Appium automation code from Swipium evidence on request.',
|
|
184
|
-
tools: [
|
|
185
|
-
{ name: 'qa_automation_plan', summary: 'Plan generated JS/TS or Python Appium automation.' },
|
|
186
|
-
{ name: 'qa_automation_generate', summary: 'Generate an Appium POM suite from recorded actions.' },
|
|
187
|
-
{ name: 'qa_automation_validate', summary: 'Validate generated automation code without a device.' },
|
|
188
|
-
],
|
|
189
|
-
},
|
|
190
|
-
];
|
|
191
|
-
const groupNames = CAPABILITY_GROUPS.map((g) => g.group);
|
|
192
|
-
export function registerCapabilities(server, _sessions) {
|
|
193
|
-
server.registerTool('qa_capabilities', {
|
|
194
|
-
title: 'List Swipium capabilities',
|
|
195
|
-
description: 'Return the public Swipium tools grouped by purpose with short summaries.',
|
|
196
|
-
inputSchema: {
|
|
197
|
-
group: z.enum(groupNames).optional().describe('Return only this group.'),
|
|
198
|
-
},
|
|
199
|
-
}, async ({ group }) => {
|
|
200
|
-
const groups = group ? CAPABILITY_GROUPS.filter((g) => g.group === group) : CAPABILITY_GROUPS;
|
|
201
|
-
const summary = `Swipium v${SWIPIUM_VERSION}: ${TOOL_COUNT} public tools in ${CAPABILITY_GROUPS.length} groups.\n` +
|
|
202
|
-
groups
|
|
203
|
-
.map((g) => `\n[${g.group}] ${g.purpose}\n` + g.tools.map((t) => ` - ${t.name}: ${t.summary}`).join('\n'))
|
|
204
|
-
.join('\n') +
|
|
205
|
-
'\n\nStart with qa_test_this for low-context "test it" requests.';
|
|
206
|
-
return qaOk({ swipiumVersion: SWIPIUM_VERSION, totalTools: TOOL_COUNT, groups }, summary);
|
|
207
|
-
});
|
|
208
|
-
}
|
|
209
|
-
//# sourceMappingURL=capabilities.js.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"capabilities.js","sourceRoot":"","sources":["../../src/tools/capabilities.ts"],"names":[],"mappings":"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"}
|
|
@@ -1,41 +0,0 @@
|
|
|
1
|
-
// qa_detect_context — scan the resolved projectRoot and report what we're looking at.
|
|
2
|
-
import { z } from 'zod';
|
|
3
|
-
import { qaOk, qaError } from '../lib/result.js';
|
|
4
|
-
import { resolveProjectRoot } from '../context/projectRoot.js';
|
|
5
|
-
import { detectContext } from '../context/detect.js';
|
|
6
|
-
export function registerDetectContext(server, sessions) {
|
|
7
|
-
server.registerTool('qa_detect_context', {
|
|
8
|
-
title: 'Detect project context',
|
|
9
|
-
description: 'Scan the resolved project root (a session root, an explicit projectRoot, or MCP workspace roots — never the server cwd) and report: framework (expo/bare-rn/native-android/native-ios/flutter), monorepo, prebuilt artifacts (apk/ipa/.app), online devices + AVDs, toolchain, and blockers. Use this to decide what qa_prepare_target needs.',
|
|
10
|
-
inputSchema: {
|
|
11
|
-
sessionId: z.string().optional().describe('Use this session\'s projectRoot if given.'),
|
|
12
|
-
projectRoot: z.string().optional().describe('Absolute path; else resolved via MCP roots.'),
|
|
13
|
-
},
|
|
14
|
-
}, async ({ sessionId, projectRoot }) => {
|
|
15
|
-
let root;
|
|
16
|
-
if (sessionId)
|
|
17
|
-
root = sessions.get(sessionId)?.root;
|
|
18
|
-
if (!root) {
|
|
19
|
-
const resolved = await resolveProjectRoot(server, projectRoot);
|
|
20
|
-
if (!resolved.root) {
|
|
21
|
-
return qaError({
|
|
22
|
-
what: 'Could not resolve a project root to scan',
|
|
23
|
-
changedState: false,
|
|
24
|
-
retrySafe: true,
|
|
25
|
-
nextSteps: ['Pass projectRoot="/abs/path", or call qa_start_session first.'],
|
|
26
|
-
clientHint: resolved.hint,
|
|
27
|
-
});
|
|
28
|
-
}
|
|
29
|
-
root = resolved.root;
|
|
30
|
-
}
|
|
31
|
-
const ctx = await detectContext(root);
|
|
32
|
-
const summary = `root=${ctx.projectRoot}\n` +
|
|
33
|
-
`framework=${ctx.framework} location=${ctx.location} monorepo=${ctx.monorepo}\n` +
|
|
34
|
-
`artifacts: ${ctx.artifacts.apks.length} apk, ${ctx.artifacts.ipas.length} ipa, ${ctx.artifacts.appBundles.length} .app\n` +
|
|
35
|
-
`devices: online=[${ctx.devices.androidOnline.join(', ')}] avds=[${ctx.devices.avds.join(', ')}]\n` +
|
|
36
|
-
`toolchain: adb=${ctx.toolchain.adb} emulator=${ctx.toolchain.emulator} java=${ctx.toolchain.java} aapt2=${ctx.toolchain.aapt2} xcodebuild=${ctx.toolchain.xcodebuild}\n` +
|
|
37
|
-
(ctx.blockers.length ? `blockers:\n - ${ctx.blockers.join('\n - ')}` : 'no blockers');
|
|
38
|
-
return qaOk(ctx, summary);
|
|
39
|
-
});
|
|
40
|
-
}
|
|
41
|
-
//# sourceMappingURL=detectContext.js.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"detectContext.js","sourceRoot":"","sources":["../../src/tools/detectContext.ts"],"names":[],"mappings":"AAAA,sFAAsF;AAEtF,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AAExB,OAAO,EAAE,IAAI,EAAE,OAAO,EAAE,MAAM,kBAAkB,CAAC;AACjD,OAAO,EAAE,kBAAkB,EAAE,MAAM,2BAA2B,CAAC;AAC/D,OAAO,EAAE,aAAa,EAAE,MAAM,sBAAsB,CAAC;AAGrD,MAAM,UAAU,qBAAqB,CAAC,MAAiB,EAAE,QAAsB;IAC7E,MAAM,CAAC,YAAY,CACjB,mBAAmB,EACnB;QACE,KAAK,EAAE,wBAAwB;QAC/B,WAAW,EACT,+UAA+U;QACjV,WAAW,EAAE;YACX,SAAS,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,QAAQ,EAAE,CAAC,QAAQ,CAAC,2CAA2C,CAAC;YACtF,WAAW,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,QAAQ,EAAE,CAAC,QAAQ,CAAC,6CAA6C,CAAC;SAC3F;KACF,EACD,KAAK,EAAE,EAAE,SAAS,EAAE,WAAW,EAAE,EAAE,EAAE;QACnC,IAAI,IAAwB,CAAC;QAC7B,IAAI,SAAS;YAAE,IAAI,GAAG,QAAQ,CAAC,GAAG,CAAC,SAAS,CAAC,EAAE,IAAI,CAAC;QACpD,IAAI,CAAC,IAAI,EAAE,CAAC;YACV,MAAM,QAAQ,GAAG,MAAM,kBAAkB,CAAC,MAAM,EAAE,WAAW,CAAC,CAAC;YAC/D,IAAI,CAAC,QAAQ,CAAC,IAAI,EAAE,CAAC;gBACnB,OAAO,OAAO,CAAC;oBACb,IAAI,EAAE,0CAA0C;oBAChD,YAAY,EAAE,KAAK;oBACnB,SAAS,EAAE,IAAI;oBACf,SAAS,EAAE,CAAC,+DAA+D,CAAC;oBAC5E,UAAU,EAAE,QAAQ,CAAC,IAAI;iBAC1B,CAAC,CAAC;YACL,CAAC;YACD,IAAI,GAAG,QAAQ,CAAC,IAAI,CAAC;QACvB,CAAC;QAED,MAAM,GAAG,GAAG,MAAM,aAAa,CAAC,IAAI,CAAC,CAAC;QACtC,MAAM,OAAO,GACX,QAAQ,GAAG,CAAC,WAAW,IAAI;YAC3B,aAAa,GAAG,CAAC,SAAS,aAAa,GAAG,CAAC,QAAQ,aAAa,GAAG,CAAC,QAAQ,IAAI;YAChF,cAAc,GAAG,CAAC,SAAS,CAAC,IAAI,CAAC,MAAM,SAAS,GAAG,CAAC,SAAS,CAAC,IAAI,CAAC,MAAM,SAAS,GAAG,CAAC,SAAS,CAAC,UAAU,CAAC,MAAM,SAAS;YAC1H,oBAAoB,GAAG,CAAC,OAAO,CAAC,aAAa,CAAC,IAAI,CAAC,IAAI,CAAC,WAAW,GAAG,CAAC,OAAO,CAAC,IAAI,CAAC,IAAI,CAAC,IAAI,CAAC,KAAK;YACnG,kBAAkB,GAAG,CAAC,SAAS,CAAC,GAAG,aAAa,GAAG,CAAC,SAAS,CAAC,QAAQ,SAAS,GAAG,CAAC,SAAS,CAAC,IAAI,UAAU,GAAG,CAAC,SAAS,CAAC,KAAK,eAAe,GAAG,CAAC,SAAS,CAAC,UAAU,IAAI;YACzK,CAAC,GAAG,CAAC,QAAQ,CAAC,MAAM,CAAC,CAAC,CAAC,iBAAiB,GAAG,CAAC,QAAQ,CAAC,IAAI,CAAC,OAAO,CAAC,EAAE,CAAC,CAAC,CAAC,aAAa,CAAC,CAAC;QACxF,OAAO,IAAI,CAAC,GAAyC,EAAE,OAAO,CAAC,CAAC;IAClE,CAAC,CACF,CAAC;AACJ,CAAC"}
|
|
@@ -1,55 +0,0 @@
|
|
|
1
|
-
// qa_flow_generate (PHASE3-PLAN §4.1 / DESIGN §8) — turn the actions recorded during this
|
|
2
|
-
// session (via qa_act) into a durable flow YAML, with a durability grade and the brittle
|
|
3
|
-
// steps that need testIDs. Optionally saves it to .swipium/flows/<name>.yaml so it shows up
|
|
4
|
-
// in qa_plan and can be replayed with qa_flow_run.
|
|
5
|
-
import { z } from 'zod';
|
|
6
|
-
import { mkdirSync, writeFileSync } from 'node:fs';
|
|
7
|
-
import { join } from 'node:path';
|
|
8
|
-
import { qaOk, qaError } from '../lib/result.js';
|
|
9
|
-
import { generateFlow } from '../flows/generate.js';
|
|
10
|
-
import { loadProjectConfig } from '../cli/scan.js';
|
|
11
|
-
export function registerFlowGenerate(server, sessions) {
|
|
12
|
-
server.registerTool('qa_flow_generate', {
|
|
13
|
-
title: 'Generate a flow from this run',
|
|
14
|
-
description: 'Draft a repeatable flow YAML from the actions recorded during this session (every qa_act is recorded). Translates @ref taps into durable text selectors where possible, turns typed credentials into ${VARS}, and reports a durability grade (A/B/C) + the steps that need a testID/accessibilityLabel. Pass save:true to write it to .swipium/flows/<name>.yaml (so qa_plan lists it and qa_flow_run can replay it).',
|
|
15
|
-
inputSchema: {
|
|
16
|
-
sessionId: z.string(),
|
|
17
|
-
name: z.string().optional().describe('Flow name (default derived from the app/session).'),
|
|
18
|
-
budgetProfile: z.enum(['guardrail', 'login_smoke', 'full_smoke', 'install_smoke']).optional(),
|
|
19
|
-
save: z.boolean().optional().describe('Write to .swipium/flows/<name>.yaml (default false → returned + saved as an artifact only).'),
|
|
20
|
-
},
|
|
21
|
-
}, async ({ sessionId, name, budgetProfile, save }) => {
|
|
22
|
-
const session = sessions.get(sessionId);
|
|
23
|
-
if (!session) {
|
|
24
|
-
return qaError({ what: `Unknown sessionId ${sessionId}`, changedState: false, retrySafe: true, nextSteps: ['Call qa_start_session first.'] });
|
|
25
|
-
}
|
|
26
|
-
if (!session.recordedActions.length) {
|
|
27
|
-
return qaError({
|
|
28
|
-
what: 'No actions recorded in this session yet',
|
|
29
|
-
changedState: false,
|
|
30
|
-
retrySafe: true,
|
|
31
|
-
nextSteps: ['Drive the app with qa_act first (each action is recorded), then qa_flow_generate.'],
|
|
32
|
-
});
|
|
33
|
-
}
|
|
34
|
-
const appId = session.appId ?? (loadProjectConfig(session.root)?.appId ?? undefined);
|
|
35
|
-
const flowName = (name ?? `${(appId ?? 'app').split('.').pop()}-smoke`).replace(/[^\w.-]+/g, '-');
|
|
36
|
-
const gen = generateFlow(session.recordedActions, { name: flowName, appId, budgetProfile });
|
|
37
|
-
// Always keep a copy as an artifact; optionally write into the project's flows dir.
|
|
38
|
-
const artifactUri = sessions.saveArtifact(session, 'flow', `${flowName}.yaml`, gen.yaml, 'text/yaml', `generated flow (durability ${gen.durability.grade})`);
|
|
39
|
-
let savedTo;
|
|
40
|
-
if (save) {
|
|
41
|
-
const dir = join(session.root, '.swipium', 'flows');
|
|
42
|
-
mkdirSync(dir, { recursive: true });
|
|
43
|
-
savedTo = join(dir, `${flowName}.yaml`);
|
|
44
|
-
writeFileSync(savedTo, gen.yaml);
|
|
45
|
-
}
|
|
46
|
-
const summary = `Generated flow "${flowName}" — durability ${gen.durability.grade} (${gen.durability.semanticPct}% semantic; ` +
|
|
47
|
-
`${gen.durability.coordinate} coordinate, ${gen.durability.needsHumanData} needs-human-data), ${gen.stepCount} steps.` +
|
|
48
|
-
(gen.variables.length ? `\nvariables: ${gen.variables.join(', ')} (provide via qa_flow_run { variables }).` : '') +
|
|
49
|
-
(gen.brittleSteps.length ? `\n⚠ brittle steps:\n - ${gen.brittleSteps.map((b) => `step ${b.index}: ${b.reason}`).join('\n - ')}` : '') +
|
|
50
|
-
(savedTo ? `\nsaved: ${savedTo}` : `\n(not saved to disk — pass save:true to write it under .swipium/flows)`) +
|
|
51
|
-
`\n\n${gen.yaml}`;
|
|
52
|
-
return qaOk({ name: flowName, appId: appId ?? null, durability: gen.durability, brittleSteps: gen.brittleSteps, variables: gen.variables, stepCount: gen.stepCount, artifactUri, savedTo: savedTo ?? null, yaml: gen.yaml }, summary);
|
|
53
|
-
});
|
|
54
|
-
}
|
|
55
|
-
//# sourceMappingURL=flowGenerate.js.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"flowGenerate.js","sourceRoot":"","sources":["../../src/tools/flowGenerate.ts"],"names":[],"mappings":"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"}
|
package/dist/tools/history.js
DELETED
|
@@ -1,56 +0,0 @@
|
|
|
1
|
-
import { z } from 'zod';
|
|
2
|
-
import { qaError, qaOk } from '../lib/result.js';
|
|
3
|
-
import { compareReports, trendForRoot } from '../report/history.js';
|
|
4
|
-
export function registerHistory(server, sessions) {
|
|
5
|
-
server.registerTool('qa_report_compare', {
|
|
6
|
-
title: 'Compare Swipium reports',
|
|
7
|
-
description: 'Compare a current Swipium report.json against a baseline report.json. Reports new failures, fixed failures, changed screenshots, outcome changes, runtime regression, and optional flake status from local trend history.',
|
|
8
|
-
inputSchema: {
|
|
9
|
-
current: z.string().describe('Path to current report.json.'),
|
|
10
|
-
baseline: z.string().describe('Path to baseline report.json.'),
|
|
11
|
-
trendRoot: z.string().optional().describe('Optional project root containing .swipium/runs or legacy .swipium/ci history for known-flaky classification.'),
|
|
12
|
-
},
|
|
13
|
-
}, async ({ current, baseline, trendRoot }) => {
|
|
14
|
-
try {
|
|
15
|
-
const cmp = compareReports(current, baseline, { trendRoot });
|
|
16
|
-
return qaOk(cmp, cmp.summary);
|
|
17
|
-
}
|
|
18
|
-
catch (e) {
|
|
19
|
-
return qaError({ what: `Could not compare reports: ${String(e.message ?? e)}`, changedState: false, retrySafe: true, nextSteps: ['Pass readable Swipium report.json files for current and baseline.'] });
|
|
20
|
-
}
|
|
21
|
-
});
|
|
22
|
-
server.registerTool('qa_run_history', {
|
|
23
|
-
title: 'Summarize Swipium run history',
|
|
24
|
-
description: 'Read local .swipium/runs/**/report.json files (and legacy .swipium/ci/**) and summarize pass rate, median runtime, top failures, environment failures, flaky flows, confidence calibration, and slowest runs.',
|
|
25
|
-
inputSchema: {
|
|
26
|
-
sessionId: z.string().optional(),
|
|
27
|
-
projectRoot: z.string().optional().describe('Project root. Defaults to the session root when sessionId is provided.'),
|
|
28
|
-
},
|
|
29
|
-
}, async ({ sessionId, projectRoot }) => {
|
|
30
|
-
const session = sessionId ? sessions.get(sessionId) : undefined;
|
|
31
|
-
if (sessionId && !session)
|
|
32
|
-
return qaError({ what: `Unknown sessionId ${sessionId}`, changedState: false, retrySafe: true, nextSteps: ['Call qa_start_session first, or pass projectRoot.'] });
|
|
33
|
-
const root = projectRoot ?? session?.root;
|
|
34
|
-
if (!root)
|
|
35
|
-
return qaError({ what: 'qa_run_history needs projectRoot or sessionId', changedState: false, retrySafe: true, nextSteps: ['Pass projectRoot, or call qa_start_session first.'] });
|
|
36
|
-
try {
|
|
37
|
-
const trend = trendForRoot(root);
|
|
38
|
-
const calibration = trend.confidenceCalibration;
|
|
39
|
-
const blockers = trend.releaseGateSignals.filter((s) => s.level === 'block').reduce((sum, s) => sum + s.count, 0);
|
|
40
|
-
const warnings = trend.releaseGateSignals.filter((s) => s.level === 'warn').reduce((sum, s) => sum + s.count, 0);
|
|
41
|
-
const locatorTrend = trend.locatorReadinessTrend;
|
|
42
|
-
const summary = `history: ${trend.reports} report(s), median ${trend.medianRuntimeSec ?? 'n/a'}s\n` +
|
|
43
|
-
`timing: avg setup ${trend.averageSetupSec ?? 'n/a'}s, avg active ${trend.averageActiveSec ?? 'n/a'}s\n` +
|
|
44
|
-
(locatorTrend.runsWithReadiness ? `locator readiness: latest durable ${locatorTrend.latestDurablePct ?? 'n/a'}%, average ${locatorTrend.averageDurablePct ?? 'n/a'}%\n` : '') +
|
|
45
|
-
Object.entries(trend.passRate).map(([flow, rate]) => ` ${flow}: ${(rate * 100).toFixed(1)}% pass`).join('\n') +
|
|
46
|
-
`\nrelease gate signals: ${blockers} block, ${warnings} warn` +
|
|
47
|
-
`\ncalibration: ${calibration.status} (${calibration.confidenceSamples}/${calibration.probabilisticEvidence} confidence sample(s), ${calibration.outcomeSamples} outcome sample(s))` +
|
|
48
|
-
(trend.slowestSteps.length ? `\nslowest step: ${trend.slowestSteps[0].workflow}#${trend.slowestSteps[0].index} ${trend.slowestSteps[0].kind} ${trend.slowestSteps[0].durationSec}s` : '');
|
|
49
|
-
return qaOk({ root, ...trend }, summary);
|
|
50
|
-
}
|
|
51
|
-
catch (e) {
|
|
52
|
-
return qaError({ what: `Could not read run history: ${String(e.message ?? e)}`, changedState: false, retrySafe: true, nextSteps: ['Confirm .swipium/runs or .swipium/ci contains report.json files.'] });
|
|
53
|
-
}
|
|
54
|
-
});
|
|
55
|
-
}
|
|
56
|
-
//# sourceMappingURL=history.js.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"history.js","sourceRoot":"","sources":["../../src/tools/history.ts"],"names":[],"mappings":"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"}
|
package/dist/tools/idling.js
DELETED
|
@@ -1,104 +0,0 @@
|
|
|
1
|
-
import { request as httpRequest } from 'node:http';
|
|
2
|
-
import { request as httpsRequest } from 'node:https';
|
|
3
|
-
import { URL } from 'node:url';
|
|
4
|
-
import { z } from 'zod';
|
|
5
|
-
import { qaError, qaOk } from '../lib/result.js';
|
|
6
|
-
import { getDriver } from '../session/attach.js';
|
|
7
|
-
import { settle } from '../snapshot/settle.js';
|
|
8
|
-
export function isLoopbackUrl(raw) {
|
|
9
|
-
try {
|
|
10
|
-
const u = new URL(raw);
|
|
11
|
-
return (u.protocol === 'http:' || u.protocol === 'https:') && ['localhost', '127.0.0.1', '::1', '[::1]'].includes(u.hostname);
|
|
12
|
-
}
|
|
13
|
-
catch {
|
|
14
|
-
return false;
|
|
15
|
-
}
|
|
16
|
-
}
|
|
17
|
-
export function parseIdlingPayload(text) {
|
|
18
|
-
const trimmed = text.trim();
|
|
19
|
-
if (!trimmed)
|
|
20
|
-
return { idle: false, detail: 'empty idling response' };
|
|
21
|
-
try {
|
|
22
|
-
const parsed = JSON.parse(trimmed);
|
|
23
|
-
if (typeof parsed === 'boolean')
|
|
24
|
-
return { idle: parsed, detail: parsed ? 'idle:true' : 'idle:false', raw: parsed };
|
|
25
|
-
if (parsed && typeof parsed === 'object') {
|
|
26
|
-
const o = parsed;
|
|
27
|
-
const value = o.idle ?? o.isIdleNow ?? (typeof o.busy === 'boolean' ? !o.busy : undefined);
|
|
28
|
-
if (typeof value === 'boolean') {
|
|
29
|
-
return { idle: value, detail: String(o.reason ?? o.status ?? (value ? 'app declared idle' : 'app declared busy')), raw: parsed };
|
|
30
|
-
}
|
|
31
|
-
if (typeof o.status === 'string') {
|
|
32
|
-
const idle = /idle|ready|settled/i.test(o.status);
|
|
33
|
-
return { idle, detail: o.status, raw: parsed };
|
|
34
|
-
}
|
|
35
|
-
}
|
|
36
|
-
}
|
|
37
|
-
catch {
|
|
38
|
-
/* fall through to text parser */
|
|
39
|
-
}
|
|
40
|
-
return { idle: /^(idle|ready|settled|true|ok)$/i.test(trimmed), detail: trimmed };
|
|
41
|
-
}
|
|
42
|
-
function fetchLoopback(raw, timeoutMs) {
|
|
43
|
-
return new Promise((resolve, reject) => {
|
|
44
|
-
const url = new URL(raw);
|
|
45
|
-
const req = (url.protocol === 'https:' ? httpsRequest : httpRequest)(url, { method: 'GET', timeout: timeoutMs }, (res) => {
|
|
46
|
-
const chunks = [];
|
|
47
|
-
res.on('data', (c) => chunks.push(c));
|
|
48
|
-
res.on('end', () => resolve(Buffer.concat(chunks).toString('utf8')));
|
|
49
|
-
});
|
|
50
|
-
req.on('timeout', () => {
|
|
51
|
-
req.destroy(new Error(`idling hook timed out after ${timeoutMs}ms`));
|
|
52
|
-
});
|
|
53
|
-
req.on('error', reject);
|
|
54
|
-
req.end();
|
|
55
|
-
});
|
|
56
|
-
}
|
|
57
|
-
export function registerIdling(server, sessions) {
|
|
58
|
-
server.registerTool('qa_idling_status', {
|
|
59
|
-
title: 'Read app idling status',
|
|
60
|
-
description: 'Report whether the app is idle before automation. With hookUrl, reads an app-declared loopback idling endpoint (Gradle/RN/Flutter test hook). Without hookUrl, uses Swipium heuristic settling and labels it as heuristic evidence.',
|
|
61
|
-
inputSchema: {
|
|
62
|
-
sessionId: z.string(),
|
|
63
|
-
hookUrl: z.string().optional().describe('Optional loopback-only URL returning { idle: boolean } / { isIdleNow: boolean } / text "idle".'),
|
|
64
|
-
timeoutMs: z.number().optional().describe('Default 3000 for hookUrl, 8000 for heuristic settling.'),
|
|
65
|
-
},
|
|
66
|
-
}, async ({ sessionId, hookUrl, timeoutMs }) => {
|
|
67
|
-
const session = sessions.get(sessionId);
|
|
68
|
-
if (!session)
|
|
69
|
-
return qaError({ what: `Unknown sessionId ${sessionId}`, changedState: false, retrySafe: true, nextSteps: ['Call qa_start_session first.'] });
|
|
70
|
-
if (hookUrl) {
|
|
71
|
-
if (!isLoopbackUrl(hookUrl)) {
|
|
72
|
-
return qaError({
|
|
73
|
-
what: 'idling hook URLs must be loopback-only',
|
|
74
|
-
changedState: false,
|
|
75
|
-
retrySafe: false,
|
|
76
|
-
failureCode: 'UNSAFE_ACTION_REFUSED',
|
|
77
|
-
nextSteps: ['Expose the app test hook on localhost/127.0.0.1 and retry.'],
|
|
78
|
-
});
|
|
79
|
-
}
|
|
80
|
-
try {
|
|
81
|
-
const body = await fetchLoopback(hookUrl, timeoutMs ?? 3000);
|
|
82
|
-
const parsed = parseIdlingPayload(body);
|
|
83
|
-
sessions.addWorkaround(session, `idling: app-declared hook ${hookUrl}`);
|
|
84
|
-
return qaOk({ source: 'app_declared', hookUrl, idle: parsed.idle, detail: parsed.detail, raw: parsed.raw ?? body }, `idling app_declared: ${parsed.idle ? 'idle' : 'busy'} (${parsed.detail})`);
|
|
85
|
-
}
|
|
86
|
-
catch (e) {
|
|
87
|
-
return qaError({
|
|
88
|
-
what: `Could not read idling hook: ${String(e)}`,
|
|
89
|
-
changedState: false,
|
|
90
|
-
retrySafe: true,
|
|
91
|
-
failureCode: 'UI_IDLE_TIMEOUT',
|
|
92
|
-
nextSteps: ['Confirm the local idling hook is running and returns JSON/text within the timeout.'],
|
|
93
|
-
});
|
|
94
|
-
}
|
|
95
|
-
}
|
|
96
|
-
const { driver } = await getDriver(session);
|
|
97
|
-
if (!driver)
|
|
98
|
-
return qaError({ what: 'No device attached to this session', changedState: false, retrySafe: true, nextSteps: ['Prepare a target first or pass hookUrl for an app-declared hook.'] });
|
|
99
|
-
const result = await settle(driver, { timeoutMs: timeoutMs ?? 8000 });
|
|
100
|
-
sessions.addWorkaround(session, 'idling: heuristic settle used (no app-declared hook)');
|
|
101
|
-
return qaOk({ source: 'heuristic', idle: result.settled, timeoutMs: timeoutMs ?? 8000 }, `idling heuristic: ${result.settled ? 'idle' : 'not idle before timeout'}`);
|
|
102
|
-
});
|
|
103
|
-
}
|
|
104
|
-
//# sourceMappingURL=idling.js.map
|
package/dist/tools/idling.js.map
DELETED
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"idling.js","sourceRoot":"","sources":["../../src/tools/idling.ts"],"names":[],"mappings":"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"}
|
|
@@ -1,30 +0,0 @@
|
|
|
1
|
-
import { z } from 'zod';
|
|
2
|
-
import { qaError, qaOk } from '../lib/result.js';
|
|
3
|
-
import { getDriver } from '../session/attach.js';
|
|
4
|
-
import { loadWdaConfig } from '../lib/wdaConfig.js';
|
|
5
|
-
export function registerInputCapabilities(server, sessions) {
|
|
6
|
-
server.registerTool('qa_input_capabilities', {
|
|
7
|
-
title: 'Text input capabilities',
|
|
8
|
-
description: 'Report backend text-entry constraints: ASCII safety, Unicode support, clipboard/paste availability, and WDA typing-frequency tuning. Use before generating fixture-backed form flows.',
|
|
9
|
-
inputSchema: { sessionId: z.string() },
|
|
10
|
-
}, async ({ sessionId }) => {
|
|
11
|
-
const session = sessions.get(sessionId);
|
|
12
|
-
const { driver } = session ? await getDriver(session) : { driver: undefined };
|
|
13
|
-
if (!session || !driver)
|
|
14
|
-
return qaError({ what: 'No device attached to this session', changedState: false, retrySafe: true, nextSteps: ['Prepare a target first.'] });
|
|
15
|
-
const wda = driver.kind === 'wda' ? loadWdaConfig(session.root) : null;
|
|
16
|
-
const caps = {
|
|
17
|
-
backend: driver.kind,
|
|
18
|
-
asciiSafe: true,
|
|
19
|
-
unicodeSupport: driver.kind === 'direct' ? 'limited_android_adb_text' : driver.kind === 'wda' ? 'wda_type_text' : driver.kind === 'remote' ? 'appium_driver_dependent' : 'limited',
|
|
20
|
-
pasteClipboardAvailable: false,
|
|
21
|
-
maxTypingFrequency: typeof wda?.settings.maxTypingFrequency === 'number' ? wda.settings.maxTypingFrequency : null,
|
|
22
|
-
unsupportedFailureCode: 'TEXT_INPUT_UNSUPPORTED',
|
|
23
|
-
policy: driver.kind === 'direct'
|
|
24
|
-
? 'Prefer ASCII fixture values on Android DirectDriver; use declared generators that emit ASCII or a backend with Unicode-safe text entry.'
|
|
25
|
-
: 'Fixture text entry is supported, but keep secrets in variables and tune WDA/Appium settings if typing flakes.',
|
|
26
|
-
};
|
|
27
|
-
return qaOk(caps, `input capabilities: ${driver.kind}; unicode=${caps.unicodeSupport}; clipboard=${caps.pasteClipboardAvailable}`);
|
|
28
|
-
});
|
|
29
|
-
}
|
|
30
|
-
//# sourceMappingURL=inputCapabilities.js.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"inputCapabilities.js","sourceRoot":"","sources":["../../src/tools/inputCapabilities.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AAExB,OAAO,EAAE,OAAO,EAAE,IAAI,EAAE,MAAM,kBAAkB,CAAC;AACjD,OAAO,EAAE,SAAS,EAAE,MAAM,sBAAsB,CAAC;AACjD,OAAO,EAAE,aAAa,EAAE,MAAM,qBAAqB,CAAC;AAGpD,MAAM,UAAU,yBAAyB,CAAC,MAAiB,EAAE,QAAsB;IACjF,MAAM,CAAC,YAAY,CACjB,uBAAuB,EACvB;QACE,KAAK,EAAE,yBAAyB;QAChC,WAAW,EAAE,uLAAuL;QACpM,WAAW,EAAE,EAAE,SAAS,EAAE,CAAC,CAAC,MAAM,EAAE,EAAE;KACvC,EACD,KAAK,EAAE,EAAE,SAAS,EAAE,EAAE,EAAE;QACtB,MAAM,OAAO,GAAG,QAAQ,CAAC,GAAG,CAAC,SAAS,CAAC,CAAC;QACxC,MAAM,EAAE,MAAM,EAAE,GAAG,OAAO,CAAC,CAAC,CAAC,MAAM,SAAS,CAAC,OAAO,CAAC,CAAC,CAAC,CAAC,EAAE,MAAM,EAAE,SAAS,EAAE,CAAC;QAC9E,IAAI,CAAC,OAAO,IAAI,CAAC,MAAM;YAAE,OAAO,OAAO,CAAC,EAAE,IAAI,EAAE,oCAAoC,EAAE,YAAY,EAAE,KAAK,EAAE,SAAS,EAAE,IAAI,EAAE,SAAS,EAAE,CAAC,yBAAyB,CAAC,EAAE,CAAC,CAAC;QACtK,MAAM,GAAG,GAAG,MAAM,CAAC,IAAI,KAAK,KAAK,CAAC,CAAC,CAAC,aAAa,CAAC,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC;QACvE,MAAM,IAAI,GAAG;YACX,OAAO,EAAE,MAAM,CAAC,IAAI;YACpB,SAAS,EAAE,IAAI;YACf,cAAc,EAAE,MAAM,CAAC,IAAI,KAAK,QAAQ,CAAC,CAAC,CAAC,0BAA0B,CAAC,CAAC,CAAC,MAAM,CAAC,IAAI,KAAK,KAAK,CAAC,CAAC,CAAC,eAAe,CAAC,CAAC,CAAC,MAAM,CAAC,IAAI,KAAK,QAAQ,CAAC,CAAC,CAAC,yBAAyB,CAAC,CAAC,CAAC,SAAS;YAClL,uBAAuB,EAAE,KAAK;YAC9B,kBAAkB,EAAE,OAAO,GAAG,EAAE,QAAQ,CAAC,kBAAkB,KAAK,QAAQ,CAAC,CAAC,CAAC,GAAG,CAAC,QAAQ,CAAC,kBAAkB,CAAC,CAAC,CAAC,IAAI;YACjH,sBAAsB,EAAE,wBAAwB;YAChD,MAAM,EAAE,MAAM,CAAC,IAAI,KAAK,QAAQ;gBAC9B,CAAC,CAAC,yIAAyI;gBAC3I,CAAC,CAAC,+GAA+G;SACpH,CAAC;QACF,OAAO,IAAI,CAAC,IAAI,EAAE,uBAAuB,MAAM,CAAC,IAAI,aAAa,IAAI,CAAC,cAAc,eAAe,IAAI,CAAC,uBAAuB,EAAE,CAAC,CAAC;IACrI,CAAC,CACF,CAAC;AACJ,CAAC"}
|