Skip to main content

Normalize Tooling

Normalize scripts, allowScripts, gypfile, config, and workspaces fields in workspace package.json files.

Summary

The normalize-tooling recipe handles tooling-related fields in each workspace's package.json.

It normalizes the scripts object, allowScripts object, gypfile flag, config object, and workspaces field according to workspace role conventions.

Why Use This Command?

  1. Keeps package scripts and tooling metadata in shapes expected by npm and the repository toolchain.
  2. Detects binding.gyp and workspace roles so native and monorepo fields appear only when applicable.
  3. Removes empty tooling objects before they become misleading configuration stubs.

Requirements

  • Node.js runtime — Use a supported Node.js LTS release with the Nova CLI available.
  • Project config — Register the workspace and enable recipes.package-json.<workspace>.normalize-tooling in nova.config.json.
  • Workspace manifest — The configured workspace must contain a readable package.json file.

Behavior

For each eligible workspace, the recipe inspects tooling-related fields and applies the following rules. See Workspace Rules for how tags are determined.

  • scripts (Required) — If the field is missing, it is added as an empty object {}. Nova organizes command families as dev, prod, check, build, deploy, clean, changelog, recipes, optional i18n, project-specific commands, and npm lifecycle scripts.
  • allowScripts (Conditional) — Removed if the field is present but empty. A non-empty policy is preserved exactly; Nova never adds an approval or changes an existing decision.
  • gypfile (Required) — If present but no binding.gyp file exists in the workspace directory, the field is removed. If missing but binding.gyp exists and neither scripts.preinstall nor scripts.install are defined, it is added as true.
  • config (Conditional) — Removed if the field is present but empty.
  • workspaces (Required) — Removed if the workspace role is not project. If the role is project and the field is missing, it is added as an empty array [].

Script Organization

  • Matching pre<name> and post<name> hooks wrap their parent or child command, while name:* children retain their authored order.
  • Project-specific command families follow optional i18n, and npm installation, preparation, packaging, publishing, versioning, and dependency hooks remain together at the end.
  • Project roots receive any missing standard dev, prod, check, build, deploy, clean, changelog, and recipes commands plus their workspace-runner children. Existing command bodies remain project-owned and are never replaced by the defaults.
  • Generated projects register Nova's package-script Vitest suite so ordering drift, missing parents, recursive hooks, and ambiguous phase-less aliases fail checks.

Nova rejects only exact top-level aliases; their scoped forms remain valid:

  • Runtime aliases — develop, development, production, run, serve, start, preview, and watch must move under dev:* or prod:* according to whether they execute source or compiled output.
  • Check aliases — lint, test, type-check, typecheck, and coverage must move under check:*.
  • Build aliases — bundle, compile, generate, package, and transpile must move under the phase that owns their output, usually build:*.
  • Mutation and release aliases — fix and format must identify a check or recipe phase, while release must identify its changelog or deployment phase.

Distinct project capabilities such as manage, tail, repl, test-api, and scaffold-versions remain valid top-level commands. npm lifecycle commands such as prepare, postinstall, prepack, and publish also remain valid and stay in the final lifecycle section.

Install-Script Trust Boundary

normalize-tooling performs shape cleanup, not dependency trust review. It does not inspect lifecycle-script source, run npm's approval commands, or infer entries from the lockfile. This prevents a routine recipe run from granting newly installed dependency code permission to execute.

Keep the reviewed policy in the project root and use exact-version approvals plus name-only denials. See Root Install-Script Policy for the field shape, npm 11 and npm 12 review commands, and the difference between approved, denied, and unreviewed packages.

Config Fields

A workspace is only processed when its nova.config.json entry opts in. The recipe filters out any workspace that does not enable normalize-tooling, and skips entirely when no workspace enables it.

FieldDescription
workspaces[].recipesPer-workspace recipe map in nova.config.json. A workspace with no recipes map is skipped.
workspaces[].recipes['normalize-tooling']Recipe tuple enabling this recipe for the workspace. The first tuple element must be true; otherwise the workspace is skipped.

Usage

Options

FlagDescription
-d, --dry-runRun without writing any files.
-r, --replace-fileOverwrite the original file instead of creating a .nova-backup copy.