@riddledc/riddle-proof 0.7.166 → 0.7.168

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.
@@ -624,6 +624,54 @@ function profileSetupCanvasSignatureStableHashGroups(results) {
624
624
  }
625
625
  return warnings;
626
626
  }
627
+ function profileSetupClickSequenceReceipts(clickedItems) {
628
+ const nthChildPattern = /:nth-child\((\d+)\)/;
629
+ const nthChildTemplatePattern = /:nth-child\(\d+\)/g;
630
+ const groups = /* @__PURE__ */ new Map();
631
+ for (const item of clickedItems) {
632
+ const selector = stringValue(item.selector);
633
+ if (!selector) continue;
634
+ const match = nthChildPattern.exec(selector);
635
+ if (!match) continue;
636
+ const frameSelector = stringValue(item.frame_selector);
637
+ const selectorTemplate = selector.replace(nthChildTemplatePattern, ":nth-child(*)");
638
+ const key = `${frameSelector || ""}
639
+ ${selectorTemplate}`;
640
+ const group = groups.get(key) || {
641
+ selector_template: selectorTemplate,
642
+ frame_selector: frameSelector,
643
+ value_source: "nth-child",
644
+ sequence: [],
645
+ ordinals: [],
646
+ result_count: 0,
647
+ click_total: 0
648
+ };
649
+ const value = Number(match[1]);
650
+ const clickCountValue = numberValue(item.click_count);
651
+ const clickCount = clickCountValue === void 0 ? 1 : Math.max(1, Math.min(100, Math.floor(clickCountValue)));
652
+ for (let index = 0; index < clickCount; index += 1) group.sequence.push(value);
653
+ const ordinal = numberValue(item.ordinal);
654
+ if (ordinal !== void 0) group.ordinals.push(ordinal);
655
+ group.result_count += 1;
656
+ group.click_total += clickCount;
657
+ groups.set(key, group);
658
+ }
659
+ return [...groups.values()].filter((group) => group.result_count >= 4).map((group) => {
660
+ const sequence = group.sequence.slice(0, 32);
661
+ const ordinals = group.ordinals.slice(0, 16);
662
+ return {
663
+ selector_template: group.selector_template,
664
+ frame_selector: group.frame_selector ?? null,
665
+ value_source: group.value_source,
666
+ result_count: group.result_count,
667
+ click_total: group.click_total,
668
+ sequence,
669
+ omitted_sequence_count: Math.max(0, group.sequence.length - sequence.length),
670
+ ordinals,
671
+ omitted_ordinal_count: Math.max(0, group.ordinals.length - ordinals.length)
672
+ };
673
+ });
674
+ }
627
675
  function sampleProfileSetupSummaryItems(items, limit) {
628
676
  if (items.length <= limit) return items;
629
677
  const firstCount = Math.floor(limit / 2);
@@ -683,6 +731,8 @@ function profileSetupSummary(viewports, actionCount, expectedActionCountByViewpo
683
731
  };
684
732
  });
685
733
  const clicked = sampleProfileSetupSummaryItems(clickedItems, 8);
734
+ const clickSequences = profileSetupClickSequenceReceipts(clickedItems);
735
+ const sampledClickSequences = sampleProfileSetupSummaryItems(clickSequences, 6);
686
736
  const text_samples = results.filter((result) => result.ok !== false && typeof result.text === "string" && (profileSetupResultAction(result) === "assert_text_visible" || profileSetupResultAction(result) === "assert_text_absent" || profileSetupResultAction(result) === "wait_for_text")).map((result) => ({
687
737
  ordinal: result.ordinal ?? null,
688
738
  action: profileSetupResultAction(result),
@@ -704,6 +754,9 @@ function profileSetupSummary(viewports, actionCount, expectedActionCountByViewpo
704
754
  setup_screenshots: profileSetupScreenshotLabels(results),
705
755
  clicked_total: clickedItems.length,
706
756
  clicked_truncated: clickedItems.length > clicked.length,
757
+ click_sequence_total: clickSequences.length,
758
+ click_sequence_truncated: clickSequences.length > sampledClickSequences.length,
759
+ click_sequences: sampledClickSequences,
707
760
  click_count_action_total: clickCountValues.length,
708
761
  click_count_value_total: clickCountValues.reduce((sum, value) => sum + value, 0),
709
762
  window_call_until_total: windowCallUntilReceipts.length,
@@ -3052,17 +3105,6 @@ function assessSetupActionsFromEvidence(profile, evidence) {
3052
3105
  const failed = [];
3053
3106
  const viewports = evidence.viewports || [];
3054
3107
  const expectedActionCountByViewport = /* @__PURE__ */ new Map();
3055
- const capturedViewportNames = new Set(viewports.map((viewport) => viewport.name));
3056
- for (const action of profile.target.setup_actions) {
3057
- if (action.viewports?.length && !action.viewports.some((name) => capturedViewportNames.has(name))) {
3058
- failed.push({
3059
- viewport: null,
3060
- action: action.type,
3061
- selector: action.selector ?? null,
3062
- reason: `setup action scoped to missing viewport(s): ${action.viewports.join(", ")}`
3063
- });
3064
- }
3065
- }
3066
3108
  for (const viewport of viewports) {
3067
3109
  const expectedActionCount = setupActionsForViewport(profile.target.setup_actions, viewport.name).length;
3068
3110
  expectedActionCountByViewport.set(viewport.name, expectedActionCount);
@@ -4288,6 +4330,55 @@ function profileSetupCanvasSignatureStableHashGroups(results) {
4288
4330
  }
4289
4331
  return warnings;
4290
4332
  }
4333
+ function profileSetupClickSequenceReceipts(clickedItems) {
4334
+ const nthChildPattern = /:nth-child\((\d+)\)/;
4335
+ const nthChildTemplatePattern = /:nth-child\(\d+\)/g;
4336
+ const groups = new Map();
4337
+ for (const item of clickedItems || []) {
4338
+ const selector = typeof item.selector === "string" && item.selector.trim() ? item.selector.trim() : undefined;
4339
+ if (!selector) continue;
4340
+ const match = nthChildPattern.exec(selector);
4341
+ if (!match) continue;
4342
+ const frameSelector = typeof item.frame_selector === "string" && item.frame_selector.trim() ? item.frame_selector.trim() : undefined;
4343
+ const selectorTemplate = selector.replace(nthChildTemplatePattern, ":nth-child(*)");
4344
+ const key = String(frameSelector || "") + "\\n" + selectorTemplate;
4345
+ const group = groups.get(key) || {
4346
+ selector_template: selectorTemplate,
4347
+ frame_selector: frameSelector,
4348
+ value_source: "nth-child",
4349
+ sequence: [],
4350
+ ordinals: [],
4351
+ result_count: 0,
4352
+ click_total: 0,
4353
+ };
4354
+ const value = Number(match[1]);
4355
+ const clickCountValue = typeof item.click_count === "number" && Number.isFinite(item.click_count) ? item.click_count : undefined;
4356
+ const clickCount = clickCountValue === undefined ? 1 : Math.max(1, Math.min(100, Math.floor(clickCountValue)));
4357
+ for (let index = 0; index < clickCount; index += 1) group.sequence.push(value);
4358
+ const ordinal = typeof item.ordinal === "number" && Number.isFinite(item.ordinal) ? item.ordinal : undefined;
4359
+ if (ordinal !== undefined) group.ordinals.push(ordinal);
4360
+ group.result_count += 1;
4361
+ group.click_total += clickCount;
4362
+ groups.set(key, group);
4363
+ }
4364
+ return [...groups.values()]
4365
+ .filter((group) => group.result_count >= 4)
4366
+ .map((group) => {
4367
+ const sequence = group.sequence.slice(0, 32);
4368
+ const ordinals = group.ordinals.slice(0, 16);
4369
+ return {
4370
+ selector_template: group.selector_template,
4371
+ frame_selector: group.frame_selector || null,
4372
+ value_source: group.value_source,
4373
+ result_count: group.result_count,
4374
+ click_total: group.click_total,
4375
+ sequence,
4376
+ omitted_sequence_count: Math.max(0, group.sequence.length - sequence.length),
4377
+ ordinals,
4378
+ omitted_ordinal_count: Math.max(0, group.ordinals.length - ordinals.length),
4379
+ };
4380
+ });
4381
+ }
4291
4382
  function sampleProfileSetupSummaryItems(items, limit) {
4292
4383
  if ((items || []).length <= limit) return items || [];
4293
4384
  const firstCount = Math.floor(limit / 2);
@@ -4363,6 +4454,8 @@ function profileSetupSummary(viewports, actionCount, expectedActionCountsByViewp
4363
4454
  };
4364
4455
  });
4365
4456
  const clicked = sampleProfileSetupSummaryItems(clickedItems, 8);
4457
+ const clickSequences = profileSetupClickSequenceReceipts(clickedItems);
4458
+ const sampledClickSequences = sampleProfileSetupSummaryItems(clickSequences, 6);
4366
4459
  const textSamples = results
4367
4460
  .filter((result) => result && result.ok !== false && typeof result.text === "string" && (
4368
4461
  profileSetupResultAction(result) === "assert_text_visible"
@@ -4392,6 +4485,9 @@ function profileSetupSummary(viewports, actionCount, expectedActionCountsByViewp
4392
4485
  setup_screenshots: profileSetupScreenshotLabels(results),
4393
4486
  clicked_total: clickedItems.length,
4394
4487
  clicked_truncated: clickedItems.length > clicked.length,
4488
+ click_sequence_total: clickSequences.length,
4489
+ click_sequence_truncated: clickSequences.length > sampledClickSequences.length,
4490
+ click_sequences: sampledClickSequences,
4395
4491
  click_count_action_total: clickCountValues.length,
4396
4492
  click_count_value_total: clickCountValues.reduce((sum, value) => sum + value, 0),
4397
4493
  window_call_until_total: windowCallUntilReceipts.length,
@@ -4539,17 +4635,6 @@ function assessProfile(profile, evidence) {
4539
4635
  const actionCount = profile.target.setup_actions.length;
4540
4636
  const failed = [];
4541
4637
  const expectedActionCountsByViewport = {};
4542
- const capturedViewportNames = new Set(viewports.map((viewport) => viewport.name));
4543
- for (const action of profile.target.setup_actions) {
4544
- if (Array.isArray(action.viewports) && action.viewports.length && !action.viewports.some((name) => capturedViewportNames.has(name))) {
4545
- failed.push({
4546
- viewport: null,
4547
- action: action.type,
4548
- selector: action.selector || null,
4549
- reason: "setup action scoped to missing viewport(s): " + action.viewports.join(", "),
4550
- });
4551
- }
4552
- }
4553
4638
  for (const viewport of viewports) {
4554
4639
  const expectedActionCount = setupActionsForViewport(profile.target.setup_actions, viewport.name).length;
4555
4640
  expectedActionCountsByViewport[viewport.name] = expectedActionCount;
package/dist/cli.cjs CHANGED
@@ -7581,6 +7581,54 @@ function profileSetupCanvasSignatureStableHashGroups(results) {
7581
7581
  }
7582
7582
  return warnings;
7583
7583
  }
7584
+ function profileSetupClickSequenceReceipts(clickedItems) {
7585
+ const nthChildPattern = /:nth-child\((\d+)\)/;
7586
+ const nthChildTemplatePattern = /:nth-child\(\d+\)/g;
7587
+ const groups = /* @__PURE__ */ new Map();
7588
+ for (const item of clickedItems) {
7589
+ const selector = stringValue2(item.selector);
7590
+ if (!selector) continue;
7591
+ const match = nthChildPattern.exec(selector);
7592
+ if (!match) continue;
7593
+ const frameSelector = stringValue2(item.frame_selector);
7594
+ const selectorTemplate = selector.replace(nthChildTemplatePattern, ":nth-child(*)");
7595
+ const key = `${frameSelector || ""}
7596
+ ${selectorTemplate}`;
7597
+ const group = groups.get(key) || {
7598
+ selector_template: selectorTemplate,
7599
+ frame_selector: frameSelector,
7600
+ value_source: "nth-child",
7601
+ sequence: [],
7602
+ ordinals: [],
7603
+ result_count: 0,
7604
+ click_total: 0
7605
+ };
7606
+ const value = Number(match[1]);
7607
+ const clickCountValue = numberValue(item.click_count);
7608
+ const clickCount = clickCountValue === void 0 ? 1 : Math.max(1, Math.min(100, Math.floor(clickCountValue)));
7609
+ for (let index = 0; index < clickCount; index += 1) group.sequence.push(value);
7610
+ const ordinal = numberValue(item.ordinal);
7611
+ if (ordinal !== void 0) group.ordinals.push(ordinal);
7612
+ group.result_count += 1;
7613
+ group.click_total += clickCount;
7614
+ groups.set(key, group);
7615
+ }
7616
+ return [...groups.values()].filter((group) => group.result_count >= 4).map((group) => {
7617
+ const sequence = group.sequence.slice(0, 32);
7618
+ const ordinals = group.ordinals.slice(0, 16);
7619
+ return {
7620
+ selector_template: group.selector_template,
7621
+ frame_selector: group.frame_selector ?? null,
7622
+ value_source: group.value_source,
7623
+ result_count: group.result_count,
7624
+ click_total: group.click_total,
7625
+ sequence,
7626
+ omitted_sequence_count: Math.max(0, group.sequence.length - sequence.length),
7627
+ ordinals,
7628
+ omitted_ordinal_count: Math.max(0, group.ordinals.length - ordinals.length)
7629
+ };
7630
+ });
7631
+ }
7584
7632
  function sampleProfileSetupSummaryItems(items, limit) {
7585
7633
  if (items.length <= limit) return items;
7586
7634
  const firstCount = Math.floor(limit / 2);
@@ -7640,6 +7688,8 @@ function profileSetupSummary(viewports, actionCount, expectedActionCountByViewpo
7640
7688
  };
7641
7689
  });
7642
7690
  const clicked = sampleProfileSetupSummaryItems(clickedItems, 8);
7691
+ const clickSequences = profileSetupClickSequenceReceipts(clickedItems);
7692
+ const sampledClickSequences = sampleProfileSetupSummaryItems(clickSequences, 6);
7643
7693
  const text_samples = results.filter((result) => result.ok !== false && typeof result.text === "string" && (profileSetupResultAction(result) === "assert_text_visible" || profileSetupResultAction(result) === "assert_text_absent" || profileSetupResultAction(result) === "wait_for_text")).map((result) => ({
7644
7694
  ordinal: result.ordinal ?? null,
7645
7695
  action: profileSetupResultAction(result),
@@ -7661,6 +7711,9 @@ function profileSetupSummary(viewports, actionCount, expectedActionCountByViewpo
7661
7711
  setup_screenshots: profileSetupScreenshotLabels(results),
7662
7712
  clicked_total: clickedItems.length,
7663
7713
  clicked_truncated: clickedItems.length > clicked.length,
7714
+ click_sequence_total: clickSequences.length,
7715
+ click_sequence_truncated: clickSequences.length > sampledClickSequences.length,
7716
+ click_sequences: sampledClickSequences,
7664
7717
  click_count_action_total: clickCountValues.length,
7665
7718
  click_count_value_total: clickCountValues.reduce((sum, value) => sum + value, 0),
7666
7719
  window_call_until_total: windowCallUntilReceipts.length,
@@ -10009,17 +10062,6 @@ function assessSetupActionsFromEvidence(profile, evidence) {
10009
10062
  const failed = [];
10010
10063
  const viewports = evidence.viewports || [];
10011
10064
  const expectedActionCountByViewport = /* @__PURE__ */ new Map();
10012
- const capturedViewportNames = new Set(viewports.map((viewport) => viewport.name));
10013
- for (const action of profile.target.setup_actions) {
10014
- if (action.viewports?.length && !action.viewports.some((name) => capturedViewportNames.has(name))) {
10015
- failed.push({
10016
- viewport: null,
10017
- action: action.type,
10018
- selector: action.selector ?? null,
10019
- reason: `setup action scoped to missing viewport(s): ${action.viewports.join(", ")}`
10020
- });
10021
- }
10022
- }
10023
10065
  for (const viewport of viewports) {
10024
10066
  const expectedActionCount = setupActionsForViewport(profile.target.setup_actions, viewport.name).length;
10025
10067
  expectedActionCountByViewport.set(viewport.name, expectedActionCount);
@@ -11229,6 +11271,55 @@ function profileSetupCanvasSignatureStableHashGroups(results) {
11229
11271
  }
11230
11272
  return warnings;
11231
11273
  }
11274
+ function profileSetupClickSequenceReceipts(clickedItems) {
11275
+ const nthChildPattern = /:nth-child\((\d+)\)/;
11276
+ const nthChildTemplatePattern = /:nth-child\(\d+\)/g;
11277
+ const groups = new Map();
11278
+ for (const item of clickedItems || []) {
11279
+ const selector = typeof item.selector === "string" && item.selector.trim() ? item.selector.trim() : undefined;
11280
+ if (!selector) continue;
11281
+ const match = nthChildPattern.exec(selector);
11282
+ if (!match) continue;
11283
+ const frameSelector = typeof item.frame_selector === "string" && item.frame_selector.trim() ? item.frame_selector.trim() : undefined;
11284
+ const selectorTemplate = selector.replace(nthChildTemplatePattern, ":nth-child(*)");
11285
+ const key = String(frameSelector || "") + "\\n" + selectorTemplate;
11286
+ const group = groups.get(key) || {
11287
+ selector_template: selectorTemplate,
11288
+ frame_selector: frameSelector,
11289
+ value_source: "nth-child",
11290
+ sequence: [],
11291
+ ordinals: [],
11292
+ result_count: 0,
11293
+ click_total: 0,
11294
+ };
11295
+ const value = Number(match[1]);
11296
+ const clickCountValue = typeof item.click_count === "number" && Number.isFinite(item.click_count) ? item.click_count : undefined;
11297
+ const clickCount = clickCountValue === undefined ? 1 : Math.max(1, Math.min(100, Math.floor(clickCountValue)));
11298
+ for (let index = 0; index < clickCount; index += 1) group.sequence.push(value);
11299
+ const ordinal = typeof item.ordinal === "number" && Number.isFinite(item.ordinal) ? item.ordinal : undefined;
11300
+ if (ordinal !== undefined) group.ordinals.push(ordinal);
11301
+ group.result_count += 1;
11302
+ group.click_total += clickCount;
11303
+ groups.set(key, group);
11304
+ }
11305
+ return [...groups.values()]
11306
+ .filter((group) => group.result_count >= 4)
11307
+ .map((group) => {
11308
+ const sequence = group.sequence.slice(0, 32);
11309
+ const ordinals = group.ordinals.slice(0, 16);
11310
+ return {
11311
+ selector_template: group.selector_template,
11312
+ frame_selector: group.frame_selector || null,
11313
+ value_source: group.value_source,
11314
+ result_count: group.result_count,
11315
+ click_total: group.click_total,
11316
+ sequence,
11317
+ omitted_sequence_count: Math.max(0, group.sequence.length - sequence.length),
11318
+ ordinals,
11319
+ omitted_ordinal_count: Math.max(0, group.ordinals.length - ordinals.length),
11320
+ };
11321
+ });
11322
+ }
11232
11323
  function sampleProfileSetupSummaryItems(items, limit) {
11233
11324
  if ((items || []).length <= limit) return items || [];
11234
11325
  const firstCount = Math.floor(limit / 2);
@@ -11304,6 +11395,8 @@ function profileSetupSummary(viewports, actionCount, expectedActionCountsByViewp
11304
11395
  };
11305
11396
  });
11306
11397
  const clicked = sampleProfileSetupSummaryItems(clickedItems, 8);
11398
+ const clickSequences = profileSetupClickSequenceReceipts(clickedItems);
11399
+ const sampledClickSequences = sampleProfileSetupSummaryItems(clickSequences, 6);
11307
11400
  const textSamples = results
11308
11401
  .filter((result) => result && result.ok !== false && typeof result.text === "string" && (
11309
11402
  profileSetupResultAction(result) === "assert_text_visible"
@@ -11333,6 +11426,9 @@ function profileSetupSummary(viewports, actionCount, expectedActionCountsByViewp
11333
11426
  setup_screenshots: profileSetupScreenshotLabels(results),
11334
11427
  clicked_total: clickedItems.length,
11335
11428
  clicked_truncated: clickedItems.length > clicked.length,
11429
+ click_sequence_total: clickSequences.length,
11430
+ click_sequence_truncated: clickSequences.length > sampledClickSequences.length,
11431
+ click_sequences: sampledClickSequences,
11336
11432
  click_count_action_total: clickCountValues.length,
11337
11433
  click_count_value_total: clickCountValues.reduce((sum, value) => sum + value, 0),
11338
11434
  window_call_until_total: windowCallUntilReceipts.length,
@@ -11480,17 +11576,6 @@ function assessProfile(profile, evidence) {
11480
11576
  const actionCount = profile.target.setup_actions.length;
11481
11577
  const failed = [];
11482
11578
  const expectedActionCountsByViewport = {};
11483
- const capturedViewportNames = new Set(viewports.map((viewport) => viewport.name));
11484
- for (const action of profile.target.setup_actions) {
11485
- if (Array.isArray(action.viewports) && action.viewports.length && !action.viewports.some((name) => capturedViewportNames.has(name))) {
11486
- failed.push({
11487
- viewport: null,
11488
- action: action.type,
11489
- selector: action.selector || null,
11490
- reason: "setup action scoped to missing viewport(s): " + action.viewports.join(", "),
11491
- });
11492
- }
11493
- }
11494
11579
  for (const viewport of viewports) {
11495
11580
  const expectedActionCount = setupActionsForViewport(profile.target.setup_actions, viewport.name).length;
11496
11581
  expectedActionCountsByViewport[viewport.name] = expectedActionCount;
@@ -15943,6 +16028,7 @@ function profileSetupSummaryMarkdown(result) {
15943
16028
  return sum + labels.filter((label) => typeof label === "string" && label.trim()).length;
15944
16029
  }, 0);
15945
16030
  const clickedTotal = viewports.reduce((sum, viewport) => sum + (cliFiniteNumber(viewport.clicked_total) || 0), 0);
16031
+ const clickSequenceTotal = viewports.reduce((sum, viewport) => sum + (cliFiniteNumber(viewport.click_sequence_total) || 0), 0);
15946
16032
  const clickCountActionTotal = viewports.reduce((sum, viewport) => sum + (cliFiniteNumber(viewport.click_count_action_total) || 0), 0);
15947
16033
  const clickCountValueTotal = viewports.reduce((sum, viewport) => sum + (cliFiniteNumber(viewport.click_count_value_total) || 0), 0);
15948
16034
  const windowCallTotal = viewports.reduce((sum, viewport) => sum + (cliFiniteNumber(viewport.window_call_total) || 0), 0);
@@ -15966,6 +16052,9 @@ function profileSetupSummaryMarkdown(result) {
15966
16052
  if (clickCountActionTotal) {
15967
16053
  lines.push(`- click counts: ${clickCountActionTotal} action(s), click_count total ${clickCountValueTotal}`);
15968
16054
  }
16055
+ if (clickSequenceTotal) {
16056
+ lines.push(`- click sequences: ${clickSequenceTotal} group(s)`);
16057
+ }
15969
16058
  if (windowCallTotal) {
15970
16059
  lines.push(`- window_call: ${windowCallTotal} action(s), stored returns ${windowCallStoredTotal}, captured returns ${windowCallCapturedTotal}`);
15971
16060
  }
@@ -15990,6 +16079,7 @@ function profileSetupSummaryMarkdown(result) {
15990
16079
  const resultCount = cliFiniteNumber(viewport.result_count) || 0;
15991
16080
  const screenshotCount = Array.isArray(viewport.setup_screenshots) ? viewport.setup_screenshots.filter((label) => typeof label === "string" && label.trim()).length : 0;
15992
16081
  const clicked = cliFiniteNumber(viewport.clicked_total) || 0;
16082
+ const clickSequenceCount = cliFiniteNumber(viewport.click_sequence_total) || 0;
15993
16083
  const clickCountActions = cliFiniteNumber(viewport.click_count_action_total) || 0;
15994
16084
  const windowCallActions = cliFiniteNumber(viewport.window_call_total) || 0;
15995
16085
  const windowCallStored = cliFiniteNumber(viewport.window_call_stored_total) || 0;
@@ -16003,8 +16093,28 @@ function profileSetupSummaryMarkdown(result) {
16003
16093
  const dragActions = cliFiniteNumber(viewport.drag_total) || 0;
16004
16094
  const canvasSignatureActions = cliFiniteNumber(viewport.canvas_signature_total) || 0;
16005
16095
  const observedPath = cliString(viewport.observed_path);
16006
- lines.push(`- ${name}: ${ok}, ${resultCount} result(s), ${screenshotCount} setup screenshot(s), ${clicked} click(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)` : ""}${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}` : ""}`);
16096
+ 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)` : ""}${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}` : ""}`);
16007
16097
  }
16098
+ const clickSequenceGroups = viewports.map((viewport) => {
16099
+ const name = cliString(viewport.name) || "viewport";
16100
+ const receipts = Array.isArray(viewport.click_sequences) ? viewport.click_sequences.map(cliRecord).filter((item) => Boolean(item)) : [];
16101
+ return receipts.map((receipt) => ({ name, receipt }));
16102
+ });
16103
+ const clickSequenceDetails = clickSequenceGroups.flat();
16104
+ const sampledClickSequenceDetails = balancedSetupReceiptDetails(clickSequenceGroups, 12);
16105
+ for (const { name, receipt } of sampledClickSequenceDetails) {
16106
+ const selectorTemplate = cliString(receipt.selector_template) || "target";
16107
+ const valueSource = cliString(receipt.value_source);
16108
+ const sequence = Array.isArray(receipt.sequence) ? receipt.sequence.map((value) => cliFiniteNumber(value)).filter((value) => value !== void 0) : [];
16109
+ const sequenceText = sequence.join(",");
16110
+ const omittedSequenceCount = cliFiniteNumber(receipt.omitted_sequence_count) || 0;
16111
+ const clickTotal = cliFiniteNumber(receipt.click_total);
16112
+ const resultCount = cliFiniteNumber(receipt.result_count);
16113
+ const ordinals = Array.isArray(receipt.ordinals) ? receipt.ordinals.map((value) => cliFiniteNumber(value)).filter((value) => value !== void 0) : [];
16114
+ const ordinalText = ordinals.length ? ordinals.join(",") : "";
16115
+ lines.push(`- ${name} click_sequence: ${markdownInlineCode(selectorTemplate)}${valueSource ? ` ${valueSource}` : ""}${sequenceText ? ` sequence ${markdownInlineCode(sequenceText, 160)}` : ""}${omittedSequenceCount ? ` (+${omittedSequenceCount} omitted)` : ""}${clickTotal === void 0 ? "" : `, clicks ${clickTotal}`}${resultCount === void 0 ? "" : `, results ${resultCount}`}${ordinalText ? `, ordinals ${markdownInlineCode(ordinalText, 120)}` : ""}`);
16116
+ }
16117
+ if (clickSequenceDetails.length > sampledClickSequenceDetails.length) lines.push(`- ${clickSequenceDetails.length - sampledClickSequenceDetails.length} additional click_sequence receipt(s) omitted.`);
16008
16118
  const dragGroups = viewports.map((viewport) => {
16009
16119
  const name = cliString(viewport.name) || "viewport";
16010
16120
  const receipts = Array.isArray(viewport.drag) ? viewport.drag.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-L6WJP5IY.js";
16
+ } from "./chunk-U56YGC5K.js";
17
17
  import {
18
18
  createRiddleApiClient,
19
19
  isTerminalRiddleJobStatus,
@@ -776,6 +776,7 @@ function profileSetupSummaryMarkdown(result) {
776
776
  return sum + labels.filter((label) => typeof label === "string" && label.trim()).length;
777
777
  }, 0);
778
778
  const clickedTotal = viewports.reduce((sum, viewport) => sum + (cliFiniteNumber(viewport.clicked_total) || 0), 0);
779
+ const clickSequenceTotal = viewports.reduce((sum, viewport) => sum + (cliFiniteNumber(viewport.click_sequence_total) || 0), 0);
779
780
  const clickCountActionTotal = viewports.reduce((sum, viewport) => sum + (cliFiniteNumber(viewport.click_count_action_total) || 0), 0);
780
781
  const clickCountValueTotal = viewports.reduce((sum, viewport) => sum + (cliFiniteNumber(viewport.click_count_value_total) || 0), 0);
781
782
  const windowCallTotal = viewports.reduce((sum, viewport) => sum + (cliFiniteNumber(viewport.window_call_total) || 0), 0);
@@ -799,6 +800,9 @@ function profileSetupSummaryMarkdown(result) {
799
800
  if (clickCountActionTotal) {
800
801
  lines.push(`- click counts: ${clickCountActionTotal} action(s), click_count total ${clickCountValueTotal}`);
801
802
  }
803
+ if (clickSequenceTotal) {
804
+ lines.push(`- click sequences: ${clickSequenceTotal} group(s)`);
805
+ }
802
806
  if (windowCallTotal) {
803
807
  lines.push(`- window_call: ${windowCallTotal} action(s), stored returns ${windowCallStoredTotal}, captured returns ${windowCallCapturedTotal}`);
804
808
  }
@@ -823,6 +827,7 @@ function profileSetupSummaryMarkdown(result) {
823
827
  const resultCount = cliFiniteNumber(viewport.result_count) || 0;
824
828
  const screenshotCount = Array.isArray(viewport.setup_screenshots) ? viewport.setup_screenshots.filter((label) => typeof label === "string" && label.trim()).length : 0;
825
829
  const clicked = cliFiniteNumber(viewport.clicked_total) || 0;
830
+ const clickSequenceCount = cliFiniteNumber(viewport.click_sequence_total) || 0;
826
831
  const clickCountActions = cliFiniteNumber(viewport.click_count_action_total) || 0;
827
832
  const windowCallActions = cliFiniteNumber(viewport.window_call_total) || 0;
828
833
  const windowCallStored = cliFiniteNumber(viewport.window_call_stored_total) || 0;
@@ -836,8 +841,28 @@ function profileSetupSummaryMarkdown(result) {
836
841
  const dragActions = cliFiniteNumber(viewport.drag_total) || 0;
837
842
  const canvasSignatureActions = cliFiniteNumber(viewport.canvas_signature_total) || 0;
838
843
  const observedPath = cliString(viewport.observed_path);
839
- lines.push(`- ${name}: ${ok}, ${resultCount} result(s), ${screenshotCount} setup screenshot(s), ${clicked} click(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)` : ""}${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}` : ""}`);
844
+ 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)` : ""}${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}` : ""}`);
840
845
  }
846
+ const clickSequenceGroups = viewports.map((viewport) => {
847
+ const name = cliString(viewport.name) || "viewport";
848
+ const receipts = Array.isArray(viewport.click_sequences) ? viewport.click_sequences.map(cliRecord).filter((item) => Boolean(item)) : [];
849
+ return receipts.map((receipt) => ({ name, receipt }));
850
+ });
851
+ const clickSequenceDetails = clickSequenceGroups.flat();
852
+ const sampledClickSequenceDetails = balancedSetupReceiptDetails(clickSequenceGroups, 12);
853
+ for (const { name, receipt } of sampledClickSequenceDetails) {
854
+ const selectorTemplate = cliString(receipt.selector_template) || "target";
855
+ const valueSource = cliString(receipt.value_source);
856
+ const sequence = Array.isArray(receipt.sequence) ? receipt.sequence.map((value) => cliFiniteNumber(value)).filter((value) => value !== void 0) : [];
857
+ const sequenceText = sequence.join(",");
858
+ const omittedSequenceCount = cliFiniteNumber(receipt.omitted_sequence_count) || 0;
859
+ const clickTotal = cliFiniteNumber(receipt.click_total);
860
+ const resultCount = cliFiniteNumber(receipt.result_count);
861
+ const ordinals = Array.isArray(receipt.ordinals) ? receipt.ordinals.map((value) => cliFiniteNumber(value)).filter((value) => value !== void 0) : [];
862
+ const ordinalText = ordinals.length ? ordinals.join(",") : "";
863
+ lines.push(`- ${name} click_sequence: ${markdownInlineCode(selectorTemplate)}${valueSource ? ` ${valueSource}` : ""}${sequenceText ? ` sequence ${markdownInlineCode(sequenceText, 160)}` : ""}${omittedSequenceCount ? ` (+${omittedSequenceCount} omitted)` : ""}${clickTotal === void 0 ? "" : `, clicks ${clickTotal}`}${resultCount === void 0 ? "" : `, results ${resultCount}`}${ordinalText ? `, ordinals ${markdownInlineCode(ordinalText, 120)}` : ""}`);
864
+ }
865
+ if (clickSequenceDetails.length > sampledClickSequenceDetails.length) lines.push(`- ${clickSequenceDetails.length - sampledClickSequenceDetails.length} additional click_sequence receipt(s) omitted.`);
841
866
  const dragGroups = viewports.map((viewport) => {
842
867
  const name = cliString(viewport.name) || "viewport";
843
868
  const receipts = Array.isArray(viewport.drag) ? viewport.drag.map(cliRecord).filter((item) => Boolean(item)) : [];
package/dist/index.cjs CHANGED
@@ -9357,6 +9357,54 @@ function profileSetupCanvasSignatureStableHashGroups(results) {
9357
9357
  }
9358
9358
  return warnings;
9359
9359
  }
9360
+ function profileSetupClickSequenceReceipts(clickedItems) {
9361
+ const nthChildPattern = /:nth-child\((\d+)\)/;
9362
+ const nthChildTemplatePattern = /:nth-child\(\d+\)/g;
9363
+ const groups = /* @__PURE__ */ new Map();
9364
+ for (const item of clickedItems) {
9365
+ const selector = stringValue5(item.selector);
9366
+ if (!selector) continue;
9367
+ const match = nthChildPattern.exec(selector);
9368
+ if (!match) continue;
9369
+ const frameSelector = stringValue5(item.frame_selector);
9370
+ const selectorTemplate = selector.replace(nthChildTemplatePattern, ":nth-child(*)");
9371
+ const key = `${frameSelector || ""}
9372
+ ${selectorTemplate}`;
9373
+ const group = groups.get(key) || {
9374
+ selector_template: selectorTemplate,
9375
+ frame_selector: frameSelector,
9376
+ value_source: "nth-child",
9377
+ sequence: [],
9378
+ ordinals: [],
9379
+ result_count: 0,
9380
+ click_total: 0
9381
+ };
9382
+ const value = Number(match[1]);
9383
+ const clickCountValue = numberValue3(item.click_count);
9384
+ const clickCount = clickCountValue === void 0 ? 1 : Math.max(1, Math.min(100, Math.floor(clickCountValue)));
9385
+ for (let index = 0; index < clickCount; index += 1) group.sequence.push(value);
9386
+ const ordinal = numberValue3(item.ordinal);
9387
+ if (ordinal !== void 0) group.ordinals.push(ordinal);
9388
+ group.result_count += 1;
9389
+ group.click_total += clickCount;
9390
+ groups.set(key, group);
9391
+ }
9392
+ return [...groups.values()].filter((group) => group.result_count >= 4).map((group) => {
9393
+ const sequence = group.sequence.slice(0, 32);
9394
+ const ordinals = group.ordinals.slice(0, 16);
9395
+ return {
9396
+ selector_template: group.selector_template,
9397
+ frame_selector: group.frame_selector ?? null,
9398
+ value_source: group.value_source,
9399
+ result_count: group.result_count,
9400
+ click_total: group.click_total,
9401
+ sequence,
9402
+ omitted_sequence_count: Math.max(0, group.sequence.length - sequence.length),
9403
+ ordinals,
9404
+ omitted_ordinal_count: Math.max(0, group.ordinals.length - ordinals.length)
9405
+ };
9406
+ });
9407
+ }
9360
9408
  function sampleProfileSetupSummaryItems(items, limit) {
9361
9409
  if (items.length <= limit) return items;
9362
9410
  const firstCount = Math.floor(limit / 2);
@@ -9416,6 +9464,8 @@ function profileSetupSummary(viewports, actionCount, expectedActionCountByViewpo
9416
9464
  };
9417
9465
  });
9418
9466
  const clicked = sampleProfileSetupSummaryItems(clickedItems, 8);
9467
+ const clickSequences = profileSetupClickSequenceReceipts(clickedItems);
9468
+ const sampledClickSequences = sampleProfileSetupSummaryItems(clickSequences, 6);
9419
9469
  const text_samples = results.filter((result) => result.ok !== false && typeof result.text === "string" && (profileSetupResultAction(result) === "assert_text_visible" || profileSetupResultAction(result) === "assert_text_absent" || profileSetupResultAction(result) === "wait_for_text")).map((result) => ({
9420
9470
  ordinal: result.ordinal ?? null,
9421
9471
  action: profileSetupResultAction(result),
@@ -9437,6 +9487,9 @@ function profileSetupSummary(viewports, actionCount, expectedActionCountByViewpo
9437
9487
  setup_screenshots: profileSetupScreenshotLabels(results),
9438
9488
  clicked_total: clickedItems.length,
9439
9489
  clicked_truncated: clickedItems.length > clicked.length,
9490
+ click_sequence_total: clickSequences.length,
9491
+ click_sequence_truncated: clickSequences.length > sampledClickSequences.length,
9492
+ click_sequences: sampledClickSequences,
9440
9493
  click_count_action_total: clickCountValues.length,
9441
9494
  click_count_value_total: clickCountValues.reduce((sum, value) => sum + value, 0),
9442
9495
  window_call_until_total: windowCallUntilReceipts.length,
@@ -11785,17 +11838,6 @@ function assessSetupActionsFromEvidence(profile, evidence) {
11785
11838
  const failed = [];
11786
11839
  const viewports = evidence.viewports || [];
11787
11840
  const expectedActionCountByViewport = /* @__PURE__ */ new Map();
11788
- const capturedViewportNames = new Set(viewports.map((viewport) => viewport.name));
11789
- for (const action of profile.target.setup_actions) {
11790
- if (action.viewports?.length && !action.viewports.some((name) => capturedViewportNames.has(name))) {
11791
- failed.push({
11792
- viewport: null,
11793
- action: action.type,
11794
- selector: action.selector ?? null,
11795
- reason: `setup action scoped to missing viewport(s): ${action.viewports.join(", ")}`
11796
- });
11797
- }
11798
- }
11799
11841
  for (const viewport of viewports) {
11800
11842
  const expectedActionCount = setupActionsForViewport(profile.target.setup_actions, viewport.name).length;
11801
11843
  expectedActionCountByViewport.set(viewport.name, expectedActionCount);
@@ -13021,6 +13063,55 @@ function profileSetupCanvasSignatureStableHashGroups(results) {
13021
13063
  }
13022
13064
  return warnings;
13023
13065
  }
13066
+ function profileSetupClickSequenceReceipts(clickedItems) {
13067
+ const nthChildPattern = /:nth-child\((\d+)\)/;
13068
+ const nthChildTemplatePattern = /:nth-child\(\d+\)/g;
13069
+ const groups = new Map();
13070
+ for (const item of clickedItems || []) {
13071
+ const selector = typeof item.selector === "string" && item.selector.trim() ? item.selector.trim() : undefined;
13072
+ if (!selector) continue;
13073
+ const match = nthChildPattern.exec(selector);
13074
+ if (!match) continue;
13075
+ const frameSelector = typeof item.frame_selector === "string" && item.frame_selector.trim() ? item.frame_selector.trim() : undefined;
13076
+ const selectorTemplate = selector.replace(nthChildTemplatePattern, ":nth-child(*)");
13077
+ const key = String(frameSelector || "") + "\\n" + selectorTemplate;
13078
+ const group = groups.get(key) || {
13079
+ selector_template: selectorTemplate,
13080
+ frame_selector: frameSelector,
13081
+ value_source: "nth-child",
13082
+ sequence: [],
13083
+ ordinals: [],
13084
+ result_count: 0,
13085
+ click_total: 0,
13086
+ };
13087
+ const value = Number(match[1]);
13088
+ const clickCountValue = typeof item.click_count === "number" && Number.isFinite(item.click_count) ? item.click_count : undefined;
13089
+ const clickCount = clickCountValue === undefined ? 1 : Math.max(1, Math.min(100, Math.floor(clickCountValue)));
13090
+ for (let index = 0; index < clickCount; index += 1) group.sequence.push(value);
13091
+ const ordinal = typeof item.ordinal === "number" && Number.isFinite(item.ordinal) ? item.ordinal : undefined;
13092
+ if (ordinal !== undefined) group.ordinals.push(ordinal);
13093
+ group.result_count += 1;
13094
+ group.click_total += clickCount;
13095
+ groups.set(key, group);
13096
+ }
13097
+ return [...groups.values()]
13098
+ .filter((group) => group.result_count >= 4)
13099
+ .map((group) => {
13100
+ const sequence = group.sequence.slice(0, 32);
13101
+ const ordinals = group.ordinals.slice(0, 16);
13102
+ return {
13103
+ selector_template: group.selector_template,
13104
+ frame_selector: group.frame_selector || null,
13105
+ value_source: group.value_source,
13106
+ result_count: group.result_count,
13107
+ click_total: group.click_total,
13108
+ sequence,
13109
+ omitted_sequence_count: Math.max(0, group.sequence.length - sequence.length),
13110
+ ordinals,
13111
+ omitted_ordinal_count: Math.max(0, group.ordinals.length - ordinals.length),
13112
+ };
13113
+ });
13114
+ }
13024
13115
  function sampleProfileSetupSummaryItems(items, limit) {
13025
13116
  if ((items || []).length <= limit) return items || [];
13026
13117
  const firstCount = Math.floor(limit / 2);
@@ -13096,6 +13187,8 @@ function profileSetupSummary(viewports, actionCount, expectedActionCountsByViewp
13096
13187
  };
13097
13188
  });
13098
13189
  const clicked = sampleProfileSetupSummaryItems(clickedItems, 8);
13190
+ const clickSequences = profileSetupClickSequenceReceipts(clickedItems);
13191
+ const sampledClickSequences = sampleProfileSetupSummaryItems(clickSequences, 6);
13099
13192
  const textSamples = results
13100
13193
  .filter((result) => result && result.ok !== false && typeof result.text === "string" && (
13101
13194
  profileSetupResultAction(result) === "assert_text_visible"
@@ -13125,6 +13218,9 @@ function profileSetupSummary(viewports, actionCount, expectedActionCountsByViewp
13125
13218
  setup_screenshots: profileSetupScreenshotLabels(results),
13126
13219
  clicked_total: clickedItems.length,
13127
13220
  clicked_truncated: clickedItems.length > clicked.length,
13221
+ click_sequence_total: clickSequences.length,
13222
+ click_sequence_truncated: clickSequences.length > sampledClickSequences.length,
13223
+ click_sequences: sampledClickSequences,
13128
13224
  click_count_action_total: clickCountValues.length,
13129
13225
  click_count_value_total: clickCountValues.reduce((sum, value) => sum + value, 0),
13130
13226
  window_call_until_total: windowCallUntilReceipts.length,
@@ -13272,17 +13368,6 @@ function assessProfile(profile, evidence) {
13272
13368
  const actionCount = profile.target.setup_actions.length;
13273
13369
  const failed = [];
13274
13370
  const expectedActionCountsByViewport = {};
13275
- const capturedViewportNames = new Set(viewports.map((viewport) => viewport.name));
13276
- for (const action of profile.target.setup_actions) {
13277
- if (Array.isArray(action.viewports) && action.viewports.length && !action.viewports.some((name) => capturedViewportNames.has(name))) {
13278
- failed.push({
13279
- viewport: null,
13280
- action: action.type,
13281
- selector: action.selector || null,
13282
- reason: "setup action scoped to missing viewport(s): " + action.viewports.join(", "),
13283
- });
13284
- }
13285
- }
13286
13371
  for (const viewport of viewports) {
13287
13372
  const expectedActionCount = setupActionsForViewport(profile.target.setup_actions, viewport.name).length;
13288
13373
  expectedActionCountsByViewport[viewport.name] = expectedActionCount;
package/dist/index.js CHANGED
@@ -62,7 +62,7 @@ import {
62
62
  resolveRiddleProofProfileTimeoutSec,
63
63
  slugifyRiddleProofProfileName,
64
64
  summarizeRiddleProofProfileResult
65
- } from "./chunk-L6WJP5IY.js";
65
+ } from "./chunk-U56YGC5K.js";
66
66
  import {
67
67
  DEFAULT_RIDDLE_API_BASE_URL,
68
68
  DEFAULT_RIDDLE_API_KEY_FILE,
package/dist/profile.cjs CHANGED
@@ -671,6 +671,54 @@ function profileSetupCanvasSignatureStableHashGroups(results) {
671
671
  }
672
672
  return warnings;
673
673
  }
674
+ function profileSetupClickSequenceReceipts(clickedItems) {
675
+ const nthChildPattern = /:nth-child\((\d+)\)/;
676
+ const nthChildTemplatePattern = /:nth-child\(\d+\)/g;
677
+ const groups = /* @__PURE__ */ new Map();
678
+ for (const item of clickedItems) {
679
+ const selector = stringValue(item.selector);
680
+ if (!selector) continue;
681
+ const match = nthChildPattern.exec(selector);
682
+ if (!match) continue;
683
+ const frameSelector = stringValue(item.frame_selector);
684
+ const selectorTemplate = selector.replace(nthChildTemplatePattern, ":nth-child(*)");
685
+ const key = `${frameSelector || ""}
686
+ ${selectorTemplate}`;
687
+ const group = groups.get(key) || {
688
+ selector_template: selectorTemplate,
689
+ frame_selector: frameSelector,
690
+ value_source: "nth-child",
691
+ sequence: [],
692
+ ordinals: [],
693
+ result_count: 0,
694
+ click_total: 0
695
+ };
696
+ const value = Number(match[1]);
697
+ const clickCountValue = numberValue(item.click_count);
698
+ const clickCount = clickCountValue === void 0 ? 1 : Math.max(1, Math.min(100, Math.floor(clickCountValue)));
699
+ for (let index = 0; index < clickCount; index += 1) group.sequence.push(value);
700
+ const ordinal = numberValue(item.ordinal);
701
+ if (ordinal !== void 0) group.ordinals.push(ordinal);
702
+ group.result_count += 1;
703
+ group.click_total += clickCount;
704
+ groups.set(key, group);
705
+ }
706
+ return [...groups.values()].filter((group) => group.result_count >= 4).map((group) => {
707
+ const sequence = group.sequence.slice(0, 32);
708
+ const ordinals = group.ordinals.slice(0, 16);
709
+ return {
710
+ selector_template: group.selector_template,
711
+ frame_selector: group.frame_selector ?? null,
712
+ value_source: group.value_source,
713
+ result_count: group.result_count,
714
+ click_total: group.click_total,
715
+ sequence,
716
+ omitted_sequence_count: Math.max(0, group.sequence.length - sequence.length),
717
+ ordinals,
718
+ omitted_ordinal_count: Math.max(0, group.ordinals.length - ordinals.length)
719
+ };
720
+ });
721
+ }
674
722
  function sampleProfileSetupSummaryItems(items, limit) {
675
723
  if (items.length <= limit) return items;
676
724
  const firstCount = Math.floor(limit / 2);
@@ -730,6 +778,8 @@ function profileSetupSummary(viewports, actionCount, expectedActionCountByViewpo
730
778
  };
731
779
  });
732
780
  const clicked = sampleProfileSetupSummaryItems(clickedItems, 8);
781
+ const clickSequences = profileSetupClickSequenceReceipts(clickedItems);
782
+ const sampledClickSequences = sampleProfileSetupSummaryItems(clickSequences, 6);
733
783
  const text_samples = results.filter((result) => result.ok !== false && typeof result.text === "string" && (profileSetupResultAction(result) === "assert_text_visible" || profileSetupResultAction(result) === "assert_text_absent" || profileSetupResultAction(result) === "wait_for_text")).map((result) => ({
734
784
  ordinal: result.ordinal ?? null,
735
785
  action: profileSetupResultAction(result),
@@ -751,6 +801,9 @@ function profileSetupSummary(viewports, actionCount, expectedActionCountByViewpo
751
801
  setup_screenshots: profileSetupScreenshotLabels(results),
752
802
  clicked_total: clickedItems.length,
753
803
  clicked_truncated: clickedItems.length > clicked.length,
804
+ click_sequence_total: clickSequences.length,
805
+ click_sequence_truncated: clickSequences.length > sampledClickSequences.length,
806
+ click_sequences: sampledClickSequences,
754
807
  click_count_action_total: clickCountValues.length,
755
808
  click_count_value_total: clickCountValues.reduce((sum, value) => sum + value, 0),
756
809
  window_call_until_total: windowCallUntilReceipts.length,
@@ -3099,17 +3152,6 @@ function assessSetupActionsFromEvidence(profile, evidence) {
3099
3152
  const failed = [];
3100
3153
  const viewports = evidence.viewports || [];
3101
3154
  const expectedActionCountByViewport = /* @__PURE__ */ new Map();
3102
- const capturedViewportNames = new Set(viewports.map((viewport) => viewport.name));
3103
- for (const action of profile.target.setup_actions) {
3104
- if (action.viewports?.length && !action.viewports.some((name) => capturedViewportNames.has(name))) {
3105
- failed.push({
3106
- viewport: null,
3107
- action: action.type,
3108
- selector: action.selector ?? null,
3109
- reason: `setup action scoped to missing viewport(s): ${action.viewports.join(", ")}`
3110
- });
3111
- }
3112
- }
3113
3155
  for (const viewport of viewports) {
3114
3156
  const expectedActionCount = setupActionsForViewport(profile.target.setup_actions, viewport.name).length;
3115
3157
  expectedActionCountByViewport.set(viewport.name, expectedActionCount);
@@ -4335,6 +4377,55 @@ function profileSetupCanvasSignatureStableHashGroups(results) {
4335
4377
  }
4336
4378
  return warnings;
4337
4379
  }
4380
+ function profileSetupClickSequenceReceipts(clickedItems) {
4381
+ const nthChildPattern = /:nth-child\((\d+)\)/;
4382
+ const nthChildTemplatePattern = /:nth-child\(\d+\)/g;
4383
+ const groups = new Map();
4384
+ for (const item of clickedItems || []) {
4385
+ const selector = typeof item.selector === "string" && item.selector.trim() ? item.selector.trim() : undefined;
4386
+ if (!selector) continue;
4387
+ const match = nthChildPattern.exec(selector);
4388
+ if (!match) continue;
4389
+ const frameSelector = typeof item.frame_selector === "string" && item.frame_selector.trim() ? item.frame_selector.trim() : undefined;
4390
+ const selectorTemplate = selector.replace(nthChildTemplatePattern, ":nth-child(*)");
4391
+ const key = String(frameSelector || "") + "\\n" + selectorTemplate;
4392
+ const group = groups.get(key) || {
4393
+ selector_template: selectorTemplate,
4394
+ frame_selector: frameSelector,
4395
+ value_source: "nth-child",
4396
+ sequence: [],
4397
+ ordinals: [],
4398
+ result_count: 0,
4399
+ click_total: 0,
4400
+ };
4401
+ const value = Number(match[1]);
4402
+ const clickCountValue = typeof item.click_count === "number" && Number.isFinite(item.click_count) ? item.click_count : undefined;
4403
+ const clickCount = clickCountValue === undefined ? 1 : Math.max(1, Math.min(100, Math.floor(clickCountValue)));
4404
+ for (let index = 0; index < clickCount; index += 1) group.sequence.push(value);
4405
+ const ordinal = typeof item.ordinal === "number" && Number.isFinite(item.ordinal) ? item.ordinal : undefined;
4406
+ if (ordinal !== undefined) group.ordinals.push(ordinal);
4407
+ group.result_count += 1;
4408
+ group.click_total += clickCount;
4409
+ groups.set(key, group);
4410
+ }
4411
+ return [...groups.values()]
4412
+ .filter((group) => group.result_count >= 4)
4413
+ .map((group) => {
4414
+ const sequence = group.sequence.slice(0, 32);
4415
+ const ordinals = group.ordinals.slice(0, 16);
4416
+ return {
4417
+ selector_template: group.selector_template,
4418
+ frame_selector: group.frame_selector || null,
4419
+ value_source: group.value_source,
4420
+ result_count: group.result_count,
4421
+ click_total: group.click_total,
4422
+ sequence,
4423
+ omitted_sequence_count: Math.max(0, group.sequence.length - sequence.length),
4424
+ ordinals,
4425
+ omitted_ordinal_count: Math.max(0, group.ordinals.length - ordinals.length),
4426
+ };
4427
+ });
4428
+ }
4338
4429
  function sampleProfileSetupSummaryItems(items, limit) {
4339
4430
  if ((items || []).length <= limit) return items || [];
4340
4431
  const firstCount = Math.floor(limit / 2);
@@ -4410,6 +4501,8 @@ function profileSetupSummary(viewports, actionCount, expectedActionCountsByViewp
4410
4501
  };
4411
4502
  });
4412
4503
  const clicked = sampleProfileSetupSummaryItems(clickedItems, 8);
4504
+ const clickSequences = profileSetupClickSequenceReceipts(clickedItems);
4505
+ const sampledClickSequences = sampleProfileSetupSummaryItems(clickSequences, 6);
4413
4506
  const textSamples = results
4414
4507
  .filter((result) => result && result.ok !== false && typeof result.text === "string" && (
4415
4508
  profileSetupResultAction(result) === "assert_text_visible"
@@ -4439,6 +4532,9 @@ function profileSetupSummary(viewports, actionCount, expectedActionCountsByViewp
4439
4532
  setup_screenshots: profileSetupScreenshotLabels(results),
4440
4533
  clicked_total: clickedItems.length,
4441
4534
  clicked_truncated: clickedItems.length > clicked.length,
4535
+ click_sequence_total: clickSequences.length,
4536
+ click_sequence_truncated: clickSequences.length > sampledClickSequences.length,
4537
+ click_sequences: sampledClickSequences,
4442
4538
  click_count_action_total: clickCountValues.length,
4443
4539
  click_count_value_total: clickCountValues.reduce((sum, value) => sum + value, 0),
4444
4540
  window_call_until_total: windowCallUntilReceipts.length,
@@ -4586,17 +4682,6 @@ function assessProfile(profile, evidence) {
4586
4682
  const actionCount = profile.target.setup_actions.length;
4587
4683
  const failed = [];
4588
4684
  const expectedActionCountsByViewport = {};
4589
- const capturedViewportNames = new Set(viewports.map((viewport) => viewport.name));
4590
- for (const action of profile.target.setup_actions) {
4591
- if (Array.isArray(action.viewports) && action.viewports.length && !action.viewports.some((name) => capturedViewportNames.has(name))) {
4592
- failed.push({
4593
- viewport: null,
4594
- action: action.type,
4595
- selector: action.selector || null,
4596
- reason: "setup action scoped to missing viewport(s): " + action.viewports.join(", "),
4597
- });
4598
- }
4599
- }
4600
4685
  for (const viewport of viewports) {
4601
4686
  const expectedActionCount = setupActionsForViewport(profile.target.setup_actions, viewport.name).length;
4602
4687
  expectedActionCountsByViewport[viewport.name] = expectedActionCount;
package/dist/profile.js CHANGED
@@ -23,7 +23,7 @@ import {
23
23
  resolveRiddleProofProfileTimeoutSec,
24
24
  slugifyRiddleProofProfileName,
25
25
  summarizeRiddleProofProfileResult
26
- } from "./chunk-L6WJP5IY.js";
26
+ } from "./chunk-U56YGC5K.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.166",
3
+ "version": "0.7.168",
4
4
  "description": "Reusable Riddle Proof contracts and helpers for evidence-backed agent changes.",
5
5
  "license": "MIT",
6
6
  "author": "RiddleDC",