@a11ign/screenreader-fleet 0.4.0 → 0.4.1
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/compare-workers.d.mts +17 -1
- package/dist/compare-workers.mjs +30 -9
- package/dist/doctor.d.mts +19 -1
- package/dist/doctor.mjs +28 -7
- package/dist/fleet-env.d.mts +21 -0
- package/dist/fleet-env.mjs +43 -8
- package/package.json +1 -1
|
@@ -1,2 +1,18 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
|
-
|
|
2
|
+
/**
|
|
3
|
+
* Where the report is written: under the caller's `--runs-dir=`, else the monorepo's own `runs/`, else a refusal naming
|
|
4
|
+
* the directory and the flag (a11ign/a11ign#3767).
|
|
5
|
+
*
|
|
6
|
+
* Resolved from THIS module, never the cwd -- same reason as `doctor.mjs`'s `runsDirFor`, which this duplicates because
|
|
7
|
+
* this package cannot import `@a11ign/lab`'s canonical `runs/` resolution without a dependency cycle. From an INSTALLED
|
|
8
|
+
* package `../../../` is `node_modules`, so the default would write the report under the dependency. A supplied
|
|
9
|
+
* directory need not exist: the report's own `mkdirSync` makes it, which is what asking for one means.
|
|
10
|
+
* `baseDir` is INJECTED so a test can stand in for either layout.
|
|
11
|
+
*
|
|
12
|
+
* @param {{ argv?: readonly string[], baseDir?: string }} [options]
|
|
13
|
+
* @returns {string}
|
|
14
|
+
*/
|
|
15
|
+
export function outDirFor({ argv, baseDir }?: {
|
|
16
|
+
argv?: readonly string[];
|
|
17
|
+
baseDir?: string;
|
|
18
|
+
}): string;
|
package/dist/compare-workers.mjs
CHANGED
|
@@ -1,11 +1,11 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
|
-
import { mkdirSync, realpathSync, writeFileSync } from "node:fs";
|
|
2
|
+
import { existsSync, mkdirSync, realpathSync, writeFileSync } from "node:fs";
|
|
3
3
|
import { fileURLToPath, pathToFileURL } from "node:url";
|
|
4
4
|
import { execFileSync } from "node:child_process";
|
|
5
5
|
import { resolve } from "node:path";
|
|
6
6
|
import { describeProbe, probeHealth, WORKER_PROBE_TIMEOUT_MS } from "./probe-outcome.mjs";
|
|
7
7
|
import { CAPTURE_CLIENT_TIMEOUT_MS, requestJson } from "./worker-http.mjs";
|
|
8
|
-
import { refuseUnknownFlags } from "./cli-flags.mjs";
|
|
8
|
+
import { refuseUnknownFlags, flagValue } from "./cli-flags.mjs";
|
|
9
9
|
async function refuseIfBusy(workers, { what, timeoutMs = WORKER_PROBE_TIMEOUT_MS, request }) {
|
|
10
10
|
const states = await Promise.all(workers.map(async (worker)=>{
|
|
11
11
|
const probe = await probeHealth(worker, {
|
|
@@ -221,12 +221,22 @@ function diffHost(before, after) {
|
|
|
221
221
|
}
|
|
222
222
|
refuseUnknownFlags([
|
|
223
223
|
"--rounds=",
|
|
224
|
-
"--runs="
|
|
224
|
+
"--runs=",
|
|
225
|
+
"--runs-dir="
|
|
225
226
|
], {
|
|
226
227
|
entry: import.meta.url,
|
|
227
228
|
command: "npm run worker:compare"
|
|
228
229
|
});
|
|
229
|
-
const
|
|
230
|
+
const MODULE_DIR = fileURLToPath(new URL(".", import.meta.url));
|
|
231
|
+
const isMonorepoRoot = (root)=>existsSync(resolve(root, "packages")) && existsSync(resolve(root, "package.json"));
|
|
232
|
+
function outDirFor({ argv = process.argv.slice(2), baseDir = MODULE_DIR } = {}) {
|
|
233
|
+
const supplied = flagValue(argv, "runs-dir");
|
|
234
|
+
if ("" === supplied) throw new Error("worker:compare: --runs-dir= is empty. Pass --runs-dir=<the runs directory>.");
|
|
235
|
+
if (void 0 !== supplied) return resolve(supplied, "worker-compare");
|
|
236
|
+
const root = resolve(baseDir, "..", "..", "..");
|
|
237
|
+
if (isMonorepoRoot(root)) return resolve(root, "runs", "worker-compare");
|
|
238
|
+
throw new Error(`worker:compare: no runs directory: ${root} is not a checkout (this is an installed package), so there is no runs/ to write worker-compare/ under. Pass --runs-dir=<the runs directory>.`);
|
|
239
|
+
}
|
|
230
240
|
const MS_PER_S = 1000;
|
|
231
241
|
function refuseIfRunsReadonly() {
|
|
232
242
|
if ("1" !== process.env.A11Y_RUNS_READONLY) return;
|
|
@@ -234,6 +244,14 @@ function refuseIfRunsReadonly() {
|
|
|
234
244
|
console.error(" Unset A11Y_RUNS_READONLY to run this for real.");
|
|
235
245
|
process.exit(3);
|
|
236
246
|
}
|
|
247
|
+
function refuseUnlessOutDir() {
|
|
248
|
+
try {
|
|
249
|
+
return outDirFor();
|
|
250
|
+
} catch (error) {
|
|
251
|
+
process.stderr.write(`${error.message}\n`);
|
|
252
|
+
return process.exit(2);
|
|
253
|
+
}
|
|
254
|
+
}
|
|
237
255
|
const compare_workers_args = process.argv.slice(2);
|
|
238
256
|
const runs = Number(compare_workers_args.find((a)=>a.startsWith("--rounds="))?.slice(9) ?? compare_workers_args.find((a)=>a.startsWith("--runs="))?.slice(7) ?? 6);
|
|
239
257
|
const [page, ...compare_workers_workers] = compare_workers_args.filter((a)=>!a.startsWith("--"));
|
|
@@ -297,6 +315,7 @@ async function main() {
|
|
|
297
315
|
process.stderr.write("usage: npm run worker:compare -- <page-url> <worker> <worker> [--rounds=6]\n");
|
|
298
316
|
process.exit(2);
|
|
299
317
|
}
|
|
318
|
+
const outDir = refuseUnlessOutDir();
|
|
300
319
|
refuseIfRunsReadonly();
|
|
301
320
|
await refuseIfBusy(compare_workers_workers, {
|
|
302
321
|
what: `worker:compare against ${page}`
|
|
@@ -334,10 +353,11 @@ async function main() {
|
|
|
334
353
|
results,
|
|
335
354
|
vitalsBefore,
|
|
336
355
|
vitalsAfter,
|
|
337
|
-
hostBefore
|
|
356
|
+
hostBefore,
|
|
357
|
+
outDir
|
|
338
358
|
});
|
|
339
359
|
}
|
|
340
|
-
function report({ results, vitalsBefore, vitalsAfter, hostBefore }) {
|
|
360
|
+
function report({ results, vitalsBefore, vitalsAfter, hostBefore, outDir }) {
|
|
341
361
|
const allPhases = [
|
|
342
362
|
...new Set(Object.values(results).flatMap((r)=>r.phases.flatMap(Object.keys)))
|
|
343
363
|
];
|
|
@@ -355,10 +375,10 @@ function report({ results, vitalsBefore, vitalsAfter, hostBefore }) {
|
|
|
355
375
|
const { foundations, hostAfter } = reportFoundations({
|
|
356
376
|
hostBefore
|
|
357
377
|
});
|
|
358
|
-
mkdirSync(
|
|
378
|
+
mkdirSync(outDir, {
|
|
359
379
|
recursive: true
|
|
360
380
|
});
|
|
361
|
-
writeFileSync(resolve(
|
|
381
|
+
writeFileSync(resolve(outDir, "compare.json"), JSON.stringify({
|
|
362
382
|
page: page,
|
|
363
383
|
rounds: runs,
|
|
364
384
|
results,
|
|
@@ -368,7 +388,7 @@ function report({ results, vitalsBefore, vitalsAfter, hostBefore }) {
|
|
|
368
388
|
hostBefore,
|
|
369
389
|
hostAfter
|
|
370
390
|
}, null, 2) + "\n", "utf8");
|
|
371
|
-
process.stdout.write(`\nReport: ${resolve(
|
|
391
|
+
process.stdout.write(`\nReport: ${resolve(outDir, "compare.json")}\n`);
|
|
372
392
|
}
|
|
373
393
|
function reportWallTime({ results, vitalsBefore, vitalsAfter }) {
|
|
374
394
|
const wallSeconds = Object.fromEntries(compare_workers_workers.map((w)=>[
|
|
@@ -458,3 +478,4 @@ function reportFoundations({ hostBefore }) {
|
|
|
458
478
|
};
|
|
459
479
|
}
|
|
460
480
|
if (import.meta.url === pathToFileURL(process.argv[1] ? realpathSync(process.argv[1]) : "").href) await main();
|
|
481
|
+
export { outDirFor };
|
package/dist/doctor.d.mts
CHANGED
|
@@ -1,4 +1,21 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
|
+
/**
|
|
3
|
+
* The `runs/` directory doctor reads the dataset from: the caller's `--runs-dir=`, else the monorepo's own `runs/`,
|
|
4
|
+
* else a refusal naming the directory and the flag (a11ign/a11ign#3767).
|
|
5
|
+
*
|
|
6
|
+
* `@a11ign/lab` owns the canonical `runs/` resolution (`packages/lab/src/dataset-paths.mjs`), but `lab` depends on
|
|
7
|
+
* `worker-fleet`, so this package cannot import it without a cycle: the same computation, duplicated (and again in
|
|
8
|
+
* `compare-workers.mjs`) rather than left cwd-anchored. From an INSTALLED package `../../../` is `node_modules`, so the
|
|
9
|
+
* default is taken only when that directory is a checkout; a missing `runs/` inside one is normal (a fresh clone).
|
|
10
|
+
* `baseDir` is INJECTED so a test can stand in for either layout.
|
|
11
|
+
*
|
|
12
|
+
* @param {{ argv?: readonly string[], baseDir?: string }} [options]
|
|
13
|
+
* @returns {string}
|
|
14
|
+
*/
|
|
15
|
+
export function runsDirFor({ argv, baseDir }?: {
|
|
16
|
+
argv?: readonly string[];
|
|
17
|
+
baseDir?: string;
|
|
18
|
+
}): string;
|
|
2
19
|
/**
|
|
3
20
|
* The remedy for a failed local-pool query, as a runnable command plus the advice that is not one.
|
|
4
21
|
*
|
|
@@ -198,7 +215,7 @@ export function errorDocument(error: unknown): {
|
|
|
198
215
|
* The whole run, as a function of its steps and its streams, returning an exit code.
|
|
199
216
|
*
|
|
200
217
|
* @param {{ steps?: (() => unknown)[], json?: boolean, out?: (line: string) => void,
|
|
201
|
-
* err?: (line: string) => void }} [deps]
|
|
218
|
+
* err?: (line: string) => void, runsDir?: () => string }} [deps]
|
|
202
219
|
* @returns {Promise<number>}
|
|
203
220
|
*/
|
|
204
221
|
export function doctorRun(deps?: {
|
|
@@ -206,6 +223,7 @@ export function doctorRun(deps?: {
|
|
|
206
223
|
json?: boolean;
|
|
207
224
|
out?: (line: string) => void;
|
|
208
225
|
err?: (line: string) => void;
|
|
226
|
+
runsDir?: () => string;
|
|
209
227
|
}): Promise<number>;
|
|
210
228
|
export function addCheck(name: string, ok: boolean, detail: string, remedy?: string | null | {
|
|
211
229
|
fix: string | null;
|
package/dist/doctor.mjs
CHANGED
|
@@ -10,7 +10,7 @@ import { availableHostMemoryMb, workersHostCanRun } from "./host-capacity.mjs";
|
|
|
10
10
|
import { fleetConsistency, describeMismatches } from "./fleet-consistency.mjs";
|
|
11
11
|
import { fleetScriptPaths } from "./src_fleet-scripts_mjs.mjs";
|
|
12
12
|
import { namedInventoryWorkers, configuredWorkers } from "./fleet-env.mjs";
|
|
13
|
-
import { refuseUnknownFlags } from "./cli-flags.mjs";
|
|
13
|
+
import { refuseUnknownFlags, flagValue } from "./cli-flags.mjs";
|
|
14
14
|
import { requestJson } from "./worker-http.mjs";
|
|
15
15
|
import { sandboxGitEnv } from "./src_git-safe-env_mjs.mjs";
|
|
16
16
|
import { assessWorker } from "./worker-health.mjs";
|
|
@@ -72,18 +72,32 @@ function shimInvocation(shim, script, args) {
|
|
|
72
72
|
};
|
|
73
73
|
}
|
|
74
74
|
refuseUnknownFlags([
|
|
75
|
-
"--json"
|
|
75
|
+
"--json",
|
|
76
|
+
"--runs-dir="
|
|
76
77
|
], {
|
|
77
78
|
entry: import.meta.url,
|
|
78
79
|
command: "pnpm run doctor"
|
|
79
80
|
});
|
|
80
81
|
const doctor_run = promisify(execFile);
|
|
81
82
|
const JSON_OUT = process.argv.includes("--json");
|
|
83
|
+
const REFUSED = 2;
|
|
82
84
|
const WORKERS_ENV = configuredWorkers();
|
|
83
85
|
const PAGES_PORT = Number(process.env.DATASET_PAGES_PORT || 5050);
|
|
84
86
|
const CTL = fleetScriptPaths().workerCtl;
|
|
85
87
|
const SCORER_MODEL_DIR = fileURLToPath(new URL("../../scorer/models/screenreader-scorer/", import.meta.url));
|
|
86
|
-
const
|
|
88
|
+
const MODULE_DIR = fileURLToPath(new URL(".", import.meta.url));
|
|
89
|
+
const isMonorepoRoot = (root)=>external_node_fs_existsSync(resolve(root, "packages")) && external_node_fs_existsSync(resolve(root, "package.json"));
|
|
90
|
+
function runsDirFor({ argv = process.argv.slice(2), baseDir = MODULE_DIR } = {}) {
|
|
91
|
+
const supplied = flagValue(argv, "runs-dir");
|
|
92
|
+
if (void 0 !== supplied) {
|
|
93
|
+
if (external_node_fs_existsSync(supplied)) return resolve(supplied);
|
|
94
|
+
throw new Error(`doctor: --runs-dir=${supplied} does not exist. Pass --runs-dir=<the runs directory>.`);
|
|
95
|
+
}
|
|
96
|
+
const root = resolve(baseDir, "..", "..", "..");
|
|
97
|
+
if (isMonorepoRoot(root)) return resolve(root, "runs");
|
|
98
|
+
throw new Error(`doctor: no runs directory: ${root} is not a checkout (this is an installed package), so there is no runs/ to default to. Pass --runs-dir=<the runs directory>.`);
|
|
99
|
+
}
|
|
100
|
+
const datasetDir = ()=>resolve(runsDirFor(), "screenreader-dataset");
|
|
87
101
|
const PROBE_TIMEOUT_MS = 8000;
|
|
88
102
|
const checks = [];
|
|
89
103
|
const GATES = Object.freeze({
|
|
@@ -419,7 +433,7 @@ function checkHostCapacity(pool) {
|
|
|
419
433
|
add("host memory", true, limit >= poolSize ? detail : `${detail}; the rest stay stopped so the run does not swap (override: A11Y_MAX_WORKERS)`);
|
|
420
434
|
}
|
|
421
435
|
async function checkDatasetPages() {
|
|
422
|
-
const manifestPath = resolve(
|
|
436
|
+
const manifestPath = resolve(datasetDir(), "manifest.json");
|
|
423
437
|
if (!external_node_fs_existsSync(manifestPath)) return add("dataset", false, "no manifest — the dataset has not been generated", "pnpm run training:generate");
|
|
424
438
|
const sample = JSON.parse(readFileSync(manifestPath, "utf8")).cases?.[0]?.id;
|
|
425
439
|
const probe = sample ? `${sample}/good.html` : "";
|
|
@@ -434,7 +448,7 @@ async function checkDatasetPages() {
|
|
|
434
448
|
}
|
|
435
449
|
}
|
|
436
450
|
function checkRunState() {
|
|
437
|
-
const progress = resolve(
|
|
451
|
+
const progress = resolve(datasetDir(), "capture-progress.json");
|
|
438
452
|
if (!external_node_fs_existsSync(progress)) return add("run", true, "no capture run recorded");
|
|
439
453
|
const p = JSON.parse(readFileSync(progress, "utf8"));
|
|
440
454
|
if (!p.startedAt) return add("run", true, "no capture run recorded");
|
|
@@ -475,7 +489,14 @@ function errorDocument(error) {
|
|
|
475
489
|
};
|
|
476
490
|
}
|
|
477
491
|
async function doctorRun(deps = {}) {
|
|
478
|
-
const { steps = DEFAULT_STEPS, json = JSON_OUT, out = console.log, err = console.error } = deps;
|
|
492
|
+
const { steps = DEFAULT_STEPS, json = JSON_OUT, out = console.log, err = console.error, runsDir = runsDirFor } = deps;
|
|
493
|
+
try {
|
|
494
|
+
runsDir();
|
|
495
|
+
} catch (error) {
|
|
496
|
+
if (json) out(JSON.stringify(errorDocument(error), null, 2));
|
|
497
|
+
else err(error.message);
|
|
498
|
+
return REFUSED;
|
|
499
|
+
}
|
|
479
500
|
try {
|
|
480
501
|
for (const step of steps)await step();
|
|
481
502
|
} catch (error) {
|
|
@@ -511,4 +532,4 @@ async function main() {
|
|
|
511
532
|
process.exit(await doctorRun());
|
|
512
533
|
}
|
|
513
534
|
if (import.meta.url === pathToFileURL(process.argv[1] ? external_node_fs_realpathSync(process.argv[1]) : "").href) await main();
|
|
514
|
-
export { addCheck, allChecks, checkoutRootFor, doctorRun, errorDocument, fleetAgreementLine, gatingChecks, isRunnableCommand, nextCommand, readyFrom, resolvesToThisCheckout, tscProjectUpToDate, workerControlFix };
|
|
535
|
+
export { addCheck, allChecks, checkoutRootFor, doctorRun, errorDocument, fleetAgreementLine, gatingChecks, isRunnableCommand, nextCommand, readyFrom, resolvesToThisCheckout, runsDirFor, tscProjectUpToDate, workerControlFix };
|
package/dist/fleet-env.d.mts
CHANGED
|
@@ -20,6 +20,27 @@ export function configuredWorkers(): Array<{
|
|
|
20
20
|
name: string;
|
|
21
21
|
url: string;
|
|
22
22
|
}>;
|
|
23
|
+
/**
|
|
24
|
+
* The two files the COMMAND reads, from the caller or else from the monorepo layout, and a refusal naming the path
|
|
25
|
+
* and the flag when the one it would read is not there (a11ign/a11ign#3767).
|
|
26
|
+
*
|
|
27
|
+
* `INVENTORY` above points into `packages/control`, which an installed `@a11ign/screenreader-fleet` does not have, so
|
|
28
|
+
* `fleet-env --list` there died on an ENOENT for a path nobody could have guessed. The library functions keep their
|
|
29
|
+
* default because their answer for "no inventory here" is `[]`, which is supported; a command that prints
|
|
30
|
+
* `export A11Y_WORKERS=''` for a missing file would be the same silent wrong answer, so it refuses.
|
|
31
|
+
*
|
|
32
|
+
* `baseDir` is INJECTED so a test can stand in for either layout without moving a file.
|
|
33
|
+
*
|
|
34
|
+
* @param {{ argv?: readonly string[], baseDir?: string }} [options]
|
|
35
|
+
* @returns {{ inventoryPath: string, groupVarsPath: string }}
|
|
36
|
+
*/
|
|
37
|
+
export function inventoryPathsFor({ argv, baseDir }?: {
|
|
38
|
+
argv?: readonly string[];
|
|
39
|
+
baseDir?: string;
|
|
40
|
+
}): {
|
|
41
|
+
inventoryPath: string;
|
|
42
|
+
groupVarsPath: string;
|
|
43
|
+
};
|
|
23
44
|
/**
|
|
24
45
|
* Which group each line of the inventory sits in, index-aligned with `text.split(/\r?\n/)`.
|
|
25
46
|
*
|
package/dist/fleet-env.mjs
CHANGED
|
@@ -1,9 +1,12 @@
|
|
|
1
|
-
import { readFileSync } from "node:fs";
|
|
1
|
+
import { existsSync, readFileSync } from "node:fs";
|
|
2
|
+
import { resolve } from "node:path";
|
|
2
3
|
import { fileURLToPath, pathToFileURL } from "node:url";
|
|
3
4
|
import { assertWorkerUrl } from "./worker-http.mjs";
|
|
4
|
-
import { refuseUnknownFlags } from "./cli-flags.mjs";
|
|
5
|
+
import { refuseUnknownFlags, flagValue } from "./cli-flags.mjs";
|
|
5
6
|
refuseUnknownFlags([
|
|
6
|
-
"--list"
|
|
7
|
+
"--list",
|
|
8
|
+
"--inventory=",
|
|
9
|
+
"--group-vars="
|
|
7
10
|
], {
|
|
8
11
|
entry: import.meta.url,
|
|
9
12
|
command: "npm run fleet:env"
|
|
@@ -19,8 +22,32 @@ function configuredWorkers() {
|
|
|
19
22
|
url
|
|
20
23
|
}));
|
|
21
24
|
}
|
|
22
|
-
const
|
|
23
|
-
const
|
|
25
|
+
const MODULE_DIR = fileURLToPath(new URL(".", import.meta.url));
|
|
26
|
+
const monorepoAnsibleFile = (relative, baseDir = MODULE_DIR)=>resolve(baseDir, "..", "..", "control", "ansible", relative);
|
|
27
|
+
const INVENTORY = monorepoAnsibleFile("inventory.yml");
|
|
28
|
+
const GROUP_VARS = monorepoAnsibleFile("group_vars/a11y_workers.yml");
|
|
29
|
+
function inventoryPathsFor({ argv = process.argv.slice(2), baseDir = MODULE_DIR } = {}) {
|
|
30
|
+
const inventoryPath = existingPath({
|
|
31
|
+
flag: "inventory",
|
|
32
|
+
supplied: flagValue(argv, "inventory"),
|
|
33
|
+
fallback: monorepoAnsibleFile("inventory.yml", baseDir)
|
|
34
|
+
});
|
|
35
|
+
const groupVarsPath = existingPath({
|
|
36
|
+
flag: "group-vars",
|
|
37
|
+
supplied: flagValue(argv, "group-vars"),
|
|
38
|
+
fallback: monorepoAnsibleFile("group_vars/a11y_workers.yml", baseDir)
|
|
39
|
+
});
|
|
40
|
+
return {
|
|
41
|
+
inventoryPath,
|
|
42
|
+
groupVarsPath
|
|
43
|
+
};
|
|
44
|
+
}
|
|
45
|
+
function existingPath({ flag, supplied, fallback }) {
|
|
46
|
+
const path = supplied ?? fallback;
|
|
47
|
+
if (existsSync(path)) return path;
|
|
48
|
+
const origin = void 0 === supplied ? "the monorepo layout this command defaults to has no such file" : "no such file";
|
|
49
|
+
throw new Error(`fleet:env: ${path} does not exist (${origin}). Pass --${flag}=<file>.`);
|
|
50
|
+
}
|
|
24
51
|
const HOST_LINE = /^\s*ansible_host\s*:\s*(\S+)\s*$/;
|
|
25
52
|
const SUSPECT = /ansible_host\s*:/;
|
|
26
53
|
const KEY_LINE = /^(\s*)([A-Za-z_][\w.-]*)\s*:/;
|
|
@@ -207,8 +234,16 @@ function fleetEnvOutput(text, { port = DEFAULT_WORKER_PORT, mode = "env" } = {})
|
|
|
207
234
|
};
|
|
208
235
|
}
|
|
209
236
|
function main() {
|
|
210
|
-
|
|
211
|
-
|
|
237
|
+
let paths;
|
|
238
|
+
try {
|
|
239
|
+
paths = inventoryPathsFor();
|
|
240
|
+
} catch (error) {
|
|
241
|
+
process.stderr.write(`${error.message}\n`);
|
|
242
|
+
process.exitCode = 2;
|
|
243
|
+
return;
|
|
244
|
+
}
|
|
245
|
+
const port = portFromGroupVars(readFileSync(paths.groupVarsPath, "utf8"));
|
|
246
|
+
const { stdout, stderr } = fleetEnvOutput(readFileSync(paths.inventoryPath, "utf8"), {
|
|
212
247
|
port,
|
|
213
248
|
mode: process.argv.includes("--list") ? "list" : "env"
|
|
214
249
|
});
|
|
@@ -216,4 +251,4 @@ function main() {
|
|
|
216
251
|
process.stdout.write(stdout);
|
|
217
252
|
}
|
|
218
253
|
if (import.meta.url === pathToFileURL(process.argv[1] ?? "").href) main();
|
|
219
|
-
export { DEFAULT_WORKER_PORT, WORKER_GROUP, configuredWorkers, fleetEnvOutput, groupPerLine, hostsOutOfCaptureSet, inventoryWorkerUrls, namedInventoryWorkers, portFromGroupVars, resolveWorkerPool, workerNamesFromInventory, workersFromInventory };
|
|
254
|
+
export { DEFAULT_WORKER_PORT, WORKER_GROUP, configuredWorkers, fleetEnvOutput, groupPerLine, hostsOutOfCaptureSet, inventoryPathsFor, inventoryWorkerUrls, namedInventoryWorkers, portFromGroupVars, resolveWorkerPool, workerNamesFromInventory, workersFromInventory };
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@a11ign/screenreader-fleet",
|
|
3
|
-
"version": "0.4.
|
|
3
|
+
"version": "0.4.1",
|
|
4
4
|
"description": "Host-side lifecycle, health and capacity for a fleet of Windows NVDA capture workers: lease one, judge whether it is degrading, and know how many the host can afford.",
|
|
5
5
|
"license": "AGPL-3.0-or-later",
|
|
6
6
|
"type": "module",
|