@williamthorsen/nmr 0.55.0 → 1.0.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/.meta/changelog.json +124 -0
- package/.readyup/kits/default.js +667 -167
- package/.readyup/manifest.json +77 -46
- package/CHANGELOG.md +40 -0
- package/README.md +1 -14
- package/agents/guidance/rulebooks/nmr.md +1 -1
- package/bin/ensure-prepublish-hooks.js +1 -1
- package/bin/nmr-actionlint.js +1 -1
- package/bin/nmr-clean.js +1 -1
- package/bin/nmr-compile.js +1 -1
- package/bin/nmr-fmt.js +1 -1
- package/bin/nmr-report-catalog.js +1 -1
- package/bin/nmr-report-overrides.js +1 -1
- package/bin/nmr-shellcheck.js +1 -1
- package/bin/nmr-taze.js +1 -1
- package/bin/nmr-vitest.js +1 -1
- package/bin/nmr.js +1 -1
- package/dist/esm/bins.d.ts +11 -0
- package/dist/esm/bins.js +11 -0
- package/dist/esm/check-cache-entries.js +5 -5
- package/dist/esm/check-cache-gate.js +2 -1
- package/dist/esm/child-env.js +2 -1
- package/dist/esm/child-process.d.ts +2 -0
- package/dist/esm/child-process.js +3 -3
- package/dist/esm/cli-actionlint.js +2 -1
- package/dist/esm/cli-build.js +2 -1
- package/dist/esm/cli-clean.js +2 -1
- package/dist/esm/cli-ensure-prepublish-hooks.js +29 -16
- package/dist/esm/cli-fmt.js +2 -1
- package/dist/esm/cli-report-catalog.js +2 -1
- package/dist/esm/cli-report-overrides.js +2 -1
- package/dist/esm/cli-shellcheck.js +2 -1
- package/dist/esm/cli-taze.js +2 -1
- package/dist/esm/cli-vitest.js +2 -1
- package/dist/esm/cli.js +2 -1
- package/dist/esm/commands/actionlint.d.ts +3 -3
- package/dist/esm/commands/actionlint.js +5 -5
- package/dist/esm/commands/build.js +6 -6
- package/dist/esm/commands/clean.js +3 -1
- package/dist/esm/commands/compiler.js +3 -3
- package/dist/esm/commands/ensure-prepublish-hooks.d.ts +1 -1
- package/dist/esm/commands/ensure-prepublish-hooks.js +4 -5
- package/dist/esm/commands/fmt.d.ts +3 -3
- package/dist/esm/commands/fmt.js +33 -52
- package/dist/esm/commands/format-targets.js +1 -13
- package/dist/esm/commands/node-pin.js +3 -4
- package/dist/esm/commands/rewrite-specifiers.js +2 -2
- package/dist/esm/commands/run-vitest.js +5 -5
- package/dist/esm/commands/shellcheck.d.ts +3 -3
- package/dist/esm/commands/shellcheck.js +8 -11
- package/dist/esm/commands/taze.js +5 -4
- package/dist/esm/commands/tsconfig-chain.js +3 -3
- package/dist/esm/commands/workflow-tools.d.ts +12 -3
- package/dist/esm/commands/workflow-tools.js +29 -14
- package/dist/esm/config-validation.js +9 -9
- package/dist/esm/config.js +2 -3
- package/dist/esm/delegate-host.d.ts +1 -1
- package/dist/esm/delegate-host.js +5 -3
- package/dist/esm/entry-chain.js +2 -3
- package/dist/esm/fan-out.d.ts +3 -3
- package/dist/esm/fan-out.js +14 -6
- package/dist/esm/git-ignored-paths.js +3 -3
- package/dist/esm/help.d.ts +14 -15
- package/dist/esm/help.js +29 -54
- package/dist/esm/helpers/filter-selection.js +2 -2
- package/dist/esm/helpers/package-json.js +8 -9
- package/dist/esm/helpers/resolveXdgBaseDir.d.ts +5 -0
- package/dist/esm/helpers/resolveXdgBaseDir.js +12 -0
- package/dist/esm/helpers/type-guards.d.ts +0 -2
- package/dist/esm/helpers/type-guards.js +2 -4
- package/dist/esm/invocation-args.d.ts +0 -32
- package/dist/esm/invocation-args.js +23 -121
- package/dist/esm/invocation.d.ts +3 -1
- package/dist/esm/invocation.js +1 -0
- package/dist/esm/machine-lock.js +3 -4
- package/dist/esm/nmr-flags.d.ts +109 -0
- package/dist/esm/nmr-flags.js +120 -0
- package/dist/esm/output-style.d.ts +1 -1
- package/dist/esm/output-style.js +2 -1
- package/dist/esm/pass-manifest.js +2 -2
- package/dist/esm/presentation.d.ts +1 -1
- package/dist/esm/remote-host-session.d.ts +2 -0
- package/dist/esm/remote-host-session.js +1 -0
- package/dist/esm/remote-probe.js +2 -2
- package/dist/esm/remote-run.d.ts +3 -3
- package/dist/esm/remote-run.js +6 -4
- package/dist/esm/remote-session.js +4 -4
- package/dist/esm/remote-snapshot.js +8 -22
- package/dist/esm/resolver.js +3 -4
- package/dist/esm/route.d.ts +29 -0
- package/dist/esm/route.js +94 -0
- package/dist/esm/run-chain.d.ts +1 -1
- package/dist/esm/run-chain.js +4 -2
- package/dist/esm/runCli.d.ts +2 -0
- package/dist/esm/runCli.js +36 -78
- package/dist/esm/stated-outcome.js +3 -3
- package/dist/esm/steps.js +6 -30
- package/dist/esm/user-config.js +7 -14
- package/dist/esm/vitest-source-resolution.js +5 -6
- package/dist/esm/vitest-temp-isolation.d.ts +2 -0
- package/dist/esm/vitest-temp-isolation.js +44 -0
- package/dist/esm/vitest.d.ts +9 -0
- package/dist/esm/vitest.js +8 -5
- package/docs/reporting.md +3 -3
- package/docs/scripts.md +1 -1
- package/docs/utilities.md +5 -5
- package/docs/vitest.md +11 -6
- package/package.json +4 -4
package/.readyup/manifest.json
CHANGED
|
@@ -3,12 +3,17 @@
|
|
|
3
3
|
"kits": [
|
|
4
4
|
{
|
|
5
5
|
"bundledDependencies": {
|
|
6
|
-
"@williamthorsen/toolbelt.
|
|
6
|
+
"@williamthorsen/toolbelt.arrays": "6.4.1",
|
|
7
|
+
"@williamthorsen/toolbelt.cli": "0.8.0",
|
|
8
|
+
"@williamthorsen/toolbelt.datetime": "4.1.1",
|
|
7
9
|
"@williamthorsen/toolbelt.errors": "0.9.0",
|
|
8
10
|
"@williamthorsen/toolbelt.filesystem": "0.10.0",
|
|
9
|
-
"@williamthorsen/toolbelt.
|
|
11
|
+
"@williamthorsen/toolbelt.guards": "4.2.0",
|
|
12
|
+
"@williamthorsen/toolbelt.numbers": "7.3.1",
|
|
10
13
|
"@williamthorsen/toolbelt.objects": "4.4.0",
|
|
11
14
|
"@williamthorsen/toolbelt.packaging": "0.7.0",
|
|
15
|
+
"@williamthorsen/toolbelt.sets": "3.1.0",
|
|
16
|
+
"@williamthorsen/toolbelt.strings": "8.2.1",
|
|
12
17
|
"@williamthorsen/toolbelt.terminal": "0.3.0",
|
|
13
18
|
"ansi-regex": "6.5.0",
|
|
14
19
|
"ansi-styles": "6.2.3",
|
|
@@ -27,7 +32,7 @@
|
|
|
27
32
|
"checklist": "nmr",
|
|
28
33
|
"checks": [
|
|
29
34
|
"@williamthorsen/nmr in devDependencies",
|
|
30
|
-
"@williamthorsen/nmr >= 0.
|
|
35
|
+
"@williamthorsen/nmr >= 1.0.0",
|
|
31
36
|
"pnpm-workspace.yaml exists",
|
|
32
37
|
"catalogued dependencies use catalog:",
|
|
33
38
|
"package.json has packageManager field",
|
|
@@ -41,6 +46,7 @@
|
|
|
41
46
|
".config/nmr.config.ts does not override lint:shell",
|
|
42
47
|
"no root install script runs lefthook install unguarded",
|
|
43
48
|
"all workspace packages can build",
|
|
49
|
+
"every publishable package declares prepublishOnly",
|
|
44
50
|
"every bin target is a committed wrapper",
|
|
45
51
|
"every bin wrapper's build-output target is covered by files",
|
|
46
52
|
"no retired Vitest config variants",
|
|
@@ -77,87 +83,97 @@
|
|
|
77
83
|
{
|
|
78
84
|
"hash": "bf29a9a3",
|
|
79
85
|
"kind": "module",
|
|
80
|
-
"path": "../../nmr-core/dist/esm/cache-store.js"
|
|
86
|
+
"path": "../../nmr-core/dist/esm/cache/cache-store.js"
|
|
81
87
|
},
|
|
82
88
|
{
|
|
83
|
-
"hash": "
|
|
89
|
+
"hash": "d2edf9e9",
|
|
84
90
|
"kind": "module",
|
|
85
|
-
"path": "../../nmr-core/dist/esm/
|
|
91
|
+
"path": "../../nmr-core/dist/esm/cli.js"
|
|
86
92
|
},
|
|
87
93
|
{
|
|
88
|
-
"hash": "
|
|
94
|
+
"hash": "6b7d0243",
|
|
89
95
|
"kind": "module",
|
|
90
|
-
"path": "../../nmr-core/dist/esm/
|
|
96
|
+
"path": "../../nmr-core/dist/esm/errors/hasErrnoCode.js"
|
|
91
97
|
},
|
|
92
98
|
{
|
|
93
|
-
"hash": "
|
|
99
|
+
"hash": "85d76864",
|
|
94
100
|
"kind": "module",
|
|
95
|
-
"path": "../../nmr-core/dist/esm/
|
|
101
|
+
"path": "../../nmr-core/dist/esm/errors/isAnticipatedFailure.js"
|
|
96
102
|
},
|
|
97
103
|
{
|
|
98
|
-
"hash": "
|
|
104
|
+
"hash": "e02e0a74",
|
|
99
105
|
"kind": "module",
|
|
100
|
-
"path": "../../nmr-core/dist/esm/
|
|
106
|
+
"path": "../../nmr-core/dist/esm/errors/UserError.js"
|
|
101
107
|
},
|
|
102
108
|
{
|
|
103
|
-
"hash": "
|
|
109
|
+
"hash": "77aa59f7",
|
|
104
110
|
"kind": "module",
|
|
105
|
-
"path": "../../nmr-core/dist/esm/
|
|
111
|
+
"path": "../../nmr-core/dist/esm/files/report-write-outcomes.js"
|
|
106
112
|
},
|
|
107
113
|
{
|
|
108
|
-
"hash": "
|
|
114
|
+
"hash": "5ae3e980",
|
|
109
115
|
"kind": "module",
|
|
110
|
-
"path": "../../nmr-core/dist/esm/
|
|
116
|
+
"path": "../../nmr-core/dist/esm/files/updateManagedFile.js"
|
|
111
117
|
},
|
|
112
118
|
{
|
|
113
|
-
"hash": "
|
|
119
|
+
"hash": "d377c37c",
|
|
114
120
|
"kind": "module",
|
|
115
|
-
"path": "../../nmr-core/dist/esm/
|
|
121
|
+
"path": "../../nmr-core/dist/esm/files/writeFileWithCheck.js"
|
|
116
122
|
},
|
|
117
123
|
{
|
|
118
|
-
"hash": "
|
|
124
|
+
"hash": "bc0baa4a",
|
|
119
125
|
"kind": "module",
|
|
120
|
-
"path": "../../nmr-core/dist/esm/
|
|
126
|
+
"path": "../../nmr-core/dist/esm/git/collectChangedPaths.js"
|
|
121
127
|
},
|
|
122
128
|
{
|
|
123
|
-
"hash": "
|
|
129
|
+
"hash": "70d519e7",
|
|
124
130
|
"kind": "module",
|
|
125
|
-
"path": "../../nmr-core/dist/esm/
|
|
131
|
+
"path": "../../nmr-core/dist/esm/git/gitObjects.js"
|
|
126
132
|
},
|
|
127
133
|
{
|
|
128
|
-
"hash": "
|
|
134
|
+
"hash": "d5a89448",
|
|
129
135
|
"kind": "module",
|
|
130
|
-
"path": "../../nmr-core/dist/esm/
|
|
136
|
+
"path": "../../nmr-core/dist/esm/git/gitOutputLimit.js"
|
|
131
137
|
},
|
|
132
138
|
{
|
|
133
|
-
"hash": "
|
|
139
|
+
"hash": "62be92c4",
|
|
134
140
|
"kind": "module",
|
|
135
|
-
"path": "../../nmr-core/dist/esm/
|
|
141
|
+
"path": "../../nmr-core/dist/esm/git/hashWorkingTree.js"
|
|
136
142
|
},
|
|
137
143
|
{
|
|
138
|
-
"hash": "
|
|
144
|
+
"hash": "6734717f",
|
|
139
145
|
"kind": "module",
|
|
140
|
-
"path": "../../nmr-core/dist/esm/
|
|
146
|
+
"path": "../../nmr-core/dist/esm/git/runGit.js"
|
|
141
147
|
},
|
|
142
148
|
{
|
|
143
|
-
"hash": "
|
|
149
|
+
"hash": "fe9fd44c",
|
|
144
150
|
"kind": "module",
|
|
145
|
-
"path": "../../nmr-core/dist/esm/
|
|
151
|
+
"path": "../../nmr-core/dist/esm/index.js"
|
|
146
152
|
},
|
|
147
153
|
{
|
|
148
|
-
"hash": "
|
|
154
|
+
"hash": "1d74f646",
|
|
149
155
|
"kind": "module",
|
|
150
|
-
"path": "../../nmr-core/dist/esm/
|
|
156
|
+
"path": "../../nmr-core/dist/esm/portable/isRecord.js"
|
|
151
157
|
},
|
|
152
158
|
{
|
|
153
|
-
"hash": "
|
|
159
|
+
"hash": "b88a9126",
|
|
154
160
|
"kind": "module",
|
|
155
|
-
"path": "../../nmr-core/dist/esm/
|
|
161
|
+
"path": "../../nmr-core/dist/esm/terminal.js"
|
|
156
162
|
},
|
|
157
163
|
{
|
|
158
|
-
"hash": "
|
|
164
|
+
"hash": "85afaf3e",
|
|
165
|
+
"kind": "module",
|
|
166
|
+
"path": "../../nmr-core/dist/esm/timer.js"
|
|
167
|
+
},
|
|
168
|
+
{
|
|
169
|
+
"hash": "c1eae24e",
|
|
170
|
+
"kind": "module",
|
|
171
|
+
"path": "../../nmr-core/dist/esm/workspace/workspace-patterns.js"
|
|
172
|
+
},
|
|
173
|
+
{
|
|
174
|
+
"hash": "995dcd83",
|
|
159
175
|
"kind": "module",
|
|
160
|
-
"path": "../../nmr-core/dist/esm/
|
|
176
|
+
"path": "../../nmr-core/dist/esm/workspace/workspace.js"
|
|
161
177
|
},
|
|
162
178
|
{
|
|
163
179
|
"hash": "9fd61bf4",
|
|
@@ -215,30 +231,35 @@
|
|
|
215
231
|
"path": "lib/vitest.ts"
|
|
216
232
|
},
|
|
217
233
|
{
|
|
218
|
-
"hash": "
|
|
234
|
+
"hash": "8c3ba269",
|
|
219
235
|
"kind": "module",
|
|
220
236
|
"path": "lib/workspace-build.ts"
|
|
221
237
|
},
|
|
222
238
|
{
|
|
223
|
-
"hash": "
|
|
239
|
+
"hash": "2afa0f3c",
|
|
224
240
|
"kind": "inline",
|
|
225
241
|
"path": "../package.json",
|
|
226
242
|
"paths": [
|
|
227
243
|
"version"
|
|
228
244
|
]
|
|
229
245
|
},
|
|
246
|
+
{
|
|
247
|
+
"hash": "eb0306ed",
|
|
248
|
+
"kind": "module",
|
|
249
|
+
"path": "../src/commands/ensure-prepublish-hooks.ts"
|
|
250
|
+
},
|
|
230
251
|
{
|
|
231
252
|
"hash": "578af9fd",
|
|
232
253
|
"kind": "module",
|
|
233
254
|
"path": "../src/config-check-cache.ts"
|
|
234
255
|
},
|
|
235
256
|
{
|
|
236
|
-
"hash": "
|
|
257
|
+
"hash": "378fb666",
|
|
237
258
|
"kind": "module",
|
|
238
259
|
"path": "../src/config-validation.ts"
|
|
239
260
|
},
|
|
240
261
|
{
|
|
241
|
-
"hash": "
|
|
262
|
+
"hash": "8cb3c082",
|
|
242
263
|
"kind": "module",
|
|
243
264
|
"path": "../src/config.ts"
|
|
244
265
|
},
|
|
@@ -248,7 +269,7 @@
|
|
|
248
269
|
"path": "../src/default-scripts.ts"
|
|
249
270
|
},
|
|
250
271
|
{
|
|
251
|
-
"hash": "
|
|
272
|
+
"hash": "b58621ab",
|
|
252
273
|
"kind": "module",
|
|
253
274
|
"path": "../src/git-ignored-paths.ts"
|
|
254
275
|
},
|
|
@@ -273,7 +294,7 @@
|
|
|
273
294
|
"path": "../src/helpers/hook-name.ts"
|
|
274
295
|
},
|
|
275
296
|
{
|
|
276
|
-
"hash": "
|
|
297
|
+
"hash": "62caa37e",
|
|
277
298
|
"kind": "module",
|
|
278
299
|
"path": "../src/helpers/package-json.ts"
|
|
279
300
|
},
|
|
@@ -283,17 +304,27 @@
|
|
|
283
304
|
"path": "../src/helpers/readStringValues.ts"
|
|
284
305
|
},
|
|
285
306
|
{
|
|
286
|
-
"hash": "
|
|
307
|
+
"hash": "e4cc5c20",
|
|
308
|
+
"kind": "module",
|
|
309
|
+
"path": "../src/helpers/reportClosing.ts"
|
|
310
|
+
},
|
|
311
|
+
{
|
|
312
|
+
"hash": "3f8448c9",
|
|
287
313
|
"kind": "module",
|
|
288
314
|
"path": "../src/helpers/type-guards.ts"
|
|
289
315
|
},
|
|
316
|
+
{
|
|
317
|
+
"hash": "77f6bb50",
|
|
318
|
+
"kind": "module",
|
|
319
|
+
"path": "../src/nmr-flags.ts"
|
|
320
|
+
},
|
|
290
321
|
{
|
|
291
322
|
"hash": "78ca6bd4",
|
|
292
323
|
"kind": "module",
|
|
293
324
|
"path": "../src/resolve-scripts.ts"
|
|
294
325
|
},
|
|
295
326
|
{
|
|
296
|
-
"hash": "
|
|
327
|
+
"hash": "5112becc",
|
|
297
328
|
"kind": "module",
|
|
298
329
|
"path": "../src/resolver.ts"
|
|
299
330
|
},
|
|
@@ -303,7 +334,7 @@
|
|
|
303
334
|
"path": "../src/shell-syntax.ts"
|
|
304
335
|
},
|
|
305
336
|
{
|
|
306
|
-
"hash": "
|
|
337
|
+
"hash": "1146fc58",
|
|
307
338
|
"kind": "module",
|
|
308
339
|
"path": "../src/steps.ts"
|
|
309
340
|
},
|
|
@@ -333,7 +364,7 @@
|
|
|
333
364
|
"readyupVersion": "0.45.0",
|
|
334
365
|
"source": "kits/default.ts",
|
|
335
366
|
"sourceHash": "9fd61bf4",
|
|
336
|
-
"targetHash": "
|
|
367
|
+
"targetHash": "5818d99b"
|
|
337
368
|
}
|
|
338
369
|
]
|
|
339
370
|
}
|
package/CHANGELOG.md
CHANGED
|
@@ -2,6 +2,46 @@
|
|
|
2
2
|
|
|
3
3
|
All notable changes to this project will be documented in this file.
|
|
4
4
|
|
|
5
|
+
## 1.0.0 — 2026-11-08
|
|
6
|
+
|
|
7
|
+
### 🧪 Tests
|
|
8
|
+
|
|
9
|
+
- Replaces the hand-written deadline loops in nmr's polling test helpers with `vi.waitFor` at the same interval and timeout, and keeps the one 50 ms real-time wait in `machine-lock.unit.test.ts` under a line-level disable of `sky-pilot/no-real-time-sleep`, because only elapsed time shows that further polls print nothing. (#1220)
|
|
10
|
+
|
|
11
|
+
## 0.56.0 — 2026-11-08
|
|
12
|
+
|
|
13
|
+
### 🎉 Features
|
|
14
|
+
|
|
15
|
+
- 🚨 **Breaking:** Route release-kit commands through toolbelt.cli (#1186)
|
|
16
|
+
|
|
17
|
+
Routes `release-kit`'s commands through the shared `toolbelt.cli` command parser, which renders each command's help from its option definitions and reports a usage error with a `Try '... --help'` line and exit code 2 instead of exit code 1. Also makes a bare `release-kit`, `release-kit overrides`, or `release-kit sync-labels` report "A command is required." and exit 2 instead of printing help and exiting 0.
|
|
18
|
+
|
|
19
|
+
- Changes the exit code of a usage error in `nmr`, `nmr-fmt`, and `ensure-prepublish-hooks` from 1 to 2, which covers an unknown flag in each, and in `nmr` an invalid `--output-style`, `NMR_COMMAND_VERBOSITY`, `NMR_REPORT_FORMAT`, or `NMR_OUTPUT_STYLE` value and `nmr --log` given without a command. (#1187)
|
|
20
|
+
- Adds a `Did you mean` line to the `Unknown command` error of `nmr` when a defined command is close to the name typed, followed by `Try 'nmr --help'.` (#1187)
|
|
21
|
+
- Generates `nmr --help` from nmr's flag definitions, listing the commands of the current scope under `Commands:` and those of the other scope after the environment variables and files, and adds `-h` as a short help flag. (#1187)
|
|
22
|
+
- Adds `--help` to `nmr-fmt` and `ensure-prepublish-hooks`, each generated from the command's flag definitions. (#1187)
|
|
23
|
+
- Prefixes each handled error line written by `nmr` and its other bins, `release-kit`, and `v11y-check` with the name of the program that wrote it, as `<bin>: <message>` in place of `Error: <message>`, for usage errors such as an unknown command or option as well, and names `v11y` for both of the bins in `v11y-check`. (#1190)
|
|
24
|
+
- Adds the warn-level check `every publishable package declares prepublishOnly` to nmr's ReadyUp kit, which lists each non-private workspace package that does not declare a `prepublishOnly` script, since a package without one publishes without its build output. (#1192)
|
|
25
|
+
- Adds the `shouldIsolateTempDir` option to `defineVitestConfig` and `defineRootVitestConfig`, on by default, which loads a global setup that points `TMPDIR` at a directory of the run's own, removes it when the run ends, and first removes any such directory left by a run that a signal stopped. (#1208)
|
|
26
|
+
- Makes `nmr-actionlint` and `nmr-shellcheck` cache the pinned actionlint and shellcheck once per machine under `$XDG_CACHE_HOME/nmr/tools/` (default `~/.cache/nmr/tools/`), so that `lint:workflows` and `lint:shell` in a new worktree reuse the copy that another worktree downloaded and fall back to the monorepo-root `node_modules/.cache/nmr-tools/` when the machine cache cannot be written. (#1210)
|
|
27
|
+
|
|
28
|
+
### 🪦 Removed
|
|
29
|
+
|
|
30
|
+
- Removes `-?` as a help flag of `nmr`, which now rejects it as an unknown flag. (#1187)
|
|
31
|
+
|
|
32
|
+
### 🐛 Bug fixes
|
|
33
|
+
|
|
34
|
+
- Fixes the issue that nmr read the value of a value-taking flag in an `nmr` step of a script, such as `--output-style plain` or `--delegate-to box`, as the step's command. (#1187)
|
|
35
|
+
- Fixes the issue that `nmr fmt`, `nmr lint:shell`, and a delegated run failed with `ENOBUFS` once git's file listing exceeded Node's 1 MiB default output buffer, and that nmr's Vitest config and test-tier check then dropped the list of git-ignored paths without reporting an error. (#1188)
|
|
36
|
+
- Fixes the issue that `ensure-prepublish-hooks --fix` wrote `npm run build` as the default `prepublishOnly` hook, which fails at publish time in an nmr repo because its packages do not declare a `build` script, and makes `nmr build` the default. (#1192)
|
|
37
|
+
|
|
38
|
+
### ♻️ Refactoring
|
|
39
|
+
|
|
40
|
+
- Replaces nmr's `isObject`, release-kit's `isRecord`, and the private copies in nmr-core's `workspace.ts` and an nmr test with one `isRecord` guard exported from the root entry of `@williamthorsen/nmr-core`. (#1194)
|
|
41
|
+
- Group nmr-core's source by role (#1196)
|
|
42
|
+
|
|
43
|
+
Groups `nmr-core`'s source modules into `cache`, `errors`, `files`, `git`, `portable`, and `workspace` directories by role, retiring `helpers/`, and moves the write-outcome reporters out of `terminal.ts` into `files/report-write-outcomes.ts`. The package's exports, including the `./workspace` subpath, resolve to the same modules at their new paths.
|
|
44
|
+
|
|
5
45
|
## 0.55.0 — 2026-11-06
|
|
6
46
|
|
|
7
47
|
### 🎉 Features
|
package/README.md
CHANGED
|
@@ -4,20 +4,7 @@
|
|
|
4
4
|
|
|
5
5
|
Context-aware script runner for pnpm monorepos. Includes an `nmr` (node-monorepo run) binary that provides centralized, consistent script execution across workspace packages and the monorepo root.
|
|
6
6
|
|
|
7
|
-
<!-- section:release-notes -->
|
|
8
|
-
## Release notes — v0.55.0 (2026-11-06)
|
|
9
|
-
|
|
10
|
-
### 🎉 Features
|
|
11
|
-
|
|
12
|
-
- Adds the built-in root command `lint:shell`, which runs the new `nmr-shellcheck` bin to lint every tracked `*.sh` file with nmr's pinned shellcheck and passes without downloading shellcheck when the repo does not track any. (#1161)
|
|
13
|
-
- Adds a warning to nmr's readyup kit that reports a `lint:shell` entry in `.config/nmr.config.ts`, which overrides the built-in command, and directs the repo to delete the entry. (#1161)
|
|
14
|
-
|
|
15
|
-
### 🐛 Bug fixes
|
|
16
|
-
|
|
17
|
-
- Adopt the crash convention in release-kit (#1158)
|
|
18
|
-
|
|
19
|
-
Makes `release-kit` report a bug in its own code as `release-kit: internal error: <message>` followed by the stack, rather than as the `Error: <message>` line that it keeps for a failure in the user's input, config, or environment. The same change makes `nmr` and `v11y-check` print a Node system error, such as `EACCES` or `ENOENT`, as `Error: <message>` rather than as an internal error.
|
|
20
|
-
<!-- /section:release-notes -->
|
|
7
|
+
<!-- section:release-notes --><!-- /section:release-notes -->
|
|
21
8
|
|
|
22
9
|
## Installation
|
|
23
10
|
|
|
@@ -6,7 +6,7 @@ delivery: ambient
|
|
|
6
6
|
|
|
7
7
|
# nmr: agent guidance
|
|
8
8
|
|
|
9
|
-
- Use `nmr <command>`, not `pnpm run <command>`, for anything nmr provides. Run bare `nmr` to list every command and the shell command to which it resolves; a wrong guess reports
|
|
9
|
+
- Use `nmr <command>`, not `pnpm run <command>`, for anything nmr provides. Run bare `nmr` to list every command and the shell command to which it resolves; a wrong guess reports `Unknown command`, a `Did you mean` line when a command is close, and `Try 'nmr --help'.`, without a list, and exits 2.
|
|
10
10
|
- Scope follows cwd, and bare `nmr` lists both registries: From the repo root a command covers root files and every workspace; from inside a package, that package alone. `nmr -F <pkg> <command>` targets one package from anywhere; `nmr root:<command>` targets root files alone, which isolates a failure to root code.
|
|
11
11
|
- Never `npx nmr`: Inside a git worktree it can resolve a different nmr from outside the tree. Fall back to `pnpm exec nmr`.
|
|
12
12
|
- `nmr ci` runs what a code-quality workflow runs (build, then strict checks) and not the dependency audit, which belongs to a workflow of its own; `nmr prepush` runs the audit first, then `ci`, so a vulnerability stops the run before the long gate. Neither installs or binds a git hook.
|
package/bin/nmr-actionlint.js
CHANGED
package/bin/nmr-clean.js
CHANGED
package/bin/nmr-compile.js
CHANGED
package/bin/nmr-fmt.js
CHANGED
package/bin/nmr-shellcheck.js
CHANGED
package/bin/nmr-taze.js
CHANGED
package/bin/nmr-vitest.js
CHANGED
package/bin/nmr.js
CHANGED
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
export declare const ENSURE_PREPUBLISH_HOOKS_BIN = "ensure-prepublish-hooks";
|
|
2
|
+
export declare const NMR_ACTIONLINT_BIN = "nmr-actionlint";
|
|
3
|
+
export declare const NMR_BIN = "nmr";
|
|
4
|
+
export declare const NMR_CLEAN_BIN = "nmr-clean";
|
|
5
|
+
export declare const NMR_COMPILE_BIN = "nmr-compile";
|
|
6
|
+
export declare const NMR_FMT_BIN = "nmr-fmt";
|
|
7
|
+
export declare const NMR_REPORT_CATALOG_BIN = "nmr-report-catalog";
|
|
8
|
+
export declare const NMR_REPORT_OVERRIDES_BIN = "nmr-report-overrides";
|
|
9
|
+
export declare const NMR_SHELLCHECK_BIN = "nmr-shellcheck";
|
|
10
|
+
export declare const NMR_TAZE_BIN = "nmr-taze";
|
|
11
|
+
export declare const NMR_VITEST_BIN = "nmr-vitest";
|
package/dist/esm/bins.js
ADDED
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
export const ENSURE_PREPUBLISH_HOOKS_BIN = 'ensure-prepublish-hooks';
|
|
2
|
+
export const NMR_ACTIONLINT_BIN = 'nmr-actionlint';
|
|
3
|
+
export const NMR_BIN = 'nmr';
|
|
4
|
+
export const NMR_CLEAN_BIN = 'nmr-clean';
|
|
5
|
+
export const NMR_COMPILE_BIN = 'nmr-compile';
|
|
6
|
+
export const NMR_FMT_BIN = 'nmr-fmt';
|
|
7
|
+
export const NMR_REPORT_CATALOG_BIN = 'nmr-report-catalog';
|
|
8
|
+
export const NMR_REPORT_OVERRIDES_BIN = 'nmr-report-overrides';
|
|
9
|
+
export const NMR_SHELLCHECK_BIN = 'nmr-shellcheck';
|
|
10
|
+
export const NMR_TAZE_BIN = 'nmr-taze';
|
|
11
|
+
export const NMR_VITEST_BIN = 'nmr-vitest';
|
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
import path from 'node:path';
|
|
2
|
-
import { readCacheEntry, readJsonCacheEntry, removeCacheDir, removeCacheEntry, resolveCacheEntryPath, writeCacheEntry, } from '@williamthorsen/nmr-core';
|
|
2
|
+
import { isRecord, readCacheEntry, readJsonCacheEntry, removeCacheDir, removeCacheEntry, resolveCacheEntryPath, writeCacheEntry, } from '@williamthorsen/nmr-core';
|
|
3
3
|
import { describeError } from '@williamthorsen/toolbelt.errors';
|
|
4
4
|
import { writeDebugNote } from "./check-cache.js";
|
|
5
|
-
import {
|
|
5
|
+
import { isStringRecord } from "./helpers/type-guards.js";
|
|
6
6
|
const CACHE_TOOL = 'nmr-check';
|
|
7
7
|
const UNSAFE_SLUG_CHARACTERS = /[^\w.-]+/g;
|
|
8
8
|
export async function certifyRetention(options) {
|
|
@@ -45,7 +45,7 @@ export async function removeCheckCache(scopeDir) {
|
|
|
45
45
|
await removeCacheDir({ tool: CACHE_TOOL, scopeDir });
|
|
46
46
|
}
|
|
47
47
|
export function isReplayLine(value) {
|
|
48
|
-
return (
|
|
48
|
+
return (isRecord(value) &&
|
|
49
49
|
typeof value['command'] === 'string' &&
|
|
50
50
|
typeof value['excerpt'] === 'string' &&
|
|
51
51
|
typeof value['scope'] === 'string');
|
|
@@ -54,7 +54,7 @@ export async function writeCheckCacheEntry(options) {
|
|
|
54
54
|
await writeCacheEntry(resolveEntryPath(options), JSON.stringify(options.entry, undefined, 2));
|
|
55
55
|
}
|
|
56
56
|
function isParsedCheckCacheEntry(value) {
|
|
57
|
-
if (!
|
|
57
|
+
if (!isRecord(value)) {
|
|
58
58
|
return false;
|
|
59
59
|
}
|
|
60
60
|
const stringFields = ['key', 'treeHash', 'headSha', 'commandString', 'nmrVersion', 'nodeVersion', 'recordedAt'];
|
|
@@ -68,7 +68,7 @@ function isParsedCheckCacheEntry(value) {
|
|
|
68
68
|
isStringRecord(value['buildDigests']));
|
|
69
69
|
}
|
|
70
70
|
function isRetention(value) {
|
|
71
|
-
return (
|
|
71
|
+
return (isRecord(value) &&
|
|
72
72
|
typeof value['key'] === 'string' &&
|
|
73
73
|
typeof value['runId'] === 'string' &&
|
|
74
74
|
Array.isArray(value['replay']) &&
|
|
@@ -8,6 +8,7 @@ import { recordPass } from "./check-cache-record.js";
|
|
|
8
8
|
import { addLockEnv, takeMachineLock } from "./child-env.js";
|
|
9
9
|
import { runPlanOnHost } from "./delegate-host.js";
|
|
10
10
|
import { VERSION } from "./invocation.js";
|
|
11
|
+
import { formatFlagSpelling } from "./nmr-flags.js";
|
|
11
12
|
import { resolveChannel } from "./output-channel.js";
|
|
12
13
|
import { writePassManifestEntry } from "./pass-manifest.js";
|
|
13
14
|
import { runSteps } from "./runner.js";
|
|
@@ -17,7 +18,7 @@ export function openGate(options) {
|
|
|
17
18
|
if (!isCacheableCommand(config.checkCache, command)) {
|
|
18
19
|
return undefined;
|
|
19
20
|
}
|
|
20
|
-
if (passthrough.includes('
|
|
21
|
+
if (passthrough.includes(formatFlagSpelling('noCache'))) {
|
|
21
22
|
stderr.write(`${formatMisplacedNoCacheWarning(command, style)}\n`);
|
|
22
23
|
}
|
|
23
24
|
if (passthrough.length > 0) {
|
package/dist/esm/child-env.js
CHANGED
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import { DEBUG_ENV_VAR, encodeTreeSnapshot, NO_CACHE_ENV_VAR, RUN_ID_ENV_VAR, TREE_SNAPSHOT_ENV_VAR, } from "./check-cache.js";
|
|
2
2
|
import { acquireMachineLock, formatMisplacedNoLockWarning, HEAVY_COMMANDS, LOCK_TOKEN_ENV_VAR, NO_LOCK_ENV_VAR, } from "./machine-lock.js";
|
|
3
|
+
import { formatFlagSpelling } from "./nmr-flags.js";
|
|
3
4
|
import { OUTPUT_STYLE_ENV_VAR } from "./output-style.js";
|
|
4
5
|
import { DELEGATE_ENV_VAR } from "./remote-run.js";
|
|
5
6
|
import { REPORT_FORMAT_ENV_VAR } from "./report-format.js";
|
|
@@ -39,7 +40,7 @@ export async function takeMachineLock(invocation) {
|
|
|
39
40
|
if (!HEAVY_COMMANDS.has(command) || parsedArgs.shouldPrintLog) {
|
|
40
41
|
return undefined;
|
|
41
42
|
}
|
|
42
|
-
if (parsedArgs.passthrough.includes('
|
|
43
|
+
if (parsedArgs.passthrough.includes(formatFlagSpelling('noLock'))) {
|
|
43
44
|
stderr.write(`${formatMisplacedNoLockWarning(command, styles.stderr)}\n`);
|
|
44
45
|
}
|
|
45
46
|
return acquireMachineLock({
|
|
@@ -2,6 +2,8 @@ import { type ChildProcess } from 'node:child_process';
|
|
|
2
2
|
import type { Writable } from 'node:stream';
|
|
3
3
|
import type { OutputChannels } from './output-channel.js';
|
|
4
4
|
export interface RunCommandOptions {
|
|
5
|
+
/** The bin under which this process runs, which names it in a spawn-failure report. */
|
|
6
|
+
bin: string;
|
|
5
7
|
/** The channel on which each of the child's output streams runs. */
|
|
6
8
|
channels: OutputChannels;
|
|
7
9
|
/** When true, suppresses output on success and writes captured output to stderr on failure. */
|
|
@@ -19,7 +19,7 @@ export function startSpawned({ args, file, input, shouldUseShell }, cwd, options
|
|
|
19
19
|
cwd,
|
|
20
20
|
env,
|
|
21
21
|
});
|
|
22
|
-
return { child, result: collectResult(child, { quiet, stderr, stdout }) };
|
|
22
|
+
return { child, result: collectResult(child, { bin: options.bin, quiet, stderr, stdout }) };
|
|
23
23
|
}
|
|
24
24
|
function awaitCompletion(child, stopReading) {
|
|
25
25
|
return new Promise((resolve) => {
|
|
@@ -76,7 +76,7 @@ function captureStream(source, destination) {
|
|
|
76
76
|
stopReading,
|
|
77
77
|
};
|
|
78
78
|
}
|
|
79
|
-
async function collectResult(child, { quiet, stderr, stdout }) {
|
|
79
|
+
async function collectResult(child, { bin, quiet, stderr, stdout }) {
|
|
80
80
|
const stdoutCapture = child.stdout === null ? undefined : captureStream(child.stdout, quiet ? undefined : stdout);
|
|
81
81
|
const stderrCapture = child.stderr === null ? undefined : captureStream(child.stderr, quiet ? undefined : stderr);
|
|
82
82
|
const commandCompletion = await awaitCompletion(child, () => {
|
|
@@ -91,7 +91,7 @@ async function collectResult(child, { quiet, stderr, stdout }) {
|
|
|
91
91
|
stderr: stderrCapture?.readBuffer(),
|
|
92
92
|
};
|
|
93
93
|
if (result.outcome === 'spawn-failed') {
|
|
94
|
-
reportError(result.error.message, stderr);
|
|
94
|
+
reportError(bin, result.error.message, stderr);
|
|
95
95
|
return result;
|
|
96
96
|
}
|
|
97
97
|
if (quiet && result.exitCode !== 0) {
|
|
@@ -1,11 +1,12 @@
|
|
|
1
1
|
import process from 'node:process';
|
|
2
2
|
import { reportFailure } from '@williamthorsen/nmr-core';
|
|
3
|
+
import { NMR_ACTIONLINT_BIN } from "./bins.js";
|
|
3
4
|
import { runActionlint } from "./commands/actionlint.js";
|
|
4
5
|
import { findMonorepoRoot } from "./workspace.js";
|
|
5
6
|
try {
|
|
6
7
|
process.exitCode = await runActionlint(findMonorepoRoot(), process.argv.slice(2));
|
|
7
8
|
}
|
|
8
9
|
catch (error) {
|
|
9
|
-
reportFailure(
|
|
10
|
+
reportFailure(NMR_ACTIONLINT_BIN, error);
|
|
10
11
|
process.exitCode = 1;
|
|
11
12
|
}
|
package/dist/esm/cli-build.js
CHANGED
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import { reportFailure } from '@williamthorsen/nmr-core';
|
|
2
|
+
import { NMR_COMPILE_BIN } from "./bins.js";
|
|
2
3
|
import { buildPackage } from "./commands/build.js";
|
|
3
4
|
import { loadWorkspaceConfig } from "./config.js";
|
|
4
5
|
import { resolveBinStyles } from "./resolveBinStyles.js";
|
|
@@ -12,6 +13,6 @@ try {
|
|
|
12
13
|
});
|
|
13
14
|
}
|
|
14
15
|
catch (error) {
|
|
15
|
-
reportFailure(
|
|
16
|
+
reportFailure(NMR_COMPILE_BIN, error);
|
|
16
17
|
process.exitCode = 1;
|
|
17
18
|
}
|
package/dist/esm/cli-clean.js
CHANGED
|
@@ -1,11 +1,12 @@
|
|
|
1
1
|
import process from 'node:process';
|
|
2
2
|
import { reportFailure } from '@williamthorsen/nmr-core';
|
|
3
|
+
import { NMR_CLEAN_BIN } from "./bins.js";
|
|
3
4
|
import { runClean } from "./commands/clean.js";
|
|
4
5
|
import { resolveBinStyles } from "./resolveBinStyles.js";
|
|
5
6
|
try {
|
|
6
7
|
await runClean(process.cwd(), resolveBinStyles().stdout);
|
|
7
8
|
}
|
|
8
9
|
catch (error) {
|
|
9
|
-
reportFailure(
|
|
10
|
+
reportFailure(NMR_CLEAN_BIN, error);
|
|
10
11
|
process.exitCode = 1;
|
|
11
12
|
}
|