@riddledc/riddle-proof 0.7.148 → 0.7.150

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/cli.cjs CHANGED
@@ -6975,6 +6975,7 @@ var RIDDLE_PROOF_PROFILE_CHECK_TYPES = [
6975
6975
  "selector_text_visible",
6976
6976
  "selector_text_absent",
6977
6977
  "selector_text_order",
6978
+ "observe_within",
6978
6979
  "frame_text_visible",
6979
6980
  "frame_url_equals",
6980
6981
  "frame_url_matches",
@@ -7446,6 +7447,22 @@ function profileSetupWindowEvalReceipts(results) {
7446
7447
  return receipt;
7447
7448
  });
7448
7449
  }
7450
+ function profileSetupRangeValueReceipts(results) {
7451
+ return results.filter((result) => profileSetupResultAction(result) === "set_range_value").map((result) => ({
7452
+ ordinal: result.ordinal ?? null,
7453
+ ok: result.ok !== false,
7454
+ selector: result.selector ?? null,
7455
+ frame_selector: result.frame_selector ?? null,
7456
+ requested_value: result.requested_value ?? null,
7457
+ actual_value: result.actual_value ?? null,
7458
+ before_value: result.before_value ?? null,
7459
+ value_as_number: result.value_as_number ?? null,
7460
+ min: result.min ?? null,
7461
+ max: result.max ?? null,
7462
+ step: result.step ?? null,
7463
+ reason: result.reason ?? result.error ?? null
7464
+ }));
7465
+ }
7449
7466
  function sampleProfileSetupSummaryItems(items, limit) {
7450
7467
  if (items.length <= limit) return items;
7451
7468
  const firstCount = Math.floor(limit / 2);
@@ -7488,6 +7505,8 @@ function profileSetupSummary(viewports, actionCount, expectedActionCountByViewpo
7488
7505
  const windowEvalStoredTotal = windowEvalReceipts.filter((result) => typeof result.return_stored_to === "string" && result.return_stored_to.trim()).length;
7489
7506
  const windowEvalCapturedTotal = windowEvalReceipts.filter((result) => result.return_captured === true).length;
7490
7507
  const sampledWindowEvalReceipts = sampleProfileSetupSummaryItems(windowEvalReceipts, 8);
7508
+ const rangeValueReceipts = profileSetupRangeValueReceipts(results);
7509
+ const sampledRangeValueReceipts = sampleProfileSetupSummaryItems(rangeValueReceipts, 8);
7491
7510
  const clickedItems = results.filter((result) => profileSetupResultAction(result) === "click" && result.ok !== false).map((result) => {
7492
7511
  const clickCount = typeof result.click_count === "number" && Number.isFinite(result.click_count) && result.click_count > 1 ? result.click_count : void 0;
7493
7512
  return {
@@ -7536,6 +7555,9 @@ function profileSetupSummary(viewports, actionCount, expectedActionCountByViewpo
7536
7555
  window_eval_captured_total: windowEvalCapturedTotal,
7537
7556
  window_eval_truncated: windowEvalReceipts.length > sampledWindowEvalReceipts.length,
7538
7557
  window_eval: sampledWindowEvalReceipts,
7558
+ set_range_value_total: rangeValueReceipts.length,
7559
+ set_range_value_truncated: rangeValueReceipts.length > sampledRangeValueReceipts.length,
7560
+ set_range_value: sampledRangeValueReceipts,
7539
7561
  clicked,
7540
7562
  text_samples,
7541
7563
  failed: failed.map((result) => ({
@@ -8276,7 +8298,7 @@ function normalizeCheck(input, index) {
8276
8298
  throw new Error(`checks[${index}].type ${type} is not supported. Supported checks: ${RIDDLE_PROOF_PROFILE_CHECK_TYPES.join(", ")}`);
8277
8299
  }
8278
8300
  const isDialogCountCheck = isDialogCountCheckType(type);
8279
- if ((type === "selector_visible" || type === "selector_absent" || type === "selector_count_at_least" || type === "selector_count_equals" || type === "selector_count_equal" || type === "selector_count_eq" || type === "selector_text_visible" || type === "selector_text_absent") && !stringValue2(input.selector)) {
8301
+ if ((type === "selector_visible" || type === "selector_absent" || type === "selector_count_at_least" || type === "selector_count_equals" || type === "selector_count_equal" || type === "selector_count_eq" || type === "selector_text_visible" || type === "selector_text_absent" || type === "observe_within" && !stringValue2(input.text) && !stringValue2(input.pattern)) && !stringValue2(input.selector)) {
8280
8302
  throw new Error(`checks[${index}] ${type} requires selector.`);
8281
8303
  }
8282
8304
  if ((type === "frame_text_visible" || type === "frame_url_equals" || type === "frame_url_matches" || type === "frame_no_horizontal_overflow") && !stringValue2(input.selector)) {
@@ -8417,7 +8439,7 @@ function normalizeCheck(input, index) {
8417
8439
  allowed_content_types: allowedContentTypes,
8418
8440
  allow_get_fallback: isLinkStatusCheck ? input.allow_get_fallback === false || input.allowGetFallback === false ? false : true : void 0,
8419
8441
  max_overflow_px: numberValue(input.max_overflow_px),
8420
- timeout_ms: numberValue(input.timeout_ms) ?? numberValue(input.timeoutMs),
8442
+ timeout_ms: numberValue(input.timeout_ms) ?? numberValue(input.timeoutMs) ?? numberValue(input.within_ms) ?? numberValue(input.withinMs),
8421
8443
  run_direct_routes: input.run_direct_routes === false || input.runDirectRoutes === false ? false : true,
8422
8444
  run_clickthroughs: input.run_clickthroughs === false || input.runClickthroughs === false ? false : true,
8423
8445
  run_all_viewports: input.run_all_viewports === true || input.runAllViewports === true,
@@ -8935,6 +8957,16 @@ function summarizeLinkStatusEvidence(viewport, check) {
8935
8957
  function textKey(check) {
8936
8958
  return check.pattern ? `pattern:${check.pattern}/${check.flags || ""}` : `text:${check.text || ""}`;
8937
8959
  }
8960
+ function observeWithinTimeoutMs(check) {
8961
+ const raw = check.timeout_ms;
8962
+ if (typeof raw === "number" && Number.isFinite(raw) && raw > 0) return Math.min(Math.round(raw), 6e4);
8963
+ return 2e3;
8964
+ }
8965
+ function observeWithinKey(check) {
8966
+ const target = check.selector ? `selector:${check.selector}` : "page";
8967
+ const expectation = check.pattern ? `pattern:${check.pattern}/${check.flags || ""}` : check.text ? `text:${check.text}` : "visible";
8968
+ return `${target}|${expectation}|within:${observeWithinTimeoutMs(check)}`;
8969
+ }
8938
8970
  function textSequenceForCheck(viewport, check) {
8939
8971
  const key = selectorKey(check);
8940
8972
  const sequence = viewport.text_sequences?.[key];
@@ -9441,6 +9473,40 @@ function assessCheckFromEvidence(check, evidence) {
9441
9473
  message: failed ? `Selector ${key} text order failed in ${failed} viewport(s).` : void 0
9442
9474
  };
9443
9475
  }
9476
+ if (check.type === "observe_within") {
9477
+ const key = observeWithinKey(check);
9478
+ const timeoutMs = observeWithinTimeoutMs(check);
9479
+ const results = viewports.map((viewport) => {
9480
+ const observation = viewport.observations?.[key];
9481
+ const matched = observation?.matched === true;
9482
+ return {
9483
+ viewport: viewport.name,
9484
+ matched,
9485
+ elapsed_ms: numberValue(observation?.elapsed_ms) ?? null,
9486
+ timeout_ms: numberValue(observation?.timeout_ms) ?? timeoutMs,
9487
+ attempts: numberValue(observation?.attempts) ?? null,
9488
+ selector_count: numberValue(observation?.selector_count) ?? null,
9489
+ visible_count: numberValue(observation?.visible_count) ?? null,
9490
+ matched_count: numberValue(observation?.matched_count) ?? null,
9491
+ sample: stringValue2(observation?.sample) ?? null,
9492
+ error: stringValue2(observation?.error) ?? null
9493
+ };
9494
+ });
9495
+ const failed = results.filter((result) => !result.matched).length;
9496
+ return {
9497
+ type: check.type,
9498
+ label: checkLabel(check),
9499
+ status: failed ? "failed" : "passed",
9500
+ evidence: {
9501
+ selector: check.selector || null,
9502
+ text: check.text || null,
9503
+ pattern: check.pattern || null,
9504
+ timeout_ms: timeoutMs,
9505
+ viewports: results.map((result) => toJsonValue(result))
9506
+ },
9507
+ message: failed ? `Observation did not match within ${timeoutMs}ms in ${failed} viewport(s).` : void 0
9508
+ };
9509
+ }
9444
9510
  if (check.type === "frame_text_visible") {
9445
9511
  const key = selectorKey(check);
9446
9512
  const results = viewports.map((viewport) => {
@@ -10829,6 +10895,24 @@ function profileSetupWindowEvalReceipts(results) {
10829
10895
  return receipt;
10830
10896
  });
10831
10897
  }
10898
+ function profileSetupRangeValueReceipts(results) {
10899
+ return (results || [])
10900
+ .filter((result) => result && profileSetupResultAction(result) === "set_range_value")
10901
+ .map((result) => ({
10902
+ ordinal: result.ordinal ?? null,
10903
+ ok: result.ok !== false,
10904
+ selector: result.selector ?? null,
10905
+ frame_selector: result.frame_selector ?? null,
10906
+ requested_value: result.requested_value ?? null,
10907
+ actual_value: result.actual_value ?? null,
10908
+ before_value: result.before_value ?? null,
10909
+ value_as_number: result.value_as_number ?? null,
10910
+ min: result.min ?? null,
10911
+ max: result.max ?? null,
10912
+ step: result.step ?? null,
10913
+ reason: result.reason || result.error || null,
10914
+ }));
10915
+ }
10832
10916
  function sampleProfileSetupSummaryItems(items, limit) {
10833
10917
  if ((items || []).length <= limit) return items || [];
10834
10918
  const firstCount = Math.floor(limit / 2);
@@ -10885,6 +10969,8 @@ function profileSetupSummary(viewports, actionCount, expectedActionCountsByViewp
10885
10969
  const windowEvalStoredTotal = windowEvalReceipts.filter((result) => typeof result.return_stored_to === "string" && result.return_stored_to.trim()).length;
10886
10970
  const windowEvalCapturedTotal = windowEvalReceipts.filter((result) => result.return_captured === true).length;
10887
10971
  const sampledWindowEvalReceipts = sampleProfileSetupSummaryItems(windowEvalReceipts, 8);
10972
+ const rangeValueReceipts = profileSetupRangeValueReceipts(results);
10973
+ const sampledRangeValueReceipts = sampleProfileSetupSummaryItems(rangeValueReceipts, 8);
10888
10974
  const clickedItems = results
10889
10975
  .filter((result) => result && profileSetupResultAction(result) === "click" && result.ok !== false)
10890
10976
  .map((result) => {
@@ -10943,6 +11029,9 @@ function profileSetupSummary(viewports, actionCount, expectedActionCountsByViewp
10943
11029
  window_eval_captured_total: windowEvalCapturedTotal,
10944
11030
  window_eval_truncated: windowEvalReceipts.length > sampledWindowEvalReceipts.length,
10945
11031
  window_eval: sampledWindowEvalReceipts,
11032
+ set_range_value_total: rangeValueReceipts.length,
11033
+ set_range_value_truncated: rangeValueReceipts.length > sampledRangeValueReceipts.length,
11034
+ set_range_value: sampledRangeValueReceipts,
10946
11035
  clicked,
10947
11036
  text_samples: textSamples,
10948
11037
  failed: failed.map((result) => ({
@@ -11311,6 +11400,36 @@ function assessProfile(profile, evidence) {
11311
11400
  });
11312
11401
  continue;
11313
11402
  }
11403
+ if (check.type === "observe_within") {
11404
+ const key = observeWithinKey(check);
11405
+ const timeoutMs = observeWithinTimeoutMs(check);
11406
+ const results = checkViewports.map((viewport) => {
11407
+ const observation = viewport.observations && viewport.observations[key] && typeof viewport.observations[key] === "object"
11408
+ ? viewport.observations[key]
11409
+ : {};
11410
+ return {
11411
+ viewport: viewport.name,
11412
+ matched: observation.matched === true,
11413
+ elapsed_ms: typeof observation.elapsed_ms === "number" && Number.isFinite(observation.elapsed_ms) ? observation.elapsed_ms : null,
11414
+ timeout_ms: typeof observation.timeout_ms === "number" && Number.isFinite(observation.timeout_ms) ? observation.timeout_ms : timeoutMs,
11415
+ attempts: typeof observation.attempts === "number" && Number.isFinite(observation.attempts) ? observation.attempts : null,
11416
+ selector_count: typeof observation.selector_count === "number" && Number.isFinite(observation.selector_count) ? observation.selector_count : null,
11417
+ visible_count: typeof observation.visible_count === "number" && Number.isFinite(observation.visible_count) ? observation.visible_count : null,
11418
+ matched_count: typeof observation.matched_count === "number" && Number.isFinite(observation.matched_count) ? observation.matched_count : null,
11419
+ sample: typeof observation.sample === "string" && observation.sample.trim() ? observation.sample.trim() : null,
11420
+ error: typeof observation.error === "string" && observation.error.trim() ? observation.error.trim() : null,
11421
+ };
11422
+ });
11423
+ const failed = results.filter((result) => !result.matched).length;
11424
+ checks.push({
11425
+ type: check.type,
11426
+ label: check.label || check.type,
11427
+ status: failed ? "failed" : "passed",
11428
+ evidence: { selector: check.selector || null, text: check.text || null, pattern: check.pattern || null, timeout_ms: timeoutMs, viewports: results },
11429
+ message: failed ? "Observation did not match within " + timeoutMs + "ms in " + failed + " viewport(s)." : undefined,
11430
+ });
11431
+ continue;
11432
+ }
11314
11433
  if (check.type === "frame_text_visible") {
11315
11434
  const selector = check.selector || "";
11316
11435
  const results = checkViewports.map((viewport) => {
@@ -11743,6 +11862,19 @@ function ensureDialogHandler() {
11743
11862
  function textKey(check) {
11744
11863
  return check.pattern ? "pattern:" + check.pattern + "/" + (check.flags || "") : "text:" + (check.text || "");
11745
11864
  }
11865
+ function observeWithinTimeoutMs(check) {
11866
+ const raw = Number(check && check.timeout_ms);
11867
+ return Number.isFinite(raw) && raw > 0 ? Math.min(Math.round(raw), 60000) : 2000;
11868
+ }
11869
+ function observeWithinKey(check) {
11870
+ const target = check && check.selector ? "selector:" + check.selector : "page";
11871
+ const expectation = check && check.pattern
11872
+ ? "pattern:" + check.pattern + "/" + (check.flags || "")
11873
+ : check && check.text
11874
+ ? "text:" + check.text
11875
+ : "visible";
11876
+ return target + "|" + expectation + "|within:" + observeWithinTimeoutMs(check);
11877
+ }
11746
11878
  function textMatches(sample, check) {
11747
11879
  if (check.pattern) {
11748
11880
  try { return new RegExp(check.pattern, check.flags || "").test(sample || ""); } catch { return false; }
@@ -13058,6 +13190,104 @@ async function selectorTextSequence(selector) {
13058
13190
  };
13059
13191
  }).catch((error) => ({ count: 0, visible_count: 0, texts: [], visible_texts: [], match_texts: [], visible_match_texts: [], error: String(error && error.message ? error.message : error).slice(0, 500) }));
13060
13192
  }
13193
+ async function observeWithinSnapshot(check) {
13194
+ const payload = {
13195
+ selector: check.selector || "",
13196
+ text: check.text || "",
13197
+ pattern: check.pattern || "",
13198
+ flags: check.flags || "",
13199
+ wants_text: Boolean(check.text || check.pattern),
13200
+ };
13201
+ if (payload.selector) {
13202
+ return page.locator(payload.selector).evaluateAll((elements, input) => {
13203
+ const compact = (value) => String(value || "").replace(/\s+/g, " ").trim();
13204
+ const matchText = (value) => {
13205
+ const source = compact(value);
13206
+ if (input.pattern) {
13207
+ try { return new RegExp(input.pattern, input.flags || "").test(source); } catch { return false; }
13208
+ }
13209
+ return source.includes(input.text || "");
13210
+ };
13211
+ const isVisible = (element) => {
13212
+ const style = window.getComputedStyle(element);
13213
+ const rect = element.getBoundingClientRect();
13214
+ return style && style.visibility !== "hidden" && style.display !== "none" && rect.width > 0 && rect.height > 0;
13215
+ };
13216
+ const rows = elements.map((element, index) => {
13217
+ const text = compact(element.innerText || element.textContent || "");
13218
+ const visible = isVisible(element);
13219
+ return { index, text, visible, matched: input.wants_text ? matchText(text) : visible };
13220
+ });
13221
+ const visibleRows = rows.filter((row) => row.visible);
13222
+ const matches = input.wants_text ? visibleRows.filter((row) => row.matched) : visibleRows;
13223
+ const sampleRow = matches[0] || visibleRows[0] || rows[0] || null;
13224
+ return {
13225
+ selector: input.selector,
13226
+ text: input.text || null,
13227
+ pattern: input.pattern || null,
13228
+ selector_count: rows.length,
13229
+ visible_count: visibleRows.length,
13230
+ matched_count: matches.length,
13231
+ matched: matches.length > 0,
13232
+ sample: sampleRow && sampleRow.text ? sampleRow.text.slice(0, 240) : null,
13233
+ };
13234
+ }, payload).catch((error) => ({
13235
+ selector: payload.selector,
13236
+ text: payload.text || null,
13237
+ pattern: payload.pattern || null,
13238
+ selector_count: 0,
13239
+ visible_count: 0,
13240
+ matched_count: 0,
13241
+ matched: false,
13242
+ sample: null,
13243
+ error: String(error && error.message ? error.message : error).slice(0, 500),
13244
+ }));
13245
+ }
13246
+ return page.evaluate((input) => {
13247
+ const compact = (value) => String(value || "").replace(/\s+/g, " ").trim();
13248
+ const sample = compact(document.body ? document.body.innerText || document.body.textContent || "" : "");
13249
+ let matched = false;
13250
+ if (input.pattern) {
13251
+ try { matched = new RegExp(input.pattern, input.flags || "").test(sample); } catch { matched = false; }
13252
+ } else {
13253
+ matched = sample.includes(input.text || "");
13254
+ }
13255
+ return {
13256
+ selector: null,
13257
+ text: input.text || null,
13258
+ pattern: input.pattern || null,
13259
+ matched,
13260
+ matched_count: matched ? 1 : 0,
13261
+ sample: sample.slice(0, 240),
13262
+ };
13263
+ }, payload).catch((error) => ({
13264
+ selector: null,
13265
+ text: payload.text || null,
13266
+ pattern: payload.pattern || null,
13267
+ matched: false,
13268
+ matched_count: 0,
13269
+ sample: null,
13270
+ error: String(error && error.message ? error.message : error).slice(0, 500),
13271
+ }));
13272
+ }
13273
+ async function observeWithin(check) {
13274
+ const timeoutMs = observeWithinTimeoutMs(check);
13275
+ const startedAt = Date.now();
13276
+ let attempts = 0;
13277
+ let last = null;
13278
+ while (true) {
13279
+ attempts += 1;
13280
+ last = await observeWithinSnapshot(check);
13281
+ const elapsedMs = Date.now() - startedAt;
13282
+ if (last && last.matched === true) {
13283
+ return { ...last, timeout_ms: timeoutMs, elapsed_ms: elapsedMs, attempts };
13284
+ }
13285
+ if (elapsedMs >= timeoutMs) {
13286
+ return { ...(last || {}), matched: false, timeout_ms: timeoutMs, elapsed_ms: elapsedMs, attempts };
13287
+ }
13288
+ await page.waitForTimeout(Math.min(100, Math.max(25, timeoutMs - elapsedMs)));
13289
+ }
13290
+ }
13061
13291
  function linkProbeMaxLinks(check) {
13062
13292
  const value = Number(check.max_links || check.maxLinks || check.limit || 100);
13063
13293
  return Number.isInteger(value) && value > 0 ? Math.min(value, 500) : 100;
@@ -14110,6 +14340,7 @@ async function captureViewport(viewport) {
14110
14340
  const text_matches = {};
14111
14341
  const text_match_samples = {};
14112
14342
  const text_case_insensitive_samples = {};
14343
+ const observations = {};
14113
14344
  const http_statuses = {};
14114
14345
  const link_statuses = {};
14115
14346
  for (const check of profile.checks || []) {
@@ -14130,6 +14361,10 @@ async function captureViewport(viewport) {
14130
14361
  selectors[check.selector] = selectors[check.selector] || await selectorStats(check.selector);
14131
14362
  text_sequences[check.selector] = await selectorTextSequence(check.selector);
14132
14363
  }
14364
+ if (check.type === "observe_within") {
14365
+ const key = observeWithinKey(check);
14366
+ observations[key] = observations[key] || await observeWithin(check);
14367
+ }
14133
14368
  if ((check.type === "text_visible" || check.type === "text_absent") && (check.text || check.pattern)) {
14134
14369
  const key = textKey(check);
14135
14370
  const sample = dom.body_text || dom.body_text_sample || "";
@@ -14223,6 +14458,7 @@ async function captureViewport(viewport) {
14223
14458
  text_matches,
14224
14459
  text_match_samples,
14225
14460
  text_case_insensitive_samples,
14461
+ observations,
14226
14462
  http_statuses,
14227
14463
  link_statuses,
14228
14464
  route_inventory: routeInventory,
@@ -14905,6 +15141,14 @@ function profileCheckMarkdownTarget(check) {
14905
15141
  if (check.type === "selector_text_order") {
14906
15142
  return selector ? `${markdownInlineCode(selector)} text order` : void 0;
14907
15143
  }
15144
+ if (check.type === "observe_within") {
15145
+ const textTarget = profileCheckTextTarget(evidence);
15146
+ const timeoutMs = cliFiniteNumber(evidence.timeout_ms);
15147
+ const withinLabel = timeoutMs === void 0 ? "within timeout" : `within ${timeoutMs}ms`;
15148
+ if (selector && textTarget) return `${markdownInlineCode(selector)} observes ${textTarget} ${withinLabel}`;
15149
+ if (selector) return `${markdownInlineCode(selector)} visible ${withinLabel}`;
15150
+ return textTarget ? `${textTarget} ${withinLabel}` : withinLabel;
15151
+ }
14908
15152
  if (check.type === "text_visible" || check.type === "text_absent") {
14909
15153
  return profileCheckTextTarget(evidence);
14910
15154
  }
@@ -15093,6 +15337,7 @@ function profileSetupSummaryMarkdown(result) {
15093
15337
  const windowEvalCapturedTotal = viewports.reduce((sum, viewport) => sum + (cliFiniteNumber(viewport.window_eval_captured_total) || 0), 0);
15094
15338
  const windowCallUntilTotal = viewports.reduce((sum, viewport) => sum + (cliFiniteNumber(viewport.window_call_until_total) || 0), 0);
15095
15339
  const windowCallUntilCallTotal = viewports.reduce((sum, viewport) => sum + (cliFiniteNumber(viewport.window_call_until_call_total) || 0), 0);
15340
+ const rangeValueTotal = viewports.reduce((sum, viewport) => sum + (cliFiniteNumber(viewport.set_range_value_total) || 0), 0);
15096
15341
  const failedTotal = viewports.reduce((sum, viewport) => sum + (Array.isArray(viewport.failed) ? viewport.failed.length : 0), 0);
15097
15342
  const lines = [
15098
15343
  `- setup actions: ${declaredActions === void 0 ? "unknown" : declaredActions} declared, ${totalResults} recorded result(s) across ${viewports.length} viewport(s)`,
@@ -15112,6 +15357,9 @@ function profileSetupSummaryMarkdown(result) {
15112
15357
  if (windowCallUntilTotal) {
15113
15358
  lines.push(`- window_call_until: ${windowCallUntilTotal} action(s), call_count total ${windowCallUntilCallTotal}`);
15114
15359
  }
15360
+ if (rangeValueTotal) {
15361
+ lines.push(`- set_range_value: ${rangeValueTotal} action(s)`);
15362
+ }
15115
15363
  for (const viewport of viewports.slice(0, 8)) {
15116
15364
  const name = cliString(viewport.name) || "viewport";
15117
15365
  const ok = viewport.ok === false ? "failed" : "ok";
@@ -15127,9 +15375,29 @@ function profileSetupSummaryMarkdown(result) {
15127
15375
  const windowEvalCaptured = cliFiniteNumber(viewport.window_eval_captured_total) || 0;
15128
15376
  const windowCallUntilActions = cliFiniteNumber(viewport.window_call_until_total) || 0;
15129
15377
  const windowCallUntilCalls = cliFiniteNumber(viewport.window_call_until_call_total) || 0;
15378
+ const rangeValueActions = cliFiniteNumber(viewport.set_range_value_total) || 0;
15130
15379
  const observedPath = cliString(viewport.observed_path);
15131
- lines.push(`- ${name}: ${ok}, ${resultCount} result(s), ${screenshotCount} setup screenshot(s), ${clicked} click(s)${clickCountActions ? `, ${clickCountActions} click_count 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}` : ""}`);
15380
+ 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)` : ""}${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}` : ""}`);
15381
+ }
15382
+ const rangeValueDetails = viewports.flatMap((viewport) => {
15383
+ const name = cliString(viewport.name) || "viewport";
15384
+ const receipts = Array.isArray(viewport.set_range_value) ? viewport.set_range_value.map(cliRecord).filter((item) => Boolean(item)) : [];
15385
+ return receipts.map((receipt) => ({ name, receipt }));
15386
+ });
15387
+ for (const { name, receipt } of rangeValueDetails.slice(0, 12)) {
15388
+ const selector = cliString(receipt.selector) || "input[type=range]";
15389
+ const requested = cliValueLabel(receipt.requested_value);
15390
+ const actual = cliValueLabel(receipt.actual_value);
15391
+ const before = cliValueLabel(receipt.before_value);
15392
+ const valueAsNumber = cliFiniteNumber(receipt.value_as_number);
15393
+ const min = cliValueLabel(receipt.min);
15394
+ const max = cliValueLabel(receipt.max);
15395
+ const step = cliValueLabel(receipt.step);
15396
+ const ok = receipt.ok === false ? "failed" : "ok";
15397
+ const reason = cliString(receipt.reason);
15398
+ lines.push(`- ${name} set_range_value: ${ok}, ${markdownInlineCode(selector)}${requested === void 0 ? "" : ` requested ${markdownInlineCode(requested, 80)}`}${actual === void 0 ? "" : ` -> ${markdownInlineCode(actual, 80)}`}${before === void 0 ? "" : `, before ${markdownInlineCode(before, 80)}`}${valueAsNumber === void 0 ? "" : `, number ${valueAsNumber}`}${min === void 0 && max === void 0 ? "" : `, range ${min === void 0 ? "?" : markdownInlineCode(min, 40)}..${max === void 0 ? "?" : markdownInlineCode(max, 40)}`}${step === void 0 ? "" : ` step ${markdownInlineCode(step, 40)}`}${reason ? `, reason ${markdownInlineCode(reason, 100)}` : ""}`);
15132
15399
  }
15400
+ if (rangeValueDetails.length > 12) lines.push(`- ${rangeValueDetails.length - 12} additional set_range_value receipt(s) omitted.`);
15133
15401
  const windowCallDetails = viewports.flatMap((viewport) => {
15134
15402
  const name = cliString(viewport.name) || "viewport";
15135
15403
  const receipts = Array.isArray(viewport.window_call) ? viewport.window_call.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-WAJA6TJV.js";
16
+ } from "./chunk-QJJ3ISMK.js";
17
17
  import {
18
18
  createRiddleApiClient,
19
19
  parseRiddleViewport
@@ -507,6 +507,14 @@ function profileCheckMarkdownTarget(check) {
507
507
  if (check.type === "selector_text_order") {
508
508
  return selector ? `${markdownInlineCode(selector)} text order` : void 0;
509
509
  }
510
+ if (check.type === "observe_within") {
511
+ const textTarget = profileCheckTextTarget(evidence);
512
+ const timeoutMs = cliFiniteNumber(evidence.timeout_ms);
513
+ const withinLabel = timeoutMs === void 0 ? "within timeout" : `within ${timeoutMs}ms`;
514
+ if (selector && textTarget) return `${markdownInlineCode(selector)} observes ${textTarget} ${withinLabel}`;
515
+ if (selector) return `${markdownInlineCode(selector)} visible ${withinLabel}`;
516
+ return textTarget ? `${textTarget} ${withinLabel}` : withinLabel;
517
+ }
510
518
  if (check.type === "text_visible" || check.type === "text_absent") {
511
519
  return profileCheckTextTarget(evidence);
512
520
  }
@@ -695,6 +703,7 @@ function profileSetupSummaryMarkdown(result) {
695
703
  const windowEvalCapturedTotal = viewports.reduce((sum, viewport) => sum + (cliFiniteNumber(viewport.window_eval_captured_total) || 0), 0);
696
704
  const windowCallUntilTotal = viewports.reduce((sum, viewport) => sum + (cliFiniteNumber(viewport.window_call_until_total) || 0), 0);
697
705
  const windowCallUntilCallTotal = viewports.reduce((sum, viewport) => sum + (cliFiniteNumber(viewport.window_call_until_call_total) || 0), 0);
706
+ const rangeValueTotal = viewports.reduce((sum, viewport) => sum + (cliFiniteNumber(viewport.set_range_value_total) || 0), 0);
698
707
  const failedTotal = viewports.reduce((sum, viewport) => sum + (Array.isArray(viewport.failed) ? viewport.failed.length : 0), 0);
699
708
  const lines = [
700
709
  `- setup actions: ${declaredActions === void 0 ? "unknown" : declaredActions} declared, ${totalResults} recorded result(s) across ${viewports.length} viewport(s)`,
@@ -714,6 +723,9 @@ function profileSetupSummaryMarkdown(result) {
714
723
  if (windowCallUntilTotal) {
715
724
  lines.push(`- window_call_until: ${windowCallUntilTotal} action(s), call_count total ${windowCallUntilCallTotal}`);
716
725
  }
726
+ if (rangeValueTotal) {
727
+ lines.push(`- set_range_value: ${rangeValueTotal} action(s)`);
728
+ }
717
729
  for (const viewport of viewports.slice(0, 8)) {
718
730
  const name = cliString(viewport.name) || "viewport";
719
731
  const ok = viewport.ok === false ? "failed" : "ok";
@@ -729,9 +741,29 @@ function profileSetupSummaryMarkdown(result) {
729
741
  const windowEvalCaptured = cliFiniteNumber(viewport.window_eval_captured_total) || 0;
730
742
  const windowCallUntilActions = cliFiniteNumber(viewport.window_call_until_total) || 0;
731
743
  const windowCallUntilCalls = cliFiniteNumber(viewport.window_call_until_call_total) || 0;
744
+ const rangeValueActions = cliFiniteNumber(viewport.set_range_value_total) || 0;
732
745
  const observedPath = cliString(viewport.observed_path);
733
- lines.push(`- ${name}: ${ok}, ${resultCount} result(s), ${screenshotCount} setup screenshot(s), ${clicked} click(s)${clickCountActions ? `, ${clickCountActions} click_count 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}` : ""}`);
746
+ 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)` : ""}${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}` : ""}`);
747
+ }
748
+ const rangeValueDetails = viewports.flatMap((viewport) => {
749
+ const name = cliString(viewport.name) || "viewport";
750
+ const receipts = Array.isArray(viewport.set_range_value) ? viewport.set_range_value.map(cliRecord).filter((item) => Boolean(item)) : [];
751
+ return receipts.map((receipt) => ({ name, receipt }));
752
+ });
753
+ for (const { name, receipt } of rangeValueDetails.slice(0, 12)) {
754
+ const selector = cliString(receipt.selector) || "input[type=range]";
755
+ const requested = cliValueLabel(receipt.requested_value);
756
+ const actual = cliValueLabel(receipt.actual_value);
757
+ const before = cliValueLabel(receipt.before_value);
758
+ const valueAsNumber = cliFiniteNumber(receipt.value_as_number);
759
+ const min = cliValueLabel(receipt.min);
760
+ const max = cliValueLabel(receipt.max);
761
+ const step = cliValueLabel(receipt.step);
762
+ const ok = receipt.ok === false ? "failed" : "ok";
763
+ const reason = cliString(receipt.reason);
764
+ lines.push(`- ${name} set_range_value: ${ok}, ${markdownInlineCode(selector)}${requested === void 0 ? "" : ` requested ${markdownInlineCode(requested, 80)}`}${actual === void 0 ? "" : ` -> ${markdownInlineCode(actual, 80)}`}${before === void 0 ? "" : `, before ${markdownInlineCode(before, 80)}`}${valueAsNumber === void 0 ? "" : `, number ${valueAsNumber}`}${min === void 0 && max === void 0 ? "" : `, range ${min === void 0 ? "?" : markdownInlineCode(min, 40)}..${max === void 0 ? "?" : markdownInlineCode(max, 40)}`}${step === void 0 ? "" : ` step ${markdownInlineCode(step, 40)}`}${reason ? `, reason ${markdownInlineCode(reason, 100)}` : ""}`);
734
765
  }
766
+ if (rangeValueDetails.length > 12) lines.push(`- ${rangeValueDetails.length - 12} additional set_range_value receipt(s) omitted.`);
735
767
  const windowCallDetails = viewports.flatMap((viewport) => {
736
768
  const name = cliString(viewport.name) || "viewport";
737
769
  const receipts = Array.isArray(viewport.window_call) ? viewport.window_call.map(cliRecord).filter((item) => Boolean(item)) : [];