@riddledc/riddle-proof 0.8.35 → 0.8.37

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/index.cjs CHANGED
@@ -10862,6 +10862,8 @@ function normalizeSetupAction(input, index) {
10862
10862
  expect_changed: booleanValue(valueFromOwn(input, "expect_changed", "expectChanged", "should_change", "shouldChange", "changed")),
10863
10863
  until_path: untilPath,
10864
10864
  until_expected_value: hasUntilExpectedValue ? toJsonValue(valueFromOwn(input, "until_expected_value", "untilExpectedValue", "until_expected", "untilExpected", "until_value", "untilValue", "expected_value", "expectedValue", "expected")) : void 0,
10865
+ expected_path: stringFromOwn(input, "expected_path", "expectedPath", "expected_terminal_path", "expectedTerminalPath"),
10866
+ expected_url: stringFromOwn(input, "expected_url", "expectedUrl", "expected_terminal_url", "expectedTerminalUrl"),
10865
10867
  max_calls: maxCalls,
10866
10868
  tap_burst_size: tapBurstSize,
10867
10869
  settle_ms: settleMs,
@@ -13219,6 +13221,80 @@ function routePathMatches(observed, expected, targetUrl) {
13219
13221
  if (normalizedObserved === normalizedExpected) return true;
13220
13222
  return normalizedObserved === normalizeRoutePath(mountedExpectedRoutePath(targetUrl, expected));
13221
13223
  }
13224
+ function setupActionExpectedRoute(action) {
13225
+ const expectedUrl = typeof action.expected_url === "string" && action.expected_url.trim()
13226
+ ? action.expected_url.trim()
13227
+ : typeof action.expectedUrl === "string" && action.expectedUrl.trim()
13228
+ ? action.expectedUrl.trim()
13229
+ : "";
13230
+ const expectedPath = typeof action.expected_path === "string" && action.expected_path.trim()
13231
+ ? action.expected_path.trim()
13232
+ : typeof action.expectedPath === "string" && action.expectedPath.trim()
13233
+ ? action.expectedPath.trim()
13234
+ : "";
13235
+ if (!expectedUrl && !expectedPath) return null;
13236
+ return { expected_url: expectedUrl || undefined, expected_path: expectedPath || undefined };
13237
+ }
13238
+ function setupUrlMatchesExpectedRoute(href, expected) {
13239
+ if (!expected) return true;
13240
+ let observedUrl;
13241
+ try {
13242
+ observedUrl = new URL(href, targetUrl);
13243
+ } catch {
13244
+ return false;
13245
+ }
13246
+ if (expected.expected_url) {
13247
+ let expectedUrl;
13248
+ try {
13249
+ expectedUrl = new URL(expected.expected_url, targetUrl);
13250
+ } catch {
13251
+ return false;
13252
+ }
13253
+ return observedUrl.href === expectedUrl.href;
13254
+ }
13255
+ const expectedPath = expected.expected_path || "/";
13256
+ if (/[?#]/.test(expectedPath)) {
13257
+ const observedRoute = observedUrl.pathname + observedUrl.search + observedUrl.hash;
13258
+ const normalizedObservedRoute = observedRoute === "/" ? "/" : observedRoute.replace(/\/+(?=[?#]|$)/, "");
13259
+ const normalizedExpectedRoute = expectedPath === "/" ? "/" : expectedPath.replace(/\/+(?=[?#]|$)/, "");
13260
+ return normalizedObservedRoute === normalizedExpectedRoute;
13261
+ }
13262
+ return routePathMatches(observedUrl.pathname, expectedPath, targetUrl);
13263
+ }
13264
+ function setupObservedRouteEvidence(expected, waitError) {
13265
+ let observedUrl = page.url();
13266
+ let observedPath = "";
13267
+ let observedRoute = "";
13268
+ try {
13269
+ const url = new URL(observedUrl, targetUrl);
13270
+ observedUrl = url.href;
13271
+ observedPath = url.pathname;
13272
+ observedRoute = url.pathname + url.search + url.hash;
13273
+ } catch {
13274
+ observedPath = "";
13275
+ observedRoute = "";
13276
+ }
13277
+ return {
13278
+ expected_url: expected && expected.expected_url || undefined,
13279
+ expected_path: expected && expected.expected_path || undefined,
13280
+ observed_url: observedUrl,
13281
+ observed_path: observedPath,
13282
+ observed_route: observedRoute,
13283
+ route_matched: setupUrlMatchesExpectedRoute(observedUrl, expected),
13284
+ route_wait_error: waitError ? String(waitError && waitError.message ? waitError.message : waitError).slice(0, 1000) : undefined,
13285
+ };
13286
+ }
13287
+ async function waitForSetupActionRoute(action, timeout) {
13288
+ const expected = setupActionExpectedRoute(action);
13289
+ if (!expected) return null;
13290
+ let waitError;
13291
+ try {
13292
+ await page.waitForURL((url) => setupUrlMatchesExpectedRoute(url.href, expected), { timeout: Math.min(timeout, 20000) });
13293
+ } catch (error) {
13294
+ waitError = error;
13295
+ }
13296
+ return setupObservedRouteEvidence(expected, waitError);
13297
+ }
13222
13298
  function routeOk(route, targetUrl) {
13223
13299
  return Boolean(route && (route.matched || routePathMatches(route.observed, route.expected_path, targetUrl)) && !route.error && (route.http_status == null || route.http_status < 400));
13224
13300
  }
@@ -16112,11 +16188,22 @@ async function executeSetupAction(action, ordinal, viewport) {
16112
16188
  const prepared = await resolveSetupTapTarget(action, base, scope, timeout);
16113
16189
  if (prepared.result) return prepared.result;
16114
16190
  await dispatchSetupTapPoint(prepared.target.point, prepared.target.pointerType, prepared.target.durationMs);
16191
+ const routeEvidence = await waitForSetupActionRoute(action, timeout);
16192
+ if (routeEvidence && !routeEvidence.route_matched) {
16193
+ return {
16194
+ ...base,
16195
+ ...setupScopeEvidence(scope),
16196
+ ...setupTapTargetEvidence(prepared.target),
16197
+ ...routeEvidence,
16198
+ reason: "expected_route_not_reached",
16199
+ };
16200
+ }
16115
16201
  return {
16116
16202
  ...base,
16117
16203
  ...setupScopeEvidence(scope),
16118
16204
  ok: true,
16119
16205
  ...setupTapTargetEvidence(prepared.target),
16206
+ ...routeEvidence,
16120
16207
  };
16121
16208
  }
16122
16209
  if (type === "tap_until") {
@@ -16977,6 +17064,26 @@ async function executeSetupAction(action, ordinal, viewport) {
16977
17064
  : { x: box.x + box.width / 2, y: box.y + box.height / 2 };
16978
17065
  if (clickCount > 1) await page.mouse.click(fallbackPoint.x, fallbackPoint.y, { clickCount });
16979
17066
  else await page.mouse.click(fallbackPoint.x, fallbackPoint.y);
17067
+ const routeEvidence = await waitForSetupActionRoute(action, timeout);
17068
+ if (routeEvidence && !routeEvidence.route_matched) {
17069
+ return {
17070
+ ...base,
17071
+ ...setupScopeEvidence(scope),
17072
+ count,
17073
+ target_index: targetIndex,
17074
+ text: matchedText,
17075
+ force: action.force === true || undefined,
17076
+ fallback_to_tap: true,
17077
+ input_dispatch: "playwright_mouse",
17078
+ click_error: String(error && error.message ? error.message : error).slice(0, 1000),
17079
+ click_count: clickCount > 1 ? clickCount : undefined,
17080
+ coordinate_mode: mode,
17081
+ x: position ? fromX : undefined,
17082
+ y: position ? fromY : undefined,
17083
+ ...routeEvidence,
17084
+ reason: "expected_route_not_reached",
17085
+ };
17086
+ }
16980
17087
  return {
16981
17088
  ...base,
16982
17089
  ...setupScopeEvidence(scope),
@@ -16992,6 +17099,24 @@ async function executeSetupAction(action, ordinal, viewport) {
16992
17099
  coordinate_mode: mode,
16993
17100
  x: position ? fromX : undefined,
16994
17101
  y: position ? fromY : undefined,
17102
+ ...routeEvidence,
17103
+ };
17104
+ }
17105
+ const routeEvidence = await waitForSetupActionRoute(action, timeout);
17106
+ if (routeEvidence && !routeEvidence.route_matched) {
17107
+ return {
17108
+ ...base,
17109
+ ...setupScopeEvidence(scope),
17110
+ count,
17111
+ target_index: targetIndex,
17112
+ text: matchedText,
17113
+ force: action.force === true || undefined,
17114
+ click_count: clickCount > 1 ? clickCount : undefined,
17115
+ coordinate_mode: mode,
17116
+ x: position ? fromX : undefined,
17117
+ y: position ? fromY : undefined,
17118
+ ...routeEvidence,
17119
+ reason: "expected_route_not_reached",
16995
17120
  };
16996
17121
  }
16997
17122
  return {
@@ -17006,6 +17131,7 @@ async function executeSetupAction(action, ordinal, viewport) {
17006
17131
  coordinate_mode: mode,
17007
17132
  x: position ? fromX : undefined,
17008
17133
  y: position ? fromY : undefined,
17134
+ ...routeEvidence,
17009
17135
  };
17010
17136
  }
17011
17137
  if (type === "fill" || type === "set_input_value") {
@@ -18940,10 +19066,68 @@ function previewDeployResultFromRecord(input) {
18940
19066
  function canRecoverPreviewPublish(error) {
18941
19067
  return error instanceof RiddleApiError && PREVIEW_PUBLISH_RECOVERY_STATUSES.has(error.status);
18942
19068
  }
19069
+ function summarizePreviewDirectory(directory) {
19070
+ const stack = [directory];
19071
+ let fileCount = 0;
19072
+ let totalBytes = 0;
19073
+ while (stack.length) {
19074
+ const current = stack.pop();
19075
+ for (const entry of (0, import_node_fs5.readdirSync)(current, { withFileTypes: true })) {
19076
+ const fullPath = import_node_path5.default.join(current, entry.name);
19077
+ if (entry.isDirectory()) {
19078
+ stack.push(fullPath);
19079
+ continue;
19080
+ }
19081
+ if (!entry.isFile()) continue;
19082
+ const stat = (0, import_node_fs5.statSync)(fullPath);
19083
+ fileCount += 1;
19084
+ totalBytes += stat.size;
19085
+ }
19086
+ }
19087
+ return { file_count: fileCount, total_bytes: totalBytes };
19088
+ }
19089
+ function previewProgressEmitter(config, base) {
19090
+ return async (snapshot) => {
19091
+ if (!config.onPreviewProgress) return;
19092
+ await config.onPreviewProgress({
19093
+ label: base.label,
19094
+ framework: base.framework,
19095
+ directory: base.directory,
19096
+ elapsed_ms: Math.max(0, Date.now() - base.startedAt),
19097
+ warnings: base.warnings?.length ? base.warnings : void 0,
19098
+ ...snapshot
19099
+ });
19100
+ };
19101
+ }
18943
19102
  async function waitForPublishedPreview(config, input) {
19103
+ await input.emitProgress?.({
19104
+ stage: "publish_recovering",
19105
+ id: input.id,
19106
+ file_count: input.localSummary?.file_count,
19107
+ total_bytes: input.localSummary?.total_bytes,
19108
+ publish_error: input.publishError.message,
19109
+ message: `publish returned ${input.publishError.status}; polling preview status`
19110
+ });
18944
19111
  for (let attempt = 1; attempt <= PREVIEW_PUBLISH_RECOVERY_ATTEMPTS; attempt += 1) {
18945
19112
  const status = await riddleRequestJson(config, `/v1/preview/${input.id}`);
19113
+ await input.emitProgress?.({
19114
+ stage: "checking_status",
19115
+ id: input.id,
19116
+ attempt,
19117
+ attempts: PREVIEW_PUBLISH_RECOVERY_ATTEMPTS,
19118
+ status: typeof status.status === "string" ? status.status : null,
19119
+ preview_url: typeof status.preview_url === "string" ? status.preview_url : void 0,
19120
+ file_count: typeof status.file_count === "number" ? status.file_count : input.localSummary?.file_count,
19121
+ total_bytes: typeof status.total_bytes === "number" ? status.total_bytes : input.localSummary?.total_bytes
19122
+ });
18946
19123
  if (String(status.status || "") === "ready" && String(status.preview_url || "").trim()) {
19124
+ await input.emitProgress?.({
19125
+ stage: "ready",
19126
+ id: input.id,
19127
+ preview_url: String(status.preview_url),
19128
+ file_count: typeof status.file_count === "number" ? status.file_count : input.localSummary?.file_count,
19129
+ total_bytes: typeof status.total_bytes === "number" ? status.total_bytes : input.localSummary?.total_bytes
19130
+ });
18947
19131
  return previewDeployResultFromRecord({
18948
19132
  record: status,
18949
19133
  id: input.id,
@@ -18965,7 +19149,17 @@ async function deployRiddlePreview(config, directory, label, framework = "static
18965
19149
  if (!directory?.trim()) throw new Error("directory is required");
18966
19150
  if (!label?.trim()) throw new Error("label is required");
18967
19151
  if (framework !== "spa" && framework !== "static") throw new Error("framework must be spa or static");
19152
+ const startedAt = Date.now();
18968
19153
  const warnings = collectRiddlePreviewDeployWarnings(directory, framework);
19154
+ const emitProgress = previewProgressEmitter(config, { label, framework, directory, startedAt, warnings });
19155
+ await emitProgress({ stage: "validating", message: "checking preview input directory" });
19156
+ const localSummary = summarizePreviewDirectory(directory);
19157
+ await emitProgress({
19158
+ stage: "creating",
19159
+ file_count: localSummary.file_count,
19160
+ total_bytes: localSummary.total_bytes,
19161
+ message: "creating preview upload target"
19162
+ });
18969
19163
  const created = await riddleRequestJson(config, "/v1/preview", {
18970
19164
  method: "POST",
18971
19165
  body: JSON.stringify({ framework, label })
@@ -18973,10 +19167,42 @@ async function deployRiddlePreview(config, directory, label, framework = "static
18973
19167
  const id = String(created.id || "");
18974
19168
  const uploadUrl = String(created.upload_url || "");
18975
19169
  if (!id || !uploadUrl) throw new Error("Riddle preview create response was missing id or upload_url.");
19170
+ await emitProgress({
19171
+ stage: "created",
19172
+ id,
19173
+ file_count: localSummary.file_count,
19174
+ total_bytes: localSummary.total_bytes,
19175
+ message: "preview upload target created"
19176
+ });
18976
19177
  const scratch = (0, import_node_fs5.mkdtempSync)(import_node_path5.default.join((0, import_node_os2.tmpdir)(), "riddle-preview-upload-"));
18977
19178
  const tarball = import_node_path5.default.join(scratch, `${id}.tar.gz`);
19179
+ let tarballBytes = 0;
18978
19180
  try {
19181
+ await emitProgress({
19182
+ stage: "archiving",
19183
+ id,
19184
+ file_count: localSummary.file_count,
19185
+ total_bytes: localSummary.total_bytes,
19186
+ message: "creating preview archive"
19187
+ });
18979
19188
  (0, import_node_child_process4.execFileSync)("tar", ["czf", tarball, "-C", directory, "."], { stdio: "pipe" });
19189
+ tarballBytes = (0, import_node_fs5.statSync)(tarball).size;
19190
+ await emitProgress({
19191
+ stage: "archived",
19192
+ id,
19193
+ file_count: localSummary.file_count,
19194
+ total_bytes: localSummary.total_bytes,
19195
+ tarball_bytes: tarballBytes,
19196
+ message: "preview archive created"
19197
+ });
19198
+ await emitProgress({
19199
+ stage: "uploading",
19200
+ id,
19201
+ file_count: localSummary.file_count,
19202
+ total_bytes: localSummary.total_bytes,
19203
+ tarball_bytes: tarballBytes,
19204
+ message: "uploading preview archive"
19205
+ });
18980
19206
  const upload = await fetchFor(config)(uploadUrl, {
18981
19207
  method: "PUT",
18982
19208
  headers: { "Content-Type": "application/gzip" },
@@ -18985,14 +19211,37 @@ async function deployRiddlePreview(config, directory, label, framework = "static
18985
19211
  if (!upload.ok) {
18986
19212
  throw new RiddleApiError(uploadUrl, upload.status, await upload.text());
18987
19213
  }
19214
+ await emitProgress({
19215
+ stage: "uploaded",
19216
+ id,
19217
+ file_count: localSummary.file_count,
19218
+ total_bytes: localSummary.total_bytes,
19219
+ tarball_bytes: tarballBytes,
19220
+ message: "preview archive uploaded"
19221
+ });
18988
19222
  } finally {
18989
19223
  (0, import_node_fs5.rmSync)(scratch, { recursive: true, force: true });
18990
19224
  }
18991
19225
  const expiresAt = typeof created.expires_at === "string" ? created.expires_at : void 0;
18992
19226
  try {
19227
+ await emitProgress({
19228
+ stage: "publishing",
19229
+ id,
19230
+ file_count: localSummary.file_count,
19231
+ total_bytes: localSummary.total_bytes,
19232
+ tarball_bytes: tarballBytes || void 0,
19233
+ message: "publishing preview"
19234
+ });
18993
19235
  const published = await riddleRequestJson(config, `/v1/preview/${id}/publish`, {
18994
19236
  method: "POST"
18995
19237
  });
19238
+ await emitProgress({
19239
+ stage: "ready",
19240
+ id,
19241
+ preview_url: String(published.preview_url || ""),
19242
+ file_count: typeof published.file_count === "number" ? published.file_count : localSummary.file_count,
19243
+ total_bytes: typeof published.total_bytes === "number" ? published.total_bytes : localSummary.total_bytes
19244
+ });
18996
19245
  return previewDeployResultFromRecord({ record: published, id, label, framework, expiresAt, warnings });
18997
19246
  } catch (error) {
18998
19247
  if (!canRecoverPreviewPublish(error)) throw error;
@@ -19002,7 +19251,9 @@ async function deployRiddlePreview(config, directory, label, framework = "static
19002
19251
  framework,
19003
19252
  expiresAt,
19004
19253
  publishError: error,
19005
- warnings
19254
+ warnings,
19255
+ localSummary,
19256
+ emitProgress
19006
19257
  });
19007
19258
  }
19008
19259
  }
package/dist/index.d.cts CHANGED
@@ -11,4 +11,4 @@ export { BuildVisualProofSessionInput, RIDDLE_PROOF_VISUAL_SESSION_FINGERPRINT_V
11
11
  export { AssessPlayabilityOptions, RIDDLE_PROOF_PLAYABILITY_ASSESSMENT_VERSION, RIDDLE_PROOF_PLAYABILITY_VERSION, RiddleProofPlayabilityAssessment, RiddleProofPlayabilityEvidence, assessPlayabilityEvidence, extractPlayabilityEvidence, isRiddleProofPlayabilityMode } from './playability.cjs';
12
12
  export { AssessBasicGameplayOptions, AttachBasicGameplayArtifactOptions, BASIC_GAMEPLAY_ACTION_TYPES, BASIC_GAMEPLAY_PROGRESS_CHECK_TYPES, BasicGameplayActionResult, BasicGameplayActionType, BasicGameplayArtifactResolution, BasicGameplayAssessmentSummary, BasicGameplayBoundsOffender, BasicGameplayCanvasState, BasicGameplayCatchRecord, BasicGameplayChangeSummary, BasicGameplayFailureCode, BasicGameplayFixReference, BasicGameplayMetric, BasicGameplayMobileEvidence, BasicGameplayProgressCheckType, BasicGameplayProgressionCheck, BasicGameplayProofArtifact, BasicGameplayResponsiveViewportEvidence, BasicGameplayRouteReference, BasicGameplaySnapshot, BasicGameplaySuiteFailure, 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, assessBasicGameplayProgressionCheck, assessBasicGameplayProgressionChecks, assessBasicGameplayRoute, attachBasicGameplayArtifactScreenshotHashes, augmentBasicGameplayAssessmentWithProgressionChecks, compactBasicGameplayText, createBasicGameplayCatchRecords, createBasicGameplayCatchSummary, extractBasicGameplayEvidence, resolveBasicGameplayProgressionCheckWithArtifactScreenshots, sanitizeBasicGameplayJsonString } from './basic-gameplay.cjs';
13
13
  export { NormalizeRiddleProofProfileOptions, RIDDLE_PROOF_PROFILE_CHECK_TYPES, RIDDLE_PROOF_PROFILE_EVIDENCE_VERSION, RIDDLE_PROOF_PROFILE_NETWORK_ABORT_ERROR_CODES, RIDDLE_PROOF_PROFILE_RESULT_VERSION, RIDDLE_PROOF_PROFILE_SETUP_ACTION_TYPES, RIDDLE_PROOF_PROFILE_STATUSES, RIDDLE_PROOF_PROFILE_VERSION, RiddleProofArtifactBodyAssertionInput, RiddleProofArtifactBodyAssertionResult, RiddleProofProfile, RiddleProofProfileArtifactRef, RiddleProofProfileBaselinePolicy, RiddleProofProfileBoundsOffender, RiddleProofProfileCheck, RiddleProofProfileCheckResult, RiddleProofProfileCheckType, RiddleProofProfileEvidence, RiddleProofProfileFailureAction, RiddleProofProfileHttpStatusBodyJsonAssertion, RiddleProofProfileHttpStatusBodyJsonAssertionResult, RiddleProofProfileHttpStatusPreflightCheckResult, RiddleProofProfileHttpStatusPreflightFetch, RiddleProofProfileHttpStatusPreflightFetchResponse, RiddleProofProfileHttpStatusPreflightOptions, RiddleProofProfileHttpStatusPreflightResult, RiddleProofProfileJsonValueType, RiddleProofProfileNetworkAbortErrorCode, RiddleProofProfileNetworkMock, RiddleProofProfileNetworkMockResponse, RiddleProofProfileResult, RiddleProofProfileReturnSummaryField, RiddleProofProfileRouteEvidence, RiddleProofProfileRouteInventoryRoute, RiddleProofProfileRunner, RiddleProofProfileSetupAction, RiddleProofProfileSetupActionType, RiddleProofProfileStatus, RiddleProofProfileTarget, RiddleProofProfileViewport, RiddleProofProfileViewportEvidence, assessRiddleProofProfileEvidence, buildRiddleProofProfileScript, collectRiddleProfileArtifactRefs, collectRiddleProofProfileWarnings, createRiddleProofProfileConfigurationError, createRiddleProofProfileEnvironmentBlockedResult, createRiddleProofProfileInsufficientResult, deriveRiddleProofArtifactBodyAssertions, extractRiddleProofProfileResult, normalizeRiddleProofProfile, preflightRiddleProofProfileHttpStatusChecks, profileStatusExitCode, resolveRiddleProofProfileRouteUrl, resolveRiddleProofProfileTargetUrl, resolveRiddleProofProfileTimeoutSec, slugifyRiddleProofProfileName, summarizeRiddleProofProfileResult } from './profile.cjs';
14
- export { DEFAULT_RIDDLE_API_BASE_URL, DEFAULT_RIDDLE_API_KEY_FILE, RiddleApiError, RiddleApiKeySource, RiddleBalanceResult, RiddleClientConfig, RiddleFetch, RiddlePollJobOptions, RiddlePollJobResult, RiddlePollProgressSnapshot, RiddlePollSummary, RiddlePreviewDeployResult, RiddlePreviewFramework, RiddleRunScriptInput, RiddleServerPreviewInput, RiddleServerPreviewResult, collectRiddlePreviewDeployWarnings, createRiddleApiClient, deployRiddlePreview, deployRiddleStaticPreview, getRiddleBalance, isTerminalRiddleJobStatus, parseRiddleViewport, pollRiddleJob, resolveRiddleApiKey, resolveRiddleApiKeySource, riddleRequestJson, runRiddleScript, runRiddleServerPreview } from './riddle-client.cjs';
14
+ export { DEFAULT_RIDDLE_API_BASE_URL, DEFAULT_RIDDLE_API_KEY_FILE, RiddleApiError, RiddleApiKeySource, RiddleBalanceResult, RiddleClientConfig, RiddleFetch, RiddlePollJobOptions, RiddlePollJobResult, RiddlePollProgressSnapshot, RiddlePollSummary, RiddlePreviewDeployProgressSnapshot, RiddlePreviewDeployResult, RiddlePreviewDeployStage, RiddlePreviewFramework, RiddleRunScriptInput, RiddleServerPreviewInput, RiddleServerPreviewResult, collectRiddlePreviewDeployWarnings, createRiddleApiClient, deployRiddlePreview, deployRiddleStaticPreview, getRiddleBalance, isTerminalRiddleJobStatus, parseRiddleViewport, pollRiddleJob, resolveRiddleApiKey, resolveRiddleApiKeySource, riddleRequestJson, runRiddleScript, runRiddleServerPreview } from './riddle-client.cjs';
package/dist/index.d.ts CHANGED
@@ -11,4 +11,4 @@ export { BuildVisualProofSessionInput, RIDDLE_PROOF_VISUAL_SESSION_FINGERPRINT_V
11
11
  export { AssessPlayabilityOptions, RIDDLE_PROOF_PLAYABILITY_ASSESSMENT_VERSION, RIDDLE_PROOF_PLAYABILITY_VERSION, RiddleProofPlayabilityAssessment, RiddleProofPlayabilityEvidence, assessPlayabilityEvidence, extractPlayabilityEvidence, isRiddleProofPlayabilityMode } from './playability.js';
12
12
  export { AssessBasicGameplayOptions, AttachBasicGameplayArtifactOptions, BASIC_GAMEPLAY_ACTION_TYPES, BASIC_GAMEPLAY_PROGRESS_CHECK_TYPES, BasicGameplayActionResult, BasicGameplayActionType, BasicGameplayArtifactResolution, BasicGameplayAssessmentSummary, BasicGameplayBoundsOffender, BasicGameplayCanvasState, BasicGameplayCatchRecord, BasicGameplayChangeSummary, BasicGameplayFailureCode, BasicGameplayFixReference, BasicGameplayMetric, BasicGameplayMobileEvidence, BasicGameplayProgressCheckType, BasicGameplayProgressionCheck, BasicGameplayProofArtifact, BasicGameplayResponsiveViewportEvidence, BasicGameplayRouteReference, BasicGameplaySnapshot, BasicGameplaySuiteFailure, 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, assessBasicGameplayProgressionCheck, assessBasicGameplayProgressionChecks, assessBasicGameplayRoute, attachBasicGameplayArtifactScreenshotHashes, augmentBasicGameplayAssessmentWithProgressionChecks, compactBasicGameplayText, createBasicGameplayCatchRecords, createBasicGameplayCatchSummary, extractBasicGameplayEvidence, resolveBasicGameplayProgressionCheckWithArtifactScreenshots, sanitizeBasicGameplayJsonString } from './basic-gameplay.js';
13
13
  export { NormalizeRiddleProofProfileOptions, RIDDLE_PROOF_PROFILE_CHECK_TYPES, RIDDLE_PROOF_PROFILE_EVIDENCE_VERSION, RIDDLE_PROOF_PROFILE_NETWORK_ABORT_ERROR_CODES, RIDDLE_PROOF_PROFILE_RESULT_VERSION, RIDDLE_PROOF_PROFILE_SETUP_ACTION_TYPES, RIDDLE_PROOF_PROFILE_STATUSES, RIDDLE_PROOF_PROFILE_VERSION, RiddleProofArtifactBodyAssertionInput, RiddleProofArtifactBodyAssertionResult, RiddleProofProfile, RiddleProofProfileArtifactRef, RiddleProofProfileBaselinePolicy, RiddleProofProfileBoundsOffender, RiddleProofProfileCheck, RiddleProofProfileCheckResult, RiddleProofProfileCheckType, RiddleProofProfileEvidence, RiddleProofProfileFailureAction, RiddleProofProfileHttpStatusBodyJsonAssertion, RiddleProofProfileHttpStatusBodyJsonAssertionResult, RiddleProofProfileHttpStatusPreflightCheckResult, RiddleProofProfileHttpStatusPreflightFetch, RiddleProofProfileHttpStatusPreflightFetchResponse, RiddleProofProfileHttpStatusPreflightOptions, RiddleProofProfileHttpStatusPreflightResult, RiddleProofProfileJsonValueType, RiddleProofProfileNetworkAbortErrorCode, RiddleProofProfileNetworkMock, RiddleProofProfileNetworkMockResponse, RiddleProofProfileResult, RiddleProofProfileReturnSummaryField, RiddleProofProfileRouteEvidence, RiddleProofProfileRouteInventoryRoute, RiddleProofProfileRunner, RiddleProofProfileSetupAction, RiddleProofProfileSetupActionType, RiddleProofProfileStatus, RiddleProofProfileTarget, RiddleProofProfileViewport, RiddleProofProfileViewportEvidence, assessRiddleProofProfileEvidence, buildRiddleProofProfileScript, collectRiddleProfileArtifactRefs, collectRiddleProofProfileWarnings, createRiddleProofProfileConfigurationError, createRiddleProofProfileEnvironmentBlockedResult, createRiddleProofProfileInsufficientResult, deriveRiddleProofArtifactBodyAssertions, extractRiddleProofProfileResult, normalizeRiddleProofProfile, preflightRiddleProofProfileHttpStatusChecks, profileStatusExitCode, resolveRiddleProofProfileRouteUrl, resolveRiddleProofProfileTargetUrl, resolveRiddleProofProfileTimeoutSec, slugifyRiddleProofProfileName, summarizeRiddleProofProfileResult } from './profile.js';
14
- export { DEFAULT_RIDDLE_API_BASE_URL, DEFAULT_RIDDLE_API_KEY_FILE, RiddleApiError, RiddleApiKeySource, RiddleBalanceResult, RiddleClientConfig, RiddleFetch, RiddlePollJobOptions, RiddlePollJobResult, RiddlePollProgressSnapshot, RiddlePollSummary, RiddlePreviewDeployResult, RiddlePreviewFramework, RiddleRunScriptInput, RiddleServerPreviewInput, RiddleServerPreviewResult, collectRiddlePreviewDeployWarnings, createRiddleApiClient, deployRiddlePreview, deployRiddleStaticPreview, getRiddleBalance, isTerminalRiddleJobStatus, parseRiddleViewport, pollRiddleJob, resolveRiddleApiKey, resolveRiddleApiKeySource, riddleRequestJson, runRiddleScript, runRiddleServerPreview } from './riddle-client.js';
14
+ export { DEFAULT_RIDDLE_API_BASE_URL, DEFAULT_RIDDLE_API_KEY_FILE, RiddleApiError, RiddleApiKeySource, RiddleBalanceResult, RiddleClientConfig, RiddleFetch, RiddlePollJobOptions, RiddlePollJobResult, RiddlePollProgressSnapshot, RiddlePollSummary, RiddlePreviewDeployProgressSnapshot, RiddlePreviewDeployResult, RiddlePreviewDeployStage, RiddlePreviewFramework, RiddleRunScriptInput, RiddleServerPreviewInput, RiddleServerPreviewResult, collectRiddlePreviewDeployWarnings, createRiddleApiClient, deployRiddlePreview, deployRiddleStaticPreview, getRiddleBalance, isTerminalRiddleJobStatus, parseRiddleViewport, pollRiddleJob, resolveRiddleApiKey, resolveRiddleApiKeySource, riddleRequestJson, runRiddleScript, runRiddleServerPreview } from './riddle-client.js';
package/dist/index.js CHANGED
@@ -62,7 +62,7 @@ import {
62
62
  resolveRiddleProofProfileTimeoutSec,
63
63
  slugifyRiddleProofProfileName,
64
64
  summarizeRiddleProofProfileResult
65
- } from "./chunk-PEWAIEER.js";
65
+ } from "./chunk-Z2LCVROU.js";
66
66
  import {
67
67
  DEFAULT_RIDDLE_API_BASE_URL,
68
68
  DEFAULT_RIDDLE_API_KEY_FILE,
@@ -80,7 +80,7 @@ import {
80
80
  riddleRequestJson,
81
81
  runRiddleScript,
82
82
  runRiddleServerPreview
83
- } from "./chunk-TWTEUS7R.js";
83
+ } from "./chunk-DI2XNGEZ.js";
84
84
  import {
85
85
  DEFAULT_DIAGNOSTIC_ARRAY_LIMIT,
86
86
  DEFAULT_DIAGNOSTIC_HISTORY_LIMIT,
@@ -1380,6 +1380,8 @@ function normalizeSetupAction(input, index) {
1380
1380
  expect_changed: booleanValue(valueFromOwn(input, "expect_changed", "expectChanged", "should_change", "shouldChange", "changed")),
1381
1381
  until_path: untilPath,
1382
1382
  until_expected_value: hasUntilExpectedValue ? toJsonValue(valueFromOwn(input, "until_expected_value", "untilExpectedValue", "until_expected", "untilExpected", "until_value", "untilValue", "expected_value", "expectedValue", "expected")) : void 0,
1383
+ expected_path: stringFromOwn(input, "expected_path", "expectedPath", "expected_terminal_path", "expectedTerminalPath"),
1384
+ expected_url: stringFromOwn(input, "expected_url", "expectedUrl", "expected_terminal_url", "expectedTerminalUrl"),
1383
1385
  max_calls: maxCalls,
1384
1386
  tap_burst_size: tapBurstSize,
1385
1387
  settle_ms: settleMs,
@@ -3737,6 +3739,80 @@ function routePathMatches(observed, expected, targetUrl) {
3737
3739
  if (normalizedObserved === normalizedExpected) return true;
3738
3740
  return normalizedObserved === normalizeRoutePath(mountedExpectedRoutePath(targetUrl, expected));
3739
3741
  }
3742
+ function setupActionExpectedRoute(action) {
3743
+ const expectedUrl = typeof action.expected_url === "string" && action.expected_url.trim()
3744
+ ? action.expected_url.trim()
3745
+ : typeof action.expectedUrl === "string" && action.expectedUrl.trim()
3746
+ ? action.expectedUrl.trim()
3747
+ : "";
3748
+ const expectedPath = typeof action.expected_path === "string" && action.expected_path.trim()
3749
+ ? action.expected_path.trim()
3750
+ : typeof action.expectedPath === "string" && action.expectedPath.trim()
3751
+ ? action.expectedPath.trim()
3752
+ : "";
3753
+ if (!expectedUrl && !expectedPath) return null;
3754
+ return { expected_url: expectedUrl || undefined, expected_path: expectedPath || undefined };
3755
+ }
3756
+ function setupUrlMatchesExpectedRoute(href, expected) {
3757
+ if (!expected) return true;
3758
+ let observedUrl;
3759
+ try {
3760
+ observedUrl = new URL(href, targetUrl);
3761
+ } catch {
3762
+ return false;
3763
+ }
3764
+ if (expected.expected_url) {
3765
+ let expectedUrl;
3766
+ try {
3767
+ expectedUrl = new URL(expected.expected_url, targetUrl);
3768
+ } catch {
3769
+ return false;
3770
+ }
3771
+ return observedUrl.href === expectedUrl.href;
3772
+ }
3773
+ const expectedPath = expected.expected_path || "/";
3774
+ if (/[?#]/.test(expectedPath)) {
3775
+ const observedRoute = observedUrl.pathname + observedUrl.search + observedUrl.hash;
3776
+ const normalizedObservedRoute = observedRoute === "/" ? "/" : observedRoute.replace(/\/+(?=[?#]|$)/, "");
3777
+ const normalizedExpectedRoute = expectedPath === "/" ? "/" : expectedPath.replace(/\/+(?=[?#]|$)/, "");
3778
+ return normalizedObservedRoute === normalizedExpectedRoute;
3779
+ }
3780
+ return routePathMatches(observedUrl.pathname, expectedPath, targetUrl);
3781
+ }
3782
+ function setupObservedRouteEvidence(expected, waitError) {
3783
+ let observedUrl = page.url();
3784
+ let observedPath = "";
3785
+ let observedRoute = "";
3786
+ try {
3787
+ const url = new URL(observedUrl, targetUrl);
3788
+ observedUrl = url.href;
3789
+ observedPath = url.pathname;
3790
+ observedRoute = url.pathname + url.search + url.hash;
3791
+ } catch {
3792
+ observedPath = "";
3793
+ observedRoute = "";
3794
+ }
3795
+ return {
3796
+ expected_url: expected && expected.expected_url || undefined,
3797
+ expected_path: expected && expected.expected_path || undefined,
3798
+ observed_url: observedUrl,
3799
+ observed_path: observedPath,
3800
+ observed_route: observedRoute,
3801
+ route_matched: setupUrlMatchesExpectedRoute(observedUrl, expected),
3802
+ route_wait_error: waitError ? String(waitError && waitError.message ? waitError.message : waitError).slice(0, 1000) : undefined,
3803
+ };
3804
+ }
3805
+ async function waitForSetupActionRoute(action, timeout) {
3806
+ const expected = setupActionExpectedRoute(action);
3807
+ if (!expected) return null;
3808
+ let waitError;
3809
+ try {
3810
+ await page.waitForURL((url) => setupUrlMatchesExpectedRoute(url.href, expected), { timeout: Math.min(timeout, 20000) });
3811
+ } catch (error) {
3812
+ waitError = error;
3813
+ }
3814
+ return setupObservedRouteEvidence(expected, waitError);
3815
+ }
3740
3816
  function routeOk(route, targetUrl) {
3741
3817
  return Boolean(route && (route.matched || routePathMatches(route.observed, route.expected_path, targetUrl)) && !route.error && (route.http_status == null || route.http_status < 400));
3742
3818
  }
@@ -6630,11 +6706,22 @@ async function executeSetupAction(action, ordinal, viewport) {
6630
6706
  const prepared = await resolveSetupTapTarget(action, base, scope, timeout);
6631
6707
  if (prepared.result) return prepared.result;
6632
6708
  await dispatchSetupTapPoint(prepared.target.point, prepared.target.pointerType, prepared.target.durationMs);
6709
+ const routeEvidence = await waitForSetupActionRoute(action, timeout);
6710
+ if (routeEvidence && !routeEvidence.route_matched) {
6711
+ return {
6712
+ ...base,
6713
+ ...setupScopeEvidence(scope),
6714
+ ...setupTapTargetEvidence(prepared.target),
6715
+ ...routeEvidence,
6716
+ reason: "expected_route_not_reached",
6717
+ };
6718
+ }
6633
6719
  return {
6634
6720
  ...base,
6635
6721
  ...setupScopeEvidence(scope),
6636
6722
  ok: true,
6637
6723
  ...setupTapTargetEvidence(prepared.target),
6724
+ ...routeEvidence,
6638
6725
  };
6639
6726
  }
6640
6727
  if (type === "tap_until") {
@@ -7495,6 +7582,26 @@ async function executeSetupAction(action, ordinal, viewport) {
7495
7582
  : { x: box.x + box.width / 2, y: box.y + box.height / 2 };
7496
7583
  if (clickCount > 1) await page.mouse.click(fallbackPoint.x, fallbackPoint.y, { clickCount });
7497
7584
  else await page.mouse.click(fallbackPoint.x, fallbackPoint.y);
7585
+ const routeEvidence = await waitForSetupActionRoute(action, timeout);
7586
+ if (routeEvidence && !routeEvidence.route_matched) {
7587
+ return {
7588
+ ...base,
7589
+ ...setupScopeEvidence(scope),
7590
+ count,
7591
+ target_index: targetIndex,
7592
+ text: matchedText,
7593
+ force: action.force === true || undefined,
7594
+ fallback_to_tap: true,
7595
+ input_dispatch: "playwright_mouse",
7596
+ click_error: String(error && error.message ? error.message : error).slice(0, 1000),
7597
+ click_count: clickCount > 1 ? clickCount : undefined,
7598
+ coordinate_mode: mode,
7599
+ x: position ? fromX : undefined,
7600
+ y: position ? fromY : undefined,
7601
+ ...routeEvidence,
7602
+ reason: "expected_route_not_reached",
7603
+ };
7604
+ }
7498
7605
  return {
7499
7606
  ...base,
7500
7607
  ...setupScopeEvidence(scope),
@@ -7510,6 +7617,24 @@ async function executeSetupAction(action, ordinal, viewport) {
7510
7617
  coordinate_mode: mode,
7511
7618
  x: position ? fromX : undefined,
7512
7619
  y: position ? fromY : undefined,
7620
+ ...routeEvidence,
7621
+ };
7622
+ }
7623
+ const routeEvidence = await waitForSetupActionRoute(action, timeout);
7624
+ if (routeEvidence && !routeEvidence.route_matched) {
7625
+ return {
7626
+ ...base,
7627
+ ...setupScopeEvidence(scope),
7628
+ count,
7629
+ target_index: targetIndex,
7630
+ text: matchedText,
7631
+ force: action.force === true || undefined,
7632
+ click_count: clickCount > 1 ? clickCount : undefined,
7633
+ coordinate_mode: mode,
7634
+ x: position ? fromX : undefined,
7635
+ y: position ? fromY : undefined,
7636
+ ...routeEvidence,
7637
+ reason: "expected_route_not_reached",
7513
7638
  };
7514
7639
  }
7515
7640
  return {
@@ -7524,6 +7649,7 @@ async function executeSetupAction(action, ordinal, viewport) {
7524
7649
  coordinate_mode: mode,
7525
7650
  x: position ? fromX : undefined,
7526
7651
  y: position ? fromY : undefined,
7652
+ ...routeEvidence,
7527
7653
  };
7528
7654
  }
7529
7655
  if (type === "fill" || type === "set_input_value") {
@@ -23,7 +23,7 @@ import {
23
23
  resolveRiddleProofProfileTimeoutSec,
24
24
  slugifyRiddleProofProfileName,
25
25
  summarizeRiddleProofProfileResult
26
- } from "../chunk-PEWAIEER.js";
26
+ } from "../chunk-Z2LCVROU.js";
27
27
  import "../chunk-MLKGABMK.js";
28
28
  export {
29
29
  RIDDLE_PROOF_PROFILE_CHECK_TYPES,