doc-detective 4.32.0 → 4.33.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/common/src/schemas/schemas.json +1288 -126
- package/dist/common/src/types/generated/record_v3.d.ts +21 -2
- package/dist/common/src/types/generated/record_v3.d.ts.map +1 -1
- package/dist/common/src/types/generated/step_v3.d.ts +21 -2
- package/dist/common/src/types/generated/step_v3.d.ts.map +1 -1
- package/dist/common/src/types/generated/test_v3.d.ts +42 -4
- package/dist/common/src/types/generated/test_v3.d.ts.map +1 -1
- package/dist/core/tests/ffmpegRecorder.d.ts.map +1 -1
- package/dist/core/tests/ffmpegRecorder.js +17 -2
- package/dist/core/tests/ffmpegRecorder.js.map +1 -1
- package/dist/core/tests/recordingCheckpoints.d.ts +76 -0
- package/dist/core/tests/recordingCheckpoints.d.ts.map +1 -0
- package/dist/core/tests/recordingCheckpoints.js +335 -0
- package/dist/core/tests/recordingCheckpoints.js.map +1 -0
- package/dist/core/tests/saveScreenshot.d.ts +5 -1
- package/dist/core/tests/saveScreenshot.d.ts.map +1 -1
- package/dist/core/tests/saveScreenshot.js +46 -12
- package/dist/core/tests/saveScreenshot.js.map +1 -1
- package/dist/core/tests/startRecording.d.ts.map +1 -1
- package/dist/core/tests/startRecording.js +26 -10
- package/dist/core/tests/startRecording.js.map +1 -1
- package/dist/core/tests/stopRecording.d.ts.map +1 -1
- package/dist/core/tests/stopRecording.js +283 -14
- package/dist/core/tests/stopRecording.js.map +1 -1
- package/dist/core/tests.d.ts.map +1 -1
- package/dist/core/tests.js +53 -37
- package/dist/core/tests.js.map +1 -1
- package/dist/hints/context.d.ts +1 -0
- package/dist/hints/context.d.ts.map +1 -1
- package/dist/hints/context.js +9 -0
- package/dist/hints/context.js.map +1 -1
- package/dist/hints/hints.d.ts.map +1 -1
- package/dist/hints/hints.js +15 -0
- package/dist/hints/hints.js.map +1 -1
- package/dist/hints/types.d.ts +8 -0
- package/dist/hints/types.d.ts.map +1 -1
- package/dist/index.cjs +1909 -325
- package/package.json +1 -1
package/dist/index.cjs
CHANGED
|
@@ -30470,9 +30470,10 @@ var init_schemas = __esm({
|
|
|
30470
30470
|
anyOf: [
|
|
30471
30471
|
{
|
|
30472
30472
|
title: "Screenshot (simple)",
|
|
30473
|
+
$comment: "The pattern gates the target's EXTENSION, not its characters or location: any path ending in .png/.PNG is accepted, plus an http(s) URL to a PNG (optionally with a query string, for signed URLs) and a `$VAR` reference. It deliberately does not restrict the character set \u2014 an earlier pattern allowed any Windows absolute path but limited non-Windows paths to [A-Za-z0-9_./\\-], so ordinary macOS/Linux projects (a space, parentheses, '~', or non-ASCII anywhere in the path) failed validation, including for the absolute paths doc-detective synthesizes internally for autoScreenshot and recording checkpoints. That charset never bounded WHERE a screenshot could be written (traversal like ../../x.png always passed), so it only made non-Windows projects second-class. See ADR 01077.",
|
|
30473
30474
|
description: "File path of the PNG file. Accepts absolute paths. If not specified, the file name is the ID of the step. If an `http(s)` URL is supplied, the remote image is downloaded and used as a read-only reference for comparison; the new capture is written to a local run-specific folder instead of being uploaded back to the URL.",
|
|
30474
30475
|
type: "string",
|
|
30475
|
-
pattern: "^(?:https?:\\/\\/.+\\.(?:png|PNG)(?:\\?.*)
|
|
30476
|
+
pattern: "^(?:https?:\\/\\/.+\\.(?:png|PNG)(?:\\?.*)?|.*\\.(?:png|PNG)|\\$[A-Za-z0-9_]+)$",
|
|
30476
30477
|
transform: [
|
|
30477
30478
|
"trim"
|
|
30478
30479
|
]
|
|
@@ -30706,9 +30707,10 @@ var init_schemas = __esm({
|
|
|
30706
30707
|
},
|
|
30707
30708
|
path: {
|
|
30708
30709
|
title: "Screenshot (simple)",
|
|
30710
|
+
$comment: "The pattern gates the target's EXTENSION, not its characters or location: any path ending in .png/.PNG is accepted, plus an http(s) URL to a PNG (optionally with a query string, for signed URLs) and a `$VAR` reference. It deliberately does not restrict the character set \u2014 an earlier pattern allowed any Windows absolute path but limited non-Windows paths to [A-Za-z0-9_./\\-], so ordinary macOS/Linux projects (a space, parentheses, '~', or non-ASCII anywhere in the path) failed validation, including for the absolute paths doc-detective synthesizes internally for autoScreenshot and recording checkpoints. That charset never bounded WHERE a screenshot could be written (traversal like ../../x.png always passed), so it only made non-Windows projects second-class. See ADR 01077.",
|
|
30709
30711
|
description: "File path of the PNG file. Accepts absolute paths. If not specified, the file name is the ID of the step. If an `http(s)` URL is supplied, the remote image is downloaded and used as a read-only reference for comparison; the new capture is written to a local run-specific folder instead of being uploaded back to the URL.",
|
|
30710
30712
|
type: "string",
|
|
30711
|
-
pattern: "^(?:https?:\\/\\/.+\\.(?:png|PNG)(?:\\?.*)
|
|
30713
|
+
pattern: "^(?:https?:\\/\\/.+\\.(?:png|PNG)(?:\\?.*)?|.*\\.(?:png|PNG)|\\$[A-Za-z0-9_]+)$",
|
|
30712
30714
|
transform: [
|
|
30713
30715
|
"trim"
|
|
30714
30716
|
]
|
|
@@ -30966,9 +30968,10 @@ var init_schemas = __esm({
|
|
|
30966
30968
|
schemas: {
|
|
30967
30969
|
path: {
|
|
30968
30970
|
title: "Screenshot (simple)",
|
|
30971
|
+
$comment: "The pattern gates the target's EXTENSION, not its characters or location: any path ending in .png/.PNG is accepted, plus an http(s) URL to a PNG (optionally with a query string, for signed URLs) and a `$VAR` reference. It deliberately does not restrict the character set \u2014 an earlier pattern allowed any Windows absolute path but limited non-Windows paths to [A-Za-z0-9_./\\-], so ordinary macOS/Linux projects (a space, parentheses, '~', or non-ASCII anywhere in the path) failed validation, including for the absolute paths doc-detective synthesizes internally for autoScreenshot and recording checkpoints. That charset never bounded WHERE a screenshot could be written (traversal like ../../x.png always passed), so it only made non-Windows projects second-class. See ADR 01077.",
|
|
30969
30972
|
description: "File path of the PNG file. Accepts absolute paths. If not specified, the file name is the ID of the step. If an `http(s)` URL is supplied, the remote image is downloaded and used as a read-only reference for comparison; the new capture is written to a local run-specific folder instead of being uploaded back to the URL.",
|
|
30970
30973
|
type: "string",
|
|
30971
|
-
pattern: "^(?:https?:\\/\\/.+\\.(?:png|PNG)(?:\\?.*)
|
|
30974
|
+
pattern: "^(?:https?:\\/\\/.+\\.(?:png|PNG)(?:\\?.*)?|.*\\.(?:png|PNG)|\\$[A-Za-z0-9_]+)$",
|
|
30972
30975
|
transform: [
|
|
30973
30976
|
"trim"
|
|
30974
30977
|
]
|
|
@@ -31202,9 +31205,10 @@ var init_schemas = __esm({
|
|
|
31202
31205
|
},
|
|
31203
31206
|
path: {
|
|
31204
31207
|
title: "Screenshot (simple)",
|
|
31208
|
+
$comment: "The pattern gates the target's EXTENSION, not its characters or location: any path ending in .png/.PNG is accepted, plus an http(s) URL to a PNG (optionally with a query string, for signed URLs) and a `$VAR` reference. It deliberately does not restrict the character set \u2014 an earlier pattern allowed any Windows absolute path but limited non-Windows paths to [A-Za-z0-9_./\\-], so ordinary macOS/Linux projects (a space, parentheses, '~', or non-ASCII anywhere in the path) failed validation, including for the absolute paths doc-detective synthesizes internally for autoScreenshot and recording checkpoints. That charset never bounded WHERE a screenshot could be written (traversal like ../../x.png always passed), so it only made non-Windows projects second-class. See ADR 01077.",
|
|
31205
31209
|
description: "File path of the PNG file. Accepts absolute paths. If not specified, the file name is the ID of the step. If an `http(s)` URL is supplied, the remote image is downloaded and used as a read-only reference for comparison; the new capture is written to a local run-specific folder instead of being uploaded back to the URL.",
|
|
31206
31210
|
type: "string",
|
|
31207
|
-
pattern: "^(?:https?:\\/\\/.+\\.(?:png|PNG)(?:\\?.*)
|
|
31211
|
+
pattern: "^(?:https?:\\/\\/.+\\.(?:png|PNG)(?:\\?.*)?|.*\\.(?:png|PNG)|\\$[A-Za-z0-9_]+)$",
|
|
31208
31212
|
transform: [
|
|
31209
31213
|
"trim"
|
|
31210
31214
|
]
|
|
@@ -31678,9 +31682,10 @@ var init_schemas = __esm({
|
|
|
31678
31682
|
},
|
|
31679
31683
|
path: {
|
|
31680
31684
|
title: "Screenshot (simple)",
|
|
31685
|
+
$comment: "The pattern gates the target's EXTENSION, not its characters or location: any path ending in .png/.PNG is accepted, plus an http(s) URL to a PNG (optionally with a query string, for signed URLs) and a `$VAR` reference. It deliberately does not restrict the character set \u2014 an earlier pattern allowed any Windows absolute path but limited non-Windows paths to [A-Za-z0-9_./\\-], so ordinary macOS/Linux projects (a space, parentheses, '~', or non-ASCII anywhere in the path) failed validation, including for the absolute paths doc-detective synthesizes internally for autoScreenshot and recording checkpoints. That charset never bounded WHERE a screenshot could be written (traversal like ../../x.png always passed), so it only made non-Windows projects second-class. See ADR 01077.",
|
|
31681
31686
|
description: "File path of the PNG file. Accepts absolute paths. If not specified, the file name is the ID of the step. If an `http(s)` URL is supplied, the remote image is downloaded and used as a read-only reference for comparison; the new capture is written to a local run-specific folder instead of being uploaded back to the URL.",
|
|
31682
31687
|
type: "string",
|
|
31683
|
-
pattern: "^(?:https?:\\/\\/.+\\.(?:png|PNG)(?:\\?.*)
|
|
31688
|
+
pattern: "^(?:https?:\\/\\/.+\\.(?:png|PNG)(?:\\?.*)?|.*\\.(?:png|PNG)|\\$[A-Za-z0-9_]+)$",
|
|
31684
31689
|
transform: [
|
|
31685
31690
|
"trim"
|
|
31686
31691
|
]
|
|
@@ -32062,6 +32067,7 @@ var init_schemas = __esm({
|
|
|
32062
32067
|
"image.png",
|
|
32063
32068
|
"static/images/image.png",
|
|
32064
32069
|
"/User/manny/projects/doc-detective/static/images/image.png",
|
|
32070
|
+
"/Users/jane doe/projects/my docs (v2)/static/images/image.png",
|
|
32065
32071
|
"https://example.com/static/images/image.png",
|
|
32066
32072
|
{
|
|
32067
32073
|
path: "https://promptless-customer-doc-assets.s3.amazonaws.com/docs-images/request-changes-button-0c851bb3.png",
|
|
@@ -34496,10 +34502,11 @@ var init_schemas = __esm({
|
|
|
34496
34502
|
},
|
|
34497
34503
|
overwrite: {
|
|
34498
34504
|
type: "string",
|
|
34499
|
-
description: "If `true`, overwrites the existing recording at `path` if it exists.",
|
|
34505
|
+
description: "If `true`, overwrites the existing recording at `path` if it exists. If `false`, skips the recording when the file already exists. If `aboveVariation`, always records, but replaces the existing file (and its checkpoint baselines) only when the span's checkpoint screenshots show it meaningfully changed \u2014 requires `checkpoints`, so it turns them on with defaults when `checkpoints` is omitted or `false`; set `checkpoints` to an object to tune `maxVariation` or `directory`.",
|
|
34500
34506
|
enum: [
|
|
34501
34507
|
"true",
|
|
34502
|
-
"false"
|
|
34508
|
+
"false",
|
|
34509
|
+
"aboveVariation"
|
|
34503
34510
|
]
|
|
34504
34511
|
},
|
|
34505
34512
|
name: {
|
|
@@ -34557,6 +34564,38 @@ var init_schemas = __esm({
|
|
|
34557
34564
|
}
|
|
34558
34565
|
}
|
|
34559
34566
|
]
|
|
34567
|
+
},
|
|
34568
|
+
checkpoints: {
|
|
34569
|
+
title: "Recording checkpoints",
|
|
34570
|
+
description: "Capture a checkpoint screenshot after every step while this recording is active and compare each against a persistent baseline stored beside the recording (`<path>.checkpoints/` by default). Baselines seed on the first run; on later runs, per-checkpoint variation is reported in the `stopRecord` step's outputs, and variation beyond `maxVariation` surfaces as a WARNING. If `false` or unset, no checkpoints are captured.",
|
|
34571
|
+
anyOf: [
|
|
34572
|
+
{
|
|
34573
|
+
type: "boolean",
|
|
34574
|
+
title: "Recording checkpoints (boolean)",
|
|
34575
|
+
description: "If `true`, enables checkpoints with default settings."
|
|
34576
|
+
},
|
|
34577
|
+
{
|
|
34578
|
+
type: "object",
|
|
34579
|
+
title: "Recording checkpoints (detailed)",
|
|
34580
|
+
additionalProperties: false,
|
|
34581
|
+
properties: {
|
|
34582
|
+
maxVariation: {
|
|
34583
|
+
type: "number",
|
|
34584
|
+
description: "Maximum fractional pixel difference tolerated between a checkpoint and its baseline before the drift surfaces as a WARNING.",
|
|
34585
|
+
default: 0.05,
|
|
34586
|
+
minimum: 0,
|
|
34587
|
+
maximum: 1
|
|
34588
|
+
},
|
|
34589
|
+
directory: {
|
|
34590
|
+
type: "string",
|
|
34591
|
+
description: "Directory for the checkpoint baselines. If unset, defaults to a `.checkpoints` directory beside the recording (for example, `demo.mp4.checkpoints/`).",
|
|
34592
|
+
transform: [
|
|
34593
|
+
"trim"
|
|
34594
|
+
]
|
|
34595
|
+
}
|
|
34596
|
+
}
|
|
34597
|
+
}
|
|
34598
|
+
]
|
|
34560
34599
|
}
|
|
34561
34600
|
},
|
|
34562
34601
|
title: "Record (detailed)"
|
|
@@ -34818,10 +34857,11 @@ var init_schemas = __esm({
|
|
|
34818
34857
|
},
|
|
34819
34858
|
overwrite: {
|
|
34820
34859
|
type: "string",
|
|
34821
|
-
description: "If `true`, overwrites the existing recording at `path` if it exists.",
|
|
34860
|
+
description: "If `true`, overwrites the existing recording at `path` if it exists. If `false`, skips the recording when the file already exists. If `aboveVariation`, always records, but replaces the existing file (and its checkpoint baselines) only when the span's checkpoint screenshots show it meaningfully changed \u2014 requires `checkpoints`, so it turns them on with defaults when `checkpoints` is omitted or `false`; set `checkpoints` to an object to tune `maxVariation` or `directory`.",
|
|
34822
34861
|
enum: [
|
|
34823
34862
|
"true",
|
|
34824
|
-
"false"
|
|
34863
|
+
"false",
|
|
34864
|
+
"aboveVariation"
|
|
34825
34865
|
]
|
|
34826
34866
|
},
|
|
34827
34867
|
name: {
|
|
@@ -34879,6 +34919,38 @@ var init_schemas = __esm({
|
|
|
34879
34919
|
}
|
|
34880
34920
|
}
|
|
34881
34921
|
]
|
|
34922
|
+
},
|
|
34923
|
+
checkpoints: {
|
|
34924
|
+
title: "Recording checkpoints",
|
|
34925
|
+
description: "Capture a checkpoint screenshot after every step while this recording is active and compare each against a persistent baseline stored beside the recording (`<path>.checkpoints/` by default). Baselines seed on the first run; on later runs, per-checkpoint variation is reported in the `stopRecord` step's outputs, and variation beyond `maxVariation` surfaces as a WARNING. If `false` or unset, no checkpoints are captured.",
|
|
34926
|
+
anyOf: [
|
|
34927
|
+
{
|
|
34928
|
+
type: "boolean",
|
|
34929
|
+
title: "Recording checkpoints (boolean)",
|
|
34930
|
+
description: "If `true`, enables checkpoints with default settings."
|
|
34931
|
+
},
|
|
34932
|
+
{
|
|
34933
|
+
type: "object",
|
|
34934
|
+
title: "Recording checkpoints (detailed)",
|
|
34935
|
+
additionalProperties: false,
|
|
34936
|
+
properties: {
|
|
34937
|
+
maxVariation: {
|
|
34938
|
+
type: "number",
|
|
34939
|
+
description: "Maximum fractional pixel difference tolerated between a checkpoint and its baseline before the drift surfaces as a WARNING.",
|
|
34940
|
+
default: 0.05,
|
|
34941
|
+
minimum: 0,
|
|
34942
|
+
maximum: 1
|
|
34943
|
+
},
|
|
34944
|
+
directory: {
|
|
34945
|
+
type: "string",
|
|
34946
|
+
description: "Directory for the checkpoint baselines. If unset, defaults to a `.checkpoints` directory beside the recording (for example, `demo.mp4.checkpoints/`).",
|
|
34947
|
+
transform: [
|
|
34948
|
+
"trim"
|
|
34949
|
+
]
|
|
34950
|
+
}
|
|
34951
|
+
}
|
|
34952
|
+
}
|
|
34953
|
+
]
|
|
34882
34954
|
}
|
|
34883
34955
|
},
|
|
34884
34956
|
title: "Record (detailed)"
|
|
@@ -34945,6 +35017,17 @@ var init_schemas = __esm({
|
|
|
34945
35017
|
path: "results.mp4",
|
|
34946
35018
|
engine: "ffmpeg"
|
|
34947
35019
|
},
|
|
35020
|
+
{
|
|
35021
|
+
path: "results.mp4",
|
|
35022
|
+
checkpoints: true
|
|
35023
|
+
},
|
|
35024
|
+
{
|
|
35025
|
+
path: "results.mp4",
|
|
35026
|
+
checkpoints: {
|
|
35027
|
+
maxVariation: 0.02,
|
|
35028
|
+
directory: "baselines/results"
|
|
35029
|
+
}
|
|
35030
|
+
},
|
|
34948
35031
|
{
|
|
34949
35032
|
path: "results.mp4",
|
|
34950
35033
|
engine: {
|
|
@@ -76109,9 +76192,10 @@ var init_schemas = __esm({
|
|
|
76109
76192
|
anyOf: [
|
|
76110
76193
|
{
|
|
76111
76194
|
title: "Screenshot (simple)",
|
|
76195
|
+
$comment: "The pattern gates the target's EXTENSION, not its characters or location: any path ending in .png/.PNG is accepted, plus an http(s) URL to a PNG (optionally with a query string, for signed URLs) and a `$VAR` reference. It deliberately does not restrict the character set \u2014 an earlier pattern allowed any Windows absolute path but limited non-Windows paths to [A-Za-z0-9_./\\-], so ordinary macOS/Linux projects (a space, parentheses, '~', or non-ASCII anywhere in the path) failed validation, including for the absolute paths doc-detective synthesizes internally for autoScreenshot and recording checkpoints. That charset never bounded WHERE a screenshot could be written (traversal like ../../x.png always passed), so it only made non-Windows projects second-class. See ADR 01077.",
|
|
76112
76196
|
description: "File path of the PNG file. Accepts absolute paths. If not specified, the file name is the ID of the step. If an `http(s)` URL is supplied, the remote image is downloaded and used as a read-only reference for comparison; the new capture is written to a local run-specific folder instead of being uploaded back to the URL.",
|
|
76113
76197
|
type: "string",
|
|
76114
|
-
pattern: "^(?:https?:\\/\\/.+\\.(?:png|PNG)(?:\\?.*)
|
|
76198
|
+
pattern: "^(?:https?:\\/\\/.+\\.(?:png|PNG)(?:\\?.*)?|.*\\.(?:png|PNG)|\\$[A-Za-z0-9_]+)$",
|
|
76115
76199
|
transform: [
|
|
76116
76200
|
"trim"
|
|
76117
76201
|
]
|
|
@@ -76345,9 +76429,10 @@ var init_schemas = __esm({
|
|
|
76345
76429
|
},
|
|
76346
76430
|
path: {
|
|
76347
76431
|
title: "Screenshot (simple)",
|
|
76432
|
+
$comment: "The pattern gates the target's EXTENSION, not its characters or location: any path ending in .png/.PNG is accepted, plus an http(s) URL to a PNG (optionally with a query string, for signed URLs) and a `$VAR` reference. It deliberately does not restrict the character set \u2014 an earlier pattern allowed any Windows absolute path but limited non-Windows paths to [A-Za-z0-9_./\\-], so ordinary macOS/Linux projects (a space, parentheses, '~', or non-ASCII anywhere in the path) failed validation, including for the absolute paths doc-detective synthesizes internally for autoScreenshot and recording checkpoints. That charset never bounded WHERE a screenshot could be written (traversal like ../../x.png always passed), so it only made non-Windows projects second-class. See ADR 01077.",
|
|
76348
76433
|
description: "File path of the PNG file. Accepts absolute paths. If not specified, the file name is the ID of the step. If an `http(s)` URL is supplied, the remote image is downloaded and used as a read-only reference for comparison; the new capture is written to a local run-specific folder instead of being uploaded back to the URL.",
|
|
76349
76434
|
type: "string",
|
|
76350
|
-
pattern: "^(?:https?:\\/\\/.+\\.(?:png|PNG)(?:\\?.*)
|
|
76435
|
+
pattern: "^(?:https?:\\/\\/.+\\.(?:png|PNG)(?:\\?.*)?|.*\\.(?:png|PNG)|\\$[A-Za-z0-9_]+)$",
|
|
76351
76436
|
transform: [
|
|
76352
76437
|
"trim"
|
|
76353
76438
|
]
|
|
@@ -76605,9 +76690,10 @@ var init_schemas = __esm({
|
|
|
76605
76690
|
schemas: {
|
|
76606
76691
|
path: {
|
|
76607
76692
|
title: "Screenshot (simple)",
|
|
76693
|
+
$comment: "The pattern gates the target's EXTENSION, not its characters or location: any path ending in .png/.PNG is accepted, plus an http(s) URL to a PNG (optionally with a query string, for signed URLs) and a `$VAR` reference. It deliberately does not restrict the character set \u2014 an earlier pattern allowed any Windows absolute path but limited non-Windows paths to [A-Za-z0-9_./\\-], so ordinary macOS/Linux projects (a space, parentheses, '~', or non-ASCII anywhere in the path) failed validation, including for the absolute paths doc-detective synthesizes internally for autoScreenshot and recording checkpoints. That charset never bounded WHERE a screenshot could be written (traversal like ../../x.png always passed), so it only made non-Windows projects second-class. See ADR 01077.",
|
|
76608
76694
|
description: "File path of the PNG file. Accepts absolute paths. If not specified, the file name is the ID of the step. If an `http(s)` URL is supplied, the remote image is downloaded and used as a read-only reference for comparison; the new capture is written to a local run-specific folder instead of being uploaded back to the URL.",
|
|
76609
76695
|
type: "string",
|
|
76610
|
-
pattern: "^(?:https?:\\/\\/.+\\.(?:png|PNG)(?:\\?.*)
|
|
76696
|
+
pattern: "^(?:https?:\\/\\/.+\\.(?:png|PNG)(?:\\?.*)?|.*\\.(?:png|PNG)|\\$[A-Za-z0-9_]+)$",
|
|
76611
76697
|
transform: [
|
|
76612
76698
|
"trim"
|
|
76613
76699
|
]
|
|
@@ -76841,9 +76927,10 @@ var init_schemas = __esm({
|
|
|
76841
76927
|
},
|
|
76842
76928
|
path: {
|
|
76843
76929
|
title: "Screenshot (simple)",
|
|
76930
|
+
$comment: "The pattern gates the target's EXTENSION, not its characters or location: any path ending in .png/.PNG is accepted, plus an http(s) URL to a PNG (optionally with a query string, for signed URLs) and a `$VAR` reference. It deliberately does not restrict the character set \u2014 an earlier pattern allowed any Windows absolute path but limited non-Windows paths to [A-Za-z0-9_./\\-], so ordinary macOS/Linux projects (a space, parentheses, '~', or non-ASCII anywhere in the path) failed validation, including for the absolute paths doc-detective synthesizes internally for autoScreenshot and recording checkpoints. That charset never bounded WHERE a screenshot could be written (traversal like ../../x.png always passed), so it only made non-Windows projects second-class. See ADR 01077.",
|
|
76844
76931
|
description: "File path of the PNG file. Accepts absolute paths. If not specified, the file name is the ID of the step. If an `http(s)` URL is supplied, the remote image is downloaded and used as a read-only reference for comparison; the new capture is written to a local run-specific folder instead of being uploaded back to the URL.",
|
|
76845
76932
|
type: "string",
|
|
76846
|
-
pattern: "^(?:https?:\\/\\/.+\\.(?:png|PNG)(?:\\?.*)
|
|
76933
|
+
pattern: "^(?:https?:\\/\\/.+\\.(?:png|PNG)(?:\\?.*)?|.*\\.(?:png|PNG)|\\$[A-Za-z0-9_]+)$",
|
|
76847
76934
|
transform: [
|
|
76848
76935
|
"trim"
|
|
76849
76936
|
]
|
|
@@ -77317,9 +77404,10 @@ var init_schemas = __esm({
|
|
|
77317
77404
|
},
|
|
77318
77405
|
path: {
|
|
77319
77406
|
title: "Screenshot (simple)",
|
|
77407
|
+
$comment: "The pattern gates the target's EXTENSION, not its characters or location: any path ending in .png/.PNG is accepted, plus an http(s) URL to a PNG (optionally with a query string, for signed URLs) and a `$VAR` reference. It deliberately does not restrict the character set \u2014 an earlier pattern allowed any Windows absolute path but limited non-Windows paths to [A-Za-z0-9_./\\-], so ordinary macOS/Linux projects (a space, parentheses, '~', or non-ASCII anywhere in the path) failed validation, including for the absolute paths doc-detective synthesizes internally for autoScreenshot and recording checkpoints. That charset never bounded WHERE a screenshot could be written (traversal like ../../x.png always passed), so it only made non-Windows projects second-class. See ADR 01077.",
|
|
77320
77408
|
description: "File path of the PNG file. Accepts absolute paths. If not specified, the file name is the ID of the step. If an `http(s)` URL is supplied, the remote image is downloaded and used as a read-only reference for comparison; the new capture is written to a local run-specific folder instead of being uploaded back to the URL.",
|
|
77321
77409
|
type: "string",
|
|
77322
|
-
pattern: "^(?:https?:\\/\\/.+\\.(?:png|PNG)(?:\\?.*)
|
|
77410
|
+
pattern: "^(?:https?:\\/\\/.+\\.(?:png|PNG)(?:\\?.*)?|.*\\.(?:png|PNG)|\\$[A-Za-z0-9_]+)$",
|
|
77323
77411
|
transform: [
|
|
77324
77412
|
"trim"
|
|
77325
77413
|
]
|
|
@@ -77701,6 +77789,7 @@ var init_schemas = __esm({
|
|
|
77701
77789
|
"image.png",
|
|
77702
77790
|
"static/images/image.png",
|
|
77703
77791
|
"/User/manny/projects/doc-detective/static/images/image.png",
|
|
77792
|
+
"/Users/jane doe/projects/my docs (v2)/static/images/image.png",
|
|
77704
77793
|
"https://example.com/static/images/image.png",
|
|
77705
77794
|
{
|
|
77706
77795
|
path: "https://promptless-customer-doc-assets.s3.amazonaws.com/docs-images/request-changes-button-0c851bb3.png",
|
|
@@ -80135,10 +80224,11 @@ var init_schemas = __esm({
|
|
|
80135
80224
|
},
|
|
80136
80225
|
overwrite: {
|
|
80137
80226
|
type: "string",
|
|
80138
|
-
description: "If `true`, overwrites the existing recording at `path` if it exists.",
|
|
80227
|
+
description: "If `true`, overwrites the existing recording at `path` if it exists. If `false`, skips the recording when the file already exists. If `aboveVariation`, always records, but replaces the existing file (and its checkpoint baselines) only when the span's checkpoint screenshots show it meaningfully changed \u2014 requires `checkpoints`, so it turns them on with defaults when `checkpoints` is omitted or `false`; set `checkpoints` to an object to tune `maxVariation` or `directory`.",
|
|
80139
80228
|
enum: [
|
|
80140
80229
|
"true",
|
|
80141
|
-
"false"
|
|
80230
|
+
"false",
|
|
80231
|
+
"aboveVariation"
|
|
80142
80232
|
]
|
|
80143
80233
|
},
|
|
80144
80234
|
name: {
|
|
@@ -80196,6 +80286,38 @@ var init_schemas = __esm({
|
|
|
80196
80286
|
}
|
|
80197
80287
|
}
|
|
80198
80288
|
]
|
|
80289
|
+
},
|
|
80290
|
+
checkpoints: {
|
|
80291
|
+
title: "Recording checkpoints",
|
|
80292
|
+
description: "Capture a checkpoint screenshot after every step while this recording is active and compare each against a persistent baseline stored beside the recording (`<path>.checkpoints/` by default). Baselines seed on the first run; on later runs, per-checkpoint variation is reported in the `stopRecord` step's outputs, and variation beyond `maxVariation` surfaces as a WARNING. If `false` or unset, no checkpoints are captured.",
|
|
80293
|
+
anyOf: [
|
|
80294
|
+
{
|
|
80295
|
+
type: "boolean",
|
|
80296
|
+
title: "Recording checkpoints (boolean)",
|
|
80297
|
+
description: "If `true`, enables checkpoints with default settings."
|
|
80298
|
+
},
|
|
80299
|
+
{
|
|
80300
|
+
type: "object",
|
|
80301
|
+
title: "Recording checkpoints (detailed)",
|
|
80302
|
+
additionalProperties: false,
|
|
80303
|
+
properties: {
|
|
80304
|
+
maxVariation: {
|
|
80305
|
+
type: "number",
|
|
80306
|
+
description: "Maximum fractional pixel difference tolerated between a checkpoint and its baseline before the drift surfaces as a WARNING.",
|
|
80307
|
+
default: 0.05,
|
|
80308
|
+
minimum: 0,
|
|
80309
|
+
maximum: 1
|
|
80310
|
+
},
|
|
80311
|
+
directory: {
|
|
80312
|
+
type: "string",
|
|
80313
|
+
description: "Directory for the checkpoint baselines. If unset, defaults to a `.checkpoints` directory beside the recording (for example, `demo.mp4.checkpoints/`).",
|
|
80314
|
+
transform: [
|
|
80315
|
+
"trim"
|
|
80316
|
+
]
|
|
80317
|
+
}
|
|
80318
|
+
}
|
|
80319
|
+
}
|
|
80320
|
+
]
|
|
80199
80321
|
}
|
|
80200
80322
|
},
|
|
80201
80323
|
title: "Record (detailed)"
|
|
@@ -80457,10 +80579,11 @@ var init_schemas = __esm({
|
|
|
80457
80579
|
},
|
|
80458
80580
|
overwrite: {
|
|
80459
80581
|
type: "string",
|
|
80460
|
-
description: "If `true`, overwrites the existing recording at `path` if it exists.",
|
|
80582
|
+
description: "If `true`, overwrites the existing recording at `path` if it exists. If `false`, skips the recording when the file already exists. If `aboveVariation`, always records, but replaces the existing file (and its checkpoint baselines) only when the span's checkpoint screenshots show it meaningfully changed \u2014 requires `checkpoints`, so it turns them on with defaults when `checkpoints` is omitted or `false`; set `checkpoints` to an object to tune `maxVariation` or `directory`.",
|
|
80461
80583
|
enum: [
|
|
80462
80584
|
"true",
|
|
80463
|
-
"false"
|
|
80585
|
+
"false",
|
|
80586
|
+
"aboveVariation"
|
|
80464
80587
|
]
|
|
80465
80588
|
},
|
|
80466
80589
|
name: {
|
|
@@ -80518,6 +80641,38 @@ var init_schemas = __esm({
|
|
|
80518
80641
|
}
|
|
80519
80642
|
}
|
|
80520
80643
|
]
|
|
80644
|
+
},
|
|
80645
|
+
checkpoints: {
|
|
80646
|
+
title: "Recording checkpoints",
|
|
80647
|
+
description: "Capture a checkpoint screenshot after every step while this recording is active and compare each against a persistent baseline stored beside the recording (`<path>.checkpoints/` by default). Baselines seed on the first run; on later runs, per-checkpoint variation is reported in the `stopRecord` step's outputs, and variation beyond `maxVariation` surfaces as a WARNING. If `false` or unset, no checkpoints are captured.",
|
|
80648
|
+
anyOf: [
|
|
80649
|
+
{
|
|
80650
|
+
type: "boolean",
|
|
80651
|
+
title: "Recording checkpoints (boolean)",
|
|
80652
|
+
description: "If `true`, enables checkpoints with default settings."
|
|
80653
|
+
},
|
|
80654
|
+
{
|
|
80655
|
+
type: "object",
|
|
80656
|
+
title: "Recording checkpoints (detailed)",
|
|
80657
|
+
additionalProperties: false,
|
|
80658
|
+
properties: {
|
|
80659
|
+
maxVariation: {
|
|
80660
|
+
type: "number",
|
|
80661
|
+
description: "Maximum fractional pixel difference tolerated between a checkpoint and its baseline before the drift surfaces as a WARNING.",
|
|
80662
|
+
default: 0.05,
|
|
80663
|
+
minimum: 0,
|
|
80664
|
+
maximum: 1
|
|
80665
|
+
},
|
|
80666
|
+
directory: {
|
|
80667
|
+
type: "string",
|
|
80668
|
+
description: "Directory for the checkpoint baselines. If unset, defaults to a `.checkpoints` directory beside the recording (for example, `demo.mp4.checkpoints/`).",
|
|
80669
|
+
transform: [
|
|
80670
|
+
"trim"
|
|
80671
|
+
]
|
|
80672
|
+
}
|
|
80673
|
+
}
|
|
80674
|
+
}
|
|
80675
|
+
]
|
|
80521
80676
|
}
|
|
80522
80677
|
},
|
|
80523
80678
|
title: "Record (detailed)"
|
|
@@ -80584,6 +80739,17 @@ var init_schemas = __esm({
|
|
|
80584
80739
|
path: "results.mp4",
|
|
80585
80740
|
engine: "ffmpeg"
|
|
80586
80741
|
},
|
|
80742
|
+
{
|
|
80743
|
+
path: "results.mp4",
|
|
80744
|
+
checkpoints: true
|
|
80745
|
+
},
|
|
80746
|
+
{
|
|
80747
|
+
path: "results.mp4",
|
|
80748
|
+
checkpoints: {
|
|
80749
|
+
maxVariation: 0.02,
|
|
80750
|
+
directory: "baselines/results"
|
|
80751
|
+
}
|
|
80752
|
+
},
|
|
80587
80753
|
{
|
|
80588
80754
|
path: "results.mp4",
|
|
80589
80755
|
engine: {
|
|
@@ -106420,10 +106586,11 @@ var init_schemas = __esm({
|
|
|
106420
106586
|
},
|
|
106421
106587
|
overwrite: {
|
|
106422
106588
|
type: "string",
|
|
106423
|
-
description: "If `true`, overwrites the existing recording at `path` if it exists.",
|
|
106589
|
+
description: "If `true`, overwrites the existing recording at `path` if it exists. If `false`, skips the recording when the file already exists. If `aboveVariation`, always records, but replaces the existing file (and its checkpoint baselines) only when the span's checkpoint screenshots show it meaningfully changed \u2014 requires `checkpoints`, so it turns them on with defaults when `checkpoints` is omitted or `false`; set `checkpoints` to an object to tune `maxVariation` or `directory`.",
|
|
106424
106590
|
enum: [
|
|
106425
106591
|
"true",
|
|
106426
|
-
"false"
|
|
106592
|
+
"false",
|
|
106593
|
+
"aboveVariation"
|
|
106427
106594
|
]
|
|
106428
106595
|
},
|
|
106429
106596
|
name: {
|
|
@@ -106481,6 +106648,38 @@ var init_schemas = __esm({
|
|
|
106481
106648
|
}
|
|
106482
106649
|
}
|
|
106483
106650
|
]
|
|
106651
|
+
},
|
|
106652
|
+
checkpoints: {
|
|
106653
|
+
title: "Recording checkpoints",
|
|
106654
|
+
description: "Capture a checkpoint screenshot after every step while this recording is active and compare each against a persistent baseline stored beside the recording (`<path>.checkpoints/` by default). Baselines seed on the first run; on later runs, per-checkpoint variation is reported in the `stopRecord` step's outputs, and variation beyond `maxVariation` surfaces as a WARNING. If `false` or unset, no checkpoints are captured.",
|
|
106655
|
+
anyOf: [
|
|
106656
|
+
{
|
|
106657
|
+
type: "boolean",
|
|
106658
|
+
title: "Recording checkpoints (boolean)",
|
|
106659
|
+
description: "If `true`, enables checkpoints with default settings."
|
|
106660
|
+
},
|
|
106661
|
+
{
|
|
106662
|
+
type: "object",
|
|
106663
|
+
title: "Recording checkpoints (detailed)",
|
|
106664
|
+
additionalProperties: false,
|
|
106665
|
+
properties: {
|
|
106666
|
+
maxVariation: {
|
|
106667
|
+
type: "number",
|
|
106668
|
+
description: "Maximum fractional pixel difference tolerated between a checkpoint and its baseline before the drift surfaces as a WARNING.",
|
|
106669
|
+
default: 0.05,
|
|
106670
|
+
minimum: 0,
|
|
106671
|
+
maximum: 1
|
|
106672
|
+
},
|
|
106673
|
+
directory: {
|
|
106674
|
+
type: "string",
|
|
106675
|
+
description: "Directory for the checkpoint baselines. If unset, defaults to a `.checkpoints` directory beside the recording (for example, `demo.mp4.checkpoints/`).",
|
|
106676
|
+
transform: [
|
|
106677
|
+
"trim"
|
|
106678
|
+
]
|
|
106679
|
+
}
|
|
106680
|
+
}
|
|
106681
|
+
}
|
|
106682
|
+
]
|
|
106484
106683
|
}
|
|
106485
106684
|
},
|
|
106486
106685
|
title: "Record (detailed)"
|
|
@@ -106742,10 +106941,11 @@ var init_schemas = __esm({
|
|
|
106742
106941
|
},
|
|
106743
106942
|
overwrite: {
|
|
106744
106943
|
type: "string",
|
|
106745
|
-
description: "If `true`, overwrites the existing recording at `path` if it exists.",
|
|
106944
|
+
description: "If `true`, overwrites the existing recording at `path` if it exists. If `false`, skips the recording when the file already exists. If `aboveVariation`, always records, but replaces the existing file (and its checkpoint baselines) only when the span's checkpoint screenshots show it meaningfully changed \u2014 requires `checkpoints`, so it turns them on with defaults when `checkpoints` is omitted or `false`; set `checkpoints` to an object to tune `maxVariation` or `directory`.",
|
|
106746
106945
|
enum: [
|
|
106747
106946
|
"true",
|
|
106748
|
-
"false"
|
|
106947
|
+
"false",
|
|
106948
|
+
"aboveVariation"
|
|
106749
106949
|
]
|
|
106750
106950
|
},
|
|
106751
106951
|
name: {
|
|
@@ -106803,6 +107003,38 @@ var init_schemas = __esm({
|
|
|
106803
107003
|
}
|
|
106804
107004
|
}
|
|
106805
107005
|
]
|
|
107006
|
+
},
|
|
107007
|
+
checkpoints: {
|
|
107008
|
+
title: "Recording checkpoints",
|
|
107009
|
+
description: "Capture a checkpoint screenshot after every step while this recording is active and compare each against a persistent baseline stored beside the recording (`<path>.checkpoints/` by default). Baselines seed on the first run; on later runs, per-checkpoint variation is reported in the `stopRecord` step's outputs, and variation beyond `maxVariation` surfaces as a WARNING. If `false` or unset, no checkpoints are captured.",
|
|
107010
|
+
anyOf: [
|
|
107011
|
+
{
|
|
107012
|
+
type: "boolean",
|
|
107013
|
+
title: "Recording checkpoints (boolean)",
|
|
107014
|
+
description: "If `true`, enables checkpoints with default settings."
|
|
107015
|
+
},
|
|
107016
|
+
{
|
|
107017
|
+
type: "object",
|
|
107018
|
+
title: "Recording checkpoints (detailed)",
|
|
107019
|
+
additionalProperties: false,
|
|
107020
|
+
properties: {
|
|
107021
|
+
maxVariation: {
|
|
107022
|
+
type: "number",
|
|
107023
|
+
description: "Maximum fractional pixel difference tolerated between a checkpoint and its baseline before the drift surfaces as a WARNING.",
|
|
107024
|
+
default: 0.05,
|
|
107025
|
+
minimum: 0,
|
|
107026
|
+
maximum: 1
|
|
107027
|
+
},
|
|
107028
|
+
directory: {
|
|
107029
|
+
type: "string",
|
|
107030
|
+
description: "Directory for the checkpoint baselines. If unset, defaults to a `.checkpoints` directory beside the recording (for example, `demo.mp4.checkpoints/`).",
|
|
107031
|
+
transform: [
|
|
107032
|
+
"trim"
|
|
107033
|
+
]
|
|
107034
|
+
}
|
|
107035
|
+
}
|
|
107036
|
+
}
|
|
107037
|
+
]
|
|
106806
107038
|
}
|
|
106807
107039
|
},
|
|
106808
107040
|
title: "Record (detailed)"
|
|
@@ -106869,6 +107101,17 @@ var init_schemas = __esm({
|
|
|
106869
107101
|
path: "results.mp4",
|
|
106870
107102
|
engine: "ffmpeg"
|
|
106871
107103
|
},
|
|
107104
|
+
{
|
|
107105
|
+
path: "results.mp4",
|
|
107106
|
+
checkpoints: true
|
|
107107
|
+
},
|
|
107108
|
+
{
|
|
107109
|
+
path: "results.mp4",
|
|
107110
|
+
checkpoints: {
|
|
107111
|
+
maxVariation: 0.02,
|
|
107112
|
+
directory: "baselines/results"
|
|
107113
|
+
}
|
|
107114
|
+
},
|
|
106872
107115
|
{
|
|
106873
107116
|
path: "results.mp4",
|
|
106874
107117
|
engine: {
|
|
@@ -135035,9 +135278,10 @@ var init_schemas = __esm({
|
|
|
135035
135278
|
anyOf: [
|
|
135036
135279
|
{
|
|
135037
135280
|
title: "Screenshot (simple)",
|
|
135281
|
+
$comment: "The pattern gates the target's EXTENSION, not its characters or location: any path ending in .png/.PNG is accepted, plus an http(s) URL to a PNG (optionally with a query string, for signed URLs) and a `$VAR` reference. It deliberately does not restrict the character set \u2014 an earlier pattern allowed any Windows absolute path but limited non-Windows paths to [A-Za-z0-9_./\\-], so ordinary macOS/Linux projects (a space, parentheses, '~', or non-ASCII anywhere in the path) failed validation, including for the absolute paths doc-detective synthesizes internally for autoScreenshot and recording checkpoints. That charset never bounded WHERE a screenshot could be written (traversal like ../../x.png always passed), so it only made non-Windows projects second-class. See ADR 01077.",
|
|
135038
135282
|
description: "File path of the PNG file. Accepts absolute paths. If not specified, the file name is the ID of the step. If an `http(s)` URL is supplied, the remote image is downloaded and used as a read-only reference for comparison; the new capture is written to a local run-specific folder instead of being uploaded back to the URL.",
|
|
135039
135283
|
type: "string",
|
|
135040
|
-
pattern: "^(?:https?:\\/\\/.+\\.(?:png|PNG)(?:\\?.*)
|
|
135284
|
+
pattern: "^(?:https?:\\/\\/.+\\.(?:png|PNG)(?:\\?.*)?|.*\\.(?:png|PNG)|\\$[A-Za-z0-9_]+)$",
|
|
135041
135285
|
transform: [
|
|
135042
135286
|
"trim"
|
|
135043
135287
|
]
|
|
@@ -135271,9 +135515,10 @@ var init_schemas = __esm({
|
|
|
135271
135515
|
},
|
|
135272
135516
|
path: {
|
|
135273
135517
|
title: "Screenshot (simple)",
|
|
135518
|
+
$comment: "The pattern gates the target's EXTENSION, not its characters or location: any path ending in .png/.PNG is accepted, plus an http(s) URL to a PNG (optionally with a query string, for signed URLs) and a `$VAR` reference. It deliberately does not restrict the character set \u2014 an earlier pattern allowed any Windows absolute path but limited non-Windows paths to [A-Za-z0-9_./\\-], so ordinary macOS/Linux projects (a space, parentheses, '~', or non-ASCII anywhere in the path) failed validation, including for the absolute paths doc-detective synthesizes internally for autoScreenshot and recording checkpoints. That charset never bounded WHERE a screenshot could be written (traversal like ../../x.png always passed), so it only made non-Windows projects second-class. See ADR 01077.",
|
|
135274
135519
|
description: "File path of the PNG file. Accepts absolute paths. If not specified, the file name is the ID of the step. If an `http(s)` URL is supplied, the remote image is downloaded and used as a read-only reference for comparison; the new capture is written to a local run-specific folder instead of being uploaded back to the URL.",
|
|
135275
135520
|
type: "string",
|
|
135276
|
-
pattern: "^(?:https?:\\/\\/.+\\.(?:png|PNG)(?:\\?.*)
|
|
135521
|
+
pattern: "^(?:https?:\\/\\/.+\\.(?:png|PNG)(?:\\?.*)?|.*\\.(?:png|PNG)|\\$[A-Za-z0-9_]+)$",
|
|
135277
135522
|
transform: [
|
|
135278
135523
|
"trim"
|
|
135279
135524
|
]
|
|
@@ -135531,9 +135776,10 @@ var init_schemas = __esm({
|
|
|
135531
135776
|
schemas: {
|
|
135532
135777
|
path: {
|
|
135533
135778
|
title: "Screenshot (simple)",
|
|
135779
|
+
$comment: "The pattern gates the target's EXTENSION, not its characters or location: any path ending in .png/.PNG is accepted, plus an http(s) URL to a PNG (optionally with a query string, for signed URLs) and a `$VAR` reference. It deliberately does not restrict the character set \u2014 an earlier pattern allowed any Windows absolute path but limited non-Windows paths to [A-Za-z0-9_./\\-], so ordinary macOS/Linux projects (a space, parentheses, '~', or non-ASCII anywhere in the path) failed validation, including for the absolute paths doc-detective synthesizes internally for autoScreenshot and recording checkpoints. That charset never bounded WHERE a screenshot could be written (traversal like ../../x.png always passed), so it only made non-Windows projects second-class. See ADR 01077.",
|
|
135534
135780
|
description: "File path of the PNG file. Accepts absolute paths. If not specified, the file name is the ID of the step. If an `http(s)` URL is supplied, the remote image is downloaded and used as a read-only reference for comparison; the new capture is written to a local run-specific folder instead of being uploaded back to the URL.",
|
|
135535
135781
|
type: "string",
|
|
135536
|
-
pattern: "^(?:https?:\\/\\/.+\\.(?:png|PNG)(?:\\?.*)
|
|
135782
|
+
pattern: "^(?:https?:\\/\\/.+\\.(?:png|PNG)(?:\\?.*)?|.*\\.(?:png|PNG)|\\$[A-Za-z0-9_]+)$",
|
|
135537
135783
|
transform: [
|
|
135538
135784
|
"trim"
|
|
135539
135785
|
]
|
|
@@ -135767,9 +136013,10 @@ var init_schemas = __esm({
|
|
|
135767
136013
|
},
|
|
135768
136014
|
path: {
|
|
135769
136015
|
title: "Screenshot (simple)",
|
|
136016
|
+
$comment: "The pattern gates the target's EXTENSION, not its characters or location: any path ending in .png/.PNG is accepted, plus an http(s) URL to a PNG (optionally with a query string, for signed URLs) and a `$VAR` reference. It deliberately does not restrict the character set \u2014 an earlier pattern allowed any Windows absolute path but limited non-Windows paths to [A-Za-z0-9_./\\-], so ordinary macOS/Linux projects (a space, parentheses, '~', or non-ASCII anywhere in the path) failed validation, including for the absolute paths doc-detective synthesizes internally for autoScreenshot and recording checkpoints. That charset never bounded WHERE a screenshot could be written (traversal like ../../x.png always passed), so it only made non-Windows projects second-class. See ADR 01077.",
|
|
135770
136017
|
description: "File path of the PNG file. Accepts absolute paths. If not specified, the file name is the ID of the step. If an `http(s)` URL is supplied, the remote image is downloaded and used as a read-only reference for comparison; the new capture is written to a local run-specific folder instead of being uploaded back to the URL.",
|
|
135771
136018
|
type: "string",
|
|
135772
|
-
pattern: "^(?:https?:\\/\\/.+\\.(?:png|PNG)(?:\\?.*)
|
|
136019
|
+
pattern: "^(?:https?:\\/\\/.+\\.(?:png|PNG)(?:\\?.*)?|.*\\.(?:png|PNG)|\\$[A-Za-z0-9_]+)$",
|
|
135773
136020
|
transform: [
|
|
135774
136021
|
"trim"
|
|
135775
136022
|
]
|
|
@@ -136243,9 +136490,10 @@ var init_schemas = __esm({
|
|
|
136243
136490
|
},
|
|
136244
136491
|
path: {
|
|
136245
136492
|
title: "Screenshot (simple)",
|
|
136493
|
+
$comment: "The pattern gates the target's EXTENSION, not its characters or location: any path ending in .png/.PNG is accepted, plus an http(s) URL to a PNG (optionally with a query string, for signed URLs) and a `$VAR` reference. It deliberately does not restrict the character set \u2014 an earlier pattern allowed any Windows absolute path but limited non-Windows paths to [A-Za-z0-9_./\\-], so ordinary macOS/Linux projects (a space, parentheses, '~', or non-ASCII anywhere in the path) failed validation, including for the absolute paths doc-detective synthesizes internally for autoScreenshot and recording checkpoints. That charset never bounded WHERE a screenshot could be written (traversal like ../../x.png always passed), so it only made non-Windows projects second-class. See ADR 01077.",
|
|
136246
136494
|
description: "File path of the PNG file. Accepts absolute paths. If not specified, the file name is the ID of the step. If an `http(s)` URL is supplied, the remote image is downloaded and used as a read-only reference for comparison; the new capture is written to a local run-specific folder instead of being uploaded back to the URL.",
|
|
136247
136495
|
type: "string",
|
|
136248
|
-
pattern: "^(?:https?:\\/\\/.+\\.(?:png|PNG)(?:\\?.*)
|
|
136496
|
+
pattern: "^(?:https?:\\/\\/.+\\.(?:png|PNG)(?:\\?.*)?|.*\\.(?:png|PNG)|\\$[A-Za-z0-9_]+)$",
|
|
136249
136497
|
transform: [
|
|
136250
136498
|
"trim"
|
|
136251
136499
|
]
|
|
@@ -136627,6 +136875,7 @@ var init_schemas = __esm({
|
|
|
136627
136875
|
"image.png",
|
|
136628
136876
|
"static/images/image.png",
|
|
136629
136877
|
"/User/manny/projects/doc-detective/static/images/image.png",
|
|
136878
|
+
"/Users/jane doe/projects/my docs (v2)/static/images/image.png",
|
|
136630
136879
|
"https://example.com/static/images/image.png",
|
|
136631
136880
|
{
|
|
136632
136881
|
path: "https://promptless-customer-doc-assets.s3.amazonaws.com/docs-images/request-changes-button-0c851bb3.png",
|
|
@@ -139061,10 +139310,11 @@ var init_schemas = __esm({
|
|
|
139061
139310
|
},
|
|
139062
139311
|
overwrite: {
|
|
139063
139312
|
type: "string",
|
|
139064
|
-
description: "If `true`, overwrites the existing recording at `path` if it exists.",
|
|
139313
|
+
description: "If `true`, overwrites the existing recording at `path` if it exists. If `false`, skips the recording when the file already exists. If `aboveVariation`, always records, but replaces the existing file (and its checkpoint baselines) only when the span's checkpoint screenshots show it meaningfully changed \u2014 requires `checkpoints`, so it turns them on with defaults when `checkpoints` is omitted or `false`; set `checkpoints` to an object to tune `maxVariation` or `directory`.",
|
|
139065
139314
|
enum: [
|
|
139066
139315
|
"true",
|
|
139067
|
-
"false"
|
|
139316
|
+
"false",
|
|
139317
|
+
"aboveVariation"
|
|
139068
139318
|
]
|
|
139069
139319
|
},
|
|
139070
139320
|
name: {
|
|
@@ -139122,6 +139372,38 @@ var init_schemas = __esm({
|
|
|
139122
139372
|
}
|
|
139123
139373
|
}
|
|
139124
139374
|
]
|
|
139375
|
+
},
|
|
139376
|
+
checkpoints: {
|
|
139377
|
+
title: "Recording checkpoints",
|
|
139378
|
+
description: "Capture a checkpoint screenshot after every step while this recording is active and compare each against a persistent baseline stored beside the recording (`<path>.checkpoints/` by default). Baselines seed on the first run; on later runs, per-checkpoint variation is reported in the `stopRecord` step's outputs, and variation beyond `maxVariation` surfaces as a WARNING. If `false` or unset, no checkpoints are captured.",
|
|
139379
|
+
anyOf: [
|
|
139380
|
+
{
|
|
139381
|
+
type: "boolean",
|
|
139382
|
+
title: "Recording checkpoints (boolean)",
|
|
139383
|
+
description: "If `true`, enables checkpoints with default settings."
|
|
139384
|
+
},
|
|
139385
|
+
{
|
|
139386
|
+
type: "object",
|
|
139387
|
+
title: "Recording checkpoints (detailed)",
|
|
139388
|
+
additionalProperties: false,
|
|
139389
|
+
properties: {
|
|
139390
|
+
maxVariation: {
|
|
139391
|
+
type: "number",
|
|
139392
|
+
description: "Maximum fractional pixel difference tolerated between a checkpoint and its baseline before the drift surfaces as a WARNING.",
|
|
139393
|
+
default: 0.05,
|
|
139394
|
+
minimum: 0,
|
|
139395
|
+
maximum: 1
|
|
139396
|
+
},
|
|
139397
|
+
directory: {
|
|
139398
|
+
type: "string",
|
|
139399
|
+
description: "Directory for the checkpoint baselines. If unset, defaults to a `.checkpoints` directory beside the recording (for example, `demo.mp4.checkpoints/`).",
|
|
139400
|
+
transform: [
|
|
139401
|
+
"trim"
|
|
139402
|
+
]
|
|
139403
|
+
}
|
|
139404
|
+
}
|
|
139405
|
+
}
|
|
139406
|
+
]
|
|
139125
139407
|
}
|
|
139126
139408
|
},
|
|
139127
139409
|
title: "Record (detailed)"
|
|
@@ -139383,10 +139665,11 @@ var init_schemas = __esm({
|
|
|
139383
139665
|
},
|
|
139384
139666
|
overwrite: {
|
|
139385
139667
|
type: "string",
|
|
139386
|
-
description: "If `true`, overwrites the existing recording at `path` if it exists.",
|
|
139668
|
+
description: "If `true`, overwrites the existing recording at `path` if it exists. If `false`, skips the recording when the file already exists. If `aboveVariation`, always records, but replaces the existing file (and its checkpoint baselines) only when the span's checkpoint screenshots show it meaningfully changed \u2014 requires `checkpoints`, so it turns them on with defaults when `checkpoints` is omitted or `false`; set `checkpoints` to an object to tune `maxVariation` or `directory`.",
|
|
139387
139669
|
enum: [
|
|
139388
139670
|
"true",
|
|
139389
|
-
"false"
|
|
139671
|
+
"false",
|
|
139672
|
+
"aboveVariation"
|
|
139390
139673
|
]
|
|
139391
139674
|
},
|
|
139392
139675
|
name: {
|
|
@@ -139444,6 +139727,38 @@ var init_schemas = __esm({
|
|
|
139444
139727
|
}
|
|
139445
139728
|
}
|
|
139446
139729
|
]
|
|
139730
|
+
},
|
|
139731
|
+
checkpoints: {
|
|
139732
|
+
title: "Recording checkpoints",
|
|
139733
|
+
description: "Capture a checkpoint screenshot after every step while this recording is active and compare each against a persistent baseline stored beside the recording (`<path>.checkpoints/` by default). Baselines seed on the first run; on later runs, per-checkpoint variation is reported in the `stopRecord` step's outputs, and variation beyond `maxVariation` surfaces as a WARNING. If `false` or unset, no checkpoints are captured.",
|
|
139734
|
+
anyOf: [
|
|
139735
|
+
{
|
|
139736
|
+
type: "boolean",
|
|
139737
|
+
title: "Recording checkpoints (boolean)",
|
|
139738
|
+
description: "If `true`, enables checkpoints with default settings."
|
|
139739
|
+
},
|
|
139740
|
+
{
|
|
139741
|
+
type: "object",
|
|
139742
|
+
title: "Recording checkpoints (detailed)",
|
|
139743
|
+
additionalProperties: false,
|
|
139744
|
+
properties: {
|
|
139745
|
+
maxVariation: {
|
|
139746
|
+
type: "number",
|
|
139747
|
+
description: "Maximum fractional pixel difference tolerated between a checkpoint and its baseline before the drift surfaces as a WARNING.",
|
|
139748
|
+
default: 0.05,
|
|
139749
|
+
minimum: 0,
|
|
139750
|
+
maximum: 1
|
|
139751
|
+
},
|
|
139752
|
+
directory: {
|
|
139753
|
+
type: "string",
|
|
139754
|
+
description: "Directory for the checkpoint baselines. If unset, defaults to a `.checkpoints` directory beside the recording (for example, `demo.mp4.checkpoints/`).",
|
|
139755
|
+
transform: [
|
|
139756
|
+
"trim"
|
|
139757
|
+
]
|
|
139758
|
+
}
|
|
139759
|
+
}
|
|
139760
|
+
}
|
|
139761
|
+
]
|
|
139447
139762
|
}
|
|
139448
139763
|
},
|
|
139449
139764
|
title: "Record (detailed)"
|
|
@@ -139510,6 +139825,17 @@ var init_schemas = __esm({
|
|
|
139510
139825
|
path: "results.mp4",
|
|
139511
139826
|
engine: "ffmpeg"
|
|
139512
139827
|
},
|
|
139828
|
+
{
|
|
139829
|
+
path: "results.mp4",
|
|
139830
|
+
checkpoints: true
|
|
139831
|
+
},
|
|
139832
|
+
{
|
|
139833
|
+
path: "results.mp4",
|
|
139834
|
+
checkpoints: {
|
|
139835
|
+
maxVariation: 0.02,
|
|
139836
|
+
directory: "baselines/results"
|
|
139837
|
+
}
|
|
139838
|
+
},
|
|
139513
139839
|
{
|
|
139514
139840
|
path: "results.mp4",
|
|
139515
139841
|
engine: {
|
|
@@ -180674,9 +181000,10 @@ var init_schemas = __esm({
|
|
|
180674
181000
|
anyOf: [
|
|
180675
181001
|
{
|
|
180676
181002
|
title: "Screenshot (simple)",
|
|
181003
|
+
$comment: "The pattern gates the target's EXTENSION, not its characters or location: any path ending in .png/.PNG is accepted, plus an http(s) URL to a PNG (optionally with a query string, for signed URLs) and a `$VAR` reference. It deliberately does not restrict the character set \u2014 an earlier pattern allowed any Windows absolute path but limited non-Windows paths to [A-Za-z0-9_./\\-], so ordinary macOS/Linux projects (a space, parentheses, '~', or non-ASCII anywhere in the path) failed validation, including for the absolute paths doc-detective synthesizes internally for autoScreenshot and recording checkpoints. That charset never bounded WHERE a screenshot could be written (traversal like ../../x.png always passed), so it only made non-Windows projects second-class. See ADR 01077.",
|
|
180677
181004
|
description: "File path of the PNG file. Accepts absolute paths. If not specified, the file name is the ID of the step. If an `http(s)` URL is supplied, the remote image is downloaded and used as a read-only reference for comparison; the new capture is written to a local run-specific folder instead of being uploaded back to the URL.",
|
|
180678
181005
|
type: "string",
|
|
180679
|
-
pattern: "^(?:https?:\\/\\/.+\\.(?:png|PNG)(?:\\?.*)
|
|
181006
|
+
pattern: "^(?:https?:\\/\\/.+\\.(?:png|PNG)(?:\\?.*)?|.*\\.(?:png|PNG)|\\$[A-Za-z0-9_]+)$",
|
|
180680
181007
|
transform: [
|
|
180681
181008
|
"trim"
|
|
180682
181009
|
]
|
|
@@ -180910,9 +181237,10 @@ var init_schemas = __esm({
|
|
|
180910
181237
|
},
|
|
180911
181238
|
path: {
|
|
180912
181239
|
title: "Screenshot (simple)",
|
|
181240
|
+
$comment: "The pattern gates the target's EXTENSION, not its characters or location: any path ending in .png/.PNG is accepted, plus an http(s) URL to a PNG (optionally with a query string, for signed URLs) and a `$VAR` reference. It deliberately does not restrict the character set \u2014 an earlier pattern allowed any Windows absolute path but limited non-Windows paths to [A-Za-z0-9_./\\-], so ordinary macOS/Linux projects (a space, parentheses, '~', or non-ASCII anywhere in the path) failed validation, including for the absolute paths doc-detective synthesizes internally for autoScreenshot and recording checkpoints. That charset never bounded WHERE a screenshot could be written (traversal like ../../x.png always passed), so it only made non-Windows projects second-class. See ADR 01077.",
|
|
180913
181241
|
description: "File path of the PNG file. Accepts absolute paths. If not specified, the file name is the ID of the step. If an `http(s)` URL is supplied, the remote image is downloaded and used as a read-only reference for comparison; the new capture is written to a local run-specific folder instead of being uploaded back to the URL.",
|
|
180914
181242
|
type: "string",
|
|
180915
|
-
pattern: "^(?:https?:\\/\\/.+\\.(?:png|PNG)(?:\\?.*)
|
|
181243
|
+
pattern: "^(?:https?:\\/\\/.+\\.(?:png|PNG)(?:\\?.*)?|.*\\.(?:png|PNG)|\\$[A-Za-z0-9_]+)$",
|
|
180916
181244
|
transform: [
|
|
180917
181245
|
"trim"
|
|
180918
181246
|
]
|
|
@@ -181170,9 +181498,10 @@ var init_schemas = __esm({
|
|
|
181170
181498
|
schemas: {
|
|
181171
181499
|
path: {
|
|
181172
181500
|
title: "Screenshot (simple)",
|
|
181501
|
+
$comment: "The pattern gates the target's EXTENSION, not its characters or location: any path ending in .png/.PNG is accepted, plus an http(s) URL to a PNG (optionally with a query string, for signed URLs) and a `$VAR` reference. It deliberately does not restrict the character set \u2014 an earlier pattern allowed any Windows absolute path but limited non-Windows paths to [A-Za-z0-9_./\\-], so ordinary macOS/Linux projects (a space, parentheses, '~', or non-ASCII anywhere in the path) failed validation, including for the absolute paths doc-detective synthesizes internally for autoScreenshot and recording checkpoints. That charset never bounded WHERE a screenshot could be written (traversal like ../../x.png always passed), so it only made non-Windows projects second-class. See ADR 01077.",
|
|
181173
181502
|
description: "File path of the PNG file. Accepts absolute paths. If not specified, the file name is the ID of the step. If an `http(s)` URL is supplied, the remote image is downloaded and used as a read-only reference for comparison; the new capture is written to a local run-specific folder instead of being uploaded back to the URL.",
|
|
181174
181503
|
type: "string",
|
|
181175
|
-
pattern: "^(?:https?:\\/\\/.+\\.(?:png|PNG)(?:\\?.*)
|
|
181504
|
+
pattern: "^(?:https?:\\/\\/.+\\.(?:png|PNG)(?:\\?.*)?|.*\\.(?:png|PNG)|\\$[A-Za-z0-9_]+)$",
|
|
181176
181505
|
transform: [
|
|
181177
181506
|
"trim"
|
|
181178
181507
|
]
|
|
@@ -181406,9 +181735,10 @@ var init_schemas = __esm({
|
|
|
181406
181735
|
},
|
|
181407
181736
|
path: {
|
|
181408
181737
|
title: "Screenshot (simple)",
|
|
181738
|
+
$comment: "The pattern gates the target's EXTENSION, not its characters or location: any path ending in .png/.PNG is accepted, plus an http(s) URL to a PNG (optionally with a query string, for signed URLs) and a `$VAR` reference. It deliberately does not restrict the character set \u2014 an earlier pattern allowed any Windows absolute path but limited non-Windows paths to [A-Za-z0-9_./\\-], so ordinary macOS/Linux projects (a space, parentheses, '~', or non-ASCII anywhere in the path) failed validation, including for the absolute paths doc-detective synthesizes internally for autoScreenshot and recording checkpoints. That charset never bounded WHERE a screenshot could be written (traversal like ../../x.png always passed), so it only made non-Windows projects second-class. See ADR 01077.",
|
|
181409
181739
|
description: "File path of the PNG file. Accepts absolute paths. If not specified, the file name is the ID of the step. If an `http(s)` URL is supplied, the remote image is downloaded and used as a read-only reference for comparison; the new capture is written to a local run-specific folder instead of being uploaded back to the URL.",
|
|
181410
181740
|
type: "string",
|
|
181411
|
-
pattern: "^(?:https?:\\/\\/.+\\.(?:png|PNG)(?:\\?.*)
|
|
181741
|
+
pattern: "^(?:https?:\\/\\/.+\\.(?:png|PNG)(?:\\?.*)?|.*\\.(?:png|PNG)|\\$[A-Za-z0-9_]+)$",
|
|
181412
181742
|
transform: [
|
|
181413
181743
|
"trim"
|
|
181414
181744
|
]
|
|
@@ -181882,9 +182212,10 @@ var init_schemas = __esm({
|
|
|
181882
182212
|
},
|
|
181883
182213
|
path: {
|
|
181884
182214
|
title: "Screenshot (simple)",
|
|
182215
|
+
$comment: "The pattern gates the target's EXTENSION, not its characters or location: any path ending in .png/.PNG is accepted, plus an http(s) URL to a PNG (optionally with a query string, for signed URLs) and a `$VAR` reference. It deliberately does not restrict the character set \u2014 an earlier pattern allowed any Windows absolute path but limited non-Windows paths to [A-Za-z0-9_./\\-], so ordinary macOS/Linux projects (a space, parentheses, '~', or non-ASCII anywhere in the path) failed validation, including for the absolute paths doc-detective synthesizes internally for autoScreenshot and recording checkpoints. That charset never bounded WHERE a screenshot could be written (traversal like ../../x.png always passed), so it only made non-Windows projects second-class. See ADR 01077.",
|
|
181885
182216
|
description: "File path of the PNG file. Accepts absolute paths. If not specified, the file name is the ID of the step. If an `http(s)` URL is supplied, the remote image is downloaded and used as a read-only reference for comparison; the new capture is written to a local run-specific folder instead of being uploaded back to the URL.",
|
|
181886
182217
|
type: "string",
|
|
181887
|
-
pattern: "^(?:https?:\\/\\/.+\\.(?:png|PNG)(?:\\?.*)
|
|
182218
|
+
pattern: "^(?:https?:\\/\\/.+\\.(?:png|PNG)(?:\\?.*)?|.*\\.(?:png|PNG)|\\$[A-Za-z0-9_]+)$",
|
|
181888
182219
|
transform: [
|
|
181889
182220
|
"trim"
|
|
181890
182221
|
]
|
|
@@ -182266,6 +182597,7 @@ var init_schemas = __esm({
|
|
|
182266
182597
|
"image.png",
|
|
182267
182598
|
"static/images/image.png",
|
|
182268
182599
|
"/User/manny/projects/doc-detective/static/images/image.png",
|
|
182600
|
+
"/Users/jane doe/projects/my docs (v2)/static/images/image.png",
|
|
182269
182601
|
"https://example.com/static/images/image.png",
|
|
182270
182602
|
{
|
|
182271
182603
|
path: "https://promptless-customer-doc-assets.s3.amazonaws.com/docs-images/request-changes-button-0c851bb3.png",
|
|
@@ -184700,10 +185032,11 @@ var init_schemas = __esm({
|
|
|
184700
185032
|
},
|
|
184701
185033
|
overwrite: {
|
|
184702
185034
|
type: "string",
|
|
184703
|
-
description: "If `true`, overwrites the existing recording at `path` if it exists.",
|
|
185035
|
+
description: "If `true`, overwrites the existing recording at `path` if it exists. If `false`, skips the recording when the file already exists. If `aboveVariation`, always records, but replaces the existing file (and its checkpoint baselines) only when the span's checkpoint screenshots show it meaningfully changed \u2014 requires `checkpoints`, so it turns them on with defaults when `checkpoints` is omitted or `false`; set `checkpoints` to an object to tune `maxVariation` or `directory`.",
|
|
184704
185036
|
enum: [
|
|
184705
185037
|
"true",
|
|
184706
|
-
"false"
|
|
185038
|
+
"false",
|
|
185039
|
+
"aboveVariation"
|
|
184707
185040
|
]
|
|
184708
185041
|
},
|
|
184709
185042
|
name: {
|
|
@@ -184761,6 +185094,38 @@ var init_schemas = __esm({
|
|
|
184761
185094
|
}
|
|
184762
185095
|
}
|
|
184763
185096
|
]
|
|
185097
|
+
},
|
|
185098
|
+
checkpoints: {
|
|
185099
|
+
title: "Recording checkpoints",
|
|
185100
|
+
description: "Capture a checkpoint screenshot after every step while this recording is active and compare each against a persistent baseline stored beside the recording (`<path>.checkpoints/` by default). Baselines seed on the first run; on later runs, per-checkpoint variation is reported in the `stopRecord` step's outputs, and variation beyond `maxVariation` surfaces as a WARNING. If `false` or unset, no checkpoints are captured.",
|
|
185101
|
+
anyOf: [
|
|
185102
|
+
{
|
|
185103
|
+
type: "boolean",
|
|
185104
|
+
title: "Recording checkpoints (boolean)",
|
|
185105
|
+
description: "If `true`, enables checkpoints with default settings."
|
|
185106
|
+
},
|
|
185107
|
+
{
|
|
185108
|
+
type: "object",
|
|
185109
|
+
title: "Recording checkpoints (detailed)",
|
|
185110
|
+
additionalProperties: false,
|
|
185111
|
+
properties: {
|
|
185112
|
+
maxVariation: {
|
|
185113
|
+
type: "number",
|
|
185114
|
+
description: "Maximum fractional pixel difference tolerated between a checkpoint and its baseline before the drift surfaces as a WARNING.",
|
|
185115
|
+
default: 0.05,
|
|
185116
|
+
minimum: 0,
|
|
185117
|
+
maximum: 1
|
|
185118
|
+
},
|
|
185119
|
+
directory: {
|
|
185120
|
+
type: "string",
|
|
185121
|
+
description: "Directory for the checkpoint baselines. If unset, defaults to a `.checkpoints` directory beside the recording (for example, `demo.mp4.checkpoints/`).",
|
|
185122
|
+
transform: [
|
|
185123
|
+
"trim"
|
|
185124
|
+
]
|
|
185125
|
+
}
|
|
185126
|
+
}
|
|
185127
|
+
}
|
|
185128
|
+
]
|
|
184764
185129
|
}
|
|
184765
185130
|
},
|
|
184766
185131
|
title: "Record (detailed)"
|
|
@@ -185022,10 +185387,11 @@ var init_schemas = __esm({
|
|
|
185022
185387
|
},
|
|
185023
185388
|
overwrite: {
|
|
185024
185389
|
type: "string",
|
|
185025
|
-
description: "If `true`, overwrites the existing recording at `path` if it exists.",
|
|
185390
|
+
description: "If `true`, overwrites the existing recording at `path` if it exists. If `false`, skips the recording when the file already exists. If `aboveVariation`, always records, but replaces the existing file (and its checkpoint baselines) only when the span's checkpoint screenshots show it meaningfully changed \u2014 requires `checkpoints`, so it turns them on with defaults when `checkpoints` is omitted or `false`; set `checkpoints` to an object to tune `maxVariation` or `directory`.",
|
|
185026
185391
|
enum: [
|
|
185027
185392
|
"true",
|
|
185028
|
-
"false"
|
|
185393
|
+
"false",
|
|
185394
|
+
"aboveVariation"
|
|
185029
185395
|
]
|
|
185030
185396
|
},
|
|
185031
185397
|
name: {
|
|
@@ -185083,6 +185449,38 @@ var init_schemas = __esm({
|
|
|
185083
185449
|
}
|
|
185084
185450
|
}
|
|
185085
185451
|
]
|
|
185452
|
+
},
|
|
185453
|
+
checkpoints: {
|
|
185454
|
+
title: "Recording checkpoints",
|
|
185455
|
+
description: "Capture a checkpoint screenshot after every step while this recording is active and compare each against a persistent baseline stored beside the recording (`<path>.checkpoints/` by default). Baselines seed on the first run; on later runs, per-checkpoint variation is reported in the `stopRecord` step's outputs, and variation beyond `maxVariation` surfaces as a WARNING. If `false` or unset, no checkpoints are captured.",
|
|
185456
|
+
anyOf: [
|
|
185457
|
+
{
|
|
185458
|
+
type: "boolean",
|
|
185459
|
+
title: "Recording checkpoints (boolean)",
|
|
185460
|
+
description: "If `true`, enables checkpoints with default settings."
|
|
185461
|
+
},
|
|
185462
|
+
{
|
|
185463
|
+
type: "object",
|
|
185464
|
+
title: "Recording checkpoints (detailed)",
|
|
185465
|
+
additionalProperties: false,
|
|
185466
|
+
properties: {
|
|
185467
|
+
maxVariation: {
|
|
185468
|
+
type: "number",
|
|
185469
|
+
description: "Maximum fractional pixel difference tolerated between a checkpoint and its baseline before the drift surfaces as a WARNING.",
|
|
185470
|
+
default: 0.05,
|
|
185471
|
+
minimum: 0,
|
|
185472
|
+
maximum: 1
|
|
185473
|
+
},
|
|
185474
|
+
directory: {
|
|
185475
|
+
type: "string",
|
|
185476
|
+
description: "Directory for the checkpoint baselines. If unset, defaults to a `.checkpoints` directory beside the recording (for example, `demo.mp4.checkpoints/`).",
|
|
185477
|
+
transform: [
|
|
185478
|
+
"trim"
|
|
185479
|
+
]
|
|
185480
|
+
}
|
|
185481
|
+
}
|
|
185482
|
+
}
|
|
185483
|
+
]
|
|
185086
185484
|
}
|
|
185087
185485
|
},
|
|
185088
185486
|
title: "Record (detailed)"
|
|
@@ -185149,6 +185547,17 @@ var init_schemas = __esm({
|
|
|
185149
185547
|
path: "results.mp4",
|
|
185150
185548
|
engine: "ffmpeg"
|
|
185151
185549
|
},
|
|
185550
|
+
{
|
|
185551
|
+
path: "results.mp4",
|
|
185552
|
+
checkpoints: true
|
|
185553
|
+
},
|
|
185554
|
+
{
|
|
185555
|
+
path: "results.mp4",
|
|
185556
|
+
checkpoints: {
|
|
185557
|
+
maxVariation: 0.02,
|
|
185558
|
+
directory: "baselines/results"
|
|
185559
|
+
}
|
|
185560
|
+
},
|
|
185152
185561
|
{
|
|
185153
185562
|
path: "results.mp4",
|
|
185154
185563
|
engine: {
|
|
@@ -228052,9 +228461,10 @@ var init_schemas = __esm({
|
|
|
228052
228461
|
anyOf: [
|
|
228053
228462
|
{
|
|
228054
228463
|
title: "Screenshot (simple)",
|
|
228464
|
+
$comment: "The pattern gates the target's EXTENSION, not its characters or location: any path ending in .png/.PNG is accepted, plus an http(s) URL to a PNG (optionally with a query string, for signed URLs) and a `$VAR` reference. It deliberately does not restrict the character set \u2014 an earlier pattern allowed any Windows absolute path but limited non-Windows paths to [A-Za-z0-9_./\\-], so ordinary macOS/Linux projects (a space, parentheses, '~', or non-ASCII anywhere in the path) failed validation, including for the absolute paths doc-detective synthesizes internally for autoScreenshot and recording checkpoints. That charset never bounded WHERE a screenshot could be written (traversal like ../../x.png always passed), so it only made non-Windows projects second-class. See ADR 01077.",
|
|
228055
228465
|
description: "File path of the PNG file. Accepts absolute paths. If not specified, the file name is the ID of the step. If an `http(s)` URL is supplied, the remote image is downloaded and used as a read-only reference for comparison; the new capture is written to a local run-specific folder instead of being uploaded back to the URL.",
|
|
228056
228466
|
type: "string",
|
|
228057
|
-
pattern: "^(?:https?:\\/\\/.+\\.(?:png|PNG)(?:\\?.*)
|
|
228467
|
+
pattern: "^(?:https?:\\/\\/.+\\.(?:png|PNG)(?:\\?.*)?|.*\\.(?:png|PNG)|\\$[A-Za-z0-9_]+)$",
|
|
228058
228468
|
transform: [
|
|
228059
228469
|
"trim"
|
|
228060
228470
|
]
|
|
@@ -228288,9 +228698,10 @@ var init_schemas = __esm({
|
|
|
228288
228698
|
},
|
|
228289
228699
|
path: {
|
|
228290
228700
|
title: "Screenshot (simple)",
|
|
228701
|
+
$comment: "The pattern gates the target's EXTENSION, not its characters or location: any path ending in .png/.PNG is accepted, plus an http(s) URL to a PNG (optionally with a query string, for signed URLs) and a `$VAR` reference. It deliberately does not restrict the character set \u2014 an earlier pattern allowed any Windows absolute path but limited non-Windows paths to [A-Za-z0-9_./\\-], so ordinary macOS/Linux projects (a space, parentheses, '~', or non-ASCII anywhere in the path) failed validation, including for the absolute paths doc-detective synthesizes internally for autoScreenshot and recording checkpoints. That charset never bounded WHERE a screenshot could be written (traversal like ../../x.png always passed), so it only made non-Windows projects second-class. See ADR 01077.",
|
|
228291
228702
|
description: "File path of the PNG file. Accepts absolute paths. If not specified, the file name is the ID of the step. If an `http(s)` URL is supplied, the remote image is downloaded and used as a read-only reference for comparison; the new capture is written to a local run-specific folder instead of being uploaded back to the URL.",
|
|
228292
228703
|
type: "string",
|
|
228293
|
-
pattern: "^(?:https?:\\/\\/.+\\.(?:png|PNG)(?:\\?.*)
|
|
228704
|
+
pattern: "^(?:https?:\\/\\/.+\\.(?:png|PNG)(?:\\?.*)?|.*\\.(?:png|PNG)|\\$[A-Za-z0-9_]+)$",
|
|
228294
228705
|
transform: [
|
|
228295
228706
|
"trim"
|
|
228296
228707
|
]
|
|
@@ -228548,9 +228959,10 @@ var init_schemas = __esm({
|
|
|
228548
228959
|
schemas: {
|
|
228549
228960
|
path: {
|
|
228550
228961
|
title: "Screenshot (simple)",
|
|
228962
|
+
$comment: "The pattern gates the target's EXTENSION, not its characters or location: any path ending in .png/.PNG is accepted, plus an http(s) URL to a PNG (optionally with a query string, for signed URLs) and a `$VAR` reference. It deliberately does not restrict the character set \u2014 an earlier pattern allowed any Windows absolute path but limited non-Windows paths to [A-Za-z0-9_./\\-], so ordinary macOS/Linux projects (a space, parentheses, '~', or non-ASCII anywhere in the path) failed validation, including for the absolute paths doc-detective synthesizes internally for autoScreenshot and recording checkpoints. That charset never bounded WHERE a screenshot could be written (traversal like ../../x.png always passed), so it only made non-Windows projects second-class. See ADR 01077.",
|
|
228551
228963
|
description: "File path of the PNG file. Accepts absolute paths. If not specified, the file name is the ID of the step. If an `http(s)` URL is supplied, the remote image is downloaded and used as a read-only reference for comparison; the new capture is written to a local run-specific folder instead of being uploaded back to the URL.",
|
|
228552
228964
|
type: "string",
|
|
228553
|
-
pattern: "^(?:https?:\\/\\/.+\\.(?:png|PNG)(?:\\?.*)
|
|
228965
|
+
pattern: "^(?:https?:\\/\\/.+\\.(?:png|PNG)(?:\\?.*)?|.*\\.(?:png|PNG)|\\$[A-Za-z0-9_]+)$",
|
|
228554
228966
|
transform: [
|
|
228555
228967
|
"trim"
|
|
228556
228968
|
]
|
|
@@ -228784,9 +229196,10 @@ var init_schemas = __esm({
|
|
|
228784
229196
|
},
|
|
228785
229197
|
path: {
|
|
228786
229198
|
title: "Screenshot (simple)",
|
|
229199
|
+
$comment: "The pattern gates the target's EXTENSION, not its characters or location: any path ending in .png/.PNG is accepted, plus an http(s) URL to a PNG (optionally with a query string, for signed URLs) and a `$VAR` reference. It deliberately does not restrict the character set \u2014 an earlier pattern allowed any Windows absolute path but limited non-Windows paths to [A-Za-z0-9_./\\-], so ordinary macOS/Linux projects (a space, parentheses, '~', or non-ASCII anywhere in the path) failed validation, including for the absolute paths doc-detective synthesizes internally for autoScreenshot and recording checkpoints. That charset never bounded WHERE a screenshot could be written (traversal like ../../x.png always passed), so it only made non-Windows projects second-class. See ADR 01077.",
|
|
228787
229200
|
description: "File path of the PNG file. Accepts absolute paths. If not specified, the file name is the ID of the step. If an `http(s)` URL is supplied, the remote image is downloaded and used as a read-only reference for comparison; the new capture is written to a local run-specific folder instead of being uploaded back to the URL.",
|
|
228788
229201
|
type: "string",
|
|
228789
|
-
pattern: "^(?:https?:\\/\\/.+\\.(?:png|PNG)(?:\\?.*)
|
|
229202
|
+
pattern: "^(?:https?:\\/\\/.+\\.(?:png|PNG)(?:\\?.*)?|.*\\.(?:png|PNG)|\\$[A-Za-z0-9_]+)$",
|
|
228790
229203
|
transform: [
|
|
228791
229204
|
"trim"
|
|
228792
229205
|
]
|
|
@@ -229260,9 +229673,10 @@ var init_schemas = __esm({
|
|
|
229260
229673
|
},
|
|
229261
229674
|
path: {
|
|
229262
229675
|
title: "Screenshot (simple)",
|
|
229676
|
+
$comment: "The pattern gates the target's EXTENSION, not its characters or location: any path ending in .png/.PNG is accepted, plus an http(s) URL to a PNG (optionally with a query string, for signed URLs) and a `$VAR` reference. It deliberately does not restrict the character set \u2014 an earlier pattern allowed any Windows absolute path but limited non-Windows paths to [A-Za-z0-9_./\\-], so ordinary macOS/Linux projects (a space, parentheses, '~', or non-ASCII anywhere in the path) failed validation, including for the absolute paths doc-detective synthesizes internally for autoScreenshot and recording checkpoints. That charset never bounded WHERE a screenshot could be written (traversal like ../../x.png always passed), so it only made non-Windows projects second-class. See ADR 01077.",
|
|
229263
229677
|
description: "File path of the PNG file. Accepts absolute paths. If not specified, the file name is the ID of the step. If an `http(s)` URL is supplied, the remote image is downloaded and used as a read-only reference for comparison; the new capture is written to a local run-specific folder instead of being uploaded back to the URL.",
|
|
229264
229678
|
type: "string",
|
|
229265
|
-
pattern: "^(?:https?:\\/\\/.+\\.(?:png|PNG)(?:\\?.*)
|
|
229679
|
+
pattern: "^(?:https?:\\/\\/.+\\.(?:png|PNG)(?:\\?.*)?|.*\\.(?:png|PNG)|\\$[A-Za-z0-9_]+)$",
|
|
229266
229680
|
transform: [
|
|
229267
229681
|
"trim"
|
|
229268
229682
|
]
|
|
@@ -229644,6 +230058,7 @@ var init_schemas = __esm({
|
|
|
229644
230058
|
"image.png",
|
|
229645
230059
|
"static/images/image.png",
|
|
229646
230060
|
"/User/manny/projects/doc-detective/static/images/image.png",
|
|
230061
|
+
"/Users/jane doe/projects/my docs (v2)/static/images/image.png",
|
|
229647
230062
|
"https://example.com/static/images/image.png",
|
|
229648
230063
|
{
|
|
229649
230064
|
path: "https://promptless-customer-doc-assets.s3.amazonaws.com/docs-images/request-changes-button-0c851bb3.png",
|
|
@@ -232078,10 +232493,11 @@ var init_schemas = __esm({
|
|
|
232078
232493
|
},
|
|
232079
232494
|
overwrite: {
|
|
232080
232495
|
type: "string",
|
|
232081
|
-
description: "If `true`, overwrites the existing recording at `path` if it exists.",
|
|
232496
|
+
description: "If `true`, overwrites the existing recording at `path` if it exists. If `false`, skips the recording when the file already exists. If `aboveVariation`, always records, but replaces the existing file (and its checkpoint baselines) only when the span's checkpoint screenshots show it meaningfully changed \u2014 requires `checkpoints`, so it turns them on with defaults when `checkpoints` is omitted or `false`; set `checkpoints` to an object to tune `maxVariation` or `directory`.",
|
|
232082
232497
|
enum: [
|
|
232083
232498
|
"true",
|
|
232084
|
-
"false"
|
|
232499
|
+
"false",
|
|
232500
|
+
"aboveVariation"
|
|
232085
232501
|
]
|
|
232086
232502
|
},
|
|
232087
232503
|
name: {
|
|
@@ -232139,6 +232555,38 @@ var init_schemas = __esm({
|
|
|
232139
232555
|
}
|
|
232140
232556
|
}
|
|
232141
232557
|
]
|
|
232558
|
+
},
|
|
232559
|
+
checkpoints: {
|
|
232560
|
+
title: "Recording checkpoints",
|
|
232561
|
+
description: "Capture a checkpoint screenshot after every step while this recording is active and compare each against a persistent baseline stored beside the recording (`<path>.checkpoints/` by default). Baselines seed on the first run; on later runs, per-checkpoint variation is reported in the `stopRecord` step's outputs, and variation beyond `maxVariation` surfaces as a WARNING. If `false` or unset, no checkpoints are captured.",
|
|
232562
|
+
anyOf: [
|
|
232563
|
+
{
|
|
232564
|
+
type: "boolean",
|
|
232565
|
+
title: "Recording checkpoints (boolean)",
|
|
232566
|
+
description: "If `true`, enables checkpoints with default settings."
|
|
232567
|
+
},
|
|
232568
|
+
{
|
|
232569
|
+
type: "object",
|
|
232570
|
+
title: "Recording checkpoints (detailed)",
|
|
232571
|
+
additionalProperties: false,
|
|
232572
|
+
properties: {
|
|
232573
|
+
maxVariation: {
|
|
232574
|
+
type: "number",
|
|
232575
|
+
description: "Maximum fractional pixel difference tolerated between a checkpoint and its baseline before the drift surfaces as a WARNING.",
|
|
232576
|
+
default: 0.05,
|
|
232577
|
+
minimum: 0,
|
|
232578
|
+
maximum: 1
|
|
232579
|
+
},
|
|
232580
|
+
directory: {
|
|
232581
|
+
type: "string",
|
|
232582
|
+
description: "Directory for the checkpoint baselines. If unset, defaults to a `.checkpoints` directory beside the recording (for example, `demo.mp4.checkpoints/`).",
|
|
232583
|
+
transform: [
|
|
232584
|
+
"trim"
|
|
232585
|
+
]
|
|
232586
|
+
}
|
|
232587
|
+
}
|
|
232588
|
+
}
|
|
232589
|
+
]
|
|
232142
232590
|
}
|
|
232143
232591
|
},
|
|
232144
232592
|
title: "Record (detailed)"
|
|
@@ -232400,10 +232848,11 @@ var init_schemas = __esm({
|
|
|
232400
232848
|
},
|
|
232401
232849
|
overwrite: {
|
|
232402
232850
|
type: "string",
|
|
232403
|
-
description: "If `true`, overwrites the existing recording at `path` if it exists.",
|
|
232851
|
+
description: "If `true`, overwrites the existing recording at `path` if it exists. If `false`, skips the recording when the file already exists. If `aboveVariation`, always records, but replaces the existing file (and its checkpoint baselines) only when the span's checkpoint screenshots show it meaningfully changed \u2014 requires `checkpoints`, so it turns them on with defaults when `checkpoints` is omitted or `false`; set `checkpoints` to an object to tune `maxVariation` or `directory`.",
|
|
232404
232852
|
enum: [
|
|
232405
232853
|
"true",
|
|
232406
|
-
"false"
|
|
232854
|
+
"false",
|
|
232855
|
+
"aboveVariation"
|
|
232407
232856
|
]
|
|
232408
232857
|
},
|
|
232409
232858
|
name: {
|
|
@@ -232461,6 +232910,38 @@ var init_schemas = __esm({
|
|
|
232461
232910
|
}
|
|
232462
232911
|
}
|
|
232463
232912
|
]
|
|
232913
|
+
},
|
|
232914
|
+
checkpoints: {
|
|
232915
|
+
title: "Recording checkpoints",
|
|
232916
|
+
description: "Capture a checkpoint screenshot after every step while this recording is active and compare each against a persistent baseline stored beside the recording (`<path>.checkpoints/` by default). Baselines seed on the first run; on later runs, per-checkpoint variation is reported in the `stopRecord` step's outputs, and variation beyond `maxVariation` surfaces as a WARNING. If `false` or unset, no checkpoints are captured.",
|
|
232917
|
+
anyOf: [
|
|
232918
|
+
{
|
|
232919
|
+
type: "boolean",
|
|
232920
|
+
title: "Recording checkpoints (boolean)",
|
|
232921
|
+
description: "If `true`, enables checkpoints with default settings."
|
|
232922
|
+
},
|
|
232923
|
+
{
|
|
232924
|
+
type: "object",
|
|
232925
|
+
title: "Recording checkpoints (detailed)",
|
|
232926
|
+
additionalProperties: false,
|
|
232927
|
+
properties: {
|
|
232928
|
+
maxVariation: {
|
|
232929
|
+
type: "number",
|
|
232930
|
+
description: "Maximum fractional pixel difference tolerated between a checkpoint and its baseline before the drift surfaces as a WARNING.",
|
|
232931
|
+
default: 0.05,
|
|
232932
|
+
minimum: 0,
|
|
232933
|
+
maximum: 1
|
|
232934
|
+
},
|
|
232935
|
+
directory: {
|
|
232936
|
+
type: "string",
|
|
232937
|
+
description: "Directory for the checkpoint baselines. If unset, defaults to a `.checkpoints` directory beside the recording (for example, `demo.mp4.checkpoints/`).",
|
|
232938
|
+
transform: [
|
|
232939
|
+
"trim"
|
|
232940
|
+
]
|
|
232941
|
+
}
|
|
232942
|
+
}
|
|
232943
|
+
}
|
|
232944
|
+
]
|
|
232464
232945
|
}
|
|
232465
232946
|
},
|
|
232466
232947
|
title: "Record (detailed)"
|
|
@@ -232527,6 +233008,17 @@ var init_schemas = __esm({
|
|
|
232527
233008
|
path: "results.mp4",
|
|
232528
233009
|
engine: "ffmpeg"
|
|
232529
233010
|
},
|
|
233011
|
+
{
|
|
233012
|
+
path: "results.mp4",
|
|
233013
|
+
checkpoints: true
|
|
233014
|
+
},
|
|
233015
|
+
{
|
|
233016
|
+
path: "results.mp4",
|
|
233017
|
+
checkpoints: {
|
|
233018
|
+
maxVariation: 0.02,
|
|
233019
|
+
directory: "baselines/results"
|
|
233020
|
+
}
|
|
233021
|
+
},
|
|
232530
233022
|
{
|
|
232531
233023
|
path: "results.mp4",
|
|
232532
233024
|
engine: {
|
|
@@ -272953,9 +273445,10 @@ var init_schemas = __esm({
|
|
|
272953
273445
|
anyOf: [
|
|
272954
273446
|
{
|
|
272955
273447
|
title: "Screenshot (simple)",
|
|
273448
|
+
$comment: "The pattern gates the target's EXTENSION, not its characters or location: any path ending in .png/.PNG is accepted, plus an http(s) URL to a PNG (optionally with a query string, for signed URLs) and a `$VAR` reference. It deliberately does not restrict the character set \u2014 an earlier pattern allowed any Windows absolute path but limited non-Windows paths to [A-Za-z0-9_./\\-], so ordinary macOS/Linux projects (a space, parentheses, '~', or non-ASCII anywhere in the path) failed validation, including for the absolute paths doc-detective synthesizes internally for autoScreenshot and recording checkpoints. That charset never bounded WHERE a screenshot could be written (traversal like ../../x.png always passed), so it only made non-Windows projects second-class. See ADR 01077.",
|
|
272956
273449
|
description: "File path of the PNG file. Accepts absolute paths. If not specified, the file name is the ID of the step. If an `http(s)` URL is supplied, the remote image is downloaded and used as a read-only reference for comparison; the new capture is written to a local run-specific folder instead of being uploaded back to the URL.",
|
|
272957
273450
|
type: "string",
|
|
272958
|
-
pattern: "^(?:https?:\\/\\/.+\\.(?:png|PNG)(?:\\?.*)
|
|
273451
|
+
pattern: "^(?:https?:\\/\\/.+\\.(?:png|PNG)(?:\\?.*)?|.*\\.(?:png|PNG)|\\$[A-Za-z0-9_]+)$",
|
|
272959
273452
|
transform: [
|
|
272960
273453
|
"trim"
|
|
272961
273454
|
]
|
|
@@ -273189,9 +273682,10 @@ var init_schemas = __esm({
|
|
|
273189
273682
|
},
|
|
273190
273683
|
path: {
|
|
273191
273684
|
title: "Screenshot (simple)",
|
|
273685
|
+
$comment: "The pattern gates the target's EXTENSION, not its characters or location: any path ending in .png/.PNG is accepted, plus an http(s) URL to a PNG (optionally with a query string, for signed URLs) and a `$VAR` reference. It deliberately does not restrict the character set \u2014 an earlier pattern allowed any Windows absolute path but limited non-Windows paths to [A-Za-z0-9_./\\-], so ordinary macOS/Linux projects (a space, parentheses, '~', or non-ASCII anywhere in the path) failed validation, including for the absolute paths doc-detective synthesizes internally for autoScreenshot and recording checkpoints. That charset never bounded WHERE a screenshot could be written (traversal like ../../x.png always passed), so it only made non-Windows projects second-class. See ADR 01077.",
|
|
273192
273686
|
description: "File path of the PNG file. Accepts absolute paths. If not specified, the file name is the ID of the step. If an `http(s)` URL is supplied, the remote image is downloaded and used as a read-only reference for comparison; the new capture is written to a local run-specific folder instead of being uploaded back to the URL.",
|
|
273193
273687
|
type: "string",
|
|
273194
|
-
pattern: "^(?:https?:\\/\\/.+\\.(?:png|PNG)(?:\\?.*)
|
|
273688
|
+
pattern: "^(?:https?:\\/\\/.+\\.(?:png|PNG)(?:\\?.*)?|.*\\.(?:png|PNG)|\\$[A-Za-z0-9_]+)$",
|
|
273195
273689
|
transform: [
|
|
273196
273690
|
"trim"
|
|
273197
273691
|
]
|
|
@@ -273449,9 +273943,10 @@ var init_schemas = __esm({
|
|
|
273449
273943
|
schemas: {
|
|
273450
273944
|
path: {
|
|
273451
273945
|
title: "Screenshot (simple)",
|
|
273946
|
+
$comment: "The pattern gates the target's EXTENSION, not its characters or location: any path ending in .png/.PNG is accepted, plus an http(s) URL to a PNG (optionally with a query string, for signed URLs) and a `$VAR` reference. It deliberately does not restrict the character set \u2014 an earlier pattern allowed any Windows absolute path but limited non-Windows paths to [A-Za-z0-9_./\\-], so ordinary macOS/Linux projects (a space, parentheses, '~', or non-ASCII anywhere in the path) failed validation, including for the absolute paths doc-detective synthesizes internally for autoScreenshot and recording checkpoints. That charset never bounded WHERE a screenshot could be written (traversal like ../../x.png always passed), so it only made non-Windows projects second-class. See ADR 01077.",
|
|
273452
273947
|
description: "File path of the PNG file. Accepts absolute paths. If not specified, the file name is the ID of the step. If an `http(s)` URL is supplied, the remote image is downloaded and used as a read-only reference for comparison; the new capture is written to a local run-specific folder instead of being uploaded back to the URL.",
|
|
273453
273948
|
type: "string",
|
|
273454
|
-
pattern: "^(?:https?:\\/\\/.+\\.(?:png|PNG)(?:\\?.*)
|
|
273949
|
+
pattern: "^(?:https?:\\/\\/.+\\.(?:png|PNG)(?:\\?.*)?|.*\\.(?:png|PNG)|\\$[A-Za-z0-9_]+)$",
|
|
273455
273950
|
transform: [
|
|
273456
273951
|
"trim"
|
|
273457
273952
|
]
|
|
@@ -273685,9 +274180,10 @@ var init_schemas = __esm({
|
|
|
273685
274180
|
},
|
|
273686
274181
|
path: {
|
|
273687
274182
|
title: "Screenshot (simple)",
|
|
274183
|
+
$comment: "The pattern gates the target's EXTENSION, not its characters or location: any path ending in .png/.PNG is accepted, plus an http(s) URL to a PNG (optionally with a query string, for signed URLs) and a `$VAR` reference. It deliberately does not restrict the character set \u2014 an earlier pattern allowed any Windows absolute path but limited non-Windows paths to [A-Za-z0-9_./\\-], so ordinary macOS/Linux projects (a space, parentheses, '~', or non-ASCII anywhere in the path) failed validation, including for the absolute paths doc-detective synthesizes internally for autoScreenshot and recording checkpoints. That charset never bounded WHERE a screenshot could be written (traversal like ../../x.png always passed), so it only made non-Windows projects second-class. See ADR 01077.",
|
|
273688
274184
|
description: "File path of the PNG file. Accepts absolute paths. If not specified, the file name is the ID of the step. If an `http(s)` URL is supplied, the remote image is downloaded and used as a read-only reference for comparison; the new capture is written to a local run-specific folder instead of being uploaded back to the URL.",
|
|
273689
274185
|
type: "string",
|
|
273690
|
-
pattern: "^(?:https?:\\/\\/.+\\.(?:png|PNG)(?:\\?.*)
|
|
274186
|
+
pattern: "^(?:https?:\\/\\/.+\\.(?:png|PNG)(?:\\?.*)?|.*\\.(?:png|PNG)|\\$[A-Za-z0-9_]+)$",
|
|
273691
274187
|
transform: [
|
|
273692
274188
|
"trim"
|
|
273693
274189
|
]
|
|
@@ -274161,9 +274657,10 @@ var init_schemas = __esm({
|
|
|
274161
274657
|
},
|
|
274162
274658
|
path: {
|
|
274163
274659
|
title: "Screenshot (simple)",
|
|
274660
|
+
$comment: "The pattern gates the target's EXTENSION, not its characters or location: any path ending in .png/.PNG is accepted, plus an http(s) URL to a PNG (optionally with a query string, for signed URLs) and a `$VAR` reference. It deliberately does not restrict the character set \u2014 an earlier pattern allowed any Windows absolute path but limited non-Windows paths to [A-Za-z0-9_./\\-], so ordinary macOS/Linux projects (a space, parentheses, '~', or non-ASCII anywhere in the path) failed validation, including for the absolute paths doc-detective synthesizes internally for autoScreenshot and recording checkpoints. That charset never bounded WHERE a screenshot could be written (traversal like ../../x.png always passed), so it only made non-Windows projects second-class. See ADR 01077.",
|
|
274164
274661
|
description: "File path of the PNG file. Accepts absolute paths. If not specified, the file name is the ID of the step. If an `http(s)` URL is supplied, the remote image is downloaded and used as a read-only reference for comparison; the new capture is written to a local run-specific folder instead of being uploaded back to the URL.",
|
|
274165
274662
|
type: "string",
|
|
274166
|
-
pattern: "^(?:https?:\\/\\/.+\\.(?:png|PNG)(?:\\?.*)
|
|
274663
|
+
pattern: "^(?:https?:\\/\\/.+\\.(?:png|PNG)(?:\\?.*)?|.*\\.(?:png|PNG)|\\$[A-Za-z0-9_]+)$",
|
|
274167
274664
|
transform: [
|
|
274168
274665
|
"trim"
|
|
274169
274666
|
]
|
|
@@ -274545,6 +275042,7 @@ var init_schemas = __esm({
|
|
|
274545
275042
|
"image.png",
|
|
274546
275043
|
"static/images/image.png",
|
|
274547
275044
|
"/User/manny/projects/doc-detective/static/images/image.png",
|
|
275045
|
+
"/Users/jane doe/projects/my docs (v2)/static/images/image.png",
|
|
274548
275046
|
"https://example.com/static/images/image.png",
|
|
274549
275047
|
{
|
|
274550
275048
|
path: "https://promptless-customer-doc-assets.s3.amazonaws.com/docs-images/request-changes-button-0c851bb3.png",
|
|
@@ -276979,10 +277477,11 @@ var init_schemas = __esm({
|
|
|
276979
277477
|
},
|
|
276980
277478
|
overwrite: {
|
|
276981
277479
|
type: "string",
|
|
276982
|
-
description: "If `true`, overwrites the existing recording at `path` if it exists.",
|
|
277480
|
+
description: "If `true`, overwrites the existing recording at `path` if it exists. If `false`, skips the recording when the file already exists. If `aboveVariation`, always records, but replaces the existing file (and its checkpoint baselines) only when the span's checkpoint screenshots show it meaningfully changed \u2014 requires `checkpoints`, so it turns them on with defaults when `checkpoints` is omitted or `false`; set `checkpoints` to an object to tune `maxVariation` or `directory`.",
|
|
276983
277481
|
enum: [
|
|
276984
277482
|
"true",
|
|
276985
|
-
"false"
|
|
277483
|
+
"false",
|
|
277484
|
+
"aboveVariation"
|
|
276986
277485
|
]
|
|
276987
277486
|
},
|
|
276988
277487
|
name: {
|
|
@@ -277040,6 +277539,38 @@ var init_schemas = __esm({
|
|
|
277040
277539
|
}
|
|
277041
277540
|
}
|
|
277042
277541
|
]
|
|
277542
|
+
},
|
|
277543
|
+
checkpoints: {
|
|
277544
|
+
title: "Recording checkpoints",
|
|
277545
|
+
description: "Capture a checkpoint screenshot after every step while this recording is active and compare each against a persistent baseline stored beside the recording (`<path>.checkpoints/` by default). Baselines seed on the first run; on later runs, per-checkpoint variation is reported in the `stopRecord` step's outputs, and variation beyond `maxVariation` surfaces as a WARNING. If `false` or unset, no checkpoints are captured.",
|
|
277546
|
+
anyOf: [
|
|
277547
|
+
{
|
|
277548
|
+
type: "boolean",
|
|
277549
|
+
title: "Recording checkpoints (boolean)",
|
|
277550
|
+
description: "If `true`, enables checkpoints with default settings."
|
|
277551
|
+
},
|
|
277552
|
+
{
|
|
277553
|
+
type: "object",
|
|
277554
|
+
title: "Recording checkpoints (detailed)",
|
|
277555
|
+
additionalProperties: false,
|
|
277556
|
+
properties: {
|
|
277557
|
+
maxVariation: {
|
|
277558
|
+
type: "number",
|
|
277559
|
+
description: "Maximum fractional pixel difference tolerated between a checkpoint and its baseline before the drift surfaces as a WARNING.",
|
|
277560
|
+
default: 0.05,
|
|
277561
|
+
minimum: 0,
|
|
277562
|
+
maximum: 1
|
|
277563
|
+
},
|
|
277564
|
+
directory: {
|
|
277565
|
+
type: "string",
|
|
277566
|
+
description: "Directory for the checkpoint baselines. If unset, defaults to a `.checkpoints` directory beside the recording (for example, `demo.mp4.checkpoints/`).",
|
|
277567
|
+
transform: [
|
|
277568
|
+
"trim"
|
|
277569
|
+
]
|
|
277570
|
+
}
|
|
277571
|
+
}
|
|
277572
|
+
}
|
|
277573
|
+
]
|
|
277043
277574
|
}
|
|
277044
277575
|
},
|
|
277045
277576
|
title: "Record (detailed)"
|
|
@@ -277301,10 +277832,11 @@ var init_schemas = __esm({
|
|
|
277301
277832
|
},
|
|
277302
277833
|
overwrite: {
|
|
277303
277834
|
type: "string",
|
|
277304
|
-
description: "If `true`, overwrites the existing recording at `path` if it exists.",
|
|
277835
|
+
description: "If `true`, overwrites the existing recording at `path` if it exists. If `false`, skips the recording when the file already exists. If `aboveVariation`, always records, but replaces the existing file (and its checkpoint baselines) only when the span's checkpoint screenshots show it meaningfully changed \u2014 requires `checkpoints`, so it turns them on with defaults when `checkpoints` is omitted or `false`; set `checkpoints` to an object to tune `maxVariation` or `directory`.",
|
|
277305
277836
|
enum: [
|
|
277306
277837
|
"true",
|
|
277307
|
-
"false"
|
|
277838
|
+
"false",
|
|
277839
|
+
"aboveVariation"
|
|
277308
277840
|
]
|
|
277309
277841
|
},
|
|
277310
277842
|
name: {
|
|
@@ -277362,6 +277894,38 @@ var init_schemas = __esm({
|
|
|
277362
277894
|
}
|
|
277363
277895
|
}
|
|
277364
277896
|
]
|
|
277897
|
+
},
|
|
277898
|
+
checkpoints: {
|
|
277899
|
+
title: "Recording checkpoints",
|
|
277900
|
+
description: "Capture a checkpoint screenshot after every step while this recording is active and compare each against a persistent baseline stored beside the recording (`<path>.checkpoints/` by default). Baselines seed on the first run; on later runs, per-checkpoint variation is reported in the `stopRecord` step's outputs, and variation beyond `maxVariation` surfaces as a WARNING. If `false` or unset, no checkpoints are captured.",
|
|
277901
|
+
anyOf: [
|
|
277902
|
+
{
|
|
277903
|
+
type: "boolean",
|
|
277904
|
+
title: "Recording checkpoints (boolean)",
|
|
277905
|
+
description: "If `true`, enables checkpoints with default settings."
|
|
277906
|
+
},
|
|
277907
|
+
{
|
|
277908
|
+
type: "object",
|
|
277909
|
+
title: "Recording checkpoints (detailed)",
|
|
277910
|
+
additionalProperties: false,
|
|
277911
|
+
properties: {
|
|
277912
|
+
maxVariation: {
|
|
277913
|
+
type: "number",
|
|
277914
|
+
description: "Maximum fractional pixel difference tolerated between a checkpoint and its baseline before the drift surfaces as a WARNING.",
|
|
277915
|
+
default: 0.05,
|
|
277916
|
+
minimum: 0,
|
|
277917
|
+
maximum: 1
|
|
277918
|
+
},
|
|
277919
|
+
directory: {
|
|
277920
|
+
type: "string",
|
|
277921
|
+
description: "Directory for the checkpoint baselines. If unset, defaults to a `.checkpoints` directory beside the recording (for example, `demo.mp4.checkpoints/`).",
|
|
277922
|
+
transform: [
|
|
277923
|
+
"trim"
|
|
277924
|
+
]
|
|
277925
|
+
}
|
|
277926
|
+
}
|
|
277927
|
+
}
|
|
277928
|
+
]
|
|
277365
277929
|
}
|
|
277366
277930
|
},
|
|
277367
277931
|
title: "Record (detailed)"
|
|
@@ -277428,6 +277992,17 @@ var init_schemas = __esm({
|
|
|
277428
277992
|
path: "results.mp4",
|
|
277429
277993
|
engine: "ffmpeg"
|
|
277430
277994
|
},
|
|
277995
|
+
{
|
|
277996
|
+
path: "results.mp4",
|
|
277997
|
+
checkpoints: true
|
|
277998
|
+
},
|
|
277999
|
+
{
|
|
278000
|
+
path: "results.mp4",
|
|
278001
|
+
checkpoints: {
|
|
278002
|
+
maxVariation: 0.02,
|
|
278003
|
+
directory: "baselines/results"
|
|
278004
|
+
}
|
|
278005
|
+
},
|
|
277431
278006
|
{
|
|
277432
278007
|
path: "results.mp4",
|
|
277433
278008
|
engine: {
|
|
@@ -320815,9 +321390,10 @@ var init_schemas = __esm({
|
|
|
320815
321390
|
anyOf: [
|
|
320816
321391
|
{
|
|
320817
321392
|
title: "Screenshot (simple)",
|
|
321393
|
+
$comment: "The pattern gates the target's EXTENSION, not its characters or location: any path ending in .png/.PNG is accepted, plus an http(s) URL to a PNG (optionally with a query string, for signed URLs) and a `$VAR` reference. It deliberately does not restrict the character set \u2014 an earlier pattern allowed any Windows absolute path but limited non-Windows paths to [A-Za-z0-9_./\\-], so ordinary macOS/Linux projects (a space, parentheses, '~', or non-ASCII anywhere in the path) failed validation, including for the absolute paths doc-detective synthesizes internally for autoScreenshot and recording checkpoints. That charset never bounded WHERE a screenshot could be written (traversal like ../../x.png always passed), so it only made non-Windows projects second-class. See ADR 01077.",
|
|
320818
321394
|
description: "File path of the PNG file. Accepts absolute paths. If not specified, the file name is the ID of the step. If an `http(s)` URL is supplied, the remote image is downloaded and used as a read-only reference for comparison; the new capture is written to a local run-specific folder instead of being uploaded back to the URL.",
|
|
320819
321395
|
type: "string",
|
|
320820
|
-
pattern: "^(?:https?:\\/\\/.+\\.(?:png|PNG)(?:\\?.*)
|
|
321396
|
+
pattern: "^(?:https?:\\/\\/.+\\.(?:png|PNG)(?:\\?.*)?|.*\\.(?:png|PNG)|\\$[A-Za-z0-9_]+)$",
|
|
320821
321397
|
transform: [
|
|
320822
321398
|
"trim"
|
|
320823
321399
|
]
|
|
@@ -321051,9 +321627,10 @@ var init_schemas = __esm({
|
|
|
321051
321627
|
},
|
|
321052
321628
|
path: {
|
|
321053
321629
|
title: "Screenshot (simple)",
|
|
321630
|
+
$comment: "The pattern gates the target's EXTENSION, not its characters or location: any path ending in .png/.PNG is accepted, plus an http(s) URL to a PNG (optionally with a query string, for signed URLs) and a `$VAR` reference. It deliberately does not restrict the character set \u2014 an earlier pattern allowed any Windows absolute path but limited non-Windows paths to [A-Za-z0-9_./\\-], so ordinary macOS/Linux projects (a space, parentheses, '~', or non-ASCII anywhere in the path) failed validation, including for the absolute paths doc-detective synthesizes internally for autoScreenshot and recording checkpoints. That charset never bounded WHERE a screenshot could be written (traversal like ../../x.png always passed), so it only made non-Windows projects second-class. See ADR 01077.",
|
|
321054
321631
|
description: "File path of the PNG file. Accepts absolute paths. If not specified, the file name is the ID of the step. If an `http(s)` URL is supplied, the remote image is downloaded and used as a read-only reference for comparison; the new capture is written to a local run-specific folder instead of being uploaded back to the URL.",
|
|
321055
321632
|
type: "string",
|
|
321056
|
-
pattern: "^(?:https?:\\/\\/.+\\.(?:png|PNG)(?:\\?.*)
|
|
321633
|
+
pattern: "^(?:https?:\\/\\/.+\\.(?:png|PNG)(?:\\?.*)?|.*\\.(?:png|PNG)|\\$[A-Za-z0-9_]+)$",
|
|
321057
321634
|
transform: [
|
|
321058
321635
|
"trim"
|
|
321059
321636
|
]
|
|
@@ -321311,9 +321888,10 @@ var init_schemas = __esm({
|
|
|
321311
321888
|
schemas: {
|
|
321312
321889
|
path: {
|
|
321313
321890
|
title: "Screenshot (simple)",
|
|
321891
|
+
$comment: "The pattern gates the target's EXTENSION, not its characters or location: any path ending in .png/.PNG is accepted, plus an http(s) URL to a PNG (optionally with a query string, for signed URLs) and a `$VAR` reference. It deliberately does not restrict the character set \u2014 an earlier pattern allowed any Windows absolute path but limited non-Windows paths to [A-Za-z0-9_./\\-], so ordinary macOS/Linux projects (a space, parentheses, '~', or non-ASCII anywhere in the path) failed validation, including for the absolute paths doc-detective synthesizes internally for autoScreenshot and recording checkpoints. That charset never bounded WHERE a screenshot could be written (traversal like ../../x.png always passed), so it only made non-Windows projects second-class. See ADR 01077.",
|
|
321314
321892
|
description: "File path of the PNG file. Accepts absolute paths. If not specified, the file name is the ID of the step. If an `http(s)` URL is supplied, the remote image is downloaded and used as a read-only reference for comparison; the new capture is written to a local run-specific folder instead of being uploaded back to the URL.",
|
|
321315
321893
|
type: "string",
|
|
321316
|
-
pattern: "^(?:https?:\\/\\/.+\\.(?:png|PNG)(?:\\?.*)
|
|
321894
|
+
pattern: "^(?:https?:\\/\\/.+\\.(?:png|PNG)(?:\\?.*)?|.*\\.(?:png|PNG)|\\$[A-Za-z0-9_]+)$",
|
|
321317
321895
|
transform: [
|
|
321318
321896
|
"trim"
|
|
321319
321897
|
]
|
|
@@ -321547,9 +322125,10 @@ var init_schemas = __esm({
|
|
|
321547
322125
|
},
|
|
321548
322126
|
path: {
|
|
321549
322127
|
title: "Screenshot (simple)",
|
|
322128
|
+
$comment: "The pattern gates the target's EXTENSION, not its characters or location: any path ending in .png/.PNG is accepted, plus an http(s) URL to a PNG (optionally with a query string, for signed URLs) and a `$VAR` reference. It deliberately does not restrict the character set \u2014 an earlier pattern allowed any Windows absolute path but limited non-Windows paths to [A-Za-z0-9_./\\-], so ordinary macOS/Linux projects (a space, parentheses, '~', or non-ASCII anywhere in the path) failed validation, including for the absolute paths doc-detective synthesizes internally for autoScreenshot and recording checkpoints. That charset never bounded WHERE a screenshot could be written (traversal like ../../x.png always passed), so it only made non-Windows projects second-class. See ADR 01077.",
|
|
321550
322129
|
description: "File path of the PNG file. Accepts absolute paths. If not specified, the file name is the ID of the step. If an `http(s)` URL is supplied, the remote image is downloaded and used as a read-only reference for comparison; the new capture is written to a local run-specific folder instead of being uploaded back to the URL.",
|
|
321551
322130
|
type: "string",
|
|
321552
|
-
pattern: "^(?:https?:\\/\\/.+\\.(?:png|PNG)(?:\\?.*)
|
|
322131
|
+
pattern: "^(?:https?:\\/\\/.+\\.(?:png|PNG)(?:\\?.*)?|.*\\.(?:png|PNG)|\\$[A-Za-z0-9_]+)$",
|
|
321553
322132
|
transform: [
|
|
321554
322133
|
"trim"
|
|
321555
322134
|
]
|
|
@@ -322023,9 +322602,10 @@ var init_schemas = __esm({
|
|
|
322023
322602
|
},
|
|
322024
322603
|
path: {
|
|
322025
322604
|
title: "Screenshot (simple)",
|
|
322605
|
+
$comment: "The pattern gates the target's EXTENSION, not its characters or location: any path ending in .png/.PNG is accepted, plus an http(s) URL to a PNG (optionally with a query string, for signed URLs) and a `$VAR` reference. It deliberately does not restrict the character set \u2014 an earlier pattern allowed any Windows absolute path but limited non-Windows paths to [A-Za-z0-9_./\\-], so ordinary macOS/Linux projects (a space, parentheses, '~', or non-ASCII anywhere in the path) failed validation, including for the absolute paths doc-detective synthesizes internally for autoScreenshot and recording checkpoints. That charset never bounded WHERE a screenshot could be written (traversal like ../../x.png always passed), so it only made non-Windows projects second-class. See ADR 01077.",
|
|
322026
322606
|
description: "File path of the PNG file. Accepts absolute paths. If not specified, the file name is the ID of the step. If an `http(s)` URL is supplied, the remote image is downloaded and used as a read-only reference for comparison; the new capture is written to a local run-specific folder instead of being uploaded back to the URL.",
|
|
322027
322607
|
type: "string",
|
|
322028
|
-
pattern: "^(?:https?:\\/\\/.+\\.(?:png|PNG)(?:\\?.*)
|
|
322608
|
+
pattern: "^(?:https?:\\/\\/.+\\.(?:png|PNG)(?:\\?.*)?|.*\\.(?:png|PNG)|\\$[A-Za-z0-9_]+)$",
|
|
322029
322609
|
transform: [
|
|
322030
322610
|
"trim"
|
|
322031
322611
|
]
|
|
@@ -322407,6 +322987,7 @@ var init_schemas = __esm({
|
|
|
322407
322987
|
"image.png",
|
|
322408
322988
|
"static/images/image.png",
|
|
322409
322989
|
"/User/manny/projects/doc-detective/static/images/image.png",
|
|
322990
|
+
"/Users/jane doe/projects/my docs (v2)/static/images/image.png",
|
|
322410
322991
|
"https://example.com/static/images/image.png",
|
|
322411
322992
|
{
|
|
322412
322993
|
path: "https://promptless-customer-doc-assets.s3.amazonaws.com/docs-images/request-changes-button-0c851bb3.png",
|
|
@@ -324841,10 +325422,11 @@ var init_schemas = __esm({
|
|
|
324841
325422
|
},
|
|
324842
325423
|
overwrite: {
|
|
324843
325424
|
type: "string",
|
|
324844
|
-
description: "If `true`, overwrites the existing recording at `path` if it exists.",
|
|
325425
|
+
description: "If `true`, overwrites the existing recording at `path` if it exists. If `false`, skips the recording when the file already exists. If `aboveVariation`, always records, but replaces the existing file (and its checkpoint baselines) only when the span's checkpoint screenshots show it meaningfully changed \u2014 requires `checkpoints`, so it turns them on with defaults when `checkpoints` is omitted or `false`; set `checkpoints` to an object to tune `maxVariation` or `directory`.",
|
|
324845
325426
|
enum: [
|
|
324846
325427
|
"true",
|
|
324847
|
-
"false"
|
|
325428
|
+
"false",
|
|
325429
|
+
"aboveVariation"
|
|
324848
325430
|
]
|
|
324849
325431
|
},
|
|
324850
325432
|
name: {
|
|
@@ -324902,6 +325484,38 @@ var init_schemas = __esm({
|
|
|
324902
325484
|
}
|
|
324903
325485
|
}
|
|
324904
325486
|
]
|
|
325487
|
+
},
|
|
325488
|
+
checkpoints: {
|
|
325489
|
+
title: "Recording checkpoints",
|
|
325490
|
+
description: "Capture a checkpoint screenshot after every step while this recording is active and compare each against a persistent baseline stored beside the recording (`<path>.checkpoints/` by default). Baselines seed on the first run; on later runs, per-checkpoint variation is reported in the `stopRecord` step's outputs, and variation beyond `maxVariation` surfaces as a WARNING. If `false` or unset, no checkpoints are captured.",
|
|
325491
|
+
anyOf: [
|
|
325492
|
+
{
|
|
325493
|
+
type: "boolean",
|
|
325494
|
+
title: "Recording checkpoints (boolean)",
|
|
325495
|
+
description: "If `true`, enables checkpoints with default settings."
|
|
325496
|
+
},
|
|
325497
|
+
{
|
|
325498
|
+
type: "object",
|
|
325499
|
+
title: "Recording checkpoints (detailed)",
|
|
325500
|
+
additionalProperties: false,
|
|
325501
|
+
properties: {
|
|
325502
|
+
maxVariation: {
|
|
325503
|
+
type: "number",
|
|
325504
|
+
description: "Maximum fractional pixel difference tolerated between a checkpoint and its baseline before the drift surfaces as a WARNING.",
|
|
325505
|
+
default: 0.05,
|
|
325506
|
+
minimum: 0,
|
|
325507
|
+
maximum: 1
|
|
325508
|
+
},
|
|
325509
|
+
directory: {
|
|
325510
|
+
type: "string",
|
|
325511
|
+
description: "Directory for the checkpoint baselines. If unset, defaults to a `.checkpoints` directory beside the recording (for example, `demo.mp4.checkpoints/`).",
|
|
325512
|
+
transform: [
|
|
325513
|
+
"trim"
|
|
325514
|
+
]
|
|
325515
|
+
}
|
|
325516
|
+
}
|
|
325517
|
+
}
|
|
325518
|
+
]
|
|
324905
325519
|
}
|
|
324906
325520
|
},
|
|
324907
325521
|
title: "Record (detailed)"
|
|
@@ -325163,10 +325777,11 @@ var init_schemas = __esm({
|
|
|
325163
325777
|
},
|
|
325164
325778
|
overwrite: {
|
|
325165
325779
|
type: "string",
|
|
325166
|
-
description: "If `true`, overwrites the existing recording at `path` if it exists.",
|
|
325780
|
+
description: "If `true`, overwrites the existing recording at `path` if it exists. If `false`, skips the recording when the file already exists. If `aboveVariation`, always records, but replaces the existing file (and its checkpoint baselines) only when the span's checkpoint screenshots show it meaningfully changed \u2014 requires `checkpoints`, so it turns them on with defaults when `checkpoints` is omitted or `false`; set `checkpoints` to an object to tune `maxVariation` or `directory`.",
|
|
325167
325781
|
enum: [
|
|
325168
325782
|
"true",
|
|
325169
|
-
"false"
|
|
325783
|
+
"false",
|
|
325784
|
+
"aboveVariation"
|
|
325170
325785
|
]
|
|
325171
325786
|
},
|
|
325172
325787
|
name: {
|
|
@@ -325224,6 +325839,38 @@ var init_schemas = __esm({
|
|
|
325224
325839
|
}
|
|
325225
325840
|
}
|
|
325226
325841
|
]
|
|
325842
|
+
},
|
|
325843
|
+
checkpoints: {
|
|
325844
|
+
title: "Recording checkpoints",
|
|
325845
|
+
description: "Capture a checkpoint screenshot after every step while this recording is active and compare each against a persistent baseline stored beside the recording (`<path>.checkpoints/` by default). Baselines seed on the first run; on later runs, per-checkpoint variation is reported in the `stopRecord` step's outputs, and variation beyond `maxVariation` surfaces as a WARNING. If `false` or unset, no checkpoints are captured.",
|
|
325846
|
+
anyOf: [
|
|
325847
|
+
{
|
|
325848
|
+
type: "boolean",
|
|
325849
|
+
title: "Recording checkpoints (boolean)",
|
|
325850
|
+
description: "If `true`, enables checkpoints with default settings."
|
|
325851
|
+
},
|
|
325852
|
+
{
|
|
325853
|
+
type: "object",
|
|
325854
|
+
title: "Recording checkpoints (detailed)",
|
|
325855
|
+
additionalProperties: false,
|
|
325856
|
+
properties: {
|
|
325857
|
+
maxVariation: {
|
|
325858
|
+
type: "number",
|
|
325859
|
+
description: "Maximum fractional pixel difference tolerated between a checkpoint and its baseline before the drift surfaces as a WARNING.",
|
|
325860
|
+
default: 0.05,
|
|
325861
|
+
minimum: 0,
|
|
325862
|
+
maximum: 1
|
|
325863
|
+
},
|
|
325864
|
+
directory: {
|
|
325865
|
+
type: "string",
|
|
325866
|
+
description: "Directory for the checkpoint baselines. If unset, defaults to a `.checkpoints` directory beside the recording (for example, `demo.mp4.checkpoints/`).",
|
|
325867
|
+
transform: [
|
|
325868
|
+
"trim"
|
|
325869
|
+
]
|
|
325870
|
+
}
|
|
325871
|
+
}
|
|
325872
|
+
}
|
|
325873
|
+
]
|
|
325227
325874
|
}
|
|
325228
325875
|
},
|
|
325229
325876
|
title: "Record (detailed)"
|
|
@@ -325290,6 +325937,17 @@ var init_schemas = __esm({
|
|
|
325290
325937
|
path: "results.mp4",
|
|
325291
325938
|
engine: "ffmpeg"
|
|
325292
325939
|
},
|
|
325940
|
+
{
|
|
325941
|
+
path: "results.mp4",
|
|
325942
|
+
checkpoints: true
|
|
325943
|
+
},
|
|
325944
|
+
{
|
|
325945
|
+
path: "results.mp4",
|
|
325946
|
+
checkpoints: {
|
|
325947
|
+
maxVariation: 0.02,
|
|
325948
|
+
directory: "baselines/results"
|
|
325949
|
+
}
|
|
325950
|
+
},
|
|
325293
325951
|
{
|
|
325294
325952
|
path: "results.mp4",
|
|
325295
325953
|
engine: {
|
|
@@ -365716,9 +366374,10 @@ var init_schemas = __esm({
|
|
|
365716
366374
|
anyOf: [
|
|
365717
366375
|
{
|
|
365718
366376
|
title: "Screenshot (simple)",
|
|
366377
|
+
$comment: "The pattern gates the target's EXTENSION, not its characters or location: any path ending in .png/.PNG is accepted, plus an http(s) URL to a PNG (optionally with a query string, for signed URLs) and a `$VAR` reference. It deliberately does not restrict the character set \u2014 an earlier pattern allowed any Windows absolute path but limited non-Windows paths to [A-Za-z0-9_./\\-], so ordinary macOS/Linux projects (a space, parentheses, '~', or non-ASCII anywhere in the path) failed validation, including for the absolute paths doc-detective synthesizes internally for autoScreenshot and recording checkpoints. That charset never bounded WHERE a screenshot could be written (traversal like ../../x.png always passed), so it only made non-Windows projects second-class. See ADR 01077.",
|
|
365719
366378
|
description: "File path of the PNG file. Accepts absolute paths. If not specified, the file name is the ID of the step. If an `http(s)` URL is supplied, the remote image is downloaded and used as a read-only reference for comparison; the new capture is written to a local run-specific folder instead of being uploaded back to the URL.",
|
|
365720
366379
|
type: "string",
|
|
365721
|
-
pattern: "^(?:https?:\\/\\/.+\\.(?:png|PNG)(?:\\?.*)
|
|
366380
|
+
pattern: "^(?:https?:\\/\\/.+\\.(?:png|PNG)(?:\\?.*)?|.*\\.(?:png|PNG)|\\$[A-Za-z0-9_]+)$",
|
|
365722
366381
|
transform: [
|
|
365723
366382
|
"trim"
|
|
365724
366383
|
]
|
|
@@ -365952,9 +366611,10 @@ var init_schemas = __esm({
|
|
|
365952
366611
|
},
|
|
365953
366612
|
path: {
|
|
365954
366613
|
title: "Screenshot (simple)",
|
|
366614
|
+
$comment: "The pattern gates the target's EXTENSION, not its characters or location: any path ending in .png/.PNG is accepted, plus an http(s) URL to a PNG (optionally with a query string, for signed URLs) and a `$VAR` reference. It deliberately does not restrict the character set \u2014 an earlier pattern allowed any Windows absolute path but limited non-Windows paths to [A-Za-z0-9_./\\-], so ordinary macOS/Linux projects (a space, parentheses, '~', or non-ASCII anywhere in the path) failed validation, including for the absolute paths doc-detective synthesizes internally for autoScreenshot and recording checkpoints. That charset never bounded WHERE a screenshot could be written (traversal like ../../x.png always passed), so it only made non-Windows projects second-class. See ADR 01077.",
|
|
365955
366615
|
description: "File path of the PNG file. Accepts absolute paths. If not specified, the file name is the ID of the step. If an `http(s)` URL is supplied, the remote image is downloaded and used as a read-only reference for comparison; the new capture is written to a local run-specific folder instead of being uploaded back to the URL.",
|
|
365956
366616
|
type: "string",
|
|
365957
|
-
pattern: "^(?:https?:\\/\\/.+\\.(?:png|PNG)(?:\\?.*)
|
|
366617
|
+
pattern: "^(?:https?:\\/\\/.+\\.(?:png|PNG)(?:\\?.*)?|.*\\.(?:png|PNG)|\\$[A-Za-z0-9_]+)$",
|
|
365958
366618
|
transform: [
|
|
365959
366619
|
"trim"
|
|
365960
366620
|
]
|
|
@@ -366212,9 +366872,10 @@ var init_schemas = __esm({
|
|
|
366212
366872
|
schemas: {
|
|
366213
366873
|
path: {
|
|
366214
366874
|
title: "Screenshot (simple)",
|
|
366875
|
+
$comment: "The pattern gates the target's EXTENSION, not its characters or location: any path ending in .png/.PNG is accepted, plus an http(s) URL to a PNG (optionally with a query string, for signed URLs) and a `$VAR` reference. It deliberately does not restrict the character set \u2014 an earlier pattern allowed any Windows absolute path but limited non-Windows paths to [A-Za-z0-9_./\\-], so ordinary macOS/Linux projects (a space, parentheses, '~', or non-ASCII anywhere in the path) failed validation, including for the absolute paths doc-detective synthesizes internally for autoScreenshot and recording checkpoints. That charset never bounded WHERE a screenshot could be written (traversal like ../../x.png always passed), so it only made non-Windows projects second-class. See ADR 01077.",
|
|
366215
366876
|
description: "File path of the PNG file. Accepts absolute paths. If not specified, the file name is the ID of the step. If an `http(s)` URL is supplied, the remote image is downloaded and used as a read-only reference for comparison; the new capture is written to a local run-specific folder instead of being uploaded back to the URL.",
|
|
366216
366877
|
type: "string",
|
|
366217
|
-
pattern: "^(?:https?:\\/\\/.+\\.(?:png|PNG)(?:\\?.*)
|
|
366878
|
+
pattern: "^(?:https?:\\/\\/.+\\.(?:png|PNG)(?:\\?.*)?|.*\\.(?:png|PNG)|\\$[A-Za-z0-9_]+)$",
|
|
366218
366879
|
transform: [
|
|
366219
366880
|
"trim"
|
|
366220
366881
|
]
|
|
@@ -366448,9 +367109,10 @@ var init_schemas = __esm({
|
|
|
366448
367109
|
},
|
|
366449
367110
|
path: {
|
|
366450
367111
|
title: "Screenshot (simple)",
|
|
367112
|
+
$comment: "The pattern gates the target's EXTENSION, not its characters or location: any path ending in .png/.PNG is accepted, plus an http(s) URL to a PNG (optionally with a query string, for signed URLs) and a `$VAR` reference. It deliberately does not restrict the character set \u2014 an earlier pattern allowed any Windows absolute path but limited non-Windows paths to [A-Za-z0-9_./\\-], so ordinary macOS/Linux projects (a space, parentheses, '~', or non-ASCII anywhere in the path) failed validation, including for the absolute paths doc-detective synthesizes internally for autoScreenshot and recording checkpoints. That charset never bounded WHERE a screenshot could be written (traversal like ../../x.png always passed), so it only made non-Windows projects second-class. See ADR 01077.",
|
|
366451
367113
|
description: "File path of the PNG file. Accepts absolute paths. If not specified, the file name is the ID of the step. If an `http(s)` URL is supplied, the remote image is downloaded and used as a read-only reference for comparison; the new capture is written to a local run-specific folder instead of being uploaded back to the URL.",
|
|
366452
367114
|
type: "string",
|
|
366453
|
-
pattern: "^(?:https?:\\/\\/.+\\.(?:png|PNG)(?:\\?.*)
|
|
367115
|
+
pattern: "^(?:https?:\\/\\/.+\\.(?:png|PNG)(?:\\?.*)?|.*\\.(?:png|PNG)|\\$[A-Za-z0-9_]+)$",
|
|
366454
367116
|
transform: [
|
|
366455
367117
|
"trim"
|
|
366456
367118
|
]
|
|
@@ -366924,9 +367586,10 @@ var init_schemas = __esm({
|
|
|
366924
367586
|
},
|
|
366925
367587
|
path: {
|
|
366926
367588
|
title: "Screenshot (simple)",
|
|
367589
|
+
$comment: "The pattern gates the target's EXTENSION, not its characters or location: any path ending in .png/.PNG is accepted, plus an http(s) URL to a PNG (optionally with a query string, for signed URLs) and a `$VAR` reference. It deliberately does not restrict the character set \u2014 an earlier pattern allowed any Windows absolute path but limited non-Windows paths to [A-Za-z0-9_./\\-], so ordinary macOS/Linux projects (a space, parentheses, '~', or non-ASCII anywhere in the path) failed validation, including for the absolute paths doc-detective synthesizes internally for autoScreenshot and recording checkpoints. That charset never bounded WHERE a screenshot could be written (traversal like ../../x.png always passed), so it only made non-Windows projects second-class. See ADR 01077.",
|
|
366927
367590
|
description: "File path of the PNG file. Accepts absolute paths. If not specified, the file name is the ID of the step. If an `http(s)` URL is supplied, the remote image is downloaded and used as a read-only reference for comparison; the new capture is written to a local run-specific folder instead of being uploaded back to the URL.",
|
|
366928
367591
|
type: "string",
|
|
366929
|
-
pattern: "^(?:https?:\\/\\/.+\\.(?:png|PNG)(?:\\?.*)
|
|
367592
|
+
pattern: "^(?:https?:\\/\\/.+\\.(?:png|PNG)(?:\\?.*)?|.*\\.(?:png|PNG)|\\$[A-Za-z0-9_]+)$",
|
|
366930
367593
|
transform: [
|
|
366931
367594
|
"trim"
|
|
366932
367595
|
]
|
|
@@ -367308,6 +367971,7 @@ var init_schemas = __esm({
|
|
|
367308
367971
|
"image.png",
|
|
367309
367972
|
"static/images/image.png",
|
|
367310
367973
|
"/User/manny/projects/doc-detective/static/images/image.png",
|
|
367974
|
+
"/Users/jane doe/projects/my docs (v2)/static/images/image.png",
|
|
367311
367975
|
"https://example.com/static/images/image.png",
|
|
367312
367976
|
{
|
|
367313
367977
|
path: "https://promptless-customer-doc-assets.s3.amazonaws.com/docs-images/request-changes-button-0c851bb3.png",
|
|
@@ -369742,10 +370406,11 @@ var init_schemas = __esm({
|
|
|
369742
370406
|
},
|
|
369743
370407
|
overwrite: {
|
|
369744
370408
|
type: "string",
|
|
369745
|
-
description: "If `true`, overwrites the existing recording at `path` if it exists.",
|
|
370409
|
+
description: "If `true`, overwrites the existing recording at `path` if it exists. If `false`, skips the recording when the file already exists. If `aboveVariation`, always records, but replaces the existing file (and its checkpoint baselines) only when the span's checkpoint screenshots show it meaningfully changed \u2014 requires `checkpoints`, so it turns them on with defaults when `checkpoints` is omitted or `false`; set `checkpoints` to an object to tune `maxVariation` or `directory`.",
|
|
369746
370410
|
enum: [
|
|
369747
370411
|
"true",
|
|
369748
|
-
"false"
|
|
370412
|
+
"false",
|
|
370413
|
+
"aboveVariation"
|
|
369749
370414
|
]
|
|
369750
370415
|
},
|
|
369751
370416
|
name: {
|
|
@@ -369803,6 +370468,38 @@ var init_schemas = __esm({
|
|
|
369803
370468
|
}
|
|
369804
370469
|
}
|
|
369805
370470
|
]
|
|
370471
|
+
},
|
|
370472
|
+
checkpoints: {
|
|
370473
|
+
title: "Recording checkpoints",
|
|
370474
|
+
description: "Capture a checkpoint screenshot after every step while this recording is active and compare each against a persistent baseline stored beside the recording (`<path>.checkpoints/` by default). Baselines seed on the first run; on later runs, per-checkpoint variation is reported in the `stopRecord` step's outputs, and variation beyond `maxVariation` surfaces as a WARNING. If `false` or unset, no checkpoints are captured.",
|
|
370475
|
+
anyOf: [
|
|
370476
|
+
{
|
|
370477
|
+
type: "boolean",
|
|
370478
|
+
title: "Recording checkpoints (boolean)",
|
|
370479
|
+
description: "If `true`, enables checkpoints with default settings."
|
|
370480
|
+
},
|
|
370481
|
+
{
|
|
370482
|
+
type: "object",
|
|
370483
|
+
title: "Recording checkpoints (detailed)",
|
|
370484
|
+
additionalProperties: false,
|
|
370485
|
+
properties: {
|
|
370486
|
+
maxVariation: {
|
|
370487
|
+
type: "number",
|
|
370488
|
+
description: "Maximum fractional pixel difference tolerated between a checkpoint and its baseline before the drift surfaces as a WARNING.",
|
|
370489
|
+
default: 0.05,
|
|
370490
|
+
minimum: 0,
|
|
370491
|
+
maximum: 1
|
|
370492
|
+
},
|
|
370493
|
+
directory: {
|
|
370494
|
+
type: "string",
|
|
370495
|
+
description: "Directory for the checkpoint baselines. If unset, defaults to a `.checkpoints` directory beside the recording (for example, `demo.mp4.checkpoints/`).",
|
|
370496
|
+
transform: [
|
|
370497
|
+
"trim"
|
|
370498
|
+
]
|
|
370499
|
+
}
|
|
370500
|
+
}
|
|
370501
|
+
}
|
|
370502
|
+
]
|
|
369806
370503
|
}
|
|
369807
370504
|
},
|
|
369808
370505
|
title: "Record (detailed)"
|
|
@@ -370064,10 +370761,11 @@ var init_schemas = __esm({
|
|
|
370064
370761
|
},
|
|
370065
370762
|
overwrite: {
|
|
370066
370763
|
type: "string",
|
|
370067
|
-
description: "If `true`, overwrites the existing recording at `path` if it exists.",
|
|
370764
|
+
description: "If `true`, overwrites the existing recording at `path` if it exists. If `false`, skips the recording when the file already exists. If `aboveVariation`, always records, but replaces the existing file (and its checkpoint baselines) only when the span's checkpoint screenshots show it meaningfully changed \u2014 requires `checkpoints`, so it turns them on with defaults when `checkpoints` is omitted or `false`; set `checkpoints` to an object to tune `maxVariation` or `directory`.",
|
|
370068
370765
|
enum: [
|
|
370069
370766
|
"true",
|
|
370070
|
-
"false"
|
|
370767
|
+
"false",
|
|
370768
|
+
"aboveVariation"
|
|
370071
370769
|
]
|
|
370072
370770
|
},
|
|
370073
370771
|
name: {
|
|
@@ -370125,6 +370823,38 @@ var init_schemas = __esm({
|
|
|
370125
370823
|
}
|
|
370126
370824
|
}
|
|
370127
370825
|
]
|
|
370826
|
+
},
|
|
370827
|
+
checkpoints: {
|
|
370828
|
+
title: "Recording checkpoints",
|
|
370829
|
+
description: "Capture a checkpoint screenshot after every step while this recording is active and compare each against a persistent baseline stored beside the recording (`<path>.checkpoints/` by default). Baselines seed on the first run; on later runs, per-checkpoint variation is reported in the `stopRecord` step's outputs, and variation beyond `maxVariation` surfaces as a WARNING. If `false` or unset, no checkpoints are captured.",
|
|
370830
|
+
anyOf: [
|
|
370831
|
+
{
|
|
370832
|
+
type: "boolean",
|
|
370833
|
+
title: "Recording checkpoints (boolean)",
|
|
370834
|
+
description: "If `true`, enables checkpoints with default settings."
|
|
370835
|
+
},
|
|
370836
|
+
{
|
|
370837
|
+
type: "object",
|
|
370838
|
+
title: "Recording checkpoints (detailed)",
|
|
370839
|
+
additionalProperties: false,
|
|
370840
|
+
properties: {
|
|
370841
|
+
maxVariation: {
|
|
370842
|
+
type: "number",
|
|
370843
|
+
description: "Maximum fractional pixel difference tolerated between a checkpoint and its baseline before the drift surfaces as a WARNING.",
|
|
370844
|
+
default: 0.05,
|
|
370845
|
+
minimum: 0,
|
|
370846
|
+
maximum: 1
|
|
370847
|
+
},
|
|
370848
|
+
directory: {
|
|
370849
|
+
type: "string",
|
|
370850
|
+
description: "Directory for the checkpoint baselines. If unset, defaults to a `.checkpoints` directory beside the recording (for example, `demo.mp4.checkpoints/`).",
|
|
370851
|
+
transform: [
|
|
370852
|
+
"trim"
|
|
370853
|
+
]
|
|
370854
|
+
}
|
|
370855
|
+
}
|
|
370856
|
+
}
|
|
370857
|
+
]
|
|
370128
370858
|
}
|
|
370129
370859
|
},
|
|
370130
370860
|
title: "Record (detailed)"
|
|
@@ -370191,6 +370921,17 @@ var init_schemas = __esm({
|
|
|
370191
370921
|
path: "results.mp4",
|
|
370192
370922
|
engine: "ffmpeg"
|
|
370193
370923
|
},
|
|
370924
|
+
{
|
|
370925
|
+
path: "results.mp4",
|
|
370926
|
+
checkpoints: true
|
|
370927
|
+
},
|
|
370928
|
+
{
|
|
370929
|
+
path: "results.mp4",
|
|
370930
|
+
checkpoints: {
|
|
370931
|
+
maxVariation: 0.02,
|
|
370932
|
+
directory: "baselines/results"
|
|
370933
|
+
}
|
|
370934
|
+
},
|
|
370194
370935
|
{
|
|
370195
370936
|
path: "results.mp4",
|
|
370196
370937
|
engine: {
|
|
@@ -385727,9 +386468,10 @@ var init_schemas = __esm({
|
|
|
385727
386468
|
anyOf: [
|
|
385728
386469
|
{
|
|
385729
386470
|
title: "Screenshot (simple)",
|
|
386471
|
+
$comment: "The pattern gates the target's EXTENSION, not its characters or location: any path ending in .png/.PNG is accepted, plus an http(s) URL to a PNG (optionally with a query string, for signed URLs) and a `$VAR` reference. It deliberately does not restrict the character set \u2014 an earlier pattern allowed any Windows absolute path but limited non-Windows paths to [A-Za-z0-9_./\\-], so ordinary macOS/Linux projects (a space, parentheses, '~', or non-ASCII anywhere in the path) failed validation, including for the absolute paths doc-detective synthesizes internally for autoScreenshot and recording checkpoints. That charset never bounded WHERE a screenshot could be written (traversal like ../../x.png always passed), so it only made non-Windows projects second-class. See ADR 01077.",
|
|
385730
386472
|
description: "File path of the PNG file. Accepts absolute paths. If not specified, the file name is the ID of the step. If an `http(s)` URL is supplied, the remote image is downloaded and used as a read-only reference for comparison; the new capture is written to a local run-specific folder instead of being uploaded back to the URL.",
|
|
385731
386473
|
type: "string",
|
|
385732
|
-
pattern: "^(?:https?:\\/\\/.+\\.(?:png|PNG)(?:\\?.*)
|
|
386474
|
+
pattern: "^(?:https?:\\/\\/.+\\.(?:png|PNG)(?:\\?.*)?|.*\\.(?:png|PNG)|\\$[A-Za-z0-9_]+)$",
|
|
385733
386475
|
transform: [
|
|
385734
386476
|
"trim"
|
|
385735
386477
|
]
|
|
@@ -385963,9 +386705,10 @@ var init_schemas = __esm({
|
|
|
385963
386705
|
},
|
|
385964
386706
|
path: {
|
|
385965
386707
|
title: "Screenshot (simple)",
|
|
386708
|
+
$comment: "The pattern gates the target's EXTENSION, not its characters or location: any path ending in .png/.PNG is accepted, plus an http(s) URL to a PNG (optionally with a query string, for signed URLs) and a `$VAR` reference. It deliberately does not restrict the character set \u2014 an earlier pattern allowed any Windows absolute path but limited non-Windows paths to [A-Za-z0-9_./\\-], so ordinary macOS/Linux projects (a space, parentheses, '~', or non-ASCII anywhere in the path) failed validation, including for the absolute paths doc-detective synthesizes internally for autoScreenshot and recording checkpoints. That charset never bounded WHERE a screenshot could be written (traversal like ../../x.png always passed), so it only made non-Windows projects second-class. See ADR 01077.",
|
|
385966
386709
|
description: "File path of the PNG file. Accepts absolute paths. If not specified, the file name is the ID of the step. If an `http(s)` URL is supplied, the remote image is downloaded and used as a read-only reference for comparison; the new capture is written to a local run-specific folder instead of being uploaded back to the URL.",
|
|
385967
386710
|
type: "string",
|
|
385968
|
-
pattern: "^(?:https?:\\/\\/.+\\.(?:png|PNG)(?:\\?.*)
|
|
386711
|
+
pattern: "^(?:https?:\\/\\/.+\\.(?:png|PNG)(?:\\?.*)?|.*\\.(?:png|PNG)|\\$[A-Za-z0-9_]+)$",
|
|
385969
386712
|
transform: [
|
|
385970
386713
|
"trim"
|
|
385971
386714
|
]
|
|
@@ -386223,9 +386966,10 @@ var init_schemas = __esm({
|
|
|
386223
386966
|
schemas: {
|
|
386224
386967
|
path: {
|
|
386225
386968
|
title: "Screenshot (simple)",
|
|
386969
|
+
$comment: "The pattern gates the target's EXTENSION, not its characters or location: any path ending in .png/.PNG is accepted, plus an http(s) URL to a PNG (optionally with a query string, for signed URLs) and a `$VAR` reference. It deliberately does not restrict the character set \u2014 an earlier pattern allowed any Windows absolute path but limited non-Windows paths to [A-Za-z0-9_./\\-], so ordinary macOS/Linux projects (a space, parentheses, '~', or non-ASCII anywhere in the path) failed validation, including for the absolute paths doc-detective synthesizes internally for autoScreenshot and recording checkpoints. That charset never bounded WHERE a screenshot could be written (traversal like ../../x.png always passed), so it only made non-Windows projects second-class. See ADR 01077.",
|
|
386226
386970
|
description: "File path of the PNG file. Accepts absolute paths. If not specified, the file name is the ID of the step. If an `http(s)` URL is supplied, the remote image is downloaded and used as a read-only reference for comparison; the new capture is written to a local run-specific folder instead of being uploaded back to the URL.",
|
|
386227
386971
|
type: "string",
|
|
386228
|
-
pattern: "^(?:https?:\\/\\/.+\\.(?:png|PNG)(?:\\?.*)
|
|
386972
|
+
pattern: "^(?:https?:\\/\\/.+\\.(?:png|PNG)(?:\\?.*)?|.*\\.(?:png|PNG)|\\$[A-Za-z0-9_]+)$",
|
|
386229
386973
|
transform: [
|
|
386230
386974
|
"trim"
|
|
386231
386975
|
]
|
|
@@ -386459,9 +387203,10 @@ var init_schemas = __esm({
|
|
|
386459
387203
|
},
|
|
386460
387204
|
path: {
|
|
386461
387205
|
title: "Screenshot (simple)",
|
|
387206
|
+
$comment: "The pattern gates the target's EXTENSION, not its characters or location: any path ending in .png/.PNG is accepted, plus an http(s) URL to a PNG (optionally with a query string, for signed URLs) and a `$VAR` reference. It deliberately does not restrict the character set \u2014 an earlier pattern allowed any Windows absolute path but limited non-Windows paths to [A-Za-z0-9_./\\-], so ordinary macOS/Linux projects (a space, parentheses, '~', or non-ASCII anywhere in the path) failed validation, including for the absolute paths doc-detective synthesizes internally for autoScreenshot and recording checkpoints. That charset never bounded WHERE a screenshot could be written (traversal like ../../x.png always passed), so it only made non-Windows projects second-class. See ADR 01077.",
|
|
386462
387207
|
description: "File path of the PNG file. Accepts absolute paths. If not specified, the file name is the ID of the step. If an `http(s)` URL is supplied, the remote image is downloaded and used as a read-only reference for comparison; the new capture is written to a local run-specific folder instead of being uploaded back to the URL.",
|
|
386463
387208
|
type: "string",
|
|
386464
|
-
pattern: "^(?:https?:\\/\\/.+\\.(?:png|PNG)(?:\\?.*)
|
|
387209
|
+
pattern: "^(?:https?:\\/\\/.+\\.(?:png|PNG)(?:\\?.*)?|.*\\.(?:png|PNG)|\\$[A-Za-z0-9_]+)$",
|
|
386465
387210
|
transform: [
|
|
386466
387211
|
"trim"
|
|
386467
387212
|
]
|
|
@@ -386935,9 +387680,10 @@ var init_schemas = __esm({
|
|
|
386935
387680
|
},
|
|
386936
387681
|
path: {
|
|
386937
387682
|
title: "Screenshot (simple)",
|
|
387683
|
+
$comment: "The pattern gates the target's EXTENSION, not its characters or location: any path ending in .png/.PNG is accepted, plus an http(s) URL to a PNG (optionally with a query string, for signed URLs) and a `$VAR` reference. It deliberately does not restrict the character set \u2014 an earlier pattern allowed any Windows absolute path but limited non-Windows paths to [A-Za-z0-9_./\\-], so ordinary macOS/Linux projects (a space, parentheses, '~', or non-ASCII anywhere in the path) failed validation, including for the absolute paths doc-detective synthesizes internally for autoScreenshot and recording checkpoints. That charset never bounded WHERE a screenshot could be written (traversal like ../../x.png always passed), so it only made non-Windows projects second-class. See ADR 01077.",
|
|
386938
387684
|
description: "File path of the PNG file. Accepts absolute paths. If not specified, the file name is the ID of the step. If an `http(s)` URL is supplied, the remote image is downloaded and used as a read-only reference for comparison; the new capture is written to a local run-specific folder instead of being uploaded back to the URL.",
|
|
386939
387685
|
type: "string",
|
|
386940
|
-
pattern: "^(?:https?:\\/\\/.+\\.(?:png|PNG)(?:\\?.*)
|
|
387686
|
+
pattern: "^(?:https?:\\/\\/.+\\.(?:png|PNG)(?:\\?.*)?|.*\\.(?:png|PNG)|\\$[A-Za-z0-9_]+)$",
|
|
386941
387687
|
transform: [
|
|
386942
387688
|
"trim"
|
|
386943
387689
|
]
|
|
@@ -387319,6 +388065,7 @@ var init_schemas = __esm({
|
|
|
387319
388065
|
"image.png",
|
|
387320
388066
|
"static/images/image.png",
|
|
387321
388067
|
"/User/manny/projects/doc-detective/static/images/image.png",
|
|
388068
|
+
"/Users/jane doe/projects/my docs (v2)/static/images/image.png",
|
|
387322
388069
|
"https://example.com/static/images/image.png",
|
|
387323
388070
|
{
|
|
387324
388071
|
path: "https://promptless-customer-doc-assets.s3.amazonaws.com/docs-images/request-changes-button-0c851bb3.png",
|
|
@@ -416902,9 +417649,10 @@ var init_schemas = __esm({
|
|
|
416902
417649
|
anyOf: [
|
|
416903
417650
|
{
|
|
416904
417651
|
title: "Screenshot (simple)",
|
|
417652
|
+
$comment: "The pattern gates the target's EXTENSION, not its characters or location: any path ending in .png/.PNG is accepted, plus an http(s) URL to a PNG (optionally with a query string, for signed URLs) and a `$VAR` reference. It deliberately does not restrict the character set \u2014 an earlier pattern allowed any Windows absolute path but limited non-Windows paths to [A-Za-z0-9_./\\-], so ordinary macOS/Linux projects (a space, parentheses, '~', or non-ASCII anywhere in the path) failed validation, including for the absolute paths doc-detective synthesizes internally for autoScreenshot and recording checkpoints. That charset never bounded WHERE a screenshot could be written (traversal like ../../x.png always passed), so it only made non-Windows projects second-class. See ADR 01077.",
|
|
416905
417653
|
description: "File path of the PNG file. Accepts absolute paths. If not specified, the file name is the ID of the step. If an `http(s)` URL is supplied, the remote image is downloaded and used as a read-only reference for comparison; the new capture is written to a local run-specific folder instead of being uploaded back to the URL.",
|
|
416906
417654
|
type: "string",
|
|
416907
|
-
pattern: "^(?:https?:\\/\\/.+\\.(?:png|PNG)(?:\\?.*)
|
|
417655
|
+
pattern: "^(?:https?:\\/\\/.+\\.(?:png|PNG)(?:\\?.*)?|.*\\.(?:png|PNG)|\\$[A-Za-z0-9_]+)$",
|
|
416908
417656
|
transform: [
|
|
416909
417657
|
"trim"
|
|
416910
417658
|
]
|
|
@@ -417138,9 +417886,10 @@ var init_schemas = __esm({
|
|
|
417138
417886
|
},
|
|
417139
417887
|
path: {
|
|
417140
417888
|
title: "Screenshot (simple)",
|
|
417889
|
+
$comment: "The pattern gates the target's EXTENSION, not its characters or location: any path ending in .png/.PNG is accepted, plus an http(s) URL to a PNG (optionally with a query string, for signed URLs) and a `$VAR` reference. It deliberately does not restrict the character set \u2014 an earlier pattern allowed any Windows absolute path but limited non-Windows paths to [A-Za-z0-9_./\\-], so ordinary macOS/Linux projects (a space, parentheses, '~', or non-ASCII anywhere in the path) failed validation, including for the absolute paths doc-detective synthesizes internally for autoScreenshot and recording checkpoints. That charset never bounded WHERE a screenshot could be written (traversal like ../../x.png always passed), so it only made non-Windows projects second-class. See ADR 01077.",
|
|
417141
417890
|
description: "File path of the PNG file. Accepts absolute paths. If not specified, the file name is the ID of the step. If an `http(s)` URL is supplied, the remote image is downloaded and used as a read-only reference for comparison; the new capture is written to a local run-specific folder instead of being uploaded back to the URL.",
|
|
417142
417891
|
type: "string",
|
|
417143
|
-
pattern: "^(?:https?:\\/\\/.+\\.(?:png|PNG)(?:\\?.*)
|
|
417892
|
+
pattern: "^(?:https?:\\/\\/.+\\.(?:png|PNG)(?:\\?.*)?|.*\\.(?:png|PNG)|\\$[A-Za-z0-9_]+)$",
|
|
417144
417893
|
transform: [
|
|
417145
417894
|
"trim"
|
|
417146
417895
|
]
|
|
@@ -417398,9 +418147,10 @@ var init_schemas = __esm({
|
|
|
417398
418147
|
schemas: {
|
|
417399
418148
|
path: {
|
|
417400
418149
|
title: "Screenshot (simple)",
|
|
418150
|
+
$comment: "The pattern gates the target's EXTENSION, not its characters or location: any path ending in .png/.PNG is accepted, plus an http(s) URL to a PNG (optionally with a query string, for signed URLs) and a `$VAR` reference. It deliberately does not restrict the character set \u2014 an earlier pattern allowed any Windows absolute path but limited non-Windows paths to [A-Za-z0-9_./\\-], so ordinary macOS/Linux projects (a space, parentheses, '~', or non-ASCII anywhere in the path) failed validation, including for the absolute paths doc-detective synthesizes internally for autoScreenshot and recording checkpoints. That charset never bounded WHERE a screenshot could be written (traversal like ../../x.png always passed), so it only made non-Windows projects second-class. See ADR 01077.",
|
|
417401
418151
|
description: "File path of the PNG file. Accepts absolute paths. If not specified, the file name is the ID of the step. If an `http(s)` URL is supplied, the remote image is downloaded and used as a read-only reference for comparison; the new capture is written to a local run-specific folder instead of being uploaded back to the URL.",
|
|
417402
418152
|
type: "string",
|
|
417403
|
-
pattern: "^(?:https?:\\/\\/.+\\.(?:png|PNG)(?:\\?.*)
|
|
418153
|
+
pattern: "^(?:https?:\\/\\/.+\\.(?:png|PNG)(?:\\?.*)?|.*\\.(?:png|PNG)|\\$[A-Za-z0-9_]+)$",
|
|
417404
418154
|
transform: [
|
|
417405
418155
|
"trim"
|
|
417406
418156
|
]
|
|
@@ -417634,9 +418384,10 @@ var init_schemas = __esm({
|
|
|
417634
418384
|
},
|
|
417635
418385
|
path: {
|
|
417636
418386
|
title: "Screenshot (simple)",
|
|
418387
|
+
$comment: "The pattern gates the target's EXTENSION, not its characters or location: any path ending in .png/.PNG is accepted, plus an http(s) URL to a PNG (optionally with a query string, for signed URLs) and a `$VAR` reference. It deliberately does not restrict the character set \u2014 an earlier pattern allowed any Windows absolute path but limited non-Windows paths to [A-Za-z0-9_./\\-], so ordinary macOS/Linux projects (a space, parentheses, '~', or non-ASCII anywhere in the path) failed validation, including for the absolute paths doc-detective synthesizes internally for autoScreenshot and recording checkpoints. That charset never bounded WHERE a screenshot could be written (traversal like ../../x.png always passed), so it only made non-Windows projects second-class. See ADR 01077.",
|
|
417637
418388
|
description: "File path of the PNG file. Accepts absolute paths. If not specified, the file name is the ID of the step. If an `http(s)` URL is supplied, the remote image is downloaded and used as a read-only reference for comparison; the new capture is written to a local run-specific folder instead of being uploaded back to the URL.",
|
|
417638
418389
|
type: "string",
|
|
417639
|
-
pattern: "^(?:https?:\\/\\/.+\\.(?:png|PNG)(?:\\?.*)
|
|
418390
|
+
pattern: "^(?:https?:\\/\\/.+\\.(?:png|PNG)(?:\\?.*)?|.*\\.(?:png|PNG)|\\$[A-Za-z0-9_]+)$",
|
|
417640
418391
|
transform: [
|
|
417641
418392
|
"trim"
|
|
417642
418393
|
]
|
|
@@ -418110,9 +418861,10 @@ var init_schemas = __esm({
|
|
|
418110
418861
|
},
|
|
418111
418862
|
path: {
|
|
418112
418863
|
title: "Screenshot (simple)",
|
|
418864
|
+
$comment: "The pattern gates the target's EXTENSION, not its characters or location: any path ending in .png/.PNG is accepted, plus an http(s) URL to a PNG (optionally with a query string, for signed URLs) and a `$VAR` reference. It deliberately does not restrict the character set \u2014 an earlier pattern allowed any Windows absolute path but limited non-Windows paths to [A-Za-z0-9_./\\-], so ordinary macOS/Linux projects (a space, parentheses, '~', or non-ASCII anywhere in the path) failed validation, including for the absolute paths doc-detective synthesizes internally for autoScreenshot and recording checkpoints. That charset never bounded WHERE a screenshot could be written (traversal like ../../x.png always passed), so it only made non-Windows projects second-class. See ADR 01077.",
|
|
418113
418865
|
description: "File path of the PNG file. Accepts absolute paths. If not specified, the file name is the ID of the step. If an `http(s)` URL is supplied, the remote image is downloaded and used as a read-only reference for comparison; the new capture is written to a local run-specific folder instead of being uploaded back to the URL.",
|
|
418114
418866
|
type: "string",
|
|
418115
|
-
pattern: "^(?:https?:\\/\\/.+\\.(?:png|PNG)(?:\\?.*)
|
|
418867
|
+
pattern: "^(?:https?:\\/\\/.+\\.(?:png|PNG)(?:\\?.*)?|.*\\.(?:png|PNG)|\\$[A-Za-z0-9_]+)$",
|
|
418116
418868
|
transform: [
|
|
418117
418869
|
"trim"
|
|
418118
418870
|
]
|
|
@@ -418494,6 +419246,7 @@ var init_schemas = __esm({
|
|
|
418494
419246
|
"image.png",
|
|
418495
419247
|
"static/images/image.png",
|
|
418496
419248
|
"/User/manny/projects/doc-detective/static/images/image.png",
|
|
419249
|
+
"/Users/jane doe/projects/my docs (v2)/static/images/image.png",
|
|
418497
419250
|
"https://example.com/static/images/image.png",
|
|
418498
419251
|
{
|
|
418499
419252
|
path: "https://promptless-customer-doc-assets.s3.amazonaws.com/docs-images/request-changes-button-0c851bb3.png",
|
|
@@ -420928,10 +421681,11 @@ var init_schemas = __esm({
|
|
|
420928
421681
|
},
|
|
420929
421682
|
overwrite: {
|
|
420930
421683
|
type: "string",
|
|
420931
|
-
description: "If `true`, overwrites the existing recording at `path` if it exists.",
|
|
421684
|
+
description: "If `true`, overwrites the existing recording at `path` if it exists. If `false`, skips the recording when the file already exists. If `aboveVariation`, always records, but replaces the existing file (and its checkpoint baselines) only when the span's checkpoint screenshots show it meaningfully changed \u2014 requires `checkpoints`, so it turns them on with defaults when `checkpoints` is omitted or `false`; set `checkpoints` to an object to tune `maxVariation` or `directory`.",
|
|
420932
421685
|
enum: [
|
|
420933
421686
|
"true",
|
|
420934
|
-
"false"
|
|
421687
|
+
"false",
|
|
421688
|
+
"aboveVariation"
|
|
420935
421689
|
]
|
|
420936
421690
|
},
|
|
420937
421691
|
name: {
|
|
@@ -420989,6 +421743,38 @@ var init_schemas = __esm({
|
|
|
420989
421743
|
}
|
|
420990
421744
|
}
|
|
420991
421745
|
]
|
|
421746
|
+
},
|
|
421747
|
+
checkpoints: {
|
|
421748
|
+
title: "Recording checkpoints",
|
|
421749
|
+
description: "Capture a checkpoint screenshot after every step while this recording is active and compare each against a persistent baseline stored beside the recording (`<path>.checkpoints/` by default). Baselines seed on the first run; on later runs, per-checkpoint variation is reported in the `stopRecord` step's outputs, and variation beyond `maxVariation` surfaces as a WARNING. If `false` or unset, no checkpoints are captured.",
|
|
421750
|
+
anyOf: [
|
|
421751
|
+
{
|
|
421752
|
+
type: "boolean",
|
|
421753
|
+
title: "Recording checkpoints (boolean)",
|
|
421754
|
+
description: "If `true`, enables checkpoints with default settings."
|
|
421755
|
+
},
|
|
421756
|
+
{
|
|
421757
|
+
type: "object",
|
|
421758
|
+
title: "Recording checkpoints (detailed)",
|
|
421759
|
+
additionalProperties: false,
|
|
421760
|
+
properties: {
|
|
421761
|
+
maxVariation: {
|
|
421762
|
+
type: "number",
|
|
421763
|
+
description: "Maximum fractional pixel difference tolerated between a checkpoint and its baseline before the drift surfaces as a WARNING.",
|
|
421764
|
+
default: 0.05,
|
|
421765
|
+
minimum: 0,
|
|
421766
|
+
maximum: 1
|
|
421767
|
+
},
|
|
421768
|
+
directory: {
|
|
421769
|
+
type: "string",
|
|
421770
|
+
description: "Directory for the checkpoint baselines. If unset, defaults to a `.checkpoints` directory beside the recording (for example, `demo.mp4.checkpoints/`).",
|
|
421771
|
+
transform: [
|
|
421772
|
+
"trim"
|
|
421773
|
+
]
|
|
421774
|
+
}
|
|
421775
|
+
}
|
|
421776
|
+
}
|
|
421777
|
+
]
|
|
420992
421778
|
}
|
|
420993
421779
|
},
|
|
420994
421780
|
title: "Record (detailed)"
|
|
@@ -421250,10 +422036,11 @@ var init_schemas = __esm({
|
|
|
421250
422036
|
},
|
|
421251
422037
|
overwrite: {
|
|
421252
422038
|
type: "string",
|
|
421253
|
-
description: "If `true`, overwrites the existing recording at `path` if it exists.",
|
|
422039
|
+
description: "If `true`, overwrites the existing recording at `path` if it exists. If `false`, skips the recording when the file already exists. If `aboveVariation`, always records, but replaces the existing file (and its checkpoint baselines) only when the span's checkpoint screenshots show it meaningfully changed \u2014 requires `checkpoints`, so it turns them on with defaults when `checkpoints` is omitted or `false`; set `checkpoints` to an object to tune `maxVariation` or `directory`.",
|
|
421254
422040
|
enum: [
|
|
421255
422041
|
"true",
|
|
421256
|
-
"false"
|
|
422042
|
+
"false",
|
|
422043
|
+
"aboveVariation"
|
|
421257
422044
|
]
|
|
421258
422045
|
},
|
|
421259
422046
|
name: {
|
|
@@ -421311,6 +422098,38 @@ var init_schemas = __esm({
|
|
|
421311
422098
|
}
|
|
421312
422099
|
}
|
|
421313
422100
|
]
|
|
422101
|
+
},
|
|
422102
|
+
checkpoints: {
|
|
422103
|
+
title: "Recording checkpoints",
|
|
422104
|
+
description: "Capture a checkpoint screenshot after every step while this recording is active and compare each against a persistent baseline stored beside the recording (`<path>.checkpoints/` by default). Baselines seed on the first run; on later runs, per-checkpoint variation is reported in the `stopRecord` step's outputs, and variation beyond `maxVariation` surfaces as a WARNING. If `false` or unset, no checkpoints are captured.",
|
|
422105
|
+
anyOf: [
|
|
422106
|
+
{
|
|
422107
|
+
type: "boolean",
|
|
422108
|
+
title: "Recording checkpoints (boolean)",
|
|
422109
|
+
description: "If `true`, enables checkpoints with default settings."
|
|
422110
|
+
},
|
|
422111
|
+
{
|
|
422112
|
+
type: "object",
|
|
422113
|
+
title: "Recording checkpoints (detailed)",
|
|
422114
|
+
additionalProperties: false,
|
|
422115
|
+
properties: {
|
|
422116
|
+
maxVariation: {
|
|
422117
|
+
type: "number",
|
|
422118
|
+
description: "Maximum fractional pixel difference tolerated between a checkpoint and its baseline before the drift surfaces as a WARNING.",
|
|
422119
|
+
default: 0.05,
|
|
422120
|
+
minimum: 0,
|
|
422121
|
+
maximum: 1
|
|
422122
|
+
},
|
|
422123
|
+
directory: {
|
|
422124
|
+
type: "string",
|
|
422125
|
+
description: "Directory for the checkpoint baselines. If unset, defaults to a `.checkpoints` directory beside the recording (for example, `demo.mp4.checkpoints/`).",
|
|
422126
|
+
transform: [
|
|
422127
|
+
"trim"
|
|
422128
|
+
]
|
|
422129
|
+
}
|
|
422130
|
+
}
|
|
422131
|
+
}
|
|
422132
|
+
]
|
|
421314
422133
|
}
|
|
421315
422134
|
},
|
|
421316
422135
|
title: "Record (detailed)"
|
|
@@ -421377,6 +422196,17 @@ var init_schemas = __esm({
|
|
|
421377
422196
|
path: "results.mp4",
|
|
421378
422197
|
engine: "ffmpeg"
|
|
421379
422198
|
},
|
|
422199
|
+
{
|
|
422200
|
+
path: "results.mp4",
|
|
422201
|
+
checkpoints: true
|
|
422202
|
+
},
|
|
422203
|
+
{
|
|
422204
|
+
path: "results.mp4",
|
|
422205
|
+
checkpoints: {
|
|
422206
|
+
maxVariation: 0.02,
|
|
422207
|
+
directory: "baselines/results"
|
|
422208
|
+
}
|
|
422209
|
+
},
|
|
421380
422210
|
{
|
|
421381
422211
|
path: "results.mp4",
|
|
421382
422212
|
engine: {
|
|
@@ -461803,9 +462633,10 @@ var init_schemas = __esm({
|
|
|
461803
462633
|
anyOf: [
|
|
461804
462634
|
{
|
|
461805
462635
|
title: "Screenshot (simple)",
|
|
462636
|
+
$comment: "The pattern gates the target's EXTENSION, not its characters or location: any path ending in .png/.PNG is accepted, plus an http(s) URL to a PNG (optionally with a query string, for signed URLs) and a `$VAR` reference. It deliberately does not restrict the character set \u2014 an earlier pattern allowed any Windows absolute path but limited non-Windows paths to [A-Za-z0-9_./\\-], so ordinary macOS/Linux projects (a space, parentheses, '~', or non-ASCII anywhere in the path) failed validation, including for the absolute paths doc-detective synthesizes internally for autoScreenshot and recording checkpoints. That charset never bounded WHERE a screenshot could be written (traversal like ../../x.png always passed), so it only made non-Windows projects second-class. See ADR 01077.",
|
|
461806
462637
|
description: "File path of the PNG file. Accepts absolute paths. If not specified, the file name is the ID of the step. If an `http(s)` URL is supplied, the remote image is downloaded and used as a read-only reference for comparison; the new capture is written to a local run-specific folder instead of being uploaded back to the URL.",
|
|
461807
462638
|
type: "string",
|
|
461808
|
-
pattern: "^(?:https?:\\/\\/.+\\.(?:png|PNG)(?:\\?.*)
|
|
462639
|
+
pattern: "^(?:https?:\\/\\/.+\\.(?:png|PNG)(?:\\?.*)?|.*\\.(?:png|PNG)|\\$[A-Za-z0-9_]+)$",
|
|
461809
462640
|
transform: [
|
|
461810
462641
|
"trim"
|
|
461811
462642
|
]
|
|
@@ -462039,9 +462870,10 @@ var init_schemas = __esm({
|
|
|
462039
462870
|
},
|
|
462040
462871
|
path: {
|
|
462041
462872
|
title: "Screenshot (simple)",
|
|
462873
|
+
$comment: "The pattern gates the target's EXTENSION, not its characters or location: any path ending in .png/.PNG is accepted, plus an http(s) URL to a PNG (optionally with a query string, for signed URLs) and a `$VAR` reference. It deliberately does not restrict the character set \u2014 an earlier pattern allowed any Windows absolute path but limited non-Windows paths to [A-Za-z0-9_./\\-], so ordinary macOS/Linux projects (a space, parentheses, '~', or non-ASCII anywhere in the path) failed validation, including for the absolute paths doc-detective synthesizes internally for autoScreenshot and recording checkpoints. That charset never bounded WHERE a screenshot could be written (traversal like ../../x.png always passed), so it only made non-Windows projects second-class. See ADR 01077.",
|
|
462042
462874
|
description: "File path of the PNG file. Accepts absolute paths. If not specified, the file name is the ID of the step. If an `http(s)` URL is supplied, the remote image is downloaded and used as a read-only reference for comparison; the new capture is written to a local run-specific folder instead of being uploaded back to the URL.",
|
|
462043
462875
|
type: "string",
|
|
462044
|
-
pattern: "^(?:https?:\\/\\/.+\\.(?:png|PNG)(?:\\?.*)
|
|
462876
|
+
pattern: "^(?:https?:\\/\\/.+\\.(?:png|PNG)(?:\\?.*)?|.*\\.(?:png|PNG)|\\$[A-Za-z0-9_]+)$",
|
|
462045
462877
|
transform: [
|
|
462046
462878
|
"trim"
|
|
462047
462879
|
]
|
|
@@ -462299,9 +463131,10 @@ var init_schemas = __esm({
|
|
|
462299
463131
|
schemas: {
|
|
462300
463132
|
path: {
|
|
462301
463133
|
title: "Screenshot (simple)",
|
|
463134
|
+
$comment: "The pattern gates the target's EXTENSION, not its characters or location: any path ending in .png/.PNG is accepted, plus an http(s) URL to a PNG (optionally with a query string, for signed URLs) and a `$VAR` reference. It deliberately does not restrict the character set \u2014 an earlier pattern allowed any Windows absolute path but limited non-Windows paths to [A-Za-z0-9_./\\-], so ordinary macOS/Linux projects (a space, parentheses, '~', or non-ASCII anywhere in the path) failed validation, including for the absolute paths doc-detective synthesizes internally for autoScreenshot and recording checkpoints. That charset never bounded WHERE a screenshot could be written (traversal like ../../x.png always passed), so it only made non-Windows projects second-class. See ADR 01077.",
|
|
462302
463135
|
description: "File path of the PNG file. Accepts absolute paths. If not specified, the file name is the ID of the step. If an `http(s)` URL is supplied, the remote image is downloaded and used as a read-only reference for comparison; the new capture is written to a local run-specific folder instead of being uploaded back to the URL.",
|
|
462303
463136
|
type: "string",
|
|
462304
|
-
pattern: "^(?:https?:\\/\\/.+\\.(?:png|PNG)(?:\\?.*)
|
|
463137
|
+
pattern: "^(?:https?:\\/\\/.+\\.(?:png|PNG)(?:\\?.*)?|.*\\.(?:png|PNG)|\\$[A-Za-z0-9_]+)$",
|
|
462305
463138
|
transform: [
|
|
462306
463139
|
"trim"
|
|
462307
463140
|
]
|
|
@@ -462535,9 +463368,10 @@ var init_schemas = __esm({
|
|
|
462535
463368
|
},
|
|
462536
463369
|
path: {
|
|
462537
463370
|
title: "Screenshot (simple)",
|
|
463371
|
+
$comment: "The pattern gates the target's EXTENSION, not its characters or location: any path ending in .png/.PNG is accepted, plus an http(s) URL to a PNG (optionally with a query string, for signed URLs) and a `$VAR` reference. It deliberately does not restrict the character set \u2014 an earlier pattern allowed any Windows absolute path but limited non-Windows paths to [A-Za-z0-9_./\\-], so ordinary macOS/Linux projects (a space, parentheses, '~', or non-ASCII anywhere in the path) failed validation, including for the absolute paths doc-detective synthesizes internally for autoScreenshot and recording checkpoints. That charset never bounded WHERE a screenshot could be written (traversal like ../../x.png always passed), so it only made non-Windows projects second-class. See ADR 01077.",
|
|
462538
463372
|
description: "File path of the PNG file. Accepts absolute paths. If not specified, the file name is the ID of the step. If an `http(s)` URL is supplied, the remote image is downloaded and used as a read-only reference for comparison; the new capture is written to a local run-specific folder instead of being uploaded back to the URL.",
|
|
462539
463373
|
type: "string",
|
|
462540
|
-
pattern: "^(?:https?:\\/\\/.+\\.(?:png|PNG)(?:\\?.*)
|
|
463374
|
+
pattern: "^(?:https?:\\/\\/.+\\.(?:png|PNG)(?:\\?.*)?|.*\\.(?:png|PNG)|\\$[A-Za-z0-9_]+)$",
|
|
462541
463375
|
transform: [
|
|
462542
463376
|
"trim"
|
|
462543
463377
|
]
|
|
@@ -463011,9 +463845,10 @@ var init_schemas = __esm({
|
|
|
463011
463845
|
},
|
|
463012
463846
|
path: {
|
|
463013
463847
|
title: "Screenshot (simple)",
|
|
463848
|
+
$comment: "The pattern gates the target's EXTENSION, not its characters or location: any path ending in .png/.PNG is accepted, plus an http(s) URL to a PNG (optionally with a query string, for signed URLs) and a `$VAR` reference. It deliberately does not restrict the character set \u2014 an earlier pattern allowed any Windows absolute path but limited non-Windows paths to [A-Za-z0-9_./\\-], so ordinary macOS/Linux projects (a space, parentheses, '~', or non-ASCII anywhere in the path) failed validation, including for the absolute paths doc-detective synthesizes internally for autoScreenshot and recording checkpoints. That charset never bounded WHERE a screenshot could be written (traversal like ../../x.png always passed), so it only made non-Windows projects second-class. See ADR 01077.",
|
|
463014
463849
|
description: "File path of the PNG file. Accepts absolute paths. If not specified, the file name is the ID of the step. If an `http(s)` URL is supplied, the remote image is downloaded and used as a read-only reference for comparison; the new capture is written to a local run-specific folder instead of being uploaded back to the URL.",
|
|
463015
463850
|
type: "string",
|
|
463016
|
-
pattern: "^(?:https?:\\/\\/.+\\.(?:png|PNG)(?:\\?.*)
|
|
463851
|
+
pattern: "^(?:https?:\\/\\/.+\\.(?:png|PNG)(?:\\?.*)?|.*\\.(?:png|PNG)|\\$[A-Za-z0-9_]+)$",
|
|
463017
463852
|
transform: [
|
|
463018
463853
|
"trim"
|
|
463019
463854
|
]
|
|
@@ -463395,6 +464230,7 @@ var init_schemas = __esm({
|
|
|
463395
464230
|
"image.png",
|
|
463396
464231
|
"static/images/image.png",
|
|
463397
464232
|
"/User/manny/projects/doc-detective/static/images/image.png",
|
|
464233
|
+
"/Users/jane doe/projects/my docs (v2)/static/images/image.png",
|
|
463398
464234
|
"https://example.com/static/images/image.png",
|
|
463399
464235
|
{
|
|
463400
464236
|
path: "https://promptless-customer-doc-assets.s3.amazonaws.com/docs-images/request-changes-button-0c851bb3.png",
|
|
@@ -465829,10 +466665,11 @@ var init_schemas = __esm({
|
|
|
465829
466665
|
},
|
|
465830
466666
|
overwrite: {
|
|
465831
466667
|
type: "string",
|
|
465832
|
-
description: "If `true`, overwrites the existing recording at `path` if it exists.",
|
|
466668
|
+
description: "If `true`, overwrites the existing recording at `path` if it exists. If `false`, skips the recording when the file already exists. If `aboveVariation`, always records, but replaces the existing file (and its checkpoint baselines) only when the span's checkpoint screenshots show it meaningfully changed \u2014 requires `checkpoints`, so it turns them on with defaults when `checkpoints` is omitted or `false`; set `checkpoints` to an object to tune `maxVariation` or `directory`.",
|
|
465833
466669
|
enum: [
|
|
465834
466670
|
"true",
|
|
465835
|
-
"false"
|
|
466671
|
+
"false",
|
|
466672
|
+
"aboveVariation"
|
|
465836
466673
|
]
|
|
465837
466674
|
},
|
|
465838
466675
|
name: {
|
|
@@ -465890,6 +466727,38 @@ var init_schemas = __esm({
|
|
|
465890
466727
|
}
|
|
465891
466728
|
}
|
|
465892
466729
|
]
|
|
466730
|
+
},
|
|
466731
|
+
checkpoints: {
|
|
466732
|
+
title: "Recording checkpoints",
|
|
466733
|
+
description: "Capture a checkpoint screenshot after every step while this recording is active and compare each against a persistent baseline stored beside the recording (`<path>.checkpoints/` by default). Baselines seed on the first run; on later runs, per-checkpoint variation is reported in the `stopRecord` step's outputs, and variation beyond `maxVariation` surfaces as a WARNING. If `false` or unset, no checkpoints are captured.",
|
|
466734
|
+
anyOf: [
|
|
466735
|
+
{
|
|
466736
|
+
type: "boolean",
|
|
466737
|
+
title: "Recording checkpoints (boolean)",
|
|
466738
|
+
description: "If `true`, enables checkpoints with default settings."
|
|
466739
|
+
},
|
|
466740
|
+
{
|
|
466741
|
+
type: "object",
|
|
466742
|
+
title: "Recording checkpoints (detailed)",
|
|
466743
|
+
additionalProperties: false,
|
|
466744
|
+
properties: {
|
|
466745
|
+
maxVariation: {
|
|
466746
|
+
type: "number",
|
|
466747
|
+
description: "Maximum fractional pixel difference tolerated between a checkpoint and its baseline before the drift surfaces as a WARNING.",
|
|
466748
|
+
default: 0.05,
|
|
466749
|
+
minimum: 0,
|
|
466750
|
+
maximum: 1
|
|
466751
|
+
},
|
|
466752
|
+
directory: {
|
|
466753
|
+
type: "string",
|
|
466754
|
+
description: "Directory for the checkpoint baselines. If unset, defaults to a `.checkpoints` directory beside the recording (for example, `demo.mp4.checkpoints/`).",
|
|
466755
|
+
transform: [
|
|
466756
|
+
"trim"
|
|
466757
|
+
]
|
|
466758
|
+
}
|
|
466759
|
+
}
|
|
466760
|
+
}
|
|
466761
|
+
]
|
|
465893
466762
|
}
|
|
465894
466763
|
},
|
|
465895
466764
|
title: "Record (detailed)"
|
|
@@ -466151,10 +467020,11 @@ var init_schemas = __esm({
|
|
|
466151
467020
|
},
|
|
466152
467021
|
overwrite: {
|
|
466153
467022
|
type: "string",
|
|
466154
|
-
description: "If `true`, overwrites the existing recording at `path` if it exists.",
|
|
467023
|
+
description: "If `true`, overwrites the existing recording at `path` if it exists. If `false`, skips the recording when the file already exists. If `aboveVariation`, always records, but replaces the existing file (and its checkpoint baselines) only when the span's checkpoint screenshots show it meaningfully changed \u2014 requires `checkpoints`, so it turns them on with defaults when `checkpoints` is omitted or `false`; set `checkpoints` to an object to tune `maxVariation` or `directory`.",
|
|
466155
467024
|
enum: [
|
|
466156
467025
|
"true",
|
|
466157
|
-
"false"
|
|
467026
|
+
"false",
|
|
467027
|
+
"aboveVariation"
|
|
466158
467028
|
]
|
|
466159
467029
|
},
|
|
466160
467030
|
name: {
|
|
@@ -466212,6 +467082,38 @@ var init_schemas = __esm({
|
|
|
466212
467082
|
}
|
|
466213
467083
|
}
|
|
466214
467084
|
]
|
|
467085
|
+
},
|
|
467086
|
+
checkpoints: {
|
|
467087
|
+
title: "Recording checkpoints",
|
|
467088
|
+
description: "Capture a checkpoint screenshot after every step while this recording is active and compare each against a persistent baseline stored beside the recording (`<path>.checkpoints/` by default). Baselines seed on the first run; on later runs, per-checkpoint variation is reported in the `stopRecord` step's outputs, and variation beyond `maxVariation` surfaces as a WARNING. If `false` or unset, no checkpoints are captured.",
|
|
467089
|
+
anyOf: [
|
|
467090
|
+
{
|
|
467091
|
+
type: "boolean",
|
|
467092
|
+
title: "Recording checkpoints (boolean)",
|
|
467093
|
+
description: "If `true`, enables checkpoints with default settings."
|
|
467094
|
+
},
|
|
467095
|
+
{
|
|
467096
|
+
type: "object",
|
|
467097
|
+
title: "Recording checkpoints (detailed)",
|
|
467098
|
+
additionalProperties: false,
|
|
467099
|
+
properties: {
|
|
467100
|
+
maxVariation: {
|
|
467101
|
+
type: "number",
|
|
467102
|
+
description: "Maximum fractional pixel difference tolerated between a checkpoint and its baseline before the drift surfaces as a WARNING.",
|
|
467103
|
+
default: 0.05,
|
|
467104
|
+
minimum: 0,
|
|
467105
|
+
maximum: 1
|
|
467106
|
+
},
|
|
467107
|
+
directory: {
|
|
467108
|
+
type: "string",
|
|
467109
|
+
description: "Directory for the checkpoint baselines. If unset, defaults to a `.checkpoints` directory beside the recording (for example, `demo.mp4.checkpoints/`).",
|
|
467110
|
+
transform: [
|
|
467111
|
+
"trim"
|
|
467112
|
+
]
|
|
467113
|
+
}
|
|
467114
|
+
}
|
|
467115
|
+
}
|
|
467116
|
+
]
|
|
466215
467117
|
}
|
|
466216
467118
|
},
|
|
466217
467119
|
title: "Record (detailed)"
|
|
@@ -466278,6 +467180,17 @@ var init_schemas = __esm({
|
|
|
466278
467180
|
path: "results.mp4",
|
|
466279
467181
|
engine: "ffmpeg"
|
|
466280
467182
|
},
|
|
467183
|
+
{
|
|
467184
|
+
path: "results.mp4",
|
|
467185
|
+
checkpoints: true
|
|
467186
|
+
},
|
|
467187
|
+
{
|
|
467188
|
+
path: "results.mp4",
|
|
467189
|
+
checkpoints: {
|
|
467190
|
+
maxVariation: 0.02,
|
|
467191
|
+
directory: "baselines/results"
|
|
467192
|
+
}
|
|
467193
|
+
},
|
|
466281
467194
|
{
|
|
466282
467195
|
path: "results.mp4",
|
|
466283
467196
|
engine: {
|
|
@@ -508396,9 +509309,10 @@ var init_schemas = __esm({
|
|
|
508396
509309
|
anyOf: [
|
|
508397
509310
|
{
|
|
508398
509311
|
title: "Screenshot (simple)",
|
|
509312
|
+
$comment: "The pattern gates the target's EXTENSION, not its characters or location: any path ending in .png/.PNG is accepted, plus an http(s) URL to a PNG (optionally with a query string, for signed URLs) and a `$VAR` reference. It deliberately does not restrict the character set \u2014 an earlier pattern allowed any Windows absolute path but limited non-Windows paths to [A-Za-z0-9_./\\-], so ordinary macOS/Linux projects (a space, parentheses, '~', or non-ASCII anywhere in the path) failed validation, including for the absolute paths doc-detective synthesizes internally for autoScreenshot and recording checkpoints. That charset never bounded WHERE a screenshot could be written (traversal like ../../x.png always passed), so it only made non-Windows projects second-class. See ADR 01077.",
|
|
508399
509313
|
description: "File path of the PNG file. Accepts absolute paths. If not specified, the file name is the ID of the step. If an `http(s)` URL is supplied, the remote image is downloaded and used as a read-only reference for comparison; the new capture is written to a local run-specific folder instead of being uploaded back to the URL.",
|
|
508400
509314
|
type: "string",
|
|
508401
|
-
pattern: "^(?:https?:\\/\\/.+\\.(?:png|PNG)(?:\\?.*)
|
|
509315
|
+
pattern: "^(?:https?:\\/\\/.+\\.(?:png|PNG)(?:\\?.*)?|.*\\.(?:png|PNG)|\\$[A-Za-z0-9_]+)$",
|
|
508402
509316
|
transform: [
|
|
508403
509317
|
"trim"
|
|
508404
509318
|
]
|
|
@@ -508632,9 +509546,10 @@ var init_schemas = __esm({
|
|
|
508632
509546
|
},
|
|
508633
509547
|
path: {
|
|
508634
509548
|
title: "Screenshot (simple)",
|
|
509549
|
+
$comment: "The pattern gates the target's EXTENSION, not its characters or location: any path ending in .png/.PNG is accepted, plus an http(s) URL to a PNG (optionally with a query string, for signed URLs) and a `$VAR` reference. It deliberately does not restrict the character set \u2014 an earlier pattern allowed any Windows absolute path but limited non-Windows paths to [A-Za-z0-9_./\\-], so ordinary macOS/Linux projects (a space, parentheses, '~', or non-ASCII anywhere in the path) failed validation, including for the absolute paths doc-detective synthesizes internally for autoScreenshot and recording checkpoints. That charset never bounded WHERE a screenshot could be written (traversal like ../../x.png always passed), so it only made non-Windows projects second-class. See ADR 01077.",
|
|
508635
509550
|
description: "File path of the PNG file. Accepts absolute paths. If not specified, the file name is the ID of the step. If an `http(s)` URL is supplied, the remote image is downloaded and used as a read-only reference for comparison; the new capture is written to a local run-specific folder instead of being uploaded back to the URL.",
|
|
508636
509551
|
type: "string",
|
|
508637
|
-
pattern: "^(?:https?:\\/\\/.+\\.(?:png|PNG)(?:\\?.*)
|
|
509552
|
+
pattern: "^(?:https?:\\/\\/.+\\.(?:png|PNG)(?:\\?.*)?|.*\\.(?:png|PNG)|\\$[A-Za-z0-9_]+)$",
|
|
508638
509553
|
transform: [
|
|
508639
509554
|
"trim"
|
|
508640
509555
|
]
|
|
@@ -508892,9 +509807,10 @@ var init_schemas = __esm({
|
|
|
508892
509807
|
schemas: {
|
|
508893
509808
|
path: {
|
|
508894
509809
|
title: "Screenshot (simple)",
|
|
509810
|
+
$comment: "The pattern gates the target's EXTENSION, not its characters or location: any path ending in .png/.PNG is accepted, plus an http(s) URL to a PNG (optionally with a query string, for signed URLs) and a `$VAR` reference. It deliberately does not restrict the character set \u2014 an earlier pattern allowed any Windows absolute path but limited non-Windows paths to [A-Za-z0-9_./\\-], so ordinary macOS/Linux projects (a space, parentheses, '~', or non-ASCII anywhere in the path) failed validation, including for the absolute paths doc-detective synthesizes internally for autoScreenshot and recording checkpoints. That charset never bounded WHERE a screenshot could be written (traversal like ../../x.png always passed), so it only made non-Windows projects second-class. See ADR 01077.",
|
|
508895
509811
|
description: "File path of the PNG file. Accepts absolute paths. If not specified, the file name is the ID of the step. If an `http(s)` URL is supplied, the remote image is downloaded and used as a read-only reference for comparison; the new capture is written to a local run-specific folder instead of being uploaded back to the URL.",
|
|
508896
509812
|
type: "string",
|
|
508897
|
-
pattern: "^(?:https?:\\/\\/.+\\.(?:png|PNG)(?:\\?.*)
|
|
509813
|
+
pattern: "^(?:https?:\\/\\/.+\\.(?:png|PNG)(?:\\?.*)?|.*\\.(?:png|PNG)|\\$[A-Za-z0-9_]+)$",
|
|
508898
509814
|
transform: [
|
|
508899
509815
|
"trim"
|
|
508900
509816
|
]
|
|
@@ -509128,9 +510044,10 @@ var init_schemas = __esm({
|
|
|
509128
510044
|
},
|
|
509129
510045
|
path: {
|
|
509130
510046
|
title: "Screenshot (simple)",
|
|
510047
|
+
$comment: "The pattern gates the target's EXTENSION, not its characters or location: any path ending in .png/.PNG is accepted, plus an http(s) URL to a PNG (optionally with a query string, for signed URLs) and a `$VAR` reference. It deliberately does not restrict the character set \u2014 an earlier pattern allowed any Windows absolute path but limited non-Windows paths to [A-Za-z0-9_./\\-], so ordinary macOS/Linux projects (a space, parentheses, '~', or non-ASCII anywhere in the path) failed validation, including for the absolute paths doc-detective synthesizes internally for autoScreenshot and recording checkpoints. That charset never bounded WHERE a screenshot could be written (traversal like ../../x.png always passed), so it only made non-Windows projects second-class. See ADR 01077.",
|
|
509131
510048
|
description: "File path of the PNG file. Accepts absolute paths. If not specified, the file name is the ID of the step. If an `http(s)` URL is supplied, the remote image is downloaded and used as a read-only reference for comparison; the new capture is written to a local run-specific folder instead of being uploaded back to the URL.",
|
|
509132
510049
|
type: "string",
|
|
509133
|
-
pattern: "^(?:https?:\\/\\/.+\\.(?:png|PNG)(?:\\?.*)
|
|
510050
|
+
pattern: "^(?:https?:\\/\\/.+\\.(?:png|PNG)(?:\\?.*)?|.*\\.(?:png|PNG)|\\$[A-Za-z0-9_]+)$",
|
|
509134
510051
|
transform: [
|
|
509135
510052
|
"trim"
|
|
509136
510053
|
]
|
|
@@ -509604,9 +510521,10 @@ var init_schemas = __esm({
|
|
|
509604
510521
|
},
|
|
509605
510522
|
path: {
|
|
509606
510523
|
title: "Screenshot (simple)",
|
|
510524
|
+
$comment: "The pattern gates the target's EXTENSION, not its characters or location: any path ending in .png/.PNG is accepted, plus an http(s) URL to a PNG (optionally with a query string, for signed URLs) and a `$VAR` reference. It deliberately does not restrict the character set \u2014 an earlier pattern allowed any Windows absolute path but limited non-Windows paths to [A-Za-z0-9_./\\-], so ordinary macOS/Linux projects (a space, parentheses, '~', or non-ASCII anywhere in the path) failed validation, including for the absolute paths doc-detective synthesizes internally for autoScreenshot and recording checkpoints. That charset never bounded WHERE a screenshot could be written (traversal like ../../x.png always passed), so it only made non-Windows projects second-class. See ADR 01077.",
|
|
509607
510525
|
description: "File path of the PNG file. Accepts absolute paths. If not specified, the file name is the ID of the step. If an `http(s)` URL is supplied, the remote image is downloaded and used as a read-only reference for comparison; the new capture is written to a local run-specific folder instead of being uploaded back to the URL.",
|
|
509608
510526
|
type: "string",
|
|
509609
|
-
pattern: "^(?:https?:\\/\\/.+\\.(?:png|PNG)(?:\\?.*)
|
|
510527
|
+
pattern: "^(?:https?:\\/\\/.+\\.(?:png|PNG)(?:\\?.*)?|.*\\.(?:png|PNG)|\\$[A-Za-z0-9_]+)$",
|
|
509610
510528
|
transform: [
|
|
509611
510529
|
"trim"
|
|
509612
510530
|
]
|
|
@@ -509988,6 +510906,7 @@ var init_schemas = __esm({
|
|
|
509988
510906
|
"image.png",
|
|
509989
510907
|
"static/images/image.png",
|
|
509990
510908
|
"/User/manny/projects/doc-detective/static/images/image.png",
|
|
510909
|
+
"/Users/jane doe/projects/my docs (v2)/static/images/image.png",
|
|
509991
510910
|
"https://example.com/static/images/image.png",
|
|
509992
510911
|
{
|
|
509993
510912
|
path: "https://promptless-customer-doc-assets.s3.amazonaws.com/docs-images/request-changes-button-0c851bb3.png",
|
|
@@ -512422,10 +513341,11 @@ var init_schemas = __esm({
|
|
|
512422
513341
|
},
|
|
512423
513342
|
overwrite: {
|
|
512424
513343
|
type: "string",
|
|
512425
|
-
description: "If `true`, overwrites the existing recording at `path` if it exists.",
|
|
513344
|
+
description: "If `true`, overwrites the existing recording at `path` if it exists. If `false`, skips the recording when the file already exists. If `aboveVariation`, always records, but replaces the existing file (and its checkpoint baselines) only when the span's checkpoint screenshots show it meaningfully changed \u2014 requires `checkpoints`, so it turns them on with defaults when `checkpoints` is omitted or `false`; set `checkpoints` to an object to tune `maxVariation` or `directory`.",
|
|
512426
513345
|
enum: [
|
|
512427
513346
|
"true",
|
|
512428
|
-
"false"
|
|
513347
|
+
"false",
|
|
513348
|
+
"aboveVariation"
|
|
512429
513349
|
]
|
|
512430
513350
|
},
|
|
512431
513351
|
name: {
|
|
@@ -512483,6 +513403,38 @@ var init_schemas = __esm({
|
|
|
512483
513403
|
}
|
|
512484
513404
|
}
|
|
512485
513405
|
]
|
|
513406
|
+
},
|
|
513407
|
+
checkpoints: {
|
|
513408
|
+
title: "Recording checkpoints",
|
|
513409
|
+
description: "Capture a checkpoint screenshot after every step while this recording is active and compare each against a persistent baseline stored beside the recording (`<path>.checkpoints/` by default). Baselines seed on the first run; on later runs, per-checkpoint variation is reported in the `stopRecord` step's outputs, and variation beyond `maxVariation` surfaces as a WARNING. If `false` or unset, no checkpoints are captured.",
|
|
513410
|
+
anyOf: [
|
|
513411
|
+
{
|
|
513412
|
+
type: "boolean",
|
|
513413
|
+
title: "Recording checkpoints (boolean)",
|
|
513414
|
+
description: "If `true`, enables checkpoints with default settings."
|
|
513415
|
+
},
|
|
513416
|
+
{
|
|
513417
|
+
type: "object",
|
|
513418
|
+
title: "Recording checkpoints (detailed)",
|
|
513419
|
+
additionalProperties: false,
|
|
513420
|
+
properties: {
|
|
513421
|
+
maxVariation: {
|
|
513422
|
+
type: "number",
|
|
513423
|
+
description: "Maximum fractional pixel difference tolerated between a checkpoint and its baseline before the drift surfaces as a WARNING.",
|
|
513424
|
+
default: 0.05,
|
|
513425
|
+
minimum: 0,
|
|
513426
|
+
maximum: 1
|
|
513427
|
+
},
|
|
513428
|
+
directory: {
|
|
513429
|
+
type: "string",
|
|
513430
|
+
description: "Directory for the checkpoint baselines. If unset, defaults to a `.checkpoints` directory beside the recording (for example, `demo.mp4.checkpoints/`).",
|
|
513431
|
+
transform: [
|
|
513432
|
+
"trim"
|
|
513433
|
+
]
|
|
513434
|
+
}
|
|
513435
|
+
}
|
|
513436
|
+
}
|
|
513437
|
+
]
|
|
512486
513438
|
}
|
|
512487
513439
|
},
|
|
512488
513440
|
title: "Record (detailed)"
|
|
@@ -512744,10 +513696,11 @@ var init_schemas = __esm({
|
|
|
512744
513696
|
},
|
|
512745
513697
|
overwrite: {
|
|
512746
513698
|
type: "string",
|
|
512747
|
-
description: "If `true`, overwrites the existing recording at `path` if it exists.",
|
|
513699
|
+
description: "If `true`, overwrites the existing recording at `path` if it exists. If `false`, skips the recording when the file already exists. If `aboveVariation`, always records, but replaces the existing file (and its checkpoint baselines) only when the span's checkpoint screenshots show it meaningfully changed \u2014 requires `checkpoints`, so it turns them on with defaults when `checkpoints` is omitted or `false`; set `checkpoints` to an object to tune `maxVariation` or `directory`.",
|
|
512748
513700
|
enum: [
|
|
512749
513701
|
"true",
|
|
512750
|
-
"false"
|
|
513702
|
+
"false",
|
|
513703
|
+
"aboveVariation"
|
|
512751
513704
|
]
|
|
512752
513705
|
},
|
|
512753
513706
|
name: {
|
|
@@ -512805,6 +513758,38 @@ var init_schemas = __esm({
|
|
|
512805
513758
|
}
|
|
512806
513759
|
}
|
|
512807
513760
|
]
|
|
513761
|
+
},
|
|
513762
|
+
checkpoints: {
|
|
513763
|
+
title: "Recording checkpoints",
|
|
513764
|
+
description: "Capture a checkpoint screenshot after every step while this recording is active and compare each against a persistent baseline stored beside the recording (`<path>.checkpoints/` by default). Baselines seed on the first run; on later runs, per-checkpoint variation is reported in the `stopRecord` step's outputs, and variation beyond `maxVariation` surfaces as a WARNING. If `false` or unset, no checkpoints are captured.",
|
|
513765
|
+
anyOf: [
|
|
513766
|
+
{
|
|
513767
|
+
type: "boolean",
|
|
513768
|
+
title: "Recording checkpoints (boolean)",
|
|
513769
|
+
description: "If `true`, enables checkpoints with default settings."
|
|
513770
|
+
},
|
|
513771
|
+
{
|
|
513772
|
+
type: "object",
|
|
513773
|
+
title: "Recording checkpoints (detailed)",
|
|
513774
|
+
additionalProperties: false,
|
|
513775
|
+
properties: {
|
|
513776
|
+
maxVariation: {
|
|
513777
|
+
type: "number",
|
|
513778
|
+
description: "Maximum fractional pixel difference tolerated between a checkpoint and its baseline before the drift surfaces as a WARNING.",
|
|
513779
|
+
default: 0.05,
|
|
513780
|
+
minimum: 0,
|
|
513781
|
+
maximum: 1
|
|
513782
|
+
},
|
|
513783
|
+
directory: {
|
|
513784
|
+
type: "string",
|
|
513785
|
+
description: "Directory for the checkpoint baselines. If unset, defaults to a `.checkpoints` directory beside the recording (for example, `demo.mp4.checkpoints/`).",
|
|
513786
|
+
transform: [
|
|
513787
|
+
"trim"
|
|
513788
|
+
]
|
|
513789
|
+
}
|
|
513790
|
+
}
|
|
513791
|
+
}
|
|
513792
|
+
]
|
|
512808
513793
|
}
|
|
512809
513794
|
},
|
|
512810
513795
|
title: "Record (detailed)"
|
|
@@ -512871,6 +513856,17 @@ var init_schemas = __esm({
|
|
|
512871
513856
|
path: "results.mp4",
|
|
512872
513857
|
engine: "ffmpeg"
|
|
512873
513858
|
},
|
|
513859
|
+
{
|
|
513860
|
+
path: "results.mp4",
|
|
513861
|
+
checkpoints: true
|
|
513862
|
+
},
|
|
513863
|
+
{
|
|
513864
|
+
path: "results.mp4",
|
|
513865
|
+
checkpoints: {
|
|
513866
|
+
maxVariation: 0.02,
|
|
513867
|
+
directory: "baselines/results"
|
|
513868
|
+
}
|
|
513869
|
+
},
|
|
512874
513870
|
{
|
|
512875
513871
|
path: "results.mp4",
|
|
512876
513872
|
engine: {
|
|
@@ -556642,9 +557638,10 @@ var init_schemas = __esm({
|
|
|
556642
557638
|
anyOf: [
|
|
556643
557639
|
{
|
|
556644
557640
|
title: "Screenshot (simple)",
|
|
557641
|
+
$comment: "The pattern gates the target's EXTENSION, not its characters or location: any path ending in .png/.PNG is accepted, plus an http(s) URL to a PNG (optionally with a query string, for signed URLs) and a `$VAR` reference. It deliberately does not restrict the character set \u2014 an earlier pattern allowed any Windows absolute path but limited non-Windows paths to [A-Za-z0-9_./\\-], so ordinary macOS/Linux projects (a space, parentheses, '~', or non-ASCII anywhere in the path) failed validation, including for the absolute paths doc-detective synthesizes internally for autoScreenshot and recording checkpoints. That charset never bounded WHERE a screenshot could be written (traversal like ../../x.png always passed), so it only made non-Windows projects second-class. See ADR 01077.",
|
|
556645
557642
|
description: "File path of the PNG file. Accepts absolute paths. If not specified, the file name is the ID of the step. If an `http(s)` URL is supplied, the remote image is downloaded and used as a read-only reference for comparison; the new capture is written to a local run-specific folder instead of being uploaded back to the URL.",
|
|
556646
557643
|
type: "string",
|
|
556647
|
-
pattern: "^(?:https?:\\/\\/.+\\.(?:png|PNG)(?:\\?.*)
|
|
557644
|
+
pattern: "^(?:https?:\\/\\/.+\\.(?:png|PNG)(?:\\?.*)?|.*\\.(?:png|PNG)|\\$[A-Za-z0-9_]+)$",
|
|
556648
557645
|
transform: [
|
|
556649
557646
|
"trim"
|
|
556650
557647
|
]
|
|
@@ -556878,9 +557875,10 @@ var init_schemas = __esm({
|
|
|
556878
557875
|
},
|
|
556879
557876
|
path: {
|
|
556880
557877
|
title: "Screenshot (simple)",
|
|
557878
|
+
$comment: "The pattern gates the target's EXTENSION, not its characters or location: any path ending in .png/.PNG is accepted, plus an http(s) URL to a PNG (optionally with a query string, for signed URLs) and a `$VAR` reference. It deliberately does not restrict the character set \u2014 an earlier pattern allowed any Windows absolute path but limited non-Windows paths to [A-Za-z0-9_./\\-], so ordinary macOS/Linux projects (a space, parentheses, '~', or non-ASCII anywhere in the path) failed validation, including for the absolute paths doc-detective synthesizes internally for autoScreenshot and recording checkpoints. That charset never bounded WHERE a screenshot could be written (traversal like ../../x.png always passed), so it only made non-Windows projects second-class. See ADR 01077.",
|
|
556881
557879
|
description: "File path of the PNG file. Accepts absolute paths. If not specified, the file name is the ID of the step. If an `http(s)` URL is supplied, the remote image is downloaded and used as a read-only reference for comparison; the new capture is written to a local run-specific folder instead of being uploaded back to the URL.",
|
|
556882
557880
|
type: "string",
|
|
556883
|
-
pattern: "^(?:https?:\\/\\/.+\\.(?:png|PNG)(?:\\?.*)
|
|
557881
|
+
pattern: "^(?:https?:\\/\\/.+\\.(?:png|PNG)(?:\\?.*)?|.*\\.(?:png|PNG)|\\$[A-Za-z0-9_]+)$",
|
|
556884
557882
|
transform: [
|
|
556885
557883
|
"trim"
|
|
556886
557884
|
]
|
|
@@ -557138,9 +558136,10 @@ var init_schemas = __esm({
|
|
|
557138
558136
|
schemas: {
|
|
557139
558137
|
path: {
|
|
557140
558138
|
title: "Screenshot (simple)",
|
|
558139
|
+
$comment: "The pattern gates the target's EXTENSION, not its characters or location: any path ending in .png/.PNG is accepted, plus an http(s) URL to a PNG (optionally with a query string, for signed URLs) and a `$VAR` reference. It deliberately does not restrict the character set \u2014 an earlier pattern allowed any Windows absolute path but limited non-Windows paths to [A-Za-z0-9_./\\-], so ordinary macOS/Linux projects (a space, parentheses, '~', or non-ASCII anywhere in the path) failed validation, including for the absolute paths doc-detective synthesizes internally for autoScreenshot and recording checkpoints. That charset never bounded WHERE a screenshot could be written (traversal like ../../x.png always passed), so it only made non-Windows projects second-class. See ADR 01077.",
|
|
557141
558140
|
description: "File path of the PNG file. Accepts absolute paths. If not specified, the file name is the ID of the step. If an `http(s)` URL is supplied, the remote image is downloaded and used as a read-only reference for comparison; the new capture is written to a local run-specific folder instead of being uploaded back to the URL.",
|
|
557142
558141
|
type: "string",
|
|
557143
|
-
pattern: "^(?:https?:\\/\\/.+\\.(?:png|PNG)(?:\\?.*)
|
|
558142
|
+
pattern: "^(?:https?:\\/\\/.+\\.(?:png|PNG)(?:\\?.*)?|.*\\.(?:png|PNG)|\\$[A-Za-z0-9_]+)$",
|
|
557144
558143
|
transform: [
|
|
557145
558144
|
"trim"
|
|
557146
558145
|
]
|
|
@@ -557374,9 +558373,10 @@ var init_schemas = __esm({
|
|
|
557374
558373
|
},
|
|
557375
558374
|
path: {
|
|
557376
558375
|
title: "Screenshot (simple)",
|
|
558376
|
+
$comment: "The pattern gates the target's EXTENSION, not its characters or location: any path ending in .png/.PNG is accepted, plus an http(s) URL to a PNG (optionally with a query string, for signed URLs) and a `$VAR` reference. It deliberately does not restrict the character set \u2014 an earlier pattern allowed any Windows absolute path but limited non-Windows paths to [A-Za-z0-9_./\\-], so ordinary macOS/Linux projects (a space, parentheses, '~', or non-ASCII anywhere in the path) failed validation, including for the absolute paths doc-detective synthesizes internally for autoScreenshot and recording checkpoints. That charset never bounded WHERE a screenshot could be written (traversal like ../../x.png always passed), so it only made non-Windows projects second-class. See ADR 01077.",
|
|
557377
558377
|
description: "File path of the PNG file. Accepts absolute paths. If not specified, the file name is the ID of the step. If an `http(s)` URL is supplied, the remote image is downloaded and used as a read-only reference for comparison; the new capture is written to a local run-specific folder instead of being uploaded back to the URL.",
|
|
557378
558378
|
type: "string",
|
|
557379
|
-
pattern: "^(?:https?:\\/\\/.+\\.(?:png|PNG)(?:\\?.*)
|
|
558379
|
+
pattern: "^(?:https?:\\/\\/.+\\.(?:png|PNG)(?:\\?.*)?|.*\\.(?:png|PNG)|\\$[A-Za-z0-9_]+)$",
|
|
557380
558380
|
transform: [
|
|
557381
558381
|
"trim"
|
|
557382
558382
|
]
|
|
@@ -557850,9 +558850,10 @@ var init_schemas = __esm({
|
|
|
557850
558850
|
},
|
|
557851
558851
|
path: {
|
|
557852
558852
|
title: "Screenshot (simple)",
|
|
558853
|
+
$comment: "The pattern gates the target's EXTENSION, not its characters or location: any path ending in .png/.PNG is accepted, plus an http(s) URL to a PNG (optionally with a query string, for signed URLs) and a `$VAR` reference. It deliberately does not restrict the character set \u2014 an earlier pattern allowed any Windows absolute path but limited non-Windows paths to [A-Za-z0-9_./\\-], so ordinary macOS/Linux projects (a space, parentheses, '~', or non-ASCII anywhere in the path) failed validation, including for the absolute paths doc-detective synthesizes internally for autoScreenshot and recording checkpoints. That charset never bounded WHERE a screenshot could be written (traversal like ../../x.png always passed), so it only made non-Windows projects second-class. See ADR 01077.",
|
|
557853
558854
|
description: "File path of the PNG file. Accepts absolute paths. If not specified, the file name is the ID of the step. If an `http(s)` URL is supplied, the remote image is downloaded and used as a read-only reference for comparison; the new capture is written to a local run-specific folder instead of being uploaded back to the URL.",
|
|
557854
558855
|
type: "string",
|
|
557855
|
-
pattern: "^(?:https?:\\/\\/.+\\.(?:png|PNG)(?:\\?.*)
|
|
558856
|
+
pattern: "^(?:https?:\\/\\/.+\\.(?:png|PNG)(?:\\?.*)?|.*\\.(?:png|PNG)|\\$[A-Za-z0-9_]+)$",
|
|
557856
558857
|
transform: [
|
|
557857
558858
|
"trim"
|
|
557858
558859
|
]
|
|
@@ -558234,6 +559235,7 @@ var init_schemas = __esm({
|
|
|
558234
559235
|
"image.png",
|
|
558235
559236
|
"static/images/image.png",
|
|
558236
559237
|
"/User/manny/projects/doc-detective/static/images/image.png",
|
|
559238
|
+
"/Users/jane doe/projects/my docs (v2)/static/images/image.png",
|
|
558237
559239
|
"https://example.com/static/images/image.png",
|
|
558238
559240
|
{
|
|
558239
559241
|
path: "https://promptless-customer-doc-assets.s3.amazonaws.com/docs-images/request-changes-button-0c851bb3.png",
|
|
@@ -560668,10 +561670,11 @@ var init_schemas = __esm({
|
|
|
560668
561670
|
},
|
|
560669
561671
|
overwrite: {
|
|
560670
561672
|
type: "string",
|
|
560671
|
-
description: "If `true`, overwrites the existing recording at `path` if it exists.",
|
|
561673
|
+
description: "If `true`, overwrites the existing recording at `path` if it exists. If `false`, skips the recording when the file already exists. If `aboveVariation`, always records, but replaces the existing file (and its checkpoint baselines) only when the span's checkpoint screenshots show it meaningfully changed \u2014 requires `checkpoints`, so it turns them on with defaults when `checkpoints` is omitted or `false`; set `checkpoints` to an object to tune `maxVariation` or `directory`.",
|
|
560672
561674
|
enum: [
|
|
560673
561675
|
"true",
|
|
560674
|
-
"false"
|
|
561676
|
+
"false",
|
|
561677
|
+
"aboveVariation"
|
|
560675
561678
|
]
|
|
560676
561679
|
},
|
|
560677
561680
|
name: {
|
|
@@ -560729,6 +561732,38 @@ var init_schemas = __esm({
|
|
|
560729
561732
|
}
|
|
560730
561733
|
}
|
|
560731
561734
|
]
|
|
561735
|
+
},
|
|
561736
|
+
checkpoints: {
|
|
561737
|
+
title: "Recording checkpoints",
|
|
561738
|
+
description: "Capture a checkpoint screenshot after every step while this recording is active and compare each against a persistent baseline stored beside the recording (`<path>.checkpoints/` by default). Baselines seed on the first run; on later runs, per-checkpoint variation is reported in the `stopRecord` step's outputs, and variation beyond `maxVariation` surfaces as a WARNING. If `false` or unset, no checkpoints are captured.",
|
|
561739
|
+
anyOf: [
|
|
561740
|
+
{
|
|
561741
|
+
type: "boolean",
|
|
561742
|
+
title: "Recording checkpoints (boolean)",
|
|
561743
|
+
description: "If `true`, enables checkpoints with default settings."
|
|
561744
|
+
},
|
|
561745
|
+
{
|
|
561746
|
+
type: "object",
|
|
561747
|
+
title: "Recording checkpoints (detailed)",
|
|
561748
|
+
additionalProperties: false,
|
|
561749
|
+
properties: {
|
|
561750
|
+
maxVariation: {
|
|
561751
|
+
type: "number",
|
|
561752
|
+
description: "Maximum fractional pixel difference tolerated between a checkpoint and its baseline before the drift surfaces as a WARNING.",
|
|
561753
|
+
default: 0.05,
|
|
561754
|
+
minimum: 0,
|
|
561755
|
+
maximum: 1
|
|
561756
|
+
},
|
|
561757
|
+
directory: {
|
|
561758
|
+
type: "string",
|
|
561759
|
+
description: "Directory for the checkpoint baselines. If unset, defaults to a `.checkpoints` directory beside the recording (for example, `demo.mp4.checkpoints/`).",
|
|
561760
|
+
transform: [
|
|
561761
|
+
"trim"
|
|
561762
|
+
]
|
|
561763
|
+
}
|
|
561764
|
+
}
|
|
561765
|
+
}
|
|
561766
|
+
]
|
|
560732
561767
|
}
|
|
560733
561768
|
},
|
|
560734
561769
|
title: "Record (detailed)"
|
|
@@ -560990,10 +562025,11 @@ var init_schemas = __esm({
|
|
|
560990
562025
|
},
|
|
560991
562026
|
overwrite: {
|
|
560992
562027
|
type: "string",
|
|
560993
|
-
description: "If `true`, overwrites the existing recording at `path` if it exists.",
|
|
562028
|
+
description: "If `true`, overwrites the existing recording at `path` if it exists. If `false`, skips the recording when the file already exists. If `aboveVariation`, always records, but replaces the existing file (and its checkpoint baselines) only when the span's checkpoint screenshots show it meaningfully changed \u2014 requires `checkpoints`, so it turns them on with defaults when `checkpoints` is omitted or `false`; set `checkpoints` to an object to tune `maxVariation` or `directory`.",
|
|
560994
562029
|
enum: [
|
|
560995
562030
|
"true",
|
|
560996
|
-
"false"
|
|
562031
|
+
"false",
|
|
562032
|
+
"aboveVariation"
|
|
560997
562033
|
]
|
|
560998
562034
|
},
|
|
560999
562035
|
name: {
|
|
@@ -561051,6 +562087,38 @@ var init_schemas = __esm({
|
|
|
561051
562087
|
}
|
|
561052
562088
|
}
|
|
561053
562089
|
]
|
|
562090
|
+
},
|
|
562091
|
+
checkpoints: {
|
|
562092
|
+
title: "Recording checkpoints",
|
|
562093
|
+
description: "Capture a checkpoint screenshot after every step while this recording is active and compare each against a persistent baseline stored beside the recording (`<path>.checkpoints/` by default). Baselines seed on the first run; on later runs, per-checkpoint variation is reported in the `stopRecord` step's outputs, and variation beyond `maxVariation` surfaces as a WARNING. If `false` or unset, no checkpoints are captured.",
|
|
562094
|
+
anyOf: [
|
|
562095
|
+
{
|
|
562096
|
+
type: "boolean",
|
|
562097
|
+
title: "Recording checkpoints (boolean)",
|
|
562098
|
+
description: "If `true`, enables checkpoints with default settings."
|
|
562099
|
+
},
|
|
562100
|
+
{
|
|
562101
|
+
type: "object",
|
|
562102
|
+
title: "Recording checkpoints (detailed)",
|
|
562103
|
+
additionalProperties: false,
|
|
562104
|
+
properties: {
|
|
562105
|
+
maxVariation: {
|
|
562106
|
+
type: "number",
|
|
562107
|
+
description: "Maximum fractional pixel difference tolerated between a checkpoint and its baseline before the drift surfaces as a WARNING.",
|
|
562108
|
+
default: 0.05,
|
|
562109
|
+
minimum: 0,
|
|
562110
|
+
maximum: 1
|
|
562111
|
+
},
|
|
562112
|
+
directory: {
|
|
562113
|
+
type: "string",
|
|
562114
|
+
description: "Directory for the checkpoint baselines. If unset, defaults to a `.checkpoints` directory beside the recording (for example, `demo.mp4.checkpoints/`).",
|
|
562115
|
+
transform: [
|
|
562116
|
+
"trim"
|
|
562117
|
+
]
|
|
562118
|
+
}
|
|
562119
|
+
}
|
|
562120
|
+
}
|
|
562121
|
+
]
|
|
561054
562122
|
}
|
|
561055
562123
|
},
|
|
561056
562124
|
title: "Record (detailed)"
|
|
@@ -561117,6 +562185,17 @@ var init_schemas = __esm({
|
|
|
561117
562185
|
path: "results.mp4",
|
|
561118
562186
|
engine: "ffmpeg"
|
|
561119
562187
|
},
|
|
562188
|
+
{
|
|
562189
|
+
path: "results.mp4",
|
|
562190
|
+
checkpoints: true
|
|
562191
|
+
},
|
|
562192
|
+
{
|
|
562193
|
+
path: "results.mp4",
|
|
562194
|
+
checkpoints: {
|
|
562195
|
+
maxVariation: 0.02,
|
|
562196
|
+
directory: "baselines/results"
|
|
562197
|
+
}
|
|
562198
|
+
},
|
|
561120
562199
|
{
|
|
561121
562200
|
path: "results.mp4",
|
|
561122
562201
|
engine: {
|
|
@@ -601543,9 +602622,10 @@ var init_schemas = __esm({
|
|
|
601543
602622
|
anyOf: [
|
|
601544
602623
|
{
|
|
601545
602624
|
title: "Screenshot (simple)",
|
|
602625
|
+
$comment: "The pattern gates the target's EXTENSION, not its characters or location: any path ending in .png/.PNG is accepted, plus an http(s) URL to a PNG (optionally with a query string, for signed URLs) and a `$VAR` reference. It deliberately does not restrict the character set \u2014 an earlier pattern allowed any Windows absolute path but limited non-Windows paths to [A-Za-z0-9_./\\-], so ordinary macOS/Linux projects (a space, parentheses, '~', or non-ASCII anywhere in the path) failed validation, including for the absolute paths doc-detective synthesizes internally for autoScreenshot and recording checkpoints. That charset never bounded WHERE a screenshot could be written (traversal like ../../x.png always passed), so it only made non-Windows projects second-class. See ADR 01077.",
|
|
601546
602626
|
description: "File path of the PNG file. Accepts absolute paths. If not specified, the file name is the ID of the step. If an `http(s)` URL is supplied, the remote image is downloaded and used as a read-only reference for comparison; the new capture is written to a local run-specific folder instead of being uploaded back to the URL.",
|
|
601547
602627
|
type: "string",
|
|
601548
|
-
pattern: "^(?:https?:\\/\\/.+\\.(?:png|PNG)(?:\\?.*)
|
|
602628
|
+
pattern: "^(?:https?:\\/\\/.+\\.(?:png|PNG)(?:\\?.*)?|.*\\.(?:png|PNG)|\\$[A-Za-z0-9_]+)$",
|
|
601549
602629
|
transform: [
|
|
601550
602630
|
"trim"
|
|
601551
602631
|
]
|
|
@@ -601779,9 +602859,10 @@ var init_schemas = __esm({
|
|
|
601779
602859
|
},
|
|
601780
602860
|
path: {
|
|
601781
602861
|
title: "Screenshot (simple)",
|
|
602862
|
+
$comment: "The pattern gates the target's EXTENSION, not its characters or location: any path ending in .png/.PNG is accepted, plus an http(s) URL to a PNG (optionally with a query string, for signed URLs) and a `$VAR` reference. It deliberately does not restrict the character set \u2014 an earlier pattern allowed any Windows absolute path but limited non-Windows paths to [A-Za-z0-9_./\\-], so ordinary macOS/Linux projects (a space, parentheses, '~', or non-ASCII anywhere in the path) failed validation, including for the absolute paths doc-detective synthesizes internally for autoScreenshot and recording checkpoints. That charset never bounded WHERE a screenshot could be written (traversal like ../../x.png always passed), so it only made non-Windows projects second-class. See ADR 01077.",
|
|
601782
602863
|
description: "File path of the PNG file. Accepts absolute paths. If not specified, the file name is the ID of the step. If an `http(s)` URL is supplied, the remote image is downloaded and used as a read-only reference for comparison; the new capture is written to a local run-specific folder instead of being uploaded back to the URL.",
|
|
601783
602864
|
type: "string",
|
|
601784
|
-
pattern: "^(?:https?:\\/\\/.+\\.(?:png|PNG)(?:\\?.*)
|
|
602865
|
+
pattern: "^(?:https?:\\/\\/.+\\.(?:png|PNG)(?:\\?.*)?|.*\\.(?:png|PNG)|\\$[A-Za-z0-9_]+)$",
|
|
601785
602866
|
transform: [
|
|
601786
602867
|
"trim"
|
|
601787
602868
|
]
|
|
@@ -602039,9 +603120,10 @@ var init_schemas = __esm({
|
|
|
602039
603120
|
schemas: {
|
|
602040
603121
|
path: {
|
|
602041
603122
|
title: "Screenshot (simple)",
|
|
603123
|
+
$comment: "The pattern gates the target's EXTENSION, not its characters or location: any path ending in .png/.PNG is accepted, plus an http(s) URL to a PNG (optionally with a query string, for signed URLs) and a `$VAR` reference. It deliberately does not restrict the character set \u2014 an earlier pattern allowed any Windows absolute path but limited non-Windows paths to [A-Za-z0-9_./\\-], so ordinary macOS/Linux projects (a space, parentheses, '~', or non-ASCII anywhere in the path) failed validation, including for the absolute paths doc-detective synthesizes internally for autoScreenshot and recording checkpoints. That charset never bounded WHERE a screenshot could be written (traversal like ../../x.png always passed), so it only made non-Windows projects second-class. See ADR 01077.",
|
|
602042
603124
|
description: "File path of the PNG file. Accepts absolute paths. If not specified, the file name is the ID of the step. If an `http(s)` URL is supplied, the remote image is downloaded and used as a read-only reference for comparison; the new capture is written to a local run-specific folder instead of being uploaded back to the URL.",
|
|
602043
603125
|
type: "string",
|
|
602044
|
-
pattern: "^(?:https?:\\/\\/.+\\.(?:png|PNG)(?:\\?.*)
|
|
603126
|
+
pattern: "^(?:https?:\\/\\/.+\\.(?:png|PNG)(?:\\?.*)?|.*\\.(?:png|PNG)|\\$[A-Za-z0-9_]+)$",
|
|
602045
603127
|
transform: [
|
|
602046
603128
|
"trim"
|
|
602047
603129
|
]
|
|
@@ -602275,9 +603357,10 @@ var init_schemas = __esm({
|
|
|
602275
603357
|
},
|
|
602276
603358
|
path: {
|
|
602277
603359
|
title: "Screenshot (simple)",
|
|
603360
|
+
$comment: "The pattern gates the target's EXTENSION, not its characters or location: any path ending in .png/.PNG is accepted, plus an http(s) URL to a PNG (optionally with a query string, for signed URLs) and a `$VAR` reference. It deliberately does not restrict the character set \u2014 an earlier pattern allowed any Windows absolute path but limited non-Windows paths to [A-Za-z0-9_./\\-], so ordinary macOS/Linux projects (a space, parentheses, '~', or non-ASCII anywhere in the path) failed validation, including for the absolute paths doc-detective synthesizes internally for autoScreenshot and recording checkpoints. That charset never bounded WHERE a screenshot could be written (traversal like ../../x.png always passed), so it only made non-Windows projects second-class. See ADR 01077.",
|
|
602278
603361
|
description: "File path of the PNG file. Accepts absolute paths. If not specified, the file name is the ID of the step. If an `http(s)` URL is supplied, the remote image is downloaded and used as a read-only reference for comparison; the new capture is written to a local run-specific folder instead of being uploaded back to the URL.",
|
|
602279
603362
|
type: "string",
|
|
602280
|
-
pattern: "^(?:https?:\\/\\/.+\\.(?:png|PNG)(?:\\?.*)
|
|
603363
|
+
pattern: "^(?:https?:\\/\\/.+\\.(?:png|PNG)(?:\\?.*)?|.*\\.(?:png|PNG)|\\$[A-Za-z0-9_]+)$",
|
|
602281
603364
|
transform: [
|
|
602282
603365
|
"trim"
|
|
602283
603366
|
]
|
|
@@ -602751,9 +603834,10 @@ var init_schemas = __esm({
|
|
|
602751
603834
|
},
|
|
602752
603835
|
path: {
|
|
602753
603836
|
title: "Screenshot (simple)",
|
|
603837
|
+
$comment: "The pattern gates the target's EXTENSION, not its characters or location: any path ending in .png/.PNG is accepted, plus an http(s) URL to a PNG (optionally with a query string, for signed URLs) and a `$VAR` reference. It deliberately does not restrict the character set \u2014 an earlier pattern allowed any Windows absolute path but limited non-Windows paths to [A-Za-z0-9_./\\-], so ordinary macOS/Linux projects (a space, parentheses, '~', or non-ASCII anywhere in the path) failed validation, including for the absolute paths doc-detective synthesizes internally for autoScreenshot and recording checkpoints. That charset never bounded WHERE a screenshot could be written (traversal like ../../x.png always passed), so it only made non-Windows projects second-class. See ADR 01077.",
|
|
602754
603838
|
description: "File path of the PNG file. Accepts absolute paths. If not specified, the file name is the ID of the step. If an `http(s)` URL is supplied, the remote image is downloaded and used as a read-only reference for comparison; the new capture is written to a local run-specific folder instead of being uploaded back to the URL.",
|
|
602755
603839
|
type: "string",
|
|
602756
|
-
pattern: "^(?:https?:\\/\\/.+\\.(?:png|PNG)(?:\\?.*)
|
|
603840
|
+
pattern: "^(?:https?:\\/\\/.+\\.(?:png|PNG)(?:\\?.*)?|.*\\.(?:png|PNG)|\\$[A-Za-z0-9_]+)$",
|
|
602757
603841
|
transform: [
|
|
602758
603842
|
"trim"
|
|
602759
603843
|
]
|
|
@@ -603135,6 +604219,7 @@ var init_schemas = __esm({
|
|
|
603135
604219
|
"image.png",
|
|
603136
604220
|
"static/images/image.png",
|
|
603137
604221
|
"/User/manny/projects/doc-detective/static/images/image.png",
|
|
604222
|
+
"/Users/jane doe/projects/my docs (v2)/static/images/image.png",
|
|
603138
604223
|
"https://example.com/static/images/image.png",
|
|
603139
604224
|
{
|
|
603140
604225
|
path: "https://promptless-customer-doc-assets.s3.amazonaws.com/docs-images/request-changes-button-0c851bb3.png",
|
|
@@ -605569,10 +606654,11 @@ var init_schemas = __esm({
|
|
|
605569
606654
|
},
|
|
605570
606655
|
overwrite: {
|
|
605571
606656
|
type: "string",
|
|
605572
|
-
description: "If `true`, overwrites the existing recording at `path` if it exists.",
|
|
606657
|
+
description: "If `true`, overwrites the existing recording at `path` if it exists. If `false`, skips the recording when the file already exists. If `aboveVariation`, always records, but replaces the existing file (and its checkpoint baselines) only when the span's checkpoint screenshots show it meaningfully changed \u2014 requires `checkpoints`, so it turns them on with defaults when `checkpoints` is omitted or `false`; set `checkpoints` to an object to tune `maxVariation` or `directory`.",
|
|
605573
606658
|
enum: [
|
|
605574
606659
|
"true",
|
|
605575
|
-
"false"
|
|
606660
|
+
"false",
|
|
606661
|
+
"aboveVariation"
|
|
605576
606662
|
]
|
|
605577
606663
|
},
|
|
605578
606664
|
name: {
|
|
@@ -605630,6 +606716,38 @@ var init_schemas = __esm({
|
|
|
605630
606716
|
}
|
|
605631
606717
|
}
|
|
605632
606718
|
]
|
|
606719
|
+
},
|
|
606720
|
+
checkpoints: {
|
|
606721
|
+
title: "Recording checkpoints",
|
|
606722
|
+
description: "Capture a checkpoint screenshot after every step while this recording is active and compare each against a persistent baseline stored beside the recording (`<path>.checkpoints/` by default). Baselines seed on the first run; on later runs, per-checkpoint variation is reported in the `stopRecord` step's outputs, and variation beyond `maxVariation` surfaces as a WARNING. If `false` or unset, no checkpoints are captured.",
|
|
606723
|
+
anyOf: [
|
|
606724
|
+
{
|
|
606725
|
+
type: "boolean",
|
|
606726
|
+
title: "Recording checkpoints (boolean)",
|
|
606727
|
+
description: "If `true`, enables checkpoints with default settings."
|
|
606728
|
+
},
|
|
606729
|
+
{
|
|
606730
|
+
type: "object",
|
|
606731
|
+
title: "Recording checkpoints (detailed)",
|
|
606732
|
+
additionalProperties: false,
|
|
606733
|
+
properties: {
|
|
606734
|
+
maxVariation: {
|
|
606735
|
+
type: "number",
|
|
606736
|
+
description: "Maximum fractional pixel difference tolerated between a checkpoint and its baseline before the drift surfaces as a WARNING.",
|
|
606737
|
+
default: 0.05,
|
|
606738
|
+
minimum: 0,
|
|
606739
|
+
maximum: 1
|
|
606740
|
+
},
|
|
606741
|
+
directory: {
|
|
606742
|
+
type: "string",
|
|
606743
|
+
description: "Directory for the checkpoint baselines. If unset, defaults to a `.checkpoints` directory beside the recording (for example, `demo.mp4.checkpoints/`).",
|
|
606744
|
+
transform: [
|
|
606745
|
+
"trim"
|
|
606746
|
+
]
|
|
606747
|
+
}
|
|
606748
|
+
}
|
|
606749
|
+
}
|
|
606750
|
+
]
|
|
605633
606751
|
}
|
|
605634
606752
|
},
|
|
605635
606753
|
title: "Record (detailed)"
|
|
@@ -605891,10 +607009,11 @@ var init_schemas = __esm({
|
|
|
605891
607009
|
},
|
|
605892
607010
|
overwrite: {
|
|
605893
607011
|
type: "string",
|
|
605894
|
-
description: "If `true`, overwrites the existing recording at `path` if it exists.",
|
|
607012
|
+
description: "If `true`, overwrites the existing recording at `path` if it exists. If `false`, skips the recording when the file already exists. If `aboveVariation`, always records, but replaces the existing file (and its checkpoint baselines) only when the span's checkpoint screenshots show it meaningfully changed \u2014 requires `checkpoints`, so it turns them on with defaults when `checkpoints` is omitted or `false`; set `checkpoints` to an object to tune `maxVariation` or `directory`.",
|
|
605895
607013
|
enum: [
|
|
605896
607014
|
"true",
|
|
605897
|
-
"false"
|
|
607015
|
+
"false",
|
|
607016
|
+
"aboveVariation"
|
|
605898
607017
|
]
|
|
605899
607018
|
},
|
|
605900
607019
|
name: {
|
|
@@ -605952,6 +607071,38 @@ var init_schemas = __esm({
|
|
|
605952
607071
|
}
|
|
605953
607072
|
}
|
|
605954
607073
|
]
|
|
607074
|
+
},
|
|
607075
|
+
checkpoints: {
|
|
607076
|
+
title: "Recording checkpoints",
|
|
607077
|
+
description: "Capture a checkpoint screenshot after every step while this recording is active and compare each against a persistent baseline stored beside the recording (`<path>.checkpoints/` by default). Baselines seed on the first run; on later runs, per-checkpoint variation is reported in the `stopRecord` step's outputs, and variation beyond `maxVariation` surfaces as a WARNING. If `false` or unset, no checkpoints are captured.",
|
|
607078
|
+
anyOf: [
|
|
607079
|
+
{
|
|
607080
|
+
type: "boolean",
|
|
607081
|
+
title: "Recording checkpoints (boolean)",
|
|
607082
|
+
description: "If `true`, enables checkpoints with default settings."
|
|
607083
|
+
},
|
|
607084
|
+
{
|
|
607085
|
+
type: "object",
|
|
607086
|
+
title: "Recording checkpoints (detailed)",
|
|
607087
|
+
additionalProperties: false,
|
|
607088
|
+
properties: {
|
|
607089
|
+
maxVariation: {
|
|
607090
|
+
type: "number",
|
|
607091
|
+
description: "Maximum fractional pixel difference tolerated between a checkpoint and its baseline before the drift surfaces as a WARNING.",
|
|
607092
|
+
default: 0.05,
|
|
607093
|
+
minimum: 0,
|
|
607094
|
+
maximum: 1
|
|
607095
|
+
},
|
|
607096
|
+
directory: {
|
|
607097
|
+
type: "string",
|
|
607098
|
+
description: "Directory for the checkpoint baselines. If unset, defaults to a `.checkpoints` directory beside the recording (for example, `demo.mp4.checkpoints/`).",
|
|
607099
|
+
transform: [
|
|
607100
|
+
"trim"
|
|
607101
|
+
]
|
|
607102
|
+
}
|
|
607103
|
+
}
|
|
607104
|
+
}
|
|
607105
|
+
]
|
|
605955
607106
|
}
|
|
605956
607107
|
},
|
|
605957
607108
|
title: "Record (detailed)"
|
|
@@ -606018,6 +607169,17 @@ var init_schemas = __esm({
|
|
|
606018
607169
|
path: "results.mp4",
|
|
606019
607170
|
engine: "ffmpeg"
|
|
606020
607171
|
},
|
|
607172
|
+
{
|
|
607173
|
+
path: "results.mp4",
|
|
607174
|
+
checkpoints: true
|
|
607175
|
+
},
|
|
607176
|
+
{
|
|
607177
|
+
path: "results.mp4",
|
|
607178
|
+
checkpoints: {
|
|
607179
|
+
maxVariation: 0.02,
|
|
607180
|
+
directory: "baselines/results"
|
|
607181
|
+
}
|
|
607182
|
+
},
|
|
606021
607183
|
{
|
|
606022
607184
|
path: "results.mp4",
|
|
606023
607185
|
engine: {
|
|
@@ -634667,12 +635829,12 @@ async function ensureBrowserInstalledImpl(name, options = {}) {
|
|
|
634667
635829
|
}
|
|
634668
635830
|
if (!force && existing && isStillFresh(existing.latestCheckedAt, now)) {
|
|
634669
635831
|
if (existing.latestKnownVersion === existing.installedVersion) {
|
|
634670
|
-
const
|
|
634671
|
-
return { path:
|
|
635832
|
+
const path30 = await locateExecutable(browsersModule, name, existing.installedVersion, cacheDir, platform);
|
|
635833
|
+
return { path: path30, version: existing.installedVersion, outdated: false };
|
|
634672
635834
|
}
|
|
634673
|
-
const
|
|
635835
|
+
const path29 = await locateExecutable(browsersModule, name, existing.installedVersion, cacheDir, platform);
|
|
634674
635836
|
logger(`${name} ${existing.installedVersion} installed in ${cacheDir}; "${BROWSER_CHANNELS[name]}" channel is now ${existing.latestKnownVersion}. Run \`doc-detective install browsers ${name} --force\` to update.`, "warn");
|
|
634675
|
-
return { path:
|
|
635837
|
+
return { path: path29, version: existing.installedVersion, outdated: true };
|
|
634676
635838
|
}
|
|
634677
635839
|
let latest;
|
|
634678
635840
|
try {
|
|
@@ -634680,8 +635842,8 @@ async function ensureBrowserInstalledImpl(name, options = {}) {
|
|
|
634680
635842
|
} catch (err) {
|
|
634681
635843
|
logger(`Channel resolution for ${name} skipped: ${String(err)}`, "debug");
|
|
634682
635844
|
if (existing) {
|
|
634683
|
-
const
|
|
634684
|
-
return { path:
|
|
635845
|
+
const path29 = await locateExecutable(browsersModule, name, existing.installedVersion, cacheDir, platform);
|
|
635846
|
+
return { path: path29, version: existing.installedVersion, outdated: false };
|
|
634685
635847
|
}
|
|
634686
635848
|
throw err;
|
|
634687
635849
|
}
|
|
@@ -634692,8 +635854,8 @@ async function ensureBrowserInstalledImpl(name, options = {}) {
|
|
|
634692
635854
|
latestCheckedAt: now.toISOString()
|
|
634693
635855
|
};
|
|
634694
635856
|
writeInstalledRecord(record, ctx);
|
|
634695
|
-
const
|
|
634696
|
-
return { path:
|
|
635857
|
+
const path29 = await locateExecutable(browsersModule, name, latest, cacheDir, platform);
|
|
635858
|
+
return { path: path29, version: latest, outdated: false };
|
|
634697
635859
|
}
|
|
634698
635860
|
if (!force && existing) {
|
|
634699
635861
|
record.browsers[name] = {
|
|
@@ -634703,8 +635865,8 @@ async function ensureBrowserInstalledImpl(name, options = {}) {
|
|
|
634703
635865
|
};
|
|
634704
635866
|
writeInstalledRecord(record, ctx);
|
|
634705
635867
|
logger(`${name} ${existing.installedVersion} installed in ${cacheDir}; "${BROWSER_CHANNELS[name]}" channel is now ${latest}. Run \`doc-detective install browsers ${name} --force\` to update.`, "warn");
|
|
634706
|
-
const
|
|
634707
|
-
return { path:
|
|
635868
|
+
const path29 = await locateExecutable(browsersModule, name, existing.installedVersion, cacheDir, platform);
|
|
635869
|
+
return { path: path29, version: existing.installedVersion, outdated: true };
|
|
634708
635870
|
}
|
|
634709
635871
|
logger(`Installing ${name} ${latest} into ${cacheDir}`, "info");
|
|
634710
635872
|
await browsersModule.install({
|
|
@@ -634712,9 +635874,9 @@ async function ensureBrowserInstalledImpl(name, options = {}) {
|
|
|
634712
635874
|
buildId: latest,
|
|
634713
635875
|
cacheDir
|
|
634714
635876
|
});
|
|
634715
|
-
let
|
|
634716
|
-
if (name === "chromedriver" && isAllowedDriverPath(
|
|
634717
|
-
let verify = await verifyDriverBinary(name,
|
|
635877
|
+
let path28 = await locateExecutable(browsersModule, name, latest, cacheDir, platform);
|
|
635878
|
+
if (name === "chromedriver" && isAllowedDriverPath(path28)) {
|
|
635879
|
+
let verify = await verifyDriverBinary(name, path28, { exec: deps.verifyExec });
|
|
634718
635880
|
if (!verify.ok) {
|
|
634719
635881
|
logger(`Installed ${name} ${latest} failed validation (${verify.error}); reinstalling once.`, "warn");
|
|
634720
635882
|
try {
|
|
@@ -634723,11 +635885,11 @@ async function ensureBrowserInstalledImpl(name, options = {}) {
|
|
|
634723
635885
|
logger(`Failed to prune broken ${name} ${latest}: ${String(err)}`, "debug");
|
|
634724
635886
|
}
|
|
634725
635887
|
await browsersModule.install({ browser: name, buildId: latest, cacheDir });
|
|
634726
|
-
|
|
634727
|
-
verify = await verifyDriverBinary(name,
|
|
635888
|
+
path28 = await locateExecutable(browsersModule, name, latest, cacheDir, platform);
|
|
635889
|
+
verify = await verifyDriverBinary(name, path28, { exec: deps.verifyExec });
|
|
634728
635890
|
}
|
|
634729
635891
|
if (!verify.ok) {
|
|
634730
|
-
throw new Error(`${name} ${latest} is present but non-functional after a reinstall (${verify.error}). It may be a partial or corrupt download; delete ${
|
|
635892
|
+
throw new Error(`${name} ${latest} is present but non-functional after a reinstall (${verify.error}). It may be a partial or corrupt download; delete ${path28} or reinstall.`);
|
|
634731
635893
|
}
|
|
634732
635894
|
}
|
|
634733
635895
|
if (existing && existing.installedVersion !== latest) {
|
|
@@ -634748,7 +635910,7 @@ async function ensureBrowserInstalledImpl(name, options = {}) {
|
|
|
634748
635910
|
latestCheckedAt: now.toISOString()
|
|
634749
635911
|
};
|
|
634750
635912
|
writeInstalledRecord(record, ctx);
|
|
634751
|
-
return { path:
|
|
635913
|
+
return { path: path28, version: latest, outdated: false };
|
|
634752
635914
|
}
|
|
634753
635915
|
async function locateExecutable(browsersModule, name, buildId, cacheDir, platform) {
|
|
634754
635916
|
if (typeof browsersModule.computeExecutablePath === "function") {
|
|
@@ -635201,10 +636363,10 @@ async function getOperation(definition = {}, operationId = "", responseCode = ""
|
|
|
635201
636363
|
if (!operationId) {
|
|
635202
636364
|
throw new Error("OperationId is required.");
|
|
635203
636365
|
}
|
|
635204
|
-
for (const
|
|
635205
|
-
for (const method in definition.paths[
|
|
635206
|
-
if (definition.paths[
|
|
635207
|
-
const operation = definition.paths[
|
|
636366
|
+
for (const path28 in definition.paths) {
|
|
636367
|
+
for (const method in definition.paths[path28]) {
|
|
636368
|
+
if (definition.paths[path28][method].operationId === operationId) {
|
|
636369
|
+
const operation = definition.paths[path28][method];
|
|
635208
636370
|
if (!server) {
|
|
635209
636371
|
if (definition.servers && definition.servers.length > 0) {
|
|
635210
636372
|
server = definition.servers[0].url;
|
|
@@ -635212,9 +636374,9 @@ async function getOperation(definition = {}, operationId = "", responseCode = ""
|
|
|
635212
636374
|
throw new Error("No server URL provided and no servers defined in the OpenAPI definition.");
|
|
635213
636375
|
}
|
|
635214
636376
|
}
|
|
635215
|
-
const example = await compileExample(operation, server +
|
|
636377
|
+
const example = await compileExample(operation, server + path28, responseCode, exampleKey);
|
|
635216
636378
|
const schemas2 = getSchemas(operation, responseCode);
|
|
635217
|
-
return { path:
|
|
636379
|
+
return { path: path28, method, definition: operation, schemas: schemas2, example };
|
|
635218
636380
|
}
|
|
635219
636381
|
}
|
|
635220
636382
|
}
|
|
@@ -635235,15 +636397,15 @@ function getSchemas(definition = {}, responseCode = "") {
|
|
|
635235
636397
|
schemas2.response = definition.responses[responseCode].content[Object.keys(definition.responses[responseCode].content)[0]].schema;
|
|
635236
636398
|
return schemas2;
|
|
635237
636399
|
}
|
|
635238
|
-
async function compileExample(operation = {},
|
|
636400
|
+
async function compileExample(operation = {}, path28 = "", responseCode = "", exampleKey = "") {
|
|
635239
636401
|
if (!operation) {
|
|
635240
636402
|
throw new Error("Operation is required.");
|
|
635241
636403
|
}
|
|
635242
|
-
if (!
|
|
636404
|
+
if (!path28) {
|
|
635243
636405
|
throw new Error("Path is required.");
|
|
635244
636406
|
}
|
|
635245
636407
|
let example = {
|
|
635246
|
-
url:
|
|
636408
|
+
url: path28,
|
|
635247
636409
|
request: { parameters: {}, headers: {}, body: {} },
|
|
635248
636410
|
response: { headers: {}, body: {} }
|
|
635249
636411
|
};
|
|
@@ -639194,11 +640356,11 @@ init_utils();
|
|
|
639194
640356
|
|
|
639195
640357
|
// dist/core/tests.js
|
|
639196
640358
|
var import_tree_kill3 = __toESM(require("tree-kill"), 1);
|
|
639197
|
-
var
|
|
640359
|
+
var import_node_fs30 = __toESM(require("node:fs"), 1);
|
|
639198
640360
|
init_loader();
|
|
639199
640361
|
init_browsers();
|
|
639200
640362
|
init_browserStepKeys();
|
|
639201
|
-
var
|
|
640363
|
+
var import_node_os12 = __toESM(require("node:os"), 1);
|
|
639202
640364
|
init_utils();
|
|
639203
640365
|
var import_axios6 = __toESM(require("axios"), 1);
|
|
639204
640366
|
|
|
@@ -639940,22 +641102,22 @@ function computeWdaKey(xcode, driverVersion) {
|
|
|
639940
641102
|
var RUNNER_APP_RELATIVE = import_node_path12.default.join("DerivedData", "Build", "Products", "Debug-iphonesimulator", "WebDriverAgentRunner-Runner.app");
|
|
639941
641103
|
var PRODUCTS_MARKER = "products.json";
|
|
639942
641104
|
var LAST_USED_STAMP = "last-used";
|
|
639943
|
-
function readProductsMarker(keyDir,
|
|
641105
|
+
function readProductsMarker(keyDir, fs29) {
|
|
639944
641106
|
try {
|
|
639945
|
-
const parsed = JSON.parse(String(
|
|
641107
|
+
const parsed = JSON.parse(String(fs29.readFileSync(import_node_path12.default.join(keyDir, PRODUCTS_MARKER))));
|
|
639946
641108
|
if (typeof parsed?.key !== "string" || typeof parsed?.driverVersion !== "string") {
|
|
639947
641109
|
return null;
|
|
639948
641110
|
}
|
|
639949
|
-
if (!
|
|
641111
|
+
if (!fs29.existsSync(import_node_path12.default.join(keyDir, RUNNER_APP_RELATIVE)))
|
|
639950
641112
|
return null;
|
|
639951
641113
|
return parsed;
|
|
639952
641114
|
} catch {
|
|
639953
641115
|
return null;
|
|
639954
641116
|
}
|
|
639955
641117
|
}
|
|
639956
|
-
function touchLastUsed(keyDir,
|
|
641118
|
+
function touchLastUsed(keyDir, fs29, now) {
|
|
639957
641119
|
try {
|
|
639958
|
-
|
|
641120
|
+
fs29.writeFileSync(import_node_path12.default.join(keyDir, LAST_USED_STAMP), String(now()));
|
|
639959
641121
|
} catch {
|
|
639960
641122
|
}
|
|
639961
641123
|
}
|
|
@@ -639977,7 +641139,7 @@ function probeXcodeVersionCached() {
|
|
|
639977
641139
|
return cachedXcodeProbe;
|
|
639978
641140
|
}
|
|
639979
641141
|
function locateManagedWda(options = {}) {
|
|
639980
|
-
const { ctx = {}, fs:
|
|
641142
|
+
const { ctx = {}, fs: fs29 = import_node_fs14.default, platform = process.platform, probeXcode = probeXcodeVersionCached, resolveDriverVersion = resolveHeavyDepVersion, now = Date.now } = options;
|
|
639981
641143
|
try {
|
|
639982
641144
|
if (platform !== "darwin")
|
|
639983
641145
|
return null;
|
|
@@ -639994,10 +641156,10 @@ function locateManagedWda(options = {}) {
|
|
|
639994
641156
|
const wdaRoot = import_node_path12.default.normalize(options.wdaRootDir ?? getWdaRoot(ctx));
|
|
639995
641157
|
const key = computeWdaKey(xcode, driverVersion);
|
|
639996
641158
|
const keyDir = import_node_path12.default.join(wdaRoot, key);
|
|
639997
|
-
const marker = readProductsMarker(keyDir,
|
|
641159
|
+
const marker = readProductsMarker(keyDir, fs29);
|
|
639998
641160
|
if (!marker || marker.key !== key)
|
|
639999
641161
|
return null;
|
|
640000
|
-
touchLastUsed(keyDir,
|
|
641162
|
+
touchLastUsed(keyDir, fs29, now);
|
|
640001
641163
|
return { key, derivedDataPath: import_node_path12.default.join(keyDir, "DerivedData") };
|
|
640002
641164
|
} catch {
|
|
640003
641165
|
return null;
|
|
@@ -640604,9 +641766,9 @@ function hostAbi(arch = process.arch) {
|
|
|
640604
641766
|
}
|
|
640605
641767
|
var JRE_FEATURE_VERSION = "17";
|
|
640606
641768
|
function jreDownloadUrl(platform = process.platform, arch = process.arch) {
|
|
640607
|
-
const
|
|
641769
|
+
const os14 = platform === "win32" ? "windows" : platform === "darwin" ? "mac" : "linux";
|
|
640608
641770
|
const adoptiumArch = arch === "arm64" ? "aarch64" : "x64";
|
|
640609
|
-
return `https://api.adoptium.net/v3/binary/latest/${JRE_FEATURE_VERSION}/ga/${
|
|
641771
|
+
return `https://api.adoptium.net/v3/binary/latest/${JRE_FEATURE_VERSION}/ga/${os14}/${adoptiumArch}/jre/hotspot/normal/eclipse`;
|
|
640610
641772
|
}
|
|
640611
641773
|
function jreArchiveFilename(platform = process.platform) {
|
|
640612
641774
|
return platform === "win32" ? "jre.zip" : "jre.tar.gz";
|
|
@@ -641374,8 +642536,8 @@ async function hostHasKvm() {
|
|
|
641374
642536
|
if (process.platform !== "linux")
|
|
641375
642537
|
return false;
|
|
641376
642538
|
try {
|
|
641377
|
-
const
|
|
641378
|
-
|
|
642539
|
+
const fs29 = await import("node:fs");
|
|
642540
|
+
fs29.accessSync("/dev/kvm", fs29.constants.R_OK | fs29.constants.W_OK);
|
|
641379
642541
|
return true;
|
|
641380
642542
|
} catch {
|
|
641381
642543
|
return false;
|
|
@@ -643304,11 +644466,14 @@ function safeContextId(contextId) {
|
|
|
643304
644466
|
const hash = import_node_crypto6.default.createHash("sha1").update(raw).digest("hex").slice(0, 8);
|
|
643305
644467
|
return `${base}-${hash}`;
|
|
643306
644468
|
}
|
|
644469
|
+
function recordingProcessToken() {
|
|
644470
|
+
return String(process.pid);
|
|
644471
|
+
}
|
|
643307
644472
|
function browserCaptureTitle(contextId) {
|
|
643308
|
-
return `RECORD_ME_${safeContextId(contextId)}`;
|
|
644473
|
+
return `RECORD_ME_${recordingProcessToken()}_${safeContextId(contextId)}`;
|
|
643309
644474
|
}
|
|
643310
644475
|
function browserDownloadDir(contextId) {
|
|
643311
|
-
return import_node_path15.default.join(import_node_os7.default.tmpdir(), "doc-detective", "recordings", safeContextId(contextId));
|
|
644476
|
+
return import_node_path15.default.join(import_node_os7.default.tmpdir(), "doc-detective", "recordings", `${safeContextId(contextId)}-${recordingProcessToken()}`);
|
|
643312
644477
|
}
|
|
643313
644478
|
function engineFields(record) {
|
|
643314
644479
|
const engine = record && typeof record === "object" ? record.engine : void 0;
|
|
@@ -644035,11 +645200,11 @@ function hasUnresolvedMetaReference(expression, context) {
|
|
|
644035
645200
|
}
|
|
644036
645201
|
return false;
|
|
644037
645202
|
}
|
|
644038
|
-
function getMetaValue(
|
|
645203
|
+
function getMetaValue(path28, context) {
|
|
644039
645204
|
if (!context) {
|
|
644040
645205
|
return void 0;
|
|
644041
645206
|
}
|
|
644042
|
-
const [basePath, jsonPointer] =
|
|
645207
|
+
const [basePath, jsonPointer] = path28.split("#");
|
|
644043
645208
|
const resolvedPath = resolvePathTemplateVariables(basePath, context);
|
|
644044
645209
|
let value = getNestedProperty(context, resolvedPath);
|
|
644045
645210
|
if (jsonPointer && value) {
|
|
@@ -644056,9 +645221,9 @@ function getMetaValue(path27, context) {
|
|
|
644056
645221
|
}
|
|
644057
645222
|
return value;
|
|
644058
645223
|
}
|
|
644059
|
-
function resolvePathTemplateVariables(
|
|
645224
|
+
function resolvePathTemplateVariables(path28, context) {
|
|
644060
645225
|
const templateRegex = /\{\{(\w+)\}\}/g;
|
|
644061
|
-
return
|
|
645226
|
+
return path28.replace(templateRegex, (match, varName) => {
|
|
644062
645227
|
if (context && context.id && varName === "id") {
|
|
644063
645228
|
return context.id;
|
|
644064
645229
|
}
|
|
@@ -644095,10 +645260,10 @@ async function resolveEmbeddedExpressions(str, context) {
|
|
|
644095
645260
|
parts.push(str.slice(lastIdx));
|
|
644096
645261
|
return parts.join("");
|
|
644097
645262
|
}
|
|
644098
|
-
function getNestedProperty(obj,
|
|
644099
|
-
if (!obj || !
|
|
645263
|
+
function getNestedProperty(obj, path28) {
|
|
645264
|
+
if (!obj || !path28)
|
|
644100
645265
|
return void 0;
|
|
644101
|
-
const parts =
|
|
645266
|
+
const parts = path28.split(".");
|
|
644102
645267
|
let current = obj;
|
|
644103
645268
|
for (const part of parts) {
|
|
644104
645269
|
if (current === null || current === void 0)
|
|
@@ -646327,7 +647492,7 @@ function aspectRatiosMatch(a, b) {
|
|
|
646327
647492
|
const rb = b.width / b.height;
|
|
646328
647493
|
return Math.abs(ra - rb) / Math.max(ra, rb) <= 0.05;
|
|
646329
647494
|
}
|
|
646330
|
-
async function saveScreenshot({ config, step, driver, appSession }) {
|
|
647495
|
+
async function saveScreenshot({ config, step, driver, appSession, internal }) {
|
|
646331
647496
|
let result = {
|
|
646332
647497
|
status: "PASS",
|
|
646333
647498
|
description: "Saved screenshot.",
|
|
@@ -646483,7 +647648,7 @@ async function saveScreenshot({ config, step, driver, appSession }) {
|
|
|
646483
647648
|
}
|
|
646484
647649
|
} else {
|
|
646485
647650
|
dir = import_node_path17.default.dirname(step.screenshot.path);
|
|
646486
|
-
if (!import_node_fs20.default.existsSync(dir)) {
|
|
647651
|
+
if (!internal?.compareOnly && !import_node_fs20.default.existsSync(dir)) {
|
|
646487
647652
|
import_node_fs20.default.mkdirSync(dir, { recursive: true });
|
|
646488
647653
|
}
|
|
646489
647654
|
if (import_node_fs20.default.existsSync(filePath)) {
|
|
@@ -646695,6 +647860,10 @@ async function saveScreenshot({ config, step, driver, appSession }) {
|
|
|
646695
647860
|
if (!writeFinalPng(filePath))
|
|
646696
647861
|
return result;
|
|
646697
647862
|
}
|
|
647863
|
+
if (internal?.compareOnly) {
|
|
647864
|
+
if (!writeFinalPng(internal.capturePath))
|
|
647865
|
+
return result;
|
|
647866
|
+
}
|
|
646698
647867
|
if (existFilePath) {
|
|
646699
647868
|
if (step.screenshot.overwrite == "true" && !isUrlPath) {
|
|
646700
647869
|
if (!writeFinalPng(existFilePath))
|
|
@@ -646765,7 +647934,7 @@ async function saveScreenshot({ config, step, driver, appSession }) {
|
|
|
646765
647934
|
severity: "warning"
|
|
646766
647935
|
});
|
|
646767
647936
|
if (fractionalDiff > step.screenshot.maxVariation) {
|
|
646768
|
-
if (step.screenshot.overwrite == "aboveVariation" && !isUrlPath) {
|
|
647937
|
+
if (step.screenshot.overwrite == "aboveVariation" && !isUrlPath && !internal?.compareOnly) {
|
|
646769
647938
|
if (!writeFinalPng(existFilePath))
|
|
646770
647939
|
return result;
|
|
646771
647940
|
}
|
|
@@ -646773,6 +647942,8 @@ async function saveScreenshot({ config, step, driver, appSession }) {
|
|
|
646773
647942
|
if (isUrlPath) {
|
|
646774
647943
|
result.outputs.screenshotPath = filePath;
|
|
646775
647944
|
result.outputs.referenceUrl = redactedUrl;
|
|
647945
|
+
} else if (internal?.compareOnly) {
|
|
647946
|
+
result.outputs.screenshotPath = internal.capturePath;
|
|
646776
647947
|
} else {
|
|
646777
647948
|
result.outputs.changed = true;
|
|
646778
647949
|
result.outputs.screenshotPath = existFilePath;
|
|
@@ -646796,25 +647967,248 @@ async function saveScreenshot({ config, step, driver, appSession }) {
|
|
|
646796
647967
|
}
|
|
646797
647968
|
}
|
|
646798
647969
|
if (!result.outputs.screenshotPath) {
|
|
646799
|
-
if (
|
|
646800
|
-
|
|
646801
|
-
|
|
646802
|
-
|
|
646803
|
-
|
|
646804
|
-
|
|
647970
|
+
if (internal?.compareOnly) {
|
|
647971
|
+
result.outputs.screenshotPath = internal.capturePath;
|
|
647972
|
+
result.outputs.baselineMissing = true;
|
|
647973
|
+
} else {
|
|
647974
|
+
if (!writeFinalPng(filePath))
|
|
647975
|
+
return result;
|
|
647976
|
+
result.outputs.screenshotPath = filePath;
|
|
647977
|
+
result.outputs.changed = true;
|
|
647978
|
+
if (step.screenshot.sourceIntegration) {
|
|
647979
|
+
result.outputs.sourceIntegration = step.screenshot.sourceIntegration;
|
|
647980
|
+
}
|
|
646805
647981
|
}
|
|
646806
647982
|
}
|
|
646807
647983
|
return await evaluateApplicable();
|
|
646808
647984
|
}
|
|
646809
647985
|
|
|
647986
|
+
// dist/core/tests/recordingCheckpoints.js
|
|
647987
|
+
var import_node_fs21 = __toESM(require("node:fs"), 1);
|
|
647988
|
+
var import_node_os8 = __toESM(require("node:os"), 1);
|
|
647989
|
+
var import_node_path18 = __toESM(require("node:path"), 1);
|
|
647990
|
+
var import_node_crypto7 = require("node:crypto");
|
|
647991
|
+
init_utils();
|
|
647992
|
+
init_browserStepKeys();
|
|
647993
|
+
function capPathSegment(segment, max = 32) {
|
|
647994
|
+
if (segment.length <= max)
|
|
647995
|
+
return segment;
|
|
647996
|
+
const hash = (0, import_node_crypto7.createHash)("sha1").update(segment).digest("hex").slice(0, 8);
|
|
647997
|
+
const tail = segment.slice(segment.length - (max - hash.length - 1));
|
|
647998
|
+
return `${hash}-${tail}`;
|
|
647999
|
+
}
|
|
648000
|
+
function stepArtifactFileName({ step, stepIndex, stepCount, testId }) {
|
|
648001
|
+
const action = BROWSER_STEP_KEYS.find((key) => typeof step[key] !== "undefined") || "step";
|
|
648002
|
+
const sanitizedTestId = sanitizeFilesystemName(String(testId ?? ""), "test");
|
|
648003
|
+
const stepIdString = sanitizeFilesystemName(String(step.stepId ?? ""), "step");
|
|
648004
|
+
const stepRef = capPathSegment(stepIdString.startsWith(`${sanitizedTestId}~`) ? stepIdString.slice(sanitizedTestId.length + 1) : stepIdString);
|
|
648005
|
+
const pad = Math.max(2, String(stepCount).length);
|
|
648006
|
+
return `${String(stepIndex + 1).padStart(pad, "0")}-${action}-${stepRef}.png`;
|
|
648007
|
+
}
|
|
648008
|
+
function recordingCheckpointsEnabled(record) {
|
|
648009
|
+
if (record?.overwrite === "aboveVariation")
|
|
648010
|
+
return true;
|
|
648011
|
+
return record?.checkpoints !== void 0 && record?.checkpoints !== false;
|
|
648012
|
+
}
|
|
648013
|
+
function resolveCheckpointsConfig({ record, targetPath, handleId }) {
|
|
648014
|
+
let raw = record?.checkpoints;
|
|
648015
|
+
if (record?.overwrite === "aboveVariation" && (raw === void 0 || raw === false)) {
|
|
648016
|
+
raw = true;
|
|
648017
|
+
}
|
|
648018
|
+
if (raw === void 0 || raw === false)
|
|
648019
|
+
return null;
|
|
648020
|
+
const opts = raw === true ? {} : raw;
|
|
648021
|
+
const baselineDir = opts.directory ? import_node_path18.default.resolve(import_node_path18.default.dirname(targetPath), opts.directory) : `${targetPath}.checkpoints`;
|
|
648022
|
+
return {
|
|
648023
|
+
maxVariation: opts.maxVariation ?? 0.05,
|
|
648024
|
+
baselineDir,
|
|
648025
|
+
stagingDir: import_node_path18.default.join(import_node_os8.default.tmpdir(), "doc-detective", "checkpoints", String(handleId)),
|
|
648026
|
+
entries: []
|
|
648027
|
+
};
|
|
648028
|
+
}
|
|
648029
|
+
function computeSpanVerdict({ entries, baselineDir, maxVariation, targetExists }) {
|
|
648030
|
+
const reasons = [];
|
|
648031
|
+
const drifted = entries.filter((e) => typeof e.variation === "number" && e.variation > maxVariation);
|
|
648032
|
+
if (drifted.length > 0) {
|
|
648033
|
+
reasons.push(`${drifted.length} checkpoint(s) drifted beyond maxVariation (${maxVariation}): pixel variation up to ${Math.max(...drifted.map((e) => e.variation)).toFixed(3)}`);
|
|
648034
|
+
}
|
|
648035
|
+
const missing = entries.filter((e) => e.baselineMissing);
|
|
648036
|
+
if (missing.length > 0) {
|
|
648037
|
+
reasons.push(`${missing.length} checkpoint(s) have no baseline (step added or renamed)`);
|
|
648038
|
+
}
|
|
648039
|
+
const errored = entries.filter((e) => e.error);
|
|
648040
|
+
if (errored.length > 0) {
|
|
648041
|
+
reasons.push(`${errored.length} checkpoint(s) couldn't be compared (capture or comparison error)`);
|
|
648042
|
+
}
|
|
648043
|
+
let orphans = [];
|
|
648044
|
+
try {
|
|
648045
|
+
const expected = new Set(entries.map((e) => e.fileName));
|
|
648046
|
+
orphans = import_node_fs21.default.readdirSync(baselineDir).filter((name) => name.endsWith(".png") && !expected.has(name));
|
|
648047
|
+
} catch {
|
|
648048
|
+
}
|
|
648049
|
+
if (orphans.length > 0) {
|
|
648050
|
+
reasons.push(`${orphans.length} baseline(s) have no matching step (step removed or renamed)`);
|
|
648051
|
+
}
|
|
648052
|
+
if (!targetExists) {
|
|
648053
|
+
reasons.push("the recording file is missing");
|
|
648054
|
+
}
|
|
648055
|
+
return { changed: reasons.length > 0, reasons, orphans };
|
|
648056
|
+
}
|
|
648057
|
+
function promoteRecordingSpan({ config, stagingTarget, targetPath, entries, orphans, baselineDir }) {
|
|
648058
|
+
const backupPath = `${targetPath}.promote-backup`;
|
|
648059
|
+
const targetExisted = import_node_fs21.default.existsSync(targetPath);
|
|
648060
|
+
try {
|
|
648061
|
+
import_node_fs21.default.rmSync(backupPath, { force: true });
|
|
648062
|
+
} catch {
|
|
648063
|
+
}
|
|
648064
|
+
try {
|
|
648065
|
+
if (targetExisted)
|
|
648066
|
+
import_node_fs21.default.renameSync(targetPath, backupPath);
|
|
648067
|
+
import_node_fs21.default.renameSync(stagingTarget, targetPath);
|
|
648068
|
+
} catch (error) {
|
|
648069
|
+
log(config, "warning", `Couldn't promote the refreshed recording over ${targetPath}; keeping the existing recording. ${error?.message ?? error}`);
|
|
648070
|
+
try {
|
|
648071
|
+
if (targetExisted && !import_node_fs21.default.existsSync(targetPath)) {
|
|
648072
|
+
import_node_fs21.default.renameSync(backupPath, targetPath);
|
|
648073
|
+
}
|
|
648074
|
+
import_node_fs21.default.rmSync(stagingTarget, { force: true });
|
|
648075
|
+
} catch {
|
|
648076
|
+
}
|
|
648077
|
+
return { videoPromoted: false, seededBaselines: 0, baselineFailures: 0 };
|
|
648078
|
+
}
|
|
648079
|
+
try {
|
|
648080
|
+
import_node_fs21.default.rmSync(backupPath, { force: true });
|
|
648081
|
+
} catch {
|
|
648082
|
+
}
|
|
648083
|
+
try {
|
|
648084
|
+
import_node_fs21.default.mkdirSync(baselineDir, { recursive: true });
|
|
648085
|
+
} catch {
|
|
648086
|
+
}
|
|
648087
|
+
let seededBaselines = 0;
|
|
648088
|
+
let baselineFailures = 0;
|
|
648089
|
+
for (const entry of entries) {
|
|
648090
|
+
if (entry.error)
|
|
648091
|
+
continue;
|
|
648092
|
+
try {
|
|
648093
|
+
const tempPath = `${entry.baselinePath}.tmp`;
|
|
648094
|
+
import_node_fs21.default.copyFileSync(entry.stagingPath, tempPath);
|
|
648095
|
+
import_node_fs21.default.renameSync(tempPath, entry.baselinePath);
|
|
648096
|
+
if (entry.baselineMissing)
|
|
648097
|
+
seededBaselines++;
|
|
648098
|
+
} catch (error) {
|
|
648099
|
+
baselineFailures++;
|
|
648100
|
+
log(config, "warning", `Couldn't update checkpoint baseline ${entry.baselinePath}: ${error?.message ?? error}`);
|
|
648101
|
+
}
|
|
648102
|
+
}
|
|
648103
|
+
for (const orphan of orphans) {
|
|
648104
|
+
try {
|
|
648105
|
+
import_node_fs21.default.unlinkSync(import_node_path18.default.join(baselineDir, orphan));
|
|
648106
|
+
} catch (error) {
|
|
648107
|
+
baselineFailures++;
|
|
648108
|
+
log(config, "warning", `Couldn't remove orphaned checkpoint baseline ${orphan}: ${error?.message ?? error}`);
|
|
648109
|
+
}
|
|
648110
|
+
}
|
|
648111
|
+
return { videoPromoted: true, seededBaselines, baselineFailures };
|
|
648112
|
+
}
|
|
648113
|
+
function buildCheckpointOutputs(entries) {
|
|
648114
|
+
let maxCheckpointVariation = 0;
|
|
648115
|
+
for (const entry of entries) {
|
|
648116
|
+
if (typeof entry.variation === "number") {
|
|
648117
|
+
maxCheckpointVariation = Math.max(maxCheckpointVariation, entry.variation);
|
|
648118
|
+
}
|
|
648119
|
+
}
|
|
648120
|
+
return {
|
|
648121
|
+
checkpoints: entries.map((entry) => ({
|
|
648122
|
+
fileName: entry.fileName,
|
|
648123
|
+
...typeof entry.variation === "number" ? { variation: entry.variation } : {},
|
|
648124
|
+
...entry.baselineMissing ? { baselineMissing: true } : {},
|
|
648125
|
+
...entry.error ? { error: entry.error } : {}
|
|
648126
|
+
})),
|
|
648127
|
+
maxCheckpointVariation,
|
|
648128
|
+
checkpointErrors: entries.filter((entry) => entry.error).length
|
|
648129
|
+
};
|
|
648130
|
+
}
|
|
648131
|
+
async function captureRecordingCheckpoints({ config, driver, recordingHost, step, stepStatus, stepIndex, stepCount, testId, appSession }) {
|
|
648132
|
+
const recordings = recordingHost?.state?.recordings;
|
|
648133
|
+
if (!Array.isArray(recordings) || recordings.length === 0)
|
|
648134
|
+
return;
|
|
648135
|
+
const qualifying = recordings.filter((h) => h?.checkpoints && !h.synthetic);
|
|
648136
|
+
if (qualifying.length === 0)
|
|
648137
|
+
return;
|
|
648138
|
+
if (!driver) {
|
|
648139
|
+
log(config, "debug", "Recording checkpoints skipped: no browser driver in this context.");
|
|
648140
|
+
return;
|
|
648141
|
+
}
|
|
648142
|
+
if (stepStatus === "FAIL") {
|
|
648143
|
+
for (const handle of qualifying) {
|
|
648144
|
+
handle.checkpoints.spanDirty = true;
|
|
648145
|
+
}
|
|
648146
|
+
log(config, "debug", `Recording checkpoint skipped for failed step ${step.stepId}; span marked dirty.`);
|
|
648147
|
+
return;
|
|
648148
|
+
}
|
|
648149
|
+
for (const handle of qualifying) {
|
|
648150
|
+
const checkpoints = handle.checkpoints;
|
|
648151
|
+
const fileName = stepArtifactFileName({
|
|
648152
|
+
step,
|
|
648153
|
+
stepIndex,
|
|
648154
|
+
stepCount,
|
|
648155
|
+
testId
|
|
648156
|
+
});
|
|
648157
|
+
const entry = {
|
|
648158
|
+
fileName,
|
|
648159
|
+
stagingPath: import_node_path18.default.join(checkpoints.stagingDir, fileName),
|
|
648160
|
+
baselinePath: import_node_path18.default.join(checkpoints.baselineDir, fileName)
|
|
648161
|
+
};
|
|
648162
|
+
try {
|
|
648163
|
+
import_node_fs21.default.mkdirSync(checkpoints.stagingDir, { recursive: true });
|
|
648164
|
+
const screenshotStep = {
|
|
648165
|
+
stepId: `${step.stepId}_checkpoint`,
|
|
648166
|
+
description: "Recording checkpoint screenshot",
|
|
648167
|
+
screenshot: {
|
|
648168
|
+
path: entry.baselinePath,
|
|
648169
|
+
maxVariation: checkpoints.maxVariation,
|
|
648170
|
+
overwrite: "aboveVariation"
|
|
648171
|
+
}
|
|
648172
|
+
};
|
|
648173
|
+
const captureResult = await saveScreenshot({
|
|
648174
|
+
config,
|
|
648175
|
+
step: screenshotStep,
|
|
648176
|
+
driver,
|
|
648177
|
+
appSession,
|
|
648178
|
+
internal: { compareOnly: true, capturePath: entry.stagingPath }
|
|
648179
|
+
});
|
|
648180
|
+
if (captureResult.status !== "PASS" && captureResult.status !== "WARNING") {
|
|
648181
|
+
entry.error = captureResult.description;
|
|
648182
|
+
log(config, "warning", `Recording checkpoint failed after step ${step.stepId}: ${captureResult.description}`);
|
|
648183
|
+
} else {
|
|
648184
|
+
if (typeof captureResult.outputs?.variation === "number") {
|
|
648185
|
+
entry.variation = captureResult.outputs.variation;
|
|
648186
|
+
}
|
|
648187
|
+
if (captureResult.outputs?.baselineMissing) {
|
|
648188
|
+
entry.baselineMissing = true;
|
|
648189
|
+
}
|
|
648190
|
+
}
|
|
648191
|
+
} catch (error) {
|
|
648192
|
+
entry.error = String(error?.message ?? error);
|
|
648193
|
+
log(config, "warning", `Recording checkpoint failed after step ${step.stepId}: ${entry.error}`);
|
|
648194
|
+
}
|
|
648195
|
+
const existingIndex = checkpoints.entries.findIndex((e) => e.fileName === fileName);
|
|
648196
|
+
if (existingIndex >= 0) {
|
|
648197
|
+
checkpoints.entries[existingIndex] = entry;
|
|
648198
|
+
} else {
|
|
648199
|
+
checkpoints.entries.push(entry);
|
|
648200
|
+
}
|
|
648201
|
+
}
|
|
648202
|
+
}
|
|
648203
|
+
|
|
646810
648204
|
// dist/core/tests/startRecording.js
|
|
646811
648205
|
init_validate();
|
|
646812
648206
|
init_utils();
|
|
646813
648207
|
var import_node_child_process12 = require("node:child_process");
|
|
646814
|
-
var
|
|
646815
|
-
var
|
|
646816
|
-
var
|
|
646817
|
-
var
|
|
648208
|
+
var import_node_crypto8 = require("node:crypto");
|
|
648209
|
+
var import_node_path19 = __toESM(require("node:path"), 1);
|
|
648210
|
+
var import_node_fs22 = __toESM(require("node:fs"), 1);
|
|
648211
|
+
var import_node_os9 = __toESM(require("node:os"), 1);
|
|
646818
648212
|
async function startRecording({ config, context, step, driver, recordingHost, appSession, deps = {} }) {
|
|
646819
648213
|
let result = {
|
|
646820
648214
|
status: "PASS",
|
|
@@ -646882,7 +648276,7 @@ async function startRecording({ config, context, step, driver, recordingHost, ap
|
|
|
646882
648276
|
if (typeof step.record.path === "undefined") {
|
|
646883
648277
|
step.record.path = `${step.stepId}.mp4`;
|
|
646884
648278
|
if (step.record.directory) {
|
|
646885
|
-
step.record.path =
|
|
648279
|
+
step.record.path = import_node_path19.default.resolve(step.record.directory, step.record.path);
|
|
646886
648280
|
}
|
|
646887
648281
|
}
|
|
646888
648282
|
step.record = {
|
|
@@ -646890,18 +648284,26 @@ async function startRecording({ config, context, step, driver, recordingHost, ap
|
|
|
646890
648284
|
overwrite: step.record.overwrite || "false"
|
|
646891
648285
|
};
|
|
646892
648286
|
let filePath = step.record.path;
|
|
646893
|
-
const baseName =
|
|
646894
|
-
const dir =
|
|
646895
|
-
if (!
|
|
646896
|
-
|
|
648287
|
+
const baseName = import_node_path19.default.basename(filePath, import_node_path19.default.extname(filePath));
|
|
648288
|
+
const dir = import_node_path19.default.dirname(step.record.path);
|
|
648289
|
+
if (!import_node_fs22.default.existsSync(dir)) {
|
|
648290
|
+
import_node_fs22.default.mkdirSync(dir, { recursive: true });
|
|
646897
648291
|
}
|
|
646898
|
-
|
|
648292
|
+
const phantomRecordingResult = (skipDescription, skipReason = "headless") => {
|
|
646899
648293
|
result.status = "SKIPPED";
|
|
646900
|
-
|
|
648294
|
+
if (recordingCheckpointsEnabled(step.record)) {
|
|
648295
|
+
result.description = `${skipDescription} Running checkpoint comparisons only, to detect whether the recording is stale.`;
|
|
648296
|
+
result.recording = { type: "phantom", targetPath: filePath, skipReason };
|
|
648297
|
+
} else {
|
|
648298
|
+
result.description = skipDescription;
|
|
648299
|
+
}
|
|
646901
648300
|
return result;
|
|
648301
|
+
};
|
|
648302
|
+
if (import_node_fs22.default.existsSync(filePath) && step.record.overwrite == "false") {
|
|
648303
|
+
return phantomRecordingResult(`File already exists: ${filePath}`, "targetExists");
|
|
646902
648304
|
}
|
|
646903
648305
|
const normalizeActiveTarget = (p) => {
|
|
646904
|
-
const resolved =
|
|
648306
|
+
const resolved = import_node_path19.default.resolve(p);
|
|
646905
648307
|
return process.platform === "win32" || process.platform === "darwin" ? resolved.toLowerCase() : resolved;
|
|
646906
648308
|
};
|
|
646907
648309
|
const normalizedTarget = normalizeActiveTarget(filePath);
|
|
@@ -646978,9 +648380,7 @@ async function startRecording({ config, context, step, driver, recordingHost, ap
|
|
|
646978
648380
|
}
|
|
646979
648381
|
if (plan.name === "browser") {
|
|
646980
648382
|
if (context.browser?.headless) {
|
|
646981
|
-
|
|
646982
|
-
result.description = `Recording isn't supported in headless mode with the browser engine. Use the ffmpeg engine to record headless.`;
|
|
646983
|
-
return result;
|
|
648383
|
+
return phantomRecordingResult(`Recording isn't supported in headless mode with the browser engine. Use the ffmpeg engine to record headless.`);
|
|
646984
648384
|
}
|
|
646985
648385
|
if (context.browser?.name !== "chrome") {
|
|
646986
648386
|
result.status = "SKIPPED";
|
|
@@ -646989,13 +648389,13 @@ async function startRecording({ config, context, step, driver, recordingHost, ap
|
|
|
646989
648389
|
}
|
|
646990
648390
|
const captureTitle = browserCaptureTitle(context.contextId);
|
|
646991
648391
|
const downloadDir = browserDownloadDir(context.contextId);
|
|
646992
|
-
if (!
|
|
646993
|
-
|
|
648392
|
+
if (!import_node_fs22.default.existsSync(downloadDir)) {
|
|
648393
|
+
import_node_fs22.default.mkdirSync(downloadDir, { recursive: true });
|
|
646994
648394
|
}
|
|
646995
|
-
const downloadPath =
|
|
646996
|
-
if (
|
|
648395
|
+
const downloadPath = import_node_path19.default.join(downloadDir, `${baseName}.webm`);
|
|
648396
|
+
if (import_node_fs22.default.existsSync(downloadPath)) {
|
|
646997
648397
|
try {
|
|
646998
|
-
|
|
648398
|
+
import_node_fs22.default.unlinkSync(downloadPath);
|
|
646999
648399
|
} catch {
|
|
647000
648400
|
}
|
|
647001
648401
|
}
|
|
@@ -647107,9 +648507,7 @@ async function startRecording({ config, context, step, driver, recordingHost, ap
|
|
|
647107
648507
|
return result;
|
|
647108
648508
|
}
|
|
647109
648509
|
if (!appRef && context.browser?.headless && !context.__display) {
|
|
647110
|
-
|
|
647111
|
-
result.description = `Recording isn't supported in headless mode without a virtual display (Xvfb).`;
|
|
647112
|
-
return result;
|
|
648510
|
+
return phantomRecordingResult(`Recording isn't supported in headless mode without a virtual display (Xvfb).`);
|
|
647113
648511
|
}
|
|
647114
648512
|
let crop = null;
|
|
647115
648513
|
let appCropRect = null;
|
|
@@ -647135,10 +648533,10 @@ async function startRecording({ config, context, step, driver, recordingHost, ap
|
|
|
647135
648533
|
} catch {
|
|
647136
648534
|
}
|
|
647137
648535
|
}
|
|
647138
|
-
const tempDir =
|
|
647139
|
-
if (!
|
|
647140
|
-
|
|
647141
|
-
const tempPath =
|
|
648536
|
+
const tempDir = import_node_path19.default.join(import_node_os9.default.tmpdir(), "doc-detective", "recordings");
|
|
648537
|
+
if (!import_node_fs22.default.existsSync(tempDir))
|
|
648538
|
+
import_node_fs22.default.mkdirSync(tempDir, { recursive: true });
|
|
648539
|
+
const tempPath = import_node_path19.default.join(tempDir, `${safeContextId(context.contextId)}-${baseName}-${(0, import_node_crypto8.randomUUID)().slice(0, 8)}.mkv`);
|
|
647142
648540
|
let ffmpegPath;
|
|
647143
648541
|
try {
|
|
647144
648542
|
ffmpegPath = await (deps.getFfmpegPath ?? getFfmpegPath)({
|
|
@@ -647209,10 +648607,10 @@ async function startRecording({ config, context, step, driver, recordingHost, ap
|
|
|
647209
648607
|
init_validate();
|
|
647210
648608
|
init_utils();
|
|
647211
648609
|
var import_node_child_process13 = require("node:child_process");
|
|
647212
|
-
var
|
|
647213
|
-
var
|
|
647214
|
-
var
|
|
647215
|
-
var
|
|
648610
|
+
var import_node_crypto9 = require("node:crypto");
|
|
648611
|
+
var import_node_path20 = __toESM(require("node:path"), 1);
|
|
648612
|
+
var import_node_fs23 = __toESM(require("node:fs"), 1);
|
|
648613
|
+
var import_node_os10 = __toESM(require("node:os"), 1);
|
|
647216
648614
|
async function stopRecording({ config, step, driver, deps = {} }) {
|
|
647217
648615
|
let result = {
|
|
647218
648616
|
status: "PASS",
|
|
@@ -647266,8 +648664,49 @@ async function stopRecording({ config, step, driver, deps = {} }) {
|
|
|
647266
648664
|
if (idx !== -1)
|
|
647267
648665
|
recordings.splice(idx, 1);
|
|
647268
648666
|
};
|
|
648667
|
+
const discardCheckpointStaging = () => {
|
|
648668
|
+
const dir = recording?.checkpoints?.stagingDir;
|
|
648669
|
+
if (!dir)
|
|
648670
|
+
return;
|
|
648671
|
+
try {
|
|
648672
|
+
import_node_fs23.default.rmSync(dir, { recursive: true, force: true });
|
|
648673
|
+
} catch {
|
|
648674
|
+
}
|
|
648675
|
+
};
|
|
648676
|
+
if (recording.type === "phantom") {
|
|
648677
|
+
dropHandle();
|
|
648678
|
+
const phantomCheckpoints = recording.checkpoints;
|
|
648679
|
+
const entries = phantomCheckpoints?.entries ?? [];
|
|
648680
|
+
discardCheckpointStaging();
|
|
648681
|
+
const skipCause = recording.skipReason === "targetExists" ? `Recording skipped (the target already exists)` : `Recording skipped (headless)`;
|
|
648682
|
+
const refreshRemedy = recording.skipReason === "targetExists" ? `Delete it, or set \`overwrite\` to "true" or "aboveVariation", to refresh it.` : `Recording is skipped in headless mode; re-run headed to refresh it.`;
|
|
648683
|
+
if (phantomCheckpoints?.spanDirty || entries.length === 0) {
|
|
648684
|
+
result.status = "SKIPPED";
|
|
648685
|
+
result.description = `${skipCause}; the span didn't produce a complete checkpoint set, so staleness couldn't be determined.`;
|
|
648686
|
+
return result;
|
|
648687
|
+
}
|
|
648688
|
+
const verdict = computeSpanVerdict({
|
|
648689
|
+
entries,
|
|
648690
|
+
baselineDir: phantomCheckpoints?.baselineDir ?? "",
|
|
648691
|
+
maxVariation: phantomCheckpoints?.maxVariation ?? 0.05,
|
|
648692
|
+
targetExists: import_node_fs23.default.existsSync(recording.targetPath)
|
|
648693
|
+
});
|
|
648694
|
+
result.outputs = {
|
|
648695
|
+
stale: verdict.changed,
|
|
648696
|
+
...buildCheckpointOutputs(entries)
|
|
648697
|
+
};
|
|
648698
|
+
if (verdict.changed) {
|
|
648699
|
+
result.status = "WARNING";
|
|
648700
|
+
result.description = `The recording at ${recording.targetPath} appears stale \u2014 ${verdict.reasons.join("; ")}. ${refreshRemedy}`;
|
|
648701
|
+
} else {
|
|
648702
|
+
result.status = "SKIPPED";
|
|
648703
|
+
result.description = `${skipCause}; checkpoints match their baselines, so the recording appears current.`;
|
|
648704
|
+
}
|
|
648705
|
+
return result;
|
|
648706
|
+
}
|
|
647269
648707
|
if (recording.type === "appium-pending") {
|
|
647270
648708
|
dropHandle();
|
|
648709
|
+
discardCheckpointStaging();
|
|
647271
648710
|
if (recording.startError) {
|
|
647272
648711
|
result.status = recording.startSkip ? "SKIPPED" : "FAIL";
|
|
647273
648712
|
result.description = recording.startError;
|
|
@@ -647277,6 +648716,9 @@ async function stopRecording({ config, step, driver, deps = {} }) {
|
|
|
647277
648716
|
result.description = "The device recording never started (no app surface opened a device session), so there is nothing to save.";
|
|
647278
648717
|
return result;
|
|
647279
648718
|
}
|
|
648719
|
+
const isAboveVariation = recording.overwrite === "aboveVariation";
|
|
648720
|
+
const finalTargetPath = recording.targetPath;
|
|
648721
|
+
const writeTargetPath = isAboveVariation ? import_node_path20.default.join(import_node_path20.default.dirname(finalTargetPath), `.${import_node_path20.default.basename(finalTargetPath, import_node_path20.default.extname(finalTargetPath))}.staging${import_node_path20.default.extname(finalTargetPath)}`) : finalTargetPath;
|
|
647280
648722
|
try {
|
|
647281
648723
|
if (recording.type === "MediaRecorder") {
|
|
647282
648724
|
let returnTab = null;
|
|
@@ -647303,6 +648745,7 @@ async function stopRecording({ config, step, driver, deps = {} }) {
|
|
|
647303
648745
|
result.description = "Recording was not properly started. The recorder object doesn't exist in the browser context.";
|
|
647304
648746
|
await closeRecorderTabAndRestoreFocus();
|
|
647305
648747
|
dropHandle();
|
|
648748
|
+
discardCheckpointStaging();
|
|
647306
648749
|
return result;
|
|
647307
648750
|
}
|
|
647308
648751
|
await driver.execute(() => {
|
|
@@ -647314,13 +648757,14 @@ async function stopRecording({ config, step, driver, deps = {} }) {
|
|
|
647314
648757
|
result.description = "Recording download timed out.";
|
|
647315
648758
|
await closeRecorderTabAndRestoreFocus();
|
|
647316
648759
|
dropHandle();
|
|
648760
|
+
discardCheckpointStaging();
|
|
647317
648761
|
return result;
|
|
647318
648762
|
}
|
|
647319
648763
|
await closeRecorderTabAndRestoreFocus();
|
|
647320
648764
|
await transcode({
|
|
647321
648765
|
config,
|
|
647322
648766
|
sourcePath: recording.downloadPath,
|
|
647323
|
-
targetPath:
|
|
648767
|
+
targetPath: writeTargetPath,
|
|
647324
648768
|
deleteSource: true
|
|
647325
648769
|
});
|
|
647326
648770
|
dropHandle();
|
|
@@ -647378,7 +648822,7 @@ async function stopRecording({ config, step, driver, deps = {} }) {
|
|
|
647378
648822
|
await transcode({
|
|
647379
648823
|
config,
|
|
647380
648824
|
sourcePath: recording.tempPath,
|
|
647381
|
-
targetPath:
|
|
648825
|
+
targetPath: writeTargetPath,
|
|
647382
648826
|
deleteSource: true,
|
|
647383
648827
|
crop
|
|
647384
648828
|
});
|
|
@@ -647389,6 +648833,7 @@ async function stopRecording({ config, step, driver, deps = {} }) {
|
|
|
647389
648833
|
result.status = "FAIL";
|
|
647390
648834
|
result.description = "The device recording returned no data; nothing was saved.";
|
|
647391
648835
|
dropHandle();
|
|
648836
|
+
discardCheckpointStaging();
|
|
647392
648837
|
return result;
|
|
647393
648838
|
}
|
|
647394
648839
|
let buffer;
|
|
@@ -647398,26 +648843,28 @@ async function stopRecording({ config, step, driver, deps = {} }) {
|
|
|
647398
648843
|
result.status = "FAIL";
|
|
647399
648844
|
result.description = `Couldn't buffer the device recording (${Math.round(b64.length / 1024 / 1024)} MB base64) \u2014 device recordings transfer in one payload, so long recordings can exhaust memory. Keep device recordings short (they cap at 30 minutes). ${error?.message ?? error}`;
|
|
647400
648845
|
dropHandle();
|
|
648846
|
+
discardCheckpointStaging();
|
|
647401
648847
|
return result;
|
|
647402
648848
|
}
|
|
647403
648849
|
if (buffer.length === 0) {
|
|
647404
648850
|
result.status = "FAIL";
|
|
647405
648851
|
result.description = "The device recording decoded to an empty payload (no data); nothing was saved.";
|
|
647406
648852
|
dropHandle();
|
|
648853
|
+
discardCheckpointStaging();
|
|
647407
648854
|
return result;
|
|
647408
648855
|
}
|
|
647409
|
-
if (
|
|
647410
|
-
|
|
648856
|
+
if (import_node_path20.default.extname(writeTargetPath) === ".mp4") {
|
|
648857
|
+
import_node_fs23.default.writeFileSync(writeTargetPath, buffer);
|
|
647411
648858
|
} else {
|
|
647412
|
-
const tempDir =
|
|
647413
|
-
if (!
|
|
647414
|
-
|
|
647415
|
-
const tempPath =
|
|
647416
|
-
|
|
648859
|
+
const tempDir = import_node_path20.default.join(import_node_os10.default.tmpdir(), "doc-detective", "recordings");
|
|
648860
|
+
if (!import_node_fs23.default.existsSync(tempDir))
|
|
648861
|
+
import_node_fs23.default.mkdirSync(tempDir, { recursive: true });
|
|
648862
|
+
const tempPath = import_node_path20.default.join(tempDir, `device-${(0, import_node_crypto9.randomUUID)().slice(0, 8)}.mp4`);
|
|
648863
|
+
import_node_fs23.default.writeFileSync(tempPath, buffer);
|
|
647417
648864
|
await transcode({
|
|
647418
648865
|
config,
|
|
647419
648866
|
sourcePath: tempPath,
|
|
647420
|
-
targetPath:
|
|
648867
|
+
targetPath: writeTargetPath,
|
|
647421
648868
|
deleteSource: true
|
|
647422
648869
|
});
|
|
647423
648870
|
}
|
|
@@ -647427,15 +648874,100 @@ async function stopRecording({ config, step, driver, deps = {} }) {
|
|
|
647427
648874
|
result.status = "FAIL";
|
|
647428
648875
|
result.description = `Couldn't stop recording. ${error}`;
|
|
647429
648876
|
dropHandle();
|
|
648877
|
+
discardCheckpointStaging();
|
|
648878
|
+
if (isAboveVariation) {
|
|
648879
|
+
try {
|
|
648880
|
+
import_node_fs23.default.rmSync(writeTargetPath, { force: true });
|
|
648881
|
+
} catch {
|
|
648882
|
+
}
|
|
648883
|
+
}
|
|
647430
648884
|
return result;
|
|
647431
648885
|
}
|
|
647432
|
-
|
|
647433
|
-
|
|
647434
|
-
|
|
647435
|
-
|
|
648886
|
+
const checkpoints = recording.checkpoints;
|
|
648887
|
+
let seededBaselines = 0;
|
|
648888
|
+
let promoteFailed = false;
|
|
648889
|
+
let baselineFailures = 0;
|
|
648890
|
+
result.outputs = {};
|
|
648891
|
+
if (isAboveVariation) {
|
|
648892
|
+
const entries = checkpoints?.entries ?? [];
|
|
648893
|
+
const targetExists = import_node_fs23.default.existsSync(finalTargetPath);
|
|
648894
|
+
const discardStagedVideo = () => {
|
|
648895
|
+
try {
|
|
648896
|
+
import_node_fs23.default.rmSync(writeTargetPath, { force: true });
|
|
648897
|
+
} catch {
|
|
648898
|
+
}
|
|
648899
|
+
};
|
|
648900
|
+
const indeterminate = checkpoints?.spanDirty || entries.length === 0;
|
|
648901
|
+
if (indeterminate && targetExists) {
|
|
648902
|
+
discardStagedVideo();
|
|
648903
|
+
result.outputs.changed = false;
|
|
648904
|
+
log(config, "warning", checkpoints?.spanDirty ? `Recording kept unchanged (${finalTargetPath}): a step failed during the span, so drift couldn't be judged.` : `Recording kept unchanged (${finalTargetPath}): no checkpoints were captured this run, so drift couldn't be judged.`);
|
|
648905
|
+
} else if (indeterminate) {
|
|
648906
|
+
const promoted = promoteRecordingSpan({
|
|
648907
|
+
config,
|
|
648908
|
+
stagingTarget: writeTargetPath,
|
|
648909
|
+
targetPath: finalTargetPath,
|
|
648910
|
+
entries,
|
|
648911
|
+
orphans: [],
|
|
648912
|
+
baselineDir: checkpoints?.baselineDir ?? ""
|
|
648913
|
+
});
|
|
648914
|
+
seededBaselines = promoted.seededBaselines;
|
|
648915
|
+
result.outputs.changed = promoted.videoPromoted;
|
|
648916
|
+
promoteFailed = !promoted.videoPromoted;
|
|
648917
|
+
baselineFailures = promoted.baselineFailures;
|
|
648918
|
+
if (promoted.videoPromoted) {
|
|
648919
|
+
result.outputs.changeReasons = ["the recording file is missing"];
|
|
648920
|
+
}
|
|
648921
|
+
} else {
|
|
648922
|
+
const verdict = computeSpanVerdict({
|
|
648923
|
+
entries,
|
|
648924
|
+
baselineDir: checkpoints?.baselineDir ?? "",
|
|
648925
|
+
maxVariation: checkpoints?.maxVariation ?? 0.05,
|
|
648926
|
+
targetExists
|
|
648927
|
+
});
|
|
648928
|
+
if (verdict.changed) {
|
|
648929
|
+
const promoted = promoteRecordingSpan({
|
|
648930
|
+
config,
|
|
648931
|
+
stagingTarget: writeTargetPath,
|
|
648932
|
+
targetPath: finalTargetPath,
|
|
648933
|
+
entries,
|
|
648934
|
+
orphans: verdict.orphans,
|
|
648935
|
+
baselineDir: checkpoints?.baselineDir ?? ""
|
|
648936
|
+
});
|
|
648937
|
+
seededBaselines = promoted.seededBaselines;
|
|
648938
|
+
result.outputs.changed = promoted.videoPromoted;
|
|
648939
|
+
promoteFailed = !promoted.videoPromoted;
|
|
648940
|
+
baselineFailures = promoted.baselineFailures;
|
|
648941
|
+
if (promoted.videoPromoted) {
|
|
648942
|
+
result.outputs.changeReasons = verdict.reasons;
|
|
648943
|
+
log(config, "info", `Recording refreshed (${finalTargetPath}): ${verdict.reasons.join("; ")}`);
|
|
648944
|
+
}
|
|
648945
|
+
} else {
|
|
648946
|
+
discardStagedVideo();
|
|
648947
|
+
result.outputs.changed = false;
|
|
648948
|
+
}
|
|
648949
|
+
}
|
|
648950
|
+
} else if (checkpoints?.entries?.length) {
|
|
648951
|
+
for (const entry of checkpoints.entries) {
|
|
648952
|
+
if (checkpoints.spanDirty)
|
|
648953
|
+
break;
|
|
648954
|
+
if (entry.baselineMissing && !entry.error) {
|
|
648955
|
+
try {
|
|
648956
|
+
import_node_fs23.default.mkdirSync(checkpoints.baselineDir, { recursive: true });
|
|
648957
|
+
import_node_fs23.default.copyFileSync(entry.stagingPath, entry.baselinePath, import_node_fs23.default.constants.COPYFILE_EXCL);
|
|
648958
|
+
seededBaselines++;
|
|
648959
|
+
} catch (error) {
|
|
648960
|
+
entry.error = error?.code === "EEXIST" ? `A baseline appeared at ${entry.baselinePath} after this checkpoint was captured; left it untouched.` : String(error?.message ?? error);
|
|
648961
|
+
log(config, "warning", `Couldn't seed checkpoint baseline ${entry.baselinePath}: ${entry.error}`);
|
|
648962
|
+
}
|
|
648963
|
+
}
|
|
648964
|
+
}
|
|
648965
|
+
}
|
|
648966
|
+
result.outputs.recordingPath = import_node_path20.default.resolve(finalTargetPath);
|
|
648967
|
+
result.outputs.format = import_node_path20.default.extname(finalTargetPath).slice(1);
|
|
647436
648968
|
const meta = await probeVideoMetadata({
|
|
647437
648969
|
cacheDir: config?.cacheDir,
|
|
647438
|
-
filePath:
|
|
648970
|
+
filePath: finalTargetPath
|
|
647439
648971
|
});
|
|
647440
648972
|
if (meta?.duration !== void 0)
|
|
647441
648973
|
result.outputs.duration = meta.duration;
|
|
@@ -647446,7 +648978,45 @@ async function stopRecording({ config, step, driver, deps = {} }) {
|
|
|
647446
648978
|
if (meta?.fps !== void 0)
|
|
647447
648979
|
result.outputs.fps = meta.fps;
|
|
647448
648980
|
if (!meta || Object.keys(meta).length === 0) {
|
|
647449
|
-
log(config, "debug", `Couldn't probe recording metadata for ${
|
|
648981
|
+
log(config, "debug", `Couldn't probe recording metadata for ${finalTargetPath}.`);
|
|
648982
|
+
}
|
|
648983
|
+
if (checkpoints?.entries?.length) {
|
|
648984
|
+
Object.assign(result.outputs, buildCheckpointOutputs(checkpoints.entries));
|
|
648985
|
+
result.outputs.seededBaselines = seededBaselines;
|
|
648986
|
+
const ctx = buildConditionContext({ outputs: result.outputs });
|
|
648987
|
+
const { assertions, status } = await evaluateImplicitAssertions([
|
|
648988
|
+
{
|
|
648989
|
+
statement: `$$outputs.maxCheckpointVariation <= ${checkpoints.maxVariation}`,
|
|
648990
|
+
severity: "warning"
|
|
648991
|
+
},
|
|
648992
|
+
{
|
|
648993
|
+
statement: `$$outputs.checkpointErrors == 0`,
|
|
648994
|
+
severity: "warning"
|
|
648995
|
+
}
|
|
648996
|
+
], ctx);
|
|
648997
|
+
result.assertions = assertions;
|
|
648998
|
+
result.status = status;
|
|
648999
|
+
if (status === "WARNING") {
|
|
649000
|
+
result.description += !isAboveVariation ? ` One or more checkpoints drifted beyond maxVariation (${checkpoints.maxVariation}) or couldn't be compared \u2014 the recorded flow's content may have changed since its baselines were captured.` : result.outputs.changed ? ` One or more checkpoints drifted beyond maxVariation (${checkpoints.maxVariation}) or couldn't be compared \u2014 the recording was refreshed to match the current content.` : ` One or more checkpoints drifted beyond maxVariation (${checkpoints.maxVariation}) or couldn't be compared \u2014 the existing recording was kept.`;
|
|
649001
|
+
}
|
|
649002
|
+
if (baselineFailures > 0) {
|
|
649003
|
+
result.outputs.baselineFailures = baselineFailures;
|
|
649004
|
+
}
|
|
649005
|
+
try {
|
|
649006
|
+
import_node_fs23.default.rmSync(checkpoints.stagingDir, { recursive: true, force: true });
|
|
649007
|
+
} catch {
|
|
649008
|
+
}
|
|
649009
|
+
}
|
|
649010
|
+
if (promoteFailed) {
|
|
649011
|
+
if (!import_node_fs23.default.existsSync(finalTargetPath)) {
|
|
649012
|
+
result.status = "FAIL";
|
|
649013
|
+
result.description = `Couldn't save the recording to ${finalTargetPath}: promoting the captured video failed and no previous recording exists at that path.`;
|
|
649014
|
+
delete result.outputs.recordingPath;
|
|
649015
|
+
delete result.outputs.format;
|
|
649016
|
+
} else {
|
|
649017
|
+
result.status = "WARNING";
|
|
649018
|
+
result.description += ` The captured video couldn't replace ${finalTargetPath}, so the existing (now stale) recording was kept.`;
|
|
649019
|
+
}
|
|
647450
649020
|
}
|
|
647451
649021
|
return result;
|
|
647452
649022
|
}
|
|
@@ -647460,7 +649030,7 @@ async function transcode({ config, sourcePath, targetPath, deleteSource, crop })
|
|
|
647460
649030
|
const cy = `max(0\\,min(${crop.y}\\,ih-${ch}))`;
|
|
647461
649031
|
filters.push(`crop=w=${cw}:h=${ch}:x=${cx}:y=${cy}`);
|
|
647462
649032
|
}
|
|
647463
|
-
if (
|
|
649033
|
+
if (import_node_path20.default.extname(targetPath) === ".gif") {
|
|
647464
649034
|
filters.push("scale=iw:-1:flags=lanczos");
|
|
647465
649035
|
}
|
|
647466
649036
|
if (filters.length > 0) {
|
|
@@ -647478,7 +649048,7 @@ async function transcode({ config, sourcePath, targetPath, deleteSource, crop })
|
|
|
647478
649048
|
if (code === 0) {
|
|
647479
649049
|
if (deleteSource && sourcePath !== targetPath) {
|
|
647480
649050
|
try {
|
|
647481
|
-
|
|
649051
|
+
import_node_fs23.default.unlinkSync(sourcePath);
|
|
647482
649052
|
} catch {
|
|
647483
649053
|
}
|
|
647484
649054
|
}
|
|
@@ -647497,7 +649067,7 @@ async function waitForStableFile(filePath, maxSeconds) {
|
|
|
647497
649067
|
for (let i = 0; i < deadline; i++) {
|
|
647498
649068
|
let size = -1;
|
|
647499
649069
|
try {
|
|
647500
|
-
size =
|
|
649070
|
+
size = import_node_fs23.default.statSync(filePath).size;
|
|
647501
649071
|
} catch {
|
|
647502
649072
|
size = -1;
|
|
647503
649073
|
}
|
|
@@ -647537,8 +649107,8 @@ async function loadVariables({ step }) {
|
|
|
647537
649107
|
// dist/core/tests/saveCookie.js
|
|
647538
649108
|
init_validate();
|
|
647539
649109
|
init_utils();
|
|
647540
|
-
var
|
|
647541
|
-
var
|
|
649110
|
+
var import_node_path21 = __toESM(require("node:path"), 1);
|
|
649111
|
+
var import_node_fs24 = __toESM(require("node:fs"), 1);
|
|
647542
649112
|
async function saveCookie({ config, step, driver }) {
|
|
647543
649113
|
let result = {
|
|
647544
649114
|
status: "PASS",
|
|
@@ -647555,7 +649125,7 @@ async function saveCookie({ config, step, driver }) {
|
|
|
647555
649125
|
let cookieName, filePath, directory, overwrite, domain, variable;
|
|
647556
649126
|
if (typeof step.saveCookie === "string") {
|
|
647557
649127
|
if (step.saveCookie.endsWith(".txt")) {
|
|
647558
|
-
cookieName =
|
|
649128
|
+
cookieName = import_node_path21.default.basename(step.saveCookie, ".txt");
|
|
647559
649129
|
filePath = step.saveCookie;
|
|
647560
649130
|
} else {
|
|
647561
649131
|
cookieName = step.saveCookie;
|
|
@@ -647604,15 +649174,15 @@ async function saveCookie({ config, step, driver }) {
|
|
|
647604
649174
|
}
|
|
647605
649175
|
if (filePath) {
|
|
647606
649176
|
const outputDirectory = directory || config.output || process.cwd();
|
|
647607
|
-
const fullPath =
|
|
647608
|
-
if (
|
|
649177
|
+
const fullPath = import_node_path21.default.resolve(outputDirectory, filePath);
|
|
649178
|
+
if (import_node_fs24.default.existsSync(fullPath) && !(overwrite === true || overwrite === "true")) {
|
|
647609
649179
|
result.status = "FAIL";
|
|
647610
649180
|
result.description = `File '${fullPath}' already exists and overwrite is not enabled.`;
|
|
647611
649181
|
return result;
|
|
647612
649182
|
}
|
|
647613
|
-
const dir =
|
|
647614
|
-
if (!
|
|
647615
|
-
|
|
649183
|
+
const dir = import_node_path21.default.dirname(fullPath);
|
|
649184
|
+
if (!import_node_fs24.default.existsSync(dir)) {
|
|
649185
|
+
import_node_fs24.default.mkdirSync(dir, { recursive: true });
|
|
647616
649186
|
}
|
|
647617
649187
|
if (targetCookie) {
|
|
647618
649188
|
const netscapeCookie = formatCookieForNetscape(targetCookie);
|
|
@@ -647620,11 +649190,11 @@ async function saveCookie({ config, step, driver }) {
|
|
|
647620
649190
|
# This is a cookie file saved by Doc Detective
|
|
647621
649191
|
${netscapeCookie}
|
|
647622
649192
|
`;
|
|
647623
|
-
|
|
649193
|
+
import_node_fs24.default.writeFileSync(fullPath, content, "utf8");
|
|
647624
649194
|
result.description = `Saved cookie '${cookieName}' to '${fullPath}'.`;
|
|
647625
649195
|
log(config, "debug", `Saved cookie '${cookieName}' to file: ${fullPath}`);
|
|
647626
649196
|
} else {
|
|
647627
|
-
|
|
649197
|
+
import_node_fs24.default.writeFileSync(fullPath, "# No cookie data\n", "utf8");
|
|
647628
649198
|
result.description = `Created empty cookie file at '${fullPath}'.`;
|
|
647629
649199
|
log(config, "debug", `Created empty cookie file: ${fullPath}`);
|
|
647630
649200
|
}
|
|
@@ -647651,8 +649221,8 @@ function formatCookieForNetscape(cookie) {
|
|
|
647651
649221
|
// dist/core/tests/loadCookie.js
|
|
647652
649222
|
init_validate();
|
|
647653
649223
|
init_utils();
|
|
647654
|
-
var
|
|
647655
|
-
var
|
|
649224
|
+
var import_node_path22 = __toESM(require("node:path"), 1);
|
|
649225
|
+
var import_node_fs25 = __toESM(require("node:fs"), 1);
|
|
647656
649226
|
async function loadCookie({ config, step, driver }) {
|
|
647657
649227
|
let result = {
|
|
647658
649228
|
status: "PASS",
|
|
@@ -647669,7 +649239,7 @@ async function loadCookie({ config, step, driver }) {
|
|
|
647669
649239
|
let cookieName, filePath, directory, domain, variable;
|
|
647670
649240
|
if (typeof step.loadCookie === "string") {
|
|
647671
649241
|
if (step.loadCookie.endsWith(".txt")) {
|
|
647672
|
-
cookieName =
|
|
649242
|
+
cookieName = import_node_path22.default.basename(step.loadCookie, ".txt");
|
|
647673
649243
|
filePath = step.loadCookie;
|
|
647674
649244
|
} else {
|
|
647675
649245
|
cookieName = step.loadCookie;
|
|
@@ -647682,9 +649252,9 @@ async function loadCookie({ config, step, driver }) {
|
|
|
647682
649252
|
domain = step.loadCookie.domain;
|
|
647683
649253
|
variable = step.loadCookie.variable;
|
|
647684
649254
|
if (filePath && !cookieName) {
|
|
647685
|
-
const ext =
|
|
649255
|
+
const ext = import_node_path22.default.extname(filePath).toLowerCase();
|
|
647686
649256
|
if (ext === ".txt") {
|
|
647687
|
-
cookieName =
|
|
649257
|
+
cookieName = import_node_path22.default.basename(filePath, ext);
|
|
647688
649258
|
}
|
|
647689
649259
|
}
|
|
647690
649260
|
}
|
|
@@ -647707,14 +649277,14 @@ async function loadCookie({ config, step, driver }) {
|
|
|
647707
649277
|
}
|
|
647708
649278
|
} else if (filePath) {
|
|
647709
649279
|
const inputDirectory = directory || config.output || process.cwd();
|
|
647710
|
-
const fullPath =
|
|
647711
|
-
if (!
|
|
649280
|
+
const fullPath = import_node_path22.default.resolve(inputDirectory, filePath);
|
|
649281
|
+
if (!import_node_fs25.default.existsSync(fullPath)) {
|
|
647712
649282
|
result.status = "FAIL";
|
|
647713
649283
|
result.description = `Cookie file '${fullPath}' not found`;
|
|
647714
649284
|
return result;
|
|
647715
649285
|
}
|
|
647716
649286
|
try {
|
|
647717
|
-
const fileContent =
|
|
649287
|
+
const fileContent = import_node_fs25.default.readFileSync(fullPath, "utf8");
|
|
647718
649288
|
const cookies = parseNetscapeCookieFile(fileContent);
|
|
647719
649289
|
if (cookies.length === 0) {
|
|
647720
649290
|
result.status = "FAIL";
|
|
@@ -647880,8 +649450,8 @@ function isDomainCompatible(currentDomain, cookieDomain) {
|
|
|
647880
649450
|
// dist/core/tests/httpRequest.js
|
|
647881
649451
|
init_validate();
|
|
647882
649452
|
var import_axios5 = __toESM(require("axios"), 1);
|
|
647883
|
-
var
|
|
647884
|
-
var
|
|
649453
|
+
var import_node_fs26 = __toESM(require("node:fs"), 1);
|
|
649454
|
+
var import_node_path23 = __toESM(require("node:path"), 1);
|
|
647885
649455
|
var import_ajv2 = __toESM(require("ajv"), 1);
|
|
647886
649456
|
init_openapi();
|
|
647887
649457
|
init_utils();
|
|
@@ -647911,9 +649481,9 @@ async function httpRequest({ config, step, openApiDefinitions = [] }) {
|
|
|
647911
649481
|
delete step.httpRequest.openApi.definition;
|
|
647912
649482
|
} else if (openApiDefinitions.length > 0) {
|
|
647913
649483
|
findOperation: for (const openApiConfig of openApiDefinitions) {
|
|
647914
|
-
for (const
|
|
647915
|
-
for (const method in openApiConfig.definition.paths[
|
|
647916
|
-
if (openApiConfig.definition.paths[
|
|
649484
|
+
for (const path28 in openApiConfig.definition.paths) {
|
|
649485
|
+
for (const method in openApiConfig.definition.paths[path28]) {
|
|
649486
|
+
if (openApiConfig.definition.paths[path28][method].operationId === step.httpRequest.openApi.operationId) {
|
|
647917
649487
|
openApiDefinition = openApiConfig.definition;
|
|
647918
649488
|
step.httpRequest.openApi = {
|
|
647919
649489
|
...openApiConfig,
|
|
@@ -648227,20 +649797,20 @@ async function httpRequest({ config, step, openApiDefinitions = [] }) {
|
|
|
648227
649797
|
}
|
|
648228
649798
|
}
|
|
648229
649799
|
if (step.httpRequest.path) {
|
|
648230
|
-
const dir =
|
|
648231
|
-
if (!
|
|
648232
|
-
|
|
649800
|
+
const dir = import_node_path23.default.dirname(step.httpRequest.path);
|
|
649801
|
+
if (!import_node_fs26.default.existsSync(dir)) {
|
|
649802
|
+
import_node_fs26.default.mkdirSync(dir, { recursive: true });
|
|
648233
649803
|
}
|
|
648234
649804
|
let filePath = step.httpRequest.path;
|
|
648235
649805
|
log(config, "debug", `Saving output to file: ${filePath}`);
|
|
648236
|
-
if (!
|
|
648237
|
-
await
|
|
649806
|
+
if (!import_node_fs26.default.existsSync(filePath)) {
|
|
649807
|
+
await import_node_fs26.default.promises.writeFile(filePath, JSON.stringify(response.data, null, 2));
|
|
648238
649808
|
descriptions.push(`Saved output to file.`);
|
|
648239
649809
|
} else {
|
|
648240
649810
|
if (step.httpRequest.overwrite == "false") {
|
|
648241
649811
|
descriptions.push(`Didn't save output. File already exists.`);
|
|
648242
649812
|
}
|
|
648243
|
-
const existingFile =
|
|
649813
|
+
const existingFile = import_node_fs26.default.readFileSync(filePath, "utf8");
|
|
648244
649814
|
const fractionalDiff = calculateFractionalDifference(existingFile, JSON.stringify(response.data, null, 2));
|
|
648245
649815
|
log(config, "debug", `Fractional difference: ${fractionalDiff}`);
|
|
648246
649816
|
result.outputs.variation = fractionalDiff;
|
|
@@ -648250,13 +649820,13 @@ async function httpRequest({ config, step, openApiDefinitions = [] }) {
|
|
|
648250
649820
|
});
|
|
648251
649821
|
if (fractionalDiff > step.httpRequest.maxVariation) {
|
|
648252
649822
|
if (step.httpRequest.overwrite == "aboveVariation") {
|
|
648253
|
-
await
|
|
649823
|
+
await import_node_fs26.default.promises.writeFile(filePath, JSON.stringify(response.data, null, 2));
|
|
648254
649824
|
descriptions.push(`Saved response to file.`);
|
|
648255
649825
|
}
|
|
648256
649826
|
descriptions.push(`The difference between the existing saved response and the new response (${fractionalDiff.toFixed(2)}) is greater than the max accepted variation (${step.httpRequest.maxVariation}).`);
|
|
648257
649827
|
} else {
|
|
648258
649828
|
if (step.httpRequest.overwrite == "true") {
|
|
648259
|
-
|
|
649829
|
+
import_node_fs26.default.writeFileSync(filePath, JSON.stringify(response.data, null, 2));
|
|
648260
649830
|
descriptions.push(`Saved response to file.`);
|
|
648261
649831
|
}
|
|
648262
649832
|
}
|
|
@@ -648269,8 +649839,8 @@ async function httpRequest({ config, step, openApiDefinitions = [] }) {
|
|
|
648269
649839
|
result.description = descriptions.join(" ").trim();
|
|
648270
649840
|
return result;
|
|
648271
649841
|
}
|
|
648272
|
-
function fieldExistsAtPath(obj,
|
|
648273
|
-
const segments =
|
|
649842
|
+
function fieldExistsAtPath(obj, path28) {
|
|
649843
|
+
const segments = path28.match(/[^.[\]]+/g);
|
|
648274
649844
|
if (!segments) {
|
|
648275
649845
|
return false;
|
|
648276
649846
|
}
|
|
@@ -648460,9 +650030,9 @@ async function clickElement({ config, step, driver, appSession }) {
|
|
|
648460
650030
|
// dist/core/tests/runCode.js
|
|
648461
650031
|
init_validate();
|
|
648462
650032
|
init_utils();
|
|
648463
|
-
var
|
|
648464
|
-
var
|
|
648465
|
-
var
|
|
650033
|
+
var import_node_fs27 = __toESM(require("node:fs"), 1);
|
|
650034
|
+
var import_node_path24 = __toESM(require("node:path"), 1);
|
|
650035
|
+
var import_node_os11 = __toESM(require("node:os"), 1);
|
|
648466
650036
|
function createTempScript(code, language) {
|
|
648467
650037
|
let extension;
|
|
648468
650038
|
switch (language) {
|
|
@@ -648485,10 +650055,10 @@ function createTempScript(code, language) {
|
|
|
648485
650055
|
default:
|
|
648486
650056
|
extension = "";
|
|
648487
650057
|
}
|
|
648488
|
-
const tmpDir =
|
|
648489
|
-
const tmpFile =
|
|
650058
|
+
const tmpDir = import_node_os11.default.tmpdir();
|
|
650059
|
+
const tmpFile = import_node_path24.default.join(tmpDir, `doc-detective-${Date.now()}${extension}`);
|
|
648490
650060
|
try {
|
|
648491
|
-
|
|
650061
|
+
import_node_fs27.default.writeFileSync(tmpFile, code);
|
|
648492
650062
|
} catch (error) {
|
|
648493
650063
|
throw new Error(`Failed to create temporary script: ${error.message}`);
|
|
648494
650064
|
}
|
|
@@ -648547,9 +650117,9 @@ async function runCode({ config, step, driver, processRegistry }) {
|
|
|
648547
650117
|
}
|
|
648548
650118
|
let command = step.runCode.command;
|
|
648549
650119
|
const wantsBash = command === "bash" || step.runCode.language?.toLowerCase() === "bash";
|
|
648550
|
-
const interpreterShell = wantsBash ? "bash" :
|
|
650120
|
+
const interpreterShell = wantsBash ? "bash" : import_node_os11.default.platform() === "win32" ? "cmd" : "bash";
|
|
648551
650121
|
let commandPreverified = false;
|
|
648552
|
-
if (
|
|
650122
|
+
if (import_node_os11.default.platform() === "win32" && command === "bash") {
|
|
648553
650123
|
try {
|
|
648554
650124
|
command = await resolveShellExecutable("bash", {
|
|
648555
650125
|
cacheDir: config?.cacheDir
|
|
@@ -648561,7 +650131,7 @@ async function runCode({ config, step, driver, processRegistry }) {
|
|
|
648561
650131
|
return result;
|
|
648562
650132
|
}
|
|
648563
650133
|
}
|
|
648564
|
-
if (
|
|
650134
|
+
if (import_node_os11.default.platform() === "win32" && interpreterShell === "bash") {
|
|
648565
650135
|
command = command.replace(/\\/g, "/");
|
|
648566
650136
|
if (/\s/.test(command) && !command.startsWith('"')) {
|
|
648567
650137
|
command = `"${command}"`;
|
|
@@ -648576,7 +650146,7 @@ async function runCode({ config, step, driver, processRegistry }) {
|
|
|
648576
650146
|
}
|
|
648577
650147
|
}
|
|
648578
650148
|
let scriptArg = scriptPath;
|
|
648579
|
-
if (
|
|
650149
|
+
if (import_node_os11.default.platform() === "win32")
|
|
648580
650150
|
scriptArg = scriptArg.replace(/\\/g, "/");
|
|
648581
650151
|
if (/\s/.test(scriptArg))
|
|
648582
650152
|
scriptArg = `"${scriptArg}"`;
|
|
@@ -648593,7 +650163,7 @@ async function runCode({ config, step, driver, processRegistry }) {
|
|
|
648593
650163
|
if (typeof step.runCode.stdio !== "undefined")
|
|
648594
650164
|
runShellOptions.stdio = step.runCode.stdio;
|
|
648595
650165
|
if (typeof step.runCode.path !== "undefined") {
|
|
648596
|
-
runShellOptions.path = step.runCode.directory ?
|
|
650166
|
+
runShellOptions.path = step.runCode.directory ? import_node_path24.default.join(step.runCode.directory, step.runCode.path) : step.runCode.path;
|
|
648597
650167
|
}
|
|
648598
650168
|
if (step.runCode.background) {
|
|
648599
650169
|
runShellOptions.background = step.runCode.background;
|
|
@@ -648622,7 +650192,7 @@ async function runCode({ config, step, driver, processRegistry }) {
|
|
|
648622
650192
|
} finally {
|
|
648623
650193
|
if (!deferTempCleanup) {
|
|
648624
650194
|
try {
|
|
648625
|
-
|
|
650195
|
+
import_node_fs27.default.unlinkSync(scriptPath);
|
|
648626
650196
|
log(config, "debug", `Removed temporary script: ${scriptPath}`);
|
|
648627
650197
|
} catch (error) {
|
|
648628
650198
|
log(config, "warning", `Failed to remove temporary script: ${scriptPath}`);
|
|
@@ -648636,7 +650206,7 @@ async function runCode({ config, step, driver, processRegistry }) {
|
|
|
648636
650206
|
init_validate();
|
|
648637
650207
|
init_utils();
|
|
648638
650208
|
var import_tree_kill2 = __toESM(require("tree-kill"), 1);
|
|
648639
|
-
var
|
|
650209
|
+
var import_node_fs28 = __toESM(require("node:fs"), 1);
|
|
648640
650210
|
async function closeSurface({ config, step, driver, processRegistry, appSession }) {
|
|
648641
650211
|
const result = {
|
|
648642
650212
|
status: "PASS",
|
|
@@ -648785,7 +650355,7 @@ async function closeSurface({ config, step, driver, processRegistry, appSession
|
|
|
648785
650355
|
}
|
|
648786
650356
|
if (entry.tempPath) {
|
|
648787
650357
|
try {
|
|
648788
|
-
|
|
650358
|
+
import_node_fs28.default.unlinkSync(entry.tempPath);
|
|
648789
650359
|
} catch {
|
|
648790
650360
|
}
|
|
648791
650361
|
}
|
|
@@ -649042,7 +650612,7 @@ async function startSurfaceStep({ config, step, platform, driver, processRegistr
|
|
|
649042
650612
|
}
|
|
649043
650613
|
|
|
649044
650614
|
// dist/core/tests/mobileBrowser.js
|
|
649045
|
-
var
|
|
650615
|
+
var import_node_path25 = __toESM(require("node:path"), 1);
|
|
649046
650616
|
var SUPPORTED_MOBILE_BROWSER = {
|
|
649047
650617
|
android: "chrome",
|
|
649048
650618
|
ios: "safari"
|
|
@@ -649121,7 +650691,7 @@ function buildMobileBrowserCapabilities({ platform, udid, cacheDir, timeout, loc
|
|
|
649121
650691
|
// --allow-insecure=uiautomator2:chromedriver_autodownload. The
|
|
649122
650692
|
// download lands in the Doc Detective cache so later runs reuse it.
|
|
649123
650693
|
"appium:chromedriverAutodownload": true,
|
|
649124
|
-
"appium:chromedriverExecutableDir":
|
|
650694
|
+
"appium:chromedriverExecutableDir": import_node_path25.default.join(cacheDir, MOBILE_CHROMEDRIVER_DIR)
|
|
649125
650695
|
};
|
|
649126
650696
|
}
|
|
649127
650697
|
const capabilities = {
|
|
@@ -649691,8 +651261,8 @@ function buildAcquireSimulatorDeps(log3) {
|
|
|
649691
651261
|
// dist/core/tests/runBrowserScript.js
|
|
649692
651262
|
init_validate();
|
|
649693
651263
|
init_utils();
|
|
649694
|
-
var
|
|
649695
|
-
var
|
|
651264
|
+
var import_node_fs29 = __toESM(require("node:fs"), 1);
|
|
651265
|
+
var import_node_path26 = __toESM(require("node:path"), 1);
|
|
649696
651266
|
async function runBrowserScript({ config, step, driver }) {
|
|
649697
651267
|
const result = {
|
|
649698
651268
|
status: "PASS",
|
|
@@ -649767,16 +651337,16 @@ async function runBrowserScript({ config, step, driver }) {
|
|
|
649767
651337
|
}
|
|
649768
651338
|
if (step.runBrowserScript.path) {
|
|
649769
651339
|
try {
|
|
649770
|
-
const dir =
|
|
649771
|
-
if (!
|
|
649772
|
-
|
|
651340
|
+
const dir = import_node_path26.default.dirname(step.runBrowserScript.path);
|
|
651341
|
+
if (!import_node_fs29.default.existsSync(dir)) {
|
|
651342
|
+
import_node_fs29.default.mkdirSync(dir, { recursive: true });
|
|
649773
651343
|
}
|
|
649774
651344
|
const filePath = step.runBrowserScript.path;
|
|
649775
651345
|
log(config, "debug", `Saving script result to file: ${filePath}`);
|
|
649776
|
-
if (!
|
|
649777
|
-
|
|
651346
|
+
if (!import_node_fs29.default.existsSync(filePath)) {
|
|
651347
|
+
import_node_fs29.default.writeFileSync(filePath, serialized);
|
|
649778
651348
|
} else {
|
|
649779
|
-
const existingFile =
|
|
651349
|
+
const existingFile = import_node_fs29.default.readFileSync(filePath, "utf8");
|
|
649780
651350
|
const fractionalDiff = calculateFractionalDifference(existingFile, serialized);
|
|
649781
651351
|
log(config, "debug", `Fractional difference: ${fractionalDiff}`);
|
|
649782
651352
|
result.outputs.variation = fractionalDiff;
|
|
@@ -649786,7 +651356,7 @@ async function runBrowserScript({ config, step, driver }) {
|
|
|
649786
651356
|
});
|
|
649787
651357
|
if (fractionalDiff > step.runBrowserScript.maxVariation) {
|
|
649788
651358
|
if (step.runBrowserScript.overwrite == "aboveVariation" || step.runBrowserScript.overwrite == "true") {
|
|
649789
|
-
|
|
651359
|
+
import_node_fs29.default.writeFileSync(filePath, serialized);
|
|
649790
651360
|
descriptions.push(`Saved output to file.`);
|
|
649791
651361
|
} else {
|
|
649792
651362
|
descriptions.push(`Didn't overwrite the existing file.`);
|
|
@@ -649794,7 +651364,7 @@ async function runBrowserScript({ config, step, driver }) {
|
|
|
649794
651364
|
descriptions.push(`The difference between the existing output and the new output (${fractionalDiff.toFixed(2)}) is greater than the max accepted variation (${step.runBrowserScript.maxVariation}).`);
|
|
649795
651365
|
} else {
|
|
649796
651366
|
if (step.runBrowserScript.overwrite == "true") {
|
|
649797
|
-
|
|
651367
|
+
import_node_fs29.default.writeFileSync(filePath, serialized);
|
|
649798
651368
|
descriptions.push(`Saved output to file.`);
|
|
649799
651369
|
}
|
|
649800
651370
|
}
|
|
@@ -649962,9 +651532,9 @@ async function dragAndDropElement({ config, step, driver }) {
|
|
|
649962
651532
|
}
|
|
649963
651533
|
|
|
649964
651534
|
// dist/core/tests.js
|
|
649965
|
-
var
|
|
651535
|
+
var import_node_path27 = __toESM(require("node:path"), 1);
|
|
649966
651536
|
var import_node_child_process15 = require("node:child_process");
|
|
649967
|
-
var
|
|
651537
|
+
var import_node_crypto10 = require("node:crypto");
|
|
649968
651538
|
init_appium();
|
|
649969
651539
|
init_config();
|
|
649970
651540
|
|
|
@@ -650116,7 +651686,7 @@ function getIntegrationConfig(config, sourceIntegration) {
|
|
|
650116
651686
|
var import_node_http2 = __toESM(require("node:http"), 1);
|
|
650117
651687
|
var import_node_https3 = __toESM(require("node:https"), 1);
|
|
650118
651688
|
var import_node_url6 = require("node:url");
|
|
650119
|
-
var __dirname5 =
|
|
651689
|
+
var __dirname5 = import_node_path27.default.dirname((0, import_node_url6.fileURLToPath)(importMetaUrl));
|
|
650120
651690
|
var KNOWN_BROWSERS = ["firefox", "chrome", "safari", "webkit"];
|
|
650121
651691
|
function killTree(pid, timeoutMs = 5e3) {
|
|
650122
651692
|
return new Promise((resolve) => {
|
|
@@ -650261,7 +651831,7 @@ function getDriverCapabilities({ runnerDetails, name, options }) {
|
|
|
650261
651831
|
prefs: {
|
|
650262
651832
|
// Per-context download dir keeps concurrent recordings from
|
|
650263
651833
|
// colliding on the same .webm filename in a shared temp dir.
|
|
650264
|
-
"download.default_directory": options.downloadDir ||
|
|
651834
|
+
"download.default_directory": options.downloadDir || import_node_os12.default.tmpdir(),
|
|
650265
651835
|
"download.prompt_for_download": false,
|
|
650266
651836
|
"download.directory_upgrade": true
|
|
650267
651837
|
},
|
|
@@ -650762,7 +652332,7 @@ async function runSpecs({ resolvedTests }) {
|
|
|
650762
652332
|
const runDir = getRunOutputDir(config, {
|
|
650763
652333
|
create: runArchivesArtifacts(config, specs)
|
|
650764
652334
|
});
|
|
650765
|
-
const runId =
|
|
652335
|
+
const runId = import_node_path27.default.basename(runDir);
|
|
650766
652336
|
const report = {
|
|
650767
652337
|
runId,
|
|
650768
652338
|
runDir,
|
|
@@ -651004,7 +652574,7 @@ async function runSpecs({ resolvedTests }) {
|
|
|
651004
652574
|
}
|
|
651005
652575
|
if (entry?.tempPath) {
|
|
651006
652576
|
try {
|
|
651007
|
-
|
|
652577
|
+
import_node_fs30.default.unlinkSync(entry.tempPath);
|
|
651008
652578
|
} catch {
|
|
651009
652579
|
}
|
|
651010
652580
|
}
|
|
@@ -651876,7 +653446,7 @@ function buildAutoRecordStep({ config, spec, test, context }) {
|
|
|
651876
653446
|
return null;
|
|
651877
653447
|
const runDir = getRunOutputDir(config, { create: false });
|
|
651878
653448
|
const contextSegment = capPathSegment(sanitizeFilesystemName(String(context.contextId ?? ""), "context"));
|
|
651879
|
-
const recordPath =
|
|
653449
|
+
const recordPath = import_node_path27.default.join(runDir, "specs", capPathSegment(sanitizeFilesystemName(String(spec.specId ?? ""), "spec")), "tests", capPathSegment(sanitizeFilesystemName(String(test.testId ?? ""), "test")), "contexts", contextSegment, "recordings", `${contextSegment}.mp4`);
|
|
651880
653450
|
return {
|
|
651881
653451
|
// Mobile-target contexts record the device screen through the app driver
|
|
651882
653452
|
// (the internal device plan, resolved from the platform) — pinning ffmpeg
|
|
@@ -651893,28 +653463,21 @@ function buildAutoRecordStep({ config, spec, test, context }) {
|
|
|
651893
653463
|
__autoRecord: true
|
|
651894
653464
|
};
|
|
651895
653465
|
}
|
|
651896
|
-
function capPathSegment(segment, max = 32) {
|
|
651897
|
-
if (segment.length <= max)
|
|
651898
|
-
return segment;
|
|
651899
|
-
const hash = (0, import_node_crypto9.createHash)("sha1").update(segment).digest("hex").slice(0, 8);
|
|
651900
|
-
const tail = segment.slice(segment.length - (max - hash.length - 1));
|
|
651901
|
-
return `${hash}-${tail}`;
|
|
651902
|
-
}
|
|
651903
653466
|
async function captureAutoScreenshot({ config, driver, spec, test, context, step, stepIndex, stepCount }) {
|
|
651904
653467
|
try {
|
|
651905
|
-
const action = BROWSER_STEP_KEYS.find((key) => typeof step[key] !== "undefined") || "step";
|
|
651906
|
-
const sanitizedTestId = sanitizeFilesystemName(String(test.testId ?? ""), "test");
|
|
651907
653468
|
const runDir = getRunOutputDir(config);
|
|
651908
|
-
const dir =
|
|
651909
|
-
const
|
|
651910
|
-
|
|
651911
|
-
|
|
651912
|
-
|
|
653469
|
+
const dir = import_node_path27.default.join(runDir, "specs", capPathSegment(sanitizeFilesystemName(String(spec.specId ?? ""), "spec")), "tests", capPathSegment(sanitizeFilesystemName(String(test.testId ?? ""), "test")), "contexts", capPathSegment(sanitizeFilesystemName(String(context.contextId ?? ""), "context")), "screenshots");
|
|
653470
|
+
const fileName = stepArtifactFileName({
|
|
653471
|
+
step,
|
|
653472
|
+
stepIndex,
|
|
653473
|
+
stepCount,
|
|
653474
|
+
testId: test.testId
|
|
653475
|
+
});
|
|
651913
653476
|
const screenshotStep = {
|
|
651914
653477
|
stepId: `${step.stepId}_auto`,
|
|
651915
653478
|
description: "Automatic post-step screenshot",
|
|
651916
653479
|
screenshot: {
|
|
651917
|
-
path:
|
|
653480
|
+
path: import_node_path27.default.join(dir, fileName),
|
|
651918
653481
|
overwrite: "true"
|
|
651919
653482
|
}
|
|
651920
653483
|
};
|
|
@@ -651927,7 +653490,7 @@ async function captureAutoScreenshot({ config, driver, spec, test, context, step
|
|
|
651927
653490
|
log(config, "warning", `Auto screenshot failed after step ${step.stepId}: ${captureResult.description}`);
|
|
651928
653491
|
return null;
|
|
651929
653492
|
}
|
|
651930
|
-
return
|
|
653493
|
+
return import_node_path27.default.relative(runDir, screenshotStep.screenshot.path).split(import_node_path27.default.sep).join("/");
|
|
651931
653494
|
} catch (error) {
|
|
651932
653495
|
log(config, "warning", `Auto screenshot failed after step ${step.stepId}: ${error?.message ?? error}`);
|
|
651933
653496
|
return null;
|
|
@@ -652355,7 +653918,7 @@ ${JSON.stringify(context, null, 2)}`);
|
|
|
652355
653918
|
const usedStepIds = new Set(context.steps.map((s) => s.stepId).filter(Boolean));
|
|
652356
653919
|
for (const step of context.steps) {
|
|
652357
653920
|
if (!step.stepId) {
|
|
652358
|
-
const baseId = sanitizeFilesystemName(`${test.testId}~s${contentHash(step)}`, `step-${(0,
|
|
653921
|
+
const baseId = sanitizeFilesystemName(`${test.testId}~s${contentHash(step)}`, `step-${(0, import_node_crypto10.randomUUID)()}`);
|
|
652359
653922
|
let stepId = baseId;
|
|
652360
653923
|
let suffix = 2;
|
|
652361
653924
|
while (usedStepIds.has(stepId)) {
|
|
@@ -652550,6 +654113,19 @@ ${JSON.stringify(r, null, 2)}`);
|
|
|
652550
654113
|
if (capturedPath)
|
|
652551
654114
|
stepReport.autoScreenshot = capturedPath;
|
|
652552
654115
|
}
|
|
654116
|
+
for (const checkpointDriver of sessionDrivers(browserSessions, driver)) {
|
|
654117
|
+
await captureRecordingCheckpoints({
|
|
654118
|
+
config,
|
|
654119
|
+
driver: checkpointDriver,
|
|
654120
|
+
recordingHost: checkpointDriver,
|
|
654121
|
+
step,
|
|
654122
|
+
stepStatus: stepReport.result,
|
|
654123
|
+
stepIndex,
|
|
654124
|
+
stepCount: context.steps.length,
|
|
654125
|
+
testId: test.testId,
|
|
654126
|
+
appSession
|
|
654127
|
+
});
|
|
654128
|
+
}
|
|
652553
654129
|
pushStepReport(stepReport);
|
|
652554
654130
|
if (routingDecision.action === "stop" && !step._fromAfter) {
|
|
652555
654131
|
if (routingDecision.scope !== "test") {
|
|
@@ -652655,7 +654231,7 @@ async function stopAllRecordings({ config, context, driver, contextReport }) {
|
|
|
652655
654231
|
stopRecord: true,
|
|
652656
654232
|
__stopAny: true,
|
|
652657
654233
|
description: "Stopping recording",
|
|
652658
|
-
stepId: (0,
|
|
654234
|
+
stepId: (0, import_node_crypto10.randomUUID)()
|
|
652659
654235
|
};
|
|
652660
654236
|
try {
|
|
652661
654237
|
const stepResult = await runStep({
|
|
@@ -652753,8 +654329,16 @@ async function runStep({ config = {}, context = {}, step, driver, metaValues = {
|
|
|
652753
654329
|
if (!Array.isArray(recordingHost.state.recordings))
|
|
652754
654330
|
recordingHost.state.recordings = [];
|
|
652755
654331
|
const handle = actionResult.recording;
|
|
652756
|
-
handle.id = handle.id ?? (0,
|
|
654332
|
+
handle.id = handle.id ?? (0, import_node_crypto10.randomUUID)();
|
|
652757
654333
|
handle.name = handle.name ?? recordStepName(step.record);
|
|
654334
|
+
handle.overwrite = step.record?.overwrite;
|
|
654335
|
+
if (handle.targetPath) {
|
|
654336
|
+
handle.checkpoints = resolveCheckpointsConfig({
|
|
654337
|
+
record: step.record,
|
|
654338
|
+
targetPath: handle.targetPath,
|
|
654339
|
+
handleId: handle.id
|
|
654340
|
+
});
|
|
654341
|
+
}
|
|
652758
654342
|
if (step.__autoRecord) {
|
|
652759
654343
|
handle.synthetic = true;
|
|
652760
654344
|
if (!driver && appSession && !isMobileTargetPlatform(context?.platform)) {
|
|
@@ -652897,7 +654481,7 @@ async function spawnAppiumServer(appiumEntry, config, display, extraEnv, extraAr
|
|
|
652897
654481
|
} : process.env;
|
|
652898
654482
|
const proc = (0, import_node_child_process15.spawn)(process.execPath, [appiumEntry, "-a", "127.0.0.1", "-p", String(port), ...extraArgs ?? []], {
|
|
652899
654483
|
windowsHide: true,
|
|
652900
|
-
cwd:
|
|
654484
|
+
cwd: import_node_path27.default.join(__dirname5, "../.."),
|
|
652901
654485
|
env
|
|
652902
654486
|
});
|
|
652903
654487
|
proc.on("error", (err) => {
|
|
@@ -653055,7 +654639,7 @@ async function getRunner(options = {}) {
|
|
|
653055
654639
|
}
|
|
653056
654640
|
const appium = (0, import_node_child_process15.spawn)(process.execPath, [appiumEntry, "-a", "127.0.0.1", "-p", String(appiumPort)], {
|
|
653057
654641
|
windowsHide: true,
|
|
653058
|
-
cwd:
|
|
654642
|
+
cwd: import_node_path27.default.join(__dirname5, "../..")
|
|
653059
654643
|
});
|
|
653060
654644
|
appium.on("error", (err) => {
|
|
653061
654645
|
log(config, "warning", `Appium process error: ${err?.stack ?? err?.message ?? String(err)}`);
|
|
@@ -653114,7 +654698,7 @@ async function getRunner(options = {}) {
|
|
|
653114
654698
|
}
|
|
653115
654699
|
|
|
653116
654700
|
// dist/core/telem.js
|
|
653117
|
-
var
|
|
654701
|
+
var import_node_os13 = __toESM(require("node:os"), 1);
|
|
653118
654702
|
init_utils();
|
|
653119
654703
|
var import_posthog_node = require("posthog-node");
|
|
653120
654704
|
var import_node_module2 = require("node:module");
|
|
@@ -653142,11 +654726,11 @@ function sendTelemetry(config, command, results) {
|
|
|
653142
654726
|
telemetryData.dist_interface = telemetryData.dist_interface || "package";
|
|
653143
654727
|
telemetryData.core_version = pkg.version;
|
|
653144
654728
|
telemetryData.dist_version = telemetryData.dist_version || telemetryData.core_version;
|
|
653145
|
-
telemetryData.core_platform = platformMap2[
|
|
654729
|
+
telemetryData.core_platform = platformMap2[import_node_os13.default.platform()] || import_node_os13.default.platform();
|
|
653146
654730
|
telemetryData.dist_platform = telemetryData.dist_platform || telemetryData.core_platform;
|
|
653147
|
-
telemetryData.core_platform_version =
|
|
654731
|
+
telemetryData.core_platform_version = import_node_os13.default.release();
|
|
653148
654732
|
telemetryData.dist_platform_version = telemetryData.dist_platform_version || telemetryData.core_platform_version;
|
|
653149
|
-
telemetryData.core_platform_arch =
|
|
654733
|
+
telemetryData.core_platform_arch = import_node_os13.default.arch();
|
|
653150
654734
|
telemetryData.dist_platform_arch = telemetryData.dist_platform_arch || telemetryData.core_platform_arch;
|
|
653151
654735
|
telemetryData.core_deployment = telemetryData.core_deployment || "node";
|
|
653152
654736
|
telemetryData.dist_deployment = telemetryData.dist_deployment || telemetryData.core_deployment;
|