@riddledc/riddle-proof 0.7.62 → 0.7.64

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md CHANGED
@@ -242,10 +242,10 @@ appears only after a picker, tab, login stub, storage seed, form fill,
242
242
  transport control, or other bounded interaction. Supported setup actions are
243
243
  `click`, `drag`, `press`, `fill`, `set_input_value`, `assert_text_visible`,
244
244
  `assert_text_absent`, `assert_selector_count`, `assert_window_value`,
245
- `assert_window_number`, `local_storage`, `session_storage`, `clear_storage`, `wait`,
246
- `wait_for_selector`, `wait_for_text`, and `window_call`; a failed setup action
247
- is recorded as a failed `setup_actions_succeeded` check so the profile cannot
248
- pass without reaching the intended state. Text-matched `click` actions prefer
245
+ `assert_window_number`, `local_storage`, `session_storage`, `clear_storage`,
246
+ `screenshot`, `wait`, `wait_for_selector`, `wait_for_text`, and `window_call`;
247
+ a failed setup action is recorded as a failed `setup_actions_succeeded` check so
248
+ the profile cannot pass without reaching the intended state. Text-matched `click` actions prefer
249
249
  visible matching elements, which keeps responsive layouts from selecting hidden
250
250
  desktop or mobile-only links. Add `force: true` to a click action only when the
251
251
  matched visible element is intentionally animated or otherwise never becomes
@@ -276,6 +276,10 @@ can include `repeat` / `repeat_count` / `times` from 1 to 100; each repetition
276
276
  is recorded with `repeat_index` and `repeat_count`, and `after_ms` runs after
277
277
  each repetition. Use it for bounded game proof helpers, retry controls, or other
278
278
  workflows where one declarative action needs to advance the app several times.
279
+ Use `screenshot` with an optional `label` to capture durable Riddle screenshots
280
+ at important setup milestones, such as after a route switch, terminal state, or
281
+ reset. These labels are recorded in setup evidence and included in profile
282
+ artifact summaries alongside final viewport screenshots.
279
283
  Add `frame_selector` / `frameSelector` to a setup action when the interaction
280
284
  target lives inside an embedded iframe, such as a community game player or
281
285
  hosted preview surface. Selector-based actions, storage actions, window calls,
@@ -287,8 +291,11 @@ it defaults to the first frame.
287
291
  Profiles with setup actions also include a compact
288
292
  `setup_actions_succeeded.evidence.setup_summary`. The summary groups each
289
293
  viewport's final route, final URL, action counts, clicked targets, iframe URLs,
290
- compact text samples, and failures so setup-heavy clickthrough or iframe proofs
291
- can be reviewed without reading every raw setup-action result.
294
+ setup screenshots, compact text samples, and failures so setup-heavy clickthrough or iframe proofs
295
+ can be reviewed without reading every raw setup-action result. Long click
296
+ sequences include `clicked_total` and `clicked_truncated`; the compact `clicked`
297
+ list keeps the first and last clicked targets so later route switches and reset
298
+ actions stay visible.
292
299
 
293
300
  `target.timeout_sec` is optional. Use it for known-heavy profile targets so the
294
301
  profile carries its own hosted Riddle worker budget; an explicit CLI `--timeout`
@@ -46,6 +46,7 @@ var RIDDLE_PROOF_PROFILE_SETUP_ACTION_TYPES = [
46
46
  "local_storage",
47
47
  "session_storage",
48
48
  "clear_storage",
49
+ "screenshot",
49
50
  "wait",
50
51
  "wait_for_selector",
51
52
  "wait_for_text",
@@ -206,6 +207,23 @@ function profileSetupActionCounts(results) {
206
207
  }
207
208
  return toJsonValue(counts);
208
209
  }
210
+ function profileSetupScreenshotLabels(results) {
211
+ return results.filter((result) => profileSetupResultAction(result) === "screenshot" && result.ok !== false && typeof result.screenshot_label === "string").map((result) => result.screenshot_label).filter(Boolean);
212
+ }
213
+ function sampleProfileSetupSummaryItems(items, limit) {
214
+ if (items.length <= limit) return items;
215
+ const firstCount = Math.floor(limit / 2);
216
+ const lastCount = limit - firstCount;
217
+ return [...items.slice(0, firstCount), ...items.slice(-lastCount)];
218
+ }
219
+ function profileScreenshotLabels(viewports) {
220
+ const labels = [];
221
+ for (const viewport of viewports || []) {
222
+ if (viewport.screenshot_label) labels.push(viewport.screenshot_label);
223
+ labels.push(...profileSetupScreenshotLabels(viewport.setup_action_results || []));
224
+ }
225
+ return labels;
226
+ }
209
227
  function profileSetupSummary(viewports, actionCount) {
210
228
  return toJsonValue({
211
229
  viewport_count: viewports.length,
@@ -213,12 +231,13 @@ function profileSetupSummary(viewports, actionCount) {
213
231
  viewports: viewports.map((viewport) => {
214
232
  const results = viewport.setup_action_results || [];
215
233
  const failed = results.filter((result) => result.ok === false);
216
- const clicked = results.filter((result) => profileSetupResultAction(result) === "click" && result.ok !== false).map((result) => ({
234
+ const clickedItems = results.filter((result) => profileSetupResultAction(result) === "click" && result.ok !== false).map((result) => ({
217
235
  ordinal: result.ordinal ?? null,
218
236
  selector: result.selector ?? null,
219
237
  frame_selector: result.frame_selector ?? null,
220
238
  text: compactProfileSetupSummaryText(result.text)
221
- })).slice(0, 8);
239
+ }));
240
+ const clicked = sampleProfileSetupSummaryItems(clickedItems, 8);
222
241
  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) => ({
223
242
  ordinal: result.ordinal ?? null,
224
243
  action: profileSetupResultAction(result),
@@ -234,6 +253,9 @@ function profileSetupSummary(viewports, actionCount) {
234
253
  action_counts: profileSetupActionCounts(results),
235
254
  frame_action_count: results.filter((result) => result.frame_selector).length,
236
255
  frame_urls: profileSetupFrameUrls(viewport),
256
+ setup_screenshots: profileSetupScreenshotLabels(results),
257
+ clicked_total: clickedItems.length,
258
+ clicked_truncated: clickedItems.length > clicked.length,
237
259
  clicked,
238
260
  text_samples,
239
261
  failed: failed.map((result) => ({
@@ -277,7 +299,7 @@ function isSupportedCheckType(value) {
277
299
  }
278
300
  function normalizeSetupActionType(value, index) {
279
301
  const normalizedInput = String(value || "").trim().replace(/-/g, "_");
280
- const normalized = normalizedInput === "clear_browser_storage" ? "clear_storage" : normalizedInput === "pointer_drag" || normalizedInput === "mouse_drag" || normalizedInput === "drag_to" ? "drag" : normalizedInput === "keyboard_press" || normalizedInput === "key_press" ? "press" : normalizedInput;
302
+ const normalized = normalizedInput === "clear_browser_storage" ? "clear_storage" : normalizedInput === "pointer_drag" || normalizedInput === "mouse_drag" || normalizedInput === "drag_to" ? "drag" : normalizedInput === "keyboard_press" || normalizedInput === "key_press" ? "press" : normalizedInput === "capture_screenshot" || normalizedInput === "save_screenshot" || normalizedInput === "setup_screenshot" ? "screenshot" : normalizedInput;
281
303
  if (RIDDLE_PROOF_PROFILE_SETUP_ACTION_TYPES.includes(normalized)) {
282
304
  return normalized;
283
305
  }
@@ -408,6 +430,7 @@ function normalizeSetupAction(input, index) {
408
430
  key,
409
431
  value,
410
432
  value_json: hasJsonValue ? toJsonValue(input.value_json ?? input.valueJson ?? input.json) : void 0,
433
+ label: stringFromOwn(input, "label", "name", "screenshot_label", "screenshotLabel"),
411
434
  path,
412
435
  args,
413
436
  expect_return: hasExpectedReturn ? toJsonValue(valueFromOwn(input, "expect_return", "expectReturn", "expected_return", "expectedReturn")) : void 0,
@@ -1450,7 +1473,7 @@ function assessRiddleProofProfileEvidence(profile, evidence, options = {}) {
1450
1473
  ].filter((check) => Boolean(check)) : [];
1451
1474
  const status = profileStatusFromEvidence(profile, evidence, checks);
1452
1475
  const firstViewport = evidence?.viewports?.[0];
1453
- const screenshots = (evidence?.viewports || []).map((viewport) => viewport.screenshot_label).filter((label) => Boolean(label));
1476
+ const screenshots = profileScreenshotLabels(evidence?.viewports);
1454
1477
  return {
1455
1478
  version: RIDDLE_PROOF_PROFILE_RESULT_VERSION,
1456
1479
  profile_name: profile.name,
@@ -1799,6 +1822,26 @@ function profileSetupActionCounts(results) {
1799
1822
  }
1800
1823
  return counts;
1801
1824
  }
1825
+ function profileSetupScreenshotLabels(results) {
1826
+ return (results || [])
1827
+ .filter((result) => result && profileSetupResultAction(result) === "screenshot" && result.ok !== false && typeof result.screenshot_label === "string")
1828
+ .map((result) => result.screenshot_label)
1829
+ .filter(Boolean);
1830
+ }
1831
+ function sampleProfileSetupSummaryItems(items, limit) {
1832
+ if ((items || []).length <= limit) return items || [];
1833
+ const firstCount = Math.floor(limit / 2);
1834
+ const lastCount = limit - firstCount;
1835
+ return [...items.slice(0, firstCount), ...items.slice(-lastCount)];
1836
+ }
1837
+ function profileScreenshotLabels(viewports) {
1838
+ const labels = [];
1839
+ for (const viewport of viewports || []) {
1840
+ if (viewport && viewport.screenshot_label) labels.push(viewport.screenshot_label);
1841
+ labels.push(...profileSetupScreenshotLabels(viewport && viewport.setup_action_results || []));
1842
+ }
1843
+ return labels;
1844
+ }
1802
1845
  function profileSetupSummary(viewports, actionCount) {
1803
1846
  return {
1804
1847
  viewport_count: (viewports || []).length,
@@ -1806,15 +1849,15 @@ function profileSetupSummary(viewports, actionCount) {
1806
1849
  viewports: (viewports || []).map((viewport) => {
1807
1850
  const results = viewport.setup_action_results || [];
1808
1851
  const failed = results.filter((result) => result && result.ok === false);
1809
- const clicked = results
1852
+ const clickedItems = results
1810
1853
  .filter((result) => result && profileSetupResultAction(result) === "click" && result.ok !== false)
1811
1854
  .map((result) => ({
1812
1855
  ordinal: result.ordinal ?? null,
1813
1856
  selector: result.selector ?? null,
1814
1857
  frame_selector: result.frame_selector ?? null,
1815
1858
  text: compactProfileSetupSummaryText(result.text),
1816
- }))
1817
- .slice(0, 8);
1859
+ }));
1860
+ const clicked = sampleProfileSetupSummaryItems(clickedItems, 8);
1818
1861
  const textSamples = results
1819
1862
  .filter((result) => result && result.ok !== false && typeof result.text === "string" && (
1820
1863
  profileSetupResultAction(result) === "assert_text_visible"
@@ -1838,6 +1881,9 @@ function profileSetupSummary(viewports, actionCount) {
1838
1881
  action_counts: profileSetupActionCounts(results),
1839
1882
  frame_action_count: results.filter((result) => result && result.frame_selector).length,
1840
1883
  frame_urls: profileSetupFrameUrls(viewport),
1884
+ setup_screenshots: profileSetupScreenshotLabels(results),
1885
+ clicked_total: clickedItems.length,
1886
+ clicked_truncated: clickedItems.length > clicked.length,
1841
1887
  clicked,
1842
1888
  text_samples: textSamples,
1843
1889
  failed: failed.map((result) => ({
@@ -2325,7 +2371,7 @@ function assessProfile(profile, evidence) {
2325
2371
  else if (expectedViewportCount && viewports.length < expectedViewportCount) status = "proof_insufficient";
2326
2372
  else if (checks.some((check) => check.status === "needs_human_review")) status = "needs_human_review";
2327
2373
  else if (checks.some((check) => check.status === "failed")) status = "product_regression";
2328
- const screenshotLabels = viewports.map((viewport) => viewport.screenshot_label).filter(Boolean);
2374
+ const screenshotLabels = profileScreenshotLabels(viewports);
2329
2375
  const route = viewports[0] && viewports[0].route ? viewports[0].route : { requested: evidence.target_url, observed: "", matched: false, error: "missing viewport evidence" };
2330
2376
  const passedChecks = checks.filter((check) => check.status === "passed").length;
2331
2377
  const failedChecks = checks.filter((check) => check.status === "failed").length;
@@ -2692,6 +2738,18 @@ async function executeSetupAction(action, ordinal) {
2692
2738
  await page.waitForTimeout(ms);
2693
2739
  return { ...base, ok: true, ms };
2694
2740
  }
2741
+ if (type === "screenshot") {
2742
+ const rawLabel = String(action.label || action.name || action.screenshot_label || action.screenshotLabel || ("setup-" + ordinal));
2743
+ const labelPart = rawLabel
2744
+ .toLowerCase()
2745
+ .replace(/[^a-z0-9_-]+/g, "-")
2746
+ .replace(/^-+|-+$/g, "")
2747
+ .slice(0, 80) || ("setup-" + ordinal);
2748
+ const label = profileSlug + "-" + viewport.name + "-" + labelPart;
2749
+ if (typeof saveScreenshot !== "function") return { ...base, reason: "save_screenshot_unavailable", label: rawLabel };
2750
+ await saveScreenshot(label);
2751
+ return { ...base, ok: true, label: rawLabel, screenshot_label: label };
2752
+ }
2695
2753
  if (type === "wait_for_selector") {
2696
2754
  const scope = await setupActionScope(action, timeout);
2697
2755
  if (!scope.ok) return setupScopeFailure(base, scope);
package/dist/cli.cjs CHANGED
@@ -6919,6 +6919,7 @@ var RIDDLE_PROOF_PROFILE_SETUP_ACTION_TYPES = [
6919
6919
  "local_storage",
6920
6920
  "session_storage",
6921
6921
  "clear_storage",
6922
+ "screenshot",
6922
6923
  "wait",
6923
6924
  "wait_for_selector",
6924
6925
  "wait_for_text",
@@ -7079,6 +7080,23 @@ function profileSetupActionCounts(results) {
7079
7080
  }
7080
7081
  return toJsonValue(counts);
7081
7082
  }
7083
+ function profileSetupScreenshotLabels(results) {
7084
+ return results.filter((result) => profileSetupResultAction(result) === "screenshot" && result.ok !== false && typeof result.screenshot_label === "string").map((result) => result.screenshot_label).filter(Boolean);
7085
+ }
7086
+ function sampleProfileSetupSummaryItems(items, limit) {
7087
+ if (items.length <= limit) return items;
7088
+ const firstCount = Math.floor(limit / 2);
7089
+ const lastCount = limit - firstCount;
7090
+ return [...items.slice(0, firstCount), ...items.slice(-lastCount)];
7091
+ }
7092
+ function profileScreenshotLabels(viewports) {
7093
+ const labels = [];
7094
+ for (const viewport of viewports || []) {
7095
+ if (viewport.screenshot_label) labels.push(viewport.screenshot_label);
7096
+ labels.push(...profileSetupScreenshotLabels(viewport.setup_action_results || []));
7097
+ }
7098
+ return labels;
7099
+ }
7082
7100
  function profileSetupSummary(viewports, actionCount) {
7083
7101
  return toJsonValue({
7084
7102
  viewport_count: viewports.length,
@@ -7086,12 +7104,13 @@ function profileSetupSummary(viewports, actionCount) {
7086
7104
  viewports: viewports.map((viewport) => {
7087
7105
  const results = viewport.setup_action_results || [];
7088
7106
  const failed = results.filter((result) => result.ok === false);
7089
- const clicked = results.filter((result) => profileSetupResultAction(result) === "click" && result.ok !== false).map((result) => ({
7107
+ const clickedItems = results.filter((result) => profileSetupResultAction(result) === "click" && result.ok !== false).map((result) => ({
7090
7108
  ordinal: result.ordinal ?? null,
7091
7109
  selector: result.selector ?? null,
7092
7110
  frame_selector: result.frame_selector ?? null,
7093
7111
  text: compactProfileSetupSummaryText(result.text)
7094
- })).slice(0, 8);
7112
+ }));
7113
+ const clicked = sampleProfileSetupSummaryItems(clickedItems, 8);
7095
7114
  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) => ({
7096
7115
  ordinal: result.ordinal ?? null,
7097
7116
  action: profileSetupResultAction(result),
@@ -7107,6 +7126,9 @@ function profileSetupSummary(viewports, actionCount) {
7107
7126
  action_counts: profileSetupActionCounts(results),
7108
7127
  frame_action_count: results.filter((result) => result.frame_selector).length,
7109
7128
  frame_urls: profileSetupFrameUrls(viewport),
7129
+ setup_screenshots: profileSetupScreenshotLabels(results),
7130
+ clicked_total: clickedItems.length,
7131
+ clicked_truncated: clickedItems.length > clicked.length,
7110
7132
  clicked,
7111
7133
  text_samples,
7112
7134
  failed: failed.map((result) => ({
@@ -7150,7 +7172,7 @@ function isSupportedCheckType(value) {
7150
7172
  }
7151
7173
  function normalizeSetupActionType(value, index) {
7152
7174
  const normalizedInput = String(value || "").trim().replace(/-/g, "_");
7153
- const normalized = normalizedInput === "clear_browser_storage" ? "clear_storage" : normalizedInput === "pointer_drag" || normalizedInput === "mouse_drag" || normalizedInput === "drag_to" ? "drag" : normalizedInput === "keyboard_press" || normalizedInput === "key_press" ? "press" : normalizedInput;
7175
+ const normalized = normalizedInput === "clear_browser_storage" ? "clear_storage" : normalizedInput === "pointer_drag" || normalizedInput === "mouse_drag" || normalizedInput === "drag_to" ? "drag" : normalizedInput === "keyboard_press" || normalizedInput === "key_press" ? "press" : normalizedInput === "capture_screenshot" || normalizedInput === "save_screenshot" || normalizedInput === "setup_screenshot" ? "screenshot" : normalizedInput;
7154
7176
  if (RIDDLE_PROOF_PROFILE_SETUP_ACTION_TYPES.includes(normalized)) {
7155
7177
  return normalized;
7156
7178
  }
@@ -7281,6 +7303,7 @@ function normalizeSetupAction(input, index) {
7281
7303
  key,
7282
7304
  value,
7283
7305
  value_json: hasJsonValue ? toJsonValue(input.value_json ?? input.valueJson ?? input.json) : void 0,
7306
+ label: stringFromOwn(input, "label", "name", "screenshot_label", "screenshotLabel"),
7284
7307
  path: path7,
7285
7308
  args,
7286
7309
  expect_return: hasExpectedReturn ? toJsonValue(valueFromOwn(input, "expect_return", "expectReturn", "expected_return", "expectedReturn")) : void 0,
@@ -8323,7 +8346,7 @@ function assessRiddleProofProfileEvidence(profile, evidence, options = {}) {
8323
8346
  ].filter((check) => Boolean(check)) : [];
8324
8347
  const status = profileStatusFromEvidence(profile, evidence, checks);
8325
8348
  const firstViewport = evidence?.viewports?.[0];
8326
- const screenshots = (evidence?.viewports || []).map((viewport) => viewport.screenshot_label).filter((label) => Boolean(label));
8349
+ const screenshots = profileScreenshotLabels(evidence?.viewports);
8327
8350
  return {
8328
8351
  version: RIDDLE_PROOF_PROFILE_RESULT_VERSION,
8329
8352
  profile_name: profile.name,
@@ -8656,6 +8679,26 @@ function profileSetupActionCounts(results) {
8656
8679
  }
8657
8680
  return counts;
8658
8681
  }
8682
+ function profileSetupScreenshotLabels(results) {
8683
+ return (results || [])
8684
+ .filter((result) => result && profileSetupResultAction(result) === "screenshot" && result.ok !== false && typeof result.screenshot_label === "string")
8685
+ .map((result) => result.screenshot_label)
8686
+ .filter(Boolean);
8687
+ }
8688
+ function sampleProfileSetupSummaryItems(items, limit) {
8689
+ if ((items || []).length <= limit) return items || [];
8690
+ const firstCount = Math.floor(limit / 2);
8691
+ const lastCount = limit - firstCount;
8692
+ return [...items.slice(0, firstCount), ...items.slice(-lastCount)];
8693
+ }
8694
+ function profileScreenshotLabels(viewports) {
8695
+ const labels = [];
8696
+ for (const viewport of viewports || []) {
8697
+ if (viewport && viewport.screenshot_label) labels.push(viewport.screenshot_label);
8698
+ labels.push(...profileSetupScreenshotLabels(viewport && viewport.setup_action_results || []));
8699
+ }
8700
+ return labels;
8701
+ }
8659
8702
  function profileSetupSummary(viewports, actionCount) {
8660
8703
  return {
8661
8704
  viewport_count: (viewports || []).length,
@@ -8663,15 +8706,15 @@ function profileSetupSummary(viewports, actionCount) {
8663
8706
  viewports: (viewports || []).map((viewport) => {
8664
8707
  const results = viewport.setup_action_results || [];
8665
8708
  const failed = results.filter((result) => result && result.ok === false);
8666
- const clicked = results
8709
+ const clickedItems = results
8667
8710
  .filter((result) => result && profileSetupResultAction(result) === "click" && result.ok !== false)
8668
8711
  .map((result) => ({
8669
8712
  ordinal: result.ordinal ?? null,
8670
8713
  selector: result.selector ?? null,
8671
8714
  frame_selector: result.frame_selector ?? null,
8672
8715
  text: compactProfileSetupSummaryText(result.text),
8673
- }))
8674
- .slice(0, 8);
8716
+ }));
8717
+ const clicked = sampleProfileSetupSummaryItems(clickedItems, 8);
8675
8718
  const textSamples = results
8676
8719
  .filter((result) => result && result.ok !== false && typeof result.text === "string" && (
8677
8720
  profileSetupResultAction(result) === "assert_text_visible"
@@ -8695,6 +8738,9 @@ function profileSetupSummary(viewports, actionCount) {
8695
8738
  action_counts: profileSetupActionCounts(results),
8696
8739
  frame_action_count: results.filter((result) => result && result.frame_selector).length,
8697
8740
  frame_urls: profileSetupFrameUrls(viewport),
8741
+ setup_screenshots: profileSetupScreenshotLabels(results),
8742
+ clicked_total: clickedItems.length,
8743
+ clicked_truncated: clickedItems.length > clicked.length,
8698
8744
  clicked,
8699
8745
  text_samples: textSamples,
8700
8746
  failed: failed.map((result) => ({
@@ -9182,7 +9228,7 @@ function assessProfile(profile, evidence) {
9182
9228
  else if (expectedViewportCount && viewports.length < expectedViewportCount) status = "proof_insufficient";
9183
9229
  else if (checks.some((check) => check.status === "needs_human_review")) status = "needs_human_review";
9184
9230
  else if (checks.some((check) => check.status === "failed")) status = "product_regression";
9185
- const screenshotLabels = viewports.map((viewport) => viewport.screenshot_label).filter(Boolean);
9231
+ const screenshotLabels = profileScreenshotLabels(viewports);
9186
9232
  const route = viewports[0] && viewports[0].route ? viewports[0].route : { requested: evidence.target_url, observed: "", matched: false, error: "missing viewport evidence" };
9187
9233
  const passedChecks = checks.filter((check) => check.status === "passed").length;
9188
9234
  const failedChecks = checks.filter((check) => check.status === "failed").length;
@@ -9549,6 +9595,18 @@ async function executeSetupAction(action, ordinal) {
9549
9595
  await page.waitForTimeout(ms);
9550
9596
  return { ...base, ok: true, ms };
9551
9597
  }
9598
+ if (type === "screenshot") {
9599
+ const rawLabel = String(action.label || action.name || action.screenshot_label || action.screenshotLabel || ("setup-" + ordinal));
9600
+ const labelPart = rawLabel
9601
+ .toLowerCase()
9602
+ .replace(/[^a-z0-9_-]+/g, "-")
9603
+ .replace(/^-+|-+$/g, "")
9604
+ .slice(0, 80) || ("setup-" + ordinal);
9605
+ const label = profileSlug + "-" + viewport.name + "-" + labelPart;
9606
+ if (typeof saveScreenshot !== "function") return { ...base, reason: "save_screenshot_unavailable", label: rawLabel };
9607
+ await saveScreenshot(label);
9608
+ return { ...base, ok: true, label: rawLabel, screenshot_label: label };
9609
+ }
9552
9610
  if (type === "wait_for_selector") {
9553
9611
  const scope = await setupActionScope(action, timeout);
9554
9612
  if (!scope.ok) return setupScopeFailure(base, scope);
package/dist/cli.js CHANGED
@@ -10,7 +10,7 @@ import {
10
10
  profileStatusExitCode,
11
11
  resolveRiddleProofProfileTargetUrl,
12
12
  resolveRiddleProofProfileTimeoutSec
13
- } from "./chunk-MIHU2AWC.js";
13
+ } from "./chunk-ZVKKBM2J.js";
14
14
  import {
15
15
  createRiddleApiClient,
16
16
  parseRiddleViewport
package/dist/index.cjs CHANGED
@@ -8760,6 +8760,7 @@ var RIDDLE_PROOF_PROFILE_SETUP_ACTION_TYPES = [
8760
8760
  "local_storage",
8761
8761
  "session_storage",
8762
8762
  "clear_storage",
8763
+ "screenshot",
8763
8764
  "wait",
8764
8765
  "wait_for_selector",
8765
8766
  "wait_for_text",
@@ -8920,6 +8921,23 @@ function profileSetupActionCounts(results) {
8920
8921
  }
8921
8922
  return toJsonValue(counts);
8922
8923
  }
8924
+ function profileSetupScreenshotLabels(results) {
8925
+ return results.filter((result) => profileSetupResultAction(result) === "screenshot" && result.ok !== false && typeof result.screenshot_label === "string").map((result) => result.screenshot_label).filter(Boolean);
8926
+ }
8927
+ function sampleProfileSetupSummaryItems(items, limit) {
8928
+ if (items.length <= limit) return items;
8929
+ const firstCount = Math.floor(limit / 2);
8930
+ const lastCount = limit - firstCount;
8931
+ return [...items.slice(0, firstCount), ...items.slice(-lastCount)];
8932
+ }
8933
+ function profileScreenshotLabels(viewports) {
8934
+ const labels = [];
8935
+ for (const viewport of viewports || []) {
8936
+ if (viewport.screenshot_label) labels.push(viewport.screenshot_label);
8937
+ labels.push(...profileSetupScreenshotLabels(viewport.setup_action_results || []));
8938
+ }
8939
+ return labels;
8940
+ }
8923
8941
  function profileSetupSummary(viewports, actionCount) {
8924
8942
  return toJsonValue({
8925
8943
  viewport_count: viewports.length,
@@ -8927,12 +8945,13 @@ function profileSetupSummary(viewports, actionCount) {
8927
8945
  viewports: viewports.map((viewport) => {
8928
8946
  const results = viewport.setup_action_results || [];
8929
8947
  const failed = results.filter((result) => result.ok === false);
8930
- const clicked = results.filter((result) => profileSetupResultAction(result) === "click" && result.ok !== false).map((result) => ({
8948
+ const clickedItems = results.filter((result) => profileSetupResultAction(result) === "click" && result.ok !== false).map((result) => ({
8931
8949
  ordinal: result.ordinal ?? null,
8932
8950
  selector: result.selector ?? null,
8933
8951
  frame_selector: result.frame_selector ?? null,
8934
8952
  text: compactProfileSetupSummaryText(result.text)
8935
- })).slice(0, 8);
8953
+ }));
8954
+ const clicked = sampleProfileSetupSummaryItems(clickedItems, 8);
8936
8955
  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) => ({
8937
8956
  ordinal: result.ordinal ?? null,
8938
8957
  action: profileSetupResultAction(result),
@@ -8948,6 +8967,9 @@ function profileSetupSummary(viewports, actionCount) {
8948
8967
  action_counts: profileSetupActionCounts(results),
8949
8968
  frame_action_count: results.filter((result) => result.frame_selector).length,
8950
8969
  frame_urls: profileSetupFrameUrls(viewport),
8970
+ setup_screenshots: profileSetupScreenshotLabels(results),
8971
+ clicked_total: clickedItems.length,
8972
+ clicked_truncated: clickedItems.length > clicked.length,
8951
8973
  clicked,
8952
8974
  text_samples,
8953
8975
  failed: failed.map((result) => ({
@@ -8991,7 +9013,7 @@ function isSupportedCheckType(value) {
8991
9013
  }
8992
9014
  function normalizeSetupActionType(value, index) {
8993
9015
  const normalizedInput = String(value || "").trim().replace(/-/g, "_");
8994
- const normalized = normalizedInput === "clear_browser_storage" ? "clear_storage" : normalizedInput === "pointer_drag" || normalizedInput === "mouse_drag" || normalizedInput === "drag_to" ? "drag" : normalizedInput === "keyboard_press" || normalizedInput === "key_press" ? "press" : normalizedInput;
9016
+ const normalized = normalizedInput === "clear_browser_storage" ? "clear_storage" : normalizedInput === "pointer_drag" || normalizedInput === "mouse_drag" || normalizedInput === "drag_to" ? "drag" : normalizedInput === "keyboard_press" || normalizedInput === "key_press" ? "press" : normalizedInput === "capture_screenshot" || normalizedInput === "save_screenshot" || normalizedInput === "setup_screenshot" ? "screenshot" : normalizedInput;
8995
9017
  if (RIDDLE_PROOF_PROFILE_SETUP_ACTION_TYPES.includes(normalized)) {
8996
9018
  return normalized;
8997
9019
  }
@@ -9122,6 +9144,7 @@ function normalizeSetupAction(input, index) {
9122
9144
  key,
9123
9145
  value,
9124
9146
  value_json: hasJsonValue ? toJsonValue(input.value_json ?? input.valueJson ?? input.json) : void 0,
9147
+ label: stringFromOwn(input, "label", "name", "screenshot_label", "screenshotLabel"),
9125
9148
  path: path6,
9126
9149
  args,
9127
9150
  expect_return: hasExpectedReturn ? toJsonValue(valueFromOwn(input, "expect_return", "expectReturn", "expected_return", "expectedReturn")) : void 0,
@@ -10164,7 +10187,7 @@ function assessRiddleProofProfileEvidence(profile, evidence, options = {}) {
10164
10187
  ].filter((check) => Boolean(check)) : [];
10165
10188
  const status = profileStatusFromEvidence(profile, evidence, checks);
10166
10189
  const firstViewport = evidence?.viewports?.[0];
10167
- const screenshots = (evidence?.viewports || []).map((viewport) => viewport.screenshot_label).filter((label) => Boolean(label));
10190
+ const screenshots = profileScreenshotLabels(evidence?.viewports);
10168
10191
  return {
10169
10192
  version: RIDDLE_PROOF_PROFILE_RESULT_VERSION,
10170
10193
  profile_name: profile.name,
@@ -10513,6 +10536,26 @@ function profileSetupActionCounts(results) {
10513
10536
  }
10514
10537
  return counts;
10515
10538
  }
10539
+ function profileSetupScreenshotLabels(results) {
10540
+ return (results || [])
10541
+ .filter((result) => result && profileSetupResultAction(result) === "screenshot" && result.ok !== false && typeof result.screenshot_label === "string")
10542
+ .map((result) => result.screenshot_label)
10543
+ .filter(Boolean);
10544
+ }
10545
+ function sampleProfileSetupSummaryItems(items, limit) {
10546
+ if ((items || []).length <= limit) return items || [];
10547
+ const firstCount = Math.floor(limit / 2);
10548
+ const lastCount = limit - firstCount;
10549
+ return [...items.slice(0, firstCount), ...items.slice(-lastCount)];
10550
+ }
10551
+ function profileScreenshotLabels(viewports) {
10552
+ const labels = [];
10553
+ for (const viewport of viewports || []) {
10554
+ if (viewport && viewport.screenshot_label) labels.push(viewport.screenshot_label);
10555
+ labels.push(...profileSetupScreenshotLabels(viewport && viewport.setup_action_results || []));
10556
+ }
10557
+ return labels;
10558
+ }
10516
10559
  function profileSetupSummary(viewports, actionCount) {
10517
10560
  return {
10518
10561
  viewport_count: (viewports || []).length,
@@ -10520,15 +10563,15 @@ function profileSetupSummary(viewports, actionCount) {
10520
10563
  viewports: (viewports || []).map((viewport) => {
10521
10564
  const results = viewport.setup_action_results || [];
10522
10565
  const failed = results.filter((result) => result && result.ok === false);
10523
- const clicked = results
10566
+ const clickedItems = results
10524
10567
  .filter((result) => result && profileSetupResultAction(result) === "click" && result.ok !== false)
10525
10568
  .map((result) => ({
10526
10569
  ordinal: result.ordinal ?? null,
10527
10570
  selector: result.selector ?? null,
10528
10571
  frame_selector: result.frame_selector ?? null,
10529
10572
  text: compactProfileSetupSummaryText(result.text),
10530
- }))
10531
- .slice(0, 8);
10573
+ }));
10574
+ const clicked = sampleProfileSetupSummaryItems(clickedItems, 8);
10532
10575
  const textSamples = results
10533
10576
  .filter((result) => result && result.ok !== false && typeof result.text === "string" && (
10534
10577
  profileSetupResultAction(result) === "assert_text_visible"
@@ -10552,6 +10595,9 @@ function profileSetupSummary(viewports, actionCount) {
10552
10595
  action_counts: profileSetupActionCounts(results),
10553
10596
  frame_action_count: results.filter((result) => result && result.frame_selector).length,
10554
10597
  frame_urls: profileSetupFrameUrls(viewport),
10598
+ setup_screenshots: profileSetupScreenshotLabels(results),
10599
+ clicked_total: clickedItems.length,
10600
+ clicked_truncated: clickedItems.length > clicked.length,
10555
10601
  clicked,
10556
10602
  text_samples: textSamples,
10557
10603
  failed: failed.map((result) => ({
@@ -11039,7 +11085,7 @@ function assessProfile(profile, evidence) {
11039
11085
  else if (expectedViewportCount && viewports.length < expectedViewportCount) status = "proof_insufficient";
11040
11086
  else if (checks.some((check) => check.status === "needs_human_review")) status = "needs_human_review";
11041
11087
  else if (checks.some((check) => check.status === "failed")) status = "product_regression";
11042
- const screenshotLabels = viewports.map((viewport) => viewport.screenshot_label).filter(Boolean);
11088
+ const screenshotLabels = profileScreenshotLabels(viewports);
11043
11089
  const route = viewports[0] && viewports[0].route ? viewports[0].route : { requested: evidence.target_url, observed: "", matched: false, error: "missing viewport evidence" };
11044
11090
  const passedChecks = checks.filter((check) => check.status === "passed").length;
11045
11091
  const failedChecks = checks.filter((check) => check.status === "failed").length;
@@ -11406,6 +11452,18 @@ async function executeSetupAction(action, ordinal) {
11406
11452
  await page.waitForTimeout(ms);
11407
11453
  return { ...base, ok: true, ms };
11408
11454
  }
11455
+ if (type === "screenshot") {
11456
+ const rawLabel = String(action.label || action.name || action.screenshot_label || action.screenshotLabel || ("setup-" + ordinal));
11457
+ const labelPart = rawLabel
11458
+ .toLowerCase()
11459
+ .replace(/[^a-z0-9_-]+/g, "-")
11460
+ .replace(/^-+|-+$/g, "")
11461
+ .slice(0, 80) || ("setup-" + ordinal);
11462
+ const label = profileSlug + "-" + viewport.name + "-" + labelPart;
11463
+ if (typeof saveScreenshot !== "function") return { ...base, reason: "save_screenshot_unavailable", label: rawLabel };
11464
+ await saveScreenshot(label);
11465
+ return { ...base, ok: true, label: rawLabel, screenshot_label: label };
11466
+ }
11409
11467
  if (type === "wait_for_selector") {
11410
11468
  const scope = await setupActionScope(action, timeout);
11411
11469
  if (!scope.ok) return setupScopeFailure(base, scope);
package/dist/index.js CHANGED
@@ -58,7 +58,7 @@ import {
58
58
  resolveRiddleProofProfileTimeoutSec,
59
59
  slugifyRiddleProofProfileName,
60
60
  summarizeRiddleProofProfileResult
61
- } from "./chunk-MIHU2AWC.js";
61
+ } from "./chunk-ZVKKBM2J.js";
62
62
  import {
63
63
  DEFAULT_RIDDLE_API_BASE_URL,
64
64
  DEFAULT_RIDDLE_API_KEY_FILE,
package/dist/profile.cjs CHANGED
@@ -89,6 +89,7 @@ var RIDDLE_PROOF_PROFILE_SETUP_ACTION_TYPES = [
89
89
  "local_storage",
90
90
  "session_storage",
91
91
  "clear_storage",
92
+ "screenshot",
92
93
  "wait",
93
94
  "wait_for_selector",
94
95
  "wait_for_text",
@@ -249,6 +250,23 @@ function profileSetupActionCounts(results) {
249
250
  }
250
251
  return toJsonValue(counts);
251
252
  }
253
+ function profileSetupScreenshotLabels(results) {
254
+ return results.filter((result) => profileSetupResultAction(result) === "screenshot" && result.ok !== false && typeof result.screenshot_label === "string").map((result) => result.screenshot_label).filter(Boolean);
255
+ }
256
+ function sampleProfileSetupSummaryItems(items, limit) {
257
+ if (items.length <= limit) return items;
258
+ const firstCount = Math.floor(limit / 2);
259
+ const lastCount = limit - firstCount;
260
+ return [...items.slice(0, firstCount), ...items.slice(-lastCount)];
261
+ }
262
+ function profileScreenshotLabels(viewports) {
263
+ const labels = [];
264
+ for (const viewport of viewports || []) {
265
+ if (viewport.screenshot_label) labels.push(viewport.screenshot_label);
266
+ labels.push(...profileSetupScreenshotLabels(viewport.setup_action_results || []));
267
+ }
268
+ return labels;
269
+ }
252
270
  function profileSetupSummary(viewports, actionCount) {
253
271
  return toJsonValue({
254
272
  viewport_count: viewports.length,
@@ -256,12 +274,13 @@ function profileSetupSummary(viewports, actionCount) {
256
274
  viewports: viewports.map((viewport) => {
257
275
  const results = viewport.setup_action_results || [];
258
276
  const failed = results.filter((result) => result.ok === false);
259
- const clicked = results.filter((result) => profileSetupResultAction(result) === "click" && result.ok !== false).map((result) => ({
277
+ const clickedItems = results.filter((result) => profileSetupResultAction(result) === "click" && result.ok !== false).map((result) => ({
260
278
  ordinal: result.ordinal ?? null,
261
279
  selector: result.selector ?? null,
262
280
  frame_selector: result.frame_selector ?? null,
263
281
  text: compactProfileSetupSummaryText(result.text)
264
- })).slice(0, 8);
282
+ }));
283
+ const clicked = sampleProfileSetupSummaryItems(clickedItems, 8);
265
284
  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) => ({
266
285
  ordinal: result.ordinal ?? null,
267
286
  action: profileSetupResultAction(result),
@@ -277,6 +296,9 @@ function profileSetupSummary(viewports, actionCount) {
277
296
  action_counts: profileSetupActionCounts(results),
278
297
  frame_action_count: results.filter((result) => result.frame_selector).length,
279
298
  frame_urls: profileSetupFrameUrls(viewport),
299
+ setup_screenshots: profileSetupScreenshotLabels(results),
300
+ clicked_total: clickedItems.length,
301
+ clicked_truncated: clickedItems.length > clicked.length,
280
302
  clicked,
281
303
  text_samples,
282
304
  failed: failed.map((result) => ({
@@ -320,7 +342,7 @@ function isSupportedCheckType(value) {
320
342
  }
321
343
  function normalizeSetupActionType(value, index) {
322
344
  const normalizedInput = String(value || "").trim().replace(/-/g, "_");
323
- const normalized = normalizedInput === "clear_browser_storage" ? "clear_storage" : normalizedInput === "pointer_drag" || normalizedInput === "mouse_drag" || normalizedInput === "drag_to" ? "drag" : normalizedInput === "keyboard_press" || normalizedInput === "key_press" ? "press" : normalizedInput;
345
+ const normalized = normalizedInput === "clear_browser_storage" ? "clear_storage" : normalizedInput === "pointer_drag" || normalizedInput === "mouse_drag" || normalizedInput === "drag_to" ? "drag" : normalizedInput === "keyboard_press" || normalizedInput === "key_press" ? "press" : normalizedInput === "capture_screenshot" || normalizedInput === "save_screenshot" || normalizedInput === "setup_screenshot" ? "screenshot" : normalizedInput;
324
346
  if (RIDDLE_PROOF_PROFILE_SETUP_ACTION_TYPES.includes(normalized)) {
325
347
  return normalized;
326
348
  }
@@ -451,6 +473,7 @@ function normalizeSetupAction(input, index) {
451
473
  key,
452
474
  value,
453
475
  value_json: hasJsonValue ? toJsonValue(input.value_json ?? input.valueJson ?? input.json) : void 0,
476
+ label: stringFromOwn(input, "label", "name", "screenshot_label", "screenshotLabel"),
454
477
  path,
455
478
  args,
456
479
  expect_return: hasExpectedReturn ? toJsonValue(valueFromOwn(input, "expect_return", "expectReturn", "expected_return", "expectedReturn")) : void 0,
@@ -1493,7 +1516,7 @@ function assessRiddleProofProfileEvidence(profile, evidence, options = {}) {
1493
1516
  ].filter((check) => Boolean(check)) : [];
1494
1517
  const status = profileStatusFromEvidence(profile, evidence, checks);
1495
1518
  const firstViewport = evidence?.viewports?.[0];
1496
- const screenshots = (evidence?.viewports || []).map((viewport) => viewport.screenshot_label).filter((label) => Boolean(label));
1519
+ const screenshots = profileScreenshotLabels(evidence?.viewports);
1497
1520
  return {
1498
1521
  version: RIDDLE_PROOF_PROFILE_RESULT_VERSION,
1499
1522
  profile_name: profile.name,
@@ -1842,6 +1865,26 @@ function profileSetupActionCounts(results) {
1842
1865
  }
1843
1866
  return counts;
1844
1867
  }
1868
+ function profileSetupScreenshotLabels(results) {
1869
+ return (results || [])
1870
+ .filter((result) => result && profileSetupResultAction(result) === "screenshot" && result.ok !== false && typeof result.screenshot_label === "string")
1871
+ .map((result) => result.screenshot_label)
1872
+ .filter(Boolean);
1873
+ }
1874
+ function sampleProfileSetupSummaryItems(items, limit) {
1875
+ if ((items || []).length <= limit) return items || [];
1876
+ const firstCount = Math.floor(limit / 2);
1877
+ const lastCount = limit - firstCount;
1878
+ return [...items.slice(0, firstCount), ...items.slice(-lastCount)];
1879
+ }
1880
+ function profileScreenshotLabels(viewports) {
1881
+ const labels = [];
1882
+ for (const viewport of viewports || []) {
1883
+ if (viewport && viewport.screenshot_label) labels.push(viewport.screenshot_label);
1884
+ labels.push(...profileSetupScreenshotLabels(viewport && viewport.setup_action_results || []));
1885
+ }
1886
+ return labels;
1887
+ }
1845
1888
  function profileSetupSummary(viewports, actionCount) {
1846
1889
  return {
1847
1890
  viewport_count: (viewports || []).length,
@@ -1849,15 +1892,15 @@ function profileSetupSummary(viewports, actionCount) {
1849
1892
  viewports: (viewports || []).map((viewport) => {
1850
1893
  const results = viewport.setup_action_results || [];
1851
1894
  const failed = results.filter((result) => result && result.ok === false);
1852
- const clicked = results
1895
+ const clickedItems = results
1853
1896
  .filter((result) => result && profileSetupResultAction(result) === "click" && result.ok !== false)
1854
1897
  .map((result) => ({
1855
1898
  ordinal: result.ordinal ?? null,
1856
1899
  selector: result.selector ?? null,
1857
1900
  frame_selector: result.frame_selector ?? null,
1858
1901
  text: compactProfileSetupSummaryText(result.text),
1859
- }))
1860
- .slice(0, 8);
1902
+ }));
1903
+ const clicked = sampleProfileSetupSummaryItems(clickedItems, 8);
1861
1904
  const textSamples = results
1862
1905
  .filter((result) => result && result.ok !== false && typeof result.text === "string" && (
1863
1906
  profileSetupResultAction(result) === "assert_text_visible"
@@ -1881,6 +1924,9 @@ function profileSetupSummary(viewports, actionCount) {
1881
1924
  action_counts: profileSetupActionCounts(results),
1882
1925
  frame_action_count: results.filter((result) => result && result.frame_selector).length,
1883
1926
  frame_urls: profileSetupFrameUrls(viewport),
1927
+ setup_screenshots: profileSetupScreenshotLabels(results),
1928
+ clicked_total: clickedItems.length,
1929
+ clicked_truncated: clickedItems.length > clicked.length,
1884
1930
  clicked,
1885
1931
  text_samples: textSamples,
1886
1932
  failed: failed.map((result) => ({
@@ -2368,7 +2414,7 @@ function assessProfile(profile, evidence) {
2368
2414
  else if (expectedViewportCount && viewports.length < expectedViewportCount) status = "proof_insufficient";
2369
2415
  else if (checks.some((check) => check.status === "needs_human_review")) status = "needs_human_review";
2370
2416
  else if (checks.some((check) => check.status === "failed")) status = "product_regression";
2371
- const screenshotLabels = viewports.map((viewport) => viewport.screenshot_label).filter(Boolean);
2417
+ const screenshotLabels = profileScreenshotLabels(viewports);
2372
2418
  const route = viewports[0] && viewports[0].route ? viewports[0].route : { requested: evidence.target_url, observed: "", matched: false, error: "missing viewport evidence" };
2373
2419
  const passedChecks = checks.filter((check) => check.status === "passed").length;
2374
2420
  const failedChecks = checks.filter((check) => check.status === "failed").length;
@@ -2735,6 +2781,18 @@ async function executeSetupAction(action, ordinal) {
2735
2781
  await page.waitForTimeout(ms);
2736
2782
  return { ...base, ok: true, ms };
2737
2783
  }
2784
+ if (type === "screenshot") {
2785
+ const rawLabel = String(action.label || action.name || action.screenshot_label || action.screenshotLabel || ("setup-" + ordinal));
2786
+ const labelPart = rawLabel
2787
+ .toLowerCase()
2788
+ .replace(/[^a-z0-9_-]+/g, "-")
2789
+ .replace(/^-+|-+$/g, "")
2790
+ .slice(0, 80) || ("setup-" + ordinal);
2791
+ const label = profileSlug + "-" + viewport.name + "-" + labelPart;
2792
+ if (typeof saveScreenshot !== "function") return { ...base, reason: "save_screenshot_unavailable", label: rawLabel };
2793
+ await saveScreenshot(label);
2794
+ return { ...base, ok: true, label: rawLabel, screenshot_label: label };
2795
+ }
2738
2796
  if (type === "wait_for_selector") {
2739
2797
  const scope = await setupActionScope(action, timeout);
2740
2798
  if (!scope.ok) return setupScopeFailure(base, scope);
@@ -5,7 +5,7 @@ declare const RIDDLE_PROOF_PROFILE_EVIDENCE_VERSION: "riddle-proof.profile-evide
5
5
  declare const RIDDLE_PROOF_PROFILE_RESULT_VERSION: "riddle-proof.profile-result.v1";
6
6
  declare const RIDDLE_PROOF_PROFILE_STATUSES: readonly ["passed", "product_regression", "proof_insufficient", "environment_blocked", "configuration_error", "needs_human_review"];
7
7
  declare const RIDDLE_PROOF_PROFILE_CHECK_TYPES: readonly ["route_loaded", "url_search_param_equals", "url_search_param_absent", "selector_visible", "selector_absent", "selector_count_at_least", "selector_count_equals", "selector_count_equal", "selector_count_eq", "selector_text_order", "frame_text_visible", "frame_url_equals", "frame_url_matches", "frame_no_horizontal_overflow", "text_visible", "text_absent", "route_inventory", "no_horizontal_overflow", "no_mobile_horizontal_overflow", "no_fatal_console_errors"];
8
- declare const RIDDLE_PROOF_PROFILE_SETUP_ACTION_TYPES: readonly ["click", "drag", "press", "fill", "set_input_value", "assert_text_visible", "assert_text_absent", "assert_selector_count", "assert_window_value", "assert_window_number", "local_storage", "session_storage", "clear_storage", "wait", "wait_for_selector", "wait_for_text", "window_call"];
8
+ declare const RIDDLE_PROOF_PROFILE_SETUP_ACTION_TYPES: readonly ["click", "drag", "press", "fill", "set_input_value", "assert_text_visible", "assert_text_absent", "assert_selector_count", "assert_window_value", "assert_window_number", "local_storage", "session_storage", "clear_storage", "screenshot", "wait", "wait_for_selector", "wait_for_text", "window_call"];
9
9
  type RiddleProofProfileStatus = typeof RIDDLE_PROOF_PROFILE_STATUSES[number];
10
10
  type RiddleProofProfileCheckType = typeof RIDDLE_PROOF_PROFILE_CHECK_TYPES[number];
11
11
  type RiddleProofProfileSetupActionType = typeof RIDDLE_PROOF_PROFILE_SETUP_ACTION_TYPES[number];
@@ -33,6 +33,7 @@ interface RiddleProofProfileSetupAction {
33
33
  key?: string;
34
34
  value?: string;
35
35
  value_json?: JsonValue;
36
+ label?: string;
36
37
  path?: string;
37
38
  args?: JsonValue[];
38
39
  expect_return?: JsonValue;
package/dist/profile.d.ts CHANGED
@@ -5,7 +5,7 @@ declare const RIDDLE_PROOF_PROFILE_EVIDENCE_VERSION: "riddle-proof.profile-evide
5
5
  declare const RIDDLE_PROOF_PROFILE_RESULT_VERSION: "riddle-proof.profile-result.v1";
6
6
  declare const RIDDLE_PROOF_PROFILE_STATUSES: readonly ["passed", "product_regression", "proof_insufficient", "environment_blocked", "configuration_error", "needs_human_review"];
7
7
  declare const RIDDLE_PROOF_PROFILE_CHECK_TYPES: readonly ["route_loaded", "url_search_param_equals", "url_search_param_absent", "selector_visible", "selector_absent", "selector_count_at_least", "selector_count_equals", "selector_count_equal", "selector_count_eq", "selector_text_order", "frame_text_visible", "frame_url_equals", "frame_url_matches", "frame_no_horizontal_overflow", "text_visible", "text_absent", "route_inventory", "no_horizontal_overflow", "no_mobile_horizontal_overflow", "no_fatal_console_errors"];
8
- declare const RIDDLE_PROOF_PROFILE_SETUP_ACTION_TYPES: readonly ["click", "drag", "press", "fill", "set_input_value", "assert_text_visible", "assert_text_absent", "assert_selector_count", "assert_window_value", "assert_window_number", "local_storage", "session_storage", "clear_storage", "wait", "wait_for_selector", "wait_for_text", "window_call"];
8
+ declare const RIDDLE_PROOF_PROFILE_SETUP_ACTION_TYPES: readonly ["click", "drag", "press", "fill", "set_input_value", "assert_text_visible", "assert_text_absent", "assert_selector_count", "assert_window_value", "assert_window_number", "local_storage", "session_storage", "clear_storage", "screenshot", "wait", "wait_for_selector", "wait_for_text", "window_call"];
9
9
  type RiddleProofProfileStatus = typeof RIDDLE_PROOF_PROFILE_STATUSES[number];
10
10
  type RiddleProofProfileCheckType = typeof RIDDLE_PROOF_PROFILE_CHECK_TYPES[number];
11
11
  type RiddleProofProfileSetupActionType = typeof RIDDLE_PROOF_PROFILE_SETUP_ACTION_TYPES[number];
@@ -33,6 +33,7 @@ interface RiddleProofProfileSetupAction {
33
33
  key?: string;
34
34
  value?: string;
35
35
  value_json?: JsonValue;
36
+ label?: string;
36
37
  path?: string;
37
38
  args?: JsonValue[];
38
39
  expect_return?: JsonValue;
package/dist/profile.js CHANGED
@@ -19,7 +19,7 @@ import {
19
19
  resolveRiddleProofProfileTimeoutSec,
20
20
  slugifyRiddleProofProfileName,
21
21
  summarizeRiddleProofProfileResult
22
- } from "./chunk-MIHU2AWC.js";
22
+ } from "./chunk-ZVKKBM2J.js";
23
23
  export {
24
24
  RIDDLE_PROOF_PROFILE_CHECK_TYPES,
25
25
  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.62",
3
+ "version": "0.7.64",
4
4
  "description": "Reusable Riddle Proof contracts and helpers for evidence-backed agent changes.",
5
5
  "license": "MIT",
6
6
  "author": "RiddleDC",