@riddledc/riddle-proof 0.5.55 → 0.5.56

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.
@@ -21,14 +21,17 @@ var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: tru
21
21
  var basic_gameplay_exports = {};
22
22
  __export(basic_gameplay_exports, {
23
23
  RIDDLE_PROOF_BASIC_GAMEPLAY_ASSESSMENT_VERSION: () => RIDDLE_PROOF_BASIC_GAMEPLAY_ASSESSMENT_VERSION,
24
+ RIDDLE_PROOF_BASIC_GAMEPLAY_CATCH_VERSION: () => RIDDLE_PROOF_BASIC_GAMEPLAY_CATCH_VERSION,
24
25
  RIDDLE_PROOF_BASIC_GAMEPLAY_VERSION: () => RIDDLE_PROOF_BASIC_GAMEPLAY_VERSION,
25
26
  assessBasicGameplayEvidence: () => assessBasicGameplayEvidence,
26
27
  assessBasicGameplayRoute: () => assessBasicGameplayRoute,
28
+ createBasicGameplayCatchSummary: () => createBasicGameplayCatchSummary,
27
29
  extractBasicGameplayEvidence: () => extractBasicGameplayEvidence
28
30
  });
29
31
  module.exports = __toCommonJS(basic_gameplay_exports);
30
32
  var RIDDLE_PROOF_BASIC_GAMEPLAY_VERSION = "riddle-proof.basic-gameplay.v1";
31
33
  var RIDDLE_PROOF_BASIC_GAMEPLAY_ASSESSMENT_VERSION = "riddle-proof.basic-gameplay.assessment.v1";
34
+ var RIDDLE_PROOF_BASIC_GAMEPLAY_CATCH_VERSION = "riddle-proof.basic-gameplay.catch.v1";
32
35
  var BASIC_GAMEPLAY_CONTAINER_KEYS = [
33
36
  "basic_gameplay",
34
37
  "basicGameplay",
@@ -138,6 +141,37 @@ function assessBasicGameplayRoute(route, options = {}) {
138
141
  }
139
142
  };
140
143
  }
144
+ function createBasicGameplayCatchSummary(input, options = {}) {
145
+ const before = summarizeAssessment(assessBasicGameplayEvidence(input.before, options));
146
+ const after = input.after === void 0 ? void 0 : summarizeAssessment(assessBasicGameplayEvidence(input.after, options));
147
+ const fixed = Boolean(after && before.notable_codes.length > 0 && after.passed && after.notable_codes.length === 0);
148
+ const title = input.title || [
149
+ input.site || "Basic gameplay",
150
+ input.route ? `${input.route} proof catch` : "proof catch"
151
+ ].join(" ");
152
+ const beforeCodes = before.notable_codes.length ? before.notable_codes.join(", ") : "no failing or warning codes";
153
+ const afterCodes = after ? after.notable_codes.length ? after.notable_codes.join(", ") : "no failing or warning codes" : "not verified";
154
+ const summaryLines = [
155
+ `Before: ${before.checked_routes} checked, ${before.passing_routes} passing, codes: ${beforeCodes}.`,
156
+ after ? `After: ${after.checked_routes} checked, ${after.passing_routes} passing, codes: ${afterCodes}.` : "After: not provided."
157
+ ];
158
+ if (input.fix?.summary) summaryLines.push(`Fix: ${input.fix.summary}`);
159
+ if (input.artifacts?.length) summaryLines.push(`Artifacts: ${input.artifacts.length} attached.`);
160
+ return {
161
+ version: RIDDLE_PROOF_BASIC_GAMEPLAY_CATCH_VERSION,
162
+ title,
163
+ site: input.site,
164
+ route: input.route,
165
+ detected_at: input.detected_at || (/* @__PURE__ */ new Date()).toISOString(),
166
+ before,
167
+ after,
168
+ fixed,
169
+ fix: input.fix,
170
+ artifacts: input.artifacts || [],
171
+ summary_lines: summaryLines,
172
+ marketing_summary: fixed ? `${title}: Riddle Proof caught ${beforeCodes}; after the fix, ${afterCodes}.` : `${title}: Riddle Proof caught ${beforeCodes}; after evidence is ${after ? "not yet clean" : "not yet attached"}.`
173
+ };
174
+ }
141
175
  function extractBasicGameplayEvidence(...sources) {
142
176
  const seen = /* @__PURE__ */ new Set();
143
177
  for (const source of sources) {
@@ -146,6 +180,21 @@ function extractBasicGameplayEvidence(...sources) {
146
180
  }
147
181
  return null;
148
182
  }
183
+ function summarizeAssessment(assessment) {
184
+ return {
185
+ evidence_present: assessment.evidence_present,
186
+ passed: assessment.passed,
187
+ checked_routes: assessment.checked_routes,
188
+ passing_routes: assessment.passing_routes,
189
+ failing_routes: assessment.failing_routes,
190
+ failure_counts: assessment.failure_counts,
191
+ warning_counts: assessment.warning_counts,
192
+ notable_codes: [
193
+ ...Object.keys(assessment.failure_counts),
194
+ ...Object.keys(assessment.warning_counts)
195
+ ].sort()
196
+ };
197
+ }
149
198
  function findBasicGameplayEvidence(value, seen, depth = 0) {
150
199
  if (depth > 6 || value === null || value === void 0) return null;
151
200
  if (typeof value === "string") {
@@ -248,8 +297,10 @@ function parseJson(value) {
248
297
  // Annotate the CommonJS export names for ESM import in node:
249
298
  0 && (module.exports = {
250
299
  RIDDLE_PROOF_BASIC_GAMEPLAY_ASSESSMENT_VERSION,
300
+ RIDDLE_PROOF_BASIC_GAMEPLAY_CATCH_VERSION,
251
301
  RIDDLE_PROOF_BASIC_GAMEPLAY_VERSION,
252
302
  assessBasicGameplayEvidence,
253
303
  assessBasicGameplayRoute,
304
+ createBasicGameplayCatchSummary,
254
305
  extractBasicGameplayEvidence
255
306
  });
@@ -1,5 +1,6 @@
1
1
  declare const RIDDLE_PROOF_BASIC_GAMEPLAY_VERSION = "riddle-proof.basic-gameplay.v1";
2
2
  declare const RIDDLE_PROOF_BASIC_GAMEPLAY_ASSESSMENT_VERSION = "riddle-proof.basic-gameplay.assessment.v1";
3
+ declare const RIDDLE_PROOF_BASIC_GAMEPLAY_CATCH_VERSION = "riddle-proof.basic-gameplay.catch.v1";
3
4
  type BasicGameplayFailureCode = "route_http_error" | "fatal_page_error" | "route_blank_or_thin" | "no_game_surface" | "mobile_horizontal_overflow" | "primary_control_missing" | "primary_control_inert";
4
5
  type BasicGameplayWarningCode = "canvas_inert" | "some_actions_failed" | "missing_reset_path" | "critical_console_error";
5
6
  interface BasicGameplayCanvasState {
@@ -110,8 +111,59 @@ interface RiddleProofBasicGameplayAssessment {
110
111
  warning_counts: Record<string, number>;
111
112
  route_results: RiddleProofBasicGameplayRouteAssessment[];
112
113
  }
114
+ interface BasicGameplayProofArtifact {
115
+ name: string;
116
+ role?: string;
117
+ kind?: string;
118
+ url?: string;
119
+ path?: string;
120
+ sha256?: string;
121
+ [key: string]: unknown;
122
+ }
123
+ interface BasicGameplayFixReference {
124
+ repo?: string;
125
+ commit?: string;
126
+ pr_url?: string;
127
+ summary?: string;
128
+ [key: string]: unknown;
129
+ }
130
+ interface CreateBasicGameplayCatchSummaryInput {
131
+ title?: string;
132
+ site?: string;
133
+ route?: string;
134
+ detected_at?: string;
135
+ before: unknown;
136
+ after?: unknown;
137
+ fix?: BasicGameplayFixReference;
138
+ artifacts?: BasicGameplayProofArtifact[];
139
+ }
140
+ interface BasicGameplayAssessmentSummary {
141
+ evidence_present: boolean;
142
+ passed: boolean;
143
+ checked_routes: number;
144
+ passing_routes: number;
145
+ failing_routes: RiddleProofBasicGameplayAssessment["failing_routes"];
146
+ failure_counts: Record<string, number>;
147
+ warning_counts: Record<string, number>;
148
+ notable_codes: string[];
149
+ }
150
+ interface RiddleProofBasicGameplayCatchSummary {
151
+ version: typeof RIDDLE_PROOF_BASIC_GAMEPLAY_CATCH_VERSION;
152
+ title: string;
153
+ site?: string;
154
+ route?: string;
155
+ detected_at: string;
156
+ before: BasicGameplayAssessmentSummary;
157
+ after?: BasicGameplayAssessmentSummary;
158
+ fixed: boolean;
159
+ fix?: BasicGameplayFixReference;
160
+ artifacts: BasicGameplayProofArtifact[];
161
+ summary_lines: string[];
162
+ marketing_summary: string;
163
+ }
113
164
  declare function assessBasicGameplayEvidence(evidence: unknown, options?: AssessBasicGameplayOptions): RiddleProofBasicGameplayAssessment;
114
165
  declare function assessBasicGameplayRoute(route: RiddleProofBasicGameplayRouteEvidence, options?: AssessBasicGameplayOptions): RiddleProofBasicGameplayRouteAssessment;
166
+ declare function createBasicGameplayCatchSummary(input: CreateBasicGameplayCatchSummaryInput, options?: AssessBasicGameplayOptions): RiddleProofBasicGameplayCatchSummary;
115
167
  declare function extractBasicGameplayEvidence(...sources: unknown[]): RiddleProofBasicGameplayEvidence | null;
116
168
 
117
- export { type AssessBasicGameplayOptions, type BasicGameplayActionResult, type BasicGameplayCanvasState, type BasicGameplayChangeSummary, type BasicGameplayFailureCode, type BasicGameplayMobileEvidence, type BasicGameplaySnapshot, type BasicGameplayWarningCode, RIDDLE_PROOF_BASIC_GAMEPLAY_ASSESSMENT_VERSION, RIDDLE_PROOF_BASIC_GAMEPLAY_VERSION, type RiddleProofBasicGameplayAssessment, type RiddleProofBasicGameplayEvidence, type RiddleProofBasicGameplayRouteAssessment, type RiddleProofBasicGameplayRouteEvidence, assessBasicGameplayEvidence, assessBasicGameplayRoute, extractBasicGameplayEvidence };
169
+ export { type AssessBasicGameplayOptions, type BasicGameplayActionResult, type BasicGameplayAssessmentSummary, type BasicGameplayCanvasState, type BasicGameplayChangeSummary, type BasicGameplayFailureCode, type BasicGameplayFixReference, type BasicGameplayMobileEvidence, type BasicGameplayProofArtifact, type BasicGameplaySnapshot, type BasicGameplayWarningCode, type CreateBasicGameplayCatchSummaryInput, RIDDLE_PROOF_BASIC_GAMEPLAY_ASSESSMENT_VERSION, RIDDLE_PROOF_BASIC_GAMEPLAY_CATCH_VERSION, RIDDLE_PROOF_BASIC_GAMEPLAY_VERSION, type RiddleProofBasicGameplayAssessment, type RiddleProofBasicGameplayCatchSummary, type RiddleProofBasicGameplayEvidence, type RiddleProofBasicGameplayRouteAssessment, type RiddleProofBasicGameplayRouteEvidence, assessBasicGameplayEvidence, assessBasicGameplayRoute, createBasicGameplayCatchSummary, extractBasicGameplayEvidence };
@@ -1,5 +1,6 @@
1
1
  declare const RIDDLE_PROOF_BASIC_GAMEPLAY_VERSION = "riddle-proof.basic-gameplay.v1";
2
2
  declare const RIDDLE_PROOF_BASIC_GAMEPLAY_ASSESSMENT_VERSION = "riddle-proof.basic-gameplay.assessment.v1";
3
+ declare const RIDDLE_PROOF_BASIC_GAMEPLAY_CATCH_VERSION = "riddle-proof.basic-gameplay.catch.v1";
3
4
  type BasicGameplayFailureCode = "route_http_error" | "fatal_page_error" | "route_blank_or_thin" | "no_game_surface" | "mobile_horizontal_overflow" | "primary_control_missing" | "primary_control_inert";
4
5
  type BasicGameplayWarningCode = "canvas_inert" | "some_actions_failed" | "missing_reset_path" | "critical_console_error";
5
6
  interface BasicGameplayCanvasState {
@@ -110,8 +111,59 @@ interface RiddleProofBasicGameplayAssessment {
110
111
  warning_counts: Record<string, number>;
111
112
  route_results: RiddleProofBasicGameplayRouteAssessment[];
112
113
  }
114
+ interface BasicGameplayProofArtifact {
115
+ name: string;
116
+ role?: string;
117
+ kind?: string;
118
+ url?: string;
119
+ path?: string;
120
+ sha256?: string;
121
+ [key: string]: unknown;
122
+ }
123
+ interface BasicGameplayFixReference {
124
+ repo?: string;
125
+ commit?: string;
126
+ pr_url?: string;
127
+ summary?: string;
128
+ [key: string]: unknown;
129
+ }
130
+ interface CreateBasicGameplayCatchSummaryInput {
131
+ title?: string;
132
+ site?: string;
133
+ route?: string;
134
+ detected_at?: string;
135
+ before: unknown;
136
+ after?: unknown;
137
+ fix?: BasicGameplayFixReference;
138
+ artifacts?: BasicGameplayProofArtifact[];
139
+ }
140
+ interface BasicGameplayAssessmentSummary {
141
+ evidence_present: boolean;
142
+ passed: boolean;
143
+ checked_routes: number;
144
+ passing_routes: number;
145
+ failing_routes: RiddleProofBasicGameplayAssessment["failing_routes"];
146
+ failure_counts: Record<string, number>;
147
+ warning_counts: Record<string, number>;
148
+ notable_codes: string[];
149
+ }
150
+ interface RiddleProofBasicGameplayCatchSummary {
151
+ version: typeof RIDDLE_PROOF_BASIC_GAMEPLAY_CATCH_VERSION;
152
+ title: string;
153
+ site?: string;
154
+ route?: string;
155
+ detected_at: string;
156
+ before: BasicGameplayAssessmentSummary;
157
+ after?: BasicGameplayAssessmentSummary;
158
+ fixed: boolean;
159
+ fix?: BasicGameplayFixReference;
160
+ artifacts: BasicGameplayProofArtifact[];
161
+ summary_lines: string[];
162
+ marketing_summary: string;
163
+ }
113
164
  declare function assessBasicGameplayEvidence(evidence: unknown, options?: AssessBasicGameplayOptions): RiddleProofBasicGameplayAssessment;
114
165
  declare function assessBasicGameplayRoute(route: RiddleProofBasicGameplayRouteEvidence, options?: AssessBasicGameplayOptions): RiddleProofBasicGameplayRouteAssessment;
166
+ declare function createBasicGameplayCatchSummary(input: CreateBasicGameplayCatchSummaryInput, options?: AssessBasicGameplayOptions): RiddleProofBasicGameplayCatchSummary;
115
167
  declare function extractBasicGameplayEvidence(...sources: unknown[]): RiddleProofBasicGameplayEvidence | null;
116
168
 
117
- export { type AssessBasicGameplayOptions, type BasicGameplayActionResult, type BasicGameplayCanvasState, type BasicGameplayChangeSummary, type BasicGameplayFailureCode, type BasicGameplayMobileEvidence, type BasicGameplaySnapshot, type BasicGameplayWarningCode, RIDDLE_PROOF_BASIC_GAMEPLAY_ASSESSMENT_VERSION, RIDDLE_PROOF_BASIC_GAMEPLAY_VERSION, type RiddleProofBasicGameplayAssessment, type RiddleProofBasicGameplayEvidence, type RiddleProofBasicGameplayRouteAssessment, type RiddleProofBasicGameplayRouteEvidence, assessBasicGameplayEvidence, assessBasicGameplayRoute, extractBasicGameplayEvidence };
169
+ export { type AssessBasicGameplayOptions, type BasicGameplayActionResult, type BasicGameplayAssessmentSummary, type BasicGameplayCanvasState, type BasicGameplayChangeSummary, type BasicGameplayFailureCode, type BasicGameplayFixReference, type BasicGameplayMobileEvidence, type BasicGameplayProofArtifact, type BasicGameplaySnapshot, type BasicGameplayWarningCode, type CreateBasicGameplayCatchSummaryInput, RIDDLE_PROOF_BASIC_GAMEPLAY_ASSESSMENT_VERSION, RIDDLE_PROOF_BASIC_GAMEPLAY_CATCH_VERSION, RIDDLE_PROOF_BASIC_GAMEPLAY_VERSION, type RiddleProofBasicGameplayAssessment, type RiddleProofBasicGameplayCatchSummary, type RiddleProofBasicGameplayEvidence, type RiddleProofBasicGameplayRouteAssessment, type RiddleProofBasicGameplayRouteEvidence, assessBasicGameplayEvidence, assessBasicGameplayRoute, createBasicGameplayCatchSummary, extractBasicGameplayEvidence };
@@ -1,14 +1,18 @@
1
1
  import {
2
2
  RIDDLE_PROOF_BASIC_GAMEPLAY_ASSESSMENT_VERSION,
3
+ RIDDLE_PROOF_BASIC_GAMEPLAY_CATCH_VERSION,
3
4
  RIDDLE_PROOF_BASIC_GAMEPLAY_VERSION,
4
5
  assessBasicGameplayEvidence,
5
6
  assessBasicGameplayRoute,
7
+ createBasicGameplayCatchSummary,
6
8
  extractBasicGameplayEvidence
7
- } from "./chunk-RNGJX62B.js";
9
+ } from "./chunk-53DJMNQ6.js";
8
10
  export {
9
11
  RIDDLE_PROOF_BASIC_GAMEPLAY_ASSESSMENT_VERSION,
12
+ RIDDLE_PROOF_BASIC_GAMEPLAY_CATCH_VERSION,
10
13
  RIDDLE_PROOF_BASIC_GAMEPLAY_VERSION,
11
14
  assessBasicGameplayEvidence,
12
15
  assessBasicGameplayRoute,
16
+ createBasicGameplayCatchSummary,
13
17
  extractBasicGameplayEvidence
14
18
  };
@@ -87,12 +87,94 @@ async function deployRiddleStaticPreview(config, directory, label) {
87
87
  raw: published
88
88
  };
89
89
  }
90
+ function createTarball(directory, label, exclude = []) {
91
+ const scratch = mkdtempSync(path.join(tmpdir(), "riddle-upload-"));
92
+ const tarball = path.join(scratch, `${label}.tar.gz`);
93
+ const excludeArgs = exclude.flatMap((item) => ["--exclude", item]);
94
+ try {
95
+ execFileSync("tar", ["czf", tarball, ...excludeArgs, "-C", directory, "."], { stdio: "pipe" });
96
+ return { scratch, tarball };
97
+ } catch (error) {
98
+ rmSync(scratch, { recursive: true, force: true });
99
+ throw error;
100
+ }
101
+ }
90
102
  function parseRiddleViewport(value) {
91
103
  if (!value) return void 0;
92
104
  const match = /^(\d+)x(\d+)$/.exec(value.trim());
93
105
  if (!match) throw new Error("viewport must look like 1280x720");
94
106
  return { width: Number(match[1]), height: Number(match[2]) };
95
107
  }
108
+ function scriptErrorFrom(job) {
109
+ const nested = job?.proof_of_execution && typeof job.proof_of_execution === "object" && !Array.isArray(job.proof_of_execution) ? job.proof_of_execution : null;
110
+ return typeof job?.script_error === "string" && job.script_error.trim() ? job.script_error : typeof nested?.script_error === "string" && nested.script_error.trim() ? nested.script_error : null;
111
+ }
112
+ async function runRiddleServerPreview(config, input) {
113
+ if (!input.directory?.trim()) throw new Error("directory is required");
114
+ if (!input.script?.trim()) throw new Error("script is required");
115
+ const port = input.port || 3e3;
116
+ const routePath = input.path || "/";
117
+ const timeoutSec = input.timeoutSec || 180;
118
+ const created = await riddleRequestJson(config, "/v1/server-preview", {
119
+ method: "POST",
120
+ body: JSON.stringify({
121
+ image: input.image || "node:22-slim",
122
+ command: input.command || "node scripts/riddleSpaPreviewServer.mjs build 3000",
123
+ port,
124
+ path: routePath,
125
+ readiness_path: input.readinessPath || routePath,
126
+ readiness_timeout: input.readinessTimeoutSec || 90,
127
+ wait_until: input.waitUntil || "domcontentloaded",
128
+ wait_for_selector: input.waitForSelector || "body",
129
+ navigation_timeout: input.navigationTimeoutSec || 60,
130
+ viewport: input.viewport,
131
+ timeout: timeoutSec,
132
+ script: input.script
133
+ })
134
+ });
135
+ const jobId = String(created.job_id || "");
136
+ const uploadUrl = String(created.upload_url || "");
137
+ if (!jobId || !uploadUrl) {
138
+ throw new Error(`Riddle server preview create response was missing job_id or upload_url.`);
139
+ }
140
+ const { scratch, tarball } = createTarball(input.directory, jobId, [
141
+ ".git",
142
+ "node_modules",
143
+ "test-results",
144
+ ...input.exclude || []
145
+ ]);
146
+ try {
147
+ const upload = await fetchFor(config)(uploadUrl, {
148
+ method: "PUT",
149
+ headers: { "Content-Type": "application/gzip" },
150
+ body: readFileSync(tarball)
151
+ });
152
+ if (!upload.ok) throw new RiddleApiError(uploadUrl, upload.status, await upload.text());
153
+ } finally {
154
+ rmSync(scratch, { recursive: true, force: true });
155
+ }
156
+ await riddleRequestJson(config, `/v1/server-preview/${jobId}/start`, {
157
+ method: "POST"
158
+ });
159
+ let job = null;
160
+ const attempts = input.pollAttempts || Math.ceil((timeoutSec + 90) / 2);
161
+ const intervalMs = input.pollIntervalMs || 2e3;
162
+ for (let index = 0; index < attempts; index += 1) {
163
+ job = await riddleRequestJson(config, `/v1/server-preview/${jobId}`);
164
+ if (isTerminalRiddleJobStatus(job.status)) break;
165
+ if (index + 1 < attempts) await new Promise((resolve) => setTimeout(resolve, intervalMs));
166
+ }
167
+ const status = job?.status ? String(job.status) : null;
168
+ const scriptError = scriptErrorFrom(job);
169
+ return {
170
+ ok: (status === "completed" || status === "complete") && !scriptError,
171
+ job_id: jobId,
172
+ status,
173
+ terminal: isTerminalRiddleJobStatus(status),
174
+ script_error: scriptError,
175
+ job
176
+ };
177
+ }
96
178
  async function runRiddleScript(config, input) {
97
179
  if (!input.url?.trim()) throw new Error("url is required");
98
180
  if (!input.script?.trim()) throw new Error("script is required");
@@ -144,6 +226,7 @@ function createRiddleApiClient(config = {}) {
144
226
  requestJson: (pathname, init) => riddleRequestJson(config, pathname, init),
145
227
  deployStaticPreview: (directory, label) => deployRiddleStaticPreview(config, directory, label),
146
228
  runScript: (input) => runRiddleScript(config, input),
229
+ runServerPreview: (input) => runRiddleServerPreview(config, input),
147
230
  pollJob: (jobId, options) => pollRiddleJob(config, jobId, options)
148
231
  };
149
232
  }
@@ -156,6 +239,7 @@ export {
156
239
  riddleRequestJson,
157
240
  deployRiddleStaticPreview,
158
241
  parseRiddleViewport,
242
+ runRiddleServerPreview,
159
243
  runRiddleScript,
160
244
  isTerminalRiddleJobStatus,
161
245
  pollRiddleJob,
@@ -1,6 +1,7 @@
1
1
  // src/basic-gameplay.ts
2
2
  var RIDDLE_PROOF_BASIC_GAMEPLAY_VERSION = "riddle-proof.basic-gameplay.v1";
3
3
  var RIDDLE_PROOF_BASIC_GAMEPLAY_ASSESSMENT_VERSION = "riddle-proof.basic-gameplay.assessment.v1";
4
+ var RIDDLE_PROOF_BASIC_GAMEPLAY_CATCH_VERSION = "riddle-proof.basic-gameplay.catch.v1";
4
5
  var BASIC_GAMEPLAY_CONTAINER_KEYS = [
5
6
  "basic_gameplay",
6
7
  "basicGameplay",
@@ -110,6 +111,37 @@ function assessBasicGameplayRoute(route, options = {}) {
110
111
  }
111
112
  };
112
113
  }
114
+ function createBasicGameplayCatchSummary(input, options = {}) {
115
+ const before = summarizeAssessment(assessBasicGameplayEvidence(input.before, options));
116
+ const after = input.after === void 0 ? void 0 : summarizeAssessment(assessBasicGameplayEvidence(input.after, options));
117
+ const fixed = Boolean(after && before.notable_codes.length > 0 && after.passed && after.notable_codes.length === 0);
118
+ const title = input.title || [
119
+ input.site || "Basic gameplay",
120
+ input.route ? `${input.route} proof catch` : "proof catch"
121
+ ].join(" ");
122
+ const beforeCodes = before.notable_codes.length ? before.notable_codes.join(", ") : "no failing or warning codes";
123
+ const afterCodes = after ? after.notable_codes.length ? after.notable_codes.join(", ") : "no failing or warning codes" : "not verified";
124
+ const summaryLines = [
125
+ `Before: ${before.checked_routes} checked, ${before.passing_routes} passing, codes: ${beforeCodes}.`,
126
+ after ? `After: ${after.checked_routes} checked, ${after.passing_routes} passing, codes: ${afterCodes}.` : "After: not provided."
127
+ ];
128
+ if (input.fix?.summary) summaryLines.push(`Fix: ${input.fix.summary}`);
129
+ if (input.artifacts?.length) summaryLines.push(`Artifacts: ${input.artifacts.length} attached.`);
130
+ return {
131
+ version: RIDDLE_PROOF_BASIC_GAMEPLAY_CATCH_VERSION,
132
+ title,
133
+ site: input.site,
134
+ route: input.route,
135
+ detected_at: input.detected_at || (/* @__PURE__ */ new Date()).toISOString(),
136
+ before,
137
+ after,
138
+ fixed,
139
+ fix: input.fix,
140
+ artifacts: input.artifacts || [],
141
+ summary_lines: summaryLines,
142
+ marketing_summary: fixed ? `${title}: Riddle Proof caught ${beforeCodes}; after the fix, ${afterCodes}.` : `${title}: Riddle Proof caught ${beforeCodes}; after evidence is ${after ? "not yet clean" : "not yet attached"}.`
143
+ };
144
+ }
113
145
  function extractBasicGameplayEvidence(...sources) {
114
146
  const seen = /* @__PURE__ */ new Set();
115
147
  for (const source of sources) {
@@ -118,6 +150,21 @@ function extractBasicGameplayEvidence(...sources) {
118
150
  }
119
151
  return null;
120
152
  }
153
+ function summarizeAssessment(assessment) {
154
+ return {
155
+ evidence_present: assessment.evidence_present,
156
+ passed: assessment.passed,
157
+ checked_routes: assessment.checked_routes,
158
+ passing_routes: assessment.passing_routes,
159
+ failing_routes: assessment.failing_routes,
160
+ failure_counts: assessment.failure_counts,
161
+ warning_counts: assessment.warning_counts,
162
+ notable_codes: [
163
+ ...Object.keys(assessment.failure_counts),
164
+ ...Object.keys(assessment.warning_counts)
165
+ ].sort()
166
+ };
167
+ }
121
168
  function findBasicGameplayEvidence(value, seen, depth = 0) {
122
169
  if (depth > 6 || value === null || value === void 0) return null;
123
170
  if (typeof value === "string") {
@@ -221,7 +268,9 @@ function parseJson(value) {
221
268
  export {
222
269
  RIDDLE_PROOF_BASIC_GAMEPLAY_VERSION,
223
270
  RIDDLE_PROOF_BASIC_GAMEPLAY_ASSESSMENT_VERSION,
271
+ RIDDLE_PROOF_BASIC_GAMEPLAY_CATCH_VERSION,
224
272
  assessBasicGameplayEvidence,
225
273
  assessBasicGameplayRoute,
274
+ createBasicGameplayCatchSummary,
226
275
  extractBasicGameplayEvidence
227
276
  };
package/dist/cli.cjs CHANGED
@@ -6487,12 +6487,94 @@ async function deployRiddleStaticPreview(config, directory, label) {
6487
6487
  raw: published
6488
6488
  };
6489
6489
  }
6490
+ function createTarball(directory, label, exclude = []) {
6491
+ const scratch = (0, import_node_fs5.mkdtempSync)(import_node_path5.default.join((0, import_node_os2.tmpdir)(), "riddle-upload-"));
6492
+ const tarball = import_node_path5.default.join(scratch, `${label}.tar.gz`);
6493
+ const excludeArgs = exclude.flatMap((item) => ["--exclude", item]);
6494
+ try {
6495
+ (0, import_node_child_process4.execFileSync)("tar", ["czf", tarball, ...excludeArgs, "-C", directory, "."], { stdio: "pipe" });
6496
+ return { scratch, tarball };
6497
+ } catch (error) {
6498
+ (0, import_node_fs5.rmSync)(scratch, { recursive: true, force: true });
6499
+ throw error;
6500
+ }
6501
+ }
6490
6502
  function parseRiddleViewport(value) {
6491
6503
  if (!value) return void 0;
6492
6504
  const match = /^(\d+)x(\d+)$/.exec(value.trim());
6493
6505
  if (!match) throw new Error("viewport must look like 1280x720");
6494
6506
  return { width: Number(match[1]), height: Number(match[2]) };
6495
6507
  }
6508
+ function scriptErrorFrom(job) {
6509
+ const nested = job?.proof_of_execution && typeof job.proof_of_execution === "object" && !Array.isArray(job.proof_of_execution) ? job.proof_of_execution : null;
6510
+ return typeof job?.script_error === "string" && job.script_error.trim() ? job.script_error : typeof nested?.script_error === "string" && nested.script_error.trim() ? nested.script_error : null;
6511
+ }
6512
+ async function runRiddleServerPreview(config, input) {
6513
+ if (!input.directory?.trim()) throw new Error("directory is required");
6514
+ if (!input.script?.trim()) throw new Error("script is required");
6515
+ const port = input.port || 3e3;
6516
+ const routePath = input.path || "/";
6517
+ const timeoutSec = input.timeoutSec || 180;
6518
+ const created = await riddleRequestJson(config, "/v1/server-preview", {
6519
+ method: "POST",
6520
+ body: JSON.stringify({
6521
+ image: input.image || "node:22-slim",
6522
+ command: input.command || "node scripts/riddleSpaPreviewServer.mjs build 3000",
6523
+ port,
6524
+ path: routePath,
6525
+ readiness_path: input.readinessPath || routePath,
6526
+ readiness_timeout: input.readinessTimeoutSec || 90,
6527
+ wait_until: input.waitUntil || "domcontentloaded",
6528
+ wait_for_selector: input.waitForSelector || "body",
6529
+ navigation_timeout: input.navigationTimeoutSec || 60,
6530
+ viewport: input.viewport,
6531
+ timeout: timeoutSec,
6532
+ script: input.script
6533
+ })
6534
+ });
6535
+ const jobId = String(created.job_id || "");
6536
+ const uploadUrl = String(created.upload_url || "");
6537
+ if (!jobId || !uploadUrl) {
6538
+ throw new Error(`Riddle server preview create response was missing job_id or upload_url.`);
6539
+ }
6540
+ const { scratch, tarball } = createTarball(input.directory, jobId, [
6541
+ ".git",
6542
+ "node_modules",
6543
+ "test-results",
6544
+ ...input.exclude || []
6545
+ ]);
6546
+ try {
6547
+ const upload = await fetchFor(config)(uploadUrl, {
6548
+ method: "PUT",
6549
+ headers: { "Content-Type": "application/gzip" },
6550
+ body: (0, import_node_fs5.readFileSync)(tarball)
6551
+ });
6552
+ if (!upload.ok) throw new RiddleApiError(uploadUrl, upload.status, await upload.text());
6553
+ } finally {
6554
+ (0, import_node_fs5.rmSync)(scratch, { recursive: true, force: true });
6555
+ }
6556
+ await riddleRequestJson(config, `/v1/server-preview/${jobId}/start`, {
6557
+ method: "POST"
6558
+ });
6559
+ let job = null;
6560
+ const attempts = input.pollAttempts || Math.ceil((timeoutSec + 90) / 2);
6561
+ const intervalMs = input.pollIntervalMs || 2e3;
6562
+ for (let index = 0; index < attempts; index += 1) {
6563
+ job = await riddleRequestJson(config, `/v1/server-preview/${jobId}`);
6564
+ if (isTerminalRiddleJobStatus(job.status)) break;
6565
+ if (index + 1 < attempts) await new Promise((resolve) => setTimeout(resolve, intervalMs));
6566
+ }
6567
+ const status = job?.status ? String(job.status) : null;
6568
+ const scriptError = scriptErrorFrom(job);
6569
+ return {
6570
+ ok: (status === "completed" || status === "complete") && !scriptError,
6571
+ job_id: jobId,
6572
+ status,
6573
+ terminal: isTerminalRiddleJobStatus(status),
6574
+ script_error: scriptError,
6575
+ job
6576
+ };
6577
+ }
6496
6578
  async function runRiddleScript(config, input) {
6497
6579
  if (!input.url?.trim()) throw new Error("url is required");
6498
6580
  if (!input.script?.trim()) throw new Error("script is required");
@@ -6544,6 +6626,7 @@ function createRiddleApiClient(config = {}) {
6544
6626
  requestJson: (pathname, init) => riddleRequestJson(config, pathname, init),
6545
6627
  deployStaticPreview: (directory, label) => deployRiddleStaticPreview(config, directory, label),
6546
6628
  runScript: (input) => runRiddleScript(config, input),
6629
+ runServerPreview: (input) => runRiddleServerPreview(config, input),
6547
6630
  pollJob: (jobId, options) => pollRiddleJob(config, jobId, options)
6548
6631
  };
6549
6632
  }
@@ -6558,6 +6641,7 @@ function usage() {
6558
6641
  " riddle-proof-loop respond --state-path <path> --decision <decision> --summary <text> [--payload-json <file|json|->]",
6559
6642
  " riddle-proof-loop status --state-path <path>",
6560
6643
  " riddle-proof-loop riddle-preview-deploy <build-dir> <label>",
6644
+ " riddle-proof-loop riddle-server-preview <directory> --script-file <file> [--path /route] [--wait-for-selector selector]",
6561
6645
  " riddle-proof-loop riddle-run-script --url <url> --script-file <file> [--viewport 1280x720]",
6562
6646
  " riddle-proof-loop riddle-poll <job-id> [--wait]",
6563
6647
  " riddle-proof-loop doctor local [--codex-command <path>]",
@@ -6801,6 +6885,32 @@ async function main() {
6801
6885
  `);
6802
6886
  return;
6803
6887
  }
6888
+ if (command === "riddle-server-preview") {
6889
+ const directory = positional[1];
6890
+ const scriptFile = optionString(options, "scriptFile");
6891
+ if (!directory || !scriptFile) throw new Error("riddle-server-preview requires <directory> and --script-file.");
6892
+ const result = await createRiddleApiClient(riddleClientConfig(options)).runServerPreview({
6893
+ directory,
6894
+ script: (0, import_node_fs6.readFileSync)(scriptFile, "utf-8"),
6895
+ image: optionString(options, "image"),
6896
+ command: optionString(options, "command"),
6897
+ port: optionString(options, "port") ? Number(optionString(options, "port")) : void 0,
6898
+ path: optionString(options, "path"),
6899
+ readinessPath: optionString(options, "readinessPath"),
6900
+ readinessTimeoutSec: optionString(options, "readinessTimeout") ? Number(optionString(options, "readinessTimeout")) : void 0,
6901
+ waitForSelector: optionString(options, "waitForSelector"),
6902
+ navigationTimeoutSec: optionString(options, "navigationTimeout") ? Number(optionString(options, "navigationTimeout")) : void 0,
6903
+ viewport: parseRiddleViewport(optionString(options, "viewport")),
6904
+ timeoutSec: optionString(options, "timeout") ? Number(optionString(options, "timeout")) : void 0,
6905
+ pollAttempts: optionString(options, "pollAttempts") ? Number(optionString(options, "pollAttempts")) : void 0,
6906
+ pollIntervalMs: optionString(options, "pollIntervalMs") ? Number(optionString(options, "pollIntervalMs")) : void 0,
6907
+ exclude: optionString(options, "exclude")?.split(",").map((item) => item.trim()).filter(Boolean)
6908
+ });
6909
+ process.stdout.write(`${JSON.stringify(result, null, 2)}
6910
+ `);
6911
+ process.exitCode = result.ok ? 0 : 1;
6912
+ return;
6913
+ }
6804
6914
  if (command === "riddle-run-script") {
6805
6915
  const url = optionString(options, "url");
6806
6916
  const scriptFile = optionString(options, "scriptFile");
package/dist/cli.js CHANGED
@@ -2,7 +2,7 @@
2
2
  import {
3
3
  createRiddleApiClient,
4
4
  parseRiddleViewport
5
- } from "./chunk-UR6ADV4Y.js";
5
+ } from "./chunk-3CVGVQTQ.js";
6
6
  import {
7
7
  createDisabledRiddleProofAgentAdapter,
8
8
  readRiddleProofRunStatus,
@@ -32,6 +32,7 @@ function usage() {
32
32
  " riddle-proof-loop respond --state-path <path> --decision <decision> --summary <text> [--payload-json <file|json|->]",
33
33
  " riddle-proof-loop status --state-path <path>",
34
34
  " riddle-proof-loop riddle-preview-deploy <build-dir> <label>",
35
+ " riddle-proof-loop riddle-server-preview <directory> --script-file <file> [--path /route] [--wait-for-selector selector]",
35
36
  " riddle-proof-loop riddle-run-script --url <url> --script-file <file> [--viewport 1280x720]",
36
37
  " riddle-proof-loop riddle-poll <job-id> [--wait]",
37
38
  " riddle-proof-loop doctor local [--codex-command <path>]",
@@ -275,6 +276,32 @@ async function main() {
275
276
  `);
276
277
  return;
277
278
  }
279
+ if (command === "riddle-server-preview") {
280
+ const directory = positional[1];
281
+ const scriptFile = optionString(options, "scriptFile");
282
+ if (!directory || !scriptFile) throw new Error("riddle-server-preview requires <directory> and --script-file.");
283
+ const result = await createRiddleApiClient(riddleClientConfig(options)).runServerPreview({
284
+ directory,
285
+ script: readFileSync(scriptFile, "utf-8"),
286
+ image: optionString(options, "image"),
287
+ command: optionString(options, "command"),
288
+ port: optionString(options, "port") ? Number(optionString(options, "port")) : void 0,
289
+ path: optionString(options, "path"),
290
+ readinessPath: optionString(options, "readinessPath"),
291
+ readinessTimeoutSec: optionString(options, "readinessTimeout") ? Number(optionString(options, "readinessTimeout")) : void 0,
292
+ waitForSelector: optionString(options, "waitForSelector"),
293
+ navigationTimeoutSec: optionString(options, "navigationTimeout") ? Number(optionString(options, "navigationTimeout")) : void 0,
294
+ viewport: parseRiddleViewport(optionString(options, "viewport")),
295
+ timeoutSec: optionString(options, "timeout") ? Number(optionString(options, "timeout")) : void 0,
296
+ pollAttempts: optionString(options, "pollAttempts") ? Number(optionString(options, "pollAttempts")) : void 0,
297
+ pollIntervalMs: optionString(options, "pollIntervalMs") ? Number(optionString(options, "pollIntervalMs")) : void 0,
298
+ exclude: optionString(options, "exclude")?.split(",").map((item) => item.trim()).filter(Boolean)
299
+ });
300
+ process.stdout.write(`${JSON.stringify(result, null, 2)}
301
+ `);
302
+ process.exitCode = result.ok ? 0 : 1;
303
+ return;
304
+ }
278
305
  if (command === "riddle-run-script") {
279
306
  const url = optionString(options, "url");
280
307
  const scriptFile = optionString(options, "scriptFile");
package/dist/index.cjs CHANGED
@@ -2779,6 +2779,7 @@ __export(index_exports, {
2779
2779
  DEFAULT_RIDDLE_API_BASE_URL: () => DEFAULT_RIDDLE_API_BASE_URL,
2780
2780
  DEFAULT_RIDDLE_API_KEY_FILE: () => DEFAULT_RIDDLE_API_KEY_FILE,
2781
2781
  RIDDLE_PROOF_BASIC_GAMEPLAY_ASSESSMENT_VERSION: () => RIDDLE_PROOF_BASIC_GAMEPLAY_ASSESSMENT_VERSION,
2782
+ RIDDLE_PROOF_BASIC_GAMEPLAY_CATCH_VERSION: () => RIDDLE_PROOF_BASIC_GAMEPLAY_CATCH_VERSION,
2782
2783
  RIDDLE_PROOF_BASIC_GAMEPLAY_VERSION: () => RIDDLE_PROOF_BASIC_GAMEPLAY_VERSION,
2783
2784
  RIDDLE_PROOF_CAPTURE_DIAGNOSTIC_VERSION: () => RIDDLE_PROOF_CAPTURE_DIAGNOSTIC_VERSION,
2784
2785
  RIDDLE_PROOF_CHECKPOINT_PACKET_VERSION: () => RIDDLE_PROOF_CHECKPOINT_PACKET_VERSION,
@@ -2808,6 +2809,7 @@ __export(index_exports, {
2808
2809
  checkpointSummaryFromState: () => checkpointSummaryFromState,
2809
2810
  compactRecord: () => compactRecord,
2810
2811
  compareVisualProofSessionFingerprint: () => compareVisualProofSessionFingerprint,
2812
+ createBasicGameplayCatchSummary: () => createBasicGameplayCatchSummary,
2811
2813
  createCaptureDiagnostic: () => createCaptureDiagnostic,
2812
2814
  createCheckpointResponseTemplate: () => createCheckpointResponseTemplate,
2813
2815
  createCodexExecAgentAdapter: () => createCodexExecAgentAdapter,
@@ -2848,6 +2850,7 @@ __export(index_exports, {
2848
2850
  runRiddleProof: () => runRiddleProof,
2849
2851
  runRiddleProofEngineHarness: () => runRiddleProofEngineHarness,
2850
2852
  runRiddleScript: () => runRiddleScript,
2853
+ runRiddleServerPreview: () => runRiddleServerPreview,
2851
2854
  setRunStatus: () => setRunStatus,
2852
2855
  statePathsForRunState: () => statePathsForRunState,
2853
2856
  summarizeCaptureArtifacts: () => summarizeCaptureArtifacts,
@@ -7619,6 +7622,7 @@ function parseJson(value) {
7619
7622
  // src/basic-gameplay.ts
7620
7623
  var RIDDLE_PROOF_BASIC_GAMEPLAY_VERSION = "riddle-proof.basic-gameplay.v1";
7621
7624
  var RIDDLE_PROOF_BASIC_GAMEPLAY_ASSESSMENT_VERSION = "riddle-proof.basic-gameplay.assessment.v1";
7625
+ var RIDDLE_PROOF_BASIC_GAMEPLAY_CATCH_VERSION = "riddle-proof.basic-gameplay.catch.v1";
7622
7626
  var BASIC_GAMEPLAY_CONTAINER_KEYS = [
7623
7627
  "basic_gameplay",
7624
7628
  "basicGameplay",
@@ -7728,6 +7732,37 @@ function assessBasicGameplayRoute(route, options = {}) {
7728
7732
  }
7729
7733
  };
7730
7734
  }
7735
+ function createBasicGameplayCatchSummary(input, options = {}) {
7736
+ const before = summarizeAssessment(assessBasicGameplayEvidence(input.before, options));
7737
+ const after = input.after === void 0 ? void 0 : summarizeAssessment(assessBasicGameplayEvidence(input.after, options));
7738
+ const fixed = Boolean(after && before.notable_codes.length > 0 && after.passed && after.notable_codes.length === 0);
7739
+ const title = input.title || [
7740
+ input.site || "Basic gameplay",
7741
+ input.route ? `${input.route} proof catch` : "proof catch"
7742
+ ].join(" ");
7743
+ const beforeCodes = before.notable_codes.length ? before.notable_codes.join(", ") : "no failing or warning codes";
7744
+ const afterCodes = after ? after.notable_codes.length ? after.notable_codes.join(", ") : "no failing or warning codes" : "not verified";
7745
+ const summaryLines = [
7746
+ `Before: ${before.checked_routes} checked, ${before.passing_routes} passing, codes: ${beforeCodes}.`,
7747
+ after ? `After: ${after.checked_routes} checked, ${after.passing_routes} passing, codes: ${afterCodes}.` : "After: not provided."
7748
+ ];
7749
+ if (input.fix?.summary) summaryLines.push(`Fix: ${input.fix.summary}`);
7750
+ if (input.artifacts?.length) summaryLines.push(`Artifacts: ${input.artifacts.length} attached.`);
7751
+ return {
7752
+ version: RIDDLE_PROOF_BASIC_GAMEPLAY_CATCH_VERSION,
7753
+ title,
7754
+ site: input.site,
7755
+ route: input.route,
7756
+ detected_at: input.detected_at || (/* @__PURE__ */ new Date()).toISOString(),
7757
+ before,
7758
+ after,
7759
+ fixed,
7760
+ fix: input.fix,
7761
+ artifacts: input.artifacts || [],
7762
+ summary_lines: summaryLines,
7763
+ marketing_summary: fixed ? `${title}: Riddle Proof caught ${beforeCodes}; after the fix, ${afterCodes}.` : `${title}: Riddle Proof caught ${beforeCodes}; after evidence is ${after ? "not yet clean" : "not yet attached"}.`
7764
+ };
7765
+ }
7731
7766
  function extractBasicGameplayEvidence(...sources) {
7732
7767
  const seen = /* @__PURE__ */ new Set();
7733
7768
  for (const source of sources) {
@@ -7736,6 +7771,21 @@ function extractBasicGameplayEvidence(...sources) {
7736
7771
  }
7737
7772
  return null;
7738
7773
  }
7774
+ function summarizeAssessment(assessment) {
7775
+ return {
7776
+ evidence_present: assessment.evidence_present,
7777
+ passed: assessment.passed,
7778
+ checked_routes: assessment.checked_routes,
7779
+ passing_routes: assessment.passing_routes,
7780
+ failing_routes: assessment.failing_routes,
7781
+ failure_counts: assessment.failure_counts,
7782
+ warning_counts: assessment.warning_counts,
7783
+ notable_codes: [
7784
+ ...Object.keys(assessment.failure_counts),
7785
+ ...Object.keys(assessment.warning_counts)
7786
+ ].sort()
7787
+ };
7788
+ }
7739
7789
  function findBasicGameplayEvidence(value, seen, depth = 0) {
7740
7790
  if (depth > 6 || value === null || value === void 0) return null;
7741
7791
  if (typeof value === "string") {
@@ -7925,12 +7975,94 @@ async function deployRiddleStaticPreview(config, directory, label) {
7925
7975
  raw: published
7926
7976
  };
7927
7977
  }
7978
+ function createTarball(directory, label, exclude = []) {
7979
+ const scratch = (0, import_node_fs5.mkdtempSync)(import_node_path5.default.join((0, import_node_os2.tmpdir)(), "riddle-upload-"));
7980
+ const tarball = import_node_path5.default.join(scratch, `${label}.tar.gz`);
7981
+ const excludeArgs = exclude.flatMap((item) => ["--exclude", item]);
7982
+ try {
7983
+ (0, import_node_child_process4.execFileSync)("tar", ["czf", tarball, ...excludeArgs, "-C", directory, "."], { stdio: "pipe" });
7984
+ return { scratch, tarball };
7985
+ } catch (error) {
7986
+ (0, import_node_fs5.rmSync)(scratch, { recursive: true, force: true });
7987
+ throw error;
7988
+ }
7989
+ }
7928
7990
  function parseRiddleViewport(value) {
7929
7991
  if (!value) return void 0;
7930
7992
  const match = /^(\d+)x(\d+)$/.exec(value.trim());
7931
7993
  if (!match) throw new Error("viewport must look like 1280x720");
7932
7994
  return { width: Number(match[1]), height: Number(match[2]) };
7933
7995
  }
7996
+ function scriptErrorFrom(job) {
7997
+ const nested = job?.proof_of_execution && typeof job.proof_of_execution === "object" && !Array.isArray(job.proof_of_execution) ? job.proof_of_execution : null;
7998
+ return typeof job?.script_error === "string" && job.script_error.trim() ? job.script_error : typeof nested?.script_error === "string" && nested.script_error.trim() ? nested.script_error : null;
7999
+ }
8000
+ async function runRiddleServerPreview(config, input) {
8001
+ if (!input.directory?.trim()) throw new Error("directory is required");
8002
+ if (!input.script?.trim()) throw new Error("script is required");
8003
+ const port = input.port || 3e3;
8004
+ const routePath = input.path || "/";
8005
+ const timeoutSec = input.timeoutSec || 180;
8006
+ const created = await riddleRequestJson(config, "/v1/server-preview", {
8007
+ method: "POST",
8008
+ body: JSON.stringify({
8009
+ image: input.image || "node:22-slim",
8010
+ command: input.command || "node scripts/riddleSpaPreviewServer.mjs build 3000",
8011
+ port,
8012
+ path: routePath,
8013
+ readiness_path: input.readinessPath || routePath,
8014
+ readiness_timeout: input.readinessTimeoutSec || 90,
8015
+ wait_until: input.waitUntil || "domcontentloaded",
8016
+ wait_for_selector: input.waitForSelector || "body",
8017
+ navigation_timeout: input.navigationTimeoutSec || 60,
8018
+ viewport: input.viewport,
8019
+ timeout: timeoutSec,
8020
+ script: input.script
8021
+ })
8022
+ });
8023
+ const jobId = String(created.job_id || "");
8024
+ const uploadUrl = String(created.upload_url || "");
8025
+ if (!jobId || !uploadUrl) {
8026
+ throw new Error(`Riddle server preview create response was missing job_id or upload_url.`);
8027
+ }
8028
+ const { scratch, tarball } = createTarball(input.directory, jobId, [
8029
+ ".git",
8030
+ "node_modules",
8031
+ "test-results",
8032
+ ...input.exclude || []
8033
+ ]);
8034
+ try {
8035
+ const upload = await fetchFor(config)(uploadUrl, {
8036
+ method: "PUT",
8037
+ headers: { "Content-Type": "application/gzip" },
8038
+ body: (0, import_node_fs5.readFileSync)(tarball)
8039
+ });
8040
+ if (!upload.ok) throw new RiddleApiError(uploadUrl, upload.status, await upload.text());
8041
+ } finally {
8042
+ (0, import_node_fs5.rmSync)(scratch, { recursive: true, force: true });
8043
+ }
8044
+ await riddleRequestJson(config, `/v1/server-preview/${jobId}/start`, {
8045
+ method: "POST"
8046
+ });
8047
+ let job = null;
8048
+ const attempts = input.pollAttempts || Math.ceil((timeoutSec + 90) / 2);
8049
+ const intervalMs = input.pollIntervalMs || 2e3;
8050
+ for (let index = 0; index < attempts; index += 1) {
8051
+ job = await riddleRequestJson(config, `/v1/server-preview/${jobId}`);
8052
+ if (isTerminalRiddleJobStatus(job.status)) break;
8053
+ if (index + 1 < attempts) await new Promise((resolve) => setTimeout(resolve, intervalMs));
8054
+ }
8055
+ const status = job?.status ? String(job.status) : null;
8056
+ const scriptError = scriptErrorFrom(job);
8057
+ return {
8058
+ ok: (status === "completed" || status === "complete") && !scriptError,
8059
+ job_id: jobId,
8060
+ status,
8061
+ terminal: isTerminalRiddleJobStatus(status),
8062
+ script_error: scriptError,
8063
+ job
8064
+ };
8065
+ }
7934
8066
  async function runRiddleScript(config, input) {
7935
8067
  if (!input.url?.trim()) throw new Error("url is required");
7936
8068
  if (!input.script?.trim()) throw new Error("script is required");
@@ -7982,6 +8114,7 @@ function createRiddleApiClient(config = {}) {
7982
8114
  requestJson: (pathname, init) => riddleRequestJson(config, pathname, init),
7983
8115
  deployStaticPreview: (directory, label) => deployRiddleStaticPreview(config, directory, label),
7984
8116
  runScript: (input) => runRiddleScript(config, input),
8117
+ runServerPreview: (input) => runRiddleServerPreview(config, input),
7985
8118
  pollJob: (jobId, options) => pollRiddleJob(config, jobId, options)
7986
8119
  };
7987
8120
  }
@@ -7993,6 +8126,7 @@ function createRiddleApiClient(config = {}) {
7993
8126
  DEFAULT_RIDDLE_API_BASE_URL,
7994
8127
  DEFAULT_RIDDLE_API_KEY_FILE,
7995
8128
  RIDDLE_PROOF_BASIC_GAMEPLAY_ASSESSMENT_VERSION,
8129
+ RIDDLE_PROOF_BASIC_GAMEPLAY_CATCH_VERSION,
7996
8130
  RIDDLE_PROOF_BASIC_GAMEPLAY_VERSION,
7997
8131
  RIDDLE_PROOF_CAPTURE_DIAGNOSTIC_VERSION,
7998
8132
  RIDDLE_PROOF_CHECKPOINT_PACKET_VERSION,
@@ -8022,6 +8156,7 @@ function createRiddleApiClient(config = {}) {
8022
8156
  checkpointSummaryFromState,
8023
8157
  compactRecord,
8024
8158
  compareVisualProofSessionFingerprint,
8159
+ createBasicGameplayCatchSummary,
8025
8160
  createCaptureDiagnostic,
8026
8161
  createCheckpointResponseTemplate,
8027
8162
  createCodexExecAgentAdapter,
@@ -8062,6 +8197,7 @@ function createRiddleApiClient(config = {}) {
8062
8197
  runRiddleProof,
8063
8198
  runRiddleProofEngineHarness,
8064
8199
  runRiddleScript,
8200
+ runRiddleServerPreview,
8065
8201
  setRunStatus,
8066
8202
  statePathsForRunState,
8067
8203
  summarizeCaptureArtifacts,
package/dist/index.d.cts CHANGED
@@ -9,5 +9,5 @@ export { CodexExecAgentConfig, CodexJsonRequest, CodexJsonResult, CodexJsonRunne
9
9
  export { CreateCaptureDiagnosticInput, DEFAULT_DIAGNOSTIC_ARRAY_LIMIT, DEFAULT_DIAGNOSTIC_HISTORY_LIMIT, DEFAULT_DIAGNOSTIC_STRING_LIMIT, RIDDLE_PROOF_CAPTURE_DIAGNOSTIC_VERSION, RiddleProofArtifactSummary, RiddleProofCaptureArtifactSummary, RiddleProofCaptureDiagnostic, RiddleProofDiagnosticRedactionOptions, appendCaptureDiagnostic, createCaptureDiagnostic, redactForProofDiagnostics, summarizeCaptureArtifacts } from './diagnostics.cjs';
10
10
  export { BuildVisualProofSessionInput, RIDDLE_PROOF_VISUAL_SESSION_FINGERPRINT_VERSION, RIDDLE_PROOF_VISUAL_SESSION_VERSION, VisualProofSessionMismatch, buildVisualProofSession, compareVisualProofSessionFingerprint, parseVisualProofSession, visualSessionFingerprint, visualSessionFingerprintBasis } from './proof-session.cjs';
11
11
  export { AssessPlayabilityOptions, RIDDLE_PROOF_PLAYABILITY_ASSESSMENT_VERSION, RIDDLE_PROOF_PLAYABILITY_VERSION, RiddleProofPlayabilityAssessment, RiddleProofPlayabilityEvidence, assessPlayabilityEvidence, extractPlayabilityEvidence, isRiddleProofPlayabilityMode } from './playability.cjs';
12
- export { AssessBasicGameplayOptions, BasicGameplayActionResult, BasicGameplayCanvasState, BasicGameplayChangeSummary, BasicGameplayFailureCode, BasicGameplayMobileEvidence, BasicGameplaySnapshot, BasicGameplayWarningCode, RIDDLE_PROOF_BASIC_GAMEPLAY_ASSESSMENT_VERSION, RIDDLE_PROOF_BASIC_GAMEPLAY_VERSION, RiddleProofBasicGameplayAssessment, RiddleProofBasicGameplayEvidence, RiddleProofBasicGameplayRouteAssessment, RiddleProofBasicGameplayRouteEvidence, assessBasicGameplayEvidence, assessBasicGameplayRoute, extractBasicGameplayEvidence } from './basic-gameplay.cjs';
13
- export { DEFAULT_RIDDLE_API_BASE_URL, DEFAULT_RIDDLE_API_KEY_FILE, RiddleApiError, RiddleClientConfig, RiddleFetch, RiddlePollJobResult, RiddlePreviewDeployResult, RiddleRunScriptInput, createRiddleApiClient, deployRiddleStaticPreview, isTerminalRiddleJobStatus, parseRiddleViewport, pollRiddleJob, resolveRiddleApiKey, riddleRequestJson, runRiddleScript } from './riddle-client.cjs';
12
+ export { AssessBasicGameplayOptions, BasicGameplayActionResult, BasicGameplayAssessmentSummary, BasicGameplayCanvasState, BasicGameplayChangeSummary, BasicGameplayFailureCode, BasicGameplayFixReference, BasicGameplayMobileEvidence, BasicGameplayProofArtifact, BasicGameplaySnapshot, BasicGameplayWarningCode, CreateBasicGameplayCatchSummaryInput, RIDDLE_PROOF_BASIC_GAMEPLAY_ASSESSMENT_VERSION, RIDDLE_PROOF_BASIC_GAMEPLAY_CATCH_VERSION, RIDDLE_PROOF_BASIC_GAMEPLAY_VERSION, RiddleProofBasicGameplayAssessment, RiddleProofBasicGameplayCatchSummary, RiddleProofBasicGameplayEvidence, RiddleProofBasicGameplayRouteAssessment, RiddleProofBasicGameplayRouteEvidence, assessBasicGameplayEvidence, assessBasicGameplayRoute, createBasicGameplayCatchSummary, extractBasicGameplayEvidence } from './basic-gameplay.cjs';
13
+ export { DEFAULT_RIDDLE_API_BASE_URL, DEFAULT_RIDDLE_API_KEY_FILE, RiddleApiError, RiddleClientConfig, RiddleFetch, RiddlePollJobResult, RiddlePreviewDeployResult, RiddleRunScriptInput, RiddleServerPreviewInput, RiddleServerPreviewResult, createRiddleApiClient, deployRiddleStaticPreview, isTerminalRiddleJobStatus, parseRiddleViewport, pollRiddleJob, resolveRiddleApiKey, riddleRequestJson, runRiddleScript, runRiddleServerPreview } from './riddle-client.cjs';
package/dist/index.d.ts CHANGED
@@ -9,5 +9,5 @@ export { CodexExecAgentConfig, CodexJsonRequest, CodexJsonResult, CodexJsonRunne
9
9
  export { CreateCaptureDiagnosticInput, DEFAULT_DIAGNOSTIC_ARRAY_LIMIT, DEFAULT_DIAGNOSTIC_HISTORY_LIMIT, DEFAULT_DIAGNOSTIC_STRING_LIMIT, RIDDLE_PROOF_CAPTURE_DIAGNOSTIC_VERSION, RiddleProofArtifactSummary, RiddleProofCaptureArtifactSummary, RiddleProofCaptureDiagnostic, RiddleProofDiagnosticRedactionOptions, appendCaptureDiagnostic, createCaptureDiagnostic, redactForProofDiagnostics, summarizeCaptureArtifacts } from './diagnostics.js';
10
10
  export { BuildVisualProofSessionInput, RIDDLE_PROOF_VISUAL_SESSION_FINGERPRINT_VERSION, RIDDLE_PROOF_VISUAL_SESSION_VERSION, VisualProofSessionMismatch, buildVisualProofSession, compareVisualProofSessionFingerprint, parseVisualProofSession, visualSessionFingerprint, visualSessionFingerprintBasis } from './proof-session.js';
11
11
  export { AssessPlayabilityOptions, RIDDLE_PROOF_PLAYABILITY_ASSESSMENT_VERSION, RIDDLE_PROOF_PLAYABILITY_VERSION, RiddleProofPlayabilityAssessment, RiddleProofPlayabilityEvidence, assessPlayabilityEvidence, extractPlayabilityEvidence, isRiddleProofPlayabilityMode } from './playability.js';
12
- export { AssessBasicGameplayOptions, BasicGameplayActionResult, BasicGameplayCanvasState, BasicGameplayChangeSummary, BasicGameplayFailureCode, BasicGameplayMobileEvidence, BasicGameplaySnapshot, BasicGameplayWarningCode, RIDDLE_PROOF_BASIC_GAMEPLAY_ASSESSMENT_VERSION, RIDDLE_PROOF_BASIC_GAMEPLAY_VERSION, RiddleProofBasicGameplayAssessment, RiddleProofBasicGameplayEvidence, RiddleProofBasicGameplayRouteAssessment, RiddleProofBasicGameplayRouteEvidence, assessBasicGameplayEvidence, assessBasicGameplayRoute, extractBasicGameplayEvidence } from './basic-gameplay.js';
13
- export { DEFAULT_RIDDLE_API_BASE_URL, DEFAULT_RIDDLE_API_KEY_FILE, RiddleApiError, RiddleClientConfig, RiddleFetch, RiddlePollJobResult, RiddlePreviewDeployResult, RiddleRunScriptInput, createRiddleApiClient, deployRiddleStaticPreview, isTerminalRiddleJobStatus, parseRiddleViewport, pollRiddleJob, resolveRiddleApiKey, riddleRequestJson, runRiddleScript } from './riddle-client.js';
12
+ export { AssessBasicGameplayOptions, BasicGameplayActionResult, BasicGameplayAssessmentSummary, BasicGameplayCanvasState, BasicGameplayChangeSummary, BasicGameplayFailureCode, BasicGameplayFixReference, BasicGameplayMobileEvidence, BasicGameplayProofArtifact, BasicGameplaySnapshot, BasicGameplayWarningCode, CreateBasicGameplayCatchSummaryInput, RIDDLE_PROOF_BASIC_GAMEPLAY_ASSESSMENT_VERSION, RIDDLE_PROOF_BASIC_GAMEPLAY_CATCH_VERSION, RIDDLE_PROOF_BASIC_GAMEPLAY_VERSION, RiddleProofBasicGameplayAssessment, RiddleProofBasicGameplayCatchSummary, RiddleProofBasicGameplayEvidence, RiddleProofBasicGameplayRouteAssessment, RiddleProofBasicGameplayRouteEvidence, assessBasicGameplayEvidence, assessBasicGameplayRoute, createBasicGameplayCatchSummary, extractBasicGameplayEvidence } from './basic-gameplay.js';
13
+ export { DEFAULT_RIDDLE_API_BASE_URL, DEFAULT_RIDDLE_API_KEY_FILE, RiddleApiError, RiddleClientConfig, RiddleFetch, RiddlePollJobResult, RiddlePreviewDeployResult, RiddleRunScriptInput, RiddleServerPreviewInput, RiddleServerPreviewResult, createRiddleApiClient, deployRiddleStaticPreview, isTerminalRiddleJobStatus, parseRiddleViewport, pollRiddleJob, resolveRiddleApiKey, riddleRequestJson, runRiddleScript, runRiddleServerPreview } from './riddle-client.js';
package/dist/index.js CHANGED
@@ -20,11 +20,13 @@ import {
20
20
  } from "./chunk-ODORKNSO.js";
21
21
  import {
22
22
  RIDDLE_PROOF_BASIC_GAMEPLAY_ASSESSMENT_VERSION,
23
+ RIDDLE_PROOF_BASIC_GAMEPLAY_CATCH_VERSION,
23
24
  RIDDLE_PROOF_BASIC_GAMEPLAY_VERSION,
24
25
  assessBasicGameplayEvidence,
25
26
  assessBasicGameplayRoute,
27
+ createBasicGameplayCatchSummary,
26
28
  extractBasicGameplayEvidence
27
- } from "./chunk-RNGJX62B.js";
29
+ } from "./chunk-53DJMNQ6.js";
28
30
  import {
29
31
  DEFAULT_RIDDLE_API_BASE_URL,
30
32
  DEFAULT_RIDDLE_API_KEY_FILE,
@@ -36,8 +38,9 @@ import {
36
38
  pollRiddleJob,
37
39
  resolveRiddleApiKey,
38
40
  riddleRequestJson,
39
- runRiddleScript
40
- } from "./chunk-UR6ADV4Y.js";
41
+ runRiddleScript,
42
+ runRiddleServerPreview
43
+ } from "./chunk-3CVGVQTQ.js";
41
44
  import {
42
45
  DEFAULT_DIAGNOSTIC_ARRAY_LIMIT,
43
46
  DEFAULT_DIAGNOSTIC_HISTORY_LIMIT,
@@ -109,6 +112,7 @@ export {
109
112
  DEFAULT_RIDDLE_API_BASE_URL,
110
113
  DEFAULT_RIDDLE_API_KEY_FILE,
111
114
  RIDDLE_PROOF_BASIC_GAMEPLAY_ASSESSMENT_VERSION,
115
+ RIDDLE_PROOF_BASIC_GAMEPLAY_CATCH_VERSION,
112
116
  RIDDLE_PROOF_BASIC_GAMEPLAY_VERSION,
113
117
  RIDDLE_PROOF_CAPTURE_DIAGNOSTIC_VERSION,
114
118
  RIDDLE_PROOF_CHECKPOINT_PACKET_VERSION,
@@ -138,6 +142,7 @@ export {
138
142
  checkpointSummaryFromState,
139
143
  compactRecord,
140
144
  compareVisualProofSessionFingerprint,
145
+ createBasicGameplayCatchSummary,
141
146
  createCaptureDiagnostic,
142
147
  createCheckpointResponseTemplate,
143
148
  createCodexExecAgentAdapter,
@@ -178,6 +183,7 @@ export {
178
183
  runRiddleProof,
179
184
  runRiddleProofEngineHarness,
180
185
  runRiddleScript,
186
+ runRiddleServerPreview,
181
187
  setRunStatus,
182
188
  statePathsForRunState,
183
189
  summarizeCaptureArtifacts,
@@ -40,7 +40,8 @@ __export(riddle_client_exports, {
40
40
  pollRiddleJob: () => pollRiddleJob,
41
41
  resolveRiddleApiKey: () => resolveRiddleApiKey,
42
42
  riddleRequestJson: () => riddleRequestJson,
43
- runRiddleScript: () => runRiddleScript
43
+ runRiddleScript: () => runRiddleScript,
44
+ runRiddleServerPreview: () => runRiddleServerPreview
44
45
  });
45
46
  module.exports = __toCommonJS(riddle_client_exports);
46
47
  var import_node_child_process = require("child_process");
@@ -131,12 +132,94 @@ async function deployRiddleStaticPreview(config, directory, label) {
131
132
  raw: published
132
133
  };
133
134
  }
135
+ function createTarball(directory, label, exclude = []) {
136
+ const scratch = (0, import_node_fs.mkdtempSync)(import_node_path.default.join((0, import_node_os.tmpdir)(), "riddle-upload-"));
137
+ const tarball = import_node_path.default.join(scratch, `${label}.tar.gz`);
138
+ const excludeArgs = exclude.flatMap((item) => ["--exclude", item]);
139
+ try {
140
+ (0, import_node_child_process.execFileSync)("tar", ["czf", tarball, ...excludeArgs, "-C", directory, "."], { stdio: "pipe" });
141
+ return { scratch, tarball };
142
+ } catch (error) {
143
+ (0, import_node_fs.rmSync)(scratch, { recursive: true, force: true });
144
+ throw error;
145
+ }
146
+ }
134
147
  function parseRiddleViewport(value) {
135
148
  if (!value) return void 0;
136
149
  const match = /^(\d+)x(\d+)$/.exec(value.trim());
137
150
  if (!match) throw new Error("viewport must look like 1280x720");
138
151
  return { width: Number(match[1]), height: Number(match[2]) };
139
152
  }
153
+ function scriptErrorFrom(job) {
154
+ const nested = job?.proof_of_execution && typeof job.proof_of_execution === "object" && !Array.isArray(job.proof_of_execution) ? job.proof_of_execution : null;
155
+ return typeof job?.script_error === "string" && job.script_error.trim() ? job.script_error : typeof nested?.script_error === "string" && nested.script_error.trim() ? nested.script_error : null;
156
+ }
157
+ async function runRiddleServerPreview(config, input) {
158
+ if (!input.directory?.trim()) throw new Error("directory is required");
159
+ if (!input.script?.trim()) throw new Error("script is required");
160
+ const port = input.port || 3e3;
161
+ const routePath = input.path || "/";
162
+ const timeoutSec = input.timeoutSec || 180;
163
+ const created = await riddleRequestJson(config, "/v1/server-preview", {
164
+ method: "POST",
165
+ body: JSON.stringify({
166
+ image: input.image || "node:22-slim",
167
+ command: input.command || "node scripts/riddleSpaPreviewServer.mjs build 3000",
168
+ port,
169
+ path: routePath,
170
+ readiness_path: input.readinessPath || routePath,
171
+ readiness_timeout: input.readinessTimeoutSec || 90,
172
+ wait_until: input.waitUntil || "domcontentloaded",
173
+ wait_for_selector: input.waitForSelector || "body",
174
+ navigation_timeout: input.navigationTimeoutSec || 60,
175
+ viewport: input.viewport,
176
+ timeout: timeoutSec,
177
+ script: input.script
178
+ })
179
+ });
180
+ const jobId = String(created.job_id || "");
181
+ const uploadUrl = String(created.upload_url || "");
182
+ if (!jobId || !uploadUrl) {
183
+ throw new Error(`Riddle server preview create response was missing job_id or upload_url.`);
184
+ }
185
+ const { scratch, tarball } = createTarball(input.directory, jobId, [
186
+ ".git",
187
+ "node_modules",
188
+ "test-results",
189
+ ...input.exclude || []
190
+ ]);
191
+ try {
192
+ const upload = await fetchFor(config)(uploadUrl, {
193
+ method: "PUT",
194
+ headers: { "Content-Type": "application/gzip" },
195
+ body: (0, import_node_fs.readFileSync)(tarball)
196
+ });
197
+ if (!upload.ok) throw new RiddleApiError(uploadUrl, upload.status, await upload.text());
198
+ } finally {
199
+ (0, import_node_fs.rmSync)(scratch, { recursive: true, force: true });
200
+ }
201
+ await riddleRequestJson(config, `/v1/server-preview/${jobId}/start`, {
202
+ method: "POST"
203
+ });
204
+ let job = null;
205
+ const attempts = input.pollAttempts || Math.ceil((timeoutSec + 90) / 2);
206
+ const intervalMs = input.pollIntervalMs || 2e3;
207
+ for (let index = 0; index < attempts; index += 1) {
208
+ job = await riddleRequestJson(config, `/v1/server-preview/${jobId}`);
209
+ if (isTerminalRiddleJobStatus(job.status)) break;
210
+ if (index + 1 < attempts) await new Promise((resolve) => setTimeout(resolve, intervalMs));
211
+ }
212
+ const status = job?.status ? String(job.status) : null;
213
+ const scriptError = scriptErrorFrom(job);
214
+ return {
215
+ ok: (status === "completed" || status === "complete") && !scriptError,
216
+ job_id: jobId,
217
+ status,
218
+ terminal: isTerminalRiddleJobStatus(status),
219
+ script_error: scriptError,
220
+ job
221
+ };
222
+ }
140
223
  async function runRiddleScript(config, input) {
141
224
  if (!input.url?.trim()) throw new Error("url is required");
142
225
  if (!input.script?.trim()) throw new Error("script is required");
@@ -188,6 +271,7 @@ function createRiddleApiClient(config = {}) {
188
271
  requestJson: (pathname, init) => riddleRequestJson(config, pathname, init),
189
272
  deployStaticPreview: (directory, label) => deployRiddleStaticPreview(config, directory, label),
190
273
  runScript: (input) => runRiddleScript(config, input),
274
+ runServerPreview: (input) => runRiddleServerPreview(config, input),
191
275
  pollJob: (jobId, options) => pollRiddleJob(config, jobId, options)
192
276
  };
193
277
  }
@@ -203,5 +287,6 @@ function createRiddleApiClient(config = {}) {
203
287
  pollRiddleJob,
204
288
  resolveRiddleApiKey,
205
289
  riddleRequestJson,
206
- runRiddleScript
290
+ runRiddleScript,
291
+ runRiddleServerPreview
207
292
  });
@@ -29,6 +29,27 @@ interface RiddleRunScriptInput {
29
29
  include?: string[];
30
30
  options?: Record<string, unknown>;
31
31
  }
32
+ interface RiddleServerPreviewInput {
33
+ directory: string;
34
+ script: string;
35
+ image?: string;
36
+ command?: string;
37
+ port?: number;
38
+ path?: string;
39
+ readinessPath?: string;
40
+ readinessTimeoutSec?: number;
41
+ waitForSelector?: string;
42
+ waitUntil?: "commit" | "domcontentloaded" | "load" | "networkidle";
43
+ navigationTimeoutSec?: number;
44
+ viewport?: {
45
+ width: number;
46
+ height: number;
47
+ };
48
+ timeoutSec?: number;
49
+ pollAttempts?: number;
50
+ pollIntervalMs?: number;
51
+ exclude?: string[];
52
+ }
32
53
  interface RiddlePollJobResult {
33
54
  ok: boolean;
34
55
  job_id: string;
@@ -37,6 +58,14 @@ interface RiddlePollJobResult {
37
58
  job: Record<string, unknown> | null;
38
59
  artifacts?: Record<string, unknown> | null;
39
60
  }
61
+ interface RiddleServerPreviewResult {
62
+ ok: boolean;
63
+ job_id: string;
64
+ status: string | null;
65
+ terminal: boolean;
66
+ script_error: string | null;
67
+ job: Record<string, unknown> | null;
68
+ }
40
69
  declare class RiddleApiError extends Error {
41
70
  readonly status: number;
42
71
  readonly body: string;
@@ -50,6 +79,7 @@ declare function parseRiddleViewport(value?: string): {
50
79
  width: number;
51
80
  height: number;
52
81
  } | undefined;
82
+ declare function runRiddleServerPreview(config: RiddleClientConfig, input: RiddleServerPreviewInput): Promise<RiddleServerPreviewResult>;
53
83
  declare function runRiddleScript(config: RiddleClientConfig, input: RiddleRunScriptInput): Promise<Record<string, unknown>>;
54
84
  declare function isTerminalRiddleJobStatus(status: unknown): boolean;
55
85
  declare function pollRiddleJob(config: RiddleClientConfig, jobId: string, options?: {
@@ -61,6 +91,7 @@ declare function createRiddleApiClient(config?: RiddleClientConfig): {
61
91
  requestJson: <T = unknown>(pathname: string, init?: RequestInit) => Promise<T>;
62
92
  deployStaticPreview: (directory: string, label: string) => Promise<RiddlePreviewDeployResult>;
63
93
  runScript: (input: RiddleRunScriptInput) => Promise<Record<string, unknown>>;
94
+ runServerPreview: (input: RiddleServerPreviewInput) => Promise<RiddleServerPreviewResult>;
64
95
  pollJob: (jobId: string, options?: {
65
96
  wait?: boolean;
66
97
  attempts?: number;
@@ -68,4 +99,4 @@ declare function createRiddleApiClient(config?: RiddleClientConfig): {
68
99
  }) => Promise<RiddlePollJobResult>;
69
100
  };
70
101
 
71
- export { DEFAULT_RIDDLE_API_BASE_URL, DEFAULT_RIDDLE_API_KEY_FILE, RiddleApiError, type RiddleClientConfig, type RiddleFetch, type RiddlePollJobResult, type RiddlePreviewDeployResult, type RiddleRunScriptInput, createRiddleApiClient, deployRiddleStaticPreview, isTerminalRiddleJobStatus, parseRiddleViewport, pollRiddleJob, resolveRiddleApiKey, riddleRequestJson, runRiddleScript };
102
+ export { DEFAULT_RIDDLE_API_BASE_URL, DEFAULT_RIDDLE_API_KEY_FILE, RiddleApiError, type RiddleClientConfig, type RiddleFetch, type RiddlePollJobResult, type RiddlePreviewDeployResult, type RiddleRunScriptInput, type RiddleServerPreviewInput, type RiddleServerPreviewResult, createRiddleApiClient, deployRiddleStaticPreview, isTerminalRiddleJobStatus, parseRiddleViewport, pollRiddleJob, resolveRiddleApiKey, riddleRequestJson, runRiddleScript, runRiddleServerPreview };
@@ -29,6 +29,27 @@ interface RiddleRunScriptInput {
29
29
  include?: string[];
30
30
  options?: Record<string, unknown>;
31
31
  }
32
+ interface RiddleServerPreviewInput {
33
+ directory: string;
34
+ script: string;
35
+ image?: string;
36
+ command?: string;
37
+ port?: number;
38
+ path?: string;
39
+ readinessPath?: string;
40
+ readinessTimeoutSec?: number;
41
+ waitForSelector?: string;
42
+ waitUntil?: "commit" | "domcontentloaded" | "load" | "networkidle";
43
+ navigationTimeoutSec?: number;
44
+ viewport?: {
45
+ width: number;
46
+ height: number;
47
+ };
48
+ timeoutSec?: number;
49
+ pollAttempts?: number;
50
+ pollIntervalMs?: number;
51
+ exclude?: string[];
52
+ }
32
53
  interface RiddlePollJobResult {
33
54
  ok: boolean;
34
55
  job_id: string;
@@ -37,6 +58,14 @@ interface RiddlePollJobResult {
37
58
  job: Record<string, unknown> | null;
38
59
  artifacts?: Record<string, unknown> | null;
39
60
  }
61
+ interface RiddleServerPreviewResult {
62
+ ok: boolean;
63
+ job_id: string;
64
+ status: string | null;
65
+ terminal: boolean;
66
+ script_error: string | null;
67
+ job: Record<string, unknown> | null;
68
+ }
40
69
  declare class RiddleApiError extends Error {
41
70
  readonly status: number;
42
71
  readonly body: string;
@@ -50,6 +79,7 @@ declare function parseRiddleViewport(value?: string): {
50
79
  width: number;
51
80
  height: number;
52
81
  } | undefined;
82
+ declare function runRiddleServerPreview(config: RiddleClientConfig, input: RiddleServerPreviewInput): Promise<RiddleServerPreviewResult>;
53
83
  declare function runRiddleScript(config: RiddleClientConfig, input: RiddleRunScriptInput): Promise<Record<string, unknown>>;
54
84
  declare function isTerminalRiddleJobStatus(status: unknown): boolean;
55
85
  declare function pollRiddleJob(config: RiddleClientConfig, jobId: string, options?: {
@@ -61,6 +91,7 @@ declare function createRiddleApiClient(config?: RiddleClientConfig): {
61
91
  requestJson: <T = unknown>(pathname: string, init?: RequestInit) => Promise<T>;
62
92
  deployStaticPreview: (directory: string, label: string) => Promise<RiddlePreviewDeployResult>;
63
93
  runScript: (input: RiddleRunScriptInput) => Promise<Record<string, unknown>>;
94
+ runServerPreview: (input: RiddleServerPreviewInput) => Promise<RiddleServerPreviewResult>;
64
95
  pollJob: (jobId: string, options?: {
65
96
  wait?: boolean;
66
97
  attempts?: number;
@@ -68,4 +99,4 @@ declare function createRiddleApiClient(config?: RiddleClientConfig): {
68
99
  }) => Promise<RiddlePollJobResult>;
69
100
  };
70
101
 
71
- export { DEFAULT_RIDDLE_API_BASE_URL, DEFAULT_RIDDLE_API_KEY_FILE, RiddleApiError, type RiddleClientConfig, type RiddleFetch, type RiddlePollJobResult, type RiddlePreviewDeployResult, type RiddleRunScriptInput, createRiddleApiClient, deployRiddleStaticPreview, isTerminalRiddleJobStatus, parseRiddleViewport, pollRiddleJob, resolveRiddleApiKey, riddleRequestJson, runRiddleScript };
102
+ export { DEFAULT_RIDDLE_API_BASE_URL, DEFAULT_RIDDLE_API_KEY_FILE, RiddleApiError, type RiddleClientConfig, type RiddleFetch, type RiddlePollJobResult, type RiddlePreviewDeployResult, type RiddleRunScriptInput, type RiddleServerPreviewInput, type RiddleServerPreviewResult, createRiddleApiClient, deployRiddleStaticPreview, isTerminalRiddleJobStatus, parseRiddleViewport, pollRiddleJob, resolveRiddleApiKey, riddleRequestJson, runRiddleScript, runRiddleServerPreview };
@@ -9,8 +9,9 @@ import {
9
9
  pollRiddleJob,
10
10
  resolveRiddleApiKey,
11
11
  riddleRequestJson,
12
- runRiddleScript
13
- } from "./chunk-UR6ADV4Y.js";
12
+ runRiddleScript,
13
+ runRiddleServerPreview
14
+ } from "./chunk-3CVGVQTQ.js";
14
15
  export {
15
16
  DEFAULT_RIDDLE_API_BASE_URL,
16
17
  DEFAULT_RIDDLE_API_KEY_FILE,
@@ -22,5 +23,6 @@ export {
22
23
  pollRiddleJob,
23
24
  resolveRiddleApiKey,
24
25
  riddleRequestJson,
25
- runRiddleScript
26
+ runRiddleScript,
27
+ runRiddleServerPreview
26
28
  };
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@riddledc/riddle-proof",
3
- "version": "0.5.55",
3
+ "version": "0.5.56",
4
4
  "description": "Reusable Riddle Proof contracts and helpers for evidence-backed agent changes.",
5
5
  "license": "MIT",
6
6
  "author": "RiddleDC",