@williamthorsen/nmr 0.38.0 โ†’ 0.40.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.
Files changed (112) hide show
  1. package/.meta/changelog.json +212 -4
  2. package/.readyup/kits/default.js +124 -104
  3. package/.readyup/manifest.json +12 -7
  4. package/CHANGELOG.md +108 -0
  5. package/README.md +41 -47
  6. package/agents/README.md +8 -8
  7. package/agents/guidance/rulebooks/nmr.md +8 -8
  8. package/bin/ensure-prepublish-hooks.js +1 -1
  9. package/bin/nmr-clean.js +1 -1
  10. package/bin/nmr-compile.js +1 -1
  11. package/bin/nmr-fmt.js +1 -1
  12. package/bin/nmr-report-catalog.js +1 -1
  13. package/bin/nmr-report-overrides.js +1 -1
  14. package/bin/nmr-taze.js +1 -1
  15. package/bin/nmr.js +1 -1
  16. package/dist/esm/UserError.d.ts +1 -2
  17. package/dist/esm/check-cache.d.ts +61 -63
  18. package/dist/esm/check-cache.js +24 -24
  19. package/dist/esm/cli-ensure-prepublish-hooks.js +4 -4
  20. package/dist/esm/commands/build-output.d.ts +37 -38
  21. package/dist/esm/commands/build-output.js +9 -9
  22. package/dist/esm/commands/build.d.ts +13 -14
  23. package/dist/esm/commands/build.js +67 -65
  24. package/dist/esm/commands/clean.d.ts +6 -6
  25. package/dist/esm/commands/clean.js +11 -11
  26. package/dist/esm/commands/ensure-prepublish-hooks.d.ts +7 -7
  27. package/dist/esm/commands/ensure-prepublish-hooks.js +41 -41
  28. package/dist/esm/commands/fmt.d.ts +8 -8
  29. package/dist/esm/commands/fmt.js +33 -33
  30. package/dist/esm/commands/report-catalog.d.ts +5 -7
  31. package/dist/esm/commands/report-catalog.js +10 -8
  32. package/dist/esm/commands/report-overrides.d.ts +0 -2
  33. package/dist/esm/commands/report-overrides.js +8 -8
  34. package/dist/esm/commands/taze.d.ts +9 -8
  35. package/dist/esm/config.d.ts +5 -5
  36. package/dist/esm/config.js +27 -27
  37. package/dist/esm/context.d.ts +1 -2
  38. package/dist/esm/context.js +8 -8
  39. package/dist/esm/default-scripts.d.ts +5 -6
  40. package/dist/esm/defineConfig.d.ts +1 -1
  41. package/dist/esm/git-ignored-paths.d.ts +9 -0
  42. package/dist/esm/git-ignored-paths.js +10 -0
  43. package/dist/esm/glyphs.d.ts +3 -3
  44. package/dist/esm/help.d.ts +4 -4
  45. package/dist/esm/help.js +21 -21
  46. package/dist/esm/helpers/clampToBytes.d.ts +4 -5
  47. package/dist/esm/helpers/clampToBytes.js +3 -3
  48. package/dist/esm/helpers/config-path.d.ts +0 -2
  49. package/dist/esm/helpers/createBoundedBuffer.d.ts +3 -3
  50. package/dist/esm/helpers/createBoundedBuffer.js +2 -2
  51. package/dist/esm/helpers/deriveExcerpt.d.ts +4 -5
  52. package/dist/esm/helpers/duration.d.ts +10 -11
  53. package/dist/esm/helpers/duration.js +7 -7
  54. package/dist/esm/helpers/filter-selection.d.ts +19 -19
  55. package/dist/esm/helpers/filter-selection.js +12 -12
  56. package/dist/esm/helpers/findClosestName.d.ts +1 -1
  57. package/dist/esm/helpers/findClosestName.js +15 -15
  58. package/dist/esm/helpers/hook-name.d.ts +2 -5
  59. package/dist/esm/helpers/package-json.d.ts +11 -10
  60. package/dist/esm/helpers/package-json.js +26 -25
  61. package/dist/esm/helpers/readStringValues.d.ts +2 -3
  62. package/dist/esm/helpers/reportClosing.d.ts +8 -9
  63. package/dist/esm/helpers/transcript.d.ts +15 -15
  64. package/dist/esm/helpers/transcript.js +14 -14
  65. package/dist/esm/helpers/type-guards.d.ts +1 -0
  66. package/dist/esm/output-style.d.ts +12 -13
  67. package/dist/esm/prettier.d.ts +2 -2
  68. package/dist/esm/prettier.js +5 -5
  69. package/dist/esm/recording.d.ts +25 -20
  70. package/dist/esm/recording.js +28 -21
  71. package/dist/esm/replay-assembly.d.ts +10 -10
  72. package/dist/esm/report-format.d.ts +15 -20
  73. package/dist/esm/report-format.js +7 -7
  74. package/dist/esm/reportCliFailure.d.ts +2 -3
  75. package/dist/esm/resolve-scripts.d.ts +4 -5
  76. package/dist/esm/resolveBinStyles.d.ts +4 -5
  77. package/dist/esm/resolveBinStyles.js +3 -3
  78. package/dist/esm/resolver.d.ts +16 -20
  79. package/dist/esm/resolver.js +15 -15
  80. package/dist/esm/runCli.d.ts +6 -6
  81. package/dist/esm/runCli.js +261 -195
  82. package/dist/esm/runner.d.ts +20 -20
  83. package/dist/esm/runner.js +18 -18
  84. package/dist/esm/steps.d.ts +51 -38
  85. package/dist/esm/steps.js +32 -27
  86. package/dist/esm/taze.d.ts +1 -1
  87. package/dist/esm/tests.d.ts +23 -18
  88. package/dist/esm/tests.js +21 -9
  89. package/dist/esm/tiers.d.ts +28 -24
  90. package/dist/esm/tiers.js +13 -9
  91. package/dist/esm/types.d.ts +5 -5
  92. package/dist/esm/verbosity.d.ts +23 -21
  93. package/dist/esm/verbosity.js +7 -7
  94. package/dist/esm/verdict.d.ts +39 -32
  95. package/dist/esm/verdict.js +63 -50
  96. package/dist/esm/vitest-source-resolution.d.ts +11 -11
  97. package/dist/esm/vitest-source-resolution.js +49 -47
  98. package/dist/esm/vitest.d.ts +27 -26
  99. package/dist/esm/vitest.js +90 -33
  100. package/dist/esm/workspace.d.ts +6 -22
  101. package/dist/esm/workspace.js +9 -67
  102. package/docs/check-cache.md +57 -57
  103. package/docs/prettier.md +10 -10
  104. package/docs/reporting.md +48 -44
  105. package/docs/scripts.md +29 -29
  106. package/docs/upgrades.md +18 -18
  107. package/docs/utilities.md +13 -13
  108. package/docs/vitest.md +68 -66
  109. package/docs/workspace.md +27 -4
  110. package/package.json +6 -6
  111. package/dist/esm/helpers/workspace-patterns.d.ts +0 -8
  112. package/dist/esm/helpers/workspace-patterns.js +0 -29
@@ -1,4 +1,211 @@
1
1
  [
2
+ {
3
+ "version": "0.40.0",
4
+ "date": "2026-10-01",
5
+ "sections": [
6
+ {
7
+ "title": "๐ŸŽ‰ Features",
8
+ "audience": "all",
9
+ "items": [
10
+ {
11
+ "description": "Makes `checkTestFileConventions` and the readyup kit's tier and placement checks skip untracked paths that git ignores, so that local build output such as a stale `.netlify/` directory no longer fails the check. (#898)",
12
+ "hash": "15132d5e797b734f1fc78bce7abc5d82c7e81974",
13
+ "entry": 1
14
+ },
15
+ {
16
+ "description": "Excludes untracked paths that git ignores from collection in `defineVitestConfig` and `defineRootVitestConfig`, so that Vitest does not run a test file that the conventions check skips. (#898)",
17
+ "hash": "15132d5e797b734f1fc78bce7abc5d82c7e81974",
18
+ "entry": 2
19
+ },
20
+ {
21
+ "description": "Rewords the `nmr --log` refusal for a run that the check-result cache does not cover to `the check-result cache does not apply here (NMR_DEBUG=1 reports why)`, and renames the matching `docs/check-cache.md` heading to \"When the cache does not apply\", which changes its anchor. (#923)",
22
+ "hash": "71d8c3dfb45aca872ca897ee589aae6351a1f516",
23
+ "entry": 1
24
+ }
25
+ ]
26
+ },
27
+ {
28
+ "title": "๐Ÿ› Bug fixes",
29
+ "audience": "all",
30
+ "items": [
31
+ {
32
+ "description": "Rewords the messages printed by `nmr`, its bin wrappers, and its readyup kit, which used figures such as \"sits under\" and \"holds\", em-dashes, and \"no\" as a determiner, so that a diagnosis such as \"-F/--filter did not match any workspace\" states its condition directly. (#932)",
33
+ "hash": "570f1103437d22b81b556f2d2b2e02f1fc32942c",
34
+ "entry": 1
35
+ },
36
+ {
37
+ "description": "Fixes the issue that the `nmr` rulebook recommended `-q` without stating that nmr reads its own flags only before the command name, which led agents to run `nmr ci -q` and fail when `nmr-fmt` rejected the flag. (#948)",
38
+ "hash": "b7cf3b3dfcd901db11546f153ec6de61580e6a69",
39
+ "entry": 1
40
+ }
41
+ ]
42
+ },
43
+ {
44
+ "title": "โ™ป๏ธ Refactoring",
45
+ "audience": "dev",
46
+ "items": [
47
+ {
48
+ "description": "Replaces every `.sort()` call that suppressed `unicorn/no-array-sort` with `toSorted()` and drops the spread copy wherever the source was already an array. (#925)",
49
+ "hash": "4680fb4e865ffce0bd135fac20d49b766b156992",
50
+ "entry": 1
51
+ }
52
+ ]
53
+ },
54
+ {
55
+ "title": "๐Ÿงช Tests",
56
+ "audience": "dev",
57
+ "items": [
58
+ {
59
+ "description": "Stubs `GIT_CEILING_DIRECTORIES` to the fixture's parent in every test that expects git to find no repository, so that a repository above the temp directory can no longer change the test's result. (#923)",
60
+ "hash": "71d8c3dfb45aca872ca897ee589aae6351a1f516",
61
+ "entry": 2
62
+ },
63
+ {
64
+ "description": "Moves the `everyBinTargetIsACommittedWrapper` tests from `kit-bin-checks.unit.test.ts` to `kit-bin-checks.tool.test.ts`, because they spawn git through readyup's `listTrackedFiles`. (#923)",
65
+ "hash": "71d8c3dfb45aca872ca897ee589aae6351a1f516",
66
+ "entry": 3
67
+ }
68
+ ]
69
+ },
70
+ {
71
+ "title": "โš™๏ธ Tooling",
72
+ "audience": "dev",
73
+ "items": [
74
+ {
75
+ "description": "Adds a check to `bootstrap.tool.test.ts` that fails when a package's `prepare` runs the build bootstrap without either depending on nmr-core or passing `--conditions nmr-source`, which would make `pnpm install` fail on a fresh clone. (#903)",
76
+ "hash": "b00b17d277197c1b18133da2e5258cf52719946a",
77
+ "entry": 3
78
+ }
79
+ ]
80
+ },
81
+ {
82
+ "title": "๐Ÿ“ฆ Dependencies",
83
+ "audience": "dev",
84
+ "items": [
85
+ {
86
+ "description": "Adds `esbuild` 0.28.2 to the pnpm catalog and declares it as a devDependency of `nmr`, `release-kit`, and `v11y-check`, because `readyup` declares it only as an optional peer and `rdy compile` failed in those packages once a regenerated lockfile stopped installing it. (#944)",
87
+ "hash": "6dffd5df5bc4209dc225d08390ef2b67fe381f1b",
88
+ "entry": 2
89
+ }
90
+ ]
91
+ },
92
+ {
93
+ "title": "๐Ÿ“š Documentation",
94
+ "audience": "dev",
95
+ "items": [
96
+ {
97
+ "description": "Revises the comments in `packages/nmr/src` and `packages/nmr/.readyup/kits/default.ts` against the comment-discipline rules, correcting comments that misstated the code, such as the Levenshtein distance quoted in `runCli.ts` and a `root-tests-config` kit check that does not exist. (#919)",
98
+ "hash": "84fe905d4142059425d82eb8d10821b687f522c2",
99
+ "entry": 1
100
+ },
101
+ {
102
+ "description": "Corrects the truncation example in `packages/nmr/docs/reporting.md`, replacing 90 seconds, which renders as `1m 30s` whether it is truncated or rounded, with 119.9 seconds, which truncates to `1m 59s`. (#919)",
103
+ "hash": "84fe905d4142059425d82eb8d10821b687f522c2",
104
+ "entry": 2
105
+ },
106
+ {
107
+ "description": "Rewrites the sentences in the README, the guides under `docs/`, the agent rulebook, and the code comments of `@williamthorsen/nmr` that broke the repository's writing rules on plain speech, em-dashes, second-person address, and relative clauses. (#932)",
108
+ "hash": "570f1103437d22b81b556f2d2b2e02f1fc32942c",
109
+ "entry": 2
110
+ },
111
+ {
112
+ "description": "Replaces \"where\" in two doc comments in `packages/nmr/src/check-cache.ts` and in the fixture comment in two tier-budget tests, because each use introduced a consequence rather than a place. (#945)",
113
+ "hash": "6f2c93ee0c73810ebd4cb4ab76618c00235edc42",
114
+ "entry": 1
115
+ },
116
+ {
117
+ "description": "Writes `-q` as `nmr -q <command>` in `docs/reporting.md` and in the README's verbosity paragraph. (#948)",
118
+ "hash": "b7cf3b3dfcd901db11546f153ec6de61580e6a69",
119
+ "entry": 2
120
+ }
121
+ ]
122
+ }
123
+ ]
124
+ },
125
+ {
126
+ "version": "0.39.0",
127
+ "date": "2026-09-22",
128
+ "sections": [
129
+ {
130
+ "title": "๐ŸŽ‰ Features",
131
+ "audience": "all",
132
+ "items": [
133
+ {
134
+ "description": "Report why a workspace selects no package, and no-op nmr's own -R steps (#841)",
135
+ "body": "- Drops a `-R` step that nmr composed into a script where the workspace holds no package, so `typecheck` and the five `test` scripts run there instead of failing the run.\n- Adds a no-op verdict for a command that the drop leaves with no step at all.\n- Replaces the single refusal for a workspace that selects no package with one message per cause.\n\nMigration: In a repo that declares a workspace package pattern and deliberately holds no package, delete the `.config/nmr.config.ts` entries added to work around the `-R` refusal, the `build: ':'` override included.",
136
+ "migration": "In a repo that declares a workspace package pattern and deliberately holds no package, delete the `.config/nmr.config.ts` entries added to work around the `-R` refusal, the `build: ':'` override included.",
137
+ "hash": "0b21f4b29a40aab5c56f10026789e8c0e72161ab"
138
+ },
139
+ {
140
+ "description": "Prefix the booleans and reject unrecognized Vitest option keys (#849)",
141
+ "body": "- Renames two boolean options of `defineVitestConfig` and `defineRootVitestConfig`, the factories that build a repo's Vitest config: `isolateGit` becomes `shouldIsolateGit`, and `resolveFromSource` becomes `shouldResolveFromSource`.\n- Makes both factories reject an option key outside the recognized set, naming the offending keys and the recognized ones, rather than ignoring a misspelled or retired key and letting its option fall back to the default with nothing in the run reporting it.\n- Adds a retired-key check that runs ahead of the unrecognized-key check, reporting the new name for a config that still sets `isolateGit` or `resolveFromSource`.\n\nMigration: In each options object passed to `defineVitestConfig` or `defineRootVitestConfig`, rename `isolateGit` to `shouldIsolateGit` and `resolveFromSource` to `shouldResolveFromSource`, and correct any other key that the factory now rejects. `defineRootVitestConfig` recognizes `monorepoRoot` on the last layer alone, so a config that sets it on an earlier layer now throws where the old code ignored it.",
142
+ "breaking": true,
143
+ "migration": "In each options object passed to `defineVitestConfig` or `defineRootVitestConfig`, rename `isolateGit` to `shouldIsolateGit` and `resolveFromSource` to `shouldResolveFromSource`, and correct any other key that the factory now rejects. `defineRootVitestConfig` recognizes `monorepoRoot` on the last layer alone, so a config that sets it on an earlier layer now throws where the old code ignored it.",
144
+ "hash": "ed2d1ba9a505c3a6d9fd5455c23bd110b9b8a7c5"
145
+ },
146
+ {
147
+ "description": "End nmr's source value names with the kind of the value (#850)",
148
+ "body": "- Renames two fields of `TestFileConventionsReport`, `misplaced` and `untiered`, to `misplacedFiles` and `untieredFiles`, and renames `TestFileConventionsOptions`'s `exclude` to `excludedBasenames`, in the `@williamthorsen/nmr/tests` entry point.\n- Adds a guard to `checkTestFileConventions` and `reportTestFileConventions` that throws a `TypeError` naming `excludedBasenames` when a call still sets `exclude`.\n\nMigration: Read `report.misplacedFiles` and `report.untieredFiles` in place of `report.misplaced` and `report.untiered`, and pass `excludedBasenames` in place of `exclude`. A call that still sets `exclude` throws rather than running with no exclusions, so the failure surfaces where Vitest loads the call site.",
149
+ "breaking": true,
150
+ "migration": "Read `report.misplacedFiles` and `report.untieredFiles` in place of `report.misplaced` and `report.untiered`, and pass `excludedBasenames` in place of `exclude`. A call that still sets `exclude` throws rather than running with no exclusions, so the failure surfaces where Vitest loads the call site.",
151
+ "hash": "059c249e2857bed87cefcce02e894ce3a9a65970"
152
+ },
153
+ {
154
+ "description": "Hoist the pnpm-workspace resolver into nmr-core as a total API (#864)",
155
+ "body": "- Adds a `./workspace` subpath export to `@williamthorsen/nmr-core`, whose `resolveWorkspace` returns a pnpm workspace's package directories, or the cause of an empty result, as a value rather than as a thrown error.\n- Reports a `pnpm-workspace.yaml` that the YAML parser rejects under a cause of its own, `unreadable-manifest`, so `nmr -R build` names the syntax error and its remedy in place of failing with the parser's own error.\n- Removes `diagnoseEmptyWorkspace` and `EmptyWorkspaceDiagnosis` from `@williamthorsen/nmr/workspace`, since `resolveWorkspace` reports the same cause in one call.\n\nMigration: Replace each `diagnoseEmptyWorkspace` call with `resolveWorkspace`, which reports the cause on the empty result it already returns, and rename the `no-manifest` cause to `no-package`. `EmptyWorkspaceCause` also gains `unreadable-manifest`, so an exhaustive switch over it stops compiling until it handles the new member; every other export of `@williamthorsen/nmr/workspace` keeps its signature and its `UserError` throws.",
156
+ "breaking": true,
157
+ "migration": "Replace each `diagnoseEmptyWorkspace` call with `resolveWorkspace`, which reports the cause on the empty result it already returns, and rename the `no-manifest` cause to `no-package`. `EmptyWorkspaceCause` also gains `unreadable-manifest`, so an exhaustive switch over it stops compiling until it handles the new member; every other export of `@williamthorsen/nmr/workspace` keeps its signature and its `UserError` throws.",
158
+ "hash": "3196b84c9d5f037ead0e98ee8547fe71e80fb5c6"
159
+ },
160
+ {
161
+ "description": "Adopt the shared workspace resolver in release-kit, honoring exclusions (#865)",
162
+ "body": "- ๐Ÿšจ **Breaking:** Narrows `no-pattern` in `@williamthorsen/nmr-core`'s `EmptyWorkspaceCause`, moving an absent or empty `packages` list onto `no-packages-list` and a value that is not a list of strings onto `unreadable-packages`.\n- Stops `release-kit` from tagging, publishing, and label-syncing a package that a `!` entry in `pnpm-workspace.yaml` excludes, which its previous `glob`-based resolution could not remove from the match.\n- Replaces the release of the root package alone with a failure naming the condition that emptied the workspace, when `pnpm-workspace.yaml` does not hold valid YAML or declares a workspace that does not resolve to a package.\n- Replaces the `no-pattern` remedy that `nmr` printed for a `pnpm-workspace.yaml` declaring no `packages` list, and for one declaring a `packages` value that is not a list of strings.\n- Raises `engines.node` to `>=24.16.0` in `@williamthorsen/nmr-core` and `@williamthorsen/release-kit`, because Node 24.0 through 24.15 ignores the `followSymlinks` option that the workspace matcher passes to `globSync` and drops a symlinked package directory from the resolution without reporting it.\n\nMigration: Add a `no-packages-list` arm and an `unreadable-packages` arm to any `switch` that covers `EmptyWorkspaceCause` exhaustively. `no-pattern` now names only a list that the resolver read in full and whose entries all failed to become a positive pattern, so move the handling of an absent `packages` key, an empty list, and a value that is not a list of strings out of the `no-pattern` arm into the two new ones. Route `no-packages-list` to single-package behavior rather than to a failure path: pnpm resolves such a manifest to the root package alone.",
163
+ "breaking": true,
164
+ "migration": "Add a `no-packages-list` arm and an `unreadable-packages` arm to any `switch` that covers `EmptyWorkspaceCause` exhaustively. `no-pattern` now names only a list that the resolver read in full and whose entries all failed to become a positive pattern, so move the handling of an absent `packages` key, an empty list, and a value that is not a list of strings out of the `no-pattern` arm into the two new ones. Route `no-packages-list` to single-package behavior rather than to a failure path: pnpm resolves such a manifest to the root package alone.",
165
+ "hash": "b1126866159402b8f027a9b82f2a19591a6e9e1b"
166
+ }
167
+ ]
168
+ },
169
+ {
170
+ "title": "โ™ป๏ธ Refactoring",
171
+ "audience": "dev",
172
+ "items": [
173
+ {
174
+ "description": "Align nmr's function names with naming conventions (#852)",
175
+ "body": "- Renames the functions in `packages/nmr` to align with naming conventions.",
176
+ "hash": "8a41a206ebe0374c844b20dca0eded7da6240133"
177
+ },
178
+ {
179
+ "description": "Suffix nmr's unit-measuring numbers and expand its abbreviations (#854)",
180
+ "body": "- Renames every unit-measuring number and abbreviated identifier under `packages/nmr/src`, adding `Ms`, `Bytes`, and `Offset` suffixes to the quantities and expanding `pkg`, `Len`, and `Idx` to `package`, `Length`, and `Index`. The renames are not part of any public API.",
181
+ "hash": "f8292228095a475b9a187ba64d700cb222f80305"
182
+ }
183
+ ]
184
+ },
185
+ {
186
+ "title": "๐Ÿงช Tests",
187
+ "audience": "dev",
188
+ "items": [
189
+ {
190
+ "description": "End nmr's test value names with the kind of the value (#851)",
191
+ "body": "- Aligns the name of every non-boolean value in `packages/nmr/src/**/__tests__` with naming conventions.\n- Renames `inline` to `inlineBody` in the repo-root `__tests__/reusable-workflow-runtime.app.unit.test.ts`.",
192
+ "hash": "d12494b2be31f0e73cda1afb7113e7508e9969ee"
193
+ }
194
+ ]
195
+ },
196
+ {
197
+ "title": "๐Ÿ‘ท CI",
198
+ "audience": "dev",
199
+ "items": [
200
+ {
201
+ "description": "Make the release workflow Corepack-agnostic (#842)",
202
+ "body": "- Removes the `Disable Corepack` step from `release.reusable.yaml`, which Node 25's removal of Corepack from the distribution would make fail with `command not found` once `actions/setup-node` moves past Node 24, and keeps `COREPACK_ENABLE_STRICT: '0'`, which guards the source-build path where the pnpm `packageManager` pin survives.\n- Adds a case to `reusable-workflow-runtime.app.unit.test.ts` that fails the test run on any reusable workflow whose `run:` commands invoke `corepack`, enumerated from `.github/workflows` so that a workflow added later is covered without editing a list.\n- Drops the Corepack recommendation from the README's pnpm prerequisite, which now points at pnpm's installation page, and from the fix text of the `.tool-versions does not list pnpm` check in nmr's readyup kit, which now names the `packageManager` field.",
203
+ "hash": "dd46b629c3b4448b701ded3301f6794bdea7af6b"
204
+ }
205
+ ]
206
+ }
207
+ ]
208
+ },
2
209
  {
3
210
  "version": "0.38.0",
4
211
  "date": "2026-09-18",
@@ -145,7 +352,8 @@
145
352
  "items": [
146
353
  {
147
354
  "description": "Keep global git ignore rules and attributes out of test subprocesses (#773)",
148
- "body": "Fixes an issue where a test that spawns `git` read ignore rules and attributes from outside the repository, so a suite could pass or fail on whatever a developer or their machine happened to have configured. The setup file that `defineVitestConfig` loads by default now isolates both, alongside the git configuration already covered.\r\n\r\nMigration: Where a test needs its own `core.excludesFile` or `core.attributesFile`, pass it on the invocation as `git -c core.excludesFile=<path>`. An environment-injected key now outranks repository-local config.",
355
+ "body": "Fixes an issue where a test that spawns `git` read ignore rules and attributes from outside the repository, so a suite could pass or fail on whatever a developer or their machine happened to have configured. The setup file that `defineVitestConfig` loads by default now isolates both, alongside the git configuration already covered.\n\nMigration: Where a test needs its own `core.excludesFile` or `core.attributesFile`, pass it on the invocation as `git -c core.excludesFile=<path>`. An environment-injected key now outranks repository-local config.",
356
+ "migration": "Where a test needs its own `core.excludesFile` or `core.attributesFile`, pass it on the invocation as `git -c core.excludesFile=<path>`. An environment-injected key now outranks repository-local config.",
149
357
  "hash": "59b454ff3344a7c00d766f041a5862faa1ee6f1f"
150
358
  }
151
359
  ]
@@ -382,7 +590,7 @@
382
590
  "items": [
383
591
  {
384
592
  "description": "Carry the test-tier convention in the ambient rulebook (#689)",
385
- "body": "Adds the test-tier convention to `nmr.md`, the ambient rulebook `codeassembly sync` deploys to each consuming repo's agent guidance. The guidance describes the `<subject>[.<aspect>].<tier>.test.ts` grammar and the four tiers, and warns that tests outside a `__tests__` directory are ignored. Tests not explicitly attributed to a tier are flagged by the ReadyUp kit bundled with `nmr`.\r\n\r\nThe previous guidance is removed from `AGENTS.md`.",
593
+ "body": "Adds the test-tier convention to `nmr.md`, the ambient rulebook `codeassembly sync` deploys to each consuming repo's agent guidance. The guidance describes the `<subject>[.<aspect>].<tier>.test.ts` grammar and the four tiers, and warns that tests outside a `__tests__` directory are ignored. Tests not explicitly attributed to a tier are flagged by the ReadyUp kit bundled with `nmr`.\n\nThe previous guidance is removed from `AGENTS.md`.",
386
594
  "hash": "a1fa0e0eb19362f0506ce4f98cd527b205baf1e7"
387
595
  },
388
596
  {
@@ -419,7 +627,7 @@
419
627
  },
420
628
  {
421
629
  "description": "Adopt `isError` and consolidate errno narrowing on a shared helper (#697)",
422
- "body": "Replaces every hand-rolled `instanceof Error` narrowing with `hasErrnoCode`, a new predicate exported from `@williamthorsen/nmr-core`, or with `isError` from `@williamthorsen/toolbelt.errors`. Previously the errno question was answered by inline copies alongside two private helpers of differing shape; both helpers are removed.\r\n\r\nSeparately, `eslint.config.ts` now bans `instanceof Error` in every position rather than in a ternary alone.",
630
+ "body": "Replaces every hand-rolled `instanceof Error` narrowing with `hasErrnoCode`, a new predicate exported from `@williamthorsen/nmr-core`, or with `isError` from `@williamthorsen/toolbelt.errors`. Previously the errno question was answered by inline copies alongside two private helpers of differing shape; both helpers are removed.\n\nSeparately, `eslint.config.ts` now bans `instanceof Error` in every position rather than in a ternary alone.",
423
631
  "hash": "c5e8e8a5e006b451e8c5aeea75d35772926d503c"
424
632
  }
425
633
  ]
@@ -497,7 +705,7 @@
497
705
  "items": [
498
706
  {
499
707
  "description": "Derive the shelled-nmr remedy from the declaration site and reject a malformed package.json (#658)",
500
- "body": "Fixes a shelled-nmr warning that named `.config/nmr.config.ts` as the remedy for every step it reported, including the `package.json` entries that tier cannot resolve. The line now names the relevant declaration and remedy. Shelled nmr can now be detected not only in a step's first token but anywhere in the step.\r\n\r\nSeparately, a configuration mistake now reports as a plain message rather than a Node stack trace.",
708
+ "body": "Fixes a shelled-nmr warning that named `.config/nmr.config.ts` as the remedy for every step it reported, including the `package.json` entries that tier cannot resolve. The line now names the relevant declaration and remedy. Shelled nmr can now be detected not only in a step's first token but anywhere in the step.\n\nSeparately, a configuration mistake now reports as a plain message rather than a Node stack trace.",
501
709
  "hash": "74ea98c361cf13e213d257952c582a4ebd631d9a"
502
710
  }
503
711
  ]