@riddledc/riddle-proof 0.7.161 → 0.7.163

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.
@@ -571,6 +571,42 @@ function profileSetupCanvasSignatureReceipts(results) {
571
571
  reason: result.reason ?? result.error ?? null
572
572
  }));
573
573
  }
574
+ function profileSetupCanvasSignatureStableHashGroups(results) {
575
+ const groups = /* @__PURE__ */ new Map();
576
+ for (const receipt of profileSetupCanvasSignatureReceipts(results)) {
577
+ if (receipt.ok === false) continue;
578
+ const hash = stringValue(receipt.hash);
579
+ if (!hash) continue;
580
+ const selector = stringValue(receipt.selector) || "canvas";
581
+ const frameSelector = stringValue(receipt.frame_selector);
582
+ const key = `${frameSelector || ""}
583
+ ${selector}`;
584
+ const group = groups.get(key) || { selector, frame_selector: frameSelector, receipts: [] };
585
+ const ordinal = numberValue(receipt.ordinal);
586
+ const label = stringValue(receipt.label) || (ordinal === void 0 ? `capture-${group.receipts.length + 1}` : `#${ordinal}`);
587
+ group.receipts.push({ hash, label, ordinal });
588
+ groups.set(key, group);
589
+ }
590
+ const warnings = [];
591
+ for (const group of groups.values()) {
592
+ const hashes = new Set(group.receipts.map((receipt) => receipt.hash));
593
+ const labels = [...new Set(group.receipts.map((receipt) => receipt.label))];
594
+ if (group.receipts.length < 2 || labels.length < 2 || hashes.size !== 1) continue;
595
+ const visibleLabels = labels.slice(0, 8);
596
+ warnings.push({
597
+ selector: group.selector,
598
+ frame_selector: group.frame_selector ?? null,
599
+ hash: group.receipts[0].hash,
600
+ count: group.receipts.length,
601
+ label_count: labels.length,
602
+ labels: visibleLabels,
603
+ omitted_label_count: Math.max(0, labels.length - visibleLabels.length),
604
+ ordinals: group.receipts.map((receipt) => receipt.ordinal).filter((value) => value !== void 0).slice(0, 12),
605
+ reason: "stable_canvas_signature_hash"
606
+ });
607
+ }
608
+ return warnings;
609
+ }
574
610
  function sampleProfileSetupSummaryItems(items, limit) {
575
611
  if (items.length <= limit) return items;
576
612
  const firstCount = Math.floor(limit / 2);
@@ -671,6 +707,7 @@ function profileSetupSummary(viewports, actionCount, expectedActionCountByViewpo
671
707
  canvas_signature_total: canvasSignatureReceipts.length,
672
708
  canvas_signature_truncated: canvasSignatureReceipts.length > sampledCanvasSignatureReceipts.length,
673
709
  canvas_signature: sampledCanvasSignatureReceipts,
710
+ canvas_signature_stable_hash_groups: profileSetupCanvasSignatureStableHashGroups(results),
674
711
  clicked,
675
712
  text_samples,
676
713
  failed: failed.map((result) => ({
@@ -5738,106 +5775,79 @@ async function executeSetupAction(action, ordinal, viewport) {
5738
5775
  const durationMs = setupNumber(action.duration_ms ?? action.durationMs, 0);
5739
5776
  const pointerType = String(action.pointer_type || action.pointerType || "mouse").trim().toLowerCase();
5740
5777
  if (pointerType === "touch" || pointerType === "pen") {
5741
- const localStart = {
5742
- x: coordinate(fromX, box.width),
5743
- y: coordinate(fromY, box.height),
5744
- };
5745
- const localEnd = {
5746
- x: coordinate(toX, box.width),
5747
- y: coordinate(toY, box.height),
5748
- };
5749
- await target.evaluate(async (element, payload) => {
5750
- const wait = (ms) => new Promise((resolve) => setTimeout(resolve, ms));
5751
- const rect = element.getBoundingClientRect();
5752
- const pointerId = payload.pointerType === "touch" ? 11 : 12;
5753
- const capturedPointers = new Set();
5754
- const originalOwnSetPointerCapture = Object.getOwnPropertyDescriptor(element, "setPointerCapture");
5755
- const originalOwnReleasePointerCapture = Object.getOwnPropertyDescriptor(element, "releasePointerCapture");
5756
- const originalOwnHasPointerCapture = Object.getOwnPropertyDescriptor(element, "hasPointerCapture");
5757
- const originalSetPointerCapture = typeof element.setPointerCapture === "function" ? element.setPointerCapture.bind(element) : undefined;
5758
- const originalReleasePointerCapture = typeof element.releasePointerCapture === "function" ? element.releasePointerCapture.bind(element) : undefined;
5759
- const originalHasPointerCapture = typeof element.hasPointerCapture === "function" ? element.hasPointerCapture.bind(element) : undefined;
5760
- const restorePointerCapture = () => {
5761
- if (originalOwnSetPointerCapture) Object.defineProperty(element, "setPointerCapture", originalOwnSetPointerCapture);
5762
- else delete (element as any).setPointerCapture;
5763
- if (originalOwnReleasePointerCapture) Object.defineProperty(element, "releasePointerCapture", originalOwnReleasePointerCapture);
5764
- else delete (element as any).releasePointerCapture;
5765
- if (originalOwnHasPointerCapture) Object.defineProperty(element, "hasPointerCapture", originalOwnHasPointerCapture);
5766
- else delete (element as any).hasPointerCapture;
5767
- };
5768
- Object.defineProperty(element, "setPointerCapture", {
5769
- configurable: true,
5770
- value: (activePointerId) => {
5771
- capturedPointers.add(activePointerId);
5772
- try {
5773
- return originalSetPointerCapture?.(activePointerId);
5774
- } catch {
5775
- return undefined;
5776
- }
5777
- },
5778
- });
5779
- Object.defineProperty(element, "releasePointerCapture", {
5780
- configurable: true,
5781
- value: (activePointerId) => {
5782
- capturedPointers.delete(activePointerId);
5783
- try {
5784
- return originalReleasePointerCapture?.(activePointerId);
5785
- } catch {
5786
- return undefined;
5787
- }
5788
- },
5789
- });
5790
- Object.defineProperty(element, "hasPointerCapture", {
5791
- configurable: true,
5792
- value: (activePointerId) => {
5793
- if (capturedPointers.has(activePointerId)) return true;
5794
- try {
5795
- return Boolean(originalHasPointerCapture?.(activePointerId));
5796
- } catch {
5797
- return false;
5798
- }
5799
- },
5800
- });
5801
- const point = (progress) => ({
5802
- clientX: rect.left + payload.start.x + (payload.end.x - payload.start.x) * progress,
5803
- clientY: rect.top + payload.start.y + (payload.end.y - payload.start.y) * progress,
5804
- });
5805
- const dispatch = (type, progress) => {
5806
- const coords = point(progress);
5807
- element.dispatchEvent(new PointerEvent(type, {
5808
- bubbles: true,
5809
- cancelable: true,
5810
- composed: true,
5811
- pointerId,
5812
- pointerType: payload.pointerType,
5813
- isPrimary: true,
5814
- buttons: type === "pointerup" ? 0 : 1,
5815
- button: type === "pointerup" ? 0 : 0,
5816
- clientX: coords.clientX,
5817
- clientY: coords.clientY,
5818
- }));
5819
- };
5820
- try {
5821
- dispatch("pointerover", 0);
5822
- dispatch("pointerenter", 0);
5823
- dispatch("pointerdown", 0);
5824
- for (let step = 1; step <= payload.steps; step += 1) {
5825
- dispatch("pointermove", step / payload.steps);
5826
- if (payload.durationMs && payload.steps > 1) await wait(payload.durationMs / payload.steps);
5778
+ const client = await page.context().newCDPSession(page);
5779
+ try {
5780
+ if (pointerType === "touch") {
5781
+ const touchPoint = (x, y) => ({
5782
+ x,
5783
+ y,
5784
+ radiusX: 1,
5785
+ radiusY: 1,
5786
+ force: 1,
5787
+ id: 11,
5788
+ });
5789
+ await client.send("Input.dispatchTouchEvent", {
5790
+ type: "touchStart",
5791
+ touchPoints: [touchPoint(start.x, start.y)],
5792
+ });
5793
+ for (let step = 1; step <= steps; step += 1) {
5794
+ const progress = step / steps;
5795
+ await client.send("Input.dispatchTouchEvent", {
5796
+ type: "touchMove",
5797
+ touchPoints: [
5798
+ touchPoint(
5799
+ start.x + (end.x - start.x) * progress,
5800
+ start.y + (end.y - start.y) * progress,
5801
+ ),
5802
+ ],
5803
+ });
5804
+ if (durationMs && steps > 1) await page.waitForTimeout(durationMs / steps);
5827
5805
  }
5828
- dispatch("pointerup", 1);
5829
- dispatch("pointerout", 1);
5830
- dispatch("pointerleave", 1);
5831
- } finally {
5832
- restorePointerCapture();
5806
+ await client.send("Input.dispatchTouchEvent", {
5807
+ type: "touchEnd",
5808
+ touchPoints: [],
5809
+ });
5810
+ } else {
5811
+ await client.send("Input.dispatchMouseEvent", {
5812
+ type: "mouseMoved",
5813
+ x: start.x,
5814
+ y: start.y,
5815
+ pointerType: "pen",
5816
+ });
5817
+ await client.send("Input.dispatchMouseEvent", {
5818
+ type: "mousePressed",
5819
+ x: start.x,
5820
+ y: start.y,
5821
+ button: "left",
5822
+ buttons: 1,
5823
+ clickCount: 1,
5824
+ pointerType: "pen",
5825
+ });
5826
+ for (let step = 1; step <= steps; step += 1) {
5827
+ const progress = step / steps;
5828
+ await client.send("Input.dispatchMouseEvent", {
5829
+ type: "mouseMoved",
5830
+ x: start.x + (end.x - start.x) * progress,
5831
+ y: start.y + (end.y - start.y) * progress,
5832
+ button: "left",
5833
+ buttons: 1,
5834
+ pointerType: "pen",
5835
+ });
5836
+ if (durationMs && steps > 1) await page.waitForTimeout(durationMs / steps);
5837
+ }
5838
+ await client.send("Input.dispatchMouseEvent", {
5839
+ type: "mouseReleased",
5840
+ x: end.x,
5841
+ y: end.y,
5842
+ button: "left",
5843
+ buttons: 0,
5844
+ clickCount: 1,
5845
+ pointerType: "pen",
5846
+ });
5833
5847
  }
5834
- }, {
5835
- pointerType,
5836
- start: localStart,
5837
- end: localEnd,
5838
- steps,
5839
- durationMs,
5840
- });
5848
+ } finally {
5849
+ await client.detach().catch(() => {});
5850
+ }
5841
5851
  } else {
5842
5852
  await page.mouse.move(start.x, start.y);
5843
5853
  await page.mouse.down();
@@ -5870,7 +5880,7 @@ async function executeSetupAction(action, ordinal, viewport) {
5870
5880
  to_x: toX,
5871
5881
  to_y: toY,
5872
5882
  pointer_type: pointerType,
5873
- pointer_capture_polyfill: pointerType === "touch" || pointerType === "pen" ? true : undefined,
5883
+ input_dispatch: pointerType === "touch" || pointerType === "pen" ? "cdp" : "playwright_mouse",
5874
5884
  steps,
5875
5885
  duration_ms: durationMs || undefined,
5876
5886
  };
package/dist/cli.cjs CHANGED
@@ -7528,6 +7528,42 @@ function profileSetupCanvasSignatureReceipts(results) {
7528
7528
  reason: result.reason ?? result.error ?? null
7529
7529
  }));
7530
7530
  }
7531
+ function profileSetupCanvasSignatureStableHashGroups(results) {
7532
+ const groups = /* @__PURE__ */ new Map();
7533
+ for (const receipt of profileSetupCanvasSignatureReceipts(results)) {
7534
+ if (receipt.ok === false) continue;
7535
+ const hash = stringValue2(receipt.hash);
7536
+ if (!hash) continue;
7537
+ const selector = stringValue2(receipt.selector) || "canvas";
7538
+ const frameSelector = stringValue2(receipt.frame_selector);
7539
+ const key = `${frameSelector || ""}
7540
+ ${selector}`;
7541
+ const group = groups.get(key) || { selector, frame_selector: frameSelector, receipts: [] };
7542
+ const ordinal = numberValue(receipt.ordinal);
7543
+ const label = stringValue2(receipt.label) || (ordinal === void 0 ? `capture-${group.receipts.length + 1}` : `#${ordinal}`);
7544
+ group.receipts.push({ hash, label, ordinal });
7545
+ groups.set(key, group);
7546
+ }
7547
+ const warnings = [];
7548
+ for (const group of groups.values()) {
7549
+ const hashes = new Set(group.receipts.map((receipt) => receipt.hash));
7550
+ const labels = [...new Set(group.receipts.map((receipt) => receipt.label))];
7551
+ if (group.receipts.length < 2 || labels.length < 2 || hashes.size !== 1) continue;
7552
+ const visibleLabels = labels.slice(0, 8);
7553
+ warnings.push({
7554
+ selector: group.selector,
7555
+ frame_selector: group.frame_selector ?? null,
7556
+ hash: group.receipts[0].hash,
7557
+ count: group.receipts.length,
7558
+ label_count: labels.length,
7559
+ labels: visibleLabels,
7560
+ omitted_label_count: Math.max(0, labels.length - visibleLabels.length),
7561
+ ordinals: group.receipts.map((receipt) => receipt.ordinal).filter((value) => value !== void 0).slice(0, 12),
7562
+ reason: "stable_canvas_signature_hash"
7563
+ });
7564
+ }
7565
+ return warnings;
7566
+ }
7531
7567
  function sampleProfileSetupSummaryItems(items, limit) {
7532
7568
  if (items.length <= limit) return items;
7533
7569
  const firstCount = Math.floor(limit / 2);
@@ -7628,6 +7664,7 @@ function profileSetupSummary(viewports, actionCount, expectedActionCountByViewpo
7628
7664
  canvas_signature_total: canvasSignatureReceipts.length,
7629
7665
  canvas_signature_truncated: canvasSignatureReceipts.length > sampledCanvasSignatureReceipts.length,
7630
7666
  canvas_signature: sampledCanvasSignatureReceipts,
7667
+ canvas_signature_stable_hash_groups: profileSetupCanvasSignatureStableHashGroups(results),
7631
7668
  clicked,
7632
7669
  text_samples,
7633
7670
  failed: failed.map((result) => ({
@@ -12679,106 +12716,79 @@ async function executeSetupAction(action, ordinal, viewport) {
12679
12716
  const durationMs = setupNumber(action.duration_ms ?? action.durationMs, 0);
12680
12717
  const pointerType = String(action.pointer_type || action.pointerType || "mouse").trim().toLowerCase();
12681
12718
  if (pointerType === "touch" || pointerType === "pen") {
12682
- const localStart = {
12683
- x: coordinate(fromX, box.width),
12684
- y: coordinate(fromY, box.height),
12685
- };
12686
- const localEnd = {
12687
- x: coordinate(toX, box.width),
12688
- y: coordinate(toY, box.height),
12689
- };
12690
- await target.evaluate(async (element, payload) => {
12691
- const wait = (ms) => new Promise((resolve) => setTimeout(resolve, ms));
12692
- const rect = element.getBoundingClientRect();
12693
- const pointerId = payload.pointerType === "touch" ? 11 : 12;
12694
- const capturedPointers = new Set();
12695
- const originalOwnSetPointerCapture = Object.getOwnPropertyDescriptor(element, "setPointerCapture");
12696
- const originalOwnReleasePointerCapture = Object.getOwnPropertyDescriptor(element, "releasePointerCapture");
12697
- const originalOwnHasPointerCapture = Object.getOwnPropertyDescriptor(element, "hasPointerCapture");
12698
- const originalSetPointerCapture = typeof element.setPointerCapture === "function" ? element.setPointerCapture.bind(element) : undefined;
12699
- const originalReleasePointerCapture = typeof element.releasePointerCapture === "function" ? element.releasePointerCapture.bind(element) : undefined;
12700
- const originalHasPointerCapture = typeof element.hasPointerCapture === "function" ? element.hasPointerCapture.bind(element) : undefined;
12701
- const restorePointerCapture = () => {
12702
- if (originalOwnSetPointerCapture) Object.defineProperty(element, "setPointerCapture", originalOwnSetPointerCapture);
12703
- else delete (element as any).setPointerCapture;
12704
- if (originalOwnReleasePointerCapture) Object.defineProperty(element, "releasePointerCapture", originalOwnReleasePointerCapture);
12705
- else delete (element as any).releasePointerCapture;
12706
- if (originalOwnHasPointerCapture) Object.defineProperty(element, "hasPointerCapture", originalOwnHasPointerCapture);
12707
- else delete (element as any).hasPointerCapture;
12708
- };
12709
- Object.defineProperty(element, "setPointerCapture", {
12710
- configurable: true,
12711
- value: (activePointerId) => {
12712
- capturedPointers.add(activePointerId);
12713
- try {
12714
- return originalSetPointerCapture?.(activePointerId);
12715
- } catch {
12716
- return undefined;
12717
- }
12718
- },
12719
- });
12720
- Object.defineProperty(element, "releasePointerCapture", {
12721
- configurable: true,
12722
- value: (activePointerId) => {
12723
- capturedPointers.delete(activePointerId);
12724
- try {
12725
- return originalReleasePointerCapture?.(activePointerId);
12726
- } catch {
12727
- return undefined;
12728
- }
12729
- },
12730
- });
12731
- Object.defineProperty(element, "hasPointerCapture", {
12732
- configurable: true,
12733
- value: (activePointerId) => {
12734
- if (capturedPointers.has(activePointerId)) return true;
12735
- try {
12736
- return Boolean(originalHasPointerCapture?.(activePointerId));
12737
- } catch {
12738
- return false;
12739
- }
12740
- },
12741
- });
12742
- const point = (progress) => ({
12743
- clientX: rect.left + payload.start.x + (payload.end.x - payload.start.x) * progress,
12744
- clientY: rect.top + payload.start.y + (payload.end.y - payload.start.y) * progress,
12745
- });
12746
- const dispatch = (type, progress) => {
12747
- const coords = point(progress);
12748
- element.dispatchEvent(new PointerEvent(type, {
12749
- bubbles: true,
12750
- cancelable: true,
12751
- composed: true,
12752
- pointerId,
12753
- pointerType: payload.pointerType,
12754
- isPrimary: true,
12755
- buttons: type === "pointerup" ? 0 : 1,
12756
- button: type === "pointerup" ? 0 : 0,
12757
- clientX: coords.clientX,
12758
- clientY: coords.clientY,
12759
- }));
12760
- };
12761
- try {
12762
- dispatch("pointerover", 0);
12763
- dispatch("pointerenter", 0);
12764
- dispatch("pointerdown", 0);
12765
- for (let step = 1; step <= payload.steps; step += 1) {
12766
- dispatch("pointermove", step / payload.steps);
12767
- if (payload.durationMs && payload.steps > 1) await wait(payload.durationMs / payload.steps);
12719
+ const client = await page.context().newCDPSession(page);
12720
+ try {
12721
+ if (pointerType === "touch") {
12722
+ const touchPoint = (x, y) => ({
12723
+ x,
12724
+ y,
12725
+ radiusX: 1,
12726
+ radiusY: 1,
12727
+ force: 1,
12728
+ id: 11,
12729
+ });
12730
+ await client.send("Input.dispatchTouchEvent", {
12731
+ type: "touchStart",
12732
+ touchPoints: [touchPoint(start.x, start.y)],
12733
+ });
12734
+ for (let step = 1; step <= steps; step += 1) {
12735
+ const progress = step / steps;
12736
+ await client.send("Input.dispatchTouchEvent", {
12737
+ type: "touchMove",
12738
+ touchPoints: [
12739
+ touchPoint(
12740
+ start.x + (end.x - start.x) * progress,
12741
+ start.y + (end.y - start.y) * progress,
12742
+ ),
12743
+ ],
12744
+ });
12745
+ if (durationMs && steps > 1) await page.waitForTimeout(durationMs / steps);
12768
12746
  }
12769
- dispatch("pointerup", 1);
12770
- dispatch("pointerout", 1);
12771
- dispatch("pointerleave", 1);
12772
- } finally {
12773
- restorePointerCapture();
12747
+ await client.send("Input.dispatchTouchEvent", {
12748
+ type: "touchEnd",
12749
+ touchPoints: [],
12750
+ });
12751
+ } else {
12752
+ await client.send("Input.dispatchMouseEvent", {
12753
+ type: "mouseMoved",
12754
+ x: start.x,
12755
+ y: start.y,
12756
+ pointerType: "pen",
12757
+ });
12758
+ await client.send("Input.dispatchMouseEvent", {
12759
+ type: "mousePressed",
12760
+ x: start.x,
12761
+ y: start.y,
12762
+ button: "left",
12763
+ buttons: 1,
12764
+ clickCount: 1,
12765
+ pointerType: "pen",
12766
+ });
12767
+ for (let step = 1; step <= steps; step += 1) {
12768
+ const progress = step / steps;
12769
+ await client.send("Input.dispatchMouseEvent", {
12770
+ type: "mouseMoved",
12771
+ x: start.x + (end.x - start.x) * progress,
12772
+ y: start.y + (end.y - start.y) * progress,
12773
+ button: "left",
12774
+ buttons: 1,
12775
+ pointerType: "pen",
12776
+ });
12777
+ if (durationMs && steps > 1) await page.waitForTimeout(durationMs / steps);
12778
+ }
12779
+ await client.send("Input.dispatchMouseEvent", {
12780
+ type: "mouseReleased",
12781
+ x: end.x,
12782
+ y: end.y,
12783
+ button: "left",
12784
+ buttons: 0,
12785
+ clickCount: 1,
12786
+ pointerType: "pen",
12787
+ });
12774
12788
  }
12775
- }, {
12776
- pointerType,
12777
- start: localStart,
12778
- end: localEnd,
12779
- steps,
12780
- durationMs,
12781
- });
12789
+ } finally {
12790
+ await client.detach().catch(() => {});
12791
+ }
12782
12792
  } else {
12783
12793
  await page.mouse.move(start.x, start.y);
12784
12794
  await page.mouse.down();
@@ -12811,7 +12821,7 @@ async function executeSetupAction(action, ordinal, viewport) {
12811
12821
  to_x: toX,
12812
12822
  to_y: toY,
12813
12823
  pointer_type: pointerType,
12814
- pointer_capture_polyfill: pointerType === "touch" || pointerType === "pen" ? true : undefined,
12824
+ input_dispatch: pointerType === "touch" || pointerType === "pen" ? "cdp" : "playwright_mouse",
12815
12825
  steps,
12816
12826
  duration_ms: durationMs || undefined,
12817
12827
  };
@@ -15885,6 +15895,25 @@ function profileSetupSummaryMarkdown(result) {
15885
15895
  lines.push(`- ${name} canvas_signature: ${ok}, ${markdownInlineCode(selector)}${label ? ` ${markdownInlineCode(label, 80)}` : ""}${hash ? ` hash ${markdownInlineCode(hash, 80)}` : ""}${sizeText}${cssSizeText}${dataLength === void 0 ? "" : `, data chars ${dataLength}`}${compareTo ? `, compared ${markdownInlineCode(compareTo)}` : ""}${previousHash ? ` previous ${markdownInlineCode(previousHash, 80)}` : ""}${changed === void 0 ? "" : `, changed ${changed}`}${storedTo ? `, stored ${markdownInlineCode(storedTo)}` : ""}${reason ? `, reason ${markdownInlineCode(reason, 100)}` : ""}`);
15886
15896
  }
15887
15897
  if (canvasSignatureDetails.length > sampledCanvasSignatureDetails.length) lines.push(`- ${canvasSignatureDetails.length - sampledCanvasSignatureDetails.length} additional canvas_signature receipt(s) omitted.`);
15898
+ const canvasSignatureWarningGroups = viewports.map((viewport) => {
15899
+ const name = cliString(viewport.name) || "viewport";
15900
+ const warnings = Array.isArray(viewport.canvas_signature_stable_hash_groups) ? viewport.canvas_signature_stable_hash_groups.map(cliRecord).filter((item) => Boolean(item)) : [];
15901
+ return warnings.map((warning) => ({ name, receipt: warning }));
15902
+ });
15903
+ const canvasSignatureWarnings = canvasSignatureWarningGroups.flat();
15904
+ const sampledCanvasSignatureWarnings = balancedSetupReceiptDetails(canvasSignatureWarningGroups, 12);
15905
+ for (const { name, receipt } of sampledCanvasSignatureWarnings) {
15906
+ const selector = cliString(receipt.selector) || "canvas";
15907
+ const frameSelector = cliString(receipt.frame_selector);
15908
+ const hash = cliString(receipt.hash);
15909
+ const count = cliFiniteNumber(receipt.count);
15910
+ const labelCount = cliFiniteNumber(receipt.label_count);
15911
+ const labels = cliStringArray(receipt.labels);
15912
+ const omittedLabelCount = cliFiniteNumber(receipt.omitted_label_count) || 0;
15913
+ const labelText = labels.length ? ` across ${labels.map((label) => markdownInlineCode(label, 60)).join(", ")}${omittedLabelCount ? `, plus ${omittedLabelCount} more` : ""}` : "";
15914
+ lines.push(`- ${name} canvas_signature warning: ${markdownInlineCode(selector)}${frameSelector ? ` in frame ${markdownInlineCode(frameSelector)}` : ""} returned the same hash${hash ? ` ${markdownInlineCode(hash, 80)}` : ""} for ${count ?? labelCount ?? "multiple"} labeled capture(s)${labelText}; treat canvas signatures as diagnostic when runtime evidence or screenshots show state changes.`);
15915
+ }
15916
+ if (canvasSignatureWarnings.length > sampledCanvasSignatureWarnings.length) lines.push(`- ${canvasSignatureWarnings.length - sampledCanvasSignatureWarnings.length} additional canvas_signature warning(s) omitted.`);
15888
15917
  const rangeValueGroups = viewports.map((viewport) => {
15889
15918
  const name = cliString(viewport.name) || "viewport";
15890
15919
  const receipts = Array.isArray(viewport.set_range_value) ? viewport.set_range_value.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-ZE2U5EML.js";
16
+ } from "./chunk-RWBG7256.js";
17
17
  import {
18
18
  createRiddleApiClient,
19
19
  isTerminalRiddleJobStatus,
@@ -860,6 +860,25 @@ function profileSetupSummaryMarkdown(result) {
860
860
  lines.push(`- ${name} canvas_signature: ${ok}, ${markdownInlineCode(selector)}${label ? ` ${markdownInlineCode(label, 80)}` : ""}${hash ? ` hash ${markdownInlineCode(hash, 80)}` : ""}${sizeText}${cssSizeText}${dataLength === void 0 ? "" : `, data chars ${dataLength}`}${compareTo ? `, compared ${markdownInlineCode(compareTo)}` : ""}${previousHash ? ` previous ${markdownInlineCode(previousHash, 80)}` : ""}${changed === void 0 ? "" : `, changed ${changed}`}${storedTo ? `, stored ${markdownInlineCode(storedTo)}` : ""}${reason ? `, reason ${markdownInlineCode(reason, 100)}` : ""}`);
861
861
  }
862
862
  if (canvasSignatureDetails.length > sampledCanvasSignatureDetails.length) lines.push(`- ${canvasSignatureDetails.length - sampledCanvasSignatureDetails.length} additional canvas_signature receipt(s) omitted.`);
863
+ const canvasSignatureWarningGroups = viewports.map((viewport) => {
864
+ const name = cliString(viewport.name) || "viewport";
865
+ const warnings = Array.isArray(viewport.canvas_signature_stable_hash_groups) ? viewport.canvas_signature_stable_hash_groups.map(cliRecord).filter((item) => Boolean(item)) : [];
866
+ return warnings.map((warning) => ({ name, receipt: warning }));
867
+ });
868
+ const canvasSignatureWarnings = canvasSignatureWarningGroups.flat();
869
+ const sampledCanvasSignatureWarnings = balancedSetupReceiptDetails(canvasSignatureWarningGroups, 12);
870
+ for (const { name, receipt } of sampledCanvasSignatureWarnings) {
871
+ const selector = cliString(receipt.selector) || "canvas";
872
+ const frameSelector = cliString(receipt.frame_selector);
873
+ const hash = cliString(receipt.hash);
874
+ const count = cliFiniteNumber(receipt.count);
875
+ const labelCount = cliFiniteNumber(receipt.label_count);
876
+ const labels = cliStringArray(receipt.labels);
877
+ const omittedLabelCount = cliFiniteNumber(receipt.omitted_label_count) || 0;
878
+ const labelText = labels.length ? ` across ${labels.map((label) => markdownInlineCode(label, 60)).join(", ")}${omittedLabelCount ? `, plus ${omittedLabelCount} more` : ""}` : "";
879
+ lines.push(`- ${name} canvas_signature warning: ${markdownInlineCode(selector)}${frameSelector ? ` in frame ${markdownInlineCode(frameSelector)}` : ""} returned the same hash${hash ? ` ${markdownInlineCode(hash, 80)}` : ""} for ${count ?? labelCount ?? "multiple"} labeled capture(s)${labelText}; treat canvas signatures as diagnostic when runtime evidence or screenshots show state changes.`);
880
+ }
881
+ if (canvasSignatureWarnings.length > sampledCanvasSignatureWarnings.length) lines.push(`- ${canvasSignatureWarnings.length - sampledCanvasSignatureWarnings.length} additional canvas_signature warning(s) omitted.`);
863
882
  const rangeValueGroups = viewports.map((viewport) => {
864
883
  const name = cliString(viewport.name) || "viewport";
865
884
  const receipts = Array.isArray(viewport.set_range_value) ? viewport.set_range_value.map(cliRecord).filter((item) => Boolean(item)) : [];
package/dist/index.cjs CHANGED
@@ -9304,6 +9304,42 @@ function profileSetupCanvasSignatureReceipts(results) {
9304
9304
  reason: result.reason ?? result.error ?? null
9305
9305
  }));
9306
9306
  }
9307
+ function profileSetupCanvasSignatureStableHashGroups(results) {
9308
+ const groups = /* @__PURE__ */ new Map();
9309
+ for (const receipt of profileSetupCanvasSignatureReceipts(results)) {
9310
+ if (receipt.ok === false) continue;
9311
+ const hash = stringValue5(receipt.hash);
9312
+ if (!hash) continue;
9313
+ const selector = stringValue5(receipt.selector) || "canvas";
9314
+ const frameSelector = stringValue5(receipt.frame_selector);
9315
+ const key = `${frameSelector || ""}
9316
+ ${selector}`;
9317
+ const group = groups.get(key) || { selector, frame_selector: frameSelector, receipts: [] };
9318
+ const ordinal = numberValue3(receipt.ordinal);
9319
+ const label = stringValue5(receipt.label) || (ordinal === void 0 ? `capture-${group.receipts.length + 1}` : `#${ordinal}`);
9320
+ group.receipts.push({ hash, label, ordinal });
9321
+ groups.set(key, group);
9322
+ }
9323
+ const warnings = [];
9324
+ for (const group of groups.values()) {
9325
+ const hashes = new Set(group.receipts.map((receipt) => receipt.hash));
9326
+ const labels = [...new Set(group.receipts.map((receipt) => receipt.label))];
9327
+ if (group.receipts.length < 2 || labels.length < 2 || hashes.size !== 1) continue;
9328
+ const visibleLabels = labels.slice(0, 8);
9329
+ warnings.push({
9330
+ selector: group.selector,
9331
+ frame_selector: group.frame_selector ?? null,
9332
+ hash: group.receipts[0].hash,
9333
+ count: group.receipts.length,
9334
+ label_count: labels.length,
9335
+ labels: visibleLabels,
9336
+ omitted_label_count: Math.max(0, labels.length - visibleLabels.length),
9337
+ ordinals: group.receipts.map((receipt) => receipt.ordinal).filter((value) => value !== void 0).slice(0, 12),
9338
+ reason: "stable_canvas_signature_hash"
9339
+ });
9340
+ }
9341
+ return warnings;
9342
+ }
9307
9343
  function sampleProfileSetupSummaryItems(items, limit) {
9308
9344
  if (items.length <= limit) return items;
9309
9345
  const firstCount = Math.floor(limit / 2);
@@ -9404,6 +9440,7 @@ function profileSetupSummary(viewports, actionCount, expectedActionCountByViewpo
9404
9440
  canvas_signature_total: canvasSignatureReceipts.length,
9405
9441
  canvas_signature_truncated: canvasSignatureReceipts.length > sampledCanvasSignatureReceipts.length,
9406
9442
  canvas_signature: sampledCanvasSignatureReceipts,
9443
+ canvas_signature_stable_hash_groups: profileSetupCanvasSignatureStableHashGroups(results),
9407
9444
  clicked,
9408
9445
  text_samples,
9409
9446
  failed: failed.map((result) => ({
@@ -14471,106 +14508,79 @@ async function executeSetupAction(action, ordinal, viewport) {
14471
14508
  const durationMs = setupNumber(action.duration_ms ?? action.durationMs, 0);
14472
14509
  const pointerType = String(action.pointer_type || action.pointerType || "mouse").trim().toLowerCase();
14473
14510
  if (pointerType === "touch" || pointerType === "pen") {
14474
- const localStart = {
14475
- x: coordinate(fromX, box.width),
14476
- y: coordinate(fromY, box.height),
14477
- };
14478
- const localEnd = {
14479
- x: coordinate(toX, box.width),
14480
- y: coordinate(toY, box.height),
14481
- };
14482
- await target.evaluate(async (element, payload) => {
14483
- const wait = (ms) => new Promise((resolve) => setTimeout(resolve, ms));
14484
- const rect = element.getBoundingClientRect();
14485
- const pointerId = payload.pointerType === "touch" ? 11 : 12;
14486
- const capturedPointers = new Set();
14487
- const originalOwnSetPointerCapture = Object.getOwnPropertyDescriptor(element, "setPointerCapture");
14488
- const originalOwnReleasePointerCapture = Object.getOwnPropertyDescriptor(element, "releasePointerCapture");
14489
- const originalOwnHasPointerCapture = Object.getOwnPropertyDescriptor(element, "hasPointerCapture");
14490
- const originalSetPointerCapture = typeof element.setPointerCapture === "function" ? element.setPointerCapture.bind(element) : undefined;
14491
- const originalReleasePointerCapture = typeof element.releasePointerCapture === "function" ? element.releasePointerCapture.bind(element) : undefined;
14492
- const originalHasPointerCapture = typeof element.hasPointerCapture === "function" ? element.hasPointerCapture.bind(element) : undefined;
14493
- const restorePointerCapture = () => {
14494
- if (originalOwnSetPointerCapture) Object.defineProperty(element, "setPointerCapture", originalOwnSetPointerCapture);
14495
- else delete (element as any).setPointerCapture;
14496
- if (originalOwnReleasePointerCapture) Object.defineProperty(element, "releasePointerCapture", originalOwnReleasePointerCapture);
14497
- else delete (element as any).releasePointerCapture;
14498
- if (originalOwnHasPointerCapture) Object.defineProperty(element, "hasPointerCapture", originalOwnHasPointerCapture);
14499
- else delete (element as any).hasPointerCapture;
14500
- };
14501
- Object.defineProperty(element, "setPointerCapture", {
14502
- configurable: true,
14503
- value: (activePointerId) => {
14504
- capturedPointers.add(activePointerId);
14505
- try {
14506
- return originalSetPointerCapture?.(activePointerId);
14507
- } catch {
14508
- return undefined;
14509
- }
14510
- },
14511
- });
14512
- Object.defineProperty(element, "releasePointerCapture", {
14513
- configurable: true,
14514
- value: (activePointerId) => {
14515
- capturedPointers.delete(activePointerId);
14516
- try {
14517
- return originalReleasePointerCapture?.(activePointerId);
14518
- } catch {
14519
- return undefined;
14520
- }
14521
- },
14522
- });
14523
- Object.defineProperty(element, "hasPointerCapture", {
14524
- configurable: true,
14525
- value: (activePointerId) => {
14526
- if (capturedPointers.has(activePointerId)) return true;
14527
- try {
14528
- return Boolean(originalHasPointerCapture?.(activePointerId));
14529
- } catch {
14530
- return false;
14531
- }
14532
- },
14533
- });
14534
- const point = (progress) => ({
14535
- clientX: rect.left + payload.start.x + (payload.end.x - payload.start.x) * progress,
14536
- clientY: rect.top + payload.start.y + (payload.end.y - payload.start.y) * progress,
14537
- });
14538
- const dispatch = (type, progress) => {
14539
- const coords = point(progress);
14540
- element.dispatchEvent(new PointerEvent(type, {
14541
- bubbles: true,
14542
- cancelable: true,
14543
- composed: true,
14544
- pointerId,
14545
- pointerType: payload.pointerType,
14546
- isPrimary: true,
14547
- buttons: type === "pointerup" ? 0 : 1,
14548
- button: type === "pointerup" ? 0 : 0,
14549
- clientX: coords.clientX,
14550
- clientY: coords.clientY,
14551
- }));
14552
- };
14553
- try {
14554
- dispatch("pointerover", 0);
14555
- dispatch("pointerenter", 0);
14556
- dispatch("pointerdown", 0);
14557
- for (let step = 1; step <= payload.steps; step += 1) {
14558
- dispatch("pointermove", step / payload.steps);
14559
- if (payload.durationMs && payload.steps > 1) await wait(payload.durationMs / payload.steps);
14511
+ const client = await page.context().newCDPSession(page);
14512
+ try {
14513
+ if (pointerType === "touch") {
14514
+ const touchPoint = (x, y) => ({
14515
+ x,
14516
+ y,
14517
+ radiusX: 1,
14518
+ radiusY: 1,
14519
+ force: 1,
14520
+ id: 11,
14521
+ });
14522
+ await client.send("Input.dispatchTouchEvent", {
14523
+ type: "touchStart",
14524
+ touchPoints: [touchPoint(start.x, start.y)],
14525
+ });
14526
+ for (let step = 1; step <= steps; step += 1) {
14527
+ const progress = step / steps;
14528
+ await client.send("Input.dispatchTouchEvent", {
14529
+ type: "touchMove",
14530
+ touchPoints: [
14531
+ touchPoint(
14532
+ start.x + (end.x - start.x) * progress,
14533
+ start.y + (end.y - start.y) * progress,
14534
+ ),
14535
+ ],
14536
+ });
14537
+ if (durationMs && steps > 1) await page.waitForTimeout(durationMs / steps);
14538
+ }
14539
+ await client.send("Input.dispatchTouchEvent", {
14540
+ type: "touchEnd",
14541
+ touchPoints: [],
14542
+ });
14543
+ } else {
14544
+ await client.send("Input.dispatchMouseEvent", {
14545
+ type: "mouseMoved",
14546
+ x: start.x,
14547
+ y: start.y,
14548
+ pointerType: "pen",
14549
+ });
14550
+ await client.send("Input.dispatchMouseEvent", {
14551
+ type: "mousePressed",
14552
+ x: start.x,
14553
+ y: start.y,
14554
+ button: "left",
14555
+ buttons: 1,
14556
+ clickCount: 1,
14557
+ pointerType: "pen",
14558
+ });
14559
+ for (let step = 1; step <= steps; step += 1) {
14560
+ const progress = step / steps;
14561
+ await client.send("Input.dispatchMouseEvent", {
14562
+ type: "mouseMoved",
14563
+ x: start.x + (end.x - start.x) * progress,
14564
+ y: start.y + (end.y - start.y) * progress,
14565
+ button: "left",
14566
+ buttons: 1,
14567
+ pointerType: "pen",
14568
+ });
14569
+ if (durationMs && steps > 1) await page.waitForTimeout(durationMs / steps);
14560
14570
  }
14561
- dispatch("pointerup", 1);
14562
- dispatch("pointerout", 1);
14563
- dispatch("pointerleave", 1);
14564
- } finally {
14565
- restorePointerCapture();
14571
+ await client.send("Input.dispatchMouseEvent", {
14572
+ type: "mouseReleased",
14573
+ x: end.x,
14574
+ y: end.y,
14575
+ button: "left",
14576
+ buttons: 0,
14577
+ clickCount: 1,
14578
+ pointerType: "pen",
14579
+ });
14566
14580
  }
14567
- }, {
14568
- pointerType,
14569
- start: localStart,
14570
- end: localEnd,
14571
- steps,
14572
- durationMs,
14573
- });
14581
+ } finally {
14582
+ await client.detach().catch(() => {});
14583
+ }
14574
14584
  } else {
14575
14585
  await page.mouse.move(start.x, start.y);
14576
14586
  await page.mouse.down();
@@ -14603,7 +14613,7 @@ async function executeSetupAction(action, ordinal, viewport) {
14603
14613
  to_x: toX,
14604
14614
  to_y: toY,
14605
14615
  pointer_type: pointerType,
14606
- pointer_capture_polyfill: pointerType === "touch" || pointerType === "pen" ? true : undefined,
14616
+ input_dispatch: pointerType === "touch" || pointerType === "pen" ? "cdp" : "playwright_mouse",
14607
14617
  steps,
14608
14618
  duration_ms: durationMs || undefined,
14609
14619
  };
package/dist/index.js CHANGED
@@ -62,7 +62,7 @@ import {
62
62
  resolveRiddleProofProfileTimeoutSec,
63
63
  slugifyRiddleProofProfileName,
64
64
  summarizeRiddleProofProfileResult
65
- } from "./chunk-ZE2U5EML.js";
65
+ } from "./chunk-RWBG7256.js";
66
66
  import {
67
67
  DEFAULT_RIDDLE_API_BASE_URL,
68
68
  DEFAULT_RIDDLE_API_KEY_FILE,
package/dist/profile.cjs CHANGED
@@ -618,6 +618,42 @@ function profileSetupCanvasSignatureReceipts(results) {
618
618
  reason: result.reason ?? result.error ?? null
619
619
  }));
620
620
  }
621
+ function profileSetupCanvasSignatureStableHashGroups(results) {
622
+ const groups = /* @__PURE__ */ new Map();
623
+ for (const receipt of profileSetupCanvasSignatureReceipts(results)) {
624
+ if (receipt.ok === false) continue;
625
+ const hash = stringValue(receipt.hash);
626
+ if (!hash) continue;
627
+ const selector = stringValue(receipt.selector) || "canvas";
628
+ const frameSelector = stringValue(receipt.frame_selector);
629
+ const key = `${frameSelector || ""}
630
+ ${selector}`;
631
+ const group = groups.get(key) || { selector, frame_selector: frameSelector, receipts: [] };
632
+ const ordinal = numberValue(receipt.ordinal);
633
+ const label = stringValue(receipt.label) || (ordinal === void 0 ? `capture-${group.receipts.length + 1}` : `#${ordinal}`);
634
+ group.receipts.push({ hash, label, ordinal });
635
+ groups.set(key, group);
636
+ }
637
+ const warnings = [];
638
+ for (const group of groups.values()) {
639
+ const hashes = new Set(group.receipts.map((receipt) => receipt.hash));
640
+ const labels = [...new Set(group.receipts.map((receipt) => receipt.label))];
641
+ if (group.receipts.length < 2 || labels.length < 2 || hashes.size !== 1) continue;
642
+ const visibleLabels = labels.slice(0, 8);
643
+ warnings.push({
644
+ selector: group.selector,
645
+ frame_selector: group.frame_selector ?? null,
646
+ hash: group.receipts[0].hash,
647
+ count: group.receipts.length,
648
+ label_count: labels.length,
649
+ labels: visibleLabels,
650
+ omitted_label_count: Math.max(0, labels.length - visibleLabels.length),
651
+ ordinals: group.receipts.map((receipt) => receipt.ordinal).filter((value) => value !== void 0).slice(0, 12),
652
+ reason: "stable_canvas_signature_hash"
653
+ });
654
+ }
655
+ return warnings;
656
+ }
621
657
  function sampleProfileSetupSummaryItems(items, limit) {
622
658
  if (items.length <= limit) return items;
623
659
  const firstCount = Math.floor(limit / 2);
@@ -718,6 +754,7 @@ function profileSetupSummary(viewports, actionCount, expectedActionCountByViewpo
718
754
  canvas_signature_total: canvasSignatureReceipts.length,
719
755
  canvas_signature_truncated: canvasSignatureReceipts.length > sampledCanvasSignatureReceipts.length,
720
756
  canvas_signature: sampledCanvasSignatureReceipts,
757
+ canvas_signature_stable_hash_groups: profileSetupCanvasSignatureStableHashGroups(results),
721
758
  clicked,
722
759
  text_samples,
723
760
  failed: failed.map((result) => ({
@@ -5785,106 +5822,79 @@ async function executeSetupAction(action, ordinal, viewport) {
5785
5822
  const durationMs = setupNumber(action.duration_ms ?? action.durationMs, 0);
5786
5823
  const pointerType = String(action.pointer_type || action.pointerType || "mouse").trim().toLowerCase();
5787
5824
  if (pointerType === "touch" || pointerType === "pen") {
5788
- const localStart = {
5789
- x: coordinate(fromX, box.width),
5790
- y: coordinate(fromY, box.height),
5791
- };
5792
- const localEnd = {
5793
- x: coordinate(toX, box.width),
5794
- y: coordinate(toY, box.height),
5795
- };
5796
- await target.evaluate(async (element, payload) => {
5797
- const wait = (ms) => new Promise((resolve) => setTimeout(resolve, ms));
5798
- const rect = element.getBoundingClientRect();
5799
- const pointerId = payload.pointerType === "touch" ? 11 : 12;
5800
- const capturedPointers = new Set();
5801
- const originalOwnSetPointerCapture = Object.getOwnPropertyDescriptor(element, "setPointerCapture");
5802
- const originalOwnReleasePointerCapture = Object.getOwnPropertyDescriptor(element, "releasePointerCapture");
5803
- const originalOwnHasPointerCapture = Object.getOwnPropertyDescriptor(element, "hasPointerCapture");
5804
- const originalSetPointerCapture = typeof element.setPointerCapture === "function" ? element.setPointerCapture.bind(element) : undefined;
5805
- const originalReleasePointerCapture = typeof element.releasePointerCapture === "function" ? element.releasePointerCapture.bind(element) : undefined;
5806
- const originalHasPointerCapture = typeof element.hasPointerCapture === "function" ? element.hasPointerCapture.bind(element) : undefined;
5807
- const restorePointerCapture = () => {
5808
- if (originalOwnSetPointerCapture) Object.defineProperty(element, "setPointerCapture", originalOwnSetPointerCapture);
5809
- else delete (element as any).setPointerCapture;
5810
- if (originalOwnReleasePointerCapture) Object.defineProperty(element, "releasePointerCapture", originalOwnReleasePointerCapture);
5811
- else delete (element as any).releasePointerCapture;
5812
- if (originalOwnHasPointerCapture) Object.defineProperty(element, "hasPointerCapture", originalOwnHasPointerCapture);
5813
- else delete (element as any).hasPointerCapture;
5814
- };
5815
- Object.defineProperty(element, "setPointerCapture", {
5816
- configurable: true,
5817
- value: (activePointerId) => {
5818
- capturedPointers.add(activePointerId);
5819
- try {
5820
- return originalSetPointerCapture?.(activePointerId);
5821
- } catch {
5822
- return undefined;
5823
- }
5824
- },
5825
- });
5826
- Object.defineProperty(element, "releasePointerCapture", {
5827
- configurable: true,
5828
- value: (activePointerId) => {
5829
- capturedPointers.delete(activePointerId);
5830
- try {
5831
- return originalReleasePointerCapture?.(activePointerId);
5832
- } catch {
5833
- return undefined;
5834
- }
5835
- },
5836
- });
5837
- Object.defineProperty(element, "hasPointerCapture", {
5838
- configurable: true,
5839
- value: (activePointerId) => {
5840
- if (capturedPointers.has(activePointerId)) return true;
5841
- try {
5842
- return Boolean(originalHasPointerCapture?.(activePointerId));
5843
- } catch {
5844
- return false;
5845
- }
5846
- },
5847
- });
5848
- const point = (progress) => ({
5849
- clientX: rect.left + payload.start.x + (payload.end.x - payload.start.x) * progress,
5850
- clientY: rect.top + payload.start.y + (payload.end.y - payload.start.y) * progress,
5851
- });
5852
- const dispatch = (type, progress) => {
5853
- const coords = point(progress);
5854
- element.dispatchEvent(new PointerEvent(type, {
5855
- bubbles: true,
5856
- cancelable: true,
5857
- composed: true,
5858
- pointerId,
5859
- pointerType: payload.pointerType,
5860
- isPrimary: true,
5861
- buttons: type === "pointerup" ? 0 : 1,
5862
- button: type === "pointerup" ? 0 : 0,
5863
- clientX: coords.clientX,
5864
- clientY: coords.clientY,
5865
- }));
5866
- };
5867
- try {
5868
- dispatch("pointerover", 0);
5869
- dispatch("pointerenter", 0);
5870
- dispatch("pointerdown", 0);
5871
- for (let step = 1; step <= payload.steps; step += 1) {
5872
- dispatch("pointermove", step / payload.steps);
5873
- if (payload.durationMs && payload.steps > 1) await wait(payload.durationMs / payload.steps);
5825
+ const client = await page.context().newCDPSession(page);
5826
+ try {
5827
+ if (pointerType === "touch") {
5828
+ const touchPoint = (x, y) => ({
5829
+ x,
5830
+ y,
5831
+ radiusX: 1,
5832
+ radiusY: 1,
5833
+ force: 1,
5834
+ id: 11,
5835
+ });
5836
+ await client.send("Input.dispatchTouchEvent", {
5837
+ type: "touchStart",
5838
+ touchPoints: [touchPoint(start.x, start.y)],
5839
+ });
5840
+ for (let step = 1; step <= steps; step += 1) {
5841
+ const progress = step / steps;
5842
+ await client.send("Input.dispatchTouchEvent", {
5843
+ type: "touchMove",
5844
+ touchPoints: [
5845
+ touchPoint(
5846
+ start.x + (end.x - start.x) * progress,
5847
+ start.y + (end.y - start.y) * progress,
5848
+ ),
5849
+ ],
5850
+ });
5851
+ if (durationMs && steps > 1) await page.waitForTimeout(durationMs / steps);
5874
5852
  }
5875
- dispatch("pointerup", 1);
5876
- dispatch("pointerout", 1);
5877
- dispatch("pointerleave", 1);
5878
- } finally {
5879
- restorePointerCapture();
5853
+ await client.send("Input.dispatchTouchEvent", {
5854
+ type: "touchEnd",
5855
+ touchPoints: [],
5856
+ });
5857
+ } else {
5858
+ await client.send("Input.dispatchMouseEvent", {
5859
+ type: "mouseMoved",
5860
+ x: start.x,
5861
+ y: start.y,
5862
+ pointerType: "pen",
5863
+ });
5864
+ await client.send("Input.dispatchMouseEvent", {
5865
+ type: "mousePressed",
5866
+ x: start.x,
5867
+ y: start.y,
5868
+ button: "left",
5869
+ buttons: 1,
5870
+ clickCount: 1,
5871
+ pointerType: "pen",
5872
+ });
5873
+ for (let step = 1; step <= steps; step += 1) {
5874
+ const progress = step / steps;
5875
+ await client.send("Input.dispatchMouseEvent", {
5876
+ type: "mouseMoved",
5877
+ x: start.x + (end.x - start.x) * progress,
5878
+ y: start.y + (end.y - start.y) * progress,
5879
+ button: "left",
5880
+ buttons: 1,
5881
+ pointerType: "pen",
5882
+ });
5883
+ if (durationMs && steps > 1) await page.waitForTimeout(durationMs / steps);
5884
+ }
5885
+ await client.send("Input.dispatchMouseEvent", {
5886
+ type: "mouseReleased",
5887
+ x: end.x,
5888
+ y: end.y,
5889
+ button: "left",
5890
+ buttons: 0,
5891
+ clickCount: 1,
5892
+ pointerType: "pen",
5893
+ });
5880
5894
  }
5881
- }, {
5882
- pointerType,
5883
- start: localStart,
5884
- end: localEnd,
5885
- steps,
5886
- durationMs,
5887
- });
5895
+ } finally {
5896
+ await client.detach().catch(() => {});
5897
+ }
5888
5898
  } else {
5889
5899
  await page.mouse.move(start.x, start.y);
5890
5900
  await page.mouse.down();
@@ -5917,7 +5927,7 @@ async function executeSetupAction(action, ordinal, viewport) {
5917
5927
  to_x: toX,
5918
5928
  to_y: toY,
5919
5929
  pointer_type: pointerType,
5920
- pointer_capture_polyfill: pointerType === "touch" || pointerType === "pen" ? true : undefined,
5930
+ input_dispatch: pointerType === "touch" || pointerType === "pen" ? "cdp" : "playwright_mouse",
5921
5931
  steps,
5922
5932
  duration_ms: durationMs || undefined,
5923
5933
  };
package/dist/profile.js CHANGED
@@ -23,7 +23,7 @@ import {
23
23
  resolveRiddleProofProfileTimeoutSec,
24
24
  slugifyRiddleProofProfileName,
25
25
  summarizeRiddleProofProfileResult
26
- } from "./chunk-ZE2U5EML.js";
26
+ } from "./chunk-RWBG7256.js";
27
27
  export {
28
28
  RIDDLE_PROOF_PROFILE_CHECK_TYPES,
29
29
  RIDDLE_PROOF_PROFILE_EVIDENCE_VERSION,
@@ -292,7 +292,7 @@ declare function executeWorkflow(params: WorkflowParams, pluginConfig: any, reso
292
292
  blocking?: boolean;
293
293
  details?: Record<string, unknown>;
294
294
  ok: boolean;
295
- action: "setup" | "recon" | "author" | "implement" | "verify" | "ship" | "run";
295
+ action: "author" | "recon" | "ship" | "implement" | "verify" | "setup" | "run";
296
296
  state_path: string;
297
297
  stage: any;
298
298
  summary: string;
@@ -382,7 +382,7 @@ declare function executeWorkflow(params: WorkflowParams, pluginConfig: any, reso
382
382
  continueWithStage?: WorkflowStage | null;
383
383
  blocking?: boolean;
384
384
  details?: Record<string, unknown>;
385
- action: "setup" | "recon" | "author" | "implement" | "verify" | "ship" | "run";
385
+ action: "author" | "recon" | "ship" | "implement" | "verify" | "setup" | "run";
386
386
  state_path: string;
387
387
  stage: any;
388
388
  checkpoint: string;
@@ -659,7 +659,7 @@ declare function executeWorkflow(params: WorkflowParams, pluginConfig: any, reso
659
659
  error?: undefined;
660
660
  } | {
661
661
  ok: boolean;
662
- action: "setup" | "recon" | "author" | "implement" | "verify" | "ship" | "run";
662
+ action: "author" | "recon" | "ship" | "implement" | "verify" | "setup" | "run";
663
663
  state_path: string;
664
664
  stage: any;
665
665
  summary: string;
@@ -292,7 +292,7 @@ declare function executeWorkflow(params: WorkflowParams, pluginConfig: any, reso
292
292
  blocking?: boolean;
293
293
  details?: Record<string, unknown>;
294
294
  ok: boolean;
295
- action: "setup" | "recon" | "author" | "implement" | "verify" | "ship" | "run";
295
+ action: "author" | "recon" | "ship" | "implement" | "verify" | "setup" | "run";
296
296
  state_path: string;
297
297
  stage: any;
298
298
  summary: string;
@@ -382,7 +382,7 @@ declare function executeWorkflow(params: WorkflowParams, pluginConfig: any, reso
382
382
  continueWithStage?: WorkflowStage | null;
383
383
  blocking?: boolean;
384
384
  details?: Record<string, unknown>;
385
- action: "setup" | "recon" | "author" | "implement" | "verify" | "ship" | "run";
385
+ action: "author" | "recon" | "ship" | "implement" | "verify" | "setup" | "run";
386
386
  state_path: string;
387
387
  stage: any;
388
388
  checkpoint: string;
@@ -659,7 +659,7 @@ declare function executeWorkflow(params: WorkflowParams, pluginConfig: any, reso
659
659
  error?: undefined;
660
660
  } | {
661
661
  ok: boolean;
662
- action: "setup" | "recon" | "author" | "implement" | "verify" | "ship" | "run";
662
+ action: "author" | "recon" | "ship" | "implement" | "verify" | "setup" | "run";
663
663
  state_path: string;
664
664
  stage: any;
665
665
  summary: string;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@riddledc/riddle-proof",
3
- "version": "0.7.161",
3
+ "version": "0.7.163",
4
4
  "description": "Reusable Riddle Proof contracts and helpers for evidence-backed agent changes.",
5
5
  "license": "MIT",
6
6
  "author": "RiddleDC",