@riddledc/riddle-proof 0.7.47 → 0.7.49

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/README.md CHANGED
@@ -237,16 +237,21 @@ where the second request must carry newer state.
237
237
  `target.setup_actions` is optional. Use it when the meaningful proof surface
238
238
  appears only after a picker, tab, login stub, storage seed, form fill,
239
239
  transport control, or other bounded interaction. Supported setup actions are
240
- `click`, `fill`, `set_input_value`, `local_storage`, `session_storage`,
241
- `clear_storage`, `wait`, `wait_for_selector`, and `wait_for_text`; a failed
242
- setup action is recorded as a failed `setup_actions_succeeded` check so the
243
- profile cannot pass without reaching the intended state. Text-matched `click`
244
- actions prefer visible matching elements, which keeps responsive layouts from
245
- selecting hidden desktop or mobile-only links. `local_storage` and
246
- `session_storage` accept a `key` plus string `value` or JSON `json` /
247
- `value_json`, and can reload the page with `reload: true`. `clear_storage`
248
- clears `local`, `session`, or `both` browser storage scopes, defaults to
249
- `both`, and can also reload with `reload: true`.
240
+ `click`, `fill`, `set_input_value`, `assert_text_visible`,
241
+ `assert_text_absent`, `assert_selector_count`, `local_storage`,
242
+ `session_storage`, `clear_storage`, `wait`, `wait_for_selector`, and
243
+ `wait_for_text`; a failed setup action is recorded as a failed
244
+ `setup_actions_succeeded` check so the profile cannot pass without reaching
245
+ the intended state. Text-matched `click` actions prefer visible matching
246
+ elements, which keeps responsive layouts from selecting hidden desktop or
247
+ mobile-only links. Use setup assertions when the pre-click or pre-navigation
248
+ state is part of the contract, for example a fresh row must be present, stale
249
+ copy must be absent, or exactly one source link must exist before clicking into
250
+ the final route. `assert_selector_count` accepts `expected_count`.
251
+ `local_storage` and `session_storage` accept a `key` plus string `value` or
252
+ JSON `json` / `value_json`, and can reload the page with `reload: true`.
253
+ `clear_storage` clears `local`, `session`, or `both` browser storage scopes,
254
+ defaults to `both`, and can also reload with `reload: true`.
250
255
 
251
256
  `target.timeout_sec` is optional. Use it for known-heavy profile targets so the
252
257
  profile carries its own hosted Riddle worker budget; an explicit CLI `--timeout`
@@ -32,6 +32,9 @@ var RIDDLE_PROOF_PROFILE_SETUP_ACTION_TYPES = [
32
32
  "click",
33
33
  "fill",
34
34
  "set_input_value",
35
+ "assert_text_visible",
36
+ "assert_text_absent",
37
+ "assert_selector_count",
35
38
  "local_storage",
36
39
  "session_storage",
37
40
  "clear_storage",
@@ -205,12 +208,19 @@ function normalizeSetupAction(input, index) {
205
208
  if (!isRecord(input)) throw new Error(`target.setup_actions[${index}] must be an object.`);
206
209
  const type = normalizeSetupActionType(stringValue(input.type), index);
207
210
  const selector = stringValue(input.selector);
208
- if ((type === "click" || type === "fill" || type === "set_input_value" || type === "wait_for_selector" || type === "wait_for_text") && !selector) {
211
+ if ((type === "click" || type === "fill" || type === "set_input_value" || type === "wait_for_selector" || type === "wait_for_text" || type === "assert_text_visible" || type === "assert_text_absent" || type === "assert_selector_count") && !selector) {
209
212
  throw new Error(`target.setup_actions[${index}] ${type} requires selector.`);
210
213
  }
211
214
  if (type === "wait_for_text" && !stringValue(input.text) && !stringValue(input.pattern)) {
212
215
  throw new Error(`target.setup_actions[${index}] wait_for_text requires text or pattern.`);
213
216
  }
217
+ if ((type === "assert_text_visible" || type === "assert_text_absent") && !stringValue(input.text) && !stringValue(input.pattern)) {
218
+ throw new Error(`target.setup_actions[${index}] ${type} requires text or pattern.`);
219
+ }
220
+ const expectedCount = numberValue(input.expected_count ?? input.expectedCount ?? input.count);
221
+ if (type === "assert_selector_count" && (expectedCount === void 0 || !Number.isInteger(expectedCount) || expectedCount < 0)) {
222
+ throw new Error(`target.setup_actions[${index}] ${type} requires non-negative integer expected_count.`);
223
+ }
214
224
  const value = stringFromOwn(input, "value", "input_value", "inputValue");
215
225
  const hasJsonValue = hasOwn(input, "value_json") || hasOwn(input, "valueJson") || hasOwn(input, "json");
216
226
  if ((type === "fill" || type === "set_input_value") && value === void 0 && !hasJsonValue) {
@@ -233,6 +243,7 @@ function normalizeSetupAction(input, index) {
233
243
  pattern: stringValue(input.pattern),
234
244
  flags: stringValue(input.flags),
235
245
  index: numberValue(input.index),
246
+ expected_count: expectedCount,
236
247
  ms: numberValue(input.ms) ?? numberValue(input.wait_ms) ?? numberValue(input.waitMs),
237
248
  timeout_ms: numberValue(input.timeout_ms) ?? numberValue(input.timeoutMs),
238
249
  after_ms: numberValue(input.after_ms) ?? numberValue(input.afterMs),
@@ -318,6 +329,7 @@ function normalizeNetworkMockResponsePayload(input, label, defaults = {}) {
318
329
  headers: stringRecord(input.headers) || defaults.headers,
319
330
  body,
320
331
  body_json: hasJsonBody ? toJsonValue(input.body_json ?? input.bodyJson ?? input.json) : defaults.body_json,
332
+ delay_ms: normalizeNetworkMockDelay(input, label, defaults.delay_ms),
321
333
  capture_request_body: requestBody.capture_request_body,
322
334
  request_body_contains: requestBody.request_body_contains,
323
335
  request_body_patterns: requestBody.request_body_patterns,
@@ -325,6 +337,16 @@ function normalizeNetworkMockResponsePayload(input, label, defaults = {}) {
325
337
  request_body_not_patterns: requestBody.request_body_not_patterns
326
338
  };
327
339
  }
340
+ function normalizeNetworkMockDelay(input, label, defaultValue) {
341
+ const value = numberValue(
342
+ input.delay_ms ?? input.delayMs ?? input.wait_ms ?? input.waitMs ?? input.latency_ms ?? input.latencyMs
343
+ ) ?? defaultValue;
344
+ if (value === void 0) return void 0;
345
+ if (!Number.isInteger(value) || value < 0 || value > 6e4) {
346
+ throw new Error(`${label}.delay_ms must be an integer from 0 to 60000.`);
347
+ }
348
+ return value;
349
+ }
328
350
  function normalizeNetworkMockResponses(value, mockIndex, defaults) {
329
351
  if (value === void 0) return void 0;
330
352
  if (!Array.isArray(value)) throw new Error(`target.network_mocks[${mockIndex}].responses must be an array.`);
@@ -335,7 +357,8 @@ function normalizeNetworkMockResponses(value, mockIndex, defaults) {
335
357
  content_type: defaults.content_type,
336
358
  headers: defaults.headers,
337
359
  body: defaults.body,
338
- body_json: defaults.body_json
360
+ body_json: defaults.body_json,
361
+ delay_ms: defaults.delay_ms
339
362
  };
340
363
  return value.map((response, responseIndex) => {
341
364
  if (!isRecord(response)) {
@@ -2034,6 +2057,7 @@ async function registerNetworkMocks(mocks) {
2034
2057
  const requestBody = shouldCaptureRequestBody && request.postData ? request.postData() || "" : "";
2035
2058
  const requestBodyFailures = shouldCaptureRequestBody ? networkMockRequestBodyFailures(requestBody, mock, responseBodyContract) : [];
2036
2059
  const status = response.status || mock.status || 200;
2060
+ const delayMs = numberValue(response.delay_ms) || 0;
2037
2061
  const event = {
2038
2062
  ok: true,
2039
2063
  label: mock.label,
@@ -2046,6 +2070,7 @@ async function registerNetworkMocks(mocks) {
2046
2070
  method,
2047
2071
  status,
2048
2072
  };
2073
+ if (delayMs) event.delay_ms = delayMs;
2049
2074
  if (shouldCaptureRequestBody) {
2050
2075
  event.request_body_matches = requestBodyFailures.length === 0;
2051
2076
  event.request_body_failures = requestBodyFailures;
@@ -2053,6 +2078,7 @@ async function registerNetworkMocks(mocks) {
2053
2078
  event.request_body_sample = compactNetworkMockRequestBody(requestBody);
2054
2079
  }
2055
2080
  networkMockEvents.push(event);
2081
+ if (delayMs) await new Promise((resolve) => setTimeout(resolve, delayMs));
2056
2082
  await route.fulfill({
2057
2083
  status,
2058
2084
  headers,
@@ -2150,6 +2176,19 @@ async function executeSetupAction(action, ordinal) {
2150
2176
  await locator.nth(targetIndex).fill(value, { timeout });
2151
2177
  return { ...base, ok: true, count, target_index: targetIndex, value_length: value.length };
2152
2178
  }
2179
+ if (type === "assert_selector_count") {
2180
+ const locator = page.locator(action.selector);
2181
+ const expectedCount = setupNumber(action.expected_count, -1);
2182
+ if (!Number.isInteger(expectedCount) || expectedCount < 0) return { ...base, reason: "invalid_expected_count", expected_count: action.expected_count };
2183
+ const startedAt = Date.now();
2184
+ let count = 0;
2185
+ while (Date.now() - startedAt <= timeout) {
2186
+ count = await locator.count().catch(() => 0);
2187
+ if (count === expectedCount) return { ...base, ok: true, count, expected_count: expectedCount, timeout_ms: timeout };
2188
+ await page.waitForTimeout(100);
2189
+ }
2190
+ return { ...base, reason: "selector_count_mismatch", count, expected_count: expectedCount, timeout_ms: timeout };
2191
+ }
2153
2192
  if (type === "wait_for_text") {
2154
2193
  const locator = page.locator(action.selector);
2155
2194
  const startedAt = Date.now();
@@ -2167,6 +2206,47 @@ async function executeSetupAction(action, ordinal) {
2167
2206
  }
2168
2207
  return { ...base, reason: "text_not_found", text: compactSetupResultText(lastText), timeout_ms: timeout };
2169
2208
  }
2209
+ if (type === "assert_text_visible" || type === "assert_text_absent") {
2210
+ const locator = page.locator(action.selector);
2211
+ const startedAt = Date.now();
2212
+ let lastText = "";
2213
+ let matchedText = "";
2214
+ let hiddenMatch = false;
2215
+ while (Date.now() - startedAt <= timeout) {
2216
+ const count = await locator.count().catch(() => 0);
2217
+ let matched = false;
2218
+ matchedText = "";
2219
+ hiddenMatch = false;
2220
+ for (let index = 0; index < count; index += 1) {
2221
+ const text = await setupLocatorText(locator, index);
2222
+ lastText = text || lastText;
2223
+ if (setupTextMatches(text, action)) {
2224
+ matched = true;
2225
+ matchedText = text;
2226
+ if (type === "assert_text_visible") {
2227
+ const visible = await setupLocatorVisible(locator, index);
2228
+ if (visible) {
2229
+ return { ...base, ok: true, count, text: compactSetupResultText(text), target_index: index, timeout_ms: timeout };
2230
+ }
2231
+ hiddenMatch = true;
2232
+ break;
2233
+ }
2234
+ break;
2235
+ }
2236
+ }
2237
+ if (type === "assert_text_absent" && !matched) {
2238
+ return { ...base, ok: true, count, timeout_ms: timeout };
2239
+ }
2240
+ await page.waitForTimeout(100);
2241
+ }
2242
+ if (type === "assert_text_visible") {
2243
+ if (hiddenMatch) {
2244
+ return { ...base, reason: "matching_element_not_visible", text: compactSetupResultText(matchedText), timeout_ms: timeout };
2245
+ }
2246
+ return { ...base, reason: "text_not_found", text: compactSetupResultText(lastText), timeout_ms: timeout };
2247
+ }
2248
+ return { ...base, reason: "text_still_present", text: compactSetupResultText(matchedText || lastText), timeout_ms: timeout };
2249
+ }
2170
2250
  return { ...base, reason: "unsupported_action" };
2171
2251
  } catch (error) {
2172
2252
  return { ...base, error: String(error && error.message ? error.message : error).slice(0, 1000) };
package/dist/cli.cjs CHANGED
@@ -6905,6 +6905,9 @@ var RIDDLE_PROOF_PROFILE_SETUP_ACTION_TYPES = [
6905
6905
  "click",
6906
6906
  "fill",
6907
6907
  "set_input_value",
6908
+ "assert_text_visible",
6909
+ "assert_text_absent",
6910
+ "assert_selector_count",
6908
6911
  "local_storage",
6909
6912
  "session_storage",
6910
6913
  "clear_storage",
@@ -7078,12 +7081,19 @@ function normalizeSetupAction(input, index) {
7078
7081
  if (!isRecord(input)) throw new Error(`target.setup_actions[${index}] must be an object.`);
7079
7082
  const type = normalizeSetupActionType(stringValue2(input.type), index);
7080
7083
  const selector = stringValue2(input.selector);
7081
- if ((type === "click" || type === "fill" || type === "set_input_value" || type === "wait_for_selector" || type === "wait_for_text") && !selector) {
7084
+ if ((type === "click" || type === "fill" || type === "set_input_value" || type === "wait_for_selector" || type === "wait_for_text" || type === "assert_text_visible" || type === "assert_text_absent" || type === "assert_selector_count") && !selector) {
7082
7085
  throw new Error(`target.setup_actions[${index}] ${type} requires selector.`);
7083
7086
  }
7084
7087
  if (type === "wait_for_text" && !stringValue2(input.text) && !stringValue2(input.pattern)) {
7085
7088
  throw new Error(`target.setup_actions[${index}] wait_for_text requires text or pattern.`);
7086
7089
  }
7090
+ if ((type === "assert_text_visible" || type === "assert_text_absent") && !stringValue2(input.text) && !stringValue2(input.pattern)) {
7091
+ throw new Error(`target.setup_actions[${index}] ${type} requires text or pattern.`);
7092
+ }
7093
+ const expectedCount = numberValue(input.expected_count ?? input.expectedCount ?? input.count);
7094
+ if (type === "assert_selector_count" && (expectedCount === void 0 || !Number.isInteger(expectedCount) || expectedCount < 0)) {
7095
+ throw new Error(`target.setup_actions[${index}] ${type} requires non-negative integer expected_count.`);
7096
+ }
7087
7097
  const value = stringFromOwn(input, "value", "input_value", "inputValue");
7088
7098
  const hasJsonValue = hasOwn(input, "value_json") || hasOwn(input, "valueJson") || hasOwn(input, "json");
7089
7099
  if ((type === "fill" || type === "set_input_value") && value === void 0 && !hasJsonValue) {
@@ -7106,6 +7116,7 @@ function normalizeSetupAction(input, index) {
7106
7116
  pattern: stringValue2(input.pattern),
7107
7117
  flags: stringValue2(input.flags),
7108
7118
  index: numberValue(input.index),
7119
+ expected_count: expectedCount,
7109
7120
  ms: numberValue(input.ms) ?? numberValue(input.wait_ms) ?? numberValue(input.waitMs),
7110
7121
  timeout_ms: numberValue(input.timeout_ms) ?? numberValue(input.timeoutMs),
7111
7122
  after_ms: numberValue(input.after_ms) ?? numberValue(input.afterMs),
@@ -7191,6 +7202,7 @@ function normalizeNetworkMockResponsePayload(input, label, defaults = {}) {
7191
7202
  headers: stringRecord(input.headers) || defaults.headers,
7192
7203
  body,
7193
7204
  body_json: hasJsonBody ? toJsonValue(input.body_json ?? input.bodyJson ?? input.json) : defaults.body_json,
7205
+ delay_ms: normalizeNetworkMockDelay(input, label, defaults.delay_ms),
7194
7206
  capture_request_body: requestBody.capture_request_body,
7195
7207
  request_body_contains: requestBody.request_body_contains,
7196
7208
  request_body_patterns: requestBody.request_body_patterns,
@@ -7198,6 +7210,16 @@ function normalizeNetworkMockResponsePayload(input, label, defaults = {}) {
7198
7210
  request_body_not_patterns: requestBody.request_body_not_patterns
7199
7211
  };
7200
7212
  }
7213
+ function normalizeNetworkMockDelay(input, label, defaultValue) {
7214
+ const value = numberValue(
7215
+ input.delay_ms ?? input.delayMs ?? input.wait_ms ?? input.waitMs ?? input.latency_ms ?? input.latencyMs
7216
+ ) ?? defaultValue;
7217
+ if (value === void 0) return void 0;
7218
+ if (!Number.isInteger(value) || value < 0 || value > 6e4) {
7219
+ throw new Error(`${label}.delay_ms must be an integer from 0 to 60000.`);
7220
+ }
7221
+ return value;
7222
+ }
7201
7223
  function normalizeNetworkMockResponses(value, mockIndex, defaults) {
7202
7224
  if (value === void 0) return void 0;
7203
7225
  if (!Array.isArray(value)) throw new Error(`target.network_mocks[${mockIndex}].responses must be an array.`);
@@ -7208,7 +7230,8 @@ function normalizeNetworkMockResponses(value, mockIndex, defaults) {
7208
7230
  content_type: defaults.content_type,
7209
7231
  headers: defaults.headers,
7210
7232
  body: defaults.body,
7211
- body_json: defaults.body_json
7233
+ body_json: defaults.body_json,
7234
+ delay_ms: defaults.delay_ms
7212
7235
  };
7213
7236
  return value.map((response, responseIndex) => {
7214
7237
  if (!isRecord(response)) {
@@ -8891,6 +8914,7 @@ async function registerNetworkMocks(mocks) {
8891
8914
  const requestBody = shouldCaptureRequestBody && request.postData ? request.postData() || "" : "";
8892
8915
  const requestBodyFailures = shouldCaptureRequestBody ? networkMockRequestBodyFailures(requestBody, mock, responseBodyContract) : [];
8893
8916
  const status = response.status || mock.status || 200;
8917
+ const delayMs = numberValue(response.delay_ms) || 0;
8894
8918
  const event = {
8895
8919
  ok: true,
8896
8920
  label: mock.label,
@@ -8903,6 +8927,7 @@ async function registerNetworkMocks(mocks) {
8903
8927
  method,
8904
8928
  status,
8905
8929
  };
8930
+ if (delayMs) event.delay_ms = delayMs;
8906
8931
  if (shouldCaptureRequestBody) {
8907
8932
  event.request_body_matches = requestBodyFailures.length === 0;
8908
8933
  event.request_body_failures = requestBodyFailures;
@@ -8910,6 +8935,7 @@ async function registerNetworkMocks(mocks) {
8910
8935
  event.request_body_sample = compactNetworkMockRequestBody(requestBody);
8911
8936
  }
8912
8937
  networkMockEvents.push(event);
8938
+ if (delayMs) await new Promise((resolve) => setTimeout(resolve, delayMs));
8913
8939
  await route.fulfill({
8914
8940
  status,
8915
8941
  headers,
@@ -9007,6 +9033,19 @@ async function executeSetupAction(action, ordinal) {
9007
9033
  await locator.nth(targetIndex).fill(value, { timeout });
9008
9034
  return { ...base, ok: true, count, target_index: targetIndex, value_length: value.length };
9009
9035
  }
9036
+ if (type === "assert_selector_count") {
9037
+ const locator = page.locator(action.selector);
9038
+ const expectedCount = setupNumber(action.expected_count, -1);
9039
+ if (!Number.isInteger(expectedCount) || expectedCount < 0) return { ...base, reason: "invalid_expected_count", expected_count: action.expected_count };
9040
+ const startedAt = Date.now();
9041
+ let count = 0;
9042
+ while (Date.now() - startedAt <= timeout) {
9043
+ count = await locator.count().catch(() => 0);
9044
+ if (count === expectedCount) return { ...base, ok: true, count, expected_count: expectedCount, timeout_ms: timeout };
9045
+ await page.waitForTimeout(100);
9046
+ }
9047
+ return { ...base, reason: "selector_count_mismatch", count, expected_count: expectedCount, timeout_ms: timeout };
9048
+ }
9010
9049
  if (type === "wait_for_text") {
9011
9050
  const locator = page.locator(action.selector);
9012
9051
  const startedAt = Date.now();
@@ -9024,6 +9063,47 @@ async function executeSetupAction(action, ordinal) {
9024
9063
  }
9025
9064
  return { ...base, reason: "text_not_found", text: compactSetupResultText(lastText), timeout_ms: timeout };
9026
9065
  }
9066
+ if (type === "assert_text_visible" || type === "assert_text_absent") {
9067
+ const locator = page.locator(action.selector);
9068
+ const startedAt = Date.now();
9069
+ let lastText = "";
9070
+ let matchedText = "";
9071
+ let hiddenMatch = false;
9072
+ while (Date.now() - startedAt <= timeout) {
9073
+ const count = await locator.count().catch(() => 0);
9074
+ let matched = false;
9075
+ matchedText = "";
9076
+ hiddenMatch = false;
9077
+ for (let index = 0; index < count; index += 1) {
9078
+ const text = await setupLocatorText(locator, index);
9079
+ lastText = text || lastText;
9080
+ if (setupTextMatches(text, action)) {
9081
+ matched = true;
9082
+ matchedText = text;
9083
+ if (type === "assert_text_visible") {
9084
+ const visible = await setupLocatorVisible(locator, index);
9085
+ if (visible) {
9086
+ return { ...base, ok: true, count, text: compactSetupResultText(text), target_index: index, timeout_ms: timeout };
9087
+ }
9088
+ hiddenMatch = true;
9089
+ break;
9090
+ }
9091
+ break;
9092
+ }
9093
+ }
9094
+ if (type === "assert_text_absent" && !matched) {
9095
+ return { ...base, ok: true, count, timeout_ms: timeout };
9096
+ }
9097
+ await page.waitForTimeout(100);
9098
+ }
9099
+ if (type === "assert_text_visible") {
9100
+ if (hiddenMatch) {
9101
+ return { ...base, reason: "matching_element_not_visible", text: compactSetupResultText(matchedText), timeout_ms: timeout };
9102
+ }
9103
+ return { ...base, reason: "text_not_found", text: compactSetupResultText(lastText), timeout_ms: timeout };
9104
+ }
9105
+ return { ...base, reason: "text_still_present", text: compactSetupResultText(matchedText || lastText), timeout_ms: timeout };
9106
+ }
9027
9107
  return { ...base, reason: "unsupported_action" };
9028
9108
  } catch (error) {
9029
9109
  return { ...base, error: String(error && error.message ? error.message : error).slice(0, 1000) };
package/dist/cli.js CHANGED
@@ -10,7 +10,7 @@ import {
10
10
  profileStatusExitCode,
11
11
  resolveRiddleProofProfileTargetUrl,
12
12
  resolveRiddleProofProfileTimeoutSec
13
- } from "./chunk-NJDY7HYE.js";
13
+ } from "./chunk-Q3X6UTPP.js";
14
14
  import {
15
15
  createRiddleApiClient,
16
16
  parseRiddleViewport
package/dist/index.cjs CHANGED
@@ -8746,6 +8746,9 @@ var RIDDLE_PROOF_PROFILE_SETUP_ACTION_TYPES = [
8746
8746
  "click",
8747
8747
  "fill",
8748
8748
  "set_input_value",
8749
+ "assert_text_visible",
8750
+ "assert_text_absent",
8751
+ "assert_selector_count",
8749
8752
  "local_storage",
8750
8753
  "session_storage",
8751
8754
  "clear_storage",
@@ -8919,12 +8922,19 @@ function normalizeSetupAction(input, index) {
8919
8922
  if (!isRecord2(input)) throw new Error(`target.setup_actions[${index}] must be an object.`);
8920
8923
  const type = normalizeSetupActionType(stringValue5(input.type), index);
8921
8924
  const selector = stringValue5(input.selector);
8922
- if ((type === "click" || type === "fill" || type === "set_input_value" || type === "wait_for_selector" || type === "wait_for_text") && !selector) {
8925
+ if ((type === "click" || type === "fill" || type === "set_input_value" || type === "wait_for_selector" || type === "wait_for_text" || type === "assert_text_visible" || type === "assert_text_absent" || type === "assert_selector_count") && !selector) {
8923
8926
  throw new Error(`target.setup_actions[${index}] ${type} requires selector.`);
8924
8927
  }
8925
8928
  if (type === "wait_for_text" && !stringValue5(input.text) && !stringValue5(input.pattern)) {
8926
8929
  throw new Error(`target.setup_actions[${index}] wait_for_text requires text or pattern.`);
8927
8930
  }
8931
+ if ((type === "assert_text_visible" || type === "assert_text_absent") && !stringValue5(input.text) && !stringValue5(input.pattern)) {
8932
+ throw new Error(`target.setup_actions[${index}] ${type} requires text or pattern.`);
8933
+ }
8934
+ const expectedCount = numberValue3(input.expected_count ?? input.expectedCount ?? input.count);
8935
+ if (type === "assert_selector_count" && (expectedCount === void 0 || !Number.isInteger(expectedCount) || expectedCount < 0)) {
8936
+ throw new Error(`target.setup_actions[${index}] ${type} requires non-negative integer expected_count.`);
8937
+ }
8928
8938
  const value = stringFromOwn(input, "value", "input_value", "inputValue");
8929
8939
  const hasJsonValue = hasOwn(input, "value_json") || hasOwn(input, "valueJson") || hasOwn(input, "json");
8930
8940
  if ((type === "fill" || type === "set_input_value") && value === void 0 && !hasJsonValue) {
@@ -8947,6 +8957,7 @@ function normalizeSetupAction(input, index) {
8947
8957
  pattern: stringValue5(input.pattern),
8948
8958
  flags: stringValue5(input.flags),
8949
8959
  index: numberValue3(input.index),
8960
+ expected_count: expectedCount,
8950
8961
  ms: numberValue3(input.ms) ?? numberValue3(input.wait_ms) ?? numberValue3(input.waitMs),
8951
8962
  timeout_ms: numberValue3(input.timeout_ms) ?? numberValue3(input.timeoutMs),
8952
8963
  after_ms: numberValue3(input.after_ms) ?? numberValue3(input.afterMs),
@@ -9032,6 +9043,7 @@ function normalizeNetworkMockResponsePayload(input, label, defaults = {}) {
9032
9043
  headers: stringRecord(input.headers) || defaults.headers,
9033
9044
  body,
9034
9045
  body_json: hasJsonBody ? toJsonValue(input.body_json ?? input.bodyJson ?? input.json) : defaults.body_json,
9046
+ delay_ms: normalizeNetworkMockDelay(input, label, defaults.delay_ms),
9035
9047
  capture_request_body: requestBody.capture_request_body,
9036
9048
  request_body_contains: requestBody.request_body_contains,
9037
9049
  request_body_patterns: requestBody.request_body_patterns,
@@ -9039,6 +9051,16 @@ function normalizeNetworkMockResponsePayload(input, label, defaults = {}) {
9039
9051
  request_body_not_patterns: requestBody.request_body_not_patterns
9040
9052
  };
9041
9053
  }
9054
+ function normalizeNetworkMockDelay(input, label, defaultValue) {
9055
+ const value = numberValue3(
9056
+ input.delay_ms ?? input.delayMs ?? input.wait_ms ?? input.waitMs ?? input.latency_ms ?? input.latencyMs
9057
+ ) ?? defaultValue;
9058
+ if (value === void 0) return void 0;
9059
+ if (!Number.isInteger(value) || value < 0 || value > 6e4) {
9060
+ throw new Error(`${label}.delay_ms must be an integer from 0 to 60000.`);
9061
+ }
9062
+ return value;
9063
+ }
9042
9064
  function normalizeNetworkMockResponses(value, mockIndex, defaults) {
9043
9065
  if (value === void 0) return void 0;
9044
9066
  if (!Array.isArray(value)) throw new Error(`target.network_mocks[${mockIndex}].responses must be an array.`);
@@ -9049,7 +9071,8 @@ function normalizeNetworkMockResponses(value, mockIndex, defaults) {
9049
9071
  content_type: defaults.content_type,
9050
9072
  headers: defaults.headers,
9051
9073
  body: defaults.body,
9052
- body_json: defaults.body_json
9074
+ body_json: defaults.body_json,
9075
+ delay_ms: defaults.delay_ms
9053
9076
  };
9054
9077
  return value.map((response, responseIndex) => {
9055
9078
  if (!isRecord2(response)) {
@@ -10748,6 +10771,7 @@ async function registerNetworkMocks(mocks) {
10748
10771
  const requestBody = shouldCaptureRequestBody && request.postData ? request.postData() || "" : "";
10749
10772
  const requestBodyFailures = shouldCaptureRequestBody ? networkMockRequestBodyFailures(requestBody, mock, responseBodyContract) : [];
10750
10773
  const status = response.status || mock.status || 200;
10774
+ const delayMs = numberValue(response.delay_ms) || 0;
10751
10775
  const event = {
10752
10776
  ok: true,
10753
10777
  label: mock.label,
@@ -10760,6 +10784,7 @@ async function registerNetworkMocks(mocks) {
10760
10784
  method,
10761
10785
  status,
10762
10786
  };
10787
+ if (delayMs) event.delay_ms = delayMs;
10763
10788
  if (shouldCaptureRequestBody) {
10764
10789
  event.request_body_matches = requestBodyFailures.length === 0;
10765
10790
  event.request_body_failures = requestBodyFailures;
@@ -10767,6 +10792,7 @@ async function registerNetworkMocks(mocks) {
10767
10792
  event.request_body_sample = compactNetworkMockRequestBody(requestBody);
10768
10793
  }
10769
10794
  networkMockEvents.push(event);
10795
+ if (delayMs) await new Promise((resolve) => setTimeout(resolve, delayMs));
10770
10796
  await route.fulfill({
10771
10797
  status,
10772
10798
  headers,
@@ -10864,6 +10890,19 @@ async function executeSetupAction(action, ordinal) {
10864
10890
  await locator.nth(targetIndex).fill(value, { timeout });
10865
10891
  return { ...base, ok: true, count, target_index: targetIndex, value_length: value.length };
10866
10892
  }
10893
+ if (type === "assert_selector_count") {
10894
+ const locator = page.locator(action.selector);
10895
+ const expectedCount = setupNumber(action.expected_count, -1);
10896
+ if (!Number.isInteger(expectedCount) || expectedCount < 0) return { ...base, reason: "invalid_expected_count", expected_count: action.expected_count };
10897
+ const startedAt = Date.now();
10898
+ let count = 0;
10899
+ while (Date.now() - startedAt <= timeout) {
10900
+ count = await locator.count().catch(() => 0);
10901
+ if (count === expectedCount) return { ...base, ok: true, count, expected_count: expectedCount, timeout_ms: timeout };
10902
+ await page.waitForTimeout(100);
10903
+ }
10904
+ return { ...base, reason: "selector_count_mismatch", count, expected_count: expectedCount, timeout_ms: timeout };
10905
+ }
10867
10906
  if (type === "wait_for_text") {
10868
10907
  const locator = page.locator(action.selector);
10869
10908
  const startedAt = Date.now();
@@ -10881,6 +10920,47 @@ async function executeSetupAction(action, ordinal) {
10881
10920
  }
10882
10921
  return { ...base, reason: "text_not_found", text: compactSetupResultText(lastText), timeout_ms: timeout };
10883
10922
  }
10923
+ if (type === "assert_text_visible" || type === "assert_text_absent") {
10924
+ const locator = page.locator(action.selector);
10925
+ const startedAt = Date.now();
10926
+ let lastText = "";
10927
+ let matchedText = "";
10928
+ let hiddenMatch = false;
10929
+ while (Date.now() - startedAt <= timeout) {
10930
+ const count = await locator.count().catch(() => 0);
10931
+ let matched = false;
10932
+ matchedText = "";
10933
+ hiddenMatch = false;
10934
+ for (let index = 0; index < count; index += 1) {
10935
+ const text = await setupLocatorText(locator, index);
10936
+ lastText = text || lastText;
10937
+ if (setupTextMatches(text, action)) {
10938
+ matched = true;
10939
+ matchedText = text;
10940
+ if (type === "assert_text_visible") {
10941
+ const visible = await setupLocatorVisible(locator, index);
10942
+ if (visible) {
10943
+ return { ...base, ok: true, count, text: compactSetupResultText(text), target_index: index, timeout_ms: timeout };
10944
+ }
10945
+ hiddenMatch = true;
10946
+ break;
10947
+ }
10948
+ break;
10949
+ }
10950
+ }
10951
+ if (type === "assert_text_absent" && !matched) {
10952
+ return { ...base, ok: true, count, timeout_ms: timeout };
10953
+ }
10954
+ await page.waitForTimeout(100);
10955
+ }
10956
+ if (type === "assert_text_visible") {
10957
+ if (hiddenMatch) {
10958
+ return { ...base, reason: "matching_element_not_visible", text: compactSetupResultText(matchedText), timeout_ms: timeout };
10959
+ }
10960
+ return { ...base, reason: "text_not_found", text: compactSetupResultText(lastText), timeout_ms: timeout };
10961
+ }
10962
+ return { ...base, reason: "text_still_present", text: compactSetupResultText(matchedText || lastText), timeout_ms: timeout };
10963
+ }
10884
10964
  return { ...base, reason: "unsupported_action" };
10885
10965
  } catch (error) {
10886
10966
  return { ...base, error: String(error && error.message ? error.message : error).slice(0, 1000) };
package/dist/index.js CHANGED
@@ -58,7 +58,7 @@ import {
58
58
  resolveRiddleProofProfileTimeoutSec,
59
59
  slugifyRiddleProofProfileName,
60
60
  summarizeRiddleProofProfileResult
61
- } from "./chunk-NJDY7HYE.js";
61
+ } from "./chunk-Q3X6UTPP.js";
62
62
  import {
63
63
  DEFAULT_RIDDLE_API_BASE_URL,
64
64
  DEFAULT_RIDDLE_API_KEY_FILE,
package/dist/profile.cjs CHANGED
@@ -75,6 +75,9 @@ var RIDDLE_PROOF_PROFILE_SETUP_ACTION_TYPES = [
75
75
  "click",
76
76
  "fill",
77
77
  "set_input_value",
78
+ "assert_text_visible",
79
+ "assert_text_absent",
80
+ "assert_selector_count",
78
81
  "local_storage",
79
82
  "session_storage",
80
83
  "clear_storage",
@@ -248,12 +251,19 @@ function normalizeSetupAction(input, index) {
248
251
  if (!isRecord(input)) throw new Error(`target.setup_actions[${index}] must be an object.`);
249
252
  const type = normalizeSetupActionType(stringValue(input.type), index);
250
253
  const selector = stringValue(input.selector);
251
- if ((type === "click" || type === "fill" || type === "set_input_value" || type === "wait_for_selector" || type === "wait_for_text") && !selector) {
254
+ if ((type === "click" || type === "fill" || type === "set_input_value" || type === "wait_for_selector" || type === "wait_for_text" || type === "assert_text_visible" || type === "assert_text_absent" || type === "assert_selector_count") && !selector) {
252
255
  throw new Error(`target.setup_actions[${index}] ${type} requires selector.`);
253
256
  }
254
257
  if (type === "wait_for_text" && !stringValue(input.text) && !stringValue(input.pattern)) {
255
258
  throw new Error(`target.setup_actions[${index}] wait_for_text requires text or pattern.`);
256
259
  }
260
+ if ((type === "assert_text_visible" || type === "assert_text_absent") && !stringValue(input.text) && !stringValue(input.pattern)) {
261
+ throw new Error(`target.setup_actions[${index}] ${type} requires text or pattern.`);
262
+ }
263
+ const expectedCount = numberValue(input.expected_count ?? input.expectedCount ?? input.count);
264
+ if (type === "assert_selector_count" && (expectedCount === void 0 || !Number.isInteger(expectedCount) || expectedCount < 0)) {
265
+ throw new Error(`target.setup_actions[${index}] ${type} requires non-negative integer expected_count.`);
266
+ }
257
267
  const value = stringFromOwn(input, "value", "input_value", "inputValue");
258
268
  const hasJsonValue = hasOwn(input, "value_json") || hasOwn(input, "valueJson") || hasOwn(input, "json");
259
269
  if ((type === "fill" || type === "set_input_value") && value === void 0 && !hasJsonValue) {
@@ -276,6 +286,7 @@ function normalizeSetupAction(input, index) {
276
286
  pattern: stringValue(input.pattern),
277
287
  flags: stringValue(input.flags),
278
288
  index: numberValue(input.index),
289
+ expected_count: expectedCount,
279
290
  ms: numberValue(input.ms) ?? numberValue(input.wait_ms) ?? numberValue(input.waitMs),
280
291
  timeout_ms: numberValue(input.timeout_ms) ?? numberValue(input.timeoutMs),
281
292
  after_ms: numberValue(input.after_ms) ?? numberValue(input.afterMs),
@@ -361,6 +372,7 @@ function normalizeNetworkMockResponsePayload(input, label, defaults = {}) {
361
372
  headers: stringRecord(input.headers) || defaults.headers,
362
373
  body,
363
374
  body_json: hasJsonBody ? toJsonValue(input.body_json ?? input.bodyJson ?? input.json) : defaults.body_json,
375
+ delay_ms: normalizeNetworkMockDelay(input, label, defaults.delay_ms),
364
376
  capture_request_body: requestBody.capture_request_body,
365
377
  request_body_contains: requestBody.request_body_contains,
366
378
  request_body_patterns: requestBody.request_body_patterns,
@@ -368,6 +380,16 @@ function normalizeNetworkMockResponsePayload(input, label, defaults = {}) {
368
380
  request_body_not_patterns: requestBody.request_body_not_patterns
369
381
  };
370
382
  }
383
+ function normalizeNetworkMockDelay(input, label, defaultValue) {
384
+ const value = numberValue(
385
+ input.delay_ms ?? input.delayMs ?? input.wait_ms ?? input.waitMs ?? input.latency_ms ?? input.latencyMs
386
+ ) ?? defaultValue;
387
+ if (value === void 0) return void 0;
388
+ if (!Number.isInteger(value) || value < 0 || value > 6e4) {
389
+ throw new Error(`${label}.delay_ms must be an integer from 0 to 60000.`);
390
+ }
391
+ return value;
392
+ }
371
393
  function normalizeNetworkMockResponses(value, mockIndex, defaults) {
372
394
  if (value === void 0) return void 0;
373
395
  if (!Array.isArray(value)) throw new Error(`target.network_mocks[${mockIndex}].responses must be an array.`);
@@ -378,7 +400,8 @@ function normalizeNetworkMockResponses(value, mockIndex, defaults) {
378
400
  content_type: defaults.content_type,
379
401
  headers: defaults.headers,
380
402
  body: defaults.body,
381
- body_json: defaults.body_json
403
+ body_json: defaults.body_json,
404
+ delay_ms: defaults.delay_ms
382
405
  };
383
406
  return value.map((response, responseIndex) => {
384
407
  if (!isRecord(response)) {
@@ -2077,6 +2100,7 @@ async function registerNetworkMocks(mocks) {
2077
2100
  const requestBody = shouldCaptureRequestBody && request.postData ? request.postData() || "" : "";
2078
2101
  const requestBodyFailures = shouldCaptureRequestBody ? networkMockRequestBodyFailures(requestBody, mock, responseBodyContract) : [];
2079
2102
  const status = response.status || mock.status || 200;
2103
+ const delayMs = numberValue(response.delay_ms) || 0;
2080
2104
  const event = {
2081
2105
  ok: true,
2082
2106
  label: mock.label,
@@ -2089,6 +2113,7 @@ async function registerNetworkMocks(mocks) {
2089
2113
  method,
2090
2114
  status,
2091
2115
  };
2116
+ if (delayMs) event.delay_ms = delayMs;
2092
2117
  if (shouldCaptureRequestBody) {
2093
2118
  event.request_body_matches = requestBodyFailures.length === 0;
2094
2119
  event.request_body_failures = requestBodyFailures;
@@ -2096,6 +2121,7 @@ async function registerNetworkMocks(mocks) {
2096
2121
  event.request_body_sample = compactNetworkMockRequestBody(requestBody);
2097
2122
  }
2098
2123
  networkMockEvents.push(event);
2124
+ if (delayMs) await new Promise((resolve) => setTimeout(resolve, delayMs));
2099
2125
  await route.fulfill({
2100
2126
  status,
2101
2127
  headers,
@@ -2193,6 +2219,19 @@ async function executeSetupAction(action, ordinal) {
2193
2219
  await locator.nth(targetIndex).fill(value, { timeout });
2194
2220
  return { ...base, ok: true, count, target_index: targetIndex, value_length: value.length };
2195
2221
  }
2222
+ if (type === "assert_selector_count") {
2223
+ const locator = page.locator(action.selector);
2224
+ const expectedCount = setupNumber(action.expected_count, -1);
2225
+ if (!Number.isInteger(expectedCount) || expectedCount < 0) return { ...base, reason: "invalid_expected_count", expected_count: action.expected_count };
2226
+ const startedAt = Date.now();
2227
+ let count = 0;
2228
+ while (Date.now() - startedAt <= timeout) {
2229
+ count = await locator.count().catch(() => 0);
2230
+ if (count === expectedCount) return { ...base, ok: true, count, expected_count: expectedCount, timeout_ms: timeout };
2231
+ await page.waitForTimeout(100);
2232
+ }
2233
+ return { ...base, reason: "selector_count_mismatch", count, expected_count: expectedCount, timeout_ms: timeout };
2234
+ }
2196
2235
  if (type === "wait_for_text") {
2197
2236
  const locator = page.locator(action.selector);
2198
2237
  const startedAt = Date.now();
@@ -2210,6 +2249,47 @@ async function executeSetupAction(action, ordinal) {
2210
2249
  }
2211
2250
  return { ...base, reason: "text_not_found", text: compactSetupResultText(lastText), timeout_ms: timeout };
2212
2251
  }
2252
+ if (type === "assert_text_visible" || type === "assert_text_absent") {
2253
+ const locator = page.locator(action.selector);
2254
+ const startedAt = Date.now();
2255
+ let lastText = "";
2256
+ let matchedText = "";
2257
+ let hiddenMatch = false;
2258
+ while (Date.now() - startedAt <= timeout) {
2259
+ const count = await locator.count().catch(() => 0);
2260
+ let matched = false;
2261
+ matchedText = "";
2262
+ hiddenMatch = false;
2263
+ for (let index = 0; index < count; index += 1) {
2264
+ const text = await setupLocatorText(locator, index);
2265
+ lastText = text || lastText;
2266
+ if (setupTextMatches(text, action)) {
2267
+ matched = true;
2268
+ matchedText = text;
2269
+ if (type === "assert_text_visible") {
2270
+ const visible = await setupLocatorVisible(locator, index);
2271
+ if (visible) {
2272
+ return { ...base, ok: true, count, text: compactSetupResultText(text), target_index: index, timeout_ms: timeout };
2273
+ }
2274
+ hiddenMatch = true;
2275
+ break;
2276
+ }
2277
+ break;
2278
+ }
2279
+ }
2280
+ if (type === "assert_text_absent" && !matched) {
2281
+ return { ...base, ok: true, count, timeout_ms: timeout };
2282
+ }
2283
+ await page.waitForTimeout(100);
2284
+ }
2285
+ if (type === "assert_text_visible") {
2286
+ if (hiddenMatch) {
2287
+ return { ...base, reason: "matching_element_not_visible", text: compactSetupResultText(matchedText), timeout_ms: timeout };
2288
+ }
2289
+ return { ...base, reason: "text_not_found", text: compactSetupResultText(lastText), timeout_ms: timeout };
2290
+ }
2291
+ return { ...base, reason: "text_still_present", text: compactSetupResultText(matchedText || lastText), timeout_ms: timeout };
2292
+ }
2213
2293
  return { ...base, reason: "unsupported_action" };
2214
2294
  } catch (error) {
2215
2295
  return { ...base, error: String(error && error.message ? error.message : error).slice(0, 1000) };
@@ -5,7 +5,7 @@ declare const RIDDLE_PROOF_PROFILE_EVIDENCE_VERSION: "riddle-proof.profile-evide
5
5
  declare const RIDDLE_PROOF_PROFILE_RESULT_VERSION: "riddle-proof.profile-result.v1";
6
6
  declare const RIDDLE_PROOF_PROFILE_STATUSES: readonly ["passed", "product_regression", "proof_insufficient", "environment_blocked", "configuration_error", "needs_human_review"];
7
7
  declare const RIDDLE_PROOF_PROFILE_CHECK_TYPES: readonly ["route_loaded", "selector_visible", "selector_absent", "selector_count_at_least", "selector_count_equals", "selector_count_equal", "selector_count_eq", "selector_text_order", "frame_text_visible", "frame_no_horizontal_overflow", "text_visible", "text_absent", "route_inventory", "no_horizontal_overflow", "no_mobile_horizontal_overflow", "no_fatal_console_errors"];
8
- declare const RIDDLE_PROOF_PROFILE_SETUP_ACTION_TYPES: readonly ["click", "fill", "set_input_value", "local_storage", "session_storage", "clear_storage", "wait", "wait_for_selector", "wait_for_text"];
8
+ declare const RIDDLE_PROOF_PROFILE_SETUP_ACTION_TYPES: readonly ["click", "fill", "set_input_value", "assert_text_visible", "assert_text_absent", "assert_selector_count", "local_storage", "session_storage", "clear_storage", "wait", "wait_for_selector", "wait_for_text"];
9
9
  type RiddleProofProfileStatus = typeof RIDDLE_PROOF_PROFILE_STATUSES[number];
10
10
  type RiddleProofProfileCheckType = typeof RIDDLE_PROOF_PROFILE_CHECK_TYPES[number];
11
11
  type RiddleProofProfileSetupActionType = typeof RIDDLE_PROOF_PROFILE_SETUP_ACTION_TYPES[number];
@@ -27,6 +27,7 @@ interface RiddleProofProfileSetupAction {
27
27
  pattern?: string;
28
28
  flags?: string;
29
29
  index?: number;
30
+ expected_count?: number;
30
31
  ms?: number;
31
32
  timeout_ms?: number;
32
33
  after_ms?: number;
@@ -41,6 +42,7 @@ interface RiddleProofProfileNetworkMockResponse {
41
42
  headers?: Record<string, string>;
42
43
  body?: string;
43
44
  body_json?: JsonValue;
45
+ delay_ms?: number;
44
46
  capture_request_body?: boolean;
45
47
  request_body_contains?: string[];
46
48
  request_body_patterns?: string[];
package/dist/profile.d.ts CHANGED
@@ -5,7 +5,7 @@ declare const RIDDLE_PROOF_PROFILE_EVIDENCE_VERSION: "riddle-proof.profile-evide
5
5
  declare const RIDDLE_PROOF_PROFILE_RESULT_VERSION: "riddle-proof.profile-result.v1";
6
6
  declare const RIDDLE_PROOF_PROFILE_STATUSES: readonly ["passed", "product_regression", "proof_insufficient", "environment_blocked", "configuration_error", "needs_human_review"];
7
7
  declare const RIDDLE_PROOF_PROFILE_CHECK_TYPES: readonly ["route_loaded", "selector_visible", "selector_absent", "selector_count_at_least", "selector_count_equals", "selector_count_equal", "selector_count_eq", "selector_text_order", "frame_text_visible", "frame_no_horizontal_overflow", "text_visible", "text_absent", "route_inventory", "no_horizontal_overflow", "no_mobile_horizontal_overflow", "no_fatal_console_errors"];
8
- declare const RIDDLE_PROOF_PROFILE_SETUP_ACTION_TYPES: readonly ["click", "fill", "set_input_value", "local_storage", "session_storage", "clear_storage", "wait", "wait_for_selector", "wait_for_text"];
8
+ declare const RIDDLE_PROOF_PROFILE_SETUP_ACTION_TYPES: readonly ["click", "fill", "set_input_value", "assert_text_visible", "assert_text_absent", "assert_selector_count", "local_storage", "session_storage", "clear_storage", "wait", "wait_for_selector", "wait_for_text"];
9
9
  type RiddleProofProfileStatus = typeof RIDDLE_PROOF_PROFILE_STATUSES[number];
10
10
  type RiddleProofProfileCheckType = typeof RIDDLE_PROOF_PROFILE_CHECK_TYPES[number];
11
11
  type RiddleProofProfileSetupActionType = typeof RIDDLE_PROOF_PROFILE_SETUP_ACTION_TYPES[number];
@@ -27,6 +27,7 @@ interface RiddleProofProfileSetupAction {
27
27
  pattern?: string;
28
28
  flags?: string;
29
29
  index?: number;
30
+ expected_count?: number;
30
31
  ms?: number;
31
32
  timeout_ms?: number;
32
33
  after_ms?: number;
@@ -41,6 +42,7 @@ interface RiddleProofProfileNetworkMockResponse {
41
42
  headers?: Record<string, string>;
42
43
  body?: string;
43
44
  body_json?: JsonValue;
45
+ delay_ms?: number;
44
46
  capture_request_body?: boolean;
45
47
  request_body_contains?: string[];
46
48
  request_body_patterns?: string[];
package/dist/profile.js CHANGED
@@ -19,7 +19,7 @@ import {
19
19
  resolveRiddleProofProfileTimeoutSec,
20
20
  slugifyRiddleProofProfileName,
21
21
  summarizeRiddleProofProfileResult
22
- } from "./chunk-NJDY7HYE.js";
22
+ } from "./chunk-Q3X6UTPP.js";
23
23
  export {
24
24
  RIDDLE_PROOF_PROFILE_CHECK_TYPES,
25
25
  RIDDLE_PROOF_PROFILE_EVIDENCE_VERSION,
@@ -292,7 +292,7 @@ declare function executeWorkflow(params: WorkflowParams, pluginConfig: any, reso
292
292
  blocking?: boolean;
293
293
  details?: Record<string, unknown>;
294
294
  ok: boolean;
295
- action: "setup" | "recon" | "author" | "implement" | "verify" | "ship" | "run";
295
+ action: "author" | "recon" | "ship" | "implement" | "verify" | "setup" | "run";
296
296
  state_path: string;
297
297
  stage: any;
298
298
  summary: string;
@@ -382,7 +382,7 @@ declare function executeWorkflow(params: WorkflowParams, pluginConfig: any, reso
382
382
  continueWithStage?: WorkflowStage | null;
383
383
  blocking?: boolean;
384
384
  details?: Record<string, unknown>;
385
- action: "setup" | "recon" | "author" | "implement" | "verify" | "ship" | "run";
385
+ action: "author" | "recon" | "ship" | "implement" | "verify" | "setup" | "run";
386
386
  state_path: string;
387
387
  stage: any;
388
388
  checkpoint: string;
@@ -659,7 +659,7 @@ declare function executeWorkflow(params: WorkflowParams, pluginConfig: any, reso
659
659
  error?: undefined;
660
660
  } | {
661
661
  ok: boolean;
662
- action: "setup" | "recon" | "author" | "implement" | "verify" | "ship" | "run";
662
+ action: "author" | "recon" | "ship" | "implement" | "verify" | "setup" | "run";
663
663
  state_path: string;
664
664
  stage: any;
665
665
  summary: string;
@@ -292,7 +292,7 @@ declare function executeWorkflow(params: WorkflowParams, pluginConfig: any, reso
292
292
  blocking?: boolean;
293
293
  details?: Record<string, unknown>;
294
294
  ok: boolean;
295
- action: "setup" | "recon" | "author" | "implement" | "verify" | "ship" | "run";
295
+ action: "author" | "recon" | "ship" | "implement" | "verify" | "setup" | "run";
296
296
  state_path: string;
297
297
  stage: any;
298
298
  summary: string;
@@ -382,7 +382,7 @@ declare function executeWorkflow(params: WorkflowParams, pluginConfig: any, reso
382
382
  continueWithStage?: WorkflowStage | null;
383
383
  blocking?: boolean;
384
384
  details?: Record<string, unknown>;
385
- action: "setup" | "recon" | "author" | "implement" | "verify" | "ship" | "run";
385
+ action: "author" | "recon" | "ship" | "implement" | "verify" | "setup" | "run";
386
386
  state_path: string;
387
387
  stage: any;
388
388
  checkpoint: string;
@@ -659,7 +659,7 @@ declare function executeWorkflow(params: WorkflowParams, pluginConfig: any, reso
659
659
  error?: undefined;
660
660
  } | {
661
661
  ok: boolean;
662
- action: "setup" | "recon" | "author" | "implement" | "verify" | "ship" | "run";
662
+ action: "author" | "recon" | "ship" | "implement" | "verify" | "setup" | "run";
663
663
  state_path: string;
664
664
  stage: any;
665
665
  summary: string;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@riddledc/riddle-proof",
3
- "version": "0.7.47",
3
+ "version": "0.7.49",
4
4
  "description": "Reusable Riddle Proof contracts and helpers for evidence-backed agent changes.",
5
5
  "license": "MIT",
6
6
  "author": "RiddleDC",