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?
- Keeps package scripts and tooling metadata in shapes expected by npm and the repository toolchain.
- Detects
binding.gypand workspace roles so native and monorepo fields appear only when applicable. - 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-toolinginnova.config.json. - Workspace manifest — The configured workspace must contain a readable
package.jsonfile.
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 asdev,prod,check,build,deploy,clean,changelog,recipes, optionali18n, 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 nobinding.gypfile exists in the workspace directory, the field is removed. If missing butbinding.gypexists and neitherscripts.preinstallnorscripts.installare defined, it is added astrue.config(Conditional) — Removed if the field is present but empty.workspaces(Required) — Removed if the workspace role is notproject. If the role isprojectand the field is missing, it is added as an empty array[].
Script Organization
- Matching
pre<name>andpost<name>hooks wrap their parent or child command, whilename:*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, andrecipescommands 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, andwatchmust move underdev:*orprod:*according to whether they execute source or compiled output. - Check aliases —
lint,test,type-check,typecheck, andcoveragemust move undercheck:*. - Build aliases —
bundle,compile,generate,package, andtranspilemust move under the phase that owns their output, usuallybuild:*. - Mutation and release aliases —
fixandformatmust identify a check or recipe phase, whilereleasemust 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.
| Field | Description |
|---|---|
workspaces[].recipes | Per-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
| Flag | Description |
|---|---|
-d, --dry-run | Run without writing any files. |
-r, --replace-file | Overwrite the original file instead of creating a .nova-backup copy. |