@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.
Files changed (36) hide show
  1. package/README.md +21 -0
  2. package/dist/advanced/index.d.cts +1 -1
  3. package/dist/advanced/index.d.ts +1 -1
  4. package/dist/advanced/proof-run-engine.d.cts +1 -1
  5. package/dist/advanced/proof-run-engine.d.ts +1 -1
  6. package/dist/chunk-6KYXX4OE.js +209 -0
  7. package/dist/{chunk-TWTEUS7R.js → chunk-DI2XNGEZ.js} +126 -1
  8. package/dist/{chunk-E25K5PDM.js → chunk-U44KBAPH.js} +168 -7
  9. package/dist/cli/index.js +3 -2
  10. package/dist/cli.cjs +488 -3
  11. package/dist/cli.js +3 -2
  12. package/dist/index.cjs +336 -1
  13. package/dist/index.d.cts +2 -1
  14. package/dist/index.d.ts +2 -1
  15. package/dist/index.js +26 -18
  16. package/dist/pr-comment.cjs +235 -0
  17. package/dist/pr-comment.d.cts +41 -0
  18. package/dist/pr-comment.d.ts +41 -0
  19. package/dist/pr-comment.js +11 -0
  20. package/dist/{proof-run-engine-DYUu2mqY.d.cts → proof-run-engine-4dM37pEx.d.cts} +3 -3
  21. package/dist/{proof-run-engine-BmNYuOJ7.d.ts → proof-run-engine-BqaeqAze.d.ts} +3 -3
  22. package/dist/proof-run-engine.d.cts +1 -1
  23. package/dist/proof-run-engine.d.ts +1 -1
  24. package/dist/riddle-client.cjs +126 -1
  25. package/dist/riddle-client.d.cts +21 -1
  26. package/dist/riddle-client.d.ts +21 -1
  27. package/dist/riddle-client.js +1 -1
  28. package/dist/runtime/index.cjs +126 -1
  29. package/dist/runtime/index.d.cts +1 -1
  30. package/dist/runtime/index.d.ts +1 -1
  31. package/dist/runtime/index.js +1 -1
  32. package/dist/runtime/riddle-client.cjs +126 -1
  33. package/dist/runtime/riddle-client.d.cts +1 -1
  34. package/dist/runtime/riddle-client.d.ts +1 -1
  35. package/dist/runtime/riddle-client.js +1 -1
  36. package/package.json +7 -2
@@ -0,0 +1,235 @@
1
+ "use strict";
2
+ var __defProp = Object.defineProperty;
3
+ var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
4
+ var __getOwnPropNames = Object.getOwnPropertyNames;
5
+ var __hasOwnProp = Object.prototype.hasOwnProperty;
6
+ var __export = (target, all) => {
7
+ for (var name in all)
8
+ __defProp(target, name, { get: all[name], enumerable: true });
9
+ };
10
+ var __copyProps = (to, from, except, desc) => {
11
+ if (from && typeof from === "object" || typeof from === "function") {
12
+ for (let key of __getOwnPropNames(from))
13
+ if (!__hasOwnProp.call(to, key) && key !== except)
14
+ __defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
15
+ }
16
+ return to;
17
+ };
18
+ var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
19
+
20
+ // src/pr-comment.ts
21
+ var pr_comment_exports = {};
22
+ __export(pr_comment_exports, {
23
+ RIDDLE_PROOF_PR_COMMENT_MARKER: () => RIDDLE_PROOF_PR_COMMENT_MARKER,
24
+ buildRiddleProofPrCommentMarkdown: () => buildRiddleProofPrCommentMarkdown,
25
+ summarizeRiddleProofPrComment: () => summarizeRiddleProofPrComment
26
+ });
27
+ module.exports = __toCommonJS(pr_comment_exports);
28
+ var RIDDLE_PROOF_PR_COMMENT_MARKER = "<!-- riddle-proof:pr-comment:v1 -->";
29
+ function asRecord(value) {
30
+ return value && typeof value === "object" && !Array.isArray(value) ? value : {};
31
+ }
32
+ function asArray(value) {
33
+ return Array.isArray(value) ? value : [];
34
+ }
35
+ function stringValue(value) {
36
+ return typeof value === "string" && value.trim() ? value.trim() : void 0;
37
+ }
38
+ function numberValue(value) {
39
+ return typeof value === "number" && Number.isFinite(value) ? value : void 0;
40
+ }
41
+ function booleanValue(value) {
42
+ return typeof value === "boolean" ? value : void 0;
43
+ }
44
+ function artifactKind(name, url) {
45
+ const target = `${name} ${url}`.toLowerCase();
46
+ if (/\.(png|jpe?g|gif|webp|avif|svg)(\?|#|$)/.test(target)) return "image";
47
+ if (/\.(json|har|txt|md|html|log)(\?|#|$)/.test(target)) return "data";
48
+ return "artifact";
49
+ }
50
+ function artifactDisplayName(value, fallback) {
51
+ const raw = stringValue(value);
52
+ if (raw) return raw;
53
+ return fallback;
54
+ }
55
+ function collectArtifacts(runResponse) {
56
+ const proofResult = asRecord(runResponse.proofResult);
57
+ const outputs = asArray(proofResult.outputs);
58
+ const artifacts = [];
59
+ const seen = /* @__PURE__ */ new Set();
60
+ for (const [index, item] of outputs.entries()) {
61
+ const artifact = asRecord(item);
62
+ const url = stringValue(artifact.url);
63
+ if (!url || seen.has(url)) continue;
64
+ seen.add(url);
65
+ const name = artifactDisplayName(artifact.name, `artifact-${index + 1}`);
66
+ artifacts.push({
67
+ name,
68
+ url,
69
+ kind: artifactKind(name, url),
70
+ size_bytes: numberValue(artifact.size)
71
+ });
72
+ }
73
+ return artifacts;
74
+ }
75
+ function pageSummaries(result) {
76
+ const pages = [];
77
+ for (const page of asArray(result.pages)) {
78
+ const record = asRecord(page);
79
+ const route = stringValue(record.route) || stringValue(record.url) || "page";
80
+ const checks = asRecord(record.checks);
81
+ let passed = 0;
82
+ let failed = 0;
83
+ for (const value of Object.values(checks)) {
84
+ if (value === true) passed += 1;
85
+ if (value === false) failed += 1;
86
+ }
87
+ pages.push({ route, passed, failed });
88
+ }
89
+ return pages;
90
+ }
91
+ function summarizeExplicitChecks(value) {
92
+ let passed = 0;
93
+ let failed = 0;
94
+ const visit = (current, inChecks = false) => {
95
+ if (current === true && inChecks) {
96
+ passed += 1;
97
+ return;
98
+ }
99
+ if (current === false && inChecks) {
100
+ failed += 1;
101
+ return;
102
+ }
103
+ if (Array.isArray(current)) {
104
+ for (const item of current) visit(item, inChecks);
105
+ return;
106
+ }
107
+ if (current && typeof current === "object") {
108
+ for (const [key, item] of Object.entries(current)) {
109
+ visit(item, inChecks || key === "checks");
110
+ }
111
+ }
112
+ };
113
+ visit(value);
114
+ return { passed, failed };
115
+ }
116
+ function selectPrimaryImage(artifacts) {
117
+ const images = artifacts.filter((artifact) => artifact.kind === "image");
118
+ return images.find((artifact) => /after|proof|screenshot/i.test(artifact.name)) || images[0];
119
+ }
120
+ function summarizeRiddleProofPrComment(input) {
121
+ const runResponse = asRecord(input.runResponse);
122
+ const result = asRecord(input.result);
123
+ const proofResult = asRecord(runResponse.proofResult);
124
+ const preview = asRecord(runResponse.preview);
125
+ const artifacts = collectArtifacts(runResponse);
126
+ const pages = pageSummaries(result);
127
+ const checkSource = { ...result };
128
+ delete checkSource.ok;
129
+ const nestedChecks = summarizeExplicitChecks(checkSource);
130
+ const ok = booleanValue(result.ok) ?? booleanValue(runResponse.ok) ?? null;
131
+ return {
132
+ ok,
133
+ status: stringValue(proofResult.status),
134
+ job_id: stringValue(proofResult.job_id),
135
+ duration_ms: numberValue(proofResult.duration_ms),
136
+ proof_url: stringValue(runResponse.proofUrl),
137
+ preview_id: stringValue(preview.id),
138
+ preview_url: stringValue(preview.preview_url) || stringValue(preview.url),
139
+ preview_publish_recovered: booleanValue(preview.publish_recovered),
140
+ preview_publish_error: stringValue(preview.publish_error),
141
+ passed_checks: nestedChecks.passed,
142
+ failed_checks: nestedChecks.failed,
143
+ pages,
144
+ artifacts,
145
+ primary_image: selectPrimaryImage(artifacts)
146
+ };
147
+ }
148
+ function formatDuration(ms) {
149
+ if (typeof ms !== "number" || !Number.isFinite(ms)) return "";
150
+ const seconds = Math.max(0, Math.round(ms / 1e3));
151
+ const minutes = Math.floor(seconds / 60);
152
+ const remainder = seconds % 60;
153
+ return minutes > 0 ? `${minutes}m${String(remainder).padStart(2, "0")}s` : `${seconds}s`;
154
+ }
155
+ function markdownLink(label, url) {
156
+ return `[${label.replace(/\]/g, "\\]")}](${url})`;
157
+ }
158
+ function resultLabel(summary) {
159
+ if (summary.ok === true) return "passed";
160
+ if (summary.ok === false) return "failed";
161
+ return summary.status || "recorded";
162
+ }
163
+ function artifactRank(artifact) {
164
+ const name = artifact.name.toLowerCase();
165
+ if (name === "proof.json") return 0;
166
+ if (name === "result.json") return 1;
167
+ if (name.includes("proof") && name.endsWith(".json") && !name.includes("layout")) return 2;
168
+ if (name === "console.json") return 3;
169
+ if (artifact.kind === "data") return 10;
170
+ if (artifact.kind === "image") return 20;
171
+ return 30;
172
+ }
173
+ function buildRiddleProofPrCommentMarkdown(input) {
174
+ const summary = summarizeRiddleProofPrComment(input);
175
+ const title = input.title?.trim() || "Riddle Proof Evidence";
176
+ const lines = [
177
+ RIDDLE_PROOF_PR_COMMENT_MARKER,
178
+ `## ${title}`,
179
+ "",
180
+ `**Result:** ${resultLabel(summary)}`
181
+ ];
182
+ if (input.goal?.trim()) lines.push(`**Goal:** ${input.goal.trim()}`);
183
+ if (input.successCriteria?.trim()) lines.push(`**Success criteria:** ${input.successCriteria.trim()}`);
184
+ if (summary.status) lines.push(`**Riddle job status:** ${summary.status}`);
185
+ if (summary.job_id) lines.push(`**Riddle job:** \`${summary.job_id}\``);
186
+ if (summary.duration_ms) lines.push(`**Duration:** ${formatDuration(summary.duration_ms)}`);
187
+ if (summary.proof_url) lines.push(`**Proof URL:** ${markdownLink(summary.proof_url, summary.proof_url)}`);
188
+ if (summary.preview_id || summary.preview_url) {
189
+ const previewLabel = summary.preview_id ? `\`${summary.preview_id}\`` : "preview";
190
+ lines.push(`**Preview:** ${summary.preview_url ? markdownLink(previewLabel, summary.preview_url) : previewLabel}`);
191
+ }
192
+ if (summary.preview_publish_recovered) {
193
+ const detail = summary.preview_publish_error ? `: ${summary.preview_publish_error}` : "";
194
+ lines.push(`**Preview publish recovery:** recovered after publish error${detail}`);
195
+ }
196
+ lines.push(`**Checks:** ${summary.passed_checks} passed / ${summary.failed_checks} failed`);
197
+ lines.push("");
198
+ if (summary.primary_image) {
199
+ lines.push("### Screenshot");
200
+ lines.push(`![${summary.primary_image.name}](${summary.primary_image.url})`);
201
+ lines.push("");
202
+ }
203
+ if (summary.pages.length) {
204
+ lines.push("### Page Checks");
205
+ for (const page of summary.pages.slice(0, 12)) {
206
+ lines.push(`- \`${page.route}\`: ${page.passed} passed / ${page.failed} failed`);
207
+ }
208
+ if (summary.pages.length > 12) lines.push(`- ${summary.pages.length - 12} more page(s) omitted`);
209
+ lines.push("");
210
+ }
211
+ 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);
212
+ if (linkedArtifacts.length) {
213
+ lines.push("### Artifacts");
214
+ for (const artifact of linkedArtifacts) {
215
+ lines.push(`- ${markdownLink(artifact.name, artifact.url)}`);
216
+ }
217
+ if (summary.artifacts.length - (summary.primary_image ? 1 : 0) > linkedArtifacts.length) {
218
+ lines.push(`- ${summary.artifacts.length - (summary.primary_image ? 1 : 0) - linkedArtifacts.length} more artifact(s) omitted`);
219
+ }
220
+ lines.push("");
221
+ }
222
+ if (input.source?.trim()) {
223
+ lines.push(`_Source: ${input.source.trim()}_`);
224
+ } else {
225
+ lines.push("_Updated by `riddle-proof-loop pr-comment`._");
226
+ }
227
+ return `${lines.join("\n").trim()}
228
+ `;
229
+ }
230
+ // Annotate the CommonJS export names for ESM import in node:
231
+ 0 && (module.exports = {
232
+ RIDDLE_PROOF_PR_COMMENT_MARKER,
233
+ buildRiddleProofPrCommentMarkdown,
234
+ summarizeRiddleProofPrComment
235
+ });
@@ -0,0 +1,41 @@
1
+ declare const RIDDLE_PROOF_PR_COMMENT_MARKER = "<!-- riddle-proof:pr-comment:v1 -->";
2
+ type RiddleProofPrCommentArtifactKind = "image" | "data" | "artifact";
3
+ interface RiddleProofPrCommentArtifact {
4
+ name: string;
5
+ url: string;
6
+ kind: RiddleProofPrCommentArtifactKind;
7
+ size_bytes?: number;
8
+ }
9
+ interface RiddleProofPrCommentPageSummary {
10
+ route: string;
11
+ passed: number;
12
+ failed: number;
13
+ }
14
+ interface RiddleProofPrCommentSummary {
15
+ ok: boolean | null;
16
+ status?: string;
17
+ job_id?: string;
18
+ duration_ms?: number;
19
+ proof_url?: string;
20
+ preview_id?: string;
21
+ preview_url?: string;
22
+ preview_publish_recovered?: boolean;
23
+ preview_publish_error?: string;
24
+ passed_checks: number;
25
+ failed_checks: number;
26
+ pages: RiddleProofPrCommentPageSummary[];
27
+ artifacts: RiddleProofPrCommentArtifact[];
28
+ primary_image?: RiddleProofPrCommentArtifact;
29
+ }
30
+ interface RiddleProofPrCommentInput {
31
+ title?: string;
32
+ goal?: string;
33
+ successCriteria?: string;
34
+ runResponse?: unknown;
35
+ result?: unknown;
36
+ source?: string;
37
+ }
38
+ declare function summarizeRiddleProofPrComment(input: RiddleProofPrCommentInput): RiddleProofPrCommentSummary;
39
+ declare function buildRiddleProofPrCommentMarkdown(input: RiddleProofPrCommentInput): string;
40
+
41
+ export { RIDDLE_PROOF_PR_COMMENT_MARKER, type RiddleProofPrCommentArtifact, type RiddleProofPrCommentArtifactKind, type RiddleProofPrCommentInput, type RiddleProofPrCommentPageSummary, type RiddleProofPrCommentSummary, buildRiddleProofPrCommentMarkdown, summarizeRiddleProofPrComment };
@@ -0,0 +1,41 @@
1
+ declare const RIDDLE_PROOF_PR_COMMENT_MARKER = "<!-- riddle-proof:pr-comment:v1 -->";
2
+ type RiddleProofPrCommentArtifactKind = "image" | "data" | "artifact";
3
+ interface RiddleProofPrCommentArtifact {
4
+ name: string;
5
+ url: string;
6
+ kind: RiddleProofPrCommentArtifactKind;
7
+ size_bytes?: number;
8
+ }
9
+ interface RiddleProofPrCommentPageSummary {
10
+ route: string;
11
+ passed: number;
12
+ failed: number;
13
+ }
14
+ interface RiddleProofPrCommentSummary {
15
+ ok: boolean | null;
16
+ status?: string;
17
+ job_id?: string;
18
+ duration_ms?: number;
19
+ proof_url?: string;
20
+ preview_id?: string;
21
+ preview_url?: string;
22
+ preview_publish_recovered?: boolean;
23
+ preview_publish_error?: string;
24
+ passed_checks: number;
25
+ failed_checks: number;
26
+ pages: RiddleProofPrCommentPageSummary[];
27
+ artifacts: RiddleProofPrCommentArtifact[];
28
+ primary_image?: RiddleProofPrCommentArtifact;
29
+ }
30
+ interface RiddleProofPrCommentInput {
31
+ title?: string;
32
+ goal?: string;
33
+ successCriteria?: string;
34
+ runResponse?: unknown;
35
+ result?: unknown;
36
+ source?: string;
37
+ }
38
+ declare function summarizeRiddleProofPrComment(input: RiddleProofPrCommentInput): RiddleProofPrCommentSummary;
39
+ declare function buildRiddleProofPrCommentMarkdown(input: RiddleProofPrCommentInput): string;
40
+
41
+ export { RIDDLE_PROOF_PR_COMMENT_MARKER, type RiddleProofPrCommentArtifact, type RiddleProofPrCommentArtifactKind, type RiddleProofPrCommentInput, type RiddleProofPrCommentPageSummary, type RiddleProofPrCommentSummary, buildRiddleProofPrCommentMarkdown, summarizeRiddleProofPrComment };
@@ -0,0 +1,11 @@
1
+ import {
2
+ RIDDLE_PROOF_PR_COMMENT_MARKER,
3
+ buildRiddleProofPrCommentMarkdown,
4
+ summarizeRiddleProofPrComment
5
+ } from "./chunk-6KYXX4OE.js";
6
+ import "./chunk-MLKGABMK.js";
7
+ export {
8
+ RIDDLE_PROOF_PR_COMMENT_MARKER,
9
+ buildRiddleProofPrCommentMarkdown,
10
+ summarizeRiddleProofPrComment
11
+ };
@@ -292,7 +292,7 @@ declare function executeWorkflow(params: WorkflowParams, pluginConfig: any, reso
292
292
  blocking?: boolean;
293
293
  details?: Record<string, unknown>;
294
294
  ok: boolean;
295
- action: "setup" | "recon" | "author" | "implement" | "verify" | "ship" | "run";
295
+ action: "author" | "recon" | "ship" | "implement" | "verify" | "setup" | "run";
296
296
  state_path: string;
297
297
  stage: any;
298
298
  summary: string;
@@ -382,7 +382,7 @@ declare function executeWorkflow(params: WorkflowParams, pluginConfig: any, reso
382
382
  continueWithStage?: WorkflowStage | null;
383
383
  blocking?: boolean;
384
384
  details?: Record<string, unknown>;
385
- action: "setup" | "recon" | "author" | "implement" | "verify" | "ship" | "run";
385
+ action: "author" | "recon" | "ship" | "implement" | "verify" | "setup" | "run";
386
386
  state_path: string;
387
387
  stage: any;
388
388
  checkpoint: string;
@@ -659,7 +659,7 @@ declare function executeWorkflow(params: WorkflowParams, pluginConfig: any, reso
659
659
  error?: undefined;
660
660
  } | {
661
661
  ok: boolean;
662
- action: "setup" | "recon" | "author" | "implement" | "verify" | "ship";
662
+ action: "author" | "recon" | "ship" | "implement" | "verify" | "setup";
663
663
  state_path: string;
664
664
  stage: any;
665
665
  summary: string;
@@ -292,7 +292,7 @@ declare function executeWorkflow(params: WorkflowParams, pluginConfig: any, reso
292
292
  blocking?: boolean;
293
293
  details?: Record<string, unknown>;
294
294
  ok: boolean;
295
- action: "setup" | "recon" | "author" | "implement" | "verify" | "ship" | "run";
295
+ action: "author" | "recon" | "ship" | "implement" | "verify" | "setup" | "run";
296
296
  state_path: string;
297
297
  stage: any;
298
298
  summary: string;
@@ -382,7 +382,7 @@ declare function executeWorkflow(params: WorkflowParams, pluginConfig: any, reso
382
382
  continueWithStage?: WorkflowStage | null;
383
383
  blocking?: boolean;
384
384
  details?: Record<string, unknown>;
385
- action: "setup" | "recon" | "author" | "implement" | "verify" | "ship" | "run";
385
+ action: "author" | "recon" | "ship" | "implement" | "verify" | "setup" | "run";
386
386
  state_path: string;
387
387
  stage: any;
388
388
  checkpoint: string;
@@ -659,7 +659,7 @@ declare function executeWorkflow(params: WorkflowParams, pluginConfig: any, reso
659
659
  error?: undefined;
660
660
  } | {
661
661
  ok: boolean;
662
- action: "setup" | "recon" | "author" | "implement" | "verify" | "ship";
662
+ action: "author" | "recon" | "ship" | "implement" | "verify" | "setup";
663
663
  state_path: string;
664
664
  stage: any;
665
665
  summary: string;
@@ -1,2 +1,2 @@
1
1
  import './proof-run-core-B1GeqkR8.cjs';
2
- export { R as RiddleProofEngine, c as createRiddleProofEngine, e as executeWorkflow } from './proof-run-engine-DYUu2mqY.cjs';
2
+ export { R as RiddleProofEngine, c as createRiddleProofEngine, e as executeWorkflow } from './proof-run-engine-4dM37pEx.cjs';
@@ -1,2 +1,2 @@
1
1
  import './proof-run-core-B1GeqkR8.js';
2
- export { R as RiddleProofEngine, c as createRiddleProofEngine, e as executeWorkflow } from './proof-run-engine-BmNYuOJ7.js';
2
+ export { R as RiddleProofEngine, c as createRiddleProofEngine, e as executeWorkflow } from './proof-run-engine-BqaeqAze.js';
@@ -130,10 +130,68 @@ function previewDeployResultFromRecord(input) {
130
130
  function canRecoverPreviewPublish(error) {
131
131
  return error instanceof RiddleApiError && PREVIEW_PUBLISH_RECOVERY_STATUSES.has(error.status);
132
132
  }
133
+ function summarizePreviewDirectory(directory) {
134
+ const stack = [directory];
135
+ let fileCount = 0;
136
+ let totalBytes = 0;
137
+ while (stack.length) {
138
+ const current = stack.pop();
139
+ for (const entry of (0, import_node_fs.readdirSync)(current, { withFileTypes: true })) {
140
+ const fullPath = import_node_path.default.join(current, entry.name);
141
+ if (entry.isDirectory()) {
142
+ stack.push(fullPath);
143
+ continue;
144
+ }
145
+ if (!entry.isFile()) continue;
146
+ const stat = (0, import_node_fs.statSync)(fullPath);
147
+ fileCount += 1;
148
+ totalBytes += stat.size;
149
+ }
150
+ }
151
+ return { file_count: fileCount, total_bytes: totalBytes };
152
+ }
153
+ function previewProgressEmitter(config, base) {
154
+ return async (snapshot) => {
155
+ if (!config.onPreviewProgress) return;
156
+ await config.onPreviewProgress({
157
+ label: base.label,
158
+ framework: base.framework,
159
+ directory: base.directory,
160
+ elapsed_ms: Math.max(0, Date.now() - base.startedAt),
161
+ warnings: base.warnings?.length ? base.warnings : void 0,
162
+ ...snapshot
163
+ });
164
+ };
165
+ }
133
166
  async function waitForPublishedPreview(config, input) {
167
+ await input.emitProgress?.({
168
+ stage: "publish_recovering",
169
+ id: input.id,
170
+ file_count: input.localSummary?.file_count,
171
+ total_bytes: input.localSummary?.total_bytes,
172
+ publish_error: input.publishError.message,
173
+ message: `publish returned ${input.publishError.status}; polling preview status`
174
+ });
134
175
  for (let attempt = 1; attempt <= PREVIEW_PUBLISH_RECOVERY_ATTEMPTS; attempt += 1) {
135
176
  const status = await riddleRequestJson(config, `/v1/preview/${input.id}`);
177
+ await input.emitProgress?.({
178
+ stage: "checking_status",
179
+ id: input.id,
180
+ attempt,
181
+ attempts: PREVIEW_PUBLISH_RECOVERY_ATTEMPTS,
182
+ status: typeof status.status === "string" ? status.status : null,
183
+ preview_url: typeof status.preview_url === "string" ? status.preview_url : void 0,
184
+ file_count: typeof status.file_count === "number" ? status.file_count : input.localSummary?.file_count,
185
+ total_bytes: typeof status.total_bytes === "number" ? status.total_bytes : input.localSummary?.total_bytes
186
+ });
136
187
  if (String(status.status || "") === "ready" && String(status.preview_url || "").trim()) {
188
+ await input.emitProgress?.({
189
+ stage: "ready",
190
+ id: input.id,
191
+ preview_url: String(status.preview_url),
192
+ file_count: typeof status.file_count === "number" ? status.file_count : input.localSummary?.file_count,
193
+ total_bytes: typeof status.total_bytes === "number" ? status.total_bytes : input.localSummary?.total_bytes
194
+ });
137
195
  return previewDeployResultFromRecord({
138
196
  record: status,
139
197
  id: input.id,
@@ -155,7 +213,17 @@ async function deployRiddlePreview(config, directory, label, framework = "static
155
213
  if (!directory?.trim()) throw new Error("directory is required");
156
214
  if (!label?.trim()) throw new Error("label is required");
157
215
  if (framework !== "spa" && framework !== "static") throw new Error("framework must be spa or static");
216
+ const startedAt = Date.now();
158
217
  const warnings = collectRiddlePreviewDeployWarnings(directory, framework);
218
+ const emitProgress = previewProgressEmitter(config, { label, framework, directory, startedAt, warnings });
219
+ await emitProgress({ stage: "validating", message: "checking preview input directory" });
220
+ const localSummary = summarizePreviewDirectory(directory);
221
+ await emitProgress({
222
+ stage: "creating",
223
+ file_count: localSummary.file_count,
224
+ total_bytes: localSummary.total_bytes,
225
+ message: "creating preview upload target"
226
+ });
159
227
  const created = await riddleRequestJson(config, "/v1/preview", {
160
228
  method: "POST",
161
229
  body: JSON.stringify({ framework, label })
@@ -163,10 +231,42 @@ async function deployRiddlePreview(config, directory, label, framework = "static
163
231
  const id = String(created.id || "");
164
232
  const uploadUrl = String(created.upload_url || "");
165
233
  if (!id || !uploadUrl) throw new Error("Riddle preview create response was missing id or upload_url.");
234
+ await emitProgress({
235
+ stage: "created",
236
+ id,
237
+ file_count: localSummary.file_count,
238
+ total_bytes: localSummary.total_bytes,
239
+ message: "preview upload target created"
240
+ });
166
241
  const scratch = (0, import_node_fs.mkdtempSync)(import_node_path.default.join((0, import_node_os.tmpdir)(), "riddle-preview-upload-"));
167
242
  const tarball = import_node_path.default.join(scratch, `${id}.tar.gz`);
243
+ let tarballBytes = 0;
168
244
  try {
245
+ await emitProgress({
246
+ stage: "archiving",
247
+ id,
248
+ file_count: localSummary.file_count,
249
+ total_bytes: localSummary.total_bytes,
250
+ message: "creating preview archive"
251
+ });
169
252
  (0, import_node_child_process.execFileSync)("tar", ["czf", tarball, "-C", directory, "."], { stdio: "pipe" });
253
+ tarballBytes = (0, import_node_fs.statSync)(tarball).size;
254
+ await emitProgress({
255
+ stage: "archived",
256
+ id,
257
+ file_count: localSummary.file_count,
258
+ total_bytes: localSummary.total_bytes,
259
+ tarball_bytes: tarballBytes,
260
+ message: "preview archive created"
261
+ });
262
+ await emitProgress({
263
+ stage: "uploading",
264
+ id,
265
+ file_count: localSummary.file_count,
266
+ total_bytes: localSummary.total_bytes,
267
+ tarball_bytes: tarballBytes,
268
+ message: "uploading preview archive"
269
+ });
170
270
  const upload = await fetchFor(config)(uploadUrl, {
171
271
  method: "PUT",
172
272
  headers: { "Content-Type": "application/gzip" },
@@ -175,14 +275,37 @@ async function deployRiddlePreview(config, directory, label, framework = "static
175
275
  if (!upload.ok) {
176
276
  throw new RiddleApiError(uploadUrl, upload.status, await upload.text());
177
277
  }
278
+ await emitProgress({
279
+ stage: "uploaded",
280
+ id,
281
+ file_count: localSummary.file_count,
282
+ total_bytes: localSummary.total_bytes,
283
+ tarball_bytes: tarballBytes,
284
+ message: "preview archive uploaded"
285
+ });
178
286
  } finally {
179
287
  (0, import_node_fs.rmSync)(scratch, { recursive: true, force: true });
180
288
  }
181
289
  const expiresAt = typeof created.expires_at === "string" ? created.expires_at : void 0;
182
290
  try {
291
+ await emitProgress({
292
+ stage: "publishing",
293
+ id,
294
+ file_count: localSummary.file_count,
295
+ total_bytes: localSummary.total_bytes,
296
+ tarball_bytes: tarballBytes || void 0,
297
+ message: "publishing preview"
298
+ });
183
299
  const published = await riddleRequestJson(config, `/v1/preview/${id}/publish`, {
184
300
  method: "POST"
185
301
  });
302
+ await emitProgress({
303
+ stage: "ready",
304
+ id,
305
+ preview_url: String(published.preview_url || ""),
306
+ file_count: typeof published.file_count === "number" ? published.file_count : localSummary.file_count,
307
+ total_bytes: typeof published.total_bytes === "number" ? published.total_bytes : localSummary.total_bytes
308
+ });
186
309
  return previewDeployResultFromRecord({ record: published, id, label, framework, expiresAt, warnings });
187
310
  } catch (error) {
188
311
  if (!canRecoverPreviewPublish(error)) throw error;
@@ -192,7 +315,9 @@ async function deployRiddlePreview(config, directory, label, framework = "static
192
315
  framework,
193
316
  expiresAt,
194
317
  publishError: error,
195
- warnings
318
+ warnings,
319
+ localSummary,
320
+ emitProgress
196
321
  });
197
322
  }
198
323
  }
@@ -6,6 +6,7 @@ interface RiddleClientConfig {
6
6
  apiKeyFile?: string;
7
7
  apiBaseUrl?: string;
8
8
  fetchImpl?: RiddleFetch;
9
+ onPreviewProgress?: (snapshot: RiddlePreviewDeployProgressSnapshot) => void | Promise<void>;
9
10
  }
10
11
  interface RiddleApiKeySource {
11
12
  source: "option" | "env" | "file";
@@ -54,6 +55,25 @@ interface RiddlePollJobOptions {
54
55
  onProgress?: (snapshot: RiddlePollProgressSnapshot) => void | Promise<void>;
55
56
  }
56
57
  type RiddlePreviewFramework = "spa" | "static";
58
+ type RiddlePreviewDeployStage = "validating" | "creating" | "created" | "archiving" | "archived" | "uploading" | "uploaded" | "publishing" | "publish_recovering" | "checking_status" | "ready";
59
+ interface RiddlePreviewDeployProgressSnapshot {
60
+ stage: RiddlePreviewDeployStage;
61
+ label: string;
62
+ framework: RiddlePreviewFramework;
63
+ directory: string;
64
+ elapsed_ms: number;
65
+ id?: string;
66
+ preview_url?: string;
67
+ file_count?: number;
68
+ total_bytes?: number;
69
+ tarball_bytes?: number;
70
+ attempt?: number;
71
+ attempts?: number;
72
+ status?: string | null;
73
+ publish_error?: string;
74
+ warnings?: string[];
75
+ message?: string;
76
+ }
57
77
  interface RiddlePreviewDeployResult {
58
78
  ok: true;
59
79
  id: string;
@@ -151,4 +171,4 @@ declare function createRiddleApiClient(config?: RiddleClientConfig): {
151
171
  pollJob: (jobId: string, options?: RiddlePollJobOptions) => Promise<RiddlePollJobResult>;
152
172
  };
153
173
 
154
- export { DEFAULT_RIDDLE_API_BASE_URL, DEFAULT_RIDDLE_API_KEY_FILE, RiddleApiError, type RiddleApiKeySource, type RiddleBalanceResult, type RiddleClientConfig, type RiddleFetch, type RiddlePollJobOptions, type RiddlePollJobResult, type RiddlePollProgressSnapshot, type RiddlePollSummary, type RiddlePreviewDeployResult, type RiddlePreviewFramework, type RiddleRunScriptInput, type RiddleServerPreviewInput, type RiddleServerPreviewResult, collectRiddlePreviewDeployWarnings, createRiddleApiClient, deployRiddlePreview, deployRiddleStaticPreview, getRiddleBalance, isTerminalRiddleJobStatus, parseRiddleViewport, pollRiddleJob, resolveRiddleApiKey, resolveRiddleApiKeySource, riddleRequestJson, runRiddleScript, runRiddleServerPreview };
174
+ export { DEFAULT_RIDDLE_API_BASE_URL, DEFAULT_RIDDLE_API_KEY_FILE, RiddleApiError, type RiddleApiKeySource, type RiddleBalanceResult, type RiddleClientConfig, type RiddleFetch, type RiddlePollJobOptions, type RiddlePollJobResult, type RiddlePollProgressSnapshot, type RiddlePollSummary, type RiddlePreviewDeployProgressSnapshot, type RiddlePreviewDeployResult, type RiddlePreviewDeployStage, type RiddlePreviewFramework, type RiddleRunScriptInput, type RiddleServerPreviewInput, type RiddleServerPreviewResult, collectRiddlePreviewDeployWarnings, createRiddleApiClient, deployRiddlePreview, deployRiddleStaticPreview, getRiddleBalance, isTerminalRiddleJobStatus, parseRiddleViewport, pollRiddleJob, resolveRiddleApiKey, resolveRiddleApiKeySource, riddleRequestJson, runRiddleScript, runRiddleServerPreview };
@@ -6,6 +6,7 @@ interface RiddleClientConfig {
6
6
  apiKeyFile?: string;
7
7
  apiBaseUrl?: string;
8
8
  fetchImpl?: RiddleFetch;
9
+ onPreviewProgress?: (snapshot: RiddlePreviewDeployProgressSnapshot) => void | Promise<void>;
9
10
  }
10
11
  interface RiddleApiKeySource {
11
12
  source: "option" | "env" | "file";
@@ -54,6 +55,25 @@ interface RiddlePollJobOptions {
54
55
  onProgress?: (snapshot: RiddlePollProgressSnapshot) => void | Promise<void>;
55
56
  }
56
57
  type RiddlePreviewFramework = "spa" | "static";
58
+ type RiddlePreviewDeployStage = "validating" | "creating" | "created" | "archiving" | "archived" | "uploading" | "uploaded" | "publishing" | "publish_recovering" | "checking_status" | "ready";
59
+ interface RiddlePreviewDeployProgressSnapshot {
60
+ stage: RiddlePreviewDeployStage;
61
+ label: string;
62
+ framework: RiddlePreviewFramework;
63
+ directory: string;
64
+ elapsed_ms: number;
65
+ id?: string;
66
+ preview_url?: string;
67
+ file_count?: number;
68
+ total_bytes?: number;
69
+ tarball_bytes?: number;
70
+ attempt?: number;
71
+ attempts?: number;
72
+ status?: string | null;
73
+ publish_error?: string;
74
+ warnings?: string[];
75
+ message?: string;
76
+ }
57
77
  interface RiddlePreviewDeployResult {
58
78
  ok: true;
59
79
  id: string;
@@ -151,4 +171,4 @@ declare function createRiddleApiClient(config?: RiddleClientConfig): {
151
171
  pollJob: (jobId: string, options?: RiddlePollJobOptions) => Promise<RiddlePollJobResult>;
152
172
  };
153
173
 
154
- export { DEFAULT_RIDDLE_API_BASE_URL, DEFAULT_RIDDLE_API_KEY_FILE, RiddleApiError, type RiddleApiKeySource, type RiddleBalanceResult, type RiddleClientConfig, type RiddleFetch, type RiddlePollJobOptions, type RiddlePollJobResult, type RiddlePollProgressSnapshot, type RiddlePollSummary, type RiddlePreviewDeployResult, type RiddlePreviewFramework, type RiddleRunScriptInput, type RiddleServerPreviewInput, type RiddleServerPreviewResult, collectRiddlePreviewDeployWarnings, createRiddleApiClient, deployRiddlePreview, deployRiddleStaticPreview, getRiddleBalance, isTerminalRiddleJobStatus, parseRiddleViewport, pollRiddleJob, resolveRiddleApiKey, resolveRiddleApiKeySource, riddleRequestJson, runRiddleScript, runRiddleServerPreview };
174
+ export { DEFAULT_RIDDLE_API_BASE_URL, DEFAULT_RIDDLE_API_KEY_FILE, RiddleApiError, type RiddleApiKeySource, type RiddleBalanceResult, type RiddleClientConfig, type RiddleFetch, type RiddlePollJobOptions, type RiddlePollJobResult, type RiddlePollProgressSnapshot, type RiddlePollSummary, type RiddlePreviewDeployProgressSnapshot, type RiddlePreviewDeployResult, type RiddlePreviewDeployStage, type RiddlePreviewFramework, type RiddleRunScriptInput, type RiddleServerPreviewInput, type RiddleServerPreviewResult, collectRiddlePreviewDeployWarnings, createRiddleApiClient, deployRiddlePreview, deployRiddleStaticPreview, getRiddleBalance, isTerminalRiddleJobStatus, parseRiddleViewport, pollRiddleJob, resolveRiddleApiKey, resolveRiddleApiKeySource, riddleRequestJson, runRiddleScript, runRiddleServerPreview };
@@ -15,7 +15,7 @@ import {
15
15
  riddleRequestJson,
16
16
  runRiddleScript,
17
17
  runRiddleServerPreview
18
- } from "./chunk-TWTEUS7R.js";
18
+ } from "./chunk-DI2XNGEZ.js";
19
19
  import "./chunk-MLKGABMK.js";
20
20
  export {
21
21
  DEFAULT_RIDDLE_API_BASE_URL,