omnius 1.0.882 → 1.0.883

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.
@@ -3178,7 +3178,7 @@ var require_util = __commonJS({
3178
3178
  }
3179
3179
  path3 = url.path;
3180
3180
  }
3181
- var isAbsolute7 = exports.isAbsolute(path3);
3181
+ var isAbsolute8 = exports.isAbsolute(path3);
3182
3182
  var parts = path3.split(/\/+/);
3183
3183
  for (var part, up = 0, i = parts.length - 1; i >= 0; i--) {
3184
3184
  part = parts[i];
@@ -3198,7 +3198,7 @@ var require_util = __commonJS({
3198
3198
  }
3199
3199
  path3 = parts.join("/");
3200
3200
  if (path3 === "") {
3201
- path3 = isAbsolute7 ? "/" : ".";
3201
+ path3 = isAbsolute8 ? "/" : ".";
3202
3202
  }
3203
3203
  if (url) {
3204
3204
  url.path = path3;
@@ -129580,7 +129580,7 @@ ${lanes.join("\n")}
129580
129580
  }
129581
129581
  }
129582
129582
  function createImportCallExpressionAMD(arg, containsLexicalThis) {
129583
- const resolve11 = factory2.createUniqueName("resolve");
129583
+ const resolve12 = factory2.createUniqueName("resolve");
129584
129584
  const reject = factory2.createUniqueName("reject");
129585
129585
  const parameters = [
129586
129586
  factory2.createParameterDeclaration(
@@ -129589,7 +129589,7 @@ ${lanes.join("\n")}
129589
129589
  /*dotDotDotToken*/
129590
129590
  void 0,
129591
129591
  /*name*/
129592
- resolve11
129592
+ resolve12
129593
129593
  ),
129594
129594
  factory2.createParameterDeclaration(
129595
129595
  /*modifiers*/
@@ -129606,7 +129606,7 @@ ${lanes.join("\n")}
129606
129606
  factory2.createIdentifier("require"),
129607
129607
  /*typeArguments*/
129608
129608
  void 0,
129609
- [factory2.createArrayLiteralExpression([arg || factory2.createOmittedExpression()]), resolve11, reject]
129609
+ [factory2.createArrayLiteralExpression([arg || factory2.createOmittedExpression()]), resolve12, reject]
129610
129610
  )
129611
129611
  )
129612
129612
  ]);
@@ -216517,8 +216517,8 @@ Additional information: BADCLIENT: Bad error code, ${badCode} not found in range
216517
216517
  installPackage(options) {
216518
216518
  this.packageInstallId++;
216519
216519
  const request = { kind: "installPackage", ...options, id: this.packageInstallId };
216520
- const promise = new Promise((resolve11, reject) => {
216521
- (this.packageInstalledPromise ?? (this.packageInstalledPromise = /* @__PURE__ */ new Map())).set(this.packageInstallId, { resolve: resolve11, reject });
216520
+ const promise = new Promise((resolve12, reject) => {
216521
+ (this.packageInstalledPromise ?? (this.packageInstalledPromise = /* @__PURE__ */ new Map())).set(this.packageInstallId, { resolve: resolve12, reject });
216522
216522
  });
216523
216523
  this.installer.send(request);
216524
216524
  return promise;
@@ -218778,7 +218778,7 @@ var require_path_browserify = __commonJS({
218778
218778
  }
218779
218779
  var posix = {
218780
218780
  // path.resolve([from ...], to)
218781
- resolve: function resolve11() {
218781
+ resolve: function resolve12() {
218782
218782
  var resolvedPath = "";
218783
218783
  var resolvedAbsolute = false;
218784
218784
  var cwd;
@@ -218813,15 +218813,15 @@ var require_path_browserify = __commonJS({
218813
218813
  normalize: function normalize(path3) {
218814
218814
  assertPath(path3);
218815
218815
  if (path3.length === 0) return ".";
218816
- var isAbsolute7 = path3.charCodeAt(0) === 47;
218816
+ var isAbsolute8 = path3.charCodeAt(0) === 47;
218817
218817
  var trailingSeparator = path3.charCodeAt(path3.length - 1) === 47;
218818
- path3 = normalizeStringPosix(path3, !isAbsolute7);
218819
- if (path3.length === 0 && !isAbsolute7) path3 = ".";
218818
+ path3 = normalizeStringPosix(path3, !isAbsolute8);
218819
+ if (path3.length === 0 && !isAbsolute8) path3 = ".";
218820
218820
  if (path3.length > 0 && trailingSeparator) path3 += "/";
218821
- if (isAbsolute7) return "/" + path3;
218821
+ if (isAbsolute8) return "/" + path3;
218822
218822
  return path3;
218823
218823
  },
218824
- isAbsolute: function isAbsolute7(path3) {
218824
+ isAbsolute: function isAbsolute8(path3) {
218825
218825
  assertPath(path3);
218826
218826
  return path3.length > 0 && path3.charCodeAt(0) === 47;
218827
218827
  },
@@ -219035,9 +219035,9 @@ var require_path_browserify = __commonJS({
219035
219035
  var ret = { root: "", dir: "", base: "", ext: "", name: "" };
219036
219036
  if (path3.length === 0) return ret;
219037
219037
  var code = path3.charCodeAt(0);
219038
- var isAbsolute7 = code === 47;
219038
+ var isAbsolute8 = code === 47;
219039
219039
  var start;
219040
- if (isAbsolute7) {
219040
+ if (isAbsolute8) {
219041
219041
  ret.root = "/";
219042
219042
  start = 1;
219043
219043
  } else {
@@ -219073,11 +219073,11 @@ var require_path_browserify = __commonJS({
219073
219073
  preDotState === 0 || // The (right-most) trimmed path component is exactly '..'
219074
219074
  preDotState === 1 && startDot === end - 1 && startDot === startPart + 1) {
219075
219075
  if (end !== -1) {
219076
- if (startPart === 0 && isAbsolute7) ret.base = ret.name = path3.slice(1, end);
219076
+ if (startPart === 0 && isAbsolute8) ret.base = ret.name = path3.slice(1, end);
219077
219077
  else ret.base = ret.name = path3.slice(startPart, end);
219078
219078
  }
219079
219079
  } else {
219080
- if (startPart === 0 && isAbsolute7) {
219080
+ if (startPart === 0 && isAbsolute8) {
219081
219081
  ret.name = path3.slice(1, startDot);
219082
219082
  ret.base = path3.slice(1, end);
219083
219083
  } else {
@@ -219087,7 +219087,7 @@ var require_path_browserify = __commonJS({
219087
219087
  ret.ext = path3.slice(startDot, end);
219088
219088
  }
219089
219089
  if (startPart > 0) ret.dir = path3.slice(0, startPart - 1);
219090
- else if (isAbsolute7) ret.dir = "/";
219090
+ else if (isAbsolute8) ret.dir = "/";
219091
219091
  return ret;
219092
219092
  },
219093
219093
  sep: "/",
@@ -219700,7 +219700,7 @@ var require_scan = __commonJS({
219700
219700
  var require_parse = __commonJS({
219701
219701
  "node_modules/.pnpm/picomatch@4.0.4/node_modules/picomatch/lib/parse.js"(exports, module) {
219702
219702
  "use strict";
219703
- var constants2 = require_constants();
219703
+ var constants3 = require_constants();
219704
219704
  var utils = require_utils();
219705
219705
  var {
219706
219706
  MAX_LENGTH,
@@ -219708,7 +219708,7 @@ var require_parse = __commonJS({
219708
219708
  REGEX_NON_SPECIAL_CHARS,
219709
219709
  REGEX_SPECIAL_CHARS_BACKREF,
219710
219710
  REPLACEMENTS
219711
- } = constants2;
219711
+ } = constants3;
219712
219712
  var expandRange = (args, options) => {
219713
219713
  if (typeof options.expandRange === "function") {
219714
219714
  return options.expandRange(...args, options);
@@ -219914,7 +219914,7 @@ var require_parse = __commonJS({
219914
219914
  if (options.maxExtglobRecursion === false) {
219915
219915
  return { risky: false };
219916
219916
  }
219917
- const max = typeof options.maxExtglobRecursion === "number" ? options.maxExtglobRecursion : constants2.DEFAULT_MAX_EXTGLOB_RECURSION;
219917
+ const max = typeof options.maxExtglobRecursion === "number" ? options.maxExtglobRecursion : constants3.DEFAULT_MAX_EXTGLOB_RECURSION;
219918
219918
  const branches = splitTopLevel(body).map((branch) => branch.trim());
219919
219919
  if (branches.length > 1) {
219920
219920
  if (branches.some((branch) => branch === "") || branches.some((branch) => /^[*?]+$/.test(branch)) || hasRepeatedCharPrefixOverlap(branches)) {
@@ -219946,8 +219946,8 @@ var require_parse = __commonJS({
219946
219946
  const bos = { type: "bos", value: "", output: opts.prepend || "" };
219947
219947
  const tokens = [bos];
219948
219948
  const capture = opts.capture ? "" : "?:";
219949
- const PLATFORM_CHARS = constants2.globChars(opts.windows);
219950
- const EXTGLOB_CHARS = constants2.extglobChars(PLATFORM_CHARS);
219949
+ const PLATFORM_CHARS = constants3.globChars(opts.windows);
219950
+ const EXTGLOB_CHARS = constants3.extglobChars(PLATFORM_CHARS);
219951
219951
  const {
219952
219952
  DOT_LITERAL,
219953
219953
  PLUS_LITERAL,
@@ -220642,7 +220642,7 @@ var require_parse = __commonJS({
220642
220642
  NO_DOTS_SLASH,
220643
220643
  STAR,
220644
220644
  START_ANCHOR
220645
- } = constants2.globChars(opts.windows);
220645
+ } = constants3.globChars(opts.windows);
220646
220646
  const nodot = opts.dot ? NO_DOTS : NO_DOT;
220647
220647
  const slashDot = opts.dot ? NO_DOTS_SLASH : NO_DOT;
220648
220648
  const capture = opts.capture ? "" : "?:";
@@ -220700,7 +220700,7 @@ var require_picomatch = __commonJS({
220700
220700
  var scan = require_scan();
220701
220701
  var parse2 = require_parse();
220702
220702
  var utils = require_utils();
220703
- var constants2 = require_constants();
220703
+ var constants3 = require_constants();
220704
220704
  var isObject = (val) => val && typeof val === "object" && !Array.isArray(val);
220705
220705
  var picomatch = (glob2, options, returnState = false) => {
220706
220706
  if (Array.isArray(glob2)) {
@@ -220828,7 +220828,7 @@ var require_picomatch = __commonJS({
220828
220828
  return /$^/;
220829
220829
  }
220830
220830
  };
220831
- picomatch.constants = constants2;
220831
+ picomatch.constants = constants3;
220832
220832
  module.exports = picomatch;
220833
220833
  }
220834
220834
  });
@@ -222969,12 +222969,12 @@ ${nodeLocation}` : message;
222969
222969
  };
222970
222970
  var NodeRuntimeFileSystem = class {
222971
222971
  delete(path4) {
222972
- return new Promise((resolve11, reject) => {
222972
+ return new Promise((resolve12, reject) => {
222973
222973
  fs__namespace.rm(path4, { recursive: true }, (err) => {
222974
222974
  if (err)
222975
222975
  reject(err);
222976
222976
  else
222977
- resolve11();
222977
+ resolve12();
222978
222978
  });
222979
222979
  });
222980
222980
  }
@@ -222993,12 +222993,12 @@ ${nodeLocation}` : message;
222993
222993
  }));
222994
222994
  }
222995
222995
  readFile(filePath, encoding = "utf-8") {
222996
- return new Promise((resolve11, reject) => {
222996
+ return new Promise((resolve12, reject) => {
222997
222997
  fs__namespace.readFile(filePath, encoding, (err, data) => {
222998
222998
  if (err)
222999
222999
  reject(err);
223000
223000
  else
223001
- resolve11(data);
223001
+ resolve12(data);
223002
223002
  });
223003
223003
  });
223004
223004
  }
@@ -223006,12 +223006,12 @@ ${nodeLocation}` : message;
223006
223006
  return fs__namespace.readFileSync(filePath, encoding);
223007
223007
  }
223008
223008
  async writeFile(filePath, fileText) {
223009
- await new Promise((resolve11, reject) => {
223009
+ await new Promise((resolve12, reject) => {
223010
223010
  fs__namespace.writeFile(filePath, fileText, (err) => {
223011
223011
  if (err)
223012
223012
  reject(err);
223013
223013
  else
223014
- resolve11();
223014
+ resolve12();
223015
223015
  });
223016
223016
  });
223017
223017
  }
@@ -223025,12 +223025,12 @@ ${nodeLocation}` : message;
223025
223025
  fs__namespace.mkdirSync(dirPath, { recursive: true });
223026
223026
  }
223027
223027
  move(srcPath, destPath) {
223028
- return new Promise((resolve11, reject) => {
223028
+ return new Promise((resolve12, reject) => {
223029
223029
  fs__namespace.rename(srcPath, destPath, (err) => {
223030
223030
  if (err)
223031
223031
  reject(err);
223032
223032
  else
223033
- resolve11();
223033
+ resolve12();
223034
223034
  });
223035
223035
  });
223036
223036
  }
@@ -223038,12 +223038,12 @@ ${nodeLocation}` : message;
223038
223038
  fs__namespace.renameSync(srcPath, destPath);
223039
223039
  }
223040
223040
  copy(srcPath, destPath) {
223041
- return new Promise((resolve11, reject) => {
223041
+ return new Promise((resolve12, reject) => {
223042
223042
  fs__namespace.copyFile(srcPath, destPath, (err) => {
223043
223043
  if (err)
223044
223044
  reject(err);
223045
223045
  else
223046
- resolve11();
223046
+ resolve12();
223047
223047
  });
223048
223048
  });
223049
223049
  }
@@ -223051,15 +223051,15 @@ ${nodeLocation}` : message;
223051
223051
  fs__namespace.copyFileSync(srcPath, destPath);
223052
223052
  }
223053
223053
  stat(path4) {
223054
- return new Promise((resolve11, reject) => {
223054
+ return new Promise((resolve12, reject) => {
223055
223055
  fs__namespace.stat(path4, (err, stat) => {
223056
223056
  if (err) {
223057
223057
  if (err.code === "ENOENT" || err.code === "ENOTDIR")
223058
- resolve11(void 0);
223058
+ resolve12(void 0);
223059
223059
  else
223060
223060
  reject(err);
223061
223061
  } else {
223062
- resolve11(stat);
223062
+ resolve12(stat);
223063
223063
  }
223064
223064
  });
223065
223065
  });
@@ -299674,7 +299674,7 @@ async function getDaemonReportedIdentity(port) {
299674
299674
  async function waitForDaemonReady(port, expectedVersion, attempts = 24) {
299675
299675
  let observedVersion = null;
299676
299676
  for (let attempt = 0; attempt < attempts; attempt++) {
299677
- await new Promise((resolve11) => setTimeout(resolve11, 500));
299677
+ await new Promise((resolve12) => setTimeout(resolve12, 500));
299678
299678
  const identity = await getDaemonReportedIdentity(port);
299679
299679
  if (!identity) continue;
299680
299680
  observedVersion = identity.bootVersion;
@@ -299685,10 +299685,10 @@ async function waitForDaemonReady(port, expectedVersion, attempts = 24) {
299685
299685
  return { ok: false, observedVersion };
299686
299686
  }
299687
299687
  function delay(ms) {
299688
- return new Promise((resolve11) => setTimeout(resolve11, ms));
299688
+ return new Promise((resolve12) => setTimeout(resolve12, ms));
299689
299689
  }
299690
299690
  function runUtilityCommand(command, args, timeout) {
299691
- return new Promise((resolve11) => {
299691
+ return new Promise((resolve12) => {
299692
299692
  let settled = false;
299693
299693
  let stdout = "";
299694
299694
  let stderr = "";
@@ -299698,7 +299698,7 @@ function runUtilityCommand(command, args, timeout) {
299698
299698
  if (settled) return;
299699
299699
  settled = true;
299700
299700
  if (timer) clearTimeout(timer);
299701
- resolve11({ available, code, stdout, stderr });
299701
+ resolve12({ available, code, stdout, stderr });
299702
299702
  };
299703
299703
  let child;
299704
299704
  try {
@@ -299707,7 +299707,7 @@ function runUtilityCommand(command, args, timeout) {
299707
299707
  windowsHide: true
299708
299708
  });
299709
299709
  } catch {
299710
- resolve11({ available: false, code: null, stdout: "", stderr: "" });
299710
+ resolve12({ available: false, code: null, stdout: "", stderr: "" });
299711
299711
  return;
299712
299712
  }
299713
299713
  child.stdout?.setEncoding("utf8");
@@ -299863,13 +299863,13 @@ async function portHolderPids(port) {
299863
299863
  return daemonListenerPids(port);
299864
299864
  }
299865
299865
  async function daemonPortIsFree(port) {
299866
- return new Promise((resolve11) => {
299866
+ return new Promise((resolve12) => {
299867
299867
  const probe = createNetServer();
299868
299868
  let settled = false;
299869
299869
  const finish = (free) => {
299870
299870
  if (settled) return;
299871
299871
  settled = true;
299872
- resolve11(free);
299872
+ resolve12(free);
299873
299873
  };
299874
299874
  probe.once("error", () => finish(false));
299875
299875
  probe.once("listening", () => {
@@ -300178,26 +300178,26 @@ async function quiesceDaemonForUpdate(port = getDaemonPort()) {
300178
300178
  import { spawn as spawn2 } from "node:child_process";
300179
300179
  import { createHash as createHash3, randomUUID as randomUUID3 } from "node:crypto";
300180
300180
  import {
300181
- constants,
300181
+ constants as constants2,
300182
300182
  chmodSync,
300183
- closeSync as closeSync3,
300183
+ closeSync as closeSync4,
300184
300184
  existsSync as existsSync6,
300185
300185
  fchmodSync,
300186
- fstatSync,
300187
- fsyncSync,
300188
- lstatSync,
300186
+ fstatSync as fstatSync2,
300187
+ fsyncSync as fsyncSync2,
300188
+ lstatSync as lstatSync2,
300189
300189
  mkdirSync as mkdirSync5,
300190
- openSync as openSync3,
300191
- readFileSync as readFileSync6,
300192
- readSync as readSync2,
300190
+ openSync as openSync4,
300191
+ readFileSync as readFileSync7,
300192
+ readSync as readSync3,
300193
300193
  renameSync as renameSync4,
300194
300194
  statSync as statSync3,
300195
- unlinkSync as unlinkSync3,
300196
- writeFileSync as writeFileSync4,
300195
+ unlinkSync as unlinkSync4,
300196
+ writeFileSync as writeFileSync5,
300197
300197
  writeSync as writeSync2
300198
300198
  } from "node:fs";
300199
300199
  import { homedir as homedir15 } from "node:os";
300200
- import { dirname as dirname9, join as join16 } from "node:path";
300200
+ import { dirname as dirname9, isAbsolute as isAbsolute7, join as join16, resolve as resolve11 } from "node:path";
300201
300201
 
300202
300202
  // packages/cli/src/service-version.ts
300203
300203
  var OmniusVersionError = class extends Error {
@@ -300254,8 +300254,16 @@ function compareOmniusVersions(left, right) {
300254
300254
 
300255
300255
  // packages/cli/src/npm-install-recovery.ts
300256
300256
  import { createHash as createHash2, randomUUID as randomUUID2 } from "node:crypto";
300257
+ import { closeSync as closeSync3, constants, fstatSync, fsyncSync, lstatSync, openSync as openSync3, readFileSync as readFileSync6, readSync as readSync2, unlinkSync as unlinkSync3, writeFileSync as writeFileSync4 } from "node:fs";
300257
300258
  import { lstat, realpath, rename, rm } from "node:fs/promises";
300258
300259
  import { basename as basename8, dirname as dirname8, isAbsolute as isAbsolute6, join as join15, resolve as resolve10 } from "node:path";
300260
+ var NpmInstallBusyError = class extends Error {
300261
+ code = "NPM_INSTALL_BUSY";
300262
+ constructor(message = "Another installer owns this npm modules directory. Wait for it to settle before retrying.") {
300263
+ super(message);
300264
+ this.name = "NpmInstallBusyError";
300265
+ }
300266
+ };
300259
300267
  function parseNpmRenameCollision(diagnostic) {
300260
300268
  const fields = /* @__PURE__ */ new Map();
300261
300269
  let previousPathField = false;
@@ -300288,15 +300296,21 @@ function assertOwnedDirectory(metadata, label) {
300288
300296
  }
300289
300297
  }
300290
300298
  async function recoverNpmRetirementCollision(collision, modulesRoot, options = {}) {
300299
+ assertNotCancelled(options.signal);
300300
+ if (collision.code !== "ENOTEMPTY" && collision.code !== "EEXIST" || collision.syscall !== "rename" || !isAbsolute6(modulesRoot) || /[\x00-\x1f\x7f]/.test(modulesRoot + collision.path + collision.dest)) return null;
300301
+ const root = resolve10(modulesRoot), source = join15(root, "omnius"), retired = retiredNpmPackagePath(source);
300302
+ if (collision.path !== source || collision.dest !== retired || dirname8(retired) !== root) return null;
300303
+ return prepareNpmRetirementSlot(root, options);
300304
+ }
300305
+ async function prepareNpmRetirementSlot(modulesRoot, options = {}) {
300291
300306
  const current = () => {
300292
300307
  assertNotCancelled(options.signal);
300293
300308
  options.assertOwned?.();
300294
300309
  assertNotCancelled(options.signal);
300295
300310
  };
300296
300311
  current();
300297
- if (collision.code !== "ENOTEMPTY" && collision.code !== "EEXIST" || collision.syscall !== "rename" || !isAbsolute6(modulesRoot) || /[\x00-\x1f\x7f]/.test(modulesRoot + collision.path + collision.dest)) return null;
300298
- const root = resolve10(modulesRoot), source = join15(root, "omnius"), retired = retiredNpmPackagePath(source);
300299
- if (collision.path !== source || collision.dest !== retired || dirname8(retired) !== root) return null;
300312
+ if (!isAbsolute6(modulesRoot) || /[\x00-\x1f\x7f]/.test(modulesRoot)) throw new Error("npm modules root must be an absolute directory path.");
300313
+ const root = resolve10(modulesRoot), retired = retiredNpmPackagePath(join15(root, "omnius"));
300300
300314
  const rootBefore = await lstat(root);
300301
300315
  assertOwnedDirectory(rootBefore, "global modules root");
300302
300316
  const canonicalRoot = await realpath(root);
@@ -300309,14 +300323,157 @@ async function recoverNpmRetirementCollision(collision, modulesRoot, options = {
300309
300323
  }
300310
300324
  assertOwnedDirectory(before, "retired package");
300311
300325
  const backup = join15(root, `.omnius-update-recovery-${randomUUID2()}`);
300326
+ const receipt = { modulesRoot: root, retiredPath: retired, backupPath: backup, device: before.dev, inode: before.ino };
300312
300327
  current();
300328
+ await options.onPrepare?.({ ...receipt });
300329
+ current();
300330
+ try {
300331
+ await lstat(backup);
300332
+ throw new Error("The planned npm retirement backup is already occupied; no directory was moved.");
300333
+ } catch (error) {
300334
+ if (error.code !== "ENOENT") throw error;
300335
+ }
300313
300336
  const [rootNow, candidateNow] = await Promise.all([lstat(root), lstat(retired)]);
300314
300337
  if (!sameIdentity(rootBefore, rootNow) || !sameIdentity(before, candidateNow) || await realpath(root) !== canonicalRoot) throw new Error("npm retirement directory changed before recovery; no cleanup was attempted.");
300315
300338
  assertOwnedDirectory(rootNow, "global modules root");
300316
300339
  assertOwnedDirectory(candidateNow, "retired package");
300317
300340
  current();
300318
300341
  await rename(retired, backup);
300319
- return { modulesRoot: root, retiredPath: retired, backupPath: backup, device: before.dev, inode: before.ino };
300342
+ return receipt;
300343
+ }
300344
+ function processIdentity(pid) {
300345
+ if (process.platform !== "linux") return;
300346
+ try {
300347
+ const raw = readFileSync6(`/proc/${pid}/stat`, "utf8"), fields = raw.slice(raw.lastIndexOf(")") + 2).trim().split(/\s+/);
300348
+ if (!/^\d+$/.test(fields[19] ?? "")) return;
300349
+ return readFileSync6("/proc/sys/kernel/random/boot_id", "utf8").trim() + ":" + fields[19];
300350
+ } catch {
300351
+ return;
300352
+ }
300353
+ }
300354
+ function readInstallOwner(path3) {
300355
+ const before = lstatSync(path3);
300356
+ const valid = (value) => value.isFile() && !value.isSymbolicLink() && value.size > 0 && value.size <= 4096 && value.nlink === 1 && (process.platform === "win32" || value.uid === process.getuid?.() && (value.mode & 63) === 0);
300357
+ if (!valid(before)) throw new NpmInstallBusyError("The npm install owner record is unsafe or unknown; it was retained for inspection.");
300358
+ const fd = openSync3(path3, constants.O_RDONLY | constants.O_NOFOLLOW | constants.O_NONBLOCK);
300359
+ try {
300360
+ const metadata = fstatSync(fd);
300361
+ if (!valid(metadata) || !sameIdentity(before, metadata)) throw new NpmInstallBusyError("The npm install owner record changed; no lock was removed.");
300362
+ const data = Buffer.alloc(4097);
300363
+ let size = 0;
300364
+ while (size < data.length) {
300365
+ const count = readSync2(fd, data, size, data.length - size, null);
300366
+ if (!count) break;
300367
+ size += count;
300368
+ }
300369
+ if (size > 4096) throw new NpmInstallBusyError("The npm install owner record is too large; it was retained.");
300370
+ let value;
300371
+ try {
300372
+ value = JSON.parse(data.subarray(0, size).toString("utf8"));
300373
+ } catch {
300374
+ throw new NpmInstallBusyError("The npm install owner record is malformed; it was retained.");
300375
+ }
300376
+ const owner = value;
300377
+ if (!owner || typeof owner !== "object" || Array.isArray(owner) || owner.schema_version !== 1 || typeof owner.nonce !== "string" || !/^[a-f0-9-]{36}$/.test(owner.nonce) || !Number.isSafeInteger(owner.pid) || owner.pid <= 0 || owner.pid > 2147483647 || owner.process_identity !== void 0 && (typeof owner.process_identity !== "string" || !/^[a-f0-9-]{36}:\d+$/.test(owner.process_identity)) || owner.operation_id !== void 0 && (typeof owner.operation_id !== "string" || !/^[a-zA-Z0-9_-]{1,128}$/.test(owner.operation_id)) || Object.keys(owner).some((key) => !["schema_version", "nonce", "pid", "process_identity", "operation_id"].includes(key))) {
300378
+ throw new NpmInstallBusyError("The npm install owner identity is unknown; its lock was retained.");
300379
+ }
300380
+ return { owner, metadata };
300381
+ } finally {
300382
+ closeSync3(fd);
300383
+ }
300384
+ }
300385
+ function provedAbsent(owner) {
300386
+ try {
300387
+ process.kill(owner.pid, 0);
300388
+ } catch (error) {
300389
+ return error.code === "ESRCH";
300390
+ }
300391
+ const current = processIdentity(owner.pid);
300392
+ return Boolean(owner.process_identity && current && owner.process_identity !== current);
300393
+ }
300394
+ async function acquireNpmInstallLease(modulesRoot, options = {}) {
300395
+ assertNotCancelled(options.signal);
300396
+ if (!isAbsolute6(modulesRoot) || /[\x00-\x1f\x7f]/.test(modulesRoot) || options.operationId !== void 0 && !/^[a-zA-Z0-9_-]{1,128}$/.test(options.operationId)) throw new Error("Invalid npm install scope.");
300397
+ const logical = resolve10(modulesRoot), logicalMetadata = await lstat(logical);
300398
+ assertOwnedDirectory(logicalMetadata, "global modules root");
300399
+ const root = await realpath(logical), rootMetadata = await lstat(root);
300400
+ assertOwnedDirectory(rootMetadata, "global modules root");
300401
+ if (!sameIdentity(logicalMetadata, rootMetadata)) throw new Error("npm modules root changed before installer admission.");
300402
+ const lockPath = join15(root, ".omnius-install.lock"), guardPath = lockPath + ".guard", nonce = randomUUID2();
300403
+ const assertRoot = () => {
300404
+ const current = lstatSync(root);
300405
+ assertOwnedDirectory(current, "global modules root");
300406
+ if (!sameIdentity(rootMetadata, current)) throw new Error("npm modules root changed; no installer may proceed.");
300407
+ };
300408
+ const withGuard = (action) => {
300409
+ assertRoot();
300410
+ let fd;
300411
+ try {
300412
+ fd = openSync3(guardPath, constants.O_WRONLY | constants.O_CREAT | constants.O_EXCL | constants.O_NOFOLLOW, 384);
300413
+ } catch (error) {
300414
+ if (error.code === "EEXIST") throw new NpmInstallBusyError("npm installer ownership is being checked, or its short guard was interrupted; no guard was stolen.");
300415
+ throw error;
300416
+ }
300417
+ const metadata = fstatSync(fd), guardNonce = randomUUID2();
300418
+ try {
300419
+ writeFileSync4(fd, JSON.stringify({ schema_version: 1, nonce: guardNonce, pid: process.pid, process_identity: processIdentity(process.pid) }));
300420
+ fsyncSync(fd);
300421
+ return action();
300422
+ } finally {
300423
+ try {
300424
+ const current = readInstallOwner(guardPath);
300425
+ if (sameIdentity(metadata, current.metadata) && current.owner.nonce === guardNonce) unlinkSync3(guardPath);
300426
+ } finally {
300427
+ closeSync3(fd);
300428
+ }
300429
+ }
300430
+ };
300431
+ let lockMetadata;
300432
+ withGuard(() => {
300433
+ assertNotCancelled(options.signal);
300434
+ try {
300435
+ const previous = readInstallOwner(lockPath);
300436
+ if (!provedAbsent(previous.owner)) throw new NpmInstallBusyError();
300437
+ const checked = readInstallOwner(lockPath);
300438
+ if (!sameIdentity(previous.metadata, checked.metadata) || checked.owner.nonce !== previous.owner.nonce) throw new NpmInstallBusyError("npm install ownership changed while checking its old owner.");
300439
+ unlinkSync3(lockPath);
300440
+ } catch (error) {
300441
+ if (error.code !== "ENOENT") throw error;
300442
+ }
300443
+ assertNotCancelled(options.signal);
300444
+ assertRoot();
300445
+ const fd = openSync3(lockPath, constants.O_WRONLY | constants.O_CREAT | constants.O_EXCL | constants.O_NOFOLLOW, 384);
300446
+ try {
300447
+ lockMetadata = fstatSync(fd);
300448
+ writeFileSync4(fd, JSON.stringify({ schema_version: 1, nonce, pid: process.pid, process_identity: processIdentity(process.pid), ...options.operationId ? { operation_id: options.operationId } : {} }));
300449
+ fsyncSync(fd);
300450
+ } finally {
300451
+ closeSync3(fd);
300452
+ }
300453
+ });
300454
+ const owns = () => {
300455
+ assertRoot();
300456
+ const current = readInstallOwner(lockPath);
300457
+ return sameIdentity(lockMetadata, current.metadata) && current.owner.nonce === nonce && current.owner.pid === process.pid;
300458
+ };
300459
+ return {
300460
+ modulesRoot: root,
300461
+ lockPath,
300462
+ nonce,
300463
+ assertOwned() {
300464
+ assertNotCancelled(options.signal);
300465
+ if (!owns()) throw new Error("npm install lease ownership changed; no installer may proceed.");
300466
+ },
300467
+ async release() {
300468
+ withGuard(() => {
300469
+ try {
300470
+ if (owns()) unlinkSync3(lockPath);
300471
+ } catch (error) {
300472
+ if (error.code !== "ENOENT") throw error;
300473
+ }
300474
+ });
300475
+ }
300476
+ };
300320
300477
  }
300321
300478
  async function removeVerifiedNpmRetirementBackup(backup) {
300322
300479
  const root = resolve10(backup.modulesRoot);
@@ -300352,9 +300509,9 @@ function watchUpdateCancellation(operationId, paths = resolveUpdatePaths()) {
300352
300509
  const check = () => {
300353
300510
  if (controller.signal.aborted) return;
300354
300511
  try {
300355
- const metadata = lstatSync(path3);
300512
+ const metadata = lstatSync2(path3);
300356
300513
  if (!metadata.isFile() || metadata.isSymbolicLink() || metadata.size > 1024) return;
300357
- const request = JSON.parse(readFileSync6(path3, "utf8"));
300514
+ const request = JSON.parse(readFileSync7(path3, "utf8"));
300358
300515
  const state = readUpdateState(paths);
300359
300516
  if (state?.operation_id === operationId && state.status === "running" && state.cancel_token_hash && request.operation_id === operationId && request.token_hash === state.cancel_token_hash) controller.abort(new UpdateCancelledError());
300360
300517
  } catch {
@@ -300366,7 +300523,7 @@ function watchUpdateCancellation(operationId, paths = resolveUpdatePaths()) {
300366
300523
  return { signal: controller.signal, close() {
300367
300524
  clearInterval(timer);
300368
300525
  try {
300369
- unlinkSync3(path3);
300526
+ unlinkSync4(path3);
300370
300527
  } catch {
300371
300528
  }
300372
300529
  } };
@@ -300387,36 +300544,36 @@ function resolveUpdatePaths(env = process.env, platform2 = process.platform, hom
300387
300544
  function ensurePrivateDirectories(paths) {
300388
300545
  for (const path3 of [paths.stateDir, paths.cacheDir]) {
300389
300546
  mkdirSync5(path3, { recursive: true, mode: 448 });
300390
- const before = lstatSync(path3);
300547
+ const before = lstatSync2(path3);
300391
300548
  if (!before.isDirectory() || before.isSymbolicLink() || process.platform !== "win32" && (before.uid !== process.getuid?.() || (before.mode & 18) !== 0)) throw new Error("Update coordination directories must be owned and not writable by other users");
300392
- const fd = openSync3(path3, constants.O_RDONLY | constants.O_DIRECTORY | constants.O_NOFOLLOW);
300549
+ const fd = openSync4(path3, constants2.O_RDONLY | constants2.O_DIRECTORY | constants2.O_NOFOLLOW);
300393
300550
  try {
300394
- const actual = fstatSync(fd);
300551
+ const actual = fstatSync2(fd);
300395
300552
  if (before.ino !== actual.ino || before.dev !== actual.dev || !actual.isDirectory() || process.platform !== "win32" && (actual.uid !== process.getuid?.() || (actual.mode & 18) !== 0)) throw new Error("Update coordination directory ownership changed");
300396
300553
  if (process.platform !== "win32" && (actual.mode & 63) !== 0) fchmodSync(fd, 448);
300397
300554
  } finally {
300398
- closeSync3(fd);
300555
+ closeSync4(fd);
300399
300556
  }
300400
300557
  }
300401
300558
  }
300402
300559
  function privateRecord(path3, limit = 4096) {
300403
300560
  let before;
300404
300561
  try {
300405
- before = lstatSync(path3);
300562
+ before = lstatSync2(path3);
300406
300563
  } catch (error) {
300407
300564
  if (error.code === "ENOENT") return null;
300408
300565
  throw error;
300409
300566
  }
300410
300567
  const valid = (st) => st.isFile() && !st.isSymbolicLink() && st.nlink === 1 && st.size <= limit && (process.platform === "win32" || st.uid === process.getuid?.() && (st.mode & 63) === 0);
300411
300568
  if (!valid(before)) throw new Error("Update coordination requires owner-only regular files");
300412
- const fd = openSync3(path3, constants.O_RDONLY | constants.O_NOFOLLOW);
300569
+ const fd = openSync4(path3, constants2.O_RDONLY | constants2.O_NOFOLLOW);
300413
300570
  try {
300414
- const actual = fstatSync(fd);
300571
+ const actual = fstatSync2(fd);
300415
300572
  if (!valid(actual) || actual.ino !== before.ino || actual.dev !== before.dev) throw new Error("Update coordination file ownership changed");
300416
300573
  const buffer = Buffer.alloc(limit + 1);
300417
300574
  let size = 0;
300418
300575
  while (size < buffer.length) {
300419
- const count = readSync2(fd, buffer, size, buffer.length - size, null);
300576
+ const count = readSync3(fd, buffer, size, buffer.length - size, null);
300420
300577
  if (!count) break;
300421
300578
  size += count;
300422
300579
  }
@@ -300427,15 +300584,15 @@ function privateRecord(path3, limit = 4096) {
300427
300584
  throw new Error("Update coordination record is invalid; inspect its private state");
300428
300585
  }
300429
300586
  } finally {
300430
- closeSync3(fd);
300587
+ closeSync4(fd);
300431
300588
  }
300432
300589
  }
300433
- function processIdentity(pid) {
300590
+ function processIdentity2(pid) {
300434
300591
  if (process.platform !== "linux") return;
300435
300592
  try {
300436
- const raw = readFileSync6(`/proc/${pid}/stat`, "utf8"), fields = raw.slice(raw.lastIndexOf(")") + 2).trim().split(/\s+/);
300593
+ const raw = readFileSync7(`/proc/${pid}/stat`, "utf8"), fields = raw.slice(raw.lastIndexOf(")") + 2).trim().split(/\s+/);
300437
300594
  if (/[ZX]/.test(fields[0] ?? "") || !/^\d+$/.test(fields[19] ?? "")) return;
300438
- return readFileSync6("/proc/sys/kernel/random/boot_id", "utf8").trim() + ":" + fields[19];
300595
+ return readFileSync7("/proc/sys/kernel/random/boot_id", "utf8").trim() + ":" + fields[19];
300439
300596
  } catch {
300440
300597
  return;
300441
300598
  }
@@ -300445,7 +300602,7 @@ function withUpdateOwnership(paths, mutation) {
300445
300602
  const path3 = paths.lockFile + ".guard", nonce = randomUUID3();
300446
300603
  let fd;
300447
300604
  try {
300448
- fd = openSync3(path3, constants.O_WRONLY | constants.O_CREAT | constants.O_EXCL | constants.O_NOFOLLOW, 384);
300605
+ fd = openSync4(path3, constants2.O_WRONLY | constants2.O_CREAT | constants2.O_EXCL | constants2.O_NOFOLLOW, 384);
300449
300606
  } catch (error) {
300450
300607
  if (error.code === "EEXIST") {
300451
300608
  const busy = new UpdateOwnershipBusyError(`Update ownership is busy or its guard was interrupted. Retry; if it persists, inspect the private ${path3} owner record before removing that guard.`);
@@ -300456,29 +300613,29 @@ function withUpdateOwnership(paths, mutation) {
300456
300613
  }
300457
300614
  let original;
300458
300615
  try {
300459
- original = fstatSync(fd);
300616
+ original = fstatSync2(fd);
300460
300617
  } catch (error) {
300461
- closeSync3(fd);
300618
+ closeSync4(fd);
300462
300619
  throw error;
300463
300620
  }
300464
300621
  const owned = () => {
300465
300622
  try {
300466
- const current = lstatSync(path3);
300623
+ const current = lstatSync2(path3);
300467
300624
  return current.ino === original.ino && current.dev === original.dev && privateRecord(path3)?.nonce === nonce;
300468
300625
  } catch {
300469
300626
  return false;
300470
300627
  }
300471
300628
  };
300472
300629
  try {
300473
- writeFileSync4(fd, JSON.stringify({ pid: process.pid, process_identity: processIdentity(process.pid), nonce }));
300474
- fsyncSync(fd);
300630
+ writeFileSync5(fd, JSON.stringify({ pid: process.pid, process_identity: processIdentity2(process.pid), nonce }));
300631
+ fsyncSync2(fd);
300475
300632
  if (!owned()) throw new Error("Update ownership guard changed before the transaction");
300476
300633
  return mutation();
300477
300634
  } finally {
300478
300635
  try {
300479
- if (owned()) unlinkSync3(path3);
300636
+ if (owned()) unlinkSync4(path3);
300480
300637
  } finally {
300481
- closeSync3(fd);
300638
+ closeSync4(fd);
300482
300639
  }
300483
300640
  }
300484
300641
  }
@@ -300492,22 +300649,22 @@ async function retryUpdateOwnership(attempt, timeoutMs = 2e3) {
300492
300649
  let live = false;
300493
300650
  try {
300494
300651
  const owner = privateRecord(error.guardPath);
300495
- live = !!owner && isPidAlive(owner.pid) && (process.platform !== "linux" || !!owner.process_identity && processIdentity(owner.pid) === owner.process_identity);
300652
+ live = !!owner && isPidAlive(owner.pid) && (process.platform !== "linux" || !!owner.process_identity && processIdentity2(owner.pid) === owner.process_identity);
300496
300653
  } catch {
300497
300654
  }
300498
300655
  if (!live) throw error;
300499
- await new Promise((resolve11) => setTimeout(resolve11, 25));
300656
+ await new Promise((resolve12) => setTimeout(resolve12, 25));
300500
300657
  }
300501
300658
  }
300502
300659
  }
300503
300660
  function releaseMatchingUpdateLock(paths, operationId, pid) {
300504
300661
  const lock = privateRecord(paths.lockFile);
300505
- if (lock?.operation_id === operationId && (pid === void 0 || lock.pid === pid)) unlinkSync3(paths.lockFile);
300662
+ if (lock?.operation_id === operationId && (pid === void 0 || lock.pid === pid)) unlinkSync4(paths.lockFile);
300506
300663
  }
300507
300664
  function atomicPrivateJson(path3, value) {
300508
300665
  const temp = `${path3}.${process.pid}.${randomUUID3()}.tmp`;
300509
300666
  try {
300510
- writeFileSync4(temp, `${JSON.stringify(value, null, 2)}
300667
+ writeFileSync5(temp, `${JSON.stringify(value, null, 2)}
300511
300668
  `, {
300512
300669
  encoding: "utf8",
300513
300670
  mode: 384,
@@ -300520,14 +300677,14 @@ function atomicPrivateJson(path3, value) {
300520
300677
  }
300521
300678
  } finally {
300522
300679
  try {
300523
- if (existsSync6(temp)) unlinkSync3(temp);
300680
+ if (existsSync6(temp)) unlinkSync4(temp);
300524
300681
  } catch {
300525
300682
  }
300526
300683
  }
300527
300684
  }
300528
300685
  function readUpdateState(paths = resolveUpdatePaths()) {
300529
300686
  try {
300530
- return JSON.parse(readFileSync6(paths.stateFile, "utf8"));
300687
+ return JSON.parse(readFileSync7(paths.stateFile, "utf8"));
300531
300688
  } catch {
300532
300689
  return null;
300533
300690
  }
@@ -300546,7 +300703,7 @@ function isPidAlive(pid) {
300546
300703
  }
300547
300704
  }
300548
300705
  function ownsAdoptedWorker(state, operationId, pid, paths) {
300549
- if (!state || state.operation_id !== operationId || state.status !== "running" || state.pid !== pid || !state.worker_adopted_at || state.worker_process_identity && state.worker_process_identity !== processIdentity(pid)) return false;
300706
+ if (!state || state.operation_id !== operationId || state.status !== "running" || state.pid !== pid || !state.worker_adopted_at || state.worker_process_identity && state.worker_process_identity !== processIdentity2(pid)) return false;
300550
300707
  const lock = privateRecord(paths.lockFile);
300551
300708
  return lock?.operation_id === operationId && lock.pid === pid;
300552
300709
  }
@@ -300580,7 +300737,7 @@ async function runUpdateCommand(command, args, options = {}) {
300580
300737
  if (options.signal?.aborted) {
300581
300738
  return { status: null, stdout: "", stderr: "command cancelled", signal: null, error: new Error("command cancelled") };
300582
300739
  }
300583
- return await new Promise((resolve11) => {
300740
+ return await new Promise((resolve12) => {
300584
300741
  const child = spawn2(command, args, {
300585
300742
  env: options.env ?? process.env,
300586
300743
  cwd: options.cwd,
@@ -300626,7 +300783,7 @@ async function runUpdateCommand(command, args, options = {}) {
300626
300783
  clearTimeout(timer);
300627
300784
  if (forceTimer) clearTimeout(forceTimer);
300628
300785
  options.signal?.removeEventListener("abort", onAbort);
300629
- resolve11(result);
300786
+ resolve12(result);
300630
300787
  };
300631
300788
  const onAbort = () => {
300632
300789
  terminate(new Error("command cancelled"));
@@ -300661,21 +300818,21 @@ function globalExecutableCandidates(prefix) {
300661
300818
  }
300662
300819
  async function inspectGlobalOmniusInstall(expectedVersion, options = {}) {
300663
300820
  const npmPath = options.npmPath ?? resolveNpmPath();
300664
- const prefixResult = await runCommand(npmPath, ["prefix", "-g"], { env: options.env, timeout: 1e4 });
300821
+ const prefixResult = await runCommand(npmPath, ["prefix", "-g"], { env: options.env, cwd: options.cwd, timeout: 1e4 });
300665
300822
  if (prefixResult.status !== 0 || !prefixResult.stdout.trim()) {
300666
300823
  throw new Error(`Could not resolve npm global prefix: ${prefixResult.stderr.trim() || "npm prefix -g failed"}`);
300667
300824
  }
300668
300825
  const npmPrefix = prefixResult.stdout.trim();
300669
300826
  const packageJsonPath = globalPackageCandidates(npmPrefix).find(existsSync6);
300670
300827
  if (!packageJsonPath) throw new Error(`Global omnius package.json not found under ${npmPrefix}`);
300671
- const packageJsonRaw = readFileSync6(packageJsonPath, "utf8");
300828
+ const packageJsonRaw = readFileSync7(packageJsonPath, "utf8");
300672
300829
  const installedVersion = String(JSON.parse(packageJsonRaw)?.version ?? "");
300673
300830
  if (installedVersion !== expectedVersion) {
300674
300831
  throw new Error(`Global package verification failed: expected ${expectedVersion}, found ${installedVersion || "unknown"}`);
300675
300832
  }
300676
300833
  const executablePath = globalExecutableCandidates(npmPrefix).find(existsSync6);
300677
300834
  if (!executablePath) throw new Error(`Global Omnius executable not found under ${npmPrefix}`);
300678
- const versionResult = await runCommand(executablePath, ["--version"], { env: options.env, timeout: 1e4 });
300835
+ const versionResult = await runCommand(executablePath, ["--version"], { env: options.env, cwd: options.cwd, timeout: 1e4 });
300679
300836
  const executableVersion = commandVersion(`${versionResult.stdout}
300680
300837
  ${versionResult.stderr}`) ?? "";
300681
300838
  if (versionResult.status !== 0 || executableVersion !== expectedVersion) {
@@ -300716,7 +300873,7 @@ async function quiesceDaemonWithRetry(quiesce, attempts = 3, pauseMs = 250) {
300716
300873
  } catch {
300717
300874
  }
300718
300875
  if (attempt < boundedAttempts && pauseMs > 0) {
300719
- await new Promise((resolve11) => setTimeout(resolve11, pauseMs));
300876
+ await new Promise((resolve12) => setTimeout(resolve12, pauseMs));
300720
300877
  }
300721
300878
  }
300722
300879
  return false;
@@ -300732,6 +300889,7 @@ async function installGlobalPackageStreaming(input) {
300732
300889
  "--no-progress"
300733
300890
  ], {
300734
300891
  env: input.env,
300892
+ cwd: input.cwd,
300735
300893
  signal: input.signal,
300736
300894
  timeout: 5 * 6e4,
300737
300895
  onStdout: (text2) => process.stdout.write(text2),
@@ -300747,7 +300905,8 @@ async function runVerifiedUpdateTransaction(initial, dependencies, paths = resol
300747
300905
  let state = initial;
300748
300906
  let daemonQuiesced = false;
300749
300907
  let installStarted = false;
300750
- let retirementBackup = null;
300908
+ const retirementBackups = [];
300909
+ let installLease;
300751
300910
  let cancelPublication;
300752
300911
  const throwIfCancelled = () => {
300753
300912
  if (dependencies.signal?.aborted) throw new UpdateCancelledError();
@@ -300772,10 +300931,63 @@ async function runVerifiedUpdateTransaction(initial, dependencies, paths = resol
300772
300931
  NPM_CONFIG_CACHE: paths.cacheDir,
300773
300932
  npm_config_cache: paths.cacheDir,
300774
300933
  npm_config_prefer_online: "true",
300775
- OMNIUS_UPDATE_COORDINATED: "1"
300934
+ OMNIUS_UPDATE_COORDINATED: "1",
300935
+ ...initial.npm_prefix ? { NPM_CONFIG_PREFIX: initial.npm_prefix, npm_config_prefix: initial.npm_prefix } : {}
300936
+ };
300937
+ const cwd = paths.cacheDir;
300938
+ const assertOwned = () => {
300939
+ installLease?.assertOwned();
300940
+ const persisted = readUpdateState(paths);
300941
+ if (!persisted || persisted.operation_id !== state.operation_id || persisted.status !== "running" || state.worker_adopted_at && !ownsAdoptedWorker(persisted, state.operation_id, state.pid, paths)) {
300942
+ throw new Error("Update ownership changed before package preparation; no directory was moved.");
300943
+ }
300944
+ };
300945
+ const preserveRetirement = async (stage, collision) => {
300946
+ const options = {
300947
+ signal: dependencies.signal,
300948
+ assertOwned,
300949
+ onPrepare: async (backup2) => {
300950
+ state = await transition(state, { npm_recoveries: [...state.npm_recoveries ?? [], {
300951
+ retired_path: backup2.retiredPath,
300952
+ backup_path: backup2.backupPath,
300953
+ status: "planned",
300954
+ stage,
300955
+ device: backup2.device,
300956
+ inode: backup2.inode
300957
+ }] }, paths);
300958
+ }
300959
+ };
300960
+ const backup = collision ? await recoverNpmRetirementCollision(collision, state.npm_modules_root, options) : await prepareNpmRetirementSlot(state.npm_modules_root, options);
300961
+ if (!backup) return null;
300962
+ retirementBackups.push(backup);
300963
+ const recovery = { retired_path: backup.retiredPath, backup_path: backup.backupPath, status: "retained" };
300964
+ state = await transition(state, {
300965
+ npm_recovery: recovery,
300966
+ npm_recoveries: state.npm_recoveries.map((item) => item.backup_path === backup.backupPath ? { ...item, status: "retained" } : item)
300967
+ }, paths);
300968
+ return backup;
300776
300969
  };
300777
300970
  try {
300778
300971
  throwIfCancelled();
300972
+ mkdirSync5(cwd, { recursive: true, mode: 448 });
300973
+ state = await transition(state, { npm_preparation: "checking", npm_working_directory: cwd }, paths);
300974
+ const prefixProbe = await runCommand(npmPath, ["prefix", "-g"], { env, cwd, timeout: 1e4, signal: dependencies.signal });
300975
+ throwIfCancelled();
300976
+ const npmPrefix = prefixProbe.stdout.trim();
300977
+ if (prefixProbe.status !== 0 || !isAbsolute7(npmPrefix)) throw new Error("Could not resolve the selected npm global prefix before installation.");
300978
+ if (initial.npm_prefix && resolve11(npmPrefix) !== resolve11(initial.npm_prefix)) throw new Error("The update worker resolved a different npm prefix; no package was changed.");
300979
+ const rootProbe = await runCommand(npmPath, ["root", "-g"], { env, cwd, timeout: 1e4, signal: dependencies.signal });
300980
+ throwIfCancelled();
300981
+ const npmRoot = rootProbe.stdout.trim();
300982
+ const expectedRoot = process.platform === "win32" ? join16(npmPrefix, "node_modules") : join16(npmPrefix, "lib", "node_modules");
300983
+ if (rootProbe.status !== 0 || !isAbsolute7(npmRoot) || resolve11(npmRoot) !== resolve11(expectedRoot)) throw new Error("Could not verify the selected npm global modules directory; no package was changed.");
300984
+ state = await transition(state, { npm_path: npmPath, npm_prefix: npmPrefix, npm_modules_root: npmRoot }, paths);
300985
+ installLease = await acquireNpmInstallLease(npmRoot, { signal: dependencies.signal, operationId: state.operation_id });
300986
+ state = await transition(state, { npm_modules_root: installLease.modulesRoot }, paths);
300987
+ assertOwned();
300988
+ await preserveRetirement("before_install");
300989
+ throwIfCancelled();
300990
+ state = await transition(state, { npm_preparation: "ready" }, paths);
300779
300991
  if (dependencies.quiesceDaemon) {
300780
300992
  state = await transition(state, { phase: "daemon_quiescing" }, paths);
300781
300993
  throwIfCancelled();
@@ -300787,52 +300999,28 @@ async function runVerifiedUpdateTransaction(initial, dependencies, paths = resol
300787
300999
  daemonQuiesced = true;
300788
301000
  throwIfCancelled();
300789
301001
  }
300790
- const prefixProbe = await runCommand(npmPath, ["prefix", "-g"], { env, timeout: 1e4, signal: dependencies.signal });
300791
- throwIfCancelled();
300792
- state = await transition(state, {
300793
- phase: "installing",
300794
- npm_path: npmPath,
300795
- ...prefixProbe.status === 0 && prefixProbe.stdout.trim() ? { npm_prefix: prefixProbe.stdout.trim() } : {}
300796
- }, paths);
301002
+ state = await transition(state, { phase: "installing" }, paths);
300797
301003
  throwIfCancelled();
300798
301004
  const installer = dependencies.install ?? installGlobalPackageStreaming;
300799
- installStarted = true;
300800
301005
  for (let attempt = 1; attempt <= 2; attempt++) {
300801
301006
  state = await transition(state, { installer_attempt: attempt }, paths);
300802
301007
  throwIfCancelled();
300803
- const installResult = await installer({ npmPath, targetVersion: target, env, signal: dependencies.signal });
301008
+ installStarted = true;
301009
+ const installResult = await installer({ npmPath, targetVersion: target, env, cwd, signal: dependencies.signal });
300804
301010
  state = await transition(state, { installer_exit_code: installResult.exitCode }, paths);
300805
301011
  throwIfCancelled();
300806
301012
  if (installResult.exitCode === 0) break;
300807
301013
  const collision = installResult.renameCollision ?? parseNpmRenameCollision(installResult.error ?? "");
300808
301014
  if (attempt === 1 && collision) {
300809
- const rootProbe = await runCommand(npmPath, ["root", "-g"], { env, timeout: 1e4, signal: dependencies.signal });
300810
- throwIfCancelled();
300811
- if (rootProbe.status === 0 && rootProbe.stdout.trim()) {
300812
- retirementBackup = await recoverNpmRetirementCollision(collision, rootProbe.stdout.trim(), {
300813
- signal: dependencies.signal,
300814
- assertOwned: () => {
300815
- const persisted = readUpdateState(paths);
300816
- if (!persisted || persisted.operation_id !== state.operation_id || persisted.status !== "running" || state.worker_adopted_at && !ownsAdoptedWorker(persisted, state.operation_id, state.pid, paths)) {
300817
- throw new Error("Update ownership changed before npm collision recovery; no directory was moved.");
300818
- }
300819
- }
300820
- });
300821
- if (retirementBackup) {
300822
- state = await transition(state, { npm_recovery: {
300823
- retired_path: retirementBackup.retiredPath,
300824
- backup_path: retirementBackup.backupPath,
300825
- status: "retained"
300826
- } }, paths);
300827
- process.stderr.write("[omnius update] Preserved the occupied npm retirement directory; retrying the same package once (attempt 2/2).\n");
300828
- throwIfCancelled();
300829
- continue;
300830
- }
301015
+ const backup = await preserveRetirement("collision", collision);
301016
+ if (backup) {
301017
+ throwIfCancelled();
301018
+ continue;
300831
301019
  }
300832
301020
  }
300833
301021
  throw new Error(installResult.error || `npm install exited with code ${installResult.exitCode}`);
300834
301022
  }
300835
- const evidence = dependencies.inspectInstall ? await dependencies.inspectInstall(target, npmPath, env) : await inspectGlobalOmniusInstall(target, { npmPath, env });
301023
+ const evidence = dependencies.inspectInstall ? await dependencies.inspectInstall(target, npmPath, env) : await inspectGlobalOmniusInstall(target, { npmPath, env, cwd });
300836
301024
  throwIfCancelled();
300837
301025
  state = await transition(state, {
300838
301026
  phase: "package_verified",
@@ -300854,7 +301042,7 @@ async function runVerifiedUpdateTransaction(initial, dependencies, paths = resol
300854
301042
  if (daemon?.bootVersion === target && daemon.bootPackageHash === evidence.packageHash) {
300855
301043
  break;
300856
301044
  }
300857
- if (attempt < 3) await new Promise((resolve11) => setTimeout(resolve11, 1e3));
301045
+ if (attempt < 3) await new Promise((resolve12) => setTimeout(resolve12, 1e3));
300858
301046
  }
300859
301047
  if (!daemon || daemon.bootVersion !== target) {
300860
301048
  const observed = daemon?.bootVersion ?? "unreachable";
@@ -300886,19 +301074,33 @@ async function runVerifiedUpdateTransaction(initial, dependencies, paths = resol
300886
301074
  state = await transition(state, { tray_restarted: true }, paths);
300887
301075
  }
300888
301076
  throwIfCancelled();
300889
- if (retirementBackup && state.npm_recovery) {
300890
- const recovery = state.npm_recovery;
301077
+ try {
301078
+ await preserveRetirement("after_install");
301079
+ } catch (error) {
301080
+ if (dependencies.signal?.aborted) throw error;
301081
+ assertOwned();
301082
+ state = await transition(state, { npm_cleanup_warning: error instanceof Error ? error.message : String(error) }, paths);
301083
+ }
301084
+ throwIfCancelled();
301085
+ for (const backup of retirementBackups) {
301086
+ assertOwned();
300891
301087
  let cleanupWarning;
300892
301088
  try {
300893
- await removeVerifiedNpmRetirementBackup(retirementBackup);
301089
+ await removeVerifiedNpmRetirementBackup(backup);
300894
301090
  } catch (error) {
300895
301091
  cleanupWarning = error instanceof Error ? error.message : String(error);
300896
301092
  }
300897
- state = await transition(state, { npm_recovery: {
300898
- ...recovery,
300899
- status: cleanupWarning ? "retained" : "removed",
300900
- ...cleanupWarning ? { cleanup_warning: cleanupWarning } : {}
300901
- } }, paths);
301093
+ const recoveries = state.npm_recoveries.map((item) => item.backup_path === backup.backupPath ? { ...item, status: cleanupWarning ? "retained" : "removed", ...cleanupWarning ? { cleanup_warning: cleanupWarning } : {} } : item);
301094
+ const last = recoveries.filter((item) => item.status !== "planned").at(-1);
301095
+ state = await transition(state, {
301096
+ npm_recoveries: recoveries,
301097
+ ...last ? { npm_recovery: {
301098
+ retired_path: last.retired_path,
301099
+ backup_path: last.backup_path,
301100
+ status: last.status,
301101
+ ...last.cleanup_warning ? { cleanup_warning: last.cleanup_warning } : {}
301102
+ } } : {}
301103
+ }, paths);
300902
301104
  }
300903
301105
  throwIfCancelled();
300904
301106
  const now = (/* @__PURE__ */ new Date()).toISOString();
@@ -300931,7 +301133,7 @@ async function runVerifiedUpdateTransaction(initial, dependencies, paths = resol
300931
301133
  error: cancelled ? "Update cancelled after the owned operation settled." : message,
300932
301134
  remediation: [
300933
301135
  cancelled && installStarted ? "Package files may have changed. No rollback was performed; verify the installed version before retrying." : void 0,
300934
- state.npm_recovery?.status === "retained" ? `The prior npm retirement directory is preserved at ${state.npm_recovery.backup_path}.` : void 0,
301136
+ ...(state.npm_recoveries ?? []).filter((item) => item.status === "retained").map((item) => `The prior npm retirement directory is preserved at ${item.backup_path}.`),
300935
301137
  permissionRemediation(message),
300936
301138
  recoveryNote
300937
301139
  ].filter(Boolean).join(" ") || void 0
@@ -300940,6 +301142,8 @@ async function runVerifiedUpdateTransaction(initial, dependencies, paths = resol
300940
301142
  } finally {
300941
301143
  dependencies.signal?.removeEventListener("abort", onCancel);
300942
301144
  if (cancelPublication) await cancelPublication;
301145
+ await installLease?.release().catch(() => {
301146
+ });
300943
301147
  await retryUpdateOwnership(() => withUpdateOwnership(paths, () => releaseMatchingUpdateLock(paths, initial.operation_id))).catch(() => {
300944
301148
  });
300945
301149
  }
@@ -300948,16 +301152,16 @@ async function runVerifiedUpdateTransaction(initial, dependencies, paths = resol
300948
301152
  // packages/cli/src/tray.ts
300949
301153
  import { spawn as spawn3 } from "node:child_process";
300950
301154
  import {
300951
- closeSync as closeSync4,
301155
+ closeSync as closeSync5,
300952
301156
  chmodSync as chmodSync2,
300953
301157
  existsSync as existsSync7,
300954
301158
  mkdirSync as mkdirSync6,
300955
- openSync as openSync4,
300956
- readFileSync as readFileSync7,
301159
+ openSync as openSync5,
301160
+ readFileSync as readFileSync8,
300957
301161
  realpathSync,
300958
301162
  renameSync as renameSync5,
300959
- unlinkSync as unlinkSync4,
300960
- writeFileSync as writeFileSync5,
301163
+ unlinkSync as unlinkSync5,
301164
+ writeFileSync as writeFileSync6,
300961
301165
  writeSync as writeSync3
300962
301166
  } from "node:fs";
300963
301167
  import { homedir as homedir16, tmpdir as tmpdir6 } from "node:os";
@@ -301082,7 +301286,7 @@ function isProcessAlive2(pid) {
301082
301286
  }
301083
301287
  function readPid(path3) {
301084
301288
  try {
301085
- const pid = Number(readFileSync7(path3, "utf8").trim());
301289
+ const pid = Number(readFileSync8(path3, "utf8").trim());
301086
301290
  return Number.isInteger(pid) && pid > 0 ? pid : null;
301087
301291
  } catch {
301088
301292
  return null;
@@ -301090,13 +301294,13 @@ function readPid(path3) {
301090
301294
  }
301091
301295
  function readProcessState(path3) {
301092
301296
  try {
301093
- return JSON.parse(readFileSync7(path3, "utf8"));
301297
+ return JSON.parse(readFileSync8(path3, "utf8"));
301094
301298
  } catch {
301095
301299
  return null;
301096
301300
  }
301097
301301
  }
301098
301302
  async function commandOutput(command, args, timeout = 2e3) {
301099
- return await new Promise((resolve11) => {
301303
+ return await new Promise((resolve12) => {
301100
301304
  const child = spawn3(command, args, { stdio: ["ignore", "pipe", "ignore"], windowsHide: true });
301101
301305
  let stdout = "";
301102
301306
  let settled = false;
@@ -301104,7 +301308,7 @@ async function commandOutput(command, args, timeout = 2e3) {
301104
301308
  if (settled) return;
301105
301309
  settled = true;
301106
301310
  clearTimeout(timer);
301107
- resolve11(stdout);
301311
+ resolve12(stdout);
301108
301312
  };
301109
301313
  child.stdout?.on("data", (chunk) => {
301110
301314
  stdout = `${stdout}${chunk.toString()}`.slice(-64 * 1024);
@@ -301124,7 +301328,7 @@ async function commandOutput(command, args, timeout = 2e3) {
301124
301328
  async function processCommandLine(pid) {
301125
301329
  try {
301126
301330
  if (process.platform === "linux") {
301127
- return readFileSync7(`/proc/${pid}/cmdline`, "utf8").replace(/\0/g, " ");
301331
+ return readFileSync8(`/proc/${pid}/cmdline`, "utf8").replace(/\0/g, " ");
301128
301332
  }
301129
301333
  if (process.platform !== "win32") {
301130
301334
  return (await commandOutput("ps", ["-p", String(pid), "-o", "command="])).trim();
@@ -301143,7 +301347,7 @@ async function getTrayStatus(explicitEndpoint) {
301143
301347
  const running = pid !== null && isProcessAlive2(pid);
301144
301348
  if (pid && !running) {
301145
301349
  try {
301146
- unlinkSync4(paths.pidFile);
301350
+ unlinkSync5(paths.pidFile);
301147
301351
  } catch {
301148
301352
  }
301149
301353
  }
@@ -301171,11 +301375,11 @@ async function stopTray() {
301171
301375
  const pid = readPid(paths.pidFile);
301172
301376
  if (!pid || !isProcessAlive2(pid)) {
301173
301377
  try {
301174
- unlinkSync4(paths.pidFile);
301378
+ unlinkSync5(paths.pidFile);
301175
301379
  } catch {
301176
301380
  }
301177
301381
  try {
301178
- unlinkSync4(paths.stateFile);
301382
+ unlinkSync5(paths.stateFile);
301179
301383
  } catch {
301180
301384
  }
301181
301385
  return false;
@@ -301192,16 +301396,16 @@ async function stopTray() {
301192
301396
  for (let i = 0; i < 30; i++) {
301193
301397
  if (!isProcessAlive2(pid)) {
301194
301398
  try {
301195
- unlinkSync4(paths.pidFile);
301399
+ unlinkSync5(paths.pidFile);
301196
301400
  } catch {
301197
301401
  }
301198
301402
  try {
301199
- unlinkSync4(paths.stateFile);
301403
+ unlinkSync5(paths.stateFile);
301200
301404
  } catch {
301201
301405
  }
301202
301406
  return true;
301203
301407
  }
301204
- await new Promise((resolve11) => setTimeout(resolve11, 100));
301408
+ await new Promise((resolve12) => setTimeout(resolve12, 100));
301205
301409
  }
301206
301410
  if (!trayProcessCommandLooksOwned(await processCommandLine(pid))) return false;
301207
301411
  try {
@@ -301211,16 +301415,16 @@ async function stopTray() {
301211
301415
  for (let i = 0; i < 20; i++) {
301212
301416
  if (!isProcessAlive2(pid)) {
301213
301417
  try {
301214
- unlinkSync4(paths.pidFile);
301418
+ unlinkSync5(paths.pidFile);
301215
301419
  } catch {
301216
301420
  }
301217
301421
  try {
301218
- unlinkSync4(paths.stateFile);
301422
+ unlinkSync5(paths.stateFile);
301219
301423
  } catch {
301220
301424
  }
301221
301425
  return true;
301222
301426
  }
301223
- await new Promise((resolve11) => setTimeout(resolve11, 100));
301427
+ await new Promise((resolve12) => setTimeout(resolve12, 100));
301224
301428
  }
301225
301429
  return false;
301226
301430
  }
@@ -301228,7 +301432,7 @@ async function stopTray() {
301228
301432
  // packages/cli/src/update-worker-runtime.ts
301229
301433
  async function restartTrayWithInstalledExecutable(executable, endpoint) {
301230
301434
  await stopTray();
301231
- const launched = await new Promise((resolve11) => {
301435
+ const launched = await new Promise((resolve12) => {
301232
301436
  const child = spawn4(executable, ["tray", "start", "--endpoint", endpoint], {
301233
301437
  stdio: "ignore",
301234
301438
  windowsHide: true
@@ -301238,15 +301442,15 @@ async function restartTrayWithInstalledExecutable(executable, endpoint) {
301238
301442
  child.kill();
301239
301443
  } catch {
301240
301444
  }
301241
- resolve11(false);
301445
+ resolve12(false);
301242
301446
  }, 15e3);
301243
301447
  child.once("error", () => {
301244
301448
  clearTimeout(timer);
301245
- resolve11(false);
301449
+ resolve12(false);
301246
301450
  });
301247
301451
  child.once("close", (code) => {
301248
301452
  clearTimeout(timer);
301249
- resolve11(code === 0);
301453
+ resolve12(code === 0);
301250
301454
  });
301251
301455
  });
301252
301456
  if (!launched) return false;
@@ -301254,7 +301458,7 @@ async function restartTrayWithInstalledExecutable(executable, endpoint) {
301254
301458
  const status = await getTrayStatus(endpoint);
301255
301459
  if (status.running && status.ready && status.endpoint === endpoint)
301256
301460
  return true;
301257
- await new Promise((resolve11) => setTimeout(resolve11, 250));
301461
+ await new Promise((resolve12) => setTimeout(resolve12, 250));
301258
301462
  }
301259
301463
  return false;
301260
301464
  }