oh-my-promptfoo 1.20.5 → 1.20.6

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.
@@ -9535,6 +9535,39 @@ async function runNative(frame, signal, peerPath) {
9535
9535
  if (typeof provider?.cleanup === "function") await provider.cleanup();
9536
9536
  }
9537
9537
  }
9538
+ const REDACTION_MASK = "******";
9539
+ const MAX_MASKS = 64;
9540
+ const MAX_MASKED_SPAN = 256;
9541
+ const MAX_ALIGNMENT_STEPS = 1e6;
9542
+ /**
9543
+ * Exact equality, or a bounded redaction of the local body: every visible character
9544
+ * matches in order, each mask hides one non-empty single-line span of at most
9545
+ * MAX_MASKED_SPAN characters, and at least 90% of the body stays visible.
9546
+ */
9547
+ function matchesLoadedBody(body, content) {
9548
+ if (body === content) return true;
9549
+ const parts = content.split(REDACTION_MASK);
9550
+ const masks = parts.length - 1;
9551
+ const visible = content.length - masks * 6;
9552
+ if (masks === 0 || masks > MAX_MASKS || visible * 10 < body.length * 9) return false;
9553
+ if (!body.startsWith(parts[0])) return false;
9554
+ const failed = /* @__PURE__ */ new Set();
9555
+ let steps = 0;
9556
+ const align = (index, position) => {
9557
+ if (index === masks) return position === body.length;
9558
+ const key = `${index}:${position}`;
9559
+ if (failed.has(key)) return false;
9560
+ const next = parts[index + 1];
9561
+ for (let span = 1; span <= MAX_MASKED_SPAN && position + span <= body.length; span++) {
9562
+ if (body[position + span - 1] === "\n" || ++steps > MAX_ALIGNMENT_STEPS) break;
9563
+ const start = position + span;
9564
+ if (body.startsWith(next, start) && align(index + 1, start + next.length)) return true;
9565
+ }
9566
+ failed.add(key);
9567
+ return false;
9568
+ };
9569
+ return align(0, parts[0].length);
9570
+ }
9538
9571
  function verifiedSkillLoaderRecord(entry, workingDir) {
9539
9572
  if (!entry || typeof entry !== "object" || Array.isArray(entry)) return;
9540
9573
  const { name, path, content } = entry;
@@ -9543,7 +9576,7 @@ function verifiedSkillLoaderRecord(entry, workingDir) {
9543
9576
  if (!local || local.name !== name) return;
9544
9577
  try {
9545
9578
  const body = readFileSync(local.path, "utf8").replace(/^---\r?\n[\s\S]*?\r?\n---\r?\n/, "").replace(/\r\n/g, "\n").trim();
9546
- if (!body || body !== content.replace(/\r\n/g, "\n").trim()) return;
9579
+ if (!body || !matchesLoadedBody(body, content.replace(/\r\n/g, "\n").trim())) return;
9547
9580
  return {
9548
9581
  ...local,
9549
9582
  source: "sdk-skill-loader"