@riddledc/riddle-proof 0.5.57 → 0.7.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/cli.js CHANGED
@@ -1,4 +1,15 @@
1
1
  #!/usr/bin/env node
2
+ import {
3
+ assessRiddleProofProfileEvidence,
4
+ buildRiddleProofProfileScript,
5
+ collectRiddleProfileArtifactRefs,
6
+ createRiddleProofProfileEnvironmentBlockedResult,
7
+ createRiddleProofProfileInsufficientResult,
8
+ extractRiddleProofProfileResult,
9
+ normalizeRiddleProofProfile,
10
+ profileStatusExitCode,
11
+ resolveRiddleProofProfileTargetUrl
12
+ } from "./chunk-7NMAU4DP.js";
2
13
  import {
3
14
  createRiddleApiClient,
4
15
  parseRiddleViewport
@@ -7,10 +18,10 @@ import {
7
18
  createDisabledRiddleProofAgentAdapter,
8
19
  readRiddleProofRunStatus,
9
20
  runRiddleProofEngineHarness
10
- } from "./chunk-2FBF2UDZ.js";
21
+ } from "./chunk-D3M2FAYQ.js";
11
22
  import "./chunk-MO24D3PY.js";
12
- import "./chunk-RFJ5BQF6.js";
13
23
  import "./chunk-3UHWI3FO.js";
24
+ import "./chunk-RFJ5BQF6.js";
14
25
  import {
15
26
  createCheckpointResponseTemplate
16
27
  } from "./chunk-33XO42CY.js";
@@ -22,7 +33,8 @@ import {
22
33
  import "./chunk-DUFDZJOF.js";
23
34
 
24
35
  // src/cli.ts
25
- import { existsSync, readFileSync } from "fs";
36
+ import { existsSync, mkdirSync, readFileSync, writeFileSync } from "fs";
37
+ import path from "path";
26
38
  function usage() {
27
39
  return [
28
40
  "Usage:",
@@ -31,6 +43,7 @@ function usage() {
31
43
  " riddle-proof-loop respond --state-path <path> --response-json <file|json|->",
32
44
  " riddle-proof-loop respond --state-path <path> --decision <decision> --summary <text> [--payload-json <file|json|->]",
33
45
  " riddle-proof-loop status --state-path <path>",
46
+ " riddle-proof-loop run-profile --profile <file|json|-> --url <base-url> [--runner riddle] [--output <dir>]",
34
47
  " riddle-proof-loop riddle-preview-deploy <build-dir> <label>",
35
48
  " riddle-proof-loop riddle-server-preview <directory> --script-file <file> [--path /route] [--wait-for-selector selector]",
36
49
  " riddle-proof-loop riddle-run-script --url <url> --script-file <file> [--viewport 1280x720]",
@@ -222,6 +235,173 @@ function riddleClientConfig(options) {
222
235
  apiBaseUrl: optionString(options, "apiBaseUrl")
223
236
  };
224
237
  }
238
+ function parseProfileViewports(value) {
239
+ if (!value) return void 0;
240
+ return value.split(",").map((part, index) => {
241
+ const trimmed = part.trim();
242
+ const named = /^([a-zA-Z0-9_-]+)=(\d+x\d+)$/.exec(trimmed);
243
+ const viewport = parseRiddleViewport(named ? named[2] : trimmed);
244
+ if (!viewport) throw new Error(`Invalid viewport ${trimmed}.`);
245
+ return {
246
+ name: named ? named[1] : `viewport-${index + 1}`,
247
+ width: viewport.width,
248
+ height: viewport.height
249
+ };
250
+ });
251
+ }
252
+ function normalizeProfileForCli(options) {
253
+ const rawProfile = readJsonValue(optionString(options, "profile"), "--profile");
254
+ return normalizeRiddleProofProfile(rawProfile, {
255
+ url: optionString(options, "url"),
256
+ route: optionString(options, "route"),
257
+ viewports: parseProfileViewports(optionString(options, "viewports") || optionString(options, "viewport"))
258
+ });
259
+ }
260
+ function profileResultMarkdown(result) {
261
+ const lines = [
262
+ `# Riddle Proof Profile: ${result.profile_name}`,
263
+ "",
264
+ `Status: ${result.status}`,
265
+ `Runner: ${result.runner}`,
266
+ `Captured: ${result.captured_at}`,
267
+ "",
268
+ result.summary,
269
+ "",
270
+ "## Checks",
271
+ ""
272
+ ];
273
+ for (const check of result.checks) {
274
+ lines.push(`- ${check.status}: ${check.label || check.type}`);
275
+ if (check.message) lines.push(` ${check.message}`);
276
+ }
277
+ if (result.artifacts.riddle_artifacts?.length) {
278
+ lines.push("", "## Riddle Artifacts", "");
279
+ for (const artifact of result.artifacts.riddle_artifacts.slice(0, 40)) {
280
+ lines.push(`- ${artifact.name || artifact.kind || "artifact"}${artifact.url ? `: ${artifact.url}` : ""}`);
281
+ }
282
+ }
283
+ return `${lines.join("\n")}
284
+ `;
285
+ }
286
+ function writeProfileOutput(outputDir, result) {
287
+ if (!outputDir) return;
288
+ mkdirSync(outputDir, { recursive: true });
289
+ writeFileSync(path.join(outputDir, "profile-result.json"), `${JSON.stringify(result, null, 2)}
290
+ `);
291
+ writeFileSync(path.join(outputDir, "summary.md"), profileResultMarkdown(result));
292
+ if (result.evidence) writeFileSync(path.join(outputDir, "proof.json"), `${JSON.stringify(result, null, 2)}
293
+ `);
294
+ if (result.evidence?.console) writeFileSync(path.join(outputDir, "console.json"), `${JSON.stringify(result.evidence.console, null, 2)}
295
+ `);
296
+ if (result.evidence?.dom_summary) writeFileSync(path.join(outputDir, "dom-summary.json"), `${JSON.stringify(result.evidence.dom_summary, null, 2)}
297
+ `);
298
+ }
299
+ async function readArtifactJson(artifact) {
300
+ const target = artifact.url || artifact.path;
301
+ if (!target) return void 0;
302
+ try {
303
+ const raw = artifact.url ? await (await fetch(artifact.url)).text() : existsSync(target) ? readFileSync(target, "utf-8") : "";
304
+ if (!raw.trim()) return void 0;
305
+ const parsed = JSON.parse(raw);
306
+ return parsed && typeof parsed === "object" && !Array.isArray(parsed) ? parsed : void 0;
307
+ } catch {
308
+ return void 0;
309
+ }
310
+ }
311
+ async function profileResultFromRiddleArtifacts(profile, artifacts, fallbackInputs) {
312
+ for (const input of fallbackInputs) {
313
+ const result = extractRiddleProofProfileResult(input);
314
+ if (result) return result;
315
+ }
316
+ const proofArtifacts = artifacts.filter((artifact) => /(^|\/)proof\.json(?:\.json)?$/i.test(artifact.name || artifact.url || artifact.path || "")).sort((left, right) => {
317
+ const leftName = left.name || left.url || left.path || "";
318
+ const rightName = right.name || right.url || right.path || "";
319
+ return Number(/proof\.json\.json$/i.test(rightName)) - Number(/proof\.json\.json$/i.test(leftName));
320
+ });
321
+ for (const artifact of proofArtifacts) {
322
+ const parsed = await readArtifactJson(artifact);
323
+ const result = extractRiddleProofProfileResult(parsed);
324
+ if (result) return result;
325
+ }
326
+ const evidenceArtifacts = artifacts.filter((artifact) => /profile-evidence|evidence\.json/i.test(artifact.name || artifact.url || artifact.path || ""));
327
+ for (const artifact of evidenceArtifacts) {
328
+ const parsed = await readArtifactJson(artifact);
329
+ if (parsed?.version === "riddle-proof.profile-evidence.v1") {
330
+ return assessRiddleProofProfileEvidence(profile, parsed, { artifacts });
331
+ }
332
+ }
333
+ return void 0;
334
+ }
335
+ function withRiddleMetadata(result, input) {
336
+ return {
337
+ ...result,
338
+ riddle: {
339
+ ...result.riddle || {},
340
+ job_id: input.job_id || result.riddle?.job_id,
341
+ status: input.status ?? result.riddle?.status,
342
+ terminal: input.terminal ?? result.riddle?.terminal
343
+ },
344
+ artifacts: {
345
+ ...result.artifacts,
346
+ riddle_artifacts: input.artifacts || result.artifacts.riddle_artifacts
347
+ }
348
+ };
349
+ }
350
+ async function runProfileForCli(profile, options) {
351
+ const runner = optionString(options, "runner") || "riddle";
352
+ if (runner !== "riddle") {
353
+ throw new Error(`Unsupported --runner ${runner}. The current CLI supports --runner riddle.`);
354
+ }
355
+ const targetUrl = resolveRiddleProofProfileTargetUrl(profile);
356
+ const client = createRiddleApiClient(riddleClientConfig(options));
357
+ let created;
358
+ try {
359
+ created = await client.runScript({
360
+ url: targetUrl,
361
+ script: buildRiddleProofProfileScript(profile),
362
+ viewport: profile.target.viewports[0],
363
+ timeoutSec: optionString(options, "timeout") ? Number(optionString(options, "timeout")) : void 0,
364
+ sync: options.sync === true ? true : void 0
365
+ });
366
+ } catch (error) {
367
+ return createRiddleProofProfileEnvironmentBlockedResult({ profile, runner, error });
368
+ }
369
+ const jobId = typeof created.job_id === "string" ? created.job_id : typeof created.id === "string" ? created.id : "";
370
+ if (!jobId) {
371
+ const directResult = extractRiddleProofProfileResult(created);
372
+ return directResult ? withRiddleMetadata(directResult, { artifacts: collectRiddleProfileArtifactRefs(created) }) : createRiddleProofProfileInsufficientResult({ profile, runner, error: "Riddle run response was missing job_id.", artifacts: collectRiddleProfileArtifactRefs(created) });
373
+ }
374
+ const poll = await client.pollJob(jobId, {
375
+ wait: true,
376
+ attempts: optionString(options, "attempts") ? Number(optionString(options, "attempts")) : void 0,
377
+ intervalMs: optionString(options, "intervalMs") ? Number(optionString(options, "intervalMs")) : void 0
378
+ });
379
+ const artifacts = collectRiddleProfileArtifactRefs(poll.artifacts);
380
+ if (!poll.ok || !poll.terminal) {
381
+ return createRiddleProofProfileEnvironmentBlockedResult({
382
+ profile,
383
+ runner,
384
+ error: `Riddle job ${jobId} ended with status ${poll.status || "unknown"}.`,
385
+ riddle: { job_id: jobId, status: poll.status, terminal: poll.terminal },
386
+ artifacts
387
+ });
388
+ }
389
+ const artifactResult = await profileResultFromRiddleArtifacts(profile, artifacts, [poll.job, poll.artifacts, created]);
390
+ if (!artifactResult) {
391
+ return createRiddleProofProfileInsufficientResult({
392
+ profile,
393
+ runner,
394
+ riddle: { job_id: jobId, status: poll.status, terminal: poll.terminal },
395
+ artifacts
396
+ });
397
+ }
398
+ return withRiddleMetadata(artifactResult, {
399
+ job_id: jobId,
400
+ status: poll.status,
401
+ terminal: poll.terminal,
402
+ artifacts
403
+ });
404
+ }
225
405
  function requestForRun(options) {
226
406
  const statePath = optionString(options, "statePath");
227
407
  const withEngineModuleUrl = (request) => {
@@ -268,6 +448,15 @@ async function main() {
268
448
  `);
269
449
  return;
270
450
  }
451
+ if (command === "run-profile") {
452
+ const profile = normalizeProfileForCli(options);
453
+ const result = await runProfileForCli(profile, options);
454
+ writeProfileOutput(optionString(options, "output"), result);
455
+ process.stdout.write(`${JSON.stringify(result, null, 2)}
456
+ `);
457
+ process.exitCode = profileStatusExitCode(profile, result.status);
458
+ return;
459
+ }
271
460
  if (command === "riddle-preview-deploy") {
272
461
  const buildDir = positional[1];
273
462
  const label = positional[2];
@@ -2,10 +2,10 @@ import {
2
2
  createDisabledRiddleProofAgentAdapter,
3
3
  readRiddleProofRunStatus,
4
4
  runRiddleProofEngineHarness
5
- } from "./chunk-2FBF2UDZ.js";
5
+ } from "./chunk-D3M2FAYQ.js";
6
6
  import "./chunk-MO24D3PY.js";
7
- import "./chunk-RFJ5BQF6.js";
8
7
  import "./chunk-3UHWI3FO.js";
8
+ import "./chunk-RFJ5BQF6.js";
9
9
  import "./chunk-33XO42CY.js";
10
10
  import "./chunk-DUFDZJOF.js";
11
11
  export {