@riddledc/riddle-proof 0.7.61 → 0.7.63

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
@@ -284,6 +284,15 @@ and setup assertions then execute in that frame context and record
284
284
  Use `frame_index` / `frameIndex` when more than one matching iframe is present;
285
285
  it defaults to the first frame.
286
286
 
287
+ Profiles with setup actions also include a compact
288
+ `setup_actions_succeeded.evidence.setup_summary`. The summary groups each
289
+ 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. Long click
292
+ sequences include `clicked_total` and `clicked_truncated`; the compact `clicked`
293
+ list keeps the first and last clicked targets so later route switches and reset
294
+ actions stay visible.
295
+
287
296
  `target.timeout_sec` is optional. Use it for known-heavy profile targets so the
288
297
  profile carries its own hosted Riddle worker budget; an explicit CLI `--timeout`
289
298
  still overrides the profile value for one-off runs.
@@ -175,6 +175,87 @@ function toJsonValue(value) {
175
175
  if (isRecord(value)) return Object.fromEntries(Object.entries(value).map(([key, child]) => [key, toJsonValue(child)]));
176
176
  return String(value);
177
177
  }
178
+ function compactProfileSetupSummaryText(value, limit = 160) {
179
+ const text = typeof value === "string" ? value.replace(/\s+/g, " ").trim() : "";
180
+ if (!text) return void 0;
181
+ if (text.length <= limit) return text;
182
+ return `${text.slice(0, Math.max(0, limit - 15)).trimEnd()}... (${text.length} chars)`;
183
+ }
184
+ function profileSetupResultAction(value) {
185
+ const action = value.action ?? value.type;
186
+ return typeof action === "string" && action ? action : "unknown";
187
+ }
188
+ function profileSetupFrameUrls(viewport) {
189
+ const urls = [];
190
+ const frames = viewport.frames || {};
191
+ for (const container of Object.values(frames)) {
192
+ if (!isRecord(container) || !Array.isArray(container.frames)) continue;
193
+ for (const frame of container.frames) {
194
+ if (!isRecord(frame)) continue;
195
+ const url = typeof frame.url === "string" ? frame.url : void 0;
196
+ if (url && !urls.includes(url)) urls.push(url);
197
+ }
198
+ }
199
+ return urls.slice(0, 10);
200
+ }
201
+ function profileSetupActionCounts(results) {
202
+ const counts = {};
203
+ for (const result of results) {
204
+ const action = profileSetupResultAction(result);
205
+ counts[action] = (counts[action] || 0) + 1;
206
+ }
207
+ return toJsonValue(counts);
208
+ }
209
+ function sampleProfileSetupSummaryItems(items, limit) {
210
+ if (items.length <= limit) return items;
211
+ const firstCount = Math.floor(limit / 2);
212
+ const lastCount = limit - firstCount;
213
+ return [...items.slice(0, firstCount), ...items.slice(-lastCount)];
214
+ }
215
+ function profileSetupSummary(viewports, actionCount) {
216
+ return toJsonValue({
217
+ viewport_count: viewports.length,
218
+ action_count: actionCount ?? null,
219
+ viewports: viewports.map((viewport) => {
220
+ const results = viewport.setup_action_results || [];
221
+ const failed = results.filter((result) => result.ok === false);
222
+ const clickedItems = results.filter((result) => profileSetupResultAction(result) === "click" && result.ok !== false).map((result) => ({
223
+ ordinal: result.ordinal ?? null,
224
+ selector: result.selector ?? null,
225
+ frame_selector: result.frame_selector ?? null,
226
+ text: compactProfileSetupSummaryText(result.text)
227
+ }));
228
+ const clicked = sampleProfileSetupSummaryItems(clickedItems, 8);
229
+ 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) => ({
230
+ ordinal: result.ordinal ?? null,
231
+ action: profileSetupResultAction(result),
232
+ frame_selector: result.frame_selector ?? null,
233
+ text: compactProfileSetupSummaryText(result.text)
234
+ })).filter((item) => item.text).slice(-6);
235
+ return {
236
+ name: viewport.name,
237
+ ok: (actionCount === void 0 ? results.length > 0 : results.length >= actionCount) && failed.length === 0,
238
+ result_count: results.length,
239
+ observed_path: viewport.route?.observed ?? null,
240
+ final_url: viewport.url ?? null,
241
+ action_counts: profileSetupActionCounts(results),
242
+ frame_action_count: results.filter((result) => result.frame_selector).length,
243
+ frame_urls: profileSetupFrameUrls(viewport),
244
+ clicked_total: clickedItems.length,
245
+ clicked_truncated: clickedItems.length > clicked.length,
246
+ clicked,
247
+ text_samples,
248
+ failed: failed.map((result) => ({
249
+ ordinal: result.ordinal ?? null,
250
+ action: profileSetupResultAction(result),
251
+ selector: result.selector ?? null,
252
+ frame_selector: result.frame_selector ?? null,
253
+ reason: result.reason ?? result.error ?? null
254
+ }))
255
+ };
256
+ })
257
+ });
258
+ }
178
259
  function normalizeName(value, fallback) {
179
260
  const name = stringValue(value) || fallback;
180
261
  return name.replace(/\s+/g, " ").trim();
@@ -1281,6 +1362,7 @@ function assessSetupActionsFromEvidence(profile, evidence) {
1281
1362
  ok: (viewport.setup_action_results || []).length >= actionCount && (viewport.setup_action_results || []).every((result) => result.ok !== false),
1282
1363
  result_count: (viewport.setup_action_results || []).length
1283
1364
  })),
1365
+ setup_summary: profileSetupSummary(viewports, actionCount),
1284
1366
  failed
1285
1367
  },
1286
1368
  message: failed.length ? `Setup actions failed in ${failed.length} viewport action(s).` : void 0
@@ -1694,6 +1776,98 @@ function requiredNetworkMockHitCount(mock) {
1694
1776
  if (Array.isArray(mock.responses) && mock.responses.length) return mock.responses.length;
1695
1777
  return 1;
1696
1778
  }
1779
+ function compactProfileSetupSummaryText(value, limit) {
1780
+ limit = limit || 160;
1781
+ const text = typeof value === "string" ? value.replace(/\\s+/g, " ").trim() : "";
1782
+ if (!text) return undefined;
1783
+ if (text.length <= limit) return text;
1784
+ return text.slice(0, Math.max(0, limit - 15)).trimEnd() + "... (" + text.length + " chars)";
1785
+ }
1786
+ function profileSetupResultAction(result) {
1787
+ const action = result && (result.action || result.type);
1788
+ return typeof action === "string" && action ? action : "unknown";
1789
+ }
1790
+ function profileSetupFrameUrls(viewport) {
1791
+ const urls = [];
1792
+ const frames = viewport && viewport.frames || {};
1793
+ for (const container of Object.values(frames)) {
1794
+ if (!container || typeof container !== "object" || Array.isArray(container) || !Array.isArray(container.frames)) continue;
1795
+ for (const frame of container.frames) {
1796
+ if (!frame || typeof frame !== "object" || Array.isArray(frame)) continue;
1797
+ const url = typeof frame.url === "string" ? frame.url : null;
1798
+ if (url && !urls.includes(url)) urls.push(url);
1799
+ }
1800
+ }
1801
+ return urls.slice(0, 10);
1802
+ }
1803
+ function profileSetupActionCounts(results) {
1804
+ const counts = {};
1805
+ for (const result of results || []) {
1806
+ const action = profileSetupResultAction(result);
1807
+ counts[action] = (counts[action] || 0) + 1;
1808
+ }
1809
+ return counts;
1810
+ }
1811
+ function sampleProfileSetupSummaryItems(items, limit) {
1812
+ if ((items || []).length <= limit) return items || [];
1813
+ const firstCount = Math.floor(limit / 2);
1814
+ const lastCount = limit - firstCount;
1815
+ return [...items.slice(0, firstCount), ...items.slice(-lastCount)];
1816
+ }
1817
+ function profileSetupSummary(viewports, actionCount) {
1818
+ return {
1819
+ viewport_count: (viewports || []).length,
1820
+ action_count: actionCount ?? null,
1821
+ viewports: (viewports || []).map((viewport) => {
1822
+ const results = viewport.setup_action_results || [];
1823
+ const failed = results.filter((result) => result && result.ok === false);
1824
+ const clickedItems = results
1825
+ .filter((result) => result && profileSetupResultAction(result) === "click" && result.ok !== false)
1826
+ .map((result) => ({
1827
+ ordinal: result.ordinal ?? null,
1828
+ selector: result.selector ?? null,
1829
+ frame_selector: result.frame_selector ?? null,
1830
+ text: compactProfileSetupSummaryText(result.text),
1831
+ }));
1832
+ const clicked = sampleProfileSetupSummaryItems(clickedItems, 8);
1833
+ const textSamples = results
1834
+ .filter((result) => result && result.ok !== false && typeof result.text === "string" && (
1835
+ profileSetupResultAction(result) === "assert_text_visible"
1836
+ || profileSetupResultAction(result) === "assert_text_absent"
1837
+ || profileSetupResultAction(result) === "wait_for_text"
1838
+ ))
1839
+ .map((result) => ({
1840
+ ordinal: result.ordinal ?? null,
1841
+ action: profileSetupResultAction(result),
1842
+ frame_selector: result.frame_selector ?? null,
1843
+ text: compactProfileSetupSummaryText(result.text),
1844
+ }))
1845
+ .filter((item) => item.text)
1846
+ .slice(-6);
1847
+ return {
1848
+ name: viewport.name,
1849
+ ok: (actionCount === undefined ? results.length > 0 : results.length >= actionCount) && failed.length === 0,
1850
+ result_count: results.length,
1851
+ observed_path: viewport.route && viewport.route.observed || null,
1852
+ final_url: viewport.url || null,
1853
+ action_counts: profileSetupActionCounts(results),
1854
+ frame_action_count: results.filter((result) => result && result.frame_selector).length,
1855
+ frame_urls: profileSetupFrameUrls(viewport),
1856
+ clicked_total: clickedItems.length,
1857
+ clicked_truncated: clickedItems.length > clicked.length,
1858
+ clicked,
1859
+ text_samples: textSamples,
1860
+ failed: failed.map((result) => ({
1861
+ ordinal: result.ordinal ?? null,
1862
+ action: profileSetupResultAction(result),
1863
+ selector: result.selector ?? null,
1864
+ frame_selector: result.frame_selector ?? null,
1865
+ reason: result.reason || result.error || null,
1866
+ })),
1867
+ };
1868
+ }),
1869
+ };
1870
+ }
1697
1871
  function assessProfile(profile, evidence) {
1698
1872
  const checks = [];
1699
1873
  const viewports = evidence.viewports || [];
@@ -1798,6 +1972,7 @@ function assessProfile(profile, evidence) {
1798
1972
  && (viewport.setup_action_results || []).every((result) => !result || result.ok !== false),
1799
1973
  result_count: (viewport.setup_action_results || []).length,
1800
1974
  })),
1975
+ setup_summary: profileSetupSummary(viewports, actionCount),
1801
1976
  failed,
1802
1977
  },
1803
1978
  message: failed.length ? "Setup actions failed in " + failed.length + " viewport action(s)." : undefined,
package/dist/cli.cjs CHANGED
@@ -7048,6 +7048,87 @@ function toJsonValue(value) {
7048
7048
  if (isRecord(value)) return Object.fromEntries(Object.entries(value).map(([key, child]) => [key, toJsonValue(child)]));
7049
7049
  return String(value);
7050
7050
  }
7051
+ function compactProfileSetupSummaryText(value, limit = 160) {
7052
+ const text = typeof value === "string" ? value.replace(/\s+/g, " ").trim() : "";
7053
+ if (!text) return void 0;
7054
+ if (text.length <= limit) return text;
7055
+ return `${text.slice(0, Math.max(0, limit - 15)).trimEnd()}... (${text.length} chars)`;
7056
+ }
7057
+ function profileSetupResultAction(value) {
7058
+ const action = value.action ?? value.type;
7059
+ return typeof action === "string" && action ? action : "unknown";
7060
+ }
7061
+ function profileSetupFrameUrls(viewport) {
7062
+ const urls = [];
7063
+ const frames = viewport.frames || {};
7064
+ for (const container of Object.values(frames)) {
7065
+ if (!isRecord(container) || !Array.isArray(container.frames)) continue;
7066
+ for (const frame of container.frames) {
7067
+ if (!isRecord(frame)) continue;
7068
+ const url = typeof frame.url === "string" ? frame.url : void 0;
7069
+ if (url && !urls.includes(url)) urls.push(url);
7070
+ }
7071
+ }
7072
+ return urls.slice(0, 10);
7073
+ }
7074
+ function profileSetupActionCounts(results) {
7075
+ const counts = {};
7076
+ for (const result of results) {
7077
+ const action = profileSetupResultAction(result);
7078
+ counts[action] = (counts[action] || 0) + 1;
7079
+ }
7080
+ return toJsonValue(counts);
7081
+ }
7082
+ function sampleProfileSetupSummaryItems(items, limit) {
7083
+ if (items.length <= limit) return items;
7084
+ const firstCount = Math.floor(limit / 2);
7085
+ const lastCount = limit - firstCount;
7086
+ return [...items.slice(0, firstCount), ...items.slice(-lastCount)];
7087
+ }
7088
+ function profileSetupSummary(viewports, actionCount) {
7089
+ return toJsonValue({
7090
+ viewport_count: viewports.length,
7091
+ action_count: actionCount ?? null,
7092
+ viewports: viewports.map((viewport) => {
7093
+ const results = viewport.setup_action_results || [];
7094
+ const failed = results.filter((result) => result.ok === false);
7095
+ const clickedItems = results.filter((result) => profileSetupResultAction(result) === "click" && result.ok !== false).map((result) => ({
7096
+ ordinal: result.ordinal ?? null,
7097
+ selector: result.selector ?? null,
7098
+ frame_selector: result.frame_selector ?? null,
7099
+ text: compactProfileSetupSummaryText(result.text)
7100
+ }));
7101
+ const clicked = sampleProfileSetupSummaryItems(clickedItems, 8);
7102
+ 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) => ({
7103
+ ordinal: result.ordinal ?? null,
7104
+ action: profileSetupResultAction(result),
7105
+ frame_selector: result.frame_selector ?? null,
7106
+ text: compactProfileSetupSummaryText(result.text)
7107
+ })).filter((item) => item.text).slice(-6);
7108
+ return {
7109
+ name: viewport.name,
7110
+ ok: (actionCount === void 0 ? results.length > 0 : results.length >= actionCount) && failed.length === 0,
7111
+ result_count: results.length,
7112
+ observed_path: viewport.route?.observed ?? null,
7113
+ final_url: viewport.url ?? null,
7114
+ action_counts: profileSetupActionCounts(results),
7115
+ frame_action_count: results.filter((result) => result.frame_selector).length,
7116
+ frame_urls: profileSetupFrameUrls(viewport),
7117
+ clicked_total: clickedItems.length,
7118
+ clicked_truncated: clickedItems.length > clicked.length,
7119
+ clicked,
7120
+ text_samples,
7121
+ failed: failed.map((result) => ({
7122
+ ordinal: result.ordinal ?? null,
7123
+ action: profileSetupResultAction(result),
7124
+ selector: result.selector ?? null,
7125
+ frame_selector: result.frame_selector ?? null,
7126
+ reason: result.reason ?? result.error ?? null
7127
+ }))
7128
+ };
7129
+ })
7130
+ });
7131
+ }
7051
7132
  function normalizeName(value, fallback) {
7052
7133
  const name = stringValue2(value) || fallback;
7053
7134
  return name.replace(/\s+/g, " ").trim();
@@ -8154,6 +8235,7 @@ function assessSetupActionsFromEvidence(profile, evidence) {
8154
8235
  ok: (viewport.setup_action_results || []).length >= actionCount && (viewport.setup_action_results || []).every((result) => result.ok !== false),
8155
8236
  result_count: (viewport.setup_action_results || []).length
8156
8237
  })),
8238
+ setup_summary: profileSetupSummary(viewports, actionCount),
8157
8239
  failed
8158
8240
  },
8159
8241
  message: failed.length ? `Setup actions failed in ${failed.length} viewport action(s).` : void 0
@@ -8551,6 +8633,98 @@ function requiredNetworkMockHitCount(mock) {
8551
8633
  if (Array.isArray(mock.responses) && mock.responses.length) return mock.responses.length;
8552
8634
  return 1;
8553
8635
  }
8636
+ function compactProfileSetupSummaryText(value, limit) {
8637
+ limit = limit || 160;
8638
+ const text = typeof value === "string" ? value.replace(/\\s+/g, " ").trim() : "";
8639
+ if (!text) return undefined;
8640
+ if (text.length <= limit) return text;
8641
+ return text.slice(0, Math.max(0, limit - 15)).trimEnd() + "... (" + text.length + " chars)";
8642
+ }
8643
+ function profileSetupResultAction(result) {
8644
+ const action = result && (result.action || result.type);
8645
+ return typeof action === "string" && action ? action : "unknown";
8646
+ }
8647
+ function profileSetupFrameUrls(viewport) {
8648
+ const urls = [];
8649
+ const frames = viewport && viewport.frames || {};
8650
+ for (const container of Object.values(frames)) {
8651
+ if (!container || typeof container !== "object" || Array.isArray(container) || !Array.isArray(container.frames)) continue;
8652
+ for (const frame of container.frames) {
8653
+ if (!frame || typeof frame !== "object" || Array.isArray(frame)) continue;
8654
+ const url = typeof frame.url === "string" ? frame.url : null;
8655
+ if (url && !urls.includes(url)) urls.push(url);
8656
+ }
8657
+ }
8658
+ return urls.slice(0, 10);
8659
+ }
8660
+ function profileSetupActionCounts(results) {
8661
+ const counts = {};
8662
+ for (const result of results || []) {
8663
+ const action = profileSetupResultAction(result);
8664
+ counts[action] = (counts[action] || 0) + 1;
8665
+ }
8666
+ return counts;
8667
+ }
8668
+ function sampleProfileSetupSummaryItems(items, limit) {
8669
+ if ((items || []).length <= limit) return items || [];
8670
+ const firstCount = Math.floor(limit / 2);
8671
+ const lastCount = limit - firstCount;
8672
+ return [...items.slice(0, firstCount), ...items.slice(-lastCount)];
8673
+ }
8674
+ function profileSetupSummary(viewports, actionCount) {
8675
+ return {
8676
+ viewport_count: (viewports || []).length,
8677
+ action_count: actionCount ?? null,
8678
+ viewports: (viewports || []).map((viewport) => {
8679
+ const results = viewport.setup_action_results || [];
8680
+ const failed = results.filter((result) => result && result.ok === false);
8681
+ const clickedItems = results
8682
+ .filter((result) => result && profileSetupResultAction(result) === "click" && result.ok !== false)
8683
+ .map((result) => ({
8684
+ ordinal: result.ordinal ?? null,
8685
+ selector: result.selector ?? null,
8686
+ frame_selector: result.frame_selector ?? null,
8687
+ text: compactProfileSetupSummaryText(result.text),
8688
+ }));
8689
+ const clicked = sampleProfileSetupSummaryItems(clickedItems, 8);
8690
+ const textSamples = results
8691
+ .filter((result) => result && result.ok !== false && typeof result.text === "string" && (
8692
+ profileSetupResultAction(result) === "assert_text_visible"
8693
+ || profileSetupResultAction(result) === "assert_text_absent"
8694
+ || profileSetupResultAction(result) === "wait_for_text"
8695
+ ))
8696
+ .map((result) => ({
8697
+ ordinal: result.ordinal ?? null,
8698
+ action: profileSetupResultAction(result),
8699
+ frame_selector: result.frame_selector ?? null,
8700
+ text: compactProfileSetupSummaryText(result.text),
8701
+ }))
8702
+ .filter((item) => item.text)
8703
+ .slice(-6);
8704
+ return {
8705
+ name: viewport.name,
8706
+ ok: (actionCount === undefined ? results.length > 0 : results.length >= actionCount) && failed.length === 0,
8707
+ result_count: results.length,
8708
+ observed_path: viewport.route && viewport.route.observed || null,
8709
+ final_url: viewport.url || null,
8710
+ action_counts: profileSetupActionCounts(results),
8711
+ frame_action_count: results.filter((result) => result && result.frame_selector).length,
8712
+ frame_urls: profileSetupFrameUrls(viewport),
8713
+ clicked_total: clickedItems.length,
8714
+ clicked_truncated: clickedItems.length > clicked.length,
8715
+ clicked,
8716
+ text_samples: textSamples,
8717
+ failed: failed.map((result) => ({
8718
+ ordinal: result.ordinal ?? null,
8719
+ action: profileSetupResultAction(result),
8720
+ selector: result.selector ?? null,
8721
+ frame_selector: result.frame_selector ?? null,
8722
+ reason: result.reason || result.error || null,
8723
+ })),
8724
+ };
8725
+ }),
8726
+ };
8727
+ }
8554
8728
  function assessProfile(profile, evidence) {
8555
8729
  const checks = [];
8556
8730
  const viewports = evidence.viewports || [];
@@ -8655,6 +8829,7 @@ function assessProfile(profile, evidence) {
8655
8829
  && (viewport.setup_action_results || []).every((result) => !result || result.ok !== false),
8656
8830
  result_count: (viewport.setup_action_results || []).length,
8657
8831
  })),
8832
+ setup_summary: profileSetupSummary(viewports, actionCount),
8658
8833
  failed,
8659
8834
  },
8660
8835
  message: failed.length ? "Setup actions failed in " + failed.length + " viewport action(s)." : undefined,
package/dist/cli.js CHANGED
@@ -10,7 +10,7 @@ import {
10
10
  profileStatusExitCode,
11
11
  resolveRiddleProofProfileTargetUrl,
12
12
  resolveRiddleProofProfileTimeoutSec
13
- } from "./chunk-T66DWLBE.js";
13
+ } from "./chunk-MLJHMZLR.js";
14
14
  import {
15
15
  createRiddleApiClient,
16
16
  parseRiddleViewport
package/dist/index.cjs CHANGED
@@ -8889,6 +8889,87 @@ function toJsonValue(value) {
8889
8889
  if (isRecord2(value)) return Object.fromEntries(Object.entries(value).map(([key, child]) => [key, toJsonValue(child)]));
8890
8890
  return String(value);
8891
8891
  }
8892
+ function compactProfileSetupSummaryText(value, limit = 160) {
8893
+ const text = typeof value === "string" ? value.replace(/\s+/g, " ").trim() : "";
8894
+ if (!text) return void 0;
8895
+ if (text.length <= limit) return text;
8896
+ return `${text.slice(0, Math.max(0, limit - 15)).trimEnd()}... (${text.length} chars)`;
8897
+ }
8898
+ function profileSetupResultAction(value) {
8899
+ const action = value.action ?? value.type;
8900
+ return typeof action === "string" && action ? action : "unknown";
8901
+ }
8902
+ function profileSetupFrameUrls(viewport) {
8903
+ const urls = [];
8904
+ const frames = viewport.frames || {};
8905
+ for (const container of Object.values(frames)) {
8906
+ if (!isRecord2(container) || !Array.isArray(container.frames)) continue;
8907
+ for (const frame of container.frames) {
8908
+ if (!isRecord2(frame)) continue;
8909
+ const url = typeof frame.url === "string" ? frame.url : void 0;
8910
+ if (url && !urls.includes(url)) urls.push(url);
8911
+ }
8912
+ }
8913
+ return urls.slice(0, 10);
8914
+ }
8915
+ function profileSetupActionCounts(results) {
8916
+ const counts = {};
8917
+ for (const result of results) {
8918
+ const action = profileSetupResultAction(result);
8919
+ counts[action] = (counts[action] || 0) + 1;
8920
+ }
8921
+ return toJsonValue(counts);
8922
+ }
8923
+ function sampleProfileSetupSummaryItems(items, limit) {
8924
+ if (items.length <= limit) return items;
8925
+ const firstCount = Math.floor(limit / 2);
8926
+ const lastCount = limit - firstCount;
8927
+ return [...items.slice(0, firstCount), ...items.slice(-lastCount)];
8928
+ }
8929
+ function profileSetupSummary(viewports, actionCount) {
8930
+ return toJsonValue({
8931
+ viewport_count: viewports.length,
8932
+ action_count: actionCount ?? null,
8933
+ viewports: viewports.map((viewport) => {
8934
+ const results = viewport.setup_action_results || [];
8935
+ const failed = results.filter((result) => result.ok === false);
8936
+ const clickedItems = results.filter((result) => profileSetupResultAction(result) === "click" && result.ok !== false).map((result) => ({
8937
+ ordinal: result.ordinal ?? null,
8938
+ selector: result.selector ?? null,
8939
+ frame_selector: result.frame_selector ?? null,
8940
+ text: compactProfileSetupSummaryText(result.text)
8941
+ }));
8942
+ const clicked = sampleProfileSetupSummaryItems(clickedItems, 8);
8943
+ 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) => ({
8944
+ ordinal: result.ordinal ?? null,
8945
+ action: profileSetupResultAction(result),
8946
+ frame_selector: result.frame_selector ?? null,
8947
+ text: compactProfileSetupSummaryText(result.text)
8948
+ })).filter((item) => item.text).slice(-6);
8949
+ return {
8950
+ name: viewport.name,
8951
+ ok: (actionCount === void 0 ? results.length > 0 : results.length >= actionCount) && failed.length === 0,
8952
+ result_count: results.length,
8953
+ observed_path: viewport.route?.observed ?? null,
8954
+ final_url: viewport.url ?? null,
8955
+ action_counts: profileSetupActionCounts(results),
8956
+ frame_action_count: results.filter((result) => result.frame_selector).length,
8957
+ frame_urls: profileSetupFrameUrls(viewport),
8958
+ clicked_total: clickedItems.length,
8959
+ clicked_truncated: clickedItems.length > clicked.length,
8960
+ clicked,
8961
+ text_samples,
8962
+ failed: failed.map((result) => ({
8963
+ ordinal: result.ordinal ?? null,
8964
+ action: profileSetupResultAction(result),
8965
+ selector: result.selector ?? null,
8966
+ frame_selector: result.frame_selector ?? null,
8967
+ reason: result.reason ?? result.error ?? null
8968
+ }))
8969
+ };
8970
+ })
8971
+ });
8972
+ }
8892
8973
  function normalizeName(value, fallback) {
8893
8974
  const name = stringValue5(value) || fallback;
8894
8975
  return name.replace(/\s+/g, " ").trim();
@@ -9995,6 +10076,7 @@ function assessSetupActionsFromEvidence(profile, evidence) {
9995
10076
  ok: (viewport.setup_action_results || []).length >= actionCount && (viewport.setup_action_results || []).every((result) => result.ok !== false),
9996
10077
  result_count: (viewport.setup_action_results || []).length
9997
10078
  })),
10079
+ setup_summary: profileSetupSummary(viewports, actionCount),
9998
10080
  failed
9999
10081
  },
10000
10082
  message: failed.length ? `Setup actions failed in ${failed.length} viewport action(s).` : void 0
@@ -10408,6 +10490,98 @@ function requiredNetworkMockHitCount(mock) {
10408
10490
  if (Array.isArray(mock.responses) && mock.responses.length) return mock.responses.length;
10409
10491
  return 1;
10410
10492
  }
10493
+ function compactProfileSetupSummaryText(value, limit) {
10494
+ limit = limit || 160;
10495
+ const text = typeof value === "string" ? value.replace(/\\s+/g, " ").trim() : "";
10496
+ if (!text) return undefined;
10497
+ if (text.length <= limit) return text;
10498
+ return text.slice(0, Math.max(0, limit - 15)).trimEnd() + "... (" + text.length + " chars)";
10499
+ }
10500
+ function profileSetupResultAction(result) {
10501
+ const action = result && (result.action || result.type);
10502
+ return typeof action === "string" && action ? action : "unknown";
10503
+ }
10504
+ function profileSetupFrameUrls(viewport) {
10505
+ const urls = [];
10506
+ const frames = viewport && viewport.frames || {};
10507
+ for (const container of Object.values(frames)) {
10508
+ if (!container || typeof container !== "object" || Array.isArray(container) || !Array.isArray(container.frames)) continue;
10509
+ for (const frame of container.frames) {
10510
+ if (!frame || typeof frame !== "object" || Array.isArray(frame)) continue;
10511
+ const url = typeof frame.url === "string" ? frame.url : null;
10512
+ if (url && !urls.includes(url)) urls.push(url);
10513
+ }
10514
+ }
10515
+ return urls.slice(0, 10);
10516
+ }
10517
+ function profileSetupActionCounts(results) {
10518
+ const counts = {};
10519
+ for (const result of results || []) {
10520
+ const action = profileSetupResultAction(result);
10521
+ counts[action] = (counts[action] || 0) + 1;
10522
+ }
10523
+ return counts;
10524
+ }
10525
+ function sampleProfileSetupSummaryItems(items, limit) {
10526
+ if ((items || []).length <= limit) return items || [];
10527
+ const firstCount = Math.floor(limit / 2);
10528
+ const lastCount = limit - firstCount;
10529
+ return [...items.slice(0, firstCount), ...items.slice(-lastCount)];
10530
+ }
10531
+ function profileSetupSummary(viewports, actionCount) {
10532
+ return {
10533
+ viewport_count: (viewports || []).length,
10534
+ action_count: actionCount ?? null,
10535
+ viewports: (viewports || []).map((viewport) => {
10536
+ const results = viewport.setup_action_results || [];
10537
+ const failed = results.filter((result) => result && result.ok === false);
10538
+ const clickedItems = results
10539
+ .filter((result) => result && profileSetupResultAction(result) === "click" && result.ok !== false)
10540
+ .map((result) => ({
10541
+ ordinal: result.ordinal ?? null,
10542
+ selector: result.selector ?? null,
10543
+ frame_selector: result.frame_selector ?? null,
10544
+ text: compactProfileSetupSummaryText(result.text),
10545
+ }));
10546
+ const clicked = sampleProfileSetupSummaryItems(clickedItems, 8);
10547
+ const textSamples = results
10548
+ .filter((result) => result && result.ok !== false && typeof result.text === "string" && (
10549
+ profileSetupResultAction(result) === "assert_text_visible"
10550
+ || profileSetupResultAction(result) === "assert_text_absent"
10551
+ || profileSetupResultAction(result) === "wait_for_text"
10552
+ ))
10553
+ .map((result) => ({
10554
+ ordinal: result.ordinal ?? null,
10555
+ action: profileSetupResultAction(result),
10556
+ frame_selector: result.frame_selector ?? null,
10557
+ text: compactProfileSetupSummaryText(result.text),
10558
+ }))
10559
+ .filter((item) => item.text)
10560
+ .slice(-6);
10561
+ return {
10562
+ name: viewport.name,
10563
+ ok: (actionCount === undefined ? results.length > 0 : results.length >= actionCount) && failed.length === 0,
10564
+ result_count: results.length,
10565
+ observed_path: viewport.route && viewport.route.observed || null,
10566
+ final_url: viewport.url || null,
10567
+ action_counts: profileSetupActionCounts(results),
10568
+ frame_action_count: results.filter((result) => result && result.frame_selector).length,
10569
+ frame_urls: profileSetupFrameUrls(viewport),
10570
+ clicked_total: clickedItems.length,
10571
+ clicked_truncated: clickedItems.length > clicked.length,
10572
+ clicked,
10573
+ text_samples: textSamples,
10574
+ failed: failed.map((result) => ({
10575
+ ordinal: result.ordinal ?? null,
10576
+ action: profileSetupResultAction(result),
10577
+ selector: result.selector ?? null,
10578
+ frame_selector: result.frame_selector ?? null,
10579
+ reason: result.reason || result.error || null,
10580
+ })),
10581
+ };
10582
+ }),
10583
+ };
10584
+ }
10411
10585
  function assessProfile(profile, evidence) {
10412
10586
  const checks = [];
10413
10587
  const viewports = evidence.viewports || [];
@@ -10512,6 +10686,7 @@ function assessProfile(profile, evidence) {
10512
10686
  && (viewport.setup_action_results || []).every((result) => !result || result.ok !== false),
10513
10687
  result_count: (viewport.setup_action_results || []).length,
10514
10688
  })),
10689
+ setup_summary: profileSetupSummary(viewports, actionCount),
10515
10690
  failed,
10516
10691
  },
10517
10692
  message: failed.length ? "Setup actions failed in " + failed.length + " viewport action(s)." : undefined,
package/dist/index.js CHANGED
@@ -58,7 +58,7 @@ import {
58
58
  resolveRiddleProofProfileTimeoutSec,
59
59
  slugifyRiddleProofProfileName,
60
60
  summarizeRiddleProofProfileResult
61
- } from "./chunk-T66DWLBE.js";
61
+ } from "./chunk-MLJHMZLR.js";
62
62
  import {
63
63
  DEFAULT_RIDDLE_API_BASE_URL,
64
64
  DEFAULT_RIDDLE_API_KEY_FILE,
package/dist/profile.cjs CHANGED
@@ -218,6 +218,87 @@ function toJsonValue(value) {
218
218
  if (isRecord(value)) return Object.fromEntries(Object.entries(value).map(([key, child]) => [key, toJsonValue(child)]));
219
219
  return String(value);
220
220
  }
221
+ function compactProfileSetupSummaryText(value, limit = 160) {
222
+ const text = typeof value === "string" ? value.replace(/\s+/g, " ").trim() : "";
223
+ if (!text) return void 0;
224
+ if (text.length <= limit) return text;
225
+ return `${text.slice(0, Math.max(0, limit - 15)).trimEnd()}... (${text.length} chars)`;
226
+ }
227
+ function profileSetupResultAction(value) {
228
+ const action = value.action ?? value.type;
229
+ return typeof action === "string" && action ? action : "unknown";
230
+ }
231
+ function profileSetupFrameUrls(viewport) {
232
+ const urls = [];
233
+ const frames = viewport.frames || {};
234
+ for (const container of Object.values(frames)) {
235
+ if (!isRecord(container) || !Array.isArray(container.frames)) continue;
236
+ for (const frame of container.frames) {
237
+ if (!isRecord(frame)) continue;
238
+ const url = typeof frame.url === "string" ? frame.url : void 0;
239
+ if (url && !urls.includes(url)) urls.push(url);
240
+ }
241
+ }
242
+ return urls.slice(0, 10);
243
+ }
244
+ function profileSetupActionCounts(results) {
245
+ const counts = {};
246
+ for (const result of results) {
247
+ const action = profileSetupResultAction(result);
248
+ counts[action] = (counts[action] || 0) + 1;
249
+ }
250
+ return toJsonValue(counts);
251
+ }
252
+ function sampleProfileSetupSummaryItems(items, limit) {
253
+ if (items.length <= limit) return items;
254
+ const firstCount = Math.floor(limit / 2);
255
+ const lastCount = limit - firstCount;
256
+ return [...items.slice(0, firstCount), ...items.slice(-lastCount)];
257
+ }
258
+ function profileSetupSummary(viewports, actionCount) {
259
+ return toJsonValue({
260
+ viewport_count: viewports.length,
261
+ action_count: actionCount ?? null,
262
+ viewports: viewports.map((viewport) => {
263
+ const results = viewport.setup_action_results || [];
264
+ const failed = results.filter((result) => result.ok === false);
265
+ const clickedItems = results.filter((result) => profileSetupResultAction(result) === "click" && result.ok !== false).map((result) => ({
266
+ ordinal: result.ordinal ?? null,
267
+ selector: result.selector ?? null,
268
+ frame_selector: result.frame_selector ?? null,
269
+ text: compactProfileSetupSummaryText(result.text)
270
+ }));
271
+ const clicked = sampleProfileSetupSummaryItems(clickedItems, 8);
272
+ 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) => ({
273
+ ordinal: result.ordinal ?? null,
274
+ action: profileSetupResultAction(result),
275
+ frame_selector: result.frame_selector ?? null,
276
+ text: compactProfileSetupSummaryText(result.text)
277
+ })).filter((item) => item.text).slice(-6);
278
+ return {
279
+ name: viewport.name,
280
+ ok: (actionCount === void 0 ? results.length > 0 : results.length >= actionCount) && failed.length === 0,
281
+ result_count: results.length,
282
+ observed_path: viewport.route?.observed ?? null,
283
+ final_url: viewport.url ?? null,
284
+ action_counts: profileSetupActionCounts(results),
285
+ frame_action_count: results.filter((result) => result.frame_selector).length,
286
+ frame_urls: profileSetupFrameUrls(viewport),
287
+ clicked_total: clickedItems.length,
288
+ clicked_truncated: clickedItems.length > clicked.length,
289
+ clicked,
290
+ text_samples,
291
+ failed: failed.map((result) => ({
292
+ ordinal: result.ordinal ?? null,
293
+ action: profileSetupResultAction(result),
294
+ selector: result.selector ?? null,
295
+ frame_selector: result.frame_selector ?? null,
296
+ reason: result.reason ?? result.error ?? null
297
+ }))
298
+ };
299
+ })
300
+ });
301
+ }
221
302
  function normalizeName(value, fallback) {
222
303
  const name = stringValue(value) || fallback;
223
304
  return name.replace(/\s+/g, " ").trim();
@@ -1324,6 +1405,7 @@ function assessSetupActionsFromEvidence(profile, evidence) {
1324
1405
  ok: (viewport.setup_action_results || []).length >= actionCount && (viewport.setup_action_results || []).every((result) => result.ok !== false),
1325
1406
  result_count: (viewport.setup_action_results || []).length
1326
1407
  })),
1408
+ setup_summary: profileSetupSummary(viewports, actionCount),
1327
1409
  failed
1328
1410
  },
1329
1411
  message: failed.length ? `Setup actions failed in ${failed.length} viewport action(s).` : void 0
@@ -1737,6 +1819,98 @@ function requiredNetworkMockHitCount(mock) {
1737
1819
  if (Array.isArray(mock.responses) && mock.responses.length) return mock.responses.length;
1738
1820
  return 1;
1739
1821
  }
1822
+ function compactProfileSetupSummaryText(value, limit) {
1823
+ limit = limit || 160;
1824
+ const text = typeof value === "string" ? value.replace(/\\s+/g, " ").trim() : "";
1825
+ if (!text) return undefined;
1826
+ if (text.length <= limit) return text;
1827
+ return text.slice(0, Math.max(0, limit - 15)).trimEnd() + "... (" + text.length + " chars)";
1828
+ }
1829
+ function profileSetupResultAction(result) {
1830
+ const action = result && (result.action || result.type);
1831
+ return typeof action === "string" && action ? action : "unknown";
1832
+ }
1833
+ function profileSetupFrameUrls(viewport) {
1834
+ const urls = [];
1835
+ const frames = viewport && viewport.frames || {};
1836
+ for (const container of Object.values(frames)) {
1837
+ if (!container || typeof container !== "object" || Array.isArray(container) || !Array.isArray(container.frames)) continue;
1838
+ for (const frame of container.frames) {
1839
+ if (!frame || typeof frame !== "object" || Array.isArray(frame)) continue;
1840
+ const url = typeof frame.url === "string" ? frame.url : null;
1841
+ if (url && !urls.includes(url)) urls.push(url);
1842
+ }
1843
+ }
1844
+ return urls.slice(0, 10);
1845
+ }
1846
+ function profileSetupActionCounts(results) {
1847
+ const counts = {};
1848
+ for (const result of results || []) {
1849
+ const action = profileSetupResultAction(result);
1850
+ counts[action] = (counts[action] || 0) + 1;
1851
+ }
1852
+ return counts;
1853
+ }
1854
+ function sampleProfileSetupSummaryItems(items, limit) {
1855
+ if ((items || []).length <= limit) return items || [];
1856
+ const firstCount = Math.floor(limit / 2);
1857
+ const lastCount = limit - firstCount;
1858
+ return [...items.slice(0, firstCount), ...items.slice(-lastCount)];
1859
+ }
1860
+ function profileSetupSummary(viewports, actionCount) {
1861
+ return {
1862
+ viewport_count: (viewports || []).length,
1863
+ action_count: actionCount ?? null,
1864
+ viewports: (viewports || []).map((viewport) => {
1865
+ const results = viewport.setup_action_results || [];
1866
+ const failed = results.filter((result) => result && result.ok === false);
1867
+ const clickedItems = results
1868
+ .filter((result) => result && profileSetupResultAction(result) === "click" && result.ok !== false)
1869
+ .map((result) => ({
1870
+ ordinal: result.ordinal ?? null,
1871
+ selector: result.selector ?? null,
1872
+ frame_selector: result.frame_selector ?? null,
1873
+ text: compactProfileSetupSummaryText(result.text),
1874
+ }));
1875
+ const clicked = sampleProfileSetupSummaryItems(clickedItems, 8);
1876
+ const textSamples = results
1877
+ .filter((result) => result && result.ok !== false && typeof result.text === "string" && (
1878
+ profileSetupResultAction(result) === "assert_text_visible"
1879
+ || profileSetupResultAction(result) === "assert_text_absent"
1880
+ || profileSetupResultAction(result) === "wait_for_text"
1881
+ ))
1882
+ .map((result) => ({
1883
+ ordinal: result.ordinal ?? null,
1884
+ action: profileSetupResultAction(result),
1885
+ frame_selector: result.frame_selector ?? null,
1886
+ text: compactProfileSetupSummaryText(result.text),
1887
+ }))
1888
+ .filter((item) => item.text)
1889
+ .slice(-6);
1890
+ return {
1891
+ name: viewport.name,
1892
+ ok: (actionCount === undefined ? results.length > 0 : results.length >= actionCount) && failed.length === 0,
1893
+ result_count: results.length,
1894
+ observed_path: viewport.route && viewport.route.observed || null,
1895
+ final_url: viewport.url || null,
1896
+ action_counts: profileSetupActionCounts(results),
1897
+ frame_action_count: results.filter((result) => result && result.frame_selector).length,
1898
+ frame_urls: profileSetupFrameUrls(viewport),
1899
+ clicked_total: clickedItems.length,
1900
+ clicked_truncated: clickedItems.length > clicked.length,
1901
+ clicked,
1902
+ text_samples: textSamples,
1903
+ failed: failed.map((result) => ({
1904
+ ordinal: result.ordinal ?? null,
1905
+ action: profileSetupResultAction(result),
1906
+ selector: result.selector ?? null,
1907
+ frame_selector: result.frame_selector ?? null,
1908
+ reason: result.reason || result.error || null,
1909
+ })),
1910
+ };
1911
+ }),
1912
+ };
1913
+ }
1740
1914
  function assessProfile(profile, evidence) {
1741
1915
  const checks = [];
1742
1916
  const viewports = evidence.viewports || [];
@@ -1841,6 +2015,7 @@ function assessProfile(profile, evidence) {
1841
2015
  && (viewport.setup_action_results || []).every((result) => !result || result.ok !== false),
1842
2016
  result_count: (viewport.setup_action_results || []).length,
1843
2017
  })),
2018
+ setup_summary: profileSetupSummary(viewports, actionCount),
1844
2019
  failed,
1845
2020
  },
1846
2021
  message: failed.length ? "Setup actions failed in " + failed.length + " viewport action(s)." : undefined,
package/dist/profile.js CHANGED
@@ -19,7 +19,7 @@ import {
19
19
  resolveRiddleProofProfileTimeoutSec,
20
20
  slugifyRiddleProofProfileName,
21
21
  summarizeRiddleProofProfileResult
22
- } from "./chunk-T66DWLBE.js";
22
+ } from "./chunk-MLJHMZLR.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.61",
3
+ "version": "0.7.63",
4
4
  "description": "Reusable Riddle Proof contracts and helpers for evidence-backed agent changes.",
5
5
  "license": "MIT",
6
6
  "author": "RiddleDC",