swipium 1.0.1 → 1.2.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 (132) hide show
  1. package/README.md +21 -6
  2. package/THREAT_MODEL.md +59 -0
  3. package/dist/appMap/codeIndex.js +37 -5
  4. package/dist/appMap/codeIndex.js.map +1 -1
  5. package/dist/appMap/diff.js +60 -0
  6. package/dist/appMap/diff.js.map +1 -0
  7. package/dist/appMap/query.js +22 -4
  8. package/dist/appMap/query.js.map +1 -1
  9. package/dist/automation/capabilities.js +167 -0
  10. package/dist/automation/capabilities.js.map +1 -0
  11. package/dist/automation/gestures.js +94 -0
  12. package/dist/automation/gestures.js.map +1 -0
  13. package/dist/automation/maestroIr.js +282 -0
  14. package/dist/automation/maestroIr.js.map +1 -0
  15. package/dist/automation/plan.js +268 -0
  16. package/dist/automation/plan.js.map +1 -0
  17. package/dist/automation/report.js +83 -0
  18. package/dist/automation/report.js.map +1 -0
  19. package/dist/automation/selectors.js +201 -0
  20. package/dist/automation/selectors.js.map +1 -0
  21. package/dist/automation/types.js +13 -0
  22. package/dist/automation/types.js.map +1 -0
  23. package/dist/automation/waits.js +91 -0
  24. package/dist/automation/waits.js.map +1 -0
  25. package/dist/automation/webview.js +81 -0
  26. package/dist/automation/webview.js.map +1 -0
  27. package/dist/drivers/WdaDriver.js +18 -5
  28. package/dist/drivers/WdaDriver.js.map +1 -1
  29. package/dist/explore/candidates.js +17 -0
  30. package/dist/explore/candidates.js.map +1 -1
  31. package/dist/explore/runner.js +29 -2
  32. package/dist/explore/runner.js.map +1 -1
  33. package/dist/flows/repair.js +363 -0
  34. package/dist/flows/repair.js.map +1 -0
  35. package/dist/interop/maestro.js +151 -0
  36. package/dist/interop/maestro.js.map +1 -0
  37. package/dist/lib/wda.js +17 -0
  38. package/dist/lib/wda.js.map +1 -1
  39. package/dist/mobileAudit/checks.js +251 -0
  40. package/dist/mobileAudit/checks.js.map +1 -0
  41. package/dist/mobileAudit/evidence.js +49 -0
  42. package/dist/mobileAudit/evidence.js.map +1 -0
  43. package/dist/mobileAudit/profiles.js +73 -0
  44. package/dist/mobileAudit/profiles.js.map +1 -0
  45. package/dist/mobileAudit/results.js +41 -0
  46. package/dist/mobileAudit/results.js.map +1 -0
  47. package/dist/mobileAudit/runner.js +229 -0
  48. package/dist/mobileAudit/runner.js.map +1 -0
  49. package/dist/oracle/failures.js +1 -0
  50. package/dist/oracle/failures.js.map +1 -1
  51. package/dist/oracle/locator.js +177 -0
  52. package/dist/oracle/locator.js.map +1 -0
  53. package/dist/orchestration/envelope.js.map +1 -1
  54. package/dist/prompts/index.js +10 -0
  55. package/dist/prompts/index.js.map +1 -1
  56. package/dist/report/export.js +3 -1
  57. package/dist/report/export.js.map +1 -1
  58. package/dist/server.js +49 -2
  59. package/dist/server.js.map +1 -1
  60. package/dist/services/build.js +15 -2
  61. package/dist/services/build.js.map +1 -1
  62. package/dist/services/prepareIos.js +34 -4
  63. package/dist/services/prepareIos.js.map +1 -1
  64. package/dist/services/report.js +26 -9
  65. package/dist/services/report.js.map +1 -1
  66. package/dist/session/store.js.map +1 -1
  67. package/dist/suite/pom.js +24 -9
  68. package/dist/suite/pom.js.map +1 -1
  69. package/dist/testSuite/exporter.js +70 -0
  70. package/dist/testSuite/exporter.js.map +1 -0
  71. package/dist/testSuite/lint.js +53 -0
  72. package/dist/testSuite/lint.js.map +1 -0
  73. package/dist/tools/act.js +23 -2
  74. package/dist/tools/act.js.map +1 -1
  75. package/dist/tools/appControl.js +176 -0
  76. package/dist/tools/appControl.js.map +1 -0
  77. package/dist/tools/capabilities.js +75 -4
  78. package/dist/tools/capabilities.js.map +1 -1
  79. package/dist/tools/device.js +151 -0
  80. package/dist/tools/device.js.map +1 -0
  81. package/dist/tools/flow.js +67 -1
  82. package/dist/tools/flow.js.map +1 -1
  83. package/dist/tools/flowRepair.js +66 -0
  84. package/dist/tools/flowRepair.js.map +1 -0
  85. package/dist/tools/history.js +56 -0
  86. package/dist/tools/history.js.map +1 -0
  87. package/dist/tools/idling.js +104 -0
  88. package/dist/tools/idling.js.map +1 -0
  89. package/dist/tools/inputCapabilities.js +30 -0
  90. package/dist/tools/inputCapabilities.js.map +1 -0
  91. package/dist/tools/issues.js +218 -0
  92. package/dist/tools/issues.js.map +1 -0
  93. package/dist/tools/jobs.js +12 -1
  94. package/dist/tools/jobs.js.map +1 -1
  95. package/dist/tools/locator.js +57 -0
  96. package/dist/tools/locator.js.map +1 -0
  97. package/dist/tools/maestro.js +78 -0
  98. package/dist/tools/maestro.js.map +1 -0
  99. package/dist/tools/metro.js +260 -0
  100. package/dist/tools/metro.js.map +1 -0
  101. package/dist/tools/mobileAudit.js +115 -0
  102. package/dist/tools/mobileAudit.js.map +1 -0
  103. package/dist/tools/network.js +97 -5
  104. package/dist/tools/network.js.map +1 -1
  105. package/dist/tools/permissions.js +149 -0
  106. package/dist/tools/permissions.js.map +1 -0
  107. package/dist/tools/screenInfo.js +70 -0
  108. package/dist/tools/screenInfo.js.map +1 -0
  109. package/dist/tools/screenRecord.js +215 -6
  110. package/dist/tools/screenRecord.js.map +1 -1
  111. package/dist/tools/seed.js +101 -0
  112. package/dist/tools/seed.js.map +1 -0
  113. package/dist/tools/state.js +83 -0
  114. package/dist/tools/state.js.map +1 -1
  115. package/dist/tools/suite.js +49 -1
  116. package/dist/tools/suite.js.map +1 -1
  117. package/dist/tools/testSuite.js +233 -0
  118. package/dist/tools/testSuite.js.map +1 -0
  119. package/dist/tools/testThis.js +11 -3
  120. package/dist/tools/testThis.js.map +1 -1
  121. package/dist/tools/visual.js +139 -0
  122. package/dist/tools/visual.js.map +1 -0
  123. package/dist/tools/visualText.js +61 -0
  124. package/dist/tools/visualText.js.map +1 -0
  125. package/dist/tools/wait.js +58 -0
  126. package/dist/tools/wait.js.map +1 -0
  127. package/dist/version.js +54 -3
  128. package/dist/version.js.map +1 -1
  129. package/docs/README.md +4 -4
  130. package/docs/mcp-server.md +3 -3
  131. package/docs/tools.md +111 -2
  132. package/package.json +3 -2
package/README.md CHANGED
@@ -236,25 +236,40 @@ After setup, verify that the client lists `qa_test_this`, `qa_capabilities`, and
236
236
 
237
237
  ## Tool Docs
238
238
 
239
- Swipium v1 exposes 42 public MCP tools. Start with `qa_test_this` for low-context requests.
239
+ Swipium exposes 83 public MCP tools. Start with `qa_test_this` for low-context requests.
240
240
 
241
241
  Full reference: [docs/tools.md](docs/tools.md)
242
242
 
243
+ New in 1.2.0 — 24 additional tools, all backward compatible:
244
+
245
+ - **Durable issue memory**: `qa_issue_log`, `qa_issue_history`, `qa_issue_mark_fixed`, `qa_issue_triage`, `qa_issue_suppress`, `qa_issue_verify_fixed`, `qa_issue_metrics`, plus `qa_mobile_audit` (named, repeatable QA profiles). Fingerprints let later runs detect regressions of previously fixed issues.
246
+ - **Persistent test suite**: `qa_test_suite_read`, `qa_test_suite_update`, `qa_test_suite_generate`, `qa_test_suite_export`, `qa_test_suite_lint` — a canonical suite that grows across runs.
247
+ - **Flow system and suite quality**: `qa_flow_plan`, `qa_flow_repair`, `qa_suite_lint`, `qa_pom_generate`.
248
+ - **Maestro interop**: `qa_maestro_import`, `qa_maestro_export`.
249
+ - **Agent-efficiency helpers**: `qa_locator_suggest`, `qa_input_capabilities`, `qa_wait`, `qa_idling_status`, `qa_job_cancel`.
250
+
251
+ Earlier, 1.1.0 added device-parity, local-first visual, seeded-state, and report-history tools.
252
+
243
253
  | Group | Tools |
244
254
  | --- | --- |
245
- | Start | `qa_agent_brief`, `qa_capabilities`, `qa_test_this`, `qa_job_status`, `qa_status`, `qa_explain_blocker`, `qa_continue_from_blocker`, `qa_get_artifact` |
255
+ | Start | `qa_agent_brief`, `qa_capabilities`, `qa_test_this`, `qa_job_status`, `qa_job_cancel`, `qa_status`, `qa_explain_blocker`, `qa_continue_from_blocker`, `qa_get_artifact` |
246
256
  | Setup | `qa_doctor`, `qa_start_session`, `qa_detect_context`, `qa_plan`, `qa_prepare_target`, `qa_prepare_ios_target`, `qa_ios`, `qa_wda` |
247
- | Drive | `qa_snapshot`, `qa_act`, `qa_clear_overlay`, `qa_check_health`, `qa_screenshot`, `qa_note`, `qa_assert_visual` |
248
- | Run | `qa_smoke`, `qa_explore`, `qa_report` |
257
+ | Device | `qa_device_info`, `qa_permissions`, `qa_orientation`, `qa_geolocation`, `qa_network`, `qa_metro`, `qa_app_control`, `qa_screen_info`, `qa_screen_record` |
258
+ | Drive | `qa_snapshot`, `qa_act`, `qa_clear_overlay`, `qa_check_health`, `qa_screenshot`, `qa_note`, `qa_assert_visual`, `qa_visual`, `qa_visual_find_text`, `qa_locator_suggest`, `qa_input_capabilities`, `qa_wait`, `qa_idling_status` |
259
+ | State | `qa_seed`, `qa_state_prepare`, `qa_state_verify`, `qa_state_teardown` |
260
+ | Run | `qa_smoke`, `qa_explore`, `qa_report`, `qa_report_compare`, `qa_run_history` |
249
261
  | App map | `qa_app_map_build`, `qa_app_map_read`, `qa_app_map_query`, `qa_app_map_feature_scope`, `qa_app_map_validate` |
250
- | Flows and suites | `qa_flow_check`, `qa_flow_run`, `qa_flow_generate`, `qa_suite_generate`, `qa_suite_compile`, `qa_testcase_generate` |
262
+ | Flows and suites | `qa_flow_check`, `qa_flow_plan`, `qa_flow_run`, `qa_flow_generate`, `qa_flow_repair`, `qa_suite_generate`, `qa_suite_compile`, `qa_suite_lint`, `qa_pom_generate`, `qa_testcase_generate` |
263
+ | Test suite | `qa_test_suite_read`, `qa_test_suite_update`, `qa_test_suite_generate`, `qa_test_suite_export`, `qa_test_suite_lint` |
264
+ | Interop | `qa_maestro_import`, `qa_maestro_export` |
265
+ | Issues | `qa_issue_log`, `qa_issue_history`, `qa_issue_mark_fixed`, `qa_issue_triage`, `qa_issue_suppress`, `qa_issue_verify_fixed`, `qa_issue_metrics`, `qa_mobile_audit` |
251
266
  | First run | `qa_first_run_plan`, `qa_first_run_continue` |
252
267
  | Automation | `qa_automation_plan`, `qa_automation_generate`, `qa_automation_validate` |
253
268
 
254
269
  ## Why Swipium?
255
270
 
256
271
  - Agent-native: exposes QA work as MCP tools with structured outputs.
257
- - Simulator-first: focuses v1 on Android Emulator and iOS Simulator reliability.
272
+ - Simulator-first: focuses on Android Emulator and iOS Simulator reliability.
258
273
  - Evidence-first: screenshots, logs, reports, dumps, and artifacts are stored and linked.
259
274
  - App memory: the app map preserves screens, features, test cases, flows, and coverage context.
260
275
  - Practical consent: mutating actions are gated instead of hidden behind agent text.
@@ -0,0 +1,59 @@
1
+ # Swipium Threat Model
2
+
3
+ Last updated: 2026-06-02 (Swipium 2.1.0)
4
+
5
+ This document describes Swipium's trust boundaries, the threats it defends against, and the controls that enforce those defenses. It follows the MCP security guidance: validate inputs, use least privilege, obtain explicit consent for sensitive operations, protect secrets, and do not over-trust tool metadata.
6
+
7
+ ## What Swipium Is
8
+
9
+ Swipium is a local stdio MCP server that lets an AI agent run mobile QA against an Android Emulator or iOS Simulator on the developer's own machine. It is not a remote service. It has no network listener, no authentication surface, and no multi-tenant state.
10
+
11
+ ## Trust Boundaries
12
+
13
+ 1. MCP client to Swipium: the client (Claude, Gemini, Codex, or another MCP host) sends tool calls over stdio. Swipium trusts the transport but not the semantic intent: destructive actions require explicit, server-side consent regardless of what the client requests.
14
+ 2. Swipium to local toolchain: Swipium shells out to `adb`, `emulator`, `xcrun`/`simctl`, Gradle, and Metro. These run with the developer's own privileges. Swipium does not escalate privileges.
15
+ 3. Swipium to the project: Swipium reads and writes within the resolved project root and `.swipium/`. It does not write outside the project root without explicit approval.
16
+ 4. App under test to Swipium: screenshots, UI dumps, and logs from the app can contain sensitive data. Swipium treats this data as untrusted and redacts known secret shapes before surfacing it.
17
+
18
+ ## Assets
19
+
20
+ - Developer machine integrity and the local toolchain.
21
+ - The project source tree and `.swipium/` state (config, app map, flows, issue ledger, run history).
22
+ - Secrets the agent handles during testing (credentials, OTPs, tokens).
23
+ - App data on the emulator/simulator.
24
+
25
+ ## Adversaries and Threats
26
+
27
+ - Malicious or compromised MCP client / prompt injection: a client (or a poisoned tool description in another server) tries to trigger a destructive or exfiltrating action. Mitigation: server-side consent state machine for all destructive/privileged actions; exact command and effect are shown before execution; consent is per-action and not satisfiable by client assertion alone. Tool descriptions are linted (`test/toolMetadata.test.ts`) to stay honest and non-manipulative.
28
+ - Untrusted app content: the app renders attacker-controlled text (deep links, usernames, server responses) that could carry injection payloads into the transcript. Mitigation: snapshots and logs are structured and redacted; Swipium does not execute app-derived text as commands.
29
+ - Accidental data loss: a data wipe (`clear_data`, `fresh_start`) on a debug RN/Expo build removes the cached JS bundle and breaks the app. Mitigation: these actions are consent-gated high and additionally require `acknowledgeBundleRisk:true`; `qa_plan` surfaces `fresh_start` as UNSAFE with reason `bundle_cache_loss`.
30
+ - Environment left dirty: a run changes network state or leaves a recorder or Metro bundler running. Mitigation: network changes record the original state and auto-restore at report end, on `restore`, and on server shutdown; screen recordings and Metro bundlers are stopped on shutdown.
31
+ - Secret leakage into artifacts/reports: credentials or tokens entered during testing get written to logs, dumps, or reports. Mitigation: secret values provided via `qa_continue_from_blocker` are registered for redaction; known secret shapes are redacted from snapshots and reports; sensitive mode withholds screenshots and visual OCR on password/OTP screens.
32
+ - Sensitive-screen capture: screen recording or OCR captures a password/payment screen. Mitigation: recording and visual OCR are consent-gated, refuse sensitive sessions, and visual text/diff ops are withheld when a secure field is on screen unless explicitly forced.
33
+ - Untrusted seed/fixture execution: a fixture seed runs a local script or API call. Mitigation: all seed/state mutations are consent-gated with risk scaled by type (`script` high), git commands are refused, and seed failures are reported as setup failures, not app bugs.
34
+ - Stale client after upgrade: an MCP client keeps an old server process after an upgrade, exposing a stale tool surface. Mitigation: version and tool-count are reported on start and by `qa_doctor`; a stale-client hint is shown.
35
+
36
+ ## Controls Summary
37
+
38
+ - Server-side consent state machine with exact command/effect display and project-root boundary.
39
+ - Destructive-action guardrails (bundle-loss refusal) that the client cannot override.
40
+ - Secret redaction and sensitive-screen mode.
41
+ - Network restore and recorder/Metro shutdown hooks.
42
+ - External artifact handling within the project root; no writes outside without approval.
43
+ - Tool metadata lint and public tool-surface lockstep tests.
44
+ - Coordinate-space metadata on all visual results.
45
+
46
+ ## Explicit Non-Goals (Current Scope)
47
+
48
+ Swipium is simulator-local. The following are intentionally out of scope until a dedicated design and threat model exist for each:
49
+
50
+ - Remote or HTTP transport, authentication, and multi-tenant operation.
51
+ - Real-device execution.
52
+ - External service integrations (for example issue trackers or CI back-ends that send data off the machine).
53
+ - Remote AI vision that sends screenshots to a third-party service by default.
54
+
55
+ Adding any of these requires extending this document first.
56
+
57
+ ## Reporting
58
+
59
+ Security issues should be reported per `SECURITY.md`.
@@ -23,7 +23,7 @@ function extractSymbols(text) {
23
23
  }
24
24
  return [...out].slice(0, 60);
25
25
  }
26
- function tokenize(text) {
26
+ function tokenize(text, limit = 40) {
27
27
  const counts = new Map();
28
28
  for (const m of text.matchAll(/[A-Za-z][A-Za-z0-9]{2,}/g)) {
29
29
  // split camelCase into sub-words so "WeatherAnalysisScreen" matches "weather"/"analysis"
@@ -33,7 +33,18 @@ function tokenize(text) {
33
33
  if (p.length >= 3)
34
34
  counts.set(p, (counts.get(p) ?? 0) + 1);
35
35
  }
36
- return [...counts.entries()].sort((a, b) => b[1] - a[1]).slice(0, 40).map(([t]) => t);
36
+ return [...counts.entries()].sort((a, b) => b[1] - a[1]).slice(0, limit).map(([t]) => t);
37
+ }
38
+ function extractVisibleText(text) {
39
+ const chunks = [];
40
+ for (const m of text.matchAll(/"([^"\\]{2,200})"|'([^'\\]{2,200})'|`([^`\\$]{2,200})`/g)) {
41
+ const s = m[1] ?? m[2] ?? m[3];
42
+ if (s && !s.includes('/') && !s.startsWith('@') && !s.startsWith('.'))
43
+ chunks.push(s);
44
+ }
45
+ for (const m of text.matchAll(/>([^<>{}\n]{2,200})</g))
46
+ chunks.push(m[1]);
47
+ return chunks.join(' ');
37
48
  }
38
49
  const STOP = new Set(['const', 'export', 'import', 'function', 'return', 'class', 'this', 'from', 'react', 'native', 'string', 'number', 'void', 'null', 'undefined', 'true', 'false', 'async', 'await']);
39
50
  /** Build a code index from collected source files. Skips tests/specs and oversized files. */
@@ -48,18 +59,20 @@ export function buildCodeIndex(root, files, generatedAt) {
48
59
  continue;
49
60
  const symbols = extractSymbols(text);
50
61
  const tokens = tokenize(text).filter((t) => !STOP.has(t));
51
- if (!symbols.length && !tokens.length)
62
+ const textTokens = tokenize(extractVisibleText(text), 160).filter((t) => !STOP.has(t));
63
+ if (!symbols.length && !tokens.length && !textTokens.length)
52
64
  continue;
53
- out.push({ file: relPath, symbols, tokens });
65
+ out.push({ file: relPath, symbols, tokens, ...(textTokens.length ? { textTokens } : {}) });
54
66
  if (out.length >= 2000)
55
67
  break;
56
68
  }
57
69
  return { schemaVersion: 1, generatedAt, files: out };
58
70
  }
59
- /** Score a file against query terms (symbol hits weigh more than token hits). */
71
+ /** Score a file against query terms. */
60
72
  export function scoreFile(entry, terms) {
61
73
  let score = 0;
62
74
  const symLower = entry.symbols.map((s) => s.toLowerCase());
75
+ const textTokens = entry.textTokens ?? [];
63
76
  for (const t of terms) {
64
77
  if (symLower.some((s) => s.includes(t)))
65
78
  score += 3;
@@ -67,7 +80,26 @@ export function scoreFile(entry, terms) {
67
80
  score += 1;
68
81
  if (entry.file.toLowerCase().includes(t))
69
82
  score += 2;
83
+ if (textTokens.includes(t))
84
+ score += 2;
70
85
  }
71
86
  return score;
72
87
  }
88
+ export function fileMatchDimensions(entry, terms) {
89
+ const dims = new Set();
90
+ const symLower = entry.symbols.map((s) => s.toLowerCase());
91
+ const textTokens = entry.textTokens ?? [];
92
+ const fileLower = entry.file.toLowerCase();
93
+ for (const t of terms) {
94
+ if (symLower.some((s) => s.includes(t)))
95
+ dims.add('component_name');
96
+ if (entry.tokens.includes(t))
97
+ dims.add('identifier');
98
+ if (fileLower.includes(t))
99
+ dims.add('file_name');
100
+ if (textTokens.includes(t))
101
+ dims.add('visible_text');
102
+ }
103
+ return [...dims];
104
+ }
73
105
  //# sourceMappingURL=codeIndex.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"codeIndex.js","sourceRoot":"","sources":["../../src/appMap/codeIndex.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"codeIndex.js","sourceRoot":"","sources":["../../src/appMap/codeIndex.ts"],"names":[],"mappings":"AAAA,2FAA2F;AAC3F,6FAA6F;AAC7F,+FAA+F;AAC/F,+FAA+F;AAE/F,OAAO,EAAE,QAAQ,EAAE,MAAM,WAAW,CAAC;AACrC,OAAO,EAAE,GAAG,EAAE,YAAY,EAAE,MAAM,aAAa,CAAC;AAehD,MAAM,UAAU,GAAa;IAC3B,kEAAkE;IAClE,+CAA+C;IAC/C,kDAAkD;IAClD,qGAAqG;IACrG,+BAA+B;IAC/B,kDAAkD,EAAE,eAAe;CACpE,CAAC;AAEF,SAAS,cAAc,CAAC,IAAY;IAClC,MAAM,GAAG,GAAG,IAAI,GAAG,EAAU,CAAC;IAC9B,KAAK,MAAM,EAAE,IAAI,UAAU,EAAE,CAAC;QAC5B,EAAE,CAAC,SAAS,GAAG,CAAC,CAAC;QACjB,IAAI,CAAyB,CAAC;QAC9B,OAAO,CAAC,CAAC,GAAG,EAAE,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;YAAE,IAAI,CAAC,CAAC,CAAC,CAAC;gBAAE,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC;IACtD,CAAC;IACD,OAAO,CAAC,GAAG,GAAG,CAAC,CAAC,KAAK,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC;AAC/B,CAAC;AAED,SAAS,QAAQ,CAAC,IAAY,EAAE,KAAK,GAAG,EAAE;IACxC,MAAM,MAAM,GAAG,IAAI,GAAG,EAAkB,CAAC;IACzC,KAAK,MAAM,CAAC,IAAI,IAAI,CAAC,QAAQ,CAAC,0BAA0B,CAAC,EAAE,CAAC;QAC1D,yFAAyF;QACzF,MAAM,IAAI,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC;QAClB,MAAM,KAAK,GAAG,IAAI,CAAC,OAAO,CAAC,oBAAoB,EAAE,OAAO,CAAC,CAAC,WAAW,EAAE,CAAC,KAAK,CAAC,KAAK,CAAC,CAAC;QACrF,KAAK,MAAM,CAAC,IAAI,KAAK;YAAE,IAAI,CAAC,CAAC,MAAM,IAAI,CAAC;gBAAE,MAAM,CAAC,GAAG,CAAC,CAAC,EAAE,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC;IACpF,CAAC;IACD,OAAO,CAAC,GAAG,MAAM,CAAC,OAAO,EAAE,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,EAAE,KAAK,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,CAAC;AAC3F,CAAC;AAED,SAAS,kBAAkB,CAAC,IAAY;IACtC,MAAM,MAAM,GAAa,EAAE,CAAC;IAC5B,KAAK,MAAM,CAAC,IAAI,IAAI,CAAC,QAAQ,CAAC,yDAAyD,CAAC,EAAE,CAAC;QACzF,MAAM,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,CAAC;QAC/B,IAAI,CAAC,IAAI,CAAC,CAAC,CAAC,QAAQ,CAAC,GAAG,CAAC,IAAI,CAAC,CAAC,CAAC,UAAU,CAAC,GAAG,CAAC,IAAI,CAAC,CAAC,CAAC,UAAU,CAAC,GAAG,CAAC;YAAE,MAAM,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;IACxF,CAAC;IACD,KAAK,MAAM,CAAC,IAAI,IAAI,CAAC,QAAQ,CAAC,uBAAuB,CAAC;QAAE,MAAM,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC;IAC1E,OAAO,MAAM,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC;AAC1B,CAAC;AAED,MAAM,IAAI,GAAG,IAAI,GAAG,CAAC,CAAC,OAAO,EAAE,QAAQ,EAAE,QAAQ,EAAE,UAAU,EAAE,QAAQ,EAAE,OAAO,EAAE,MAAM,EAAE,MAAM,EAAE,OAAO,EAAE,QAAQ,EAAE,QAAQ,EAAE,QAAQ,EAAE,MAAM,EAAE,MAAM,EAAE,WAAW,EAAE,MAAM,EAAE,OAAO,EAAE,OAAO,EAAE,OAAO,CAAC,CAAC,CAAC;AAE1M,6FAA6F;AAC7F,MAAM,UAAU,cAAc,CAAC,IAAY,EAAE,KAAe,EAAE,WAAmB;IAC/E,MAAM,GAAG,GAAqB,EAAE,CAAC;IACjC,KAAK,MAAM,CAAC,IAAI,KAAK,EAAE,CAAC;QACtB,MAAM,OAAO,GAAG,GAAG,CAAC,IAAI,EAAE,CAAC,CAAC,CAAC;QAC7B,IAAI,yBAAyB,CAAC,IAAI,CAAC,QAAQ,CAAC,CAAC,CAAC,CAAC;YAAE,SAAS;QAC1D,MAAM,IAAI,GAAG,YAAY,CAAC,CAAC,CAAC,CAAC;QAC7B,IAAI,CAAC,IAAI,IAAI,IAAI,CAAC,MAAM,GAAG,OAAO;YAAE,SAAS;QAC7C,MAAM,OAAO,GAAG,cAAc,CAAC,IAAI,CAAC,CAAC;QACrC,MAAM,MAAM,GAAG,QAAQ,CAAC,IAAI,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC;QAC1D,MAAM,UAAU,GAAG,QAAQ,CAAC,kBAAkB,CAAC,IAAI,CAAC,EAAE,GAAG,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC;QACvF,IAAI,CAAC,OAAO,CAAC,MAAM,IAAI,CAAC,MAAM,CAAC,MAAM,IAAI,CAAC,UAAU,CAAC,MAAM;YAAE,SAAS;QACtE,GAAG,CAAC,IAAI,CAAC,EAAE,IAAI,EAAE,OAAO,EAAE,OAAO,EAAE,MAAM,EAAE,GAAG,CAAC,UAAU,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,UAAU,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,CAAC;QAC3F,IAAI,GAAG,CAAC,MAAM,IAAI,IAAI;YAAE,MAAM;IAChC,CAAC;IACD,OAAO,EAAE,aAAa,EAAE,CAAC,EAAE,WAAW,EAAE,KAAK,EAAE,GAAG,EAAE,CAAC;AACvD,CAAC;AAED,wCAAwC;AACxC,MAAM,UAAU,SAAS,CAAC,KAAqB,EAAE,KAAe;IAC9D,IAAI,KAAK,GAAG,CAAC,CAAC;IACd,MAAM,QAAQ,GAAG,KAAK,CAAC,OAAO,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,WAAW,EAAE,CAAC,CAAC;IAC3D,MAAM,UAAU,GAAG,KAAK,CAAC,UAAU,IAAI,EAAE,CAAC;IAC1C,KAAK,MAAM,CAAC,IAAI,KAAK,EAAE,CAAC;QACtB,IAAI,QAAQ,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,QAAQ,CAAC,CAAC,CAAC,CAAC;YAAE,KAAK,IAAI,CAAC,CAAC;QACpD,IAAI,KAAK,CAAC,MAAM,CAAC,QAAQ,CAAC,CAAC,CAAC;YAAE,KAAK,IAAI,CAAC,CAAC;QACzC,IAAI,KAAK,CAAC,IAAI,CAAC,WAAW,EAAE,CAAC,QAAQ,CAAC,CAAC,CAAC;YAAE,KAAK,IAAI,CAAC,CAAC;QACrD,IAAI,UAAU,CAAC,QAAQ,CAAC,CAAC,CAAC;YAAE,KAAK,IAAI,CAAC,CAAC;IACzC,CAAC;IACD,OAAO,KAAK,CAAC;AACf,CAAC;AAED,MAAM,UAAU,mBAAmB,CAAC,KAAqB,EAAE,KAAe;IACxE,MAAM,IAAI,GAAG,IAAI,GAAG,EAAU,CAAC;IAC/B,MAAM,QAAQ,GAAG,KAAK,CAAC,OAAO,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,WAAW,EAAE,CAAC,CAAC;IAC3D,MAAM,UAAU,GAAG,KAAK,CAAC,UAAU,IAAI,EAAE,CAAC;IAC1C,MAAM,SAAS,GAAG,KAAK,CAAC,IAAI,CAAC,WAAW,EAAE,CAAC;IAC3C,KAAK,MAAM,CAAC,IAAI,KAAK,EAAE,CAAC;QACtB,IAAI,QAAQ,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,QAAQ,CAAC,CAAC,CAAC,CAAC;YAAE,IAAI,CAAC,GAAG,CAAC,gBAAgB,CAAC,CAAC;QACpE,IAAI,KAAK,CAAC,MAAM,CAAC,QAAQ,CAAC,CAAC,CAAC;YAAE,IAAI,CAAC,GAAG,CAAC,YAAY,CAAC,CAAC;QACrD,IAAI,SAAS,CAAC,QAAQ,CAAC,CAAC,CAAC;YAAE,IAAI,CAAC,GAAG,CAAC,WAAW,CAAC,CAAC;QACjD,IAAI,UAAU,CAAC,QAAQ,CAAC,CAAC,CAAC;YAAE,IAAI,CAAC,GAAG,CAAC,cAAc,CAAC,CAAC;IACvD,CAAC;IACD,OAAO,CAAC,GAAG,IAAI,CAAC,CAAC;AACnB,CAAC"}
@@ -0,0 +1,60 @@
1
+ // Map diff (SWIPIUM-REQ-01 qa_app_map_diff). Reports added/removed/changed screens, feature
2
+ // coverage changes, stale test cases, locator-readiness changes, and new untested code areas
3
+ // between two AppKnowledgeMap snapshots. Pure — the tool layer resolves which two maps to compare.
4
+ function ids(arr) {
5
+ return new Set(arr.map((a) => a.id));
6
+ }
7
+ export function diffAppMaps(baseline, current) {
8
+ const baseStatic = ids(baseline.staticTopology.screens);
9
+ const curStatic = ids(current.staticTopology.screens);
10
+ const baseRuntime = ids(baseline.runtimeTopology.screens);
11
+ const curRuntime = ids(current.runtimeTopology.screens);
12
+ const staticAdded = [...curStatic].filter((id) => !baseStatic.has(id));
13
+ const staticRemoved = [...baseStatic].filter((id) => !curStatic.has(id));
14
+ const runtimeAdded = [...curRuntime].filter((id) => !baseRuntime.has(id));
15
+ const runtimeRemoved = [...baseRuntime].filter((id) => !curRuntime.has(id));
16
+ // changed runtime screens: visits / link / readiness drift
17
+ const changedScreens = [];
18
+ const locatorReadinessChanges = [];
19
+ for (const cur of current.runtimeTopology.screens) {
20
+ const prev = baseline.runtimeTopology.screens.find((s) => s.id === cur.id || s.signature === cur.signature);
21
+ if (!prev)
22
+ continue;
23
+ if (prev.linkedStaticScreenId !== cur.linkedStaticScreenId) {
24
+ changedScreens.push({ id: cur.id, field: 'linkedStaticScreenId', was: prev.linkedStaticScreenId ?? null, now: cur.linkedStaticScreenId ?? null });
25
+ }
26
+ if (prev.locatorReadiness !== cur.locatorReadiness) {
27
+ locatorReadinessChanges.push({ id: cur.id, was: prev.locatorReadiness, now: cur.locatorReadiness });
28
+ }
29
+ }
30
+ // feature coverage changes
31
+ const featureCoverageChanges = [];
32
+ for (const cur of current.features) {
33
+ const prev = baseline.features.find((f) => f.id === cur.id);
34
+ if (prev && prev.testCoverage !== cur.testCoverage) {
35
+ featureCoverageChanges.push({ featureId: cur.id, was: prev.testCoverage, now: cur.testCoverage });
36
+ }
37
+ }
38
+ // stale tests: cases whose feature/screen no longer exists in current
39
+ const curFeatureIds = ids(current.features);
40
+ const staleTests = current.testSuite.cases
41
+ .filter((c) => (c.featureId && !curFeatureIds.has(c.featureId)) || (c.screenId && !curStatic.has(c.screenId) && !curRuntime.has(c.screenId)) || c.stale)
42
+ .map((c) => c.id);
43
+ // new untested code areas: newly added static screens with no linked runtime screen
44
+ const linkedStatic = new Set(current.runtimeTopology.screens.map((r) => r.linkedStaticScreenId).filter(Boolean));
45
+ const newUntestedCodeAreas = staticAdded.filter((id) => !linkedStatic.has(id));
46
+ const summary = `+${staticAdded.length}/-${staticRemoved.length} static screens, +${runtimeAdded.length}/-${runtimeRemoved.length} runtime screens; ` +
47
+ `${featureCoverageChanges.length} coverage change(s), ${locatorReadinessChanges.length} locator-readiness change(s), ` +
48
+ `${staleTests.length} stale test(s), ${newUntestedCodeAreas.length} new untested area(s)`;
49
+ return {
50
+ staticScreens: { added: staticAdded, removed: staticRemoved },
51
+ runtimeScreens: { added: runtimeAdded, removed: runtimeRemoved },
52
+ changedScreens,
53
+ featureCoverageChanges,
54
+ locatorReadinessChanges,
55
+ staleTests,
56
+ newUntestedCodeAreas,
57
+ summary,
58
+ };
59
+ }
60
+ //# sourceMappingURL=diff.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"diff.js","sourceRoot":"","sources":["../../src/appMap/diff.ts"],"names":[],"mappings":"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"}
@@ -1,7 +1,7 @@
1
1
  // Map query (SWIPIUM-REQ-01 qa_app_map_query). Searches the feature index, static topology, runtime
2
2
  // graph, and tests, returning RANKED results with provenance, confidence, source files,
3
3
  // screens, and a recommended next Swipium tool call. Pure + deterministic so it is unit-testable.
4
- import { scoreFile } from './codeIndex.js';
4
+ import { fileMatchDimensions, scoreFile } from './codeIndex.js';
5
5
  function terms(query) {
6
6
  return [...new Set(query.toLowerCase().match(/[a-z0-9]{3,}/g) ?? [])];
7
7
  }
@@ -19,6 +19,17 @@ export function queryAppMap(map, codeIndex, opts) {
19
19
  const wantsScreen = intent === 'screen' || intent === 'freeform';
20
20
  const wantsCode = intent === 'code' || intent === 'freeform';
21
21
  const wantsTest = intent === 'test' || intent === 'freeform';
22
+ const textTokensByFile = new Map();
23
+ for (const f of codeIndex?.files ?? []) {
24
+ if (f.textTokens?.length)
25
+ textTokensByFile.set(f.file, new Set(f.textTokens));
26
+ }
27
+ const fileTextHits = (file) => {
28
+ const tokens = textTokensByFile.get(file);
29
+ if (!tokens)
30
+ return 0;
31
+ return ts.filter((t) => tokens.has(t)).length;
32
+ };
22
33
  if (wantsFeature) {
23
34
  for (const f of map.features) {
24
35
  const hay = `${f.title} ${f.objective ?? ''} ${f.reasons.join(' ')} ${f.id}`;
@@ -45,16 +56,23 @@ export function queryAppMap(map, codeIndex, opts) {
45
56
  if (wantsScreen) {
46
57
  for (const s of map.staticTopology.screens) {
47
58
  const hay = `${s.name} ${s.route ?? ''} ${s.sourceFiles.join(' ')} ${s.reasons.join(' ')}`;
48
- const score = termHits(hay, ts) * 2;
59
+ const nameRouteHits = termHits(hay, ts);
60
+ const visibleHits = s.sourceFiles.reduce((sum, f) => sum + fileTextHits(f), 0);
61
+ const score = nameRouteHits * 2 + visibleHits * 2;
49
62
  if (score <= 0)
50
63
  continue;
64
+ const provenance = ['code_scan'];
65
+ if (nameRouteHits > 0)
66
+ provenance.push('route/name');
67
+ if (visibleHits > 0)
68
+ provenance.push('visible_text');
51
69
  results.push({
52
70
  type: 'screen',
53
71
  id: s.id,
54
72
  title: s.name,
55
73
  score,
56
74
  confidence: s.confidence,
57
- provenance: ['code_scan'],
75
+ provenance,
58
76
  sourceFiles: s.sourceFiles.slice(0, 8),
59
77
  screens: [s.id],
60
78
  recommendedNextTool: { tool: 'qa_explore', args: { goal: `reach the ${s.name} screen` }, why: 'Exercise this screen at runtime to confirm + capture locators' },
@@ -87,7 +105,7 @@ export function queryAppMap(map, codeIndex, opts) {
87
105
  id: file.file,
88
106
  title: file.file,
89
107
  score,
90
- provenance: ['code_scan'],
108
+ provenance: ['code_scan', ...fileMatchDimensions(file, ts)],
91
109
  sourceFiles: [file.file],
92
110
  screens: [],
93
111
  recommendedNextTool: { tool: 'qa_app_map_query', args: { query: opts.query, intent: 'feature' }, why: 'Pivot from this file to the feature(s) it backs' },
@@ -1 +1 @@
1
- {"version":3,"file":"query.js","sourceRoot":"","sources":["../../src/appMap/query.ts"],"names":[],"mappings":"AAAA,oGAAoG;AACpG,wFAAwF;AACxF,kGAAkG;AAElG,OAAO,EAAE,SAAS,EAAkB,MAAM,gBAAgB,CAAC;AA8B3D,SAAS,KAAK,CAAC,KAAa;IAC1B,OAAO,CAAC,GAAG,IAAI,GAAG,CAAC,KAAK,CAAC,WAAW,EAAE,CAAC,KAAK,CAAC,eAAe,CAAC,IAAI,EAAE,CAAC,CAAC,CAAC;AACxE,CAAC;AAED,MAAM,IAAI,GAAG,IAAI,GAAG,CAAC,CAAC,KAAK,EAAE,KAAK,EAAE,KAAK,EAAE,MAAM,EAAE,MAAM,EAAE,KAAK,EAAE,SAAS,EAAE,QAAQ,EAAE,MAAM,EAAE,MAAM,CAAC,CAAC,CAAC;AAExG,SAAS,QAAQ,CAAC,QAAgB,EAAE,EAAY;IAC9C,MAAM,KAAK,GAAG,QAAQ,CAAC,WAAW,EAAE,CAAC;IACrC,OAAO,EAAE,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,KAAK,CAAC,QAAQ,CAAC,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC;AACpD,CAAC;AAED,MAAM,UAAU,WAAW,CACzB,GAAoB,EACpB,SAA2B,EAC3B,IAA6D;IAE7D,MAAM,MAAM,GAAG,IAAI,CAAC,MAAM,IAAI,UAAU,CAAC;IACzC,MAAM,KAAK,GAAG,IAAI,CAAC,KAAK,IAAI,EAAE,CAAC;IAC/B,MAAM,EAAE,GAAG,KAAK,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC;IACzD,MAAM,OAAO,GAAkB,EAAE,CAAC;IAElC,MAAM,YAAY,GAAG,MAAM,KAAK,SAAS,IAAI,MAAM,KAAK,UAAU,CAAC;IACnE,MAAM,WAAW,GAAG,MAAM,KAAK,QAAQ,IAAI,MAAM,KAAK,UAAU,CAAC;IACjE,MAAM,SAAS,GAAG,MAAM,KAAK,MAAM,IAAI,MAAM,KAAK,UAAU,CAAC;IAC7D,MAAM,SAAS,GAAG,MAAM,KAAK,MAAM,IAAI,MAAM,KAAK,UAAU,CAAC;IAE7D,IAAI,YAAY,EAAE,CAAC;QACjB,KAAK,MAAM,CAAC,IAAI,GAAG,CAAC,QAAQ,EAAE,CAAC;YAC7B,MAAM,GAAG,GAAG,GAAG,CAAC,CAAC,KAAK,IAAI,CAAC,CAAC,SAAS,IAAI,EAAE,IAAI,CAAC,CAAC,OAAO,CAAC,IAAI,CAAC,GAAG,CAAC,IAAI,CAAC,CAAC,EAAE,EAAE,CAAC;YAC7E,MAAM,KAAK,GAAG,QAAQ,CAAC,GAAG,EAAE,EAAE,CAAC,GAAG,CAAC,GAAG,QAAQ,CAAC,CAAC,CAAC,WAAW,CAAC,IAAI,CAAC,GAAG,CAAC,EAAE,EAAE,CAAC,CAAC;YAC5E,IAAI,KAAK,IAAI,CAAC;gBAAE,SAAS;YACzB,OAAO,CAAC,IAAI,CAAC;gBACX,IAAI,EAAE,SAAS;gBACf,EAAE,EAAE,CAAC,CAAC,EAAE;gBACR,KAAK,EAAE,CAAC,CAAC,KAAK;gBACd,KAAK;gBACL,UAAU,EAAE,CAAC,CAAC,UAAU;gBACxB,UAAU,EAAE,CAAC,CAAC,CAAC,MAAM,KAAK,MAAM,CAAC,CAAC,CAAC,WAAW,CAAC,CAAC,CAAC,uBAAuB,CAAC;gBACzE,WAAW,EAAE,CAAC,CAAC,WAAW,CAAC,KAAK,CAAC,CAAC,EAAE,CAAC,CAAC;gBACtC,OAAO,EAAE,CAAC,GAAG,CAAC,CAAC,aAAa,EAAE,GAAG,CAAC,CAAC,cAAc,CAAC,CAAC,KAAK,CAAC,CAAC,EAAE,EAAE,CAAC;gBAC/D,mBAAmB,EAAE;oBACnB,IAAI,EAAE,cAAc;oBACpB,IAAI,EAAE,EAAE,IAAI,EAAE,SAAS,EAAE,IAAI,EAAE,eAAe,EAAE,QAAQ,EAAE,CAAC,CAAC,KAAK,EAAE,OAAO,EAAE,IAAI,EAAE;oBAClF,GAAG,EAAE,uBAAuB,CAAC,CAAC,KAAK,cAAc,CAAC,CAAC,YAAY,YAAY;iBAC5E;aACF,CAAC,CAAC;QACL,CAAC;IACH,CAAC;IAED,IAAI,WAAW,EAAE,CAAC;QAChB,KAAK,MAAM,CAAC,IAAI,GAAG,CAAC,cAAc,CAAC,OAAO,EAAE,CAAC;YAC3C,MAAM,GAAG,GAAG,GAAG,CAAC,CAAC,IAAI,IAAI,CAAC,CAAC,KAAK,IAAI,EAAE,IAAI,CAAC,CAAC,WAAW,CAAC,IAAI,CAAC,GAAG,CAAC,IAAI,CAAC,CAAC,OAAO,CAAC,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC;YAC3F,MAAM,KAAK,GAAG,QAAQ,CAAC,GAAG,EAAE,EAAE,CAAC,GAAG,CAAC,CAAC;YACpC,IAAI,KAAK,IAAI,CAAC;gBAAE,SAAS;YACzB,OAAO,CAAC,IAAI,CAAC;gBACX,IAAI,EAAE,QAAQ;gBACd,EAAE,EAAE,CAAC,CAAC,EAAE;gBACR,KAAK,EAAE,CAAC,CAAC,IAAI;gBACb,KAAK;gBACL,UAAU,EAAE,CAAC,CAAC,UAAU;gBACxB,UAAU,EAAE,CAAC,WAAW,CAAC;gBACzB,WAAW,EAAE,CAAC,CAAC,WAAW,CAAC,KAAK,CAAC,CAAC,EAAE,CAAC,CAAC;gBACtC,OAAO,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;gBACf,mBAAmB,EAAE,EAAE,IAAI,EAAE,YAAY,EAAE,IAAI,EAAE,EAAE,IAAI,EAAE,aAAa,CAAC,CAAC,IAAI,SAAS,EAAE,EAAE,GAAG,EAAE,+DAA+D,EAAE;aAChK,CAAC,CAAC;QACL,CAAC;QACD,KAAK,MAAM,CAAC,IAAI,GAAG,CAAC,eAAe,CAAC,OAAO,EAAE,CAAC;YAC5C,MAAM,GAAG,GAAG,GAAG,CAAC,CAAC,KAAK,IAAI,EAAE,IAAI,CAAC,CAAC,CAAC,UAAU,IAAI,EAAE,CAAC,CAAC,IAAI,CAAC,GAAG,CAAC,IAAI,CAAC,CAAC,KAAK,IAAI,EAAE,EAAE,CAAC;YAClF,MAAM,KAAK,GAAG,QAAQ,CAAC,GAAG,EAAE,EAAE,CAAC,GAAG,CAAC,CAAC;YACpC,IAAI,KAAK,IAAI,CAAC;gBAAE,SAAS;YACzB,OAAO,CAAC,IAAI,CAAC;gBACX,IAAI,EAAE,QAAQ;gBACd,EAAE,EAAE,CAAC,CAAC,EAAE;gBACR,KAAK,EAAE,CAAC,CAAC,KAAK,IAAI,CAAC,CAAC,EAAE;gBACtB,KAAK;gBACL,UAAU,EAAE,CAAC,SAAS,CAAC;gBACvB,WAAW,EAAE,EAAE;gBACf,OAAO,EAAE,CAAC,CAAC,CAAC,EAAE,EAAE,GAAG,CAAC,CAAC,CAAC,oBAAoB,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,oBAAoB,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC;gBAC5E,mBAAmB,EAAE,EAAE,IAAI,EAAE,iBAAiB,EAAE,IAAI,EAAE,EAAE,OAAO,EAAE,SAAS,EAAE,QAAQ,EAAE,CAAC,CAAC,EAAE,EAAE,EAAE,GAAG,EAAE,yCAAyC,EAAE;aAC/I,CAAC,CAAC;QACL,CAAC;IACH,CAAC;IAED,IAAI,SAAS,IAAI,SAAS,EAAE,CAAC;QAC3B,KAAK,MAAM,IAAI,IAAI,SAAS,CAAC,KAAK,EAAE,CAAC;YACnC,MAAM,KAAK,GAAG,SAAS,CAAC,IAAI,EAAE,EAAE,CAAC,CAAC;YAClC,IAAI,KAAK,IAAI,CAAC;gBAAE,SAAS;YACzB,OAAO,CAAC,IAAI,CAAC;gBACX,IAAI,EAAE,MAAM;gBACZ,EAAE,EAAE,IAAI,CAAC,IAAI;gBACb,KAAK,EAAE,IAAI,CAAC,IAAI;gBAChB,KAAK;gBACL,UAAU,EAAE,CAAC,WAAW,CAAC;gBACzB,WAAW,EAAE,CAAC,IAAI,CAAC,IAAI,CAAC;gBACxB,OAAO,EAAE,EAAE;gBACX,mBAAmB,EAAE,EAAE,IAAI,EAAE,kBAAkB,EAAE,IAAI,EAAE,EAAE,KAAK,EAAE,IAAI,CAAC,KAAK,EAAE,MAAM,EAAE,SAAS,EAAE,EAAE,GAAG,EAAE,iDAAiD,EAAE;aAC1J,CAAC,CAAC;QACL,CAAC;IACH,CAAC;IAED,IAAI,SAAS,EAAE,CAAC;QACd,KAAK,MAAM,CAAC,IAAI,GAAG,CAAC,SAAS,CAAC,KAAK,EAAE,CAAC;YACpC,MAAM,GAAG,GAAG,GAAG,CAAC,CAAC,KAAK,IAAI,CAAC,CAAC,EAAE,IAAI,CAAC,CAAC,MAAM,IAAI,EAAE,EAAE,CAAC;YACnD,MAAM,KAAK,GAAG,QAAQ,CAAC,GAAG,EAAE,EAAE,CAAC,GAAG,CAAC,CAAC;YACpC,IAAI,KAAK,IAAI,CAAC;gBAAE,SAAS;YACzB,OAAO,CAAC,IAAI,CAAC;gBACX,IAAI,EAAE,MAAM;gBACZ,EAAE,EAAE,CAAC,CAAC,EAAE;gBACR,KAAK,EAAE,CAAC,CAAC,KAAK;gBACd,KAAK;gBACL,UAAU,EAAE,CAAC,WAAW,CAAC;gBACzB,WAAW,EAAE,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,EAAE;gBACvC,OAAO,EAAE,CAAC,CAAC,CAAC,SAAS,EAAE,CAAC,CAAC,QAAQ,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,EAAe,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC;gBAClE,mBAAmB,EAAE,EAAE,IAAI,EAAE,aAAa,EAAE,IAAI,EAAE,EAAE,EAAE,GAAG,EAAE,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,4CAA4C,CAAC,CAAC,CAAC,6BAA6B,EAAE;aACpJ,CAAC,CAAC;QACL,CAAC;IACH,CAAC;IAED,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,KAAK,GAAG,CAAC,CAAC,KAAK,IAAI,CAAC,CAAC,CAAC,UAAU,IAAI,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,UAAU,IAAI,CAAC,CAAC,CAAC,CAAC;IACvF,OAAO,EAAE,KAAK,EAAE,IAAI,CAAC,KAAK,EAAE,MAAM,EAAE,OAAO,EAAE,OAAO,CAAC,KAAK,CAAC,CAAC,EAAE,KAAK,CAAC,EAAE,KAAK,EAAE,OAAO,CAAC,MAAM,EAAE,CAAC;AAChG,CAAC"}
1
+ {"version":3,"file":"query.js","sourceRoot":"","sources":["../../src/appMap/query.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,167 @@
1
+ // Automation Kernel V2 — Workstream 1: backend capability matrix. Pure functions that answer
2
+ // "what can this backend actually do?" before any device is touched. The planner (plan.ts) consumes
3
+ // these to classify each step as native / supported_with_fallback / visual_only / unsupported and to
4
+ // name the exact missing capability when something cannot run.
5
+ //
6
+ // Driver.kind values map to backends as: 'direct' → android-direct, 'simulator' → ios-raw-simulator,
7
+ // 'wda' → ios-wda, 'remote' → an Appium backend (uiautomator2 | xcuitest, disambiguated by session).
8
+ function base(backend) {
9
+ return {
10
+ backend,
11
+ install: false,
12
+ launch: false,
13
+ terminate: false,
14
+ openUrl: false,
15
+ screenshot: false,
16
+ logs: false,
17
+ structuredTree: false,
18
+ nativeSelectors: false,
19
+ resourceId: false,
20
+ accessibilityId: false,
21
+ iosPredicate: false,
22
+ iosClassChain: false,
23
+ textSelector: false,
24
+ textInputAscii: false,
25
+ textInputUnicode: false,
26
+ clearText: false,
27
+ longPress: false,
28
+ doubleTap: false,
29
+ scrollUntilVisible: false,
30
+ pinch: false,
31
+ drag: false,
32
+ systemAlerts: false,
33
+ appDeclaredIdling: false,
34
+ wdaIdling: false,
35
+ webviewContexts: false,
36
+ screenRecording: false,
37
+ visualFallback: false,
38
+ ocrFallback: false,
39
+ notes: [],
40
+ };
41
+ }
42
+ /** Map a Swipium Driver.kind (+ optional Appium session) to an automation backend identity. */
43
+ export function backendForDriverKind(kind, session) {
44
+ switch (kind) {
45
+ case 'direct':
46
+ return 'android-direct';
47
+ case 'simulator':
48
+ return 'ios-raw-simulator';
49
+ case 'wda':
50
+ return 'ios-wda';
51
+ case 'remote':
52
+ return appiumBackendFromSession(session);
53
+ default:
54
+ return 'unknown';
55
+ }
56
+ }
57
+ export function appiumBackendFromSession(session) {
58
+ const name = (session?.automationName ?? '').toLowerCase();
59
+ const platform = (session?.platformName ?? '').toLowerCase();
60
+ // iOS evidence first (an XCUITest automationName or an iOS platform), then Android.
61
+ if (name.includes('xcuitest') || platform.includes('ios'))
62
+ return 'appium-xcuitest';
63
+ // Android: infer UiAutomator2 from the driver name OR from Android platform evidence alone
64
+ // (espresso also implies an Android session).
65
+ if (name.includes('uiautomator2') || name.includes('espresso') || name.includes('android') || platform.includes('android'))
66
+ return 'appium-uiautomator2';
67
+ // Without driver/session evidence we cannot claim a concrete Appium driver family.
68
+ return 'unknown';
69
+ }
70
+ export function backendCapabilities(backend, session) {
71
+ const c = base(backend);
72
+ switch (backend) {
73
+ case 'android-direct':
74
+ // Android DirectDriver via adb + UI Automator dump: resource-id / text / accessibility tree,
75
+ // ascii text input, basic gestures. No WebView context switching, no app-declared idle proof.
76
+ Object.assign(c, {
77
+ install: true, launch: true, terminate: true, openUrl: true, screenshot: true, logs: true,
78
+ structuredTree: true, nativeSelectors: true, resourceId: true, accessibilityId: true,
79
+ textSelector: true, textInputAscii: true, textInputUnicode: false, clearText: true,
80
+ longPress: true, doubleTap: true, scrollUntilVisible: true, pinch: false, drag: true,
81
+ systemAlerts: true, appDeclaredIdling: false, screenRecording: true,
82
+ visualFallback: true, ocrFallback: true,
83
+ });
84
+ c.notes.push('Unicode text input is not safe on adb input; use a fixture-provided ASCII value or a stronger backend.');
85
+ c.notes.push('No WebView context switching on the Android direct backend; attach Appium UiAutomator2 for hybrid contexts.');
86
+ return c;
87
+ case 'ios-raw-simulator':
88
+ // simctl lifecycle + screenshot + deep links + visual/OCR only. NO structured taps/selectors.
89
+ Object.assign(c, {
90
+ install: true, launch: true, terminate: true, openUrl: true, screenshot: true, logs: true,
91
+ structuredTree: false, nativeSelectors: false, screenRecording: true,
92
+ visualFallback: true, ocrFallback: true,
93
+ });
94
+ c.notes.push('iOS raw simulator cannot run structured taps; attach WDA or Appium XCUITest for selector-based automation.');
95
+ return c;
96
+ case 'ios-wda':
97
+ // WebDriverAgent / XCTest: accessibility id / name / predicate / class-chain, idle settings.
98
+ Object.assign(c, {
99
+ install: true, launch: true, terminate: true, openUrl: true, screenshot: true, logs: true,
100
+ structuredTree: true, nativeSelectors: true, accessibilityId: true, iosPredicate: true,
101
+ iosClassChain: true, textSelector: true, textInputAscii: true, textInputUnicode: true,
102
+ clearText: true, longPress: true, doubleTap: true, scrollUntilVisible: true, pinch: false,
103
+ drag: true, systemAlerts: true, wdaIdling: true, screenRecording: true,
104
+ visualFallback: true, ocrFallback: true,
105
+ });
106
+ c.notes.push('iOS resource-id selectors do not exist; use accessibility id / name / predicate / class chain.');
107
+ c.notes.push('Pinch/zoom is capability-gated until a tested WDA/Appium implementation exists.');
108
+ return c;
109
+ case 'appium-uiautomator2':
110
+ Object.assign(c, {
111
+ install: true, launch: true, terminate: true, openUrl: true, screenshot: true, logs: true,
112
+ structuredTree: true, nativeSelectors: true, resourceId: true, accessibilityId: true,
113
+ textSelector: true, textInputAscii: true, textInputUnicode: true, clearText: true,
114
+ longPress: true, doubleTap: true, scrollUntilVisible: true, pinch: true, drag: true,
115
+ systemAlerts: true, appDeclaredIdling: false, screenRecording: true,
116
+ visualFallback: true, ocrFallback: true,
117
+ // Web/hybrid potential is only claimed when the live session reports contexts.
118
+ webviewContexts: session?.webviewContextsAvailable === true,
119
+ });
120
+ if (!c.webviewContexts)
121
+ c.notes.push('WebView contexts only available when the Appium session reports a non-native context; not claimed without session evidence.');
122
+ return c;
123
+ case 'appium-xcuitest':
124
+ Object.assign(c, {
125
+ install: true, launch: true, terminate: true, openUrl: true, screenshot: true, logs: true,
126
+ structuredTree: true, nativeSelectors: true, accessibilityId: true, iosPredicate: true,
127
+ iosClassChain: true, textSelector: true, textInputAscii: true, textInputUnicode: true,
128
+ clearText: true, longPress: true, doubleTap: true, scrollUntilVisible: true, pinch: true,
129
+ drag: true, systemAlerts: true, wdaIdling: true, screenRecording: true,
130
+ visualFallback: true, ocrFallback: true,
131
+ webviewContexts: session?.webviewContextsAvailable === true,
132
+ });
133
+ c.notes.push('XCUITest sessions expose WDA settings (snapshot depth, waitForIdleTimeout, reduceMotion); bind automation evidence to them.');
134
+ if (!c.webviewContexts)
135
+ c.notes.push('WebView contexts only available when the Appium session reports a non-native context; not claimed without session evidence.');
136
+ return c;
137
+ case 'unknown':
138
+ default:
139
+ c.notes.push('Backend is unknown; attach a device/session so capabilities can be resolved.');
140
+ return c;
141
+ }
142
+ }
143
+ /** Whether a backend can target an element with the given selector strategy. */
144
+ export function selectorSupported(caps, strategy) {
145
+ switch (strategy) {
146
+ case 'resource_id':
147
+ return caps.resourceId;
148
+ case 'accessibility_id':
149
+ return caps.accessibilityId;
150
+ case 'text':
151
+ return caps.textSelector;
152
+ case 'ios_predicate':
153
+ return caps.iosPredicate;
154
+ case 'ios_class_chain':
155
+ return caps.iosClassChain;
156
+ case 'ocr_text':
157
+ return caps.ocrFallback;
158
+ case 'image':
159
+ return caps.visualFallback;
160
+ case 'coordinate':
161
+ // Any backend that can screenshot can be driven by coordinate as a last resort.
162
+ return caps.screenshot;
163
+ default:
164
+ return false;
165
+ }
166
+ }
167
+ //# sourceMappingURL=capabilities.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"capabilities.js","sourceRoot":"","sources":["../../src/automation/capabilities.ts"],"names":[],"mappings":"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"}