@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/profile.cjs CHANGED
@@ -73,6 +73,7 @@ var RIDDLE_PROOF_PROFILE_CHECK_TYPES = [
73
73
  "selector_text_visible",
74
74
  "selector_text_absent",
75
75
  "selector_text_order",
76
+ "observe_within",
76
77
  "frame_text_visible",
77
78
  "frame_url_equals",
78
79
  "frame_url_matches",
@@ -544,6 +545,22 @@ function profileSetupWindowEvalReceipts(results) {
544
545
  return receipt;
545
546
  });
546
547
  }
548
+ function profileSetupRangeValueReceipts(results) {
549
+ return results.filter((result) => profileSetupResultAction(result) === "set_range_value").map((result) => ({
550
+ ordinal: result.ordinal ?? null,
551
+ ok: result.ok !== false,
552
+ selector: result.selector ?? null,
553
+ frame_selector: result.frame_selector ?? null,
554
+ requested_value: result.requested_value ?? null,
555
+ actual_value: result.actual_value ?? null,
556
+ before_value: result.before_value ?? null,
557
+ value_as_number: result.value_as_number ?? null,
558
+ min: result.min ?? null,
559
+ max: result.max ?? null,
560
+ step: result.step ?? null,
561
+ reason: result.reason ?? result.error ?? null
562
+ }));
563
+ }
547
564
  function sampleProfileSetupSummaryItems(items, limit) {
548
565
  if (items.length <= limit) return items;
549
566
  const firstCount = Math.floor(limit / 2);
@@ -586,6 +603,8 @@ function profileSetupSummary(viewports, actionCount, expectedActionCountByViewpo
586
603
  const windowEvalStoredTotal = windowEvalReceipts.filter((result) => typeof result.return_stored_to === "string" && result.return_stored_to.trim()).length;
587
604
  const windowEvalCapturedTotal = windowEvalReceipts.filter((result) => result.return_captured === true).length;
588
605
  const sampledWindowEvalReceipts = sampleProfileSetupSummaryItems(windowEvalReceipts, 8);
606
+ const rangeValueReceipts = profileSetupRangeValueReceipts(results);
607
+ const sampledRangeValueReceipts = sampleProfileSetupSummaryItems(rangeValueReceipts, 8);
589
608
  const clickedItems = results.filter((result) => profileSetupResultAction(result) === "click" && result.ok !== false).map((result) => {
590
609
  const clickCount = typeof result.click_count === "number" && Number.isFinite(result.click_count) && result.click_count > 1 ? result.click_count : void 0;
591
610
  return {
@@ -634,6 +653,9 @@ function profileSetupSummary(viewports, actionCount, expectedActionCountByViewpo
634
653
  window_eval_captured_total: windowEvalCapturedTotal,
635
654
  window_eval_truncated: windowEvalReceipts.length > sampledWindowEvalReceipts.length,
636
655
  window_eval: sampledWindowEvalReceipts,
656
+ set_range_value_total: rangeValueReceipts.length,
657
+ set_range_value_truncated: rangeValueReceipts.length > sampledRangeValueReceipts.length,
658
+ set_range_value: sampledRangeValueReceipts,
637
659
  clicked,
638
660
  text_samples,
639
661
  failed: failed.map((result) => ({
@@ -1374,7 +1396,7 @@ function normalizeCheck(input, index) {
1374
1396
  throw new Error(`checks[${index}].type ${type} is not supported. Supported checks: ${RIDDLE_PROOF_PROFILE_CHECK_TYPES.join(", ")}`);
1375
1397
  }
1376
1398
  const isDialogCountCheck = isDialogCountCheckType(type);
1377
- 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") && !stringValue(input.selector)) {
1399
+ 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" && !stringValue(input.text) && !stringValue(input.pattern)) && !stringValue(input.selector)) {
1378
1400
  throw new Error(`checks[${index}] ${type} requires selector.`);
1379
1401
  }
1380
1402
  if ((type === "frame_text_visible" || type === "frame_url_equals" || type === "frame_url_matches" || type === "frame_no_horizontal_overflow") && !stringValue(input.selector)) {
@@ -1515,7 +1537,7 @@ function normalizeCheck(input, index) {
1515
1537
  allowed_content_types: allowedContentTypes,
1516
1538
  allow_get_fallback: isLinkStatusCheck ? input.allow_get_fallback === false || input.allowGetFallback === false ? false : true : void 0,
1517
1539
  max_overflow_px: numberValue(input.max_overflow_px),
1518
- timeout_ms: numberValue(input.timeout_ms) ?? numberValue(input.timeoutMs),
1540
+ timeout_ms: numberValue(input.timeout_ms) ?? numberValue(input.timeoutMs) ?? numberValue(input.within_ms) ?? numberValue(input.withinMs),
1519
1541
  run_direct_routes: input.run_direct_routes === false || input.runDirectRoutes === false ? false : true,
1520
1542
  run_clickthroughs: input.run_clickthroughs === false || input.runClickthroughs === false ? false : true,
1521
1543
  run_all_viewports: input.run_all_viewports === true || input.runAllViewports === true,
@@ -2033,6 +2055,16 @@ function summarizeLinkStatusEvidence(viewport, check) {
2033
2055
  function textKey(check) {
2034
2056
  return check.pattern ? `pattern:${check.pattern}/${check.flags || ""}` : `text:${check.text || ""}`;
2035
2057
  }
2058
+ function observeWithinTimeoutMs(check) {
2059
+ const raw = check.timeout_ms;
2060
+ if (typeof raw === "number" && Number.isFinite(raw) && raw > 0) return Math.min(Math.round(raw), 6e4);
2061
+ return 2e3;
2062
+ }
2063
+ function observeWithinKey(check) {
2064
+ const target = check.selector ? `selector:${check.selector}` : "page";
2065
+ const expectation = check.pattern ? `pattern:${check.pattern}/${check.flags || ""}` : check.text ? `text:${check.text}` : "visible";
2066
+ return `${target}|${expectation}|within:${observeWithinTimeoutMs(check)}`;
2067
+ }
2036
2068
  function textSequenceForCheck(viewport, check) {
2037
2069
  const key = selectorKey(check);
2038
2070
  const sequence = viewport.text_sequences?.[key];
@@ -2539,6 +2571,40 @@ function assessCheckFromEvidence(check, evidence) {
2539
2571
  message: failed ? `Selector ${key} text order failed in ${failed} viewport(s).` : void 0
2540
2572
  };
2541
2573
  }
2574
+ if (check.type === "observe_within") {
2575
+ const key = observeWithinKey(check);
2576
+ const timeoutMs = observeWithinTimeoutMs(check);
2577
+ const results = viewports.map((viewport) => {
2578
+ const observation = viewport.observations?.[key];
2579
+ const matched = observation?.matched === true;
2580
+ return {
2581
+ viewport: viewport.name,
2582
+ matched,
2583
+ elapsed_ms: numberValue(observation?.elapsed_ms) ?? null,
2584
+ timeout_ms: numberValue(observation?.timeout_ms) ?? timeoutMs,
2585
+ attempts: numberValue(observation?.attempts) ?? null,
2586
+ selector_count: numberValue(observation?.selector_count) ?? null,
2587
+ visible_count: numberValue(observation?.visible_count) ?? null,
2588
+ matched_count: numberValue(observation?.matched_count) ?? null,
2589
+ sample: stringValue(observation?.sample) ?? null,
2590
+ error: stringValue(observation?.error) ?? null
2591
+ };
2592
+ });
2593
+ const failed = results.filter((result) => !result.matched).length;
2594
+ return {
2595
+ type: check.type,
2596
+ label: checkLabel(check),
2597
+ status: failed ? "failed" : "passed",
2598
+ evidence: {
2599
+ selector: check.selector || null,
2600
+ text: check.text || null,
2601
+ pattern: check.pattern || null,
2602
+ timeout_ms: timeoutMs,
2603
+ viewports: results.map((result) => toJsonValue(result))
2604
+ },
2605
+ message: failed ? `Observation did not match within ${timeoutMs}ms in ${failed} viewport(s).` : void 0
2606
+ };
2607
+ }
2542
2608
  if (check.type === "frame_text_visible") {
2543
2609
  const key = selectorKey(check);
2544
2610
  const results = viewports.map((viewport) => {
@@ -3943,6 +4009,24 @@ function profileSetupWindowEvalReceipts(results) {
3943
4009
  return receipt;
3944
4010
  });
3945
4011
  }
4012
+ function profileSetupRangeValueReceipts(results) {
4013
+ return (results || [])
4014
+ .filter((result) => result && profileSetupResultAction(result) === "set_range_value")
4015
+ .map((result) => ({
4016
+ ordinal: result.ordinal ?? null,
4017
+ ok: result.ok !== false,
4018
+ selector: result.selector ?? null,
4019
+ frame_selector: result.frame_selector ?? null,
4020
+ requested_value: result.requested_value ?? null,
4021
+ actual_value: result.actual_value ?? null,
4022
+ before_value: result.before_value ?? null,
4023
+ value_as_number: result.value_as_number ?? null,
4024
+ min: result.min ?? null,
4025
+ max: result.max ?? null,
4026
+ step: result.step ?? null,
4027
+ reason: result.reason || result.error || null,
4028
+ }));
4029
+ }
3946
4030
  function sampleProfileSetupSummaryItems(items, limit) {
3947
4031
  if ((items || []).length <= limit) return items || [];
3948
4032
  const firstCount = Math.floor(limit / 2);
@@ -3999,6 +4083,8 @@ function profileSetupSummary(viewports, actionCount, expectedActionCountsByViewp
3999
4083
  const windowEvalStoredTotal = windowEvalReceipts.filter((result) => typeof result.return_stored_to === "string" && result.return_stored_to.trim()).length;
4000
4084
  const windowEvalCapturedTotal = windowEvalReceipts.filter((result) => result.return_captured === true).length;
4001
4085
  const sampledWindowEvalReceipts = sampleProfileSetupSummaryItems(windowEvalReceipts, 8);
4086
+ const rangeValueReceipts = profileSetupRangeValueReceipts(results);
4087
+ const sampledRangeValueReceipts = sampleProfileSetupSummaryItems(rangeValueReceipts, 8);
4002
4088
  const clickedItems = results
4003
4089
  .filter((result) => result && profileSetupResultAction(result) === "click" && result.ok !== false)
4004
4090
  .map((result) => {
@@ -4057,6 +4143,9 @@ function profileSetupSummary(viewports, actionCount, expectedActionCountsByViewp
4057
4143
  window_eval_captured_total: windowEvalCapturedTotal,
4058
4144
  window_eval_truncated: windowEvalReceipts.length > sampledWindowEvalReceipts.length,
4059
4145
  window_eval: sampledWindowEvalReceipts,
4146
+ set_range_value_total: rangeValueReceipts.length,
4147
+ set_range_value_truncated: rangeValueReceipts.length > sampledRangeValueReceipts.length,
4148
+ set_range_value: sampledRangeValueReceipts,
4060
4149
  clicked,
4061
4150
  text_samples: textSamples,
4062
4151
  failed: failed.map((result) => ({
@@ -4425,6 +4514,36 @@ function assessProfile(profile, evidence) {
4425
4514
  });
4426
4515
  continue;
4427
4516
  }
4517
+ if (check.type === "observe_within") {
4518
+ const key = observeWithinKey(check);
4519
+ const timeoutMs = observeWithinTimeoutMs(check);
4520
+ const results = checkViewports.map((viewport) => {
4521
+ const observation = viewport.observations && viewport.observations[key] && typeof viewport.observations[key] === "object"
4522
+ ? viewport.observations[key]
4523
+ : {};
4524
+ return {
4525
+ viewport: viewport.name,
4526
+ matched: observation.matched === true,
4527
+ elapsed_ms: typeof observation.elapsed_ms === "number" && Number.isFinite(observation.elapsed_ms) ? observation.elapsed_ms : null,
4528
+ timeout_ms: typeof observation.timeout_ms === "number" && Number.isFinite(observation.timeout_ms) ? observation.timeout_ms : timeoutMs,
4529
+ attempts: typeof observation.attempts === "number" && Number.isFinite(observation.attempts) ? observation.attempts : null,
4530
+ selector_count: typeof observation.selector_count === "number" && Number.isFinite(observation.selector_count) ? observation.selector_count : null,
4531
+ visible_count: typeof observation.visible_count === "number" && Number.isFinite(observation.visible_count) ? observation.visible_count : null,
4532
+ matched_count: typeof observation.matched_count === "number" && Number.isFinite(observation.matched_count) ? observation.matched_count : null,
4533
+ sample: typeof observation.sample === "string" && observation.sample.trim() ? observation.sample.trim() : null,
4534
+ error: typeof observation.error === "string" && observation.error.trim() ? observation.error.trim() : null,
4535
+ };
4536
+ });
4537
+ const failed = results.filter((result) => !result.matched).length;
4538
+ checks.push({
4539
+ type: check.type,
4540
+ label: check.label || check.type,
4541
+ status: failed ? "failed" : "passed",
4542
+ evidence: { selector: check.selector || null, text: check.text || null, pattern: check.pattern || null, timeout_ms: timeoutMs, viewports: results },
4543
+ message: failed ? "Observation did not match within " + timeoutMs + "ms in " + failed + " viewport(s)." : undefined,
4544
+ });
4545
+ continue;
4546
+ }
4428
4547
  if (check.type === "frame_text_visible") {
4429
4548
  const selector = check.selector || "";
4430
4549
  const results = checkViewports.map((viewport) => {
@@ -4857,6 +4976,19 @@ function ensureDialogHandler() {
4857
4976
  function textKey(check) {
4858
4977
  return check.pattern ? "pattern:" + check.pattern + "/" + (check.flags || "") : "text:" + (check.text || "");
4859
4978
  }
4979
+ function observeWithinTimeoutMs(check) {
4980
+ const raw = Number(check && check.timeout_ms);
4981
+ return Number.isFinite(raw) && raw > 0 ? Math.min(Math.round(raw), 60000) : 2000;
4982
+ }
4983
+ function observeWithinKey(check) {
4984
+ const target = check && check.selector ? "selector:" + check.selector : "page";
4985
+ const expectation = check && check.pattern
4986
+ ? "pattern:" + check.pattern + "/" + (check.flags || "")
4987
+ : check && check.text
4988
+ ? "text:" + check.text
4989
+ : "visible";
4990
+ return target + "|" + expectation + "|within:" + observeWithinTimeoutMs(check);
4991
+ }
4860
4992
  function textMatches(sample, check) {
4861
4993
  if (check.pattern) {
4862
4994
  try { return new RegExp(check.pattern, check.flags || "").test(sample || ""); } catch { return false; }
@@ -6172,6 +6304,104 @@ async function selectorTextSequence(selector) {
6172
6304
  };
6173
6305
  }).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) }));
6174
6306
  }
6307
+ async function observeWithinSnapshot(check) {
6308
+ const payload = {
6309
+ selector: check.selector || "",
6310
+ text: check.text || "",
6311
+ pattern: check.pattern || "",
6312
+ flags: check.flags || "",
6313
+ wants_text: Boolean(check.text || check.pattern),
6314
+ };
6315
+ if (payload.selector) {
6316
+ return page.locator(payload.selector).evaluateAll((elements, input) => {
6317
+ const compact = (value) => String(value || "").replace(/\s+/g, " ").trim();
6318
+ const matchText = (value) => {
6319
+ const source = compact(value);
6320
+ if (input.pattern) {
6321
+ try { return new RegExp(input.pattern, input.flags || "").test(source); } catch { return false; }
6322
+ }
6323
+ return source.includes(input.text || "");
6324
+ };
6325
+ const isVisible = (element) => {
6326
+ const style = window.getComputedStyle(element);
6327
+ const rect = element.getBoundingClientRect();
6328
+ return style && style.visibility !== "hidden" && style.display !== "none" && rect.width > 0 && rect.height > 0;
6329
+ };
6330
+ const rows = elements.map((element, index) => {
6331
+ const text = compact(element.innerText || element.textContent || "");
6332
+ const visible = isVisible(element);
6333
+ return { index, text, visible, matched: input.wants_text ? matchText(text) : visible };
6334
+ });
6335
+ const visibleRows = rows.filter((row) => row.visible);
6336
+ const matches = input.wants_text ? visibleRows.filter((row) => row.matched) : visibleRows;
6337
+ const sampleRow = matches[0] || visibleRows[0] || rows[0] || null;
6338
+ return {
6339
+ selector: input.selector,
6340
+ text: input.text || null,
6341
+ pattern: input.pattern || null,
6342
+ selector_count: rows.length,
6343
+ visible_count: visibleRows.length,
6344
+ matched_count: matches.length,
6345
+ matched: matches.length > 0,
6346
+ sample: sampleRow && sampleRow.text ? sampleRow.text.slice(0, 240) : null,
6347
+ };
6348
+ }, payload).catch((error) => ({
6349
+ selector: payload.selector,
6350
+ text: payload.text || null,
6351
+ pattern: payload.pattern || null,
6352
+ selector_count: 0,
6353
+ visible_count: 0,
6354
+ matched_count: 0,
6355
+ matched: false,
6356
+ sample: null,
6357
+ error: String(error && error.message ? error.message : error).slice(0, 500),
6358
+ }));
6359
+ }
6360
+ return page.evaluate((input) => {
6361
+ const compact = (value) => String(value || "").replace(/\s+/g, " ").trim();
6362
+ const sample = compact(document.body ? document.body.innerText || document.body.textContent || "" : "");
6363
+ let matched = false;
6364
+ if (input.pattern) {
6365
+ try { matched = new RegExp(input.pattern, input.flags || "").test(sample); } catch { matched = false; }
6366
+ } else {
6367
+ matched = sample.includes(input.text || "");
6368
+ }
6369
+ return {
6370
+ selector: null,
6371
+ text: input.text || null,
6372
+ pattern: input.pattern || null,
6373
+ matched,
6374
+ matched_count: matched ? 1 : 0,
6375
+ sample: sample.slice(0, 240),
6376
+ };
6377
+ }, payload).catch((error) => ({
6378
+ selector: null,
6379
+ text: payload.text || null,
6380
+ pattern: payload.pattern || null,
6381
+ matched: false,
6382
+ matched_count: 0,
6383
+ sample: null,
6384
+ error: String(error && error.message ? error.message : error).slice(0, 500),
6385
+ }));
6386
+ }
6387
+ async function observeWithin(check) {
6388
+ const timeoutMs = observeWithinTimeoutMs(check);
6389
+ const startedAt = Date.now();
6390
+ let attempts = 0;
6391
+ let last = null;
6392
+ while (true) {
6393
+ attempts += 1;
6394
+ last = await observeWithinSnapshot(check);
6395
+ const elapsedMs = Date.now() - startedAt;
6396
+ if (last && last.matched === true) {
6397
+ return { ...last, timeout_ms: timeoutMs, elapsed_ms: elapsedMs, attempts };
6398
+ }
6399
+ if (elapsedMs >= timeoutMs) {
6400
+ return { ...(last || {}), matched: false, timeout_ms: timeoutMs, elapsed_ms: elapsedMs, attempts };
6401
+ }
6402
+ await page.waitForTimeout(Math.min(100, Math.max(25, timeoutMs - elapsedMs)));
6403
+ }
6404
+ }
6175
6405
  function linkProbeMaxLinks(check) {
6176
6406
  const value = Number(check.max_links || check.maxLinks || check.limit || 100);
6177
6407
  return Number.isInteger(value) && value > 0 ? Math.min(value, 500) : 100;
@@ -7224,6 +7454,7 @@ async function captureViewport(viewport) {
7224
7454
  const text_matches = {};
7225
7455
  const text_match_samples = {};
7226
7456
  const text_case_insensitive_samples = {};
7457
+ const observations = {};
7227
7458
  const http_statuses = {};
7228
7459
  const link_statuses = {};
7229
7460
  for (const check of profile.checks || []) {
@@ -7244,6 +7475,10 @@ async function captureViewport(viewport) {
7244
7475
  selectors[check.selector] = selectors[check.selector] || await selectorStats(check.selector);
7245
7476
  text_sequences[check.selector] = await selectorTextSequence(check.selector);
7246
7477
  }
7478
+ if (check.type === "observe_within") {
7479
+ const key = observeWithinKey(check);
7480
+ observations[key] = observations[key] || await observeWithin(check);
7481
+ }
7247
7482
  if ((check.type === "text_visible" || check.type === "text_absent") && (check.text || check.pattern)) {
7248
7483
  const key = textKey(check);
7249
7484
  const sample = dom.body_text || dom.body_text_sample || "";
@@ -7337,6 +7572,7 @@ async function captureViewport(viewport) {
7337
7572
  text_matches,
7338
7573
  text_match_samples,
7339
7574
  text_case_insensitive_samples,
7575
+ observations,
7340
7576
  http_statuses,
7341
7577
  link_statuses,
7342
7578
  route_inventory: routeInventory,
@@ -4,7 +4,7 @@ declare const RIDDLE_PROOF_PROFILE_VERSION: "riddle-proof.profile.v1";
4
4
  declare const RIDDLE_PROOF_PROFILE_EVIDENCE_VERSION: "riddle-proof.profile-evidence.v1";
5
5
  declare const RIDDLE_PROOF_PROFILE_RESULT_VERSION: "riddle-proof.profile-result.v1";
6
6
  declare const RIDDLE_PROOF_PROFILE_STATUSES: readonly ["passed", "product_regression", "proof_insufficient", "environment_blocked", "configuration_error", "needs_human_review"];
7
- declare const RIDDLE_PROOF_PROFILE_CHECK_TYPES: readonly ["route_loaded", "url_search_param_equals", "url_search_param_absent", "selector_visible", "selector_absent", "selector_count_at_least", "selector_count_equals", "selector_count_equal", "selector_count_eq", "dialog_count_equals", "dialog_accept_count_equals", "dialog_dismiss_count_equals", "selector_text_visible", "selector_text_absent", "selector_text_order", "frame_text_visible", "frame_url_equals", "frame_url_matches", "frame_no_horizontal_overflow", "text_visible", "text_absent", "http_status", "link_status", "artifact_link_status", "route_inventory", "no_horizontal_overflow", "no_mobile_horizontal_overflow", "no_fatal_console_errors", "no_console_warnings"];
7
+ declare const RIDDLE_PROOF_PROFILE_CHECK_TYPES: readonly ["route_loaded", "url_search_param_equals", "url_search_param_absent", "selector_visible", "selector_absent", "selector_count_at_least", "selector_count_equals", "selector_count_equal", "selector_count_eq", "dialog_count_equals", "dialog_accept_count_equals", "dialog_dismiss_count_equals", "selector_text_visible", "selector_text_absent", "selector_text_order", "observe_within", "frame_text_visible", "frame_url_equals", "frame_url_matches", "frame_no_horizontal_overflow", "text_visible", "text_absent", "http_status", "link_status", "artifact_link_status", "route_inventory", "no_horizontal_overflow", "no_mobile_horizontal_overflow", "no_fatal_console_errors", "no_console_warnings"];
8
8
  declare const RIDDLE_PROOF_PROFILE_SETUP_ACTION_TYPES: readonly ["click", "drag", "press", "fill", "set_input_value", "set_range_value", "assert_text_visible", "assert_text_absent", "assert_selector_count", "assert_window_value", "assert_window_number", "local_storage", "session_storage", "clear_storage", "clear_console", "dialog_response", "screenshot", "wait", "wait_for_selector", "wait_for_text", "window_eval", "window_call", "window_call_until"];
9
9
  type RiddleProofProfileStatus = typeof RIDDLE_PROOF_PROFILE_STATUSES[number];
10
10
  type RiddleProofProfileCheckType = typeof RIDDLE_PROOF_PROFILE_CHECK_TYPES[number];
@@ -319,6 +319,7 @@ interface RiddleProofProfileViewportEvidence {
319
319
  text_matches?: Record<string, boolean>;
320
320
  text_match_samples?: Record<string, string[]>;
321
321
  text_case_insensitive_samples?: Record<string, string[]>;
322
+ observations?: Record<string, Record<string, JsonValue>>;
322
323
  http_statuses?: Record<string, Record<string, JsonValue>>;
323
324
  link_statuses?: Record<string, Record<string, JsonValue>>;
324
325
  route_inventory?: Record<string, JsonValue>;
package/dist/profile.d.ts CHANGED
@@ -4,7 +4,7 @@ declare const RIDDLE_PROOF_PROFILE_VERSION: "riddle-proof.profile.v1";
4
4
  declare const RIDDLE_PROOF_PROFILE_EVIDENCE_VERSION: "riddle-proof.profile-evidence.v1";
5
5
  declare const RIDDLE_PROOF_PROFILE_RESULT_VERSION: "riddle-proof.profile-result.v1";
6
6
  declare const RIDDLE_PROOF_PROFILE_STATUSES: readonly ["passed", "product_regression", "proof_insufficient", "environment_blocked", "configuration_error", "needs_human_review"];
7
- declare const RIDDLE_PROOF_PROFILE_CHECK_TYPES: readonly ["route_loaded", "url_search_param_equals", "url_search_param_absent", "selector_visible", "selector_absent", "selector_count_at_least", "selector_count_equals", "selector_count_equal", "selector_count_eq", "dialog_count_equals", "dialog_accept_count_equals", "dialog_dismiss_count_equals", "selector_text_visible", "selector_text_absent", "selector_text_order", "frame_text_visible", "frame_url_equals", "frame_url_matches", "frame_no_horizontal_overflow", "text_visible", "text_absent", "http_status", "link_status", "artifact_link_status", "route_inventory", "no_horizontal_overflow", "no_mobile_horizontal_overflow", "no_fatal_console_errors", "no_console_warnings"];
7
+ declare const RIDDLE_PROOF_PROFILE_CHECK_TYPES: readonly ["route_loaded", "url_search_param_equals", "url_search_param_absent", "selector_visible", "selector_absent", "selector_count_at_least", "selector_count_equals", "selector_count_equal", "selector_count_eq", "dialog_count_equals", "dialog_accept_count_equals", "dialog_dismiss_count_equals", "selector_text_visible", "selector_text_absent", "selector_text_order", "observe_within", "frame_text_visible", "frame_url_equals", "frame_url_matches", "frame_no_horizontal_overflow", "text_visible", "text_absent", "http_status", "link_status", "artifact_link_status", "route_inventory", "no_horizontal_overflow", "no_mobile_horizontal_overflow", "no_fatal_console_errors", "no_console_warnings"];
8
8
  declare const RIDDLE_PROOF_PROFILE_SETUP_ACTION_TYPES: readonly ["click", "drag", "press", "fill", "set_input_value", "set_range_value", "assert_text_visible", "assert_text_absent", "assert_selector_count", "assert_window_value", "assert_window_number", "local_storage", "session_storage", "clear_storage", "clear_console", "dialog_response", "screenshot", "wait", "wait_for_selector", "wait_for_text", "window_eval", "window_call", "window_call_until"];
9
9
  type RiddleProofProfileStatus = typeof RIDDLE_PROOF_PROFILE_STATUSES[number];
10
10
  type RiddleProofProfileCheckType = typeof RIDDLE_PROOF_PROFILE_CHECK_TYPES[number];
@@ -319,6 +319,7 @@ interface RiddleProofProfileViewportEvidence {
319
319
  text_matches?: Record<string, boolean>;
320
320
  text_match_samples?: Record<string, string[]>;
321
321
  text_case_insensitive_samples?: Record<string, string[]>;
322
+ observations?: Record<string, Record<string, JsonValue>>;
322
323
  http_statuses?: Record<string, Record<string, JsonValue>>;
323
324
  link_statuses?: Record<string, Record<string, JsonValue>>;
324
325
  route_inventory?: Record<string, JsonValue>;
package/dist/profile.js CHANGED
@@ -23,7 +23,7 @@ import {
23
23
  resolveRiddleProofProfileTimeoutSec,
24
24
  slugifyRiddleProofProfileName,
25
25
  summarizeRiddleProofProfileResult
26
- } from "./chunk-WAJA6TJV.js";
26
+ } from "./chunk-QJJ3ISMK.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.148",
3
+ "version": "0.7.150",
4
4
  "description": "Reusable Riddle Proof contracts and helpers for evidence-backed agent changes.",
5
5
  "license": "MIT",
6
6
  "author": "RiddleDC",