@riddledc/riddle-proof 0.7.165 → 0.7.167

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.
@@ -914,12 +914,27 @@ function normalizeSetupAction(input, index) {
914
914
  if ((type === "click" || type === "drag" || type === "fill" || type === "set_input_value" || type === "set_range_value" || type === "canvas_signature" || type === "wait_for_selector" || type === "wait_for_text" || type === "assert_text_visible" || type === "assert_text_absent" || type === "assert_selector_count") && !selector) {
915
915
  throw new Error(`target.setup_actions[${index}] ${type} requires selector.`);
916
916
  }
917
- const fromX = numberValue(valueFromOwn(input, "from_x", "fromX", "start_x", "startX", "x1"));
918
- const fromY = numberValue(valueFromOwn(input, "from_y", "fromY", "start_y", "startY", "y1"));
917
+ const fromX = type === "click" ? numberValue(valueFromOwn(input, "from_x", "fromX", "x", "click_x", "clickX", "start_x", "startX", "x1")) : numberValue(valueFromOwn(input, "from_x", "fromX", "start_x", "startX", "x1"));
918
+ const fromY = type === "click" ? numberValue(valueFromOwn(input, "from_y", "fromY", "y", "click_y", "clickY", "start_y", "startY", "y1")) : numberValue(valueFromOwn(input, "from_y", "fromY", "start_y", "startY", "y1"));
919
919
  const toX = numberValue(valueFromOwn(input, "to_x", "toX", "end_x", "endX", "x2"));
920
920
  const toY = numberValue(valueFromOwn(input, "to_y", "toY", "end_y", "endY", "y2"));
921
921
  const coordinateMode = normalizeSetupActionCoordinateMode(valueFromOwn(input, "coordinate_mode", "coordinateMode", "coords", "units"), index);
922
922
  const pointerType = normalizeSetupActionPointerType(valueFromOwn(input, "pointer_type", "pointerType", "input_type", "inputType"), type, index);
923
+ if (type === "click") {
924
+ const hasClickCoordinate = fromX !== void 0 || fromY !== void 0;
925
+ if (hasClickCoordinate && (fromX === void 0 || fromY === void 0)) {
926
+ throw new Error(`target.setup_actions[${index}] click coordinates require both x and y.`);
927
+ }
928
+ if (hasClickCoordinate && fromX !== void 0 && fromY !== void 0) {
929
+ const clickCoordinates = [fromX, fromY];
930
+ if (coordinateMode === "ratio" && clickCoordinates.some((value2) => value2 < 0 || value2 > 1)) {
931
+ throw new Error(`target.setup_actions[${index}] click ratio coordinates must be between 0 and 1.`);
932
+ }
933
+ if ((coordinateMode === void 0 || coordinateMode === "pixels") && clickCoordinates.some((value2) => value2 < 0)) {
934
+ throw new Error(`target.setup_actions[${index}] click pixel coordinates must be non-negative.`);
935
+ }
936
+ }
937
+ }
923
938
  if (type === "drag") {
924
939
  if (fromX === void 0 || fromY === void 0 || toX === void 0 || toY === void 0) {
925
940
  throw new Error(`target.setup_actions[${index}] drag requires from_x, from_y, to_x, and to_y.`);
@@ -3037,17 +3052,6 @@ function assessSetupActionsFromEvidence(profile, evidence) {
3037
3052
  const failed = [];
3038
3053
  const viewports = evidence.viewports || [];
3039
3054
  const expectedActionCountByViewport = /* @__PURE__ */ new Map();
3040
- const capturedViewportNames = new Set(viewports.map((viewport) => viewport.name));
3041
- for (const action of profile.target.setup_actions) {
3042
- if (action.viewports?.length && !action.viewports.some((name) => capturedViewportNames.has(name))) {
3043
- failed.push({
3044
- viewport: null,
3045
- action: action.type,
3046
- selector: action.selector ?? null,
3047
- reason: `setup action scoped to missing viewport(s): ${action.viewports.join(", ")}`
3048
- });
3049
- }
3050
- }
3051
3055
  for (const viewport of viewports) {
3052
3056
  const expectedActionCount = setupActionsForViewport(profile.target.setup_actions, viewport.name).length;
3053
3057
  expectedActionCountByViewport.set(viewport.name, expectedActionCount);
@@ -4524,17 +4528,6 @@ function assessProfile(profile, evidence) {
4524
4528
  const actionCount = profile.target.setup_actions.length;
4525
4529
  const failed = [];
4526
4530
  const expectedActionCountsByViewport = {};
4527
- const capturedViewportNames = new Set(viewports.map((viewport) => viewport.name));
4528
- for (const action of profile.target.setup_actions) {
4529
- if (Array.isArray(action.viewports) && action.viewports.length && !action.viewports.some((name) => capturedViewportNames.has(name))) {
4530
- failed.push({
4531
- viewport: null,
4532
- action: action.type,
4533
- selector: action.selector || null,
4534
- reason: "setup action scoped to missing viewport(s): " + action.viewports.join(", "),
4535
- });
4536
- }
4537
- }
4538
4531
  for (const viewport of viewports) {
4539
4532
  const expectedActionCount = setupActionsForViewport(profile.target.setup_actions, viewport.name).length;
4540
4533
  expectedActionCountsByViewport[viewport.name] = expectedActionCount;
@@ -6377,8 +6370,35 @@ async function executeSetupAction(action, ordinal, viewport) {
6377
6370
  : { timeout, noWaitAfter: true };
6378
6371
  const clickCount = setupNumber(action.click_count, 1);
6379
6372
  if (Number.isInteger(clickCount) && clickCount > 1) clickOptions.clickCount = clickCount;
6373
+ const fromX = setupFiniteNumber(action.from_x ?? action.fromX ?? action.x ?? action.click_x ?? action.clickX);
6374
+ const fromY = setupFiniteNumber(action.from_y ?? action.fromY ?? action.y ?? action.click_y ?? action.clickY);
6375
+ const hasClickPosition = fromX !== undefined || fromY !== undefined;
6376
+ let position;
6377
+ let mode;
6378
+ if (hasClickPosition) {
6379
+ if (fromX === undefined || fromY === undefined) return { ...base, ...setupScopeEvidence(scope), reason: "missing_click_coordinates", count, target_index: targetIndex };
6380
+ const target = locator.nth(targetIndex);
6381
+ const box = await target.boundingBox();
6382
+ if (!box) return { ...base, ...setupScopeEvidence(scope), reason: "bounding_box_unavailable", count, target_index: targetIndex };
6383
+ mode = String(action.coordinate_mode || action.coordinateMode || "pixels").trim();
6384
+ const coordinate = (value, size) => mode === "ratio" ? value * size : value;
6385
+ position = { x: coordinate(fromX, box.width), y: coordinate(fromY, box.height) };
6386
+ clickOptions.position = position;
6387
+ }
6380
6388
  await locator.nth(targetIndex).click(clickOptions);
6381
- return { ...base, ...setupScopeEvidence(scope), ok: true, count, target_index: targetIndex, text: matchedText, force: action.force === true || undefined, click_count: clickCount > 1 ? clickCount : undefined };
6389
+ return {
6390
+ ...base,
6391
+ ...setupScopeEvidence(scope),
6392
+ ok: true,
6393
+ count,
6394
+ target_index: targetIndex,
6395
+ text: matchedText,
6396
+ force: action.force === true || undefined,
6397
+ click_count: clickCount > 1 ? clickCount : undefined,
6398
+ coordinate_mode: mode,
6399
+ x: position ? fromX : undefined,
6400
+ y: position ? fromY : undefined,
6401
+ };
6382
6402
  }
6383
6403
  if (type === "fill" || type === "set_input_value") {
6384
6404
  const scope = await setupActionScope(action, timeout);
package/dist/cli.cjs CHANGED
@@ -7871,12 +7871,27 @@ function normalizeSetupAction(input, index) {
7871
7871
  if ((type === "click" || type === "drag" || type === "fill" || type === "set_input_value" || type === "set_range_value" || type === "canvas_signature" || type === "wait_for_selector" || type === "wait_for_text" || type === "assert_text_visible" || type === "assert_text_absent" || type === "assert_selector_count") && !selector) {
7872
7872
  throw new Error(`target.setup_actions[${index}] ${type} requires selector.`);
7873
7873
  }
7874
- const fromX = numberValue(valueFromOwn(input, "from_x", "fromX", "start_x", "startX", "x1"));
7875
- const fromY = numberValue(valueFromOwn(input, "from_y", "fromY", "start_y", "startY", "y1"));
7874
+ const fromX = type === "click" ? numberValue(valueFromOwn(input, "from_x", "fromX", "x", "click_x", "clickX", "start_x", "startX", "x1")) : numberValue(valueFromOwn(input, "from_x", "fromX", "start_x", "startX", "x1"));
7875
+ const fromY = type === "click" ? numberValue(valueFromOwn(input, "from_y", "fromY", "y", "click_y", "clickY", "start_y", "startY", "y1")) : numberValue(valueFromOwn(input, "from_y", "fromY", "start_y", "startY", "y1"));
7876
7876
  const toX = numberValue(valueFromOwn(input, "to_x", "toX", "end_x", "endX", "x2"));
7877
7877
  const toY = numberValue(valueFromOwn(input, "to_y", "toY", "end_y", "endY", "y2"));
7878
7878
  const coordinateMode = normalizeSetupActionCoordinateMode(valueFromOwn(input, "coordinate_mode", "coordinateMode", "coords", "units"), index);
7879
7879
  const pointerType = normalizeSetupActionPointerType(valueFromOwn(input, "pointer_type", "pointerType", "input_type", "inputType"), type, index);
7880
+ if (type === "click") {
7881
+ const hasClickCoordinate = fromX !== void 0 || fromY !== void 0;
7882
+ if (hasClickCoordinate && (fromX === void 0 || fromY === void 0)) {
7883
+ throw new Error(`target.setup_actions[${index}] click coordinates require both x and y.`);
7884
+ }
7885
+ if (hasClickCoordinate && fromX !== void 0 && fromY !== void 0) {
7886
+ const clickCoordinates = [fromX, fromY];
7887
+ if (coordinateMode === "ratio" && clickCoordinates.some((value2) => value2 < 0 || value2 > 1)) {
7888
+ throw new Error(`target.setup_actions[${index}] click ratio coordinates must be between 0 and 1.`);
7889
+ }
7890
+ if ((coordinateMode === void 0 || coordinateMode === "pixels") && clickCoordinates.some((value2) => value2 < 0)) {
7891
+ throw new Error(`target.setup_actions[${index}] click pixel coordinates must be non-negative.`);
7892
+ }
7893
+ }
7894
+ }
7880
7895
  if (type === "drag") {
7881
7896
  if (fromX === void 0 || fromY === void 0 || toX === void 0 || toY === void 0) {
7882
7897
  throw new Error(`target.setup_actions[${index}] drag requires from_x, from_y, to_x, and to_y.`);
@@ -9994,17 +10009,6 @@ function assessSetupActionsFromEvidence(profile, evidence) {
9994
10009
  const failed = [];
9995
10010
  const viewports = evidence.viewports || [];
9996
10011
  const expectedActionCountByViewport = /* @__PURE__ */ new Map();
9997
- const capturedViewportNames = new Set(viewports.map((viewport) => viewport.name));
9998
- for (const action of profile.target.setup_actions) {
9999
- if (action.viewports?.length && !action.viewports.some((name) => capturedViewportNames.has(name))) {
10000
- failed.push({
10001
- viewport: null,
10002
- action: action.type,
10003
- selector: action.selector ?? null,
10004
- reason: `setup action scoped to missing viewport(s): ${action.viewports.join(", ")}`
10005
- });
10006
- }
10007
- }
10008
10012
  for (const viewport of viewports) {
10009
10013
  const expectedActionCount = setupActionsForViewport(profile.target.setup_actions, viewport.name).length;
10010
10014
  expectedActionCountByViewport.set(viewport.name, expectedActionCount);
@@ -11465,17 +11469,6 @@ function assessProfile(profile, evidence) {
11465
11469
  const actionCount = profile.target.setup_actions.length;
11466
11470
  const failed = [];
11467
11471
  const expectedActionCountsByViewport = {};
11468
- const capturedViewportNames = new Set(viewports.map((viewport) => viewport.name));
11469
- for (const action of profile.target.setup_actions) {
11470
- if (Array.isArray(action.viewports) && action.viewports.length && !action.viewports.some((name) => capturedViewportNames.has(name))) {
11471
- failed.push({
11472
- viewport: null,
11473
- action: action.type,
11474
- selector: action.selector || null,
11475
- reason: "setup action scoped to missing viewport(s): " + action.viewports.join(", "),
11476
- });
11477
- }
11478
- }
11479
11472
  for (const viewport of viewports) {
11480
11473
  const expectedActionCount = setupActionsForViewport(profile.target.setup_actions, viewport.name).length;
11481
11474
  expectedActionCountsByViewport[viewport.name] = expectedActionCount;
@@ -13318,8 +13311,35 @@ async function executeSetupAction(action, ordinal, viewport) {
13318
13311
  : { timeout, noWaitAfter: true };
13319
13312
  const clickCount = setupNumber(action.click_count, 1);
13320
13313
  if (Number.isInteger(clickCount) && clickCount > 1) clickOptions.clickCount = clickCount;
13314
+ const fromX = setupFiniteNumber(action.from_x ?? action.fromX ?? action.x ?? action.click_x ?? action.clickX);
13315
+ const fromY = setupFiniteNumber(action.from_y ?? action.fromY ?? action.y ?? action.click_y ?? action.clickY);
13316
+ const hasClickPosition = fromX !== undefined || fromY !== undefined;
13317
+ let position;
13318
+ let mode;
13319
+ if (hasClickPosition) {
13320
+ if (fromX === undefined || fromY === undefined) return { ...base, ...setupScopeEvidence(scope), reason: "missing_click_coordinates", count, target_index: targetIndex };
13321
+ const target = locator.nth(targetIndex);
13322
+ const box = await target.boundingBox();
13323
+ if (!box) return { ...base, ...setupScopeEvidence(scope), reason: "bounding_box_unavailable", count, target_index: targetIndex };
13324
+ mode = String(action.coordinate_mode || action.coordinateMode || "pixels").trim();
13325
+ const coordinate = (value, size) => mode === "ratio" ? value * size : value;
13326
+ position = { x: coordinate(fromX, box.width), y: coordinate(fromY, box.height) };
13327
+ clickOptions.position = position;
13328
+ }
13321
13329
  await locator.nth(targetIndex).click(clickOptions);
13322
- return { ...base, ...setupScopeEvidence(scope), ok: true, count, target_index: targetIndex, text: matchedText, force: action.force === true || undefined, click_count: clickCount > 1 ? clickCount : undefined };
13330
+ return {
13331
+ ...base,
13332
+ ...setupScopeEvidence(scope),
13333
+ ok: true,
13334
+ count,
13335
+ target_index: targetIndex,
13336
+ text: matchedText,
13337
+ force: action.force === true || undefined,
13338
+ click_count: clickCount > 1 ? clickCount : undefined,
13339
+ coordinate_mode: mode,
13340
+ x: position ? fromX : undefined,
13341
+ y: position ? fromY : undefined,
13342
+ };
13323
13343
  }
13324
13344
  if (type === "fill" || type === "set_input_value") {
13325
13345
  const scope = await setupActionScope(action, timeout);
package/dist/cli.js CHANGED
@@ -13,7 +13,7 @@ import {
13
13
  profileStatusExitCode,
14
14
  resolveRiddleProofProfileTargetUrl,
15
15
  resolveRiddleProofProfileTimeoutSec
16
- } from "./chunk-ZNPSDMJX.js";
16
+ } from "./chunk-UZZA33AX.js";
17
17
  import {
18
18
  createRiddleApiClient,
19
19
  isTerminalRiddleJobStatus,
package/dist/index.cjs CHANGED
@@ -9647,12 +9647,27 @@ function normalizeSetupAction(input, index) {
9647
9647
  if ((type === "click" || type === "drag" || type === "fill" || type === "set_input_value" || type === "set_range_value" || type === "canvas_signature" || type === "wait_for_selector" || type === "wait_for_text" || type === "assert_text_visible" || type === "assert_text_absent" || type === "assert_selector_count") && !selector) {
9648
9648
  throw new Error(`target.setup_actions[${index}] ${type} requires selector.`);
9649
9649
  }
9650
- const fromX = numberValue3(valueFromOwn(input, "from_x", "fromX", "start_x", "startX", "x1"));
9651
- const fromY = numberValue3(valueFromOwn(input, "from_y", "fromY", "start_y", "startY", "y1"));
9650
+ const fromX = type === "click" ? numberValue3(valueFromOwn(input, "from_x", "fromX", "x", "click_x", "clickX", "start_x", "startX", "x1")) : numberValue3(valueFromOwn(input, "from_x", "fromX", "start_x", "startX", "x1"));
9651
+ const fromY = type === "click" ? numberValue3(valueFromOwn(input, "from_y", "fromY", "y", "click_y", "clickY", "start_y", "startY", "y1")) : numberValue3(valueFromOwn(input, "from_y", "fromY", "start_y", "startY", "y1"));
9652
9652
  const toX = numberValue3(valueFromOwn(input, "to_x", "toX", "end_x", "endX", "x2"));
9653
9653
  const toY = numberValue3(valueFromOwn(input, "to_y", "toY", "end_y", "endY", "y2"));
9654
9654
  const coordinateMode = normalizeSetupActionCoordinateMode(valueFromOwn(input, "coordinate_mode", "coordinateMode", "coords", "units"), index);
9655
9655
  const pointerType = normalizeSetupActionPointerType(valueFromOwn(input, "pointer_type", "pointerType", "input_type", "inputType"), type, index);
9656
+ if (type === "click") {
9657
+ const hasClickCoordinate = fromX !== void 0 || fromY !== void 0;
9658
+ if (hasClickCoordinate && (fromX === void 0 || fromY === void 0)) {
9659
+ throw new Error(`target.setup_actions[${index}] click coordinates require both x and y.`);
9660
+ }
9661
+ if (hasClickCoordinate && fromX !== void 0 && fromY !== void 0) {
9662
+ const clickCoordinates = [fromX, fromY];
9663
+ if (coordinateMode === "ratio" && clickCoordinates.some((value2) => value2 < 0 || value2 > 1)) {
9664
+ throw new Error(`target.setup_actions[${index}] click ratio coordinates must be between 0 and 1.`);
9665
+ }
9666
+ if ((coordinateMode === void 0 || coordinateMode === "pixels") && clickCoordinates.some((value2) => value2 < 0)) {
9667
+ throw new Error(`target.setup_actions[${index}] click pixel coordinates must be non-negative.`);
9668
+ }
9669
+ }
9670
+ }
9656
9671
  if (type === "drag") {
9657
9672
  if (fromX === void 0 || fromY === void 0 || toX === void 0 || toY === void 0) {
9658
9673
  throw new Error(`target.setup_actions[${index}] drag requires from_x, from_y, to_x, and to_y.`);
@@ -11770,17 +11785,6 @@ function assessSetupActionsFromEvidence(profile, evidence) {
11770
11785
  const failed = [];
11771
11786
  const viewports = evidence.viewports || [];
11772
11787
  const expectedActionCountByViewport = /* @__PURE__ */ new Map();
11773
- const capturedViewportNames = new Set(viewports.map((viewport) => viewport.name));
11774
- for (const action of profile.target.setup_actions) {
11775
- if (action.viewports?.length && !action.viewports.some((name) => capturedViewportNames.has(name))) {
11776
- failed.push({
11777
- viewport: null,
11778
- action: action.type,
11779
- selector: action.selector ?? null,
11780
- reason: `setup action scoped to missing viewport(s): ${action.viewports.join(", ")}`
11781
- });
11782
- }
11783
- }
11784
11788
  for (const viewport of viewports) {
11785
11789
  const expectedActionCount = setupActionsForViewport(profile.target.setup_actions, viewport.name).length;
11786
11790
  expectedActionCountByViewport.set(viewport.name, expectedActionCount);
@@ -13257,17 +13261,6 @@ function assessProfile(profile, evidence) {
13257
13261
  const actionCount = profile.target.setup_actions.length;
13258
13262
  const failed = [];
13259
13263
  const expectedActionCountsByViewport = {};
13260
- const capturedViewportNames = new Set(viewports.map((viewport) => viewport.name));
13261
- for (const action of profile.target.setup_actions) {
13262
- if (Array.isArray(action.viewports) && action.viewports.length && !action.viewports.some((name) => capturedViewportNames.has(name))) {
13263
- failed.push({
13264
- viewport: null,
13265
- action: action.type,
13266
- selector: action.selector || null,
13267
- reason: "setup action scoped to missing viewport(s): " + action.viewports.join(", "),
13268
- });
13269
- }
13270
- }
13271
13264
  for (const viewport of viewports) {
13272
13265
  const expectedActionCount = setupActionsForViewport(profile.target.setup_actions, viewport.name).length;
13273
13266
  expectedActionCountsByViewport[viewport.name] = expectedActionCount;
@@ -15110,8 +15103,35 @@ async function executeSetupAction(action, ordinal, viewport) {
15110
15103
  : { timeout, noWaitAfter: true };
15111
15104
  const clickCount = setupNumber(action.click_count, 1);
15112
15105
  if (Number.isInteger(clickCount) && clickCount > 1) clickOptions.clickCount = clickCount;
15106
+ const fromX = setupFiniteNumber(action.from_x ?? action.fromX ?? action.x ?? action.click_x ?? action.clickX);
15107
+ const fromY = setupFiniteNumber(action.from_y ?? action.fromY ?? action.y ?? action.click_y ?? action.clickY);
15108
+ const hasClickPosition = fromX !== undefined || fromY !== undefined;
15109
+ let position;
15110
+ let mode;
15111
+ if (hasClickPosition) {
15112
+ if (fromX === undefined || fromY === undefined) return { ...base, ...setupScopeEvidence(scope), reason: "missing_click_coordinates", count, target_index: targetIndex };
15113
+ const target = locator.nth(targetIndex);
15114
+ const box = await target.boundingBox();
15115
+ if (!box) return { ...base, ...setupScopeEvidence(scope), reason: "bounding_box_unavailable", count, target_index: targetIndex };
15116
+ mode = String(action.coordinate_mode || action.coordinateMode || "pixels").trim();
15117
+ const coordinate = (value, size) => mode === "ratio" ? value * size : value;
15118
+ position = { x: coordinate(fromX, box.width), y: coordinate(fromY, box.height) };
15119
+ clickOptions.position = position;
15120
+ }
15113
15121
  await locator.nth(targetIndex).click(clickOptions);
15114
- return { ...base, ...setupScopeEvidence(scope), ok: true, count, target_index: targetIndex, text: matchedText, force: action.force === true || undefined, click_count: clickCount > 1 ? clickCount : undefined };
15122
+ return {
15123
+ ...base,
15124
+ ...setupScopeEvidence(scope),
15125
+ ok: true,
15126
+ count,
15127
+ target_index: targetIndex,
15128
+ text: matchedText,
15129
+ force: action.force === true || undefined,
15130
+ click_count: clickCount > 1 ? clickCount : undefined,
15131
+ coordinate_mode: mode,
15132
+ x: position ? fromX : undefined,
15133
+ y: position ? fromY : undefined,
15134
+ };
15115
15135
  }
15116
15136
  if (type === "fill" || type === "set_input_value") {
15117
15137
  const scope = await setupActionScope(action, timeout);
package/dist/index.js CHANGED
@@ -62,7 +62,7 @@ import {
62
62
  resolveRiddleProofProfileTimeoutSec,
63
63
  slugifyRiddleProofProfileName,
64
64
  summarizeRiddleProofProfileResult
65
- } from "./chunk-ZNPSDMJX.js";
65
+ } from "./chunk-UZZA33AX.js";
66
66
  import {
67
67
  DEFAULT_RIDDLE_API_BASE_URL,
68
68
  DEFAULT_RIDDLE_API_KEY_FILE,
package/dist/profile.cjs CHANGED
@@ -961,12 +961,27 @@ function normalizeSetupAction(input, index) {
961
961
  if ((type === "click" || type === "drag" || type === "fill" || type === "set_input_value" || type === "set_range_value" || type === "canvas_signature" || type === "wait_for_selector" || type === "wait_for_text" || type === "assert_text_visible" || type === "assert_text_absent" || type === "assert_selector_count") && !selector) {
962
962
  throw new Error(`target.setup_actions[${index}] ${type} requires selector.`);
963
963
  }
964
- const fromX = numberValue(valueFromOwn(input, "from_x", "fromX", "start_x", "startX", "x1"));
965
- const fromY = numberValue(valueFromOwn(input, "from_y", "fromY", "start_y", "startY", "y1"));
964
+ const fromX = type === "click" ? numberValue(valueFromOwn(input, "from_x", "fromX", "x", "click_x", "clickX", "start_x", "startX", "x1")) : numberValue(valueFromOwn(input, "from_x", "fromX", "start_x", "startX", "x1"));
965
+ const fromY = type === "click" ? numberValue(valueFromOwn(input, "from_y", "fromY", "y", "click_y", "clickY", "start_y", "startY", "y1")) : numberValue(valueFromOwn(input, "from_y", "fromY", "start_y", "startY", "y1"));
966
966
  const toX = numberValue(valueFromOwn(input, "to_x", "toX", "end_x", "endX", "x2"));
967
967
  const toY = numberValue(valueFromOwn(input, "to_y", "toY", "end_y", "endY", "y2"));
968
968
  const coordinateMode = normalizeSetupActionCoordinateMode(valueFromOwn(input, "coordinate_mode", "coordinateMode", "coords", "units"), index);
969
969
  const pointerType = normalizeSetupActionPointerType(valueFromOwn(input, "pointer_type", "pointerType", "input_type", "inputType"), type, index);
970
+ if (type === "click") {
971
+ const hasClickCoordinate = fromX !== void 0 || fromY !== void 0;
972
+ if (hasClickCoordinate && (fromX === void 0 || fromY === void 0)) {
973
+ throw new Error(`target.setup_actions[${index}] click coordinates require both x and y.`);
974
+ }
975
+ if (hasClickCoordinate && fromX !== void 0 && fromY !== void 0) {
976
+ const clickCoordinates = [fromX, fromY];
977
+ if (coordinateMode === "ratio" && clickCoordinates.some((value2) => value2 < 0 || value2 > 1)) {
978
+ throw new Error(`target.setup_actions[${index}] click ratio coordinates must be between 0 and 1.`);
979
+ }
980
+ if ((coordinateMode === void 0 || coordinateMode === "pixels") && clickCoordinates.some((value2) => value2 < 0)) {
981
+ throw new Error(`target.setup_actions[${index}] click pixel coordinates must be non-negative.`);
982
+ }
983
+ }
984
+ }
970
985
  if (type === "drag") {
971
986
  if (fromX === void 0 || fromY === void 0 || toX === void 0 || toY === void 0) {
972
987
  throw new Error(`target.setup_actions[${index}] drag requires from_x, from_y, to_x, and to_y.`);
@@ -3084,17 +3099,6 @@ function assessSetupActionsFromEvidence(profile, evidence) {
3084
3099
  const failed = [];
3085
3100
  const viewports = evidence.viewports || [];
3086
3101
  const expectedActionCountByViewport = /* @__PURE__ */ new Map();
3087
- const capturedViewportNames = new Set(viewports.map((viewport) => viewport.name));
3088
- for (const action of profile.target.setup_actions) {
3089
- if (action.viewports?.length && !action.viewports.some((name) => capturedViewportNames.has(name))) {
3090
- failed.push({
3091
- viewport: null,
3092
- action: action.type,
3093
- selector: action.selector ?? null,
3094
- reason: `setup action scoped to missing viewport(s): ${action.viewports.join(", ")}`
3095
- });
3096
- }
3097
- }
3098
3102
  for (const viewport of viewports) {
3099
3103
  const expectedActionCount = setupActionsForViewport(profile.target.setup_actions, viewport.name).length;
3100
3104
  expectedActionCountByViewport.set(viewport.name, expectedActionCount);
@@ -4571,17 +4575,6 @@ function assessProfile(profile, evidence) {
4571
4575
  const actionCount = profile.target.setup_actions.length;
4572
4576
  const failed = [];
4573
4577
  const expectedActionCountsByViewport = {};
4574
- const capturedViewportNames = new Set(viewports.map((viewport) => viewport.name));
4575
- for (const action of profile.target.setup_actions) {
4576
- if (Array.isArray(action.viewports) && action.viewports.length && !action.viewports.some((name) => capturedViewportNames.has(name))) {
4577
- failed.push({
4578
- viewport: null,
4579
- action: action.type,
4580
- selector: action.selector || null,
4581
- reason: "setup action scoped to missing viewport(s): " + action.viewports.join(", "),
4582
- });
4583
- }
4584
- }
4585
4578
  for (const viewport of viewports) {
4586
4579
  const expectedActionCount = setupActionsForViewport(profile.target.setup_actions, viewport.name).length;
4587
4580
  expectedActionCountsByViewport[viewport.name] = expectedActionCount;
@@ -6424,8 +6417,35 @@ async function executeSetupAction(action, ordinal, viewport) {
6424
6417
  : { timeout, noWaitAfter: true };
6425
6418
  const clickCount = setupNumber(action.click_count, 1);
6426
6419
  if (Number.isInteger(clickCount) && clickCount > 1) clickOptions.clickCount = clickCount;
6420
+ const fromX = setupFiniteNumber(action.from_x ?? action.fromX ?? action.x ?? action.click_x ?? action.clickX);
6421
+ const fromY = setupFiniteNumber(action.from_y ?? action.fromY ?? action.y ?? action.click_y ?? action.clickY);
6422
+ const hasClickPosition = fromX !== undefined || fromY !== undefined;
6423
+ let position;
6424
+ let mode;
6425
+ if (hasClickPosition) {
6426
+ if (fromX === undefined || fromY === undefined) return { ...base, ...setupScopeEvidence(scope), reason: "missing_click_coordinates", count, target_index: targetIndex };
6427
+ const target = locator.nth(targetIndex);
6428
+ const box = await target.boundingBox();
6429
+ if (!box) return { ...base, ...setupScopeEvidence(scope), reason: "bounding_box_unavailable", count, target_index: targetIndex };
6430
+ mode = String(action.coordinate_mode || action.coordinateMode || "pixels").trim();
6431
+ const coordinate = (value, size) => mode === "ratio" ? value * size : value;
6432
+ position = { x: coordinate(fromX, box.width), y: coordinate(fromY, box.height) };
6433
+ clickOptions.position = position;
6434
+ }
6427
6435
  await locator.nth(targetIndex).click(clickOptions);
6428
- return { ...base, ...setupScopeEvidence(scope), ok: true, count, target_index: targetIndex, text: matchedText, force: action.force === true || undefined, click_count: clickCount > 1 ? clickCount : undefined };
6436
+ return {
6437
+ ...base,
6438
+ ...setupScopeEvidence(scope),
6439
+ ok: true,
6440
+ count,
6441
+ target_index: targetIndex,
6442
+ text: matchedText,
6443
+ force: action.force === true || undefined,
6444
+ click_count: clickCount > 1 ? clickCount : undefined,
6445
+ coordinate_mode: mode,
6446
+ x: position ? fromX : undefined,
6447
+ y: position ? fromY : undefined,
6448
+ };
6429
6449
  }
6430
6450
  if (type === "fill" || type === "set_input_value") {
6431
6451
  const scope = await setupActionScope(action, timeout);
package/dist/profile.js CHANGED
@@ -23,7 +23,7 @@ import {
23
23
  resolveRiddleProofProfileTimeoutSec,
24
24
  slugifyRiddleProofProfileName,
25
25
  summarizeRiddleProofProfileResult
26
- } from "./chunk-ZNPSDMJX.js";
26
+ } from "./chunk-UZZA33AX.js";
27
27
  export {
28
28
  RIDDLE_PROOF_PROFILE_CHECK_TYPES,
29
29
  RIDDLE_PROOF_PROFILE_EVIDENCE_VERSION,
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@riddledc/riddle-proof",
3
- "version": "0.7.165",
3
+ "version": "0.7.167",
4
4
  "description": "Reusable Riddle Proof contracts and helpers for evidence-backed agent changes.",
5
5
  "license": "MIT",
6
6
  "author": "RiddleDC",