@riddledc/riddle-proof 0.8.83 → 0.8.85
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 +247 -29
- package/capabilities.json +17 -0
- package/dist/advanced/engine-harness.js +2 -2
- package/dist/advanced/index.d.cts +1 -1
- package/dist/advanced/index.d.ts +1 -1
- package/dist/advanced/index.js +4 -4
- package/dist/advanced/proof-run-engine.d.cts +1 -1
- package/dist/advanced/proof-run-engine.d.ts +1 -1
- package/dist/advanced/runner.js +2 -2
- package/dist/change-proof.cjs +22 -260
- package/dist/change-proof.d.cts +1 -1
- package/dist/change-proof.d.ts +1 -1
- package/dist/change-proof.js +2 -2
- package/dist/checked-meaning.cjs +67 -0
- package/dist/checked-meaning.d.cts +2 -0
- package/dist/checked-meaning.d.ts +2 -0
- package/dist/checked-meaning.js +41 -0
- package/dist/{chunk-QYZ3GKCP.js → chunk-AFARUBE4.js} +12 -11
- package/dist/chunk-J2SIQGQI.js +71 -0
- package/dist/{chunk-7OAETQU3.js → chunk-JZKLCY5G.js} +1 -1
- package/dist/chunk-KB7FYRBG.js +46 -0
- package/dist/chunk-NWLKJ2WI.js +31 -0
- package/dist/{chunk-LR4UYJDY.js → chunk-O2AO726C.js} +1 -1
- package/dist/chunk-ODLGSEP2.js +43 -0
- package/dist/chunk-OHDNCXRM.js +17 -0
- package/dist/cli/index.js +7 -7
- package/dist/cli.cjs +265 -1122
- package/dist/cli.d.cts +0 -1
- package/dist/cli.d.ts +0 -1
- package/dist/cli.js +7 -7
- package/dist/engine-harness.js +2 -2
- package/dist/grounded-evidence.cjs +95 -0
- package/dist/grounded-evidence.d.cts +2 -0
- package/dist/grounded-evidence.d.ts +2 -0
- package/dist/grounded-evidence.js +69 -0
- package/dist/index.cjs +318 -1539
- package/dist/index.d.cts +9 -3
- package/dist/index.d.ts +9 -3
- package/dist/index.js +136 -16
- package/dist/pr-comment.cjs +17 -107
- package/dist/pr-comment.d.cts +1 -1
- package/dist/pr-comment.d.ts +1 -1
- package/dist/pr-comment.js +3 -3
- package/dist/{proof-run-engine-MiKZt9oY.d.ts → proof-run-engine-BqRoA3Do.d.ts} +3 -3
- package/dist/{proof-run-engine-Baiv6l3A.d.cts → proof-run-engine-DpChFR5H.d.cts} +3 -3
- package/dist/proof-run-engine.d.cts +1 -1
- package/dist/proof-run-engine.d.ts +1 -1
- package/dist/receipts.cjs +10 -255
- package/dist/receipts.d.cts +7 -115
- package/dist/receipts.d.ts +7 -115
- package/dist/receipts.js +1 -1
- package/dist/riddle-client.cjs +23 -695
- package/dist/riddle-client.d.cts +1 -188
- package/dist/riddle-client.d.ts +1 -188
- package/dist/riddle-client.js +5 -2
- package/dist/runner.js +2 -2
- package/dist/runtime/index.cjs +23 -695
- package/dist/runtime/index.d.cts +1 -5
- package/dist/runtime/index.d.ts +1 -5
- package/dist/runtime/index.js +5 -2
- package/dist/runtime/riddle-client.cjs +23 -695
- package/dist/runtime/riddle-client.d.cts +1 -5
- package/dist/runtime/riddle-client.d.ts +1 -5
- package/dist/runtime/riddle-client.js +5 -2
- package/dist/semantic-certificate.cjs +23 -582
- package/dist/semantic-certificate.d.cts +2 -191
- package/dist/semantic-certificate.d.ts +2 -191
- package/dist/semantic-certificate.js +15 -3
- package/package.json +28 -5
- package/runtime/lib/riddle_core_call.mjs +3 -806
- package/dist/chunk-5IFZSUPF.js +0 -644
- package/dist/chunk-DB5ZHRUP.js +0 -585
- package/dist/chunk-MEVVL4TI.js +0 -258
- package/dist/{chunk-WLUMLHII.js → chunk-BID7CKMM.js} +9 -9
- package/dist/{chunk-YH7ADFY4.js → chunk-IVSP24XI.js} +3 -3
package/dist/cli.cjs
CHANGED
|
@@ -21,6 +21,7 @@ var __copyProps = (to, from, except, desc) => {
|
|
|
21
21
|
}
|
|
22
22
|
return to;
|
|
23
23
|
};
|
|
24
|
+
var __reExport = (target, mod, secondTarget) => (__copyProps(target, mod, "default"), secondTarget && __copyProps(secondTarget, mod, "default"));
|
|
24
25
|
var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__getProtoOf(mod)) : {}, __copyProps(
|
|
25
26
|
// If the importer is in node compatibility mode or this is not an ESM
|
|
26
27
|
// file that has been converted to a CommonJS file using a Babel-
|
|
@@ -3405,9 +3406,9 @@ var init_proof_run_engine = __esm({
|
|
|
3405
3406
|
});
|
|
3406
3407
|
|
|
3407
3408
|
// src/cli.ts
|
|
3408
|
-
var
|
|
3409
|
-
var
|
|
3410
|
-
var
|
|
3409
|
+
var import_node_child_process4 = require("child_process");
|
|
3410
|
+
var import_node_fs5 = require("fs");
|
|
3411
|
+
var import_node_path5 = __toESM(require("path"), 1);
|
|
3411
3412
|
|
|
3412
3413
|
// src/engine-harness.ts
|
|
3413
3414
|
var import_node_child_process2 = require("child_process");
|
|
@@ -7875,877 +7876,7 @@ async function runCodexExecAgentDoctor(config = {}, runner = createCodexExecJson
|
|
|
7875
7876
|
}
|
|
7876
7877
|
|
|
7877
7878
|
// src/riddle-client.ts
|
|
7878
|
-
var
|
|
7879
|
-
var import_node_fs5 = require("fs");
|
|
7880
|
-
var import_node_os2 = require("os");
|
|
7881
|
-
var import_node_path5 = __toESM(require("path"), 1);
|
|
7882
|
-
|
|
7883
|
-
// src/receipts.ts
|
|
7884
|
-
var RIDDLE_PREVIEW_RECEIPT_VERSION = "riddle.preview-receipt.v1";
|
|
7885
|
-
var RIDDLE_PROOF_OBSERVATION_RECEIPT_VERSION = "riddle-proof.observation-receipt.v1";
|
|
7886
|
-
function isRecord(value) {
|
|
7887
|
-
return Boolean(value) && typeof value === "object" && !Array.isArray(value);
|
|
7888
|
-
}
|
|
7889
|
-
function requiredString(record, key, context) {
|
|
7890
|
-
const value = record[key];
|
|
7891
|
-
if (typeof value !== "string" || !value.trim()) {
|
|
7892
|
-
throw new Error(`${context}.${key} must be a non-empty string.`);
|
|
7893
|
-
}
|
|
7894
|
-
return value.trim();
|
|
7895
|
-
}
|
|
7896
|
-
function normalizedSourceIdentity(value) {
|
|
7897
|
-
if (!isRecord(value)) return {};
|
|
7898
|
-
return {
|
|
7899
|
-
git_revision: typeof value.git_revision === "string" && value.git_revision.trim() ? value.git_revision.trim() : void 0,
|
|
7900
|
-
repository: typeof value.repository === "string" && value.repository.trim() ? value.repository.trim() : void 0,
|
|
7901
|
-
dirty: typeof value.dirty === "boolean" ? value.dirty : void 0,
|
|
7902
|
-
label: typeof value.label === "string" && value.label.trim() ? value.label.trim() : void 0
|
|
7903
|
-
};
|
|
7904
|
-
}
|
|
7905
|
-
function parseRiddlePreviewReceipt(value) {
|
|
7906
|
-
if (!isRecord(value)) throw new Error("Preview receipt must be an object.");
|
|
7907
|
-
if (value.version !== RIDDLE_PREVIEW_RECEIPT_VERSION) {
|
|
7908
|
-
throw new Error(`Unsupported Preview receipt version ${String(value.version || "missing")}.`);
|
|
7909
|
-
}
|
|
7910
|
-
if (!isRecord(value.source)) throw new Error("Preview receipt source must be an object.");
|
|
7911
|
-
const expiresAt = requiredString(value, "expires_at", "preview receipt");
|
|
7912
|
-
const publishedAt = requiredString(value, "published_at", "preview receipt");
|
|
7913
|
-
const contentDigest = requiredString(value, "content_digest", "preview receipt");
|
|
7914
|
-
if (!contentDigest.startsWith("sha256:") || contentDigest.length <= "sha256:".length) {
|
|
7915
|
-
throw new Error("preview receipt.content_digest must be a sha256 digest.");
|
|
7916
|
-
}
|
|
7917
|
-
if (!Number.isFinite(Date.parse(expiresAt)) || !Number.isFinite(Date.parse(publishedAt))) {
|
|
7918
|
-
throw new Error("Preview receipt timestamps must be valid ISO date strings.");
|
|
7919
|
-
}
|
|
7920
|
-
return {
|
|
7921
|
-
version: RIDDLE_PREVIEW_RECEIPT_VERSION,
|
|
7922
|
-
preview_id: requiredString(value, "preview_id", "preview receipt"),
|
|
7923
|
-
url: requiredString(value, "url", "preview receipt"),
|
|
7924
|
-
expires_at: expiresAt,
|
|
7925
|
-
content_digest: contentDigest,
|
|
7926
|
-
source: normalizedSourceIdentity(value.source),
|
|
7927
|
-
published_at: publishedAt
|
|
7928
|
-
};
|
|
7929
|
-
}
|
|
7930
|
-
function comparableArtifactName(value) {
|
|
7931
|
-
return (value || "").split(/[/?#]/).pop()?.toLowerCase().replace(/\.(png|jpe?g|gif|webp|avif|svg)$/u, "").replace(/[^a-z0-9_-]+/gu, "-").replace(/^-+|-+$/g, "") || "";
|
|
7932
|
-
}
|
|
7933
|
-
function artifactMatchesLabel(artifact, label) {
|
|
7934
|
-
const expected = comparableArtifactName(label);
|
|
7935
|
-
if (!expected) return false;
|
|
7936
|
-
return [artifact.name, artifact.url, artifact.path].map(comparableArtifactName).some((name) => name === expected || name.endsWith(`-${expected}`));
|
|
7937
|
-
}
|
|
7938
|
-
function artifactLooksLikeScreenshot(ref) {
|
|
7939
|
-
const text = [ref.name, ref.url, ref.path, ref.kind, ref.content_type].filter(Boolean).join(" ").toLowerCase();
|
|
7940
|
-
return /screenshot|\bimage\b/.test(text) || /\.(png|jpe?g|gif|webp|avif|svg)(\?|#|$)/.test(text);
|
|
7941
|
-
}
|
|
7942
|
-
function finalScreenshotLabels(result) {
|
|
7943
|
-
const explicit = result.artifacts.canonical_screenshots || [];
|
|
7944
|
-
if (explicit.length) return explicit;
|
|
7945
|
-
const fromEvidence = (result.evidence?.viewports || []).map((viewport) => viewport.screenshot_label).filter((label) => typeof label === "string" && Boolean(label.trim()));
|
|
7946
|
-
if (fromEvidence.length) return fromEvidence;
|
|
7947
|
-
return (result.artifacts.screenshots || []).slice(0, 1);
|
|
7948
|
-
}
|
|
7949
|
-
function setupScreenshotLabels(result) {
|
|
7950
|
-
const explicit = result.artifacts.setup_screenshots || [];
|
|
7951
|
-
if (explicit.length) return explicit;
|
|
7952
|
-
return (result.evidence?.viewports || []).flatMap(
|
|
7953
|
-
(viewport) => (viewport.setup_action_results || []).filter((action) => action.action === "screenshot" && action.ok !== false && typeof action.screenshot_label === "string").map((action) => String(action.screenshot_label))
|
|
7954
|
-
);
|
|
7955
|
-
}
|
|
7956
|
-
function observationArtifactFromRef(ref, canonicalLabels, setupLabels) {
|
|
7957
|
-
const base = {
|
|
7958
|
-
name: ref.name,
|
|
7959
|
-
role: ref.role || "artifact",
|
|
7960
|
-
url: ref.url,
|
|
7961
|
-
path: ref.path,
|
|
7962
|
-
kind: ref.kind,
|
|
7963
|
-
content_type: ref.content_type,
|
|
7964
|
-
source: ref.source
|
|
7965
|
-
};
|
|
7966
|
-
if (!artifactLooksLikeScreenshot(ref)) return base;
|
|
7967
|
-
if (canonicalLabels.some((label) => artifactMatchesLabel(base, label))) {
|
|
7968
|
-
return { ...base, role: "canonical_screenshot" };
|
|
7969
|
-
}
|
|
7970
|
-
if (setupLabels.some((label) => artifactMatchesLabel(base, label))) {
|
|
7971
|
-
return { ...base, role: "setup_screenshot" };
|
|
7972
|
-
}
|
|
7973
|
-
return { ...base, role: "diagnostic" };
|
|
7974
|
-
}
|
|
7975
|
-
function profileObservationArtifacts(result) {
|
|
7976
|
-
const canonicalLabels = finalScreenshotLabels(result);
|
|
7977
|
-
const setupLabels = setupScreenshotLabels(result);
|
|
7978
|
-
const artifacts = [];
|
|
7979
|
-
const seen = /* @__PURE__ */ new Set();
|
|
7980
|
-
const add = (artifact) => {
|
|
7981
|
-
const key = artifact.url || artifact.path || `${artifact.role}:${artifact.name}`;
|
|
7982
|
-
if (!artifact.name || seen.has(key)) return;
|
|
7983
|
-
seen.add(key);
|
|
7984
|
-
artifacts.push(artifact);
|
|
7985
|
-
};
|
|
7986
|
-
for (const ref of result.artifacts.riddle_artifacts || []) {
|
|
7987
|
-
add(observationArtifactFromRef(ref, canonicalLabels, setupLabels));
|
|
7988
|
-
}
|
|
7989
|
-
for (const label of canonicalLabels) {
|
|
7990
|
-
if (!artifacts.some((artifact) => artifactMatchesLabel(artifact, label))) {
|
|
7991
|
-
add({ name: label, path: label, role: "canonical_screenshot", kind: "image" });
|
|
7992
|
-
}
|
|
7993
|
-
}
|
|
7994
|
-
for (const label of setupLabels) {
|
|
7995
|
-
if (!artifacts.some((artifact) => artifactMatchesLabel(artifact, label))) {
|
|
7996
|
-
add({ name: label, path: label, role: "setup_screenshot", kind: "image" });
|
|
7997
|
-
}
|
|
7998
|
-
}
|
|
7999
|
-
for (const label of result.artifacts.screenshots || []) {
|
|
8000
|
-
if (!artifacts.some((artifact) => artifactMatchesLabel(artifact, label))) {
|
|
8001
|
-
add({ name: label, path: label, role: "diagnostic", kind: "image" });
|
|
8002
|
-
}
|
|
8003
|
-
}
|
|
8004
|
-
return artifacts;
|
|
8005
|
-
}
|
|
8006
|
-
function mergeObservationArtifacts(profileArtifacts, suppliedArtifacts) {
|
|
8007
|
-
const artifacts = [...profileArtifacts];
|
|
8008
|
-
for (const supplied of suppliedArtifacts) {
|
|
8009
|
-
const suppliedNames = [supplied.name, supplied.url, supplied.path].map(comparableArtifactName).filter(Boolean);
|
|
8010
|
-
const existingIndex = artifacts.findIndex((artifact) => {
|
|
8011
|
-
if (supplied.url && artifact.url === supplied.url) return true;
|
|
8012
|
-
if (supplied.path && artifact.path === supplied.path) return true;
|
|
8013
|
-
return [artifact.name, artifact.url, artifact.path].map(comparableArtifactName).some((name) => name && suppliedNames.includes(name));
|
|
8014
|
-
});
|
|
8015
|
-
if (existingIndex < 0) {
|
|
8016
|
-
artifacts.push(supplied);
|
|
8017
|
-
continue;
|
|
8018
|
-
}
|
|
8019
|
-
const existing = artifacts[existingIndex];
|
|
8020
|
-
const role = supplied.role === "canonical_screenshot" || supplied.role === "setup_screenshot" ? supplied.role : existing.role === "canonical_screenshot" || existing.role === "setup_screenshot" ? existing.role : supplied.role === "artifact" ? existing.role : supplied.role;
|
|
8021
|
-
artifacts[existingIndex] = {
|
|
8022
|
-
...existing,
|
|
8023
|
-
...supplied,
|
|
8024
|
-
role
|
|
8025
|
-
};
|
|
8026
|
-
}
|
|
8027
|
-
return artifacts;
|
|
8028
|
-
}
|
|
8029
|
-
function defaultObservationId(role, capturedAt) {
|
|
8030
|
-
return `obs_${role}_${capturedAt.replace(/[^0-9]/g, "").slice(0, 17) || "unknown"}`;
|
|
8031
|
-
}
|
|
8032
|
-
function profileCheckCounts(result) {
|
|
8033
|
-
const counts = { total: result.checks.length, passed: 0, failed: 0, skipped: 0, needs_human_review: 0 };
|
|
8034
|
-
for (const check of result.checks) {
|
|
8035
|
-
if (check.status === "passed") counts.passed += 1;
|
|
8036
|
-
if (check.status === "failed") counts.failed += 1;
|
|
8037
|
-
if (check.status === "skipped") counts.skipped += 1;
|
|
8038
|
-
if (check.status === "needs_human_review") counts.needs_human_review += 1;
|
|
8039
|
-
}
|
|
8040
|
-
return counts;
|
|
8041
|
-
}
|
|
8042
|
-
function createRiddleProofObservationReceipt(input) {
|
|
8043
|
-
const capturedAt = input.captured_at || input.profile_result?.captured_at || (/* @__PURE__ */ new Date()).toISOString();
|
|
8044
|
-
const profileArtifacts = input.profile_result ? profileObservationArtifacts(input.profile_result) : [];
|
|
8045
|
-
const requestedCanonical = input.canonical_screenshot ? { ...input.canonical_screenshot, role: "canonical_screenshot" } : void 0;
|
|
8046
|
-
const artifacts = mergeObservationArtifacts(
|
|
8047
|
-
profileArtifacts,
|
|
8048
|
-
[...input.artifacts || [], ...requestedCanonical ? [requestedCanonical] : []]
|
|
8049
|
-
);
|
|
8050
|
-
const canonicalScreenshot = requestedCanonical ? artifacts.find((artifact) => artifact.role === "canonical_screenshot" && artifactMatchesLabel(artifact, requestedCanonical.name)) || requestedCanonical : artifacts.find((artifact) => artifact.role === "canonical_screenshot");
|
|
8051
|
-
const target = input.target.kind === "preview" && input.target.preview ? { ...input.target, preview: parseRiddlePreviewReceipt(input.target.preview) } : input.target;
|
|
8052
|
-
return {
|
|
8053
|
-
version: RIDDLE_PROOF_OBSERVATION_RECEIPT_VERSION,
|
|
8054
|
-
observation_id: input.observation_id || defaultObservationId(input.comparison_role, capturedAt),
|
|
8055
|
-
comparison_role: input.comparison_role,
|
|
8056
|
-
executor: input.executor,
|
|
8057
|
-
target,
|
|
8058
|
-
source: normalizedSourceIdentity(input.source || input.target.preview?.source),
|
|
8059
|
-
captured_at: capturedAt,
|
|
8060
|
-
artifacts,
|
|
8061
|
-
canonical_screenshot: canonicalScreenshot,
|
|
8062
|
-
profile_summary: input.profile_result ? {
|
|
8063
|
-
profile_name: input.profile_result.profile_name,
|
|
8064
|
-
status: input.profile_result.status,
|
|
8065
|
-
summary: input.profile_result.summary,
|
|
8066
|
-
route: input.profile_result.route,
|
|
8067
|
-
checks: profileCheckCounts(input.profile_result)
|
|
8068
|
-
} : void 0,
|
|
8069
|
-
proof: input.profile_result ? {
|
|
8070
|
-
profile_name: input.profile_result.profile_name,
|
|
8071
|
-
result: input.profile_result
|
|
8072
|
-
} : void 0,
|
|
8073
|
-
publication: input.publication,
|
|
8074
|
-
execution: input.execution,
|
|
8075
|
-
metadata: input.metadata
|
|
8076
|
-
};
|
|
8077
|
-
}
|
|
8078
|
-
function parseRiddleProofObservationReceipt(value) {
|
|
8079
|
-
if (!isRecord(value)) throw new Error("Observation receipt must be an object.");
|
|
8080
|
-
if (value.version !== RIDDLE_PROOF_OBSERVATION_RECEIPT_VERSION) {
|
|
8081
|
-
throw new Error(`Unsupported Observation receipt version ${String(value.version || "missing")}.`);
|
|
8082
|
-
}
|
|
8083
|
-
if (!isRecord(value.executor)) throw new Error("Observation receipt executor must be an object.");
|
|
8084
|
-
if (!isRecord(value.target)) throw new Error("Observation receipt target must be an object.");
|
|
8085
|
-
if (!isRecord(value.source)) throw new Error("Observation receipt source must be an object.");
|
|
8086
|
-
requiredString(value, "observation_id", "observation receipt");
|
|
8087
|
-
requiredString(value, "captured_at", "observation receipt");
|
|
8088
|
-
const executorKind = requiredString(value.executor, "kind", "observation receipt executor");
|
|
8089
|
-
if (!"local_playwright,riddle_hosted,browser_api,other".split(",").includes(executorKind)) {
|
|
8090
|
-
throw new Error(`Unsupported observation executor kind ${executorKind}.`);
|
|
8091
|
-
}
|
|
8092
|
-
if (value.executor.runner !== void 0) {
|
|
8093
|
-
requiredString(value.executor, "runner", "observation receipt executor");
|
|
8094
|
-
}
|
|
8095
|
-
const role = requiredString(value, "comparison_role", "observation receipt");
|
|
8096
|
-
if (!["before", "after", "standalone"].includes(role)) {
|
|
8097
|
-
throw new Error(`Unsupported observation comparison role ${role}.`);
|
|
8098
|
-
}
|
|
8099
|
-
const targetKind = requiredString(value.target, "kind", "observation receipt target");
|
|
8100
|
-
if (targetKind !== "url" && targetKind !== "preview") {
|
|
8101
|
-
throw new Error(`Unsupported observation target kind ${targetKind}.`);
|
|
8102
|
-
}
|
|
8103
|
-
requiredString(value.target, "url", "observation receipt target");
|
|
8104
|
-
if (targetKind === "preview") {
|
|
8105
|
-
if (value.target.preview === void 0) {
|
|
8106
|
-
throw new Error("Preview Observation target must include its Preview receipt.");
|
|
8107
|
-
}
|
|
8108
|
-
parseRiddlePreviewReceipt(value.target.preview);
|
|
8109
|
-
}
|
|
8110
|
-
if (!Array.isArray(value.artifacts)) throw new Error("Observation receipt artifacts must be an array.");
|
|
8111
|
-
const artifactRoles = /* @__PURE__ */ new Set(["canonical_screenshot", "setup_screenshot", "data", "diagnostic", "artifact"]);
|
|
8112
|
-
const artifacts = value.artifacts.map((artifact, index) => {
|
|
8113
|
-
if (!isRecord(artifact)) throw new Error(`Observation receipt artifact ${index} must be an object.`);
|
|
8114
|
-
requiredString(artifact, "name", `observation receipt artifact ${index}`);
|
|
8115
|
-
const artifactRole = requiredString(artifact, "role", `observation receipt artifact ${index}`);
|
|
8116
|
-
if (!artifactRoles.has(artifactRole)) {
|
|
8117
|
-
throw new Error(`Unsupported observation artifact role ${artifactRole}.`);
|
|
8118
|
-
}
|
|
8119
|
-
return artifact;
|
|
8120
|
-
});
|
|
8121
|
-
if (value.canonical_screenshot !== void 0) {
|
|
8122
|
-
if (!isRecord(value.canonical_screenshot) || value.canonical_screenshot.role !== "canonical_screenshot") {
|
|
8123
|
-
throw new Error("Observation canonical_screenshot must have the canonical_screenshot role.");
|
|
8124
|
-
}
|
|
8125
|
-
const canonical = value.canonical_screenshot;
|
|
8126
|
-
const included = artifacts.some((artifact) => artifact.role === "canonical_screenshot" && artifact.name === canonical.name && artifact.url === canonical.url && artifact.path === canonical.path);
|
|
8127
|
-
if (!included) {
|
|
8128
|
-
throw new Error("Observation canonical_screenshot must reference an artifact in the receipt.");
|
|
8129
|
-
}
|
|
8130
|
-
}
|
|
8131
|
-
return value;
|
|
8132
|
-
}
|
|
8133
|
-
|
|
8134
|
-
// src/riddle-client.ts
|
|
8135
|
-
var DEFAULT_RIDDLE_API_BASE_URL = "https://api.riddledc.com";
|
|
8136
|
-
var DEFAULT_RIDDLE_API_KEY_FILE = "/tmp/riddle-api-key";
|
|
8137
|
-
var RIDDLE_UNSUBMITTED_WAKE_HINT = "hosted worker may still be waking or waiting for a lease";
|
|
8138
|
-
var RiddleApiError = class extends Error {
|
|
8139
|
-
constructor(pathname, status, body) {
|
|
8140
|
-
super(`Riddle API ${pathname} failed HTTP ${status}: ${body}`);
|
|
8141
|
-
this.name = "RiddleApiError";
|
|
8142
|
-
this.status = status;
|
|
8143
|
-
this.body = body;
|
|
8144
|
-
this.path = pathname;
|
|
8145
|
-
}
|
|
8146
|
-
};
|
|
8147
|
-
var PREVIEW_PUBLISH_RECOVERY_STATUSES = /* @__PURE__ */ new Set([408, 429, 500, 502, 503, 504]);
|
|
8148
|
-
var PREVIEW_PUBLISH_RECOVERY_ATTEMPTS = 30;
|
|
8149
|
-
var PREVIEW_PUBLISH_RECOVERY_INTERVAL_MS = 2e3;
|
|
8150
|
-
function normalizeBaseUrl(value) {
|
|
8151
|
-
return (value || DEFAULT_RIDDLE_API_BASE_URL).replace(/\/$/, "");
|
|
8152
|
-
}
|
|
8153
|
-
function fetchFor(config = {}) {
|
|
8154
|
-
return config.fetchImpl || fetch;
|
|
8155
|
-
}
|
|
8156
|
-
function resolveRiddleApiKeyWithSource(config = {}) {
|
|
8157
|
-
if (config.apiKey?.trim()) return { apiKey: config.apiKey.trim(), source: "option" };
|
|
8158
|
-
if (process.env.RIDDLE_API_KEY?.trim()) return { apiKey: process.env.RIDDLE_API_KEY.trim(), source: "env" };
|
|
8159
|
-
const keyFile = config.apiKeyFile || process.env.RIDDLE_API_KEY_FILE || DEFAULT_RIDDLE_API_KEY_FILE;
|
|
8160
|
-
if ((0, import_node_fs5.existsSync)(keyFile)) {
|
|
8161
|
-
const key = (0, import_node_fs5.readFileSync)(keyFile, "utf8").trim();
|
|
8162
|
-
if (key) return { apiKey: key, source: "file", file: keyFile };
|
|
8163
|
-
}
|
|
8164
|
-
throw new Error(`Riddle API key missing. Set RIDDLE_API_KEY or write ${DEFAULT_RIDDLE_API_KEY_FILE}.`);
|
|
8165
|
-
}
|
|
8166
|
-
function resolveRiddleApiKeySource(config = {}) {
|
|
8167
|
-
const { apiKey: _apiKey, ...source } = resolveRiddleApiKeyWithSource(config);
|
|
8168
|
-
return source;
|
|
8169
|
-
}
|
|
8170
|
-
function resolveRiddleApiKey(config = {}) {
|
|
8171
|
-
return resolveRiddleApiKeyWithSource(config).apiKey;
|
|
8172
|
-
}
|
|
8173
|
-
async function riddleRequestJson(config, pathname, init = {}) {
|
|
8174
|
-
const response = await fetchFor(config)(`${normalizeBaseUrl(config.apiBaseUrl)}${pathname}`, {
|
|
8175
|
-
...init,
|
|
8176
|
-
headers: {
|
|
8177
|
-
Authorization: `Bearer ${resolveRiddleApiKey(config)}`,
|
|
8178
|
-
"Content-Type": "application/json",
|
|
8179
|
-
...init.headers || {}
|
|
8180
|
-
}
|
|
8181
|
-
});
|
|
8182
|
-
const text = await response.text();
|
|
8183
|
-
let json = null;
|
|
8184
|
-
try {
|
|
8185
|
-
json = JSON.parse(text);
|
|
8186
|
-
} catch {
|
|
8187
|
-
}
|
|
8188
|
-
if (!response.ok) throw new RiddleApiError(pathname, response.status, text);
|
|
8189
|
-
return json ?? text;
|
|
8190
|
-
}
|
|
8191
|
-
async function getRiddleBalance(config = {}) {
|
|
8192
|
-
return riddleRequestJson(config, "/v1/balance", { method: "GET" });
|
|
8193
|
-
}
|
|
8194
|
-
function previewDeployResultFromRecord(input) {
|
|
8195
|
-
const { record, id, label, framework, expiresAt, publishRecovered, publishError } = input;
|
|
8196
|
-
const receipt = record.receipt && typeof record.receipt === "object" ? parseRiddlePreviewReceipt(record.receipt) : void 0;
|
|
8197
|
-
return {
|
|
8198
|
-
ok: true,
|
|
8199
|
-
id: String(record.id || record.preview_id || id),
|
|
8200
|
-
label,
|
|
8201
|
-
framework,
|
|
8202
|
-
preview_url: String(record.preview_url || ""),
|
|
8203
|
-
file_count: typeof record.file_count === "number" ? record.file_count : void 0,
|
|
8204
|
-
total_bytes: typeof record.total_bytes === "number" ? record.total_bytes : void 0,
|
|
8205
|
-
expires_at: receipt?.expires_at || expiresAt,
|
|
8206
|
-
receipt,
|
|
8207
|
-
publish_recovered: publishRecovered || void 0,
|
|
8208
|
-
publish_error: publishError,
|
|
8209
|
-
warnings: input.warnings?.length ? input.warnings : void 0,
|
|
8210
|
-
raw: record
|
|
8211
|
-
};
|
|
8212
|
-
}
|
|
8213
|
-
function gitOutput(directory, args) {
|
|
8214
|
-
try {
|
|
8215
|
-
return (0, import_node_child_process4.execFileSync)("git", ["-C", directory, ...args], { encoding: "utf8", stdio: ["ignore", "pipe", "ignore"] }).trim();
|
|
8216
|
-
} catch {
|
|
8217
|
-
return "";
|
|
8218
|
-
}
|
|
8219
|
-
}
|
|
8220
|
-
function detectRiddlePreviewSource(directory) {
|
|
8221
|
-
const gitRevision = gitOutput(directory, ["rev-parse", "HEAD"]);
|
|
8222
|
-
if (!gitRevision) return {};
|
|
8223
|
-
const repository = gitOutput(directory, ["config", "--get", "remote.origin.url"]);
|
|
8224
|
-
const status = gitOutput(directory, ["status", "--porcelain", "--untracked-files=normal"]);
|
|
8225
|
-
return {
|
|
8226
|
-
git_revision: gitRevision,
|
|
8227
|
-
repository: repository || void 0,
|
|
8228
|
-
dirty: Boolean(status)
|
|
8229
|
-
};
|
|
8230
|
-
}
|
|
8231
|
-
function canRecoverPreviewPublish(error) {
|
|
8232
|
-
return error instanceof RiddleApiError && PREVIEW_PUBLISH_RECOVERY_STATUSES.has(error.status);
|
|
8233
|
-
}
|
|
8234
|
-
function summarizePreviewDirectory(directory) {
|
|
8235
|
-
const stack = [directory];
|
|
8236
|
-
let fileCount = 0;
|
|
8237
|
-
let totalBytes = 0;
|
|
8238
|
-
while (stack.length) {
|
|
8239
|
-
const current = stack.pop();
|
|
8240
|
-
for (const entry of (0, import_node_fs5.readdirSync)(current, { withFileTypes: true })) {
|
|
8241
|
-
const fullPath = import_node_path5.default.join(current, entry.name);
|
|
8242
|
-
if (entry.isDirectory()) {
|
|
8243
|
-
stack.push(fullPath);
|
|
8244
|
-
continue;
|
|
8245
|
-
}
|
|
8246
|
-
if (!entry.isFile()) continue;
|
|
8247
|
-
const stat = (0, import_node_fs5.statSync)(fullPath);
|
|
8248
|
-
fileCount += 1;
|
|
8249
|
-
totalBytes += stat.size;
|
|
8250
|
-
}
|
|
8251
|
-
}
|
|
8252
|
-
return { file_count: fileCount, total_bytes: totalBytes };
|
|
8253
|
-
}
|
|
8254
|
-
function previewProgressEmitter(config, base) {
|
|
8255
|
-
return async (snapshot) => {
|
|
8256
|
-
if (!config.onPreviewProgress) return;
|
|
8257
|
-
await config.onPreviewProgress({
|
|
8258
|
-
label: base.label,
|
|
8259
|
-
framework: base.framework,
|
|
8260
|
-
directory: base.directory,
|
|
8261
|
-
elapsed_ms: Math.max(0, Date.now() - base.startedAt),
|
|
8262
|
-
warnings: base.warnings?.length ? base.warnings : void 0,
|
|
8263
|
-
...snapshot
|
|
8264
|
-
});
|
|
8265
|
-
};
|
|
8266
|
-
}
|
|
8267
|
-
async function waitForPublishedPreview(config, input) {
|
|
8268
|
-
await input.emitProgress?.({
|
|
8269
|
-
stage: "publish_recovering",
|
|
8270
|
-
id: input.id,
|
|
8271
|
-
file_count: input.localSummary?.file_count,
|
|
8272
|
-
total_bytes: input.localSummary?.total_bytes,
|
|
8273
|
-
publish_error: input.publishError.message,
|
|
8274
|
-
message: `publish returned ${input.publishError.status}; polling preview status`
|
|
8275
|
-
});
|
|
8276
|
-
for (let attempt = 1; attempt <= PREVIEW_PUBLISH_RECOVERY_ATTEMPTS; attempt += 1) {
|
|
8277
|
-
const status = await riddleRequestJson(config, `/v1/preview/${input.id}`);
|
|
8278
|
-
await input.emitProgress?.({
|
|
8279
|
-
stage: "checking_status",
|
|
8280
|
-
id: input.id,
|
|
8281
|
-
attempt,
|
|
8282
|
-
attempts: PREVIEW_PUBLISH_RECOVERY_ATTEMPTS,
|
|
8283
|
-
status: typeof status.status === "string" ? status.status : null,
|
|
8284
|
-
preview_url: typeof status.preview_url === "string" ? status.preview_url : void 0,
|
|
8285
|
-
file_count: typeof status.file_count === "number" ? status.file_count : input.localSummary?.file_count,
|
|
8286
|
-
total_bytes: typeof status.total_bytes === "number" ? status.total_bytes : input.localSummary?.total_bytes
|
|
8287
|
-
});
|
|
8288
|
-
if (String(status.status || "") === "ready" && String(status.preview_url || "").trim()) {
|
|
8289
|
-
await input.emitProgress?.({
|
|
8290
|
-
stage: "ready",
|
|
8291
|
-
id: input.id,
|
|
8292
|
-
preview_url: String(status.preview_url),
|
|
8293
|
-
file_count: typeof status.file_count === "number" ? status.file_count : input.localSummary?.file_count,
|
|
8294
|
-
total_bytes: typeof status.total_bytes === "number" ? status.total_bytes : input.localSummary?.total_bytes
|
|
8295
|
-
});
|
|
8296
|
-
return previewDeployResultFromRecord({
|
|
8297
|
-
record: status,
|
|
8298
|
-
id: input.id,
|
|
8299
|
-
label: input.label,
|
|
8300
|
-
framework: input.framework,
|
|
8301
|
-
expiresAt: input.expiresAt,
|
|
8302
|
-
publishRecovered: true,
|
|
8303
|
-
publishError: input.publishError.message,
|
|
8304
|
-
warnings: input.warnings
|
|
8305
|
-
});
|
|
8306
|
-
}
|
|
8307
|
-
if (attempt < PREVIEW_PUBLISH_RECOVERY_ATTEMPTS) {
|
|
8308
|
-
await new Promise((resolve) => setTimeout(resolve, PREVIEW_PUBLISH_RECOVERY_INTERVAL_MS));
|
|
8309
|
-
}
|
|
8310
|
-
}
|
|
8311
|
-
throw input.publishError;
|
|
8312
|
-
}
|
|
8313
|
-
async function deployRiddlePreview(config, directory, label, framework = "static", options = {}) {
|
|
8314
|
-
if (!directory?.trim()) throw new Error("directory is required");
|
|
8315
|
-
if (!label?.trim()) throw new Error("label is required");
|
|
8316
|
-
if (framework !== "spa" && framework !== "static") throw new Error("framework must be spa or static");
|
|
8317
|
-
const startedAt = Date.now();
|
|
8318
|
-
const warnings = collectRiddlePreviewDeployWarnings(directory, framework);
|
|
8319
|
-
const source = options.source || detectRiddlePreviewSource(directory);
|
|
8320
|
-
const emitProgress = previewProgressEmitter(config, { label, framework, directory, startedAt, warnings });
|
|
8321
|
-
await emitProgress({ stage: "validating", message: "checking preview input directory" });
|
|
8322
|
-
const localSummary = summarizePreviewDirectory(directory);
|
|
8323
|
-
await emitProgress({
|
|
8324
|
-
stage: "creating",
|
|
8325
|
-
file_count: localSummary.file_count,
|
|
8326
|
-
total_bytes: localSummary.total_bytes,
|
|
8327
|
-
message: "creating preview upload target"
|
|
8328
|
-
});
|
|
8329
|
-
const created = await riddleRequestJson(config, "/v1/preview", {
|
|
8330
|
-
method: "POST",
|
|
8331
|
-
body: JSON.stringify({ framework, label, source })
|
|
8332
|
-
});
|
|
8333
|
-
const id = String(created.id || "");
|
|
8334
|
-
const uploadUrl = String(created.upload_url || "");
|
|
8335
|
-
if (!id || !uploadUrl) throw new Error("Riddle preview create response was missing id or upload_url.");
|
|
8336
|
-
await emitProgress({
|
|
8337
|
-
stage: "created",
|
|
8338
|
-
id,
|
|
8339
|
-
file_count: localSummary.file_count,
|
|
8340
|
-
total_bytes: localSummary.total_bytes,
|
|
8341
|
-
message: "preview upload target created"
|
|
8342
|
-
});
|
|
8343
|
-
const scratch = (0, import_node_fs5.mkdtempSync)(import_node_path5.default.join((0, import_node_os2.tmpdir)(), "riddle-preview-upload-"));
|
|
8344
|
-
const tarball = import_node_path5.default.join(scratch, `${id}.tar.gz`);
|
|
8345
|
-
let tarballBytes = 0;
|
|
8346
|
-
try {
|
|
8347
|
-
await emitProgress({
|
|
8348
|
-
stage: "archiving",
|
|
8349
|
-
id,
|
|
8350
|
-
file_count: localSummary.file_count,
|
|
8351
|
-
total_bytes: localSummary.total_bytes,
|
|
8352
|
-
message: "creating preview archive"
|
|
8353
|
-
});
|
|
8354
|
-
(0, import_node_child_process4.execFileSync)("tar", ["czf", tarball, "-C", directory, "."], { stdio: "pipe" });
|
|
8355
|
-
tarballBytes = (0, import_node_fs5.statSync)(tarball).size;
|
|
8356
|
-
await emitProgress({
|
|
8357
|
-
stage: "archived",
|
|
8358
|
-
id,
|
|
8359
|
-
file_count: localSummary.file_count,
|
|
8360
|
-
total_bytes: localSummary.total_bytes,
|
|
8361
|
-
tarball_bytes: tarballBytes,
|
|
8362
|
-
message: "preview archive created"
|
|
8363
|
-
});
|
|
8364
|
-
await emitProgress({
|
|
8365
|
-
stage: "uploading",
|
|
8366
|
-
id,
|
|
8367
|
-
file_count: localSummary.file_count,
|
|
8368
|
-
total_bytes: localSummary.total_bytes,
|
|
8369
|
-
tarball_bytes: tarballBytes,
|
|
8370
|
-
message: "uploading preview archive"
|
|
8371
|
-
});
|
|
8372
|
-
const upload = await fetchFor(config)(uploadUrl, {
|
|
8373
|
-
method: "PUT",
|
|
8374
|
-
headers: { "Content-Type": "application/gzip" },
|
|
8375
|
-
body: (0, import_node_fs5.readFileSync)(tarball)
|
|
8376
|
-
});
|
|
8377
|
-
if (!upload.ok) {
|
|
8378
|
-
throw new RiddleApiError(uploadUrl, upload.status, await upload.text());
|
|
8379
|
-
}
|
|
8380
|
-
await emitProgress({
|
|
8381
|
-
stage: "uploaded",
|
|
8382
|
-
id,
|
|
8383
|
-
file_count: localSummary.file_count,
|
|
8384
|
-
total_bytes: localSummary.total_bytes,
|
|
8385
|
-
tarball_bytes: tarballBytes,
|
|
8386
|
-
message: "preview archive uploaded"
|
|
8387
|
-
});
|
|
8388
|
-
} finally {
|
|
8389
|
-
(0, import_node_fs5.rmSync)(scratch, { recursive: true, force: true });
|
|
8390
|
-
}
|
|
8391
|
-
const expiresAt = typeof created.expires_at === "string" ? created.expires_at : void 0;
|
|
8392
|
-
try {
|
|
8393
|
-
await emitProgress({
|
|
8394
|
-
stage: "publishing",
|
|
8395
|
-
id,
|
|
8396
|
-
file_count: localSummary.file_count,
|
|
8397
|
-
total_bytes: localSummary.total_bytes,
|
|
8398
|
-
tarball_bytes: tarballBytes || void 0,
|
|
8399
|
-
message: "publishing preview"
|
|
8400
|
-
});
|
|
8401
|
-
const published = await riddleRequestJson(config, `/v1/preview/${id}/publish`, {
|
|
8402
|
-
method: "POST"
|
|
8403
|
-
});
|
|
8404
|
-
await emitProgress({
|
|
8405
|
-
stage: "ready",
|
|
8406
|
-
id,
|
|
8407
|
-
preview_url: String(published.preview_url || ""),
|
|
8408
|
-
file_count: typeof published.file_count === "number" ? published.file_count : localSummary.file_count,
|
|
8409
|
-
total_bytes: typeof published.total_bytes === "number" ? published.total_bytes : localSummary.total_bytes
|
|
8410
|
-
});
|
|
8411
|
-
return previewDeployResultFromRecord({ record: published, id, label, framework, expiresAt, warnings });
|
|
8412
|
-
} catch (error) {
|
|
8413
|
-
if (!canRecoverPreviewPublish(error)) throw error;
|
|
8414
|
-
return waitForPublishedPreview(config, {
|
|
8415
|
-
id,
|
|
8416
|
-
label,
|
|
8417
|
-
framework,
|
|
8418
|
-
expiresAt,
|
|
8419
|
-
publishError: error,
|
|
8420
|
-
warnings,
|
|
8421
|
-
localSummary,
|
|
8422
|
-
emitProgress
|
|
8423
|
-
});
|
|
8424
|
-
}
|
|
8425
|
-
}
|
|
8426
|
-
function latestMatchingMtimeMs(directory, predicate) {
|
|
8427
|
-
let latest = 0;
|
|
8428
|
-
const stack = [directory];
|
|
8429
|
-
let visited = 0;
|
|
8430
|
-
while (stack.length) {
|
|
8431
|
-
const current = stack.pop();
|
|
8432
|
-
for (const entry of (0, import_node_fs5.readdirSync)(current, { withFileTypes: true })) {
|
|
8433
|
-
const fullPath = import_node_path5.default.join(current, entry.name);
|
|
8434
|
-
if (entry.isDirectory()) {
|
|
8435
|
-
stack.push(fullPath);
|
|
8436
|
-
continue;
|
|
8437
|
-
}
|
|
8438
|
-
if (!entry.isFile() || !predicate(fullPath)) continue;
|
|
8439
|
-
const stat = (0, import_node_fs5.statSync)(fullPath);
|
|
8440
|
-
latest = Math.max(latest, stat.mtimeMs);
|
|
8441
|
-
visited += 1;
|
|
8442
|
-
if (visited >= 1e4) return latest;
|
|
8443
|
-
}
|
|
8444
|
-
}
|
|
8445
|
-
return latest;
|
|
8446
|
-
}
|
|
8447
|
-
function collectRiddlePreviewDeployWarnings(directory, framework = "static") {
|
|
8448
|
-
try {
|
|
8449
|
-
if (framework !== "static") return [];
|
|
8450
|
-
const resolvedDirectory = import_node_path5.default.resolve(directory);
|
|
8451
|
-
if (import_node_path5.default.basename(resolvedDirectory) !== "out") return [];
|
|
8452
|
-
const repoRoot = import_node_path5.default.dirname(resolvedDirectory);
|
|
8453
|
-
const nextAppDir = import_node_path5.default.join(repoRoot, ".next", "server", "app");
|
|
8454
|
-
if (!(0, import_node_fs5.existsSync)(nextAppDir)) return [];
|
|
8455
|
-
const nextRenderedMtimeMs = latestMatchingMtimeMs(nextAppDir, (filePath) => /\.(?:html|rsc)$/i.test(filePath));
|
|
8456
|
-
if (!nextRenderedMtimeMs) return [];
|
|
8457
|
-
const outRenderedMtimeMs = (0, import_node_fs5.existsSync)(resolvedDirectory) ? latestMatchingMtimeMs(resolvedDirectory, (filePath) => /\.(?:html|txt|rsc)$/i.test(filePath)) : 0;
|
|
8458
|
-
if (!outRenderedMtimeMs) {
|
|
8459
|
-
return [
|
|
8460
|
-
"Riddle Preview static deploy target is an out/ directory with newer Next render output in .next/server/app, but no rendered HTML/RSC files were found in out/. Run the project static bundle/export step before deploying."
|
|
8461
|
-
];
|
|
8462
|
-
}
|
|
8463
|
-
if (nextRenderedMtimeMs > outRenderedMtimeMs + 1e3) {
|
|
8464
|
-
return [
|
|
8465
|
-
"Riddle Preview static deploy target out/ appears older than the Next render output in .next/server/app. Run the project static bundle/export step, such as npm run build:static-deploy or next export, before deploying to avoid a stale Preview."
|
|
8466
|
-
];
|
|
8467
|
-
}
|
|
8468
|
-
return [];
|
|
8469
|
-
} catch {
|
|
8470
|
-
return [];
|
|
8471
|
-
}
|
|
8472
|
-
}
|
|
8473
|
-
async function deployRiddleStaticPreview(config, directory, label, options = {}) {
|
|
8474
|
-
return deployRiddlePreview(config, directory, label, "static", options);
|
|
8475
|
-
}
|
|
8476
|
-
function createTarball(directory, label, exclude = []) {
|
|
8477
|
-
const scratch = (0, import_node_fs5.mkdtempSync)(import_node_path5.default.join((0, import_node_os2.tmpdir)(), "riddle-upload-"));
|
|
8478
|
-
const tarball = import_node_path5.default.join(scratch, `${label}.tar.gz`);
|
|
8479
|
-
const excludeArgs = exclude.flatMap((item) => ["--exclude", item]);
|
|
8480
|
-
try {
|
|
8481
|
-
(0, import_node_child_process4.execFileSync)("tar", ["czf", tarball, ...excludeArgs, "-C", directory, "."], { stdio: "pipe" });
|
|
8482
|
-
return { scratch, tarball };
|
|
8483
|
-
} catch (error) {
|
|
8484
|
-
(0, import_node_fs5.rmSync)(scratch, { recursive: true, force: true });
|
|
8485
|
-
throw error;
|
|
8486
|
-
}
|
|
8487
|
-
}
|
|
8488
|
-
function parseRiddleViewport(value) {
|
|
8489
|
-
if (!value) return void 0;
|
|
8490
|
-
const match = /^(\d+)x(\d+)$/.exec(value.trim());
|
|
8491
|
-
if (!match) throw new Error("viewport must look like 1280x720");
|
|
8492
|
-
return { width: Number(match[1]), height: Number(match[2]) };
|
|
8493
|
-
}
|
|
8494
|
-
function scriptErrorFrom(job) {
|
|
8495
|
-
const nested = job?.proof_of_execution && typeof job.proof_of_execution === "object" && !Array.isArray(job.proof_of_execution) ? job.proof_of_execution : null;
|
|
8496
|
-
return typeof job?.script_error === "string" && job.script_error.trim() ? job.script_error : typeof nested?.script_error === "string" && nested.script_error.trim() ? nested.script_error : null;
|
|
8497
|
-
}
|
|
8498
|
-
async function runRiddleServerPreview(config, input) {
|
|
8499
|
-
if (!input.directory?.trim()) throw new Error("directory is required");
|
|
8500
|
-
if (!input.script?.trim()) throw new Error("script is required");
|
|
8501
|
-
const port = input.port || 3e3;
|
|
8502
|
-
const routePath = input.path || "/";
|
|
8503
|
-
const timeoutSec = input.timeoutSec || 180;
|
|
8504
|
-
const created = await riddleRequestJson(config, "/v1/server-preview", {
|
|
8505
|
-
method: "POST",
|
|
8506
|
-
body: JSON.stringify({
|
|
8507
|
-
image: input.image || "node:22-slim",
|
|
8508
|
-
command: input.command || "node scripts/riddleSpaPreviewServer.mjs build 3000",
|
|
8509
|
-
port,
|
|
8510
|
-
path: routePath,
|
|
8511
|
-
readiness_path: input.readinessPath || routePath,
|
|
8512
|
-
readiness_timeout: input.readinessTimeoutSec || 90,
|
|
8513
|
-
wait_until: input.waitUntil || "domcontentloaded",
|
|
8514
|
-
wait_for_selector: input.waitForSelector || "body",
|
|
8515
|
-
navigation_timeout: input.navigationTimeoutSec || 60,
|
|
8516
|
-
viewport: input.viewport,
|
|
8517
|
-
timeout: timeoutSec,
|
|
8518
|
-
script: input.script
|
|
8519
|
-
})
|
|
8520
|
-
});
|
|
8521
|
-
const jobId = String(created.job_id || "");
|
|
8522
|
-
const uploadUrl = String(created.upload_url || "");
|
|
8523
|
-
if (!jobId || !uploadUrl) {
|
|
8524
|
-
throw new Error(`Riddle server preview create response was missing job_id or upload_url.`);
|
|
8525
|
-
}
|
|
8526
|
-
const { scratch, tarball } = createTarball(input.directory, jobId, [
|
|
8527
|
-
".git",
|
|
8528
|
-
"node_modules",
|
|
8529
|
-
"test-results",
|
|
8530
|
-
...input.exclude || []
|
|
8531
|
-
]);
|
|
8532
|
-
try {
|
|
8533
|
-
const upload = await fetchFor(config)(uploadUrl, {
|
|
8534
|
-
method: "PUT",
|
|
8535
|
-
headers: { "Content-Type": "application/gzip" },
|
|
8536
|
-
body: (0, import_node_fs5.readFileSync)(tarball)
|
|
8537
|
-
});
|
|
8538
|
-
if (!upload.ok) throw new RiddleApiError(uploadUrl, upload.status, await upload.text());
|
|
8539
|
-
} finally {
|
|
8540
|
-
(0, import_node_fs5.rmSync)(scratch, { recursive: true, force: true });
|
|
8541
|
-
}
|
|
8542
|
-
await riddleRequestJson(config, `/v1/server-preview/${jobId}/start`, {
|
|
8543
|
-
method: "POST"
|
|
8544
|
-
});
|
|
8545
|
-
let job = null;
|
|
8546
|
-
const attempts = input.pollAttempts || Math.ceil((timeoutSec + 90) / 2);
|
|
8547
|
-
const intervalMs = input.pollIntervalMs || 2e3;
|
|
8548
|
-
for (let index = 0; index < attempts; index += 1) {
|
|
8549
|
-
job = await riddleRequestJson(config, `/v1/server-preview/${jobId}`);
|
|
8550
|
-
if (isTerminalRiddleJobStatus(job.status)) break;
|
|
8551
|
-
if (index + 1 < attempts) await new Promise((resolve) => setTimeout(resolve, intervalMs));
|
|
8552
|
-
}
|
|
8553
|
-
const status = job?.status ? String(job.status) : null;
|
|
8554
|
-
const scriptError = scriptErrorFrom(job);
|
|
8555
|
-
return {
|
|
8556
|
-
ok: (status === "completed" || status === "complete") && !scriptError,
|
|
8557
|
-
job_id: jobId,
|
|
8558
|
-
status,
|
|
8559
|
-
terminal: isTerminalRiddleJobStatus(status),
|
|
8560
|
-
script_error: scriptError,
|
|
8561
|
-
job
|
|
8562
|
-
};
|
|
8563
|
-
}
|
|
8564
|
-
async function runRiddleScript(config, input) {
|
|
8565
|
-
if (!input.url?.trim()) throw new Error("url is required");
|
|
8566
|
-
if (!input.script?.trim()) throw new Error("script is required");
|
|
8567
|
-
const payload = {
|
|
8568
|
-
url: input.url,
|
|
8569
|
-
script: input.script,
|
|
8570
|
-
sync: input.sync ?? false,
|
|
8571
|
-
timeout_sec: input.timeoutSec || 120
|
|
8572
|
-
};
|
|
8573
|
-
if (input.viewport) payload.viewport = input.viewport;
|
|
8574
|
-
if (input.include) payload.include = input.include;
|
|
8575
|
-
if (typeof input.strict === "boolean") payload.strict = input.strict;
|
|
8576
|
-
if (input.options) payload.options = input.options;
|
|
8577
|
-
return riddleRequestJson(config, "/v1/run", {
|
|
8578
|
-
method: "POST",
|
|
8579
|
-
body: JSON.stringify(payload)
|
|
8580
|
-
});
|
|
8581
|
-
}
|
|
8582
|
-
function isTerminalRiddleJobStatus(status) {
|
|
8583
|
-
return ["completed", "complete", "completed_error", "completed_timeout", "failed"].includes(String(status || ""));
|
|
8584
|
-
}
|
|
8585
|
-
function stringField(record, key) {
|
|
8586
|
-
const value = record?.[key];
|
|
8587
|
-
return typeof value === "string" && value.trim() ? value.trim() : null;
|
|
8588
|
-
}
|
|
8589
|
-
function parseTimestampMs(value) {
|
|
8590
|
-
if (!value) return null;
|
|
8591
|
-
const parsed = Date.parse(value);
|
|
8592
|
-
return Number.isFinite(parsed) ? parsed : null;
|
|
8593
|
-
}
|
|
8594
|
-
function buildPollSnapshot(jobId, job, input) {
|
|
8595
|
-
const status = job?.status ? String(job.status) : null;
|
|
8596
|
-
const phase = job?.phase ? String(job.phase) : null;
|
|
8597
|
-
const terminal = isTerminalRiddleJobStatus(status);
|
|
8598
|
-
const createdAt = stringField(job, "created_at");
|
|
8599
|
-
const submittedAt = stringField(job, "submitted_at");
|
|
8600
|
-
const completedAt = stringField(job, "completed_at");
|
|
8601
|
-
const createdMs = parseTimestampMs(createdAt);
|
|
8602
|
-
const submittedMs = parseTimestampMs(submittedAt);
|
|
8603
|
-
const rawExecution = job?.execution && typeof job.execution === "object" && !Array.isArray(job.execution) ? job.execution : null;
|
|
8604
|
-
const enqueuedAt = rawExecution ? stringField(rawExecution, "enqueued_at") : null;
|
|
8605
|
-
const enqueuedMs = parseTimestampMs(enqueuedAt);
|
|
8606
|
-
const queueStartedMs = enqueuedMs ?? createdMs;
|
|
8607
|
-
const claimedAt = rawExecution ? stringField(rawExecution, "claimed_at") : null;
|
|
8608
|
-
const claimedMs = parseTimestampMs(claimedAt);
|
|
8609
|
-
let queueElapsedMs = null;
|
|
8610
|
-
if (queueStartedMs !== null && claimedMs !== null) {
|
|
8611
|
-
queueElapsedMs = Math.max(0, claimedMs - queueStartedMs);
|
|
8612
|
-
} else if (queueStartedMs !== null && submittedMs !== null) {
|
|
8613
|
-
queueElapsedMs = Math.max(0, submittedMs - queueStartedMs);
|
|
8614
|
-
} else if (queueStartedMs !== null && !submittedAt && !terminal) {
|
|
8615
|
-
queueElapsedMs = Math.max(0, input.observedAt - queueStartedMs);
|
|
8616
|
-
}
|
|
8617
|
-
return {
|
|
8618
|
-
job_id: jobId,
|
|
8619
|
-
status,
|
|
8620
|
-
phase,
|
|
8621
|
-
terminal,
|
|
8622
|
-
attempt: input.attempt,
|
|
8623
|
-
attempts: input.attempts,
|
|
8624
|
-
elapsed_ms: Math.max(0, input.observedAt - input.startedAt),
|
|
8625
|
-
created_at: createdAt,
|
|
8626
|
-
submitted_at: submittedAt,
|
|
8627
|
-
completed_at: completedAt,
|
|
8628
|
-
queue_elapsed_ms: queueElapsedMs,
|
|
8629
|
-
pre_submission_elapsed_ms: Math.max(0, Math.floor(input.preSubmissionElapsedMs ?? 0)),
|
|
8630
|
-
running_without_submission: Boolean(status && !terminal && !submittedAt),
|
|
8631
|
-
active_execution: Boolean(status === "running" && phase && phase !== "queued"),
|
|
8632
|
-
execution: rawExecution ? rawExecution : void 0
|
|
8633
|
-
};
|
|
8634
|
-
}
|
|
8635
|
-
function pollMessage(snapshot, timedOut) {
|
|
8636
|
-
if (!timedOut) return void 0;
|
|
8637
|
-
const submitted = snapshot.submitted_at || "not submitted";
|
|
8638
|
-
const wakeHint = snapshot.running_without_submission && !snapshot.created_at && !snapshot.submitted_at ? ` ${RIDDLE_UNSUBMITTED_WAKE_HINT}.` : "";
|
|
8639
|
-
const queue = snapshot.queue_elapsed_ms !== null ? ` queue_elapsed_ms=${snapshot.queue_elapsed_ms}` : "";
|
|
8640
|
-
const preSubmit = snapshot.pre_submission_elapsed_ms > 0 ? ` pre_submission_elapsed_ms=${snapshot.pre_submission_elapsed_ms}` : "";
|
|
8641
|
-
return `Riddle job ${snapshot.job_id} did not reach a terminal status after ${snapshot.attempt} poll attempts; status=${snapshot.status || "unknown"} phase=${snapshot.phase || "unknown"} submitted_at=${submitted}.${wakeHint}${queue}${preSubmit}`;
|
|
8642
|
-
}
|
|
8643
|
-
async function pollRiddleJob(config, jobId, options = {}) {
|
|
8644
|
-
if (!jobId?.trim()) throw new Error("jobId is required");
|
|
8645
|
-
const attempts = Math.max(1, Math.floor(options.attempts ?? (options.wait ? 300 : 1)));
|
|
8646
|
-
const intervalMs = Math.max(0, Math.floor(options.intervalMs ?? 2e3));
|
|
8647
|
-
const progressEveryMs = Math.max(0, Math.floor(options.progressEveryMs ?? 1e4));
|
|
8648
|
-
const unsubmittedTimeoutMs = Math.max(0, Math.floor(options.unsubmittedTimeoutMs ?? 0));
|
|
8649
|
-
const startedAt = Date.now();
|
|
8650
|
-
let job = null;
|
|
8651
|
-
let lastSnapshot = null;
|
|
8652
|
-
let lastProgressAt = 0;
|
|
8653
|
-
let lastProgressKey = "";
|
|
8654
|
-
let preSubmissionElapsedMs = 0;
|
|
8655
|
-
let unsubmittedTimedOut = false;
|
|
8656
|
-
for (let index = 0; index < attempts; index += 1) {
|
|
8657
|
-
job = await riddleRequestJson(config, `/v1/jobs/${jobId}`);
|
|
8658
|
-
const observedAt = Date.now();
|
|
8659
|
-
const nextSnapshot = buildPollSnapshot(jobId, job, {
|
|
8660
|
-
attempt: index + 1,
|
|
8661
|
-
attempts,
|
|
8662
|
-
startedAt,
|
|
8663
|
-
observedAt,
|
|
8664
|
-
preSubmissionElapsedMs
|
|
8665
|
-
});
|
|
8666
|
-
if (nextSnapshot.running_without_submission) {
|
|
8667
|
-
preSubmissionElapsedMs = Math.max(preSubmissionElapsedMs, nextSnapshot.elapsed_ms);
|
|
8668
|
-
}
|
|
8669
|
-
lastSnapshot = {
|
|
8670
|
-
...nextSnapshot,
|
|
8671
|
-
pre_submission_elapsed_ms: preSubmissionElapsedMs
|
|
8672
|
-
};
|
|
8673
|
-
const progressKey = [
|
|
8674
|
-
lastSnapshot.status || "unknown",
|
|
8675
|
-
lastSnapshot.phase || "unknown",
|
|
8676
|
-
lastSnapshot.terminal ? "terminal" : "nonterminal",
|
|
8677
|
-
lastSnapshot.submitted_at ? "submitted" : "unsubmitted"
|
|
8678
|
-
].join(":");
|
|
8679
|
-
if (options.onProgress) {
|
|
8680
|
-
const shouldReport = index === 0 || lastSnapshot.terminal || progressKey !== lastProgressKey || observedAt - lastProgressAt >= progressEveryMs;
|
|
8681
|
-
if (shouldReport) {
|
|
8682
|
-
lastProgressAt = observedAt;
|
|
8683
|
-
lastProgressKey = progressKey;
|
|
8684
|
-
await options.onProgress(lastSnapshot);
|
|
8685
|
-
}
|
|
8686
|
-
}
|
|
8687
|
-
unsubmittedTimedOut = Boolean(
|
|
8688
|
-
options.wait && unsubmittedTimeoutMs > 0 && lastSnapshot.running_without_submission && !lastSnapshot.created_at && !lastSnapshot.submitted_at && preSubmissionElapsedMs >= unsubmittedTimeoutMs
|
|
8689
|
-
);
|
|
8690
|
-
if (lastSnapshot.terminal) break;
|
|
8691
|
-
if (unsubmittedTimedOut) break;
|
|
8692
|
-
if (index + 1 < attempts) {
|
|
8693
|
-
await new Promise((resolve) => setTimeout(resolve, intervalMs));
|
|
8694
|
-
}
|
|
8695
|
-
}
|
|
8696
|
-
const status = job?.status ? String(job.status) : null;
|
|
8697
|
-
const fallbackObservedAt = Date.now();
|
|
8698
|
-
const snapshot = lastSnapshot || buildPollSnapshot(jobId, job, {
|
|
8699
|
-
attempt: 0,
|
|
8700
|
-
attempts,
|
|
8701
|
-
startedAt,
|
|
8702
|
-
observedAt: fallbackObservedAt
|
|
8703
|
-
});
|
|
8704
|
-
if (!isTerminalRiddleJobStatus(status)) {
|
|
8705
|
-
const timedOut = Boolean(options.wait);
|
|
8706
|
-
return {
|
|
8707
|
-
ok: !timedOut,
|
|
8708
|
-
job_id: jobId,
|
|
8709
|
-
status,
|
|
8710
|
-
terminal: false,
|
|
8711
|
-
job,
|
|
8712
|
-
poll: {
|
|
8713
|
-
...snapshot,
|
|
8714
|
-
timed_out: timedOut,
|
|
8715
|
-
interval_ms: intervalMs,
|
|
8716
|
-
unsubmitted_timeout: unsubmittedTimedOut || void 0,
|
|
8717
|
-
unsubmitted_timeout_ms: unsubmittedTimedOut ? unsubmittedTimeoutMs : void 0,
|
|
8718
|
-
message: pollMessage(snapshot, timedOut)
|
|
8719
|
-
}
|
|
8720
|
-
};
|
|
8721
|
-
}
|
|
8722
|
-
const artifacts = await riddleRequestJson(config, `/v1/jobs/${jobId}/artifacts`);
|
|
8723
|
-
return {
|
|
8724
|
-
ok: status === "completed" || status === "complete",
|
|
8725
|
-
job_id: jobId,
|
|
8726
|
-
status,
|
|
8727
|
-
terminal: true,
|
|
8728
|
-
job,
|
|
8729
|
-
artifacts,
|
|
8730
|
-
poll: {
|
|
8731
|
-
...snapshot,
|
|
8732
|
-
timed_out: false,
|
|
8733
|
-
interval_ms: intervalMs
|
|
8734
|
-
}
|
|
8735
|
-
};
|
|
8736
|
-
}
|
|
8737
|
-
function createRiddleApiClient(config = {}) {
|
|
8738
|
-
return {
|
|
8739
|
-
apiKeySource: () => resolveRiddleApiKeySource(config),
|
|
8740
|
-
requestJson: (pathname, init) => riddleRequestJson(config, pathname, init),
|
|
8741
|
-
getBalance: () => getRiddleBalance(config),
|
|
8742
|
-
deployPreview: (directory, label, framework = "static", options) => deployRiddlePreview(config, directory, label, framework, options),
|
|
8743
|
-
deployStaticPreview: (directory, label, options) => deployRiddleStaticPreview(config, directory, label, options),
|
|
8744
|
-
runScript: (input) => runRiddleScript(config, input),
|
|
8745
|
-
runServerPreview: (input) => runRiddleServerPreview(config, input),
|
|
8746
|
-
pollJob: (jobId, options) => pollRiddleJob(config, jobId, options)
|
|
8747
|
-
};
|
|
8748
|
-
}
|
|
7879
|
+
var import_client = require("@riddledc/riddle-proof-riddle-client/client");
|
|
8749
7880
|
|
|
8750
7881
|
// src/profile.ts
|
|
8751
7882
|
var RIDDLE_PROOF_PROFILE_VERSION = "riddle-proof.profile.v1";
|
|
@@ -8887,7 +8018,7 @@ function deriveRiddleProofArtifactBodyAssertions(input) {
|
|
|
8887
8018
|
var DEFAULT_VIEWPORTS = [
|
|
8888
8019
|
{ name: "desktop", width: 1280, height: 800 }
|
|
8889
8020
|
];
|
|
8890
|
-
function
|
|
8021
|
+
function isRecord(value) {
|
|
8891
8022
|
return Boolean(value) && typeof value === "object" && !Array.isArray(value);
|
|
8892
8023
|
}
|
|
8893
8024
|
function stringValue3(value) {
|
|
@@ -8918,7 +8049,7 @@ function booleanValue2(value) {
|
|
|
8918
8049
|
return typeof value === "boolean" ? value : void 0;
|
|
8919
8050
|
}
|
|
8920
8051
|
function horizontalBoundsOverflowPx(value) {
|
|
8921
|
-
if (!
|
|
8052
|
+
if (!isRecord(value)) return 0;
|
|
8922
8053
|
let max = maxPositiveNumber(
|
|
8923
8054
|
value.overflow_px,
|
|
8924
8055
|
value.overflow,
|
|
@@ -8933,7 +8064,7 @@ function horizontalBoundsOverflowPx(value) {
|
|
|
8933
8064
|
return roundPixels(max);
|
|
8934
8065
|
}
|
|
8935
8066
|
function horizontalOffenderOverflowPx(value) {
|
|
8936
|
-
if (!
|
|
8067
|
+
if (!isRecord(value)) return 0;
|
|
8937
8068
|
let max = maxPositiveNumber(
|
|
8938
8069
|
value.overflow,
|
|
8939
8070
|
value.overflow_px,
|
|
@@ -8944,8 +8075,8 @@ function horizontalOffenderOverflowPx(value) {
|
|
|
8944
8075
|
value.leftOverflowPx,
|
|
8945
8076
|
value.rightOverflowPx
|
|
8946
8077
|
);
|
|
8947
|
-
const clipped =
|
|
8948
|
-
if (
|
|
8078
|
+
const clipped = isRecord(value.clipped || value.clip || value.clipping) ? value.clipped || value.clip || value.clipping : void 0;
|
|
8079
|
+
if (isRecord(clipped)) {
|
|
8949
8080
|
max = Math.max(max, maxPositiveNumber(
|
|
8950
8081
|
clipped.left,
|
|
8951
8082
|
clipped.right,
|
|
@@ -8955,9 +8086,9 @@ function horizontalOffenderOverflowPx(value) {
|
|
|
8955
8086
|
clipped.rightPx
|
|
8956
8087
|
));
|
|
8957
8088
|
}
|
|
8958
|
-
const rect =
|
|
8089
|
+
const rect = isRecord(value.rect || value.bounds || value.bounding_rect || value.boundingRect) ? value.rect || value.bounds || value.bounding_rect || value.boundingRect : void 0;
|
|
8959
8090
|
const viewportWidth = numberValue2(value.viewport_width ?? value.viewportWidth);
|
|
8960
|
-
if (
|
|
8091
|
+
if (isRecord(rect) && viewportWidth !== void 0) {
|
|
8961
8092
|
const left = numberValue2(rect.left);
|
|
8962
8093
|
const right = numberValue2(rect.right);
|
|
8963
8094
|
if (left !== void 0 && left < 0) max = Math.max(max, Math.abs(left));
|
|
@@ -8966,7 +8097,7 @@ function horizontalOffenderOverflowPx(value) {
|
|
|
8966
8097
|
return roundPixels(max);
|
|
8967
8098
|
}
|
|
8968
8099
|
function boundsOffendersForEvidence(value) {
|
|
8969
|
-
if (!
|
|
8100
|
+
if (!isRecord(value)) return [];
|
|
8970
8101
|
const offenders = [
|
|
8971
8102
|
...Array.isArray(value.overflow_offenders) ? value.overflow_offenders : [],
|
|
8972
8103
|
...Array.isArray(value.overflowOffenders) ? value.overflowOffenders : [],
|
|
@@ -8977,7 +8108,7 @@ function boundsOffendersForEvidence(value) {
|
|
|
8977
8108
|
...Array.isArray(value.clipping_offenders) ? value.clipping_offenders : [],
|
|
8978
8109
|
...Array.isArray(value.clippingOffenders) ? value.clippingOffenders : []
|
|
8979
8110
|
];
|
|
8980
|
-
return offenders.filter((item) =>
|
|
8111
|
+
return offenders.filter((item) => isRecord(item)).sort((a, b) => horizontalOffenderOverflowPx(b) - horizontalOffenderOverflowPx(a));
|
|
8981
8112
|
}
|
|
8982
8113
|
function maxPositiveNumber(...values) {
|
|
8983
8114
|
let max = 0;
|
|
@@ -8995,11 +8126,11 @@ function timeoutSecValue(value) {
|
|
|
8995
8126
|
return number && number > 0 ? Math.ceil(number) : void 0;
|
|
8996
8127
|
}
|
|
8997
8128
|
function jsonRecord(value) {
|
|
8998
|
-
if (!
|
|
8129
|
+
if (!isRecord(value)) return void 0;
|
|
8999
8130
|
return Object.fromEntries(Object.entries(value).map(([key, child]) => [key, toJsonValue(child)]));
|
|
9000
8131
|
}
|
|
9001
8132
|
function stringRecord(value) {
|
|
9002
|
-
if (!
|
|
8133
|
+
if (!isRecord(value)) return void 0;
|
|
9003
8134
|
const entries = Object.entries(value).map(([key, child]) => [key, String(child)]).filter(([key]) => key.trim());
|
|
9004
8135
|
return entries.length ? Object.fromEntries(entries) : void 0;
|
|
9005
8136
|
}
|
|
@@ -9008,7 +8139,7 @@ function toJsonValue(value) {
|
|
|
9008
8139
|
if (typeof value === "string" || typeof value === "boolean") return value;
|
|
9009
8140
|
if (typeof value === "number") return Number.isFinite(value) ? value : null;
|
|
9010
8141
|
if (Array.isArray(value)) return value.map(toJsonValue);
|
|
9011
|
-
if (
|
|
8142
|
+
if (isRecord(value)) return Object.fromEntries(Object.entries(value).map(([key, child]) => [key, toJsonValue(child)]));
|
|
9012
8143
|
return String(value);
|
|
9013
8144
|
}
|
|
9014
8145
|
function jsonValueType(value) {
|
|
@@ -9026,7 +8157,7 @@ function compactJsonAssertionSample(value, depth = 0) {
|
|
|
9026
8157
|
if (depth >= 2) return `[array:${value.length}]`;
|
|
9027
8158
|
return value.slice(0, 3).map((item) => compactJsonAssertionSample(item, depth + 1));
|
|
9028
8159
|
}
|
|
9029
|
-
if (
|
|
8160
|
+
if (isRecord(value)) {
|
|
9030
8161
|
const entries = Object.entries(value).slice(0, 8);
|
|
9031
8162
|
if (depth >= 2) return `[object:${Object.keys(value).length} keys]`;
|
|
9032
8163
|
return Object.fromEntries(entries.map(([key, child]) => [key, compactJsonAssertionSample(child, depth + 1)]));
|
|
@@ -9041,7 +8172,7 @@ function attachJsonAssertionObservedValue(result, value) {
|
|
|
9041
8172
|
result.observed_sample = compactJsonAssertionSample(value);
|
|
9042
8173
|
return;
|
|
9043
8174
|
}
|
|
9044
|
-
if (type === "object" &&
|
|
8175
|
+
if (type === "object" && isRecord(value)) {
|
|
9045
8176
|
const keyCount = Object.keys(value).length;
|
|
9046
8177
|
result.observed_key_count = keyCount;
|
|
9047
8178
|
result.observed_omitted_count = Math.max(0, keyCount - 8);
|
|
@@ -9059,7 +8190,7 @@ function deepJsonEqual(left, right) {
|
|
|
9059
8190
|
if (!Array.isArray(left) || !Array.isArray(right) || left.length !== right.length) return false;
|
|
9060
8191
|
return left.every((item, index) => deepJsonEqual(item, right[index]));
|
|
9061
8192
|
}
|
|
9062
|
-
if (!
|
|
8193
|
+
if (!isRecord(left) || !isRecord(right)) return false;
|
|
9063
8194
|
const leftKeys = Object.keys(left).sort();
|
|
9064
8195
|
const rightKeys = Object.keys(right).sort();
|
|
9065
8196
|
if (!deepJsonEqual(leftKeys, rightKeys)) return false;
|
|
@@ -9072,13 +8203,13 @@ function jsonContains(observed, expected) {
|
|
|
9072
8203
|
if (Array.isArray(observed)) {
|
|
9073
8204
|
return observed.some((item) => deepJsonEqual(item, expected));
|
|
9074
8205
|
}
|
|
9075
|
-
if (
|
|
8206
|
+
if (isRecord(observed) && isRecord(expected)) {
|
|
9076
8207
|
return Object.entries(expected).every(([key, value]) => hasOwn(observed, key) && deepJsonEqual(observed[key], value));
|
|
9077
8208
|
}
|
|
9078
8209
|
return false;
|
|
9079
8210
|
}
|
|
9080
|
-
function parseJsonPathSegments(
|
|
9081
|
-
let input =
|
|
8211
|
+
function parseJsonPathSegments(path6) {
|
|
8212
|
+
let input = path6.trim();
|
|
9082
8213
|
if (!input) throw new Error("path is empty");
|
|
9083
8214
|
if (input === "$") return [];
|
|
9084
8215
|
if (input.startsWith("$.")) input = input.slice(2);
|
|
@@ -9118,10 +8249,10 @@ function parseJsonPathSegments(path7) {
|
|
|
9118
8249
|
pushToken();
|
|
9119
8250
|
return segments;
|
|
9120
8251
|
}
|
|
9121
|
-
function resolveJsonPath(root,
|
|
8252
|
+
function resolveJsonPath(root, path6) {
|
|
9122
8253
|
let segments;
|
|
9123
8254
|
try {
|
|
9124
|
-
segments = parseJsonPathSegments(
|
|
8255
|
+
segments = parseJsonPathSegments(path6);
|
|
9125
8256
|
} catch (error) {
|
|
9126
8257
|
return { exists: false, error: String(error instanceof Error ? error.message : error) };
|
|
9127
8258
|
}
|
|
@@ -9140,7 +8271,7 @@ function resolveJsonPath(root, path7) {
|
|
|
9140
8271
|
if (typeof segment === "number") {
|
|
9141
8272
|
return { exists: false };
|
|
9142
8273
|
}
|
|
9143
|
-
if (!
|
|
8274
|
+
if (!isRecord(current) || !hasOwn(current, segment)) return { exists: false };
|
|
9144
8275
|
current = current[segment];
|
|
9145
8276
|
}
|
|
9146
8277
|
return { exists: true, value: current };
|
|
@@ -9155,7 +8286,7 @@ function assessRiddleProofOrderedTrace(trace, events) {
|
|
|
9155
8286
|
missing_paths: missingPaths,
|
|
9156
8287
|
reason
|
|
9157
8288
|
});
|
|
9158
|
-
const parsePath = (
|
|
8289
|
+
const parsePath = (path6) => {
|
|
9159
8290
|
const segments = [];
|
|
9160
8291
|
let token = "";
|
|
9161
8292
|
const pushToken = () => {
|
|
@@ -9163,8 +8294,8 @@ function assessRiddleProofOrderedTrace(trace, events) {
|
|
|
9163
8294
|
if (value) segments.push(value);
|
|
9164
8295
|
token = "";
|
|
9165
8296
|
};
|
|
9166
|
-
for (let index = 0; index <
|
|
9167
|
-
const char =
|
|
8297
|
+
for (let index = 0; index < path6.length; index += 1) {
|
|
8298
|
+
const char = path6[index];
|
|
9168
8299
|
if (char === ".") {
|
|
9169
8300
|
pushToken();
|
|
9170
8301
|
continue;
|
|
@@ -9174,9 +8305,9 @@ function assessRiddleProofOrderedTrace(trace, events) {
|
|
|
9174
8305
|
continue;
|
|
9175
8306
|
}
|
|
9176
8307
|
pushToken();
|
|
9177
|
-
const closeIndex =
|
|
8308
|
+
const closeIndex = path6.indexOf("]", index + 1);
|
|
9178
8309
|
if (closeIndex === -1) throw new Error(`unterminated bracket at ${index}`);
|
|
9179
|
-
const bracket =
|
|
8310
|
+
const bracket = path6.slice(index + 1, closeIndex).trim();
|
|
9180
8311
|
if (!bracket) throw new Error(`empty bracket at ${index}`);
|
|
9181
8312
|
if (/^\d+$/.test(bracket)) {
|
|
9182
8313
|
segments.push(Number(bracket));
|
|
@@ -9188,10 +8319,10 @@ function assessRiddleProofOrderedTrace(trace, events) {
|
|
|
9188
8319
|
pushToken();
|
|
9189
8320
|
return segments;
|
|
9190
8321
|
};
|
|
9191
|
-
const resolve = (root,
|
|
8322
|
+
const resolve = (root, path6) => {
|
|
9192
8323
|
let segments;
|
|
9193
8324
|
try {
|
|
9194
|
-
segments = parsePath(
|
|
8325
|
+
segments = parsePath(path6);
|
|
9195
8326
|
} catch {
|
|
9196
8327
|
return { exists: false };
|
|
9197
8328
|
}
|
|
@@ -9393,9 +8524,9 @@ function profileSetupFrameUrls(viewport) {
|
|
|
9393
8524
|
const urls = [];
|
|
9394
8525
|
const frames = viewport.frames || {};
|
|
9395
8526
|
for (const container of Object.values(frames)) {
|
|
9396
|
-
if (!
|
|
8527
|
+
if (!isRecord(container) || !Array.isArray(container.frames)) continue;
|
|
9397
8528
|
for (const frame of container.frames) {
|
|
9398
|
-
if (!
|
|
8529
|
+
if (!isRecord(frame)) continue;
|
|
9399
8530
|
const url = typeof frame.url === "string" ? frame.url : void 0;
|
|
9400
8531
|
if (url && !urls.includes(url)) urls.push(url);
|
|
9401
8532
|
}
|
|
@@ -9487,15 +8618,15 @@ function profileSetupReturnSummaryFields(result) {
|
|
|
9487
8618
|
const fields = [];
|
|
9488
8619
|
for (const item of input) {
|
|
9489
8620
|
if (typeof item === "string") {
|
|
9490
|
-
const
|
|
9491
|
-
if (
|
|
8621
|
+
const path7 = item.trim();
|
|
8622
|
+
if (path7) fields.push({ path: path7 });
|
|
9492
8623
|
continue;
|
|
9493
8624
|
}
|
|
9494
|
-
if (!
|
|
9495
|
-
const
|
|
9496
|
-
if (!
|
|
8625
|
+
if (!isRecord(item)) continue;
|
|
8626
|
+
const path6 = stringValue3(item.path) ?? stringValue3(item.key) ?? stringValue3(item.json_path) ?? stringValue3(item.jsonPath);
|
|
8627
|
+
if (!path6) continue;
|
|
9497
8628
|
const label = stringValue3(item.label) ?? stringValue3(item.name) ?? stringValue3(item.title);
|
|
9498
|
-
fields.push(label ? { path:
|
|
8629
|
+
fields.push(label ? { path: path6, label } : { path: path6 });
|
|
9499
8630
|
}
|
|
9500
8631
|
return fields;
|
|
9501
8632
|
}
|
|
@@ -9887,7 +9018,7 @@ function slugifyRiddleProofProfileName(value) {
|
|
|
9887
9018
|
return value.toLowerCase().replace(/[^a-z0-9]+/g, "-").replace(/^-+|-+$/g, "").slice(0, 80) || "profile";
|
|
9888
9019
|
}
|
|
9889
9020
|
function normalizeViewport(input, index) {
|
|
9890
|
-
if (!
|
|
9021
|
+
if (!isRecord(input)) throw new Error(`target.viewports[${index}] must be an object.`);
|
|
9891
9022
|
const width = numberValue2(input.width);
|
|
9892
9023
|
const height = numberValue2(input.height);
|
|
9893
9024
|
if (!width || !height || width < 100 || height < 100) {
|
|
@@ -9953,17 +9084,17 @@ function normalizeReturnSummaryFields(input, index) {
|
|
|
9953
9084
|
}
|
|
9954
9085
|
return fieldsInput.map((field, fieldIndex) => {
|
|
9955
9086
|
if (typeof field === "string") {
|
|
9956
|
-
const
|
|
9957
|
-
if (!
|
|
9958
|
-
return { path:
|
|
9087
|
+
const path7 = field.trim();
|
|
9088
|
+
if (!path7) throw new Error(`target.setup_actions[${index}].return_summary_fields[${fieldIndex}] requires path.`);
|
|
9089
|
+
return { path: path7 };
|
|
9959
9090
|
}
|
|
9960
|
-
if (!
|
|
9091
|
+
if (!isRecord(field)) {
|
|
9961
9092
|
throw new Error(`target.setup_actions[${index}].return_summary_fields[${fieldIndex}] must be a string path or object.`);
|
|
9962
9093
|
}
|
|
9963
|
-
const
|
|
9964
|
-
if (!
|
|
9094
|
+
const path6 = stringFromOwn(field, "path", "key", "json_path", "jsonPath");
|
|
9095
|
+
if (!path6) throw new Error(`target.setup_actions[${index}].return_summary_fields[${fieldIndex}] requires path.`);
|
|
9965
9096
|
const label = stringFromOwn(field, "label", "name", "title");
|
|
9966
|
-
return label ? { path:
|
|
9097
|
+
return label ? { path: path6, label } : { path: path6 };
|
|
9967
9098
|
});
|
|
9968
9099
|
}
|
|
9969
9100
|
function normalizeSetupActionRepeat(input, index) {
|
|
@@ -10066,7 +9197,7 @@ function normalizeSetupActionNonNegativeNumber(input, index, outputKey, ...keys)
|
|
|
10066
9197
|
return value;
|
|
10067
9198
|
}
|
|
10068
9199
|
function normalizeSetupAction(input, index) {
|
|
10069
|
-
if (!
|
|
9200
|
+
if (!isRecord(input)) throw new Error(`target.setup_actions[${index}] must be an object.`);
|
|
10070
9201
|
const type = normalizeSetupActionType(stringValue3(input.type), index);
|
|
10071
9202
|
const rawType = String(input.type || "").trim().replace(/-/g, "_").toLowerCase();
|
|
10072
9203
|
const selector = stringValue3(input.selector);
|
|
@@ -10178,8 +9309,8 @@ function normalizeSetupAction(input, index) {
|
|
|
10178
9309
|
if ((type === "local_storage" || type === "session_storage") && value === void 0 && !hasJsonValue) {
|
|
10179
9310
|
throw new Error(`target.setup_actions[${index}] ${type} requires value.`);
|
|
10180
9311
|
}
|
|
10181
|
-
const
|
|
10182
|
-
if ((type === "window_call" || type === "window_call_until" || type === "assert_window_value" || type === "assert_window_number") && !
|
|
9312
|
+
const path6 = stringFromOwn(input, "path", "function_path", "functionPath", "window_path", "windowPath", "state_path", "statePath");
|
|
9313
|
+
if ((type === "window_call" || type === "window_call_until" || type === "assert_window_value" || type === "assert_window_number") && !path6) {
|
|
10183
9314
|
throw new Error(`target.setup_actions[${index}] ${type} requires path.`);
|
|
10184
9315
|
}
|
|
10185
9316
|
const script = stringFromOwn(input, "script", "code", "source", "body");
|
|
@@ -10277,7 +9408,7 @@ function normalizeSetupAction(input, index) {
|
|
|
10277
9408
|
restore: deterministicRestore || void 0,
|
|
10278
9409
|
label: stringFromOwn(input, "label", "name", "screenshot_label", "screenshotLabel"),
|
|
10279
9410
|
script,
|
|
10280
|
-
path:
|
|
9411
|
+
path: path6,
|
|
10281
9412
|
args,
|
|
10282
9413
|
expect_return: hasExpectedReturn ? toJsonValue(valueFromOwn(input, "expect_return", "expectReturn", "expected_return", "expectedReturn")) : void 0,
|
|
10283
9414
|
store_return_to: storeReturnTo,
|
|
@@ -10358,7 +9489,7 @@ function normalizeTargetScreenshotFullPage(input) {
|
|
|
10358
9489
|
return values[0];
|
|
10359
9490
|
}
|
|
10360
9491
|
function normalizeNetworkMock(input, index) {
|
|
10361
|
-
if (!
|
|
9492
|
+
if (!isRecord(input)) throw new Error(`target.network_mocks[${index}] must be an object.`);
|
|
10362
9493
|
const url = stringValue3(input.url) || stringValue3(input.glob) || stringValue3(input.pattern);
|
|
10363
9494
|
if (!url) throw new Error(`target.network_mocks[${index}] requires url.`);
|
|
10364
9495
|
const payload = normalizeNetworkMockResponsePayload(input, `target.network_mocks[${index}]`);
|
|
@@ -10513,7 +9644,7 @@ function normalizeNetworkMockResponses(value, mockIndex, defaults) {
|
|
|
10513
9644
|
abort_error_code: defaults.abort_error_code
|
|
10514
9645
|
};
|
|
10515
9646
|
return value.map((response, responseIndex) => {
|
|
10516
|
-
if (!
|
|
9647
|
+
if (!isRecord(response)) {
|
|
10517
9648
|
throw new Error(`target.network_mocks[${mockIndex}].responses[${responseIndex}] must be an object.`);
|
|
10518
9649
|
}
|
|
10519
9650
|
return normalizeNetworkMockResponsePayload(
|
|
@@ -10603,14 +9734,14 @@ function collectRiddleProofProfileEnvironmentBlockedWarnings(profile, blocker) {
|
|
|
10603
9734
|
return warnings;
|
|
10604
9735
|
}
|
|
10605
9736
|
function normalizeRouteInventoryPath(value, label) {
|
|
10606
|
-
const
|
|
10607
|
-
if (!
|
|
10608
|
-
if (!
|
|
10609
|
-
return normalizeRoutePath2(
|
|
9737
|
+
const path6 = stringValue3(value);
|
|
9738
|
+
if (!path6) throw new Error(`${label} requires path.`);
|
|
9739
|
+
if (!path6.startsWith("/")) throw new Error(`${label}.path must start with /.`);
|
|
9740
|
+
return normalizeRoutePath2(path6);
|
|
10610
9741
|
}
|
|
10611
9742
|
function normalizeRouteInventoryRoute(input, index) {
|
|
10612
9743
|
if (typeof input === "string") return { path: normalizeRouteInventoryPath(input, `checks route_inventory expected_routes[${index}]`) };
|
|
10613
|
-
if (!
|
|
9744
|
+
if (!isRecord(input)) throw new Error(`checks route_inventory expected_routes[${index}] must be a string or object.`);
|
|
10614
9745
|
return {
|
|
10615
9746
|
name: stringValue3(input.name),
|
|
10616
9747
|
path: normalizeRouteInventoryPath(input.path, `checks route_inventory expected_routes[${index}]`)
|
|
@@ -10685,16 +9816,16 @@ function normalizeHttpStatusBodyJsonAssertions(value, label) {
|
|
|
10685
9816
|
return value.map((item, index) => {
|
|
10686
9817
|
const itemLabel = `${label}[${index}]`;
|
|
10687
9818
|
if (typeof item === "string") {
|
|
10688
|
-
const
|
|
10689
|
-
if (!
|
|
10690
|
-
return { path:
|
|
9819
|
+
const path7 = stringValue3(item);
|
|
9820
|
+
if (!path7) throw new Error(`${itemLabel} path must not be empty.`);
|
|
9821
|
+
return { path: path7, exists: true };
|
|
10691
9822
|
}
|
|
10692
|
-
if (!
|
|
10693
|
-
const
|
|
10694
|
-
if (!
|
|
9823
|
+
if (!isRecord(item)) throw new Error(`${itemLabel} must be an object or JSON path string.`);
|
|
9824
|
+
const path6 = stringFromOwn(item, "path", "json_path", "jsonPath", "key");
|
|
9825
|
+
if (!path6) throw new Error(`${itemLabel}.path is required.`);
|
|
10695
9826
|
const assertion = {
|
|
10696
9827
|
label: stringValue3(item.label),
|
|
10697
|
-
path:
|
|
9828
|
+
path: path6
|
|
10698
9829
|
};
|
|
10699
9830
|
const exists = booleanValue2(valueFromOwn(item, "exists", "present"));
|
|
10700
9831
|
if (exists !== void 0) assertion.exists = exists;
|
|
@@ -10732,7 +9863,7 @@ function normalizeOrderedTraceEvents(value, label) {
|
|
|
10732
9863
|
const seenLabels = /* @__PURE__ */ new Set();
|
|
10733
9864
|
return value.map((item, eventIndex) => {
|
|
10734
9865
|
const eventLabel = `${label}[${eventIndex}]`;
|
|
10735
|
-
if (!
|
|
9866
|
+
if (!isRecord(item)) throw new Error(`${eventLabel} must be an object.`);
|
|
10736
9867
|
const name = stringFromOwn(item, "label", "name", "event");
|
|
10737
9868
|
if (!name) throw new Error(`${eventLabel}.label is required.`);
|
|
10738
9869
|
if (seenLabels.has(name)) throw new Error(`${eventLabel}.label must be unique.`);
|
|
@@ -10743,9 +9874,9 @@ function normalizeOrderedTraceEvents(value, label) {
|
|
|
10743
9874
|
}
|
|
10744
9875
|
const predicates = predicatesInput.map((predicateInput, predicateIndex) => {
|
|
10745
9876
|
const predicateLabel = `${eventLabel}.predicates[${predicateIndex}]`;
|
|
10746
|
-
if (!
|
|
10747
|
-
const
|
|
10748
|
-
if (!
|
|
9877
|
+
if (!isRecord(predicateInput)) throw new Error(`${predicateLabel} must be an object.`);
|
|
9878
|
+
const path6 = stringFromOwn(predicateInput, "path", "field", "key");
|
|
9879
|
+
if (!path6) throw new Error(`${predicateLabel}.path is required.`);
|
|
10749
9880
|
const op = stringFromOwn(predicateInput, "op", "operator");
|
|
10750
9881
|
if (!op || !RIDDLE_PROOF_ORDERED_TRACE_OPERATORS.includes(op)) {
|
|
10751
9882
|
throw new Error(`${predicateLabel}.op must be one of ${RIDDLE_PROOF_ORDERED_TRACE_OPERATORS.join(", ")}.`);
|
|
@@ -10763,7 +9894,7 @@ function normalizeOrderedTraceEvents(value, label) {
|
|
|
10763
9894
|
}
|
|
10764
9895
|
}
|
|
10765
9896
|
return {
|
|
10766
|
-
path:
|
|
9897
|
+
path: path6,
|
|
10767
9898
|
op,
|
|
10768
9899
|
value: requiresValue ? toJsonValue(value2) : void 0
|
|
10769
9900
|
};
|
|
@@ -10772,7 +9903,7 @@ function normalizeOrderedTraceEvents(value, label) {
|
|
|
10772
9903
|
});
|
|
10773
9904
|
}
|
|
10774
9905
|
function normalizeCheck(input, index) {
|
|
10775
|
-
if (!
|
|
9906
|
+
if (!isRecord(input)) throw new Error(`checks[${index}] must be an object.`);
|
|
10776
9907
|
const type = stringValue3(input.type);
|
|
10777
9908
|
if (!type) throw new Error(`checks[${index}].type is required.`);
|
|
10778
9909
|
if (!isSupportedCheckType(type)) {
|
|
@@ -10951,7 +10082,7 @@ function normalizeFailurePolicy(input) {
|
|
|
10951
10082
|
configuration_error: "fail",
|
|
10952
10083
|
needs_human_review: "fail"
|
|
10953
10084
|
};
|
|
10954
|
-
if (!
|
|
10085
|
+
if (!isRecord(input)) return defaults;
|
|
10955
10086
|
const next = { ...defaults };
|
|
10956
10087
|
for (const [key, value] of Object.entries(input)) {
|
|
10957
10088
|
if (!RIDDLE_PROOF_PROFILE_STATUSES.includes(key)) continue;
|
|
@@ -10962,12 +10093,12 @@ function normalizeFailurePolicy(input) {
|
|
|
10962
10093
|
return next;
|
|
10963
10094
|
}
|
|
10964
10095
|
function normalizeRiddleProofProfile(input, options = {}) {
|
|
10965
|
-
if (!
|
|
10096
|
+
if (!isRecord(input)) throw new Error("profile must be a JSON object.");
|
|
10966
10097
|
const version = stringValue3(input.version) || RIDDLE_PROOF_PROFILE_VERSION;
|
|
10967
10098
|
if (version !== RIDDLE_PROOF_PROFILE_VERSION) {
|
|
10968
10099
|
throw new Error(`Unsupported profile version ${version}. Expected ${RIDDLE_PROOF_PROFILE_VERSION}.`);
|
|
10969
10100
|
}
|
|
10970
|
-
const targetInput =
|
|
10101
|
+
const targetInput = isRecord(input.target) ? input.target : {};
|
|
10971
10102
|
const checks = Array.isArray(input.checks) ? input.checks.map(normalizeCheck) : [];
|
|
10972
10103
|
if (!checks.length) throw new Error("profile.checks must contain at least one check.");
|
|
10973
10104
|
const targetUrl = stringValue3(options.url) || stringValue3(targetInput.url);
|
|
@@ -11112,19 +10243,19 @@ function linkStatusContentTypeOk(result, check) {
|
|
|
11112
10243
|
function httpStatusBodyContainsFailures(result, check) {
|
|
11113
10244
|
const expected = check.body_contains?.filter(Boolean) ?? [];
|
|
11114
10245
|
if (!expected.length) return [];
|
|
11115
|
-
const observed =
|
|
10246
|
+
const observed = isRecord(result.body_contains) ? result.body_contains : {};
|
|
11116
10247
|
return expected.filter((text) => observed[text] !== true);
|
|
11117
10248
|
}
|
|
11118
10249
|
function httpStatusBodyNotContainsFailures(result, check) {
|
|
11119
10250
|
const forbidden = check.body_not_contains?.filter(Boolean) ?? [];
|
|
11120
10251
|
if (!forbidden.length) return [];
|
|
11121
|
-
const observed =
|
|
10252
|
+
const observed = isRecord(result.body_not_contains) ? result.body_not_contains : {};
|
|
11122
10253
|
return forbidden.filter((text) => observed[text] !== false);
|
|
11123
10254
|
}
|
|
11124
10255
|
function httpStatusBodyNotPatternFailures(result, check) {
|
|
11125
10256
|
const forbidden = check.body_not_patterns?.filter(Boolean) ?? [];
|
|
11126
10257
|
if (!forbidden.length) return [];
|
|
11127
|
-
const observed =
|
|
10258
|
+
const observed = isRecord(result.body_not_patterns) ? result.body_not_patterns : {};
|
|
11128
10259
|
return forbidden.filter((pattern) => observed[pattern] !== false);
|
|
11129
10260
|
}
|
|
11130
10261
|
function httpStatusBodyJsonAssertionFailures(result, check) {
|
|
@@ -11140,7 +10271,7 @@ function httpStatusBodyJsonAssertionFailures(result, check) {
|
|
|
11140
10271
|
errors: ["body_json_assertions evidence missing"]
|
|
11141
10272
|
}));
|
|
11142
10273
|
}
|
|
11143
|
-
return result.body_json_assertions.filter((assertion) =>
|
|
10274
|
+
return result.body_json_assertions.filter((assertion) => isRecord(assertion) && assertion.ok !== true).map((assertion) => ({
|
|
11144
10275
|
label: stringValue3(assertion.label) || stringValue3(assertion.path) || "json assertion",
|
|
11145
10276
|
path: stringValue3(assertion.path) || "",
|
|
11146
10277
|
ok: false,
|
|
@@ -11206,7 +10337,7 @@ async function responseBodyText(response) {
|
|
|
11206
10337
|
return { text: "", bytes: null };
|
|
11207
10338
|
}
|
|
11208
10339
|
function httpStatusRequestBody(check) {
|
|
11209
|
-
const headers =
|
|
10340
|
+
const headers = isRecord(check.headers) ? Object.fromEntries(Object.entries(check.headers).map(([key, value]) => [key, String(value)]).filter(([key]) => key.trim())) : {};
|
|
11210
10341
|
if (check.body_json !== void 0) {
|
|
11211
10342
|
if (!Object.keys(headers).some((key) => key.toLowerCase() === "content-type")) {
|
|
11212
10343
|
headers["content-type"] = "application/json";
|
|
@@ -11283,11 +10414,11 @@ async function preflightHttpStatusCheck(check, index, targetUrl, fetchImpl) {
|
|
|
11283
10414
|
content_type: stringValue3(result.content_type) ?? null,
|
|
11284
10415
|
content_length: numberValue2(result.content_length) ?? null,
|
|
11285
10416
|
bytes: numberValue2(result.bytes) ?? null,
|
|
11286
|
-
body_contains:
|
|
10417
|
+
body_contains: isRecord(result.body_contains) ? Object.fromEntries(Object.entries(result.body_contains).map(([key, value]) => [key, value === true])) : null,
|
|
11287
10418
|
body_contains_missing: bodyContainsMissing,
|
|
11288
|
-
body_not_contains:
|
|
10419
|
+
body_not_contains: isRecord(result.body_not_contains) ? Object.fromEntries(Object.entries(result.body_not_contains).map(([key, value]) => [key, value === true])) : null,
|
|
11289
10420
|
body_not_contains_found: bodyNotContainsFound,
|
|
11290
|
-
body_not_patterns:
|
|
10421
|
+
body_not_patterns: isRecord(result.body_not_patterns) ? Object.fromEntries(Object.entries(result.body_not_patterns).map(([key, value]) => [key, value === true])) : null,
|
|
11291
10422
|
body_not_patterns_found: bodyNotPatternsFound,
|
|
11292
10423
|
body_json_assertions: Array.isArray(result.body_json_assertions) ? result.body_json_assertions : null,
|
|
11293
10424
|
body_json_assertions_failed: bodyJsonAssertionsFailed
|
|
@@ -11315,7 +10446,7 @@ async function preflightRiddleProofProfileHttpStatusChecks(profile, options = {}
|
|
|
11315
10446
|
}
|
|
11316
10447
|
function httpStatusEvidenceForCheck(viewport, check) {
|
|
11317
10448
|
const evidence = viewport.http_statuses?.[httpStatusKey(check, viewport.url)];
|
|
11318
|
-
return
|
|
10449
|
+
return isRecord(evidence) ? evidence : void 0;
|
|
11319
10450
|
}
|
|
11320
10451
|
function summarizeHttpStatusEvidence(viewport, check) {
|
|
11321
10452
|
const key = httpStatusKey(check, viewport.url);
|
|
@@ -11371,11 +10502,11 @@ function summarizeHttpStatusEvidence(viewport, check) {
|
|
|
11371
10502
|
content_type: stringValue3(statusEvidence.content_type) ?? null,
|
|
11372
10503
|
content_length: numberValue2(statusEvidence.content_length) ?? null,
|
|
11373
10504
|
bytes: linkStatusObservedBytes(statusEvidence) ?? null,
|
|
11374
|
-
body_contains:
|
|
10505
|
+
body_contains: isRecord(statusEvidence.body_contains) ? toJsonValue(statusEvidence.body_contains) : null,
|
|
11375
10506
|
body_contains_missing: bodyContainsMissing,
|
|
11376
|
-
body_not_contains:
|
|
10507
|
+
body_not_contains: isRecord(statusEvidence.body_not_contains) ? toJsonValue(statusEvidence.body_not_contains) : null,
|
|
11377
10508
|
body_not_contains_found: bodyNotContainsFound,
|
|
11378
|
-
body_not_patterns:
|
|
10509
|
+
body_not_patterns: isRecord(statusEvidence.body_not_patterns) ? toJsonValue(statusEvidence.body_not_patterns) : null,
|
|
11379
10510
|
body_not_patterns_found: bodyNotPatternsFound,
|
|
11380
10511
|
body_json_assertions: Array.isArray(statusEvidence.body_json_assertions) ? toJsonValue(statusEvidence.body_json_assertions) : null,
|
|
11381
10512
|
body_json_assertions_failed: bodyJsonAssertionsFailed.map((assertion) => toJsonValue(assertion)),
|
|
@@ -11385,7 +10516,7 @@ function summarizeHttpStatusEvidence(viewport, check) {
|
|
|
11385
10516
|
}
|
|
11386
10517
|
function linkStatusEvidenceForCheck(viewport, check) {
|
|
11387
10518
|
const evidence = viewport.link_statuses?.[linkStatusSelector(check)];
|
|
11388
|
-
return
|
|
10519
|
+
return isRecord(evidence) ? evidence : void 0;
|
|
11389
10520
|
}
|
|
11390
10521
|
function summarizeLinkStatusEvidence(viewport, check) {
|
|
11391
10522
|
const linkEvidence = linkStatusEvidenceForCheck(viewport, check);
|
|
@@ -11399,7 +10530,7 @@ function summarizeLinkStatusEvidence(viewport, check) {
|
|
|
11399
10530
|
failures: [{ code: "link_status_evidence_missing" }]
|
|
11400
10531
|
};
|
|
11401
10532
|
}
|
|
11402
|
-
const results = Array.isArray(linkEvidence.results) ? linkEvidence.results.filter(
|
|
10533
|
+
const results = Array.isArray(linkEvidence.results) ? linkEvidence.results.filter(isRecord) : [];
|
|
11403
10534
|
const totalCount = numberValue2(linkEvidence.total_count) ?? results.length;
|
|
11404
10535
|
const resultCount = numberValue2(linkEvidence.result_count) ?? totalCount;
|
|
11405
10536
|
const storedResultCount = numberValue2(linkEvidence.stored_result_count) ?? results.length;
|
|
@@ -11442,7 +10573,7 @@ function summarizeLinkStatusEvidence(viewport, check) {
|
|
|
11442
10573
|
if (check.min_count !== void 0 && totalCount < check.min_count) {
|
|
11443
10574
|
failures.push({ code: "link_status_count_below_minimum", min_count: check.min_count, actual: totalCount });
|
|
11444
10575
|
}
|
|
11445
|
-
const statusCounts =
|
|
10576
|
+
const statusCounts = isRecord(linkEvidence.status_counts) ? linkEvidence.status_counts : {};
|
|
11446
10577
|
return {
|
|
11447
10578
|
viewport: viewport.name,
|
|
11448
10579
|
selector: linkStatusSelector(check),
|
|
@@ -11479,7 +10610,7 @@ function observeWithinKey(check) {
|
|
|
11479
10610
|
function textSequenceForCheck(viewport, check) {
|
|
11480
10611
|
const key = selectorKey(check);
|
|
11481
10612
|
const sequence = viewport.text_sequences?.[key];
|
|
11482
|
-
if (
|
|
10613
|
+
if (isRecord(sequence)) {
|
|
11483
10614
|
const visibleMatchTexts = Array.isArray(sequence.visible_match_texts) ? sequence.visible_match_texts : [];
|
|
11484
10615
|
const matchTexts = Array.isArray(sequence.match_texts) ? sequence.match_texts : [];
|
|
11485
10616
|
const visibleTexts = Array.isArray(sequence.visible_texts) ? sequence.visible_texts : [];
|
|
@@ -11509,9 +10640,9 @@ function textOrderMatch(texts, expectedTexts) {
|
|
|
11509
10640
|
}
|
|
11510
10641
|
function frameEvidenceForSelector(viewport, selector) {
|
|
11511
10642
|
const container = viewport.frames?.[selector];
|
|
11512
|
-
if (!
|
|
10643
|
+
if (!isRecord(container)) return [];
|
|
11513
10644
|
const frames = Array.isArray(container.frames) ? container.frames : [];
|
|
11514
|
-
return frames.filter((frame) =>
|
|
10645
|
+
return frames.filter((frame) => isRecord(frame));
|
|
11515
10646
|
}
|
|
11516
10647
|
function frameTextSample(frame) {
|
|
11517
10648
|
const parts = [
|
|
@@ -11531,7 +10662,7 @@ function summarizeRouteInventory(viewport, inventory) {
|
|
|
11531
10662
|
const sourceCandidateCount = numberValue2(inventory.source_candidate_count);
|
|
11532
10663
|
const sourceCandidateUniqueLinkCount = numberValue2(inventory.source_candidate_unique_link_count);
|
|
11533
10664
|
const sourceLinkScope = stringValue3(inventory.source_link_scope);
|
|
11534
|
-
const duplicateSourceLinks = Array.isArray(inventory.duplicate_source_link_paths) ? inventory.duplicate_source_link_paths.map((
|
|
10665
|
+
const duplicateSourceLinks = Array.isArray(inventory.duplicate_source_link_paths) ? inventory.duplicate_source_link_paths.map((path6) => String(path6)) : [];
|
|
11535
10666
|
const duplicateSourceLinkCount = numberValue2(inventory.duplicate_source_link_count) ?? (sourceLinkCount !== null && sourceUniqueLinkCount !== null ? Math.max(0, sourceLinkCount - sourceUniqueLinkCount) : null);
|
|
11536
10667
|
const failures = Array.isArray(inventory.failures) ? inventory.failures : [];
|
|
11537
10668
|
return {
|
|
@@ -11552,14 +10683,14 @@ function routeInventoryExpectedRouteSummaries(value, fallback) {
|
|
|
11552
10683
|
const rawRoutes = Array.isArray(value) ? value : Array.isArray(fallback) ? fallback : [];
|
|
11553
10684
|
return rawRoutes.map((route) => {
|
|
11554
10685
|
if (typeof route === "string") {
|
|
11555
|
-
const
|
|
11556
|
-
return
|
|
10686
|
+
const path7 = route.trim();
|
|
10687
|
+
return path7 ? { path: path7 } : void 0;
|
|
11557
10688
|
}
|
|
11558
|
-
if (!
|
|
11559
|
-
const
|
|
11560
|
-
if (!
|
|
10689
|
+
if (!isRecord(route)) return void 0;
|
|
10690
|
+
const path6 = stringValue3(route.path);
|
|
10691
|
+
if (!path6) return void 0;
|
|
11561
10692
|
const name = stringValue3(route.name);
|
|
11562
|
-
return name ? { name, path:
|
|
10693
|
+
return name ? { name, path: path6 } : { path: path6 };
|
|
11563
10694
|
}).filter((route) => Boolean(route));
|
|
11564
10695
|
}
|
|
11565
10696
|
function matchText(sample, check) {
|
|
@@ -11637,11 +10768,11 @@ function textCheckFailureSamples(viewport, check) {
|
|
|
11637
10768
|
return fallback ? [fallback] : [];
|
|
11638
10769
|
}
|
|
11639
10770
|
function allowedMessageSample(input) {
|
|
11640
|
-
if (!
|
|
10771
|
+
if (!isRecord(input)) return String(input || "");
|
|
11641
10772
|
const parts = [
|
|
11642
10773
|
input.text,
|
|
11643
10774
|
input.message,
|
|
11644
|
-
|
|
10775
|
+
isRecord(input.location) ? input.location.url : void 0
|
|
11645
10776
|
];
|
|
11646
10777
|
return parts.map((part) => String(part || "")).filter(Boolean).join(" ");
|
|
11647
10778
|
}
|
|
@@ -11658,12 +10789,12 @@ function matchesAllowedMessage(input, texts, patterns) {
|
|
|
11658
10789
|
return false;
|
|
11659
10790
|
}
|
|
11660
10791
|
function consoleEventLocationUrl(input) {
|
|
11661
|
-
if (!
|
|
10792
|
+
if (!isRecord(input) || !isRecord(input.location)) return void 0;
|
|
11662
10793
|
return stringValue3(input.location.url);
|
|
11663
10794
|
}
|
|
11664
10795
|
function expectedFailedNetworkMockEvents(evidence) {
|
|
11665
10796
|
return (evidence.network_mocks || []).filter((event) => {
|
|
11666
|
-
if (!
|
|
10797
|
+
if (!isRecord(event) || event.ok === false) return false;
|
|
11667
10798
|
const status = numberValue2(event.status);
|
|
11668
10799
|
const isHttpFailure = status !== void 0 && status >= 400;
|
|
11669
10800
|
const isAbortedMock = event.abort === true && Boolean(stringValue3(event.abort_error_code));
|
|
@@ -11693,11 +10824,11 @@ function expectedFailedNetworkMockConsoleEventSummary(event, evidence) {
|
|
|
11693
10824
|
abort_error_code: match ? stringValue3(match.abort_error_code) ?? null : null,
|
|
11694
10825
|
label: match ? stringValue3(match.label) ?? null : null,
|
|
11695
10826
|
response_label: match ? stringValue3(match.response_label) ?? null : null,
|
|
11696
|
-
text:
|
|
10827
|
+
text: isRecord(event) && typeof event.text === "string" ? event.text.slice(0, 300) : sample.slice(0, 300)
|
|
11697
10828
|
};
|
|
11698
10829
|
}
|
|
11699
|
-
function normalizeRoutePath2(
|
|
11700
|
-
const value =
|
|
10830
|
+
function normalizeRoutePath2(path6) {
|
|
10831
|
+
const value = path6 || "/";
|
|
11701
10832
|
if (value === "/") return "/";
|
|
11702
10833
|
return value.replace(/\/+$/, "") || "/";
|
|
11703
10834
|
}
|
|
@@ -12240,7 +11371,7 @@ function assessCheckFromEvidence(check, evidence) {
|
|
|
12240
11371
|
};
|
|
12241
11372
|
}
|
|
12242
11373
|
if (check.type === "route_inventory") {
|
|
12243
|
-
const inventories = viewports.map((viewport) => ({ viewport: viewport.name, inventory: viewport.route_inventory })).filter((item) =>
|
|
11374
|
+
const inventories = viewports.map((viewport) => ({ viewport: viewport.name, inventory: viewport.route_inventory })).filter((item) => isRecord(item.inventory));
|
|
12244
11375
|
if (!inventories.length) {
|
|
12245
11376
|
return {
|
|
12246
11377
|
type: check.type,
|
|
@@ -12263,7 +11394,7 @@ function assessCheckFromEvidence(check, evidence) {
|
|
|
12263
11394
|
const sourceCandidateCount = numberValue2(first?.source_candidate_count);
|
|
12264
11395
|
const sourceCandidateUniqueLinkCount = numberValue2(first?.source_candidate_unique_link_count);
|
|
12265
11396
|
const sourceLinkScope = stringValue3(first?.source_link_scope);
|
|
12266
|
-
const duplicateSourceLinks = Array.isArray(first?.duplicate_source_link_paths) ? first.duplicate_source_link_paths.map((
|
|
11397
|
+
const duplicateSourceLinks = Array.isArray(first?.duplicate_source_link_paths) ? first.duplicate_source_link_paths.map((path6) => String(path6)) : [];
|
|
12267
11398
|
const duplicateSourceLinkCount = numberValue2(first?.duplicate_source_link_count) ?? (sourceLinkCount !== null && sourceUniqueLinkCount !== null ? Math.max(0, sourceLinkCount - sourceUniqueLinkCount) : null);
|
|
12268
11399
|
const expectedRoutes = routeInventoryExpectedRouteSummaries(first?.expected_routes, check.expected_routes);
|
|
12269
11400
|
return {
|
|
@@ -18625,18 +17756,18 @@ function collectRiddleProfileArtifactRefs(input) {
|
|
|
18625
17756
|
const indexes = /* @__PURE__ */ new Map();
|
|
18626
17757
|
const priorities = /* @__PURE__ */ new Map();
|
|
18627
17758
|
function add(item, source) {
|
|
18628
|
-
if (!
|
|
17759
|
+
if (!isRecord(item)) return;
|
|
18629
17760
|
const url = stringValue3(item.url);
|
|
18630
|
-
const
|
|
18631
|
-
const rawName = stringValue3(item.name) || stringValue3(item.filename) || artifactNameFromPath(url ||
|
|
17761
|
+
const path6 = stringValue3(item.path);
|
|
17762
|
+
const rawName = stringValue3(item.name) || stringValue3(item.filename) || artifactNameFromPath(url || path6) || "";
|
|
18632
17763
|
const name = normalizeRiddleProfileArtifactName(rawName);
|
|
18633
|
-
if (!name && !url && !
|
|
18634
|
-
const key = profileArtifactDedupeKey(name, url ||
|
|
17764
|
+
if (!name && !url && !path6) return;
|
|
17765
|
+
const key = profileArtifactDedupeKey(name, url || path6 || "");
|
|
18635
17766
|
const priority = profileArtifactPriority(rawName, name);
|
|
18636
17767
|
const ref = {
|
|
18637
17768
|
name,
|
|
18638
17769
|
url,
|
|
18639
|
-
path:
|
|
17770
|
+
path: path6,
|
|
18640
17771
|
kind: stringValue3(item.kind) || stringValue3(item.type),
|
|
18641
17772
|
content_type: stringValue3(item.content_type) || stringValue3(item.contentType),
|
|
18642
17773
|
source
|
|
@@ -18658,7 +17789,7 @@ function collectRiddleProfileArtifactRefs(input) {
|
|
|
18658
17789
|
for (const item of value) add(item, source);
|
|
18659
17790
|
return;
|
|
18660
17791
|
}
|
|
18661
|
-
if (!
|
|
17792
|
+
if (!isRecord(value)) return;
|
|
18662
17793
|
for (const key of ["artifacts", "outputs", "screenshots", "files"]) {
|
|
18663
17794
|
if (Array.isArray(value[key])) visit(value[key], key);
|
|
18664
17795
|
}
|
|
@@ -18692,26 +17823,38 @@ var PROFILE_SINGLETON_ARTIFACT_NAMES = /* @__PURE__ */ new Set([
|
|
|
18692
17823
|
"dom-summary.json"
|
|
18693
17824
|
]);
|
|
18694
17825
|
function extractRiddleProofProfileResult(input) {
|
|
18695
|
-
if (!
|
|
17826
|
+
if (!isRecord(input)) return void 0;
|
|
18696
17827
|
if (input.version === RIDDLE_PROOF_PROFILE_RESULT_VERSION) return input;
|
|
18697
17828
|
const candidates = [
|
|
18698
17829
|
input.result,
|
|
18699
17830
|
input.return_value,
|
|
18700
17831
|
input.value,
|
|
18701
17832
|
input.profile_result,
|
|
18702
|
-
|
|
18703
|
-
|
|
17833
|
+
isRecord(input["proof.json"]) ? input["proof.json"] : void 0,
|
|
17834
|
+
isRecord(input._proof_json) ? input._proof_json : void 0
|
|
18704
17835
|
];
|
|
18705
17836
|
for (const candidate of candidates) {
|
|
18706
17837
|
const result = extractRiddleProofProfileResult(candidate);
|
|
18707
17838
|
if (result) return result;
|
|
18708
17839
|
}
|
|
18709
|
-
if (
|
|
17840
|
+
if (isRecord(input._artifact_json)) {
|
|
18710
17841
|
return extractRiddleProofProfileResult(input._artifact_json["proof.json"]);
|
|
18711
17842
|
}
|
|
18712
17843
|
return void 0;
|
|
18713
17844
|
}
|
|
18714
17845
|
|
|
17846
|
+
// src/receipts.ts
|
|
17847
|
+
var receipts_exports = {};
|
|
17848
|
+
__export(receipts_exports, {
|
|
17849
|
+
RIDDLE_PREVIEW_RECEIPT_VERSION: () => import_receipts.RIDDLE_PREVIEW_RECEIPT_VERSION,
|
|
17850
|
+
RIDDLE_PROOF_OBSERVATION_RECEIPT_VERSION: () => import_receipts.RIDDLE_PROOF_OBSERVATION_RECEIPT_VERSION,
|
|
17851
|
+
createRiddleProofObservationReceipt: () => import_receipts.createRiddleProofObservationReceipt,
|
|
17852
|
+
parseRiddlePreviewReceipt: () => import_receipts.parseRiddlePreviewReceipt,
|
|
17853
|
+
parseRiddleProofObservationReceipt: () => import_receipts.parseRiddleProofObservationReceipt
|
|
17854
|
+
});
|
|
17855
|
+
__reExport(receipts_exports, require("@riddledc/riddle-proof-core/receipts"));
|
|
17856
|
+
var import_receipts = require("@riddledc/riddle-proof-core/receipts");
|
|
17857
|
+
|
|
18715
17858
|
// src/change-proof.ts
|
|
18716
17859
|
var RIDDLE_PROOF_CHANGE_RESULT_VERSION = "riddle-proof.change-result.v1";
|
|
18717
17860
|
var RIDDLE_PROOF_CHANGE_RECEIPT_V1_VERSION = "riddle-proof.change-receipt.v1";
|
|
@@ -19053,7 +18196,7 @@ function changeReceiptVerdict(status) {
|
|
|
19053
18196
|
if (status === "proof_insufficient") return "proof_insufficient";
|
|
19054
18197
|
return "not_mergeable";
|
|
19055
18198
|
}
|
|
19056
|
-
function
|
|
18199
|
+
function profileCheckCounts(result) {
|
|
19057
18200
|
const counts = {
|
|
19058
18201
|
total: result.checks.length,
|
|
19059
18202
|
passed: 0,
|
|
@@ -19126,7 +18269,7 @@ function observationExecutor(result) {
|
|
|
19126
18269
|
function observationForReceiptSide(side, result, source, sourceIdentity) {
|
|
19127
18270
|
if (!result) throw new Error(`${side}_result or ${side}_observation is required.`);
|
|
19128
18271
|
if (!source) throw new Error(`${side}_source or ${side}_observation is required.`);
|
|
19129
|
-
return createRiddleProofObservationReceipt({
|
|
18272
|
+
return (0, import_receipts.createRiddleProofObservationReceipt)({
|
|
19130
18273
|
comparison_role: side,
|
|
19131
18274
|
executor: observationExecutor(result),
|
|
19132
18275
|
target: { kind: "url", url: source },
|
|
@@ -19137,8 +18280,8 @@ function observationForReceiptSide(side, result, source, sourceIdentity) {
|
|
|
19137
18280
|
});
|
|
19138
18281
|
}
|
|
19139
18282
|
function createRiddleProofChangeReceipt(input) {
|
|
19140
|
-
const before = input.before_observation ? parseRiddleProofObservationReceipt(input.before_observation) : observationForReceiptSide("before", input.before_result, input.before_source, input.before_source_identity);
|
|
19141
|
-
const after = input.after_observation ? parseRiddleProofObservationReceipt(input.after_observation) : observationForReceiptSide("after", input.after_result, input.after_source, input.after_source_identity);
|
|
18283
|
+
const before = input.before_observation ? (0, import_receipts.parseRiddleProofObservationReceipt)(input.before_observation) : observationForReceiptSide("before", input.before_result, input.before_source, input.before_source_identity);
|
|
18284
|
+
const after = input.after_observation ? (0, import_receipts.parseRiddleProofObservationReceipt)(input.after_observation) : observationForReceiptSide("after", input.after_result, input.after_source, input.after_source_identity);
|
|
19142
18285
|
const verdict = changeReceiptVerdict(input.result.status);
|
|
19143
18286
|
const shippingAuthorization = input.shipping_authorization || noShippingAuthorization();
|
|
19144
18287
|
assertShippingAuthorizationConsistent(shippingAuthorization, "Change receipt");
|
|
@@ -19168,7 +18311,7 @@ function createRiddleProofChangeReceipt(input) {
|
|
|
19168
18311
|
metadata: input.result.metadata
|
|
19169
18312
|
};
|
|
19170
18313
|
}
|
|
19171
|
-
function
|
|
18314
|
+
function isRecord2(value) {
|
|
19172
18315
|
return Boolean(value) && typeof value === "object" && !Array.isArray(value);
|
|
19173
18316
|
}
|
|
19174
18317
|
function migratedObservationFromLegacySide(side, legacy) {
|
|
@@ -19245,7 +18388,7 @@ function migrateRiddleProofChangeReceipt(legacy) {
|
|
|
19245
18388
|
};
|
|
19246
18389
|
}
|
|
19247
18390
|
function parseRiddleProofChangeReceipt(value) {
|
|
19248
|
-
if (!
|
|
18391
|
+
if (!isRecord2(value)) throw new Error("Change receipt must be an object.");
|
|
19249
18392
|
if (value.version === RIDDLE_PROOF_CHANGE_RECEIPT_V1_VERSION) {
|
|
19250
18393
|
return migrateRiddleProofChangeReceipt(value);
|
|
19251
18394
|
}
|
|
@@ -19256,8 +18399,8 @@ function parseRiddleProofChangeReceipt(value) {
|
|
|
19256
18399
|
if (!RIDDLE_PROOF_PROFILE_STATUSES.includes(receipt.status)) {
|
|
19257
18400
|
throw new Error(`Unsupported Change receipt status ${String(receipt.status || "missing")}.`);
|
|
19258
18401
|
}
|
|
19259
|
-
parseRiddleProofObservationReceipt(receipt.before);
|
|
19260
|
-
parseRiddleProofObservationReceipt(receipt.after);
|
|
18402
|
+
(0, import_receipts.parseRiddleProofObservationReceipt)(receipt.before);
|
|
18403
|
+
(0, import_receipts.parseRiddleProofObservationReceipt)(receipt.after);
|
|
19261
18404
|
if (receipt.before.comparison_role !== "before" || receipt.after.comparison_role !== "after") {
|
|
19262
18405
|
throw new Error("Change receipt observations must preserve their before and after comparison roles.");
|
|
19263
18406
|
}
|
|
@@ -19289,8 +18432,8 @@ function createRiddleProofHandoffReceipt(changeReceipt, options = {}) {
|
|
|
19289
18432
|
};
|
|
19290
18433
|
}
|
|
19291
18434
|
function parseRiddleProofHandoffReceipt(value) {
|
|
19292
|
-
if (!
|
|
19293
|
-
throw new Error(`Unsupported Handoff receipt version ${String(
|
|
18435
|
+
if (!isRecord2(value) || value.version !== RIDDLE_PROOF_HANDOFF_RECEIPT_VERSION) {
|
|
18436
|
+
throw new Error(`Unsupported Handoff receipt version ${String(isRecord2(value) ? value.version || "missing" : "missing")}.`);
|
|
19294
18437
|
}
|
|
19295
18438
|
const receipt = value;
|
|
19296
18439
|
if (!Number.isFinite(Date.parse(receipt.created_at))) {
|
|
@@ -19345,7 +18488,7 @@ function receiptSideView(side, observation) {
|
|
|
19345
18488
|
summary: summary?.summary || observation.proof?.result.summary || "No profile summary recorded.",
|
|
19346
18489
|
route: summary?.route,
|
|
19347
18490
|
captured_at: observation.captured_at,
|
|
19348
|
-
checks: summary?.checks || (observation.proof ?
|
|
18491
|
+
checks: summary?.checks || (observation.proof ? profileCheckCounts(observation.proof.result) : {
|
|
19349
18492
|
total: 0,
|
|
19350
18493
|
passed: 0,
|
|
19351
18494
|
failed: 0,
|
|
@@ -19703,7 +18846,7 @@ function pageSummaries(result) {
|
|
|
19703
18846
|
}
|
|
19704
18847
|
return pages;
|
|
19705
18848
|
}
|
|
19706
|
-
function
|
|
18849
|
+
function profileCheckCounts2(result) {
|
|
19707
18850
|
const checks = asArray(result.checks);
|
|
19708
18851
|
if (checks.length) {
|
|
19709
18852
|
let passed2 = 0;
|
|
@@ -19842,7 +18985,7 @@ function summarizeRiddleProofPrComment(input) {
|
|
|
19842
18985
|
const resultDetails = asRecord2(result.details);
|
|
19843
18986
|
const resultRaw = asRecord2(result.raw);
|
|
19844
18987
|
const rawDetails = asRecord2(resultRaw.details);
|
|
19845
|
-
const profileChecks = profileResult ?
|
|
18988
|
+
const profileChecks = profileResult ? profileCheckCounts2(result) : void 0;
|
|
19846
18989
|
const changeChecks = changeResult ? changeReceiptCheckCounts(result) : void 0;
|
|
19847
18990
|
const artifacts = mergeArtifacts(
|
|
19848
18991
|
collectArtifacts(runResponse),
|
|
@@ -20498,18 +19641,18 @@ var DEFAULT_PROFILE_UNSUBMITTED_RETRIES = 2;
|
|
|
20498
19641
|
function cliPackageRoot() {
|
|
20499
19642
|
const entryPath = process.argv[1] ? (() => {
|
|
20500
19643
|
try {
|
|
20501
|
-
return (0,
|
|
19644
|
+
return (0, import_node_fs5.realpathSync)(process.argv[1]);
|
|
20502
19645
|
} catch {
|
|
20503
19646
|
return process.argv[1];
|
|
20504
19647
|
}
|
|
20505
19648
|
})() : "";
|
|
20506
19649
|
const candidates = [
|
|
20507
|
-
entryPath ?
|
|
20508
|
-
|
|
19650
|
+
entryPath ? import_node_path5.default.resolve(import_node_path5.default.dirname(entryPath), "..") : "",
|
|
19651
|
+
import_node_path5.default.resolve(process.cwd(), "packages", "riddle-proof"),
|
|
20509
19652
|
process.cwd()
|
|
20510
19653
|
].filter(Boolean);
|
|
20511
19654
|
for (const candidate of candidates) {
|
|
20512
|
-
if ((0,
|
|
19655
|
+
if ((0, import_node_fs5.existsSync)(import_node_path5.default.join(candidate, "runtime", "tests", "trust_boundary_regression.py")) && (0, import_node_fs5.existsSync)(import_node_path5.default.join(candidate, "examples", "regression-packs"))) {
|
|
20513
19656
|
return candidate;
|
|
20514
19657
|
}
|
|
20515
19658
|
}
|
|
@@ -20606,16 +19749,16 @@ function regressionPackResultFormatOption(options) {
|
|
|
20606
19749
|
}
|
|
20607
19750
|
function regressionPackPathForCli(options) {
|
|
20608
19751
|
const packFile = optionString(options, "packFile");
|
|
20609
|
-
if (packFile) return
|
|
19752
|
+
if (packFile) return import_node_path5.default.resolve(packFile);
|
|
20610
19753
|
const pack = optionString(options, "pack") || "oc-flow-regression";
|
|
20611
|
-
if ((0,
|
|
19754
|
+
if ((0, import_node_fs5.existsSync)(pack)) return import_node_path5.default.resolve(pack);
|
|
20612
19755
|
const normalized = pack.endsWith(".json") ? pack : `${pack}.json`;
|
|
20613
|
-
return
|
|
19756
|
+
return import_node_path5.default.join(CLI_PACKAGE_ROOT, "examples", "regression-packs", normalized);
|
|
20614
19757
|
}
|
|
20615
19758
|
function readRegressionPackForCli(options) {
|
|
20616
19759
|
const filePath = regressionPackPathForCli(options);
|
|
20617
|
-
if (!(0,
|
|
20618
|
-
const parsed = JSON.parse((0,
|
|
19760
|
+
if (!(0, import_node_fs5.existsSync)(filePath)) throw new Error(`Regression pack not found: ${filePath}`);
|
|
19761
|
+
const parsed = JSON.parse((0, import_node_fs5.readFileSync)(filePath, "utf-8"));
|
|
20619
19762
|
if (parsed.version !== "riddle-proof.regression-pack.v1") {
|
|
20620
19763
|
throw new Error(`${filePath} is not a riddle-proof.regression-pack.v1 manifest.`);
|
|
20621
19764
|
}
|
|
@@ -20632,7 +19775,7 @@ function regressionPackCommandForLocalCore(pack) {
|
|
|
20632
19775
|
return cliString(suite.command) || "python3 packages/riddle-proof/runtime/tests/trust_boundary_regression.py";
|
|
20633
19776
|
}
|
|
20634
19777
|
function regressionPackLocalCoreScriptPath() {
|
|
20635
|
-
return
|
|
19778
|
+
return import_node_path5.default.join(CLI_PACKAGE_ROOT, "runtime", "tests", "trust_boundary_regression.py");
|
|
20636
19779
|
}
|
|
20637
19780
|
function tailLines(text, limit = 40) {
|
|
20638
19781
|
const lines = text.split(/\r?\n/).filter((line) => line.trim().length > 0);
|
|
@@ -20672,7 +19815,7 @@ function runRegressionPackLocalCore(pack) {
|
|
|
20672
19815
|
const forbiddenMarkers = regressionPackStringArray(pack.forbidden_terminal_markers);
|
|
20673
19816
|
const command = regressionPackCommandForLocalCore(pack);
|
|
20674
19817
|
const startedAt = (/* @__PURE__ */ new Date()).toISOString();
|
|
20675
|
-
if (!(0,
|
|
19818
|
+
if (!(0, import_node_fs5.existsSync)(script)) {
|
|
20676
19819
|
return {
|
|
20677
19820
|
requested: true,
|
|
20678
19821
|
ok: false,
|
|
@@ -20685,7 +19828,7 @@ function runRegressionPackLocalCore(pack) {
|
|
|
20685
19828
|
forbidden_terminal_markers_seen: []
|
|
20686
19829
|
};
|
|
20687
19830
|
}
|
|
20688
|
-
const child = (0,
|
|
19831
|
+
const child = (0, import_node_child_process4.spawnSync)("python3", [script], {
|
|
20689
19832
|
cwd: CLI_PACKAGE_ROOT,
|
|
20690
19833
|
encoding: "utf-8",
|
|
20691
19834
|
timeout: 12e4
|
|
@@ -20709,7 +19852,7 @@ function runRegressionPackLocalCore(pack) {
|
|
|
20709
19852
|
command,
|
|
20710
19853
|
executed: {
|
|
20711
19854
|
binary: "python3",
|
|
20712
|
-
args: [
|
|
19855
|
+
args: [import_node_path5.default.relative(CLI_PACKAGE_ROOT, script)],
|
|
20713
19856
|
cwd: CLI_PACKAGE_ROOT
|
|
20714
19857
|
},
|
|
20715
19858
|
exit_code: child.status,
|
|
@@ -20761,7 +19904,7 @@ function regressionPackHostedRiddlePlan(pack) {
|
|
|
20761
19904
|
};
|
|
20762
19905
|
}
|
|
20763
19906
|
function regressionPackHostedRiddleCaseOutputDir(outputDir, caseId) {
|
|
20764
|
-
return outputDir ?
|
|
19907
|
+
return outputDir ? import_node_path5.default.join(outputDir, "hosted-riddle", safeProfileOutputSegment(caseId)) : void 0;
|
|
20765
19908
|
}
|
|
20766
19909
|
function compactHostedRiddleCaseResult(testCase, result, ok) {
|
|
20767
19910
|
const expectedMessage = regressionPackHostedRiddleExpectedMessage(testCase);
|
|
@@ -20799,7 +19942,7 @@ function hostedRiddleBlockedCaseResult(testCase, error, environmentBlocker) {
|
|
|
20799
19942
|
}
|
|
20800
19943
|
async function hostedRiddleSuiteEnvironmentBlocker(cases, options) {
|
|
20801
19944
|
if (!runProfileBalancePreflightOption(options) || !cases.length) return void 0;
|
|
20802
|
-
const client = createRiddleApiClient(riddleClientConfig(options));
|
|
19945
|
+
const client = (0, import_client.createRiddleApiClient)(riddleClientConfig(options));
|
|
20803
19946
|
const requiredSeconds = cases.length * RIDDLE_PROFILE_BALANCE_PREFLIGHT_MIN_SECONDS_PER_JOB;
|
|
20804
19947
|
let balance;
|
|
20805
19948
|
try {
|
|
@@ -20810,7 +19953,7 @@ async function hostedRiddleSuiteEnvironmentBlocker(cases, options) {
|
|
|
20810
19953
|
error: message,
|
|
20811
19954
|
environment_blocker: {
|
|
20812
19955
|
source: "riddle_api",
|
|
20813
|
-
endpoint:
|
|
19956
|
+
endpoint: import_client.RIDDLE_BALANCE_ENDPOINT_PATH,
|
|
20814
19957
|
reason: "balance_preflight_failed",
|
|
20815
19958
|
balance_preflight: true,
|
|
20816
19959
|
job_count: cases.length,
|
|
@@ -20830,7 +19973,7 @@ async function hostedRiddleSuiteEnvironmentBlocker(cases, options) {
|
|
|
20830
19973
|
error: `Riddle hosted regression balance preflight failed: ${availableSeconds}s available for ${cases.length} serial hosted job(s), minimum ${requiredSeconds}s required.`,
|
|
20831
19974
|
environment_blocker: {
|
|
20832
19975
|
source: "riddle_api",
|
|
20833
|
-
endpoint:
|
|
19976
|
+
endpoint: import_client.RIDDLE_BALANCE_ENDPOINT_PATH,
|
|
20834
19977
|
reason: "insufficient_balance",
|
|
20835
19978
|
error: "Insufficient available balance",
|
|
20836
19979
|
balance_preflight: true,
|
|
@@ -21095,13 +20238,13 @@ function regressionPackRunMarkdown(result) {
|
|
|
21095
20238
|
}
|
|
21096
20239
|
function writeRegressionPackOutput(outputDir, result) {
|
|
21097
20240
|
if (!outputDir) return;
|
|
21098
|
-
(0,
|
|
21099
|
-
(0,
|
|
20241
|
+
(0, import_node_fs5.mkdirSync)(outputDir, { recursive: true });
|
|
20242
|
+
(0, import_node_fs5.writeFileSync)(import_node_path5.default.join(outputDir, "regression-pack-result.json"), `${JSON.stringify(result, null, 2)}
|
|
21100
20243
|
`);
|
|
21101
|
-
(0,
|
|
21102
|
-
(0,
|
|
20244
|
+
(0, import_node_fs5.writeFileSync)(import_node_path5.default.join(outputDir, "summary.md"), regressionPackRunMarkdown(result));
|
|
20245
|
+
(0, import_node_fs5.writeFileSync)(import_node_path5.default.join(outputDir, "hosted-riddle-handoff.md"), `${cliString(result.hosted_riddle_handoff_prompt) || ""}
|
|
21103
20246
|
`);
|
|
21104
|
-
(0,
|
|
20247
|
+
(0, import_node_fs5.writeFileSync)(import_node_path5.default.join(outputDir, "oc-handoff.md"), `${cliString(result.openclaw_handoff_prompt) || ""}
|
|
21105
20248
|
`);
|
|
21106
20249
|
}
|
|
21107
20250
|
async function runRegressionPackForCli(options) {
|
|
@@ -21169,7 +20312,7 @@ function previewFrameworkOption(options) {
|
|
|
21169
20312
|
throw new Error("--framework must be spa or static.");
|
|
21170
20313
|
}
|
|
21171
20314
|
function readStdin() {
|
|
21172
|
-
return (0,
|
|
20315
|
+
return (0, import_node_fs5.readFileSync)(0, "utf-8");
|
|
21173
20316
|
}
|
|
21174
20317
|
async function readTextValue(value, label) {
|
|
21175
20318
|
if (!value) throw new Error(`${label} is required.`);
|
|
@@ -21180,7 +20323,7 @@ async function readTextValue(value, label) {
|
|
|
21180
20323
|
if (!response.ok) throw new Error(`${label} URL failed HTTP ${response.status}: ${text.slice(0, 500)}`);
|
|
21181
20324
|
return text;
|
|
21182
20325
|
}
|
|
21183
|
-
if ((0,
|
|
20326
|
+
if ((0, import_node_fs5.existsSync)(value)) return (0, import_node_fs5.readFileSync)(value, "utf-8");
|
|
21184
20327
|
throw new Error(`${label} must be a readable file path, URL, or -.`);
|
|
21185
20328
|
}
|
|
21186
20329
|
function formatPollDuration(ms) {
|
|
@@ -21229,11 +20372,11 @@ function riddlePreviewProgressLine(snapshot) {
|
|
|
21229
20372
|
return `[riddle-preview] ${snapshot.stage}${idPart}${statusPart}${attemptPart} elapsed=${formatPollDuration(snapshot.elapsed_ms)} label=${snapshot.label} framework=${snapshot.framework}${filePart}${totalPart}${archivePart}${previewPart}${recoveryPart}${messagePart}`;
|
|
21230
20373
|
}
|
|
21231
20374
|
function readJsonFileIfExists(filePath) {
|
|
21232
|
-
if (!filePath || !(0,
|
|
20375
|
+
if (!filePath || !(0, import_node_fs5.existsSync)(filePath)) return void 0;
|
|
21233
20376
|
return readJsonValue(filePath, filePath);
|
|
21234
20377
|
}
|
|
21235
20378
|
function defaultProofDirJsonPath(proofDir, filename) {
|
|
21236
|
-
return proofDir ?
|
|
20379
|
+
return proofDir ? import_node_path5.default.join(proofDir, filename) : void 0;
|
|
21237
20380
|
}
|
|
21238
20381
|
function prNumberFromValue(value) {
|
|
21239
20382
|
const text = value?.trim();
|
|
@@ -21242,7 +20385,7 @@ function prNumberFromValue(value) {
|
|
|
21242
20385
|
return match ? match[1] : text;
|
|
21243
20386
|
}
|
|
21244
20387
|
function ghJson(args, input) {
|
|
21245
|
-
const result = (0,
|
|
20388
|
+
const result = (0, import_node_child_process4.spawnSync)("gh", args, {
|
|
21246
20389
|
input: typeof input === "undefined" ? void 0 : `${JSON.stringify(input)}
|
|
21247
20390
|
`,
|
|
21248
20391
|
encoding: "utf-8",
|
|
@@ -21258,7 +20401,7 @@ function ghJson(args, input) {
|
|
|
21258
20401
|
}
|
|
21259
20402
|
function resolveGhRepoName(repoOption) {
|
|
21260
20403
|
if (repoOption?.trim()) return repoOption.trim();
|
|
21261
|
-
const result = (0,
|
|
20404
|
+
const result = (0, import_node_child_process4.spawnSync)("gh", ["repo", "view", "--json", "nameWithOwner", "--jq", ".nameWithOwner"], {
|
|
21262
20405
|
encoding: "utf-8",
|
|
21263
20406
|
timeout: 3e4
|
|
21264
20407
|
});
|
|
@@ -21305,7 +20448,7 @@ function upsertPrComment(input) {
|
|
|
21305
20448
|
}
|
|
21306
20449
|
function readJsonValue(value, label) {
|
|
21307
20450
|
if (!value) throw new Error(`${label} is required.`);
|
|
21308
|
-
const raw = value === "-" ? readStdin() : (0,
|
|
20451
|
+
const raw = value === "-" ? readStdin() : (0, import_node_fs5.existsSync)(value) ? (0, import_node_fs5.readFileSync)(value, "utf-8") : value;
|
|
21309
20452
|
const parsed = JSON.parse(raw);
|
|
21310
20453
|
if (!parsed || typeof parsed !== "object" || Array.isArray(parsed)) {
|
|
21311
20454
|
throw new Error(`${label} must be a JSON object.`);
|
|
@@ -21314,7 +20457,7 @@ function readJsonValue(value, label) {
|
|
|
21314
20457
|
}
|
|
21315
20458
|
function readJsonAnyValue(value, label) {
|
|
21316
20459
|
if (!value) throw new Error(`${label} is required.`);
|
|
21317
|
-
const raw = value === "-" ? readStdin() : (0,
|
|
20460
|
+
const raw = value === "-" ? readStdin() : (0, import_node_fs5.existsSync)(value) ? (0, import_node_fs5.readFileSync)(value, "utf-8") : value;
|
|
21318
20461
|
return JSON.parse(raw);
|
|
21319
20462
|
}
|
|
21320
20463
|
function readOptionalJsonRecord(value, label) {
|
|
@@ -21323,7 +20466,7 @@ function readOptionalJsonRecord(value, label) {
|
|
|
21323
20466
|
}
|
|
21324
20467
|
function readOptionalJsonStringArray(value, label) {
|
|
21325
20468
|
if (!value) return void 0;
|
|
21326
|
-
const parsed = value === "-" ? JSON.parse(readStdin()) : (0,
|
|
20469
|
+
const parsed = value === "-" ? JSON.parse(readStdin()) : (0, import_node_fs5.existsSync)(value) ? JSON.parse((0, import_node_fs5.readFileSync)(value, "utf-8")) : JSON.parse(value);
|
|
21327
20470
|
if (!Array.isArray(parsed) || parsed.some((item) => typeof item !== "string")) {
|
|
21328
20471
|
throw new Error(`${label} must be a JSON array of strings.`);
|
|
21329
20472
|
}
|
|
@@ -21468,7 +20611,7 @@ function parseProfileViewports(value) {
|
|
|
21468
20611
|
return value.split(",").map((part, index) => {
|
|
21469
20612
|
const trimmed = part.trim();
|
|
21470
20613
|
const named = /^([a-zA-Z0-9_-]+)=(\d+x\d+)$/.exec(trimmed);
|
|
21471
|
-
const viewport = parseRiddleViewport(named ? named[2] : trimmed);
|
|
20614
|
+
const viewport = (0, import_client.parseRiddleViewport)(named ? named[2] : trimmed);
|
|
21472
20615
|
if (!viewport) throw new Error(`Invalid viewport ${trimmed}.`);
|
|
21473
20616
|
return {
|
|
21474
20617
|
name: named ? named[1] : `viewport-${index + 1}`,
|
|
@@ -21708,7 +20851,7 @@ function profileRiddleJobMarkdown(result) {
|
|
|
21708
20851
|
lines.push("- artifact recovery: used artifacts endpoint after non-terminal poll");
|
|
21709
20852
|
}
|
|
21710
20853
|
if (retryCount !== void 0 && retryCount > 0) {
|
|
21711
|
-
lines.push(`- retry recovery: replaced ${retryCount} unsubmitted hosted job${retryCount === 1 ? "" : "s"}${staleJobIds.length ? ` (${staleJobIds.map((value) => markdownInlineCode(value)).join(", ")})` : ""}; ${RIDDLE_UNSUBMITTED_WAKE_HINT}`);
|
|
20854
|
+
lines.push(`- retry recovery: replaced ${retryCount} unsubmitted hosted job${retryCount === 1 ? "" : "s"}${staleJobIds.length ? ` (${staleJobIds.map((value) => markdownInlineCode(value)).join(", ")})` : ""}; ${import_client.RIDDLE_UNSUBMITTED_WAKE_HINT}`);
|
|
21712
20855
|
}
|
|
21713
20856
|
for (const job of splitJobs.slice(0, 12)) {
|
|
21714
20857
|
const viewport = cliString(job.viewport) || "viewport";
|
|
@@ -21945,9 +21088,9 @@ function profileHasCleanupBoundaryAffordanceReceipt(receipts) {
|
|
|
21945
21088
|
return receipts.some((receipt) => {
|
|
21946
21089
|
const storedTo = cliString(receipt.return_stored_to) || "";
|
|
21947
21090
|
const label = cliString(receipt.label) || "";
|
|
21948
|
-
const
|
|
21091
|
+
const path6 = cliString(receipt.path) || cliString(receipt.function_name) || "";
|
|
21949
21092
|
const summary = cliReturnSummaryLabel(receipt.return_summary) || "";
|
|
21950
|
-
const haystack = `${storedTo} ${label} ${
|
|
21093
|
+
const haystack = `${storedTo} ${label} ${path6} ${summary}`.toLowerCase();
|
|
21951
21094
|
const mentionsCleanupBoundary = haystack.includes("cleanup") || haystack.includes("precleanup") || haystack.includes("pre-cleanup") || haystack.includes("boundary") || haystack.includes("undo") || haystack.includes("clear") || haystack.includes("reset") || haystack.includes("discard");
|
|
21952
21095
|
const visibleControl = visibleFields.some((name) => setupReturnSummaryValue(receipt, [name]) === true);
|
|
21953
21096
|
const controlText = textFields.map((name) => cliString(setupReturnSummaryValue(receipt, [name]))).find((value) => profileCleanupLabelMatches(value));
|
|
@@ -21990,11 +21133,11 @@ function profileHasOfflineAudioMetricsReceipt(receipts) {
|
|
|
21990
21133
|
};
|
|
21991
21134
|
const metricSummaryItem = (item) => {
|
|
21992
21135
|
const label = (cliString(item.label) || "").toLowerCase();
|
|
21993
|
-
const
|
|
21994
|
-
const tail = (
|
|
21136
|
+
const path6 = (cliString(item.path) || "").toLowerCase();
|
|
21137
|
+
const tail = (path6.split(".").filter(Boolean).pop() || label).toLowerCase();
|
|
21995
21138
|
const normalizedLabel = label.replace(/[^a-z0-9]+/g, "");
|
|
21996
21139
|
const normalizedTail = tail.replace(/[^a-z0-9]+/g, "");
|
|
21997
|
-
return metricFieldNames.has(normalizedLabel) || metricFieldNames.has(normalizedTail) || /(^|\.)(mixhealth|monitormetrics|instrumentmetrics)\.(peak|rms)$/.test(
|
|
21140
|
+
return metricFieldNames.has(normalizedLabel) || metricFieldNames.has(normalizedTail) || /(^|\.)(mixhealth|monitormetrics|instrumentmetrics)\.(peak|rms)$/.test(path6);
|
|
21998
21141
|
};
|
|
21999
21142
|
return receipts.some((receipt) => {
|
|
22000
21143
|
if (metricFields.some((name) => positiveMetricValue(setupReturnSummaryValue(receipt, [name])))) return true;
|
|
@@ -22049,8 +21192,8 @@ function profileHasTerminalLossReceipt(receipts) {
|
|
|
22049
21192
|
const outOfBounds = setupReturnSummaryValue(receipt, ["lastFlightOutOfBounds", "outOfBounds"]) === true;
|
|
22050
21193
|
const storedTo = cliString(receipt.return_stored_to) || "";
|
|
22051
21194
|
const label = cliString(receipt.label) || "";
|
|
22052
|
-
const
|
|
22053
|
-
const haystack = `${storedTo} ${label} ${
|
|
21195
|
+
const path6 = cliString(receipt.path) || cliString(receipt.function_name) || "";
|
|
21196
|
+
const haystack = `${storedTo} ${label} ${path6}`.toLowerCase();
|
|
22054
21197
|
const labelsLoss = haystack.includes("loss") || haystack.includes("lost") || haystack.includes("terminal");
|
|
22055
21198
|
if (!labelsLoss && !lastFlightLost && !outOfBounds) return false;
|
|
22056
21199
|
return lastFlightLost || outOfBounds || ["over", "lost", "loss", "failed", "failure", "game_over", "gameover"].includes(status) || ["lost", "loss", "failed", "failure", "game_over", "gameover"].includes(outcome);
|
|
@@ -22064,9 +21207,9 @@ function profileHasTerminalGameOverReceipt(receipts) {
|
|
|
22064
21207
|
const caught = setupReturnSummaryValue(receipt, ["caught", "playerCaught", "wasCaught"]) === true;
|
|
22065
21208
|
const storedTo = cliString(receipt.return_stored_to) || "";
|
|
22066
21209
|
const label = cliString(receipt.label) || "";
|
|
22067
|
-
const
|
|
21210
|
+
const path6 = cliString(receipt.path) || cliString(receipt.function_name) || "";
|
|
22068
21211
|
const slot = cliString(setupReturnSummaryValue(receipt, ["slot"])) || "";
|
|
22069
|
-
const haystack = `${storedTo} ${label} ${
|
|
21212
|
+
const haystack = `${storedTo} ${label} ${path6} ${slot}`.toLowerCase();
|
|
22070
21213
|
const labelsTerminal = haystack.includes("gameover") || haystack.includes("game_over") || haystack.includes("game-over") || haystack.includes("game over") || haystack.includes("terminal") || haystack.includes("caught") || haystack.includes("catch");
|
|
22071
21214
|
const terminalStatus = ["over", "game_over", "gameover"].includes(status) || ["game_over", "gameover"].includes(outcome);
|
|
22072
21215
|
if (!labelsTerminal && !caught && !gameOver && !terminalStatus) return false;
|
|
@@ -22079,8 +21222,8 @@ function profileHasTerminalSuccessReceipt(receipts) {
|
|
|
22079
21222
|
const outcome = profileLowerSummaryValue(receipt, ["lastOutcome", "outcome", "terminalOutcome", "terminal", "result"]);
|
|
22080
21223
|
const storedTo = cliString(receipt.return_stored_to) || "";
|
|
22081
21224
|
const label = cliString(receipt.label) || "";
|
|
22082
|
-
const
|
|
22083
|
-
const haystack = `${storedTo} ${label} ${
|
|
21225
|
+
const path6 = cliString(receipt.path) || cliString(receipt.function_name) || "";
|
|
21226
|
+
const haystack = `${storedTo} ${label} ${path6}`.toLowerCase();
|
|
22084
21227
|
if (haystack.includes("shot")) return false;
|
|
22085
21228
|
const labelsSuccess = haystack.includes("success") || haystack.includes("terminal") || haystack.includes("completed") || haystack.includes("complete");
|
|
22086
21229
|
const success = setupReturnSummaryValue(receipt, ["success", "passed", "completed"]) === true;
|
|
@@ -22110,9 +21253,9 @@ function profileHasRouteContinuationReceipt(receipts) {
|
|
|
22110
21253
|
if (!fromRoute || !target && !afterRoute) return false;
|
|
22111
21254
|
const storedTo = cliString(receipt.return_stored_to) || "";
|
|
22112
21255
|
const label = cliString(receipt.label) || "";
|
|
22113
|
-
const
|
|
21256
|
+
const path6 = cliString(receipt.path) || cliString(receipt.function_name) || "";
|
|
22114
21257
|
const summary = cliReturnSummaryLabel(receipt.return_summary) || "";
|
|
22115
|
-
const haystack = `${storedTo} ${label} ${
|
|
21258
|
+
const haystack = `${storedTo} ${label} ${path6} ${summary}`.toLowerCase();
|
|
22116
21259
|
return haystack.includes("navigation") || haystack.includes("continuation") || haystack.includes("route") || haystack.includes("next") || haystack.includes("target");
|
|
22117
21260
|
});
|
|
22118
21261
|
}
|
|
@@ -22120,9 +21263,9 @@ function profileHasRecoveredStateReceipt(receipts) {
|
|
|
22120
21263
|
return receipts.some((receipt) => {
|
|
22121
21264
|
const storedTo = cliString(receipt.return_stored_to) || "";
|
|
22122
21265
|
const label = cliString(receipt.label) || "";
|
|
22123
|
-
const
|
|
21266
|
+
const path6 = cliString(receipt.path) || cliString(receipt.function_name) || "";
|
|
22124
21267
|
const summary = cliReturnSummaryLabel(receipt.return_summary) || "";
|
|
22125
|
-
const haystack = `${storedTo} ${label} ${
|
|
21268
|
+
const haystack = `${storedTo} ${label} ${path6} ${summary}`.toLowerCase();
|
|
22126
21269
|
const labelsRecovery = haystack.includes("recover") || haystack.includes("repaired") || haystack.includes("repair") || haystack.includes("retry") || haystack.includes("restart") || haystack.includes("play again") || haystack.includes("playagain") || haystack.includes("play-again") || haystack.includes("try fix") || haystack.includes("tryfix") || haystack.includes("after-fix") || haystack.includes("fixed");
|
|
22127
21270
|
if (!labelsRecovery) return false;
|
|
22128
21271
|
const status = profileLowerSummaryValue(receipt, ["status", "state", "phase"]);
|
|
@@ -22143,11 +21286,11 @@ function profileHasSequenceInputReceipt(receipts) {
|
|
|
22143
21286
|
for (const receipt of receipts) {
|
|
22144
21287
|
const storedTo = cliString(receipt.return_stored_to) || "";
|
|
22145
21288
|
const label = cliString(receipt.label) || "";
|
|
22146
|
-
const
|
|
21289
|
+
const path6 = cliString(receipt.path) || cliString(receipt.function_name) || "";
|
|
22147
21290
|
const slot = profileLowerSummaryValue(receipt, ["slot", "phase", "state"]);
|
|
22148
21291
|
const statusText = profileLowerSummaryValue(receipt, ["statusText", "status", "message"]);
|
|
22149
21292
|
const summary = cliReturnSummaryLabel(receipt.return_summary) || "";
|
|
22150
|
-
const haystack = `${storedTo} ${label} ${
|
|
21293
|
+
const haystack = `${storedTo} ${label} ${path6} ${slot} ${statusText} ${summary}`.toLowerCase();
|
|
22151
21294
|
const sequenceText = [
|
|
22152
21295
|
"expectedSequence",
|
|
22153
21296
|
"expectedLevel2Sequence",
|
|
@@ -22186,11 +21329,11 @@ function profileHasRestartReadyReceipt(receipts) {
|
|
|
22186
21329
|
return receipts.some((receipt) => {
|
|
22187
21330
|
const storedTo = cliString(receipt.return_stored_to) || "";
|
|
22188
21331
|
const label = cliString(receipt.label) || "";
|
|
22189
|
-
const
|
|
21332
|
+
const path6 = cliString(receipt.path) || cliString(receipt.function_name) || "";
|
|
22190
21333
|
const slot = profileLowerSummaryValue(receipt, ["slot", "phase", "state"]);
|
|
22191
21334
|
const statusText = profileLowerSummaryValue(receipt, ["statusText", "status", "message"]);
|
|
22192
21335
|
const summary = cliReturnSummaryLabel(receipt.return_summary) || "";
|
|
22193
|
-
const haystack = `${storedTo} ${label} ${
|
|
21336
|
+
const haystack = `${storedTo} ${label} ${path6} ${slot} ${statusText} ${summary}`.toLowerCase();
|
|
22194
21337
|
const labelsRestart = haystack.includes("restart") || haystack.includes("reset") || haystack.includes("reset-ready") || haystack.includes("reset ready") || haystack.includes("play again") || haystack.includes("play-again") || haystack.includes("playagain") || haystack.includes("retry");
|
|
22195
21338
|
if (!labelsRestart) return false;
|
|
22196
21339
|
const ok = receipt.ok !== false && setupReturnSummaryValue(receipt, ["ok"]) !== false;
|
|
@@ -22220,9 +21363,9 @@ function profileHasGeneratedOutputReceipt(receipts) {
|
|
|
22220
21363
|
for (const receipt of receipts) {
|
|
22221
21364
|
const storedTo = cliString(receipt.return_stored_to) || "";
|
|
22222
21365
|
const label = cliString(receipt.label) || "";
|
|
22223
|
-
const
|
|
21366
|
+
const path6 = cliString(receipt.path) || cliString(receipt.function_name) || "";
|
|
22224
21367
|
const summary = cliReturnSummaryLabel(receipt.return_summary) || "";
|
|
22225
|
-
const haystack = `${storedTo} ${label} ${
|
|
21368
|
+
const haystack = `${storedTo} ${label} ${path6} ${summary}`.toLowerCase();
|
|
22226
21369
|
const readySignal = setupReturnSummaryValue(receipt, ["outputReady", "outputStillReady"]) === true || cliFiniteNumber(setupReturnSummaryValue(receipt, ["surfaceCount", "before.surfaceCount", "after.surfaceCount"])) !== void 0 || setupReturnSummaryValue(receipt, ["size", "before.size", "after.size", "size.text", "before.size.text", "after.size.text"]) !== void 0;
|
|
22227
21370
|
if (readySignal && (haystack.includes("output") || haystack.includes("size") || haystack.includes("result"))) {
|
|
22228
21371
|
outputReady = true;
|
|
@@ -22492,10 +21635,10 @@ function profilePackReceiptStatus(result, metadata, receipt) {
|
|
|
22492
21635
|
const hasPositiveStateGrowthMetric = valueReceipts.some((item) => stateGrowthMetricNames.some((name) => {
|
|
22493
21636
|
const storedTo = cliString(item.return_stored_to) || "";
|
|
22494
21637
|
const label = cliString(item.label) || "";
|
|
22495
|
-
const
|
|
21638
|
+
const path6 = cliString(item.path) || cliString(item.function_name) || "";
|
|
22496
21639
|
const slot = profileLowerSummaryValue(item, ["slot", "phase", "state"]);
|
|
22497
21640
|
const statusText = profileLowerSummaryValue(item, ["statusText", "status", "message"]);
|
|
22498
|
-
const haystack = `${storedTo} ${label} ${
|
|
21641
|
+
const haystack = `${storedTo} ${label} ${path6} ${slot} ${statusText}`.toLowerCase();
|
|
22499
21642
|
const stateGrowthOutcome = haystack.includes("growth") || haystack.includes("success") || haystack.includes("after") || haystack.includes("add") || haystack.includes("upgrade") || haystack.includes("bought") || haystack.includes("perfect") || setupReturnSummaryValue(item, ["success", "passed"]) === true;
|
|
22500
21643
|
if (!stateGrowthOutcome) return false;
|
|
22501
21644
|
const value = cliFiniteNumber(setupReturnSummaryValue(item, [name]));
|
|
@@ -23099,8 +22242,8 @@ function setupReturnedSummaryValue(receipt, names) {
|
|
|
23099
22242
|
const summaries = Array.isArray(receipt.return_summary) ? receipt.return_summary.map(cliRecord).filter((item) => Boolean(item)) : [];
|
|
23100
22243
|
for (const item of summaries) {
|
|
23101
22244
|
const label = cliString(item.label);
|
|
23102
|
-
const
|
|
23103
|
-
if (names.some((name) => label === name ||
|
|
22245
|
+
const path6 = cliString(item.path);
|
|
22246
|
+
if (names.some((name) => label === name || path6 === name)) return item.value;
|
|
23104
22247
|
}
|
|
23105
22248
|
return void 0;
|
|
23106
22249
|
}
|
|
@@ -23874,7 +23017,7 @@ function profileSetupSummaryMarkdown(result) {
|
|
|
23874
23017
|
const windowCallDetails = windowCallGroups.flat();
|
|
23875
23018
|
const sampledWindowCallDetails = balancedSetupReceiptDetails(windowCallGroups, 12);
|
|
23876
23019
|
for (const { name, receipt } of sampledWindowCallDetails) {
|
|
23877
|
-
const
|
|
23020
|
+
const path6 = cliString(receipt.path) || "window_function";
|
|
23878
23021
|
const storedTo = cliString(receipt.return_stored_to);
|
|
23879
23022
|
const returned = cliValueLabel(receipt.returned);
|
|
23880
23023
|
const expected = cliValueLabel(receipt.expected_return);
|
|
@@ -23882,7 +23025,7 @@ function profileSetupSummaryMarkdown(result) {
|
|
|
23882
23025
|
const captured = receipt.return_captured === true ? "captured" : receipt.return_captured === false ? "not captured" : "capture unknown";
|
|
23883
23026
|
const ok = receipt.ok === false ? "failed" : "ok";
|
|
23884
23027
|
const reason = cliString(receipt.reason);
|
|
23885
|
-
lines.push(`- ${name} window_call: ${ok}, ${markdownInlineCode(
|
|
23028
|
+
lines.push(`- ${name} window_call: ${ok}, ${markdownInlineCode(path6)}${storedTo ? `, stored ${markdownInlineCode(storedTo)}` : ""}, return ${captured}${expected === void 0 ? "" : `, expected ${markdownInlineCode(expected, 80)}`}${returnSummary ? `, summary ${markdownInlineCode(returnSummary, 140)}` : ""}${returned === void 0 ? "" : `, returned ${markdownInlineCode(returned, 80)}`}${reason ? `, reason ${markdownInlineCode(reason, 100)}` : ""}`);
|
|
23886
23029
|
}
|
|
23887
23030
|
if (windowCallDetails.length > sampledWindowCallDetails.length) lines.push(`- ${windowCallDetails.length - sampledWindowCallDetails.length} additional window_call receipt(s) omitted.`);
|
|
23888
23031
|
const windowEvalGroups = viewports.map((viewport) => {
|
|
@@ -23912,7 +23055,7 @@ function profileSetupSummaryMarkdown(result) {
|
|
|
23912
23055
|
const windowCallUntilDetails = windowCallUntilGroups.flat();
|
|
23913
23056
|
const sampledWindowCallUntilDetails = balancedSetupReceiptDetails(windowCallUntilGroups, 12);
|
|
23914
23057
|
for (const { name, receipt } of sampledWindowCallUntilDetails) {
|
|
23915
|
-
const
|
|
23058
|
+
const path6 = cliString(receipt.path) || "window_function";
|
|
23916
23059
|
const untilPath = cliString(receipt.until_path) || "until_path";
|
|
23917
23060
|
const expected = cliValueLabel(receipt.until_expected_value);
|
|
23918
23061
|
const actual = cliValueLabel(receipt.until_value);
|
|
@@ -23921,7 +23064,7 @@ function profileSetupSummaryMarkdown(result) {
|
|
|
23921
23064
|
const ok = receipt.ok === false ? "failed" : "ok";
|
|
23922
23065
|
const reason = cliString(receipt.reason);
|
|
23923
23066
|
const callText = callCount === void 0 ? "" : ` in ${callCount}${maxCalls === void 0 ? "" : `/${maxCalls}`} call(s)`;
|
|
23924
|
-
lines.push(`- ${name} window_call_until: ${ok}, ${markdownInlineCode(
|
|
23067
|
+
lines.push(`- ${name} window_call_until: ${ok}, ${markdownInlineCode(path6)} until ${markdownInlineCode(untilPath)}${expected === void 0 ? "" : ` == ${markdownInlineCode(expected, 80)}`}${callText}${actual === void 0 ? "" : `, observed ${markdownInlineCode(actual, 80)}`}${reason ? `, reason ${markdownInlineCode(reason, 100)}` : ""}`);
|
|
23925
23068
|
}
|
|
23926
23069
|
if (windowCallUntilDetails.length > sampledWindowCallUntilDetails.length) lines.push(`- ${windowCallUntilDetails.length - sampledWindowCallUntilDetails.length} additional window_call_until receipt(s) omitted.`);
|
|
23927
23070
|
const failedDetails = viewports.flatMap((viewport) => {
|
|
@@ -24171,7 +23314,7 @@ function profileObservationForOutput(result, outputDir, options) {
|
|
|
24171
23314
|
if (options.observation) return options.observation;
|
|
24172
23315
|
const preview = options.previewReceipt;
|
|
24173
23316
|
const targetUrl = profileResultTargetUrl(result);
|
|
24174
|
-
return createRiddleProofObservationReceipt({
|
|
23317
|
+
return (0, import_receipts.createRiddleProofObservationReceipt)({
|
|
24175
23318
|
comparison_role: options.comparisonRole || "standalone",
|
|
24176
23319
|
executor: result.runner === "local-playwright" ? { kind: "local_playwright", runner: result.runner } : {
|
|
24177
23320
|
kind: "riddle_hosted",
|
|
@@ -24188,7 +23331,7 @@ function profileObservationForOutput(result, outputDir, options) {
|
|
|
24188
23331
|
}
|
|
24189
23332
|
function profileOutputOptionsForCli(options) {
|
|
24190
23333
|
const previewInput = optionString(options, "previewReceipt");
|
|
24191
|
-
const previewReceipt = previewInput ? parseRiddlePreviewReceipt(readJsonValue(previewInput, "--preview-receipt")) : void 0;
|
|
23334
|
+
const previewReceipt = previewInput ? (0, import_receipts.parseRiddlePreviewReceipt)(readJsonValue(previewInput, "--preview-receipt")) : void 0;
|
|
24192
23335
|
const sourceDirty = optionBoolean(options, "sourceDirty");
|
|
24193
23336
|
const source = {
|
|
24194
23337
|
...previewReceipt?.source || {},
|
|
@@ -24200,18 +23343,18 @@ function profileOutputOptionsForCli(options) {
|
|
|
24200
23343
|
}
|
|
24201
23344
|
function writeProfileOutput(outputDir, result, options = {}) {
|
|
24202
23345
|
if (!outputDir) return;
|
|
24203
|
-
(0,
|
|
24204
|
-
(0,
|
|
23346
|
+
(0, import_node_fs5.mkdirSync)(outputDir, { recursive: true });
|
|
23347
|
+
(0, import_node_fs5.writeFileSync)(import_node_path5.default.join(outputDir, "profile-result.json"), `${JSON.stringify(result, null, 2)}
|
|
24205
23348
|
`);
|
|
24206
23349
|
const observation = profileObservationForOutput(result, outputDir, options);
|
|
24207
|
-
(0,
|
|
23350
|
+
(0, import_node_fs5.writeFileSync)(import_node_path5.default.join(outputDir, "observation-receipt.json"), `${JSON.stringify(observation, null, 2)}
|
|
24208
23351
|
`);
|
|
24209
|
-
(0,
|
|
24210
|
-
if (result.evidence) (0,
|
|
23352
|
+
(0, import_node_fs5.writeFileSync)(import_node_path5.default.join(outputDir, "summary.md"), profileResultMarkdown(result));
|
|
23353
|
+
if (result.evidence) (0, import_node_fs5.writeFileSync)(import_node_path5.default.join(outputDir, "proof.json"), `${JSON.stringify(result, null, 2)}
|
|
24211
23354
|
`);
|
|
24212
|
-
if (result.evidence?.console) (0,
|
|
23355
|
+
if (result.evidence?.console) (0, import_node_fs5.writeFileSync)(import_node_path5.default.join(outputDir, "console.json"), `${JSON.stringify(result.evidence.console, null, 2)}
|
|
24213
23356
|
`);
|
|
24214
|
-
if (result.evidence?.dom_summary) (0,
|
|
23357
|
+
if (result.evidence?.dom_summary) (0, import_node_fs5.writeFileSync)(import_node_path5.default.join(outputDir, "dom-summary.json"), `${JSON.stringify(result.evidence.dom_summary, null, 2)}
|
|
24215
23358
|
`);
|
|
24216
23359
|
}
|
|
24217
23360
|
function readChangeContractForCli(options) {
|
|
@@ -24228,7 +23371,7 @@ function readChangeContractForCli(options) {
|
|
|
24228
23371
|
return parsed;
|
|
24229
23372
|
}
|
|
24230
23373
|
function changeProofSideOutputDir(outputDir, side) {
|
|
24231
|
-
return outputDir ?
|
|
23374
|
+
return outputDir ? import_node_path5.default.join(outputDir, side) : void 0;
|
|
24232
23375
|
}
|
|
24233
23376
|
function profileOptionsForChangeProofSide(options, url, outputDir) {
|
|
24234
23377
|
const next = {
|
|
@@ -24301,17 +23444,17 @@ function changeProofResultMarkdown(run) {
|
|
|
24301
23444
|
}
|
|
24302
23445
|
function writeChangeProofOutput(outputDir, run) {
|
|
24303
23446
|
if (!outputDir) return;
|
|
24304
|
-
(0,
|
|
24305
|
-
(0,
|
|
23447
|
+
(0, import_node_fs5.mkdirSync)(outputDir, { recursive: true });
|
|
23448
|
+
(0, import_node_fs5.writeFileSync)(import_node_path5.default.join(outputDir, "change-proof-result.json"), `${JSON.stringify(run.result, null, 2)}
|
|
24306
23449
|
`);
|
|
24307
|
-
(0,
|
|
23450
|
+
(0, import_node_fs5.writeFileSync)(import_node_path5.default.join(outputDir, "change-proof-receipt.json"), `${JSON.stringify(run.receipt, null, 2)}
|
|
24308
23451
|
`);
|
|
24309
|
-
(0,
|
|
24310
|
-
(0,
|
|
24311
|
-
(0,
|
|
23452
|
+
(0, import_node_fs5.writeFileSync)(import_node_path5.default.join(outputDir, "change-proof-receipt.md"), riddleProofChangeReceiptMarkdown(run.receipt));
|
|
23453
|
+
(0, import_node_fs5.writeFileSync)(import_node_path5.default.join(outputDir, "change-proof-receipt.html"), riddleProofChangeReceiptHtml(run.receipt));
|
|
23454
|
+
(0, import_node_fs5.writeFileSync)(import_node_path5.default.join(outputDir, "handoff-receipt.json"), `${JSON.stringify(run.handoff, null, 2)}
|
|
24312
23455
|
`);
|
|
24313
|
-
(0,
|
|
24314
|
-
(0,
|
|
23456
|
+
(0, import_node_fs5.writeFileSync)(import_node_path5.default.join(outputDir, "handoff-receipt.md"), buildRiddleProofPrCommentMarkdown({ result: run.handoff }));
|
|
23457
|
+
(0, import_node_fs5.writeFileSync)(import_node_path5.default.join(outputDir, "summary.md"), changeProofResultMarkdown(run));
|
|
24315
23458
|
writeProfileOutput(changeProofSideOutputDir(outputDir, "before"), run.beforeResult, { observation: run.beforeObservation });
|
|
24316
23459
|
writeProfileOutput(changeProofSideOutputDir(outputDir, "after"), run.afterResult, { observation: run.afterObservation });
|
|
24317
23460
|
}
|
|
@@ -24332,8 +23475,8 @@ function writeRunChangeProofResult(run, options) {
|
|
|
24332
23475
|
}
|
|
24333
23476
|
function writeRiddleJobReceipt(outputDir, input) {
|
|
24334
23477
|
if (!outputDir) return;
|
|
24335
|
-
(0,
|
|
24336
|
-
(0,
|
|
23478
|
+
(0, import_node_fs5.mkdirSync)(outputDir, { recursive: true });
|
|
23479
|
+
(0, import_node_fs5.writeFileSync)(import_node_path5.default.join(outputDir, "riddle-job.json"), `${JSON.stringify({
|
|
24337
23480
|
version: "riddle-proof.riddle-job-receipt.v1",
|
|
24338
23481
|
profile_name: input.profile.name,
|
|
24339
23482
|
job_id: input.jobId,
|
|
@@ -24349,7 +23492,7 @@ async function readArtifactJson(artifact) {
|
|
|
24349
23492
|
const target = artifact.url || artifact.path;
|
|
24350
23493
|
if (!target) return void 0;
|
|
24351
23494
|
try {
|
|
24352
|
-
const raw = artifact.url ? await (await fetch(artifact.url)).text() : (0,
|
|
23495
|
+
const raw = artifact.url ? await (await fetch(artifact.url)).text() : (0, import_node_fs5.existsSync)(target) ? (0, import_node_fs5.readFileSync)(target, "utf-8") : "";
|
|
24353
23496
|
if (!raw.trim()) return void 0;
|
|
24354
23497
|
const parsed = JSON.parse(raw);
|
|
24355
23498
|
return parsed && typeof parsed === "object" && !Array.isArray(parsed) ? parsed : void 0;
|
|
@@ -24445,14 +23588,14 @@ async function recoverProfileResultFromRiddleArtifacts(profile, input) {
|
|
|
24445
23588
|
for (let attempt = 0; attempt < attempts; attempt += 1) {
|
|
24446
23589
|
let artifactPayload;
|
|
24447
23590
|
try {
|
|
24448
|
-
artifactPayload = await input.client.
|
|
23591
|
+
artifactPayload = await input.client.getJobArtifacts(input.jobId);
|
|
24449
23592
|
} catch {
|
|
24450
23593
|
artifactPayload = {};
|
|
24451
23594
|
}
|
|
24452
23595
|
const artifacts = collectRiddleProfileArtifactRefs(artifactPayload);
|
|
24453
23596
|
if (artifacts.length) {
|
|
24454
23597
|
const artifactStatus = riddleArtifactsPayloadStatus(artifactPayload);
|
|
24455
|
-
const terminal = artifactStatus ? isTerminalRiddleJobStatus(artifactStatus) : true;
|
|
23598
|
+
const terminal = artifactStatus ? (0, import_client.isTerminalRiddleJobStatus)(artifactStatus) : true;
|
|
24456
23599
|
const recoveredPoll = input.poll.poll ? {
|
|
24457
23600
|
...input.poll.poll,
|
|
24458
23601
|
status: artifactStatus ?? input.poll.poll.status,
|
|
@@ -24609,17 +23752,17 @@ function splitViewportOutputDir(outputDir, viewportName, seen) {
|
|
|
24609
23752
|
const base = safeProfileOutputSegment(viewportName);
|
|
24610
23753
|
const count = seen.get(base) || 0;
|
|
24611
23754
|
seen.set(base, count + 1);
|
|
24612
|
-
return
|
|
23755
|
+
return import_node_path5.default.join(outputDir, count ? `${base}-${count + 1}` : base);
|
|
24613
23756
|
}
|
|
24614
23757
|
function profileResultPathFromInput(inputPath) {
|
|
24615
|
-
if (!(0,
|
|
24616
|
-
const stat = (0,
|
|
23758
|
+
if (!(0, import_node_fs5.existsSync)(inputPath)) throw new Error(`Profile aggregate input path does not exist: ${inputPath}`);
|
|
23759
|
+
const stat = (0, import_node_fs5.statSync)(inputPath);
|
|
24617
23760
|
if (stat.isFile()) return [inputPath];
|
|
24618
23761
|
if (!stat.isDirectory()) throw new Error(`Profile aggregate input path must be a file or directory: ${inputPath}`);
|
|
24619
|
-
const childProfileResults = (0,
|
|
23762
|
+
const childProfileResults = (0, import_node_fs5.readdirSync)(inputPath, { withFileTypes: true }).filter((entry) => entry.isDirectory()).map((entry) => import_node_path5.default.join(inputPath, entry.name, "profile-result.json")).filter((candidate) => (0, import_node_fs5.existsSync)(candidate));
|
|
24620
23763
|
if (childProfileResults.length) return childProfileResults;
|
|
24621
|
-
const directProfileResult =
|
|
24622
|
-
if ((0,
|
|
23764
|
+
const directProfileResult = import_node_path5.default.join(inputPath, "profile-result.json");
|
|
23765
|
+
if ((0, import_node_fs5.existsSync)(directProfileResult)) return [directProfileResult];
|
|
24623
23766
|
throw new Error(`Profile aggregate input directory has no child profile-result.json files: ${inputPath}`);
|
|
24624
23767
|
}
|
|
24625
23768
|
function runProfileAggregateInputPathsOption(options) {
|
|
@@ -24633,7 +23776,7 @@ function runProfileAggregateInputPathsOption(options) {
|
|
|
24633
23776
|
const inputDir = optionString(options, "inputDir") ?? optionString(options, "resultsDir") ?? optionString(options, "runDir");
|
|
24634
23777
|
const discoveredInputs = inputDir ? profileResultPathFromInput(inputDir) : [];
|
|
24635
23778
|
const paths = [...explicitInputs.flatMap(profileResultPathFromInput), ...discoveredInputs];
|
|
24636
|
-
const uniquePaths = [...new Set(paths.map((inputPath) =>
|
|
23779
|
+
const uniquePaths = [...new Set(paths.map((inputPath) => import_node_path5.default.resolve(inputPath)))];
|
|
24637
23780
|
if (!uniquePaths.length) {
|
|
24638
23781
|
throw new Error("run-profile aggregate requires --input-dir <dir> or --inputs <path[,path...]>.");
|
|
24639
23782
|
}
|
|
@@ -24889,7 +24032,7 @@ async function preflightRiddleProfileBalanceForCli(profile, options, input) {
|
|
|
24889
24032
|
error,
|
|
24890
24033
|
environmentBlocker: {
|
|
24891
24034
|
source: "riddle_api",
|
|
24892
|
-
endpoint:
|
|
24035
|
+
endpoint: import_client.RIDDLE_BALANCE_ENDPOINT_PATH,
|
|
24893
24036
|
reason: "balance_preflight_failed",
|
|
24894
24037
|
balance_preflight: true,
|
|
24895
24038
|
...riddleApiErrorBlockerMetadata(error),
|
|
@@ -24911,7 +24054,7 @@ async function preflightRiddleProfileBalanceForCli(profile, options, input) {
|
|
|
24911
24054
|
error: `Riddle balance preflight failed: ${availableSeconds}s available for ${jobCount} intended hosted job(s), minimum ${requiredSeconds}s required.`,
|
|
24912
24055
|
environmentBlocker: {
|
|
24913
24056
|
source: "riddle_api",
|
|
24914
|
-
endpoint:
|
|
24057
|
+
endpoint: import_client.RIDDLE_BALANCE_ENDPOINT_PATH,
|
|
24915
24058
|
reason: "insufficient_balance",
|
|
24916
24059
|
error: "Insufficient available balance",
|
|
24917
24060
|
balance_preflight: true,
|
|
@@ -24988,7 +24131,7 @@ async function runSingleRiddleProfileForCli(profile, options, input) {
|
|
|
24988
24131
|
}
|
|
24989
24132
|
staleJobIds.push(jobId);
|
|
24990
24133
|
if (options.quiet !== true) {
|
|
24991
|
-
process.stderr.write(`[riddle-poll] ${jobId} stayed unsubmitted for ${formatPollDuration(poll.poll?.pre_submission_elapsed_ms)}; ${RIDDLE_UNSUBMITTED_WAKE_HINT}; retrying hosted run ${attempt + 1}/${retryLimit}
|
|
24134
|
+
process.stderr.write(`[riddle-poll] ${jobId} stayed unsubmitted for ${formatPollDuration(poll.poll?.pre_submission_elapsed_ms)}; ${import_client.RIDDLE_UNSUBMITTED_WAKE_HINT}; retrying hosted run ${attempt + 1}/${retryLimit}
|
|
24992
24135
|
`);
|
|
24993
24136
|
}
|
|
24994
24137
|
continue;
|
|
@@ -25114,10 +24257,10 @@ async function recoverProfileForCli(profile, options) {
|
|
|
25114
24257
|
}
|
|
25115
24258
|
const jobId = optionString(options, "job") ?? optionString(options, "jobId");
|
|
25116
24259
|
if (!jobId) throw new Error("run-profile recover requires --job <job-id>.");
|
|
25117
|
-
const client = createRiddleApiClient(riddleClientConfig(options));
|
|
24260
|
+
const client = (0, import_client.createRiddleApiClient)(riddleClientConfig(options));
|
|
25118
24261
|
let artifactPayload;
|
|
25119
24262
|
try {
|
|
25120
|
-
artifactPayload = await client.
|
|
24263
|
+
artifactPayload = await client.getJobArtifacts(jobId);
|
|
25121
24264
|
} catch (error) {
|
|
25122
24265
|
return createRiddleProofProfileEnvironmentBlockedResult({
|
|
25123
24266
|
profile,
|
|
@@ -25128,7 +24271,7 @@ async function recoverProfileForCli(profile, options) {
|
|
|
25128
24271
|
}
|
|
25129
24272
|
const artifacts = collectRiddleProfileArtifactRefs(artifactPayload);
|
|
25130
24273
|
const artifactStatus = riddleArtifactsPayloadStatus(artifactPayload);
|
|
25131
|
-
const terminal = artifactStatus ? isTerminalRiddleJobStatus(artifactStatus) : artifacts.length > 0;
|
|
24274
|
+
const terminal = artifactStatus ? (0, import_client.isTerminalRiddleJobStatus)(artifactStatus) : artifacts.length > 0;
|
|
25132
24275
|
const recovered = await profileResultFromRiddleArtifacts(profile, artifacts, [artifactPayload]);
|
|
25133
24276
|
if (recovered) {
|
|
25134
24277
|
return withRiddleMetadata(recovered, {
|
|
@@ -25171,7 +24314,7 @@ async function runProfileForCli(profile, options) {
|
|
|
25171
24314
|
}
|
|
25172
24315
|
});
|
|
25173
24316
|
}
|
|
25174
|
-
const client = createRiddleApiClient(riddleClientConfig(options));
|
|
24317
|
+
const client = (0, import_client.createRiddleApiClient)(riddleClientConfig(options));
|
|
25175
24318
|
const balanceBlocked = await preflightRiddleProfileBalanceForCli(profile, options, { client, runner });
|
|
25176
24319
|
if (balanceBlocked) return balanceBlocked;
|
|
25177
24320
|
if (runProfileSplitViewportsOption(options) && profile.target.viewports.length > 1) {
|
|
@@ -25189,8 +24332,8 @@ async function runChangeProofForCli(rawProfile, options) {
|
|
|
25189
24332
|
const afterUrl = optionString(options, "afterUrl");
|
|
25190
24333
|
const beforePreviewInput = optionString(options, "beforePreviewReceipt");
|
|
25191
24334
|
const afterPreviewInput = optionString(options, "afterPreviewReceipt");
|
|
25192
|
-
const beforePreview = beforePreviewInput ? parseRiddlePreviewReceipt(readJsonValue(beforePreviewInput, "--before-preview-receipt")) : void 0;
|
|
25193
|
-
const afterPreview = afterPreviewInput ? parseRiddlePreviewReceipt(readJsonValue(afterPreviewInput, "--after-preview-receipt")) : void 0;
|
|
24335
|
+
const beforePreview = beforePreviewInput ? (0, import_receipts.parseRiddlePreviewReceipt)(readJsonValue(beforePreviewInput, "--before-preview-receipt")) : void 0;
|
|
24336
|
+
const afterPreview = afterPreviewInput ? (0, import_receipts.parseRiddlePreviewReceipt)(readJsonValue(afterPreviewInput, "--after-preview-receipt")) : void 0;
|
|
25194
24337
|
const hasResultInputs = Boolean(beforeResultPath || afterResultPath);
|
|
25195
24338
|
const hasObservationInputs = Boolean(beforeObservationPath || afterObservationPath);
|
|
25196
24339
|
const hasUrlInputs = Boolean(beforeUrl || afterUrl);
|
|
@@ -25226,11 +24369,11 @@ async function runChangeProofForCli(rawProfile, options) {
|
|
|
25226
24369
|
}
|
|
25227
24370
|
profile = profileWithSelectedViewportNamesForCli(normalizeProfileRecordForCli(rawProfile, options), options);
|
|
25228
24371
|
beforeObservation = observationForChangeSide(
|
|
25229
|
-
parseRiddleProofObservationReceipt(readJsonValue(beforeObservationPath, "--before-observation")),
|
|
24372
|
+
(0, import_receipts.parseRiddleProofObservationReceipt)(readJsonValue(beforeObservationPath, "--before-observation")),
|
|
25230
24373
|
"before"
|
|
25231
24374
|
);
|
|
25232
24375
|
afterObservation = observationForChangeSide(
|
|
25233
|
-
parseRiddleProofObservationReceipt(readJsonValue(afterObservationPath, "--after-observation")),
|
|
24376
|
+
(0, import_receipts.parseRiddleProofObservationReceipt)(readJsonValue(afterObservationPath, "--after-observation")),
|
|
25234
24377
|
"after"
|
|
25235
24378
|
);
|
|
25236
24379
|
if (!beforeObservation.proof?.result || !afterObservation.proof?.result) {
|
|
@@ -25249,7 +24392,7 @@ async function runChangeProofForCli(rawProfile, options) {
|
|
|
25249
24392
|
afterResult = readProfileResultForCli(afterResultPath, "--after-result");
|
|
25250
24393
|
beforeSource = profileResultTargetUrl(beforeResult);
|
|
25251
24394
|
afterSource = profileResultTargetUrl(afterResult);
|
|
25252
|
-
beforeObservation = createRiddleProofObservationReceipt({
|
|
24395
|
+
beforeObservation = (0, import_receipts.createRiddleProofObservationReceipt)({
|
|
25253
24396
|
comparison_role: "before",
|
|
25254
24397
|
executor: { kind: beforeResult.runner === "local-playwright" ? "local_playwright" : "riddle_hosted", runner: beforeResult.runner, job_id: beforeResult.riddle?.job_id },
|
|
25255
24398
|
target: { kind: "url", url: beforeSource },
|
|
@@ -25257,7 +24400,7 @@ async function runChangeProofForCli(rawProfile, options) {
|
|
|
25257
24400
|
execution: beforeResult.riddle?.execution,
|
|
25258
24401
|
publication: { kind: "local", path: beforeResultPath }
|
|
25259
24402
|
});
|
|
25260
|
-
afterObservation = createRiddleProofObservationReceipt({
|
|
24403
|
+
afterObservation = (0, import_receipts.createRiddleProofObservationReceipt)({
|
|
25261
24404
|
comparison_role: "after",
|
|
25262
24405
|
executor: { kind: afterResult.runner === "local-playwright" ? "local_playwright" : "riddle_hosted", runner: afterResult.runner, job_id: afterResult.riddle?.job_id },
|
|
25263
24406
|
target: { kind: "url", url: afterSource },
|
|
@@ -25278,7 +24421,7 @@ async function runChangeProofForCli(rawProfile, options) {
|
|
|
25278
24421
|
afterResult = await runProfileForCli(afterProfile, afterOptions);
|
|
25279
24422
|
beforeSource = beforeUrl;
|
|
25280
24423
|
afterSource = afterUrl;
|
|
25281
|
-
beforeObservation = createRiddleProofObservationReceipt({
|
|
24424
|
+
beforeObservation = (0, import_receipts.createRiddleProofObservationReceipt)({
|
|
25282
24425
|
comparison_role: "before",
|
|
25283
24426
|
executor: { kind: "riddle_hosted", runner: beforeResult.runner, job_id: beforeResult.riddle?.job_id },
|
|
25284
24427
|
target: beforePreview ? { kind: "preview", url: beforeSource, preview: beforePreview } : { kind: "url", url: beforeSource },
|
|
@@ -25286,7 +24429,7 @@ async function runChangeProofForCli(rawProfile, options) {
|
|
|
25286
24429
|
profile_result: beforeResult,
|
|
25287
24430
|
execution: beforeResult.riddle?.execution
|
|
25288
24431
|
});
|
|
25289
|
-
afterObservation = createRiddleProofObservationReceipt({
|
|
24432
|
+
afterObservation = (0, import_receipts.createRiddleProofObservationReceipt)({
|
|
25290
24433
|
comparison_role: "after",
|
|
25291
24434
|
executor: { kind: "riddle_hosted", runner: afterResult.runner, job_id: afterResult.riddle?.job_id },
|
|
25292
24435
|
target: afterPreview ? { kind: "preview", url: afterSource, preview: afterPreview } : { kind: "url", url: afterSource },
|
|
@@ -25427,7 +24570,7 @@ async function main() {
|
|
|
25427
24570
|
result
|
|
25428
24571
|
});
|
|
25429
24572
|
const bodyFile = optionString(options, "bodyFile");
|
|
25430
|
-
if (bodyFile) (0,
|
|
24573
|
+
if (bodyFile) (0, import_node_fs5.writeFileSync)(bodyFile, body);
|
|
25431
24574
|
if (optionBoolean(options, "dryRun")) {
|
|
25432
24575
|
process.stdout.write(body);
|
|
25433
24576
|
return;
|
|
@@ -25529,14 +24672,14 @@ async function main() {
|
|
|
25529
24672
|
`);
|
|
25530
24673
|
};
|
|
25531
24674
|
}
|
|
25532
|
-
const result = await createRiddleApiClient(clientConfig).deployPreview(buildDir, label, previewFrameworkOption(options));
|
|
24675
|
+
const result = await (0, import_client.createRiddleApiClient)(clientConfig).deployPreview(buildDir, label, previewFrameworkOption(options));
|
|
25533
24676
|
const outputDir = profileOutputDirOption(options);
|
|
25534
24677
|
if (outputDir) {
|
|
25535
|
-
(0,
|
|
25536
|
-
(0,
|
|
24678
|
+
(0, import_node_fs5.mkdirSync)(outputDir, { recursive: true });
|
|
24679
|
+
(0, import_node_fs5.writeFileSync)(import_node_path5.default.join(outputDir, "preview-deploy-result.json"), `${JSON.stringify(result, null, 2)}
|
|
25537
24680
|
`);
|
|
25538
24681
|
if (result.receipt) {
|
|
25539
|
-
(0,
|
|
24682
|
+
(0, import_node_fs5.writeFileSync)(import_node_path5.default.join(outputDir, "preview-receipt.json"), `${JSON.stringify(result.receipt, null, 2)}
|
|
25540
24683
|
`);
|
|
25541
24684
|
}
|
|
25542
24685
|
}
|
|
@@ -25552,9 +24695,9 @@ async function main() {
|
|
|
25552
24695
|
const directory = positional[1];
|
|
25553
24696
|
const scriptFile = optionString(options, "scriptFile");
|
|
25554
24697
|
if (!directory || !scriptFile) throw new Error("riddle-server-preview requires <directory> and --script-file.");
|
|
25555
|
-
const result = await createRiddleApiClient(riddleClientConfig(options)).runServerPreview({
|
|
24698
|
+
const result = await (0, import_client.createRiddleApiClient)(riddleClientConfig(options)).runServerPreview({
|
|
25556
24699
|
directory,
|
|
25557
|
-
script: (0,
|
|
24700
|
+
script: (0, import_node_fs5.readFileSync)(scriptFile, "utf-8"),
|
|
25558
24701
|
image: optionString(options, "image"),
|
|
25559
24702
|
command: optionString(options, "command"),
|
|
25560
24703
|
port: optionString(options, "port") ? Number(optionString(options, "port")) : void 0,
|
|
@@ -25563,7 +24706,7 @@ async function main() {
|
|
|
25563
24706
|
readinessTimeoutSec: optionString(options, "readinessTimeout") ? Number(optionString(options, "readinessTimeout")) : void 0,
|
|
25564
24707
|
waitForSelector: optionString(options, "waitForSelector"),
|
|
25565
24708
|
navigationTimeoutSec: optionString(options, "navigationTimeout") ? Number(optionString(options, "navigationTimeout")) : void 0,
|
|
25566
|
-
viewport: parseRiddleViewport(optionString(options, "viewport")),
|
|
24709
|
+
viewport: (0, import_client.parseRiddleViewport)(optionString(options, "viewport")),
|
|
25567
24710
|
timeoutSec: optionString(options, "timeout") ? Number(optionString(options, "timeout")) : void 0,
|
|
25568
24711
|
pollAttempts: optionString(options, "pollAttempts") ? Number(optionString(options, "pollAttempts")) : void 0,
|
|
25569
24712
|
pollIntervalMs: optionString(options, "pollIntervalMs") ? Number(optionString(options, "pollIntervalMs")) : void 0,
|
|
@@ -25578,10 +24721,10 @@ async function main() {
|
|
|
25578
24721
|
const url = optionString(options, "url");
|
|
25579
24722
|
const scriptFile = optionString(options, "scriptFile");
|
|
25580
24723
|
if (!url || !scriptFile) throw new Error("riddle-run-script requires --url and --script-file.");
|
|
25581
|
-
const result = await createRiddleApiClient(riddleClientConfig(options)).runScript({
|
|
24724
|
+
const result = await (0, import_client.createRiddleApiClient)(riddleClientConfig(options)).runScript({
|
|
25582
24725
|
url,
|
|
25583
|
-
script: (0,
|
|
25584
|
-
viewport: parseRiddleViewport(optionString(options, "viewport")),
|
|
24726
|
+
script: (0, import_node_fs5.readFileSync)(scriptFile, "utf-8"),
|
|
24727
|
+
viewport: (0, import_client.parseRiddleViewport)(optionString(options, "viewport")),
|
|
25585
24728
|
timeoutSec: optionString(options, "timeout") ? Number(optionString(options, "timeout")) : void 0,
|
|
25586
24729
|
strict: optionBoolean(options, "strict"),
|
|
25587
24730
|
sync: options.sync === true ? true : void 0
|
|
@@ -25594,7 +24737,7 @@ async function main() {
|
|
|
25594
24737
|
const jobId = positional[1];
|
|
25595
24738
|
if (!jobId) throw new Error("riddle-poll requires <job-id>.");
|
|
25596
24739
|
const wait = options.wait === true;
|
|
25597
|
-
const result = await createRiddleApiClient(riddleClientConfig(options)).pollJob(jobId, {
|
|
24740
|
+
const result = await (0, import_client.createRiddleApiClient)(riddleClientConfig(options)).pollJob(jobId, {
|
|
25598
24741
|
wait,
|
|
25599
24742
|
attempts: optionString(options, "attempts") ? Number(optionString(options, "attempts")) : void 0,
|
|
25600
24743
|
intervalMs: optionString(options, "intervalMs") ? Number(optionString(options, "intervalMs")) : void 0,
|