@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/README.md
CHANGED
|
@@ -968,6 +968,27 @@ way to a ready PR after proof and CI; `leave_draft: true` is only an explicit
|
|
|
968
968
|
debug or user-request escape hatch. The notification adapter is where a host
|
|
969
969
|
updates Discord, OpenClaw, GitHub, or another integration.
|
|
970
970
|
|
|
971
|
+
## PR Proof Comments
|
|
972
|
+
|
|
973
|
+
Use `pr-comment` when a project already has a PR and a Riddle Proof output
|
|
974
|
+
directory, but is not using the full ship loop. It reads
|
|
975
|
+
`riddle-run-response.json` and `result.json`, builds a managed GitHub comment,
|
|
976
|
+
embeds the primary hosted screenshot when available, links structured artifacts,
|
|
977
|
+
summarizes check counts, and updates the existing Riddle Proof comment on
|
|
978
|
+
reruns.
|
|
979
|
+
|
|
980
|
+
```sh
|
|
981
|
+
riddle-proof-loop pr-comment \
|
|
982
|
+
--proof-dir test-results/riddle-proof-docs \
|
|
983
|
+
--pr 228 \
|
|
984
|
+
--repo davisdiehl/riddle-site
|
|
985
|
+
```
|
|
986
|
+
|
|
987
|
+
Use `--dry-run` to print the exact Markdown without touching GitHub, or
|
|
988
|
+
`--body-file proof-comment.md` to save the generated body for another tool. The
|
|
989
|
+
markdown builder is also exported from `@riddledc/riddle-proof/pr-comment` for
|
|
990
|
+
host integrations that want to post comments themselves.
|
|
991
|
+
|
|
971
992
|
## Runtime Scratch Space
|
|
972
993
|
|
|
973
994
|
The packaged proof-run setup uses isolated git worktrees for before and after
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
export { b as runner } from '../runner-4LJ5z0D-.cjs';
|
|
2
2
|
export { l as engineHarness } from '../engine-harness-LBfqbFSe.cjs';
|
|
3
3
|
export { p as proofRunCore } from '../proof-run-core-B1GeqkR8.cjs';
|
|
4
|
-
export { p as proofRunEngine } from '../proof-run-engine-
|
|
4
|
+
export { p as proofRunEngine } from '../proof-run-engine-4dM37pEx.cjs';
|
|
5
5
|
import '../types.cjs';
|
package/dist/advanced/index.d.ts
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
export { b as runner } from '../runner-BdQpOkZD.js';
|
|
2
2
|
export { l as engineHarness } from '../engine-harness-CMACHP6A.js';
|
|
3
3
|
export { p as proofRunCore } from '../proof-run-core-B1GeqkR8.js';
|
|
4
|
-
export { p as proofRunEngine } from '../proof-run-engine-
|
|
4
|
+
export { p as proofRunEngine } from '../proof-run-engine-BqaeqAze.js';
|
|
5
5
|
import '../types.js';
|
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
export { R as RiddleProofEngine, c as createRiddleProofEngine, e as executeWorkflow } from '../proof-run-engine-
|
|
1
|
+
export { R as RiddleProofEngine, c as createRiddleProofEngine, e as executeWorkflow } from '../proof-run-engine-4dM37pEx.cjs';
|
|
2
2
|
import '../proof-run-core-B1GeqkR8.cjs';
|
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
export { R as RiddleProofEngine, c as createRiddleProofEngine, e as executeWorkflow } from '../proof-run-engine-
|
|
1
|
+
export { R as RiddleProofEngine, c as createRiddleProofEngine, e as executeWorkflow } from '../proof-run-engine-BqaeqAze.js';
|
|
2
2
|
import '../proof-run-core-B1GeqkR8.js';
|
|
@@ -0,0 +1,209 @@
|
|
|
1
|
+
// src/pr-comment.ts
|
|
2
|
+
var RIDDLE_PROOF_PR_COMMENT_MARKER = "<!-- riddle-proof:pr-comment:v1 -->";
|
|
3
|
+
function asRecord(value) {
|
|
4
|
+
return value && typeof value === "object" && !Array.isArray(value) ? value : {};
|
|
5
|
+
}
|
|
6
|
+
function asArray(value) {
|
|
7
|
+
return Array.isArray(value) ? value : [];
|
|
8
|
+
}
|
|
9
|
+
function stringValue(value) {
|
|
10
|
+
return typeof value === "string" && value.trim() ? value.trim() : void 0;
|
|
11
|
+
}
|
|
12
|
+
function numberValue(value) {
|
|
13
|
+
return typeof value === "number" && Number.isFinite(value) ? value : void 0;
|
|
14
|
+
}
|
|
15
|
+
function booleanValue(value) {
|
|
16
|
+
return typeof value === "boolean" ? value : void 0;
|
|
17
|
+
}
|
|
18
|
+
function artifactKind(name, url) {
|
|
19
|
+
const target = `${name} ${url}`.toLowerCase();
|
|
20
|
+
if (/\.(png|jpe?g|gif|webp|avif|svg)(\?|#|$)/.test(target)) return "image";
|
|
21
|
+
if (/\.(json|har|txt|md|html|log)(\?|#|$)/.test(target)) return "data";
|
|
22
|
+
return "artifact";
|
|
23
|
+
}
|
|
24
|
+
function artifactDisplayName(value, fallback) {
|
|
25
|
+
const raw = stringValue(value);
|
|
26
|
+
if (raw) return raw;
|
|
27
|
+
return fallback;
|
|
28
|
+
}
|
|
29
|
+
function collectArtifacts(runResponse) {
|
|
30
|
+
const proofResult = asRecord(runResponse.proofResult);
|
|
31
|
+
const outputs = asArray(proofResult.outputs);
|
|
32
|
+
const artifacts = [];
|
|
33
|
+
const seen = /* @__PURE__ */ new Set();
|
|
34
|
+
for (const [index, item] of outputs.entries()) {
|
|
35
|
+
const artifact = asRecord(item);
|
|
36
|
+
const url = stringValue(artifact.url);
|
|
37
|
+
if (!url || seen.has(url)) continue;
|
|
38
|
+
seen.add(url);
|
|
39
|
+
const name = artifactDisplayName(artifact.name, `artifact-${index + 1}`);
|
|
40
|
+
artifacts.push({
|
|
41
|
+
name,
|
|
42
|
+
url,
|
|
43
|
+
kind: artifactKind(name, url),
|
|
44
|
+
size_bytes: numberValue(artifact.size)
|
|
45
|
+
});
|
|
46
|
+
}
|
|
47
|
+
return artifacts;
|
|
48
|
+
}
|
|
49
|
+
function pageSummaries(result) {
|
|
50
|
+
const pages = [];
|
|
51
|
+
for (const page of asArray(result.pages)) {
|
|
52
|
+
const record = asRecord(page);
|
|
53
|
+
const route = stringValue(record.route) || stringValue(record.url) || "page";
|
|
54
|
+
const checks = asRecord(record.checks);
|
|
55
|
+
let passed = 0;
|
|
56
|
+
let failed = 0;
|
|
57
|
+
for (const value of Object.values(checks)) {
|
|
58
|
+
if (value === true) passed += 1;
|
|
59
|
+
if (value === false) failed += 1;
|
|
60
|
+
}
|
|
61
|
+
pages.push({ route, passed, failed });
|
|
62
|
+
}
|
|
63
|
+
return pages;
|
|
64
|
+
}
|
|
65
|
+
function summarizeExplicitChecks(value) {
|
|
66
|
+
let passed = 0;
|
|
67
|
+
let failed = 0;
|
|
68
|
+
const visit = (current, inChecks = false) => {
|
|
69
|
+
if (current === true && inChecks) {
|
|
70
|
+
passed += 1;
|
|
71
|
+
return;
|
|
72
|
+
}
|
|
73
|
+
if (current === false && inChecks) {
|
|
74
|
+
failed += 1;
|
|
75
|
+
return;
|
|
76
|
+
}
|
|
77
|
+
if (Array.isArray(current)) {
|
|
78
|
+
for (const item of current) visit(item, inChecks);
|
|
79
|
+
return;
|
|
80
|
+
}
|
|
81
|
+
if (current && typeof current === "object") {
|
|
82
|
+
for (const [key, item] of Object.entries(current)) {
|
|
83
|
+
visit(item, inChecks || key === "checks");
|
|
84
|
+
}
|
|
85
|
+
}
|
|
86
|
+
};
|
|
87
|
+
visit(value);
|
|
88
|
+
return { passed, failed };
|
|
89
|
+
}
|
|
90
|
+
function selectPrimaryImage(artifacts) {
|
|
91
|
+
const images = artifacts.filter((artifact) => artifact.kind === "image");
|
|
92
|
+
return images.find((artifact) => /after|proof|screenshot/i.test(artifact.name)) || images[0];
|
|
93
|
+
}
|
|
94
|
+
function summarizeRiddleProofPrComment(input) {
|
|
95
|
+
const runResponse = asRecord(input.runResponse);
|
|
96
|
+
const result = asRecord(input.result);
|
|
97
|
+
const proofResult = asRecord(runResponse.proofResult);
|
|
98
|
+
const preview = asRecord(runResponse.preview);
|
|
99
|
+
const artifacts = collectArtifacts(runResponse);
|
|
100
|
+
const pages = pageSummaries(result);
|
|
101
|
+
const checkSource = { ...result };
|
|
102
|
+
delete checkSource.ok;
|
|
103
|
+
const nestedChecks = summarizeExplicitChecks(checkSource);
|
|
104
|
+
const ok = booleanValue(result.ok) ?? booleanValue(runResponse.ok) ?? null;
|
|
105
|
+
return {
|
|
106
|
+
ok,
|
|
107
|
+
status: stringValue(proofResult.status),
|
|
108
|
+
job_id: stringValue(proofResult.job_id),
|
|
109
|
+
duration_ms: numberValue(proofResult.duration_ms),
|
|
110
|
+
proof_url: stringValue(runResponse.proofUrl),
|
|
111
|
+
preview_id: stringValue(preview.id),
|
|
112
|
+
preview_url: stringValue(preview.preview_url) || stringValue(preview.url),
|
|
113
|
+
preview_publish_recovered: booleanValue(preview.publish_recovered),
|
|
114
|
+
preview_publish_error: stringValue(preview.publish_error),
|
|
115
|
+
passed_checks: nestedChecks.passed,
|
|
116
|
+
failed_checks: nestedChecks.failed,
|
|
117
|
+
pages,
|
|
118
|
+
artifacts,
|
|
119
|
+
primary_image: selectPrimaryImage(artifacts)
|
|
120
|
+
};
|
|
121
|
+
}
|
|
122
|
+
function formatDuration(ms) {
|
|
123
|
+
if (typeof ms !== "number" || !Number.isFinite(ms)) return "";
|
|
124
|
+
const seconds = Math.max(0, Math.round(ms / 1e3));
|
|
125
|
+
const minutes = Math.floor(seconds / 60);
|
|
126
|
+
const remainder = seconds % 60;
|
|
127
|
+
return minutes > 0 ? `${minutes}m${String(remainder).padStart(2, "0")}s` : `${seconds}s`;
|
|
128
|
+
}
|
|
129
|
+
function markdownLink(label, url) {
|
|
130
|
+
return `[${label.replace(/\]/g, "\\]")}](${url})`;
|
|
131
|
+
}
|
|
132
|
+
function resultLabel(summary) {
|
|
133
|
+
if (summary.ok === true) return "passed";
|
|
134
|
+
if (summary.ok === false) return "failed";
|
|
135
|
+
return summary.status || "recorded";
|
|
136
|
+
}
|
|
137
|
+
function artifactRank(artifact) {
|
|
138
|
+
const name = artifact.name.toLowerCase();
|
|
139
|
+
if (name === "proof.json") return 0;
|
|
140
|
+
if (name === "result.json") return 1;
|
|
141
|
+
if (name.includes("proof") && name.endsWith(".json") && !name.includes("layout")) return 2;
|
|
142
|
+
if (name === "console.json") return 3;
|
|
143
|
+
if (artifact.kind === "data") return 10;
|
|
144
|
+
if (artifact.kind === "image") return 20;
|
|
145
|
+
return 30;
|
|
146
|
+
}
|
|
147
|
+
function buildRiddleProofPrCommentMarkdown(input) {
|
|
148
|
+
const summary = summarizeRiddleProofPrComment(input);
|
|
149
|
+
const title = input.title?.trim() || "Riddle Proof Evidence";
|
|
150
|
+
const lines = [
|
|
151
|
+
RIDDLE_PROOF_PR_COMMENT_MARKER,
|
|
152
|
+
`## ${title}`,
|
|
153
|
+
"",
|
|
154
|
+
`**Result:** ${resultLabel(summary)}`
|
|
155
|
+
];
|
|
156
|
+
if (input.goal?.trim()) lines.push(`**Goal:** ${input.goal.trim()}`);
|
|
157
|
+
if (input.successCriteria?.trim()) lines.push(`**Success criteria:** ${input.successCriteria.trim()}`);
|
|
158
|
+
if (summary.status) lines.push(`**Riddle job status:** ${summary.status}`);
|
|
159
|
+
if (summary.job_id) lines.push(`**Riddle job:** \`${summary.job_id}\``);
|
|
160
|
+
if (summary.duration_ms) lines.push(`**Duration:** ${formatDuration(summary.duration_ms)}`);
|
|
161
|
+
if (summary.proof_url) lines.push(`**Proof URL:** ${markdownLink(summary.proof_url, summary.proof_url)}`);
|
|
162
|
+
if (summary.preview_id || summary.preview_url) {
|
|
163
|
+
const previewLabel = summary.preview_id ? `\`${summary.preview_id}\`` : "preview";
|
|
164
|
+
lines.push(`**Preview:** ${summary.preview_url ? markdownLink(previewLabel, summary.preview_url) : previewLabel}`);
|
|
165
|
+
}
|
|
166
|
+
if (summary.preview_publish_recovered) {
|
|
167
|
+
const detail = summary.preview_publish_error ? `: ${summary.preview_publish_error}` : "";
|
|
168
|
+
lines.push(`**Preview publish recovery:** recovered after publish error${detail}`);
|
|
169
|
+
}
|
|
170
|
+
lines.push(`**Checks:** ${summary.passed_checks} passed / ${summary.failed_checks} failed`);
|
|
171
|
+
lines.push("");
|
|
172
|
+
if (summary.primary_image) {
|
|
173
|
+
lines.push("### Screenshot");
|
|
174
|
+
lines.push(``);
|
|
175
|
+
lines.push("");
|
|
176
|
+
}
|
|
177
|
+
if (summary.pages.length) {
|
|
178
|
+
lines.push("### Page Checks");
|
|
179
|
+
for (const page of summary.pages.slice(0, 12)) {
|
|
180
|
+
lines.push(`- \`${page.route}\`: ${page.passed} passed / ${page.failed} failed`);
|
|
181
|
+
}
|
|
182
|
+
if (summary.pages.length > 12) lines.push(`- ${summary.pages.length - 12} more page(s) omitted`);
|
|
183
|
+
lines.push("");
|
|
184
|
+
}
|
|
185
|
+
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);
|
|
186
|
+
if (linkedArtifacts.length) {
|
|
187
|
+
lines.push("### Artifacts");
|
|
188
|
+
for (const artifact of linkedArtifacts) {
|
|
189
|
+
lines.push(`- ${markdownLink(artifact.name, artifact.url)}`);
|
|
190
|
+
}
|
|
191
|
+
if (summary.artifacts.length - (summary.primary_image ? 1 : 0) > linkedArtifacts.length) {
|
|
192
|
+
lines.push(`- ${summary.artifacts.length - (summary.primary_image ? 1 : 0) - linkedArtifacts.length} more artifact(s) omitted`);
|
|
193
|
+
}
|
|
194
|
+
lines.push("");
|
|
195
|
+
}
|
|
196
|
+
if (input.source?.trim()) {
|
|
197
|
+
lines.push(`_Source: ${input.source.trim()}_`);
|
|
198
|
+
} else {
|
|
199
|
+
lines.push("_Updated by `riddle-proof-loop pr-comment`._");
|
|
200
|
+
}
|
|
201
|
+
return `${lines.join("\n").trim()}
|
|
202
|
+
`;
|
|
203
|
+
}
|
|
204
|
+
|
|
205
|
+
export {
|
|
206
|
+
RIDDLE_PROOF_PR_COMMENT_MARKER,
|
|
207
|
+
summarizeRiddleProofPrComment,
|
|
208
|
+
buildRiddleProofPrCommentMarkdown
|
|
209
|
+
};
|
|
@@ -81,10 +81,68 @@ function previewDeployResultFromRecord(input) {
|
|
|
81
81
|
function canRecoverPreviewPublish(error) {
|
|
82
82
|
return error instanceof RiddleApiError && PREVIEW_PUBLISH_RECOVERY_STATUSES.has(error.status);
|
|
83
83
|
}
|
|
84
|
+
function summarizePreviewDirectory(directory) {
|
|
85
|
+
const stack = [directory];
|
|
86
|
+
let fileCount = 0;
|
|
87
|
+
let totalBytes = 0;
|
|
88
|
+
while (stack.length) {
|
|
89
|
+
const current = stack.pop();
|
|
90
|
+
for (const entry of readdirSync(current, { withFileTypes: true })) {
|
|
91
|
+
const fullPath = path.join(current, entry.name);
|
|
92
|
+
if (entry.isDirectory()) {
|
|
93
|
+
stack.push(fullPath);
|
|
94
|
+
continue;
|
|
95
|
+
}
|
|
96
|
+
if (!entry.isFile()) continue;
|
|
97
|
+
const stat = statSync(fullPath);
|
|
98
|
+
fileCount += 1;
|
|
99
|
+
totalBytes += stat.size;
|
|
100
|
+
}
|
|
101
|
+
}
|
|
102
|
+
return { file_count: fileCount, total_bytes: totalBytes };
|
|
103
|
+
}
|
|
104
|
+
function previewProgressEmitter(config, base) {
|
|
105
|
+
return async (snapshot) => {
|
|
106
|
+
if (!config.onPreviewProgress) return;
|
|
107
|
+
await config.onPreviewProgress({
|
|
108
|
+
label: base.label,
|
|
109
|
+
framework: base.framework,
|
|
110
|
+
directory: base.directory,
|
|
111
|
+
elapsed_ms: Math.max(0, Date.now() - base.startedAt),
|
|
112
|
+
warnings: base.warnings?.length ? base.warnings : void 0,
|
|
113
|
+
...snapshot
|
|
114
|
+
});
|
|
115
|
+
};
|
|
116
|
+
}
|
|
84
117
|
async function waitForPublishedPreview(config, input) {
|
|
118
|
+
await input.emitProgress?.({
|
|
119
|
+
stage: "publish_recovering",
|
|
120
|
+
id: input.id,
|
|
121
|
+
file_count: input.localSummary?.file_count,
|
|
122
|
+
total_bytes: input.localSummary?.total_bytes,
|
|
123
|
+
publish_error: input.publishError.message,
|
|
124
|
+
message: `publish returned ${input.publishError.status}; polling preview status`
|
|
125
|
+
});
|
|
85
126
|
for (let attempt = 1; attempt <= PREVIEW_PUBLISH_RECOVERY_ATTEMPTS; attempt += 1) {
|
|
86
127
|
const status = await riddleRequestJson(config, `/v1/preview/${input.id}`);
|
|
128
|
+
await input.emitProgress?.({
|
|
129
|
+
stage: "checking_status",
|
|
130
|
+
id: input.id,
|
|
131
|
+
attempt,
|
|
132
|
+
attempts: PREVIEW_PUBLISH_RECOVERY_ATTEMPTS,
|
|
133
|
+
status: typeof status.status === "string" ? status.status : null,
|
|
134
|
+
preview_url: typeof status.preview_url === "string" ? status.preview_url : void 0,
|
|
135
|
+
file_count: typeof status.file_count === "number" ? status.file_count : input.localSummary?.file_count,
|
|
136
|
+
total_bytes: typeof status.total_bytes === "number" ? status.total_bytes : input.localSummary?.total_bytes
|
|
137
|
+
});
|
|
87
138
|
if (String(status.status || "") === "ready" && String(status.preview_url || "").trim()) {
|
|
139
|
+
await input.emitProgress?.({
|
|
140
|
+
stage: "ready",
|
|
141
|
+
id: input.id,
|
|
142
|
+
preview_url: String(status.preview_url),
|
|
143
|
+
file_count: typeof status.file_count === "number" ? status.file_count : input.localSummary?.file_count,
|
|
144
|
+
total_bytes: typeof status.total_bytes === "number" ? status.total_bytes : input.localSummary?.total_bytes
|
|
145
|
+
});
|
|
88
146
|
return previewDeployResultFromRecord({
|
|
89
147
|
record: status,
|
|
90
148
|
id: input.id,
|
|
@@ -106,7 +164,17 @@ async function deployRiddlePreview(config, directory, label, framework = "static
|
|
|
106
164
|
if (!directory?.trim()) throw new Error("directory is required");
|
|
107
165
|
if (!label?.trim()) throw new Error("label is required");
|
|
108
166
|
if (framework !== "spa" && framework !== "static") throw new Error("framework must be spa or static");
|
|
167
|
+
const startedAt = Date.now();
|
|
109
168
|
const warnings = collectRiddlePreviewDeployWarnings(directory, framework);
|
|
169
|
+
const emitProgress = previewProgressEmitter(config, { label, framework, directory, startedAt, warnings });
|
|
170
|
+
await emitProgress({ stage: "validating", message: "checking preview input directory" });
|
|
171
|
+
const localSummary = summarizePreviewDirectory(directory);
|
|
172
|
+
await emitProgress({
|
|
173
|
+
stage: "creating",
|
|
174
|
+
file_count: localSummary.file_count,
|
|
175
|
+
total_bytes: localSummary.total_bytes,
|
|
176
|
+
message: "creating preview upload target"
|
|
177
|
+
});
|
|
110
178
|
const created = await riddleRequestJson(config, "/v1/preview", {
|
|
111
179
|
method: "POST",
|
|
112
180
|
body: JSON.stringify({ framework, label })
|
|
@@ -114,10 +182,42 @@ async function deployRiddlePreview(config, directory, label, framework = "static
|
|
|
114
182
|
const id = String(created.id || "");
|
|
115
183
|
const uploadUrl = String(created.upload_url || "");
|
|
116
184
|
if (!id || !uploadUrl) throw new Error("Riddle preview create response was missing id or upload_url.");
|
|
185
|
+
await emitProgress({
|
|
186
|
+
stage: "created",
|
|
187
|
+
id,
|
|
188
|
+
file_count: localSummary.file_count,
|
|
189
|
+
total_bytes: localSummary.total_bytes,
|
|
190
|
+
message: "preview upload target created"
|
|
191
|
+
});
|
|
117
192
|
const scratch = mkdtempSync(path.join(tmpdir(), "riddle-preview-upload-"));
|
|
118
193
|
const tarball = path.join(scratch, `${id}.tar.gz`);
|
|
194
|
+
let tarballBytes = 0;
|
|
119
195
|
try {
|
|
196
|
+
await emitProgress({
|
|
197
|
+
stage: "archiving",
|
|
198
|
+
id,
|
|
199
|
+
file_count: localSummary.file_count,
|
|
200
|
+
total_bytes: localSummary.total_bytes,
|
|
201
|
+
message: "creating preview archive"
|
|
202
|
+
});
|
|
120
203
|
execFileSync("tar", ["czf", tarball, "-C", directory, "."], { stdio: "pipe" });
|
|
204
|
+
tarballBytes = statSync(tarball).size;
|
|
205
|
+
await emitProgress({
|
|
206
|
+
stage: "archived",
|
|
207
|
+
id,
|
|
208
|
+
file_count: localSummary.file_count,
|
|
209
|
+
total_bytes: localSummary.total_bytes,
|
|
210
|
+
tarball_bytes: tarballBytes,
|
|
211
|
+
message: "preview archive created"
|
|
212
|
+
});
|
|
213
|
+
await emitProgress({
|
|
214
|
+
stage: "uploading",
|
|
215
|
+
id,
|
|
216
|
+
file_count: localSummary.file_count,
|
|
217
|
+
total_bytes: localSummary.total_bytes,
|
|
218
|
+
tarball_bytes: tarballBytes,
|
|
219
|
+
message: "uploading preview archive"
|
|
220
|
+
});
|
|
121
221
|
const upload = await fetchFor(config)(uploadUrl, {
|
|
122
222
|
method: "PUT",
|
|
123
223
|
headers: { "Content-Type": "application/gzip" },
|
|
@@ -126,14 +226,37 @@ async function deployRiddlePreview(config, directory, label, framework = "static
|
|
|
126
226
|
if (!upload.ok) {
|
|
127
227
|
throw new RiddleApiError(uploadUrl, upload.status, await upload.text());
|
|
128
228
|
}
|
|
229
|
+
await emitProgress({
|
|
230
|
+
stage: "uploaded",
|
|
231
|
+
id,
|
|
232
|
+
file_count: localSummary.file_count,
|
|
233
|
+
total_bytes: localSummary.total_bytes,
|
|
234
|
+
tarball_bytes: tarballBytes,
|
|
235
|
+
message: "preview archive uploaded"
|
|
236
|
+
});
|
|
129
237
|
} finally {
|
|
130
238
|
rmSync(scratch, { recursive: true, force: true });
|
|
131
239
|
}
|
|
132
240
|
const expiresAt = typeof created.expires_at === "string" ? created.expires_at : void 0;
|
|
133
241
|
try {
|
|
242
|
+
await emitProgress({
|
|
243
|
+
stage: "publishing",
|
|
244
|
+
id,
|
|
245
|
+
file_count: localSummary.file_count,
|
|
246
|
+
total_bytes: localSummary.total_bytes,
|
|
247
|
+
tarball_bytes: tarballBytes || void 0,
|
|
248
|
+
message: "publishing preview"
|
|
249
|
+
});
|
|
134
250
|
const published = await riddleRequestJson(config, `/v1/preview/${id}/publish`, {
|
|
135
251
|
method: "POST"
|
|
136
252
|
});
|
|
253
|
+
await emitProgress({
|
|
254
|
+
stage: "ready",
|
|
255
|
+
id,
|
|
256
|
+
preview_url: String(published.preview_url || ""),
|
|
257
|
+
file_count: typeof published.file_count === "number" ? published.file_count : localSummary.file_count,
|
|
258
|
+
total_bytes: typeof published.total_bytes === "number" ? published.total_bytes : localSummary.total_bytes
|
|
259
|
+
});
|
|
137
260
|
return previewDeployResultFromRecord({ record: published, id, label, framework, expiresAt, warnings });
|
|
138
261
|
} catch (error) {
|
|
139
262
|
if (!canRecoverPreviewPublish(error)) throw error;
|
|
@@ -143,7 +266,9 @@ async function deployRiddlePreview(config, directory, label, framework = "static
|
|
|
143
266
|
framework,
|
|
144
267
|
expiresAt,
|
|
145
268
|
publishError: error,
|
|
146
|
-
warnings
|
|
269
|
+
warnings,
|
|
270
|
+
localSummary,
|
|
271
|
+
emitProgress
|
|
147
272
|
});
|
|
148
273
|
}
|
|
149
274
|
}
|