CodeVetter · Repo Unpack · Behavior traces
npm/cli
The investigated flows include startup and dispatch, installation through filesystem persistence, clean installation, login through credential persistence, explicit script execution, and publishing. Each trace follows source call order and preserves significant branches. Installation and ci differ in validation, cleanup, and root-script timing. These are static traces rather than observed runtime executions.
- Startup: npm-cli.js → cli(process) → validateEngines → getCli() → entry(process, validation) → gracefulify(fs) → new ExitHandler → new Npm → npm.load(); unsupported but parseable Node versions receive a warning.
- Dispatch: entry awaits load, exits early for version-only mode or missing commands, starts npm.exec(command,args), launches an unawaited update notification, awaits execution, and routes success or failure to exitHandler.exit.
- Bare local install: Install.exec → resolveAllowScripts → root preinstall when scripts are enabled → new Arborist → strictAllowScriptsPreflight → arb.reify → install/postinstall/prepublish/preprepare/prepare/postprepare → reifyFinish; explicit additions and global installs skip this root lifecycle sequence.
- Arborist persistence: reify → _loadTrees → _diffTrees → #reifyPackages → _saveIdealTree → actualize tree → save hidden lock; local tree loading runs loadActual and buildIdealTree concurrently, while global loading builds ideal state first.
- Clean install: CI.exec rejects global mode and CLI patch-relax flags → loadVirtual on one Arborist → buildIdealTree on another → script preflight → validate inventories, packageExtensions, and extension hash → clear workspace node_modules unless dry-run → root preinstall → reify → remaining root hooks → reifyFinish.
- Login persistence: Login.exec chooses scoped registry unless CLI overrides it → getCredentialsByURI → auth.login → loginWeb or ENYI fallback to username/password and loginCouch through otplease → setCredentialsByURI → save('user') → print message.
- Explicit script: RunScript.exec → #run → normalize package → resolve requested/default event → handle missing script or if-present → construct pre/main/post events → await runScript for each; only the main event receives forwarded positional arguments.
- Publish: exec → #publish → #getManifest → reject non-private packageExtensions → directory prepublishOnly → pack → reread manifest → pickRegistry → oidc → credential/version checks → libpub through otplease, or staged libpub without OTP → directory publish/postpublish hooks → output.