@flighthq/tool-capture 0.2.1-next.448.afbdd31 → 0.2.1-next.451.d9a4a4e

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md CHANGED
@@ -78,6 +78,66 @@ Optional manifest policy keeps intentional exceptions beside the suite:
78
78
 
79
79
  `runCaptureValidation` exposes the same validation lifecycle programmatically. Comparison tolerances and baseline formats come from `@flighthq/capture`; `tool-capture` owns browser execution and reporting.
80
80
 
81
+ ## Batch many resources and subjects
82
+
83
+ 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:
84
+
85
+ ```json
86
+ {
87
+ "subject": "asset-library",
88
+ "entries": [
89
+ {
90
+ "name": "spaceship",
91
+ "renderers": ["canvas", "webgl", "webgpu"],
92
+ "routes": {
93
+ "canvas": "preview/?asset=spaceship&renderer=canvas",
94
+ "webgl": "preview/?asset=spaceship&renderer=webgl",
95
+ "webgpu": "preview/?asset=spaceship&renderer=webgpu"
96
+ }
97
+ }
98
+ ]
99
+ }
100
+ ```
101
+
102
+ Use an existing server and tune the resource worker pool for the host:
103
+
104
+ ```sh
105
+ tool-capture capture --url http://localhost:5173 --parallel 12 --frames 1 --fail-on-error
106
+ tool-capture validate --url http://localhost:5173 --parallel 12 --update-fingerprints
107
+ tool-capture validate --url http://localhost:5173 --parallel 12
108
+ ```
109
+
110
+ 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:
111
+
112
+ ```json
113
+ {
114
+ "subjects": [
115
+ {
116
+ "name": "icons",
117
+ "args": ["--manifest=packages/icons/tool-capture.json", "--url=http://localhost:5173", "--parallel=12"]
118
+ },
119
+ {
120
+ "name": "models",
121
+ "args": ["--manifest=packages/models/tool-capture.json", "--dir=packages/models/dist", "--parallel=6"]
122
+ },
123
+ {
124
+ "name": "shaders",
125
+ "args": ["--manifest=packages/shaders/tool-capture.json", "--dir=packages/shaders/dist"],
126
+ "operations": ["validate"]
127
+ }
128
+ ]
129
+ }
130
+ ```
131
+
132
+ ```sh
133
+ tool-capture batch
134
+ tool-capture batch --only models
135
+ tool-capture batch --filter terrain --renderer webgl,webgpu
136
+ tool-capture batch --subjects-parallel 2
137
+ ```
138
+
139
+ Arguments after `batch` override each subject's defaults. Subjects run sequentially unless `--subjects-parallel` is set; entries use each subject's `--parallel` worker pool. Capture and validation reuse the subject's server, avoiding a second build/startup. `runCaptureWorkflow` and `runCaptureBatch` provide the same composition for generated resource catalogs.
140
+
81
141
  ## Observe one page
82
142
 
83
143
  `observe` is the zero-integration eyes primitive. It always emits the best available screenshot and diagnostics rather than enforcing a suite gate:
package/dist/bin.js CHANGED
@@ -2,8 +2,11 @@
2
2
  // Turn-key capture CLI:
3
3
  // - observe <url>: one arbitrary page, zero integration, always emit eyes + diagnostics.
4
4
  // - capture: a full entry × renderer report from a JSON manifest or Flight's built-in suites.
5
+ // - validate: tolerant regression/parity fingerprints over the same suite.
6
+ // - batch: capture + validate workflow over many independently-configured subjects.
5
7
  import { existsSync } from 'node:fs';
6
8
  import { resolve } from 'node:path';
9
+ import { readCaptureBatchManifest } from './captureBatchManifest.js';
7
10
  import { discoverEntries } from './captureEntries.js';
8
11
  import { captureUrl } from './captureEntry.js';
9
12
  import { isBrowserClosedError } from './captureInterrupt.js';
@@ -11,12 +14,14 @@ import { readCaptureManifest } from './captureManifest.js';
11
14
  import { resolveCaptureDirectoryServer, resolveServer, resolveStaticServer } from './captureServer.js';
12
15
  import { runCaptureSuite } from './captureSuite.js';
13
16
  import { runCaptureValidation } from './captureValidation.js';
17
+ import { runCaptureBatch } from './captureWorkflow.js';
14
18
  const USAGE = `usage:
15
19
  tool-capture observe <url> [--out <dir>] [--wait <ms>] [--frames <n>]
16
20
  tool-capture capture [--manifest <file>] (--url <url> | --dir <built-dir>) [options]
17
21
  tool-capture capture --tool <examples|functional> [options]
18
22
  tool-capture validate [--manifest <file>] (--url <url> | --dir <built-dir>) [options]
19
23
  tool-capture validate --tool <examples|functional> [options]
24
+ tool-capture batch [--config <file>] [--only <subject>] [--subjects-parallel <n>] [options]
20
25
 
21
26
  capture options:
22
27
  --filter <name> --renderer <ids> --out <dir> --wait <ms> --frames <n>
@@ -27,6 +32,9 @@ validation options:
27
32
  --report --update-fingerprints --no-regression --no-parity
28
33
  --stability-epsilon <n> --regression-tolerance <n> --parity-tolerance <n>
29
34
 
35
+ batch options:
36
+ --config <file> defaults to tool-capture.batch.json; remaining options override every subject
37
+
30
38
  Manifest: { "subject": "app", "entries": [{ "name": "home", "renderers": ["webgl"],
31
39
  "routes": { "webgl": "pages/home/" } }] }`;
32
40
  function flag(argv, key) {
@@ -58,7 +66,7 @@ async function resolveCaptureCliSuite(argv) {
58
66
  else {
59
67
  const conventionalManifest = resolve(root, 'tool-capture.json');
60
68
  if (!existsSync(conventionalManifest))
61
- throw new Error(`capture/validate requires --manifest or --tool\n${USAGE}`);
69
+ throw new Error(`suite requires --manifest or --tool\n${USAGE}`);
62
70
  manifest = readCaptureManifest(conventionalManifest);
63
71
  subject = flag(argv, 'subject') ?? manifest.subject;
64
72
  entries = manifest.entries;
@@ -88,31 +96,18 @@ async function resolveCaptureCliSuite(argv) {
88
96
  console.log(`Ready at ${server.url}\n`);
89
97
  }
90
98
  else {
91
- throw new Error(`capture/validate requires --url or --dir for manifest suites\n${USAGE}`);
99
+ throw new Error(`suite requires --url or --dir for manifest suites\n${USAGE}`);
92
100
  }
93
101
  return { entries, manifest, root, server, subject };
94
102
  }
95
103
  async function capture(argv) {
96
104
  const { subject, entries, server, root } = await resolveCaptureCliSuite(argv);
97
- const frames = flag(argv, 'frames');
98
- const parallel = flag(argv, 'parallel');
99
105
  const result = await runCaptureSuite({
106
+ ...captureOptions(argv),
100
107
  subject,
101
108
  entries,
102
109
  server,
103
110
  root,
104
- outBase: flag(argv, 'out') ?? '.artifacts',
105
- filter: flag(argv, 'filter'),
106
- rendererFilter: (flag(argv, 'renderer') ?? '').split(',').filter(Boolean),
107
- extraWait: parseNonNegativeInteger(flag(argv, 'wait'), 0),
108
- captureFrames: parseNonNegativeInteger(frames?.split(',')[0], 0),
109
- workerCount: Math.max(1, parseNonNegativeInteger(parallel, 6)),
110
- sequential: hasFlag(argv, 'sequential'),
111
- updateBaseline: hasFlag(argv, 'update-baseline'),
112
- failOnChanged: hasFlag(argv, 'fail-on-changed'),
113
- failOnError: hasFlag(argv, 'fail-on-error'),
114
- observe: hasFlag(argv, 'observe'),
115
- verify: hasFlag(argv, 'verify') ? true : hasFlag(argv, 'no-verify') ? false : undefined,
116
111
  });
117
112
  if (result.aborted)
118
113
  return 130;
@@ -121,10 +116,35 @@ async function capture(argv) {
121
116
  async function validate(argv) {
122
117
  const { subject, entries, server, root, manifest } = await resolveCaptureCliSuite(argv);
123
118
  const result = await runCaptureValidation({
119
+ ...validationOptions(argv, subject, manifest),
124
120
  subject,
125
121
  entries,
126
122
  server,
127
123
  root,
124
+ });
125
+ if (result.aborted)
126
+ return 130;
127
+ return result.shouldFail ? 1 : 0;
128
+ }
129
+ function captureOptions(argv) {
130
+ const frames = flag(argv, 'frames');
131
+ return {
132
+ outBase: flag(argv, 'out') ?? '.artifacts',
133
+ filter: flag(argv, 'filter'),
134
+ rendererFilter: (flag(argv, 'renderer') ?? '').split(',').filter(Boolean),
135
+ extraWait: parseNonNegativeInteger(flag(argv, 'wait'), 0),
136
+ captureFrames: parseNonNegativeInteger(frames?.split(',')[0], 0),
137
+ workerCount: Math.max(1, parseNonNegativeInteger(flag(argv, 'parallel'), 6)),
138
+ sequential: hasFlag(argv, 'sequential'),
139
+ updateBaseline: hasFlag(argv, 'update-baseline'),
140
+ failOnChanged: hasFlag(argv, 'fail-on-changed'),
141
+ failOnError: hasFlag(argv, 'fail-on-error'),
142
+ observe: hasFlag(argv, 'observe'),
143
+ verify: hasFlag(argv, 'verify') ? true : hasFlag(argv, 'no-verify') ? false : undefined,
144
+ };
145
+ }
146
+ function validationOptions(argv, subject, manifest) {
147
+ return {
128
148
  filter: flag(argv, 'filter'),
129
149
  rendererFilter: (flag(argv, 'renderer') ?? '').split(',').filter(Boolean),
130
150
  captureFrames: Math.max(1, parseNonNegativeInteger(flag(argv, 'frames'), 1)),
@@ -139,6 +159,41 @@ async function validate(argv) {
139
159
  workerCount: Math.max(1, parseNonNegativeInteger(flag(argv, 'parallel'), 6)),
140
160
  fingerprintSkip: manifest?.validation?.fingerprintSkip ?? (manifest === null && subject === 'examples' ? ['playingsound'] : []),
141
161
  paritySkip: manifest?.validation?.paritySkip ?? (manifest === null ? FLIGHT_PARITY_SKIP : {}),
162
+ };
163
+ }
164
+ async function batch(argv) {
165
+ const root = resolve(flag(argv, 'root') ?? process.cwd());
166
+ const configPath = resolve(root, flag(argv, 'config') ?? 'tool-capture.batch.json');
167
+ const manifest = readCaptureBatchManifest(configPath);
168
+ const only = flag(argv, 'only');
169
+ const globalArgs = removeBatchOptions(argv);
170
+ const subjects = manifest.subjects
171
+ .filter((subject) => only === undefined || subject.name === only)
172
+ .map((subject) => ({
173
+ name: subject.name,
174
+ async resolve() {
175
+ // Put global CLI arguments first: flag() deliberately takes the first occurrence, making
176
+ // command-line values batch-wide overrides of subject defaults.
177
+ const subjectArgv = [...globalArgs, ...subject.args];
178
+ const suite = await resolveCaptureCliSuite(subjectArgv);
179
+ const operations = new Set(subject.operations ?? ['capture', 'validate']);
180
+ return {
181
+ subject: suite.subject,
182
+ entries: suite.entries,
183
+ server: suite.server,
184
+ root: suite.root,
185
+ capture: operations.has('capture') ? captureOptions(subjectArgv) : false,
186
+ validation: operations.has('validate')
187
+ ? validationOptions(subjectArgv, suite.subject, suite.manifest)
188
+ : false,
189
+ };
190
+ },
191
+ }));
192
+ if (subjects.length === 0)
193
+ throw new Error(`No batch subject matched --only=${only ?? ''}`);
194
+ const result = await runCaptureBatch({
195
+ subjects,
196
+ subjectWorkerCount: Math.max(1, parseNonNegativeInteger(flag(argv, 'subjects-parallel'), 1)),
142
197
  });
143
198
  if (result.aborted)
144
199
  return 130;
@@ -164,6 +219,8 @@ async function main() {
164
219
  process.exit(await capture(argv));
165
220
  if (command === 'validate')
166
221
  process.exit(await validate(argv));
222
+ if (command === 'batch')
223
+ process.exit(await batch(argv));
167
224
  console.error(USAGE);
168
225
  process.exit(2);
169
226
  }
@@ -179,6 +236,18 @@ function parseNumber(value) {
179
236
  const parsed = Number.parseFloat(value);
180
237
  return Number.isFinite(parsed) ? parsed : undefined;
181
238
  }
239
+ function removeBatchOptions(argv) {
240
+ const result = [];
241
+ for (let index = 0; index < argv.length; index++) {
242
+ const argument = argv[index];
243
+ const key = ['config', 'only', 'subjects-parallel'].find((candidate) => argument === `--${candidate}` || argument.startsWith(`--${candidate}=`));
244
+ if (key === undefined)
245
+ result.push(argument);
246
+ else if (argument === `--${key}`)
247
+ index++;
248
+ }
249
+ return result;
250
+ }
182
251
  const FLIGHT_PARITY_SKIP = {
183
252
  playingvideo: 'all',
184
253
  'effect-hue-saturation': ['canvas'],
package/dist/bin.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"bin.js","sourceRoot":"","sources":["../src/bin.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"bin.js","sourceRoot":"","sources":["../src/bin.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,14 @@
1
+ export type CaptureBatchOperation = 'capture' | 'validate';
2
+ export interface CaptureBatchManifestSubject {
3
+ name: string;
4
+ args: string[];
5
+ operations?: CaptureBatchOperation[];
6
+ }
7
+ export interface CaptureBatchManifest {
8
+ subjects: CaptureBatchManifestSubject[];
9
+ }
10
+ /** Parses a multi-subject plan whose args are forwarded to the existing capture/validate option surface. */
11
+ export declare function parseCaptureBatchManifest(source: string, sourceName?: string): CaptureBatchManifest;
12
+ /** Reads and parses a capture batch manifest from disk. */
13
+ export declare function readCaptureBatchManifest(path: string): CaptureBatchManifest;
14
+ //# sourceMappingURL=captureBatchManifest.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"captureBatchManifest.d.ts","sourceRoot":"","sources":["../src/captureBatchManifest.ts"],"names":[],"mappings":"AAEA,MAAM,MAAM,qBAAqB,GAAG,SAAS,GAAG,UAAU,CAAC;AAE3D,MAAM,WAAW,2BAA2B;IAC1C,IAAI,EAAE,MAAM,CAAC;IACb,IAAI,EAAE,MAAM,EAAE,CAAC;IACf,UAAU,CAAC,EAAE,qBAAqB,EAAE,CAAC;CACtC;AAED,MAAM,WAAW,oBAAoB;IACnC,QAAQ,EAAE,2BAA2B,EAAE,CAAC;CACzC;AAED,4GAA4G;AAC5G,wBAAgB,yBAAyB,CACvC,MAAM,EAAE,MAAM,EACd,UAAU,GAAE,MAAiC,GAC5C,oBAAoB,CAoBtB;AAED,2DAA2D;AAC3D,wBAAgB,wBAAwB,CAAC,IAAI,EAAE,MAAM,GAAG,oBAAoB,CAE3E"}
@@ -0,0 +1,30 @@
1
+ import { readFileSync } from 'node:fs';
2
+ /** Parses a multi-subject plan whose args are forwarded to the existing capture/validate option surface. */
3
+ export function parseCaptureBatchManifest(source, sourceName = 'capture batch manifest') {
4
+ const value = JSON.parse(source);
5
+ if (!Array.isArray(value.subjects) || value.subjects.length === 0) {
6
+ throw new Error(`${sourceName}: missing non-empty subjects array`);
7
+ }
8
+ for (const subject of value.subjects) {
9
+ if (typeof subject?.name !== 'string' || subject.name === '') {
10
+ throw new Error(`${sourceName}: every subject needs a name`);
11
+ }
12
+ if (!isStringArray(subject.args))
13
+ throw new Error(`${sourceName}: subject ${subject.name} needs an args array`);
14
+ if (subject.operations !== undefined &&
15
+ (!Array.isArray(subject.operations) ||
16
+ subject.operations.length === 0 ||
17
+ subject.operations.some((operation) => operation !== 'capture' && operation !== 'validate'))) {
18
+ throw new Error(`${sourceName}: subject ${subject.name} has invalid operations`);
19
+ }
20
+ }
21
+ return value;
22
+ }
23
+ /** Reads and parses a capture batch manifest from disk. */
24
+ export function readCaptureBatchManifest(path) {
25
+ return parseCaptureBatchManifest(readFileSync(path, 'utf8'), path);
26
+ }
27
+ function isStringArray(value) {
28
+ return Array.isArray(value) && value.every((item) => typeof item === 'string');
29
+ }
30
+ //# sourceMappingURL=captureBatchManifest.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"captureBatchManifest.js","sourceRoot":"","sources":["../src/captureBatchManifest.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,YAAY,EAAE,MAAM,SAAS,CAAC;AAcvC,4GAA4G;AAC5G,MAAM,UAAU,yBAAyB,CACvC,MAAc,EACd,aAAqB,wBAAwB;IAE7C,MAAM,KAAK,GAAG,IAAI,CAAC,KAAK,CAAC,MAAM,CAAkC,CAAC;IAClE,IAAI,CAAC,KAAK,CAAC,OAAO,CAAC,KAAK,CAAC,QAAQ,CAAC,IAAI,KAAK,CAAC,QAAQ,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;QAClE,MAAM,IAAI,KAAK,CAAC,GAAG,UAAU,oCAAoC,CAAC,CAAC;IACrE,CAAC;IACD,KAAK,MAAM,OAAO,IAAI,KAAK,CAAC,QAAQ,EAAE,CAAC;QACrC,IAAI,OAAO,OAAO,EAAE,IAAI,KAAK,QAAQ,IAAI,OAAO,CAAC,IAAI,KAAK,EAAE,EAAE,CAAC;YAC7D,MAAM,IAAI,KAAK,CAAC,GAAG,UAAU,8BAA8B,CAAC,CAAC;QAC/D,CAAC;QACD,IAAI,CAAC,aAAa,CAAC,OAAO,CAAC,IAAI,CAAC;YAAE,MAAM,IAAI,KAAK,CAAC,GAAG,UAAU,aAAa,OAAO,CAAC,IAAI,sBAAsB,CAAC,CAAC;QAChH,IACE,OAAO,CAAC,UAAU,KAAK,SAAS;YAChC,CAAC,CAAC,KAAK,CAAC,OAAO,CAAC,OAAO,CAAC,UAAU,CAAC;gBACjC,OAAO,CAAC,UAAU,CAAC,MAAM,KAAK,CAAC;gBAC/B,OAAO,CAAC,UAAU,CAAC,IAAI,CAAC,CAAC,SAAS,EAAE,EAAE,CAAC,SAAS,KAAK,SAAS,IAAI,SAAS,KAAK,UAAU,CAAC,CAAC,EAC9F,CAAC;YACD,MAAM,IAAI,KAAK,CAAC,GAAG,UAAU,aAAa,OAAO,CAAC,IAAI,yBAAyB,CAAC,CAAC;QACnF,CAAC;IACH,CAAC;IACD,OAAO,KAA6B,CAAC;AACvC,CAAC;AAED,2DAA2D;AAC3D,MAAM,UAAU,wBAAwB,CAAC,IAAY;IACnD,OAAO,yBAAyB,CAAC,YAAY,CAAC,IAAI,EAAE,MAAM,CAAC,EAAE,IAAI,CAAC,CAAC;AACrE,CAAC;AAED,SAAS,aAAa,CAAC,KAAc;IACnC,OAAO,KAAK,CAAC,OAAO,CAAC,KAAK,CAAC,IAAI,KAAK,CAAC,KAAK,CAAC,CAAC,IAAI,EAAE,EAAE,CAAC,OAAO,IAAI,KAAK,QAAQ,CAAC,CAAC;AACjF,CAAC"}
@@ -0,0 +1,48 @@
1
+ import type { Entry } from './captureEntries.js';
2
+ import type { Server } from './captureServer.js';
3
+ import type { CaptureSuiteOptions, CaptureSuiteResult } from './captureSuite.js';
4
+ import type { CaptureValidationOptions, CaptureValidationResult } from './captureValidation.js';
5
+ export type CaptureWorkflowCaptureOptions = Omit<CaptureSuiteOptions, 'entries' | 'root' | 'server' | 'subject'>;
6
+ export type CaptureWorkflowValidationOptions = Omit<CaptureValidationOptions, 'entries' | 'root' | 'server' | 'subject'>;
7
+ export interface CaptureWorkflowOptions {
8
+ subject: string;
9
+ entries: Readonly<Entry[]>;
10
+ server: Server;
11
+ root?: string;
12
+ /** Screenshot/log/status pass. Defaults to enabled; set false for validation-only workflows. */
13
+ capture?: Readonly<CaptureWorkflowCaptureOptions> | false;
14
+ /** Fingerprint parity/regression pass. Defaults to enabled; set false for capture-only workflows. */
15
+ validation?: Readonly<CaptureWorkflowValidationOptions> | false;
16
+ }
17
+ export interface CaptureWorkflowResult {
18
+ aborted: boolean;
19
+ capture: CaptureSuiteResult | null;
20
+ shouldFail: boolean;
21
+ validation: CaptureValidationResult | null;
22
+ }
23
+ /** Runs lazily-resolved subject workflows through a bounded worker pool and returns one aggregate verdict. */
24
+ export declare function runCaptureBatch(options: Readonly<CaptureBatchOptions>): Promise<CaptureBatchResult>;
25
+ export interface CaptureBatchSubject {
26
+ name: string;
27
+ resolve(): Promise<CaptureWorkflowOptions>;
28
+ }
29
+ export interface CaptureBatchOptions {
30
+ subjects: Readonly<CaptureBatchSubject[]>;
31
+ /** Number of subjects processed concurrently. Resource concurrency remains configured per subject. */
32
+ subjectWorkerCount?: number;
33
+ }
34
+ export interface CaptureBatchSubjectResult {
35
+ error: string | null;
36
+ name: string;
37
+ result: CaptureWorkflowResult | null;
38
+ }
39
+ export interface CaptureBatchResult {
40
+ aborted: boolean;
41
+ failed: number;
42
+ passed: number;
43
+ shouldFail: boolean;
44
+ subjects: CaptureBatchSubjectResult[];
45
+ }
46
+ /** Runs the enabled capture and validation passes for one subject against one shared server. */
47
+ export declare function runCaptureWorkflow(options: Readonly<CaptureWorkflowOptions>): Promise<CaptureWorkflowResult>;
48
+ //# sourceMappingURL=captureWorkflow.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"captureWorkflow.d.ts","sourceRoot":"","sources":["../src/captureWorkflow.ts"],"names":[],"mappings":"AAMA,OAAO,KAAK,EAAE,KAAK,EAAE,MAAM,qBAAqB,CAAC;AACjD,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,oBAAoB,CAAC;AACjD,OAAO,KAAK,EAAE,mBAAmB,EAAE,kBAAkB,EAAE,MAAM,mBAAmB,CAAC;AAEjF,OAAO,KAAK,EAAE,wBAAwB,EAAE,uBAAuB,EAAE,MAAM,wBAAwB,CAAC;AAGhG,MAAM,MAAM,6BAA6B,GAAG,IAAI,CAAC,mBAAmB,EAAE,SAAS,GAAG,MAAM,GAAG,QAAQ,GAAG,SAAS,CAAC,CAAC;AACjH,MAAM,MAAM,gCAAgC,GAAG,IAAI,CACjD,wBAAwB,EACxB,SAAS,GAAG,MAAM,GAAG,QAAQ,GAAG,SAAS,CAC1C,CAAC;AAEF,MAAM,WAAW,sBAAsB;IACrC,OAAO,EAAE,MAAM,CAAC;IAChB,OAAO,EAAE,QAAQ,CAAC,KAAK,EAAE,CAAC,CAAC;IAC3B,MAAM,EAAE,MAAM,CAAC;IACf,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,gGAAgG;IAChG,OAAO,CAAC,EAAE,QAAQ,CAAC,6BAA6B,CAAC,GAAG,KAAK,CAAC;IAC1D,qGAAqG;IACrG,UAAU,CAAC,EAAE,QAAQ,CAAC,gCAAgC,CAAC,GAAG,KAAK,CAAC;CACjE;AAED,MAAM,WAAW,qBAAqB;IACpC,OAAO,EAAE,OAAO,CAAC;IACjB,OAAO,EAAE,kBAAkB,GAAG,IAAI,CAAC;IACnC,UAAU,EAAE,OAAO,CAAC;IACpB,UAAU,EAAE,uBAAuB,GAAG,IAAI,CAAC;CAC5C;AAED,8GAA8G;AAC9G,wBAAsB,eAAe,CAAC,OAAO,EAAE,QAAQ,CAAC,mBAAmB,CAAC,GAAG,OAAO,CAAC,kBAAkB,CAAC,CAgCzG;AAED,MAAM,WAAW,mBAAmB;IAClC,IAAI,EAAE,MAAM,CAAC;IACb,OAAO,IAAI,OAAO,CAAC,sBAAsB,CAAC,CAAC;CAC5C;AAED,MAAM,WAAW,mBAAmB;IAClC,QAAQ,EAAE,QAAQ,CAAC,mBAAmB,EAAE,CAAC,CAAC;IAC1C,sGAAsG;IACtG,kBAAkB,CAAC,EAAE,MAAM,CAAC;CAC7B;AAED,MAAM,WAAW,yBAAyB;IACxC,KAAK,EAAE,MAAM,GAAG,IAAI,CAAC;IACrB,IAAI,EAAE,MAAM,CAAC;IACb,MAAM,EAAE,qBAAqB,GAAG,IAAI,CAAC;CACtC;AAED,MAAM,WAAW,kBAAkB;IACjC,OAAO,EAAE,OAAO,CAAC;IACjB,MAAM,EAAE,MAAM,CAAC;IACf,MAAM,EAAE,MAAM,CAAC;IACf,UAAU,EAAE,OAAO,CAAC;IACpB,QAAQ,EAAE,yBAAyB,EAAE,CAAC;CACvC;AAED,gGAAgG;AAChG,wBAAsB,kBAAkB,CAAC,OAAO,EAAE,QAAQ,CAAC,sBAAsB,CAAC,GAAG,OAAO,CAAC,qBAAqB,CAAC,CAkClH"}
@@ -0,0 +1,71 @@
1
+ // High-level capture + fingerprint-validation workflow. The lower-level passes continue to own their
2
+ // browser contexts; this layer lends both the same server and closes it once the complete subject has
3
+ // finished, avoiding a duplicate build/server startup for the common smoke-then-verify workflow.
4
+ import pc from 'picocolors';
5
+ import { runCaptureSuite } from './captureSuite.js';
6
+ import { runCaptureValidation } from './captureValidation.js';
7
+ /** Runs lazily-resolved subject workflows through a bounded worker pool and returns one aggregate verdict. */
8
+ export async function runCaptureBatch(options) {
9
+ if (options.subjects.length === 0)
10
+ throw new Error('No capture batch subjects found');
11
+ const jobs = options.subjects.map((subject, index) => ({ index, subject }));
12
+ const results = Array.from({ length: jobs.length });
13
+ const activeWorkers = Math.min(Math.max(1, options.subjectWorkerCount ?? 1), jobs.length);
14
+ await Promise.all(Array.from({ length: activeWorkers }, async () => {
15
+ while (true) {
16
+ const job = jobs.shift();
17
+ if (job === undefined)
18
+ return;
19
+ console.log(`${pc.bold(`Subject ${job.index + 1}/${results.length}:`)} ${job.subject.name}\n`);
20
+ try {
21
+ const result = await runCaptureWorkflow(await job.subject.resolve());
22
+ results[job.index] = { error: null, name: job.subject.name, result };
23
+ }
24
+ catch (error) {
25
+ const message = error instanceof Error ? error.message : String(error);
26
+ console.error(pc.red(`${job.subject.name}: ${message}\n`));
27
+ results[job.index] = { error: message, name: job.subject.name, result: null };
28
+ }
29
+ }
30
+ }));
31
+ const failed = results.filter((subject) => subject.error !== null || subject.result?.shouldFail === true).length;
32
+ const aborted = results.some((subject) => subject.result?.aborted === true);
33
+ const passed = results.length - failed;
34
+ const shouldFail = failed > 0;
35
+ console.log(`${shouldFail ? pc.red('✗ failed') : pc.green('✓ passed')} ${passed} subjects passed ${failed} subjects failed${aborted ? pc.yellow(' — interrupted') : ''}`);
36
+ return { aborted, failed, passed, shouldFail, subjects: results };
37
+ }
38
+ /** Runs the enabled capture and validation passes for one subject against one shared server. */
39
+ export async function runCaptureWorkflow(options) {
40
+ const borrowedServer = { url: options.server.url, kill() { } };
41
+ let capture = null;
42
+ let validation = null;
43
+ try {
44
+ if (options.capture !== false) {
45
+ capture = await runCaptureSuite({
46
+ ...options.capture,
47
+ subject: options.subject,
48
+ entries: options.entries,
49
+ server: borrowedServer,
50
+ root: options.root,
51
+ });
52
+ }
53
+ if (capture?.aborted !== true && options.validation !== false) {
54
+ validation = await runCaptureValidation({
55
+ ...options.validation,
56
+ subject: options.subject,
57
+ entries: options.entries,
58
+ server: borrowedServer,
59
+ root: options.root,
60
+ });
61
+ }
62
+ }
63
+ finally {
64
+ options.server.kill();
65
+ }
66
+ const aborted = capture?.aborted === true || validation?.aborted === true;
67
+ const shouldFail = capture?.shouldFail === true || validation?.shouldFail === true;
68
+ console.log(`${pc.bold(options.subject)} workflow ${shouldFail ? pc.red('failed') : aborted ? pc.yellow('interrupted') : pc.green('passed')}\n`);
69
+ return { aborted, capture, shouldFail, validation };
70
+ }
71
+ //# sourceMappingURL=captureWorkflow.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"captureWorkflow.js","sourceRoot":"","sources":["../src/captureWorkflow.ts"],"names":[],"mappings":"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"}
package/dist/index.d.ts CHANGED
@@ -1,5 +1,6 @@
1
1
  export * from './baselineStore';
2
2
  export * from './captureBrowser';
3
+ export * from './captureBatchManifest';
3
4
  export * from './captureEntries';
4
5
  export * from './captureEntry';
5
6
  export * from './captureFormat';
@@ -9,6 +10,7 @@ export * from './captureRenderTarget';
9
10
  export * from './captureServer';
10
11
  export * from './captureSuite';
11
12
  export * from './captureValidation';
13
+ export * from './captureWorkflow';
12
14
  export * from './functionalScenes';
13
15
  export * from './functionalVerify';
14
16
  export * from './referenceCapture';
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,cAAc,iBAAiB,CAAC;AAChC,cAAc,kBAAkB,CAAC;AACjC,cAAc,kBAAkB,CAAC;AACjC,cAAc,gBAAgB,CAAC;AAC/B,cAAc,iBAAiB,CAAC;AAChC,cAAc,oBAAoB,CAAC;AACnC,cAAc,mBAAmB,CAAC;AAClC,cAAc,uBAAuB,CAAC;AACtC,cAAc,iBAAiB,CAAC;AAChC,cAAc,gBAAgB,CAAC;AAC/B,cAAc,qBAAqB,CAAC;AACpC,cAAc,oBAAoB,CAAC;AACnC,cAAc,oBAAoB,CAAC;AACnC,cAAc,oBAAoB,CAAC"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,cAAc,iBAAiB,CAAC;AAChC,cAAc,kBAAkB,CAAC;AACjC,cAAc,wBAAwB,CAAC;AACvC,cAAc,kBAAkB,CAAC;AACjC,cAAc,gBAAgB,CAAC;AAC/B,cAAc,iBAAiB,CAAC;AAChC,cAAc,oBAAoB,CAAC;AACnC,cAAc,mBAAmB,CAAC;AAClC,cAAc,uBAAuB,CAAC;AACtC,cAAc,iBAAiB,CAAC;AAChC,cAAc,gBAAgB,CAAC;AAC/B,cAAc,qBAAqB,CAAC;AACpC,cAAc,mBAAmB,CAAC;AAClC,cAAc,oBAAoB,CAAC;AACnC,cAAc,oBAAoB,CAAC;AACnC,cAAc,oBAAoB,CAAC"}
package/dist/index.js CHANGED
@@ -1,5 +1,6 @@
1
1
  export * from './baselineStore';
2
2
  export * from './captureBrowser';
3
+ export * from './captureBatchManifest';
3
4
  export * from './captureEntries';
4
5
  export * from './captureEntry';
5
6
  export * from './captureFormat';
@@ -9,6 +10,7 @@ export * from './captureRenderTarget';
9
10
  export * from './captureServer';
10
11
  export * from './captureSuite';
11
12
  export * from './captureValidation';
13
+ export * from './captureWorkflow';
12
14
  export * from './functionalScenes';
13
15
  export * from './functionalVerify';
14
16
  export * from './referenceCapture';
package/dist/index.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,cAAc,iBAAiB,CAAC;AAChC,cAAc,kBAAkB,CAAC;AACjC,cAAc,kBAAkB,CAAC;AACjC,cAAc,gBAAgB,CAAC;AAC/B,cAAc,iBAAiB,CAAC;AAChC,cAAc,oBAAoB,CAAC;AACnC,cAAc,mBAAmB,CAAC;AAClC,cAAc,uBAAuB,CAAC;AACtC,cAAc,iBAAiB,CAAC;AAChC,cAAc,gBAAgB,CAAC;AAC/B,cAAc,qBAAqB,CAAC;AACpC,cAAc,oBAAoB,CAAC;AACnC,cAAc,oBAAoB,CAAC;AACnC,cAAc,oBAAoB,CAAC"}
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,cAAc,iBAAiB,CAAC;AAChC,cAAc,kBAAkB,CAAC;AACjC,cAAc,wBAAwB,CAAC;AACvC,cAAc,kBAAkB,CAAC;AACjC,cAAc,gBAAgB,CAAC;AAC/B,cAAc,iBAAiB,CAAC;AAChC,cAAc,oBAAoB,CAAC;AACnC,cAAc,mBAAmB,CAAC;AAClC,cAAc,uBAAuB,CAAC;AACtC,cAAc,iBAAiB,CAAC;AAChC,cAAc,gBAAgB,CAAC;AAC/B,cAAc,qBAAqB,CAAC;AACpC,cAAc,mBAAmB,CAAC;AAClC,cAAc,oBAAoB,CAAC;AACnC,cAAc,oBAAoB,CAAC;AACnC,cAAc,oBAAoB,CAAC"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@flighthq/tool-capture",
3
- "version": "0.2.1-next.448.afbdd31",
3
+ "version": "0.2.1-next.451.d9a4a4e",
4
4
  "repository": {
5
5
  "type": "git",
6
6
  "url": "https://github.com/flighthq/flight.git",
@@ -35,10 +35,10 @@
35
35
  "clean:dist": "tsx ../../scripts/clean-package-dist.ts"
36
36
  },
37
37
  "dependencies": {
38
- "@flighthq/capture": "0.2.1-next.448.afbdd31",
39
- "@flighthq/render-wgpu": "0.2.1-next.448.afbdd31",
40
- "@flighthq/surface": "0.2.1-next.448.afbdd31",
41
- "@flighthq/types": "0.2.1-next.448.afbdd31",
38
+ "@flighthq/capture": "0.2.1-next.451.d9a4a4e",
39
+ "@flighthq/render-wgpu": "0.2.1-next.451.d9a4a4e",
40
+ "@flighthq/surface": "0.2.1-next.451.d9a4a4e",
41
+ "@flighthq/types": "0.2.1-next.451.d9a4a4e",
42
42
  "@playwright/test": "^1.50.0",
43
43
  "picocolors": "^1.1.1"
44
44
  },
@@ -0,0 +1,49 @@
1
+ import { mkdtempSync, rmSync, writeFileSync } from 'node:fs';
2
+ import { tmpdir } from 'node:os';
3
+ import { join } from 'node:path';
4
+
5
+ import { describe, expect, it } from 'vitest';
6
+
7
+ import { parseCaptureBatchManifest, readCaptureBatchManifest } from './captureBatchManifest';
8
+
9
+ describe('parseCaptureBatchManifest', () => {
10
+ it('parses subject arguments and optional operations', () => {
11
+ expect(
12
+ parseCaptureBatchManifest(
13
+ JSON.stringify({
14
+ subjects: [
15
+ { name: 'icons', args: ['--manifest=icons/tool-capture.json', '--url=http://localhost:5173'] },
16
+ { name: 'models', args: ['--manifest=models/tool-capture.json'], operations: ['validate'] },
17
+ ],
18
+ }),
19
+ ),
20
+ ).toEqual({
21
+ subjects: [
22
+ { name: 'icons', args: ['--manifest=icons/tool-capture.json', '--url=http://localhost:5173'] },
23
+ { name: 'models', args: ['--manifest=models/tool-capture.json'], operations: ['validate'] },
24
+ ],
25
+ });
26
+ });
27
+
28
+ it('rejects empty and malformed plans', () => {
29
+ expect(() => parseCaptureBatchManifest('{}')).toThrow(/subjects/);
30
+ expect(() => parseCaptureBatchManifest('{"subjects":[]}')).toThrow(/subjects/);
31
+ expect(() => parseCaptureBatchManifest('{"subjects":[{"name":"icons","args":true}]}')).toThrow(/args/);
32
+ expect(() =>
33
+ parseCaptureBatchManifest('{"subjects":[{"name":"icons","args":[],"operations":["publish"]}]}'),
34
+ ).toThrow(/operations/);
35
+ });
36
+ });
37
+
38
+ describe('readCaptureBatchManifest', () => {
39
+ it('reads and parses a batch plan from disk', () => {
40
+ const directory = mkdtempSync(join(tmpdir(), 'capture-batch-'));
41
+ const path = join(directory, 'tool-capture.batch.json');
42
+ writeFileSync(path, '{"subjects":[{"name":"icons","args":[]}]}');
43
+ try {
44
+ expect(readCaptureBatchManifest(path)).toEqual({ subjects: [{ name: 'icons', args: [] }] });
45
+ } finally {
46
+ rmSync(directory, { recursive: true, force: true });
47
+ }
48
+ });
49
+ });
@@ -0,0 +1,58 @@
1
+ import { describe, expect, it } from 'vitest';
2
+
3
+ import { runCaptureBatch, runCaptureWorkflow } from './captureWorkflow';
4
+
5
+ describe('runCaptureBatch', () => {
6
+ it('exports the batch orchestrator', () => {
7
+ expect(typeof runCaptureBatch).toBe('function');
8
+ });
9
+
10
+ it('rejects an empty batch before launching browser work', async () => {
11
+ await expect(runCaptureBatch({ subjects: [] })).rejects.toThrow(/No capture batch subjects/);
12
+ });
13
+
14
+ it('continues after a subject setup error and aggregates the verdict', async () => {
15
+ const result = await runCaptureBatch({
16
+ subjectWorkerCount: 2,
17
+ subjects: [
18
+ {
19
+ name: 'ready',
20
+ resolve: async () => ({
21
+ subject: 'ready',
22
+ entries: [],
23
+ server: { url: 'http://localhost:1', kill() {} },
24
+ capture: false,
25
+ validation: false,
26
+ }),
27
+ },
28
+ {
29
+ name: 'broken',
30
+ resolve: () => Promise.reject(new Error('server did not start')),
31
+ },
32
+ ],
33
+ });
34
+ expect(result.passed).toBe(1);
35
+ expect(result.failed).toBe(1);
36
+ expect(result.shouldFail).toBe(true);
37
+ expect(result.subjects[1]?.error).toBe('server did not start');
38
+ });
39
+ });
40
+
41
+ describe('runCaptureWorkflow', () => {
42
+ it('exports the subject orchestrator', () => {
43
+ expect(typeof runCaptureWorkflow).toBe('function');
44
+ });
45
+
46
+ it('owns the subject server once across the workflow', async () => {
47
+ let kills = 0;
48
+ const result = await runCaptureWorkflow({
49
+ subject: 'fixture',
50
+ entries: [],
51
+ server: { url: 'http://localhost:1', kill: () => kills++ },
52
+ capture: false,
53
+ validation: false,
54
+ });
55
+ expect(kills).toBe(1);
56
+ expect(result).toEqual({ aborted: false, capture: null, shouldFail: false, validation: null });
57
+ });
58
+ });