@williamthorsen/nmr 0.30.0 → 0.32.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/.readyup/kits/default.js +56 -16
- package/.readyup/manifest.json +34 -3
- package/README.md +265 -64
- package/agents/guidance/rulebooks/nmr.md +5 -2
- package/bin/nmr-report-catalog.js +11 -0
- package/dist/esm/UserError.d.ts +3 -0
- package/dist/esm/UserError.js +6 -0
- package/dist/esm/check-cache.d.ts +36 -1
- package/dist/esm/check-cache.js +91 -23
- package/dist/esm/cli-build.js +2 -1
- package/dist/esm/cli-clean.js +2 -1
- package/dist/esm/cli-ensure-prepublish-hooks.js +4 -24
- package/dist/esm/cli-report-catalog.d.ts +1 -0
- package/dist/esm/cli-report-catalog.js +11 -0
- package/dist/esm/cli-report-overrides.js +2 -1
- package/dist/esm/cli-taze.js +2 -1
- package/dist/esm/cli.js +2 -1
- package/dist/esm/commands/build-output.d.ts +1 -0
- package/dist/esm/commands/build-output.js +25 -2
- package/dist/esm/commands/build.d.ts +5 -1
- package/dist/esm/commands/build.js +22 -8
- package/dist/esm/commands/clean.js +12 -0
- package/dist/esm/commands/ensure-prepublish-hooks.d.ts +1 -0
- package/dist/esm/commands/ensure-prepublish-hooks.js +43 -0
- package/dist/esm/commands/report-catalog.d.ts +1 -0
- package/dist/esm/commands/report-catalog.js +40 -0
- package/dist/esm/commands/report-overrides.js +30 -7
- package/dist/esm/commands/taze.js +2 -1
- package/dist/esm/config.d.ts +1 -0
- package/dist/esm/config.js +66 -18
- package/dist/esm/default-scripts.d.ts +5 -1
- package/dist/esm/default-scripts.js +13 -10
- package/dist/esm/defineConfig.d.ts +1 -1
- package/dist/esm/help.js +3 -1
- package/dist/esm/helpers/clampToBytes.d.ts +2 -0
- package/dist/esm/helpers/clampToBytes.js +20 -0
- package/dist/esm/helpers/createBoundedBuffer.js +1 -4
- package/dist/esm/helpers/deriveExcerpt.d.ts +1 -0
- package/dist/esm/helpers/deriveExcerpt.js +30 -0
- package/dist/esm/helpers/duration.js +16 -9
- package/dist/esm/helpers/package-json.d.ts +11 -4
- package/dist/esm/helpers/package-json.js +51 -22
- package/dist/esm/helpers/readStringValues.d.ts +1 -0
- package/dist/esm/helpers/readStringValues.js +8 -0
- package/dist/esm/helpers/reportClosing.d.ts +1 -0
- package/dist/esm/helpers/reportClosing.js +3 -0
- package/dist/esm/helpers/transcript.d.ts +5 -0
- package/dist/esm/helpers/transcript.js +59 -0
- package/dist/esm/recording.d.ts +65 -0
- package/dist/esm/recording.js +96 -0
- package/dist/esm/replay-assembly.d.ts +9 -0
- package/dist/esm/replay-assembly.js +26 -0
- package/dist/esm/report-format.d.ts +18 -0
- package/dist/esm/report-format.js +25 -0
- package/dist/esm/reportCliFailure.d.ts +2 -0
- package/dist/esm/reportCliFailure.js +11 -0
- package/dist/esm/resolve-scripts.d.ts +1 -1
- package/dist/esm/resolver.d.ts +9 -1
- package/dist/esm/resolver.js +28 -18
- package/dist/esm/runCli.js +339 -74
- package/dist/esm/runner.d.ts +9 -3
- package/dist/esm/runner.js +25 -4
- package/dist/esm/scripts.d.ts +1 -1
- package/dist/esm/steps.d.ts +9 -2
- package/dist/esm/steps.js +117 -4
- package/dist/esm/types.d.ts +11 -2
- package/dist/esm/verbosity.d.ts +15 -4
- package/dist/esm/verbosity.js +32 -12
- package/dist/esm/verdict.d.ts +29 -0
- package/dist/esm/verdict.js +150 -0
- package/dist/esm/workspace.d.ts +2 -0
- package/dist/esm/workspace.js +20 -3
- package/package.json +14 -5
package/.readyup/kits/default.js
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
/** @noformat — @generated. Do not edit. Compiled by rdy. */
|
|
2
2
|
/* eslint-disable */
|
|
3
|
-
export const __readyupVersion = "0.
|
|
3
|
+
export const __readyupVersion = "0.28.0";
|
|
4
4
|
|
|
5
5
|
|
|
6
6
|
// .readyup/kits/default.ts
|
|
@@ -20,10 +20,12 @@ import {
|
|
|
20
20
|
|
|
21
21
|
// src/default-scripts.ts
|
|
22
22
|
var GATE_PROJECTS = "--project unit --project tool";
|
|
23
|
+
var TYPECHECK_STEP = { run: "typecheck", declinesArgs: true };
|
|
24
|
+
var ROOT_TYPECHECK_STEP = { run: "root:typecheck", declinesArgs: true };
|
|
23
25
|
var workspaceScripts = {
|
|
24
26
|
build: ["compile"],
|
|
25
|
-
check: [
|
|
26
|
-
"check:strict": [
|
|
27
|
+
check: [TYPECHECK_STEP, "fmt:check", "lint:check", "test"],
|
|
28
|
+
"check:strict": [TYPECHECK_STEP, "fmt:check", "lint:strict", "test:coverage"],
|
|
27
29
|
clean: "nmr-clean",
|
|
28
30
|
compile: "nmr-compile",
|
|
29
31
|
fix: ["lint", "fmt"],
|
|
@@ -33,6 +35,7 @@ var workspaceScripts = {
|
|
|
33
35
|
lint: "eslint --fix .",
|
|
34
36
|
"lint:check": "eslint .",
|
|
35
37
|
"lint:strict": "strict-lint",
|
|
38
|
+
"report-catalog": "nmr-report-catalog",
|
|
36
39
|
test: `pnpm exec vitest ${GATE_PROJECTS}`,
|
|
37
40
|
"test:all": "pnpm exec vitest",
|
|
38
41
|
"test:coverage": `pnpm exec vitest ${GATE_PROJECTS} --coverage`,
|
|
@@ -40,8 +43,9 @@ var workspaceScripts = {
|
|
|
40
43
|
"test:unit": "pnpm exec vitest --project unit",
|
|
41
44
|
"test:watch": `pnpm exec vitest ${GATE_PROJECTS} --watch`,
|
|
42
45
|
typecheck: "tsgo --noEmit",
|
|
43
|
-
// Without `--include-locked`, nothing would be reported in a repo that pins exact version numbers.
|
|
44
|
-
|
|
46
|
+
// Without `--include-locked`, nothing would be reported in a repo that pins exact version numbers. The
|
|
47
|
+
// command is a string because neither half names an nmr command: both are binaries.
|
|
48
|
+
upgrade: "nmr-report-catalog && nmr-taze --include-locked",
|
|
45
49
|
"view-coverage": "open coverage/index.html"
|
|
46
50
|
};
|
|
47
51
|
var rootScripts = {
|
|
@@ -49,10 +53,11 @@ var rootScripts = {
|
|
|
49
53
|
"audit:dev": "pnpm exec v11y --dev",
|
|
50
54
|
"audit:prod": "pnpm exec v11y --prod",
|
|
51
55
|
build: ["-R build"],
|
|
52
|
-
check: [
|
|
53
|
-
"check:strict": [
|
|
54
|
-
// Excludes the audit, which in CI has a workflow of its own.
|
|
55
|
-
|
|
56
|
+
check: [TYPECHECK_STEP, "fmt:check", "lint:check", "test"],
|
|
57
|
+
"check:strict": [TYPECHECK_STEP, "fmt:check", "lint:strict", "test:coverage"],
|
|
58
|
+
// Excludes the audit, which in CI has a workflow of its own. The build is what the narrowed check runs
|
|
59
|
+
// against, so it declines the arguments rather than being narrowed by them.
|
|
60
|
+
ci: [{ run: "build", declinesArgs: true }, "check:strict"],
|
|
56
61
|
clean: "nmr-clean",
|
|
57
62
|
fix: ["lint", "fmt"],
|
|
58
63
|
"fix:check": ["fmt:check", "lint:check"],
|
|
@@ -61,10 +66,11 @@ var rootScripts = {
|
|
|
61
66
|
lint: "eslint --fix .",
|
|
62
67
|
"lint:check": "eslint .",
|
|
63
68
|
"lint:strict": "strict-lint",
|
|
64
|
-
// The audit costs seconds and `ci` costs minutes, so the cheap gate fails first.
|
|
65
|
-
|
|
69
|
+
// The audit costs seconds and `ci` costs minutes, so the cheap gate fails first. The audit reads the
|
|
70
|
+
// dependency tree, which no argument narrowing the code under test says anything about.
|
|
71
|
+
prepush: [{ run: "audit", declinesArgs: true }, "ci"],
|
|
66
72
|
"report-overrides": "nmr-report-overrides",
|
|
67
|
-
"root:check": [
|
|
73
|
+
"root:check": [ROOT_TYPECHECK_STEP, "fmt:check", "root:lint:check", "root:test"],
|
|
68
74
|
"root:lint": "eslint --fix --ignore-pattern 'packages/**' .",
|
|
69
75
|
"root:lint:check": "eslint --ignore-pattern 'packages/**' .",
|
|
70
76
|
"root:lint:strict": "strict-lint --ignore-pattern 'packages/**' .",
|
|
@@ -73,15 +79,20 @@ var rootScripts = {
|
|
|
73
79
|
"root:test:tool": "vitest --config ./vitest.root.config.ts --project tool",
|
|
74
80
|
"root:test:unit": "vitest --config ./vitest.root.config.ts --project unit",
|
|
75
81
|
"root:typecheck": "tsgo --noEmit",
|
|
76
|
-
|
|
82
|
+
// Carries the override report for the same reason `upgrade` does: both end in the tool that rewrites a
|
|
83
|
+
// `pnpm.overrides` block, so both need the reporter's rejection ahead of them.
|
|
84
|
+
"root:upgrade": "nmr-report-overrides && nmr-taze --include-locked",
|
|
77
85
|
test: ["root:test", "-R test"],
|
|
78
86
|
"test:all": ["root:test:all", "-R test:all"],
|
|
79
87
|
"test:coverage": ["root:test", "-R test:coverage"],
|
|
80
88
|
"test:tool": ["root:test:tool", "-R test:tool"],
|
|
81
89
|
"test:unit": ["root:test:unit", "-R test:unit"],
|
|
82
90
|
"test:watch": `vitest ${GATE_PROJECTS} --watch`,
|
|
83
|
-
|
|
84
|
-
//
|
|
91
|
+
// Neither step is narrowable, so `nmr typecheck <file>` is rejected rather than checking that file under
|
|
92
|
+
// default options at the root and hunting for it in every package.
|
|
93
|
+
typecheck: [ROOT_TYPECHECK_STEP, { run: "-R typecheck", declinesArgs: true }],
|
|
94
|
+
// The command is a string because neither half names an nmr command: both are binaries, and a composite
|
|
95
|
+
// element can name only a command.
|
|
85
96
|
upgrade: "nmr-report-overrides && nmr-taze --include-locked --recursive"
|
|
86
97
|
};
|
|
87
98
|
|
|
@@ -168,6 +179,13 @@ var default_default = defineRdyKit({
|
|
|
168
179
|
check: toolVersionsHasNoPnpm,
|
|
169
180
|
fix: "Remove pnpm from .tool-versions \u2014 manage via packageManager field and corepack"
|
|
170
181
|
},
|
|
182
|
+
{
|
|
183
|
+
name: "no package.json declares a pnpm field",
|
|
184
|
+
severity: "error",
|
|
185
|
+
quiet: true,
|
|
186
|
+
check: () => noPnpmFieldInPackageJson(),
|
|
187
|
+
fix: "Move these settings into pnpm-workspace.yaml, quoting each version under `overrides`, or run `pnpx codemod run pnpm-v10-to-v11`. pnpm 11 reads no key from the `pnpm` field, so an override left there pins nothing while an upgrade run with `--write` goes on rewriting it"
|
|
188
|
+
},
|
|
171
189
|
{
|
|
172
190
|
name: ".config/nmr.config.ts uses defineConfig",
|
|
173
191
|
severity: "recommend",
|
|
@@ -376,7 +394,7 @@ function formatPaths(paths) {
|
|
|
376
394
|
${paths.map((path2) => ` ${path2}`).join("\n")}`;
|
|
377
395
|
}
|
|
378
396
|
function getMinVersion() {
|
|
379
|
-
const picked = { "version": "0.
|
|
397
|
+
const picked = { "version": "0.32.0" };
|
|
380
398
|
if (typeof picked["version"] !== "string") {
|
|
381
399
|
throw new TypeError("nmr/package.json: 'version' must be a string");
|
|
382
400
|
}
|
|
@@ -402,6 +420,15 @@ function isReExportOnly(content) {
|
|
|
402
420
|
const statements = content.replace(/\/\*[\s\S]*?\*\//g, "").replace(/^\s*\/\/.*$/gm, "").split("\n").map((line) => line.trim()).filter((line) => line.length > 0);
|
|
403
421
|
return statements.length > 0 && statements.every((line) => RE_EXPORT_LINE_PATTERN.test(line));
|
|
404
422
|
}
|
|
423
|
+
function noPnpmFieldInPackageJson(cwd = process.cwd()) {
|
|
424
|
+
const declaring = findFiles(["**/package.json"], cwd).flatMap((relativePath) => {
|
|
425
|
+
const keys = readPnpmFieldKeys(readFileIn(cwd, relativePath));
|
|
426
|
+
if (keys === void 0) return [];
|
|
427
|
+
return [keys.length > 0 ? `${relativePath} (${keys.join(", ")})` : relativePath];
|
|
428
|
+
});
|
|
429
|
+
if (declaring.length === 0) return true;
|
|
430
|
+
return { ok: false, detail: formatPaths(declaring) };
|
|
431
|
+
}
|
|
405
432
|
function noReExportOnlyVitestConfigs(cwd = process.cwd()) {
|
|
406
433
|
const nonRootConfigs = findFiles([`**/vitest.config.${CONFIG_EXTENSIONS}`], cwd).filter((path2) => path2.includes("/"));
|
|
407
434
|
const reExports = nonRootConfigs.filter((path2) => isReExportOnly(readFileIn(cwd, path2)));
|
|
@@ -453,6 +480,18 @@ function readFileIn(cwd, relativePath) {
|
|
|
453
480
|
return void 0;
|
|
454
481
|
}
|
|
455
482
|
}
|
|
483
|
+
function readPnpmFieldKeys(content) {
|
|
484
|
+
if (content === void 0) return void 0;
|
|
485
|
+
let parsed;
|
|
486
|
+
try {
|
|
487
|
+
parsed = JSON.parse(content);
|
|
488
|
+
} catch {
|
|
489
|
+
return void 0;
|
|
490
|
+
}
|
|
491
|
+
if (!isRecord(parsed)) return void 0;
|
|
492
|
+
const pnpm = parsed["pnpm"];
|
|
493
|
+
return isRecord(pnpm) ? Object.keys(pnpm).toSorted() : void 0;
|
|
494
|
+
}
|
|
456
495
|
function resolvesVersionViaWorkspace(range) {
|
|
457
496
|
return WORKSPACE_VERSION_MARKERS.some((marker) => range.startsWith(marker));
|
|
458
497
|
}
|
|
@@ -472,6 +511,7 @@ export {
|
|
|
472
511
|
everyTestFileNamesItsTier,
|
|
473
512
|
hasSupportedEslintVersion,
|
|
474
513
|
hasSupportedStrictLintVersion,
|
|
514
|
+
noPnpmFieldInPackageJson,
|
|
475
515
|
noReExportOnlyVitestConfigs,
|
|
476
516
|
noRetiredVitestConfigs,
|
|
477
517
|
prettierConfigBuildsOnSharedConfig,
|
package/.readyup/manifest.json
CHANGED
|
@@ -5,12 +5,43 @@
|
|
|
5
5
|
"checklists": [
|
|
6
6
|
"nmr"
|
|
7
7
|
],
|
|
8
|
+
"esbuildVersion": "0.28.1",
|
|
9
|
+
"inputs": [
|
|
10
|
+
{
|
|
11
|
+
"hash": "67afdcb4",
|
|
12
|
+
"kind": "module",
|
|
13
|
+
"path": "kits/default.ts"
|
|
14
|
+
},
|
|
15
|
+
{
|
|
16
|
+
"hash": "2bd89ec9",
|
|
17
|
+
"kind": "inline",
|
|
18
|
+
"path": "../package.json",
|
|
19
|
+
"paths": [
|
|
20
|
+
"version"
|
|
21
|
+
]
|
|
22
|
+
},
|
|
23
|
+
{
|
|
24
|
+
"hash": "3dfc2ee7",
|
|
25
|
+
"kind": "module",
|
|
26
|
+
"path": "../src/default-scripts.ts"
|
|
27
|
+
},
|
|
28
|
+
{
|
|
29
|
+
"hash": "b42c7523",
|
|
30
|
+
"kind": "module",
|
|
31
|
+
"path": "../src/resolve-scripts.ts"
|
|
32
|
+
},
|
|
33
|
+
{
|
|
34
|
+
"hash": "c2d21075",
|
|
35
|
+
"kind": "module",
|
|
36
|
+
"path": "../src/tiers.ts"
|
|
37
|
+
}
|
|
38
|
+
],
|
|
8
39
|
"name": "default",
|
|
9
40
|
"path": "kits/default.js",
|
|
10
|
-
"readyupVersion": "0.
|
|
41
|
+
"readyupVersion": "0.28.0",
|
|
11
42
|
"source": "kits/default.ts",
|
|
12
|
-
"sourceHash": "
|
|
13
|
-
"targetHash": "
|
|
43
|
+
"sourceHash": "67afdcb4",
|
|
44
|
+
"targetHash": "b923a4b4"
|
|
14
45
|
}
|
|
15
46
|
]
|
|
16
47
|
}
|