@mawesome/npm-vm 0.0.0-stage → 0.1.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/LICENSE +21 -0
- package/README.md +51 -2
- package/dist/cli.js +4157 -0
- package/dist/cli.js.map +1 -0
- package/dist/index-B071ZJDk.d.cts +164 -0
- package/dist/index-B071ZJDk.d.ts +164 -0
- package/dist/index.cjs +7 -0
- package/dist/index.d.cts +2 -0
- package/dist/index.d.ts +2 -0
- package/dist/index.js +2 -0
- package/dist/internal.cjs +2709 -0
- package/dist/internal.cjs.map +1 -0
- package/dist/internal.d.cts +139 -0
- package/dist/internal.d.ts +139 -0
- package/dist/internal.js +2706 -0
- package/dist/internal.js.map +1 -0
- package/dist/provenance--sOYCeF2.js +322 -0
- package/dist/provenance--sOYCeF2.js.map +1 -0
- package/dist/provenance-DDegWCyS.js +2 -0
- package/dist/runtime/atomic-C3shKdH9.cjs +88 -0
- package/dist/runtime/bootstrap.cjs +271 -0
- package/dist/runtime/commonjs-AANzyd21.cjs +7393 -0
- package/dist/runtime/dispatch-B9OSfqsn.cjs +25156 -0
- package/dist/runtime/dist-CXwBT6rE.cjs +30766 -0
- package/dist/runtime/home-BaoZZSBy.cjs +91 -0
- package/dist/runtime/install-C_M5WK98.cjs +13598 -0
- package/dist/runtime/journal-_bs-eJRJ.cjs +282 -0
- package/dist/runtime/launchers/cmd.tmpl +2 -0
- package/dist/runtime/launchers/ps1.tmpl +5 -0
- package/dist/runtime/launchers/sh.tmpl +3 -0
- package/dist/runtime/lease-HBD4CmBx.cjs +224 -0
- package/dist/runtime/lock-DBeYN-Zg.cjs +141 -0
- package/dist/runtime/messages-vUDkl1-0.cjs +174 -0
- package/dist/runtime/p-map-b8pXdaFZ.cjs +105 -0
- package/dist/runtime/proc-hB8N9WjN.cjs +127 -0
- package/dist/runtime/provenance-B4bajGXQ.cjs +2 -0
- package/dist/runtime/rolldown-runtime-BGT596CS.cjs +64 -0
- package/dist/runtime/runtime.cjs +143 -0
- package/dist/runtime/src-SpeGbMJx.cjs +314 -0
- package/dist/src-Bc9nN1Kl.cjs +2125 -0
- package/dist/src-Bc9nN1Kl.cjs.map +1 -0
- package/dist/src-NhNG2mnQ.js +1798 -0
- package/dist/src-NhNG2mnQ.js.map +1 -0
- package/package.json +85 -3
package/dist/cli.js.map
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"cli.js","names":["sleep","cryptoVerify","readManifest","readManifest","forget","run","describe"],"sources":["../src/own-npm.ts","../src/state/proc.ts","../src/state/lease.ts","../src/spec.ts","../src/select.ts","../src/install/verify.ts","../src/install/cache.ts","../src/state/atomic.ts","../src/state/prune.ts","../src/setup/home.ts","../src/install/config.ts","../src/install/fetch.ts","../src/install/keys.ts","../src/install/index.ts","../src/project.ts","../src/index.ts","../src/setup/shims.ts","../src/setup/shell.ts","../src/state/meta.ts","../src/state/journal.ts","../src/state/lock.ts","../src/commands/cache.ts","../src/commands/context.ts","../src/setup/link.ts","../src/setup/layout.ts","../src/setup/profile.ts","../src/setup/windows.ts","../src/commands/doctor.ts","../src/commands/pin.ts","../src/commands/self-update.ts","../src/commands/setup.ts","../src/commands/uninstall.ts","../src/commands/dispatch.ts","../src/cli.ts"],"sourcesContent":["import { existsSync, readFileSync, realpathSync } from 'node:fs';\nimport { posix, win32 } from 'node:path';\n\n/** The npm in the active Node's prefix: bundled, or whatever `npm i -g npm@x` put there. */\nexport interface OwnNpm {\n\troot: string;\n\tversion: string;\n\tcliPath: string;\n\tnpxCliPath: string;\n}\n\n/**\n * Locates Node's own npm from the running binary (spec section 1).\n * The lib dir, not the `bin/npm` link: under `--link` that link is the shim.\n */\nexport function ownNpmRoot(execPath: string, platform: NodeJS.Platform = process.platform): string {\n\tif (platform === 'win32') {\n\t\treturn win32.join(win32.dirname(execPath), 'node_modules', 'npm');\n\t}\n\tlet real = execPath;\n\ttry {\n\t\treal = realpathSync(execPath);\n\t} catch {\n\t\t// A missing or unreadable binary resolves as given; the caller reports the missing npm.\n\t}\n\treturn posix.join(posix.dirname(real), '..', 'lib', 'node_modules', 'npm');\n}\n\nexport function findOwnNpm(\n\texecPath: string = process.execPath,\n\tplatform: NodeJS.Platform = process.platform,\n): OwnNpm | null {\n\tconst root = ownNpmRoot(execPath, platform);\n\tconst { join } = platform === 'win32' ? win32 : posix;\n\tconst manifest = join(root, 'package.json');\n\tif (!existsSync(manifest)) {\n\t\treturn null;\n\t}\n\tlet version: unknown;\n\ttry {\n\t\tversion = (JSON.parse(readFileSync(manifest, 'utf8')) as { version?: unknown }).version;\n\t} catch {\n\t\treturn null;\n\t}\n\tif (typeof version !== 'string') {\n\t\treturn null;\n\t}\n\treturn {\n\t\troot,\n\t\tversion,\n\t\tcliPath: join(root, 'bin', 'npm-cli.js'),\n\t\tnpxCliPath: join(root, 'bin', 'npx-cli.js'),\n\t};\n}\n","import { execFileSync } from 'node:child_process';\nimport { existsSync, readFileSync } from 'node:fs';\nimport { basename, isAbsolute, join } from 'node:path';\n\n/** A process plus the start identity that tells it apart from a later process reusing its PID (spec PROC-1). */\nexport interface ProcessIdentity {\n\tpid: number;\n\t/** Platform-specific start identity, compared as an exact string; null when unreadable. */\n\tstart: string | null;\n}\n\nexport function powershellPath(env: NodeJS.ProcessEnv = process.env): string {\n\treturn join(\n\t\tenv['SystemRoot'] ?? 'C:\\\\Windows',\n\t\t'System32',\n\t\t'WindowsPowerShell',\n\t\t'v1.0',\n\t\t'powershell.exe',\n\t);\n}\n\nconst SHELL_DIRS = ['/bin', '/usr/bin', '/usr/local/bin', '/opt/homebrew/bin', '/snap/bin'];\n\n/**\n * An absolute path for a shell to probe (spec SEC-8): the login shell when `$SHELL` is absolute, else system dirs.\n * Never PATH, which inside an npm script starts with `node_modules/.bin`.\n */\nexport function shellBinary(\n\tshell: 'zsh' | 'bash' | 'fish' | 'powershell',\n\tenv: NodeJS.ProcessEnv = process.env,\n\tplatform: NodeJS.Platform = process.platform,\n): string | null {\n\tconst name = shell === 'powershell' ? 'pwsh' : shell;\n\tif (platform === 'win32') {\n\t\tconst pwsh = join(env['ProgramFiles'] ?? 'C:\\\\Program Files', 'PowerShell', '7', 'pwsh.exe');\n\t\treturn shell === 'powershell' && existsSync(pwsh) ? pwsh : null;\n\t}\n\tconst login = env['SHELL'];\n\tconst candidates = [\n\t\t...(login !== undefined && isAbsolute(login) && basename(login) === name ? [login] : []),\n\t\t...SHELL_DIRS.map((dir) => join(dir, name)),\n\t];\n\treturn candidates.find((candidate) => existsSync(candidate)) ?? null;\n}\n\n/** The start identity of `pid`, or null when the lookup fails or is ambiguous. */\nexport function startIdentity(\n\tpid: number,\n\tplatform: NodeJS.Platform = process.platform,\n\tenv: NodeJS.ProcessEnv = process.env,\n): string | null {\n\ttry {\n\t\tif (platform === 'linux') {\n\t\t\tconst stat = readFileSync(`/proc/${pid}/stat`, 'utf8');\n\t\t\t// The command name sits in parentheses and may hold spaces; fields are counted after the last one.\n\t\t\tconst after = stat\n\t\t\t\t.slice(stat.lastIndexOf(')') + 1)\n\t\t\t\t.trim()\n\t\t\t\t.split(/\\s+/);\n\t\t\tconst start = after[19];\n\t\t\treturn start !== undefined && /^\\d+$/.test(start) ? start : null;\n\t\t}\n\t\tif (platform === 'darwin') {\n\t\t\tconst out = execFileSync('/bin/ps', ['-o', 'lstart=', '-p', String(pid)], {\n\t\t\t\tencoding: 'utf8',\n\t\t\t\tenv: { LC_ALL: 'C', PATH: '/usr/bin:/bin' },\n\t\t\t}).trim();\n\t\t\treturn out === '' || out.includes('\\n') ? null : out;\n\t\t}\n\t\tif (platform === 'win32') {\n\t\t\tconst out = execFileSync(\n\t\t\t\tpowershellPath(env),\n\t\t\t\t[\n\t\t\t\t\t'-NoProfile',\n\t\t\t\t\t'-NonInteractive',\n\t\t\t\t\t'-Command',\n\t\t\t\t\t`(Get-Process -Id ${pid}).StartTime.ToFileTimeUtc()`,\n\t\t\t\t],\n\t\t\t\t{ encoding: 'utf8', windowsHide: true },\n\t\t\t).trim();\n\t\t\treturn /^\\d+$/.test(out) ? out : null;\n\t\t}\n\t} catch {\n\t\treturn null;\n\t}\n\treturn null;\n}\n\nexport function ownIdentity(platform?: NodeJS.Platform, env?: NodeJS.ProcessEnv): ProcessIdentity {\n\treturn { pid: process.pid, start: startIdentity(process.pid, platform, env) };\n}\n\n/**\n * Whether the recorded process still runs: dead only when the PID is gone or its start identity differs.\n * Any failure to look up means live, so nothing ever expires a process that merely cannot be inspected.\n */\nexport function isLive(\n\tidentity: ProcessIdentity,\n\tplatform: NodeJS.Platform = process.platform,\n): boolean {\n\ttry {\n\t\tprocess.kill(identity.pid, 0);\n\t} catch (error) {\n\t\tif ((error as NodeJS.ErrnoException).code === 'ESRCH') {\n\t\t\treturn false;\n\t\t}\n\t\treturn true;\n\t}\n\tif (identity.start === null) {\n\t\treturn true;\n\t}\n\tconst current = startIdentity(identity.pid, platform);\n\treturn current === null || current === identity.start;\n}\n","import { randomBytes } from 'node:crypto';\nimport { existsSync, mkdirSync, readdirSync, readFileSync, rmSync, writeFileSync } from 'node:fs';\nimport { hostname } from 'node:os';\nimport { join } from 'node:path';\nimport { isLive, ownIdentity, type ProcessIdentity } from './proc.ts';\n\n/** What a lease, gate or lock file records about its owner (spec LEASE-1, PROC-1). */\nexport interface OwnerRecord extends ProcessIdentity {\n\thost: string;\n\tmachineId: string;\n\tcreatedAt: string;\n}\n\nexport interface Lease {\n\tpath: string;\n\trelease(): void;\n}\n\nexport function leasesDir(entry: string): string {\n\treturn `${entry}.leases`;\n}\n\nexport function gatePath(entry: string): string {\n\treturn `${entry}.prune`;\n}\n\nexport function newToken(): string {\n\treturn randomBytes(8).toString('hex');\n}\n\nexport function ownerRecord(\n\tmachineId: string,\n\tidentity: ProcessIdentity = ownIdentity(),\n): OwnerRecord {\n\treturn { ...identity, host: hostname(), machineId, createdAt: new Date().toISOString() };\n}\n\nexport function readOwner(file: string): OwnerRecord | null {\n\ttry {\n\t\tconst parsed = JSON.parse(readFileSync(file, 'utf8')) as Partial<OwnerRecord>;\n\t\tif (typeof parsed.pid !== 'number') {\n\t\t\treturn null;\n\t\t}\n\t\treturn {\n\t\t\tpid: parsed.pid,\n\t\t\tstart: typeof parsed.start === 'string' ? parsed.start : null,\n\t\t\thost: typeof parsed.host === 'string' ? parsed.host : '?',\n\t\t\tmachineId: typeof parsed.machineId === 'string' ? parsed.machineId : '?',\n\t\t\tcreatedAt: typeof parsed.createdAt === 'string' ? parsed.createdAt : '',\n\t\t};\n\t} catch {\n\t\treturn null;\n\t}\n}\n\n/** A file in the per-machine cache belongs to a dead owner only when PROC-1 says so; unreadable means live. */\nexport function ownerLive(file: string): boolean {\n\tconst owner = readOwner(file);\n\treturn owner === null ? true : isLive(owner);\n}\n\n/** Creates a shared lease on `entry`; the file name is unique, so a prune can never delete a live one by mistake. */\nexport function createLease(entry: string, owner: OwnerRecord): Lease {\n\tconst dir = leasesDir(entry);\n\tfor (let attempt = 0; ; attempt += 1) {\n\t\tmkdirSync(dir, { recursive: true, mode: 0o700 });\n\t\tconst path = join(dir, newToken());\n\t\ttry {\n\t\t\twriteFileSync(path, JSON.stringify(owner), { mode: 0o600, flag: 'wx' });\n\t\t} catch (error) {\n\t\t\t// An unreadable lease counts as live and would keep the entry forever.\n\t\t\trmSync(path, { force: true });\n\t\t\t// A prune can move the leases dir away between the mkdir and the write; the next attempt recreates it.\n\t\t\tif ((error as NodeJS.ErrnoException).code === 'ENOENT' && attempt < 3) {\n\t\t\t\tcontinue;\n\t\t\t}\n\t\t\tthrow error;\n\t\t}\n\t\treturn {\n\t\t\tpath,\n\t\t\trelease() {\n\t\t\t\trmSync(path, { force: true });\n\t\t\t},\n\t\t};\n\t}\n}\n\n/**\n * Whether a lease created before a gate check is still in place (spec LEASE-1).\n * A prune that passed its own lease check first moves the whole leases dir away, taking the file with it.\n */\nexport function leaseSurvived(lease: Lease): boolean {\n\treturn existsSync(lease.path);\n}\n\nexport function listLeases(entry: string): string[] {\n\ttry {\n\t\treturn readdirSync(leasesDir(entry)).map((name) => join(leasesDir(entry), name));\n\t} catch {\n\t\treturn [];\n\t}\n}\n\nfunction sleep(ms: number): Promise<void> {\n\treturn new Promise((resolve) => setTimeout(resolve, ms));\n}\n\nconst GATE_WAIT_MS = 5000;\n\n/**\n * The runtime's shared lease (spec LEASE-1): lease first, then look for a live prune gate.\n * A live gate means the entry is going away: wait briefly, retry once, else return null so the caller fetches a private entry.\n */\nexport async function acquireShared(\n\tentry: string,\n\towner: OwnerRecord,\n\toptions: { waitMs?: number } = {},\n): Promise<Lease | null> {\n\tfor (let attempt = 0; attempt < 3; attempt += 1) {\n\t\tconst lease = createLease(entry, owner);\n\t\tconst gate = gatePath(entry);\n\t\tlet gated = false;\n\t\ttry {\n\t\t\tgated = ownerLive(gate);\n\t\t} catch {\n\t\t\tgated = false;\n\t\t}\n\t\tif (!gated || !gateExists(gate)) {\n\t\t\tif (leaseSurvived(lease)) {\n\t\t\t\treturn lease;\n\t\t\t}\n\t\t\t// A prune between the lease and the gate check moved the lease away with the entry; lease again.\n\t\t\tcontinue;\n\t\t}\n\t\tlease.release();\n\t\tconst deadline = Date.now() + (options.waitMs ?? GATE_WAIT_MS);\n\t\twhile (Date.now() < deadline && gateExists(gate)) {\n\t\t\tawait sleep(50);\n\t\t}\n\t}\n\treturn null;\n}\n\nfunction gateExists(gate: string): boolean {\n\ttry {\n\t\treturn readOwner(gate) !== null;\n\t} catch {\n\t\treturn false;\n\t}\n}\n\n/** Creates the prune gate with O_EXCL; false when another gate exists (there is only ever one prune, so a leftover). */\nexport function createGate(entry: string, owner: OwnerRecord): boolean {\n\ttry {\n\t\twriteFileSync(gatePath(entry), JSON.stringify(owner), { flag: 'wx', mode: 0o600 });\n\t} catch (error) {\n\t\tif ((error as NodeJS.ErrnoException).code === 'EEXIST') {\n\t\t\treturn false;\n\t\t}\n\t\t// A gate without a readable owner would make every later prune skip the entry.\n\t\trmSync(gatePath(entry), { force: true });\n\t\tthrow error;\n\t}\n\treturn true;\n}\n\nexport function removeGate(entry: string): void {\n\trmSync(gatePath(entry), { force: true });\n}\n","import semver from 'semver';\n\nexport type HashAlgorithm = 'sha512' | 'sha256' | 'sha224';\n\nexport interface SpecHash {\n\talgorithm: HashAlgorithm;\n\thex: string;\n}\n\n/** One npm version requirement: a range, or an exact version optionally pinned to a tarball hash. */\nexport interface NpmSpec {\n\t/** The range as written, without any hash suffix. */\n\trange: string;\n\t/** Set when the range is a single exact version. */\n\texact: string | null;\n\thash: SpecHash | null;\n}\n\nexport type OnFail = 'ignore' | 'warn' | 'error' | 'download';\n\nexport type SpecField = 'devEngines' | 'packageManager';\n\nexport interface ParsedSpecs {\n\t/** Alternatives: Node's own npm or a candidate satisfies the project when it matches any of them. */\n\tspecs: NpmSpec[];\n\t/** The policy of the last `devEngines.packageManager` entry (spec RES-7); `error` for `packageManager`. */\n\tonFail: OnFail;\n\tfield: SpecField;\n}\n\nexport class SpecError extends Error {\n\toverride name = 'SpecError';\n\treadonly field: string;\n\t/** The project's policy for this failure, when the entry declaring it could still be read. */\n\tonFail: OnFail = 'error';\n\n\tconstructor(field: string, message: string) {\n\t\tsuper(message);\n\t\tthis.field = field;\n\t}\n}\n\nconst MAX_RANGE_LENGTH = 256;\nconst HASH_HEX_LENGTH: Record<HashAlgorithm, number> = { sha512: 128, sha256: 64, sha224: 56 };\nconst ON_FAIL = new Set<string>(['ignore', 'warn', 'error', 'download']);\n\n/**\n * Validates one version string before it reaches a transport argv or a message (spec RES-4).\n * Build metadata other than a well-formed hash suffix is rejected: semver would silently drop it.\n */\nexport function parseVersionSpec(raw: string, field: string): NpmSpec {\n\tif (raw.length > MAX_RANGE_LENGTH) {\n\t\tthrow new SpecError(field, `${field}: version is longer than ${MAX_RANGE_LENGTH} characters`);\n\t}\n\tconst plus = raw.indexOf('+');\n\tconst range = (plus === -1 ? raw : raw.slice(0, plus)).trim();\n\tlet hash: SpecHash | null = null;\n\tif (plus !== -1) {\n\t\thash = parseHash(raw.slice(plus + 1), field);\n\t}\n\tif (semver.validRange(range) === null) {\n\t\tthrow new SpecError(field, `${field}: ${JSON.stringify(raw)} is not a semver range`);\n\t}\n\tconst exact = semver.valid(range);\n\tif (hash !== null && exact === null) {\n\t\tthrow new SpecError(\n\t\t\tfield,\n\t\t\t`${field}: a hash needs an exact version, got ${JSON.stringify(raw)}`,\n\t\t);\n\t}\n\treturn { range, exact, hash };\n}\n\nfunction parseHash(suffix: string, field: string): SpecHash {\n\tconst match = /^(sha512|sha256|sha224)\\.([0-9a-fA-F]+)$/.exec(suffix);\n\tif (match === null) {\n\t\tthrow new SpecError(field, `${field}: unsupported hash suffix ${JSON.stringify(`+${suffix}`)}`);\n\t}\n\tconst algorithm = match[1] as HashAlgorithm;\n\tconst hex = (match[2] as string).toLowerCase();\n\tif (hex.length !== HASH_HEX_LENGTH[algorithm]) {\n\t\tthrow new SpecError(\n\t\t\tfield,\n\t\t\t`${field}: ${algorithm} hash must be ${HASH_HEX_LENGTH[algorithm]} hex characters`,\n\t\t);\n\t}\n\treturn { algorithm, hex };\n}\n\ninterface ManagerEntry {\n\tname?: unknown;\n\tversion?: unknown;\n\tonFail?: unknown;\n}\n\nfunction isObject(value: unknown): value is Record<string, unknown> {\n\treturn typeof value === 'object' && value !== null && !Array.isArray(value);\n}\n\n/**\n * Reads the npm requirements of a parsed `package.json` (spec RES-4).\n * Returns null when the project declares nothing for npm, including when it declares only pnpm or yarn.\n */\nexport function parseSpecs(pkg: unknown): ParsedSpecs | null {\n\tif (!isObject(pkg)) {\n\t\treturn null;\n\t}\n\tconst devEngines = pkg['devEngines'];\n\tif (isObject(devEngines) && devEngines['packageManager'] !== undefined) {\n\t\tconst fromDevEngines = parseDevEngines(devEngines['packageManager']);\n\t\tif (fromDevEngines !== null) {\n\t\t\treturn fromDevEngines;\n\t\t}\n\t}\n\tconst packageManager = pkg['packageManager'];\n\tif (typeof packageManager === 'string' && packageManager.startsWith('npm@')) {\n\t\tconst field = 'packageManager';\n\t\treturn {\n\t\t\tspecs: [parseVersionSpec(packageManager.slice('npm@'.length), field)],\n\t\t\tonFail: 'error',\n\t\t\tfield,\n\t\t};\n\t}\n\treturn null;\n}\n\nfunction parseDevEngines(value: unknown): ParsedSpecs | null {\n\tconst field = 'devEngines.packageManager';\n\tconst entries = Array.isArray(value) ? value : [value];\n\tif (entries.length === 0) {\n\t\treturn null;\n\t}\n\tconst specs: NpmSpec[] = [];\n\t// The policy comes first, so an entry with a broken version still fails the way it asked to.\n\tconst last = entries[entries.length - 1];\n\tconst onFail = isObject(last) ? parseOnFail(last, field) : 'error';\n\ttry {\n\t\tfor (const entry of entries) {\n\t\t\tif (!isObject(entry)) {\n\t\t\t\tthrow new SpecError(field, `${field}: every entry must be an object`);\n\t\t\t}\n\t\t\tif (entry['name'] !== 'npm') {\n\t\t\t\tcontinue;\n\t\t\t}\n\t\t\tconst version = entry['version'];\n\t\t\tif (version === undefined) {\n\t\t\t\tspecs.push({ range: '*', exact: null, hash: null });\n\t\t\t} else if (typeof version === 'string') {\n\t\t\t\tspecs.push(parseVersionSpec(version, field));\n\t\t\t} else {\n\t\t\t\tthrow new SpecError(field, `${field}: version must be a string`);\n\t\t\t}\n\t\t}\n\t} catch (error) {\n\t\tif (error instanceof SpecError) {\n\t\t\terror.onFail = onFail;\n\t\t}\n\t\tthrow error;\n\t}\n\tif (specs.length === 0) {\n\t\treturn null;\n\t}\n\treturn { specs, onFail, field: 'devEngines' };\n}\n\nfunction parseOnFail(entry: ManagerEntry, field: string): OnFail {\n\tconst onFail = entry.onFail;\n\tif (onFail === undefined) {\n\t\treturn 'error';\n\t}\n\tif (typeof onFail !== 'string' || !ON_FAIL.has(onFail)) {\n\t\tthrow new SpecError(field, `${field}: onFail must be ignore, warn, error or download`);\n\t}\n\treturn onFail as OnFail;\n}\n\n/** Whether a concrete version satisfies the spec's range, hash aside (spec RES-5 and RES-6). */\nexport function matchesRange(version: string, spec: NpmSpec): boolean {\n\treturn semver.satisfies(version, spec.range);\n}\n","import semver from 'semver';\nimport { matchesRange, type NpmSpec, type SpecHash } from './spec.ts';\n\nexport interface RegistrySignature {\n\tkeyid: string;\n\tsig: string;\n}\n\n/** A published npm version as the registry or the cache describes it. */\nexport interface Candidate {\n\tversion: string;\n\t/** `engines.node` of the package; missing means any Node. */\n\tenginesNode: string | null;\n\t/** `dist.integrity` (sha512 SRI). */\n\tintegrity: string;\n\t/** Where the candidate lives when it is already cached. */\n\tentryPath: string | null;\n\t/** `dist.signatures` from the registry; null for a cached candidate. */\n\tsignatures: RegistrySignature[] | null;\n\t/** For a cached entry: the key that verified it, or null when only a project's pin did. */\n\tkeyid?: string | null;\n\t/** For a cached entry: the tarball digests recorded at verification, so a pin can be judged without the bytes. */\n\tdigests?: { sha256: string; sha224: string } | null;\n}\n\nexport interface Selection {\n\tcandidate: Candidate;\n\t/** Pins from the specs that selected the candidate; the download must match one of them. Empty: unpinned. */\n\thashes: SpecHash[];\n}\n\nexport type SelectFailure =\n\t| { kind: 'engine'; version: string; enginesNode: string }\n\t| { kind: 'nomatch'; reason: string };\n\nexport type SelectResult =\n\t| { kind: 'selected'; selection: Selection }\n\t| { kind: 'failed'; failure: SelectFailure };\n\nfunction engineAccepts(candidate: Candidate, nodeVersion: string): boolean {\n\treturn (\n\t\tcandidate.enginesNode === null ||\n\t\tsemver.satisfies(nodeVersion, candidate.enginesNode, { includePrerelease: true })\n\t);\n}\n\nfunction hashAccepts(candidate: Candidate, spec: NpmSpec): boolean {\n\tif (spec.hash === null) {\n\t\t// An entry that only a pin ever vouched for is not an alternative for an unpinned project (spec SEC-1).\n\t\treturn candidate.keyid !== null;\n\t}\n\tif (spec.hash.algorithm === 'sha512') {\n\t\treturn sriHex(candidate.integrity) === spec.hash.hex;\n\t}\n\tif (candidate.digests === undefined || candidate.digests === null) {\n\t\t// Only the tarball bytes can answer a sha256 or sha224 pin; verification checks it after download.\n\t\treturn true;\n\t}\n\treturn candidate.digests[spec.hash.algorithm] === spec.hash.hex;\n}\n\n/** The hex digest of a `sha512-<base64>` SRI string, or null for any other form. */\nexport function sriHex(integrity: string): string | null {\n\tconst match = /^sha512-([A-Za-z0-9+/=]+)$/.exec(integrity.trim());\n\treturn match === null ? null : Buffer.from(match[1] as string, 'base64').toString('hex');\n}\n\n/** Whether Node's own npm satisfies a spec without a hash (spec RES-5). */\nexport function ownNpmSatisfies(ownVersion: string, specs: readonly NpmSpec[]): boolean {\n\treturn specs.some((spec) => spec.hash === null && matchesRange(ownVersion, spec));\n}\n\n/**\n * Picks the highest candidate matching any spec and the active Node (spec RES-6), cached first.\n * Returns the reason when nothing fits, distinguishing an `engines.node` exclusion from no match at all.\n */\nexport function selectCandidate(\n\tspecs: readonly NpmSpec[],\n\tcandidates: readonly Candidate[],\n\tnodeVersion: string,\n): SelectResult {\n\tlet best: Selection | null = null;\n\tlet excluded: Candidate | null = null;\n\tfor (const candidate of candidates) {\n\t\tconst matching = specs.filter(\n\t\t\t(entry) => matchesRange(candidate.version, entry) && hashAccepts(candidate, entry),\n\t\t);\n\t\tif (matching.length === 0) {\n\t\t\tcontinue;\n\t\t}\n\t\tif (!engineAccepts(candidate, nodeVersion)) {\n\t\t\tif (excluded === null || semver.gt(candidate.version, excluded.version)) {\n\t\t\t\texcluded = candidate;\n\t\t\t}\n\t\t\tcontinue;\n\t\t}\n\t\tif (best === null || semver.gt(candidate.version, best.candidate.version)) {\n\t\t\t// An unpinned alternative needs no pin; otherwise every matching pin is carried and any one may verify.\n\t\t\tconst unpinned = matching.some((entry) => entry.hash === null);\n\t\t\tbest = {\n\t\t\t\tcandidate,\n\t\t\t\thashes: unpinned\n\t\t\t\t\t? []\n\t\t\t\t\t: matching.flatMap((entry) => (entry.hash === null ? [] : [entry.hash])),\n\t\t\t};\n\t\t}\n\t}\n\tif (best !== null) {\n\t\treturn { kind: 'selected', selection: best };\n\t}\n\tif (excluded !== null) {\n\t\treturn {\n\t\t\tkind: 'failed',\n\t\t\tfailure: {\n\t\t\t\tkind: 'engine',\n\t\t\t\tversion: excluded.version,\n\t\t\t\tenginesNode: excluded.enginesNode ?? '*',\n\t\t\t},\n\t\t};\n\t}\n\treturn { kind: 'failed', failure: { kind: 'nomatch', reason: 'no published version matches' } };\n}\n","import { createHash, createPublicKey, verify as cryptoVerify } from 'node:crypto';\nimport {\n\tcreateReadStream,\n\tcreateWriteStream,\n\tmkdirSync,\n\treadFileSync,\n\twriteFileSync,\n} from 'node:fs';\nimport { dirname, join, posix } from 'node:path';\nimport { Transform } from 'node:stream';\nimport { pipeline } from 'node:stream/promises';\nimport { createGunzip } from 'node:zlib';\nimport { Parser, type ReadEntry } from 'tar';\nimport { EXIT, NpmVmError } from '../errors.ts';\nimport { integrityMessage, keyMessage, unsignedMessage } from '../messages.ts';\nimport type { RegistrySignature } from '../select.ts';\nimport type { SpecHash } from '../spec.ts';\nimport type { RegistryKey } from './keys.ts';\n\nexport interface Digests {\n\t/** `sha512-<base64>`, the SRI form the registry uses. */\n\tsha512: string;\n\tsha512hex: string;\n\tsha256hex: string;\n\tsha224hex: string;\n}\n\n/** Every digest a spec or the registry may ask for, in one pass over the file. */\nexport async function fileDigests(file: string): Promise<Digests> {\n\tconst sha512 = createHash('sha512');\n\tconst sha256 = createHash('sha256');\n\tconst sha224 = createHash('sha224');\n\tawait pipeline(\n\t\tcreateReadStream(file),\n\t\tnew Transform({\n\t\t\ttransform(chunk: Buffer, _encoding, callback) {\n\t\t\t\tsha512.update(chunk);\n\t\t\t\tsha256.update(chunk);\n\t\t\t\tsha224.update(chunk);\n\t\t\t\tcallback();\n\t\t\t},\n\t\t}),\n\t);\n\tconst sha512Digest = sha512.digest();\n\treturn {\n\t\tsha512: `sha512-${sha512Digest.toString('base64')}`,\n\t\tsha512hex: sha512Digest.toString('hex'),\n\t\tsha256hex: sha256.digest('hex'),\n\t\tsha224hex: sha224.digest('hex'),\n\t};\n}\n\nfunction integrityFailure(expected: string, actual: string, detail: string): NpmVmError {\n\treturn new NpmVmError(\n\t\t'M-INTEGRITY',\n\t\tEXIT.verification,\n\t\tintegrityMessage(expected, actual, detail),\n\t);\n}\n\n/** The tarball must match the registry's integrity and, when the project pins hashes, one of them (spec SEC-2). */\nexport function checkIntegrity(\n\tdigests: Digests,\n\tintegrity: string,\n\thashes: readonly SpecHash[],\n): void {\n\tif (digests.sha512 !== integrity.trim()) {\n\t\tthrow integrityFailure(\n\t\t\tintegrity,\n\t\t\tdigests.sha512,\n\t\t\t'the tarball does not match the registry integrity',\n\t\t);\n\t}\n\tif (hashes.length === 0) {\n\t\treturn;\n\t}\n\tconst actual = {\n\t\tsha512: digests.sha512hex,\n\t\tsha256: digests.sha256hex,\n\t\tsha224: digests.sha224hex,\n\t};\n\tif (!hashes.some((hash) => actual[hash.algorithm] === hash.hex)) {\n\t\tconst [first] = hashes as [SpecHash, ...SpecHash[]];\n\t\tthrow integrityFailure(\n\t\t\t`${first.algorithm}.${first.hex}`,\n\t\t\t`${first.algorithm}.${actual[first.algorithm]}`,\n\t\t\t'the tarball does not match the pinned hash',\n\t\t);\n\t}\n}\n\nexport interface SignatureInput {\n\tname: string;\n\tversion: string;\n\tintegrity: string;\n\tsignatures: readonly RegistrySignature[];\n\t/** Resolves the publication time, consulted only when a signing key has expired. */\n\tpublishedAt: () => Promise<string | null>;\n\tkeys: readonly RegistryKey[];\n\tregistry: string;\n\t/** A hash-pinned spec may accept an unsigned registry. */\n\tpinned: boolean;\n}\n\n/**\n * Checks the registry signatures over `name@version:integrity` against the pinned keyring (spec SEC-1).\n * Returns the key id that verified; throws M-KEY for an unknown key and M-UNSIGNED when no signature is usable.\n */\nexport async function verifySignatures(input: SignatureInput): Promise<string | null> {\n\tif (input.signatures.length === 0) {\n\t\tif (input.pinned) {\n\t\t\treturn null;\n\t\t}\n\t\tthrow new NpmVmError(\n\t\t\t'M-UNSIGNED',\n\t\t\tEXIT.verification,\n\t\t\tunsignedMessage(input.registry, input.version),\n\t\t);\n\t}\n\tconst payload = Buffer.from(`${input.name}@${input.version}:${input.integrity}`, 'utf8');\n\tlet unknown: string | null = null;\n\tfor (const signature of input.signatures) {\n\t\tconst key = input.keys.find((entry) => entry.keyid === signature.keyid);\n\t\tif (key === undefined) {\n\t\t\tunknown ??= signature.keyid;\n\t\t\tcontinue;\n\t\t}\n\t\tif (key.revoked === true || !(await keyCurrent(key, input.publishedAt))) {\n\t\t\tcontinue;\n\t\t}\n\t\tconst publicKey = createPublicKey({\n\t\t\tkey: Buffer.from(key.key, 'base64'),\n\t\t\tformat: 'der',\n\t\t\ttype: 'spki',\n\t\t});\n\t\tif (cryptoVerify('sha256', payload, publicKey, Buffer.from(signature.sig, 'base64'))) {\n\t\t\treturn key.keyid;\n\t\t}\n\t}\n\tif (unknown !== null) {\n\t\tthrow new NpmVmError('M-KEY', EXIT.verification, keyMessage(unknown));\n\t}\n\tthrow new NpmVmError(\n\t\t'M-UNSIGNED',\n\t\tEXIT.verification,\n\t\tunsignedMessage(input.registry, input.version),\n\t);\n}\n\n/** An expired key still vouches for versions published before it expired; an unknown time fails closed. */\nasync function keyCurrent(\n\tkey: RegistryKey,\n\tpublishedAt: () => Promise<string | null>,\n): Promise<boolean> {\n\tif (key.expires === null) {\n\t\treturn true;\n\t}\n\tconst published = await publishedAt();\n\treturn published !== null && Date.parse(published) < Date.parse(key.expires);\n}\n\nexport interface ExtractLimits {\n\tmaxEntries: number;\n\tmaxBytes: number;\n}\n\nexport const DEFAULT_LIMITS: ExtractLimits = { maxEntries: 10_000, maxBytes: 256 * 1024 * 1024 };\n\nfunction unsafe(detail: string): NpmVmError {\n\treturn integrityFailure('a safe npm tarball', 'an unsafe entry', detail);\n}\n\n/** The destination-relative path of a tarball entry, or a thrown M-INTEGRITY for anything outside `package/` (spec SEC-3). */\nexport function entryRelativePath(path: string): string {\n\tif (\n\t\tpath.includes('\\\\') ||\n\t\t[...path].some((char) => char.charCodeAt(0) < 0x20 || char.charCodeAt(0) === 0x7f)\n\t) {\n\t\tthrow unsafe(`entry name contains a control character or backslash: ${JSON.stringify(path)}`);\n\t}\n\tif (path.startsWith('/') || /^[A-Za-z]:/.test(path)) {\n\t\tthrow unsafe(`absolute entry name: ${path}`);\n\t}\n\tconst segments = path.split('/').filter((segment) => segment !== '' && segment !== '.');\n\tif (segments.includes('..')) {\n\t\tthrow unsafe(`entry name climbs out of the archive: ${path}`);\n\t}\n\tif (segments[0] !== 'package') {\n\t\tthrow unsafe(`entry outside package/: ${path}`);\n\t}\n\treturn segments.length === 1 ? '' : posix.join(...segments.slice(1));\n}\n\n/**\n * Extracts regular files and directories under `package/` into `dest`, rejecting everything else (spec SEC-3).\n * Modes are `0644` or `0755` by the owner exec bit; ownership and extended attributes are ignored.\n */\nexport async function safeExtract(\n\ttarball: string,\n\tdest: string,\n\tlimits: ExtractLimits = DEFAULT_LIMITS,\n): Promise<void> {\n\tlet entries = 0;\n\tlet bytes = 0;\n\tlet decompressed = 0;\n\tconst writes: Promise<void>[] = [];\n\tconst parser = new Parser({ strict: true });\n\tlet aborted: Error | null = null;\n\tconst abort = (error: Error): void => {\n\t\taborted ??= error;\n\t\tparser.abort(error);\n\t};\n\tparser.on('entry', (entry: ReadEntry) => {\n\t\ttry {\n\t\t\tentries += 1;\n\t\t\tbytes += entry.size;\n\t\t\tif (entries > limits.maxEntries) {\n\t\t\t\tthrow unsafe(`more than ${limits.maxEntries} entries`);\n\t\t\t}\n\t\t\tif (bytes > limits.maxBytes) {\n\t\t\t\tthrow unsafe(`more than ${limits.maxBytes} bytes`);\n\t\t\t}\n\t\t\tconst relative = entryRelativePath(entry.path);\n\t\t\tconst target = relative === '' ? dest : join(dest, relative);\n\t\t\tif (entry.type === 'Directory') {\n\t\t\t\tmkdirSync(target, { recursive: true, mode: 0o755 });\n\t\t\t\tentry.resume();\n\t\t\t\treturn;\n\t\t\t}\n\t\t\tif (entry.type !== 'File' || relative === '') {\n\t\t\t\tthrow unsafe(`${entry.type} entry: ${entry.path}`);\n\t\t\t}\n\t\t\tmkdirSync(dirname(target), { recursive: true, mode: 0o755 });\n\t\t\tconst mode = ((entry.mode ?? 0o644) & 0o100) === 0 ? 0o644 : 0o755;\n\t\t\twrites.push(pipeline(entry, createWriteStream(target, { mode })));\n\t\t} catch (error) {\n\t\t\tabort(error as Error);\n\t\t}\n\t});\n\tconst counter = new Transform({\n\t\ttransform(chunk: Buffer, _encoding, callback) {\n\t\t\tdecompressed += chunk.length;\n\t\t\tif (decompressed > limits.maxBytes) {\n\t\t\t\tcallback(unsafe(`more than ${limits.maxBytes} bytes after decompression`));\n\t\t\t\treturn;\n\t\t\t}\n\t\t\tcallback(null, chunk);\n\t\t},\n\t});\n\tconst done = new Promise<void>((resolve, reject) => {\n\t\tparser.on('end', () => resolve());\n\t\tparser.on('error', (error: Error) => reject(error));\n\t});\n\t// The pipeline surfaces the same error first; the second rejection must not go unhandled.\n\tdone.catch(() => undefined);\n\ttry {\n\t\tawait pipeline(createReadStream(tarball), createGunzip(), counter, parser);\n\t\tawait done;\n\t\tawait Promise.all(writes);\n\t} catch (error) {\n\t\t// Let in-flight file writes settle, so the caller can remove the destination at once.\n\t\tawait Promise.allSettled(writes);\n\t\tthrow (\n\t\t\taborted ??\n\t\t\t(error instanceof NpmVmError\n\t\t\t\t? error\n\t\t\t\t: unsafe(`cannot read the tarball: ${(error as Error).message}`))\n\t\t);\n\t}\n\tif (aborted !== null) {\n\t\tthrow aborted;\n\t}\n}\n\n/** The marker an entry carries once verified (spec SEC-4). */\nexport interface Verified {\n\tversion: string;\n\tintegrity: string;\n\t/** The registry key that verified the tarball, or null when only a project's pin did. */\n\tkeyid: string | null;\n\t/** Tarball digests, so a later pin of another algorithm can be judged against the entry. */\n\tsha256: string;\n\tsha224: string;\n\tverifiedAt: string;\n}\n\nexport const VERIFIED_FILE = '.verified';\n\nexport function writeVerified(dir: string, verified: Verified): void {\n\twriteFileSync(join(dir, VERIFIED_FILE), JSON.stringify(verified), { mode: 0o600 });\n}\n\nexport function readVerified(dir: string): Verified | null {\n\ttry {\n\t\tconst parsed = JSON.parse(readFileSync(join(dir, VERIFIED_FILE), 'utf8')) as Partial<Verified>;\n\t\tif (typeof parsed.version !== 'string' || typeof parsed.integrity !== 'string') {\n\t\t\treturn null;\n\t\t}\n\t\tif (typeof parsed.sha256 !== 'string' || typeof parsed.sha224 !== 'string') {\n\t\t\treturn null;\n\t\t}\n\t\treturn {\n\t\t\tversion: parsed.version,\n\t\t\tintegrity: parsed.integrity,\n\t\t\tkeyid: typeof parsed.keyid === 'string' ? parsed.keyid : null,\n\t\t\tsha256: parsed.sha256,\n\t\t\tsha224: parsed.sha224,\n\t\t\tverifiedAt: typeof parsed.verifiedAt === 'string' ? parsed.verifiedAt : '',\n\t\t};\n\t} catch {\n\t\treturn null;\n\t}\n}\n","import { existsSync, readdirSync, readFileSync, renameSync, rmSync, statSync } from 'node:fs';\nimport { join } from 'node:path';\nimport { sriHex, type Candidate } from '../select.ts';\nimport {\n\tcreateLease,\n\tgatePath,\n\tleaseSurvived,\n\tnewToken,\n\townerLive,\n\ttype Lease,\n\ttype OwnerRecord,\n} from '../state/lease.ts';\nimport type { RegistryKey } from './keys.ts';\nimport { readVerified } from './verify.ts';\n\nexport const ENTRIES_DIR = 'npm';\n\n/** `<version>-<16 hex of the integrity>`: two registries serving different bytes get two entries (spec SEC-4). */\nexport function entryName(version: string, integrity: string): string {\n\tconst hex = sriHex(integrity);\n\tif (hex === null) {\n\t\tthrow new Error(`not a sha512 integrity: ${integrity}`);\n\t}\n\treturn `${version}-${hex.slice(0, 16)}`;\n}\n\n/** Where verified entries are staged before the rename into `npm/`: same filesystem, so the rename stays atomic. */\nexport function stagingDir(cacheRoot: string): string {\n\treturn join(cacheRoot, 'staging');\n}\n\nexport function canonicalEntry(cacheRoot: string, version: string, integrity: string): string {\n\treturn join(cacheRoot, ENTRIES_DIR, entryName(version, integrity));\n}\n\nexport function privateEntry(canonical: string, token: string): string {\n\treturn `${canonical}.${token}`;\n}\n\n/** Whether a directory name under `npm/` is an entry rather than a lease dir, a gate or a deletion in progress. */\nexport function isEntryName(name: string): boolean {\n\treturn /^\\d+\\.\\d+\\.\\d+(?:-[0-9A-Za-z.-]+)?-[0-9a-f]{16}(?:\\.[0-9a-f]{16})?$/.test(name);\n}\n\nfunction readManifest(\n\tdir: string,\n): { name: unknown; version: unknown; enginesNode: string | null } | null {\n\ttry {\n\t\tconst pkg = JSON.parse(readFileSync(join(dir, 'package.json'), 'utf8')) as Record<\n\t\t\tstring,\n\t\t\tunknown\n\t\t>;\n\t\tconst engines = pkg['engines'];\n\t\tconst node =\n\t\t\ttypeof engines === 'object' && engines !== null\n\t\t\t\t? (engines as Record<string, unknown>)['node']\n\t\t\t\t: undefined;\n\t\treturn {\n\t\t\tname: pkg['name'],\n\t\t\tversion: pkg['version'],\n\t\t\tenginesNode: typeof node === 'string' ? node : null,\n\t\t};\n\t} catch {\n\t\treturn null;\n\t}\n}\n\n/**\n * Whether an entry may run (spec SEC-5): verified for this integrity, owned by the current user,\n * and holding the npm it claims. Never deletes anything.\n */\nexport function validateEntry(entryPath: string, integrity: string): boolean {\n\ttry {\n\t\tconst stat = statSync(entryPath);\n\t\tif (!stat.isDirectory() || (process.getuid !== undefined && stat.uid !== process.getuid())) {\n\t\t\treturn false;\n\t\t}\n\t} catch {\n\t\treturn false;\n\t}\n\tconst verified = readVerified(entryPath);\n\tif (verified === null || verified.integrity !== integrity) {\n\t\treturn false;\n\t}\n\tconst manifest = readManifest(entryPath);\n\treturn manifest !== null && manifest.name === 'npm' && manifest.version === verified.version;\n}\n\n/** Every verified entry in the cache as a candidate, whatever its validity; use-time validation decides. */\nexport function listEntries(cacheRoot: string, keys: readonly RegistryKey[] = []): Candidate[] {\n\tlet names: string[];\n\ttry {\n\t\tnames = readdirSync(join(cacheRoot, ENTRIES_DIR));\n\t} catch {\n\t\treturn [];\n\t}\n\tconst candidates: Candidate[] = [];\n\tfor (const name of names) {\n\t\tif (!isEntryName(name)) {\n\t\t\tcontinue;\n\t\t}\n\t\tconst entryPath = join(cacheRoot, ENTRIES_DIR, name);\n\t\tconst verified = readVerified(entryPath);\n\t\tconst manifest = readManifest(entryPath);\n\t\tif (verified === null || manifest === null || manifest.version !== verified.version) {\n\t\t\tcontinue;\n\t\t}\n\t\t// A key revoked since the entry was verified withdraws the entry with it.\n\t\tif (\n\t\t\tverified.keyid !== null &&\n\t\t\tkeys.some((key) => key.keyid === verified.keyid && key.revoked === true)\n\t\t) {\n\t\t\tcontinue;\n\t\t}\n\t\tcandidates.push({\n\t\t\tversion: verified.version,\n\t\t\tenginesNode: manifest.enginesNode,\n\t\t\tintegrity: verified.integrity,\n\t\t\tentryPath,\n\t\t\tsignatures: null,\n\t\t\tkeyid: verified.keyid,\n\t\t\tdigests: { sha256: verified.sha256, sha224: verified.sha224 },\n\t\t});\n\t}\n\treturn candidates;\n}\n\nexport interface PublishedEntry {\n\tentryPath: string;\n\tlease: Lease;\n}\n\nfunction isCollision(error: unknown): boolean {\n\tconst code = (error as NodeJS.ErrnoException).code;\n\treturn code === 'EEXIST' || code === 'ENOTEMPTY' || code === 'EPERM' || code === 'EISDIR';\n}\n\n/**\n * Moves a verified temp dir into the cache under a lease (spec SEC-4). The lease exists before the\n * rename, so a prune never sees the entry without it; a lost race reuses or sidesteps the winner's entry.\n */\nexport function publishEntry(\n\ttempDir: string,\n\tcanonical: string,\n\tintegrity: string,\n\towner: OwnerRecord,\n): PublishedEntry {\n\tconst lease = createLease(canonical, owner);\n\t// Lease first, then look for a live prune gate: a prune checks leases after creating its gate, so one side always sees the other.\n\tif (existsSync(gatePath(canonical)) && ownerLive(gatePath(canonical))) {\n\t\tlease.release();\n\t\treturn publishPrivately(tempDir, canonical, owner);\n\t}\n\tif (!leaseSurvived(lease)) {\n\t\t// A prune between the lease and the gate check moved the lease away with the old entry; the path is free now.\n\t\treturn publishEntry(tempDir, canonical, integrity, owner);\n\t}\n\ttry {\n\t\trenameSync(tempDir, canonical);\n\t\treturn { entryPath: canonical, lease };\n\t} catch (error) {\n\t\tif (!isCollision(error)) {\n\t\t\tlease.release();\n\t\t\tthrow error;\n\t\t}\n\t}\n\t// The lease taken above already covers the winner's entry, so a prune cannot take it away meanwhile.\n\tif (validateEntry(canonical, integrity)) {\n\t\trmSync(tempDir, { recursive: true, force: true });\n\t\treturn { entryPath: canonical, lease };\n\t}\n\tlease.release();\n\treturn publishPrivately(tempDir, canonical, owner);\n}\n\nfunction publishPrivately(tempDir: string, canonical: string, owner: OwnerRecord): PublishedEntry {\n\t// The same handshake as the canonical path: a prune that found the fresh leases dir first may have moved it away.\n\tfor (;;) {\n\t\tconst entryPath = privateEntry(canonical, newToken());\n\t\tconst privateLease = createLease(entryPath, owner);\n\t\tif (existsSync(gatePath(entryPath)) && ownerLive(gatePath(entryPath))) {\n\t\t\tprivateLease.release();\n\t\t\tcontinue;\n\t\t}\n\t\tif (!leaseSurvived(privateLease)) {\n\t\t\tcontinue;\n\t\t}\n\t\ttry {\n\t\t\trenameSync(tempDir, entryPath);\n\t\t} catch (error) {\n\t\t\tprivateLease.release();\n\t\t\tthrow error;\n\t\t}\n\t\treturn { entryPath, lease: privateLease };\n\t}\n}\n","import { closeSync, fsyncSync, mkdirSync, openSync, renameSync, rmSync, writeSync } from 'node:fs';\nimport { dirname, join } from 'node:path';\nimport { newToken } from './lease.ts';\n\nconst RETRY_CODES = new Set(['EBUSY', 'EPERM', 'EACCES']);\nconst RETRY_LIMIT_MS = 5000;\n\nfunction sleepSync(ms: number): void {\n\tAtomics.wait(new Int32Array(new SharedArrayBuffer(4)), 0, 0, ms);\n}\n\n/**\n * Runs a file operation, retrying Windows sharing violations with backoff for up to 5 s (spec MUT-3).\n * Elsewhere the same codes are real permission errors and surface at once.\n */\nexport function withSharingRetry<T>(\n\toperation: () => T,\n\tplatform: NodeJS.Platform = process.platform,\n\tlimitMs: number = RETRY_LIMIT_MS,\n): T {\n\tconst started = Date.now();\n\tlet delay = 20;\n\tfor (;;) {\n\t\ttry {\n\t\t\treturn operation();\n\t\t} catch (error) {\n\t\t\tconst code = (error as NodeJS.ErrnoException).code ?? '';\n\t\t\tif (\n\t\t\t\tplatform !== 'win32' ||\n\t\t\t\t!RETRY_CODES.has(code) ||\n\t\t\t\tDate.now() - started + delay > limitMs\n\t\t\t) {\n\t\t\t\tthrow error;\n\t\t\t}\n\t\t\tsleepSync(delay);\n\t\t\tdelay = Math.min(delay * 2, 500);\n\t\t}\n\t}\n}\n\n/** Writes `content` to `path` through a temp file in the same dir, fsynced and renamed into place. */\nexport function atomicWrite(path: string, content: string | Buffer, mode = 0o644): void {\n\tconst dir = dirname(path);\n\tmkdirSync(dir, { recursive: true });\n\tconst temp = join(dir, `.${newToken()}.tmp`);\n\ttry {\n\t\tconst fd = openSync(temp, 'wx', mode);\n\t\ttry {\n\t\t\tconst buffer = typeof content === 'string' ? Buffer.from(content, 'utf8') : content;\n\t\t\t// writeSync may stop short without throwing; a truncated file must never reach the rename.\n\t\t\tfor (let offset = 0; offset < buffer.length;) {\n\t\t\t\tconst written = writeSync(fd, buffer, offset, buffer.length - offset);\n\t\t\t\tif (written <= 0) {\n\t\t\t\t\tthrow new Error(`short write to ${temp}: ${offset} of ${buffer.length} bytes`);\n\t\t\t\t}\n\t\t\t\toffset += written;\n\t\t\t}\n\t\t\tfsyncSync(fd);\n\t\t} finally {\n\t\t\tcloseSync(fd);\n\t\t}\n\t\twithSharingRetry(() => renameSync(temp, path));\n\t} catch (error) {\n\t\trmSync(temp, { force: true });\n\t\tthrow error;\n\t}\n}\n\n/** Renames with the Windows retry; a cross-device rename is not retried, it is a layout error. */\nexport function atomicRename(from: string, to: string): void {\n\twithSharingRetry(() => renameSync(from, to));\n}\n\nexport function removeWithRetry(path: string): void {\n\twithSharingRetry(() => rmSync(path, { recursive: true, force: true }));\n}\n","import { existsSync, readdirSync, rmSync, statSync, utimesSync, writeFileSync } from 'node:fs';\nimport { join } from 'node:path';\nimport { ENTRIES_DIR, isEntryName, stagingDir, validateEntry } from '../install/cache.ts';\nimport { readVerified } from '../install/verify.ts';\nimport { atomicRename, removeWithRetry } from './atomic.ts';\nimport {\n\tcreateGate,\n\tgatePath,\n\tleasesDir,\n\tlistLeases,\n\tnewToken,\n\townerLive,\n\tremoveGate,\n\ttype OwnerRecord,\n} from './lease.ts';\n\nexport const USED_SUFFIX = '.used';\n\n/** Records a resolution of `entry` for the prune age, in a sidecar so the entry itself stays untouched. */\nexport function touchUsed(entry: string): void {\n\tconst marker = `${entry}${USED_SUFFIX}`;\n\ttry {\n\t\tconst now = new Date();\n\t\tutimesSync(marker, now, now);\n\t} catch {\n\t\twriteFileSync(marker, '', { flag: 'a' });\n\t}\n}\n\nexport function lastUsed(entry: string): number | null {\n\ttry {\n\t\treturn statSync(`${entry}${USED_SUFFIX}`).mtimeMs;\n\t} catch {\n\t\treturn null;\n\t}\n}\n\nexport interface PruneOptions {\n\t/** Entries not resolved for this long are removed; `Infinity` keeps every valid entry. */\n\tmaxAgeMs: number;\n\tnow?: number;\n}\n\nexport interface PruneReport {\n\tremoved: string[];\n\tkept: string[];\n\tskipped: string[];\n}\n\nexport type PruneReason = 'stale' | 'invalid' | 'orphan-private' | 'leftover';\n\n/** Why one entry would go, or null to keep it. */\nexport function pruneReason(\n\tcacheRoot: string,\n\tname: string,\n\toptions: PruneOptions,\n): PruneReason | null {\n\tconst entry = join(cacheRoot, ENTRIES_DIR, name);\n\tif (name.includes('.deleting.')) {\n\t\treturn 'leftover';\n\t}\n\tif (!isEntryName(name)) {\n\t\treturn null;\n\t}\n\tconst verified = readVerified(entry);\n\tif (verified === null || !validateEntry(entry, verified.integrity)) {\n\t\treturn 'invalid';\n\t}\n\tconst isPrivate = /\\.[0-9a-f]{16}$/.test(name);\n\tif (isPrivate && !listLeases(entry).some((lease) => ownerLive(lease))) {\n\t\treturn 'orphan-private';\n\t}\n\tconst used = lastUsed(entry);\n\tconst age = (options.now ?? Date.now()) - (used ?? statSync(entry).mtimeMs);\n\treturn age > options.maxAgeMs ? 'stale' : null;\n}\n\n/**\n * Removes one entry the exclusive way (spec LEASE-1): gate, drop dead leases, bail on a live one, rename aside, drop the gate, delete.\n * After the gate is gone nothing here touches the entry's paths again.\n */\nexport function pruneEntry(entry: string, owner: OwnerRecord): boolean {\n\tif (existsSync(gatePath(entry)) && !ownerLive(gatePath(entry))) {\n\t\tremoveGate(entry);\n\t}\n\tif (!createGate(entry, owner)) {\n\t\treturn false;\n\t}\n\tfor (const lease of listLeases(entry)) {\n\t\tif (!ownerLive(lease)) {\n\t\t\trmSync(lease, { force: true });\n\t\t}\n\t}\n\tif (listLeases(entry).length > 0) {\n\t\tremoveGate(entry);\n\t\treturn false;\n\t}\n\tconst token = newToken();\n\tconst deletingEntry = `${entry}.deleting.${token}`;\n\tconst deletingLeases = `${entry}.leases.deleting.${token}`;\n\tif (existsSync(entry)) {\n\t\tatomicRename(entry, deletingEntry);\n\t}\n\tif (existsSync(leasesDir(entry))) {\n\t\tatomicRename(leasesDir(entry), deletingLeases);\n\t}\n\tremoveGate(entry);\n\tremoveWithRetry(deletingEntry);\n\tremoveWithRetry(deletingLeases);\n\trmSync(`${entry}${USED_SUFFIX}`, { force: true });\n\treturn true;\n}\n\nconst STAGING_MAX_AGE_MS = 24 * 60 * 60 * 1000;\n\n/** Work dirs a crashed extraction left under `staging/`; a live one is never a day old. */\nfunction pruneStaging(cacheRoot: string, now: number): void {\n\tlet names: string[];\n\ttry {\n\t\tnames = readdirSync(stagingDir(cacheRoot));\n\t} catch {\n\t\treturn;\n\t}\n\tfor (const name of names) {\n\t\tconst dir = join(stagingDir(cacheRoot), name);\n\t\ttry {\n\t\t\tif (now - statSync(dir).mtimeMs > STAGING_MAX_AGE_MS) {\n\t\t\t\tremoveWithRetry(dir);\n\t\t\t}\n\t\t} catch {\n\t\t\t// Gone already, or unreadable: nothing to reclaim.\n\t\t}\n\t}\n}\n\n/** Prunes the whole cache; the caller holds the exclusive lock (MUT-1) so only one prune ever runs. */\nexport function pruneCache(\n\tcacheRoot: string,\n\towner: OwnerRecord,\n\toptions: PruneOptions,\n): PruneReport {\n\tconst report: PruneReport = { removed: [], kept: [], skipped: [] };\n\tpruneStaging(cacheRoot, options.now ?? Date.now());\n\tlet names: string[];\n\ttry {\n\t\tnames = readdirSync(join(cacheRoot, ENTRIES_DIR));\n\t} catch {\n\t\treturn report;\n\t}\n\tfor (const name of names) {\n\t\tconst entry = join(cacheRoot, ENTRIES_DIR, name);\n\t\t// A lease dir whose entry is gone and whose owners are all dead is a crashed prune's leftover too.\n\t\tif (\n\t\t\tname.endsWith('.leases') &&\n\t\t\texistsSync(entry) &&\n\t\t\t!existsSync(entry.slice(0, -'.leases'.length))\n\t\t) {\n\t\t\t// Through the gate like any entry: a publisher creating its lease right now still wins.\n\t\t\t(pruneEntry(entry.slice(0, -'.leases'.length), owner) ? report.removed : report.skipped).push(\n\t\t\t\tname,\n\t\t\t);\n\t\t\tcontinue;\n\t\t}\n\t\t// A gate whose entry is gone and whose owner is dead is a crashed prune's leftover.\n\t\tif (\n\t\t\tname.endsWith('.prune') &&\n\t\t\t!existsSync(entry.slice(0, -'.prune'.length)) &&\n\t\t\t!ownerLive(entry)\n\t\t) {\n\t\t\trmSync(entry, { force: true });\n\t\t\treport.removed.push(name);\n\t\t\tcontinue;\n\t\t}\n\t\tconst reason = pruneReason(cacheRoot, name, options);\n\t\tif (reason === null) {\n\t\t\tif (isEntryName(name)) {\n\t\t\t\treport.kept.push(name);\n\t\t\t}\n\t\t\tcontinue;\n\t\t}\n\t\tif (reason === 'leftover') {\n\t\t\tremoveWithRetry(entry);\n\t\t\treport.removed.push(name);\n\t\t\tcontinue;\n\t\t}\n\t\tif (pruneEntry(entry, owner)) {\n\t\t\treport.removed.push(name);\n\t\t} else {\n\t\t\treport.skipped.push(name);\n\t\t}\n\t}\n\treturn report;\n}\n","import { execFileSync } from 'node:child_process';\nimport { createHash } from 'node:crypto';\nimport { readFileSync } from 'node:fs';\nimport { homedir, hostname } from 'node:os';\nimport { join, resolve } from 'node:path';\n\nexport interface MachineId {\n\t/** sha256 of the platform id, first 16 hex chars (spec DIST-2). */\n\tid: string;\n\t/** True when only the hostname was available, which cloned machines can share. */\n\tfallback: boolean;\n}\n\n/** Every directory the tool uses (spec DIST-1 and SET-1). */\nexport interface Dirs {\n\thome: string;\n\tcache: string;\n\tstate: string;\n\ttmp: string;\n\tjournal: string;\n\tmachine: MachineId;\n}\n\nfunction localAppData(env: NodeJS.ProcessEnv): string {\n\treturn env['LOCALAPPDATA'] ?? join(homedir(), 'AppData', 'Local');\n}\n\nexport function defaultHome(\n\tenv: NodeJS.ProcessEnv,\n\tplatform: NodeJS.Platform = process.platform,\n): string {\n\tif (platform === 'win32') {\n\t\treturn join(localAppData(env), 'npm-vm');\n\t}\n\treturn join(env['XDG_DATA_HOME'] || join(homedir(), '.local', 'share'), 'npm-vm');\n}\n\nexport function cacheBase(\n\tenv: NodeJS.ProcessEnv,\n\tplatform: NodeJS.Platform = process.platform,\n): string {\n\tif (platform === 'win32') {\n\t\t// Beside the home, not inside it: uninstall removes the home and must leave the cache alone.\n\t\treturn join(localAppData(env), 'npm-vm-cache');\n\t}\n\treturn join(env['XDG_CACHE_HOME'] || join(homedir(), '.cache'), 'npm-vm');\n}\n\nfunction platformId(platform: NodeJS.Platform, env: NodeJS.ProcessEnv): string | null {\n\ttry {\n\t\tif (platform === 'linux') {\n\t\t\tfor (const file of ['/etc/machine-id', '/var/lib/dbus/machine-id']) {\n\t\t\t\ttry {\n\t\t\t\t\tconst id = readFileSync(file, 'utf8').trim();\n\t\t\t\t\tif (id !== '') {\n\t\t\t\t\t\treturn id;\n\t\t\t\t\t}\n\t\t\t\t} catch {\n\t\t\t\t\t// Try the next location.\n\t\t\t\t}\n\t\t\t}\n\t\t\treturn null;\n\t\t}\n\t\tif (platform === 'darwin') {\n\t\t\tconst out = execFileSync('/usr/sbin/ioreg', ['-rd1', '-c', 'IOPlatformExpertDevice'], {\n\t\t\t\tencoding: 'utf8',\n\t\t\t\tenv: { PATH: '/usr/bin:/bin:/usr/sbin:/sbin' },\n\t\t\t});\n\t\t\treturn /\"IOPlatformUUID\"\\s*=\\s*\"([^\"]+)\"/.exec(out)?.[1] ?? null;\n\t\t}\n\t\tif (platform === 'win32') {\n\t\t\tconst reg = join(env['SystemRoot'] ?? 'C:\\\\Windows', 'System32', 'reg.exe');\n\t\t\tconst out = execFileSync(\n\t\t\t\treg,\n\t\t\t\t['query', 'HKLM\\\\SOFTWARE\\\\Microsoft\\\\Cryptography', '/v', 'MachineGuid'],\n\t\t\t\t{\n\t\t\t\t\tencoding: 'utf8',\n\t\t\t\t},\n\t\t\t);\n\t\t\treturn /MachineGuid\\s+REG_SZ\\s+(\\S+)/.exec(out)?.[1] ?? null;\n\t\t}\n\t} catch {\n\t\t// Fall back to the hostname below.\n\t}\n\treturn null;\n}\n\n/** The hashed machine id, or a hashed hostname when the platform id is unreadable. */\nexport function readMachineId(\n\tenv: NodeJS.ProcessEnv = process.env,\n\tplatform: NodeJS.Platform = process.platform,\n): MachineId {\n\tconst raw = platformId(platform, env);\n\tconst source = raw ?? hostname();\n\treturn {\n\t\tid: createHash('sha256').update(source).digest('hex').slice(0, 16),\n\t\tfallback: raw === null,\n\t};\n}\n\nexport function resolveDirs(\n\tenv: NodeJS.ProcessEnv = process.env,\n\thome: string = env['NPM_VM_HOME'] || defaultHome(env),\n\tplatform: NodeJS.Platform = process.platform,\n\tmachine: MachineId = readMachineId(env, platform),\n): Dirs {\n\t// The shims embed this path, so a relative NPM_VM_HOME must become absolute here, once.\n\tconst absoluteHome = resolve(home);\n\tconst state = join(absoluteHome, 'state');\n\treturn {\n\t\thome: absoluteHome,\n\t\tcache: join(cacheBase(env, platform), machine.id),\n\t\tstate,\n\t\ttmp: join(state, 'tmp'),\n\t\tjournal: join(state, 'journal'),\n\t\tmachine,\n\t};\n}\n","import Config from '@npmcli/config';\nimport npmDefinitions from '@npmcli/config/lib/definitions/index.js';\nimport type { OwnNpm } from '../own-npm.ts';\n\n/** The npm settings a download may use, read from user and global config only (spec DL-2). */\nexport interface NpmConfigView {\n\tregistry: string;\n\tuserconfig: string;\n\tglobalconfig: string;\n\tcache: string;\n\tcredentials: {\n\t\ttoken?: string;\n\t\tusername?: string;\n\t\tpassword?: string;\n\t\tauth?: string;\n\t\tcertfile?: string;\n\t\tkeyfile?: string;\n\t};\n\thttpsProxy: string | null;\n\tproxy: string | null;\n\tnoproxy: string | null;\n\tca: string[] | null;\n\tcafile: string | null;\n\tstrictSsl: boolean;\n}\n\nconst DROPPED = new Set(['NODE_OPTIONS', 'NODE_EXTRA_CA_CERTS']);\n/** Proxy settings reach the transport only from the user and global npm config (spec DL-2), never the env. */\nconst PROXY_VARS = /^(https?_proxy|all_proxy|no_proxy|proxy)$/i;\n\n/** The env without anything that would steer npm or Node: `npm_config_*`, proxies, `NODE_OPTIONS`, `NODE_EXTRA_CA_CERTS`. */\nexport function sanitizeEnv(env: NodeJS.ProcessEnv): NodeJS.ProcessEnv {\n\tconst clean: NodeJS.ProcessEnv = {};\n\tfor (const [key, value] of Object.entries(env)) {\n\t\tif (/^npm_config_/i.test(key) || DROPPED.has(key.toUpperCase()) || PROXY_VARS.test(key)) {\n\t\t\tcontinue;\n\t\t}\n\t\tclean[key] = value;\n\t}\n\treturn clean;\n}\n\nfunction optionalString(value: unknown): string | null {\n\tconst text = Array.isArray(value)\n\t\t? value\n\t\t\t\t.map(String)\n\t\t\t\t.filter((item) => item !== '')\n\t\t\t\t.join(',')\n\t\t: value;\n\treturn typeof text === 'string' && text !== '' ? text : null;\n}\n\n/**\n * Loads npm's config the way npm does, minus the project: `cwd` is an empty dir under the home,\n * the env is sanitized and nothing is printed. Credentials come only from `getCredentialsByURI`.\n */\nexport async function loadNpmConfig(\n\town: OwnNpm,\n\tenv: NodeJS.ProcessEnv,\n\tcwd: string,\n\tnodePath: string = process.execPath,\n): Promise<NpmConfigView> {\n\tconst { definitions, shorthands, flatten, nerfDarts } = npmDefinitions;\n\tconst config = new Config({\n\t\tdefinitions,\n\t\tshorthands,\n\t\tflatten,\n\t\tnerfDarts,\n\t\tnpmPath: own.root,\n\t\t/* The global prefix and its npmrc belong to the Node the shims run, not to this process.\n\t\t * Global mode makes the loader skip project config, so no ancestor of the home can inject an .npmrc. */\n\t\targv: [nodePath, own.cliPath, '--location=global'],\n\t\texecPath: nodePath,\n\t\tenv: { ...sanitizeEnv(env) },\n\t\tcwd,\n\t\texcludeNpmCwd: true,\n\t});\n\tawait config.load();\n\tconst registry = String(config.get('registry'));\n\tconst ca = config.get('ca');\n\treturn {\n\t\tregistry,\n\t\tuserconfig: String(config.get('userconfig')),\n\t\tglobalconfig: String(config.get('globalconfig')),\n\t\tcache: String(config.get('cache')),\n\t\tcredentials: config.getCredentialsByURI(registry),\n\t\thttpsProxy: optionalString(config.get('https-proxy')),\n\t\tproxy: optionalString(config.get('proxy')),\n\t\tnoproxy: optionalString(config.get('noproxy')),\n\t\tca: Array.isArray(ca) ? ca.map(String) : typeof ca === 'string' ? [ca] : null,\n\t\tcafile: optionalString(config.get('cafile')),\n\t\tstrictSsl: config.get('strict-ssl') !== false,\n\t};\n}\n","import { execFile } from 'node:child_process';\nimport { mkdirSync, mkdtempSync, rmSync } from 'node:fs';\nimport { join } from 'node:path';\nimport semver from 'semver';\nimport { EXIT, NpmVmError } from '../errors.ts';\nimport { integrityMessage, redactUrls, transportMessage } from '../messages.ts';\nimport type { OwnNpm } from '../own-npm.ts';\nimport type { RegistrySignature } from '../select.ts';\nimport { sanitizeEnv, type NpmConfigView } from './config.ts';\n\n/** One published version as `npm view` reports it. */\nexport interface RegistryVersion {\n\tversion: string;\n\tenginesNode: string | null;\n\tintegrity: string;\n\ttarball: string;\n\tsignatures: RegistrySignature[];\n\t/** `dist.attestations.url`, present for packages published with provenance. */\n\tattestationsUrl: string | null;\n}\n\nexport interface PackedTarball {\n\tfile: string;\n\tintegrity: string;\n}\n\nconst MIN_TRANSPORT = '8.0.0';\nconst MAX_OUTPUT = 256 * 1024 * 1024;\n\n/** Whether Node's own npm can serve as the transport (spec DL-1). */\nexport function transportUsable(own: OwnNpm | null): own is OwnNpm {\n\treturn own !== null && semver.gte(own.version, MIN_TRANSPORT);\n}\n\n/** A fresh private working dir under `state/tmp/`, never the shared system temp dir (spec DL-2). */\nexport function newWorkDir(tmpRoot: string): string {\n\tmkdirSync(tmpRoot, { recursive: true, mode: 0o700 });\n\treturn mkdtempSync(join(tmpRoot, 'work-'));\n}\n\n/**\n * Runs Node's own npm as the download transport, isolated from the project (spec DL-1, DL-2).\n * Every call runs in its own empty working dir, with that dir as the prefix and the user and global config named explicitly.\n */\nexport class Transport {\n\treadonly #own: OwnNpm;\n\treadonly #config: NpmConfigView;\n\treadonly #env: NodeJS.ProcessEnv;\n\treadonly #tmpRoot: string;\n\treadonly #nodePath: string;\n\n\tconstructor(\n\t\town: OwnNpm,\n\t\tconfig: NpmConfigView,\n\t\tenv: NodeJS.ProcessEnv,\n\t\ttmpRoot: string,\n\t\tnodePath: string = process.execPath,\n\t) {\n\t\tthis.#own = own;\n\t\tthis.#config = config;\n\t\tthis.#env = sanitizeEnv(env);\n\t\tthis.#tmpRoot = tmpRoot;\n\t\tthis.#nodePath = nodePath;\n\t}\n\n\t/** Versions of npm matching `range`, newest last as npm lists them; an unmatched range is an empty list. */\n\tview(range: string): Promise<RegistryVersion[]> {\n\t\treturn this.viewPackage('npm', range);\n\t}\n\n\t/** The same for any package, used by self-update for its own package. */\n\tasync viewPackage(name: string, range: string): Promise<RegistryVersion[]> {\n\t\tconst output = await this.#run(\n\t\t\t['view', `${name}@${range}`, 'version', 'engines', 'dist'],\n\t\t\ttrue,\n\t\t);\n\t\tif (output === null) {\n\t\t\treturn [];\n\t\t}\n\t\treturn asList(output).flatMap((item) => {\n\t\t\tconst version = readString(item, 'version');\n\t\t\tconst dist = readObject(item, 'dist');\n\t\t\tconst integrity = dist === null ? null : readString(dist, 'integrity');\n\t\t\tconst tarball = dist === null ? null : readString(dist, 'tarball');\n\t\t\tif (version === null || integrity === null || tarball === null) {\n\t\t\t\treturn [];\n\t\t\t}\n\t\t\tconst engines = readObject(item, 'engines');\n\t\t\tconst signatures = (dist === null ? null : dist['signatures']) ?? [];\n\t\t\tconst attestations = dist === null ? null : readObject(dist, 'attestations');\n\t\t\treturn [\n\t\t\t\t{\n\t\t\t\t\tversion,\n\t\t\t\t\tenginesNode: engines === null ? null : readString(engines, 'node'),\n\t\t\t\t\tintegrity,\n\t\t\t\t\ttarball,\n\t\t\t\t\tsignatures: Array.isArray(signatures) ? signatures.filter(isSignature) : [],\n\t\t\t\t\tattestationsUrl: attestations === null ? null : readString(attestations, 'url'),\n\t\t\t\t},\n\t\t\t];\n\t\t});\n\t}\n\n\t/** Publication time per version, used only to judge signatures by expired keys. */\n\tasync times(): Promise<Record<string, string>> {\n\t\tconst output = await this.#run(['view', 'npm', 'time'], true);\n\t\tconst map = output === null ? null : (asList(output)[0] ?? null);\n\t\tconst times: Record<string, string> = {};\n\t\tif (map !== null && typeof map === 'object') {\n\t\t\tfor (const [version, time] of Object.entries(map)) {\n\t\t\t\tif (typeof time === 'string') {\n\t\t\t\t\ttimes[version] = time;\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t\treturn times;\n\t}\n\n\t/** Downloads one npm version's tarball into `dest` through `npm pack`. */\n\tpack(version: string, dest: string): Promise<PackedTarball> {\n\t\treturn this.packPackage('npm', version, dest);\n\t}\n\n\tasync packPackage(name: string, version: string, dest: string): Promise<PackedTarball> {\n\t\tconst output = await this.#run(\n\t\t\t['pack', `${name}@${version}`, `--pack-destination=${dest}`],\n\t\t\tfalse,\n\t\t);\n\t\t// npm 8 prints a list; npm 9 and later print an object keyed by package name.\n\t\tconst items = asList(output).flatMap((item) =>\n\t\t\treadString(item, 'filename') === null ? asList(Object.values(item)) : [item],\n\t\t);\n\t\tconst item = items.find((candidate) => readString(candidate, 'filename') !== null) ?? null;\n\t\tconst filename = item === null ? null : readString(item, 'filename');\n\t\tconst integrity = item === null ? null : readString(item, 'integrity');\n\t\tif (filename === null || integrity === null) {\n\t\t\tthrow this.#failure(`npm pack returned no tarball for ${name}@${version}`);\n\t\t}\n\t\treturn { file: join(dest, filename), integrity };\n\t}\n\n\t#failure(detail: string): NpmVmError {\n\t\treturn new NpmVmError(\n\t\t\t'M-TRANSPORT',\n\t\t\tEXIT.transport,\n\t\t\ttransportMessage(this.#own.version, detail),\n\t\t);\n\t}\n\n\t/** Runs npm with the isolation flags; returns parsed JSON, or null for a 404 when `missingIsEmpty`. */\n\tasync #run(args: string[], missingIsEmpty: boolean): Promise<unknown> {\n\t\tconst cwd = newWorkDir(this.#tmpRoot);\n\t\tconst argv = [\n\t\t\tthis.#own.cliPath,\n\t\t\t...args,\n\t\t\t'--json',\n\t\t\t'--ignore-scripts',\n\t\t\t'--loglevel=error',\n\t\t\t// A packument's tarball URL never redirects the download to another host (spec SEC-7).\n\t\t\t'--replace-registry-host=always',\n\t\t\t...proxyFlags(this.#config),\n\t\t\t'--fetch-retry-mintimeout=1000',\n\t\t\t'--fetch-retry-maxtimeout=10000',\n\t\t\t`--prefix=${cwd}`,\n\t\t\t`--cache=${this.#config.cache}`,\n\t\t\t`--userconfig=${this.#config.userconfig}`,\n\t\t\t`--globalconfig=${this.#config.globalconfig}`,\n\t\t];\n\t\ttry {\n\t\t\tconst { stdout: output } = await new Promise<{ stdout: string }>((resolve, reject) => {\n\t\t\t\texecFile(\n\t\t\t\t\tthis.#nodePath,\n\t\t\t\t\targv,\n\t\t\t\t\t{ cwd, env: this.#env, maxBuffer: MAX_OUTPUT, timeout: 300_000, windowsHide: true },\n\t\t\t\t\t(error, stdout, stderr) => {\n\t\t\t\t\t\tif (error === null) {\n\t\t\t\t\t\t\tresolve({ stdout });\n\t\t\t\t\t\t\treturn;\n\t\t\t\t\t\t}\n\t\t\t\t\t\treject(Object.assign(error, { stdout, stderr }));\n\t\t\t\t\t},\n\t\t\t\t);\n\t\t\t});\n\t\t\treturn parseJson(output);\n\t\t} catch (error) {\n\t\t\tconst stderr = String((error as { stderr?: string }).stderr ?? '');\n\t\t\tif (missingIsEmpty && /\\bE404\\b/.test(stderr)) {\n\t\t\t\treturn null;\n\t\t\t}\n\t\t\tconst line = (\n\t\t\t\tstderr.split('\\n').find((text) => /^npm (ERR!|error)/.test(text)) ??\n\t\t\t\t(error as Error).message\n\t\t\t)\n\t\t\t\t.replace(/^npm (ERR!|error) /, '')\n\t\t\t\t.trim();\n\t\t\tconst redacted = redactUrls(line);\n\t\t\tif (/\\bEINTEGRITY\\b/.test(stderr)) {\n\t\t\t\tthrow new NpmVmError(\n\t\t\t\t\t'M-INTEGRITY',\n\t\t\t\t\tEXIT.verification,\n\t\t\t\t\tintegrityMessage('the registry integrity', 'other bytes', redacted),\n\t\t\t\t);\n\t\t\t}\n\t\t\tthrow this.#failure(redacted);\n\t\t} finally {\n\t\t\trmSync(cwd, { recursive: true, force: true });\n\t\t}\n\t}\n}\n\n/** Proxy settings as flags, since the env the transport sees carries none (spec DL-2). */\nfunction proxyFlags(config: NpmConfigView): string[] {\n\tconst flags: string[] = [];\n\tif (config.httpsProxy !== null) {\n\t\tflags.push(`--https-proxy=${config.httpsProxy}`);\n\t}\n\tif (config.proxy !== null) {\n\t\tflags.push(`--proxy=${config.proxy}`);\n\t}\n\tif (config.noproxy !== null) {\n\t\tflags.push(`--noproxy=${config.noproxy}`);\n\t}\n\treturn flags;\n}\n\nfunction parseJson(text: string): unknown {\n\tconst trimmed = text.trim();\n\tif (trimmed === '') {\n\t\treturn null;\n\t}\n\treturn JSON.parse(trimmed) as unknown;\n}\n\nfunction asList(value: unknown): Record<string, unknown>[] {\n\tconst items = Array.isArray(value) ? value : [value];\n\treturn items.filter(\n\t\t(item): item is Record<string, unknown> => typeof item === 'object' && item !== null,\n\t);\n}\n\nfunction readString(record: Record<string, unknown>, key: string): string | null {\n\tconst value = record[key];\n\treturn typeof value === 'string' ? value : null;\n}\n\nfunction readObject(record: Record<string, unknown>, key: string): Record<string, unknown> | null {\n\tconst value = record[key];\n\treturn typeof value === 'object' && value !== null && !Array.isArray(value)\n\t\t? (value as Record<string, unknown>)\n\t\t: null;\n}\n\nfunction isSignature(value: unknown): value is RegistrySignature {\n\treturn (\n\t\ttypeof value === 'object' &&\n\t\tvalue !== null &&\n\t\ttypeof (value as RegistrySignature).keyid === 'string' &&\n\t\ttypeof (value as RegistrySignature).sig === 'string'\n\t);\n}\n","import { readFileSync } from 'node:fs';\nimport { join } from 'node:path';\n\n/** A registry signing key as `https://registry.npmjs.org/-/npm/v1/keys` lists it (spec SEC-1). */\nexport interface RegistryKey {\n\tkeyid: string;\n\t/** SPKI DER, base64. */\n\tkey: string;\n\texpires: string | null;\n\t/** A revoked key never verifies anything, whatever the dates say. */\n\trevoked?: boolean;\n}\n\n/*\n * Append-only: a rotated key keeps its entry with `expires`; a compromised one gets `revoked: true`.\n * Snapshot of the registry listing taken on 2026-10-15.\n */\nexport const REGISTRY_KEYS: readonly RegistryKey[] = [\n\t{\n\t\tkeyid: 'SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA',\n\t\tkey: 'MFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAE1Olb3zMAFFxXKHiIkQO5cJ3Yhl5i6UPp+IhuteBJbuHcA5UogKo0EWtlWwW6KSaKoTNEYL7JlCQiVnkhBktUgg==',\n\t\texpires: '2025-01-29T00:00:00.000Z',\n\t},\n\t{\n\t\tkeyid: 'SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U',\n\t\tkey: 'MFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAEY6Ya7W++7aUPzvMTrezH6Ycx3c+HOKYCcNGybJZSCJq/fd7Qa8uuAKtdIkUQtQiEKERhAmE5lMMJhP8OkDOa2g==',\n\t\texpires: null,\n\t},\n];\n\nexport const EXTRA_KEYS_FILE = 'keys.json';\n\n/**\n * Keys added beside the built-in ones from `<home>/state/keys.json`, for registries that sign with their own keys.\n * Anything able to write there could replace the runtime itself, so this adds no trust the home does not already hold.\n */\nexport function loadKeyring(stateDir: string): RegistryKey[] {\n\tlet extra: unknown;\n\ttry {\n\t\textra = JSON.parse(readFileSync(join(stateDir, EXTRA_KEYS_FILE), 'utf8'));\n\t} catch {\n\t\treturn [...REGISTRY_KEYS];\n\t}\n\tconst keys = Array.isArray(extra) ? extra : [];\n\treturn [\n\t\t...REGISTRY_KEYS,\n\t\t...keys.filter(\n\t\t\t(key): key is RegistryKey =>\n\t\t\t\ttypeof key === 'object' &&\n\t\t\t\tkey !== null &&\n\t\t\t\ttypeof (key as RegistryKey).keyid === 'string' &&\n\t\t\t\ttypeof (key as RegistryKey).key === 'string' &&\n\t\t\t\t((key as RegistryKey).expires === null || typeof (key as RegistryKey).expires === 'string'),\n\t\t),\n\t];\n}\n","import { createHash } from 'node:crypto';\nimport { mkdirSync, readFileSync, rmSync } from 'node:fs';\nimport { join } from 'node:path';\nimport semver from 'semver';\nimport { EXIT, NpmVmError } from '../errors.ts';\nimport { engineMessage, integrityMessage, transportMessage } from '../messages.ts';\nimport { findOwnNpm, type OwnNpm } from '../own-npm.ts';\nimport type { ResolveProviders } from '../index.ts';\nimport type { Candidate, Selection } from '../select.ts';\nimport type { NpmSpec } from '../spec.ts';\nimport { acquireShared, ownerRecord, type Lease } from '../state/lease.ts';\nimport { touchUsed } from '../state/prune.ts';\nimport { resolveDirs, type Dirs } from '../setup/home.ts';\nimport {\n\tcanonicalEntry,\n\tlistEntries,\n\tpublishEntry,\n\tstagingDir,\n\tvalidateEntry,\n\ttype PublishedEntry,\n} from './cache.ts';\nimport { loadNpmConfig, type NpmConfigView } from './config.ts';\nimport { newWorkDir, Transport, transportUsable, type RegistryVersion } from './fetch.ts';\nimport { loadKeyring, type RegistryKey } from './keys.ts';\nimport {\n\tcheckIntegrity,\n\tfileDigests,\n\tsafeExtract,\n\tverifySignatures,\n\twriteVerified,\n\ttype Digests,\n} from './verify.ts';\n\nexport interface InstallContext {\n\tdirs: Dirs;\n\town: OwnNpm | null;\n\tenv: NodeJS.ProcessEnv;\n\tnodeVersion: string;\n\t/** The Node that runs the transport and, through the shims, npm itself. */\n\tnodePath: string;\n\tkeys: readonly RegistryKey[];\n}\n\nexport interface ContextNode {\n\t/** The Node binary the shims resolve through PATH; the Action passes the one setup-node installed. */\n\texecPath: string;\n\tversion: string;\n}\n\nexport function createContext(\n\tenv: NodeJS.ProcessEnv = process.env,\n\thome?: string,\n\tnode: ContextNode = { execPath: process.execPath, version: process.version },\n): InstallContext {\n\tconst dirs = resolveDirs(env, home);\n\treturn {\n\t\tdirs,\n\t\town: findOwnNpm(node.execPath),\n\t\tenv,\n\t\tnodeVersion: node.version,\n\t\tnodePath: node.execPath,\n\t\tkeys: loadKeyring(dirs.state),\n\t};\n}\n\nfunction toCandidate(version: RegistryVersion): Candidate {\n\treturn {\n\t\tversion: version.version,\n\t\tenginesNode: version.enginesNode,\n\t\tintegrity: version.integrity,\n\t\tentryPath: null,\n\t\tsignatures: version.signatures,\n\t};\n}\n\n/** Lazily loads the npm config and builds the transport once per process. */\nclass TransportFactory {\n\treadonly #context: InstallContext;\n\t#ready: Promise<{ transport: Transport; config: NpmConfigView }> | null = null;\n\n\tconstructor(context: InstallContext) {\n\t\tthis.#context = context;\n\t}\n\n\tget(): Promise<{ transport: Transport; config: NpmConfigView }> {\n\t\tthis.#ready ??= this.#create();\n\t\treturn this.#ready;\n\t}\n\n\tasync #create(): Promise<{ transport: Transport; config: NpmConfigView }> {\n\t\tconst { own, env, dirs } = this.#context;\n\t\tconst found = own?.version ?? null;\n\t\tif (!transportUsable(own)) {\n\t\t\tthrow new NpmVmError(\n\t\t\t\t'M-TRANSPORT',\n\t\t\t\tEXIT.transport,\n\t\t\t\ttransportMessage(found, 'too old or missing'),\n\t\t\t);\n\t\t}\n\t\tconst cwd = newWorkDir(dirs.tmp);\n\t\ttry {\n\t\t\tconst config = await loadNpmConfig(own, env, cwd, this.#context.nodePath);\n\t\t\treturn {\n\t\t\t\ttransport: new Transport(own, config, env, dirs.tmp, this.#context.nodePath),\n\t\t\t\tconfig,\n\t\t\t};\n\t\t} finally {\n\t\t\trmSync(cwd, { recursive: true, force: true });\n\t\t}\n\t}\n}\n\n/** A downloaded tarball plus what the registry said about it, ready for verification. */\nexport interface PackedSource {\n\tfile: string;\n\tpublished: RegistryVersion;\n\tpublishedAt: () => Promise<string | null>;\n\tregistry: string;\n}\n\nexport interface EnsureOptions {\n\t/** Called with the verified tarball before it is extracted, so a caller can keep a copy (the Action's cache). */\n\tonPacked?: (source: PackedSource, digests: Digests) => Promise<void>;\n\t/** Never contact the registry; defaults to `NPM_VM_OFFLINE` in the context env. */\n\toffline?: boolean;\n}\n\nexport interface Installer extends ResolveProviders {\n\t/** Makes the selected npm runnable: validates a cached entry or downloads, verifies and publishes one (spec SEC-4, SEC-5). */\n\tensure(\n\t\tselection: Selection,\n\t\toptions?: EnsureOptions,\n\t): Promise<{ entryPath: string; lease: Lease }>;\n\t/** Verifies and publishes a tarball obtained elsewhere, such as a restored CI cache (spec SEC-1 to SEC-5). */\n\tinstallTarball(selection: Selection, source: PackedSource): Promise<PublishedEntry>;\n\t/** A short stable id of the configured registry, for cache keys that must not mix registries. */\n\tregistryIdentity(): Promise<string>;\n}\n\nexport function createInstaller(context: InstallContext): Installer {\n\tconst factory = new TransportFactory(context);\n\n\tasync function registryVersions(specs: readonly NpmSpec[]): Promise<RegistryVersion[]> {\n\t\tconst { transport } = await factory.get();\n\t\tconst byVersion = new Map<string, RegistryVersion>();\n\t\tfor (const spec of specs) {\n\t\t\tfor (const version of await transport.view(spec.exact ?? spec.range)) {\n\t\t\t\tbyVersion.set(version.version, version);\n\t\t\t}\n\t\t}\n\t\treturn [...byVersion.values()];\n\t}\n\n\tasync function installTarball(\n\t\tselection: Selection,\n\t\tsource: PackedSource,\n\t\tonPacked?: EnsureOptions['onPacked'],\n\t): Promise<PublishedEntry> {\n\t\tconst { candidate } = selection;\n\t\tconst owner = ownerRecord(context.dirs.machine.id);\n\t\tif (\n\t\t\tsource.published.version !== candidate.version ||\n\t\t\tsource.published.integrity !== candidate.integrity\n\t\t) {\n\t\t\tthrow new NpmVmError(\n\t\t\t\t'M-INTEGRITY',\n\t\t\t\tEXIT.verification,\n\t\t\t\tintegrityMessage(\n\t\t\t\t\tcandidate.integrity,\n\t\t\t\t\tsource.published.integrity,\n\t\t\t\t\t`the registry no longer serves npm ${candidate.version} with this integrity`,\n\t\t\t\t),\n\t\t\t);\n\t\t}\n\t\tconst digests = await fileDigests(source.file);\n\t\tcheckIntegrity(digests, candidate.integrity, selection.hashes);\n\t\tconst keyid = await verifySignatures({\n\t\t\tname: 'npm',\n\t\t\tversion: candidate.version,\n\t\t\tintegrity: candidate.integrity,\n\t\t\tsignatures: source.published.signatures,\n\t\t\tpublishedAt: source.publishedAt,\n\t\t\tkeys: context.keys,\n\t\t\tregistry: source.registry,\n\t\t\tpinned: selection.hashes.length > 0,\n\t\t});\n\t\tif (onPacked !== undefined) {\n\t\t\tawait onPacked(source, digests);\n\t\t}\n\t\t// Extracted on the cache's own filesystem: the final rename into the cache must not cross one (EXDEV).\n\t\tconst work = newWorkDir(stagingDir(context.dirs.cache));\n\t\ttry {\n\t\t\tconst extracted = join(work, 'package');\n\t\t\tmkdirSync(extracted, { mode: 0o700 });\n\t\t\tawait safeExtract(source.file, extracted);\n\t\t\tcheckExtracted(extracted, candidate, context.nodeVersion);\n\t\t\twriteVerified(extracted, {\n\t\t\t\tversion: candidate.version,\n\t\t\t\tintegrity: candidate.integrity,\n\t\t\t\tkeyid,\n\t\t\t\tsha256: digests.sha256hex,\n\t\t\t\tsha224: digests.sha224hex,\n\t\t\t\tverifiedAt: new Date().toISOString(),\n\t\t\t});\n\t\t\tconst canonical = canonicalEntry(context.dirs.cache, candidate.version, candidate.integrity);\n\t\t\tmkdirSync(join(canonical, '..'), { recursive: true, mode: 0o700 });\n\t\t\tconst published = publishEntry(extracted, canonical, candidate.integrity, owner);\n\t\t\ttouchUsed(published.entryPath);\n\t\t\treturn published;\n\t\t} finally {\n\t\t\trmSync(work, { recursive: true, force: true });\n\t\t}\n\t}\n\n\treturn {\n\t\tnodeVersion: context.nodeVersion,\n\t\townNpm: () => context.own,\n\t\tcached: async () => listEntries(context.dirs.cache, context.keys),\n\t\tregistry: async (specs) => (await registryVersions(specs)).map(toCandidate),\n\t\tentryPathFor: (candidate) =>\n\t\t\tcanonicalEntry(context.dirs.cache, candidate.version, candidate.integrity),\n\t\tasync registryIdentity() {\n\t\t\tconst { config } = await factory.get();\n\t\t\treturn createHash('sha256').update(config.registry).digest('hex').slice(0, 12);\n\t\t},\n\t\tinstallTarball: (selection, source) => installTarball(selection, source),\n\t\tasync ensure(selection, options = {}) {\n\t\t\tconst { candidate } = selection;\n\t\t\tconst owner = ownerRecord(context.dirs.machine.id);\n\t\t\tif (candidate.entryPath !== null && validateEntry(candidate.entryPath, candidate.integrity)) {\n\t\t\t\tconst lease = await acquireShared(candidate.entryPath, owner);\n\t\t\t\t// A live prune gate means the entry is on its way out; fetch a private copy instead of waiting.\n\t\t\t\tif (lease !== null && validateEntry(candidate.entryPath, candidate.integrity)) {\n\t\t\t\t\ttouchUsed(candidate.entryPath);\n\t\t\t\t\treturn { entryPath: candidate.entryPath, lease };\n\t\t\t\t}\n\t\t\t\tlease?.release();\n\t\t\t}\n\t\t\t// Offline means offline even when the cached entry turned out unusable (spec RES-7).\n\t\t\tif (options.offline ?? (context.env['NPM_VM_OFFLINE'] ?? '') !== '') {\n\t\t\t\tthrow new NpmVmError(\n\t\t\t\t\t'M-NOMATCH',\n\t\t\t\t\tEXIT.resolution,\n\t\t\t\t\t`npm ${candidate.version} is not usable from the cache and NPM_VM_OFFLINE forbids the registry.`,\n\t\t\t\t);\n\t\t\t}\n\t\t\tconst { transport, config } = await factory.get();\n\t\t\tconst published = (await transport.view(candidate.version)).find(\n\t\t\t\t(item) => item.version === candidate.version,\n\t\t\t);\n\t\t\tif (published === undefined) {\n\t\t\t\tthrow new NpmVmError(\n\t\t\t\t\t'M-INTEGRITY',\n\t\t\t\t\tEXIT.verification,\n\t\t\t\t\tintegrityMessage(\n\t\t\t\t\t\tcandidate.integrity,\n\t\t\t\t\t\t'nothing',\n\t\t\t\t\t\t`the registry no longer serves npm ${candidate.version}`,\n\t\t\t\t\t),\n\t\t\t\t);\n\t\t\t}\n\t\t\tconst work = newWorkDir(context.dirs.tmp);\n\t\t\ttry {\n\t\t\t\tconst packed = await transport.pack(candidate.version, work);\n\t\t\t\tconst source: PackedSource = {\n\t\t\t\t\tfile: packed.file,\n\t\t\t\t\tpublished,\n\t\t\t\t\tpublishedAt: async () => (await transport.times())[candidate.version] ?? null,\n\t\t\t\t\tregistry: config.registry,\n\t\t\t\t};\n\t\t\t\treturn await installTarball(selection, source, options.onPacked);\n\t\t\t} finally {\n\t\t\t\trmSync(work, { recursive: true, force: true });\n\t\t\t}\n\t\t},\n\t};\n}\n\n/** The extracted manifest is authoritative for name, version and engines (spec SEC-5). */\nfunction checkExtracted(dir: string, candidate: Candidate, nodeVersion: string): void {\n\tlet pkg: Record<string, unknown>;\n\ttry {\n\t\tpkg = JSON.parse(readFileSync(join(dir, 'package.json'), 'utf8')) as Record<string, unknown>;\n\t} catch (error) {\n\t\tthrow new NpmVmError(\n\t\t\t'M-INTEGRITY',\n\t\t\tEXIT.verification,\n\t\t\tintegrityMessage('npm package.json', 'unreadable', (error as Error).message),\n\t\t);\n\t}\n\tif (pkg['name'] !== 'npm' || pkg['version'] !== candidate.version) {\n\t\tthrow new NpmVmError(\n\t\t\t'M-INTEGRITY',\n\t\t\tEXIT.verification,\n\t\t\tintegrityMessage(\n\t\t\t\t`npm@${candidate.version}`,\n\t\t\t\t`${String(pkg['name'])}@${String(pkg['version'])}`,\n\t\t\t\t'the tarball holds a different package',\n\t\t\t),\n\t\t);\n\t}\n\tconst engines = pkg['engines'];\n\tconst node =\n\t\ttypeof engines === 'object' && engines !== null\n\t\t\t? (engines as Record<string, unknown>)['node']\n\t\t\t: undefined;\n\tif (\n\t\ttypeof node === 'string' &&\n\t\t!semver.satisfies(nodeVersion, node, { includePrerelease: true })\n\t) {\n\t\tthrow new NpmVmError(\n\t\t\t'M-ENGINE',\n\t\t\tEXIT.resolution,\n\t\t\tengineMessage(candidate.version, node, nodeVersion),\n\t\t);\n\t}\n}\n","import { readFileSync, statSync } from 'node:fs';\nimport { dirname, isAbsolute, join, matchesGlob, relative, resolve, sep } from 'node:path';\n\nexport interface ProjectLocation {\n\t/** npm's `localPrefix` for this argv and cwd (spec RES-2). */\n\troot: string;\n\t/** Global mode, computed as npm does (spec RES-3). */\n\tglobal: boolean;\n\t/** The `--prefix` the command line carries, resolved, when it carries one. */\n\tcliPrefix: string | null;\n}\n\ninterface CliFlags {\n\tprefix: string | null;\n\tglobal: boolean | null;\n\tlocation: string | null;\n\tworkspaces: boolean | null;\n}\n\nconst BOOLEANS = new Set(['global', 'workspaces']);\nconst SHORTHANDS: Record<string, string> = {\n\tC: 'prefix',\n\tg: 'global',\n\tL: 'location',\n\tws: 'workspaces',\n};\n\n/**\n * The subset of nopt that decides the prefix: `--flag value`, `--flag=value`, `--no-flag`, `--flag true|false` for booleans, npm's shorthands and `--`.\n * Later flags win, as in nopt.\n */\nexport function parsePrefixFlags(argv: readonly string[], cwd: string): CliFlags {\n\tconst flags: CliFlags = { prefix: null, global: null, location: null, workspaces: null };\n\tfor (let i = 0; i < argv.length; i += 1) {\n\t\tconst arg = argv[i] as string;\n\t\tif (arg === '--') {\n\t\t\tbreak;\n\t\t}\n\t\tlet name: string;\n\t\tlet value: string | null = null;\n\t\tif (arg.startsWith('--')) {\n\t\t\tconst eq = arg.indexOf('=');\n\t\t\tname = eq === -1 ? arg.slice(2) : arg.slice(2, eq);\n\t\t\tvalue = eq === -1 ? null : arg.slice(eq + 1);\n\t\t\tname = SHORTHANDS[name] ?? name;\n\t\t} else if (arg.startsWith('-') && arg.length > 1 && SHORTHANDS[arg.slice(1)] !== undefined) {\n\t\t\tname = SHORTHANDS[arg.slice(1)] as string;\n\t\t} else {\n\t\t\tcontinue;\n\t\t}\n\t\tlet negated = false;\n\t\tif (name.startsWith('no-') && BOOLEANS.has(name.slice(3))) {\n\t\t\tnegated = true;\n\t\t\tname = name.slice(3);\n\t\t}\n\t\tif (BOOLEANS.has(name)) {\n\t\t\tlet bool = !negated;\n\t\t\tif (value !== null) {\n\t\t\t\tbool = value !== 'false';\n\t\t\t} else if (!negated && (argv[i + 1] === 'true' || argv[i + 1] === 'false')) {\n\t\t\t\tbool = argv[i + 1] === 'true';\n\t\t\t\ti += 1;\n\t\t\t}\n\t\t\tif (name === 'global') {\n\t\t\t\tflags.global = bool;\n\t\t\t} else {\n\t\t\t\tflags.workspaces = bool;\n\t\t\t}\n\t\t\tcontinue;\n\t\t}\n\t\tif (name !== 'prefix' && name !== 'location') {\n\t\t\tcontinue;\n\t\t}\n\t\tif (value === null) {\n\t\t\tif (i + 1 >= argv.length) {\n\t\t\t\tcontinue;\n\t\t\t}\n\t\t\tvalue = argv[i + 1] as string;\n\t\t\ti += 1;\n\t\t}\n\t\tif (name === 'prefix') {\n\t\t\tflags.prefix = resolve(cwd, value);\n\t\t} else {\n\t\t\tflags.location = value;\n\t\t}\n\t}\n\treturn flags;\n}\n\n/** Global mode from the command line and the npm env, CLI winning (spec RES-3). */\nexport function isGlobalMode(flags: CliFlags, env: NodeJS.ProcessEnv): boolean {\n\t// npm: `global || location === 'global'`, each setting resolved on its own, CLI over env.\n\tconst fromEnv = env['npm_config_global'];\n\t// npm ignores an empty value; nopt reads any other value as true except its spellings of false.\n\tconst global =\n\t\tflags.global ??\n\t\t(fromEnv === undefined || fromEnv === '' ? null : !['false', '0', 'null'].includes(fromEnv));\n\tconst location = flags.location ?? env['npm_config_location'] ?? null;\n\treturn global === true || location === 'global';\n}\n\nfunction hasPackageJson(dir: string): boolean {\n\ttry {\n\t\treturn statSync(join(dir, 'package.json')).isFile();\n\t} catch {\n\t\treturn false;\n\t}\n}\n\nfunction hasNodeModules(dir: string): boolean {\n\ttry {\n\t\treturn statSync(join(dir, 'node_modules')).isDirectory();\n\t} catch {\n\t\treturn false;\n\t}\n}\n\nfunction* walkUp(start: string): Generator<string> {\n\tlet dir = resolve(start);\n\tfor (;;) {\n\t\tyield dir;\n\t\tconst parent = dirname(dir);\n\t\tif (parent === dir) {\n\t\t\treturn;\n\t\t}\n\t\tdir = parent;\n\t}\n}\n\n/** The `workspaces` patterns of a manifest: the array form or `{ packages: [] }`, else none. */\nexport function workspacePatterns(pkg: unknown): string[] {\n\tif (typeof pkg !== 'object' || pkg === null) {\n\t\treturn [];\n\t}\n\tlet raw = (pkg as { workspaces?: unknown }).workspaces;\n\tif (typeof raw === 'object' && raw !== null && !Array.isArray(raw)) {\n\t\traw = (raw as { packages?: unknown }).packages;\n\t}\n\tif (!Array.isArray(raw)) {\n\t\treturn [];\n\t}\n\treturn raw.filter((entry): entry is string => typeof entry === 'string');\n}\n\n/**\n * Whether `candidate` is one of the workspaces `root` declares, matched like `@npmcli/map-workspaces`.\n * A pattern selects directories holding a `package.json`, `!pattern` removes matches, and `node_modules` never matches.\n */\nexport function isWorkspaceOf(\n\troot: string,\n\tcandidate: string,\n\tpatterns: readonly string[],\n): boolean {\n\tconst rel = relative(root, candidate);\n\tif (rel === '' || rel.startsWith('..') || isAbsolute(rel) || !hasPackageJson(candidate)) {\n\t\treturn false;\n\t}\n\tif (rel.split(sep).includes('node_modules')) {\n\t\treturn false;\n\t}\n\tconst posix = rel.split(sep).join('/');\n\tconst { positive, negative } = splitPatterns(patterns);\n\treturn (\n\t\tpositive.some((pattern) => matchesGlob(posix, pattern)) &&\n\t\t!negative.some((pattern) => matchesGlob(posix, pattern))\n\t);\n}\n\n/*\n * map-workspaces drops a negated pattern when a later positive pattern falls under it,\n * so `['packages/**', '!packages/b/**', 'packages/b/a']` keeps `packages/b/a`.\n */\nfunction splitPatterns(patterns: readonly string[]): { positive: string[]; negative: string[] } {\n\tconst positive: string[] = [];\n\tconst negative: string[] = [];\n\tfor (const raw of patterns) {\n\t\tconst bangs = /^!+/.exec(raw)?.[0].length ?? 0;\n\t\tconst pattern = normalizePattern(raw.slice(bangs));\n\t\tif (bangs % 2 === 1) {\n\t\t\tnegative.push(pattern);\n\t\t\tcontinue;\n\t\t}\n\t\tfor (let i = negative.length - 1; i >= 0; i -= 1) {\n\t\t\tif (matchesGlob(pattern, negative[i] as string)) {\n\t\t\t\tnegative.splice(i, 1);\n\t\t\t}\n\t\t}\n\t\tpositive.push(pattern);\n\t}\n\treturn { positive, negative };\n}\n\nfunction normalizePattern(pattern: string): string {\n\treturn pattern\n\t\t.replace(/\\\\/g, '/')\n\t\t.replace(/^\\.?\\/+/, '')\n\t\t.replace(/\\/+$/, '');\n}\n\nfunction readManifest(dir: string): unknown {\n\ttry {\n\t\treturn JSON.parse(readFileSync(join(dir, 'package.json'), 'utf8')) as unknown;\n\t} catch {\n\t\treturn null;\n\t}\n}\n\n/**\n * Mirrors `@npmcli/config` `loadLocalPrefix` (spec RES-2): a CLI prefix is final.\n * Otherwise the nearest ancestor with `package.json` or `node_modules` wins, promoted to a parent whose `workspaces` include it unless `--no-workspaces` or global mode.\n */\nexport function findProject(\n\targv: readonly string[],\n\tcwd: string,\n\tenv: NodeJS.ProcessEnv = process.env,\n): ProjectLocation {\n\tconst flags = parsePrefixFlags(argv, cwd);\n\tconst global = isGlobalMode(flags, env);\n\tif (flags.prefix !== null) {\n\t\treturn { root: flags.prefix, global, cliPrefix: flags.prefix };\n\t}\n\tlet localPrefix: string | null = null;\n\tfor (const dir of walkUp(cwd)) {\n\t\tconst manifest = hasPackageJson(dir);\n\t\tif (localPrefix === null) {\n\t\t\tif (manifest || hasNodeModules(dir)) {\n\t\t\t\tlocalPrefix = dir;\n\t\t\t\tif (flags.workspaces === false || global) {\n\t\t\t\t\tbreak;\n\t\t\t\t}\n\t\t\t}\n\t\t\tcontinue;\n\t\t}\n\t\tif (!manifest) {\n\t\t\tcontinue;\n\t\t}\n\t\tconst pkg = readManifest(dir);\n\t\tif (pkg !== null && isWorkspaceOf(dir, localPrefix, workspacePatterns(pkg))) {\n\t\t\tlocalPrefix = dir;\n\t\t\tbreak;\n\t\t}\n\t}\n\treturn { root: localPrefix ?? resolve(cwd), global, cliPrefix: null };\n}\n","import { readFileSync } from 'node:fs';\nimport { join } from 'node:path';\nimport { EXIT, NpmVmError } from './errors.ts';\nimport { engineMessage, noMatchMessage } from './messages.ts';\nimport type { OwnNpm } from './own-npm.ts';\nimport { createContext, createInstaller } from './install/index.ts';\nimport { findProject } from './project.ts';\nimport { selectCandidate, ownNpmSatisfies, type Candidate, type Selection } from './select.ts';\nimport {\n\tparseSpecs,\n\tparseVersionSpec,\n\tSpecError,\n\ttype NpmSpec,\n\ttype OnFail,\n\ttype ParsedSpecs,\n} from './spec.ts';\n\n// The public API is `resolveNpm` and what it returns (spec section 3.1); everything else lives in `./internal`.\nexport type { NpmSpec, OnFail, ParsedSpecs } from './spec.ts';\nexport type { Candidate, Selection } from './select.ts';\nexport { EXIT, isNpmVmError, NpmVmError } from './errors.ts';\n\nexport interface ResolveSource {\n\tfile: string;\n\tfield: 'devEngines' | 'packageManager' | 'env';\n}\n\nexport interface ResolveResult {\n\tkind: 'own' | 'cached' | 'download';\n\tversion: string;\n\t/** Absolute path to `bin/npm-cli.js`; for a download, the path the entry will have once fetched. */\n\tcliPath: string;\n\tsource: ResolveSource | null;\n\tprojectRoot: string | null;\n\t/** Set for `cached` and `download`: what to fetch or verify. */\n\tselection: Selection | null;\n\t/** The project's npm requirements, when it declares any. */\n\tspecs: NpmSpec[] | null;\n\t/** A warning to print on stderr before running Node's own npm (`onFail: warn`). */\n\twarning: string | null;\n}\n\nexport interface ResolveOptions {\n\tenv?: NodeJS.ProcessEnv;\n\toffline?: boolean;\n\t/** The npm-vm home holding the cache namespace; defaults to `NPM_VM_HOME` or the platform location. */\n\thome?: string;\n}\n\n/** The lookups resolution depends on; the install layer provides the real ones. */\nexport interface ResolveProviders {\n\townNpm(): OwnNpm | null;\n\tcached(specs: readonly NpmSpec[]): Promise<Candidate[]>;\n\tregistry(specs: readonly NpmSpec[]): Promise<Candidate[]>;\n\tnodeVersion: string;\n\t/** Path a download will occupy, so callers can report it before fetching. */\n\tentryPathFor(candidate: Candidate): string;\n}\n\n/** Resolves the npm to run for `argv` in `cwd` (spec section 5); writes only under the cache, spawns npm only as the transport. */\nexport function resolveNpm(\n\targv: readonly string[],\n\tcwd: string,\n\toptions: ResolveOptions = {},\n): Promise<ResolveResult> {\n\tconst env = options.env ?? process.env;\n\treturn resolveNpmWith(argv, cwd, options, createInstaller(createContext(env, options.home)));\n}\n\nexport async function resolveNpmWith(\n\targv: readonly string[],\n\tcwd: string,\n\toptions: ResolveOptions,\n\tproviders: ResolveProviders,\n): Promise<ResolveResult> {\n\tconst env = options.env ?? process.env;\n\tconst own = providers.ownNpm();\n\tconst ownResult = (\n\t\tprojectRoot: string | null,\n\t\tsource: ResolveSource | null,\n\t\twarning: string | null,\n\t): ResolveResult => {\n\t\tif (own === null) {\n\t\t\tthrow new NpmVmError(\n\t\t\t\t'M-TRANSPORT',\n\t\t\t\tEXIT.transport,\n\t\t\t\t'No npm found beside the active Node; reinstall Node.',\n\t\t\t);\n\t\t}\n\t\treturn {\n\t\t\tkind: 'own',\n\t\t\tversion: own.version,\n\t\t\tcliPath: own.cliPath,\n\t\t\tsource,\n\t\t\tprojectRoot,\n\t\t\tselection: null,\n\t\t\tspecs: null,\n\t\t\twarning,\n\t\t};\n\t};\n\n\tif (nonEmpty(env['NPM_VM_DISABLE'])) {\n\t\treturn ownResult(null, null, null);\n\t}\n\tconst project = findProject(argv, cwd, env);\n\tif (project.global) {\n\t\treturn ownResult(project.root, null, null);\n\t}\n\n\tlet parsed: ParsedSpecs;\n\tlet source: ResolveSource;\n\tif (nonEmpty(env['NPM_VM_VERSION'])) {\n\t\tparsed = {\n\t\t\tspecs: [parseVersionSpec(env['NPM_VM_VERSION'] as string, 'NPM_VM_VERSION')],\n\t\t\tonFail: 'error',\n\t\t\tfield: 'devEngines',\n\t\t};\n\t\tsource = { file: 'NPM_VM_VERSION', field: 'env' };\n\t} else {\n\t\tconst file = join(project.root, 'package.json');\n\t\tlet read: ParsedSpecs | null;\n\t\ttry {\n\t\t\tread = readSpecs(file);\n\t\t} catch (error) {\n\t\t\tif (!(error instanceof SpecError)) {\n\t\t\t\tthrow error;\n\t\t\t}\n\t\t\tconst message = `${file}: ${error.message}`;\n\t\t\tconst failure = new NpmVmError('M-NOMATCH', EXIT.resolution, message);\n\t\t\treturn applyPolicy(error.onFail, failure, () => ownResult(project.root, null, message));\n\t\t}\n\t\tif (read === null) {\n\t\t\treturn ownResult(project.root, null, null);\n\t\t}\n\t\tparsed = read;\n\t\tsource = { file, field: read.field };\n\t}\n\n\tif (own !== null && ownNpmSatisfies(own.version, parsed.specs)) {\n\t\treturn ownResult(project.root, source, null);\n\t}\n\n\tconst cached = await providers.cached(parsed.specs);\n\tlet result = selectCandidate(parsed.specs, cached, providers.nodeVersion);\n\tif (result.kind === 'failed' && !options.offline && !nonEmpty(env['NPM_VM_OFFLINE'])) {\n\t\tlet fromRegistry: Candidate[];\n\t\ttry {\n\t\t\tfromRegistry = await providers.registry(parsed.specs);\n\t\t} catch (error) {\n\t\t\t// A download that cannot happen follows the project's policy like a missing version does.\n\t\t\tif (!(error instanceof NpmVmError) || error.id !== 'M-TRANSPORT') {\n\t\t\t\tthrow error;\n\t\t\t}\n\t\t\treturn applyPolicy(parsed.onFail, error, () =>\n\t\t\t\townResult(project.root, source, error.message),\n\t\t\t);\n\t\t}\n\t\tresult = selectCandidate(parsed.specs, fromRegistry, providers.nodeVersion);\n\t}\n\tif (result.kind === 'selected') {\n\t\tconst { candidate } = result.selection;\n\t\tconst entry = candidate.entryPath ?? providers.entryPathFor(candidate);\n\t\treturn {\n\t\t\tkind: candidate.entryPath === null ? 'download' : 'cached',\n\t\t\tversion: candidate.version,\n\t\t\tcliPath: join(entry, 'bin', 'npm-cli.js'),\n\t\t\tsource,\n\t\t\tprojectRoot: project.root,\n\t\t\tselection: result.selection,\n\t\t\tspecs: parsed.specs,\n\t\t\twarning: null,\n\t\t};\n\t}\n\n\tconst message =\n\t\tresult.failure.kind === 'engine'\n\t\t\t? engineMessage(result.failure.version, result.failure.enginesNode, providers.nodeVersion)\n\t\t\t: noMatchMessage(parsed.specs, source.file, result.failure.reason);\n\tconst id = result.failure.kind === 'engine' ? 'M-ENGINE' : 'M-NOMATCH';\n\tconst failure = new NpmVmError(id, EXIT.resolution, message);\n\treturn applyPolicy(parsed.onFail, failure, () => ownResult(project.root, source, message));\n}\n\n/** `onFail` makes a failed resolution fatal, a warning before Node's own npm, or silent (spec RES-7). */\nfunction applyPolicy(\n\tonFail: OnFail,\n\tfailure: NpmVmError,\n\tfallback: () => ResolveResult,\n): ResolveResult {\n\tif (onFail === 'ignore') {\n\t\treturn { ...fallback(), warning: null };\n\t}\n\tif (onFail === 'warn') {\n\t\treturn fallback();\n\t}\n\tthrow failure;\n}\n\n/** Reads and validates the project's specs; a broken file or range follows its own `onFail` when readable, else errors. */\nfunction readSpecs(file: string): ParsedSpecs | null {\n\tlet text: string;\n\ttry {\n\t\ttext = readFileSync(file, 'utf8');\n\t} catch {\n\t\treturn null;\n\t}\n\tlet pkg: unknown;\n\ttry {\n\t\tpkg = JSON.parse(text);\n\t} catch (error) {\n\t\tthrow new NpmVmError(\n\t\t\t'M-NOMATCH',\n\t\t\tEXIT.resolution,\n\t\t\t`${file} is not valid JSON: ${(error as Error).message}`,\n\t\t);\n\t}\n\treturn parseSpecs(pkg);\n}\n\nfunction nonEmpty(value: string | undefined): boolean {\n\treturn value !== undefined && value !== '';\n}\n","import { existsSync, readFileSync } from 'node:fs';\nimport { join, posix, win32 } from 'node:path';\nimport { EXIT, NpmVmError } from '../errors.ts';\n\n/** The launcher ABI the shims carry; a runtime declares the ABI it needs (spec RUN-2). */\nexport const SHIM_ABI = 1;\n\nexport const SHIM_DIR = 'shims';\nexport const LAUNCHERS_DIR = 'launchers';\nexport const SELECTORS = ['npm', 'npx', 'npm-vm'] as const;\nexport type ShimName = (typeof SELECTORS)[number];\n\nexport interface ShimFile {\n\t/** File name inside `shims/`, with the Windows extension where there is one. */\n\tname: string;\n\tcontent: string;\n\tmode: number;\n}\n\nconst UNSAFE = /[\\n\\r\"'`$%!]/;\n\n/** Refuses a home no quoting makes safe in all four shells and cmd (spec SET-2, M-HOMEPATH). */\nexport function assertSafeHome(home: string): void {\n\tconst match = UNSAFE.exec(home);\n\tif (match !== null) {\n\t\tconst shown = match[0] === '\\n' || match[0] === '\\r' ? 'a line break' : `\"${match[0]}\"`;\n\t\tthrow new NpmVmError(\n\t\t\t'M-HOMEPATH',\n\t\t\tEXIT.usage,\n\t\t\t`The npm-vm home ${home} contains ${shown}, which cannot be quoted safely in every shell. Set NPM_VM_HOME to a plain path and run setup again.`,\n\t\t);\n\t}\n}\n\nfunction selectorOf(name: ShimName): 'npm' | 'npx' | 'cli' {\n\treturn name === 'npm-vm' ? 'cli' : name;\n}\n\n/**\n * The launcher templates shipped beside this code: `src/launchers/` from source, `dist/runtime/launchers/`\n * from the bin, and `launchers/` beside an installed `runtime.cjs`.\n */\nexport function templatesDir(): string {\n\tconst here = import.meta.dirname;\n\tfor (const candidate of [\n\t\tjoin(here, LAUNCHERS_DIR),\n\t\tjoin(here, '..', LAUNCHERS_DIR),\n\t\tjoin(here, 'runtime', LAUNCHERS_DIR),\n\t]) {\n\t\tif (existsSync(join(candidate, 'sh.tmpl'))) {\n\t\t\treturn candidate;\n\t\t}\n\t}\n\tthrow new Error(`npm-vm launcher templates not found near ${here}`);\n}\n\nexport type TemplateKind = 'sh' | 'cmd' | 'ps1';\n\nexport function readTemplate(dir: string, kind: TemplateKind): string {\n\t// cmd and ps1 keep their CRLF; an autocrlf checkout must not hand the sh shim CRLF.\n\tconst text = readFileSync(join(dir, `${kind}.tmpl`), 'utf8');\n\treturn kind === 'sh' ? text.replace(/\\r\\n/g, '\\n') : text;\n}\n\n/** Fills one launcher template; the ABI comes from the launcher generation the templates belong to. */\nexport function renderTemplate(\n\ttemplate: string,\n\tvalues: { bootstrap: string; selector: string; abi: number },\n): string {\n\treturn template\n\t\t.replace(/\\{\\{ABI\\}\\}/g, String(values.abi))\n\t\t.replace(/\\{\\{BOOTSTRAP\\}\\}/g, values.bootstrap)\n\t\t.replace(/\\{\\{SELECTOR\\}\\}/g, values.selector);\n}\n\n/** The POSIX shim: `sh` on every OS, so Git Bash and MSYS on Windows get one too. */\nexport function posixShim(\n\thome: string,\n\tname: ShimName,\n\ttemplates: string = templatesDir(),\n\tabi: number = SHIM_ABI,\n\tplatform: NodeJS.Platform = process.platform,\n): string {\n\t// Git Bash passes a backslash path through to node; everywhere else the shim must keep forward slashes.\n\tconst { join: joinPath } = platform === 'win32' ? win32 : posix;\n\treturn renderTemplate(readTemplate(templates, 'sh'), {\n\t\tbootstrap: joinPath(home, 'bootstrap.cjs'),\n\t\tselector: selectorOf(name),\n\t\tabi,\n\t});\n}\n\n/**\n * The cmd shim resolves node.exe through PATH only (`%~$PATH:i`): cmd would otherwise run a `node.exe`\n * committed to the current directory. One command line, so `%*` keeps its quoting.\n */\nexport function cmdShim(\n\thome: string,\n\tname: ShimName,\n\ttemplates: string = templatesDir(),\n\tabi: number = SHIM_ABI,\n): string {\n\treturn renderTemplate(readTemplate(templates, 'cmd'), {\n\t\tbootstrap: win32.join(home, 'bootstrap.cjs'),\n\t\tselector: selectorOf(name),\n\t\tabi,\n\t});\n}\n\n/** PowerShell never searches the current directory for a command, so `Get-Command` is enough. */\nexport function powershellShim(\n\thome: string,\n\tname: ShimName,\n\ttemplates: string = templatesDir(),\n\tabi: number = SHIM_ABI,\n): string {\n\treturn renderTemplate(readTemplate(templates, 'ps1'), {\n\t\tbootstrap: win32.join(home, 'bootstrap.cjs'),\n\t\tselector: selectorOf(name),\n\t\tabi,\n\t});\n}\n\nexport interface RenderOptions {\n\tpowershell?: boolean;\n\ttemplates?: string;\n\tabi?: number;\n}\n\n/** Every shim file for the platform (spec SET-2); `.ps1` files are included only when the policy allows them (WIN-2). */\nexport function renderShims(\n\thome: string,\n\tplatform: NodeJS.Platform,\n\toptions: RenderOptions = {},\n): ShimFile[] {\n\tassertSafeHome(home);\n\tconst templates = options.templates ?? templatesDir();\n\tconst abi = options.abi ?? SHIM_ABI;\n\tconst files: ShimFile[] = [];\n\tfor (const name of SELECTORS) {\n\t\tfiles.push({ name, content: posixShim(home, name, templates, abi, platform), mode: 0o755 });\n\t\tif (platform === 'win32') {\n\t\t\tfiles.push({\n\t\t\t\tname: `${name}.cmd`,\n\t\t\t\tcontent: cmdShim(home, name, templates, abi),\n\t\t\t\tmode: 0o644,\n\t\t\t});\n\t\t\tif (options.powershell !== false) {\n\t\t\t\tfiles.push({\n\t\t\t\t\tname: `${name}.ps1`,\n\t\t\t\t\tcontent: powershellShim(home, name, templates, abi),\n\t\t\t\t\tmode: 0o644,\n\t\t\t\t});\n\t\t\t}\n\t\t}\n\t}\n\treturn files;\n}\n\n/** The ABI a shim or bootstrap file declares, or null when the file is not ours. */\nexport function shimAbi(content: string): number | null {\n\tconst match = /npm-vm launcher abi=(\\d+)|LAUNCHER_ABI = (\\d+)/.exec(content);\n\treturn match === null ? null : Number(match[1] ?? match[2]);\n}\n\nexport function shimDir(home: string): string {\n\treturn join(home, SHIM_DIR);\n}\n\n/** Our `.ps1` shims left from a permissive policy; PowerShell would still prefer them over `.cmd` (WIN-2). */\nexport function stalePowershellShims(home: string): string[] {\n\treturn SELECTORS.map((name) => join(shimDir(home), `${name}.ps1`)).filter((file) => {\n\t\ttry {\n\t\t\treturn shimAbi(readFileSync(file, 'utf8')) !== null;\n\t\t} catch {\n\t\t\treturn false;\n\t\t}\n\t});\n}\n","import { win32 } from 'node:path';\nimport { assertSafeHome, SHIM_DIR, shimDir } from './shims.ts';\n\nexport const SHELLS = ['zsh', 'bash', 'fish', 'powershell'] as const;\nexport type Shell = (typeof SHELLS)[number];\n\nexport function isShell(value: string): value is Shell {\n\treturn (SHELLS as readonly string[]).includes(value);\n}\n\nexport const BLOCK_START = '# >>> npm-vm >>>';\nexport const BLOCK_END = '# <<< npm-vm <<<';\n\n/** Escapes a path for use inside a bash or zsh `${var//pattern/}` pattern, where `/` and glob characters are special. */\nfunction patternOf(path: string): string {\n\treturn path.replace(/[\\\\/*?[\\]]/g, (char) => `\\\\${char}`);\n}\n\n/** Adds `shims/` to the front of PATH when absent; sourcing it twice changes nothing (spec SH-1). */\nfunction shimsFor(shell: Shell, home: string): string {\n\tif (shell === 'powershell') {\n\t\treturn win32.join(home, SHIM_DIR);\n\t}\n\t// POSIX shells on Windows (Git Bash, MSYS) take forward slashes; a backslash would escape.\n\treturn process.platform === 'win32' ? shimDir(home).replace(/\\\\/g, '/') : shimDir(home);\n}\n\nexport function pathSnippet(shell: Shell, home: string): string {\n\tassertSafeHome(home);\n\tconst shims = shimsFor(shell, home);\n\tswitch (shell) {\n\t\tcase 'zsh':\n\t\tcase 'bash':\n\t\t\treturn [\n\t\t\t\t`case \":$PATH:\" in`,\n\t\t\t\t` *\":${shims}:\"*) ;;`,\n\t\t\t\t` *) export PATH=\"${shims}:$PATH\" ;;`,\n\t\t\t\t'esac',\n\t\t\t\t'',\n\t\t\t].join('\\n');\n\t\tcase 'fish':\n\t\t\treturn [\n\t\t\t\t`if not contains -- \"${shims}\" $PATH`,\n\t\t\t\t` set -gx PATH \"${shims}\" $PATH`,\n\t\t\t\t'end',\n\t\t\t\t'',\n\t\t\t].join('\\n');\n\t\tcase 'powershell':\n\t\t\treturn [\n\t\t\t\t`if (($env:Path -split [IO.Path]::PathSeparator) -notcontains '${shims}') {`,\n\t\t\t\t` $env:Path = '${shims}' + [IO.Path]::PathSeparator + $env:Path`,\n\t\t\t\t'}',\n\t\t\t\t'',\n\t\t\t].join('\\n');\n\t}\n}\n\n/**\n * The prompt hook (spec SH-2): moves `shims/` back to the front when something prepended over it,\n * with parameter expansion only, keeping `$?` and chaining whatever hook was there.\n */\nexport function hookSnippet(shell: Shell, home: string): string {\n\tassertSafeHome(home);\n\tconst shims = shimsFor(shell, home);\n\tswitch (shell) {\n\t\tcase 'zsh':\n\t\t\treturn [\n\t\t\t\t'_npm_vm_guard() {',\n\t\t\t\t' local ret=$?',\n\t\t\t\t` if [[ \"$path[1]\" != \"${shims}\" ]]; then`,\n\t\t\t\t` path=(\"${shims}\" \\${path:#${shims}})`,\n\t\t\t\t' fi',\n\t\t\t\t' return $ret',\n\t\t\t\t'}',\n\t\t\t\t'if [[ -z \"${precmd_functions[(r)_npm_vm_guard]}\" ]]; then',\n\t\t\t\t' precmd_functions+=(_npm_vm_guard)',\n\t\t\t\t'fi',\n\t\t\t\t'',\n\t\t\t].join('\\n');\n\t\tcase 'bash':\n\t\t\treturn [\n\t\t\t\t'_npm_vm_guard() {',\n\t\t\t\t' local ret=$?',\n\t\t\t\t` case \":$PATH:\" in`,\n\t\t\t\t` \":${shims}:\"*) ;;`,\n\t\t\t\t' *)',\n\t\t\t\t' local rest=\":$PATH:\"',\n\t\t\t\t` rest=\"\\${rest//:${patternOf(shims)}:/:}\"`,\n\t\t\t\t' rest=\"${rest#:}\"',\n\t\t\t\t' rest=\"${rest%:}\"',\n\t\t\t\t` PATH=\"${shims}\\${rest:+:$rest}\"`,\n\t\t\t\t' ;;',\n\t\t\t\t' esac',\n\t\t\t\t' return $ret',\n\t\t\t\t'}',\n\t\t\t\t'case \";${PROMPT_COMMAND};\" in',\n\t\t\t\t' *\";_npm_vm_guard;\"*) ;;',\n\t\t\t\t' *) PROMPT_COMMAND=\"_npm_vm_guard${PROMPT_COMMAND:+;$PROMPT_COMMAND}\" ;;',\n\t\t\t\t'esac',\n\t\t\t\t'',\n\t\t\t].join('\\n');\n\t\tcase 'fish':\n\t\t\treturn [\n\t\t\t\t'if status is-interactive',\n\t\t\t\t' function _npm_vm_guard --on-event fish_prompt',\n\t\t\t\t` if test \"$PATH[1]\" != \"${shims}\"`,\n\t\t\t\t` set -l found (contains -i -- \"${shims}\" $PATH)`,\n\t\t\t\t' if test -n \"$found\"',\n\t\t\t\t' set -e PATH[$found]',\n\t\t\t\t' end',\n\t\t\t\t` set -gx PATH \"${shims}\" $PATH`,\n\t\t\t\t' end',\n\t\t\t\t' end',\n\t\t\t\t'end',\n\t\t\t\t'',\n\t\t\t].join('\\n');\n\t\tcase 'powershell':\n\t\t\treturn [\n\t\t\t\t'if (-not (Test-Path Function:\\\\global:_npm_vm_original_prompt)) {',\n\t\t\t\t' $prev = Get-Item Function:\\\\prompt -ErrorAction SilentlyContinue',\n\t\t\t\t' if ($prev) { Set-Item Function:\\\\global:_npm_vm_original_prompt $prev.ScriptBlock }',\n\t\t\t\t' else { function global:_npm_vm_original_prompt { \"PS $($executionContext.SessionState.Path.CurrentLocation)$(\\'>\\' * ($nestedPromptLevel + 1)) \" } }',\n\t\t\t\t' function global:prompt {',\n\t\t\t\t' $ok = $?',\n\t\t\t\t' $exit = $global:LASTEXITCODE',\n\t\t\t\t` $shims = '${shims}'`,\n\t\t\t\t' $parts = @($env:Path -split [IO.Path]::PathSeparator)',\n\t\t\t\t' if ($parts.Length -eq 0 -or $parts[0] -ne $shims) {',\n\t\t\t\t' $env:Path = (@($shims) + @($parts | Where-Object { $_ -ne $shims })) -join [IO.Path]::PathSeparator',\n\t\t\t\t' }',\n\t\t\t\t' $out = & $function:global:_npm_vm_original_prompt',\n\t\t\t\t' $global:LASTEXITCODE = $exit',\n\t\t\t\t' $out',\n\t\t\t\t\" if (-not $ok) { Write-Error 'npm-vm: preserving $?' -ErrorAction SilentlyContinue }\",\n\t\t\t\t' }',\n\t\t\t\t'}',\n\t\t\t\t'',\n\t\t\t].join('\\n');\n\t}\n}\n\n/** Both snippets inside the marked block `setup` writes and `uninstall` removes (spec SH-4). */\nexport function profileBlock(\n\tshell: Shell,\n\thome: string,\n\tparts: { path: boolean; hook: boolean },\n): string {\n\tconst body = [\n\t\tparts.path ? pathSnippet(shell, home) : '',\n\t\tparts.hook ? hookSnippet(shell, home) : '',\n\t]\n\t\t.filter((text) => text !== '')\n\t\t.join('');\n\treturn `${BLOCK_START}\\n${body}${BLOCK_END}\\n`;\n}\n","import { createHash } from 'node:crypto';\nimport { lstatSync, readFileSync, readlinkSync } from 'node:fs';\n\nexport type FileType = 'file' | 'directory' | 'symlink' | 'other' | 'missing';\nexport type LineEndings = 'lf' | 'crlf' | 'mixed' | 'none';\n\n/** What a target looked like at one moment (spec MUT-4), enough to tell our write from someone else's. */\nexport interface Meta {\n\ttype: FileType;\n\t/** POSIX permission bits; Windows ACLs are left to the OS and recorded as 0. */\n\tmode: number;\n\tsha256: string | null;\n\tencoding: 'utf8' | 'binary' | null;\n\tlineEndings: LineEndings | null;\n\tsymlinkTarget: string | null;\n}\n\nexport function sha256(content: Buffer | string): string {\n\treturn createHash('sha256').update(content).digest('hex');\n}\n\nfunction isUtf8(content: Buffer): boolean {\n\treturn !content.includes(0) && Buffer.from(content.toString('utf8'), 'utf8').equals(content);\n}\n\nexport function lineEndingsOf(text: string): LineEndings {\n\tconst crlf = (text.match(/\\r\\n/g) ?? []).length;\n\tconst lf = (text.match(/\\n/g) ?? []).length - crlf;\n\tif (crlf === 0 && lf === 0) {\n\t\treturn 'none';\n\t}\n\tif (crlf > 0 && lf > 0) {\n\t\treturn 'mixed';\n\t}\n\treturn crlf > 0 ? 'crlf' : 'lf';\n}\n\nexport const MISSING: Meta = {\n\ttype: 'missing',\n\tmode: 0,\n\tsha256: null,\n\tencoding: null,\n\tlineEndings: null,\n\tsymlinkTarget: null,\n};\n\n/** Captures `path` without following symlinks; a missing path is a valid state, not an error. */\nexport function captureMeta(path: string): Meta {\n\tlet stat;\n\ttry {\n\t\tstat = lstatSync(path);\n\t} catch {\n\t\treturn MISSING;\n\t}\n\tconst mode = process.platform === 'win32' ? 0 : stat.mode & 0o7777;\n\tif (stat.isSymbolicLink()) {\n\t\treturn {\n\t\t\ttype: 'symlink',\n\t\t\tmode,\n\t\t\tsha256: null,\n\t\t\tencoding: null,\n\t\t\tlineEndings: null,\n\t\t\tsymlinkTarget: readlinkSync(path),\n\t\t};\n\t}\n\tif (stat.isDirectory()) {\n\t\treturn {\n\t\t\ttype: 'directory',\n\t\t\tmode,\n\t\t\tsha256: null,\n\t\t\tencoding: null,\n\t\t\tlineEndings: null,\n\t\t\tsymlinkTarget: null,\n\t\t};\n\t}\n\tif (!stat.isFile()) {\n\t\treturn {\n\t\t\ttype: 'other',\n\t\t\tmode,\n\t\t\tsha256: null,\n\t\t\tencoding: null,\n\t\t\tlineEndings: null,\n\t\t\tsymlinkTarget: null,\n\t\t};\n\t}\n\tconst content = readFileSync(path);\n\tconst utf8 = isUtf8(content);\n\treturn {\n\t\ttype: 'file',\n\t\tmode,\n\t\tsha256: sha256(content),\n\t\tencoding: utf8 ? 'utf8' : 'binary',\n\t\tlineEndings: utf8 ? lineEndingsOf(content.toString('utf8')) : null,\n\t\tsymlinkTarget: null,\n\t};\n}\n\n/** Whether the path still holds exactly what `meta` recorded (spec MUT-5): same type, same bytes or link target. */\nexport function metaMatches(path: string, meta: Meta): boolean {\n\tconst now = captureMeta(path);\n\treturn (\n\t\tnow.type === meta.type && now.sha256 === meta.sha256 && now.symlinkTarget === meta.symlinkTarget\n\t);\n}\n","import {\n\tcopyFileSync,\n\texistsSync,\n\tmkdirSync,\n\treaddirSync,\n\treadFileSync,\n\trmSync,\n\tunlinkSync,\n} from 'node:fs';\nimport { join } from 'node:path';\nimport { atomicWrite, removeWithRetry, withSharingRetry } from './atomic.ts';\nimport { newToken, type OwnerRecord } from './lease.ts';\nimport { captureMeta, metaMatches, sha256, type Meta } from './meta.ts';\nimport { isLive } from './proc.ts';\n\nexport type JournalKind = 'launcher' | 'profile' | 'link' | 'home' | 'project';\n\n/** A pending change to one file (spec MUT-2): enough to finish it or undo it after a crash. */\nexport interface Journal {\n\tid: string;\n\tkind: JournalKind;\n\towner: OwnerRecord;\n\ttarget: string;\n\toriginal: Meta;\n\t/** The sha256 the target will have, or null when the change deletes it. */\n\tintended: string | null;\n\t/** Staged copy of the new content, beside the journal. */\n\tstaged: string | null;\n\t/** Backup of the original content, beside the journal; null when there was none. */\n\tbackup: string | null;\n\tmode: number;\n\tcreatedAt: string;\n}\n\nexport interface RecoveryReport {\n\tfinished: string[];\n\treplayed: string[];\n\trolledBack: string[];\n\tchanged: string[];\n\tskipped: string[];\n}\n\nexport function journalPath(journalDir: string, id: string): string {\n\treturn join(journalDir, `${id}.json`);\n}\n\nexport function readJournal(file: string): Journal | null {\n\ttry {\n\t\tconst parsed = JSON.parse(readFileSync(file, 'utf8')) as Journal;\n\t\treturn typeof parsed.id === 'string' && typeof parsed.target === 'string' ? parsed : null;\n\t} catch {\n\t\treturn null;\n\t}\n}\n\nexport function listJournals(journalDir: string): Journal[] {\n\tlet names: string[];\n\ttry {\n\t\tnames = readdirSync(journalDir);\n\t} catch {\n\t\treturn [];\n\t}\n\treturn names\n\t\t.filter((name) => name.endsWith('.json'))\n\t\t.map((name) => readJournal(join(journalDir, name)))\n\t\t.filter((journal): journal is Journal => journal !== null);\n}\n\nexport function hasJournals(journalDir: string): boolean {\n\treturn listJournals(journalDir).length > 0;\n}\n\n/**\n * Applies one file change under a journal: backup and staged copy first, the journal, then the write.\n * The journal and its sidecars disappear only after the target holds the intended bytes.\n */\nexport function mutateFile(\n\tjournalDir: string,\n\tkind: JournalKind,\n\towner: OwnerRecord,\n\ttarget: string,\n\tcontent: Buffer | null,\n\tmode = 0o644,\n): void {\n\tmkdirSync(journalDir, { recursive: true, mode: 0o700 });\n\tconst id = `${kind}-${newToken()}`;\n\tconst original = captureMeta(target);\n\tlet backup: string | null = null;\n\tif (original.type === 'file') {\n\t\tbackup = join(journalDir, `${id}.bak`);\n\t\tcopyFileSync(target, backup);\n\t}\n\tlet staged: string | null = null;\n\tif (content !== null) {\n\t\tstaged = join(journalDir, `${id}.new`);\n\t\tatomicWrite(staged, content, 0o600);\n\t}\n\tconst journal: Journal = {\n\t\tid,\n\t\tkind,\n\t\towner,\n\t\ttarget,\n\t\toriginal,\n\t\tintended: content === null ? null : sha256(content),\n\t\tstaged,\n\t\tbackup,\n\t\tmode,\n\t\tcreatedAt: new Date().toISOString(),\n\t};\n\tatomicWrite(journalPath(journalDir, id), JSON.stringify(journal), 0o600);\n\tapply(journal, content);\n\tdiscard(journalDir, journal);\n}\n\nfunction apply(journal: Journal, content: Buffer | null): void {\n\tif (content === null) {\n\t\twithSharingRetry(() => {\n\t\t\tif (existsSync(journal.target)) {\n\t\t\t\tunlinkSync(journal.target);\n\t\t\t}\n\t\t});\n\t\treturn;\n\t}\n\tatomicWrite(journal.target, content, journal.mode);\n}\n\nfunction discard(journalDir: string, journal: Journal): void {\n\tfor (const sidecar of [journal.backup, journal.staged]) {\n\t\tif (sidecar !== null) {\n\t\t\trmSync(sidecar, { force: true });\n\t\t}\n\t}\n\trmSync(journalPath(journalDir, journal.id), { force: true });\n}\n\nfunction targetSha(target: string): string | null {\n\tconst meta = captureMeta(target);\n\treturn meta.type === 'file' ? meta.sha256 : null;\n}\n\n/**\n * Finishes one journal (spec MUT-2): a target already at the intended bytes is done; one still at the\n * original is replayed from the staged copy; anything else is left alone and reported as changed (MUT-5).\n */\nexport function recoverJournal(journalDir: string, journal: Journal, report: RecoveryReport): void {\n\tconst current = targetSha(journal.target);\n\tconst exists = captureMeta(journal.target).type !== 'missing';\n\tif (journal.intended === null ? !exists : current === journal.intended) {\n\t\tdiscard(journalDir, journal);\n\t\treport.finished.push(journal.id);\n\t\treturn;\n\t}\n\tif (metaMatches(journal.target, journal.original)) {\n\t\tif (journal.intended === null) {\n\t\t\tapply(journal, null);\n\t\t\treport.replayed.push(journal.id);\n\t\t} else if (\n\t\t\tjournal.staged !== null &&\n\t\t\texistsSync(journal.staged) &&\n\t\t\tsha256(readFileSync(journal.staged)) === journal.intended\n\t\t) {\n\t\t\tapply(journal, readFileSync(journal.staged));\n\t\t\treport.replayed.push(journal.id);\n\t\t} else {\n\t\t\t// Nothing to replay from, and the target is untouched: the change simply never happened.\n\t\t\treport.rolledBack.push(journal.id);\n\t\t}\n\t\tdiscard(journalDir, journal);\n\t\treturn;\n\t}\n\t// Writes are atomic renames, so a target matching neither side was changed by someone else: leave it.\n\treport.changed.push(journal.target);\n\tdiscard(journalDir, journal);\n}\n\n/** Recovers every journal whose owner is dead on this machine; foreign and live ones are skipped. */\nexport function recoverDeadJournals(\n\tjournalDir: string,\n\tmachineId: string,\n\tkinds?: readonly JournalKind[],\n): RecoveryReport {\n\tconst report: RecoveryReport = {\n\t\tfinished: [],\n\t\treplayed: [],\n\t\trolledBack: [],\n\t\tchanged: [],\n\t\tskipped: [],\n\t};\n\tfor (const journal of listJournals(journalDir)) {\n\t\tif (kinds !== undefined && !kinds.includes(journal.kind)) {\n\t\t\tcontinue;\n\t\t}\n\t\tif (journal.owner.machineId !== machineId || isLive(journal.owner)) {\n\t\t\treport.skipped.push(journal.id);\n\t\t\tcontinue;\n\t\t}\n\t\trecoverJournal(journalDir, journal, report);\n\t}\n\treturn report;\n}\n\n/** Recovers one journal the operator vouched for, whatever machine owns it (the `recover` command). */\nexport function recoverForeignJournal(\n\tjournalDir: string,\n\tid: string,\n\tconfirmedMachineId: string,\n): RecoveryReport {\n\tconst report: RecoveryReport = {\n\t\tfinished: [],\n\t\treplayed: [],\n\t\trolledBack: [],\n\t\tchanged: [],\n\t\tskipped: [],\n\t};\n\tconst journal = readJournal(journalPath(journalDir, id));\n\tif (journal === null) {\n\t\tthrow new Error(`no journal ${id} in ${journalDir}`);\n\t}\n\tif (journal.owner.machineId !== confirmedMachineId) {\n\t\tthrow new Error(\n\t\t\t`journal ${id} belongs to machine ${journal.owner.machineId}, not ${confirmedMachineId}`,\n\t\t);\n\t}\n\trecoverJournal(journalDir, journal, report);\n\treturn report;\n}\n\nexport function removeJournalDir(journalDir: string): void {\n\tremoveWithRetry(journalDir);\n}\n","import { mkdirSync, readFileSync, rmSync, writeFileSync } from 'node:fs';\nimport { join } from 'node:path';\nimport { EXIT, NpmVmError } from '../errors.ts';\nimport { lockedMessage } from '../messages.ts';\nimport { newToken, type OwnerRecord } from './lease.ts';\nimport { isLive } from './proc.ts';\n\nexport const LOCK_FILE = 'lock';\nconst WAIT_LIMIT_MS = 10_000;\n\n/** What the lock file records: the owner plus a token only the owner knows, so only it can release. */\nexport interface LockRecord extends OwnerRecord {\n\ttoken: string;\n}\n\nexport interface Lock {\n\tpath: string;\n\trelease(): void;\n}\n\nexport function lockPath(stateDir: string): string {\n\treturn join(stateDir, LOCK_FILE);\n}\n\nexport function readLock(stateDir: string): LockRecord | null {\n\ttry {\n\t\tconst parsed = JSON.parse(readFileSync(lockPath(stateDir), 'utf8')) as Partial<LockRecord>;\n\t\tif (typeof parsed.pid !== 'number' || typeof parsed.token !== 'string') {\n\t\t\treturn null;\n\t\t}\n\t\treturn {\n\t\t\tpid: parsed.pid,\n\t\t\tstart: typeof parsed.start === 'string' ? parsed.start : null,\n\t\t\thost: typeof parsed.host === 'string' ? parsed.host : '?',\n\t\t\tmachineId: typeof parsed.machineId === 'string' ? parsed.machineId : '?',\n\t\t\tcreatedAt: typeof parsed.createdAt === 'string' ? parsed.createdAt : '',\n\t\t\ttoken: parsed.token,\n\t\t};\n\t} catch {\n\t\treturn null;\n\t}\n}\n\n/** Whether the lock owner can be shown to be dead: only on this machine, and only by PROC-1. */\nexport function lockOwnerLive(record: LockRecord | null, machineId: string): boolean {\n\tif (record === null) {\n\t\treturn true;\n\t}\n\tif (record.machineId !== machineId) {\n\t\treturn true;\n\t}\n\treturn isLive(record);\n}\n\nfunction tryCreate(path: string, record: LockRecord): boolean {\n\ttry {\n\t\twriteFileSync(path, JSON.stringify(record), { flag: 'wx', mode: 0o600 });\n\t} catch (error) {\n\t\tif ((error as NodeJS.ErrnoException).code === 'EEXIST') {\n\t\t\treturn false;\n\t\t}\n\t\t// A half-written lock would block everyone with no owner to release it.\n\t\trmSync(path, { force: true });\n\t\tthrow error;\n\t}\n\treturn true;\n}\n\nfunction sleep(ms: number): Promise<void> {\n\treturn new Promise((resolve) => setTimeout(resolve, ms));\n}\n\n/**\n * Takes the exclusive lock (spec MUT-1): created with O_EXCL, released only by its owner, never reclaimed.\n * Waits with backoff for up to 10 s, then fails with M-LOCKED naming the file and whether the owner is live.\n */\nexport async function acquireLock(\n\tstateDir: string,\n\towner: OwnerRecord,\n\toptions: { waitMs?: number } = {},\n): Promise<Lock> {\n\tmkdirSync(stateDir, { recursive: true, mode: 0o700 });\n\tconst path = lockPath(stateDir);\n\tconst record: LockRecord = { ...owner, token: newToken() };\n\tconst deadline = Date.now() + (options.waitMs ?? WAIT_LIMIT_MS);\n\tlet delay = 50;\n\tfor (;;) {\n\t\tif (tryCreate(path, record)) {\n\t\t\treturn {\n\t\t\t\tpath,\n\t\t\t\trelease() {\n\t\t\t\t\t// Only the owner removes the lock, and only while the file still carries its token.\n\t\t\t\t\tif (readLock(stateDir)?.token === record.token) {\n\t\t\t\t\t\trmSync(path, { force: true });\n\t\t\t\t\t}\n\t\t\t\t},\n\t\t\t};\n\t\t}\n\t\tif (Date.now() + delay > deadline) {\n\t\t\tconst holder = readLock(stateDir);\n\t\t\tconst foreign = holder !== null && holder.machineId !== owner.machineId;\n\t\t\tconst live = lockOwnerLive(holder, owner.machineId);\n\t\t\tthrow new NpmVmError('M-LOCKED', EXIT.problems, lockedMessage(path, holder, live, foreign));\n\t\t}\n\t\tawait sleep(delay);\n\t\tdelay = Math.min(delay * 2, 1000);\n\t}\n}\n\n/** One attempt, no waiting; for the launcher's recovery check, which must never delay npm. */\nexport function tryLock(stateDir: string, owner: OwnerRecord): Lock | null {\n\tmkdirSync(stateDir, { recursive: true, mode: 0o700 });\n\tconst path = lockPath(stateDir);\n\tconst record: LockRecord = { ...owner, token: newToken() };\n\tif (!tryCreate(path, record)) {\n\t\treturn null;\n\t}\n\treturn {\n\t\tpath,\n\t\trelease() {\n\t\t\tif (readLock(stateDir)?.token === record.token) {\n\t\t\t\trmSync(path, { force: true });\n\t\t\t}\n\t\t},\n\t};\n}\n","import { EXIT, NpmVmError } from '../errors.ts';\nimport { resolveNpmWith } from '../index.ts';\nimport { listEntries } from '../install/cache.ts';\nimport { createContext, createInstaller } from '../install/index.ts';\nimport { readVerified } from '../install/verify.ts';\nimport { listJournals, recoverDeadJournals, recoverForeignJournal } from '../state/journal.ts';\nimport { listLeases, ownerLive } from '../state/lease.ts';\nimport { acquireLock } from '../state/lock.ts';\nimport { isLive } from '../state/proc.ts';\nimport { lastUsed, pruneCache, type PruneReport } from '../state/prune.ts';\nimport type { CommandContext } from './context.ts';\n\nconst DAY_MS = 86_400_000;\nexport const DEFAULT_PRUNE_DAYS = 90;\n\n/** `install [<spec>]`: fetches and verifies the project's npm, or the given spec, into the cache. */\nexport async function install(\n\tcontext: CommandContext,\n\tspec: string | undefined,\n\tcwd: string = process.cwd(),\n): Promise<number> {\n\tconst env = spec === undefined ? context.env : { ...context.env, NPM_VM_VERSION: spec };\n\tconst installer = createInstaller(createContext(env, context.dirs.home));\n\tconst result = await resolveNpmWith([], cwd, { env }, installer);\n\tif (result.selection === null) {\n\t\tcontext.io.out(\n\t\t\tcontext.json\n\t\t\t\t? JSON.stringify(result)\n\t\t\t\t: `Node's own npm ${result.version} satisfies the requirement; nothing to download.`,\n\t\t);\n\t\treturn EXIT.ok;\n\t}\n\tconst ensured = await installer.ensure(result.selection);\n\tensured.lease.release();\n\tcontext.io.out(\n\t\tcontext.json\n\t\t\t? JSON.stringify({ ...result, entryPath: ensured.entryPath })\n\t\t\t: `npm ${result.version} is ready in ${ensured.entryPath}`,\n\t);\n\treturn EXIT.ok;\n}\n\nexport interface CacheEntryView {\n\tversion: string;\n\tintegrity: string;\n\tpath: string;\n\tlastUsed: string | null;\n\tliveLeases: number;\n\tverifiedAt: string;\n}\n\nexport function cacheList(context: CommandContext): number {\n\tconst entries: CacheEntryView[] = listEntries(context.dirs.cache).map((entry) => {\n\t\tconst used = lastUsed(entry.entryPath as string);\n\t\treturn {\n\t\t\tversion: entry.version,\n\t\t\tintegrity: entry.integrity,\n\t\t\tpath: entry.entryPath as string,\n\t\t\tlastUsed: used === null ? null : new Date(used).toISOString(),\n\t\t\tliveLeases: listLeases(entry.entryPath as string).filter((lease) => ownerLive(lease)).length,\n\t\t\tverifiedAt: readVerified(entry.entryPath as string)?.verifiedAt ?? '',\n\t\t};\n\t});\n\tif (context.json) {\n\t\tcontext.io.out(JSON.stringify({ cache: context.dirs.cache, entries }, null, 2));\n\t} else {\n\t\tconst lines = [`${context.dirs.cache}`];\n\t\tfor (const entry of entries) {\n\t\t\tlines.push(\n\t\t\t\t` npm ${entry.version} ${entry.path} last used ${entry.lastUsed ?? 'never'}${entry.liveLeases > 0 ? ` in use by ${entry.liveLeases}` : ''}`,\n\t\t\t);\n\t\t}\n\t\tif (entries.length === 0) {\n\t\t\tlines.push(' (empty)');\n\t\t}\n\t\tcontext.io.out(lines.join('\\n'));\n\t}\n\treturn EXIT.ok;\n}\n\nexport async function cachePrune(\n\tcontext: CommandContext,\n\tolderThanDays: number = DEFAULT_PRUNE_DAYS,\n): Promise<number> {\n\tif (!Number.isFinite(olderThanDays) || olderThanDays < 0) {\n\t\tthrow new NpmVmError(\n\t\t\t'M-NOMATCH',\n\t\t\tEXIT.usage,\n\t\t\t'--older-than needs a non-negative number of days.',\n\t\t);\n\t}\n\tconst lock = await acquireLock(context.dirs.state, context.owner);\n\ttry {\n\t\trecoverDeadJournals(context.dirs.journal, context.dirs.machine.id);\n\t\t// Homes differ, the per-machine cache does not: a lock inside the cache keeps two homes from pruning at once.\n\t\tconst cacheLock = await acquireLock(context.dirs.cache, context.owner);\n\t\tlet report: PruneReport;\n\t\ttry {\n\t\t\treport = pruneCache(context.dirs.cache, context.owner, {\n\t\t\t\tmaxAgeMs: olderThanDays * DAY_MS,\n\t\t\t});\n\t\t} finally {\n\t\t\tcacheLock.release();\n\t\t}\n\t\tcontext.io.out(\n\t\t\tcontext.json\n\t\t\t\t? JSON.stringify(report, null, 2)\n\t\t\t\t: `Removed ${report.removed.length}, kept ${report.kept.length}, skipped ${report.skipped.length} (in use).`,\n\t\t);\n\t} finally {\n\t\tlock.release();\n\t}\n\treturn EXIT.ok;\n}\n\n/** `recover --journal <id> --confirm-dead-machine <machine-id>` (spec PROC-1, CLI). */\nexport async function recover(\n\tcontext: CommandContext,\n\tjournalId: string,\n\tconfirmedMachine: string,\n): Promise<number> {\n\tconst journal = listJournals(context.dirs.journal).find((entry) => entry.id === journalId);\n\tif (journal === undefined) {\n\t\tthrow new NpmVmError(\n\t\t\t'M-NOMATCH',\n\t\t\tEXIT.usage,\n\t\t\t`No journal ${journalId} under ${context.dirs.journal}.`,\n\t\t);\n\t}\n\tif (journal.owner.machineId !== confirmedMachine) {\n\t\tthrow new NpmVmError(\n\t\t\t'M-NOMATCH',\n\t\t\tEXIT.usage,\n\t\t\t`Journal ${journalId} belongs to machine ${journal.owner.machineId}, not ${confirmedMachine}.`,\n\t\t);\n\t}\n\tif (journal.owner.machineId === context.dirs.machine.id && isLive(journal.owner)) {\n\t\tthrow new NpmVmError(\n\t\t\t'M-LOCKED',\n\t\t\tEXIT.problems,\n\t\t\t`Journal ${journalId} belongs to PID ${journal.owner.pid} on this machine, which is still running.`,\n\t\t);\n\t}\n\tconst lock = await acquireLock(context.dirs.state, context.owner);\n\ttry {\n\t\tconst report = recoverForeignJournal(context.dirs.journal, journalId, confirmedMachine);\n\t\tcontext.io.out(\n\t\t\tcontext.json ? JSON.stringify(report) : `Recovered ${journalId}: ${describeReport(report)}`,\n\t\t);\n\t} finally {\n\t\tlock.release();\n\t}\n\treturn EXIT.ok;\n}\n\nfunction describeReport(report: {\n\tfinished: string[];\n\treplayed: string[];\n\trolledBack: string[];\n\tchanged: string[];\n}): string {\n\tif (report.replayed.length > 0) {\n\t\treturn 'replayed';\n\t}\n\tif (report.rolledBack.length > 0) {\n\t\treturn 'rolled back';\n\t}\n\tif (report.changed.length > 0) {\n\t\treturn 'target changed since, left untouched';\n\t}\n\treturn 'already finished';\n}\n","import { createInterface } from 'node:readline/promises';\nimport { resolveDirs, type Dirs } from '../setup/home.ts';\nimport { ownerRecord, type OwnerRecord } from '../state/lease.ts';\n\nexport interface CommandIo {\n\tout(text: string): void;\n\terr(text: string): void;\n\t/** Asks a yes/no question; a non-interactive session answers no. */\n\tconfirm(question: string): Promise<boolean>;\n\tinteractive: boolean;\n}\n\nexport interface CommandContext {\n\tdirs: Dirs;\n\tenv: NodeJS.ProcessEnv;\n\tplatform: NodeJS.Platform;\n\towner: OwnerRecord;\n\tio: CommandIo;\n\tjson: boolean;\n\tversion: string;\n}\n\nexport interface ContextOptions {\n\thome?: string;\n\tenv?: NodeJS.ProcessEnv;\n\tjson?: boolean;\n\tio?: CommandIo;\n\tversion: string;\n}\n\nexport function terminalIo(): CommandIo {\n\tconst interactive = Boolean(process.stdin.isTTY && process.stdout.isTTY);\n\treturn {\n\t\tout: (text) => process.stdout.write(`${text}\\n`),\n\t\terr: (text) => process.stderr.write(`${text}\\n`),\n\t\tinteractive,\n\t\tasync confirm(question) {\n\t\t\tif (!interactive) {\n\t\t\t\treturn false;\n\t\t\t}\n\t\t\tconst rl = createInterface({ input: process.stdin, output: process.stdout });\n\t\t\ttry {\n\t\t\t\tconst answer = await rl.question(`${question} [y/N] `);\n\t\t\t\treturn /^y(es)?$/i.test(answer.trim());\n\t\t\t} finally {\n\t\t\t\trl.close();\n\t\t\t}\n\t\t},\n\t};\n}\n\nexport function createCommandContext(options: ContextOptions): CommandContext {\n\tconst env = options.env ?? process.env;\n\tconst dirs = resolveDirs(env, options.home);\n\treturn {\n\t\tdirs,\n\t\tenv,\n\t\tplatform: process.platform,\n\t\towner: ownerRecord(dirs.machine.id),\n\t\tio: options.io ?? terminalIo(),\n\t\tjson: options.json ?? false,\n\t\tversion: options.version,\n\t};\n}\n","import {\n\tcopyFileSync,\n\texistsSync,\n\tlstatSync,\n\treaddirSync,\n\treadFileSync,\n\treadlinkSync,\n\trealpathSync,\n\trenameSync,\n\trmSync,\n\tsymlinkSync,\n} from 'node:fs';\nimport { homedir } from 'node:os';\nimport { basename, dirname, join } from 'node:path';\nimport { atomicWrite, withSharingRetry } from '../state/atomic.ts';\nimport { mutateFile } from '../state/journal.ts';\nimport type { OwnerRecord } from '../state/lease.ts';\nimport { captureMeta, metaMatches, MISSING, type Meta } from '../state/meta.ts';\nimport type { Dirs } from './home.ts';\nimport { cmdShim, posixShim, powershellShim, type ShimName } from './shims.ts';\n\nexport type NodeManager = 'nvm' | 'fnm' | 'nvm-windows';\n\n/** One Node install whose `npm` and `npx` entry points `--link` replaces (spec LNK-1). */\nexport interface NodeInstall {\n\tmanager: NodeManager;\n\tversion: string;\n\tbinDir: string;\n}\n\nexport const ORIGINAL_SUFFIX = '.npm-vm-original';\nexport const LINKS_FILE = 'links.json';\n\nexport interface LinkRecord {\n\tbinDir: string;\n\t/** The entry point we replaced, e.g. `npm` or `npm.cmd`. */\n\tname: string;\n\ttarget: string;\n\toriginalPath: string | null;\n\toriginal: Meta;\n\tshim: Meta;\n\tlinkedAt: string;\n}\n\nexport interface LinksFile {\n\tversion: 1;\n\tentries: LinkRecord[];\n}\n\nfunction versionsUnder(dir: string): string[] {\n\ttry {\n\t\treturn readdirSync(dir).filter((name) => /^v?\\d+\\.\\d+\\.\\d+$/.test(name));\n\t} catch {\n\t\treturn [];\n\t}\n}\n\nfunction fnmDir(env: NodeJS.ProcessEnv, platform: NodeJS.Platform, home: string): string {\n\tif (env['FNM_DIR']) {\n\t\treturn env['FNM_DIR'];\n\t}\n\tif (platform === 'win32') {\n\t\treturn join(env['APPDATA'] ?? join(home, 'AppData', 'Roaming'), 'fnm');\n\t}\n\tif (platform === 'darwin') {\n\t\treturn join(home, 'Library', 'Application Support', 'fnm');\n\t}\n\treturn join(env['XDG_DATA_HOME'] || join(home, '.local', 'share'), 'fnm');\n}\n\n/** The root nvm-windows keeps its versions in, from its settings.txt (spec LNK-1). */\nfunction nvmWindowsRoot(env: NodeJS.ProcessEnv): string | null {\n\tconst nvmHome = env['NVM_HOME'];\n\tif (!nvmHome) {\n\t\treturn null;\n\t}\n\ttry {\n\t\tconst settings = readFileSync(join(nvmHome, 'settings.txt'), 'utf8');\n\t\tconst root = /^root:\\s*(.+)$/m.exec(settings)?.[1]?.trim();\n\t\treturn root ?? nvmHome;\n\t} catch {\n\t\treturn nvmHome;\n\t}\n}\n\n/** Windows paths resolved through junctions and compared without case, so one install is never linked twice (LNK-4). */\nexport function installKey(binDir: string, platform: NodeJS.Platform): string {\n\tlet real = binDir;\n\ttry {\n\t\treal = realpathSync(binDir);\n\t} catch {\n\t\t// A missing dir is listed as given and skipped as unwritable later.\n\t}\n\treturn platform === 'win32' ? real.toLowerCase() : real;\n}\n\nexport function findNodeInstalls(\n\tenv: NodeJS.ProcessEnv = process.env,\n\tplatform: NodeJS.Platform = process.platform,\n\thome: string = env['HOME'] || homedir(),\n): NodeInstall[] {\n\tconst installs: NodeInstall[] = [];\n\tconst seen = new Set<string>();\n\tconst add = (install: NodeInstall): void => {\n\t\tconst key = installKey(install.binDir, platform);\n\t\tif (!seen.has(key) && existsSync(install.binDir)) {\n\t\t\tseen.add(key);\n\t\t\tinstalls.push(install);\n\t\t}\n\t};\n\tconst nvmDir = env['NVM_DIR'] || join(home, '.nvm');\n\tfor (const version of versionsUnder(join(nvmDir, 'versions', 'node'))) {\n\t\tadd({\n\t\t\tmanager: 'nvm',\n\t\t\tversion: version.replace(/^v/, ''),\n\t\t\tbinDir: join(nvmDir, 'versions', 'node', version, 'bin'),\n\t\t});\n\t}\n\tconst fnm = join(fnmDir(env, platform, home), 'node-versions');\n\tfor (const version of versionsUnder(fnm)) {\n\t\tconst installation = join(fnm, version, 'installation');\n\t\tadd({\n\t\t\tmanager: 'fnm',\n\t\t\tversion: version.replace(/^v/, ''),\n\t\t\tbinDir: platform === 'win32' ? installation : join(installation, 'bin'),\n\t\t});\n\t}\n\tif (platform === 'win32') {\n\t\tconst root = nvmWindowsRoot(env);\n\t\tif (root !== null) {\n\t\t\tfor (const version of versionsUnder(root)) {\n\t\t\t\tadd({\n\t\t\t\t\tmanager: 'nvm-windows',\n\t\t\t\t\tversion: version.replace(/^v/, ''),\n\t\t\t\t\tbinDir: join(root, version),\n\t\t\t\t});\n\t\t\t}\n\t\t}\n\t}\n\treturn installs;\n}\n\n/** A file `--link` touches in one install: a shim to write, or `content: null` for a file to move aside (WIN-2). */\nexport interface LinkTarget {\n\tname: string;\n\tcontent: string | null;\n\tmode: number;\n}\n\n/** The files `--link` replaces in one install; blocked `.ps1` files are moved aside so `.cmd` wins. */\nexport function linkTargets(\n\thome: string,\n\tplatform: NodeJS.Platform,\n\tpowershell: boolean,\n): LinkTarget[] {\n\tconst targets: LinkTarget[] = [];\n\tfor (const name of ['npm', 'npx'] as const satisfies readonly ShimName[]) {\n\t\ttargets.push({ name, content: posixShim(home, name), mode: 0o755 });\n\t\tif (platform === 'win32') {\n\t\t\ttargets.push({ name: `${name}.cmd`, content: cmdShim(home, name), mode: 0o644 });\n\t\t\ttargets.push({\n\t\t\t\tname: `${name}.ps1`,\n\t\t\t\tcontent: powershell ? powershellShim(home, name) : null,\n\t\t\t\tmode: 0o644,\n\t\t\t});\n\t\t}\n\t}\n\treturn targets;\n}\n\nexport type LinkOutcome = 'linked' | 'already' | 'foreign' | 'unwritable' | 'missing';\n\nexport interface LinkResult {\n\ttarget: string;\n\toutcome: LinkOutcome;\n\tdetail?: string;\n}\n\n/** Keeps a copy of the original beside the target; a symlink is copied as a symlink. */\nfunction preserveOriginal(path: string, originalPath: string, meta: Meta): void {\n\tif (meta.type === 'symlink') {\n\t\tsymlinkSync(readlinkSync(path), originalPath);\n\t} else {\n\t\tcopyFileSync(path, originalPath);\n\t}\n}\n\n/** Puts the preserved original back in place of whatever is (or is not) at the target. */\nfunction restoreOriginal(dirs: Dirs, owner: OwnerRecord, entry: LinkRecord): void {\n\tconst originalPath = entry.originalPath as string;\n\tif (entry.original.type === 'symlink') {\n\t\tmutateFile(dirs.journal, 'link', owner, entry.target, null);\n\t\twithSharingRetry(() => renameSync(originalPath, entry.target));\n\t\treturn;\n\t}\n\tmutateFile(\n\t\tdirs.journal,\n\t\t'link',\n\t\towner,\n\t\tentry.target,\n\t\treadFileSync(originalPath),\n\t\tentry.original.mode || 0o755,\n\t);\n\trmSync(originalPath, { force: true });\n}\n\n/**\n * Replaces one entry point with a shim (spec LNK-2, LNK-3). The original is copied beside the target and\n * recorded before the journaled write, so a crash at any step leaves either a restorable original or the shim.\n * A file matching neither our shim nor the recorded original is reported and left alone.\n */\nexport function linkOne(\n\tdirs: Dirs,\n\towner: OwnerRecord,\n\tbinDir: string,\n\ttarget: LinkTarget,\n): LinkResult {\n\tconst path = join(binDir, target.name);\n\tconst originalPath = `${path}${ORIGINAL_SUFFIX}`;\n\tconst known = readLinks(dirs).entries.find((entry) => entry.target === path);\n\tlet current = captureMeta(path);\n\tif (\n\t\tcurrent.type === 'missing' &&\n\t\tknown !== undefined &&\n\t\tknown.shim.type !== 'missing' &&\n\t\tknown.originalPath !== null &&\n\t\texistsSync(known.originalPath)\n\t) {\n\t\t// A crash between moving the original aside and writing the shim: put the original back first.\n\t\trestoreOriginal(dirs, owner, known);\n\t\tforget(dirs, known);\n\t\tcurrent = captureMeta(path);\n\t}\n\tif (target.content === null) {\n\t\treturn moveAside(dirs, owner, binDir, target.name, known);\n\t}\n\tif (\n\t\tcurrent.type === 'missing' &&\n\t\tknown !== undefined &&\n\t\tknown.shim.type === 'missing' &&\n\t\tknown.originalPath !== null &&\n\t\tmetaMatches(known.originalPath, known.original)\n\t) {\n\t\t// Moved aside under a restrictive policy that is permissive again: the shim goes in, the original stays aside.\n\t\tmutateFile(dirs.journal, 'link', owner, path, Buffer.from(target.content, 'utf8'), target.mode);\n\t\trecord(dirs, { ...known, shim: captureMeta(path), linkedAt: new Date().toISOString() });\n\t\treturn { target: path, outcome: 'linked' };\n\t}\n\tif (current.type === 'missing') {\n\t\treturn { target: path, outcome: 'missing' };\n\t}\n\tif (current.type === 'file' && readFileSync(path, 'utf8') === target.content) {\n\t\tif (known === undefined) {\n\t\t\trecord(dirs, {\n\t\t\t\tbinDir,\n\t\t\t\tname: target.name,\n\t\t\t\ttarget: path,\n\t\t\t\toriginalPath: existsSync(originalPath) ? originalPath : null,\n\t\t\t\toriginal: captureMeta(originalPath),\n\t\t\t\tshim: current,\n\t\t\t\tlinkedAt: new Date().toISOString(),\n\t\t\t});\n\t\t} else if (known.shim.type === 'missing') {\n\t\t\t// A crash between writing the shim and recording it: the file is ours, the record catches up.\n\t\t\trecord(dirs, { ...known, shim: current, linkedAt: new Date().toISOString() });\n\t\t}\n\t\treturn { target: path, outcome: 'already' };\n\t}\n\tif (known !== undefined && metaMatches(path, known.shim)) {\n\t\t// Still our shim, only the template changed: rewrite it in place and keep the original where it is.\n\t\tmutateFile(dirs.journal, 'link', owner, path, Buffer.from(target.content, 'utf8'), target.mode);\n\t\trecord(dirs, { ...known, shim: captureMeta(path), linkedAt: new Date().toISOString() });\n\t\treturn { target: path, outcome: 'linked' };\n\t}\n\tif (known !== undefined && !metaMatches(path, known.original)) {\n\t\treturn { target: path, outcome: 'foreign', detail: 'changed since npm-vm linked it' };\n\t}\n\tif (existsSync(originalPath) && !metaMatches(originalPath, current)) {\n\t\treturn { target: path, outcome: 'foreign', detail: `${originalPath} already exists` };\n\t}\n\ttry {\n\t\tif (!existsSync(originalPath)) {\n\t\t\tpreserveOriginal(path, originalPath, current);\n\t\t}\n\t} catch (error) {\n\t\treturn { target: path, outcome: 'unwritable', detail: (error as Error).message };\n\t}\n\tconst entry: LinkRecord = {\n\t\tbinDir,\n\t\tname: target.name,\n\t\ttarget: path,\n\t\toriginalPath,\n\t\toriginal: current,\n\t\tshim: MISSING,\n\t\tlinkedAt: new Date().toISOString(),\n\t};\n\trecord(dirs, entry);\n\ttry {\n\t\tmutateFile(dirs.journal, 'link', owner, path, Buffer.from(target.content, 'utf8'), target.mode);\n\t} catch (error) {\n\t\treturn { target: path, outcome: 'unwritable', detail: (error as Error).message };\n\t}\n\trecord(dirs, { ...entry, shim: captureMeta(path) });\n\treturn { target: path, outcome: 'linked' };\n}\n\n/** Moves a file aside without a replacement, for Node's `.ps1` entry points when scripts are blocked. */\nfunction moveAside(\n\tdirs: Dirs,\n\towner: OwnerRecord,\n\tbinDir: string,\n\tname: string,\n\tknown: LinkRecord | undefined,\n): LinkResult {\n\tconst path = join(binDir, name);\n\tconst originalPath = `${path}${ORIGINAL_SUFFIX}`;\n\tconst current = captureMeta(path);\n\tif (known !== undefined && known.shim.type !== 'missing' && metaMatches(path, known.shim)) {\n\t\t// The policy turned restrictive after a link: drop our shim and keep the preserved original aside.\n\t\tmutateFile(dirs.journal, 'link', owner, path, null);\n\t\trecord(dirs, { ...known, shim: MISSING, linkedAt: new Date().toISOString() });\n\t\treturn { target: path, outcome: 'linked' };\n\t}\n\tif (current.type === 'missing') {\n\t\tif (known === undefined && existsSync(originalPath)) {\n\t\t\t// A crash after the rename and before the record: adopt the aside copy so unlink can restore it.\n\t\t\trecord(dirs, {\n\t\t\t\tbinDir,\n\t\t\t\tname,\n\t\t\t\ttarget: path,\n\t\t\t\toriginalPath,\n\t\t\t\toriginal: captureMeta(originalPath),\n\t\t\t\tshim: MISSING,\n\t\t\t\tlinkedAt: new Date().toISOString(),\n\t\t\t});\n\t\t\treturn { target: path, outcome: 'already' };\n\t\t}\n\t\treturn {\n\t\t\ttarget: path,\n\t\t\toutcome: known !== undefined && existsSync(originalPath) ? 'already' : 'missing',\n\t\t};\n\t}\n\tif (known !== undefined && !metaMatches(path, known.original)) {\n\t\treturn { target: path, outcome: 'foreign', detail: 'changed since npm-vm linked it' };\n\t}\n\tif (existsSync(originalPath) && !metaMatches(originalPath, current)) {\n\t\treturn { target: path, outcome: 'foreign', detail: `${originalPath} already exists` };\n\t}\n\ttry {\n\t\twithSharingRetry(() => renameSync(path, originalPath));\n\t} catch (error) {\n\t\treturn { target: path, outcome: 'unwritable', detail: (error as Error).message };\n\t}\n\trecord(dirs, {\n\t\tbinDir,\n\t\tname,\n\t\ttarget: path,\n\t\toriginalPath,\n\t\toriginal: current,\n\t\tshim: MISSING,\n\t\tlinkedAt: new Date().toISOString(),\n\t});\n\tvoid owner;\n\treturn { target: path, outcome: 'linked' };\n}\n\nexport type UnlinkOutcome = 'restored' | 'changed' | 'missing';\n\n/** Puts the original back only when the shim is still ours (spec MUT-5); a replaced file is left as is. */\nexport function unlinkOne(dirs: Dirs, owner: OwnerRecord, entry: LinkRecord): UnlinkOutcome {\n\tconst current = captureMeta(entry.target);\n\tconst hasOriginal = entry.originalPath !== null && existsSync(entry.originalPath);\n\tif (current.type === 'missing') {\n\t\tif (hasOriginal && metaMatches(entry.originalPath as string, entry.original)) {\n\t\t\trestoreOriginal(dirs, owner, entry);\n\t\t\tforget(dirs, entry);\n\t\t\treturn 'restored';\n\t\t}\n\t\tif (hasOriginal) {\n\t\t\treturn 'changed';\n\t\t}\n\t\tforget(dirs, entry);\n\t\treturn 'missing';\n\t}\n\tif (entry.shim.type === 'missing') {\n\t\t// The file was only moved aside; something else put a file back, which is not ours to replace.\n\t\treturn 'changed';\n\t}\n\tif (!metaMatches(entry.target, entry.shim)) {\n\t\treturn 'changed';\n\t}\n\tif (hasOriginal) {\n\t\trestoreOriginal(dirs, owner, entry);\n\t} else {\n\t\tmutateFile(dirs.journal, 'link', owner, entry.target, null);\n\t}\n\tforget(dirs, entry);\n\treturn 'restored';\n}\n\nfunction record(dirs: Dirs, entry: LinkRecord): void {\n\tconst links = readLinks(dirs);\n\tlinks.entries = [...links.entries.filter((item) => item.target !== entry.target), entry];\n\twriteLinks(dirs, links);\n}\n\nfunction forget(dirs: Dirs, entry: LinkRecord): void {\n\tconst links = readLinks(dirs);\n\tlinks.entries = links.entries.filter((item) => item.target !== entry.target);\n\twriteLinks(dirs, links);\n}\n\nexport function readLinks(dirs: Dirs): LinksFile {\n\ttry {\n\t\tconst parsed = JSON.parse(readFileSync(join(dirs.state, LINKS_FILE), 'utf8')) as LinksFile;\n\t\treturn Array.isArray(parsed.entries) ? parsed : { version: 1, entries: [] };\n\t} catch {\n\t\treturn { version: 1, entries: [] };\n\t}\n}\n\nexport function writeLinks(dirs: Dirs, links: LinksFile): void {\n\tatomicWrite(join(dirs.state, LINKS_FILE), JSON.stringify(links, null, '\\t'), 0o600);\n}\n\n/** Whether a recorded link still holds our shim, for `doctor` (spec CLI). */\nexport function linkState(entry: LinkRecord): 'intact' | 'changed' | 'missing' {\n\tconst type = captureMeta(entry.target).type;\n\tif (entry.shim.type === 'missing') {\n\t\t// Moved aside on purpose (WIN-2): intact while nothing took its place and the preserved copy is still there.\n\t\tconst preserved =\n\t\t\tentry.originalPath !== null && metaMatches(entry.originalPath, entry.original);\n\t\treturn type === 'missing' ? (preserved ? 'intact' : 'missing') : 'changed';\n\t}\n\tif (type === 'missing') {\n\t\treturn 'missing';\n\t}\n\treturn metaMatches(entry.target, entry.shim) ? 'intact' : 'changed';\n}\n\nexport function describeInstall(install: NodeInstall): string {\n\treturn `${install.manager} ${install.version} (${install.binDir})`;\n}\n\nexport function isSymlinkTo(path: string, suffix: string): boolean {\n\ttry {\n\t\treturn lstatSync(path).isSymbolicLink() && basename(dirname(path)) === suffix;\n\t} catch {\n\t\treturn false;\n\t}\n}\n","import {\n\tcopyFileSync,\n\texistsSync,\n\tmkdirSync,\n\treaddirSync,\n\treadFileSync,\n\trmSync,\n\tstatSync,\n\twriteFileSync,\n} from 'node:fs';\nimport { join } from 'node:path';\nimport { atomicRename, removeWithRetry } from '../state/atomic.ts';\n\nexport const BOOTSTRAP_FILE = 'bootstrap.cjs';\nexport const RUNTIME_FILE = 'runtime.cjs';\nexport const CURRENT_FILE = 'current';\nexport const PREVIOUS_FILE = 'previous';\nexport const MANIFEST_FILE = 'manifest.json';\nexport const VERSIONS_DIR = 'versions';\n\nexport interface VersionManifest {\n\tversion: string;\n\tabi: number;\n\tfiles: string[];\n}\n\n/**\n * Where this code's runtime build lives: beside an installed `runtime.cjs`, under `dist/runtime/` for the\n * bin, or `../../dist/runtime/` when running from source. Null when nothing has been built.\n */\nexport function runtimeDistDir(): string | null {\n\tconst here = import.meta.dirname;\n\tconst candidates = [\n\t\there,\n\t\tjoin(here, 'runtime'),\n\t\tjoin(here, '..', 'dist', 'runtime'),\n\t\tjoin(here, '..', '..', 'dist', 'runtime'),\n\t];\n\tfor (const candidate of candidates) {\n\t\tif (existsSync(join(candidate, RUNTIME_FILE)) && existsSync(join(candidate, BOOTSTRAP_FILE))) {\n\t\t\treturn candidate;\n\t\t}\n\t}\n\treturn null;\n}\n\nexport function versionDir(home: string, version: string): string {\n\treturn join(home, VERSIONS_DIR, version);\n}\n\nfunction copyTree(from: string, to: string, files: string[], prefix = ''): void {\n\tmkdirSync(to, { recursive: true, mode: 0o755 });\n\tfor (const name of readdirSync(from)) {\n\t\tconst source = join(from, name);\n\t\tconst target = join(to, name);\n\t\tif (statSync(source).isDirectory()) {\n\t\t\tcopyTree(source, target, files, `${prefix}${name}/`);\n\t\t} else {\n\t\t\tcopyFileSync(source, target);\n\t\t\tfiles.push(`${prefix}${name}`);\n\t\t}\n\t}\n}\n\n/**\n * Installs one runtime version under `versions/<version>/` atomically (spec SET-1): copied into a\n * temp dir beside it and renamed into place, so a crash never leaves a half-written version.\n */\nexport function installVersion(\n\thome: string,\n\tversion: string,\n\tdistDir: string,\n\tabi: number,\n): string {\n\tconst versions = join(home, VERSIONS_DIR);\n\tmkdirSync(versions, { recursive: true, mode: 0o755 });\n\tconst target = versionDir(home, version);\n\tconst staging = join(versions, `.${version}.${process.pid}.${Date.now()}`);\n\trmSync(staging, { recursive: true, force: true });\n\tconst files: string[] = [];\n\tcopyTree(distDir, staging, files);\n\tconst manifest: VersionManifest = { version, abi, files: files.toSorted() };\n\twriteFileSync(join(staging, MANIFEST_FILE), JSON.stringify(manifest, null, '\\t'));\n\t// The old copy moves aside and the new one moves in: two renames, no window where the version is deleted.\n\tconst replaced = join(versions, `.${version}.replaced.${process.pid}.${Date.now()}`);\n\tif (existsSync(target)) {\n\t\tatomicRename(target, replaced);\n\t}\n\ttry {\n\t\tatomicRename(staging, target);\n\t} catch (error) {\n\t\tif (existsSync(replaced)) {\n\t\t\tatomicRename(replaced, target);\n\t\t}\n\t\tthrow error;\n\t}\n\tremoveWithRetry(replaced);\n\treturn target;\n}\n\n/** Points `current` at an installed version; the write is atomic so a launcher never reads a partial file. */\nexport function setCurrent(home: string, version: string): void {\n\tconst temp = join(home, `.current.${process.pid}.${Date.now()}`);\n\twriteFileSync(temp, `${version}\\n`);\n\tatomicRename(temp, join(home, CURRENT_FILE));\n}\n\nexport function readCurrent(home: string): string | null {\n\ttry {\n\t\treturn readFileSync(join(home, CURRENT_FILE), 'utf8').trim();\n\t} catch {\n\t\treturn null;\n\t}\n}\n\nexport function readPrevious(home: string): string | null {\n\ttry {\n\t\treturn readFileSync(join(home, PREVIOUS_FILE), 'utf8').trim();\n\t} catch {\n\t\treturn null;\n\t}\n}\n\n/** Copies the launcher entry of an installed version to the home root, where the shims point. */\nexport function installBootstrap(home: string, version: string): void {\n\tconst source = join(versionDir(home, version), BOOTSTRAP_FILE);\n\tconst temp = join(home, `.${BOOTSTRAP_FILE}.${process.pid}.${Date.now()}`);\n\tcopyFileSync(source, temp);\n\tatomicRename(temp, join(home, BOOTSTRAP_FILE));\n}\n\nexport function readManifest(home: string, version: string): VersionManifest | null {\n\ttry {\n\t\treturn JSON.parse(\n\t\t\treadFileSync(join(versionDir(home, version), MANIFEST_FILE), 'utf8'),\n\t\t) as VersionManifest;\n\t} catch {\n\t\treturn null;\n\t}\n}\n\n/** Removes copies a crashed reinstall moved aside; the launcher only reads them while `versions/<v>` is missing. */\nexport function sweepReplaced(home: string): void {\n\tlet names: string[];\n\ttry {\n\t\tnames = readdirSync(join(home, VERSIONS_DIR));\n\t} catch {\n\t\treturn;\n\t}\n\tfor (const name of names) {\n\t\tconst match = /^\\.(.+)\\.replaced\\./.exec(name);\n\t\tif (match !== null && existsSync(join(home, VERSIONS_DIR, match[1] as string, RUNTIME_FILE))) {\n\t\t\tremoveWithRetry(join(home, VERSIONS_DIR, name));\n\t\t}\n\t}\n}\n\nexport function installedVersions(home: string): string[] {\n\ttry {\n\t\treturn readdirSync(join(home, VERSIONS_DIR)).filter((name) => /^\\d+\\.\\d+\\.\\d+/.test(name));\n\t} catch {\n\t\treturn [];\n\t}\n}\n\n/** The ABI an installed runtime declares, read from its manifest. */\nexport function runtimeAbi(home: string, version: string): number | null {\n\treturn readManifest(home, version)?.abi ?? null;\n}\n","import { execFileSync } from 'node:child_process';\nimport { accessSync, constants, existsSync, lstatSync, readFileSync, realpathSync } from 'node:fs';\nimport { homedir } from 'node:os';\nimport { basename, dirname, join } from 'node:path';\nimport { atomicWrite } from '../state/atomic.ts';\nimport { mutateFile } from '../state/journal.ts';\nimport type { OwnerRecord } from '../state/lease.ts';\nimport { captureMeta, sha256 } from '../state/meta.ts';\nimport { powershellPath, shellBinary } from '../state/proc.ts';\nimport type { Dirs } from './home.ts';\nimport { BLOCK_END, BLOCK_START, profileBlock, type Shell } from './shell.ts';\n\nexport interface ProfileParts {\n\tpath: boolean;\n\thook: boolean;\n}\n\n/** One file `setup` would edit for one shell (spec SH-3). */\nexport interface ProfileTarget {\n\tshell: Shell;\n\tfile: string;\n\tparts: ProfileParts;\n}\n\nexport interface ProfileRecord {\n\tfile: string;\n\tshell: Shell;\n\tparts: ProfileParts;\n\t/** sha256 of the whole file as written, so `uninstall` can tell a later edit (spec MUT-5). */\n\twrittenSha256: string;\n\tbackup: string | null;\n\tupdatedAt: string;\n}\n\nexport interface ProfilesFile {\n\tversion: 1;\n\tentries: ProfileRecord[];\n}\n\nexport const PROFILES_FILE = 'profiles.json';\n\nconst BLOCK_RE = /^# >>> npm-vm >>>\\n[\\s\\S]*?^# <<< npm-vm <<<\\n?/m;\n\nfunction bashLoginFile(home: string): string {\n\tfor (const name of ['.bash_profile', '.bash_login', '.profile']) {\n\t\tif (existsSync(join(home, name))) {\n\t\t\treturn join(home, name);\n\t\t}\n\t}\n\treturn join(home, '.bash_profile');\n}\n\n/** The user profile of one PowerShell host, asked with `-NoProfile` so nothing of the user's runs (spec SEC-8). */\nexport function powershellProfile(\n\thost: 'powershell' | 'pwsh',\n\tenv: NodeJS.ProcessEnv,\n\tplatform: NodeJS.Platform = process.platform,\n): string | null {\n\tconst bin =\n\t\thost === 'powershell' ? powershellPath(env) : shellBinary('powershell', env, platform);\n\tif (bin === null) {\n\t\treturn null;\n\t}\n\ttry {\n\t\tconst out = execFileSync(\n\t\t\tbin,\n\t\t\t['-NoProfile', '-NonInteractive', '-Command', '$PROFILE.CurrentUserAllHosts'],\n\t\t\t{\n\t\t\t\tencoding: 'utf8',\n\t\t\t\tenv,\n\t\t\t\twindowsHide: true,\n\t\t\t\tstdio: ['ignore', 'pipe', 'ignore'],\n\t\t\t},\n\t\t).trim();\n\t\treturn out === '' ? null : out;\n\t} catch {\n\t\treturn null;\n\t}\n}\n\n/** The files to edit for `shells` (spec SH-3); PowerShell hosts that are not installed yield nothing. */\nexport function profileTargets(\n\tshells: readonly Shell[],\n\tenv: NodeJS.ProcessEnv = process.env,\n\tplatform: NodeJS.Platform = process.platform,\n\thome: string = env['HOME'] || homedir(),\n): ProfileTarget[] {\n\tconst targets: ProfileTarget[] = [];\n\tfor (const shell of shells) {\n\t\tswitch (shell) {\n\t\t\tcase 'zsh': {\n\t\t\t\tconst zdot = env['ZDOTDIR'] || home;\n\t\t\t\ttargets.push({ shell, file: join(zdot, '.zshenv'), parts: { path: true, hook: false } });\n\t\t\t\ttargets.push({ shell, file: join(zdot, '.zshrc'), parts: { path: false, hook: true } });\n\t\t\t\tbreak;\n\t\t\t}\n\t\t\tcase 'bash': {\n\t\t\t\ttargets.push({ shell, file: join(home, '.bashrc'), parts: { path: true, hook: true } });\n\t\t\t\tconst login = bashLoginFile(home);\n\t\t\t\tif (login !== join(home, '.bashrc')) {\n\t\t\t\t\ttargets.push({ shell, file: login, parts: { path: true, hook: false } });\n\t\t\t\t}\n\t\t\t\tbreak;\n\t\t\t}\n\t\t\tcase 'fish': {\n\t\t\t\tconst config = env['XDG_CONFIG_HOME'] || join(home, '.config');\n\t\t\t\ttargets.push({\n\t\t\t\t\tshell,\n\t\t\t\t\tfile: join(config, 'fish', 'conf.d', 'npm-vm.fish'),\n\t\t\t\t\tparts: { path: true, hook: true },\n\t\t\t\t});\n\t\t\t\tbreak;\n\t\t\t}\n\t\t\tcase 'powershell': {\n\t\t\t\tconst hosts: Array<'powershell' | 'pwsh'> =\n\t\t\t\t\tplatform === 'win32' ? ['powershell', 'pwsh'] : ['pwsh'];\n\t\t\t\tfor (const host of hosts) {\n\t\t\t\t\tconst file = powershellProfile(host, env, platform);\n\t\t\t\t\tif (file !== null && !targets.some((target) => target.file === file)) {\n\t\t\t\t\t\ttargets.push({ shell, file, parts: { path: true, hook: true } });\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t\tbreak;\n\t\t\t}\n\t\t}\n\t}\n\treturn targets;\n}\n\n/** Why a profile is printed instead of edited (spec SH-5), or null when editing it is fine. */\nexport function profileGuard(\n\tfile: string,\n\tenv: NodeJS.ProcessEnv = process.env,\n\tplatform: NodeJS.Platform = process.platform,\n): string | null {\n\tlet stat;\n\ttry {\n\t\tstat = lstatSync(file);\n\t} catch {\n\t\tstat = null;\n\t}\n\tif (stat !== null && stat.isSymbolicLink()) {\n\t\treturn 'it is a symlink, so a dotfile manager probably owns it';\n\t}\n\tlet probe = stat === null ? dirname(file) : file;\n\twhile (!existsSync(probe) && dirname(probe) !== probe) {\n\t\tprobe = dirname(probe);\n\t}\n\ttry {\n\t\taccessSync(probe, constants.W_OK);\n\t} catch {\n\t\treturn 'it is not writable';\n\t}\n\ttry {\n\t\tif (realpathSync(probe).startsWith('/nix/store')) {\n\t\t\treturn 'it lives in the Nix store (home-manager)';\n\t\t}\n\t} catch {\n\t\t// An unresolvable path is handled by the write itself.\n\t}\n\tconst chezmoi = join(env['HOME'] || homedir(), '.local', 'share', 'chezmoi');\n\tif (existsSync(join(chezmoi, `dot_${basename(file).replace(/^\\./, '')}`))) {\n\t\treturn 'chezmoi manages it';\n\t}\n\tif (platform === 'win32' && stat !== null && file.endsWith('.ps1')) {\n\t\tconst content = readFileSync(file, 'utf8');\n\t\tif (content.includes('# SIG # Begin signature block') && executionPolicy(env) === 'AllSigned') {\n\t\t\treturn 'it is signed and the execution policy is AllSigned';\n\t\t}\n\t}\n\treturn null;\n}\n\n/** The effective PowerShell execution policy, asked without a profile (spec WIN-2). */\nexport function executionPolicy(env: NodeJS.ProcessEnv = process.env): string | null {\n\ttry {\n\t\treturn execFileSync(\n\t\t\tpowershellPath(env),\n\t\t\t['-NoProfile', '-NonInteractive', '-Command', 'Get-ExecutionPolicy'],\n\t\t\t{\n\t\t\t\tencoding: 'utf8',\n\t\t\t\twindowsHide: true,\n\t\t\t\tstdio: ['ignore', 'pipe', 'ignore'],\n\t\t\t},\n\t\t).trim();\n\t} catch {\n\t\treturn null;\n\t}\n}\n\nexport interface ProfileEdit {\n\ttarget: ProfileTarget;\n\tbefore: string | null;\n\tafter: string;\n\t/** A diff of the block the edit adds or replaces, for the consent prompt. */\n\tdiff: string;\n}\n\n/** The content with our block replaced or appended; a trailing newline is guaranteed before the block. */\nexport function withBlock(content: string | null, block: string): string {\n\tconst text = content ?? '';\n\tif (BLOCK_RE.test(text)) {\n\t\treturn text.replace(BLOCK_RE, block);\n\t}\n\tconst separator = text === '' || text.endsWith('\\n') ? '' : '\\n';\n\treturn `${text}${separator}${text === '' ? '' : '\\n'}${block}`;\n}\n\n/** The content without our block and the blank line that separated it; nothing else moves. */\nexport function withoutBlock(content: string): string {\n\tconst match = BLOCK_RE.exec(content);\n\tif (match === null) {\n\t\treturn content;\n\t}\n\tlet before = content.slice(0, match.index).replace(/\\n+$/, '\\n');\n\tif (before === '\\n') {\n\t\tbefore = '';\n\t}\n\tconst after = content.slice(match.index + match[0].length);\n\treturn before !== '' && after !== '' ? `${before}\\n${after}` : `${before}${after}`;\n}\n\nexport function currentBlock(content: string): string | null {\n\tconst match = BLOCK_RE.exec(content);\n\treturn match === null ? null : match[0];\n}\n\nfunction renderDiff(file: string, before: string | null, after: string): string {\n\tconst oldBlock = before === null ? null : currentBlock(before);\n\tconst newBlock = currentBlock(after) ?? '';\n\tconst lines = [`--- ${file}`, `+++ ${file}`];\n\tif (oldBlock !== null) {\n\t\tlines.push(\n\t\t\t...oldBlock\n\t\t\t\t.trimEnd()\n\t\t\t\t.split('\\n')\n\t\t\t\t.map((line) => `-${line}`),\n\t\t);\n\t}\n\tlines.push(\n\t\t...newBlock\n\t\t\t.trimEnd()\n\t\t\t.split('\\n')\n\t\t\t.map((line) => `+${line}`),\n\t);\n\treturn `${lines.join('\\n')}\\n`;\n}\n\n/** What `setup` would write for `target`, or null when the file already holds exactly this block. */\nexport function planProfileEdit(target: ProfileTarget, home: string): ProfileEdit | null {\n\tconst before = existsSync(target.file) ? readFileSync(target.file, 'utf8') : null;\n\tconst block = profileBlock(target.shell, home, target.parts);\n\tconst after = withBlock(before, block);\n\tif (before === after) {\n\t\treturn null;\n\t}\n\treturn { target, before, after, diff: renderDiff(target.file, before, after) };\n}\n\nfunction uniqueBackup(file: string): string {\n\tconst stamp = new Date().toISOString().replace(/[:.]/g, '-');\n\tlet candidate = `${file}.npm-vm-backup-${stamp}`;\n\tlet counter = 1;\n\twhile (existsSync(candidate)) {\n\t\tcandidate = `${file}.npm-vm-backup-${stamp}-${counter}`;\n\t\tcounter += 1;\n\t}\n\treturn candidate;\n}\n\n/** Applies one consented edit under a journal and a unique backup, and records it (spec SH-4). */\nexport function applyProfileEdit(dirs: Dirs, owner: OwnerRecord, edit: ProfileEdit): ProfileRecord {\n\tlet backup: string | null = null;\n\tif (edit.before !== null) {\n\t\tbackup = uniqueBackup(edit.target.file);\n\t\tatomicWrite(backup, edit.before, 0o600);\n\t}\n\tconst mode = edit.before === null ? 0o644 : captureMeta(edit.target.file).mode || 0o644;\n\tmutateFile(\n\t\tdirs.journal,\n\t\t'profile',\n\t\towner,\n\t\tedit.target.file,\n\t\tBuffer.from(edit.after, 'utf8'),\n\t\tmode,\n\t);\n\tconst record: ProfileRecord = {\n\t\tfile: edit.target.file,\n\t\tshell: edit.target.shell,\n\t\tparts: edit.target.parts,\n\t\twrittenSha256: sha256(edit.after),\n\t\tbackup,\n\t\tupdatedAt: new Date().toISOString(),\n\t};\n\tconst profiles = readProfiles(dirs);\n\tprofiles.entries = [...profiles.entries.filter((entry) => entry.file !== record.file), record];\n\twriteProfiles(dirs, profiles);\n\treturn record;\n}\n\nexport type RemoveOutcome = 'removed' | 'changed' | 'missing';\n\n/** Removes our block only when the file is still what we wrote (spec MUT-5); otherwise it is left alone. */\nexport function removeProfileBlock(\n\tdirs: Dirs,\n\towner: OwnerRecord,\n\trecord: ProfileRecord,\n): RemoveOutcome {\n\tif (!existsSync(record.file)) {\n\t\tforget(dirs, record);\n\t\treturn 'missing';\n\t}\n\tconst content = readFileSync(record.file, 'utf8');\n\tif (sha256(content) !== record.writtenSha256) {\n\t\treturn 'changed';\n\t}\n\tconst after = withoutBlock(content);\n\tmutateFile(\n\t\tdirs.journal,\n\t\t'profile',\n\t\towner,\n\t\trecord.file,\n\t\tafter.trim() === '' ? null : Buffer.from(after, 'utf8'),\n\t\tcaptureMeta(record.file).mode || 0o644,\n\t);\n\tforget(dirs, record);\n\treturn 'removed';\n}\n\nfunction forget(dirs: Dirs, record: ProfileRecord): void {\n\tconst profiles = readProfiles(dirs);\n\tprofiles.entries = profiles.entries.filter((entry) => entry.file !== record.file);\n\twriteProfiles(dirs, profiles);\n}\n\nexport function readProfiles(dirs: Dirs): ProfilesFile {\n\ttry {\n\t\tconst parsed = JSON.parse(\n\t\t\treadFileSync(join(dirs.state, PROFILES_FILE), 'utf8'),\n\t\t) as ProfilesFile;\n\t\treturn Array.isArray(parsed.entries) ? parsed : { version: 1, entries: [] };\n\t} catch {\n\t\treturn { version: 1, entries: [] };\n\t}\n}\n\nexport function writeProfiles(dirs: Dirs, profiles: ProfilesFile): void {\n\tatomicWrite(join(dirs.state, PROFILES_FILE), JSON.stringify(profiles, null, '\\t'), 0o600);\n}\n\nexport { BLOCK_END, BLOCK_START };\n","import { execFileSync } from 'node:child_process';\nimport { join } from 'node:path';\nimport { powershellPath } from '../state/proc.ts';\n\n/*\n * Windows integration (spec WIN-1 to WIN-3). Every helper runs by absolute path with no profile (SEC-8).\n * `[Environment]::SetEnvironmentVariable(..., 'User')` writes HKCU\\Environment and broadcasts WM_SETTINGCHANGE, so no setx.\n */\n\nfunction powershell(env: NodeJS.ProcessEnv, command: string): string {\n\treturn execFileSync(powershellPath(env), ['-NoProfile', '-NonInteractive', '-Command', command], {\n\t\tencoding: 'utf8',\n\t\tenv,\n\t\twindowsHide: true,\n\t\tstdio: ['ignore', 'pipe', 'pipe'],\n\t}).trim();\n}\n\nfunction regExe(env: NodeJS.ProcessEnv): string {\n\treturn join(env['SystemRoot'] ?? 'C:\\\\Windows', 'System32', 'reg.exe');\n}\n\nfunction quote(value: string): string {\n\treturn `'${value.replace(/'/g, \"''\")}'`;\n}\n\nexport function readUserPath(env: NodeJS.ProcessEnv): string {\n\treturn powershell(env, \"[Environment]::GetEnvironmentVariable('Path', 'User')\");\n}\n\nexport function writeUserPath(env: NodeJS.ProcessEnv, value: string): void {\n\tpowershell(env, `[Environment]::SetEnvironmentVariable('Path', ${quote(value)}, 'User')`);\n}\n\nfunction sameDir(a: string, b: string): boolean {\n\treturn a.replace(/[\\\\/]+$/, '').toLowerCase() === b.replace(/[\\\\/]+$/, '').toLowerCase();\n}\n\n/** Prepends `dir` to the user PATH unless present; returns whether anything changed. */\nexport function addToUserPath(env: NodeJS.ProcessEnv, dir: string): boolean {\n\tconst current = readUserPath(env);\n\tconst parts = current.split(';').filter((part) => part !== '');\n\tif (parts.some((part) => sameDir(part, dir))) {\n\t\treturn false;\n\t}\n\twriteUserPath(env, [dir, ...parts].join(';'));\n\treturn true;\n}\n\nexport function removeFromUserPath(env: NodeJS.ProcessEnv, dir: string): boolean {\n\tconst current = readUserPath(env);\n\tconst parts = current.split(';').filter((part) => part !== '');\n\tconst kept = parts.filter((part) => !sameDir(part, dir));\n\tif (kept.length === parts.length) {\n\t\treturn false;\n\t}\n\twriteUserPath(env, kept.join(';'));\n\treturn true;\n}\n\nconst AUTORUN_KEY = 'HKCU\\\\Software\\\\Microsoft\\\\Command Processor';\nconst AUTORUN_MARK = 'npm-vm';\n\nexport function readCmdAutoRun(env: NodeJS.ProcessEnv): string | null {\n\ttry {\n\t\tconst out = execFileSync(regExe(env), ['query', AUTORUN_KEY, '/v', 'AutoRun'], {\n\t\t\tencoding: 'utf8',\n\t\t\twindowsHide: true,\n\t\t\tstdio: ['ignore', 'pipe', 'ignore'],\n\t\t});\n\t\treturn /AutoRun\\s+REG_(?:EXPAND_)?SZ\\s+(.*)$/m.exec(out)?.[1]?.trim() ?? null;\n\t} catch {\n\t\treturn null;\n\t}\n}\n\n/** The cmd AutoRun entry that puts shims first in every cmd session; only with `--cmd-autorun` (WIN-3). */\nexport function autoRunCommand(shimsDir: string): string {\n\treturn `set \"PATH=${shimsDir};%PATH%\" & rem ${AUTORUN_MARK}`;\n}\n\n/** `value` without the fragment `autoRunCommand` generated, whatever home it named; the user's own commands stay. */\nexport function withoutAutoRunCommand(value: string | null): string {\n\tif (value === null) {\n\t\treturn '';\n\t}\n\treturn value.replace(/^set \"PATH=[^\"]*;%PATH%\" & rem npm-vm(?: & )?/, '').trim();\n}\n\nexport function setCmdAutoRun(env: NodeJS.ProcessEnv, shimsDir: string): void {\n\tconst ours = autoRunCommand(shimsDir);\n\tconst kept = withoutAutoRunCommand(readCmdAutoRun(env));\n\tconst value = kept === '' ? ours : `${ours} & ${kept}`;\n\texecFileSync(\n\t\tregExe(env),\n\t\t['add', AUTORUN_KEY, '/v', 'AutoRun', '/t', 'REG_SZ', '/d', value, '/f'],\n\t\t{\n\t\t\twindowsHide: true,\n\t\t\tstdio: 'ignore',\n\t\t},\n\t);\n}\n\nexport function clearCmdAutoRun(env: NodeJS.ProcessEnv): boolean {\n\tconst existing = readCmdAutoRun(env);\n\tif (existing === null || !existing.includes(`rem ${AUTORUN_MARK}`)) {\n\t\treturn false;\n\t}\n\tconst rest = withoutAutoRunCommand(existing);\n\tif (rest === '') {\n\t\texecFileSync(regExe(env), ['delete', AUTORUN_KEY, '/v', 'AutoRun', '/f'], {\n\t\t\twindowsHide: true,\n\t\t\tstdio: 'ignore',\n\t\t});\n\t} else {\n\t\texecFileSync(\n\t\t\tregExe(env),\n\t\t\t['add', AUTORUN_KEY, '/v', 'AutoRun', '/t', 'REG_SZ', '/d', rest, '/f'],\n\t\t\t{\n\t\t\t\twindowsHide: true,\n\t\t\t\tstdio: 'ignore',\n\t\t\t},\n\t\t);\n\t}\n\treturn true;\n}\n\n/** Whether the effective execution policy lets our unsigned `.ps1` shims run (spec WIN-2). */\nexport function powershellAllowsScripts(policy: string | null): boolean {\n\treturn policy !== null && !['Restricted', 'AllSigned', 'Undefined'].includes(policy);\n}\n\n/** Which `npm` each Windows context resolves first, for `doctor`. */\nexport function windowsWinners(\n\tenv: NodeJS.ProcessEnv,\n): Array<{ context: string; path: string | null }> {\n\tconst results: Array<{ context: string; path: string | null }> = [];\n\ttry {\n\t\tconst out = execFileSync(\n\t\t\tjoin(env['SystemRoot'] ?? 'C:\\\\Windows', 'System32', 'where.exe'),\n\t\t\t['npm'],\n\t\t\t{\n\t\t\t\tencoding: 'utf8',\n\t\t\t\tenv,\n\t\t\t\twindowsHide: true,\n\t\t\t\tstdio: ['ignore', 'pipe', 'ignore'],\n\t\t\t},\n\t\t);\n\t\tresults.push({ context: 'cmd', path: out.split(/\\r?\\n/)[0] ?? null });\n\t} catch {\n\t\tresults.push({ context: 'cmd', path: null });\n\t}\n\ttry {\n\t\tresults.push({\n\t\t\tcontext: 'PowerShell',\n\t\t\tpath: powershell(env, '(Get-Command npm -All | Select-Object -First 1).Source') || null,\n\t\t});\n\t} catch {\n\t\tresults.push({ context: 'PowerShell', path: null });\n\t}\n\treturn results;\n}\n","import { execFileSync } from 'node:child_process';\nimport { existsSync, readFileSync, realpathSync } from 'node:fs';\nimport { basename, join } from 'node:path';\nimport { EXIT } from '../errors.ts';\nimport { findProject } from '../project.ts';\nimport { listJournals } from '../state/journal.ts';\nimport { lockOwnerLive, lockPath, readLock } from '../state/lock.ts';\nimport { shellBinary } from '../state/proc.ts';\nimport { findNodeInstalls, linkState, readLinks } from '../setup/link.ts';\nimport { BOOTSTRAP_FILE, readCurrent, readManifest, versionDir } from '../setup/layout.ts';\nimport { readProfiles } from '../setup/profile.ts';\nimport { BLOCK_START, isShell, type Shell } from '../setup/shell.ts';\nimport { SELECTORS, SHIM_ABI, shimAbi, shimDir } from '../setup/shims.ts';\nimport { windowsWinners } from '../setup/windows.ts';\nimport type { CommandContext } from './context.ts';\n\nexport interface Problem {\n\tcheck: string;\n\tdetail: string;\n\tfix: string;\n}\n\nexport interface DoctorReport {\n\thome: string;\n\tversion: string | null;\n\tproblems: Problem[];\n\tnotes: string[];\n}\n\nconst PROBE_TIMEOUT_MS = 5000;\n\n/** The `npm` an interactive login shell resolves, by asking that shell (its profiles decide the PATH). */\nfunction shellWinner(shell: Shell, env: NodeJS.ProcessEnv): string | null {\n\tconst bin = shellBinary(shell, env);\n\tif (bin === null) {\n\t\treturn null;\n\t}\n\t/* `-c` never reaches a prompt, so the hooks run by hand first: on macOS, /etc/zprofile reorders PATH after .zshenv. */\n\tconst args =\n\t\tshell === 'fish'\n\t\t\t? ['-l', '-i', '-c', 'emit fish_prompt; command -v npm']\n\t\t\t: shell === 'powershell'\n\t\t\t\t? ['-NoProfile', '-Command', '(Get-Command npm).Source']\n\t\t\t\t: shell === 'zsh'\n\t\t\t\t\t? ['-l', '-i', '-c', 'for f in $precmd_functions; do \"$f\"; done; command -v npm']\n\t\t\t\t\t: ['-l', '-i', '-c', 'eval \"$PROMPT_COMMAND\"; command -v npm'];\n\ttry {\n\t\tconst out = execFileSync(bin, args, {\n\t\t\tencoding: 'utf8',\n\t\t\tenv,\n\t\t\ttimeout: PROBE_TIMEOUT_MS,\n\t\t\tstdio: ['ignore', 'pipe', 'ignore'],\n\t\t})\n\t\t\t.trim()\n\t\t\t.split('\\n')\n\t\t\t.pop();\n\t\treturn out === undefined || out === '' ? null : out;\n\t} catch {\n\t\treturn null;\n\t}\n}\n\n/** A Windows path for comparison: `where` answers with the long name, the home may carry an 8.3 short name. */\nfunction canonical(path: string): string {\n\ttry {\n\t\treturn realpathSync.native(path).toLowerCase();\n\t} catch {\n\t\treturn path.toLowerCase();\n\t}\n}\n\n/** What `command -v npm` printed: an alias or a function wins over PATH, so no PATH fix can help. */\nexport function winnerKind(winner: string): 'alias' | 'function' | 'path' {\n\tif (winner.startsWith('alias ')) {\n\t\treturn 'alias';\n\t}\n\treturn winner === 'npm' ? 'function' : 'path';\n}\n\nfunction samePath(a: string, b: string, platform: NodeJS.Platform): boolean {\n\treturn platform === 'win32' ? a.toLowerCase() === b.toLowerCase() : a === b;\n}\n\nexport async function collect(context: CommandContext): Promise<DoctorReport> {\n\tconst { dirs, env, platform } = context;\n\tconst report: DoctorReport = {\n\t\thome: dirs.home,\n\t\tversion: readCurrent(dirs.home),\n\t\tproblems: [],\n\t\tnotes: [],\n\t};\n\tconst setupHint = 'Run `npx --prefix ~ -y @mawesome/npm-vm setup`.';\n\tconst problem = (check: string, detail: string, fix: string): void => {\n\t\treport.problems.push({ check, detail, fix });\n\t};\n\n\tif (report.version === null || readManifest(dirs.home, report.version) === null) {\n\t\tproblem('runtime', `no runtime is installed under ${dirs.home}`, setupHint);\n\t} else {\n\t\tconst root = join(dirs.home, BOOTSTRAP_FILE);\n\t\tconst shipped = join(versionDir(dirs.home, report.version), BOOTSTRAP_FILE);\n\t\tif (!existsSync(root) || !readFileSync(root).equals(readFileSync(shipped))) {\n\t\t\tproblem('launcher', `${root} differs from the installed version's launcher`, setupHint);\n\t\t}\n\t}\n\tfor (const name of SELECTORS) {\n\t\tconst file = join(shimDir(dirs.home), name);\n\t\tconst abi = existsSync(file) ? shimAbi(readFileSync(file, 'utf8')) : null;\n\t\tif (abi === null) {\n\t\t\tproblem('shims', `${file} is missing or not an npm-vm shim`, setupHint);\n\t\t} else if (abi !== SHIM_ABI) {\n\t\t\tproblem(\n\t\t\t\t'shims',\n\t\t\t\t`${file} declares launcher ABI ${abi}, this version needs ${SHIM_ABI}`,\n\t\t\t\tsetupHint,\n\t\t\t);\n\t\t}\n\t}\n\tif (dirs.machine.fallback) {\n\t\treport.notes.push(\n\t\t\t'The machine id falls back to the hostname; cloned machines or containers sharing this home could collide in the cache.',\n\t\t);\n\t}\n\tconst lock = readLock(dirs.state);\n\tif (lock !== null && !lockOwnerLive(lock, dirs.machine.id)) {\n\t\tproblem(\n\t\t\t'lock',\n\t\t\t`${lockPath(dirs.state)} is held by PID ${lock.pid}, which no longer runs`,\n\t\t\t`Delete ${lockPath(dirs.state)}.`,\n\t\t);\n\t}\n\tfor (const journal of listJournals(dirs.journal)) {\n\t\tconst foreign = journal.owner.machineId !== dirs.machine.id;\n\t\tproblem(\n\t\t\t'journal',\n\t\t\t`${journal.id} (${journal.kind}) for ${journal.target} was left by ${foreign ? `another machine (${journal.owner.host})` : `PID ${journal.owner.pid}`}`,\n\t\t\tforeign\n\t\t\t\t? `Confirm no npm-vm runs on ${journal.owner.host}, then run \\`npm-vm recover --journal ${journal.id} --confirm-dead-machine ${journal.owner.machineId}\\`.`\n\t\t\t\t: 'Run any npm-vm command; dead owners are recovered automatically.',\n\t\t);\n\t}\n\n\tconst profiles = readProfiles(dirs);\n\tfor (const entry of profiles.entries) {\n\t\tif (!existsSync(entry.file) || !readFileSync(entry.file, 'utf8').includes(BLOCK_START)) {\n\t\t\tproblem(\n\t\t\t\t'profile',\n\t\t\t\t`${entry.file} no longer holds the npm-vm block`,\n\t\t\t\t`Run \\`npm-vm init ${entry.shell}\\` and add the block, or run setup again.`,\n\t\t\t);\n\t\t}\n\t}\n\tconst shimsDir = shimDir(dirs.home);\n\tif (platform === 'win32') {\n\t\tconst shimsCanonical = canonical(shimsDir);\n\t\tfor (const winner of windowsWinners(env)) {\n\t\t\tif (winner.path === null || !canonical(winner.path).startsWith(shimsCanonical)) {\n\t\t\t\tproblem(\n\t\t\t\t\t'path',\n\t\t\t\t\t`${winner.context} resolves npm to ${winner.path ?? 'nothing'}`,\n\t\t\t\t\t'Run setup again, then restart the terminal (M-RESTART).',\n\t\t\t\t);\n\t\t\t}\n\t\t}\n\t} else {\n\t\tconst login = basename(env['SHELL'] ?? '');\n\t\tconst shells = new Set<Shell>([\n\t\t\t...profiles.entries.map((entry) => entry.shell),\n\t\t\t...(isShell(login) ? [login] : []),\n\t\t]);\n\t\tfor (const shell of shells) {\n\t\t\tif (shell === 'powershell') {\n\t\t\t\tcontinue;\n\t\t\t}\n\t\t\tconst winner = shellWinner(shell, env);\n\t\t\tif (winner === null) {\n\t\t\t\tcontinue;\n\t\t\t}\n\t\t\tconst kind = winnerKind(winner);\n\t\t\tif (kind !== 'path') {\n\t\t\t\tproblem(\n\t\t\t\t\t'path',\n\t\t\t\t\t`${shell} resolves npm to a shell ${kind}: ${winner}`,\n\t\t\t\t\t`A shell ${kind} wins over PATH. Remove it from your ${shell} profile, or make it run ${join(shimsDir, 'npm')}.`,\n\t\t\t\t);\n\t\t\t} else if (!samePath(winner, join(shimsDir, 'npm'), platform)) {\n\t\t\t\tconst corepack = winner.includes('corepack') ? ' (a Corepack shim)' : '';\n\t\t\t\tproblem(\n\t\t\t\t\t'path',\n\t\t\t\t\t`${shell} resolves npm to ${winner}${corepack}`,\n\t\t\t\t\t`Add the snippet from \\`npm-vm init ${shell}\\` after your Node manager's init line, or run setup with --link.`,\n\t\t\t\t);\n\t\t\t}\n\t\t}\n\t}\n\n\tconst links = readLinks(dirs);\n\tif (links.entries.length > 0) {\n\t\tfor (const entry of links.entries) {\n\t\t\tconst state = linkState(entry);\n\t\t\tif (state !== 'intact') {\n\t\t\t\tproblem(\n\t\t\t\t\t'link',\n\t\t\t\t\t`${entry.target} is ${state === 'missing' ? 'missing' : 'no longer the npm-vm shim'}`,\n\t\t\t\t\t'Run `npm-vm setup --link` to relink, or `npm-vm uninstall` to stop linking.',\n\t\t\t\t);\n\t\t\t}\n\t\t}\n\t\tconst linked = new Set(links.entries.map((entry) => entry.binDir));\n\t\tfor (const install of findNodeInstalls(env, platform)) {\n\t\t\tif (!linked.has(install.binDir)) {\n\t\t\t\tproblem(\n\t\t\t\t\t'link',\n\t\t\t\t\t`${install.manager} ${install.version} at ${install.binDir} is not linked`,\n\t\t\t\t\t'Run `npm-vm setup --link`.',\n\t\t\t\t);\n\t\t\t}\n\t\t}\n\t}\n\treport.notes.push(\n\t\t...findNodeInstalls(env, platform).map(\n\t\t\t(install) => `Found ${install.manager} ${install.version} at ${install.binDir}`,\n\t\t),\n\t);\n\n\tconst project = findProject([], process.cwd(), env);\n\tif (existsSync(join(project.root, 'node_modules', '.bin', 'npm'))) {\n\t\treport.notes.push(\n\t\t\t`${project.root}/node_modules/.bin/npm exists; npm scripts in this project run it instead of the shim.`,\n\t\t);\n\t}\n\treturn report;\n}\n\nexport async function doctor(\n\tcontext: CommandContext,\n\toptions: { quiet?: boolean } = {},\n): Promise<number> {\n\tconst report = await collect(context);\n\tif (options.quiet) {\n\t\treturn report.problems.length === 0 ? EXIT.ok : EXIT.problems;\n\t}\n\tif (context.json) {\n\t\tcontext.io.out(JSON.stringify(report, null, 2));\n\t} else {\n\t\tconst lines = [`npm-vm ${report.version ?? '(not installed)'} in ${report.home}`];\n\t\tfor (const problem of report.problems) {\n\t\t\tlines.push(` problem [${problem.check}]: ${problem.detail}`, ` fix: ${problem.fix}`);\n\t\t}\n\t\tfor (const note of report.notes) {\n\t\t\tlines.push(` note: ${note}`);\n\t\t}\n\t\tlines.push(\n\t\t\treport.problems.length === 0 ? ' healthy' : ` ${report.problems.length} problem(s)`,\n\t\t);\n\t\tcontext.io.out(lines.join('\\n'));\n\t}\n\treturn report.problems.length === 0 ? EXIT.ok : EXIT.problems;\n}\n","import { existsSync, readFileSync, statSync } from 'node:fs';\nimport { dirname, join } from 'node:path';\nimport semver from 'semver';\nimport { EXIT, NpmVmError } from '../errors.ts';\nimport { createContext, createInstaller } from '../install/index.ts';\nimport { findProject } from '../project.ts';\nimport { parseVersionSpec } from '../spec.ts';\nimport { mutateFile, recoverDeadJournals } from '../state/journal.ts';\nimport { acquireLock } from '../state/lock.ts';\nimport type { CommandContext } from './context.ts';\n\n/** The indentation and newline a JSON file uses, so the rewrite keeps its shape. */\nexport function detectFormat(text: string): {\n\tindent: string;\n\tnewline: '\\n' | '\\r\\n';\n\ttrailingNewline: boolean;\n} {\n\tconst indent = /^[ \\t]+(?=\")/m.exec(text)?.[0] ?? ' ';\n\treturn {\n\t\tindent,\n\t\tnewline: text.includes('\\r\\n') ? '\\r\\n' : '\\n',\n\t\ttrailingNewline: text.endsWith('\\n'),\n\t};\n}\n\n/** `devEngines.packageManager` with one npm entry, keeping other managers and the field's shape. */\nexport function pinnedManifest(\n\tpkg: Record<string, unknown>,\n\tversion: string,\n): Record<string, unknown> {\n\tconst entry = { name: 'npm', version, onFail: 'error' };\n\tconst devEngines =\n\t\ttypeof pkg['devEngines'] === 'object' && pkg['devEngines'] !== null\n\t\t\t? { ...(pkg['devEngines'] as Record<string, unknown>) }\n\t\t\t: {};\n\tconst existing = devEngines['packageManager'];\n\tif (Array.isArray(existing)) {\n\t\tconst others = existing.filter(\n\t\t\t(item) =>\n\t\t\t\t!(typeof item === 'object' && item !== null && (item as { name?: unknown }).name === 'npm'),\n\t\t);\n\t\tdevEngines['packageManager'] = [...others, entry];\n\t} else if (\n\t\ttypeof existing === 'object' &&\n\t\texisting !== null &&\n\t\t(existing as { name?: unknown }).name !== 'npm'\n\t) {\n\t\tdevEngines['packageManager'] = [existing, entry];\n\t} else {\n\t\tdevEngines['packageManager'] = entry;\n\t}\n\treturn { ...pkg, devEngines };\n}\n\nfunction nearestManifestDir(cwd: string): string | null {\n\tlet dir = cwd;\n\tfor (;;) {\n\t\tif (existsSync(join(dir, 'package.json'))) {\n\t\t\treturn dir;\n\t\t}\n\t\tconst parent = dirname(dir);\n\t\tif (parent === dir) {\n\t\t\treturn null;\n\t\t}\n\t\tdir = parent;\n\t}\n}\n\n/** `^<latest npm whose engines accept the active Node>`, asked from the registry. */\nasync function defaultRange(context: CommandContext): Promise<string> {\n\tconst installer = createInstaller(createContext(context.env, context.dirs.home));\n\tconst candidates = await installer.registry([parseVersionSpec('>=8', 'pin')]);\n\tconst usable = candidates.filter(\n\t\t(candidate) =>\n\t\t\tcandidate.enginesNode === null ||\n\t\t\tsemver.satisfies(process.version, candidate.enginesNode, { includePrerelease: true }),\n\t);\n\tconst latest = usable.map((candidate) => candidate.version).toSorted(semver.rcompare)[0];\n\tif (latest === undefined) {\n\t\tthrow new NpmVmError(\n\t\t\t'M-NOMATCH',\n\t\t\tEXIT.resolution,\n\t\t\t`No npm release supports Node ${process.version}.`,\n\t\t);\n\t}\n\treturn `^${latest}`;\n}\n\nexport async function pin(\n\tcontext: CommandContext,\n\trange: string | undefined,\n\tcwd: string = process.cwd(),\n): Promise<number> {\n\tconst project = findProject([], cwd, context.env);\n\tconst nearest = nearestManifestDir(cwd);\n\tif (nearest !== null && nearest !== project.root) {\n\t\tthrow new NpmVmError(\n\t\t\t'M-NOMATCH',\n\t\t\tEXIT.usage,\n\t\t\t`${nearest} is a workspace of ${project.root}; npm reads devEngines from the root. Run pin from ${project.root} to pin it there.`,\n\t\t);\n\t}\n\tconst file = join(project.root, 'package.json');\n\tif (!existsSync(file)) {\n\t\tthrow new NpmVmError('M-NOMATCH', EXIT.usage, `No package.json in ${project.root}.`);\n\t}\n\tconst version = range ?? (await defaultRange(context));\n\ttry {\n\t\tparseVersionSpec(version, 'pin');\n\t} catch (error) {\n\t\tthrow new NpmVmError('M-NOMATCH', EXIT.usage, (error as Error).message);\n\t}\n\t// The manifest is read and rewritten under the exclusive lock (spec MUT-1), like every other mutation.\n\tconst lock = await acquireLock(context.dirs.state, context.owner);\n\ttry {\n\t\trecoverDeadJournals(context.dirs.journal, context.dirs.machine.id);\n\t\tconst text = readFileSync(file, 'utf8');\n\t\tlet pkg: Record<string, unknown>;\n\t\ttry {\n\t\t\tpkg = JSON.parse(text) as Record<string, unknown>;\n\t\t} catch (error) {\n\t\t\tthrow new NpmVmError(\n\t\t\t\t'M-NOMATCH',\n\t\t\t\tEXIT.usage,\n\t\t\t\t`${file} is not valid JSON: ${(error as Error).message}`,\n\t\t\t);\n\t\t}\n\t\tconst format = detectFormat(text);\n\t\tconst body = JSON.stringify(pinnedManifest(pkg, version), null, format.indent).replace(\n\t\t\t/\\n/g,\n\t\t\tformat.newline,\n\t\t);\n\t\tconst output = `${body}${format.trailingNewline ? format.newline : ''}`;\n\t\tif (output !== text) {\n\t\t\tconst mode = process.platform === 'win32' ? 0o644 : statSync(file).mode & 0o7777;\n\t\t\tmutateFile(\n\t\t\t\tcontext.dirs.journal,\n\t\t\t\t'project',\n\t\t\t\tcontext.owner,\n\t\t\t\tfile,\n\t\t\t\tBuffer.from(output, 'utf8'),\n\t\t\t\tmode,\n\t\t\t);\n\t\t}\n\t} finally {\n\t\tlock.release();\n\t}\n\tcontext.io.out(\n\t\tcontext.json ? JSON.stringify({ file, version }) : `Pinned npm ${version} in ${file}`,\n\t);\n\treturn EXIT.ok;\n}\n","import { execFile } from 'node:child_process';\nimport { existsSync, mkdirSync, readFileSync, rmSync } from 'node:fs';\nimport { join } from 'node:path';\nimport semver from 'semver';\nimport { EXIT, NpmVmError } from '../errors.ts';\nimport { abiMessage } from '../messages.ts';\nimport { loadNpmConfig } from '../install/config.ts';\nimport { newWorkDir, Transport, transportUsable } from '../install/fetch.ts';\nimport { loadKeyring } from '../install/keys.ts';\nimport {\n\tverifyProvenance,\n\ttype AttestationFetcher,\n\ttype BundleVerifier,\n} from '../install/provenance.ts';\nimport { fileDigests, safeExtract, verifySignatures } from '../install/verify.ts';\nimport { findOwnNpm } from '../own-npm.ts';\nimport { transportMessage } from '../messages.ts';\nimport { atomicWrite } from '../state/atomic.ts';\nimport { mutateFile, recoverDeadJournals } from '../state/journal.ts';\nimport { acquireLock } from '../state/lock.ts';\nimport {\n\tBOOTSTRAP_FILE,\n\tinstallVersion,\n\tPREVIOUS_FILE,\n\treadCurrent,\n\treadPrevious,\n\truntimeAbi,\n\tversionDir,\n} from '../setup/layout.ts';\nimport { executionPolicy } from '../setup/profile.ts';\nimport {\n\tLAUNCHERS_DIR,\n\trenderShims,\n\tshimAbi,\n\tshimDir,\n\tstalePowershellShims,\n} from '../setup/shims.ts';\nimport { powershellAllowsScripts } from '../setup/windows.ts';\nimport type { CommandContext } from './context.ts';\n\nexport const PACKAGE_NAME = '@mawesome/npm-vm';\n\nexport interface SelfUpdateDeps {\n\tfetchAttestations?: AttestationFetcher;\n\tverifyBundle?: BundleVerifier;\n}\n\nexport interface SelfUpdateOptions {\n\trollback: boolean;\n}\n\nfunction run(\n\tfile: string,\n\targs: string[],\n): Promise<{ code: number | null; stdout: string; stderr: string }> {\n\treturn new Promise((resolve) => {\n\t\texecFile(\n\t\t\tprocess.execPath,\n\t\t\t[file, ...args],\n\t\t\t{ encoding: 'utf8', timeout: 60_000, windowsHide: true },\n\t\t\t(error, stdout, stderr) => {\n\t\t\t\tresolve({\n\t\t\t\t\tcode:\n\t\t\t\t\t\terror === null\n\t\t\t\t\t\t\t? 0\n\t\t\t\t\t\t\t: (((error as { code?: number | string }).code as number | null) ?? 1),\n\t\t\t\t\tstdout,\n\t\t\t\t\tstderr,\n\t\t\t\t});\n\t\t\t},\n\t\t);\n\t});\n}\n\n/** The launcher generation a bootstrap file belongs to, read from its `LAUNCHER_ABI` constant. */\nexport function launcherAbiOf(bootstrapFile: string): number {\n\tconst abi = shimAbi(readFileSync(bootstrapFile, 'utf8'));\n\tif (abi === null) {\n\t\tthrow new NpmVmError(\n\t\t\t'M-ABI',\n\t\t\tEXIT.abi,\n\t\t\tabiMessage(`${bootstrapFile} declares no launcher ABI`),\n\t\t);\n\t}\n\treturn abi;\n}\n\n/**\n * Replaces the home's launcher files with those of `version` (spec SUP-3): the bootstrap at the root and\n * every shim, rendered from that version's templates, each under a journal.\n */\nexport function installLaunchers(context: CommandContext, version: string): void {\n\tconst { dirs, platform, env } = context;\n\tconst dir = versionDir(dirs.home, version);\n\tconst bootstrap = join(dir, BOOTSTRAP_FILE);\n\tconst abi = launcherAbiOf(bootstrap);\n\tmutateFile(\n\t\tdirs.journal,\n\t\t'launcher',\n\t\tcontext.owner,\n\t\tjoin(dirs.home, BOOTSTRAP_FILE),\n\t\treadFileSync(bootstrap),\n\t\t0o644,\n\t);\n\tconst powershell = platform !== 'win32' || powershellAllowsScripts(executionPolicy(env));\n\tmkdirSync(shimDir(dirs.home), { recursive: true, mode: 0o755 });\n\tfor (const file of renderShims(dirs.home, platform, {\n\t\tpowershell,\n\t\ttemplates: join(dir, LAUNCHERS_DIR),\n\t\tabi,\n\t})) {\n\t\tmutateFile(\n\t\t\tdirs.journal,\n\t\t\t'launcher',\n\t\t\tcontext.owner,\n\t\t\tjoin(shimDir(dirs.home), file.name),\n\t\t\tBuffer.from(file.content),\n\t\t\tfile.mode,\n\t\t);\n\t}\n\tif (platform === 'win32' && !powershell) {\n\t\tfor (const stale of stalePowershellShims(dirs.home)) {\n\t\t\tmutateFile(dirs.journal, 'launcher', context.owner, stale, null);\n\t\t}\n\t}\n}\n\nexport function currentLauncherAbi(context: CommandContext): number | null {\n\tconst file = join(context.dirs.home, BOOTSTRAP_FILE);\n\treturn existsSync(file) ? shimAbi(readFileSync(file, 'utf8')) : null;\n}\n\nexport async function selfUpdate(\n\tcontext: CommandContext,\n\toptions: SelfUpdateOptions,\n\tdeps: SelfUpdateDeps = {},\n): Promise<number> {\n\tconst lock = await acquireLock(context.dirs.state, context.owner);\n\ttry {\n\t\trecoverDeadJournals(context.dirs.journal, context.dirs.machine.id);\n\t\treturn options.rollback ? rollback(context) : await update(context, deps);\n\t} finally {\n\t\tlock.release();\n\t}\n}\n\n/** `self-update --rollback` (spec SUP-4): offline, swaps `current` back and restores the previous launchers if the ABI differs. */\nfunction rollback(context: CommandContext): number {\n\tconst { dirs, io } = context;\n\tconst current = readCurrent(dirs.home);\n\tconst previous = readPrevious(dirs.home);\n\tif (previous === null || !existsSync(versionDir(dirs.home, previous)) || current === null) {\n\t\tthrow new NpmVmError('M-ABI', EXIT.usage, 'No previous version to roll back to.');\n\t}\n\t// The newer launcher still runs the previous runtime, so `current` moves first; the older launcher could not run the newer runtime.\n\tmutateFile(\n\t\tdirs.journal,\n\t\t'launcher',\n\t\tcontext.owner,\n\t\tjoin(dirs.home, 'current'),\n\t\tBuffer.from(`${previous}\\n`),\n\t);\n\tif (\n\t\tlauncherAbiOf(join(versionDir(dirs.home, previous), BOOTSTRAP_FILE)) !==\n\t\tcurrentLauncherAbi(context)\n\t) {\n\t\tinstallLaunchers(context, previous);\n\t}\n\tatomicWrite(join(dirs.home, PREVIOUS_FILE), `${current}\\n`);\n\tio.out(\n\t\tcontext.json\n\t\t\t? JSON.stringify({ current: previous, previous: current })\n\t\t\t: `Rolled back to npm-vm ${previous} (from ${current}).`,\n\t);\n\treturn EXIT.ok;\n}\n\nasync function update(context: CommandContext, deps: SelfUpdateDeps): Promise<number> {\n\tconst { dirs, env, io } = context;\n\tconst installed = readCurrent(dirs.home) ?? context.version;\n\tconst own = findOwnNpm();\n\tconst found = own?.version ?? null;\n\tif (!transportUsable(own)) {\n\t\tthrow new NpmVmError(\n\t\t\t'M-TRANSPORT',\n\t\t\tEXIT.transport,\n\t\t\ttransportMessage(found, 'too old or missing'),\n\t\t);\n\t}\n\tconst work = newWorkDir(dirs.tmp);\n\ttry {\n\t\tconst config = await loadNpmConfig(own, env, work);\n\t\tconst transport = new Transport(own, config, env, dirs.tmp);\n\t\tconst latest = (await transport.viewPackage(PACKAGE_NAME, 'latest'))[0];\n\t\tif (latest === undefined) {\n\t\t\tthrow new NpmVmError(\n\t\t\t\t'M-TRANSPORT',\n\t\t\t\tEXIT.transport,\n\t\t\t\ttransportMessage(own.version, `${PACKAGE_NAME}@latest is not published`),\n\t\t\t);\n\t\t}\n\t\t// Forward-only (SUP-1): a registry that serves an older \"latest\" cannot move the install back.\n\t\tif (!semver.gt(latest.version, installed)) {\n\t\t\tio.out(\n\t\t\t\tcontext.json\n\t\t\t\t\t? JSON.stringify({ current: installed, latest: latest.version, updated: false })\n\t\t\t\t\t: `npm-vm ${installed} is up to date (latest is ${latest.version}).`,\n\t\t\t);\n\t\t\treturn EXIT.ok;\n\t\t}\n\t\tconst packed = await transport.packPackage(PACKAGE_NAME, latest.version, work);\n\t\tconst digests = await fileDigests(packed.file);\n\t\tif (digests.sha512 !== latest.integrity) {\n\t\t\tthrow new NpmVmError(\n\t\t\t\t'M-INTEGRITY',\n\t\t\t\tEXIT.verification,\n\t\t\t\t`${PACKAGE_NAME}@${latest.version}: tarball does not match the registry integrity.`,\n\t\t\t);\n\t\t}\n\t\tawait verifySignatures({\n\t\t\tname: PACKAGE_NAME,\n\t\t\tversion: latest.version,\n\t\t\tintegrity: latest.integrity,\n\t\t\tsignatures: latest.signatures,\n\t\t\tpublishedAt: async () => null,\n\t\t\tkeys: loadKeyring(dirs.state),\n\t\t\tregistry: config.registry,\n\t\t\tpinned: false,\n\t\t});\n\t\tawait verifyProvenance(\n\t\t\t{\n\t\t\t\tname: PACKAGE_NAME,\n\t\t\t\tversion: latest.version,\n\t\t\t\tsha512hex: digests.sha512hex,\n\t\t\t\tattestationsUrl: latest.attestationsUrl,\n\t\t\t\tconfig,\n\t\t\t\tstateDir: dirs.state,\n\t\t\t},\n\t\t\t{\n\t\t\t\t...(deps.fetchAttestations === undefined ? {} : { fetch: deps.fetchAttestations }),\n\t\t\t\t...(deps.verifyBundle === undefined ? {} : { verify: deps.verifyBundle }),\n\t\t\t\tenv,\n\t\t\t},\n\t\t);\n\t\tconst extracted = join(work, 'package');\n\t\tmkdirSync(extracted, { mode: 0o700 });\n\t\tawait safeExtract(packed.file, extracted);\n\t\tconst runtimeSource = join(extracted, 'dist', 'runtime');\n\t\tif (\n\t\t\t!existsSync(join(runtimeSource, 'runtime.cjs')) ||\n\t\t\t!existsSync(join(runtimeSource, BOOTSTRAP_FILE))\n\t\t) {\n\t\t\tthrow new NpmVmError(\n\t\t\t\t'M-INTEGRITY',\n\t\t\t\tEXIT.verification,\n\t\t\t\t`${PACKAGE_NAME}@${latest.version} ships no runtime build.`,\n\t\t\t);\n\t\t}\n\t\tconst candidateAbi = launcherAbiOf(join(runtimeSource, BOOTSTRAP_FILE));\n\t\tconst installedRuntimeAbi =\n\t\t\truntimeAbi(dirs.home, installed) ?? currentLauncherAbi(context) ?? candidateAbi;\n\t\tif (installedRuntimeAbi < candidateAbi - 1) {\n\t\t\tthrow new NpmVmError(\n\t\t\t\t'M-ABI',\n\t\t\t\tEXIT.abi,\n\t\t\t\tabiMessage(\n\t\t\t\t\t`npm-vm ${latest.version} skips launcher generations (${installedRuntimeAbi} to ${candidateAbi})`,\n\t\t\t\t),\n\t\t\t);\n\t\t}\n\t\t// The launcher is swapped before `current`: one older than the installed runtime would break every shim meanwhile.\n\t\tif (candidateAbi < installedRuntimeAbi) {\n\t\t\tthrow new NpmVmError(\n\t\t\t\t'M-ABI',\n\t\t\t\tEXIT.abi,\n\t\t\t\tabiMessage(\n\t\t\t\t\t`npm-vm ${latest.version} ships launcher ABI ${candidateAbi}, older than the installed runtime's ${installedRuntimeAbi}`,\n\t\t\t\t),\n\t\t\t);\n\t\t}\n\t\tconst target = installVersion(dirs.home, latest.version, runtimeSource, candidateAbi);\n\t\tconst health = await run(join(target, BOOTSTRAP_FILE), ['--candidate', 'cli', '--version']);\n\t\tif (health.code !== 0 || health.stdout.trim() !== latest.version) {\n\t\t\trmSync(target, { recursive: true, force: true });\n\t\t\tthrow new NpmVmError(\n\t\t\t\t'M-ABI',\n\t\t\t\tEXIT.abi,\n\t\t\t\tabiMessage(\n\t\t\t\t\t`the downloaded runtime failed its health check: ${health.stderr.trim() || health.stdout.trim() || `exit ${health.code}`}`,\n\t\t\t\t),\n\t\t\t);\n\t\t}\n\t\tif (candidateAbi !== currentLauncherAbi(context)) {\n\t\t\tinstallLaunchers(context, latest.version);\n\t\t}\n\t\tatomicWrite(join(dirs.home, PREVIOUS_FILE), `${installed}\\n`);\n\t\tmutateFile(\n\t\t\tdirs.journal,\n\t\t\t'launcher',\n\t\t\tcontext.owner,\n\t\t\tjoin(dirs.home, 'current'),\n\t\t\tBuffer.from(`${latest.version}\\n`),\n\t\t);\n\t\tio.out(\n\t\t\tcontext.json\n\t\t\t\t? JSON.stringify({ current: latest.version, previous: installed, updated: true })\n\t\t\t\t: `Updated npm-vm ${installed} to ${latest.version}.`,\n\t\t);\n\t\treturn EXIT.ok;\n\t} finally {\n\t\trmSync(work, { recursive: true, force: true });\n\t}\n}\n","import { chmodSync, existsSync, mkdirSync, readFileSync, statSync } from 'node:fs';\nimport { basename, join } from 'node:path';\nimport { EXIT, NpmVmError } from '../errors.ts';\nimport { dirPermsMessage, restartMessage } from '../messages.ts';\nimport { recoverDeadJournals, mutateFile } from '../state/journal.ts';\nimport { acquireLock } from '../state/lock.ts';\nimport { findNodeInstalls, linkOne, linkTargets, type LinkResult } from '../setup/link.ts';\nimport {\n\tBOOTSTRAP_FILE,\n\tinstallBootstrap,\n\tinstallVersion,\n\treadCurrent,\n\treadManifest,\n\truntimeDistDir,\n\tsetCurrent,\n\tsweepReplaced,\n\tversionDir,\n} from '../setup/layout.ts';\nimport {\n\tapplyProfileEdit,\n\texecutionPolicy,\n\tplanProfileEdit,\n\tprofileGuard,\n\tprofileTargets,\n\ttype ProfileTarget,\n} from '../setup/profile.ts';\nimport { isShell, profileBlock, type Shell } from '../setup/shell.ts';\nimport {\n\tassertSafeHome,\n\trenderShims,\n\tSHIM_ABI,\n\tshimDir,\n\tstalePowershellShims,\n} from '../setup/shims.ts';\nimport { addToUserPath, powershellAllowsScripts, setCmdAutoRun } from '../setup/windows.ts';\nimport type { CommandContext } from './context.ts';\nimport { doctor } from './doctor.ts';\n\nexport interface SetupOptions {\n\tlink: boolean;\n\tshells: Shell[] | null;\n\tyes: boolean;\n\tdryRun: boolean;\n\tmodifyProfile: boolean;\n\tcmdAutorun: boolean;\n\tstrict: boolean;\n\t/** Write the Windows user PATH and AutoRun; the Action turns this off and relies on GITHUB_PATH. */\n\tuserPath: boolean;\n}\n\nexport interface SetupReport {\n\thome: string;\n\tversion: string;\n\tprofiles: Array<{\n\t\tfile: string;\n\t\toutcome: 'written' | 'unchanged' | 'printed' | 'declined' | 'changed' | 'dry-run';\n\t\treason?: string;\n\t}>;\n\tlinks: LinkResult[];\n\tskipped: number;\n}\n\n/** Refuses a home or cache another user could write to (spec SEC-9). */\nexport function assertPrivateDir(dir: string, platform: NodeJS.Platform): void {\n\tif (platform === 'win32') {\n\t\treturn;\n\t}\n\tconst stat = statSync(dir);\n\tif (process.getuid !== undefined && stat.uid !== process.getuid()) {\n\t\tthrow new NpmVmError(\n\t\t\t'M-DIRPERMS',\n\t\t\tEXIT.problems,\n\t\t\tdirPermsMessage(dir, 'is not owned by you', `chown $(id -u) ${dir}`),\n\t\t);\n\t}\n\tif ((stat.mode & 0o022) !== 0) {\n\t\tthrow new NpmVmError(\n\t\t\t'M-DIRPERMS',\n\t\t\tEXIT.problems,\n\t\t\tdirPermsMessage(dir, 'is writable by other users', `chmod go-w ${dir}`),\n\t\t);\n\t}\n}\n\nfunction ensurePrivateDir(dir: string, platform: NodeJS.Platform): void {\n\tif (!existsSync(dir)) {\n\t\tmkdirSync(dir, { recursive: true, mode: 0o700 });\n\t\tif (platform !== 'win32') {\n\t\t\tchmodSync(dir, 0o700);\n\t\t}\n\t}\n\tassertPrivateDir(dir, platform);\n}\n\n/** The shells to configure: `--shell` values, else the login shell, plus PowerShell on Windows. */\nexport function defaultShells(env: NodeJS.ProcessEnv, platform: NodeJS.Platform): Shell[] {\n\tif (platform === 'win32') {\n\t\treturn ['powershell'];\n\t}\n\tconst login = basename(env['SHELL'] ?? '');\n\treturn isShell(login) ? [login] : ['bash'];\n}\n\nfunction sameFiles(home: string, version: string, distDir: string): boolean {\n\tconst manifest = readManifest(home, version);\n\tif (manifest === null) {\n\t\treturn false;\n\t}\n\treturn manifest.files.every((file) => {\n\t\ttry {\n\t\t\treturn readFileSync(join(distDir, file)).equals(\n\t\t\t\treadFileSync(join(versionDir(home, version), file)),\n\t\t\t);\n\t\t} catch {\n\t\t\treturn false;\n\t\t}\n\t});\n}\n\nexport async function setup(context: CommandContext, options: SetupOptions): Promise<number> {\n\tconst { dirs, env, platform, io } = context;\n\tassertSafeHome(dirs.home);\n\tconst distDir = runtimeDistDir();\n\tif (distDir === null) {\n\t\tthrow new NpmVmError(\n\t\t\t'M-ABI',\n\t\t\tEXIT.problems,\n\t\t\t'This npm-vm installation ships no runtime build; reinstall the package.',\n\t\t);\n\t}\n\tfor (const dir of [dirs.home, dirs.state, dirs.cache]) {\n\t\tif (options.dryRun) {\n\t\t\tif (existsSync(dir)) {\n\t\t\t\tassertPrivateDir(dir, platform);\n\t\t\t}\n\t\t} else {\n\t\t\tensurePrivateDir(dir, platform);\n\t\t}\n\t}\n\tconst report: SetupReport = {\n\t\thome: dirs.home,\n\t\tversion: context.version,\n\t\tprofiles: [],\n\t\tlinks: [],\n\t\tskipped: 0,\n\t};\n\tconst shells = options.shells ?? defaultShells(env, platform);\n\tconst targets = options.modifyProfile ? profileTargets(shells, env, platform) : [];\n\tconst policy = platform === 'win32' ? executionPolicy(env) : null;\n\tconst powershell = platform !== 'win32' || powershellAllowsScripts(policy);\n\n\t// Every target is examined before anything is written, so a refusal costs nothing.\n\tconst plans = targets.map((target) => ({\n\t\ttarget,\n\t\tguard: profileGuard(target.file, env, platform),\n\t\tedit: planProfileEdit(target, dirs.home),\n\t}));\n\n\t// A dry run writes nothing, not even the lock, so the home stays absent when it did not exist.\n\tconst lock = options.dryRun ? null : await acquireLock(dirs.state, context.owner);\n\ttry {\n\t\tif (lock !== null) {\n\t\t\trecoverDeadJournals(dirs.journal, dirs.machine.id);\n\t\t}\n\t\tif (!options.dryRun) {\n\t\t\tinstallRuntime(context, distDir);\n\t\t\tmkdirSync(shimDir(dirs.home), { recursive: true, mode: 0o755 });\n\t\t\tfor (const file of renderShims(dirs.home, platform, { powershell })) {\n\t\t\t\tmutateFile(\n\t\t\t\t\tdirs.journal,\n\t\t\t\t\t'launcher',\n\t\t\t\t\tcontext.owner,\n\t\t\t\t\tjoin(shimDir(dirs.home), file.name),\n\t\t\t\t\tBuffer.from(file.content),\n\t\t\t\t\tfile.mode,\n\t\t\t\t);\n\t\t\t}\n\t\t\tif (platform === 'win32' && !powershell) {\n\t\t\t\tfor (const stale of stalePowershellShims(dirs.home)) {\n\t\t\t\t\tmutateFile(dirs.journal, 'launcher', context.owner, stale, null);\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t\tfor (const plan of plans) {\n\t\t\treport.profiles.push(await applyPlan(context, options, plan));\n\t\t}\n\t\tif (options.link) {\n\t\t\tfor (const install of findNodeInstalls(env, platform)) {\n\t\t\t\tfor (const target of linkTargets(dirs.home, platform, powershell)) {\n\t\t\t\t\tif (options.dryRun) {\n\t\t\t\t\t\treport.links.push({\n\t\t\t\t\t\t\ttarget: join(install.binDir, target.name),\n\t\t\t\t\t\t\toutcome: 'linked',\n\t\t\t\t\t\t\tdetail: 'dry run',\n\t\t\t\t\t\t});\n\t\t\t\t\t} else {\n\t\t\t\t\t\treport.links.push(linkOne(dirs, context.owner, install.binDir, target));\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t\tif (platform === 'win32' && !options.dryRun && options.userPath) {\n\t\t\tif (addToUserPath(env, shimDir(dirs.home))) {\n\t\t\t\tenv['Path'] = `${shimDir(dirs.home)};${env['Path'] ?? ''}`;\n\t\t\t\tio.err(restartMessage());\n\t\t\t}\n\t\t\tif (options.cmdAutorun) {\n\t\t\t\tsetCmdAutoRun(env, shimDir(dirs.home));\n\t\t\t}\n\t\t\tif (!powershell) {\n\t\t\t\tio.err(\n\t\t\t\t\t`PowerShell's execution policy (${policy ?? 'unknown'}) blocks unsigned scripts, so no .ps1 shims were installed; cmd shims take over.`,\n\t\t\t\t);\n\t\t\t}\n\t\t}\n\t} finally {\n\t\tlock?.release();\n\t}\n\treport.skipped =\n\t\treport.profiles.filter(\n\t\t\t(entry) =>\n\t\t\t\tentry.outcome === 'printed' || entry.outcome === 'declined' || entry.outcome === 'changed',\n\t\t).length +\n\t\treport.links.filter((link) => ['foreign', 'unwritable', 'missing'].includes(link.outcome))\n\t\t\t.length;\n\tif (context.json) {\n\t\tio.out(JSON.stringify(report, null, 2));\n\t} else {\n\t\tio.out(describe(report));\n\t}\n\tif (!options.dryRun) {\n\t\t// With --json the setup report is the only document on stdout; doctor still decides --strict.\n\t\tconst health = await doctor(context, { quiet: context.json });\n\t\tif (health !== EXIT.ok && options.strict) {\n\t\t\treturn EXIT.partial;\n\t\t}\n\t}\n\treturn options.strict && report.skipped > 0 ? EXIT.partial : EXIT.ok;\n}\n\n/** Installs this version's runtime and launcher unless the identical files are already in place. */\nfunction installRuntime(context: CommandContext, distDir: string): void {\n\tconst { dirs, version } = context;\n\tif (!sameFiles(dirs.home, version, distDir)) {\n\t\tinstallVersion(dirs.home, version, distDir, SHIM_ABI);\n\t}\n\tsweepReplaced(dirs.home);\n\tif (readCurrent(dirs.home) !== version) {\n\t\tmutateFile(\n\t\t\tdirs.journal,\n\t\t\t'launcher',\n\t\t\tcontext.owner,\n\t\t\tjoin(dirs.home, 'current'),\n\t\t\tBuffer.from(`${version}\\n`),\n\t\t);\n\t}\n\tconst bootstrap = readFileSync(join(versionDir(dirs.home, version), BOOTSTRAP_FILE));\n\tconst installed = existsSync(join(dirs.home, BOOTSTRAP_FILE))\n\t\t? readFileSync(join(dirs.home, BOOTSTRAP_FILE))\n\t\t: null;\n\tif (installed === null || !installed.equals(bootstrap)) {\n\t\tmutateFile(\n\t\t\tdirs.journal,\n\t\t\t'launcher',\n\t\t\tcontext.owner,\n\t\t\tjoin(dirs.home, BOOTSTRAP_FILE),\n\t\t\tbootstrap,\n\t\t\t0o644,\n\t\t);\n\t}\n\tvoid setCurrent;\n\tvoid installBootstrap;\n}\n\nasync function applyPlan(\n\tcontext: CommandContext,\n\toptions: SetupOptions,\n\tplan: { target: ProfileTarget; guard: string | null; edit: ReturnType<typeof planProfileEdit> },\n): Promise<SetupReport['profiles'][number]> {\n\tconst { io, dirs } = context;\n\tconst { target } = plan;\n\tif (plan.guard !== null) {\n\t\tio.out(\n\t\t\t`Not editing ${target.file}: ${plan.guard}. Add this yourself:\\n${profileBlock(target.shell, dirs.home, target.parts)}`,\n\t\t);\n\t\treturn { file: target.file, outcome: 'printed', reason: plan.guard };\n\t}\n\tif (plan.edit === null) {\n\t\treturn { file: target.file, outcome: 'unchanged' };\n\t}\n\tif (options.dryRun) {\n\t\tio.out(`Would edit ${target.file}:\\n${plan.edit.diff}`);\n\t\treturn { file: target.file, outcome: 'dry-run' };\n\t}\n\tif (!options.yes) {\n\t\tio.out(plan.edit.diff);\n\t\tconst agreed = await io.confirm(`Apply this change to ${target.file}?`);\n\t\tif (!agreed) {\n\t\t\tio.out(\n\t\t\t\t`Skipped ${target.file}. Add this yourself:\\n${profileBlock(target.shell, dirs.home, target.parts)}`,\n\t\t\t);\n\t\t\treturn { file: target.file, outcome: 'declined' };\n\t\t}\n\t}\n\t/* The file may have changed while the prompt was open: guard and plan again, and never write over what was not shown.\n\t * The guard runs again because a swap for a symlink keeps the content equal (spec SH-5). */\n\tconst guard = profileGuard(target.file, context.env, context.platform);\n\tconst fresh = planProfileEdit(target, dirs.home);\n\tif (fresh === null) {\n\t\treturn { file: target.file, outcome: 'unchanged' };\n\t}\n\tif (guard !== null || (fresh.before !== plan.edit.before && !options.yes)) {\n\t\tio.out(\n\t\t\t`${target.file} changed while the prompt was open; run setup again to review the new change.`,\n\t\t);\n\t\treturn { file: target.file, outcome: 'changed' };\n\t}\n\tapplyProfileEdit(dirs, context.owner, fresh);\n\treturn { file: target.file, outcome: 'written' };\n}\n\nfunction describe(report: SetupReport): string {\n\tconst lines = [`npm-vm ${report.version} installed in ${report.home}`];\n\tfor (const profile of report.profiles) {\n\t\tlines.push(\n\t\t\t` ${profile.file}: ${profile.outcome}${profile.reason ? ` (${profile.reason})` : ''}`,\n\t\t);\n\t}\n\tfor (const link of report.links) {\n\t\tlines.push(` ${link.target}: ${link.outcome}${link.detail ? ` (${link.detail})` : ''}`);\n\t}\n\treturn lines.join('\\n');\n}\n","import { rmdirSync } from 'node:fs';\nimport { join } from 'node:path';\nimport { atomicRename, removeWithRetry } from '../state/atomic.ts';\nimport { EXIT } from '../errors.ts';\nimport { ENTRIES_DIR, stagingDir } from '../install/cache.ts';\nimport { changedMessage } from '../messages.ts';\nimport { recoverDeadJournals } from '../state/journal.ts';\nimport { acquireLock } from '../state/lock.ts';\nimport { pruneCache } from '../state/prune.ts';\nimport { readLinks, unlinkOne } from '../setup/link.ts';\nimport { readProfiles, removeProfileBlock } from '../setup/profile.ts';\nimport { shimDir } from '../setup/shims.ts';\nimport { clearCmdAutoRun, removeFromUserPath } from '../setup/windows.ts';\nimport type { CommandContext } from './context.ts';\n\nexport interface UninstallOptions {\n\tyes: boolean;\n\tpurgeCache: boolean;\n}\n\nexport interface UninstallReport {\n\tprofiles: Array<{ file: string; outcome: string }>;\n\tlinks: Array<{ target: string; outcome: string }>;\n\thomeRemoved: boolean;\n\tcacheRemoved: boolean;\n\t/** Entries `--purge-cache` left because a running npm holds them. */\n\tcacheKept: string[];\n}\n\n/** Removes the cache's directories only while empty: an npm publishing right now keeps its entry. */\nfunction removeEmptyTree(cache: string): void {\n\tfor (const dir of [join(cache, ENTRIES_DIR), stagingDir(cache), cache]) {\n\t\ttry {\n\t\t\trmdirSync(dir);\n\t\t} catch {\n\t\t\t// Not empty or already gone; either way it stays as it is.\n\t\t}\n\t}\n}\n\nexport async function uninstall(\n\tcontext: CommandContext,\n\toptions: UninstallOptions,\n): Promise<number> {\n\tconst { dirs, env, platform, io } = context;\n\tif (!options.yes) {\n\t\tconst agreed = await io.confirm(\n\t\t\t`Remove npm-vm from ${dirs.home}, its profile blocks and links${options.purgeCache ? ', and the cache' : ''}?`,\n\t\t);\n\t\tif (!agreed) {\n\t\t\tio.out('Nothing removed.');\n\t\t\treturn EXIT.ok;\n\t\t}\n\t}\n\tconst report: UninstallReport = {\n\t\tprofiles: [],\n\t\tlinks: [],\n\t\thomeRemoved: false,\n\t\tcacheRemoved: false,\n\t\tcacheKept: [],\n\t};\n\tconst lock = await acquireLock(dirs.state, context.owner);\n\tlet clean = true;\n\ttry {\n\t\trecoverDeadJournals(dirs.journal, dirs.machine.id);\n\t\tfor (const entry of readProfiles(dirs).entries) {\n\t\t\tconst outcome = removeProfileBlock(dirs, context.owner, entry);\n\t\t\treport.profiles.push({ file: entry.file, outcome });\n\t\t\tif (outcome === 'changed') {\n\t\t\t\tclean = false;\n\t\t\t\tio.err(changedMessage(entry.file, 'npm-vm block'));\n\t\t\t}\n\t\t}\n\t\tfor (const entry of readLinks(dirs).entries) {\n\t\t\tconst outcome = unlinkOne(dirs, context.owner, entry);\n\t\t\treport.links.push({ target: entry.target, outcome });\n\t\t\tif (outcome === 'changed') {\n\t\t\t\tclean = false;\n\t\t\t\tio.err(changedMessage(entry.target, 'shim'));\n\t\t\t}\n\t\t}\n\t\tif (platform === 'win32') {\n\t\t\tremoveFromUserPath(env, shimDir(dirs.home));\n\t\t\tclearCmdAutoRun(env);\n\t\t}\n\t\tif (options.purgeCache) {\n\t\t\t// Through the gate and lease protocol, under the home lock and the cache's own lock, which other homes share.\n\t\t\tconst cacheLock = await acquireLock(dirs.cache, context.owner);\n\t\t\ttry {\n\t\t\t\tconst pruned = pruneCache(dirs.cache, context.owner, { maxAgeMs: 0 });\n\t\t\t\treport.cacheKept = pruned.kept.concat(pruned.skipped);\n\t\t\t\tif (report.cacheKept.length === 0) {\n\t\t\t\t\tremoveEmptyTree(dirs.cache);\n\t\t\t\t\treport.cacheRemoved = true;\n\t\t\t\t}\n\t\t\t} finally {\n\t\t\t\tcacheLock.release();\n\t\t\t}\n\t\t\tif (report.cacheRemoved) {\n\t\t\t\t// The lock file itself kept the root; now it can go too.\n\t\t\t\tremoveEmptyTree(dirs.cache);\n\t\t\t}\n\t\t\tif (report.cacheKept.length > 0) {\n\t\t\t\tclean = false;\n\t\t\t\tio.err(\n\t\t\t\t\t`Cache kept: ${report.cacheKept.join(', ')} ${report.cacheKept.length === 1 ? 'is' : 'are'} in use by a running npm.`,\n\t\t\t\t);\n\t\t\t}\n\t\t}\n\t\t// Under the lock the home moves aside in one rename, so a setup that follows never writes into a dir being deleted.\n\t\tconst tombstone = `${dirs.home}.removing.${process.pid}.${Date.now()}`;\n\t\tatomicRename(dirs.home, tombstone);\n\t\tremoveWithRetry(tombstone);\n\t\treport.homeRemoved = true;\n\t} finally {\n\t\tlock.release();\n\t}\n\tio.out(context.json ? JSON.stringify(report, null, 2) : describe(report, dirs.cache));\n\treturn clean ? EXIT.ok : EXIT.problems;\n}\n\nfunction describe(report: UninstallReport, cache: string): string {\n\tconst lines = ['npm-vm removed.'];\n\tfor (const profile of report.profiles) {\n\t\tlines.push(` ${profile.file}: ${profile.outcome}`);\n\t}\n\tfor (const link of report.links) {\n\t\tlines.push(` ${link.target}: ${link.outcome}`);\n\t}\n\tif (report.cacheRemoved) {\n\t\tlines.push(` cache removed (${cache})`);\n\t} else if (report.cacheKept.length > 0) {\n\t\tlines.push(` cache kept at ${cache}: ${report.cacheKept.join(', ')} in use by a running npm`);\n\t} else {\n\t\tlines.push(` cache kept at ${cache}; add --purge-cache to remove it`);\n\t}\n\treturn lines.join('\\n');\n}\n","import { readFileSync } from 'node:fs';\nimport { parseArgs } from 'node:util';\nimport { EXIT, isNpmVmError } from '../errors.ts';\nimport { resolveNpm, type ResolveResult } from '../index.ts';\nimport { isShell, profileBlock, SHELLS, type Shell } from '../setup/shell.ts';\nimport { cacheList, cachePrune, DEFAULT_PRUNE_DAYS, install, recover } from './cache.ts';\nimport { createCommandContext, type CommandContext, type CommandIo } from './context.ts';\nimport { doctor } from './doctor.ts';\nimport { pin } from './pin.ts';\nimport { selfUpdate } from './self-update.ts';\nimport { setup } from './setup.ts';\nimport { uninstall } from './uninstall.ts';\n\nconst VERSION = readSelfVersion();\n\nconst USAGE = `npm-vm v${VERSION}: run the npm version a project declares in devEngines\n\nUsage:\n npm-vm <command> [options]\n\nCommands:\n setup Install the launcher, shims and shell snippets; --link also replaces npm\n inside every nvm/fnm Node. --shell <s> (repeatable), --yes, --dry-run,\n --no-modify-profile, --cmd-autorun and --no-user-path (Windows), --strict (exit 2 on skips).\n init <shell> Print the snippet for zsh, bash, fish or powershell (--path, --hook; default both).\n doctor Check the installation; exit 1 when something needs fixing.\n which Print the npm that would run for the current directory.\n pin [<range>] Write devEngines.packageManager for npm into the project's package.json.\n install [<spec>] Download and verify the project's npm, or <spec>, into the cache.\n cache list List cached npm versions.\n cache prune Remove unused entries; --older-than <days> (default ${DEFAULT_PRUNE_DAYS}).\n self-update Update npm-vm with provenance verification; --rollback restores the previous version.\n recover Finish a journal left by another machine: --journal <id> --confirm-dead-machine <id>.\n uninstall Remove npm-vm (--yes to skip the prompt, --purge-cache to drop the cache too).\n\nGlobal options:\n --json Machine-readable output where a command offers it.\n --version, -v Print the version.\n --help, -h Print this help.\n\nEnvironment:\n NPM_VM_VERSION Use this range or version instead of the project's.\n NPM_VM_DISABLE Any value: always run Node's own npm.\n NPM_VM_OFFLINE Any value: never contact the registry.\n NPM_VM_HOME The home directory (setup only).\n\nExit codes: 0 ok, 1 problems found, 2 partial setup under --strict, 3 resolution failed, 4 transport\nunavailable, 5 verification failed, 6 launcher mismatch, 64 usage error.`;\n\nexport interface DispatchOptions {\n\t/** The home the launcher runs from; the bin entry leaves it to the env and defaults. */\n\thome?: string;\n\tio?: CommandIo;\n\tenv?: NodeJS.ProcessEnv;\n}\n\nfunction parse(argv: string[]) {\n\treturn parseArgs({\n\t\targs: argv,\n\t\tallowPositionals: true,\n\t\tallowNegative: true,\n\t\toptions: {\n\t\t\tjson: { type: 'boolean' },\n\t\t\tpath: { type: 'boolean' },\n\t\t\thook: { type: 'boolean' },\n\t\t\tlink: { type: 'boolean' },\n\t\t\tshell: { type: 'string', multiple: true },\n\t\t\tyes: { type: 'boolean' },\n\t\t\t'dry-run': { type: 'boolean' },\n\t\t\t'modify-profile': { type: 'boolean' },\n\t\t\t'cmd-autorun': { type: 'boolean' },\n\t\t\t'user-path': { type: 'boolean' },\n\t\t\tstrict: { type: 'boolean' },\n\t\t\t'older-than': { type: 'string' },\n\t\t\trollback: { type: 'boolean' },\n\t\t\tjournal: { type: 'string' },\n\t\t\t'confirm-dead-machine': { type: 'string' },\n\t\t\t'purge-cache': { type: 'boolean' },\n\t\t\tbundle: { type: 'string' },\n\t\t\t'tuf-cache': { type: 'string' },\n\t\t\tversion: { type: 'boolean', short: 'v' },\n\t\t\thelp: { type: 'boolean', short: 'h' },\n\t\t},\n\t});\n}\n\ntype Values = ReturnType<typeof parse>['values'];\n\n/** Command-specific options, so a flag meant for another command is an error rather than silently ignored. */\nconst COMMAND_OPTIONS: Record<string, readonly (keyof Values)[]> = {\n\tsetup: [\n\t\t'link',\n\t\t'shell',\n\t\t'yes',\n\t\t'dry-run',\n\t\t'modify-profile',\n\t\t'cmd-autorun',\n\t\t'user-path',\n\t\t'strict',\n\t],\n\tinit: ['path', 'hook'],\n\tdoctor: [],\n\twhich: [],\n\tpin: [],\n\tinstall: [],\n\tcache: ['older-than'],\n\t'self-update': ['rollback'],\n\trecover: ['journal', 'confirm-dead-machine'],\n\tuninstall: ['yes', 'purge-cache'],\n\t'verify-attestation': ['bundle', 'tuf-cache'],\n};\n\nfunction misplacedOptions(command: string, values: Values): string[] {\n\tconst allowed = new Set<keyof Values>(COMMAND_OPTIONS[command] ?? []);\n\treturn Object.values(COMMAND_OPTIONS)\n\t\t.flat()\n\t\t.filter((option) => !allowed.has(option) && values[option] !== undefined)\n\t\t.map((option) => `--${option}`);\n}\n\nexport async function run(argv: string[], options: DispatchOptions): Promise<number> {\n\tlet parsed: ReturnType<typeof parse>;\n\ttry {\n\t\tparsed = parse(argv);\n\t} catch (error) {\n\t\tconsole.error((error as Error).message);\n\t\tconsole.error(USAGE);\n\t\treturn EXIT.usage;\n\t}\n\tconst { values, positionals } = parsed;\n\tif (values.version) {\n\t\tconsole.log(VERSION);\n\t\treturn EXIT.ok;\n\t}\n\tconst command = positionals[0];\n\tif (values.help || command === undefined) {\n\t\tconsole.log(USAGE);\n\t\treturn command === undefined && !values.help ? EXIT.usage : EXIT.ok;\n\t}\n\tif (COMMAND_OPTIONS[command] === undefined) {\n\t\tconsole.error(`Unknown command: ${command}`);\n\t\tconsole.error(USAGE);\n\t\treturn EXIT.usage;\n\t}\n\tconst misplaced = misplacedOptions(command, values);\n\tif (misplaced.length > 0) {\n\t\tconsole.error(`${misplaced.join(', ')} cannot be used with ${command}`);\n\t\treturn EXIT.usage;\n\t}\n\tconst context = createCommandContext({\n\t\t...(options.home === undefined ? {} : { home: options.home }),\n\t\t...(options.env === undefined ? {} : { env: options.env }),\n\t\t...(options.io === undefined ? {} : { io: options.io }),\n\t\tjson: values.json ?? false,\n\t\tversion: VERSION,\n\t});\n\ttry {\n\t\treturn await dispatch(command, positionals.slice(1), values, context, options);\n\t} catch (error) {\n\t\treturn reportError(error, context);\n\t}\n}\n\nasync function dispatch(\n\tcommand: string,\n\trest: string[],\n\tvalues: Values,\n\tcontext: CommandContext,\n\toptions: DispatchOptions,\n): Promise<number> {\n\tswitch (command) {\n\t\tcase 'setup': {\n\t\t\tconst shells = values.shell ?? null;\n\t\t\tconst bad = shells?.filter((shell) => !isShell(shell)) ?? [];\n\t\t\tif (bad.length > 0) {\n\t\t\t\tcontext.io.err(`--shell needs one of: ${SHELLS.join(', ')} (got ${bad.join(', ')})`);\n\t\t\t\treturn EXIT.usage;\n\t\t\t}\n\t\t\treturn setup(context, {\n\t\t\t\tlink: values.link ?? false,\n\t\t\t\tshells: shells as Shell[] | null,\n\t\t\t\tyes: values.yes ?? false,\n\t\t\t\tdryRun: values['dry-run'] ?? false,\n\t\t\t\tmodifyProfile: values['modify-profile'] ?? true,\n\t\t\t\tcmdAutorun: values['cmd-autorun'] ?? false,\n\t\t\t\tstrict: values.strict ?? false,\n\t\t\t\tuserPath: values['user-path'] ?? true,\n\t\t\t});\n\t\t}\n\t\tcase 'init': {\n\t\t\tconst shell = rest[0];\n\t\t\tif (shell === undefined || !isShell(shell)) {\n\t\t\t\tcontext.io.err(`init needs one of: ${SHELLS.join(', ')}`);\n\t\t\t\treturn EXIT.usage;\n\t\t\t}\n\t\t\tconst both = values.path !== true && values.hook !== true;\n\t\t\tprocess.stdout.write(\n\t\t\t\tprofileBlock(shell, context.dirs.home, {\n\t\t\t\t\tpath: both || values.path === true,\n\t\t\t\t\thook: both || values.hook === true,\n\t\t\t\t}),\n\t\t\t);\n\t\t\treturn EXIT.ok;\n\t\t}\n\t\tcase 'doctor':\n\t\t\treturn doctor(context);\n\t\tcase 'which': {\n\t\t\tconst result = await resolveNpm([], process.cwd(), {\n\t\t\t\thome: context.dirs.home,\n\t\t\t\t...(options.env === undefined ? {} : { env: options.env }),\n\t\t\t});\n\t\t\tcontext.io.out(context.json ? JSON.stringify(result, null, 2) : describeWhich(result));\n\t\t\treturn EXIT.ok;\n\t\t}\n\t\tcase 'pin':\n\t\t\treturn pin(context, rest[0]);\n\t\tcase 'install':\n\t\t\treturn install(context, rest[0]);\n\t\tcase 'cache': {\n\t\t\tif (rest[0] === 'list') {\n\t\t\t\treturn cacheList(context);\n\t\t\t}\n\t\t\tif (rest[0] === 'prune') {\n\t\t\t\treturn cachePrune(\n\t\t\t\t\tcontext,\n\t\t\t\t\tvalues['older-than'] === undefined ? DEFAULT_PRUNE_DAYS : Number(values['older-than']),\n\t\t\t\t);\n\t\t\t}\n\t\t\tcontext.io.err('cache needs list or prune');\n\t\t\treturn EXIT.usage;\n\t\t}\n\t\tcase 'self-update':\n\t\t\treturn selfUpdate(context, { rollback: values.rollback ?? false });\n\t\tcase 'recover': {\n\t\t\tif (values.journal === undefined || values['confirm-dead-machine'] === undefined) {\n\t\t\t\tcontext.io.err('recover needs --journal <id> and --confirm-dead-machine <machine-id>');\n\t\t\t\treturn EXIT.usage;\n\t\t\t}\n\t\t\treturn recover(context, values.journal, values['confirm-dead-machine']);\n\t\t}\n\t\tcase 'verify-attestation': {\n\t\t\t// Internal: self-update runs it in a child Node whose env carries the proxy and CA settings.\n\t\t\tif (values.bundle === undefined || values['tuf-cache'] === undefined) {\n\t\t\t\treturn EXIT.usage;\n\t\t\t}\n\t\t\tconst { verifyBundleHere } = await import('../install/provenance.ts');\n\t\t\tawait verifyBundleHere(JSON.parse(readFileSync(values.bundle, 'utf8')), values['tuf-cache']);\n\t\t\treturn EXIT.ok;\n\t\t}\n\t\tcase 'uninstall':\n\t\t\treturn uninstall(context, {\n\t\t\t\tyes: values.yes ?? false,\n\t\t\t\tpurgeCache: values['purge-cache'] ?? false,\n\t\t\t});\n\t\tdefault:\n\t\t\treturn EXIT.usage;\n\t}\n}\n\nfunction describeWhich(result: ResolveResult): string {\n\tconst where =\n\t\tresult.kind === 'own' ? \"Node's own npm\" : result.kind === 'cached' ? 'cached' : 'to download';\n\tconst from =\n\t\tresult.source === null\n\t\t\t? 'no project requirement'\n\t\t\t: `${result.source.field} in ${result.source.file}`;\n\tconst lines = [`npm ${result.version} (${where}): ${result.cliPath}`, `Source: ${from}`];\n\tif (result.warning !== null) {\n\t\tlines.push(`Warning: ${result.warning}`);\n\t}\n\treturn lines.join('\\n');\n}\n\nfunction reportError(error: unknown, context: CommandContext): number {\n\tif (isNpmVmError(error)) {\n\t\tcontext.io.err(`npm-vm: ${error.message}`);\n\t\treturn error.exitCode;\n\t}\n\tcontext.io.err(\n\t\t`npm-vm: ${error instanceof Error ? (error.stack ?? error.message) : String(error)}`,\n\t);\n\treturn EXIT.problems;\n}\n\ndeclare const NPM_VM_BUILD_VERSION: string | undefined;\n\n/** The build injects the package version; running from source reads the manifest instead. */\nfunction readSelfVersion(): string {\n\tif (typeof NPM_VM_BUILD_VERSION === 'string') {\n\t\treturn NPM_VM_BUILD_VERSION;\n\t}\n\ttry {\n\t\tconst manifest = JSON.parse(\n\t\t\treadFileSync(new URL('../../package.json', import.meta.url), 'utf8'),\n\t\t) as { version?: string };\n\t\treturn manifest.version ?? '0.0.0';\n\t} catch {\n\t\treturn '0.0.0';\n\t}\n}\n","#!/usr/bin/env node\nimport { run } from './commands/dispatch.ts';\n\nprocess.exitCode = await run(process.argv.slice(2), {});\n"],"mappings":"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"}
|