@riddledc/riddle-proof 0.7.173 → 0.7.175

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/README.md CHANGED
@@ -397,7 +397,7 @@ when body matching overrides sequence order.
397
397
  `target.setup_actions` is optional. Use it when the meaningful proof surface
398
398
  appears only after a picker, tab, login stub, storage seed, form fill,
399
399
  transport control, or other bounded interaction. Supported setup actions are
400
- `click`, `drag`, `press`, `fill`, `set_input_value`, `set_range_value`,
400
+ `click`, `tap`, `drag`, `press`, `fill`, `set_input_value`, `set_range_value`,
401
401
  `deterministic_runtime`, `canvas_signature`, `assert_text_visible`, `assert_text_absent`,
402
402
  `assert_selector_count`, `assert_window_value`, `assert_window_number`,
403
403
  `local_storage`, `session_storage`, `clear_storage`, `clear_console`,
@@ -416,6 +416,12 @@ Use `click_count` / `clickCount` / `clicks` from 1 to 10 on a single `click`
416
416
  action for atomic double-click or double-submit contracts where modeling the
417
417
  interaction as repeated setup actions would incorrectly require the target to
418
418
  remain in the DOM after the first click.
419
+ Use `tap` for touch-first controls, especially canvas regions where a mobile
420
+ tap should produce trusted touch events and the browser's synthesized click.
421
+ It requires `selector`, defaults to a touch tap at the target center, and
422
+ accepts `x` / `y` or `from_x` / `from_y` plus `coordinate_mode: "ratio"` for
423
+ element-relative coordinates. Set `pointer_type` to `mouse`, `touch`, or `pen`
424
+ when the proof must distinguish input modality.
419
425
  Use `set_range_value` for HTML range inputs and React-controlled sliders. It
420
426
  accepts aliases such as `set-slider-value`, requires `selector` plus `value`,
421
427
  uses the native input value setter, dispatches bubbling `input` and `change`
@@ -44,6 +44,7 @@ var RIDDLE_PROOF_PROFILE_CHECK_TYPES = [
44
44
  ];
45
45
  var RIDDLE_PROOF_PROFILE_SETUP_ACTION_TYPES = [
46
46
  "click",
47
+ "tap",
47
48
  "drag",
48
49
  "press",
49
50
  "fill",
@@ -595,6 +596,21 @@ function profileSetupDragReceipts(results) {
595
596
  reason: result.reason ?? result.error ?? null
596
597
  }));
597
598
  }
599
+ function profileSetupTapReceipts(results) {
600
+ return results.filter((result) => profileSetupResultAction(result) === "tap").map((result) => ({
601
+ ordinal: result.ordinal ?? null,
602
+ ok: result.ok !== false,
603
+ selector: result.selector ?? null,
604
+ frame_selector: result.frame_selector ?? null,
605
+ pointer_type: result.pointer_type ?? null,
606
+ input_dispatch: result.input_dispatch ?? null,
607
+ coordinate_mode: result.coordinate_mode ?? null,
608
+ x: result.x ?? null,
609
+ y: result.y ?? null,
610
+ duration_ms: result.duration_ms ?? null,
611
+ reason: result.reason ?? result.error ?? null
612
+ }));
613
+ }
598
614
  function profileSetupCanvasSignatureReceipts(results) {
599
615
  return results.filter((result) => profileSetupResultAction(result) === "canvas_signature").map((result) => ({
600
616
  ordinal: result.ordinal ?? null,
@@ -756,6 +772,8 @@ function profileSetupSummary(viewports, actionCount, expectedActionCountByViewpo
756
772
  const sampledRangeValueReceipts = sampleProfileSetupSummaryItems(rangeValueReceipts, 8);
757
773
  const dragReceipts = profileSetupDragReceipts(results);
758
774
  const sampledDragReceipts = sampleProfileSetupSummaryItems(dragReceipts, 8);
775
+ const tapReceipts = profileSetupTapReceipts(results);
776
+ const sampledTapReceipts = sampleProfileSetupSummaryItems(tapReceipts, 8);
759
777
  const canvasSignatureReceipts = profileSetupCanvasSignatureReceipts(results);
760
778
  const sampledCanvasSignatureReceipts = sampleProfileSetupSummaryItems(canvasSignatureReceipts, 8);
761
779
  const clickedItems = results.filter((result) => profileSetupResultAction(result) === "click" && result.ok !== false).map((result) => {
@@ -820,6 +838,9 @@ function profileSetupSummary(viewports, actionCount, expectedActionCountByViewpo
820
838
  drag_total: dragReceipts.length,
821
839
  drag_truncated: dragReceipts.length > sampledDragReceipts.length,
822
840
  drag: sampledDragReceipts,
841
+ tap_total: tapReceipts.length,
842
+ tap_truncated: tapReceipts.length > sampledTapReceipts.length,
843
+ tap: sampledTapReceipts,
823
844
  canvas_signature_total: canvasSignatureReceipts.length,
824
845
  canvas_signature_truncated: canvasSignatureReceipts.length > sampledCanvasSignatureReceipts.length,
825
846
  canvas_signature: sampledCanvasSignatureReceipts,
@@ -876,7 +897,7 @@ function isSupportedCheckType(value) {
876
897
  }
877
898
  function normalizeSetupActionType(value, index) {
878
899
  const normalizedInput = String(value || "").trim().replace(/-/g, "_");
879
- const normalized = normalizedInput === "clear_browser_storage" ? "clear_storage" : normalizedInput === "reset_console" || normalizedInput === "clear_browser_console" || normalizedInput === "reset_browser_console" ? "clear_console" : normalizedInput === "pointer_drag" || normalizedInput === "mouse_drag" || normalizedInput === "drag_to" ? "drag" : normalizedInput === "keyboard_press" || normalizedInput === "key_press" ? "press" : normalizedInput === "set_slider_value" || normalizedInput === "slider_value" || normalizedInput === "set_slider" || normalizedInput === "set_range" || normalizedInput === "range_value" || normalizedInput === "range_input" || normalizedInput === "set_range_input" ? "set_range_value" : normalizedInput === "deterministic_runtime" || normalizedInput === "mock_runtime" || normalizedInput === "mock_random" || normalizedInput === "mock_random_queue" || normalizedInput === "seed_random_queue" || normalizedInput === "set_random_queue" || normalizedInput === "mock_clock" || normalizedInput === "set_mock_clock" || normalizedInput === "set_runtime_determinism" || normalizedInput === "runtime_determinism" ? "deterministic_runtime" : normalizedInput === "canvas_hash" || normalizedInput === "capture_canvas_hash" || normalizedInput === "capture_canvas_signature" || normalizedInput === "canvas_state_signature" ? "canvas_signature" : normalizedInput === "capture_screenshot" || normalizedInput === "save_screenshot" || normalizedInput === "setup_screenshot" ? "screenshot" : normalizedInput === "accept_dialog" || normalizedInput === "accept_dialogs" || normalizedInput === "confirm_dialog" || normalizedInput === "set_dialog_response" ? "dialog_response" : normalizedInput === "dismiss_dialog" || normalizedInput === "dismiss_dialogs" || normalizedInput === "cancel_dialog" ? "dialog_response" : normalizedInput === "window_call_until" || normalizedInput === "call_until" || normalizedInput === "window_call_repeat_until" || normalizedInput === "repeat_window_call_until" ? "window_call_until" : normalizedInput === "window_evaluate" || normalizedInput === "browser_eval" || normalizedInput === "browser_evaluate" || normalizedInput === "evaluate_script" || normalizedInput === "profile_script" ? "window_eval" : normalizedInput;
900
+ const normalized = normalizedInput === "clear_browser_storage" ? "clear_storage" : normalizedInput === "reset_console" || normalizedInput === "clear_browser_console" || normalizedInput === "reset_browser_console" ? "clear_console" : normalizedInput === "pointer_drag" || normalizedInput === "mouse_drag" || normalizedInput === "drag_to" ? "drag" : normalizedInput === "pointer_tap" || normalizedInput === "touch_tap" || normalizedInput === "canvas_tap" ? "tap" : normalizedInput === "keyboard_press" || normalizedInput === "key_press" ? "press" : normalizedInput === "set_slider_value" || normalizedInput === "slider_value" || normalizedInput === "set_slider" || normalizedInput === "set_range" || normalizedInput === "range_value" || normalizedInput === "range_input" || normalizedInput === "set_range_input" ? "set_range_value" : normalizedInput === "deterministic_runtime" || normalizedInput === "mock_runtime" || normalizedInput === "mock_random" || normalizedInput === "mock_random_queue" || normalizedInput === "seed_random_queue" || normalizedInput === "set_random_queue" || normalizedInput === "mock_clock" || normalizedInput === "set_mock_clock" || normalizedInput === "set_runtime_determinism" || normalizedInput === "runtime_determinism" ? "deterministic_runtime" : normalizedInput === "canvas_hash" || normalizedInput === "capture_canvas_hash" || normalizedInput === "capture_canvas_signature" || normalizedInput === "canvas_state_signature" ? "canvas_signature" : normalizedInput === "capture_screenshot" || normalizedInput === "save_screenshot" || normalizedInput === "setup_screenshot" ? "screenshot" : normalizedInput === "accept_dialog" || normalizedInput === "accept_dialogs" || normalizedInput === "confirm_dialog" || normalizedInput === "set_dialog_response" ? "dialog_response" : normalizedInput === "dismiss_dialog" || normalizedInput === "dismiss_dialogs" || normalizedInput === "cancel_dialog" ? "dialog_response" : normalizedInput === "window_call_until" || normalizedInput === "call_until" || normalizedInput === "window_call_repeat_until" || normalizedInput === "repeat_window_call_until" ? "window_call_until" : normalizedInput === "window_evaluate" || normalizedInput === "browser_eval" || normalizedInput === "browser_evaluate" || normalizedInput === "evaluate_script" || normalizedInput === "profile_script" ? "window_eval" : normalizedInput;
880
901
  if (RIDDLE_PROOF_PROFILE_SETUP_ACTION_TYPES.includes(normalized)) {
881
902
  return normalized;
882
903
  }
@@ -958,8 +979,8 @@ function normalizeSetupActionCoordinateMode(value, index) {
958
979
  }
959
980
  function normalizeSetupActionPointerType(value, type, index) {
960
981
  if (value === void 0 || value === null || value === "") return void 0;
961
- if (type !== "drag") {
962
- throw new Error(`target.setup_actions[${index}].pointer_type is only supported for drag actions.`);
982
+ if (type !== "drag" && type !== "tap") {
983
+ throw new Error(`target.setup_actions[${index}].pointer_type is only supported for drag/tap actions.`);
963
984
  }
964
985
  const normalized = String(value).trim().replace(/-/g, "_").toLowerCase();
965
986
  if (normalized === "mouse") return "mouse";
@@ -1038,11 +1059,11 @@ function normalizeSetupAction(input, index) {
1038
1059
  if (frameIndex !== void 0 && (!Number.isInteger(frameIndex) || frameIndex < 0)) {
1039
1060
  throw new Error(`target.setup_actions[${index}].frame_index must be a non-negative integer.`);
1040
1061
  }
1041
- 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) {
1062
+ if ((type === "click" || type === "tap" || 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) {
1042
1063
  throw new Error(`target.setup_actions[${index}] ${type} requires selector.`);
1043
1064
  }
1044
- 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"));
1045
- 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"));
1065
+ const fromX = type === "click" || type === "tap" ? numberValue(valueFromOwn(input, "from_x", "fromX", "x", "click_x", "clickX", "start_x", "startX", "x1")) : numberValue(valueFromOwn(input, "from_x", "fromX", "start_x", "startX", "x1"));
1066
+ const fromY = type === "click" || type === "tap" ? numberValue(valueFromOwn(input, "from_y", "fromY", "y", "click_y", "clickY", "start_y", "startY", "y1")) : numberValue(valueFromOwn(input, "from_y", "fromY", "start_y", "startY", "y1"));
1046
1067
  const toX = numberValue(valueFromOwn(input, "to_x", "toX", "end_x", "endX", "x2"));
1047
1068
  const toY = numberValue(valueFromOwn(input, "to_y", "toY", "end_y", "endY", "y2"));
1048
1069
  const coordinateMode = normalizeSetupActionCoordinateMode(valueFromOwn(input, "coordinate_mode", "coordinateMode", "coords", "units"), index);
@@ -1062,6 +1083,21 @@ function normalizeSetupAction(input, index) {
1062
1083
  }
1063
1084
  }
1064
1085
  }
1086
+ if (type === "tap") {
1087
+ const hasTapCoordinate = fromX !== void 0 || fromY !== void 0;
1088
+ if (hasTapCoordinate && (fromX === void 0 || fromY === void 0)) {
1089
+ throw new Error(`target.setup_actions[${index}] tap coordinates require both x and y.`);
1090
+ }
1091
+ if (hasTapCoordinate && fromX !== void 0 && fromY !== void 0) {
1092
+ const tapCoordinates = [fromX, fromY];
1093
+ if (coordinateMode === "ratio" && tapCoordinates.some((value2) => value2 < 0 || value2 > 1)) {
1094
+ throw new Error(`target.setup_actions[${index}] tap ratio coordinates must be between 0 and 1.`);
1095
+ }
1096
+ if ((coordinateMode === void 0 || coordinateMode === "pixels") && tapCoordinates.some((value2) => value2 < 0)) {
1097
+ throw new Error(`target.setup_actions[${index}] tap pixel coordinates must be non-negative.`);
1098
+ }
1099
+ }
1100
+ }
1065
1101
  if (type === "drag") {
1066
1102
  if (fromX === void 0 || fromY === void 0 || toX === void 0 || toY === void 0) {
1067
1103
  throw new Error(`target.setup_actions[${index}] drag requires from_x, from_y, to_x, and to_y.`);
@@ -4373,6 +4409,23 @@ function profileSetupDragReceipts(results) {
4373
4409
  reason: result.reason || result.error || null,
4374
4410
  }));
4375
4411
  }
4412
+ function profileSetupTapReceipts(results) {
4413
+ return (results || [])
4414
+ .filter((result) => result && profileSetupResultAction(result) === "tap")
4415
+ .map((result) => ({
4416
+ ordinal: result.ordinal ?? null,
4417
+ ok: result.ok !== false,
4418
+ selector: result.selector ?? null,
4419
+ frame_selector: result.frame_selector ?? null,
4420
+ pointer_type: result.pointer_type ?? null,
4421
+ input_dispatch: result.input_dispatch ?? null,
4422
+ coordinate_mode: result.coordinate_mode ?? null,
4423
+ x: result.x ?? null,
4424
+ y: result.y ?? null,
4425
+ duration_ms: result.duration_ms ?? null,
4426
+ reason: result.reason || result.error || null,
4427
+ }));
4428
+ }
4376
4429
  function profileSetupCanvasSignatureReceipts(results) {
4377
4430
  return (results || [])
4378
4431
  .filter((result) => result && profileSetupResultAction(result) === "canvas_signature")
@@ -4559,6 +4612,8 @@ function profileSetupSummary(viewports, actionCount, expectedActionCountsByViewp
4559
4612
  const sampledRangeValueReceipts = sampleProfileSetupSummaryItems(rangeValueReceipts, 8);
4560
4613
  const dragReceipts = profileSetupDragReceipts(results);
4561
4614
  const sampledDragReceipts = sampleProfileSetupSummaryItems(dragReceipts, 8);
4615
+ const tapReceipts = profileSetupTapReceipts(results);
4616
+ const sampledTapReceipts = sampleProfileSetupSummaryItems(tapReceipts, 8);
4562
4617
  const canvasSignatureReceipts = profileSetupCanvasSignatureReceipts(results);
4563
4618
  const sampledCanvasSignatureReceipts = sampleProfileSetupSummaryItems(canvasSignatureReceipts, 8);
4564
4619
  const clickedItems = results
@@ -4633,6 +4688,9 @@ function profileSetupSummary(viewports, actionCount, expectedActionCountsByViewp
4633
4688
  drag_total: dragReceipts.length,
4634
4689
  drag_truncated: dragReceipts.length > sampledDragReceipts.length,
4635
4690
  drag: sampledDragReceipts,
4691
+ tap_total: tapReceipts.length,
4692
+ tap_truncated: tapReceipts.length > sampledTapReceipts.length,
4693
+ tap: sampledTapReceipts,
4636
4694
  canvas_signature_total: canvasSignatureReceipts.length,
4637
4695
  canvas_signature_truncated: canvasSignatureReceipts.length > sampledCanvasSignatureReceipts.length,
4638
4696
  canvas_signature: sampledCanvasSignatureReceipts,
@@ -6057,6 +6115,96 @@ async function executeSetupAction(action, ordinal, viewport) {
6057
6115
  await waitForAnyVisibleSelector(scope.context, action.selector, timeout);
6058
6116
  return { ...base, ...setupScopeEvidence(scope), ok: true, timeout_ms: timeout };
6059
6117
  }
6118
+ if (type === "tap") {
6119
+ const scope = await setupActionScope(action, timeout);
6120
+ if (!scope.ok) return setupScopeFailure(base, scope);
6121
+ const locator = scope.context.locator(action.selector);
6122
+ const count = await locator.count();
6123
+ if (!count) return { ...base, ...setupScopeEvidence(scope), reason: "selector_not_found", count };
6124
+ const targetIndex = Number.isInteger(action.index) ? action.index : 0;
6125
+ if (targetIndex < 0 || targetIndex >= count) return { ...base, ...setupScopeEvidence(scope), reason: "index_out_of_range", count, target_index: targetIndex };
6126
+ const target = locator.nth(targetIndex);
6127
+ await target.waitFor({ state: "visible", timeout });
6128
+ const box = await target.boundingBox();
6129
+ if (!box) return { ...base, ...setupScopeEvidence(scope), reason: "bounding_box_unavailable", count, target_index: targetIndex };
6130
+ const fromX = setupFiniteNumber(action.from_x ?? action.fromX ?? action.x ?? action.click_x ?? action.clickX);
6131
+ const fromY = setupFiniteNumber(action.from_y ?? action.fromY ?? action.y ?? action.click_y ?? action.clickY);
6132
+ const hasTapPosition = fromX !== undefined || fromY !== undefined;
6133
+ if (hasTapPosition && (fromX === undefined || fromY === undefined)) return { ...base, ...setupScopeEvidence(scope), reason: "missing_tap_coordinates", count, target_index: targetIndex };
6134
+ const mode = String(action.coordinate_mode || action.coordinateMode || (hasTapPosition ? "pixels" : "ratio")).trim();
6135
+ if (hasTapPosition && mode === "ratio" && [fromX, fromY].some((value) => value < 0 || value > 1)) return { ...base, ...setupScopeEvidence(scope), reason: "invalid_ratio_coordinates", count, target_index: targetIndex };
6136
+ if (hasTapPosition && mode !== "ratio" && [fromX, fromY].some((value) => value < 0)) return { ...base, ...setupScopeEvidence(scope), reason: "invalid_pixel_coordinates", count, target_index: targetIndex };
6137
+ const coordinate = (value, size) => mode === "ratio" ? value * size : value;
6138
+ const localX = hasTapPosition && fromX !== undefined ? fromX : 0.5;
6139
+ const localY = hasTapPosition && fromY !== undefined ? fromY : 0.5;
6140
+ const point = {
6141
+ x: box.x + coordinate(localX, box.width),
6142
+ y: box.y + coordinate(localY, box.height),
6143
+ };
6144
+ const durationMs = setupNumber(action.duration_ms ?? action.durationMs, 0);
6145
+ const pointerType = String(action.pointer_type || action.pointerType || "touch").trim().toLowerCase();
6146
+ if (pointerType === "touch" || pointerType === "pen") {
6147
+ const client = await page.context().newCDPSession(page);
6148
+ try {
6149
+ if (pointerType === "touch") {
6150
+ const touchPoint = {
6151
+ x: point.x,
6152
+ y: point.y,
6153
+ radiusX: 1,
6154
+ radiusY: 1,
6155
+ force: 1,
6156
+ id: 11,
6157
+ };
6158
+ await client.send("Input.dispatchTouchEvent", {
6159
+ type: "touchStart",
6160
+ touchPoints: [touchPoint],
6161
+ });
6162
+ if (durationMs) await page.waitForTimeout(durationMs);
6163
+ await client.send("Input.dispatchTouchEvent", {
6164
+ type: "touchEnd",
6165
+ touchPoints: [],
6166
+ });
6167
+ } else {
6168
+ await client.send("Input.dispatchMouseEvent", {
6169
+ type: "mousePressed",
6170
+ x: point.x,
6171
+ y: point.y,
6172
+ button: "left",
6173
+ buttons: 1,
6174
+ clickCount: 1,
6175
+ pointerType: "pen",
6176
+ });
6177
+ if (durationMs) await page.waitForTimeout(durationMs);
6178
+ await client.send("Input.dispatchMouseEvent", {
6179
+ type: "mouseReleased",
6180
+ x: point.x,
6181
+ y: point.y,
6182
+ button: "left",
6183
+ buttons: 0,
6184
+ clickCount: 1,
6185
+ pointerType: "pen",
6186
+ });
6187
+ }
6188
+ } finally {
6189
+ await client.detach().catch(() => {});
6190
+ }
6191
+ } else {
6192
+ await page.mouse.click(point.x, point.y);
6193
+ }
6194
+ return {
6195
+ ...base,
6196
+ ...setupScopeEvidence(scope),
6197
+ ok: true,
6198
+ count,
6199
+ target_index: targetIndex,
6200
+ coordinate_mode: hasTapPosition ? mode : undefined,
6201
+ x: hasTapPosition ? fromX : undefined,
6202
+ y: hasTapPosition ? fromY : undefined,
6203
+ pointer_type: pointerType,
6204
+ input_dispatch: pointerType === "touch" || pointerType === "pen" ? "cdp" : "playwright_mouse",
6205
+ duration_ms: durationMs || undefined,
6206
+ };
6207
+ }
6060
6208
  if (type === "drag") {
6061
6209
  const scope = await setupActionScope(action, timeout);
6062
6210
  if (!scope.ok) return setupScopeFailure(base, scope);
package/dist/cli.cjs CHANGED
@@ -7001,6 +7001,7 @@ var RIDDLE_PROOF_PROFILE_CHECK_TYPES = [
7001
7001
  ];
7002
7002
  var RIDDLE_PROOF_PROFILE_SETUP_ACTION_TYPES = [
7003
7003
  "click",
7004
+ "tap",
7004
7005
  "drag",
7005
7006
  "press",
7006
7007
  "fill",
@@ -7552,6 +7553,21 @@ function profileSetupDragReceipts(results) {
7552
7553
  reason: result.reason ?? result.error ?? null
7553
7554
  }));
7554
7555
  }
7556
+ function profileSetupTapReceipts(results) {
7557
+ return results.filter((result) => profileSetupResultAction(result) === "tap").map((result) => ({
7558
+ ordinal: result.ordinal ?? null,
7559
+ ok: result.ok !== false,
7560
+ selector: result.selector ?? null,
7561
+ frame_selector: result.frame_selector ?? null,
7562
+ pointer_type: result.pointer_type ?? null,
7563
+ input_dispatch: result.input_dispatch ?? null,
7564
+ coordinate_mode: result.coordinate_mode ?? null,
7565
+ x: result.x ?? null,
7566
+ y: result.y ?? null,
7567
+ duration_ms: result.duration_ms ?? null,
7568
+ reason: result.reason ?? result.error ?? null
7569
+ }));
7570
+ }
7555
7571
  function profileSetupCanvasSignatureReceipts(results) {
7556
7572
  return results.filter((result) => profileSetupResultAction(result) === "canvas_signature").map((result) => ({
7557
7573
  ordinal: result.ordinal ?? null,
@@ -7713,6 +7729,8 @@ function profileSetupSummary(viewports, actionCount, expectedActionCountByViewpo
7713
7729
  const sampledRangeValueReceipts = sampleProfileSetupSummaryItems(rangeValueReceipts, 8);
7714
7730
  const dragReceipts = profileSetupDragReceipts(results);
7715
7731
  const sampledDragReceipts = sampleProfileSetupSummaryItems(dragReceipts, 8);
7732
+ const tapReceipts = profileSetupTapReceipts(results);
7733
+ const sampledTapReceipts = sampleProfileSetupSummaryItems(tapReceipts, 8);
7716
7734
  const canvasSignatureReceipts = profileSetupCanvasSignatureReceipts(results);
7717
7735
  const sampledCanvasSignatureReceipts = sampleProfileSetupSummaryItems(canvasSignatureReceipts, 8);
7718
7736
  const clickedItems = results.filter((result) => profileSetupResultAction(result) === "click" && result.ok !== false).map((result) => {
@@ -7777,6 +7795,9 @@ function profileSetupSummary(viewports, actionCount, expectedActionCountByViewpo
7777
7795
  drag_total: dragReceipts.length,
7778
7796
  drag_truncated: dragReceipts.length > sampledDragReceipts.length,
7779
7797
  drag: sampledDragReceipts,
7798
+ tap_total: tapReceipts.length,
7799
+ tap_truncated: tapReceipts.length > sampledTapReceipts.length,
7800
+ tap: sampledTapReceipts,
7780
7801
  canvas_signature_total: canvasSignatureReceipts.length,
7781
7802
  canvas_signature_truncated: canvasSignatureReceipts.length > sampledCanvasSignatureReceipts.length,
7782
7803
  canvas_signature: sampledCanvasSignatureReceipts,
@@ -7833,7 +7854,7 @@ function isSupportedCheckType(value) {
7833
7854
  }
7834
7855
  function normalizeSetupActionType(value, index) {
7835
7856
  const normalizedInput = String(value || "").trim().replace(/-/g, "_");
7836
- const normalized = normalizedInput === "clear_browser_storage" ? "clear_storage" : normalizedInput === "reset_console" || normalizedInput === "clear_browser_console" || normalizedInput === "reset_browser_console" ? "clear_console" : normalizedInput === "pointer_drag" || normalizedInput === "mouse_drag" || normalizedInput === "drag_to" ? "drag" : normalizedInput === "keyboard_press" || normalizedInput === "key_press" ? "press" : normalizedInput === "set_slider_value" || normalizedInput === "slider_value" || normalizedInput === "set_slider" || normalizedInput === "set_range" || normalizedInput === "range_value" || normalizedInput === "range_input" || normalizedInput === "set_range_input" ? "set_range_value" : normalizedInput === "deterministic_runtime" || normalizedInput === "mock_runtime" || normalizedInput === "mock_random" || normalizedInput === "mock_random_queue" || normalizedInput === "seed_random_queue" || normalizedInput === "set_random_queue" || normalizedInput === "mock_clock" || normalizedInput === "set_mock_clock" || normalizedInput === "set_runtime_determinism" || normalizedInput === "runtime_determinism" ? "deterministic_runtime" : normalizedInput === "canvas_hash" || normalizedInput === "capture_canvas_hash" || normalizedInput === "capture_canvas_signature" || normalizedInput === "canvas_state_signature" ? "canvas_signature" : normalizedInput === "capture_screenshot" || normalizedInput === "save_screenshot" || normalizedInput === "setup_screenshot" ? "screenshot" : normalizedInput === "accept_dialog" || normalizedInput === "accept_dialogs" || normalizedInput === "confirm_dialog" || normalizedInput === "set_dialog_response" ? "dialog_response" : normalizedInput === "dismiss_dialog" || normalizedInput === "dismiss_dialogs" || normalizedInput === "cancel_dialog" ? "dialog_response" : normalizedInput === "window_call_until" || normalizedInput === "call_until" || normalizedInput === "window_call_repeat_until" || normalizedInput === "repeat_window_call_until" ? "window_call_until" : normalizedInput === "window_evaluate" || normalizedInput === "browser_eval" || normalizedInput === "browser_evaluate" || normalizedInput === "evaluate_script" || normalizedInput === "profile_script" ? "window_eval" : normalizedInput;
7857
+ const normalized = normalizedInput === "clear_browser_storage" ? "clear_storage" : normalizedInput === "reset_console" || normalizedInput === "clear_browser_console" || normalizedInput === "reset_browser_console" ? "clear_console" : normalizedInput === "pointer_drag" || normalizedInput === "mouse_drag" || normalizedInput === "drag_to" ? "drag" : normalizedInput === "pointer_tap" || normalizedInput === "touch_tap" || normalizedInput === "canvas_tap" ? "tap" : normalizedInput === "keyboard_press" || normalizedInput === "key_press" ? "press" : normalizedInput === "set_slider_value" || normalizedInput === "slider_value" || normalizedInput === "set_slider" || normalizedInput === "set_range" || normalizedInput === "range_value" || normalizedInput === "range_input" || normalizedInput === "set_range_input" ? "set_range_value" : normalizedInput === "deterministic_runtime" || normalizedInput === "mock_runtime" || normalizedInput === "mock_random" || normalizedInput === "mock_random_queue" || normalizedInput === "seed_random_queue" || normalizedInput === "set_random_queue" || normalizedInput === "mock_clock" || normalizedInput === "set_mock_clock" || normalizedInput === "set_runtime_determinism" || normalizedInput === "runtime_determinism" ? "deterministic_runtime" : normalizedInput === "canvas_hash" || normalizedInput === "capture_canvas_hash" || normalizedInput === "capture_canvas_signature" || normalizedInput === "canvas_state_signature" ? "canvas_signature" : normalizedInput === "capture_screenshot" || normalizedInput === "save_screenshot" || normalizedInput === "setup_screenshot" ? "screenshot" : normalizedInput === "accept_dialog" || normalizedInput === "accept_dialogs" || normalizedInput === "confirm_dialog" || normalizedInput === "set_dialog_response" ? "dialog_response" : normalizedInput === "dismiss_dialog" || normalizedInput === "dismiss_dialogs" || normalizedInput === "cancel_dialog" ? "dialog_response" : normalizedInput === "window_call_until" || normalizedInput === "call_until" || normalizedInput === "window_call_repeat_until" || normalizedInput === "repeat_window_call_until" ? "window_call_until" : normalizedInput === "window_evaluate" || normalizedInput === "browser_eval" || normalizedInput === "browser_evaluate" || normalizedInput === "evaluate_script" || normalizedInput === "profile_script" ? "window_eval" : normalizedInput;
7837
7858
  if (RIDDLE_PROOF_PROFILE_SETUP_ACTION_TYPES.includes(normalized)) {
7838
7859
  return normalized;
7839
7860
  }
@@ -7915,8 +7936,8 @@ function normalizeSetupActionCoordinateMode(value, index) {
7915
7936
  }
7916
7937
  function normalizeSetupActionPointerType(value, type, index) {
7917
7938
  if (value === void 0 || value === null || value === "") return void 0;
7918
- if (type !== "drag") {
7919
- throw new Error(`target.setup_actions[${index}].pointer_type is only supported for drag actions.`);
7939
+ if (type !== "drag" && type !== "tap") {
7940
+ throw new Error(`target.setup_actions[${index}].pointer_type is only supported for drag/tap actions.`);
7920
7941
  }
7921
7942
  const normalized = String(value).trim().replace(/-/g, "_").toLowerCase();
7922
7943
  if (normalized === "mouse") return "mouse";
@@ -7995,11 +8016,11 @@ function normalizeSetupAction(input, index) {
7995
8016
  if (frameIndex !== void 0 && (!Number.isInteger(frameIndex) || frameIndex < 0)) {
7996
8017
  throw new Error(`target.setup_actions[${index}].frame_index must be a non-negative integer.`);
7997
8018
  }
7998
- 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) {
8019
+ if ((type === "click" || type === "tap" || 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) {
7999
8020
  throw new Error(`target.setup_actions[${index}] ${type} requires selector.`);
8000
8021
  }
8001
- 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"));
8002
- 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"));
8022
+ const fromX = type === "click" || type === "tap" ? numberValue(valueFromOwn(input, "from_x", "fromX", "x", "click_x", "clickX", "start_x", "startX", "x1")) : numberValue(valueFromOwn(input, "from_x", "fromX", "start_x", "startX", "x1"));
8023
+ const fromY = type === "click" || type === "tap" ? numberValue(valueFromOwn(input, "from_y", "fromY", "y", "click_y", "clickY", "start_y", "startY", "y1")) : numberValue(valueFromOwn(input, "from_y", "fromY", "start_y", "startY", "y1"));
8003
8024
  const toX = numberValue(valueFromOwn(input, "to_x", "toX", "end_x", "endX", "x2"));
8004
8025
  const toY = numberValue(valueFromOwn(input, "to_y", "toY", "end_y", "endY", "y2"));
8005
8026
  const coordinateMode = normalizeSetupActionCoordinateMode(valueFromOwn(input, "coordinate_mode", "coordinateMode", "coords", "units"), index);
@@ -8019,6 +8040,21 @@ function normalizeSetupAction(input, index) {
8019
8040
  }
8020
8041
  }
8021
8042
  }
8043
+ if (type === "tap") {
8044
+ const hasTapCoordinate = fromX !== void 0 || fromY !== void 0;
8045
+ if (hasTapCoordinate && (fromX === void 0 || fromY === void 0)) {
8046
+ throw new Error(`target.setup_actions[${index}] tap coordinates require both x and y.`);
8047
+ }
8048
+ if (hasTapCoordinate && fromX !== void 0 && fromY !== void 0) {
8049
+ const tapCoordinates = [fromX, fromY];
8050
+ if (coordinateMode === "ratio" && tapCoordinates.some((value2) => value2 < 0 || value2 > 1)) {
8051
+ throw new Error(`target.setup_actions[${index}] tap ratio coordinates must be between 0 and 1.`);
8052
+ }
8053
+ if ((coordinateMode === void 0 || coordinateMode === "pixels") && tapCoordinates.some((value2) => value2 < 0)) {
8054
+ throw new Error(`target.setup_actions[${index}] tap pixel coordinates must be non-negative.`);
8055
+ }
8056
+ }
8057
+ }
8022
8058
  if (type === "drag") {
8023
8059
  if (fromX === void 0 || fromY === void 0 || toX === void 0 || toY === void 0) {
8024
8060
  throw new Error(`target.setup_actions[${index}] drag requires from_x, from_y, to_x, and to_y.`);
@@ -11314,6 +11350,23 @@ function profileSetupDragReceipts(results) {
11314
11350
  reason: result.reason || result.error || null,
11315
11351
  }));
11316
11352
  }
11353
+ function profileSetupTapReceipts(results) {
11354
+ return (results || [])
11355
+ .filter((result) => result && profileSetupResultAction(result) === "tap")
11356
+ .map((result) => ({
11357
+ ordinal: result.ordinal ?? null,
11358
+ ok: result.ok !== false,
11359
+ selector: result.selector ?? null,
11360
+ frame_selector: result.frame_selector ?? null,
11361
+ pointer_type: result.pointer_type ?? null,
11362
+ input_dispatch: result.input_dispatch ?? null,
11363
+ coordinate_mode: result.coordinate_mode ?? null,
11364
+ x: result.x ?? null,
11365
+ y: result.y ?? null,
11366
+ duration_ms: result.duration_ms ?? null,
11367
+ reason: result.reason || result.error || null,
11368
+ }));
11369
+ }
11317
11370
  function profileSetupCanvasSignatureReceipts(results) {
11318
11371
  return (results || [])
11319
11372
  .filter((result) => result && profileSetupResultAction(result) === "canvas_signature")
@@ -11500,6 +11553,8 @@ function profileSetupSummary(viewports, actionCount, expectedActionCountsByViewp
11500
11553
  const sampledRangeValueReceipts = sampleProfileSetupSummaryItems(rangeValueReceipts, 8);
11501
11554
  const dragReceipts = profileSetupDragReceipts(results);
11502
11555
  const sampledDragReceipts = sampleProfileSetupSummaryItems(dragReceipts, 8);
11556
+ const tapReceipts = profileSetupTapReceipts(results);
11557
+ const sampledTapReceipts = sampleProfileSetupSummaryItems(tapReceipts, 8);
11503
11558
  const canvasSignatureReceipts = profileSetupCanvasSignatureReceipts(results);
11504
11559
  const sampledCanvasSignatureReceipts = sampleProfileSetupSummaryItems(canvasSignatureReceipts, 8);
11505
11560
  const clickedItems = results
@@ -11574,6 +11629,9 @@ function profileSetupSummary(viewports, actionCount, expectedActionCountsByViewp
11574
11629
  drag_total: dragReceipts.length,
11575
11630
  drag_truncated: dragReceipts.length > sampledDragReceipts.length,
11576
11631
  drag: sampledDragReceipts,
11632
+ tap_total: tapReceipts.length,
11633
+ tap_truncated: tapReceipts.length > sampledTapReceipts.length,
11634
+ tap: sampledTapReceipts,
11577
11635
  canvas_signature_total: canvasSignatureReceipts.length,
11578
11636
  canvas_signature_truncated: canvasSignatureReceipts.length > sampledCanvasSignatureReceipts.length,
11579
11637
  canvas_signature: sampledCanvasSignatureReceipts,
@@ -12998,6 +13056,96 @@ async function executeSetupAction(action, ordinal, viewport) {
12998
13056
  await waitForAnyVisibleSelector(scope.context, action.selector, timeout);
12999
13057
  return { ...base, ...setupScopeEvidence(scope), ok: true, timeout_ms: timeout };
13000
13058
  }
13059
+ if (type === "tap") {
13060
+ const scope = await setupActionScope(action, timeout);
13061
+ if (!scope.ok) return setupScopeFailure(base, scope);
13062
+ const locator = scope.context.locator(action.selector);
13063
+ const count = await locator.count();
13064
+ if (!count) return { ...base, ...setupScopeEvidence(scope), reason: "selector_not_found", count };
13065
+ const targetIndex = Number.isInteger(action.index) ? action.index : 0;
13066
+ if (targetIndex < 0 || targetIndex >= count) return { ...base, ...setupScopeEvidence(scope), reason: "index_out_of_range", count, target_index: targetIndex };
13067
+ const target = locator.nth(targetIndex);
13068
+ await target.waitFor({ state: "visible", timeout });
13069
+ const box = await target.boundingBox();
13070
+ if (!box) return { ...base, ...setupScopeEvidence(scope), reason: "bounding_box_unavailable", count, target_index: targetIndex };
13071
+ const fromX = setupFiniteNumber(action.from_x ?? action.fromX ?? action.x ?? action.click_x ?? action.clickX);
13072
+ const fromY = setupFiniteNumber(action.from_y ?? action.fromY ?? action.y ?? action.click_y ?? action.clickY);
13073
+ const hasTapPosition = fromX !== undefined || fromY !== undefined;
13074
+ if (hasTapPosition && (fromX === undefined || fromY === undefined)) return { ...base, ...setupScopeEvidence(scope), reason: "missing_tap_coordinates", count, target_index: targetIndex };
13075
+ const mode = String(action.coordinate_mode || action.coordinateMode || (hasTapPosition ? "pixels" : "ratio")).trim();
13076
+ if (hasTapPosition && mode === "ratio" && [fromX, fromY].some((value) => value < 0 || value > 1)) return { ...base, ...setupScopeEvidence(scope), reason: "invalid_ratio_coordinates", count, target_index: targetIndex };
13077
+ if (hasTapPosition && mode !== "ratio" && [fromX, fromY].some((value) => value < 0)) return { ...base, ...setupScopeEvidence(scope), reason: "invalid_pixel_coordinates", count, target_index: targetIndex };
13078
+ const coordinate = (value, size) => mode === "ratio" ? value * size : value;
13079
+ const localX = hasTapPosition && fromX !== undefined ? fromX : 0.5;
13080
+ const localY = hasTapPosition && fromY !== undefined ? fromY : 0.5;
13081
+ const point = {
13082
+ x: box.x + coordinate(localX, box.width),
13083
+ y: box.y + coordinate(localY, box.height),
13084
+ };
13085
+ const durationMs = setupNumber(action.duration_ms ?? action.durationMs, 0);
13086
+ const pointerType = String(action.pointer_type || action.pointerType || "touch").trim().toLowerCase();
13087
+ if (pointerType === "touch" || pointerType === "pen") {
13088
+ const client = await page.context().newCDPSession(page);
13089
+ try {
13090
+ if (pointerType === "touch") {
13091
+ const touchPoint = {
13092
+ x: point.x,
13093
+ y: point.y,
13094
+ radiusX: 1,
13095
+ radiusY: 1,
13096
+ force: 1,
13097
+ id: 11,
13098
+ };
13099
+ await client.send("Input.dispatchTouchEvent", {
13100
+ type: "touchStart",
13101
+ touchPoints: [touchPoint],
13102
+ });
13103
+ if (durationMs) await page.waitForTimeout(durationMs);
13104
+ await client.send("Input.dispatchTouchEvent", {
13105
+ type: "touchEnd",
13106
+ touchPoints: [],
13107
+ });
13108
+ } else {
13109
+ await client.send("Input.dispatchMouseEvent", {
13110
+ type: "mousePressed",
13111
+ x: point.x,
13112
+ y: point.y,
13113
+ button: "left",
13114
+ buttons: 1,
13115
+ clickCount: 1,
13116
+ pointerType: "pen",
13117
+ });
13118
+ if (durationMs) await page.waitForTimeout(durationMs);
13119
+ await client.send("Input.dispatchMouseEvent", {
13120
+ type: "mouseReleased",
13121
+ x: point.x,
13122
+ y: point.y,
13123
+ button: "left",
13124
+ buttons: 0,
13125
+ clickCount: 1,
13126
+ pointerType: "pen",
13127
+ });
13128
+ }
13129
+ } finally {
13130
+ await client.detach().catch(() => {});
13131
+ }
13132
+ } else {
13133
+ await page.mouse.click(point.x, point.y);
13134
+ }
13135
+ return {
13136
+ ...base,
13137
+ ...setupScopeEvidence(scope),
13138
+ ok: true,
13139
+ count,
13140
+ target_index: targetIndex,
13141
+ coordinate_mode: hasTapPosition ? mode : undefined,
13142
+ x: hasTapPosition ? fromX : undefined,
13143
+ y: hasTapPosition ? fromY : undefined,
13144
+ pointer_type: pointerType,
13145
+ input_dispatch: pointerType === "touch" || pointerType === "pen" ? "cdp" : "playwright_mouse",
13146
+ duration_ms: durationMs || undefined,
13147
+ };
13148
+ }
13001
13149
  if (type === "drag") {
13002
13150
  const scope = await setupActionScope(action, timeout);
13003
13151
  if (!scope.ok) return setupScopeFailure(base, scope);
@@ -16279,6 +16427,7 @@ function profileSetupSummaryMarkdown(result) {
16279
16427
  const windowCallUntilCallTotal = viewports.reduce((sum, viewport) => sum + (cliFiniteNumber(viewport.window_call_until_call_total) || 0), 0);
16280
16428
  const rangeValueTotal = viewports.reduce((sum, viewport) => sum + (cliFiniteNumber(viewport.set_range_value_total) || 0), 0);
16281
16429
  const dragTotal = viewports.reduce((sum, viewport) => sum + (cliFiniteNumber(viewport.drag_total) || 0), 0);
16430
+ const tapTotal = viewports.reduce((sum, viewport) => sum + (cliFiniteNumber(viewport.tap_total) || 0), 0);
16282
16431
  const canvasSignatureTotal = viewports.reduce((sum, viewport) => sum + (cliFiniteNumber(viewport.canvas_signature_total) || 0), 0);
16283
16432
  const failedTotal = viewports.reduce((sum, viewport) => sum + (Array.isArray(viewport.failed) ? viewport.failed.length : 0), 0);
16284
16433
  const lines = [
@@ -16311,6 +16460,9 @@ function profileSetupSummaryMarkdown(result) {
16311
16460
  if (dragTotal) {
16312
16461
  lines.push(`- drag: ${dragTotal} action(s)`);
16313
16462
  }
16463
+ if (tapTotal) {
16464
+ lines.push(`- tap: ${tapTotal} action(s)`);
16465
+ }
16314
16466
  if (canvasSignatureTotal) {
16315
16467
  lines.push(`- canvas_signature: ${canvasSignatureTotal} action(s)`);
16316
16468
  }
@@ -16333,9 +16485,10 @@ function profileSetupSummaryMarkdown(result) {
16333
16485
  const windowCallUntilCalls = cliFiniteNumber(viewport.window_call_until_call_total) || 0;
16334
16486
  const rangeValueActions = cliFiniteNumber(viewport.set_range_value_total) || 0;
16335
16487
  const dragActions = cliFiniteNumber(viewport.drag_total) || 0;
16488
+ const tapActions = cliFiniteNumber(viewport.tap_total) || 0;
16336
16489
  const canvasSignatureActions = cliFiniteNumber(viewport.canvas_signature_total) || 0;
16337
16490
  const observedPath = cliString(viewport.observed_path);
16338
- lines.push(`- ${name}: ${ok}, ${resultCount} result(s), ${screenshotCount} setup screenshot(s), ${clicked} click(s)${clickSequenceCount ? `, ${clickSequenceCount} click sequence(s)` : ""}${clickCountActions ? `, ${clickCountActions} click_count action(s)` : ""}${rangeValueActions ? `, ${rangeValueActions} set_range_value action(s)` : ""}${dragActions ? `, ${dragActions} drag action(s)` : ""}${canvasSignatureActions ? `, ${canvasSignatureActions} canvas_signature action(s)` : ""}${deterministicRuntimeActions ? `, ${deterministicRuntimeActions} deterministic_runtime action(s)` : ""}${windowCallActions ? `, ${windowCallActions} window_call action(s), ${windowCallStored} stored return(s), ${windowCallCaptured} captured return(s)` : ""}${windowEvalActions ? `, ${windowEvalActions} window_eval action(s), ${windowEvalStored} stored return(s), ${windowEvalCaptured} captured return(s)` : ""}${windowCallUntilActions ? `, ${windowCallUntilActions} window_call_until action(s), ${windowCallUntilCalls} call(s)` : ""}${observedPath ? `, path ${observedPath}` : ""}`);
16491
+ lines.push(`- ${name}: ${ok}, ${resultCount} result(s), ${screenshotCount} setup screenshot(s), ${clicked} click(s)${clickSequenceCount ? `, ${clickSequenceCount} click sequence(s)` : ""}${clickCountActions ? `, ${clickCountActions} click_count action(s)` : ""}${rangeValueActions ? `, ${rangeValueActions} set_range_value action(s)` : ""}${dragActions ? `, ${dragActions} drag action(s)` : ""}${tapActions ? `, ${tapActions} tap action(s)` : ""}${canvasSignatureActions ? `, ${canvasSignatureActions} canvas_signature action(s)` : ""}${deterministicRuntimeActions ? `, ${deterministicRuntimeActions} deterministic_runtime action(s)` : ""}${windowCallActions ? `, ${windowCallActions} window_call action(s), ${windowCallStored} stored return(s), ${windowCallCaptured} captured return(s)` : ""}${windowEvalActions ? `, ${windowEvalActions} window_eval action(s), ${windowEvalStored} stored return(s), ${windowEvalCaptured} captured return(s)` : ""}${windowCallUntilActions ? `, ${windowCallUntilActions} window_call_until action(s), ${windowCallUntilCalls} call(s)` : ""}${observedPath ? `, path ${observedPath}` : ""}`);
16339
16492
  }
16340
16493
  const clickSequenceGroups = viewports.map((viewport) => {
16341
16494
  const name = cliString(viewport.name) || "viewport";
@@ -16381,6 +16534,27 @@ function profileSetupSummaryMarkdown(result) {
16381
16534
  lines.push(`- ${name} drag: ${ok}, ${markdownInlineCode(selector)}${pointerType ? ` ${markdownInlineCode(pointerType)}` : ""}${inputDispatch ? ` via ${markdownInlineCode(inputDispatch)}` : ""}${coordinateText}${steps === void 0 ? "" : `, steps ${steps}`}${durationMs === void 0 ? "" : `, duration ${durationMs}ms`}${reason ? `, reason ${markdownInlineCode(reason, 100)}` : ""}`);
16382
16535
  }
16383
16536
  if (dragDetails.length > sampledDragDetails.length) lines.push(`- ${dragDetails.length - sampledDragDetails.length} additional drag receipt(s) omitted.`);
16537
+ const tapGroups = viewports.map((viewport) => {
16538
+ const name = cliString(viewport.name) || "viewport";
16539
+ const receipts = Array.isArray(viewport.tap) ? viewport.tap.map(cliRecord).filter((item) => Boolean(item)) : [];
16540
+ return receipts.map((receipt) => ({ name, receipt }));
16541
+ });
16542
+ const tapDetails = tapGroups.flat();
16543
+ const sampledTapDetails = balancedSetupReceiptDetails(tapGroups, 12);
16544
+ for (const { name, receipt } of sampledTapDetails) {
16545
+ const selector = cliString(receipt.selector) || "target";
16546
+ const pointerType = cliString(receipt.pointer_type);
16547
+ const inputDispatch = cliString(receipt.input_dispatch);
16548
+ const coordinateMode = cliString(receipt.coordinate_mode);
16549
+ const x = cliValueLabel(receipt.x);
16550
+ const y = cliValueLabel(receipt.y);
16551
+ const durationMs = cliFiniteNumber(receipt.duration_ms);
16552
+ const ok = receipt.ok === false ? "failed" : "ok";
16553
+ const reason = cliString(receipt.reason);
16554
+ const coordinateText = x && y ? `, ${coordinateMode ? `${coordinateMode} ` : ""}${markdownInlineCode(`${x},${y}`)}` : "";
16555
+ lines.push(`- ${name} tap: ${ok}, ${markdownInlineCode(selector)}${pointerType ? ` ${markdownInlineCode(pointerType)}` : ""}${inputDispatch ? ` via ${markdownInlineCode(inputDispatch)}` : ""}${coordinateText}${durationMs === void 0 ? "" : `, duration ${durationMs}ms`}${reason ? `, reason ${markdownInlineCode(reason, 100)}` : ""}`);
16556
+ }
16557
+ if (tapDetails.length > sampledTapDetails.length) lines.push(`- ${tapDetails.length - sampledTapDetails.length} additional tap receipt(s) omitted.`);
16384
16558
  const canvasSignatureGroups = viewports.map((viewport) => {
16385
16559
  const name = cliString(viewport.name) || "viewport";
16386
16560
  const receipts = Array.isArray(viewport.canvas_signature) ? viewport.canvas_signature.map(cliRecord).filter((item) => Boolean(item)) : [];
package/dist/cli.js CHANGED
@@ -13,7 +13,7 @@ import {
13
13
  profileStatusExitCode,
14
14
  resolveRiddleProofProfileTargetUrl,
15
15
  resolveRiddleProofProfileTimeoutSec
16
- } from "./chunk-JIAMASZX.js";
16
+ } from "./chunk-RAEZDEAU.js";
17
17
  import {
18
18
  createRiddleApiClient,
19
19
  isTerminalRiddleJobStatus,
@@ -790,6 +790,7 @@ function profileSetupSummaryMarkdown(result) {
790
790
  const windowCallUntilCallTotal = viewports.reduce((sum, viewport) => sum + (cliFiniteNumber(viewport.window_call_until_call_total) || 0), 0);
791
791
  const rangeValueTotal = viewports.reduce((sum, viewport) => sum + (cliFiniteNumber(viewport.set_range_value_total) || 0), 0);
792
792
  const dragTotal = viewports.reduce((sum, viewport) => sum + (cliFiniteNumber(viewport.drag_total) || 0), 0);
793
+ const tapTotal = viewports.reduce((sum, viewport) => sum + (cliFiniteNumber(viewport.tap_total) || 0), 0);
793
794
  const canvasSignatureTotal = viewports.reduce((sum, viewport) => sum + (cliFiniteNumber(viewport.canvas_signature_total) || 0), 0);
794
795
  const failedTotal = viewports.reduce((sum, viewport) => sum + (Array.isArray(viewport.failed) ? viewport.failed.length : 0), 0);
795
796
  const lines = [
@@ -822,6 +823,9 @@ function profileSetupSummaryMarkdown(result) {
822
823
  if (dragTotal) {
823
824
  lines.push(`- drag: ${dragTotal} action(s)`);
824
825
  }
826
+ if (tapTotal) {
827
+ lines.push(`- tap: ${tapTotal} action(s)`);
828
+ }
825
829
  if (canvasSignatureTotal) {
826
830
  lines.push(`- canvas_signature: ${canvasSignatureTotal} action(s)`);
827
831
  }
@@ -844,9 +848,10 @@ function profileSetupSummaryMarkdown(result) {
844
848
  const windowCallUntilCalls = cliFiniteNumber(viewport.window_call_until_call_total) || 0;
845
849
  const rangeValueActions = cliFiniteNumber(viewport.set_range_value_total) || 0;
846
850
  const dragActions = cliFiniteNumber(viewport.drag_total) || 0;
851
+ const tapActions = cliFiniteNumber(viewport.tap_total) || 0;
847
852
  const canvasSignatureActions = cliFiniteNumber(viewport.canvas_signature_total) || 0;
848
853
  const observedPath = cliString(viewport.observed_path);
849
- lines.push(`- ${name}: ${ok}, ${resultCount} result(s), ${screenshotCount} setup screenshot(s), ${clicked} click(s)${clickSequenceCount ? `, ${clickSequenceCount} click sequence(s)` : ""}${clickCountActions ? `, ${clickCountActions} click_count action(s)` : ""}${rangeValueActions ? `, ${rangeValueActions} set_range_value action(s)` : ""}${dragActions ? `, ${dragActions} drag action(s)` : ""}${canvasSignatureActions ? `, ${canvasSignatureActions} canvas_signature action(s)` : ""}${deterministicRuntimeActions ? `, ${deterministicRuntimeActions} deterministic_runtime action(s)` : ""}${windowCallActions ? `, ${windowCallActions} window_call action(s), ${windowCallStored} stored return(s), ${windowCallCaptured} captured return(s)` : ""}${windowEvalActions ? `, ${windowEvalActions} window_eval action(s), ${windowEvalStored} stored return(s), ${windowEvalCaptured} captured return(s)` : ""}${windowCallUntilActions ? `, ${windowCallUntilActions} window_call_until action(s), ${windowCallUntilCalls} call(s)` : ""}${observedPath ? `, path ${observedPath}` : ""}`);
854
+ lines.push(`- ${name}: ${ok}, ${resultCount} result(s), ${screenshotCount} setup screenshot(s), ${clicked} click(s)${clickSequenceCount ? `, ${clickSequenceCount} click sequence(s)` : ""}${clickCountActions ? `, ${clickCountActions} click_count action(s)` : ""}${rangeValueActions ? `, ${rangeValueActions} set_range_value action(s)` : ""}${dragActions ? `, ${dragActions} drag action(s)` : ""}${tapActions ? `, ${tapActions} tap action(s)` : ""}${canvasSignatureActions ? `, ${canvasSignatureActions} canvas_signature action(s)` : ""}${deterministicRuntimeActions ? `, ${deterministicRuntimeActions} deterministic_runtime action(s)` : ""}${windowCallActions ? `, ${windowCallActions} window_call action(s), ${windowCallStored} stored return(s), ${windowCallCaptured} captured return(s)` : ""}${windowEvalActions ? `, ${windowEvalActions} window_eval action(s), ${windowEvalStored} stored return(s), ${windowEvalCaptured} captured return(s)` : ""}${windowCallUntilActions ? `, ${windowCallUntilActions} window_call_until action(s), ${windowCallUntilCalls} call(s)` : ""}${observedPath ? `, path ${observedPath}` : ""}`);
850
855
  }
851
856
  const clickSequenceGroups = viewports.map((viewport) => {
852
857
  const name = cliString(viewport.name) || "viewport";
@@ -892,6 +897,27 @@ function profileSetupSummaryMarkdown(result) {
892
897
  lines.push(`- ${name} drag: ${ok}, ${markdownInlineCode(selector)}${pointerType ? ` ${markdownInlineCode(pointerType)}` : ""}${inputDispatch ? ` via ${markdownInlineCode(inputDispatch)}` : ""}${coordinateText}${steps === void 0 ? "" : `, steps ${steps}`}${durationMs === void 0 ? "" : `, duration ${durationMs}ms`}${reason ? `, reason ${markdownInlineCode(reason, 100)}` : ""}`);
893
898
  }
894
899
  if (dragDetails.length > sampledDragDetails.length) lines.push(`- ${dragDetails.length - sampledDragDetails.length} additional drag receipt(s) omitted.`);
900
+ const tapGroups = viewports.map((viewport) => {
901
+ const name = cliString(viewport.name) || "viewport";
902
+ const receipts = Array.isArray(viewport.tap) ? viewport.tap.map(cliRecord).filter((item) => Boolean(item)) : [];
903
+ return receipts.map((receipt) => ({ name, receipt }));
904
+ });
905
+ const tapDetails = tapGroups.flat();
906
+ const sampledTapDetails = balancedSetupReceiptDetails(tapGroups, 12);
907
+ for (const { name, receipt } of sampledTapDetails) {
908
+ const selector = cliString(receipt.selector) || "target";
909
+ const pointerType = cliString(receipt.pointer_type);
910
+ const inputDispatch = cliString(receipt.input_dispatch);
911
+ const coordinateMode = cliString(receipt.coordinate_mode);
912
+ const x = cliValueLabel(receipt.x);
913
+ const y = cliValueLabel(receipt.y);
914
+ const durationMs = cliFiniteNumber(receipt.duration_ms);
915
+ const ok = receipt.ok === false ? "failed" : "ok";
916
+ const reason = cliString(receipt.reason);
917
+ const coordinateText = x && y ? `, ${coordinateMode ? `${coordinateMode} ` : ""}${markdownInlineCode(`${x},${y}`)}` : "";
918
+ lines.push(`- ${name} tap: ${ok}, ${markdownInlineCode(selector)}${pointerType ? ` ${markdownInlineCode(pointerType)}` : ""}${inputDispatch ? ` via ${markdownInlineCode(inputDispatch)}` : ""}${coordinateText}${durationMs === void 0 ? "" : `, duration ${durationMs}ms`}${reason ? `, reason ${markdownInlineCode(reason, 100)}` : ""}`);
919
+ }
920
+ if (tapDetails.length > sampledTapDetails.length) lines.push(`- ${tapDetails.length - sampledTapDetails.length} additional tap receipt(s) omitted.`);
895
921
  const canvasSignatureGroups = viewports.map((viewport) => {
896
922
  const name = cliString(viewport.name) || "viewport";
897
923
  const receipts = Array.isArray(viewport.canvas_signature) ? viewport.canvas_signature.map(cliRecord).filter((item) => Boolean(item)) : [];
package/dist/index.cjs CHANGED
@@ -8777,6 +8777,7 @@ var RIDDLE_PROOF_PROFILE_CHECK_TYPES = [
8777
8777
  ];
8778
8778
  var RIDDLE_PROOF_PROFILE_SETUP_ACTION_TYPES = [
8779
8779
  "click",
8780
+ "tap",
8780
8781
  "drag",
8781
8782
  "press",
8782
8783
  "fill",
@@ -9328,6 +9329,21 @@ function profileSetupDragReceipts(results) {
9328
9329
  reason: result.reason ?? result.error ?? null
9329
9330
  }));
9330
9331
  }
9332
+ function profileSetupTapReceipts(results) {
9333
+ return results.filter((result) => profileSetupResultAction(result) === "tap").map((result) => ({
9334
+ ordinal: result.ordinal ?? null,
9335
+ ok: result.ok !== false,
9336
+ selector: result.selector ?? null,
9337
+ frame_selector: result.frame_selector ?? null,
9338
+ pointer_type: result.pointer_type ?? null,
9339
+ input_dispatch: result.input_dispatch ?? null,
9340
+ coordinate_mode: result.coordinate_mode ?? null,
9341
+ x: result.x ?? null,
9342
+ y: result.y ?? null,
9343
+ duration_ms: result.duration_ms ?? null,
9344
+ reason: result.reason ?? result.error ?? null
9345
+ }));
9346
+ }
9331
9347
  function profileSetupCanvasSignatureReceipts(results) {
9332
9348
  return results.filter((result) => profileSetupResultAction(result) === "canvas_signature").map((result) => ({
9333
9349
  ordinal: result.ordinal ?? null,
@@ -9489,6 +9505,8 @@ function profileSetupSummary(viewports, actionCount, expectedActionCountByViewpo
9489
9505
  const sampledRangeValueReceipts = sampleProfileSetupSummaryItems(rangeValueReceipts, 8);
9490
9506
  const dragReceipts = profileSetupDragReceipts(results);
9491
9507
  const sampledDragReceipts = sampleProfileSetupSummaryItems(dragReceipts, 8);
9508
+ const tapReceipts = profileSetupTapReceipts(results);
9509
+ const sampledTapReceipts = sampleProfileSetupSummaryItems(tapReceipts, 8);
9492
9510
  const canvasSignatureReceipts = profileSetupCanvasSignatureReceipts(results);
9493
9511
  const sampledCanvasSignatureReceipts = sampleProfileSetupSummaryItems(canvasSignatureReceipts, 8);
9494
9512
  const clickedItems = results.filter((result) => profileSetupResultAction(result) === "click" && result.ok !== false).map((result) => {
@@ -9553,6 +9571,9 @@ function profileSetupSummary(viewports, actionCount, expectedActionCountByViewpo
9553
9571
  drag_total: dragReceipts.length,
9554
9572
  drag_truncated: dragReceipts.length > sampledDragReceipts.length,
9555
9573
  drag: sampledDragReceipts,
9574
+ tap_total: tapReceipts.length,
9575
+ tap_truncated: tapReceipts.length > sampledTapReceipts.length,
9576
+ tap: sampledTapReceipts,
9556
9577
  canvas_signature_total: canvasSignatureReceipts.length,
9557
9578
  canvas_signature_truncated: canvasSignatureReceipts.length > sampledCanvasSignatureReceipts.length,
9558
9579
  canvas_signature: sampledCanvasSignatureReceipts,
@@ -9609,7 +9630,7 @@ function isSupportedCheckType(value) {
9609
9630
  }
9610
9631
  function normalizeSetupActionType(value, index) {
9611
9632
  const normalizedInput = String(value || "").trim().replace(/-/g, "_");
9612
- const normalized = normalizedInput === "clear_browser_storage" ? "clear_storage" : normalizedInput === "reset_console" || normalizedInput === "clear_browser_console" || normalizedInput === "reset_browser_console" ? "clear_console" : normalizedInput === "pointer_drag" || normalizedInput === "mouse_drag" || normalizedInput === "drag_to" ? "drag" : normalizedInput === "keyboard_press" || normalizedInput === "key_press" ? "press" : normalizedInput === "set_slider_value" || normalizedInput === "slider_value" || normalizedInput === "set_slider" || normalizedInput === "set_range" || normalizedInput === "range_value" || normalizedInput === "range_input" || normalizedInput === "set_range_input" ? "set_range_value" : normalizedInput === "deterministic_runtime" || normalizedInput === "mock_runtime" || normalizedInput === "mock_random" || normalizedInput === "mock_random_queue" || normalizedInput === "seed_random_queue" || normalizedInput === "set_random_queue" || normalizedInput === "mock_clock" || normalizedInput === "set_mock_clock" || normalizedInput === "set_runtime_determinism" || normalizedInput === "runtime_determinism" ? "deterministic_runtime" : normalizedInput === "canvas_hash" || normalizedInput === "capture_canvas_hash" || normalizedInput === "capture_canvas_signature" || normalizedInput === "canvas_state_signature" ? "canvas_signature" : normalizedInput === "capture_screenshot" || normalizedInput === "save_screenshot" || normalizedInput === "setup_screenshot" ? "screenshot" : normalizedInput === "accept_dialog" || normalizedInput === "accept_dialogs" || normalizedInput === "confirm_dialog" || normalizedInput === "set_dialog_response" ? "dialog_response" : normalizedInput === "dismiss_dialog" || normalizedInput === "dismiss_dialogs" || normalizedInput === "cancel_dialog" ? "dialog_response" : normalizedInput === "window_call_until" || normalizedInput === "call_until" || normalizedInput === "window_call_repeat_until" || normalizedInput === "repeat_window_call_until" ? "window_call_until" : normalizedInput === "window_evaluate" || normalizedInput === "browser_eval" || normalizedInput === "browser_evaluate" || normalizedInput === "evaluate_script" || normalizedInput === "profile_script" ? "window_eval" : normalizedInput;
9633
+ const normalized = normalizedInput === "clear_browser_storage" ? "clear_storage" : normalizedInput === "reset_console" || normalizedInput === "clear_browser_console" || normalizedInput === "reset_browser_console" ? "clear_console" : normalizedInput === "pointer_drag" || normalizedInput === "mouse_drag" || normalizedInput === "drag_to" ? "drag" : normalizedInput === "pointer_tap" || normalizedInput === "touch_tap" || normalizedInput === "canvas_tap" ? "tap" : normalizedInput === "keyboard_press" || normalizedInput === "key_press" ? "press" : normalizedInput === "set_slider_value" || normalizedInput === "slider_value" || normalizedInput === "set_slider" || normalizedInput === "set_range" || normalizedInput === "range_value" || normalizedInput === "range_input" || normalizedInput === "set_range_input" ? "set_range_value" : normalizedInput === "deterministic_runtime" || normalizedInput === "mock_runtime" || normalizedInput === "mock_random" || normalizedInput === "mock_random_queue" || normalizedInput === "seed_random_queue" || normalizedInput === "set_random_queue" || normalizedInput === "mock_clock" || normalizedInput === "set_mock_clock" || normalizedInput === "set_runtime_determinism" || normalizedInput === "runtime_determinism" ? "deterministic_runtime" : normalizedInput === "canvas_hash" || normalizedInput === "capture_canvas_hash" || normalizedInput === "capture_canvas_signature" || normalizedInput === "canvas_state_signature" ? "canvas_signature" : normalizedInput === "capture_screenshot" || normalizedInput === "save_screenshot" || normalizedInput === "setup_screenshot" ? "screenshot" : normalizedInput === "accept_dialog" || normalizedInput === "accept_dialogs" || normalizedInput === "confirm_dialog" || normalizedInput === "set_dialog_response" ? "dialog_response" : normalizedInput === "dismiss_dialog" || normalizedInput === "dismiss_dialogs" || normalizedInput === "cancel_dialog" ? "dialog_response" : normalizedInput === "window_call_until" || normalizedInput === "call_until" || normalizedInput === "window_call_repeat_until" || normalizedInput === "repeat_window_call_until" ? "window_call_until" : normalizedInput === "window_evaluate" || normalizedInput === "browser_eval" || normalizedInput === "browser_evaluate" || normalizedInput === "evaluate_script" || normalizedInput === "profile_script" ? "window_eval" : normalizedInput;
9613
9634
  if (RIDDLE_PROOF_PROFILE_SETUP_ACTION_TYPES.includes(normalized)) {
9614
9635
  return normalized;
9615
9636
  }
@@ -9691,8 +9712,8 @@ function normalizeSetupActionCoordinateMode(value, index) {
9691
9712
  }
9692
9713
  function normalizeSetupActionPointerType(value, type, index) {
9693
9714
  if (value === void 0 || value === null || value === "") return void 0;
9694
- if (type !== "drag") {
9695
- throw new Error(`target.setup_actions[${index}].pointer_type is only supported for drag actions.`);
9715
+ if (type !== "drag" && type !== "tap") {
9716
+ throw new Error(`target.setup_actions[${index}].pointer_type is only supported for drag/tap actions.`);
9696
9717
  }
9697
9718
  const normalized = String(value).trim().replace(/-/g, "_").toLowerCase();
9698
9719
  if (normalized === "mouse") return "mouse";
@@ -9771,11 +9792,11 @@ function normalizeSetupAction(input, index) {
9771
9792
  if (frameIndex !== void 0 && (!Number.isInteger(frameIndex) || frameIndex < 0)) {
9772
9793
  throw new Error(`target.setup_actions[${index}].frame_index must be a non-negative integer.`);
9773
9794
  }
9774
- 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) {
9795
+ if ((type === "click" || type === "tap" || 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) {
9775
9796
  throw new Error(`target.setup_actions[${index}] ${type} requires selector.`);
9776
9797
  }
9777
- 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"));
9778
- 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"));
9798
+ const fromX = type === "click" || type === "tap" ? numberValue3(valueFromOwn(input, "from_x", "fromX", "x", "click_x", "clickX", "start_x", "startX", "x1")) : numberValue3(valueFromOwn(input, "from_x", "fromX", "start_x", "startX", "x1"));
9799
+ const fromY = type === "click" || type === "tap" ? numberValue3(valueFromOwn(input, "from_y", "fromY", "y", "click_y", "clickY", "start_y", "startY", "y1")) : numberValue3(valueFromOwn(input, "from_y", "fromY", "start_y", "startY", "y1"));
9779
9800
  const toX = numberValue3(valueFromOwn(input, "to_x", "toX", "end_x", "endX", "x2"));
9780
9801
  const toY = numberValue3(valueFromOwn(input, "to_y", "toY", "end_y", "endY", "y2"));
9781
9802
  const coordinateMode = normalizeSetupActionCoordinateMode(valueFromOwn(input, "coordinate_mode", "coordinateMode", "coords", "units"), index);
@@ -9795,6 +9816,21 @@ function normalizeSetupAction(input, index) {
9795
9816
  }
9796
9817
  }
9797
9818
  }
9819
+ if (type === "tap") {
9820
+ const hasTapCoordinate = fromX !== void 0 || fromY !== void 0;
9821
+ if (hasTapCoordinate && (fromX === void 0 || fromY === void 0)) {
9822
+ throw new Error(`target.setup_actions[${index}] tap coordinates require both x and y.`);
9823
+ }
9824
+ if (hasTapCoordinate && fromX !== void 0 && fromY !== void 0) {
9825
+ const tapCoordinates = [fromX, fromY];
9826
+ if (coordinateMode === "ratio" && tapCoordinates.some((value2) => value2 < 0 || value2 > 1)) {
9827
+ throw new Error(`target.setup_actions[${index}] tap ratio coordinates must be between 0 and 1.`);
9828
+ }
9829
+ if ((coordinateMode === void 0 || coordinateMode === "pixels") && tapCoordinates.some((value2) => value2 < 0)) {
9830
+ throw new Error(`target.setup_actions[${index}] tap pixel coordinates must be non-negative.`);
9831
+ }
9832
+ }
9833
+ }
9798
9834
  if (type === "drag") {
9799
9835
  if (fromX === void 0 || fromY === void 0 || toX === void 0 || toY === void 0) {
9800
9836
  throw new Error(`target.setup_actions[${index}] drag requires from_x, from_y, to_x, and to_y.`);
@@ -13106,6 +13142,23 @@ function profileSetupDragReceipts(results) {
13106
13142
  reason: result.reason || result.error || null,
13107
13143
  }));
13108
13144
  }
13145
+ function profileSetupTapReceipts(results) {
13146
+ return (results || [])
13147
+ .filter((result) => result && profileSetupResultAction(result) === "tap")
13148
+ .map((result) => ({
13149
+ ordinal: result.ordinal ?? null,
13150
+ ok: result.ok !== false,
13151
+ selector: result.selector ?? null,
13152
+ frame_selector: result.frame_selector ?? null,
13153
+ pointer_type: result.pointer_type ?? null,
13154
+ input_dispatch: result.input_dispatch ?? null,
13155
+ coordinate_mode: result.coordinate_mode ?? null,
13156
+ x: result.x ?? null,
13157
+ y: result.y ?? null,
13158
+ duration_ms: result.duration_ms ?? null,
13159
+ reason: result.reason || result.error || null,
13160
+ }));
13161
+ }
13109
13162
  function profileSetupCanvasSignatureReceipts(results) {
13110
13163
  return (results || [])
13111
13164
  .filter((result) => result && profileSetupResultAction(result) === "canvas_signature")
@@ -13292,6 +13345,8 @@ function profileSetupSummary(viewports, actionCount, expectedActionCountsByViewp
13292
13345
  const sampledRangeValueReceipts = sampleProfileSetupSummaryItems(rangeValueReceipts, 8);
13293
13346
  const dragReceipts = profileSetupDragReceipts(results);
13294
13347
  const sampledDragReceipts = sampleProfileSetupSummaryItems(dragReceipts, 8);
13348
+ const tapReceipts = profileSetupTapReceipts(results);
13349
+ const sampledTapReceipts = sampleProfileSetupSummaryItems(tapReceipts, 8);
13295
13350
  const canvasSignatureReceipts = profileSetupCanvasSignatureReceipts(results);
13296
13351
  const sampledCanvasSignatureReceipts = sampleProfileSetupSummaryItems(canvasSignatureReceipts, 8);
13297
13352
  const clickedItems = results
@@ -13366,6 +13421,9 @@ function profileSetupSummary(viewports, actionCount, expectedActionCountsByViewp
13366
13421
  drag_total: dragReceipts.length,
13367
13422
  drag_truncated: dragReceipts.length > sampledDragReceipts.length,
13368
13423
  drag: sampledDragReceipts,
13424
+ tap_total: tapReceipts.length,
13425
+ tap_truncated: tapReceipts.length > sampledTapReceipts.length,
13426
+ tap: sampledTapReceipts,
13369
13427
  canvas_signature_total: canvasSignatureReceipts.length,
13370
13428
  canvas_signature_truncated: canvasSignatureReceipts.length > sampledCanvasSignatureReceipts.length,
13371
13429
  canvas_signature: sampledCanvasSignatureReceipts,
@@ -14790,6 +14848,96 @@ async function executeSetupAction(action, ordinal, viewport) {
14790
14848
  await waitForAnyVisibleSelector(scope.context, action.selector, timeout);
14791
14849
  return { ...base, ...setupScopeEvidence(scope), ok: true, timeout_ms: timeout };
14792
14850
  }
14851
+ if (type === "tap") {
14852
+ const scope = await setupActionScope(action, timeout);
14853
+ if (!scope.ok) return setupScopeFailure(base, scope);
14854
+ const locator = scope.context.locator(action.selector);
14855
+ const count = await locator.count();
14856
+ if (!count) return { ...base, ...setupScopeEvidence(scope), reason: "selector_not_found", count };
14857
+ const targetIndex = Number.isInteger(action.index) ? action.index : 0;
14858
+ if (targetIndex < 0 || targetIndex >= count) return { ...base, ...setupScopeEvidence(scope), reason: "index_out_of_range", count, target_index: targetIndex };
14859
+ const target = locator.nth(targetIndex);
14860
+ await target.waitFor({ state: "visible", timeout });
14861
+ const box = await target.boundingBox();
14862
+ if (!box) return { ...base, ...setupScopeEvidence(scope), reason: "bounding_box_unavailable", count, target_index: targetIndex };
14863
+ const fromX = setupFiniteNumber(action.from_x ?? action.fromX ?? action.x ?? action.click_x ?? action.clickX);
14864
+ const fromY = setupFiniteNumber(action.from_y ?? action.fromY ?? action.y ?? action.click_y ?? action.clickY);
14865
+ const hasTapPosition = fromX !== undefined || fromY !== undefined;
14866
+ if (hasTapPosition && (fromX === undefined || fromY === undefined)) return { ...base, ...setupScopeEvidence(scope), reason: "missing_tap_coordinates", count, target_index: targetIndex };
14867
+ const mode = String(action.coordinate_mode || action.coordinateMode || (hasTapPosition ? "pixels" : "ratio")).trim();
14868
+ if (hasTapPosition && mode === "ratio" && [fromX, fromY].some((value) => value < 0 || value > 1)) return { ...base, ...setupScopeEvidence(scope), reason: "invalid_ratio_coordinates", count, target_index: targetIndex };
14869
+ if (hasTapPosition && mode !== "ratio" && [fromX, fromY].some((value) => value < 0)) return { ...base, ...setupScopeEvidence(scope), reason: "invalid_pixel_coordinates", count, target_index: targetIndex };
14870
+ const coordinate = (value, size) => mode === "ratio" ? value * size : value;
14871
+ const localX = hasTapPosition && fromX !== undefined ? fromX : 0.5;
14872
+ const localY = hasTapPosition && fromY !== undefined ? fromY : 0.5;
14873
+ const point = {
14874
+ x: box.x + coordinate(localX, box.width),
14875
+ y: box.y + coordinate(localY, box.height),
14876
+ };
14877
+ const durationMs = setupNumber(action.duration_ms ?? action.durationMs, 0);
14878
+ const pointerType = String(action.pointer_type || action.pointerType || "touch").trim().toLowerCase();
14879
+ if (pointerType === "touch" || pointerType === "pen") {
14880
+ const client = await page.context().newCDPSession(page);
14881
+ try {
14882
+ if (pointerType === "touch") {
14883
+ const touchPoint = {
14884
+ x: point.x,
14885
+ y: point.y,
14886
+ radiusX: 1,
14887
+ radiusY: 1,
14888
+ force: 1,
14889
+ id: 11,
14890
+ };
14891
+ await client.send("Input.dispatchTouchEvent", {
14892
+ type: "touchStart",
14893
+ touchPoints: [touchPoint],
14894
+ });
14895
+ if (durationMs) await page.waitForTimeout(durationMs);
14896
+ await client.send("Input.dispatchTouchEvent", {
14897
+ type: "touchEnd",
14898
+ touchPoints: [],
14899
+ });
14900
+ } else {
14901
+ await client.send("Input.dispatchMouseEvent", {
14902
+ type: "mousePressed",
14903
+ x: point.x,
14904
+ y: point.y,
14905
+ button: "left",
14906
+ buttons: 1,
14907
+ clickCount: 1,
14908
+ pointerType: "pen",
14909
+ });
14910
+ if (durationMs) await page.waitForTimeout(durationMs);
14911
+ await client.send("Input.dispatchMouseEvent", {
14912
+ type: "mouseReleased",
14913
+ x: point.x,
14914
+ y: point.y,
14915
+ button: "left",
14916
+ buttons: 0,
14917
+ clickCount: 1,
14918
+ pointerType: "pen",
14919
+ });
14920
+ }
14921
+ } finally {
14922
+ await client.detach().catch(() => {});
14923
+ }
14924
+ } else {
14925
+ await page.mouse.click(point.x, point.y);
14926
+ }
14927
+ return {
14928
+ ...base,
14929
+ ...setupScopeEvidence(scope),
14930
+ ok: true,
14931
+ count,
14932
+ target_index: targetIndex,
14933
+ coordinate_mode: hasTapPosition ? mode : undefined,
14934
+ x: hasTapPosition ? fromX : undefined,
14935
+ y: hasTapPosition ? fromY : undefined,
14936
+ pointer_type: pointerType,
14937
+ input_dispatch: pointerType === "touch" || pointerType === "pen" ? "cdp" : "playwright_mouse",
14938
+ duration_ms: durationMs || undefined,
14939
+ };
14940
+ }
14793
14941
  if (type === "drag") {
14794
14942
  const scope = await setupActionScope(action, timeout);
14795
14943
  if (!scope.ok) return setupScopeFailure(base, scope);
package/dist/index.js CHANGED
@@ -62,7 +62,7 @@ import {
62
62
  resolveRiddleProofProfileTimeoutSec,
63
63
  slugifyRiddleProofProfileName,
64
64
  summarizeRiddleProofProfileResult
65
- } from "./chunk-JIAMASZX.js";
65
+ } from "./chunk-RAEZDEAU.js";
66
66
  import {
67
67
  DEFAULT_RIDDLE_API_BASE_URL,
68
68
  DEFAULT_RIDDLE_API_KEY_FILE,
package/dist/profile.cjs CHANGED
@@ -91,6 +91,7 @@ var RIDDLE_PROOF_PROFILE_CHECK_TYPES = [
91
91
  ];
92
92
  var RIDDLE_PROOF_PROFILE_SETUP_ACTION_TYPES = [
93
93
  "click",
94
+ "tap",
94
95
  "drag",
95
96
  "press",
96
97
  "fill",
@@ -642,6 +643,21 @@ function profileSetupDragReceipts(results) {
642
643
  reason: result.reason ?? result.error ?? null
643
644
  }));
644
645
  }
646
+ function profileSetupTapReceipts(results) {
647
+ return results.filter((result) => profileSetupResultAction(result) === "tap").map((result) => ({
648
+ ordinal: result.ordinal ?? null,
649
+ ok: result.ok !== false,
650
+ selector: result.selector ?? null,
651
+ frame_selector: result.frame_selector ?? null,
652
+ pointer_type: result.pointer_type ?? null,
653
+ input_dispatch: result.input_dispatch ?? null,
654
+ coordinate_mode: result.coordinate_mode ?? null,
655
+ x: result.x ?? null,
656
+ y: result.y ?? null,
657
+ duration_ms: result.duration_ms ?? null,
658
+ reason: result.reason ?? result.error ?? null
659
+ }));
660
+ }
645
661
  function profileSetupCanvasSignatureReceipts(results) {
646
662
  return results.filter((result) => profileSetupResultAction(result) === "canvas_signature").map((result) => ({
647
663
  ordinal: result.ordinal ?? null,
@@ -803,6 +819,8 @@ function profileSetupSummary(viewports, actionCount, expectedActionCountByViewpo
803
819
  const sampledRangeValueReceipts = sampleProfileSetupSummaryItems(rangeValueReceipts, 8);
804
820
  const dragReceipts = profileSetupDragReceipts(results);
805
821
  const sampledDragReceipts = sampleProfileSetupSummaryItems(dragReceipts, 8);
822
+ const tapReceipts = profileSetupTapReceipts(results);
823
+ const sampledTapReceipts = sampleProfileSetupSummaryItems(tapReceipts, 8);
806
824
  const canvasSignatureReceipts = profileSetupCanvasSignatureReceipts(results);
807
825
  const sampledCanvasSignatureReceipts = sampleProfileSetupSummaryItems(canvasSignatureReceipts, 8);
808
826
  const clickedItems = results.filter((result) => profileSetupResultAction(result) === "click" && result.ok !== false).map((result) => {
@@ -867,6 +885,9 @@ function profileSetupSummary(viewports, actionCount, expectedActionCountByViewpo
867
885
  drag_total: dragReceipts.length,
868
886
  drag_truncated: dragReceipts.length > sampledDragReceipts.length,
869
887
  drag: sampledDragReceipts,
888
+ tap_total: tapReceipts.length,
889
+ tap_truncated: tapReceipts.length > sampledTapReceipts.length,
890
+ tap: sampledTapReceipts,
870
891
  canvas_signature_total: canvasSignatureReceipts.length,
871
892
  canvas_signature_truncated: canvasSignatureReceipts.length > sampledCanvasSignatureReceipts.length,
872
893
  canvas_signature: sampledCanvasSignatureReceipts,
@@ -923,7 +944,7 @@ function isSupportedCheckType(value) {
923
944
  }
924
945
  function normalizeSetupActionType(value, index) {
925
946
  const normalizedInput = String(value || "").trim().replace(/-/g, "_");
926
- const normalized = normalizedInput === "clear_browser_storage" ? "clear_storage" : normalizedInput === "reset_console" || normalizedInput === "clear_browser_console" || normalizedInput === "reset_browser_console" ? "clear_console" : normalizedInput === "pointer_drag" || normalizedInput === "mouse_drag" || normalizedInput === "drag_to" ? "drag" : normalizedInput === "keyboard_press" || normalizedInput === "key_press" ? "press" : normalizedInput === "set_slider_value" || normalizedInput === "slider_value" || normalizedInput === "set_slider" || normalizedInput === "set_range" || normalizedInput === "range_value" || normalizedInput === "range_input" || normalizedInput === "set_range_input" ? "set_range_value" : normalizedInput === "deterministic_runtime" || normalizedInput === "mock_runtime" || normalizedInput === "mock_random" || normalizedInput === "mock_random_queue" || normalizedInput === "seed_random_queue" || normalizedInput === "set_random_queue" || normalizedInput === "mock_clock" || normalizedInput === "set_mock_clock" || normalizedInput === "set_runtime_determinism" || normalizedInput === "runtime_determinism" ? "deterministic_runtime" : normalizedInput === "canvas_hash" || normalizedInput === "capture_canvas_hash" || normalizedInput === "capture_canvas_signature" || normalizedInput === "canvas_state_signature" ? "canvas_signature" : normalizedInput === "capture_screenshot" || normalizedInput === "save_screenshot" || normalizedInput === "setup_screenshot" ? "screenshot" : normalizedInput === "accept_dialog" || normalizedInput === "accept_dialogs" || normalizedInput === "confirm_dialog" || normalizedInput === "set_dialog_response" ? "dialog_response" : normalizedInput === "dismiss_dialog" || normalizedInput === "dismiss_dialogs" || normalizedInput === "cancel_dialog" ? "dialog_response" : normalizedInput === "window_call_until" || normalizedInput === "call_until" || normalizedInput === "window_call_repeat_until" || normalizedInput === "repeat_window_call_until" ? "window_call_until" : normalizedInput === "window_evaluate" || normalizedInput === "browser_eval" || normalizedInput === "browser_evaluate" || normalizedInput === "evaluate_script" || normalizedInput === "profile_script" ? "window_eval" : normalizedInput;
947
+ const normalized = normalizedInput === "clear_browser_storage" ? "clear_storage" : normalizedInput === "reset_console" || normalizedInput === "clear_browser_console" || normalizedInput === "reset_browser_console" ? "clear_console" : normalizedInput === "pointer_drag" || normalizedInput === "mouse_drag" || normalizedInput === "drag_to" ? "drag" : normalizedInput === "pointer_tap" || normalizedInput === "touch_tap" || normalizedInput === "canvas_tap" ? "tap" : normalizedInput === "keyboard_press" || normalizedInput === "key_press" ? "press" : normalizedInput === "set_slider_value" || normalizedInput === "slider_value" || normalizedInput === "set_slider" || normalizedInput === "set_range" || normalizedInput === "range_value" || normalizedInput === "range_input" || normalizedInput === "set_range_input" ? "set_range_value" : normalizedInput === "deterministic_runtime" || normalizedInput === "mock_runtime" || normalizedInput === "mock_random" || normalizedInput === "mock_random_queue" || normalizedInput === "seed_random_queue" || normalizedInput === "set_random_queue" || normalizedInput === "mock_clock" || normalizedInput === "set_mock_clock" || normalizedInput === "set_runtime_determinism" || normalizedInput === "runtime_determinism" ? "deterministic_runtime" : normalizedInput === "canvas_hash" || normalizedInput === "capture_canvas_hash" || normalizedInput === "capture_canvas_signature" || normalizedInput === "canvas_state_signature" ? "canvas_signature" : normalizedInput === "capture_screenshot" || normalizedInput === "save_screenshot" || normalizedInput === "setup_screenshot" ? "screenshot" : normalizedInput === "accept_dialog" || normalizedInput === "accept_dialogs" || normalizedInput === "confirm_dialog" || normalizedInput === "set_dialog_response" ? "dialog_response" : normalizedInput === "dismiss_dialog" || normalizedInput === "dismiss_dialogs" || normalizedInput === "cancel_dialog" ? "dialog_response" : normalizedInput === "window_call_until" || normalizedInput === "call_until" || normalizedInput === "window_call_repeat_until" || normalizedInput === "repeat_window_call_until" ? "window_call_until" : normalizedInput === "window_evaluate" || normalizedInput === "browser_eval" || normalizedInput === "browser_evaluate" || normalizedInput === "evaluate_script" || normalizedInput === "profile_script" ? "window_eval" : normalizedInput;
927
948
  if (RIDDLE_PROOF_PROFILE_SETUP_ACTION_TYPES.includes(normalized)) {
928
949
  return normalized;
929
950
  }
@@ -1005,8 +1026,8 @@ function normalizeSetupActionCoordinateMode(value, index) {
1005
1026
  }
1006
1027
  function normalizeSetupActionPointerType(value, type, index) {
1007
1028
  if (value === void 0 || value === null || value === "") return void 0;
1008
- if (type !== "drag") {
1009
- throw new Error(`target.setup_actions[${index}].pointer_type is only supported for drag actions.`);
1029
+ if (type !== "drag" && type !== "tap") {
1030
+ throw new Error(`target.setup_actions[${index}].pointer_type is only supported for drag/tap actions.`);
1010
1031
  }
1011
1032
  const normalized = String(value).trim().replace(/-/g, "_").toLowerCase();
1012
1033
  if (normalized === "mouse") return "mouse";
@@ -1085,11 +1106,11 @@ function normalizeSetupAction(input, index) {
1085
1106
  if (frameIndex !== void 0 && (!Number.isInteger(frameIndex) || frameIndex < 0)) {
1086
1107
  throw new Error(`target.setup_actions[${index}].frame_index must be a non-negative integer.`);
1087
1108
  }
1088
- 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) {
1109
+ if ((type === "click" || type === "tap" || 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) {
1089
1110
  throw new Error(`target.setup_actions[${index}] ${type} requires selector.`);
1090
1111
  }
1091
- 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"));
1092
- 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"));
1112
+ const fromX = type === "click" || type === "tap" ? numberValue(valueFromOwn(input, "from_x", "fromX", "x", "click_x", "clickX", "start_x", "startX", "x1")) : numberValue(valueFromOwn(input, "from_x", "fromX", "start_x", "startX", "x1"));
1113
+ const fromY = type === "click" || type === "tap" ? numberValue(valueFromOwn(input, "from_y", "fromY", "y", "click_y", "clickY", "start_y", "startY", "y1")) : numberValue(valueFromOwn(input, "from_y", "fromY", "start_y", "startY", "y1"));
1093
1114
  const toX = numberValue(valueFromOwn(input, "to_x", "toX", "end_x", "endX", "x2"));
1094
1115
  const toY = numberValue(valueFromOwn(input, "to_y", "toY", "end_y", "endY", "y2"));
1095
1116
  const coordinateMode = normalizeSetupActionCoordinateMode(valueFromOwn(input, "coordinate_mode", "coordinateMode", "coords", "units"), index);
@@ -1109,6 +1130,21 @@ function normalizeSetupAction(input, index) {
1109
1130
  }
1110
1131
  }
1111
1132
  }
1133
+ if (type === "tap") {
1134
+ const hasTapCoordinate = fromX !== void 0 || fromY !== void 0;
1135
+ if (hasTapCoordinate && (fromX === void 0 || fromY === void 0)) {
1136
+ throw new Error(`target.setup_actions[${index}] tap coordinates require both x and y.`);
1137
+ }
1138
+ if (hasTapCoordinate && fromX !== void 0 && fromY !== void 0) {
1139
+ const tapCoordinates = [fromX, fromY];
1140
+ if (coordinateMode === "ratio" && tapCoordinates.some((value2) => value2 < 0 || value2 > 1)) {
1141
+ throw new Error(`target.setup_actions[${index}] tap ratio coordinates must be between 0 and 1.`);
1142
+ }
1143
+ if ((coordinateMode === void 0 || coordinateMode === "pixels") && tapCoordinates.some((value2) => value2 < 0)) {
1144
+ throw new Error(`target.setup_actions[${index}] tap pixel coordinates must be non-negative.`);
1145
+ }
1146
+ }
1147
+ }
1112
1148
  if (type === "drag") {
1113
1149
  if (fromX === void 0 || fromY === void 0 || toX === void 0 || toY === void 0) {
1114
1150
  throw new Error(`target.setup_actions[${index}] drag requires from_x, from_y, to_x, and to_y.`);
@@ -4420,6 +4456,23 @@ function profileSetupDragReceipts(results) {
4420
4456
  reason: result.reason || result.error || null,
4421
4457
  }));
4422
4458
  }
4459
+ function profileSetupTapReceipts(results) {
4460
+ return (results || [])
4461
+ .filter((result) => result && profileSetupResultAction(result) === "tap")
4462
+ .map((result) => ({
4463
+ ordinal: result.ordinal ?? null,
4464
+ ok: result.ok !== false,
4465
+ selector: result.selector ?? null,
4466
+ frame_selector: result.frame_selector ?? null,
4467
+ pointer_type: result.pointer_type ?? null,
4468
+ input_dispatch: result.input_dispatch ?? null,
4469
+ coordinate_mode: result.coordinate_mode ?? null,
4470
+ x: result.x ?? null,
4471
+ y: result.y ?? null,
4472
+ duration_ms: result.duration_ms ?? null,
4473
+ reason: result.reason || result.error || null,
4474
+ }));
4475
+ }
4423
4476
  function profileSetupCanvasSignatureReceipts(results) {
4424
4477
  return (results || [])
4425
4478
  .filter((result) => result && profileSetupResultAction(result) === "canvas_signature")
@@ -4606,6 +4659,8 @@ function profileSetupSummary(viewports, actionCount, expectedActionCountsByViewp
4606
4659
  const sampledRangeValueReceipts = sampleProfileSetupSummaryItems(rangeValueReceipts, 8);
4607
4660
  const dragReceipts = profileSetupDragReceipts(results);
4608
4661
  const sampledDragReceipts = sampleProfileSetupSummaryItems(dragReceipts, 8);
4662
+ const tapReceipts = profileSetupTapReceipts(results);
4663
+ const sampledTapReceipts = sampleProfileSetupSummaryItems(tapReceipts, 8);
4609
4664
  const canvasSignatureReceipts = profileSetupCanvasSignatureReceipts(results);
4610
4665
  const sampledCanvasSignatureReceipts = sampleProfileSetupSummaryItems(canvasSignatureReceipts, 8);
4611
4666
  const clickedItems = results
@@ -4680,6 +4735,9 @@ function profileSetupSummary(viewports, actionCount, expectedActionCountsByViewp
4680
4735
  drag_total: dragReceipts.length,
4681
4736
  drag_truncated: dragReceipts.length > sampledDragReceipts.length,
4682
4737
  drag: sampledDragReceipts,
4738
+ tap_total: tapReceipts.length,
4739
+ tap_truncated: tapReceipts.length > sampledTapReceipts.length,
4740
+ tap: sampledTapReceipts,
4683
4741
  canvas_signature_total: canvasSignatureReceipts.length,
4684
4742
  canvas_signature_truncated: canvasSignatureReceipts.length > sampledCanvasSignatureReceipts.length,
4685
4743
  canvas_signature: sampledCanvasSignatureReceipts,
@@ -6104,6 +6162,96 @@ async function executeSetupAction(action, ordinal, viewport) {
6104
6162
  await waitForAnyVisibleSelector(scope.context, action.selector, timeout);
6105
6163
  return { ...base, ...setupScopeEvidence(scope), ok: true, timeout_ms: timeout };
6106
6164
  }
6165
+ if (type === "tap") {
6166
+ const scope = await setupActionScope(action, timeout);
6167
+ if (!scope.ok) return setupScopeFailure(base, scope);
6168
+ const locator = scope.context.locator(action.selector);
6169
+ const count = await locator.count();
6170
+ if (!count) return { ...base, ...setupScopeEvidence(scope), reason: "selector_not_found", count };
6171
+ const targetIndex = Number.isInteger(action.index) ? action.index : 0;
6172
+ if (targetIndex < 0 || targetIndex >= count) return { ...base, ...setupScopeEvidence(scope), reason: "index_out_of_range", count, target_index: targetIndex };
6173
+ const target = locator.nth(targetIndex);
6174
+ await target.waitFor({ state: "visible", timeout });
6175
+ const box = await target.boundingBox();
6176
+ if (!box) return { ...base, ...setupScopeEvidence(scope), reason: "bounding_box_unavailable", count, target_index: targetIndex };
6177
+ const fromX = setupFiniteNumber(action.from_x ?? action.fromX ?? action.x ?? action.click_x ?? action.clickX);
6178
+ const fromY = setupFiniteNumber(action.from_y ?? action.fromY ?? action.y ?? action.click_y ?? action.clickY);
6179
+ const hasTapPosition = fromX !== undefined || fromY !== undefined;
6180
+ if (hasTapPosition && (fromX === undefined || fromY === undefined)) return { ...base, ...setupScopeEvidence(scope), reason: "missing_tap_coordinates", count, target_index: targetIndex };
6181
+ const mode = String(action.coordinate_mode || action.coordinateMode || (hasTapPosition ? "pixels" : "ratio")).trim();
6182
+ if (hasTapPosition && mode === "ratio" && [fromX, fromY].some((value) => value < 0 || value > 1)) return { ...base, ...setupScopeEvidence(scope), reason: "invalid_ratio_coordinates", count, target_index: targetIndex };
6183
+ if (hasTapPosition && mode !== "ratio" && [fromX, fromY].some((value) => value < 0)) return { ...base, ...setupScopeEvidence(scope), reason: "invalid_pixel_coordinates", count, target_index: targetIndex };
6184
+ const coordinate = (value, size) => mode === "ratio" ? value * size : value;
6185
+ const localX = hasTapPosition && fromX !== undefined ? fromX : 0.5;
6186
+ const localY = hasTapPosition && fromY !== undefined ? fromY : 0.5;
6187
+ const point = {
6188
+ x: box.x + coordinate(localX, box.width),
6189
+ y: box.y + coordinate(localY, box.height),
6190
+ };
6191
+ const durationMs = setupNumber(action.duration_ms ?? action.durationMs, 0);
6192
+ const pointerType = String(action.pointer_type || action.pointerType || "touch").trim().toLowerCase();
6193
+ if (pointerType === "touch" || pointerType === "pen") {
6194
+ const client = await page.context().newCDPSession(page);
6195
+ try {
6196
+ if (pointerType === "touch") {
6197
+ const touchPoint = {
6198
+ x: point.x,
6199
+ y: point.y,
6200
+ radiusX: 1,
6201
+ radiusY: 1,
6202
+ force: 1,
6203
+ id: 11,
6204
+ };
6205
+ await client.send("Input.dispatchTouchEvent", {
6206
+ type: "touchStart",
6207
+ touchPoints: [touchPoint],
6208
+ });
6209
+ if (durationMs) await page.waitForTimeout(durationMs);
6210
+ await client.send("Input.dispatchTouchEvent", {
6211
+ type: "touchEnd",
6212
+ touchPoints: [],
6213
+ });
6214
+ } else {
6215
+ await client.send("Input.dispatchMouseEvent", {
6216
+ type: "mousePressed",
6217
+ x: point.x,
6218
+ y: point.y,
6219
+ button: "left",
6220
+ buttons: 1,
6221
+ clickCount: 1,
6222
+ pointerType: "pen",
6223
+ });
6224
+ if (durationMs) await page.waitForTimeout(durationMs);
6225
+ await client.send("Input.dispatchMouseEvent", {
6226
+ type: "mouseReleased",
6227
+ x: point.x,
6228
+ y: point.y,
6229
+ button: "left",
6230
+ buttons: 0,
6231
+ clickCount: 1,
6232
+ pointerType: "pen",
6233
+ });
6234
+ }
6235
+ } finally {
6236
+ await client.detach().catch(() => {});
6237
+ }
6238
+ } else {
6239
+ await page.mouse.click(point.x, point.y);
6240
+ }
6241
+ return {
6242
+ ...base,
6243
+ ...setupScopeEvidence(scope),
6244
+ ok: true,
6245
+ count,
6246
+ target_index: targetIndex,
6247
+ coordinate_mode: hasTapPosition ? mode : undefined,
6248
+ x: hasTapPosition ? fromX : undefined,
6249
+ y: hasTapPosition ? fromY : undefined,
6250
+ pointer_type: pointerType,
6251
+ input_dispatch: pointerType === "touch" || pointerType === "pen" ? "cdp" : "playwright_mouse",
6252
+ duration_ms: durationMs || undefined,
6253
+ };
6254
+ }
6107
6255
  if (type === "drag") {
6108
6256
  const scope = await setupActionScope(action, timeout);
6109
6257
  if (!scope.ok) return setupScopeFailure(base, scope);
@@ -5,7 +5,7 @@ declare const RIDDLE_PROOF_PROFILE_EVIDENCE_VERSION: "riddle-proof.profile-evide
5
5
  declare const RIDDLE_PROOF_PROFILE_RESULT_VERSION: "riddle-proof.profile-result.v1";
6
6
  declare const RIDDLE_PROOF_PROFILE_STATUSES: readonly ["passed", "product_regression", "proof_insufficient", "environment_blocked", "configuration_error", "needs_human_review"];
7
7
  declare const RIDDLE_PROOF_PROFILE_CHECK_TYPES: readonly ["route_loaded", "url_search_param_equals", "url_search_param_absent", "selector_visible", "selector_absent", "selector_count_at_least", "selector_count_equals", "selector_count_equal", "selector_count_eq", "dialog_count_equals", "dialog_accept_count_equals", "dialog_dismiss_count_equals", "selector_text_visible", "selector_text_absent", "selector_text_order", "observe_within", "frame_text_visible", "frame_url_equals", "frame_url_matches", "frame_no_horizontal_overflow", "text_visible", "text_absent", "http_status", "link_status", "artifact_link_status", "route_inventory", "no_horizontal_overflow", "no_mobile_horizontal_overflow", "no_fatal_console_errors", "no_console_warnings"];
8
- declare const RIDDLE_PROOF_PROFILE_SETUP_ACTION_TYPES: readonly ["click", "drag", "press", "fill", "set_input_value", "set_range_value", "deterministic_runtime", "canvas_signature", "assert_text_visible", "assert_text_absent", "assert_selector_count", "assert_window_value", "assert_window_number", "local_storage", "session_storage", "clear_storage", "clear_console", "dialog_response", "screenshot", "wait", "wait_for_selector", "wait_for_text", "window_eval", "window_call", "window_call_until"];
8
+ declare const RIDDLE_PROOF_PROFILE_SETUP_ACTION_TYPES: readonly ["click", "tap", "drag", "press", "fill", "set_input_value", "set_range_value", "deterministic_runtime", "canvas_signature", "assert_text_visible", "assert_text_absent", "assert_selector_count", "assert_window_value", "assert_window_number", "local_storage", "session_storage", "clear_storage", "clear_console", "dialog_response", "screenshot", "wait", "wait_for_selector", "wait_for_text", "window_eval", "window_call", "window_call_until"];
9
9
  type RiddleProofProfileStatus = typeof RIDDLE_PROOF_PROFILE_STATUSES[number];
10
10
  type RiddleProofProfileCheckType = typeof RIDDLE_PROOF_PROFILE_CHECK_TYPES[number];
11
11
  type RiddleProofProfileSetupActionType = typeof RIDDLE_PROOF_PROFILE_SETUP_ACTION_TYPES[number];
package/dist/profile.d.ts CHANGED
@@ -5,7 +5,7 @@ declare const RIDDLE_PROOF_PROFILE_EVIDENCE_VERSION: "riddle-proof.profile-evide
5
5
  declare const RIDDLE_PROOF_PROFILE_RESULT_VERSION: "riddle-proof.profile-result.v1";
6
6
  declare const RIDDLE_PROOF_PROFILE_STATUSES: readonly ["passed", "product_regression", "proof_insufficient", "environment_blocked", "configuration_error", "needs_human_review"];
7
7
  declare const RIDDLE_PROOF_PROFILE_CHECK_TYPES: readonly ["route_loaded", "url_search_param_equals", "url_search_param_absent", "selector_visible", "selector_absent", "selector_count_at_least", "selector_count_equals", "selector_count_equal", "selector_count_eq", "dialog_count_equals", "dialog_accept_count_equals", "dialog_dismiss_count_equals", "selector_text_visible", "selector_text_absent", "selector_text_order", "observe_within", "frame_text_visible", "frame_url_equals", "frame_url_matches", "frame_no_horizontal_overflow", "text_visible", "text_absent", "http_status", "link_status", "artifact_link_status", "route_inventory", "no_horizontal_overflow", "no_mobile_horizontal_overflow", "no_fatal_console_errors", "no_console_warnings"];
8
- declare const RIDDLE_PROOF_PROFILE_SETUP_ACTION_TYPES: readonly ["click", "drag", "press", "fill", "set_input_value", "set_range_value", "deterministic_runtime", "canvas_signature", "assert_text_visible", "assert_text_absent", "assert_selector_count", "assert_window_value", "assert_window_number", "local_storage", "session_storage", "clear_storage", "clear_console", "dialog_response", "screenshot", "wait", "wait_for_selector", "wait_for_text", "window_eval", "window_call", "window_call_until"];
8
+ declare const RIDDLE_PROOF_PROFILE_SETUP_ACTION_TYPES: readonly ["click", "tap", "drag", "press", "fill", "set_input_value", "set_range_value", "deterministic_runtime", "canvas_signature", "assert_text_visible", "assert_text_absent", "assert_selector_count", "assert_window_value", "assert_window_number", "local_storage", "session_storage", "clear_storage", "clear_console", "dialog_response", "screenshot", "wait", "wait_for_selector", "wait_for_text", "window_eval", "window_call", "window_call_until"];
9
9
  type RiddleProofProfileStatus = typeof RIDDLE_PROOF_PROFILE_STATUSES[number];
10
10
  type RiddleProofProfileCheckType = typeof RIDDLE_PROOF_PROFILE_CHECK_TYPES[number];
11
11
  type RiddleProofProfileSetupActionType = typeof RIDDLE_PROOF_PROFILE_SETUP_ACTION_TYPES[number];
package/dist/profile.js CHANGED
@@ -23,7 +23,7 @@ import {
23
23
  resolveRiddleProofProfileTimeoutSec,
24
24
  slugifyRiddleProofProfileName,
25
25
  summarizeRiddleProofProfileResult
26
- } from "./chunk-JIAMASZX.js";
26
+ } from "./chunk-RAEZDEAU.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.173",
3
+ "version": "0.7.175",
4
4
  "description": "Reusable Riddle Proof contracts and helpers for evidence-backed agent changes.",
5
5
  "license": "MIT",
6
6
  "author": "RiddleDC",