@riddledc/riddle-proof 0.8.36 → 0.8.38
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 +21 -0
- package/dist/advanced/index.d.cts +1 -1
- package/dist/advanced/index.d.ts +1 -1
- package/dist/advanced/proof-run-engine.d.cts +1 -1
- package/dist/advanced/proof-run-engine.d.ts +1 -1
- package/dist/chunk-6KYXX4OE.js +209 -0
- package/dist/{chunk-TWTEUS7R.js → chunk-DI2XNGEZ.js} +126 -1
- package/dist/{chunk-E25K5PDM.js → chunk-U44KBAPH.js} +168 -7
- package/dist/cli/index.js +3 -2
- package/dist/cli.cjs +488 -3
- package/dist/cli.js +3 -2
- package/dist/index.cjs +336 -1
- package/dist/index.d.cts +2 -1
- package/dist/index.d.ts +2 -1
- package/dist/index.js +26 -18
- package/dist/pr-comment.cjs +235 -0
- package/dist/pr-comment.d.cts +41 -0
- package/dist/pr-comment.d.ts +41 -0
- package/dist/pr-comment.js +11 -0
- package/dist/{proof-run-engine-DYUu2mqY.d.cts → proof-run-engine-4dM37pEx.d.cts} +3 -3
- package/dist/{proof-run-engine-BmNYuOJ7.d.ts → proof-run-engine-BqaeqAze.d.ts} +3 -3
- package/dist/proof-run-engine.d.cts +1 -1
- package/dist/proof-run-engine.d.ts +1 -1
- package/dist/riddle-client.cjs +126 -1
- package/dist/riddle-client.d.cts +21 -1
- package/dist/riddle-client.d.ts +21 -1
- package/dist/riddle-client.js +1 -1
- package/dist/runtime/index.cjs +126 -1
- package/dist/runtime/index.d.cts +1 -1
- package/dist/runtime/index.d.ts +1 -1
- package/dist/runtime/index.js +1 -1
- package/dist/runtime/riddle-client.cjs +126 -1
- package/dist/runtime/riddle-client.d.cts +1 -1
- package/dist/runtime/riddle-client.d.ts +1 -1
- package/dist/runtime/riddle-client.js +1 -1
- package/package.json +7 -2
package/dist/cli.cjs
CHANGED
|
@@ -7438,10 +7438,68 @@ function previewDeployResultFromRecord(input) {
|
|
|
7438
7438
|
function canRecoverPreviewPublish(error) {
|
|
7439
7439
|
return error instanceof RiddleApiError && PREVIEW_PUBLISH_RECOVERY_STATUSES.has(error.status);
|
|
7440
7440
|
}
|
|
7441
|
+
function summarizePreviewDirectory(directory) {
|
|
7442
|
+
const stack = [directory];
|
|
7443
|
+
let fileCount = 0;
|
|
7444
|
+
let totalBytes = 0;
|
|
7445
|
+
while (stack.length) {
|
|
7446
|
+
const current = stack.pop();
|
|
7447
|
+
for (const entry of (0, import_node_fs5.readdirSync)(current, { withFileTypes: true })) {
|
|
7448
|
+
const fullPath = import_node_path5.default.join(current, entry.name);
|
|
7449
|
+
if (entry.isDirectory()) {
|
|
7450
|
+
stack.push(fullPath);
|
|
7451
|
+
continue;
|
|
7452
|
+
}
|
|
7453
|
+
if (!entry.isFile()) continue;
|
|
7454
|
+
const stat = (0, import_node_fs5.statSync)(fullPath);
|
|
7455
|
+
fileCount += 1;
|
|
7456
|
+
totalBytes += stat.size;
|
|
7457
|
+
}
|
|
7458
|
+
}
|
|
7459
|
+
return { file_count: fileCount, total_bytes: totalBytes };
|
|
7460
|
+
}
|
|
7461
|
+
function previewProgressEmitter(config, base) {
|
|
7462
|
+
return async (snapshot) => {
|
|
7463
|
+
if (!config.onPreviewProgress) return;
|
|
7464
|
+
await config.onPreviewProgress({
|
|
7465
|
+
label: base.label,
|
|
7466
|
+
framework: base.framework,
|
|
7467
|
+
directory: base.directory,
|
|
7468
|
+
elapsed_ms: Math.max(0, Date.now() - base.startedAt),
|
|
7469
|
+
warnings: base.warnings?.length ? base.warnings : void 0,
|
|
7470
|
+
...snapshot
|
|
7471
|
+
});
|
|
7472
|
+
};
|
|
7473
|
+
}
|
|
7441
7474
|
async function waitForPublishedPreview(config, input) {
|
|
7475
|
+
await input.emitProgress?.({
|
|
7476
|
+
stage: "publish_recovering",
|
|
7477
|
+
id: input.id,
|
|
7478
|
+
file_count: input.localSummary?.file_count,
|
|
7479
|
+
total_bytes: input.localSummary?.total_bytes,
|
|
7480
|
+
publish_error: input.publishError.message,
|
|
7481
|
+
message: `publish returned ${input.publishError.status}; polling preview status`
|
|
7482
|
+
});
|
|
7442
7483
|
for (let attempt = 1; attempt <= PREVIEW_PUBLISH_RECOVERY_ATTEMPTS; attempt += 1) {
|
|
7443
7484
|
const status = await riddleRequestJson(config, `/v1/preview/${input.id}`);
|
|
7485
|
+
await input.emitProgress?.({
|
|
7486
|
+
stage: "checking_status",
|
|
7487
|
+
id: input.id,
|
|
7488
|
+
attempt,
|
|
7489
|
+
attempts: PREVIEW_PUBLISH_RECOVERY_ATTEMPTS,
|
|
7490
|
+
status: typeof status.status === "string" ? status.status : null,
|
|
7491
|
+
preview_url: typeof status.preview_url === "string" ? status.preview_url : void 0,
|
|
7492
|
+
file_count: typeof status.file_count === "number" ? status.file_count : input.localSummary?.file_count,
|
|
7493
|
+
total_bytes: typeof status.total_bytes === "number" ? status.total_bytes : input.localSummary?.total_bytes
|
|
7494
|
+
});
|
|
7444
7495
|
if (String(status.status || "") === "ready" && String(status.preview_url || "").trim()) {
|
|
7496
|
+
await input.emitProgress?.({
|
|
7497
|
+
stage: "ready",
|
|
7498
|
+
id: input.id,
|
|
7499
|
+
preview_url: String(status.preview_url),
|
|
7500
|
+
file_count: typeof status.file_count === "number" ? status.file_count : input.localSummary?.file_count,
|
|
7501
|
+
total_bytes: typeof status.total_bytes === "number" ? status.total_bytes : input.localSummary?.total_bytes
|
|
7502
|
+
});
|
|
7445
7503
|
return previewDeployResultFromRecord({
|
|
7446
7504
|
record: status,
|
|
7447
7505
|
id: input.id,
|
|
@@ -7463,7 +7521,17 @@ async function deployRiddlePreview(config, directory, label, framework = "static
|
|
|
7463
7521
|
if (!directory?.trim()) throw new Error("directory is required");
|
|
7464
7522
|
if (!label?.trim()) throw new Error("label is required");
|
|
7465
7523
|
if (framework !== "spa" && framework !== "static") throw new Error("framework must be spa or static");
|
|
7524
|
+
const startedAt = Date.now();
|
|
7466
7525
|
const warnings = collectRiddlePreviewDeployWarnings(directory, framework);
|
|
7526
|
+
const emitProgress = previewProgressEmitter(config, { label, framework, directory, startedAt, warnings });
|
|
7527
|
+
await emitProgress({ stage: "validating", message: "checking preview input directory" });
|
|
7528
|
+
const localSummary = summarizePreviewDirectory(directory);
|
|
7529
|
+
await emitProgress({
|
|
7530
|
+
stage: "creating",
|
|
7531
|
+
file_count: localSummary.file_count,
|
|
7532
|
+
total_bytes: localSummary.total_bytes,
|
|
7533
|
+
message: "creating preview upload target"
|
|
7534
|
+
});
|
|
7467
7535
|
const created = await riddleRequestJson(config, "/v1/preview", {
|
|
7468
7536
|
method: "POST",
|
|
7469
7537
|
body: JSON.stringify({ framework, label })
|
|
@@ -7471,10 +7539,42 @@ async function deployRiddlePreview(config, directory, label, framework = "static
|
|
|
7471
7539
|
const id = String(created.id || "");
|
|
7472
7540
|
const uploadUrl = String(created.upload_url || "");
|
|
7473
7541
|
if (!id || !uploadUrl) throw new Error("Riddle preview create response was missing id or upload_url.");
|
|
7542
|
+
await emitProgress({
|
|
7543
|
+
stage: "created",
|
|
7544
|
+
id,
|
|
7545
|
+
file_count: localSummary.file_count,
|
|
7546
|
+
total_bytes: localSummary.total_bytes,
|
|
7547
|
+
message: "preview upload target created"
|
|
7548
|
+
});
|
|
7474
7549
|
const scratch = (0, import_node_fs5.mkdtempSync)(import_node_path5.default.join((0, import_node_os2.tmpdir)(), "riddle-preview-upload-"));
|
|
7475
7550
|
const tarball = import_node_path5.default.join(scratch, `${id}.tar.gz`);
|
|
7551
|
+
let tarballBytes = 0;
|
|
7476
7552
|
try {
|
|
7553
|
+
await emitProgress({
|
|
7554
|
+
stage: "archiving",
|
|
7555
|
+
id,
|
|
7556
|
+
file_count: localSummary.file_count,
|
|
7557
|
+
total_bytes: localSummary.total_bytes,
|
|
7558
|
+
message: "creating preview archive"
|
|
7559
|
+
});
|
|
7477
7560
|
(0, import_node_child_process4.execFileSync)("tar", ["czf", tarball, "-C", directory, "."], { stdio: "pipe" });
|
|
7561
|
+
tarballBytes = (0, import_node_fs5.statSync)(tarball).size;
|
|
7562
|
+
await emitProgress({
|
|
7563
|
+
stage: "archived",
|
|
7564
|
+
id,
|
|
7565
|
+
file_count: localSummary.file_count,
|
|
7566
|
+
total_bytes: localSummary.total_bytes,
|
|
7567
|
+
tarball_bytes: tarballBytes,
|
|
7568
|
+
message: "preview archive created"
|
|
7569
|
+
});
|
|
7570
|
+
await emitProgress({
|
|
7571
|
+
stage: "uploading",
|
|
7572
|
+
id,
|
|
7573
|
+
file_count: localSummary.file_count,
|
|
7574
|
+
total_bytes: localSummary.total_bytes,
|
|
7575
|
+
tarball_bytes: tarballBytes,
|
|
7576
|
+
message: "uploading preview archive"
|
|
7577
|
+
});
|
|
7478
7578
|
const upload = await fetchFor(config)(uploadUrl, {
|
|
7479
7579
|
method: "PUT",
|
|
7480
7580
|
headers: { "Content-Type": "application/gzip" },
|
|
@@ -7483,14 +7583,37 @@ async function deployRiddlePreview(config, directory, label, framework = "static
|
|
|
7483
7583
|
if (!upload.ok) {
|
|
7484
7584
|
throw new RiddleApiError(uploadUrl, upload.status, await upload.text());
|
|
7485
7585
|
}
|
|
7586
|
+
await emitProgress({
|
|
7587
|
+
stage: "uploaded",
|
|
7588
|
+
id,
|
|
7589
|
+
file_count: localSummary.file_count,
|
|
7590
|
+
total_bytes: localSummary.total_bytes,
|
|
7591
|
+
tarball_bytes: tarballBytes,
|
|
7592
|
+
message: "preview archive uploaded"
|
|
7593
|
+
});
|
|
7486
7594
|
} finally {
|
|
7487
7595
|
(0, import_node_fs5.rmSync)(scratch, { recursive: true, force: true });
|
|
7488
7596
|
}
|
|
7489
7597
|
const expiresAt = typeof created.expires_at === "string" ? created.expires_at : void 0;
|
|
7490
7598
|
try {
|
|
7599
|
+
await emitProgress({
|
|
7600
|
+
stage: "publishing",
|
|
7601
|
+
id,
|
|
7602
|
+
file_count: localSummary.file_count,
|
|
7603
|
+
total_bytes: localSummary.total_bytes,
|
|
7604
|
+
tarball_bytes: tarballBytes || void 0,
|
|
7605
|
+
message: "publishing preview"
|
|
7606
|
+
});
|
|
7491
7607
|
const published = await riddleRequestJson(config, `/v1/preview/${id}/publish`, {
|
|
7492
7608
|
method: "POST"
|
|
7493
7609
|
});
|
|
7610
|
+
await emitProgress({
|
|
7611
|
+
stage: "ready",
|
|
7612
|
+
id,
|
|
7613
|
+
preview_url: String(published.preview_url || ""),
|
|
7614
|
+
file_count: typeof published.file_count === "number" ? published.file_count : localSummary.file_count,
|
|
7615
|
+
total_bytes: typeof published.total_bytes === "number" ? published.total_bytes : localSummary.total_bytes
|
|
7616
|
+
});
|
|
7494
7617
|
return previewDeployResultFromRecord({ record: published, id, label, framework, expiresAt, warnings });
|
|
7495
7618
|
} catch (error) {
|
|
7496
7619
|
if (!canRecoverPreviewPublish(error)) throw error;
|
|
@@ -7500,7 +7623,9 @@ async function deployRiddlePreview(config, directory, label, framework = "static
|
|
|
7500
7623
|
framework,
|
|
7501
7624
|
expiresAt,
|
|
7502
7625
|
publishError: error,
|
|
7503
|
-
warnings
|
|
7626
|
+
warnings,
|
|
7627
|
+
localSummary,
|
|
7628
|
+
emitProgress
|
|
7504
7629
|
});
|
|
7505
7630
|
}
|
|
7506
7631
|
}
|
|
@@ -17252,6 +17377,210 @@ function extractRiddleProofProfileResult(input) {
|
|
|
17252
17377
|
return void 0;
|
|
17253
17378
|
}
|
|
17254
17379
|
|
|
17380
|
+
// src/pr-comment.ts
|
|
17381
|
+
var RIDDLE_PROOF_PR_COMMENT_MARKER = "<!-- riddle-proof:pr-comment:v1 -->";
|
|
17382
|
+
function asRecord(value) {
|
|
17383
|
+
return value && typeof value === "object" && !Array.isArray(value) ? value : {};
|
|
17384
|
+
}
|
|
17385
|
+
function asArray(value) {
|
|
17386
|
+
return Array.isArray(value) ? value : [];
|
|
17387
|
+
}
|
|
17388
|
+
function stringValue3(value) {
|
|
17389
|
+
return typeof value === "string" && value.trim() ? value.trim() : void 0;
|
|
17390
|
+
}
|
|
17391
|
+
function numberValue2(value) {
|
|
17392
|
+
return typeof value === "number" && Number.isFinite(value) ? value : void 0;
|
|
17393
|
+
}
|
|
17394
|
+
function booleanValue2(value) {
|
|
17395
|
+
return typeof value === "boolean" ? value : void 0;
|
|
17396
|
+
}
|
|
17397
|
+
function artifactKind(name, url) {
|
|
17398
|
+
const target = `${name} ${url}`.toLowerCase();
|
|
17399
|
+
if (/\.(png|jpe?g|gif|webp|avif|svg)(\?|#|$)/.test(target)) return "image";
|
|
17400
|
+
if (/\.(json|har|txt|md|html|log)(\?|#|$)/.test(target)) return "data";
|
|
17401
|
+
return "artifact";
|
|
17402
|
+
}
|
|
17403
|
+
function artifactDisplayName(value, fallback) {
|
|
17404
|
+
const raw = stringValue3(value);
|
|
17405
|
+
if (raw) return raw;
|
|
17406
|
+
return fallback;
|
|
17407
|
+
}
|
|
17408
|
+
function collectArtifacts(runResponse) {
|
|
17409
|
+
const proofResult = asRecord(runResponse.proofResult);
|
|
17410
|
+
const outputs = asArray(proofResult.outputs);
|
|
17411
|
+
const artifacts = [];
|
|
17412
|
+
const seen = /* @__PURE__ */ new Set();
|
|
17413
|
+
for (const [index, item] of outputs.entries()) {
|
|
17414
|
+
const artifact = asRecord(item);
|
|
17415
|
+
const url = stringValue3(artifact.url);
|
|
17416
|
+
if (!url || seen.has(url)) continue;
|
|
17417
|
+
seen.add(url);
|
|
17418
|
+
const name = artifactDisplayName(artifact.name, `artifact-${index + 1}`);
|
|
17419
|
+
artifacts.push({
|
|
17420
|
+
name,
|
|
17421
|
+
url,
|
|
17422
|
+
kind: artifactKind(name, url),
|
|
17423
|
+
size_bytes: numberValue2(artifact.size)
|
|
17424
|
+
});
|
|
17425
|
+
}
|
|
17426
|
+
return artifacts;
|
|
17427
|
+
}
|
|
17428
|
+
function pageSummaries(result) {
|
|
17429
|
+
const pages = [];
|
|
17430
|
+
for (const page of asArray(result.pages)) {
|
|
17431
|
+
const record = asRecord(page);
|
|
17432
|
+
const route = stringValue3(record.route) || stringValue3(record.url) || "page";
|
|
17433
|
+
const checks = asRecord(record.checks);
|
|
17434
|
+
let passed = 0;
|
|
17435
|
+
let failed = 0;
|
|
17436
|
+
for (const value of Object.values(checks)) {
|
|
17437
|
+
if (value === true) passed += 1;
|
|
17438
|
+
if (value === false) failed += 1;
|
|
17439
|
+
}
|
|
17440
|
+
pages.push({ route, passed, failed });
|
|
17441
|
+
}
|
|
17442
|
+
return pages;
|
|
17443
|
+
}
|
|
17444
|
+
function summarizeExplicitChecks(value) {
|
|
17445
|
+
let passed = 0;
|
|
17446
|
+
let failed = 0;
|
|
17447
|
+
const visit = (current, inChecks = false) => {
|
|
17448
|
+
if (current === true && inChecks) {
|
|
17449
|
+
passed += 1;
|
|
17450
|
+
return;
|
|
17451
|
+
}
|
|
17452
|
+
if (current === false && inChecks) {
|
|
17453
|
+
failed += 1;
|
|
17454
|
+
return;
|
|
17455
|
+
}
|
|
17456
|
+
if (Array.isArray(current)) {
|
|
17457
|
+
for (const item of current) visit(item, inChecks);
|
|
17458
|
+
return;
|
|
17459
|
+
}
|
|
17460
|
+
if (current && typeof current === "object") {
|
|
17461
|
+
for (const [key, item] of Object.entries(current)) {
|
|
17462
|
+
visit(item, inChecks || key === "checks");
|
|
17463
|
+
}
|
|
17464
|
+
}
|
|
17465
|
+
};
|
|
17466
|
+
visit(value);
|
|
17467
|
+
return { passed, failed };
|
|
17468
|
+
}
|
|
17469
|
+
function selectPrimaryImage(artifacts) {
|
|
17470
|
+
const images = artifacts.filter((artifact) => artifact.kind === "image");
|
|
17471
|
+
return images.find((artifact) => /after|proof|screenshot/i.test(artifact.name)) || images[0];
|
|
17472
|
+
}
|
|
17473
|
+
function summarizeRiddleProofPrComment(input) {
|
|
17474
|
+
const runResponse = asRecord(input.runResponse);
|
|
17475
|
+
const result = asRecord(input.result);
|
|
17476
|
+
const proofResult = asRecord(runResponse.proofResult);
|
|
17477
|
+
const preview = asRecord(runResponse.preview);
|
|
17478
|
+
const artifacts = collectArtifacts(runResponse);
|
|
17479
|
+
const pages = pageSummaries(result);
|
|
17480
|
+
const checkSource = { ...result };
|
|
17481
|
+
delete checkSource.ok;
|
|
17482
|
+
const nestedChecks = summarizeExplicitChecks(checkSource);
|
|
17483
|
+
const ok = booleanValue2(result.ok) ?? booleanValue2(runResponse.ok) ?? null;
|
|
17484
|
+
return {
|
|
17485
|
+
ok,
|
|
17486
|
+
status: stringValue3(proofResult.status),
|
|
17487
|
+
job_id: stringValue3(proofResult.job_id),
|
|
17488
|
+
duration_ms: numberValue2(proofResult.duration_ms),
|
|
17489
|
+
proof_url: stringValue3(runResponse.proofUrl),
|
|
17490
|
+
preview_id: stringValue3(preview.id),
|
|
17491
|
+
preview_url: stringValue3(preview.preview_url) || stringValue3(preview.url),
|
|
17492
|
+
preview_publish_recovered: booleanValue2(preview.publish_recovered),
|
|
17493
|
+
preview_publish_error: stringValue3(preview.publish_error),
|
|
17494
|
+
passed_checks: nestedChecks.passed,
|
|
17495
|
+
failed_checks: nestedChecks.failed,
|
|
17496
|
+
pages,
|
|
17497
|
+
artifacts,
|
|
17498
|
+
primary_image: selectPrimaryImage(artifacts)
|
|
17499
|
+
};
|
|
17500
|
+
}
|
|
17501
|
+
function formatDuration(ms) {
|
|
17502
|
+
if (typeof ms !== "number" || !Number.isFinite(ms)) return "";
|
|
17503
|
+
const seconds = Math.max(0, Math.round(ms / 1e3));
|
|
17504
|
+
const minutes = Math.floor(seconds / 60);
|
|
17505
|
+
const remainder = seconds % 60;
|
|
17506
|
+
return minutes > 0 ? `${minutes}m${String(remainder).padStart(2, "0")}s` : `${seconds}s`;
|
|
17507
|
+
}
|
|
17508
|
+
function markdownLink(label, url) {
|
|
17509
|
+
return `[${label.replace(/\]/g, "\\]")}](${url})`;
|
|
17510
|
+
}
|
|
17511
|
+
function resultLabel(summary) {
|
|
17512
|
+
if (summary.ok === true) return "passed";
|
|
17513
|
+
if (summary.ok === false) return "failed";
|
|
17514
|
+
return summary.status || "recorded";
|
|
17515
|
+
}
|
|
17516
|
+
function artifactRank(artifact) {
|
|
17517
|
+
const name = artifact.name.toLowerCase();
|
|
17518
|
+
if (name === "proof.json") return 0;
|
|
17519
|
+
if (name === "result.json") return 1;
|
|
17520
|
+
if (name.includes("proof") && name.endsWith(".json") && !name.includes("layout")) return 2;
|
|
17521
|
+
if (name === "console.json") return 3;
|
|
17522
|
+
if (artifact.kind === "data") return 10;
|
|
17523
|
+
if (artifact.kind === "image") return 20;
|
|
17524
|
+
return 30;
|
|
17525
|
+
}
|
|
17526
|
+
function buildRiddleProofPrCommentMarkdown(input) {
|
|
17527
|
+
const summary = summarizeRiddleProofPrComment(input);
|
|
17528
|
+
const title = input.title?.trim() || "Riddle Proof Evidence";
|
|
17529
|
+
const lines = [
|
|
17530
|
+
RIDDLE_PROOF_PR_COMMENT_MARKER,
|
|
17531
|
+
`## ${title}`,
|
|
17532
|
+
"",
|
|
17533
|
+
`**Result:** ${resultLabel(summary)}`
|
|
17534
|
+
];
|
|
17535
|
+
if (input.goal?.trim()) lines.push(`**Goal:** ${input.goal.trim()}`);
|
|
17536
|
+
if (input.successCriteria?.trim()) lines.push(`**Success criteria:** ${input.successCriteria.trim()}`);
|
|
17537
|
+
if (summary.status) lines.push(`**Riddle job status:** ${summary.status}`);
|
|
17538
|
+
if (summary.job_id) lines.push(`**Riddle job:** \`${summary.job_id}\``);
|
|
17539
|
+
if (summary.duration_ms) lines.push(`**Duration:** ${formatDuration(summary.duration_ms)}`);
|
|
17540
|
+
if (summary.proof_url) lines.push(`**Proof URL:** ${markdownLink(summary.proof_url, summary.proof_url)}`);
|
|
17541
|
+
if (summary.preview_id || summary.preview_url) {
|
|
17542
|
+
const previewLabel = summary.preview_id ? `\`${summary.preview_id}\`` : "preview";
|
|
17543
|
+
lines.push(`**Preview:** ${summary.preview_url ? markdownLink(previewLabel, summary.preview_url) : previewLabel}`);
|
|
17544
|
+
}
|
|
17545
|
+
if (summary.preview_publish_recovered) {
|
|
17546
|
+
const detail = summary.preview_publish_error ? `: ${summary.preview_publish_error}` : "";
|
|
17547
|
+
lines.push(`**Preview publish recovery:** recovered after publish error${detail}`);
|
|
17548
|
+
}
|
|
17549
|
+
lines.push(`**Checks:** ${summary.passed_checks} passed / ${summary.failed_checks} failed`);
|
|
17550
|
+
lines.push("");
|
|
17551
|
+
if (summary.primary_image) {
|
|
17552
|
+
lines.push("### Screenshot");
|
|
17553
|
+
lines.push(``);
|
|
17554
|
+
lines.push("");
|
|
17555
|
+
}
|
|
17556
|
+
if (summary.pages.length) {
|
|
17557
|
+
lines.push("### Page Checks");
|
|
17558
|
+
for (const page of summary.pages.slice(0, 12)) {
|
|
17559
|
+
lines.push(`- \`${page.route}\`: ${page.passed} passed / ${page.failed} failed`);
|
|
17560
|
+
}
|
|
17561
|
+
if (summary.pages.length > 12) lines.push(`- ${summary.pages.length - 12} more page(s) omitted`);
|
|
17562
|
+
lines.push("");
|
|
17563
|
+
}
|
|
17564
|
+
const linkedArtifacts = summary.artifacts.filter((artifact) => artifact.url !== summary.primary_image?.url).sort((left, right) => artifactRank(left) - artifactRank(right) || left.name.localeCompare(right.name)).slice(0, 20);
|
|
17565
|
+
if (linkedArtifacts.length) {
|
|
17566
|
+
lines.push("### Artifacts");
|
|
17567
|
+
for (const artifact of linkedArtifacts) {
|
|
17568
|
+
lines.push(`- ${markdownLink(artifact.name, artifact.url)}`);
|
|
17569
|
+
}
|
|
17570
|
+
if (summary.artifacts.length - (summary.primary_image ? 1 : 0) > linkedArtifacts.length) {
|
|
17571
|
+
lines.push(`- ${summary.artifacts.length - (summary.primary_image ? 1 : 0) - linkedArtifacts.length} more artifact(s) omitted`);
|
|
17572
|
+
}
|
|
17573
|
+
lines.push("");
|
|
17574
|
+
}
|
|
17575
|
+
if (input.source?.trim()) {
|
|
17576
|
+
lines.push(`_Source: ${input.source.trim()}_`);
|
|
17577
|
+
} else {
|
|
17578
|
+
lines.push("_Updated by `riddle-proof-loop pr-comment`._");
|
|
17579
|
+
}
|
|
17580
|
+
return `${lines.join("\n").trim()}
|
|
17581
|
+
`;
|
|
17582
|
+
}
|
|
17583
|
+
|
|
17255
17584
|
// src/cli.ts
|
|
17256
17585
|
var RIDDLE_PROFILE_BALANCE_PREFLIGHT_MIN_SECONDS_PER_JOB = 30;
|
|
17257
17586
|
var KNOWN_CLI_OPTIONS = /* @__PURE__ */ new Set([
|
|
@@ -17274,11 +17603,14 @@ var KNOWN_CLI_OPTIONS = /* @__PURE__ */ new Set([
|
|
|
17274
17603
|
"codexSandbox",
|
|
17275
17604
|
"codexTimeoutMs",
|
|
17276
17605
|
"command",
|
|
17606
|
+
"commentMode",
|
|
17277
17607
|
"continueWithStage",
|
|
17278
17608
|
"createdAt",
|
|
17279
17609
|
"decision",
|
|
17280
17610
|
"defaultReviewer",
|
|
17281
17611
|
"defaultShipMode",
|
|
17612
|
+
"bodyFile",
|
|
17613
|
+
"dryRun",
|
|
17282
17614
|
"exclude",
|
|
17283
17615
|
"format",
|
|
17284
17616
|
"framework",
|
|
@@ -17306,20 +17638,25 @@ var KNOWN_CLI_OPTIONS = /* @__PURE__ */ new Set([
|
|
|
17306
17638
|
"pack",
|
|
17307
17639
|
"packFile",
|
|
17308
17640
|
"profile",
|
|
17641
|
+
"proofDir",
|
|
17642
|
+
"pr",
|
|
17309
17643
|
"progressEveryMs",
|
|
17310
17644
|
"quiet",
|
|
17311
17645
|
"readinessPath",
|
|
17312
17646
|
"readinessTimeout",
|
|
17313
17647
|
"reasonsJson",
|
|
17648
|
+
"repo",
|
|
17314
17649
|
"requestJson",
|
|
17315
17650
|
"requiredJson",
|
|
17316
17651
|
"responseJson",
|
|
17317
17652
|
"resultFormat",
|
|
17653
|
+
"resultJson",
|
|
17318
17654
|
"resultsDir",
|
|
17319
17655
|
"riddleEngineModuleUrl",
|
|
17320
17656
|
"riddleProofDir",
|
|
17321
17657
|
"route",
|
|
17322
17658
|
"runDir",
|
|
17659
|
+
"runResponse",
|
|
17323
17660
|
"runner",
|
|
17324
17661
|
"scriptFile",
|
|
17325
17662
|
"sourceKind",
|
|
@@ -17356,9 +17693,10 @@ function usage() {
|
|
|
17356
17693
|
" riddle-proof-loop run-profile aggregate --profile <file|json|-> --url <base-url> [--base-url <base-url>] --input-dir <dir>|--inputs <path[,path...]> [--output <dir>|--output-dir <dir>] [--result-format json|compact-json|summary|none; default json]",
|
|
17357
17694
|
" riddle-proof-loop run-profile recover --profile <file|json|-> --url <base-url> [--base-url <base-url>] --job <job-id> [--viewport-name <name[,name...]>] [--output <dir>|--output-dir <dir>] [--result-format json|compact-json|summary|none; default json]",
|
|
17358
17695
|
" riddle-proof-loop regression-pack run [--pack oc-flow-regression|--pack-file <file>] [--local-core true|false; default true] [--hosted-riddle true|false; default false] [--format json|markdown|compact-json; default json] [--output <dir>|--output-dir <dir>]",
|
|
17696
|
+
" riddle-proof-loop pr-comment --proof-dir <dir>|--run-response <file> [--result-json <file>] --pr <number|url> [--repo owner/name] [--dry-run] [--body-file <file>] [--comment-mode update|append]",
|
|
17359
17697
|
" riddle-proof-loop profile-body-assertions --artifact <file|url|-> --candidates-json <file|json|-> [--required-json <file|json|->] [--format json|body-contains]",
|
|
17360
17698
|
" riddle-proof-loop profile-http-status-preflight --profile <file|json|-> --url <base-url> [--format json|summary]",
|
|
17361
|
-
" riddle-proof-loop riddle-preview-deploy <build-dir> <label> [--framework spa|static]",
|
|
17699
|
+
" riddle-proof-loop riddle-preview-deploy <build-dir> <label> [--framework spa|static] [--quiet]",
|
|
17362
17700
|
" riddle-proof-loop riddle-server-preview <directory> --script-file <file> [--path /route] [--wait-for-selector selector]",
|
|
17363
17701
|
" riddle-proof-loop riddle-run-script --url <url> --script-file <file> [--viewport 1280x720] [--strict true|false]",
|
|
17364
17702
|
" riddle-proof-loop riddle-poll <job-id> [--wait] [--attempts n] [--quiet]",
|
|
@@ -18127,6 +18465,18 @@ function formatPollDuration(ms) {
|
|
|
18127
18465
|
const remainder = seconds % 60;
|
|
18128
18466
|
return minutes > 0 ? `${minutes}m${String(remainder).padStart(2, "0")}s` : `${seconds}s`;
|
|
18129
18467
|
}
|
|
18468
|
+
function formatByteCount(bytes) {
|
|
18469
|
+
if (typeof bytes !== "number" || !Number.isFinite(bytes)) return "n/a";
|
|
18470
|
+
if (bytes < 1024) return `${bytes}B`;
|
|
18471
|
+
const units = ["KB", "MB", "GB", "TB"];
|
|
18472
|
+
let value = bytes / 1024;
|
|
18473
|
+
let unitIndex = 0;
|
|
18474
|
+
while (value >= 1024 && unitIndex < units.length - 1) {
|
|
18475
|
+
value /= 1024;
|
|
18476
|
+
unitIndex += 1;
|
|
18477
|
+
}
|
|
18478
|
+
return `${value >= 10 ? value.toFixed(0) : value.toFixed(1)}${units[unitIndex]}`;
|
|
18479
|
+
}
|
|
18130
18480
|
function riddlePollProgressLine(snapshot) {
|
|
18131
18481
|
const submittedAt = snapshot.submitted_at || "not-submitted";
|
|
18132
18482
|
const queuePart = snapshot.running_without_submission ? ` waiting_for_submit=${formatPollDuration(snapshot.pre_submission_elapsed_ms)}${snapshot.queue_elapsed_ms !== null ? ` queued_for=${formatPollDuration(snapshot.queue_elapsed_ms)}` : ""}` : snapshot.queue_elapsed_ms !== null ? ` queue=${formatPollDuration(snapshot.queue_elapsed_ms)}` : "";
|
|
@@ -18140,6 +18490,93 @@ function riddlePollProgressLine(snapshot) {
|
|
|
18140
18490
|
`submitted_at=${submittedAt}${queuePart}${terminalPart}`
|
|
18141
18491
|
].join(" ");
|
|
18142
18492
|
}
|
|
18493
|
+
function riddlePreviewProgressLine(snapshot) {
|
|
18494
|
+
const idPart = snapshot.id ? ` id=${snapshot.id}` : "";
|
|
18495
|
+
const statusPart = snapshot.status ? ` status=${snapshot.status}` : "";
|
|
18496
|
+
const attemptPart = snapshot.attempt && snapshot.attempts ? ` attempt=${snapshot.attempt}/${snapshot.attempts}` : "";
|
|
18497
|
+
const previewPart = snapshot.preview_url ? ` url=${snapshot.preview_url}` : "";
|
|
18498
|
+
const filePart = typeof snapshot.file_count === "number" ? ` files=${snapshot.file_count}` : "";
|
|
18499
|
+
const totalPart = typeof snapshot.total_bytes === "number" ? ` bytes=${formatByteCount(snapshot.total_bytes)}` : "";
|
|
18500
|
+
const archivePart = typeof snapshot.tarball_bytes === "number" ? ` archive=${formatByteCount(snapshot.tarball_bytes)}` : "";
|
|
18501
|
+
const recoveryPart = snapshot.publish_error ? ` publish_error=${JSON.stringify(snapshot.publish_error)}` : "";
|
|
18502
|
+
const messagePart = snapshot.message ? ` ${snapshot.message}` : "";
|
|
18503
|
+
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}`;
|
|
18504
|
+
}
|
|
18505
|
+
function readJsonFileIfExists(filePath) {
|
|
18506
|
+
if (!filePath || !(0, import_node_fs6.existsSync)(filePath)) return void 0;
|
|
18507
|
+
return readJsonValue(filePath, filePath);
|
|
18508
|
+
}
|
|
18509
|
+
function defaultProofDirJsonPath(proofDir, filename) {
|
|
18510
|
+
return proofDir ? import_node_path6.default.join(proofDir, filename) : void 0;
|
|
18511
|
+
}
|
|
18512
|
+
function prNumberFromValue(value) {
|
|
18513
|
+
const text = value?.trim();
|
|
18514
|
+
if (!text) return "";
|
|
18515
|
+
const match = text.match(/\/pull\/(\d+)(?:\/|$)/) || text.match(/^#?(\d+)$/);
|
|
18516
|
+
return match ? match[1] : text;
|
|
18517
|
+
}
|
|
18518
|
+
function ghJson(args, input) {
|
|
18519
|
+
const result = (0, import_node_child_process5.spawnSync)("gh", args, {
|
|
18520
|
+
input: typeof input === "undefined" ? void 0 : `${JSON.stringify(input)}
|
|
18521
|
+
`,
|
|
18522
|
+
encoding: "utf-8",
|
|
18523
|
+
timeout: 9e4
|
|
18524
|
+
});
|
|
18525
|
+
if (result.error) throw result.error;
|
|
18526
|
+
if (result.status !== 0) {
|
|
18527
|
+
const detail = (result.stderr || result.stdout || "").trim();
|
|
18528
|
+
throw new Error(`gh ${args.join(" ")} failed${detail ? `: ${detail}` : ""}`);
|
|
18529
|
+
}
|
|
18530
|
+
const stdout = (result.stdout || "").trim();
|
|
18531
|
+
return stdout ? JSON.parse(stdout) : {};
|
|
18532
|
+
}
|
|
18533
|
+
function resolveGhRepoName(repoOption) {
|
|
18534
|
+
if (repoOption?.trim()) return repoOption.trim();
|
|
18535
|
+
const result = (0, import_node_child_process5.spawnSync)("gh", ["repo", "view", "--json", "nameWithOwner", "--jq", ".nameWithOwner"], {
|
|
18536
|
+
encoding: "utf-8",
|
|
18537
|
+
timeout: 3e4
|
|
18538
|
+
});
|
|
18539
|
+
if (result.error) throw result.error;
|
|
18540
|
+
if (result.status !== 0 || !result.stdout.trim()) {
|
|
18541
|
+
const detail = (result.stderr || result.stdout || "").trim();
|
|
18542
|
+
throw new Error(`Could not resolve GitHub repository. Pass --repo owner/name.${detail ? ` gh said: ${detail}` : ""}`);
|
|
18543
|
+
}
|
|
18544
|
+
return result.stdout.trim();
|
|
18545
|
+
}
|
|
18546
|
+
function findManagedPrComment(repo, prNumber) {
|
|
18547
|
+
const comments = ghJson(["api", `repos/${repo}/issues/${prNumber}/comments`, "--paginate"]);
|
|
18548
|
+
return comments.find((comment) => typeof comment.body === "string" && comment.body.includes(RIDDLE_PROOF_PR_COMMENT_MARKER));
|
|
18549
|
+
}
|
|
18550
|
+
function upsertPrComment(input) {
|
|
18551
|
+
const payload = { body: input.body };
|
|
18552
|
+
if (input.mode !== "append") {
|
|
18553
|
+
const existing = findManagedPrComment(input.repo, input.prNumber);
|
|
18554
|
+
if (existing?.id) {
|
|
18555
|
+
return {
|
|
18556
|
+
action: "updated",
|
|
18557
|
+
comment: ghJson([
|
|
18558
|
+
"api",
|
|
18559
|
+
`repos/${input.repo}/issues/comments/${existing.id}`,
|
|
18560
|
+
"-X",
|
|
18561
|
+
"PATCH",
|
|
18562
|
+
"--input",
|
|
18563
|
+
"-"
|
|
18564
|
+
], payload)
|
|
18565
|
+
};
|
|
18566
|
+
}
|
|
18567
|
+
}
|
|
18568
|
+
return {
|
|
18569
|
+
action: "created",
|
|
18570
|
+
comment: ghJson([
|
|
18571
|
+
"api",
|
|
18572
|
+
`repos/${input.repo}/issues/${input.prNumber}/comments`,
|
|
18573
|
+
"-X",
|
|
18574
|
+
"POST",
|
|
18575
|
+
"--input",
|
|
18576
|
+
"-"
|
|
18577
|
+
], payload)
|
|
18578
|
+
};
|
|
18579
|
+
}
|
|
18143
18580
|
function readJsonValue(value, label) {
|
|
18144
18581
|
if (!value) throw new Error(`${label} is required.`);
|
|
18145
18582
|
const raw = value === "-" ? readStdin() : (0, import_node_fs6.existsSync)(value) ? (0, import_node_fs6.readFileSync)(value, "utf-8") : value;
|
|
@@ -21772,6 +22209,47 @@ async function main() {
|
|
|
21772
22209
|
process.exitCode = result.ok ? 0 : 1;
|
|
21773
22210
|
return;
|
|
21774
22211
|
}
|
|
22212
|
+
if (command === "pr-comment") {
|
|
22213
|
+
const proofDir = optionString(options, "proofDir") || optionString(options, "outputDir") || positional[1];
|
|
22214
|
+
const runResponsePath = optionString(options, "runResponse") || defaultProofDirJsonPath(proofDir, "riddle-run-response.json");
|
|
22215
|
+
const resultJsonPath = optionString(options, "resultJson") || defaultProofDirJsonPath(proofDir, "result.json");
|
|
22216
|
+
const runResponse = readJsonFileIfExists(runResponsePath);
|
|
22217
|
+
const result = readJsonFileIfExists(resultJsonPath);
|
|
22218
|
+
if (!runResponse && !result) {
|
|
22219
|
+
throw new Error("pr-comment requires --proof-dir with riddle-run-response.json/result.json or explicit --run-response/--result-json.");
|
|
22220
|
+
}
|
|
22221
|
+
const body = buildRiddleProofPrCommentMarkdown({
|
|
22222
|
+
title: optionString(options, "title"),
|
|
22223
|
+
goal: optionString(options, "summary"),
|
|
22224
|
+
successCriteria: optionString(options, "successCriteria"),
|
|
22225
|
+
runResponse,
|
|
22226
|
+
result
|
|
22227
|
+
});
|
|
22228
|
+
const bodyFile = optionString(options, "bodyFile");
|
|
22229
|
+
if (bodyFile) (0, import_node_fs6.writeFileSync)(bodyFile, body);
|
|
22230
|
+
if (optionBoolean(options, "dryRun")) {
|
|
22231
|
+
process.stdout.write(body);
|
|
22232
|
+
return;
|
|
22233
|
+
}
|
|
22234
|
+
const prNumber = prNumberFromValue(optionString(options, "pr"));
|
|
22235
|
+
if (!prNumber) throw new Error("pr-comment requires --pr <number|url> unless --dry-run is used.");
|
|
22236
|
+
const commentMode = optionString(options, "commentMode") || "update";
|
|
22237
|
+
if (!["update", "append"].includes(commentMode)) throw new Error("--comment-mode must be update or append.");
|
|
22238
|
+
const repo = resolveGhRepoName(optionString(options, "repo"));
|
|
22239
|
+
const resultPayload = upsertPrComment({ repo, prNumber, body, mode: commentMode });
|
|
22240
|
+
const comment = resultPayload.comment;
|
|
22241
|
+
process.stdout.write(`${JSON.stringify({
|
|
22242
|
+
ok: true,
|
|
22243
|
+
action: resultPayload.action,
|
|
22244
|
+
repo,
|
|
22245
|
+
pr: prNumber,
|
|
22246
|
+
comment_url: cliString(comment.html_url) || null,
|
|
22247
|
+
summary: summarizeRiddleProofPrComment({ runResponse, result }),
|
|
22248
|
+
body_file: bodyFile || null
|
|
22249
|
+
}, null, 2)}
|
|
22250
|
+
`);
|
|
22251
|
+
return;
|
|
22252
|
+
}
|
|
21775
22253
|
if (command === "profile-http-status-preflight") {
|
|
21776
22254
|
const profile = normalizeProfileForCli(options);
|
|
21777
22255
|
const result = await preflightRiddleProofProfileHttpStatusChecks(profile);
|
|
@@ -21815,7 +22293,14 @@ async function main() {
|
|
|
21815
22293
|
if (command === "riddle-preview-deploy") {
|
|
21816
22294
|
const buildDir = positional[1];
|
|
21817
22295
|
const label = positional[2];
|
|
21818
|
-
const
|
|
22296
|
+
const clientConfig = riddleClientConfig(options);
|
|
22297
|
+
if (options.quiet !== true) {
|
|
22298
|
+
clientConfig.onPreviewProgress = (snapshot) => {
|
|
22299
|
+
process.stderr.write(`${riddlePreviewProgressLine(snapshot)}
|
|
22300
|
+
`);
|
|
22301
|
+
};
|
|
22302
|
+
}
|
|
22303
|
+
const result = await createRiddleApiClient(clientConfig).deployPreview(buildDir, label, previewFrameworkOption(options));
|
|
21819
22304
|
for (const warning of result.warnings ?? []) {
|
|
21820
22305
|
process.stderr.write(`Warning: ${warning}
|
|
21821
22306
|
`);
|
package/dist/cli.js
CHANGED
|
@@ -1,7 +1,8 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
|
-
import "./chunk-
|
|
2
|
+
import "./chunk-U44KBAPH.js";
|
|
3
|
+
import "./chunk-DI2XNGEZ.js";
|
|
4
|
+
import "./chunk-6KYXX4OE.js";
|
|
3
5
|
import "./chunk-Z2LCVROU.js";
|
|
4
|
-
import "./chunk-TWTEUS7R.js";
|
|
5
6
|
import "./chunk-ZREWMTFA.js";
|
|
6
7
|
import "./chunk-ZQWVXQKJ.js";
|
|
7
8
|
import "./chunk-RDPG554T.js";
|