@validate.qa/runner 1.0.74 → 1.0.76
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/dist/cli.js +48 -28
- package/dist/cli.mjs +48 -28
- package/package.json +1 -1
package/dist/cli.js
CHANGED
|
@@ -320970,6 +320970,7 @@ var require_primary_action_ledger = __commonJS({
|
|
|
320970
320970
|
exports2.getBlockingActionDebt = getBlockingActionDebt;
|
|
320971
320971
|
exports2.identityLabelForKey = identityLabelForKey;
|
|
320972
320972
|
exports2.entryMatchesClick = entryMatchesClick;
|
|
320973
|
+
exports2.computeNewlyClicked = computeNewlyClicked;
|
|
320973
320974
|
exports2.reconcileCapture = reconcileCapture;
|
|
320974
320975
|
exports2.classifyActionOutcome = classifyActionOutcome;
|
|
320975
320976
|
exports2.detectPrimaryActions = detectPrimaryActions;
|
|
@@ -320997,7 +320998,7 @@ var require_primary_action_ledger = __commonJS({
|
|
|
320997
320998
|
exports2.AMBIGUOUS_ACTION_VERB_RE = /^(continue|next|apply|go|proceed|confirm|update|add|edit|ok|done|finish|complete|approve|enable|activate)\b/i;
|
|
320998
320999
|
exports2.DESTRUCTIVE_ACTION_VERB_RE = /^(delete|remove|archive|reset|disconnect|deactivate|destroy|purge|revoke|discard|drop|wipe|erase|unsubscribe|cancel|clear|trash)\b/i;
|
|
320999
321000
|
exports2.PAID_ACTION_RE = /\b(pay|payment|checkout|check\s*out|subscribe|subscription|purchase|buy|upgrade|billing|(?:submit|place|confirm|complete|review)\s+(?:order|purchase|payment|booking)|(?:start|activate|begin|choose|select|try)\s+(?:a\s+|your\s+|the\s+)?(?:free\s+)?(?:subscription|trial|plan|membership|billing)|free\s+trial|send\s+(?:money|funds|cash|a\s+payment|payment|a\s+gift|gift)|order\s*now|donate|tip|renew|add\s*funds|add\s+to\s+cart|withdraw|deposit|transfer\s+(?:funds|money))\b/i;
|
|
321000
|
-
exports2.PROD_SIDE_EFFECT_RE = /\b(deploy|publish|push|ship|release|promote|roll\s*back|rollback)\b[
|
|
321001
|
+
exports2.PROD_SIDE_EFFECT_RE = /\b(deploy|publish|push|ship|release|promote|roll\s*back|rollback)\b[^.\n;:,—–]{0,40}\bto\b[^.\n;:,—–]{0,40}\b(prod|production|live|mainnet)\b/i;
|
|
321001
321002
|
exports2.MESSAGE_PEOPLE_RE = /\b(invite|(?:send|resend)\s+(?:a\s+|an\s+|the\s+|new\s+|your\s+)?(?:invitation|invite|email|message|sms|text|reminder|notification|note|campaign|newsletter|broadcast|blast|bulk\s+email)|(?:send|email|message|text|notify)\b[^.]*\bto\s+(?:all|everyone|subscribers|the\s+list|your\s+list|contacts|customers|the\s+team)\b|share\s*via|notify\s*(?:team|user|member|people|everyone)|(?:email|message|text)\s+(?:the|a|all|your|team|user|customer|member))\b/i;
|
|
321002
321003
|
function leadingVerb(label) {
|
|
321003
321004
|
if (!label)
|
|
@@ -321103,10 +321104,13 @@ var require_primary_action_ledger = __commonJS({
|
|
|
321103
321104
|
function normLabelKey(label) {
|
|
321104
321105
|
return label.trim().toLowerCase().replace(/\s+/g, " ");
|
|
321105
321106
|
}
|
|
321107
|
+
function stableLabelStem(label) {
|
|
321108
|
+
return normLabelKey(label).replace(/\s*\(\d{1,3}\)\s*$/, "").replace(/(?:\s*\.\.\.|…)\s*$/, "").replace(/\s+/g, " ").trim();
|
|
321109
|
+
}
|
|
321106
321110
|
function identityLabelForKey(containerScope, label) {
|
|
321107
321111
|
if (containerScope && GRID_SCOPE_RE.test(containerScope))
|
|
321108
321112
|
return "";
|
|
321109
|
-
return
|
|
321113
|
+
return stableLabelStem(label);
|
|
321110
321114
|
}
|
|
321111
321115
|
function entryMatchesClick(entry, clickedLabels) {
|
|
321112
321116
|
if (clickedLabels.has(entry.label))
|
|
@@ -321118,6 +321122,13 @@ var require_primary_action_ledger = __commonJS({
|
|
|
321118
321122
|
}
|
|
321119
321123
|
return false;
|
|
321120
321124
|
}
|
|
321125
|
+
function computeNewlyClicked(prevCounts, curCounts) {
|
|
321126
|
+
const out = /* @__PURE__ */ new Set();
|
|
321127
|
+
for (const [label, n] of curCounts)
|
|
321128
|
+
if (n > (prevCounts.get(label) ?? 0))
|
|
321129
|
+
out.add(label);
|
|
321130
|
+
return out;
|
|
321131
|
+
}
|
|
321121
321132
|
function reconcileCapture(input) {
|
|
321122
321133
|
const nCur = normalizeActionRoute(input.route);
|
|
321123
321134
|
const nPrev = input.previousRoute ? normalizeActionRoute(input.previousRoute) : null;
|
|
@@ -321133,36 +321144,38 @@ var require_primary_action_ledger = __commonJS({
|
|
|
321133
321144
|
}
|
|
321134
321145
|
}
|
|
321135
321146
|
if (input.prevSignatures) {
|
|
321136
|
-
const
|
|
321147
|
+
const matching = [];
|
|
321137
321148
|
for (const e of input.ledger.values()) {
|
|
321138
321149
|
if (e.kind !== "primary" || e.isExempt)
|
|
321139
321150
|
continue;
|
|
321140
|
-
if (e.status === "OUTCOME_CAPTURED" || e.status === "BLOCKED")
|
|
321141
|
-
continue;
|
|
321142
321151
|
if (normalizeActionRoute(e.route) !== nCur)
|
|
321143
321152
|
continue;
|
|
321144
321153
|
if (entryMatchesClick(e, input.newlyClickedThisRoute))
|
|
321145
|
-
|
|
321154
|
+
matching.push(e);
|
|
321146
321155
|
}
|
|
321147
|
-
|
|
321156
|
+
const active = matching.filter((e) => e.status !== "OUTCOME_CAPTURED" && e.status !== "BLOCKED");
|
|
321157
|
+
if (matching.length === 1 && active.length === 1) {
|
|
321148
321158
|
const revealed = (0, reveal_diff_js_1.computeRevealedControls)(input.prevSignatures, input.currentSignatures);
|
|
321149
321159
|
if (revealed.size > 0)
|
|
321150
|
-
outcomes.push({ id:
|
|
321160
|
+
outcomes.push({ id: active[0].id, signal: `revealed:${revealed.size}` });
|
|
321151
321161
|
}
|
|
321152
321162
|
}
|
|
321153
321163
|
if (nPrev && nPrev !== nCur && input.transitionTriggerLabels.size > 0) {
|
|
321164
|
+
const matching = [];
|
|
321154
321165
|
for (const e of input.ledger.values()) {
|
|
321155
321166
|
if (e.kind !== "primary" || e.isExempt)
|
|
321156
321167
|
continue;
|
|
321157
|
-
if (e.status === "OUTCOME_CAPTURED" || e.status === "BLOCKED")
|
|
321158
|
-
continue;
|
|
321159
321168
|
if (normalizeActionRoute(e.route) !== nPrev)
|
|
321160
321169
|
continue;
|
|
321161
|
-
if (entryMatchesClick(e, input.transitionTriggerLabels))
|
|
321162
|
-
|
|
321163
|
-
|
|
321164
|
-
|
|
321165
|
-
|
|
321170
|
+
if (entryMatchesClick(e, input.transitionTriggerLabels))
|
|
321171
|
+
matching.push(e);
|
|
321172
|
+
}
|
|
321173
|
+
const active = matching.filter((e) => e.status !== "OUTCOME_CAPTURED" && e.status !== "BLOCKED");
|
|
321174
|
+
if (matching.length === 1 && active.length === 1) {
|
|
321175
|
+
const e = active[0];
|
|
321176
|
+
if (e.status === "DETECTED")
|
|
321177
|
+
attempts.push(e.id);
|
|
321178
|
+
outcomes.push({ id: e.id, signal: "route-change" });
|
|
321166
321179
|
}
|
|
321167
321180
|
}
|
|
321168
321181
|
return { attempts, outcomes };
|
|
@@ -321281,6 +321294,7 @@ var require_exploration_state = __commonJS({
|
|
|
321281
321294
|
testedRoutes: /* @__PURE__ */ new Set(),
|
|
321282
321295
|
routeState: /* @__PURE__ */ new Map(),
|
|
321283
321296
|
actionLedger: /* @__PURE__ */ new Map(),
|
|
321297
|
+
actionLedgerDropped: 0,
|
|
321284
321298
|
frontier: /* @__PURE__ */ new Map(),
|
|
321285
321299
|
recordedJourneys: [],
|
|
321286
321300
|
suggestCommandCursors: /* @__PURE__ */ new Map(),
|
|
@@ -321321,6 +321335,7 @@ var require_exploration_state = __commonJS({
|
|
|
321321
321335
|
recentProgressSignals: [],
|
|
321322
321336
|
lastMeaningfulAction: null,
|
|
321323
321337
|
interactedElements: /* @__PURE__ */ new Set(),
|
|
321338
|
+
interactionCounts: /* @__PURE__ */ new Map(),
|
|
321324
321339
|
discoveredSubNav: [],
|
|
321325
321340
|
exploredSubNav: /* @__PURE__ */ new Set(),
|
|
321326
321341
|
failedActions: [],
|
|
@@ -321425,6 +321440,7 @@ var require_exploration_state = __commonJS({
|
|
|
321425
321440
|
if (nameMatch) {
|
|
321426
321441
|
const label = nameMatch[1];
|
|
321427
321442
|
rs.interactedElements.add(label);
|
|
321443
|
+
rs.interactionCounts.set(label, (rs.interactionCounts.get(label) ?? 0) + 1);
|
|
321428
321444
|
if (rs.discoveredSubNav.some((s) => s.label === label)) {
|
|
321429
321445
|
rs.exploredSubNav.add(label);
|
|
321430
321446
|
}
|
|
@@ -321467,8 +321483,10 @@ var require_exploration_state = __commonJS({
|
|
|
321467
321483
|
const key = (0, primary_action_ledger_js_1.primaryActionKey)(event.route, c.verb, c.role, a.containerScope, c.kind, c.exemptReason, a.identityLabel);
|
|
321468
321484
|
const existing = state2.actionLedger.get(key);
|
|
321469
321485
|
if (!existing) {
|
|
321470
|
-
if (state2.actionLedger.size >= LEDGER_CAP)
|
|
321486
|
+
if (state2.actionLedger.size >= LEDGER_CAP) {
|
|
321487
|
+
state2.actionLedgerDropped++;
|
|
321471
321488
|
continue;
|
|
321489
|
+
}
|
|
321472
321490
|
const entry = (0, primary_action_ledger_js_1.makeLedgerEntry)(key, c, event.route, a.containerScope, state2.iteration);
|
|
321473
321491
|
entry.collapsed = Math.max(1, a.count);
|
|
321474
321492
|
state2.actionLedger.set(key, entry);
|
|
@@ -322724,7 +322742,8 @@ var require_exploration_prompt_builder = __commonJS({
|
|
|
322724
322742
|
const out = [
|
|
322725
322743
|
"",
|
|
322726
322744
|
"### Primary Actions Not Yet Exercised",
|
|
322727
|
-
"These are the feature's core actions
|
|
322745
|
+
"These are the feature's core actions \u2014 what it EXISTS to do. You are on a PROVISIONED TEST ACCOUNT, so exercising them is the point of this exploration. For each: click it, wait for it to finish (an async job can take 10-60s \u2014 keep waiting and capturing, do not give up early), then capture_page the result (a new panel, row, score, status, or route change).",
|
|
322746
|
+
`Spending in-app COMPUTE credits is expected and budgeted \u2014 running an Analyze / Generate / Run / Process ONCE to observe its output is exactly what you should do; an "N of M used" usage or AI-credit meter is NOT a reason to skip. These were auto-screened, but YOU are the final check: if you can see a specific listed action actually charges REAL money at a checkout (Buy / Upgrade / Subscribe), makes an irreversible or destructive change (Delete / Wipe / Deploy to production), or sends a message to real people (Send email / Invite), SKIP just that one \u2014 note it as blocked with the reason and move on. Don't finish until every other action below has produced an observed outcome:`
|
|
322728
322747
|
];
|
|
322729
322748
|
for (const e of debt.slice(0, 8)) {
|
|
322730
322749
|
const note = e.status === "ATTEMPTED" ? " \u2014 clicked but no result captured yet" : "";
|
|
@@ -326547,8 +326566,9 @@ ${inbox_tools_js_1.EMAIL_VERIFICATION_UNAVAILABLE_OVERRIDE_BLOCK}` : ""}`;
|
|
|
326547
326566
|
const primaryActionLedgerActive = (0, primary_action_ledger_js_1.isLedgerActive)(primaryActionMode) && options?.mode === "deep";
|
|
326548
326567
|
const primaryActionEnforcing = primaryActionLedgerActive && (0, primary_action_ledger_js_1.isGateEnforcing)(primaryActionMode);
|
|
326549
326568
|
const prevRouteSignatures = /* @__PURE__ */ new Map();
|
|
326550
|
-
const
|
|
326569
|
+
const prevInteractionCountsByRoute = /* @__PURE__ */ new Map();
|
|
326551
326570
|
let previousCaptureRoute = null;
|
|
326571
|
+
let previousCaptureTransitionCount = 0;
|
|
326552
326572
|
const linkScope = (0, survey_link_frontier_js_1.deriveLinkScope)(baseUrl);
|
|
326553
326573
|
const surveyNavScope = options?.mode === "survey" ? (0, survey_scope_js_1.deriveSurveyPathScope)(baseUrl) : null;
|
|
326554
326574
|
let finishRedirects = 0;
|
|
@@ -327519,16 +327539,15 @@ ${currentSummary}`;
|
|
|
327519
327539
|
}
|
|
327520
327540
|
const currentSigs = (0, reveal_diff_js_1.buildSnapshotSignatures)(capElements);
|
|
327521
327541
|
const cumClicked = state2.routeState.get(capRoute)?.interactedElements ?? /* @__PURE__ */ new Set();
|
|
327522
|
-
const
|
|
327523
|
-
const
|
|
327524
|
-
|
|
327525
|
-
if (!prevClicked.has(l))
|
|
327526
|
-
newlyClicked.add(l);
|
|
327542
|
+
const curCounts = state2.routeState.get(capRoute)?.interactionCounts ?? /* @__PURE__ */ new Map();
|
|
327543
|
+
const prevCounts = prevInteractionCountsByRoute.get(capRoute) ?? /* @__PURE__ */ new Map();
|
|
327544
|
+
const newlyClicked = (0, primary_action_ledger_js_1.computeNewlyClicked)(prevCounts, curCounts);
|
|
327527
327545
|
const transitionTriggerLabels = /* @__PURE__ */ new Set();
|
|
327528
327546
|
if (previousCaptureRoute && (0, exploration_parser_js_1.normalizeRouteForFocusScope)(previousCaptureRoute) !== (0, exploration_parser_js_1.normalizeRouteForFocusScope)(capRoute)) {
|
|
327529
327547
|
const nPrevCap = (0, exploration_parser_js_1.normalizeRouteForFocusScope)(previousCaptureRoute);
|
|
327530
327548
|
const nCap = (0, exploration_parser_js_1.normalizeRouteForFocusScope)(capRoute);
|
|
327531
|
-
for (
|
|
327549
|
+
for (let ti = previousCaptureTransitionCount; ti < state2.collectedTransitions.length; ti++) {
|
|
327550
|
+
const t = state2.collectedTransitions[ti];
|
|
327532
327551
|
if (!t.triggerLabel)
|
|
327533
327552
|
continue;
|
|
327534
327553
|
if ((0, exploration_parser_js_1.normalizeRouteForFocusScope)(t.fromRoute) === nPrevCap && (0, exploration_parser_js_1.normalizeRouteForFocusScope)(t.toRoute) === nCap) {
|
|
@@ -327551,8 +327570,9 @@ ${currentSummary}`;
|
|
|
327551
327570
|
for (const o of outcomes)
|
|
327552
327571
|
(0, exploration_state_js_1.reduceEvent)(state2, { type: "ACTION_OUTCOME_CAPTURED", id: o.id, signal: o.signal });
|
|
327553
327572
|
prevRouteSignatures.set(capRoute, currentSigs);
|
|
327554
|
-
|
|
327573
|
+
prevInteractionCountsByRoute.set(capRoute, new Map(curCounts));
|
|
327555
327574
|
previousCaptureRoute = capRoute;
|
|
327575
|
+
previousCaptureTransitionCount = state2.collectedTransitions.length;
|
|
327556
327576
|
}
|
|
327557
327577
|
{
|
|
327558
327578
|
const pendingScreenshot = consumePendingRouteScreenshot(pendingRouteScreenshot, {
|
|
@@ -328109,7 +328129,7 @@ finish_exploration bounced (primary-action ${finishRedirects}/${survey_link_fron
|
|
|
328109
328129
|
content: JSON.stringify({
|
|
328110
328130
|
acknowledged: false,
|
|
328111
328131
|
keepExploring: true,
|
|
328112
|
-
reason: `Not done yet \u2014 ${actionDebt.length} primary action(s) for this feature were never exercised to an observed result: ${targets}.
|
|
328132
|
+
reason: `Not done yet \u2014 ${actionDebt.length} primary action(s) for this feature were never exercised to an observed result: ${targets}. This is a provisioned TEST account: click each, wait for it to complete (an async job can take 10-60s), then capture_page the result state (a new panel, row, score, status, or route change). Spending in-app compute/AI credits once is expected \u2014 not a blocker. Only if one is genuinely blocked \u2014 it charges REAL money at a checkout, makes an irreversible/destructive change or a production deployment, needs a real recipient, or needs a permission you don't have \u2014 say so in your summary and finish.`
|
|
328113
328133
|
})
|
|
328114
328134
|
});
|
|
328115
328135
|
if (!finishStreakCountedThisBatch) {
|
|
@@ -328133,7 +328153,7 @@ finish_exploration bounced (primary-action ${finishRedirects}/${survey_link_fron
|
|
|
328133
328153
|
logs2.push(`
|
|
328134
328154
|
Exploration complete: ${summary}`);
|
|
328135
328155
|
if (primaryActionLedgerActive) {
|
|
328136
|
-
logs2.push(` [primary-action-ledger] mode=${primaryActionMode}: ${(0, primary_action_ledger_js_1.summarizeLedger)(state2.actionLedger)}`);
|
|
328156
|
+
logs2.push(` [primary-action-ledger] mode=${primaryActionMode}: ${(0, primary_action_ledger_js_1.summarizeLedger)(state2.actionLedger)}${state2.actionLedgerDropped > 0 ? ` ledger_cap_hits=${state2.actionLedgerDropped}` : ""}`);
|
|
328137
328157
|
}
|
|
328138
328158
|
toolResults.push({
|
|
328139
328159
|
role: "tool",
|
|
@@ -353014,7 +353034,7 @@ var require_package4 = __commonJS({
|
|
|
353014
353034
|
"package.json"(exports2, module2) {
|
|
353015
353035
|
module2.exports = {
|
|
353016
353036
|
name: "@validate.qa/runner",
|
|
353017
|
-
version: "1.0.
|
|
353037
|
+
version: "1.0.76",
|
|
353018
353038
|
description: "validate local test runner - execute Playwright tests on your machine, connected to validate.qa cloud.",
|
|
353019
353039
|
bin: {
|
|
353020
353040
|
"validate-runner": "dist/cli.js"
|
package/dist/cli.mjs
CHANGED
|
@@ -320975,6 +320975,7 @@ var require_primary_action_ledger = __commonJS({
|
|
|
320975
320975
|
exports.getBlockingActionDebt = getBlockingActionDebt;
|
|
320976
320976
|
exports.identityLabelForKey = identityLabelForKey;
|
|
320977
320977
|
exports.entryMatchesClick = entryMatchesClick;
|
|
320978
|
+
exports.computeNewlyClicked = computeNewlyClicked;
|
|
320978
320979
|
exports.reconcileCapture = reconcileCapture;
|
|
320979
320980
|
exports.classifyActionOutcome = classifyActionOutcome;
|
|
320980
320981
|
exports.detectPrimaryActions = detectPrimaryActions;
|
|
@@ -321002,7 +321003,7 @@ var require_primary_action_ledger = __commonJS({
|
|
|
321002
321003
|
exports.AMBIGUOUS_ACTION_VERB_RE = /^(continue|next|apply|go|proceed|confirm|update|add|edit|ok|done|finish|complete|approve|enable|activate)\b/i;
|
|
321003
321004
|
exports.DESTRUCTIVE_ACTION_VERB_RE = /^(delete|remove|archive|reset|disconnect|deactivate|destroy|purge|revoke|discard|drop|wipe|erase|unsubscribe|cancel|clear|trash)\b/i;
|
|
321004
321005
|
exports.PAID_ACTION_RE = /\b(pay|payment|checkout|check\s*out|subscribe|subscription|purchase|buy|upgrade|billing|(?:submit|place|confirm|complete|review)\s+(?:order|purchase|payment|booking)|(?:start|activate|begin|choose|select|try)\s+(?:a\s+|your\s+|the\s+)?(?:free\s+)?(?:subscription|trial|plan|membership|billing)|free\s+trial|send\s+(?:money|funds|cash|a\s+payment|payment|a\s+gift|gift)|order\s*now|donate|tip|renew|add\s*funds|add\s+to\s+cart|withdraw|deposit|transfer\s+(?:funds|money))\b/i;
|
|
321005
|
-
exports.PROD_SIDE_EFFECT_RE = /\b(deploy|publish|push|ship|release|promote|roll\s*back|rollback)\b[
|
|
321006
|
+
exports.PROD_SIDE_EFFECT_RE = /\b(deploy|publish|push|ship|release|promote|roll\s*back|rollback)\b[^.\n;:,—–]{0,40}\bto\b[^.\n;:,—–]{0,40}\b(prod|production|live|mainnet)\b/i;
|
|
321006
321007
|
exports.MESSAGE_PEOPLE_RE = /\b(invite|(?:send|resend)\s+(?:a\s+|an\s+|the\s+|new\s+|your\s+)?(?:invitation|invite|email|message|sms|text|reminder|notification|note|campaign|newsletter|broadcast|blast|bulk\s+email)|(?:send|email|message|text|notify)\b[^.]*\bto\s+(?:all|everyone|subscribers|the\s+list|your\s+list|contacts|customers|the\s+team)\b|share\s*via|notify\s*(?:team|user|member|people|everyone)|(?:email|message|text)\s+(?:the|a|all|your|team|user|customer|member))\b/i;
|
|
321007
321008
|
function leadingVerb(label) {
|
|
321008
321009
|
if (!label)
|
|
@@ -321108,10 +321109,13 @@ var require_primary_action_ledger = __commonJS({
|
|
|
321108
321109
|
function normLabelKey(label) {
|
|
321109
321110
|
return label.trim().toLowerCase().replace(/\s+/g, " ");
|
|
321110
321111
|
}
|
|
321112
|
+
function stableLabelStem(label) {
|
|
321113
|
+
return normLabelKey(label).replace(/\s*\(\d{1,3}\)\s*$/, "").replace(/(?:\s*\.\.\.|…)\s*$/, "").replace(/\s+/g, " ").trim();
|
|
321114
|
+
}
|
|
321111
321115
|
function identityLabelForKey(containerScope, label) {
|
|
321112
321116
|
if (containerScope && GRID_SCOPE_RE.test(containerScope))
|
|
321113
321117
|
return "";
|
|
321114
|
-
return
|
|
321118
|
+
return stableLabelStem(label);
|
|
321115
321119
|
}
|
|
321116
321120
|
function entryMatchesClick(entry, clickedLabels) {
|
|
321117
321121
|
if (clickedLabels.has(entry.label))
|
|
@@ -321123,6 +321127,13 @@ var require_primary_action_ledger = __commonJS({
|
|
|
321123
321127
|
}
|
|
321124
321128
|
return false;
|
|
321125
321129
|
}
|
|
321130
|
+
function computeNewlyClicked(prevCounts, curCounts) {
|
|
321131
|
+
const out = /* @__PURE__ */ new Set();
|
|
321132
|
+
for (const [label, n] of curCounts)
|
|
321133
|
+
if (n > (prevCounts.get(label) ?? 0))
|
|
321134
|
+
out.add(label);
|
|
321135
|
+
return out;
|
|
321136
|
+
}
|
|
321126
321137
|
function reconcileCapture(input) {
|
|
321127
321138
|
const nCur = normalizeActionRoute(input.route);
|
|
321128
321139
|
const nPrev = input.previousRoute ? normalizeActionRoute(input.previousRoute) : null;
|
|
@@ -321138,36 +321149,38 @@ var require_primary_action_ledger = __commonJS({
|
|
|
321138
321149
|
}
|
|
321139
321150
|
}
|
|
321140
321151
|
if (input.prevSignatures) {
|
|
321141
|
-
const
|
|
321152
|
+
const matching = [];
|
|
321142
321153
|
for (const e of input.ledger.values()) {
|
|
321143
321154
|
if (e.kind !== "primary" || e.isExempt)
|
|
321144
321155
|
continue;
|
|
321145
|
-
if (e.status === "OUTCOME_CAPTURED" || e.status === "BLOCKED")
|
|
321146
|
-
continue;
|
|
321147
321156
|
if (normalizeActionRoute(e.route) !== nCur)
|
|
321148
321157
|
continue;
|
|
321149
321158
|
if (entryMatchesClick(e, input.newlyClickedThisRoute))
|
|
321150
|
-
|
|
321159
|
+
matching.push(e);
|
|
321151
321160
|
}
|
|
321152
|
-
|
|
321161
|
+
const active = matching.filter((e) => e.status !== "OUTCOME_CAPTURED" && e.status !== "BLOCKED");
|
|
321162
|
+
if (matching.length === 1 && active.length === 1) {
|
|
321153
321163
|
const revealed = (0, reveal_diff_js_1.computeRevealedControls)(input.prevSignatures, input.currentSignatures);
|
|
321154
321164
|
if (revealed.size > 0)
|
|
321155
|
-
outcomes.push({ id:
|
|
321165
|
+
outcomes.push({ id: active[0].id, signal: `revealed:${revealed.size}` });
|
|
321156
321166
|
}
|
|
321157
321167
|
}
|
|
321158
321168
|
if (nPrev && nPrev !== nCur && input.transitionTriggerLabels.size > 0) {
|
|
321169
|
+
const matching = [];
|
|
321159
321170
|
for (const e of input.ledger.values()) {
|
|
321160
321171
|
if (e.kind !== "primary" || e.isExempt)
|
|
321161
321172
|
continue;
|
|
321162
|
-
if (e.status === "OUTCOME_CAPTURED" || e.status === "BLOCKED")
|
|
321163
|
-
continue;
|
|
321164
321173
|
if (normalizeActionRoute(e.route) !== nPrev)
|
|
321165
321174
|
continue;
|
|
321166
|
-
if (entryMatchesClick(e, input.transitionTriggerLabels))
|
|
321167
|
-
|
|
321168
|
-
|
|
321169
|
-
|
|
321170
|
-
|
|
321175
|
+
if (entryMatchesClick(e, input.transitionTriggerLabels))
|
|
321176
|
+
matching.push(e);
|
|
321177
|
+
}
|
|
321178
|
+
const active = matching.filter((e) => e.status !== "OUTCOME_CAPTURED" && e.status !== "BLOCKED");
|
|
321179
|
+
if (matching.length === 1 && active.length === 1) {
|
|
321180
|
+
const e = active[0];
|
|
321181
|
+
if (e.status === "DETECTED")
|
|
321182
|
+
attempts.push(e.id);
|
|
321183
|
+
outcomes.push({ id: e.id, signal: "route-change" });
|
|
321171
321184
|
}
|
|
321172
321185
|
}
|
|
321173
321186
|
return { attempts, outcomes };
|
|
@@ -321286,6 +321299,7 @@ var require_exploration_state = __commonJS({
|
|
|
321286
321299
|
testedRoutes: /* @__PURE__ */ new Set(),
|
|
321287
321300
|
routeState: /* @__PURE__ */ new Map(),
|
|
321288
321301
|
actionLedger: /* @__PURE__ */ new Map(),
|
|
321302
|
+
actionLedgerDropped: 0,
|
|
321289
321303
|
frontier: /* @__PURE__ */ new Map(),
|
|
321290
321304
|
recordedJourneys: [],
|
|
321291
321305
|
suggestCommandCursors: /* @__PURE__ */ new Map(),
|
|
@@ -321326,6 +321340,7 @@ var require_exploration_state = __commonJS({
|
|
|
321326
321340
|
recentProgressSignals: [],
|
|
321327
321341
|
lastMeaningfulAction: null,
|
|
321328
321342
|
interactedElements: /* @__PURE__ */ new Set(),
|
|
321343
|
+
interactionCounts: /* @__PURE__ */ new Map(),
|
|
321329
321344
|
discoveredSubNav: [],
|
|
321330
321345
|
exploredSubNav: /* @__PURE__ */ new Set(),
|
|
321331
321346
|
failedActions: [],
|
|
@@ -321430,6 +321445,7 @@ var require_exploration_state = __commonJS({
|
|
|
321430
321445
|
if (nameMatch) {
|
|
321431
321446
|
const label = nameMatch[1];
|
|
321432
321447
|
rs.interactedElements.add(label);
|
|
321448
|
+
rs.interactionCounts.set(label, (rs.interactionCounts.get(label) ?? 0) + 1);
|
|
321433
321449
|
if (rs.discoveredSubNav.some((s) => s.label === label)) {
|
|
321434
321450
|
rs.exploredSubNav.add(label);
|
|
321435
321451
|
}
|
|
@@ -321472,8 +321488,10 @@ var require_exploration_state = __commonJS({
|
|
|
321472
321488
|
const key = (0, primary_action_ledger_js_1.primaryActionKey)(event.route, c.verb, c.role, a.containerScope, c.kind, c.exemptReason, a.identityLabel);
|
|
321473
321489
|
const existing = state2.actionLedger.get(key);
|
|
321474
321490
|
if (!existing) {
|
|
321475
|
-
if (state2.actionLedger.size >= LEDGER_CAP)
|
|
321491
|
+
if (state2.actionLedger.size >= LEDGER_CAP) {
|
|
321492
|
+
state2.actionLedgerDropped++;
|
|
321476
321493
|
continue;
|
|
321494
|
+
}
|
|
321477
321495
|
const entry = (0, primary_action_ledger_js_1.makeLedgerEntry)(key, c, event.route, a.containerScope, state2.iteration);
|
|
321478
321496
|
entry.collapsed = Math.max(1, a.count);
|
|
321479
321497
|
state2.actionLedger.set(key, entry);
|
|
@@ -322729,7 +322747,8 @@ var require_exploration_prompt_builder = __commonJS({
|
|
|
322729
322747
|
const out = [
|
|
322730
322748
|
"",
|
|
322731
322749
|
"### Primary Actions Not Yet Exercised",
|
|
322732
|
-
"These are the feature's core actions
|
|
322750
|
+
"These are the feature's core actions \u2014 what it EXISTS to do. You are on a PROVISIONED TEST ACCOUNT, so exercising them is the point of this exploration. For each: click it, wait for it to finish (an async job can take 10-60s \u2014 keep waiting and capturing, do not give up early), then capture_page the result (a new panel, row, score, status, or route change).",
|
|
322751
|
+
`Spending in-app COMPUTE credits is expected and budgeted \u2014 running an Analyze / Generate / Run / Process ONCE to observe its output is exactly what you should do; an "N of M used" usage or AI-credit meter is NOT a reason to skip. These were auto-screened, but YOU are the final check: if you can see a specific listed action actually charges REAL money at a checkout (Buy / Upgrade / Subscribe), makes an irreversible or destructive change (Delete / Wipe / Deploy to production), or sends a message to real people (Send email / Invite), SKIP just that one \u2014 note it as blocked with the reason and move on. Don't finish until every other action below has produced an observed outcome:`
|
|
322733
322752
|
];
|
|
322734
322753
|
for (const e of debt.slice(0, 8)) {
|
|
322735
322754
|
const note = e.status === "ATTEMPTED" ? " \u2014 clicked but no result captured yet" : "";
|
|
@@ -326552,8 +326571,9 @@ ${inbox_tools_js_1.EMAIL_VERIFICATION_UNAVAILABLE_OVERRIDE_BLOCK}` : ""}`;
|
|
|
326552
326571
|
const primaryActionLedgerActive = (0, primary_action_ledger_js_1.isLedgerActive)(primaryActionMode) && options?.mode === "deep";
|
|
326553
326572
|
const primaryActionEnforcing = primaryActionLedgerActive && (0, primary_action_ledger_js_1.isGateEnforcing)(primaryActionMode);
|
|
326554
326573
|
const prevRouteSignatures = /* @__PURE__ */ new Map();
|
|
326555
|
-
const
|
|
326574
|
+
const prevInteractionCountsByRoute = /* @__PURE__ */ new Map();
|
|
326556
326575
|
let previousCaptureRoute = null;
|
|
326576
|
+
let previousCaptureTransitionCount = 0;
|
|
326557
326577
|
const linkScope = (0, survey_link_frontier_js_1.deriveLinkScope)(baseUrl);
|
|
326558
326578
|
const surveyNavScope = options?.mode === "survey" ? (0, survey_scope_js_1.deriveSurveyPathScope)(baseUrl) : null;
|
|
326559
326579
|
let finishRedirects = 0;
|
|
@@ -327524,16 +327544,15 @@ ${currentSummary}`;
|
|
|
327524
327544
|
}
|
|
327525
327545
|
const currentSigs = (0, reveal_diff_js_1.buildSnapshotSignatures)(capElements);
|
|
327526
327546
|
const cumClicked = state2.routeState.get(capRoute)?.interactedElements ?? /* @__PURE__ */ new Set();
|
|
327527
|
-
const
|
|
327528
|
-
const
|
|
327529
|
-
|
|
327530
|
-
if (!prevClicked.has(l))
|
|
327531
|
-
newlyClicked.add(l);
|
|
327547
|
+
const curCounts = state2.routeState.get(capRoute)?.interactionCounts ?? /* @__PURE__ */ new Map();
|
|
327548
|
+
const prevCounts = prevInteractionCountsByRoute.get(capRoute) ?? /* @__PURE__ */ new Map();
|
|
327549
|
+
const newlyClicked = (0, primary_action_ledger_js_1.computeNewlyClicked)(prevCounts, curCounts);
|
|
327532
327550
|
const transitionTriggerLabels = /* @__PURE__ */ new Set();
|
|
327533
327551
|
if (previousCaptureRoute && (0, exploration_parser_js_1.normalizeRouteForFocusScope)(previousCaptureRoute) !== (0, exploration_parser_js_1.normalizeRouteForFocusScope)(capRoute)) {
|
|
327534
327552
|
const nPrevCap = (0, exploration_parser_js_1.normalizeRouteForFocusScope)(previousCaptureRoute);
|
|
327535
327553
|
const nCap = (0, exploration_parser_js_1.normalizeRouteForFocusScope)(capRoute);
|
|
327536
|
-
for (
|
|
327554
|
+
for (let ti = previousCaptureTransitionCount; ti < state2.collectedTransitions.length; ti++) {
|
|
327555
|
+
const t = state2.collectedTransitions[ti];
|
|
327537
327556
|
if (!t.triggerLabel)
|
|
327538
327557
|
continue;
|
|
327539
327558
|
if ((0, exploration_parser_js_1.normalizeRouteForFocusScope)(t.fromRoute) === nPrevCap && (0, exploration_parser_js_1.normalizeRouteForFocusScope)(t.toRoute) === nCap) {
|
|
@@ -327556,8 +327575,9 @@ ${currentSummary}`;
|
|
|
327556
327575
|
for (const o of outcomes)
|
|
327557
327576
|
(0, exploration_state_js_1.reduceEvent)(state2, { type: "ACTION_OUTCOME_CAPTURED", id: o.id, signal: o.signal });
|
|
327558
327577
|
prevRouteSignatures.set(capRoute, currentSigs);
|
|
327559
|
-
|
|
327578
|
+
prevInteractionCountsByRoute.set(capRoute, new Map(curCounts));
|
|
327560
327579
|
previousCaptureRoute = capRoute;
|
|
327580
|
+
previousCaptureTransitionCount = state2.collectedTransitions.length;
|
|
327561
327581
|
}
|
|
327562
327582
|
{
|
|
327563
327583
|
const pendingScreenshot = consumePendingRouteScreenshot(pendingRouteScreenshot, {
|
|
@@ -328114,7 +328134,7 @@ finish_exploration bounced (primary-action ${finishRedirects}/${survey_link_fron
|
|
|
328114
328134
|
content: JSON.stringify({
|
|
328115
328135
|
acknowledged: false,
|
|
328116
328136
|
keepExploring: true,
|
|
328117
|
-
reason: `Not done yet \u2014 ${actionDebt.length} primary action(s) for this feature were never exercised to an observed result: ${targets}.
|
|
328137
|
+
reason: `Not done yet \u2014 ${actionDebt.length} primary action(s) for this feature were never exercised to an observed result: ${targets}. This is a provisioned TEST account: click each, wait for it to complete (an async job can take 10-60s), then capture_page the result state (a new panel, row, score, status, or route change). Spending in-app compute/AI credits once is expected \u2014 not a blocker. Only if one is genuinely blocked \u2014 it charges REAL money at a checkout, makes an irreversible/destructive change or a production deployment, needs a real recipient, or needs a permission you don't have \u2014 say so in your summary and finish.`
|
|
328118
328138
|
})
|
|
328119
328139
|
});
|
|
328120
328140
|
if (!finishStreakCountedThisBatch) {
|
|
@@ -328138,7 +328158,7 @@ finish_exploration bounced (primary-action ${finishRedirects}/${survey_link_fron
|
|
|
328138
328158
|
logs2.push(`
|
|
328139
328159
|
Exploration complete: ${summary}`);
|
|
328140
328160
|
if (primaryActionLedgerActive) {
|
|
328141
|
-
logs2.push(` [primary-action-ledger] mode=${primaryActionMode}: ${(0, primary_action_ledger_js_1.summarizeLedger)(state2.actionLedger)}`);
|
|
328161
|
+
logs2.push(` [primary-action-ledger] mode=${primaryActionMode}: ${(0, primary_action_ledger_js_1.summarizeLedger)(state2.actionLedger)}${state2.actionLedgerDropped > 0 ? ` ledger_cap_hits=${state2.actionLedgerDropped}` : ""}`);
|
|
328142
328162
|
}
|
|
328143
328163
|
toolResults.push({
|
|
328144
328164
|
role: "tool",
|
|
@@ -353019,7 +353039,7 @@ var require_package4 = __commonJS({
|
|
|
353019
353039
|
"package.json"(exports, module) {
|
|
353020
353040
|
module.exports = {
|
|
353021
353041
|
name: "@validate.qa/runner",
|
|
353022
|
-
version: "1.0.
|
|
353042
|
+
version: "1.0.76",
|
|
353023
353043
|
description: "validate local test runner - execute Playwright tests on your machine, connected to validate.qa cloud.",
|
|
353024
353044
|
bin: {
|
|
353025
353045
|
"validate-runner": "dist/cli.js"
|
package/package.json
CHANGED