@riddledc/riddle-proof 0.7.22 → 0.7.24

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.
@@ -1121,6 +1121,20 @@ async function captureViewport(viewport) {
1121
1121
  const scrollWidth = documentElement ? documentElement.scrollWidth : 0;
1122
1122
  const viewportWidth = clientWidth || window.innerWidth;
1123
1123
  const overflowOffenders = [];
1124
+ function isContainedByHorizontalScroller(element) {
1125
+ let current = element.parentElement;
1126
+ while (current && current !== body && current !== documentElement) {
1127
+ const style = window.getComputedStyle(current);
1128
+ const overflowX = style.overflowX || style.overflow || "";
1129
+ if ((overflowX === "auto" || overflowX === "scroll") && current.scrollWidth > current.clientWidth + 1) {
1130
+ const currentRect = current.getBoundingClientRect();
1131
+ const contained = currentRect.left >= -0.5 && currentRect.right <= viewportWidth + 0.5;
1132
+ if (contained) return true;
1133
+ }
1134
+ current = current.parentElement;
1135
+ }
1136
+ return false;
1137
+ }
1124
1138
  for (const element of Array.from(body ? body.querySelectorAll("*") : [])) {
1125
1139
  const rect = element.getBoundingClientRect();
1126
1140
  if (!rect || rect.width < 1 || rect.height < 1) continue;
@@ -1130,6 +1144,7 @@ async function captureViewport(viewport) {
1130
1144
  const rightOverflow = Math.max(0, rect.right - viewportWidth);
1131
1145
  const overflow = Math.max(leftOverflow, rightOverflow);
1132
1146
  if (overflow <= 0.5) continue;
1147
+ if (isContainedByHorizontalScroller(element)) continue;
1133
1148
  const tag = element.tagName ? element.tagName.toLowerCase() : "element";
1134
1149
  const id = element.id ? "#" + element.id : "";
1135
1150
  const className = typeof element.className === "string"
@@ -1161,6 +1176,7 @@ async function captureViewport(viewport) {
1161
1176
  pathname: location.pathname,
1162
1177
  title: document.title,
1163
1178
  body_text_length: text.length,
1179
+ body_text: text,
1164
1180
  body_text_sample: text.slice(0, 8000),
1165
1181
  scroll_width: scrollWidth,
1166
1182
  client_width: clientWidth,
@@ -1186,7 +1202,7 @@ async function captureViewport(viewport) {
1186
1202
  selectors[check.selector] = await selectorStats(check.selector);
1187
1203
  }
1188
1204
  if ((check.type === "text_visible" || check.type === "text_absent") && (check.text || check.pattern)) {
1189
- text_matches[textKey(check)] = textMatches(dom.body_text_sample || "", check);
1205
+ text_matches[textKey(check)] = textMatches(dom.body_text || dom.body_text_sample || "", check);
1190
1206
  }
1191
1207
  }
1192
1208
  const screenshotLabel = profileSlug + "-" + viewport.name;
@@ -1273,24 +1289,36 @@ return result;
1273
1289
  }
1274
1290
  function collectRiddleProfileArtifactRefs(input) {
1275
1291
  const refs = [];
1276
- const seen = /* @__PURE__ */ new Set();
1292
+ const indexes = /* @__PURE__ */ new Map();
1293
+ const priorities = /* @__PURE__ */ new Map();
1277
1294
  function add(item, source) {
1278
1295
  if (!isRecord(item)) return;
1279
- const name = stringValue(item.name) || stringValue(item.filename) || "";
1280
1296
  const url = stringValue(item.url);
1281
1297
  const path = stringValue(item.path);
1298
+ const rawName = stringValue(item.name) || stringValue(item.filename) || artifactNameFromPath(url || path) || "";
1299
+ const name = normalizeRiddleProfileArtifactName(rawName);
1282
1300
  if (!name && !url && !path) return;
1283
- const key = `${name}:${url || path || ""}`;
1284
- if (seen.has(key)) return;
1285
- seen.add(key);
1286
- refs.push({
1301
+ const key = profileArtifactDedupeKey(name, url || path || "");
1302
+ const priority = profileArtifactPriority(rawName, name);
1303
+ const ref = {
1287
1304
  name,
1288
1305
  url,
1289
1306
  path,
1290
1307
  kind: stringValue(item.kind) || stringValue(item.type),
1291
1308
  content_type: stringValue(item.content_type) || stringValue(item.contentType),
1292
1309
  source
1293
- });
1310
+ };
1311
+ const existingIndex = indexes.get(key);
1312
+ if (existingIndex !== void 0) {
1313
+ if (priority > (priorities.get(key) || 0)) {
1314
+ refs[existingIndex] = ref;
1315
+ priorities.set(key, priority);
1316
+ }
1317
+ return;
1318
+ }
1319
+ indexes.set(key, refs.length);
1320
+ priorities.set(key, priority);
1321
+ refs.push(ref);
1294
1322
  }
1295
1323
  function visit(value, source) {
1296
1324
  if (Array.isArray(value)) {
@@ -1305,6 +1333,31 @@ function collectRiddleProfileArtifactRefs(input) {
1305
1333
  visit(input, "artifacts");
1306
1334
  return refs;
1307
1335
  }
1336
+ function normalizeRiddleProfileArtifactName(name) {
1337
+ return name.replace(/\.json\.json$/i, ".json");
1338
+ }
1339
+ function profileArtifactDedupeKey(name, location) {
1340
+ if (PROFILE_SINGLETON_ARTIFACT_NAMES.has(name.toLowerCase())) return name.toLowerCase();
1341
+ return `${name}:${location}`;
1342
+ }
1343
+ function profileArtifactPriority(rawName, normalizedName) {
1344
+ const lower = normalizedName.toLowerCase();
1345
+ if (!PROFILE_SINGLETON_ARTIFACT_NAMES.has(lower)) return 1;
1346
+ return /\.json\.json$/i.test(rawName) ? 2 : 1;
1347
+ }
1348
+ function artifactNameFromPath(value) {
1349
+ if (!value) return "";
1350
+ try {
1351
+ return new URL(value).pathname.split("/").filter(Boolean).pop() || "";
1352
+ } catch {
1353
+ return value.split(/[\\/]/).filter(Boolean).pop() || "";
1354
+ }
1355
+ }
1356
+ var PROFILE_SINGLETON_ARTIFACT_NAMES = /* @__PURE__ */ new Set([
1357
+ "proof.json",
1358
+ "console.json",
1359
+ "dom-summary.json"
1360
+ ]);
1308
1361
  function extractRiddleProofProfileResult(input) {
1309
1362
  if (!isRecord(input)) return void 0;
1310
1363
  if (input.version === RIDDLE_PROOF_PROFILE_RESULT_VERSION) return input;
package/dist/cli.cjs CHANGED
@@ -7885,6 +7885,20 @@ async function captureViewport(viewport) {
7885
7885
  const scrollWidth = documentElement ? documentElement.scrollWidth : 0;
7886
7886
  const viewportWidth = clientWidth || window.innerWidth;
7887
7887
  const overflowOffenders = [];
7888
+ function isContainedByHorizontalScroller(element) {
7889
+ let current = element.parentElement;
7890
+ while (current && current !== body && current !== documentElement) {
7891
+ const style = window.getComputedStyle(current);
7892
+ const overflowX = style.overflowX || style.overflow || "";
7893
+ if ((overflowX === "auto" || overflowX === "scroll") && current.scrollWidth > current.clientWidth + 1) {
7894
+ const currentRect = current.getBoundingClientRect();
7895
+ const contained = currentRect.left >= -0.5 && currentRect.right <= viewportWidth + 0.5;
7896
+ if (contained) return true;
7897
+ }
7898
+ current = current.parentElement;
7899
+ }
7900
+ return false;
7901
+ }
7888
7902
  for (const element of Array.from(body ? body.querySelectorAll("*") : [])) {
7889
7903
  const rect = element.getBoundingClientRect();
7890
7904
  if (!rect || rect.width < 1 || rect.height < 1) continue;
@@ -7894,6 +7908,7 @@ async function captureViewport(viewport) {
7894
7908
  const rightOverflow = Math.max(0, rect.right - viewportWidth);
7895
7909
  const overflow = Math.max(leftOverflow, rightOverflow);
7896
7910
  if (overflow <= 0.5) continue;
7911
+ if (isContainedByHorizontalScroller(element)) continue;
7897
7912
  const tag = element.tagName ? element.tagName.toLowerCase() : "element";
7898
7913
  const id = element.id ? "#" + element.id : "";
7899
7914
  const className = typeof element.className === "string"
@@ -7925,6 +7940,7 @@ async function captureViewport(viewport) {
7925
7940
  pathname: location.pathname,
7926
7941
  title: document.title,
7927
7942
  body_text_length: text.length,
7943
+ body_text: text,
7928
7944
  body_text_sample: text.slice(0, 8000),
7929
7945
  scroll_width: scrollWidth,
7930
7946
  client_width: clientWidth,
@@ -7950,7 +7966,7 @@ async function captureViewport(viewport) {
7950
7966
  selectors[check.selector] = await selectorStats(check.selector);
7951
7967
  }
7952
7968
  if ((check.type === "text_visible" || check.type === "text_absent") && (check.text || check.pattern)) {
7953
- text_matches[textKey(check)] = textMatches(dom.body_text_sample || "", check);
7969
+ text_matches[textKey(check)] = textMatches(dom.body_text || dom.body_text_sample || "", check);
7954
7970
  }
7955
7971
  }
7956
7972
  const screenshotLabel = profileSlug + "-" + viewport.name;
@@ -8037,24 +8053,36 @@ return result;
8037
8053
  }
8038
8054
  function collectRiddleProfileArtifactRefs(input) {
8039
8055
  const refs = [];
8040
- const seen = /* @__PURE__ */ new Set();
8056
+ const indexes = /* @__PURE__ */ new Map();
8057
+ const priorities = /* @__PURE__ */ new Map();
8041
8058
  function add(item, source) {
8042
8059
  if (!isRecord(item)) return;
8043
- const name = stringValue2(item.name) || stringValue2(item.filename) || "";
8044
8060
  const url = stringValue2(item.url);
8045
8061
  const path7 = stringValue2(item.path);
8062
+ const rawName = stringValue2(item.name) || stringValue2(item.filename) || artifactNameFromPath(url || path7) || "";
8063
+ const name = normalizeRiddleProfileArtifactName(rawName);
8046
8064
  if (!name && !url && !path7) return;
8047
- const key = `${name}:${url || path7 || ""}`;
8048
- if (seen.has(key)) return;
8049
- seen.add(key);
8050
- refs.push({
8065
+ const key = profileArtifactDedupeKey(name, url || path7 || "");
8066
+ const priority = profileArtifactPriority(rawName, name);
8067
+ const ref = {
8051
8068
  name,
8052
8069
  url,
8053
8070
  path: path7,
8054
8071
  kind: stringValue2(item.kind) || stringValue2(item.type),
8055
8072
  content_type: stringValue2(item.content_type) || stringValue2(item.contentType),
8056
8073
  source
8057
- });
8074
+ };
8075
+ const existingIndex = indexes.get(key);
8076
+ if (existingIndex !== void 0) {
8077
+ if (priority > (priorities.get(key) || 0)) {
8078
+ refs[existingIndex] = ref;
8079
+ priorities.set(key, priority);
8080
+ }
8081
+ return;
8082
+ }
8083
+ indexes.set(key, refs.length);
8084
+ priorities.set(key, priority);
8085
+ refs.push(ref);
8058
8086
  }
8059
8087
  function visit(value, source) {
8060
8088
  if (Array.isArray(value)) {
@@ -8069,6 +8097,31 @@ function collectRiddleProfileArtifactRefs(input) {
8069
8097
  visit(input, "artifacts");
8070
8098
  return refs;
8071
8099
  }
8100
+ function normalizeRiddleProfileArtifactName(name) {
8101
+ return name.replace(/\.json\.json$/i, ".json");
8102
+ }
8103
+ function profileArtifactDedupeKey(name, location) {
8104
+ if (PROFILE_SINGLETON_ARTIFACT_NAMES.has(name.toLowerCase())) return name.toLowerCase();
8105
+ return `${name}:${location}`;
8106
+ }
8107
+ function profileArtifactPriority(rawName, normalizedName) {
8108
+ const lower = normalizedName.toLowerCase();
8109
+ if (!PROFILE_SINGLETON_ARTIFACT_NAMES.has(lower)) return 1;
8110
+ return /\.json\.json$/i.test(rawName) ? 2 : 1;
8111
+ }
8112
+ function artifactNameFromPath(value) {
8113
+ if (!value) return "";
8114
+ try {
8115
+ return new URL(value).pathname.split("/").filter(Boolean).pop() || "";
8116
+ } catch {
8117
+ return value.split(/[\\/]/).filter(Boolean).pop() || "";
8118
+ }
8119
+ }
8120
+ var PROFILE_SINGLETON_ARTIFACT_NAMES = /* @__PURE__ */ new Set([
8121
+ "proof.json",
8122
+ "console.json",
8123
+ "dom-summary.json"
8124
+ ]);
8072
8125
  function extractRiddleProofProfileResult(input) {
8073
8126
  if (!isRecord(input)) return void 0;
8074
8127
  if (input.version === RIDDLE_PROOF_PROFILE_RESULT_VERSION) return input;
package/dist/cli.js CHANGED
@@ -10,7 +10,7 @@ import {
10
10
  profileStatusExitCode,
11
11
  resolveRiddleProofProfileTargetUrl,
12
12
  resolveRiddleProofProfileTimeoutSec
13
- } from "./chunk-WTHSVHG5.js";
13
+ } from "./chunk-SDSBS64X.js";
14
14
  import {
15
15
  createRiddleApiClient,
16
16
  parseRiddleViewport
package/dist/index.cjs CHANGED
@@ -9835,6 +9835,20 @@ async function captureViewport(viewport) {
9835
9835
  const scrollWidth = documentElement ? documentElement.scrollWidth : 0;
9836
9836
  const viewportWidth = clientWidth || window.innerWidth;
9837
9837
  const overflowOffenders = [];
9838
+ function isContainedByHorizontalScroller(element) {
9839
+ let current = element.parentElement;
9840
+ while (current && current !== body && current !== documentElement) {
9841
+ const style = window.getComputedStyle(current);
9842
+ const overflowX = style.overflowX || style.overflow || "";
9843
+ if ((overflowX === "auto" || overflowX === "scroll") && current.scrollWidth > current.clientWidth + 1) {
9844
+ const currentRect = current.getBoundingClientRect();
9845
+ const contained = currentRect.left >= -0.5 && currentRect.right <= viewportWidth + 0.5;
9846
+ if (contained) return true;
9847
+ }
9848
+ current = current.parentElement;
9849
+ }
9850
+ return false;
9851
+ }
9838
9852
  for (const element of Array.from(body ? body.querySelectorAll("*") : [])) {
9839
9853
  const rect = element.getBoundingClientRect();
9840
9854
  if (!rect || rect.width < 1 || rect.height < 1) continue;
@@ -9844,6 +9858,7 @@ async function captureViewport(viewport) {
9844
9858
  const rightOverflow = Math.max(0, rect.right - viewportWidth);
9845
9859
  const overflow = Math.max(leftOverflow, rightOverflow);
9846
9860
  if (overflow <= 0.5) continue;
9861
+ if (isContainedByHorizontalScroller(element)) continue;
9847
9862
  const tag = element.tagName ? element.tagName.toLowerCase() : "element";
9848
9863
  const id = element.id ? "#" + element.id : "";
9849
9864
  const className = typeof element.className === "string"
@@ -9875,6 +9890,7 @@ async function captureViewport(viewport) {
9875
9890
  pathname: location.pathname,
9876
9891
  title: document.title,
9877
9892
  body_text_length: text.length,
9893
+ body_text: text,
9878
9894
  body_text_sample: text.slice(0, 8000),
9879
9895
  scroll_width: scrollWidth,
9880
9896
  client_width: clientWidth,
@@ -9900,7 +9916,7 @@ async function captureViewport(viewport) {
9900
9916
  selectors[check.selector] = await selectorStats(check.selector);
9901
9917
  }
9902
9918
  if ((check.type === "text_visible" || check.type === "text_absent") && (check.text || check.pattern)) {
9903
- text_matches[textKey(check)] = textMatches(dom.body_text_sample || "", check);
9919
+ text_matches[textKey(check)] = textMatches(dom.body_text || dom.body_text_sample || "", check);
9904
9920
  }
9905
9921
  }
9906
9922
  const screenshotLabel = profileSlug + "-" + viewport.name;
@@ -9987,24 +10003,36 @@ return result;
9987
10003
  }
9988
10004
  function collectRiddleProfileArtifactRefs(input) {
9989
10005
  const refs = [];
9990
- const seen = /* @__PURE__ */ new Set();
10006
+ const indexes = /* @__PURE__ */ new Map();
10007
+ const priorities = /* @__PURE__ */ new Map();
9991
10008
  function add(item, source) {
9992
10009
  if (!isRecord2(item)) return;
9993
- const name = stringValue5(item.name) || stringValue5(item.filename) || "";
9994
10010
  const url = stringValue5(item.url);
9995
10011
  const path6 = stringValue5(item.path);
10012
+ const rawName = stringValue5(item.name) || stringValue5(item.filename) || artifactNameFromPath(url || path6) || "";
10013
+ const name = normalizeRiddleProfileArtifactName(rawName);
9996
10014
  if (!name && !url && !path6) return;
9997
- const key = `${name}:${url || path6 || ""}`;
9998
- if (seen.has(key)) return;
9999
- seen.add(key);
10000
- refs.push({
10015
+ const key = profileArtifactDedupeKey(name, url || path6 || "");
10016
+ const priority = profileArtifactPriority(rawName, name);
10017
+ const ref = {
10001
10018
  name,
10002
10019
  url,
10003
10020
  path: path6,
10004
10021
  kind: stringValue5(item.kind) || stringValue5(item.type),
10005
10022
  content_type: stringValue5(item.content_type) || stringValue5(item.contentType),
10006
10023
  source
10007
- });
10024
+ };
10025
+ const existingIndex = indexes.get(key);
10026
+ if (existingIndex !== void 0) {
10027
+ if (priority > (priorities.get(key) || 0)) {
10028
+ refs[existingIndex] = ref;
10029
+ priorities.set(key, priority);
10030
+ }
10031
+ return;
10032
+ }
10033
+ indexes.set(key, refs.length);
10034
+ priorities.set(key, priority);
10035
+ refs.push(ref);
10008
10036
  }
10009
10037
  function visit(value, source) {
10010
10038
  if (Array.isArray(value)) {
@@ -10019,6 +10047,31 @@ function collectRiddleProfileArtifactRefs(input) {
10019
10047
  visit(input, "artifacts");
10020
10048
  return refs;
10021
10049
  }
10050
+ function normalizeRiddleProfileArtifactName(name) {
10051
+ return name.replace(/\.json\.json$/i, ".json");
10052
+ }
10053
+ function profileArtifactDedupeKey(name, location) {
10054
+ if (PROFILE_SINGLETON_ARTIFACT_NAMES.has(name.toLowerCase())) return name.toLowerCase();
10055
+ return `${name}:${location}`;
10056
+ }
10057
+ function profileArtifactPriority(rawName, normalizedName) {
10058
+ const lower = normalizedName.toLowerCase();
10059
+ if (!PROFILE_SINGLETON_ARTIFACT_NAMES.has(lower)) return 1;
10060
+ return /\.json\.json$/i.test(rawName) ? 2 : 1;
10061
+ }
10062
+ function artifactNameFromPath(value) {
10063
+ if (!value) return "";
10064
+ try {
10065
+ return new URL(value).pathname.split("/").filter(Boolean).pop() || "";
10066
+ } catch {
10067
+ return value.split(/[\\/]/).filter(Boolean).pop() || "";
10068
+ }
10069
+ }
10070
+ var PROFILE_SINGLETON_ARTIFACT_NAMES = /* @__PURE__ */ new Set([
10071
+ "proof.json",
10072
+ "console.json",
10073
+ "dom-summary.json"
10074
+ ]);
10022
10075
  function extractRiddleProofProfileResult(input) {
10023
10076
  if (!isRecord2(input)) return void 0;
10024
10077
  if (input.version === RIDDLE_PROOF_PROFILE_RESULT_VERSION) return input;
package/dist/index.js CHANGED
@@ -58,7 +58,7 @@ import {
58
58
  resolveRiddleProofProfileTimeoutSec,
59
59
  slugifyRiddleProofProfileName,
60
60
  summarizeRiddleProofProfileResult
61
- } from "./chunk-WTHSVHG5.js";
61
+ } from "./chunk-SDSBS64X.js";
62
62
  import {
63
63
  DEFAULT_RIDDLE_API_BASE_URL,
64
64
  DEFAULT_RIDDLE_API_KEY_FILE,
package/dist/profile.cjs CHANGED
@@ -1164,6 +1164,20 @@ async function captureViewport(viewport) {
1164
1164
  const scrollWidth = documentElement ? documentElement.scrollWidth : 0;
1165
1165
  const viewportWidth = clientWidth || window.innerWidth;
1166
1166
  const overflowOffenders = [];
1167
+ function isContainedByHorizontalScroller(element) {
1168
+ let current = element.parentElement;
1169
+ while (current && current !== body && current !== documentElement) {
1170
+ const style = window.getComputedStyle(current);
1171
+ const overflowX = style.overflowX || style.overflow || "";
1172
+ if ((overflowX === "auto" || overflowX === "scroll") && current.scrollWidth > current.clientWidth + 1) {
1173
+ const currentRect = current.getBoundingClientRect();
1174
+ const contained = currentRect.left >= -0.5 && currentRect.right <= viewportWidth + 0.5;
1175
+ if (contained) return true;
1176
+ }
1177
+ current = current.parentElement;
1178
+ }
1179
+ return false;
1180
+ }
1167
1181
  for (const element of Array.from(body ? body.querySelectorAll("*") : [])) {
1168
1182
  const rect = element.getBoundingClientRect();
1169
1183
  if (!rect || rect.width < 1 || rect.height < 1) continue;
@@ -1173,6 +1187,7 @@ async function captureViewport(viewport) {
1173
1187
  const rightOverflow = Math.max(0, rect.right - viewportWidth);
1174
1188
  const overflow = Math.max(leftOverflow, rightOverflow);
1175
1189
  if (overflow <= 0.5) continue;
1190
+ if (isContainedByHorizontalScroller(element)) continue;
1176
1191
  const tag = element.tagName ? element.tagName.toLowerCase() : "element";
1177
1192
  const id = element.id ? "#" + element.id : "";
1178
1193
  const className = typeof element.className === "string"
@@ -1204,6 +1219,7 @@ async function captureViewport(viewport) {
1204
1219
  pathname: location.pathname,
1205
1220
  title: document.title,
1206
1221
  body_text_length: text.length,
1222
+ body_text: text,
1207
1223
  body_text_sample: text.slice(0, 8000),
1208
1224
  scroll_width: scrollWidth,
1209
1225
  client_width: clientWidth,
@@ -1229,7 +1245,7 @@ async function captureViewport(viewport) {
1229
1245
  selectors[check.selector] = await selectorStats(check.selector);
1230
1246
  }
1231
1247
  if ((check.type === "text_visible" || check.type === "text_absent") && (check.text || check.pattern)) {
1232
- text_matches[textKey(check)] = textMatches(dom.body_text_sample || "", check);
1248
+ text_matches[textKey(check)] = textMatches(dom.body_text || dom.body_text_sample || "", check);
1233
1249
  }
1234
1250
  }
1235
1251
  const screenshotLabel = profileSlug + "-" + viewport.name;
@@ -1316,24 +1332,36 @@ return result;
1316
1332
  }
1317
1333
  function collectRiddleProfileArtifactRefs(input) {
1318
1334
  const refs = [];
1319
- const seen = /* @__PURE__ */ new Set();
1335
+ const indexes = /* @__PURE__ */ new Map();
1336
+ const priorities = /* @__PURE__ */ new Map();
1320
1337
  function add(item, source) {
1321
1338
  if (!isRecord(item)) return;
1322
- const name = stringValue(item.name) || stringValue(item.filename) || "";
1323
1339
  const url = stringValue(item.url);
1324
1340
  const path = stringValue(item.path);
1341
+ const rawName = stringValue(item.name) || stringValue(item.filename) || artifactNameFromPath(url || path) || "";
1342
+ const name = normalizeRiddleProfileArtifactName(rawName);
1325
1343
  if (!name && !url && !path) return;
1326
- const key = `${name}:${url || path || ""}`;
1327
- if (seen.has(key)) return;
1328
- seen.add(key);
1329
- refs.push({
1344
+ const key = profileArtifactDedupeKey(name, url || path || "");
1345
+ const priority = profileArtifactPriority(rawName, name);
1346
+ const ref = {
1330
1347
  name,
1331
1348
  url,
1332
1349
  path,
1333
1350
  kind: stringValue(item.kind) || stringValue(item.type),
1334
1351
  content_type: stringValue(item.content_type) || stringValue(item.contentType),
1335
1352
  source
1336
- });
1353
+ };
1354
+ const existingIndex = indexes.get(key);
1355
+ if (existingIndex !== void 0) {
1356
+ if (priority > (priorities.get(key) || 0)) {
1357
+ refs[existingIndex] = ref;
1358
+ priorities.set(key, priority);
1359
+ }
1360
+ return;
1361
+ }
1362
+ indexes.set(key, refs.length);
1363
+ priorities.set(key, priority);
1364
+ refs.push(ref);
1337
1365
  }
1338
1366
  function visit(value, source) {
1339
1367
  if (Array.isArray(value)) {
@@ -1348,6 +1376,31 @@ function collectRiddleProfileArtifactRefs(input) {
1348
1376
  visit(input, "artifacts");
1349
1377
  return refs;
1350
1378
  }
1379
+ function normalizeRiddleProfileArtifactName(name) {
1380
+ return name.replace(/\.json\.json$/i, ".json");
1381
+ }
1382
+ function profileArtifactDedupeKey(name, location) {
1383
+ if (PROFILE_SINGLETON_ARTIFACT_NAMES.has(name.toLowerCase())) return name.toLowerCase();
1384
+ return `${name}:${location}`;
1385
+ }
1386
+ function profileArtifactPriority(rawName, normalizedName) {
1387
+ const lower = normalizedName.toLowerCase();
1388
+ if (!PROFILE_SINGLETON_ARTIFACT_NAMES.has(lower)) return 1;
1389
+ return /\.json\.json$/i.test(rawName) ? 2 : 1;
1390
+ }
1391
+ function artifactNameFromPath(value) {
1392
+ if (!value) return "";
1393
+ try {
1394
+ return new URL(value).pathname.split("/").filter(Boolean).pop() || "";
1395
+ } catch {
1396
+ return value.split(/[\\/]/).filter(Boolean).pop() || "";
1397
+ }
1398
+ }
1399
+ var PROFILE_SINGLETON_ARTIFACT_NAMES = /* @__PURE__ */ new Set([
1400
+ "proof.json",
1401
+ "console.json",
1402
+ "dom-summary.json"
1403
+ ]);
1351
1404
  function extractRiddleProofProfileResult(input) {
1352
1405
  if (!isRecord(input)) return void 0;
1353
1406
  if (input.version === RIDDLE_PROOF_PROFILE_RESULT_VERSION) return input;
package/dist/profile.js CHANGED
@@ -19,7 +19,7 @@ import {
19
19
  resolveRiddleProofProfileTimeoutSec,
20
20
  slugifyRiddleProofProfileName,
21
21
  summarizeRiddleProofProfileResult
22
- } from "./chunk-WTHSVHG5.js";
22
+ } from "./chunk-SDSBS64X.js";
23
23
  export {
24
24
  RIDDLE_PROOF_PROFILE_CHECK_TYPES,
25
25
  RIDDLE_PROOF_PROFILE_EVIDENCE_VERSION,
@@ -292,7 +292,7 @@ declare function executeWorkflow(params: WorkflowParams, pluginConfig: any, reso
292
292
  blocking?: boolean;
293
293
  details?: Record<string, unknown>;
294
294
  ok: boolean;
295
- action: "author" | "recon" | "ship" | "implement" | "verify" | "setup" | "run";
295
+ action: "setup" | "recon" | "author" | "implement" | "verify" | "ship" | "run";
296
296
  state_path: string;
297
297
  stage: any;
298
298
  summary: string;
@@ -382,7 +382,7 @@ declare function executeWorkflow(params: WorkflowParams, pluginConfig: any, reso
382
382
  continueWithStage?: WorkflowStage | null;
383
383
  blocking?: boolean;
384
384
  details?: Record<string, unknown>;
385
- action: "author" | "recon" | "ship" | "implement" | "verify" | "setup" | "run";
385
+ action: "setup" | "recon" | "author" | "implement" | "verify" | "ship" | "run";
386
386
  state_path: string;
387
387
  stage: any;
388
388
  checkpoint: string;
@@ -659,7 +659,7 @@ declare function executeWorkflow(params: WorkflowParams, pluginConfig: any, reso
659
659
  error?: undefined;
660
660
  } | {
661
661
  ok: boolean;
662
- action: "author" | "recon" | "ship" | "implement" | "verify" | "setup" | "run";
662
+ action: "setup" | "recon" | "author" | "implement" | "verify" | "ship" | "run";
663
663
  state_path: string;
664
664
  stage: any;
665
665
  summary: string;
@@ -292,7 +292,7 @@ declare function executeWorkflow(params: WorkflowParams, pluginConfig: any, reso
292
292
  blocking?: boolean;
293
293
  details?: Record<string, unknown>;
294
294
  ok: boolean;
295
- action: "author" | "recon" | "ship" | "implement" | "verify" | "setup" | "run";
295
+ action: "setup" | "recon" | "author" | "implement" | "verify" | "ship" | "run";
296
296
  state_path: string;
297
297
  stage: any;
298
298
  summary: string;
@@ -382,7 +382,7 @@ declare function executeWorkflow(params: WorkflowParams, pluginConfig: any, reso
382
382
  continueWithStage?: WorkflowStage | null;
383
383
  blocking?: boolean;
384
384
  details?: Record<string, unknown>;
385
- action: "author" | "recon" | "ship" | "implement" | "verify" | "setup" | "run";
385
+ action: "setup" | "recon" | "author" | "implement" | "verify" | "ship" | "run";
386
386
  state_path: string;
387
387
  stage: any;
388
388
  checkpoint: string;
@@ -659,7 +659,7 @@ declare function executeWorkflow(params: WorkflowParams, pluginConfig: any, reso
659
659
  error?: undefined;
660
660
  } | {
661
661
  ok: boolean;
662
- action: "author" | "recon" | "ship" | "implement" | "verify" | "setup" | "run";
662
+ action: "setup" | "recon" | "author" | "implement" | "verify" | "ship" | "run";
663
663
  state_path: string;
664
664
  stage: any;
665
665
  summary: string;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@riddledc/riddle-proof",
3
- "version": "0.7.22",
3
+ "version": "0.7.24",
4
4
  "description": "Reusable Riddle Proof contracts and helpers for evidence-backed agent changes.",
5
5
  "license": "MIT",
6
6
  "author": "RiddleDC",