@crvy/rprtr 0.1.4 → 0.2.2

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.
Files changed (41) hide show
  1. package/CHANGELOG.md +61 -0
  2. package/README.md +8 -7
  3. package/dist/{chunk-WRMHUY5A.js → chunk-HAFWYUNO.js} +181 -130
  4. package/dist/{chunk-KLGJSEKV.js → chunk-RFZGJSL3.js} +439 -127
  5. package/dist/cli.d.ts.map +1 -1
  6. package/dist/cli.js +6 -4
  7. package/dist/index.css +26 -0
  8. package/dist/index.js +297 -76
  9. package/dist/offline-reports.d.ts +4 -0
  10. package/dist/offline-reports.d.ts.map +1 -1
  11. package/dist/report-state.d.ts +3 -1
  12. package/dist/report-state.d.ts.map +1 -1
  13. package/dist/reporter-utils.d.ts +0 -1
  14. package/dist/reporter-utils.d.ts.map +1 -1
  15. package/dist/reporter.cjs +186 -134
  16. package/dist/reporter.d.ts +1 -1
  17. package/dist/reporter.d.ts.map +1 -1
  18. package/dist/reporter.js +8 -6
  19. package/dist/schemas/http.d.ts +44 -0
  20. package/dist/schemas/http.d.ts.map +1 -0
  21. package/dist/schemas.d.ts +25 -6
  22. package/dist/schemas.d.ts.map +1 -1
  23. package/dist/server/app.d.ts +6 -0
  24. package/dist/server/app.d.ts.map +1 -1
  25. package/dist/server/handlers.d.ts +3 -0
  26. package/dist/server/handlers.d.ts.map +1 -1
  27. package/dist/server/playwright-config.d.ts +2 -0
  28. package/dist/server/playwright-config.d.ts.map +1 -0
  29. package/dist/server/routes-context.d.ts +13 -0
  30. package/dist/server/routes-context.d.ts.map +1 -0
  31. package/dist/server/routes.d.ts +6 -1
  32. package/dist/server/routes.d.ts.map +1 -1
  33. package/dist/server/run-controller.d.ts +85 -0
  34. package/dist/server/run-controller.d.ts.map +1 -0
  35. package/dist/server/run-routes.d.ts +3 -0
  36. package/dist/server/run-routes.d.ts.map +1 -0
  37. package/dist/server.cjs +633 -273
  38. package/dist/server.js +2 -2
  39. package/dist/types.d.ts +6 -0
  40. package/dist/types.d.ts.map +1 -1
  41. package/package.json +6 -5
package/CHANGELOG.md CHANGED
@@ -5,6 +5,67 @@ All notable changes to this project will be documented in this file.
5
5
  The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.1.0/),
6
6
  and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
7
7
 
8
+ ## [0.2.2] - 2026-07-03
9
+
10
+ ### Miscellaneous
11
+
12
+ - Update repository URLs to creevey/rprtr
13
+ ## [0.2.1] - 2026-07-03
14
+ ## [0.2.0] - 2026-07-03
15
+
16
+ ### Added
17
+
18
+ - **types:** Add run-status variant to ClientWebSocketMessage
19
+ - **reporter:** Include configFile and cwd in register message
20
+ - **server:** Add RunController for spawning playwright test
21
+ - **server:** Persist register payload configFile and cwd as runContext
22
+ - **server:** Instantiate RunController in createServerApp and dispose on close
23
+ - **server:** Add POST /api/run and /api/stop, surface runEnabled in /api/report
24
+ - **client:** Wire Start/Stop buttons to /api/run and /api/stop
25
+ - **client:** Add per-test and per-suite run buttons to sidebar tree
26
+ - **run-controller:** Resolve playwright via project package manager
27
+ - **run-controller:** Descriptor-based filter with positional translation
28
+ - **run-controller:** --test-list for suites with version fallback
29
+ - **client:** Descriptor filters, no-location feedback, isRunning guard
30
+ - **client:** Add captureTestStatuses/restoreTestStatuses helpers
31
+ - **client:** Revert orphaned pending on no-event run
32
+
33
+ ### Changed
34
+
35
+ - **schemas:** Extract HTTP request schemas to schemas/http.ts
36
+ - **schemas:** Use discriminatedUnion for Run/Stop responses
37
+ - **run-controller:** Document cwd param and test launch fallback
38
+ - **reporter:** Make onBegin synchronous and defer screenshotDir creation
39
+ - **client:** Reset runEventIds on rejected-start path
40
+
41
+ ### Documentation
42
+
43
+ - **spec:** Run tests from UI design
44
+ - **plan:** Run tests from UI implementation plan
45
+ - **spec:** Run-from-UI robustness design
46
+ - **plan:** Run-from-UI robustness implementation plan
47
+ - **spec:** Stuck-pending run recovery design
48
+ - **plan:** Stuck-pending run recovery implementation plan
49
+
50
+ ### Fixed
51
+
52
+ - **run-controller:** Guard against duplicate exit/error cleanup
53
+ - **reporter:** Honor CRVY_RPRTR_SERVER_URL env as fallback serverUrl
54
+ - **run-controller:** Override reporters and strip CI env for UI-triggered runs
55
+ - **run-from-ui:** Row height, re-run status, filtered-run scope, startup config
56
+ - **run-from-ui:** Mark tests pending on start, use file:line:column for precise re-runs
57
+ - **run-controller:** Resolve @crvy/rprtr from project cwd then server module
58
+ - **run-controller:** Clean up test-list temp file on spawn throw
59
+ - **knip:** Enable production-mode analysis in strict checks
60
+
61
+ ### Styling
62
+
63
+ - **client:** Match semicolon convention and destructure location
64
+ - **docs:** Reformat CLI options table
65
+
66
+ ### Testing
67
+
68
+ - **client:** Cover undefined-restore and empty/bare-root edge cases
8
69
  ## [0.1.4] - 2026-06-19
9
70
 
10
71
  ### Added
package/README.md CHANGED
@@ -74,13 +74,14 @@ If `artifact-dir` is provided, the CLI treats it as the directory containing:
74
74
 
75
75
  Explicit flags override the paths derived from `artifact-dir`.
76
76
 
77
- | Option | Short | Default | Description |
78
- | ------------------ | ----- | --------------- | ----------------------------------------------------------------------------------------- |
79
- | `--port` | `-p` | `3000` | Server port |
80
- | `--screenshot-dir` | `-s` | `./screenshots` | Screenshot directory path |
81
- | `--report-path` | `-r` | `./report.json` | Report JSON file path or directory containing `report.json` and `crvy-rprtr-*.json` files |
82
-
83
- The CLI currently exposes only these flags. Approval-routing resolver overrides are available through the programmatic server API, not additional CLI flags.
77
+ | Option | Short | Default | Description |
78
+ | ------------------ | ----- | --------------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
79
+ | `--port` | `-p` | `3000` | Server port |
80
+ | `--screenshot-dir` | `-s` | `./screenshots` | Screenshot directory path |
81
+ | `--report-path` | `-r` | `./report.json` | Report JSON file path or directory containing `report.json` and `crvy-rprtr-*.json` files |
82
+ | `--config` | `-c` | auto-detect | Playwright config path used to enable the run buttons at startup. When omitted, the server discovers `playwright.config.*` in the working directory. A registering reporter always overrides this. |
83
+
84
+ When the server can resolve a Playwright config (via `--config` or auto-discovery, or once a reporter registers), the sidebar shows Start/Stop and per-test run buttons that trigger `playwright test` without leaving the browser. Approval-routing resolver overrides are available through the programmatic server API, not additional CLI flags.
84
85
 
85
86
  ## How It Works
86
87
 
@@ -170,169 +170,211 @@ function resolveBaselineTargets(input) {
170
170
  }
171
171
 
172
172
  // src/schemas.ts
173
+ import { z as z2 } from "zod";
174
+
175
+ // src/schemas/http.ts
173
176
  import { z } from "zod";
174
- var LocationSchema = z.object({
177
+ var ApproveRequestBodySchema = z.object({
178
+ id: z.string(),
179
+ retry: z.number(),
180
+ image: z.string()
181
+ });
182
+ var RunTestDescriptorSchema = z.object({
175
183
  file: z.string(),
176
- line: z.number()
184
+ line: z.number(),
185
+ column: z.number().optional(),
186
+ projectName: z.string().optional(),
187
+ titlePath: z.array(z.string())
177
188
  });
178
- var VisualSourceSchema = z.enum(["comparison", "baseline-only", "declared-only"]);
179
- var ImagesSchema = z.object({
180
- actual: z.string().optional(),
181
- expect: z.string().optional(),
182
- diff: z.string().optional(),
183
- error: z.string().optional(),
184
- source: VisualSourceSchema.optional()
189
+ var RunRequestBodySchema = z.object({
190
+ tests: z.array(RunTestDescriptorSchema).optional()
185
191
  });
186
- var ScreenshotDeclarationSchema = z.discriminatedUnion("kind", [
192
+ var RunResponseSchema = z.discriminatedUnion("ok", [
193
+ z.object({ ok: z.literal(true) }),
187
194
  z.object({
188
- visualName: z.string(),
189
- kind: z.literal("named"),
190
- declaredName: z.string(),
191
- snapshotBaseName: z.string(),
192
- occurrenceIndex: z.number()
193
- }),
195
+ ok: z.literal(false),
196
+ reason: z.enum(["no-config", "already-running", "no-tests"])
197
+ })
198
+ ]);
199
+ var StopResponseSchema = z.discriminatedUnion("ok", [
200
+ z.object({ ok: z.literal(true) }),
194
201
  z.object({
195
- visualName: z.string(),
196
- kind: z.literal("unnamed"),
197
- occurrenceIndex: z.number()
202
+ ok: z.literal(false),
203
+ reason: z.literal("not-running")
204
+ })
205
+ ]);
206
+
207
+ // src/schemas.ts
208
+ var LocationSchema = z2.object({
209
+ file: z2.string(),
210
+ line: z2.number(),
211
+ column: z2.number().optional()
212
+ });
213
+ var VisualSourceSchema = z2.enum(["comparison", "baseline-only", "declared-only"]);
214
+ var ImagesSchema = z2.object({
215
+ actual: z2.string().optional(),
216
+ expect: z2.string().optional(),
217
+ diff: z2.string().optional(),
218
+ error: z2.string().optional(),
219
+ source: VisualSourceSchema.optional()
220
+ });
221
+ var ScreenshotDeclarationSchema = z2.discriminatedUnion("kind", [
222
+ z2.object({
223
+ visualName: z2.string(),
224
+ kind: z2.literal("named"),
225
+ declaredName: z2.string(),
226
+ snapshotBaseName: z2.string(),
227
+ occurrenceIndex: z2.number()
228
+ }),
229
+ z2.object({
230
+ visualName: z2.string(),
231
+ kind: z2.literal("unnamed"),
232
+ occurrenceIndex: z2.number()
198
233
  })
199
234
  ]);
200
- var AttachmentSchema = z.object({
201
- name: z.string(),
202
- path: z.string(),
203
- contentType: z.string()
235
+ var AttachmentSchema = z2.object({
236
+ name: z2.string(),
237
+ path: z2.string(),
238
+ contentType: z2.string()
204
239
  });
205
- var TestStatusSchema = z.enum(["unknown", "pending", "running", "failed", "approved", "success", "retrying"]);
206
- var TestResultStatusSchema = z.enum(["failed", "success", "pending"]);
207
- var TestResultSchema = z.object({
240
+ var TestStatusSchema = z2.enum(["unknown", "pending", "running", "failed", "approved", "success", "retrying"]);
241
+ var TestResultStatusSchema = z2.enum(["failed", "success", "pending"]);
242
+ var TestResultSchema = z2.object({
208
243
  status: TestResultStatusSchema,
209
- retries: z.number(),
210
- images: z.record(z.string(), ImagesSchema).optional(),
211
- visualDeclarations: z.array(ScreenshotDeclarationSchema).optional(),
212
- error: z.string().optional(),
213
- duration: z.number().optional()
244
+ retries: z2.number(),
245
+ images: z2.record(z2.string(), ImagesSchema).optional(),
246
+ visualDeclarations: z2.array(ScreenshotDeclarationSchema).optional(),
247
+ error: z2.string().optional(),
248
+ duration: z2.number().optional()
214
249
  });
215
- var TestDataSchema = z.object({
216
- id: z.string(),
217
- titlePath: z.array(z.string()),
218
- browser: z.string(),
219
- projectName: z.string().optional(),
220
- title: z.string(),
221
- skip: z.union([z.boolean(), z.string()]).optional(),
222
- retries: z.number().optional(),
250
+ var TestDataSchema = z2.object({
251
+ id: z2.string(),
252
+ titlePath: z2.array(z2.string()),
253
+ browser: z2.string(),
254
+ projectName: z2.string().optional(),
255
+ title: z2.string(),
256
+ skip: z2.union([z2.boolean(), z2.string()]).optional(),
257
+ retries: z2.number().optional(),
223
258
  status: TestStatusSchema.optional(),
224
- results: z.array(TestResultSchema).optional(),
225
- approved: z.record(z.string(), z.number()).nullable().optional(),
226
- attachments: z.array(AttachmentSchema).optional(),
259
+ results: z2.array(TestResultSchema).optional(),
260
+ approved: z2.record(z2.string(), z2.number()).nullable().optional(),
261
+ attachments: z2.array(AttachmentSchema).optional(),
227
262
  location: LocationSchema.optional()
228
263
  });
229
264
  var CrvyRprtrTestSchema = TestDataSchema.extend({
230
- checked: z.boolean()
265
+ checked: z2.boolean()
231
266
  });
232
- var CrvyRprtrSuiteSchema = z.lazy(
233
- () => z.object({
234
- path: z.array(z.string()),
235
- skip: z.boolean(),
267
+ var CrvyRprtrSuiteSchema = z2.lazy(
268
+ () => z2.object({
269
+ path: z2.array(z2.string()),
270
+ skip: z2.boolean(),
236
271
  status: TestStatusSchema.optional(),
237
- opened: z.boolean(),
238
- checked: z.boolean(),
239
- indeterminate: z.boolean(),
240
- children: z.record(z.string(), z.union([CrvyRprtrSuiteSchema, CrvyRprtrTestSchema])).optional()
272
+ opened: z2.boolean(),
273
+ checked: z2.boolean(),
274
+ indeterminate: z2.boolean(),
275
+ children: z2.record(z2.string(), z2.union([CrvyRprtrSuiteSchema, CrvyRprtrTestSchema])).optional()
241
276
  })
242
277
  );
243
- var IncomingWebSocketMessageSchema = z.object({
244
- type: z.enum(["test-begin", "test-end", "run-end", "approve", "sync", "register"]),
245
- data: z.unknown()
278
+ var IncomingWebSocketMessageSchema = z2.object({
279
+ type: z2.enum(["test-begin", "test-end", "run-end", "approve", "sync", "register"]),
280
+ data: z2.unknown()
246
281
  });
247
- var WebSocketMessageSchema = z.discriminatedUnion("type", [
248
- z.object({ type: z.literal("test-begin"), data: TestDataSchema }),
249
- z.object({ type: z.literal("test-update"), data: TestDataSchema }),
250
- z.object({
251
- type: z.literal("run-end"),
252
- data: z.object({
253
- status: z.enum(["passed", "failed", "skipped"]),
254
- removedTestIds: z.array(z.string())
282
+ var WebSocketMessageSchema = z2.discriminatedUnion("type", [
283
+ z2.object({ type: z2.literal("test-begin"), data: TestDataSchema }),
284
+ z2.object({ type: z2.literal("test-update"), data: TestDataSchema }),
285
+ z2.object({
286
+ type: z2.literal("run-end"),
287
+ data: z2.object({
288
+ status: z2.enum(["passed", "failed", "skipped"]),
289
+ removedTestIds: z2.array(z2.string())
255
290
  })
256
291
  }),
257
- z.object({
258
- type: z.literal("sync"),
259
- data: z.object({
260
- tests: z.record(z.string(), TestDataSchema),
261
- isUpdateMode: z.boolean().optional()
292
+ z2.object({
293
+ type: z2.literal("sync"),
294
+ data: z2.object({
295
+ tests: z2.record(z2.string(), TestDataSchema),
296
+ isUpdateMode: z2.boolean().optional()
262
297
  })
263
298
  }),
264
- z.object({ type: z.literal("approve"), data: z.unknown() })
299
+ z2.object({ type: z2.literal("approve"), data: z2.unknown() }),
300
+ z2.object({
301
+ type: z2.literal("run-status"),
302
+ data: z2.object({
303
+ running: z2.boolean()
304
+ })
305
+ })
265
306
  ]);
266
- var TestBeginDataSchema = z.object({
267
- id: z.string(),
268
- title: z.string(),
269
- titlePath: z.array(z.string()),
270
- browser: z.string(),
271
- projectName: z.string().optional(),
307
+ var TestBeginDataSchema = z2.object({
308
+ id: z2.string(),
309
+ title: z2.string(),
310
+ titlePath: z2.array(z2.string()),
311
+ browser: z2.string(),
312
+ projectName: z2.string().optional(),
272
313
  location: LocationSchema
273
314
  });
274
- var TestEndDataSchema = z.object({
275
- id: z.string(),
276
- status: z.enum(["passed", "failed", "skipped"]),
277
- attachments: z.array(AttachmentSchema),
278
- visualNames: z.array(z.string()).default([]),
279
- visualDeclarations: z.preprocess(
315
+ var TestEndDataSchema = z2.object({
316
+ id: z2.string(),
317
+ status: z2.enum(["passed", "failed", "skipped"]),
318
+ attachments: z2.array(AttachmentSchema),
319
+ visualNames: z2.array(z2.string()).default([]),
320
+ visualDeclarations: z2.preprocess(
280
321
  (value) => value === null ? void 0 : value,
281
- z.array(ScreenshotDeclarationSchema).optional()
322
+ z2.array(ScreenshotDeclarationSchema).optional()
282
323
  ),
283
- error: z.string().optional(),
284
- duration: z.number().optional()
324
+ error: z2.string().optional(),
325
+ duration: z2.number().optional()
285
326
  });
286
- var RunEndDataSchema = z.object({
287
- status: z.enum(["passed", "failed", "skipped"])
327
+ var RunEndDataSchema = z2.object({
328
+ status: z2.enum(["passed", "failed", "skipped"])
288
329
  });
289
- var RegisterDataSchema = z.object({
290
- playwrightSnapshotDir: z.string().optional(),
291
- playwrightTestDir: z.string().optional(),
292
- playwrightSnapshotPathTemplate: z.string().optional(),
293
- playwrightToHaveScreenshotPathTemplate: z.string().optional()
330
+ var RegisterDataSchema = z2.object({
331
+ playwrightSnapshotDir: z2.string().optional(),
332
+ playwrightTestDir: z2.string().optional(),
333
+ playwrightSnapshotPathTemplate: z2.string().optional(),
334
+ playwrightToHaveScreenshotPathTemplate: z2.string().optional(),
335
+ configFile: z2.string().optional(),
336
+ cwd: z2.string().optional()
294
337
  });
295
- var ReportDataSchema = z.object({
296
- isRunning: z.boolean(),
297
- tests: z.record(z.string(), TestDataSchema),
298
- browsers: z.array(z.string()),
299
- isUpdateMode: z.boolean(),
300
- screenshotDir: z.string()
338
+ var ReportDataSchema = z2.object({
339
+ isRunning: z2.boolean(),
340
+ tests: z2.record(z2.string(), TestDataSchema),
341
+ browsers: z2.array(z2.string()),
342
+ isUpdateMode: z2.boolean(),
343
+ screenshotDir: z2.string()
301
344
  });
302
- var LoadedReportDataSchema = z.object({
303
- tests: z.record(z.string(), TestDataSchema).optional(),
304
- isUpdateMode: z.boolean().optional()
345
+ var LoadedReportDataSchema = z2.object({
346
+ tests: z2.record(z2.string(), TestDataSchema).optional(),
347
+ isUpdateMode: z2.boolean().optional()
305
348
  });
306
- var OfflineEventSchema = z.object({
307
- type: z.enum(["test-begin", "test-end", "run-end"]),
308
- data: z.unknown(),
309
- timestamp: z.number(),
310
- workerIndex: z.number()
349
+ var OfflineEventSchema = z2.object({
350
+ type: z2.enum(["test-begin", "test-end", "run-end"]),
351
+ data: z2.unknown(),
352
+ timestamp: z2.number(),
353
+ workerIndex: z2.number()
311
354
  });
312
- var OfflineReportSchema = z.object({
313
- version: z.number(),
314
- generatedAt: z.string(),
315
- workers: z.number(),
316
- events: z.array(OfflineEventSchema)
355
+ var OfflineReportSchema = z2.object({
356
+ version: z2.number(),
357
+ generatedAt: z2.string(),
358
+ workers: z2.number(),
359
+ events: z2.array(OfflineEventSchema)
317
360
  });
318
- var ApproveRequestBodySchema = z.object({
319
- id: z.string(),
320
- retry: z.number(),
321
- image: z.string()
361
+ var ReportApiResponseSchema = z2.object({
362
+ tests: z2.record(z2.string(), TestDataSchema),
363
+ isUpdateMode: z2.boolean().optional(),
364
+ isRunning: z2.boolean().optional(),
365
+ runEnabled: z2.boolean().optional()
322
366
  });
323
- var ReportApiResponseSchema = z.object({
324
- tests: z.record(z.string(), TestDataSchema),
325
- isUpdateMode: z.boolean().optional()
326
- });
327
- var ClientBootstrapDataSchema = z.object({
367
+ var ClientBootstrapDataSchema = z2.object({
328
368
  report: ReportApiResponseSchema.extend({
329
- isUpdateMode: z.boolean()
369
+ isUpdateMode: z2.boolean()
330
370
  }),
331
- liveUpdates: z.boolean(),
332
- approvalEnabled: z.boolean(),
333
- approvalMessage: z.string().optional()
371
+ liveUpdates: z2.boolean(),
372
+ approvalEnabled: z2.boolean(),
373
+ approvalMessage: z2.string().optional(),
374
+ runEnabled: z2.boolean().optional(),
375
+ isRunning: z2.boolean().optional()
334
376
  });
335
- var ImagesViewModeSchema = z.enum(["side-by-side", "swap", "slide", "blend"]);
377
+ var ImagesViewModeSchema = z2.enum(["side-by-side", "swap", "slide", "blend"]);
336
378
  function safeParse(schema, data) {
337
379
  const result = schema.safeParse(data);
338
380
  if (result.success) {
@@ -484,7 +526,12 @@ function createMutableReportState(screenshotDir = "./screenshots") {
484
526
  function applyTestBeginEvent(state, data) {
485
527
  const { id, title, titlePath, browser, projectName, location } = data;
486
528
  state.currentRunIds.add(id);
487
- state.reportData.tests[id] ??= {
529
+ const existing = state.reportData.tests[id];
530
+ if (existing !== void 0) {
531
+ existing.status = "running";
532
+ return existing;
533
+ }
534
+ const created = {
488
535
  id,
489
536
  titlePath: titlePath ?? [],
490
537
  browser: browser ?? "",
@@ -496,7 +543,8 @@ function applyTestBeginEvent(state, data) {
496
543
  location,
497
544
  status: "running"
498
545
  };
499
- return state.reportData.tests[id];
546
+ state.reportData.tests[id] = created;
547
+ return created;
500
548
  }
501
549
  function applyTestEndEvent(state, data, options = {}) {
502
550
  const test = state.reportData.tests[data.id];
@@ -534,11 +582,13 @@ function applyTestEndEvent(state, data, options = {}) {
534
582
  diffCount
535
583
  };
536
584
  }
537
- function finalizeRunEvent(state) {
585
+ function finalizeRunEvent(state, options = {}) {
538
586
  state.reportData.isRunning = false;
539
- state.reportData.tests = Object.fromEntries(
540
- Object.entries(state.reportData.tests).filter(([id]) => state.currentRunIds.has(id))
541
- );
587
+ if (options.preserveNonCurrent !== true) {
588
+ state.reportData.tests = Object.fromEntries(
589
+ Object.entries(state.reportData.tests).filter(([id]) => state.currentRunIds.has(id))
590
+ );
591
+ }
542
592
  state.currentRunIds.clear();
543
593
  const runTests = Object.values(state.reportData.tests).filter((test) => test !== void 0);
544
594
  return {
@@ -554,6 +604,8 @@ export {
554
604
  applyTestBeginEvent,
555
605
  applyTestEndEvent,
556
606
  finalizeRunEvent,
607
+ ApproveRequestBodySchema,
608
+ RunRequestBodySchema,
557
609
  IncomingWebSocketMessageSchema,
558
610
  TestBeginDataSchema,
559
611
  TestEndDataSchema,
@@ -561,7 +613,6 @@ export {
561
613
  RegisterDataSchema,
562
614
  LoadedReportDataSchema,
563
615
  OfflineReportSchema,
564
- ApproveRequestBodySchema,
565
616
  ClientBootstrapDataSchema,
566
617
  safeParse,
567
618
  withResolvedVisualNames,