Skip to content

Package build scripts invoke nmr through a shell, so every nmr build warns #1289

Description

@williamthorsen

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

  • nmr build from the repo root emits no shelled-nmr warnings.
  • The agents build produces the same artifacts, in the same order, as before the change.
  • A test fails when a workspace package.json declares an nmr-invoking script under a name nmr resolves as a command.

Metadata

Metadata

Projects

No projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions