@riddledc/riddle-proof 0.5.54 → 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.
@@ -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.54",
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",
@@ -79,6 +79,11 @@
79
79
  "import": "./dist/playability.js",
80
80
  "require": "./dist/playability.cjs"
81
81
  },
82
+ "./basic-gameplay": {
83
+ "types": "./dist/basic-gameplay.d.ts",
84
+ "import": "./dist/basic-gameplay.js",
85
+ "require": "./dist/basic-gameplay.cjs"
86
+ },
82
87
  "./openclaw": {
83
88
  "types": "./dist/openclaw.d.ts",
84
89
  "import": "./dist/openclaw.js",
@@ -120,7 +125,7 @@
120
125
  "typescript": "^5.4.5"
121
126
  },
122
127
  "scripts": {
123
- "build": "tsup src/index.ts src/types.ts src/result.ts src/state.ts src/checkpoint.ts src/run-card.ts src/runner.ts src/engine-harness.ts src/codex-exec-agent.ts src/local-agent.ts src/cli.ts src/diagnostics.ts src/proof-session.ts src/playability.ts src/openclaw.ts src/proof-run-core.ts src/proof-run-engine.ts src/riddle-client.ts --format cjs,esm --dts --out-dir dist --clean",
128
+ "build": "tsup src/index.ts src/types.ts src/result.ts src/state.ts src/checkpoint.ts src/run-card.ts src/runner.ts src/engine-harness.ts src/codex-exec-agent.ts src/local-agent.ts src/cli.ts src/diagnostics.ts src/proof-session.ts src/playability.ts src/basic-gameplay.ts src/openclaw.ts src/proof-run-core.ts src/proof-run-engine.ts src/riddle-client.ts --format cjs,esm --dts --out-dir dist --clean",
124
129
  "clean": "rm -rf dist",
125
130
  "lint": "echo 'lint: (not configured)'",
126
131
  "test": "npm run build && node test.js && node proof-run.test.js"
@@ -1,8 +1,3 @@
1
- import {
2
- visualDeltaForState,
3
- visualDeltaRequiredForState,
4
- visualDeltaShipGateReason
5
- } from "./chunk-RFJ5BQF6.js";
6
1
  import {
7
2
  appendRunEvent,
8
3
  appendStageHeartbeat,
@@ -11,6 +6,11 @@ import {
11
6
  normalizeRunParams,
12
7
  setRunStatus
13
8
  } from "./chunk-MO24D3PY.js";
9
+ import {
10
+ visualDeltaForState,
11
+ visualDeltaRequiredForState,
12
+ visualDeltaShipGateReason
13
+ } from "./chunk-RFJ5BQF6.js";
14
14
  import {
15
15
  createRiddleProofRunCard
16
16
  } from "./chunk-3UHWI3FO.js";