Problem
nmr build emits five warnings, one per package whose package.json declares a build script that reaches nmr through a shell. A shelled step hides the nested run: nmr handles its output as a tool's rather than a nested run's, so a quiet failure surrenders the whole nested subtree instead of the failing step, and an interrupt does not stop what would have followed.
⚠️ build: `nmr compile` runs nmr behind a shell, so nmr handles its output as a tool's rather than a nested run's. A step list in `.config/nmr.config.ts` avoids it.
Context
nmr's warning names a step list in .config/nmr.config.ts as the remedy. That does not apply here — resolveScript returns on the package.json hit before reaching the registry, so a config entry stays shadowed while the override remains. Reported upstream as williamthorsen/node-monorepo-tools#656; no upstream change is needed to resolve this ticket.
nmr's own repo declares no nmr-invoking build script in any package, and expresses a package-specific post-compile step as a build:post hook (release-kit). This change adopts that layout.
Proposed solution
No package declares a build script that invokes nmr. Packages restating nmr's built-in workspace default resolve to it directly, and agents' two post-compile steps move into its existing build:post hook ahead of rdy compile, preserving step order. A root test guards against reintroduction, exempting npm lifecycle script names — nmr never resolves those as commands, and prepublishOnly: "nmr build" is the upstream-sanctioned pattern.
.config/nmr.config.ts needs no entry. The guard reads the monorepo root's manifest alongside each package's, since nmr resolves root's scripts as a tier-3 override the way it resolves a package's. Three exclusions are deliberate: fleet's ":" build, an intentional skip whose removal would start compiling a tsx-run server; factory's and foreman's vite builds, which invoke no nmr; and root's bootstrap, exempted by name because pnpm run bootstrap is the fresh-checkout entry point on a machine with neither direnv nor pnpm exec — a call upstream likewise keeps in pnpm.
Acceptance criteria
Must have
Problem
nmr buildemits five warnings, one per package whosepackage.jsondeclares abuildscript that reachesnmrthrough a shell. A shelled step hides the nested run: nmr handles its output as a tool's rather than a nested run's, so a quiet failure surrenders the whole nested subtree instead of the failing step, and an interrupt does not stop what would have followed.Context
nmr's warning names a step list in
.config/nmr.config.tsas the remedy. That does not apply here —resolveScriptreturns on thepackage.jsonhit before reaching the registry, so a config entry stays shadowed while the override remains. Reported upstream as williamthorsen/node-monorepo-tools#656; no upstream change is needed to resolve this ticket.nmr's own repo declares no nmr-invoking
buildscript in any package, and expresses a package-specific post-compile step as abuild:posthook (release-kit). This change adopts that layout.Proposed solution
No package declares a
buildscript that invokes nmr. Packages restating nmr's built-in workspace default resolve to it directly, and agents' two post-compile steps move into its existingbuild:posthook ahead ofrdy compile, preserving step order. A root test guards against reintroduction, exempting npm lifecycle script names — nmr never resolves those as commands, andprepublishOnly: "nmr build"is the upstream-sanctioned pattern..config/nmr.config.tsneeds no entry. The guard reads the monorepo root's manifest alongside each package's, since nmr resolves root's scripts as a tier-3 override the way it resolves a package's. Three exclusions are deliberate: fleet's":"build, an intentional skip whose removal would start compiling a tsx-run server; factory's and foreman's vite builds, which invoke no nmr; and root'sbootstrap, exempted by name becausepnpm run bootstrapis the fresh-checkout entry point on a machine with neither direnv norpnpm exec— a call upstream likewise keeps in pnpm.Acceptance criteria
Must have
nmr buildfrom the repo root emits no shelled-nmr warnings.package.jsondeclares an nmr-invoking script under a name nmr resolves as a command.