checkly 9.1.0-prerelease-d080e8d → 9.2.0-prerelease-2ea1376

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.
@@ -16,8 +16,8 @@
16
16
  - For pnpm projects, the workspace-root pnpmfile (`.pnpmfile.cjs` / `.pnpmfile.mjs`) is bundled automatically so the remote install can reproduce the lockfile — but only when the lockfile records a pnpmfile checksum (run `pnpm install` with the pnpmfile in place to record one; without it the pnpmfile is silently not bundled). The pnpmfile must also be self-contained: it may only load side-effect-free Node.js builtins (such as `path`, `crypto`, `util`) via literal `require('...')`/`import` specifiers, and must not reference `process`, `__dirname`, `import.meta`, or dynamically computed module paths. A pnpmfile that is not self-contained is skipped with a warning, and the remote install may re-resolve dependencies instead of using the lockfile. The pnpmfile is uploaded, so avoid embedding secrets in it.
17
17
  - In a workspace (monorepo) whose code bundle covers only part of the workspace, the bundled lockfile is pruned automatically so the remote install only fetches what the bundle needs, instead of failing on dependencies of workspace members that were left out.
18
18
  - Supported for `pnpm-lock.yaml` (v6/9), `package-lock.json` (v2/3), the text `bun.lock`, and Yarn Berry `yarn.lock`. Yarn Classic v1 lockfiles are not supported; for bun's binary `bun.lockb`, regenerate a text lockfile with `bun install --save-text-lockfile`.
19
- - The workspace's package manager binary must be available on the machine running the CLI.
20
- - When pruning was needed but cannot run or cannot verify its result, the original lockfile ships unchanged and the CLI prints a note explaining why — follow it. Skips are silent when there is nothing to prune, or when pruning is disabled via `CHECKLY_LOCKFILE_PRUNE=0`; silent skip reasons and per-entry embed match details are visible under `DEBUG='checkly:cli:services:check-parser:*'` and `DEBUG='checkly:cli:services:embedded-packages'`.
19
+ - The workspace's package manager binary must be available on the machine running the CLI. pnpm resolves against the workspace's own store plus cached registry metadata, npm reuses its cached metadata, and both only contact the registry for misses; yarn Berry and bun regenerate offline.
20
+ - When pruning was needed but cannot run or cannot verify its result, the original lockfile ships unchanged and the CLI prints a note explaining why — follow it (a timed-out prune's note names `CHECKLY_LOCKFILE_PRUNE_TIMEOUT=<seconds>`, which raises the default 30 s budget). Skips are silent when there is nothing to prune, or when pruning is disabled via `CHECKLY_LOCKFILE_PRUNE=0`; silent skip reasons, a timed-out prune's partial package manager output, and per-entry embed match details are visible under `DEBUG='checkly:cli:services:check-parser:*'` and `DEBUG='checkly:cli:services:embedded-packages'`.
21
21
  - For pnpm projects with `patchedDependencies`, patches belonging to unbundled workspace members are filtered out automatically. A note naming stale patch declarations means the lockfile is out of date with the config — refresh it with a regular install.
22
22
  - Checkly caches installed dependencies between runs, keyed off the workspace's dependency inputs (the lock file, every workspace member's `package.json` and `.npmrc` — whether or not the member is in the bundle) plus the bundle's own install inputs, so the key can change without a file edit, e.g. when a different set of workspace members lands in the bundle. To force a reinstall for deployed checks, set `runner.cache.install.version` (a string or a safe integer) at the top level of `checkly.config.ts` — not per check — and change its value whenever the cache should be invalidated; deployed, scheduled checks pick up the change on the next `checkly deploy`. If the config still declares the deprecated `caching.dependencyCache.version`, remove it — setting both fails config loading. Unset or empty values leave the cache key unchanged, so a dynamic value such as `version: process.env.DEPENDENCY_CACHE_VERSION` is safe when the variable is not always set. For a one-off reinstall during an ad-hoc run, use the `--refresh-cache` flag on `checkly test`, `checkly pw-test`, `checkly trigger`, or `checkly checks run` instead.
23
23
  - If dependencies come from a private registry that Checkly's infrastructure cannot reach (for example an intranet-only Nexus mirror), list them in `bundle.packages.embed` in `checkly.config.ts` — a top-level section: `bundle: { packages: { embed: ['@acme/private-utils', 'legacy-private-pkg@2.1.0'] } }`. The CLI resolves the entries against the workspace-root lockfile (Yarn Classic v1 lockfiles are not supported), downloads their tarballs, verifies each tarball's integrity (recorded in the lockfile, or fetched from registry metadata for Yarn Berry), and ships them inside the code bundle so the runner can install them without reaching the registry. Applies to Playwright Check Suites only, not Browser or Multistep Checks.
@@ -11,7 +11,7 @@ export interface PlaywrightCheckProps extends Omit<RuntimeCheckProps, 'retryStra
11
11
  * The JavaScript engine used to run the Playwright tests.
12
12
  * Use {@link Engine.node} or {@link Engine.bun} to create an engine instance.
13
13
  * When omitted, the CLI auto-detects from project version files
14
- * (.node-version, .nvmrc, .tool-versions, .bun-version, or package.json engines).
14
+ * (.node-version, .nvmrc, .tool-versions, .bun-version, or package.json volta/engines).
15
15
  *
16
16
  * @example Engine.node('24')
17
17
  * @example Engine.bun('1.3')
@@ -216,7 +216,8 @@ export class PlaywrightCheck extends RuntimeCheck {
216
216
  }
217
217
  async #resolveEngine(diagnostics) {
218
218
  if (!this.engine && Session.basePath) {
219
- Session.detectedEnginePromise ??= detectEngine(Session.basePath).then(e => e ?? null);
219
+ Session.detectedEnginePromise ??= detectEngine(Session.basePath, Session.contextPath)
220
+ .then(e => e ?? null);
220
221
  const result = await Session.detectedEnginePromise;
221
222
  if (result) {
222
223
  this.engine = result.engine;
@@ -227,7 +228,7 @@ export class PlaywrightCheck extends RuntimeCheck {
227
228
  diagnostics.add(new Diagnostic('engine', new Error(notice
228
229
  + '\n\n'
229
230
  + `Hint: The value was automatically detected from your `
230
- + `project's version files (.node-version, .nvmrc, etc.). `
231
+ + `project's version files (.node-version, .nvmrc, package.json volta/engines, etc.). `
231
232
  + `To override, set "engine" explicitly using Engine.node() `
232
233
  + `or Engine.bun().`)));
233
234
  }
@@ -1 +1 @@
1
- {"version":3,"file":"playwright-check.js","sourceRoot":"","sources":["../../src/constructs/playwright-check.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"playwright-check.js","sourceRoot":"","sources":["../../src/constructs/playwright-check.ts"],"names":[],"mappings":"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"}
@@ -93,6 +93,17 @@ export declare function shouldPruneLockfile(workspace: Workspace, files: Readonl
93
93
  * lockfile matches the remote install's inputs.
94
94
  */
95
95
  export declare function selectMaterializationEntries(files: ReadonlyMap<string, File>, lockfileArchivePath: string): Array<[string, File]>;
96
+ /**
97
+ * Scrubs credentials from package manager output before it is surfaced
98
+ * anywhere. Every http(s) URL is collapsed to scheme and host by
99
+ * `redactUrl`: registries carry tokens in userinfo, in the query string and
100
+ * in path segments (Gemfury-style `https://host/<token>/npm/`), and the host
101
+ * is all a stalled-request diagnosis needs. A scheme-less `//user:pw@host`
102
+ * (pnpm prints registry keys in that form) loses its userinfo. Redaction is
103
+ * by removal only; nothing is reconstructed from the credential-bearing
104
+ * parts.
105
+ */
106
+ export declare function redactDetail(detail: string): string;
96
107
  /**
97
108
  * Regenerates the bundle's lockfile so it matches the bundle's actual set of
98
109
  * manifests, by materializing the resolution-relevant bundle entries into a
@@ -9,7 +9,8 @@ import { parse as parseYaml } from 'yaml';
9
9
  import { createFauxPackageFiles } from './faux-package.js';
10
10
  import { isPnpmfilePath } from './package-files/pnpmfile.js';
11
11
  import { lineage } from './package-files/walk.js';
12
- import { PathLookup } from './package-files/package-manager.js';
12
+ import { PathLookup, Runnable } from './package-files/package-manager.js';
13
+ import { capList, redactUrl } from '../embedded-packages/diagnostics.js';
13
14
  import { pathToPosix } from '../util.js';
14
15
  const debug = Debug('checkly:cli:services:check-parser:lockfile-pruner');
15
16
  // A legitimate prune reuses resolutions from the lockfile and takes seconds
@@ -18,11 +19,96 @@ const debug = Debug('checkly:cli:services:check-parser:lockfile-pruner');
18
19
  // ends in a fallback anyway because the subset check rejects fresh
19
20
  // resolutions — so waiting minutes buys nothing.
20
21
  const DEFAULT_TIMEOUT_MS = 30_000;
21
- // The yarn version probe shares the install's budget; if it leaves the
22
- // install less than this, the prune is abandoned with a provisioning
23
- // message rather than spawning an install doomed to time out.
24
- const YARN_PROBE_MIN_INSTALL_BUDGET_MS = 1_000;
22
+ // A pre-install probe (yarn's version check, pnpm's store lookup) shares
23
+ // the install's budget, see PruneBudget; if it leaves the install less than
24
+ // this, the prune is abandoned with a message naming the probe rather than
25
+ // spawning an install doomed to time out.
26
+ const PROBE_MIN_INSTALL_BUDGET_MS = 1_000;
27
+ /**
28
+ * The prune's time budget, shared between the pre-install probes (yarn's
29
+ * version check, pnpm's store lookup) and the install itself, so the prune
30
+ * cannot block for longer than the documented timeout in total — a stalled
31
+ * first-use corepack download would otherwise be paid once per spawn. A
32
+ * total of 0 means "no timeout" (execa's own semantics), so nothing is
33
+ * ever exhausted then.
34
+ */
35
+ class PruneBudget {
36
+ totalMs;
37
+ #spentMs = 0;
38
+ constructor(totalMs) {
39
+ this.totalMs = totalMs;
40
+ }
41
+ /**
42
+ * execa timeout for the next spawn. Never 0 for a bounded budget: execa
43
+ * would read that as "no timeout".
44
+ */
45
+ get remainingMs() {
46
+ if (this.totalMs === 0) {
47
+ return 0;
48
+ }
49
+ return Math.max(this.totalMs - this.#spentMs, 1);
50
+ }
51
+ /**
52
+ * Whether a bounded budget has less than the install floor left, in
53
+ * which case spawning the install would only produce a misleading
54
+ * ~zero-length timeout.
55
+ */
56
+ get belowFloor() {
57
+ return this.totalMs > 0 && this.totalMs - this.#spentMs < PROBE_MIN_INSTALL_BUDGET_MS;
58
+ }
59
+ /**
60
+ * Spawns a child within the remaining budget and charges its wall-clock
61
+ * time. The timeout is read before the clock starts, so the first spawn
62
+ * reports exactly the configured budget when it times out. Returned
63
+ * alongside the result for that message.
64
+ */
65
+ async spawn(runnable, options) {
66
+ const timeoutMs = this.remainingMs;
67
+ const startedAt = Date.now();
68
+ const result = await execa(runnable.executable, runnable.args, {
69
+ cwd: options.cwd,
70
+ env: options.env,
71
+ extendEnv: false,
72
+ timeout: timeoutMs,
73
+ reject: false,
74
+ });
75
+ this.#spentMs += Date.now() - startedAt;
76
+ return { result, timeoutMs };
77
+ }
78
+ }
25
79
  const MAX_FAILURE_DETAIL_LENGTH = 400;
80
+ // Cap for the child's partial output logged at debug level when a prune
81
+ // times out. Generous enough to reach the stalled request past pnpm's
82
+ // progress lines, bounded so a chatty child cannot flood the log.
83
+ const MAX_DEBUG_OUTPUT_LENGTH = 8_192;
84
+ const TIMEOUT_HINT = 'set CHECKLY_LOCKFILE_PRUNE_TIMEOUT=<seconds> to raise it';
85
+ // Node's timers cannot represent a delay beyond 2^31-1 ms and would clamp a
86
+ // larger one to 1 ms, turning a "raise the budget" request into an instant
87
+ // timeout, so anything past that is rejected as unusable.
88
+ const MAX_TIMEOUT_SECONDS = Math.floor(2_147_483_647 / 1000);
89
+ /**
90
+ * Reads the prune time budget from CHECKLY_LOCKFILE_PRUNE_TIMEOUT, given in
91
+ * whole seconds; `0` disables the timeout (execa's own semantics). Anything
92
+ * else (unset, empty, negative, fractional, non-numeric, too large) yields
93
+ * undefined so the caller falls back to the default; an unusable value is
94
+ * only noted on the debug channel, since it cannot make a prune fail.
95
+ */
96
+ function timeoutFromEnv(env) {
97
+ const raw = env.CHECKLY_LOCKFILE_PRUNE_TIMEOUT;
98
+ if (raw === undefined || raw === '') {
99
+ return undefined;
100
+ }
101
+ if (!/^\d+$/.test(raw) || Number(raw) > MAX_TIMEOUT_SECONDS) {
102
+ debug(`Ignoring CHECKLY_LOCKFILE_PRUNE_TIMEOUT=${JSON.stringify(raw)}: not a whole number of seconds`
103
+ + ` up to ${MAX_TIMEOUT_SECONDS}`);
104
+ return undefined;
105
+ }
106
+ return Number(raw) * 1000;
107
+ }
108
+ /** Whole seconds where possible, so the reason matches the env var's unit. */
109
+ function formatBudget(timeoutMs) {
110
+ return timeoutMs % 1000 === 0 ? `${timeoutMs / 1000}s` : `${timeoutMs}ms`;
111
+ }
26
112
  /**
27
113
  * Environment keys that alter the very behavior the prune command pins with
28
114
  * explicit flags. Everything else (registry and auth configuration in
@@ -213,7 +299,10 @@ function parseLockfileSnapshot(content, lockfileName) {
213
299
  // is what the subset check needs.
214
300
  for (const section of ['packages', 'snapshots']) {
215
301
  for (const key of Object.keys(doc[section] ?? {})) {
216
- snapshot.resolutions.set(`${section}\0${key}`, '');
302
+ // The display name drops the peer suffix (`foo@1.0.0(bar@2.0.0)`)
303
+ // that the `snapshots` key carries and the `packages` key does not,
304
+ // so a re-resolved package is named once across the two sections.
305
+ snapshot.resolutions.set(`${section}\0${key}`, key.replace(/\(.*$/, ''));
217
306
  }
218
307
  }
219
308
  return snapshot;
@@ -255,7 +344,11 @@ function parseLockfileSnapshot(content, lockfileName) {
255
344
  isLink: entry.link === true,
256
345
  });
257
346
  if (entry.link !== true) {
258
- snapshot.resolutions.set(key, String(entry.version ?? entry.resolved ?? ''));
347
+ // Paths are unique per lockfile, so the version can ride along in
348
+ // the key to make a changed version an unknown entry.
349
+ const version = String(entry.version ?? entry.resolved ?? '');
350
+ const pinned = version === '' ? key : `${key}@${version}`;
351
+ snapshot.resolutions.set(pinned, pinned);
259
352
  }
260
353
  }
261
354
  return snapshot;
@@ -342,7 +435,8 @@ function parseLockfileSnapshot(content, lockfileName) {
342
435
  // still fail the check. Serialization is stable because both sides are
343
436
  // parsed from bun's own deterministic output by this same function.
344
437
  for (const tuple of Object.values(packages)) {
345
- snapshot.resolutions.set(JSON.stringify(tuple), '');
438
+ const name = Array.isArray(tuple) && typeof tuple[0] === 'string' ? tuple[0] : JSON.stringify(tuple);
439
+ snapshot.resolutions.set(JSON.stringify(tuple), name);
346
440
  }
347
441
  return snapshot;
348
442
  }
@@ -445,7 +539,7 @@ function parseLockfileSnapshot(content, lockfileName) {
445
539
  // dependencies) must still fail the check. Serialization is stable
446
540
  // because both sides are parsed from yarn's own deterministic
447
541
  // output by this same function.
448
- snapshot.resolutions.set(JSON.stringify(entry), '');
542
+ snapshot.resolutions.set(JSON.stringify(entry), resolution);
449
543
  continue;
450
544
  }
451
545
  // Workspace entries are the importers: their resolution carries the
@@ -516,12 +610,28 @@ function verifyPrunedLockfile(original, regenerated, files) {
516
610
  // lockfile was out of date with the bundled manifests and the package
517
611
  // manager resolved something fresh from the registry — versions the user
518
612
  // never installed or tested with.
519
- for (const [key, version] of regenerated.resolutions) {
520
- if (original.resolutions.get(key) !== version) {
521
- return `the regenerated lockfile resolves entries not present in the original `
522
- + `(is the lockfile out of date with package.json?)`;
613
+ // Collected by display name: pnpm records a re-resolved package under
614
+ // both `packages` and `snapshots`, which would otherwise list it twice.
615
+ const unexpected = new Set();
616
+ for (const [key, name] of regenerated.resolutions) {
617
+ if (!original.resolutions.has(key)) {
618
+ unexpected.add(name);
523
619
  }
524
620
  }
621
+ if (unexpected.size > 0) {
622
+ // Names can be URLs (tarball and git dependencies), so each is
623
+ // redacted on its own, after deduplication (two entries can redact to
624
+ // the same text) and before joining (a URL's redaction would swallow
625
+ // the separator after it). Only the length cap applies to the joined
626
+ // sample; the complete list goes to the debug channel.
627
+ const listed = [...unexpected].map(name => redactDetail(name));
628
+ if (debug.enabled) {
629
+ debug('%d unexpected resolution(s) in the regenerated lockfile: %s', listed.length, listed.join(', '));
630
+ }
631
+ return `the regenerated lockfile resolves entries not present in the original: `
632
+ + capDetail(capList(listed, ', ', ' and '))
633
+ + ` (is the lockfile out of date with package.json?)`;
634
+ }
525
635
  // Every dependency edge that was a workspace link and that still exists
526
636
  // must still be a link. Catches npm's silent registry substitution (a
527
637
  // member whose version does not satisfy a range is fetched from the
@@ -664,14 +774,65 @@ function buildChildEnv(baseEnv) {
664
774
  env.YARN_ENABLE_SCRIPTS = '0';
665
775
  return env;
666
776
  }
777
+ /**
778
+ * Scrubs credentials from package manager output before it is surfaced
779
+ * anywhere. Every http(s) URL is collapsed to scheme and host by
780
+ * `redactUrl`: registries carry tokens in userinfo, in the query string and
781
+ * in path segments (Gemfury-style `https://host/<token>/npm/`), and the host
782
+ * is all a stalled-request diagnosis needs. A scheme-less `//user:pw@host`
783
+ * (pnpm prints registry keys in that form) loses its userinfo. Redaction is
784
+ * by removal only; nothing is reconstructed from the credential-bearing
785
+ * parts.
786
+ */
787
+ export function redactDetail(detail) {
788
+ return detail
789
+ .replace(/https?:\/\/\S+/gi, url => redactUrl(url))
790
+ // Greedy up to the last '@' before the path, so an unencoded '@' inside
791
+ // the password does not leave its tail behind.
792
+ .replace(/\/\/[^/\s]+@/g, '//')
793
+ .trim();
794
+ }
667
795
  function sanitizeDetail(detail) {
668
- // Package manager output can embed registry URLs with userinfo credentials
669
- // (pnpm does not redact them); scrub before surfacing anywhere.
670
- const redacted = detail.replace(/\/\/[^/@\s]+@/g, '//').trim();
671
- if (redacted.length <= MAX_FAILURE_DETAIL_LENGTH) {
672
- return redacted;
796
+ return capDetail(redactDetail(detail));
797
+ }
798
+ /** The length cap alone, for text that is already redacted. */
799
+ function capDetail(detail) {
800
+ if (detail.length <= MAX_FAILURE_DETAIL_LENGTH) {
801
+ return detail;
802
+ }
803
+ return `${detail.slice(0, MAX_FAILURE_DETAIL_LENGTH)}…`;
804
+ }
805
+ /**
806
+ * Logs a child's stdout/stderr at debug level, redacted. Only the tail is
807
+ * kept: for a timed-out child the most recent output is where a stalled
808
+ * request shows, and a probe's answer is its last line. The user-facing
809
+ * reason stays a one-liner, so this is the only place the output survives.
810
+ */
811
+ function debugChildOutput(label, output, { timedOut }) {
812
+ if (!debug.enabled) {
813
+ return;
673
814
  }
674
- return `${redacted.slice(0, MAX_FAILURE_DETAIL_LENGTH)}…`;
815
+ for (const [stream, text] of [['stdout', output.stdout], ['stderr', output.stderr]]) {
816
+ const redacted = redactDetail(text ?? '');
817
+ if (redacted.length === 0) {
818
+ continue;
819
+ }
820
+ const tail = redacted.length <= MAX_DEBUG_OUTPUT_LENGTH
821
+ ? redacted
822
+ : `…${redacted.slice(-MAX_DEBUG_OUTPUT_LENGTH)}`;
823
+ // The output goes in as an argument, not the format string, so `%o`
824
+ // and `%%` sequences in it are printed verbatim.
825
+ debug(timedOut ? '%s timed out; partial %s:\n%s' : '%s %s:\n%s', label, stream, tail);
826
+ }
827
+ }
828
+ /**
829
+ * The first non-empty stream of a failed child, for the failure reason:
830
+ * stderr carries the error for most package managers, stdout for some,
831
+ * and execa's own message covers a child that never wrote at all.
832
+ */
833
+ function firstChildOutput(result) {
834
+ return [result.stderr, result.stdout, result.shortMessage]
835
+ .find(value => typeof value === 'string' && value.trim() !== '') ?? 'unknown error';
675
836
  }
676
837
  // Larger files are not plausible manifests; the cap also keeps a scan of a
677
838
  // shared temp root from slurping an arbitrarily large unrelated file.
@@ -704,6 +865,25 @@ function executableMissing(executable) {
704
865
  notable: true,
705
866
  };
706
867
  }
868
+ /**
869
+ * Classifies a failed spawn whose executable may simply be absent. On
870
+ * Windows a missing executable never surfaces as a spawn ENOENT: execa
871
+ * resolves the command itself (via which-command) and wraps an
872
+ * unresolvable command in cmd.exe, so the child "runs" and exits non-zero
873
+ * with cmd.exe's not-recognized message. Classify after the fact with a
874
+ * PATH probe — safe against probe/spawn resolution differences, because
875
+ * the command has already failed either way and only the reporting is at
876
+ * stake. Executables given as a path are left to the spawn's own error
877
+ * detail. Returns undefined when the executable exists, i.e. the failure
878
+ * is the command's own.
879
+ */
880
+ async function missingFromPath(executable) {
881
+ if (path.basename(executable) !== executable) {
882
+ return undefined;
883
+ }
884
+ const executablePath = await new PathLookup().lookupPath(executable);
885
+ return executablePath === undefined ? executableMissing(executable) : undefined;
886
+ }
707
887
  /**
708
888
  * Walks from `startDir` to the filesystem root looking for a package.json
709
889
  * that declares npm workspaces. The caller treats any hit as "this location
@@ -752,7 +932,10 @@ async function findWorkspaceAncestor(startDir) {
752
932
  * when the caller should fall back to the original lockfile.
753
933
  */
754
934
  export async function pruneBundledLockfile(options) {
755
- const { workspace, packageManager, files, rewrittenManifests = new Set(), timeoutMs = DEFAULT_TIMEOUT_MS, env = process.env, } = options;
935
+ const { workspace, packageManager, files, rewrittenManifests = new Set(), env = process.env, } = options;
936
+ // An explicit option (tests) outranks the environment; the destructuring
937
+ // carries no default so that an omitted option is distinguishable.
938
+ const timeoutMs = options.timeoutMs ?? timeoutFromEnv(env) ?? DEFAULT_TIMEOUT_MS;
756
939
  const decision = shouldPruneLockfile(workspace, files, env, rewrittenManifests);
757
940
  if (!decision.prune) {
758
941
  return { status: 'skipped', reason: decision.reason, notable: decision.notable };
@@ -766,7 +949,9 @@ export async function pruneBundledLockfile(options) {
766
949
  // unsupported package manager should always skip notably, never surface
767
950
  // a lockfile read error as a 'failed' warning that implies pruning was
768
951
  // attempted.
769
- const runnable = packageManager.lockfileOnlyInstallCommand();
952
+ // Reassigned once the store directory is known (see below), so every
953
+ // message past that point names the command that actually ran.
954
+ let runnable = packageManager.lockfileOnlyInstallCommand();
770
955
  if (runnable === undefined) {
771
956
  return {
772
957
  status: 'skipped',
@@ -886,49 +1071,36 @@ export async function pruneBundledLockfile(options) {
886
1071
  // below. Probe and install share the executable, cwd and env, so their
887
1072
  // version resolution cannot diverge.
888
1073
  const childEnv = buildChildEnv(env);
889
- // The probe shares the install's time budget so the yarn path cannot
890
- // block for longer than the documented timeout in total (a stalled
891
- // first-use corepack download would otherwise be paid twice).
892
- // timeoutMs === 0 means "no timeout" to execa, so the whole budget
893
- // dance is skipped in that case.
894
- let installTimeoutMs = timeoutMs;
1074
+ const budget = new PruneBudget(timeoutMs);
1075
+ const storeDirCommand = packageManager.storeDirCommand();
1076
+ // A whole budget below the install floor can never succeed when a probe
1077
+ // precedes the install (the yarn version check, the store lookup), so
1078
+ // reject it up front before the probe, whose own outcome under such
1079
+ // a budget would be a misleading "timed out" rather than this
1080
+ // caller-misconfiguration.
1081
+ if ((packageManager.name === 'yarn' || storeDirCommand !== undefined) && budget.belowFloor) {
1082
+ return {
1083
+ status: 'failed',
1084
+ reason: `the prune timeout (${timeoutMs}ms) is below the minimum needed to run ${packageManager.name}`,
1085
+ };
1086
+ }
895
1087
  if (packageManager.name === 'yarn') {
896
- // A whole budget below the install floor can never succeed (the yarn
897
- // path spends a probe plus an install), so reject it up front —
898
- // before the probe, whose own outcome under such a budget would be a
899
- // misleading "timed out" rather than this caller-misconfiguration.
900
- if (timeoutMs > 0 && timeoutMs < YARN_PROBE_MIN_INSTALL_BUDGET_MS) {
901
- return {
902
- status: 'failed',
903
- reason: `the prune timeout (${timeoutMs}ms) is below the minimum needed to run yarn`,
904
- };
905
- }
906
- const probeStartedAt = Date.now();
907
- const probe = await execa(runnable.executable, ['--version'], {
908
- cwd: tempDir,
909
- env: childEnv,
910
- extendEnv: false,
911
- timeout: timeoutMs,
912
- reject: false,
913
- });
1088
+ const { result: probe, timeoutMs: probeTimeoutMs } = await budget.spawn(new Runnable(runnable.executable, ['--version']), { cwd: tempDir, env: childEnv });
914
1089
  if (probe.timedOut) {
915
1090
  // The probe consumed the whole budget; spawning the install with
916
1091
  // the ~zero remainder would only produce a confusing second kill.
917
- return { status: 'failed', reason: `${runnable.executable} timed out after ${timeoutMs}ms` };
1092
+ debugChildOutput(`${runnable.executable} --version`, probe, { timedOut: true });
1093
+ return { status: 'failed', reason: `${runnable.executable} timed out after ${formatBudget(probeTimeoutMs)}; ${TIMEOUT_HINT}` };
918
1094
  }
919
- if (timeoutMs > 0) {
920
- const remaining = timeoutMs - (Date.now() - probeStartedAt);
921
- if (remaining < YARN_PROBE_MIN_INSTALL_BUDGET_MS) {
922
- // The probe (typically a slow first-use corepack toolchain
923
- // download) left too little for the install; a 1 ms install would
924
- // be a misleading second timeout, so say what actually happened.
925
- return {
926
- status: 'failed',
927
- reason: 'provisioning the yarn toolchain used up the prune time budget before the'
928
- + ' lockfile could be regenerated; pre-install yarn or raise the timeout',
929
- };
930
- }
931
- installTimeoutMs = remaining;
1095
+ if (budget.belowFloor) {
1096
+ // The probe (typically a slow first-use corepack toolchain
1097
+ // download) left too little for the install; a 1 ms install would
1098
+ // be a misleading second timeout, so say what actually happened.
1099
+ return {
1100
+ status: 'failed',
1101
+ reason: 'provisioning the yarn toolchain used up the prune time budget before the'
1102
+ + ` lockfile could be regenerated; pre-install yarn or ${TIMEOUT_HINT}`,
1103
+ };
932
1104
  }
933
1105
  const probeVersion = probe.failed ? '' : probe.stdout?.trim() ?? '';
934
1106
  const major = Number.parseInt(probeVersion, 10);
@@ -970,16 +1142,72 @@ export async function pruneBundledLockfile(options) {
970
1142
  childEnv.YARN_ENABLE_HARDENED_MODE = '0';
971
1143
  }
972
1144
  }
1145
+ // Pins the store the install resolves from to the workspace's own,
1146
+ // which pnpm would not pick for a temp dir on another filesystem (the
1147
+ // rationale is with PNpmDetector.lockfileOnlyInstallCommand). The
1148
+ // lookup runs in the WORKSPACE ROOT so it reads the workspace's own
1149
+ // config and applies pnpm's same-mount rule to the real project dir.
1150
+ // An unusable answer is a notable skip, not a failure: running against
1151
+ // an empty store is the very thing being avoided, and the remedy is
1152
+ // the package manager's installation or configuration, not the
1153
+ // lockfile.
1154
+ if (storeDirCommand !== undefined) {
1155
+ const display = storeDirCommand.unsafeDisplayCommand;
1156
+ const { result: probe, timeoutMs: probeTimeoutMs } = await budget.spawn(storeDirCommand, { cwd: workspace.root.path, env: childEnv });
1157
+ if (probe.timedOut) {
1158
+ debugChildOutput(display, probe, { timedOut: true });
1159
+ return { status: 'failed', reason: `${display} timed out after ${formatBudget(probeTimeoutMs)}; ${TIMEOUT_HINT}` };
1160
+ }
1161
+ debugChildOutput(display, probe, { timedOut: false });
1162
+ if (probe.code === 'ENOENT') {
1163
+ // execa also reports ENOENT for an invalid working directory, so
1164
+ // rule out a vanished workspace root before blaming the executable.
1165
+ if (!await directoryExists(workspace.root.path)) {
1166
+ return { status: 'failed', reason: `the workspace directory '${workspace.root.path}' disappeared` };
1167
+ }
1168
+ return executableMissing(storeDirCommand.executable);
1169
+ }
1170
+ if (budget.belowFloor) {
1171
+ return {
1172
+ status: 'failed',
1173
+ reason: `determining the ${packageManager.name} store directory used up the prune time budget before the`
1174
+ + ` lockfile could be regenerated; pre-install ${packageManager.name} or ${TIMEOUT_HINT}`,
1175
+ };
1176
+ }
1177
+ if (probe.failed || probe.exitCode !== 0) {
1178
+ const missing = await missingFromPath(storeDirCommand.executable);
1179
+ if (missing !== undefined) {
1180
+ return missing;
1181
+ }
1182
+ return {
1183
+ status: 'skipped',
1184
+ reason: `the ${packageManager.name} store directory could not be determined`
1185
+ + ` (${display} failed: ${sanitizeDetail(firstChildOutput(probe))})`,
1186
+ notable: true,
1187
+ };
1188
+ }
1189
+ // The path is the last non-empty line: pnpm 10's default reporter
1190
+ // can print warnings to stdout ahead of it. It must be absolute and
1191
+ // versioned (`<storeDir>/v10`) — anything else means the command's
1192
+ // output changed shape, and guessing would risk an empty store. The
1193
+ // PARENT is what gets pinned: pnpm appends its own version segment,
1194
+ // and the install's pnpm may be of another major than the lookup's.
1195
+ const printed = (probe.stdout ?? '').split(/\r?\n/).map(line => line.trim()).filter(line => line !== '').at(-1);
1196
+ if (printed === undefined || !path.isAbsolute(printed) || !/^v\d+$/.test(path.basename(printed))) {
1197
+ return {
1198
+ status: 'skipped',
1199
+ reason: `the ${packageManager.name} store directory could not be determined (${display} printed`
1200
+ + ` ${printed === undefined ? 'nothing' : `'${sanitizeDetail(printed)}'`} instead of a versioned store path)`,
1201
+ notable: true,
1202
+ };
1203
+ }
1204
+ runnable = packageManager.lockfileOnlyInstallCommand({ storeDir: path.dirname(printed) }) ?? runnable;
1205
+ }
973
1206
  debug(`Running ${runnable.unsafeDisplayCommand} in ${tempDir}`);
974
- const result = await execa(runnable.executable, runnable.args, {
975
- cwd: tempDir,
976
- env: childEnv,
977
- extendEnv: false,
978
- timeout: installTimeoutMs,
979
- reject: false,
980
- });
1207
+ const { result, timeoutMs: installTimeoutMs } = await budget.spawn(runnable, { cwd: tempDir, env: childEnv });
981
1208
  if (result.timedOut) {
982
- return { status: 'failed', reason: `${runnable.executable} timed out after ${installTimeoutMs}ms` };
1209
+ debugChildOutput(runnable.executable, result, { timedOut: true });
1210
+ return { status: 'failed', reason: `${runnable.executable} timed out after ${formatBudget(installTimeoutMs)}; ${TIMEOUT_HINT}` };
983
1211
  }
984
1212
  if (result.code === 'ENOENT') {
985
1213
  // A spawn ENOENT can also mean the working directory vanished (a temp
@@ -991,22 +1219,11 @@ export async function pruneBundledLockfile(options) {
991
1219
  return executableMissing(runnable.executable);
992
1220
  }
993
1221
  if (result.failed || result.exitCode !== 0) {
994
- // On Windows a missing executable never surfaces as a spawn ENOENT:
995
- // execa resolves the command itself (via which-command) and wraps an
996
- // unresolvable command in cmd.exe, so the child "runs" and exits
997
- // non-zero with cmd.exe's not-recognized message. Classify after the fact with a
998
- // PATH probe — safe against probe/spawn resolution differences,
999
- // because the command has already failed either way and only the
1000
- // reporting is at stake. Executables given as a path are left to the
1001
- // spawn's own error detail.
1002
- if (path.basename(runnable.executable) === runnable.executable) {
1003
- const executablePath = await new PathLookup().lookupPath(runnable.executable);
1004
- if (executablePath === undefined) {
1005
- return executableMissing(runnable.executable);
1006
- }
1222
+ const missing = await missingFromPath(runnable.executable);
1223
+ if (missing !== undefined) {
1224
+ return missing;
1007
1225
  }
1008
- const detail = [result.stderr, result.stdout, result.shortMessage]
1009
- .find(value => typeof value === 'string' && value.trim() !== '') ?? 'unknown error';
1226
+ const detail = firstChildOutput(result);
1010
1227
  // Yarn's blocked-request error is the network guard doing its job;
1011
1228
  // surfaced verbatim it reads like the user's own configuration is
1012
1229
  // broken. Name the two real causes instead — a stale lockfile, or a
@@ -1032,7 +1249,7 @@ export async function pruneBundledLockfile(options) {
1032
1249
  }
1033
1250
  return {
1034
1251
  status: 'failed',
1035
- reason: `${runnable.unsafeDisplayCommand} failed: ${sanitizeDetail(String(detail))}`,
1252
+ reason: `${runnable.unsafeDisplayCommand} failed: ${sanitizeDetail(detail)}`,
1036
1253
  };
1037
1254
  }
1038
1255
  let regeneratedContent;