@flighthq/tool-capture 0.4.0-next.1920.b93ad0f → 0.4.0-next.1932.1ef883a
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/LICENSE.md +9 -0
- package/README.md +9 -223
- package/package.json +6 -6
package/LICENSE.md
ADDED
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
# MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2013-2026 Joshua Granick and other contributors
|
|
4
|
+
|
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
|
|
6
|
+
|
|
7
|
+
The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
|
|
8
|
+
|
|
9
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
package/README.md
CHANGED
|
@@ -1,231 +1,17 @@
|
|
|
1
|
-
#
|
|
1
|
+
# @flighthq/tool-capture
|
|
2
2
|
|
|
3
|
-
|
|
3
|
+
Turn-key Flight capture, visual verification, parity, and benchmark CLI and API
|
|
4
4
|
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
## Choose the contract
|
|
8
|
-
|
|
9
|
-
- **Observe:** zero page integration. Produces agent eyesight and explicit `usable`, `blank`, `timedOut`, retry, and error diagnostics.
|
|
10
|
-
- **Capture gate:** a manifest plus CLI flags. Produces deterministic screenshots, logs, hashes, and smoke failures.
|
|
11
|
-
- **Verification:** one shared page adapter. Adds asserted non-blank readback, fingerprints, parity, and regression without capture code in each example.
|
|
12
|
-
- **Benchmark:** repeatable page work with backend completion fences, robust statistics, calibrated scores, relative comparisons, and committed performance baselines.
|
|
13
|
-
|
|
14
|
-
Every command writes versioned `status.json` files and an aggregate `report.json` envelope intended for CI and AI agents. Capture retries transient navigation/protocol failures in a fresh page; `observe` retries blank or timed-out attempts while preserving the best full-page evidence from its final attempt.
|
|
15
|
-
|
|
16
|
-
## Capture a suite
|
|
17
|
-
|
|
18
|
-
Add a `tool-capture.json` manifest to a package:
|
|
19
|
-
|
|
20
|
-
```json
|
|
21
|
-
{
|
|
22
|
-
"subject": "my-app",
|
|
23
|
-
"entries": [
|
|
24
|
-
{
|
|
25
|
-
"name": "home",
|
|
26
|
-
"renderers": ["canvas", "webgl"],
|
|
27
|
-
"routes": {
|
|
28
|
-
"canvas": "pages/home/canvas/",
|
|
29
|
-
"webgl": "pages/home/webgl/"
|
|
30
|
-
}
|
|
31
|
-
}
|
|
32
|
-
]
|
|
33
|
-
}
|
|
34
|
-
```
|
|
35
|
-
|
|
36
|
-
Then capture either an existing server or an already-built directory:
|
|
5
|
+
## Install
|
|
37
6
|
|
|
38
7
|
```sh
|
|
39
|
-
tool-capture
|
|
40
|
-
tool-capture capture --dir dist
|
|
8
|
+
npm install @flighthq/tool-capture
|
|
41
9
|
```
|
|
42
10
|
|
|
43
|
-
|
|
11
|
+
Import the supported application-facing API from `@flighthq/tool-capture`. The `@flighthq/tool-capture/contract` export is the wider package-to-package contract used to compose Flight itself.
|
|
44
12
|
|
|
45
|
-
|
|
46
|
-
tool-capture capture --dir dist --frames 1 --fail-on-error
|
|
47
|
-
tool-capture capture --dir dist --update-baseline
|
|
48
|
-
tool-capture capture --dir dist --fail-on-changed
|
|
49
|
-
tool-capture capture --dir dist --renderer webgl,webgpu --parallel 4
|
|
50
|
-
```
|
|
51
|
-
|
|
52
|
-
Use `runCaptureSuite` when entries or server lifecycle are generated programmatically. It owns browser setup and teardown, deterministic frame synchronization, parallel or sequential scheduling, baseline policy, interruption, summaries, and the final verdict.
|
|
53
|
-
|
|
54
|
-
## Install verification once
|
|
55
|
-
|
|
56
|
-
Import page APIs from the same package root as the CLI/API; browser-aware bundlers select its page-only condition:
|
|
13
|
+
This package is part of the locked-version Flight SDK graph. Applications may instead install and import `@flighthq/sdk` when package-level tree shaking is sufficient.
|
|
57
14
|
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
Raw consumers can register, render, and verify with one call after constructing their normal renderer state:
|
|
63
|
-
|
|
64
|
-
```ts
|
|
65
|
-
await installCaptureTarget({
|
|
66
|
-
renderer: 'webgl',
|
|
67
|
-
state,
|
|
68
|
-
render: () => renderScene(scene),
|
|
69
|
-
assertRender,
|
|
70
|
-
});
|
|
71
|
-
```
|
|
72
|
-
|
|
73
|
-
An external renderer inside a Flight ecosystem project can register its owned element without manufacturing a Flight render state. Pass the existing WebGL context rather than requesting the canvas context again:
|
|
74
|
-
|
|
75
|
-
```ts
|
|
76
|
-
await installCaptureElementTarget({
|
|
77
|
-
renderer: 'webgl',
|
|
78
|
-
element: canvas,
|
|
79
|
-
gl,
|
|
80
|
-
render: () => referenceApp.render(),
|
|
81
|
-
});
|
|
82
|
-
```
|
|
83
|
-
|
|
84
|
-
The adapter is inert outside a tool-capture browser. During capture it registers readable WebGL/WebGPU state before drawing and publishes the complete versioned terminal contract only after assertions pass. A project whose shared renderer factory already registers the target needs one runner-level line and zero capture-specific lines in each example:
|
|
85
|
-
|
|
86
|
-
```ts
|
|
87
|
-
await verifyCaptureTarget(exampleModule, renderer);
|
|
88
|
-
```
|
|
89
|
-
|
|
90
|
-
Fingerprints use the `<grid-size>:<rgb-hex>` format produced by `formatBitmapFingerprint`. Once the page reaches a terminal verification state, validation is turn-key:
|
|
91
|
-
|
|
92
|
-
```sh
|
|
93
|
-
tool-capture validate --dir dist --no-regression
|
|
94
|
-
tool-capture validate --dir dist --no-parity
|
|
95
|
-
tool-capture validate --dir dist --update-fingerprints
|
|
96
|
-
```
|
|
97
|
-
|
|
98
|
-
Optional manifest policy keeps intentional exceptions beside the suite:
|
|
99
|
-
|
|
100
|
-
```json
|
|
101
|
-
{
|
|
102
|
-
"subject": "my-app",
|
|
103
|
-
"entries": [],
|
|
104
|
-
"validation": {
|
|
105
|
-
"fingerprintSkip": ["audio-only"],
|
|
106
|
-
"paritySkip": {
|
|
107
|
-
"video": "all",
|
|
108
|
-
"approximate-effect": ["canvas"]
|
|
109
|
-
}
|
|
110
|
-
}
|
|
111
|
-
}
|
|
112
|
-
```
|
|
113
|
-
|
|
114
|
-
Explicit groups compare any target IDs, including DOM and WASM-backed variants. DOM targets are rasterized to the same normalized 16×16 RGB fingerprint as canvas/GPU targets. A reference produces clear reference-to-target failures instead of an increasingly noisy all-pairs matrix:
|
|
115
|
-
|
|
116
|
-
```json
|
|
117
|
-
{
|
|
118
|
-
"validation": {
|
|
119
|
-
"parityGroups": {
|
|
120
|
-
"visual": {
|
|
121
|
-
"targets": ["dom", "canvas", "webgl", "webgpu", "wasm:webgl"],
|
|
122
|
-
"reference": "canvas",
|
|
123
|
-
"tolerance": 15
|
|
124
|
-
}
|
|
125
|
-
}
|
|
126
|
-
}
|
|
127
|
-
}
|
|
128
|
-
```
|
|
129
|
-
|
|
130
|
-
Legacy manifests retain raster-only all-pairs behavior. Explicit groups are same-run comparisons and do not require committed regression fingerprints, though each target still reports its independent regression-baseline status.
|
|
131
|
-
|
|
132
|
-
`runCaptureValidation` exposes the same validation lifecycle programmatically. Comparison tolerances and baseline formats come from `@flighthq/capture`; `tool-capture` owns browser execution and reporting.
|
|
133
|
-
|
|
134
|
-
## Benchmark repeatable render work
|
|
135
|
-
|
|
136
|
-
`installCaptureTarget({ render })` and Flight's normal functional-target registration automatically expose the last rendered scene as benchmark work. Custom/WASM pages can call `registerCaptureBenchmarkTarget({ kind, run, synchronize })`; `synchronize` must fence submitted work. Screenshots, fingerprinting, page startup, and calibration are outside timed intervals.
|
|
137
|
-
|
|
138
|
-
```json
|
|
139
|
-
{
|
|
140
|
-
"benchmark": {
|
|
141
|
-
"reference": "canvas",
|
|
142
|
-
"warmupIterations": 3,
|
|
143
|
-
"iterations": 10,
|
|
144
|
-
"samples": 7,
|
|
145
|
-
"sampleDurationMs": 20,
|
|
146
|
-
"maxRetries": 1,
|
|
147
|
-
"regressionTolerance": 0.2,
|
|
148
|
-
"stabilityTolerance": 0.1
|
|
149
|
-
}
|
|
150
|
-
}
|
|
151
|
-
```
|
|
152
|
-
|
|
153
|
-
```sh
|
|
154
|
-
tool-capture benchmark --dir dist --update-benchmarks
|
|
155
|
-
tool-capture benchmark --dir dist
|
|
156
|
-
tool-capture benchmark --url http://localhost:5173 --renderer canvas,webgl --samples 11
|
|
157
|
-
```
|
|
158
|
-
|
|
159
|
-
The update command writes stable baselines to `<subject>/benchmarks/<entry>.json`; a target whose median absolute deviation exceeds the configured stability tolerance is not baselined. Transient navigation, browser, and protocol failures retry in a fresh page (`maxRetries`, default 1), while deterministic verification failures do not. Every run writes `.artifacts/<subject>/benchmark-report.json` with raw samples, median, p95, MAD, retry count, browser/host metadata, CPU/GPU calibration throughput, normalized work, reference ratios, baseline choice, and percentage change.
|
|
160
|
-
|
|
161
|
-
`iterations` is a minimum: the runner adaptively increases it until each timed sample reaches `sampleDurationMs`, avoiding zero-duration and timer-quantization noise for very fast targets.
|
|
162
|
-
|
|
163
|
-
A gating run with no committed baseline for any selected target is unconfigured: it reports the missing baseline evidence and exits non-zero instead of treating zero comparisons as clean. Once baselines exist, no calibration makes performance completely host-independent: renderer workloads stress different parts of CPUs, drivers, and GPUs. The gate therefore prefers a same-run ratio when `reference` is available, because shared host conditions cancel best. Choose a reference with a comparable resource path; a CPU-DOM versus discrete-GPU ratio still reflects that machine's CPU/GPU balance. Otherwise the gate compares `median × calibration throughput`, an estimate of host-normalized work. Keep raw medians for same-machine trends, use ratios for heterogeneous CI, and treat calibrated scores as a useful secondary signal rather than a physical unit. Benchmarks run serially by design so ordinary capture worker concurrency cannot contaminate them.
|
|
164
|
-
|
|
165
|
-
## Batch many resources and subjects
|
|
166
|
-
|
|
167
|
-
Treat each resource as an entry. Routes may point at one reusable preview page with resource and renderer query parameters, so large catalogs need no generated HTML:
|
|
168
|
-
|
|
169
|
-
```json
|
|
170
|
-
{
|
|
171
|
-
"subject": "asset-library",
|
|
172
|
-
"entries": [
|
|
173
|
-
{
|
|
174
|
-
"name": "spaceship",
|
|
175
|
-
"renderers": ["canvas", "webgl", "webgpu"],
|
|
176
|
-
"routes": {
|
|
177
|
-
"canvas": "preview/?asset=spaceship&renderer=canvas",
|
|
178
|
-
"webgl": "preview/?asset=spaceship&renderer=webgl",
|
|
179
|
-
"webgpu": "preview/?asset=spaceship&renderer=webgpu"
|
|
180
|
-
}
|
|
181
|
-
}
|
|
182
|
-
]
|
|
183
|
-
}
|
|
184
|
-
```
|
|
185
|
-
|
|
186
|
-
Use an existing server and tune the resource worker pool for the host:
|
|
187
|
-
|
|
188
|
-
```sh
|
|
189
|
-
tool-capture capture --url http://localhost:5173 --parallel 12 --frames 1 --fail-on-error
|
|
190
|
-
tool-capture validate --url http://localhost:5173 --parallel 12 --update-fingerprints
|
|
191
|
-
tool-capture validate --url http://localhost:5173 --parallel 12
|
|
192
|
-
```
|
|
193
|
-
|
|
194
|
-
The existing `capture` and `validate` baseline commands remain independent. To run the usual capture-then-validation workflow across several packages, add `tool-capture.batch.json` at the repository root:
|
|
195
|
-
|
|
196
|
-
```json
|
|
197
|
-
{
|
|
198
|
-
"subjects": [
|
|
199
|
-
{
|
|
200
|
-
"name": "icons",
|
|
201
|
-
"args": ["--manifest=packages/icons/tool-capture.json", "--url=http://localhost:5173", "--parallel=12"]
|
|
202
|
-
},
|
|
203
|
-
{
|
|
204
|
-
"name": "models",
|
|
205
|
-
"args": ["--manifest=packages/models/tool-capture.json", "--dir=packages/models/dist", "--parallel=6"]
|
|
206
|
-
},
|
|
207
|
-
{
|
|
208
|
-
"name": "shaders",
|
|
209
|
-
"args": ["--manifest=packages/shaders/tool-capture.json", "--dir=packages/shaders/dist"],
|
|
210
|
-
"operations": ["validate", "benchmark"]
|
|
211
|
-
}
|
|
212
|
-
]
|
|
213
|
-
}
|
|
214
|
-
```
|
|
215
|
-
|
|
216
|
-
```sh
|
|
217
|
-
tool-capture batch
|
|
218
|
-
tool-capture batch --only models
|
|
219
|
-
tool-capture batch --filter terrain --renderer webgl,webgpu
|
|
220
|
-
tool-capture batch --subjects-parallel 2
|
|
221
|
-
```
|
|
222
|
-
|
|
223
|
-
Arguments after `batch` override each subject's defaults. Subjects run sequentially unless `--subjects-parallel` is set; targets use each subject's `--parallel` worker pool. All operations reuse the subject's server, and capture/validation share a browser so capture-supplied fingerprints avoid validation reloads. Before benchmarking, that parallel visual browser is closed and a clean serial browser is launched so GPU/process contention cannot contaminate timing. Standalone validation flattens entries × renderers into the same balanced page queue. `runCaptureWorkflow` and `runCaptureBatch` provide the same composition for generated resource catalogs.
|
|
224
|
-
|
|
225
|
-
## Observe one page
|
|
226
|
-
|
|
227
|
-
`observe` is the zero-integration eyes primitive. It actively polls presented pixels, ignores dev-server WebSocket shutdown noise, and retries twice by default. If a canvas remains blank, it captures the full page so an error overlay or loading UI is visible instead of cropping the only useful evidence away. A clean blank result exits nonzero, but `screenshot.png`, `status.json`, and `report.json` remain available:
|
|
228
|
-
|
|
229
|
-
```sh
|
|
230
|
-
tool-capture observe http://localhost:5173/example --out capture --retries 2
|
|
231
|
-
```
|
|
15
|
+
- [Flight project](https://github.com/flighthq/flight)
|
|
16
|
+
- [Source for @flighthq/tool-capture@0.4.0-next.1932.1ef883a](https://github.com/flighthq/flight/tree/1ef883a866729a9bc6f461111970f6377de1499f/packages/tool-capture)
|
|
17
|
+
- [License](https://github.com/flighthq/flight/blob/1ef883a866729a9bc6f461111970f6377de1499f/LICENSE.md)
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@flighthq/tool-capture",
|
|
3
|
-
"version": "0.4.0-next.
|
|
3
|
+
"version": "0.4.0-next.1932.1ef883a",
|
|
4
4
|
"author": "Joshua Granick and other contributors",
|
|
5
5
|
"license": "MIT",
|
|
6
6
|
"repository": {
|
|
@@ -42,11 +42,11 @@
|
|
|
42
42
|
"clean:dist": "tsx ../../scripts/clean-package-dist.ts"
|
|
43
43
|
},
|
|
44
44
|
"dependencies": {
|
|
45
|
-
"@flighthq/capture": "0.4.0-next.
|
|
46
|
-
"@flighthq/effects-wgpu": "0.4.0-next.
|
|
47
|
-
"@flighthq/render-wgpu": "0.4.0-next.
|
|
48
|
-
"@flighthq/bitmap": "0.4.0-next.
|
|
49
|
-
"@flighthq/types": "0.4.0-next.
|
|
45
|
+
"@flighthq/capture": "0.4.0-next.1932.1ef883a",
|
|
46
|
+
"@flighthq/effects-wgpu": "0.4.0-next.1932.1ef883a",
|
|
47
|
+
"@flighthq/render-wgpu": "0.4.0-next.1932.1ef883a",
|
|
48
|
+
"@flighthq/bitmap": "0.4.0-next.1932.1ef883a",
|
|
49
|
+
"@flighthq/types": "0.4.0-next.1932.1ef883a",
|
|
50
50
|
"@playwright/test": "^1.50.0",
|
|
51
51
|
"picocolors": "^1.1.1"
|
|
52
52
|
},
|