@exodus/xqa 1.12.0 → 1.13.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 (2) hide show
  1. package/dist/xqa.cjs +24 -7
  2. package/package.json +3 -3
package/dist/xqa.cjs CHANGED
@@ -62958,6 +62958,7 @@ var STUCK_LOOP_RULE = `Stuck loop: emit a \`stuck-loop\` finding when any of the
62958
62958
  var LOADING_STATE_RULE = `Transient loading state: when the screen shows spinners, skeleton screens, progress bars, "Loading..." text, or placeholder content NOT described in spec or app context \u2014 use \`screenshot\` to poll for resolution (up to 3 retries); switch to \`view_ui\` only on the final check or when you need element data to act \u2014 if loading persists after 3 retries, proceed with what is visible; if spec or app context explicitly describes a loading screen as a step, do not retry \u2014 call \`view_ui\` and assert normally`;
62959
62959
  var EXPECTED_CONTENT_MISSING_RULE = `Expected content missing: when \`view_ui\` shows no loading indicator yet omits an element named or strongly implied by spec or app context \u2014 and its absence is not semantically consistent with the current screen \u2014 call \`wait_seconds\` with 2\u20135 seconds and retry \`view_ui\` up to 2 times; if element remains absent, emit a \`missing-content\` finding stating what was expected and what was observed`;
62960
62960
  var CLIPPED_ELEMENT_RULE = `Never tap an element tagged \`[clipped-top]\`, \`[clipped-bottom]\`, \`[clipped-left]\`, or \`[clipped-right]\` \u2014 scroll to fully reveal it first, then re-call \`view_ui\` before tapping`;
62961
+ var A11Y_FALLBACK_RULE = `Missing a11y element: if you intend to tap or interact with a UI element and that element is absent from the most recent \`view_ui\` a11y tree \u2014 do NOT estimate its coordinates from the screenshot or attempt any pixel-based tap \u2014 instead, emit a \`missing-a11y-element\` finding that states: (1) your intent (what you were trying to do), (2) the approximate visual region where the element appeared (coords/size from the screenshot), (3) nearby labeled elements from the a11y tree that serve as landmarks \u2014 then continue: in freestyle mode keep exploring other reachable screens; in spec mode advance to the next step`;
62961
62962
  var WHAT_TO_TEST_SECTION = `## What to Test
62962
62963
 
62963
62964
  Test navigation elements first, interactions second.
@@ -62977,6 +62978,15 @@ Test navigation elements first, interactions second.
62977
62978
  - Static labels, decorative images, dividers
62978
62979
 
62979
62980
  If an interaction produces no observable change, retry once before flagging.`;
62981
+ var DESTRUCTIVE_ACTIONS_SECTION = `## Destructive Actions
62982
+
62983
+ Never confirm actions that have permanent, irreversible, or externally observable consequences. Examples: sending or signing transactions, transferring funds, broadcasting messages, deleting accounts or wallets, wiping data, resetting the app, revoking sessions, logging out, uninstall prompts, in-app purchases, granting permissions to third parties, or any dialog whose primary button is labeled \`Send\`, \`Confirm\`, \`Sign\`, \`Pay\`, \`Delete\`, \`Remove\`, \`Reset\`, \`Erase\`, \`Log out\`, \`Sign out\`, \`Approve\`, or equivalent.
62984
+
62985
+ Rules:
62986
+ - Navigate up to the confirmation step to verify the flow is reachable and the dialog renders correctly, then back out via cancel, close, or back \u2014 do not tap the destructive confirm.
62987
+ - If the only exit from a screen is the destructive confirm, emit a \`destructive-only-exit\` finding and halt that branch \u2014 do not proceed.
62988
+ - Treat irreversible in-app state changes (e.g. marking an item as consumed, claiming a one-time reward, rotating a seed) the same as destructive actions unless app context explicitly authorizes them.
62989
+ - When in doubt about reversibility, treat the action as destructive and back out.`;
62980
62990
  var DEAD_END_SECTION = `## Dead End and Modal Detection
62981
62991
 
62982
62992
  **Dead end** \u2014 when \`view_ui\` shows no interactive exit affordance, first consult App Knowledge for gesture-based navigation on this screen, then attempt ALL of before emitting a finding: (1) any visible back/close button, (2) swipe from the left edge (back gesture), (3) swipe down (dismiss gesture). If all fail, emit a \`dead-end\` finding describing what was visible and what was attempted.
@@ -63039,6 +63049,7 @@ var SPEC_RULES_SECTION = `## Rules
63039
63049
  - ${LOADING_STATE_RULE}
63040
63050
  - ${EXPECTED_CONTENT_MISSING_RULE}
63041
63051
  - ${CLIPPED_ELEMENT_RULE}
63052
+ - ${A11Y_FALLBACK_RULE}
63042
63053
  - Each item in \`**Assertions**\` is a mandatory pass/fail check \u2014 verify using \`view_ui\` when the assertion targets an element attribute, label, or presence in the tree; use \`screenshot\` when the assertion is purely visual; if neither can confirm, emit a \`spec-deviation\` finding based on what is observable
63043
63054
  - Flag crash dialogs, unexpected system errors, or navigation failures that occur as a direct result of executing a spec step; if you observe a visibly broken element in passing while navigating, note it without interacting with it`;
63044
63055
  function buildSpecModeBody({
@@ -63083,12 +63094,7 @@ var SPEC_MODE_TEMPLATE = (specContent, options) => {
63083
63094
  ${DEV_ENVIRONMENT_SECTION}` : "";
63084
63095
  return buildSpecModeBody({ specContent, contextBlock, environmentSection });
63085
63096
  };
63086
- var FREESTYLE_TEMPLATE = (options) => {
63087
- const { appContext, initialState: initialState2, buildEnv } = options ?? {};
63088
- const contextBlock = buildContextSections(appContext, initialState2);
63089
- const environmentSection = buildEnv === "dev" ? `
63090
-
63091
- ${DEV_ENVIRONMENT_SECTION}` : "";
63097
+ function buildFreestyleBody({ contextBlock, environmentSection }) {
63092
63098
  return `You are a navigation and interaction testing agent. Your first action MUST be a \`view_ui\` call. Your role is to find broken navigation flows and non-functional interactive elements. Do not report content bugs, copy errors, or visual style issues unless they directly prevent a navigation action from completing.
63093
63099
 
63094
63100
  ${contextBlock}
@@ -63106,6 +63112,7 @@ ${TOOL_SELECTION_SECTION}
63106
63112
  - ${LOADING_STATE_RULE}
63107
63113
  - ${EXPECTED_CONTENT_MISSING_RULE}
63108
63114
  - ${CLIPPED_ELEMENT_RULE}
63115
+ - ${A11Y_FALLBACK_RULE}
63109
63116
 
63110
63117
  ## Exploration Strategy
63111
63118
 
@@ -63113,11 +63120,21 @@ Explore breadth-first: map all screens reachable from the current screen before
63113
63120
 
63114
63121
  ${WHAT_TO_TEST_SECTION}
63115
63122
 
63123
+ ${DESTRUCTIVE_ACTIONS_SECTION}
63124
+
63116
63125
  ${DEAD_END_SECTION}${environmentSection}
63117
63126
 
63118
63127
  ## Output
63119
63128
 
63120
63129
  CRITICAL: Call \`set_output\` each time your findings change \u2014 when you discover something new, confirm a false positive, or revise a finding. Each call replaces the previous output entirely, so always pass the full current list. Do not reply in plain text.`;
63130
+ }
63131
+ var FREESTYLE_TEMPLATE = (options) => {
63132
+ const { appContext, initialState: initialState2, buildEnv } = options ?? {};
63133
+ const contextBlock = buildContextSections(appContext, initialState2);
63134
+ const environmentSection = buildEnv === "dev" ? `
63135
+
63136
+ ${DEV_ENVIRONMENT_SECTION}` : "";
63137
+ return buildFreestyleBody({ contextBlock, environmentSection });
63121
63138
  };
63122
63139
  function generateExplorerPrompt({
63123
63140
  mode,
@@ -76458,7 +76475,7 @@ function resolveXqaDirectory() {
76458
76475
  return result.value;
76459
76476
  }
76460
76477
  var program2 = new Command();
76461
- program2.name("xqa").description("AI-powered QA agent CLI").version(`${"1.12.0"}${false ? ` (dev build +${"3c4f23d"})` : ""}`);
76478
+ program2.name("xqa").description("AI-powered QA agent CLI").version(`${"1.13.0"}${false ? ` (dev build +${"5e72ba0"})` : ""}`);
76462
76479
  program2.command("init").description("Initialize a new xqa project in the current directory").action(() => {
76463
76480
  runInitCommand();
76464
76481
  });
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@exodus/xqa",
3
- "version": "1.12.0",
3
+ "version": "1.13.0",
4
4
  "type": "module",
5
5
  "engines": {
6
6
  "node": ">=22"
@@ -26,9 +26,9 @@
26
26
  "typescript": "^5.8.3",
27
27
  "vitest": "^3.2.1",
28
28
  "zod": "^3.0.0",
29
- "@qa-agents/eslint-config": "0.0.0",
30
- "@qa-agents/explorer": "0.0.0",
31
29
  "@qa-agents/display": "0.0.0",
30
+ "@qa-agents/explorer": "0.0.0",
31
+ "@qa-agents/eslint-config": "0.0.0",
32
32
  "@qa-agents/mobile-ios": "0.0.0",
33
33
  "@qa-agents/pipeline": "0.0.0",
34
34
  "@qa-agents/shared": "0.0.0",