@williamthorsen/nmr 0.53.1 → 0.54.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.
Files changed (65) hide show
  1. package/.meta/changelog.json +49 -0
  2. package/.readyup/kits/default.js +10 -10
  3. package/.readyup/manifest.json +19 -19
  4. package/CHANGELOG.md +15 -0
  5. package/README.md +12 -3
  6. package/bin/ensure-prepublish-hooks.js +6 -2
  7. package/bin/nmr-actionlint.js +6 -2
  8. package/bin/nmr-clean.js +6 -2
  9. package/bin/nmr-compile.js +6 -2
  10. package/bin/nmr-fmt.js +6 -2
  11. package/bin/nmr-report-catalog.js +6 -2
  12. package/bin/nmr-report-overrides.js +6 -2
  13. package/bin/nmr-taze.js +6 -2
  14. package/bin/nmr-vitest.js +6 -2
  15. package/bin/nmr.js +6 -2
  16. package/dist/esm/child-process.js +1 -1
  17. package/dist/esm/cli-actionlint.js +2 -3
  18. package/dist/esm/cli-build.js +2 -3
  19. package/dist/esm/cli-clean.js +2 -3
  20. package/dist/esm/cli-ensure-prepublish-hooks.js +2 -3
  21. package/dist/esm/cli-fmt.js +8 -1
  22. package/dist/esm/cli-report-catalog.js +2 -3
  23. package/dist/esm/cli-report-overrides.js +2 -3
  24. package/dist/esm/cli-taze.js +4 -4
  25. package/dist/esm/cli-vitest.js +8 -1
  26. package/dist/esm/cli.js +2 -2
  27. package/dist/esm/commands/actionlint.js +2 -1
  28. package/dist/esm/commands/build.js +9 -6
  29. package/dist/esm/commands/clean.js +2 -2
  30. package/dist/esm/commands/compiler.js +3 -3
  31. package/dist/esm/commands/ensure-prepublish-hooks.js +10 -3
  32. package/dist/esm/commands/node-pin.d.ts +30 -0
  33. package/dist/esm/commands/node-pin.js +127 -0
  34. package/dist/esm/commands/report-overrides.js +1 -2
  35. package/dist/esm/commands/rewrite-specifiers.js +3 -2
  36. package/dist/esm/commands/taze.d.ts +10 -0
  37. package/dist/esm/commands/taze.js +15 -0
  38. package/dist/esm/commands/tsconfig-chain.js +4 -3
  39. package/dist/esm/commands/workflow-tools.js +10 -8
  40. package/dist/esm/config-check-cache.js +1 -1
  41. package/dist/esm/config-validation.js +1 -1
  42. package/dist/esm/config.js +1 -1
  43. package/dist/esm/crossing-diagnostics.js +1 -2
  44. package/dist/esm/delegation-target.d.ts +5 -4
  45. package/dist/esm/delegation-target.js +15 -0
  46. package/dist/esm/entry-chain.js +1 -1
  47. package/dist/esm/glyphs.d.ts +1 -1
  48. package/dist/esm/glyphs.js +1 -0
  49. package/dist/esm/helpers/deriveExcerpt.js +1 -1
  50. package/dist/esm/helpers/duration.js +1 -1
  51. package/dist/esm/helpers/package-json.js +1 -1
  52. package/dist/esm/machine-lock.js +1 -1
  53. package/dist/esm/pass-manifest.js +2 -3
  54. package/dist/esm/remote-host-session.js +2 -2
  55. package/dist/esm/resolveBinStyles.js +1 -2
  56. package/dist/esm/user-config.js +1 -1
  57. package/dist/esm/vitest-source-resolution.js +1 -1
  58. package/dist/esm/workspace.js +1 -1
  59. package/docs/delegate.md +7 -5
  60. package/docs/upgrades.md +19 -2
  61. package/package.json +6 -6
  62. package/dist/esm/UserError.d.ts +0 -8
  63. package/dist/esm/UserError.js +0 -6
  64. package/dist/esm/reportCliFailure.d.ts +0 -9
  65. package/dist/esm/reportCliFailure.js +0 -11
@@ -1,4 +1,53 @@
1
1
  [
2
+ {
3
+ "version": "0.54.1",
4
+ "date": "2026-11-05",
5
+ "sections": [
6
+ {
7
+ "title": "🐛 Bug fixes",
8
+ "audience": "all",
9
+ "items": [
10
+ {
11
+ "description": "Fixes the issue that `pnpm add` failed when an install hook such as `postinstall` ran an nmr command delegated by `NMR_DELEGATE` or the user config, because the host's frozen install rejected a manifest that was ahead of its lockfile, by making nmr run such a command on this machine unless `--delegate` or `--delegate-to` is passed. (#1151)",
12
+ "hash": "0037919912a86b9bf927e1afccf079956d6c2968",
13
+ "entry": 1
14
+ },
15
+ {
16
+ "description": "Fixes the issue that `nmr` printed an unexpected crash as its raw stack, whose first line, `Error: <message>`, read the same as a handled error; it now prints `nmr: internal error: <message>` followed by the stack frames, and still prints an error caused by the user's own config as `Error: <message>`. (#1153)",
17
+ "hash": "0289c032b00438984efcf7466f2b3055b4dbc546",
18
+ "entry": 1
19
+ },
20
+ {
21
+ "description": "Fixes the issue that the `nmr` sub-bins, such as `nmr-compile` and `nmr-fmt`, and the `v11y` subcommands reported an unexpected crash as a handled `Error: <message>` line, rather than as `<bin>: internal error: <message>` with its stack frames. (#1157)",
22
+ "hash": "ef1ed5f50bf0b01f19b6d6fe82a40322a8286002",
23
+ "entry": 1
24
+ },
25
+ {
26
+ "description": "Fixes the issue that the bin scripts of `nmr`, `release-kit`, and `v11y-check` reported every error other than missing build output as `<bin>: failed to load: <message>` without a stack, which hid where the fault occurred. (#1157)",
27
+ "hash": "ef1ed5f50bf0b01f19b6d6fe82a40322a8286002",
28
+ "entry": 2
29
+ }
30
+ ]
31
+ }
32
+ ]
33
+ },
34
+ {
35
+ "version": "0.54.0",
36
+ "date": "2026-10-31",
37
+ "sections": [
38
+ {
39
+ "title": "🎉 Features",
40
+ "audience": "all",
41
+ "items": [
42
+ {
43
+ "description": "Adds a check of the `nodejs` pin in `.tool-versions` to `nmr upgrade`, which reports the newest release at least 24 hours old in the pin's major line and, under `--write`, rewrites the pin to it. (#1141)",
44
+ "hash": "d6459b4f867e39162a3e41dd8639993b12ba579f",
45
+ "entry": 1
46
+ }
47
+ ]
48
+ }
49
+ ]
50
+ },
2
51
  {
3
52
  "version": "0.53.1",
4
53
  "date": "2026-10-28",
@@ -1,6 +1,6 @@
1
1
  /** @noformat -- @generated. Do not edit. Compiled by rdy. */
2
2
  /* eslint-disable */
3
- export const __readyupVersion = "0.44.0";
3
+ export const __readyupVersion = "0.45.0";
4
4
  import { createRequire as __rdyCreateRequire } from 'node:module';
5
5
  const require = __rdyCreateRequire(import.meta.url);
6
6
 
@@ -7829,10 +7829,15 @@ function readWorkspaceManifest(monorepoRoot) {
7829
7829
  }
7830
7830
  }
7831
7831
 
7832
- // src/UserError.ts
7832
+ // ../nmr-core/dist/esm/hasErrnoCode.js
7833
+ function hasErrnoCode(error, code) {
7834
+ return isError(error) && "code" in error && error.code === code;
7835
+ }
7836
+
7837
+ // ../nmr-core/dist/esm/UserError.js
7833
7838
  var UserError = class extends Error {
7834
- constructor(message) {
7835
- super(message);
7839
+ constructor(message, options) {
7840
+ super(message, options);
7836
7841
  this.name = "UserError";
7837
7842
  }
7838
7843
  };
@@ -8026,11 +8031,6 @@ function isHookName(key) {
8026
8031
  // src/resolver.ts
8027
8032
  import { readFileSync as readFileSync2 } from "node:fs";
8028
8033
 
8029
- // ../nmr-core/dist/esm/hasErrnoCode.js
8030
- function hasErrnoCode(error, code) {
8031
- return isError(error) && "code" in error && error.code === code;
8032
- }
8033
-
8034
8034
  // src/helpers/package-json.ts
8035
8035
  import path5 from "node:path";
8036
8036
 
@@ -9190,7 +9190,7 @@ function hasSupportedStrictLintVersion() {
9190
9190
  });
9191
9191
  }
9192
9192
  function getMinVersion() {
9193
- const pickedFields = { "version": "0.53.1" };
9193
+ const pickedFields = { "version": "0.54.1" };
9194
9194
  if (typeof pickedFields["version"] !== "string") {
9195
9195
  throw new TypeError("nmr/package.json: 'version' must be a string");
9196
9196
  }
@@ -10,7 +10,7 @@
10
10
  "@williamthorsen/toolbelt.objects": "4.4.0",
11
11
  "@williamthorsen/toolbelt.packaging": "0.7.0",
12
12
  "@williamthorsen/toolbelt.terminal": "0.3.0",
13
- "ansi-regex": "6.4.0",
13
+ "ansi-regex": "6.5.0",
14
14
  "ansi-styles": "6.2.3",
15
15
  "cli-truncate": "6.1.1",
16
16
  "diff": "9.0.0",
@@ -27,7 +27,7 @@
27
27
  "checklist": "nmr",
28
28
  "checks": [
29
29
  "@williamthorsen/nmr in devDependencies",
30
- "@williamthorsen/nmr >= 0.53.1",
30
+ "@williamthorsen/nmr >= 0.54.1",
31
31
  "pnpm-workspace.yaml exists",
32
32
  "catalogued dependencies use catalog:",
33
33
  "package.json has packageManager field",
@@ -89,7 +89,7 @@
89
89
  "path": "../../nmr-core/dist/esm/gitObjects.js"
90
90
  },
91
91
  {
92
- "hash": "14216f5f",
92
+ "hash": "d5a89448",
93
93
  "kind": "module",
94
94
  "path": "../../nmr-core/dist/esm/gitOutputLimit.js"
95
95
  },
@@ -109,12 +109,12 @@
109
109
  "path": "../../nmr-core/dist/esm/helpers/workspace-patterns.js"
110
110
  },
111
111
  {
112
- "hash": "dcd24627",
112
+ "hash": "8fe9a346",
113
113
  "kind": "module",
114
114
  "path": "../../nmr-core/dist/esm/index.js"
115
115
  },
116
116
  {
117
- "hash": "a2053951",
117
+ "hash": "de51ceb3",
118
118
  "kind": "module",
119
119
  "path": "../../nmr-core/dist/esm/parseArgs.js"
120
120
  },
@@ -124,7 +124,7 @@
124
124
  "path": "../../nmr-core/dist/esm/runGit.js"
125
125
  },
126
126
  {
127
- "hash": "46b44e18",
127
+ "hash": "6f46d90a",
128
128
  "kind": "module",
129
129
  "path": "../../nmr-core/dist/esm/terminal.js"
130
130
  },
@@ -138,6 +138,11 @@
138
138
  "kind": "module",
139
139
  "path": "../../nmr-core/dist/esm/updateManagedFile.js"
140
140
  },
141
+ {
142
+ "hash": "e02e0a74",
143
+ "kind": "module",
144
+ "path": "../../nmr-core/dist/esm/UserError.js"
145
+ },
141
146
  {
142
147
  "hash": "00d00fae",
143
148
  "kind": "module",
@@ -209,7 +214,7 @@
209
214
  "path": "lib/workspace-build.ts"
210
215
  },
211
216
  {
212
- "hash": "b54c684e",
217
+ "hash": "dad7f436",
213
218
  "kind": "inline",
214
219
  "path": "../package.json",
215
220
  "paths": [
@@ -217,17 +222,17 @@
217
222
  ]
218
223
  },
219
224
  {
220
- "hash": "19b57f2e",
225
+ "hash": "578af9fd",
221
226
  "kind": "module",
222
227
  "path": "../src/config-check-cache.ts"
223
228
  },
224
229
  {
225
- "hash": "2cfe8c2e",
230
+ "hash": "fa9330c5",
226
231
  "kind": "module",
227
232
  "path": "../src/config-validation.ts"
228
233
  },
229
234
  {
230
- "hash": "5b589c7e",
235
+ "hash": "4240e226",
231
236
  "kind": "module",
232
237
  "path": "../src/config.ts"
233
238
  },
@@ -262,7 +267,7 @@
262
267
  "path": "../src/helpers/hook-name.ts"
263
268
  },
264
269
  {
265
- "hash": "8850834f",
270
+ "hash": "7fb6c09d",
266
271
  "kind": "module",
267
272
  "path": "../src/helpers/package-json.ts"
268
273
  },
@@ -301,11 +306,6 @@
301
306
  "kind": "module",
302
307
  "path": "../src/tiers.ts"
303
308
  },
304
- {
305
- "hash": "faad986a",
306
- "kind": "module",
307
- "path": "../src/UserError.ts"
308
- },
309
309
  {
310
310
  "hash": "ecf8a873",
311
311
  "kind": "module",
@@ -317,17 +317,17 @@
317
317
  "path": "../src/workspace-globs.ts"
318
318
  },
319
319
  {
320
- "hash": "922e7155",
320
+ "hash": "770e4f3a",
321
321
  "kind": "module",
322
322
  "path": "../src/workspace.ts"
323
323
  }
324
324
  ],
325
325
  "name": "default",
326
326
  "path": "kits/default.js",
327
- "readyupVersion": "0.44.0",
327
+ "readyupVersion": "0.45.0",
328
328
  "source": "kits/default.ts",
329
329
  "sourceHash": "9fd61bf4",
330
- "targetHash": "6ad36b20"
330
+ "targetHash": "04e5d541"
331
331
  }
332
332
  ]
333
333
  }
package/CHANGELOG.md CHANGED
@@ -2,6 +2,21 @@
2
2
 
3
3
  All notable changes to this project will be documented in this file.
4
4
 
5
+ ## 0.54.1 — 2026-11-05
6
+
7
+ ### 🐛 Bug fixes
8
+
9
+ - Fixes the issue that `pnpm add` failed when an install hook such as `postinstall` ran an nmr command delegated by `NMR_DELEGATE` or the user config, because the host's frozen install rejected a manifest that was ahead of its lockfile, by making nmr run such a command on this machine unless `--delegate` or `--delegate-to` is passed. (#1151)
10
+ - Fixes the issue that `nmr` printed an unexpected crash as its raw stack, whose first line, `Error: <message>`, read the same as a handled error; it now prints `nmr: internal error: <message>` followed by the stack frames, and still prints an error caused by the user's own config as `Error: <message>`. (#1153)
11
+ - Fixes the issue that the `nmr` sub-bins, such as `nmr-compile` and `nmr-fmt`, and the `v11y` subcommands reported an unexpected crash as a handled `Error: <message>` line, rather than as `<bin>: internal error: <message>` with its stack frames. (#1157)
12
+ - Fixes the issue that the bin scripts of `nmr`, `release-kit`, and `v11y-check` reported every error other than missing build output as `<bin>: failed to load: <message>` without a stack, which hid where the fault occurred. (#1157)
13
+
14
+ ## 0.54.0 — 2026-10-31
15
+
16
+ ### 🎉 Features
17
+
18
+ - Adds a check of the `nodejs` pin in `.tool-versions` to `nmr upgrade`, which reports the newest release at least 24 hours old in the pin's major line and, under `--write`, rewrites the pin to it. (#1141)
19
+
5
20
  ## 0.53.1 — 2026-10-28
6
21
 
7
22
  ### ♻️ Refactoring
package/README.md CHANGED
@@ -4,7 +4,16 @@
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 --><!-- /section:release-notes -->
7
+ <!-- section:release-notes -->
8
+ ## Release notes — v0.54.1 (2026-11-05)
9
+
10
+ ### 🐛 Bug fixes
11
+
12
+ - Fixes the issue that `pnpm add` failed when an install hook such as `postinstall` ran an nmr command delegated by `NMR_DELEGATE` or the user config, because the host's frozen install rejected a manifest that was ahead of its lockfile, by making nmr run such a command on this machine unless `--delegate` or `--delegate-to` is passed. (#1151)
13
+ - Fixes the issue that `nmr` printed an unexpected crash as its raw stack, whose first line, `Error: <message>`, read the same as a handled error; it now prints `nmr: internal error: <message>` followed by the stack frames, and still prints an error caused by the user's own config as `Error: <message>`. (#1153)
14
+ - Fixes the issue that the `nmr` sub-bins, such as `nmr-compile` and `nmr-fmt`, and the `v11y` subcommands reported an unexpected crash as a handled `Error: <message>` line, rather than as `<bin>: internal error: <message>` with its stack frames. (#1157)
15
+ - Fixes the issue that the bin scripts of `nmr`, `release-kit`, and `v11y-check` reported every error other than missing build output as `<bin>: failed to load: <message>` without a stack, which hid where the fault occurred. (#1157)
16
+ <!-- /section:release-notes -->
8
17
 
9
18
  ## Installation
10
19
 
@@ -234,7 +243,7 @@ export default definePrettierConfig();
234
243
 
235
244
  ### Dependency upgrades
236
245
 
237
- `nmr upgrade` reports available dependency upgrades. A `taze.config.ts` at the monorepo root, built with the `defineConfig` exported by `@williamthorsen/nmr/taze`, declares the upgrade policy. [Dependency upgrades](docs/upgrades.md) covers what each invocation reaches, the policy and its ceilings, per-package maturity periods, and the request timeout.
246
+ `nmr upgrade` reports available dependency upgrades, and newer releases in the major line of the `.tool-versions` Node pin. A `taze.config.ts` at the monorepo root, built with the `defineConfig` exported by `@williamthorsen/nmr/taze`, declares the upgrade policy. [Dependency upgrades](docs/upgrades.md) covers what each invocation reaches, the policy and its ceilings, per-package maturity periods, the Node version pin, and the request timeout.
238
247
 
239
248
  ### Workspace introspection
240
249
 
@@ -309,7 +318,7 @@ rdy list --from npm:@williamthorsen/nmr # what nmr publishes
309
318
  - [Check-result cache](docs/check-cache.md): What is skipped, what a hit requires, and replaying, reading, and bypassing recorded runs
310
319
  - [Machine lock](docs/machine-lock.md): Which commands wait for one another, where the lock lives, and bypassing it
311
320
  - [Delegating to another machine](docs/delegate.md): The user config, `--delegate`, `--delegate-to`, `NMR_DELEGATE`, where a command runs, choosing among several hosts, what the host runs, and setting it up
312
- - [Dependency upgrades](docs/upgrades.md): `nmr upgrade`, the upgrade policy, `report-catalog`, `report-overrides`, and `nmr-taze`
321
+ - [Dependency upgrades](docs/upgrades.md): `nmr upgrade`, the upgrade policy, the Node version pin, `report-catalog`, `report-overrides`, and `nmr-taze`
313
322
  - [Standalone utilities](docs/utilities.md): `nmr-actionlint`, `nmr-clean`, `nmr-compile`, `nmr-fmt`, `nmr-vitest`, and `ensure-prepublish-hooks`
314
323
  - [Shared Vitest config](docs/vitest.md): Test tiers, test selections, the conventions check, and customization
315
324
  - [Shared Prettier config](docs/prettier.md): What it formats and how to customize it
@@ -2,10 +2,14 @@
2
2
  try {
3
3
  await import('../dist/esm/cli-ensure-prepublish-hooks.js');
4
4
  } catch (error) {
5
- if (error.code === 'ERR_MODULE_NOT_FOUND') {
5
+ if (error?.code === 'ERR_MODULE_NOT_FOUND') {
6
6
  process.stderr.write('ensure-prepublish-hooks: build output not found; run `pnpm run bootstrap` first\n');
7
7
  } else {
8
- process.stderr.write(`ensure-prepublish-hooks: failed to load: ${error.message}\n`);
8
+ const message = typeof error?.message === 'string' && error.message !== '' ? error.message : String(error);
9
+ const lines = typeof error?.stack === 'string' ? error.stack.split('\n') : [];
10
+ const firstFrame = lines.findIndex((line) => /^\s+at /.test(line));
11
+ const frames = firstFrame === -1 ? '' : `${lines.slice(firstFrame).join('\n')}\n`;
12
+ process.stderr.write(`ensure-prepublish-hooks: internal error: ${message}\n${frames}`);
9
13
  }
10
14
  process.exit(1);
11
15
  }
@@ -2,10 +2,14 @@
2
2
  try {
3
3
  await import('../dist/esm/cli-actionlint.js');
4
4
  } catch (error) {
5
- if (error.code === 'ERR_MODULE_NOT_FOUND') {
5
+ if (error?.code === 'ERR_MODULE_NOT_FOUND') {
6
6
  process.stderr.write('nmr-actionlint: build output not found; run `pnpm run bootstrap` first\n');
7
7
  } else {
8
- process.stderr.write(`nmr-actionlint: failed to load: ${error.message}\n`);
8
+ const message = typeof error?.message === 'string' && error.message !== '' ? error.message : String(error);
9
+ const lines = typeof error?.stack === 'string' ? error.stack.split('\n') : [];
10
+ const firstFrame = lines.findIndex((line) => /^\s+at /.test(line));
11
+ const frames = firstFrame === -1 ? '' : `${lines.slice(firstFrame).join('\n')}\n`;
12
+ process.stderr.write(`nmr-actionlint: internal error: ${message}\n${frames}`);
9
13
  }
10
14
  process.exit(1);
11
15
  }
package/bin/nmr-clean.js CHANGED
@@ -2,10 +2,14 @@
2
2
  try {
3
3
  await import('../dist/esm/cli-clean.js');
4
4
  } catch (error) {
5
- if (error.code === 'ERR_MODULE_NOT_FOUND') {
5
+ if (error?.code === 'ERR_MODULE_NOT_FOUND') {
6
6
  process.stderr.write('nmr-clean: build output not found; run `pnpm run bootstrap` first\n');
7
7
  } else {
8
- process.stderr.write(`nmr-clean: failed to load: ${error.message}\n`);
8
+ const message = typeof error?.message === 'string' && error.message !== '' ? error.message : String(error);
9
+ const lines = typeof error?.stack === 'string' ? error.stack.split('\n') : [];
10
+ const firstFrame = lines.findIndex((line) => /^\s+at /.test(line));
11
+ const frames = firstFrame === -1 ? '' : `${lines.slice(firstFrame).join('\n')}\n`;
12
+ process.stderr.write(`nmr-clean: internal error: ${message}\n${frames}`);
9
13
  }
10
14
  process.exit(1);
11
15
  }
@@ -2,10 +2,14 @@
2
2
  try {
3
3
  await import('../dist/esm/cli-build.js');
4
4
  } catch (error) {
5
- if (error.code === 'ERR_MODULE_NOT_FOUND') {
5
+ if (error?.code === 'ERR_MODULE_NOT_FOUND') {
6
6
  process.stderr.write('nmr-compile: build output not found; run `pnpm run bootstrap` first\n');
7
7
  } else {
8
- process.stderr.write(`nmr-compile: failed to load: ${error.message}\n`);
8
+ const message = typeof error?.message === 'string' && error.message !== '' ? error.message : String(error);
9
+ const lines = typeof error?.stack === 'string' ? error.stack.split('\n') : [];
10
+ const firstFrame = lines.findIndex((line) => /^\s+at /.test(line));
11
+ const frames = firstFrame === -1 ? '' : `${lines.slice(firstFrame).join('\n')}\n`;
12
+ process.stderr.write(`nmr-compile: internal error: ${message}\n${frames}`);
9
13
  }
10
14
  process.exit(1);
11
15
  }
package/bin/nmr-fmt.js CHANGED
@@ -2,10 +2,14 @@
2
2
  try {
3
3
  await import('../dist/esm/cli-fmt.js');
4
4
  } catch (error) {
5
- if (error.code === 'ERR_MODULE_NOT_FOUND') {
5
+ if (error?.code === 'ERR_MODULE_NOT_FOUND') {
6
6
  process.stderr.write('nmr-fmt: build output not found; run `pnpm run bootstrap` first\n');
7
7
  } else {
8
- process.stderr.write(`nmr-fmt: failed to load: ${error.message}\n`);
8
+ const message = typeof error?.message === 'string' && error.message !== '' ? error.message : String(error);
9
+ const lines = typeof error?.stack === 'string' ? error.stack.split('\n') : [];
10
+ const firstFrame = lines.findIndex((line) => /^\s+at /.test(line));
11
+ const frames = firstFrame === -1 ? '' : `${lines.slice(firstFrame).join('\n')}\n`;
12
+ process.stderr.write(`nmr-fmt: internal error: ${message}\n${frames}`);
9
13
  }
10
14
  process.exit(1);
11
15
  }
@@ -2,10 +2,14 @@
2
2
  try {
3
3
  await import('../dist/esm/cli-report-catalog.js');
4
4
  } catch (error) {
5
- if (error.code === 'ERR_MODULE_NOT_FOUND') {
5
+ if (error?.code === 'ERR_MODULE_NOT_FOUND') {
6
6
  process.stderr.write('nmr-report-catalog: build output not found; run `pnpm run bootstrap` first\n');
7
7
  } else {
8
- process.stderr.write(`nmr-report-catalog: failed to load: ${error.message}\n`);
8
+ const message = typeof error?.message === 'string' && error.message !== '' ? error.message : String(error);
9
+ const lines = typeof error?.stack === 'string' ? error.stack.split('\n') : [];
10
+ const firstFrame = lines.findIndex((line) => /^\s+at /.test(line));
11
+ const frames = firstFrame === -1 ? '' : `${lines.slice(firstFrame).join('\n')}\n`;
12
+ process.stderr.write(`nmr-report-catalog: internal error: ${message}\n${frames}`);
9
13
  }
10
14
  process.exit(1);
11
15
  }
@@ -2,10 +2,14 @@
2
2
  try {
3
3
  await import('../dist/esm/cli-report-overrides.js');
4
4
  } catch (error) {
5
- if (error.code === 'ERR_MODULE_NOT_FOUND') {
5
+ if (error?.code === 'ERR_MODULE_NOT_FOUND') {
6
6
  process.stderr.write('nmr-report-overrides: build output not found; run `pnpm run bootstrap` first\n');
7
7
  } else {
8
- process.stderr.write(`nmr-report-overrides: failed to load: ${error.message}\n`);
8
+ const message = typeof error?.message === 'string' && error.message !== '' ? error.message : String(error);
9
+ const lines = typeof error?.stack === 'string' ? error.stack.split('\n') : [];
10
+ const firstFrame = lines.findIndex((line) => /^\s+at /.test(line));
11
+ const frames = firstFrame === -1 ? '' : `${lines.slice(firstFrame).join('\n')}\n`;
12
+ process.stderr.write(`nmr-report-overrides: internal error: ${message}\n${frames}`);
9
13
  }
10
14
  process.exit(1);
11
15
  }
package/bin/nmr-taze.js CHANGED
@@ -2,10 +2,14 @@
2
2
  try {
3
3
  await import('../dist/esm/cli-taze.js');
4
4
  } catch (error) {
5
- if (error.code === 'ERR_MODULE_NOT_FOUND') {
5
+ if (error?.code === 'ERR_MODULE_NOT_FOUND') {
6
6
  process.stderr.write('nmr-taze: build output not found; run `pnpm run bootstrap` first\n');
7
7
  } else {
8
- process.stderr.write(`nmr-taze: failed to load: ${error.message}\n`);
8
+ const message = typeof error?.message === 'string' && error.message !== '' ? error.message : String(error);
9
+ const lines = typeof error?.stack === 'string' ? error.stack.split('\n') : [];
10
+ const firstFrame = lines.findIndex((line) => /^\s+at /.test(line));
11
+ const frames = firstFrame === -1 ? '' : `${lines.slice(firstFrame).join('\n')}\n`;
12
+ process.stderr.write(`nmr-taze: internal error: ${message}\n${frames}`);
9
13
  }
10
14
  process.exit(1);
11
15
  }
package/bin/nmr-vitest.js CHANGED
@@ -2,10 +2,14 @@
2
2
  try {
3
3
  await import('../dist/esm/cli-vitest.js');
4
4
  } catch (error) {
5
- if (error.code === 'ERR_MODULE_NOT_FOUND') {
5
+ if (error?.code === 'ERR_MODULE_NOT_FOUND') {
6
6
  process.stderr.write('nmr-vitest: build output not found; run `pnpm run bootstrap` first\n');
7
7
  } else {
8
- process.stderr.write(`nmr-vitest: failed to load: ${error.message}\n`);
8
+ const message = typeof error?.message === 'string' && error.message !== '' ? error.message : String(error);
9
+ const lines = typeof error?.stack === 'string' ? error.stack.split('\n') : [];
10
+ const firstFrame = lines.findIndex((line) => /^\s+at /.test(line));
11
+ const frames = firstFrame === -1 ? '' : `${lines.slice(firstFrame).join('\n')}\n`;
12
+ process.stderr.write(`nmr-vitest: internal error: ${message}\n${frames}`);
9
13
  }
10
14
  process.exit(1);
11
15
  }
package/bin/nmr.js CHANGED
@@ -2,10 +2,14 @@
2
2
  try {
3
3
  await import('../dist/esm/cli.js');
4
4
  } catch (error) {
5
- if (error.code === 'ERR_MODULE_NOT_FOUND') {
5
+ if (error?.code === 'ERR_MODULE_NOT_FOUND') {
6
6
  process.stderr.write('nmr: build output not found; run `pnpm run bootstrap` first\n');
7
7
  } else {
8
- process.stderr.write(`nmr: failed to load: ${error.message}\n`);
8
+ const message = typeof error?.message === 'string' && error.message !== '' ? error.message : String(error);
9
+ const lines = typeof error?.stack === 'string' ? error.stack.split('\n') : [];
10
+ const firstFrame = lines.findIndex((line) => /^\s+at /.test(line));
11
+ const frames = firstFrame === -1 ? '' : `${lines.slice(firstFrame).join('\n')}\n`;
12
+ process.stderr.write(`nmr: internal error: ${message}\n${frames}`);
9
13
  }
10
14
  process.exit(1);
11
15
  }
@@ -4,7 +4,7 @@ import process from 'node:process';
4
4
  import { reportError } from '@williamthorsen/nmr-core';
5
5
  import { createBoundedBuffer } from "./helpers/createBoundedBuffer.js";
6
6
  const SIGNAL_EXIT_BASE = 128;
7
- const PIPE_DRAIN_GRACE_MS = 2_000;
7
+ const PIPE_DRAIN_GRACE_MS = 2000;
8
8
  export function describeSignalExitCode(signal) {
9
9
  return SIGNAL_EXIT_BASE + os.constants.signals[signal];
10
10
  }
@@ -1,12 +1,11 @@
1
1
  import process from 'node:process';
2
- import { reportError } from '@williamthorsen/nmr-core';
3
- import { describeError } from '@williamthorsen/toolbelt.errors';
2
+ import { reportFailure } from '@williamthorsen/nmr-core';
4
3
  import { runActionlint } from "./commands/actionlint.js";
5
4
  import { findMonorepoRoot } from "./workspace.js";
6
5
  try {
7
6
  process.exitCode = await runActionlint(findMonorepoRoot(), process.argv.slice(2));
8
7
  }
9
8
  catch (error) {
10
- reportError(describeError(error));
9
+ reportFailure('nmr-actionlint', error);
11
10
  process.exitCode = 1;
12
11
  }
@@ -1,5 +1,4 @@
1
- import { reportError } from '@williamthorsen/nmr-core';
2
- import { describeError } from '@williamthorsen/toolbelt.errors';
1
+ import { reportFailure } from '@williamthorsen/nmr-core';
3
2
  import { buildPackage } from "./commands/build.js";
4
3
  import { loadWorkspaceConfig } from "./config.js";
5
4
  import { resolveBinStyles } from "./resolveBinStyles.js";
@@ -13,6 +12,6 @@ try {
13
12
  });
14
13
  }
15
14
  catch (error) {
16
- reportError(describeError(error));
15
+ reportFailure('nmr-compile', error);
17
16
  process.exitCode = 1;
18
17
  }
@@ -1,12 +1,11 @@
1
1
  import process from 'node:process';
2
- import { reportError } from '@williamthorsen/nmr-core';
3
- import { describeError } from '@williamthorsen/toolbelt.errors';
2
+ import { reportFailure } from '@williamthorsen/nmr-core';
4
3
  import { runClean } from "./commands/clean.js";
5
4
  import { resolveBinStyles } from "./resolveBinStyles.js";
6
5
  try {
7
6
  await runClean(process.cwd(), resolveBinStyles().stdout);
8
7
  }
9
8
  catch (error) {
10
- reportError(describeError(error));
9
+ reportFailure('nmr-clean', error);
11
10
  process.exitCode = 1;
12
11
  }
@@ -1,5 +1,4 @@
1
- import { parseArgsOrExit, reportError } from '@williamthorsen/nmr-core';
2
- import { describeError } from '@williamthorsen/toolbelt.errors';
1
+ import { parseArgsOrExit, reportFailure } from '@williamthorsen/nmr-core';
3
2
  import { DEFAULT_HOOK, ensurePrepublishHooks, reportPrepublishHooks } from "./commands/ensure-prepublish-hooks.js";
4
3
  import { resolveBinStyles } from "./resolveBinStyles.js";
5
4
  import { findMonorepoRoot } from "./workspace.js";
@@ -20,6 +19,6 @@ try {
20
19
  }
21
20
  }
22
21
  catch (error) {
23
- reportError(describeError(error));
22
+ reportFailure('ensure-prepublish-hooks', error);
24
23
  process.exitCode = 1;
25
24
  }
@@ -1,3 +1,10 @@
1
1
  import process from 'node:process';
2
+ import { reportFailure } from '@williamthorsen/nmr-core';
2
3
  import { runFmt } from "./commands/fmt.js";
3
- process.exitCode = await runFmt(process.argv.slice(2), process.cwd());
4
+ try {
5
+ process.exitCode = await runFmt(process.argv.slice(2), process.cwd());
6
+ }
7
+ catch (error) {
8
+ reportFailure('nmr-fmt', error);
9
+ process.exitCode = 1;
10
+ }
@@ -1,12 +1,11 @@
1
1
  import process from 'node:process';
2
- import { reportError } from '@williamthorsen/nmr-core';
3
- import { describeError } from '@williamthorsen/toolbelt.errors';
2
+ import { reportFailure } from '@williamthorsen/nmr-core';
4
3
  import { reportCatalog } from "./commands/report-catalog.js";
5
4
  import { resolveBinStyles } from "./resolveBinStyles.js";
6
5
  try {
7
6
  reportCatalog(process.cwd(), resolveBinStyles().stderr);
8
7
  }
9
8
  catch (error) {
10
- reportError(describeError(error));
9
+ reportFailure('nmr-report-catalog', error);
11
10
  process.exitCode = 1;
12
11
  }
@@ -1,5 +1,4 @@
1
- import { reportError } from '@williamthorsen/nmr-core';
2
- import { describeError } from '@williamthorsen/toolbelt.errors';
1
+ import { reportFailure } from '@williamthorsen/nmr-core';
3
2
  import { reportOverrides } from "./commands/report-overrides.js";
4
3
  import { resolveBinStyles } from "./resolveBinStyles.js";
5
4
  import { findMonorepoRoot } from "./workspace.js";
@@ -8,6 +7,6 @@ try {
8
7
  reportOverrides(monorepoRoot, resolveBinStyles().stderr);
9
8
  }
10
9
  catch (error) {
11
- reportError(describeError(error));
10
+ reportFailure('nmr-report-overrides', error);
12
11
  process.exitCode = 1;
13
12
  }
@@ -1,11 +1,11 @@
1
1
  import process from 'node:process';
2
- import { reportError } from '@williamthorsen/nmr-core';
3
- import { describeError } from '@williamthorsen/toolbelt.errors';
2
+ import { reportFailure } from '@williamthorsen/nmr-core';
4
3
  import { runTaze } from "./commands/taze.js";
4
+ import { resolveBinStyles } from "./resolveBinStyles.js";
5
5
  try {
6
- process.exitCode = await runTaze(process.argv.slice(2));
6
+ process.exitCode = await runTaze(process.argv.slice(2), { stderrStyle: resolveBinStyles().stderr });
7
7
  }
8
8
  catch (error) {
9
- reportError(describeError(error));
9
+ reportFailure('nmr-taze', error);
10
10
  process.exitCode = 1;
11
11
  }
@@ -1,3 +1,10 @@
1
1
  import process from 'node:process';
2
+ import { reportFailure } from '@williamthorsen/nmr-core';
2
3
  import { runNmrVitest } from "./commands/run-vitest.js";
3
- process.exitCode = runNmrVitest(process.argv.slice(2), process.cwd());
4
+ try {
5
+ process.exitCode = runNmrVitest(process.argv.slice(2), process.cwd());
6
+ }
7
+ catch (error) {
8
+ reportFailure('nmr-vitest', error);
9
+ process.exitCode = 1;
10
+ }
package/dist/esm/cli.js CHANGED
@@ -1,5 +1,5 @@
1
1
  import process from 'node:process';
2
- import { reportCliFailure } from "./reportCliFailure.js";
2
+ import { reportFailure } from '@williamthorsen/nmr-core';
3
3
  import { runCli } from "./runCli.js";
4
4
  try {
5
5
  const { exitCode } = await runCli({
@@ -12,6 +12,6 @@ try {
12
12
  process.exitCode = exitCode;
13
13
  }
14
14
  catch (error) {
15
- reportCliFailure(error, process.stderr);
15
+ reportFailure('nmr', error);
16
16
  process.exitCode = 1;
17
17
  }