jorgex-stack 1.9.63 → 1.9.64

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.
Files changed (2) hide show
  1. package/dist/cli.js +475 -436
  2. package/package.json +1 -1
package/dist/cli.js CHANGED
@@ -4330,7 +4330,7 @@ var init_pi = __esm({
4330
4330
 
4331
4331
  // src/cli.ts
4332
4332
  import * as p6 from "@clack/prompts";
4333
- import fs43 from "fs";
4333
+ import fs44 from "fs";
4334
4334
  import { pathToFileURL as pathToFileURL2 } from "url";
4335
4335
 
4336
4336
  // src/install.ts
@@ -12734,8 +12734,8 @@ init_model_map();
12734
12734
 
12735
12735
  // src/lib/pi-runtime.ts
12736
12736
  import os6 from "os";
12737
- import path47 from "path";
12738
- import fs39 from "fs";
12737
+ import path48 from "path";
12738
+ import fs40 from "fs";
12739
12739
  import { spawnSync as spawnSync5 } from "child_process";
12740
12740
 
12741
12741
  // src/lib/pi-runtime-pin.json
@@ -12789,8 +12789,8 @@ init_paths();
12789
12789
 
12790
12790
  // src/lib/pi-install-preflight.ts
12791
12791
  init_npm_provider();
12792
- import fs35 from "fs";
12793
- import path43 from "path";
12792
+ import fs36 from "fs";
12793
+ import path44 from "path";
12794
12794
 
12795
12795
  // src/lib/pi-candidate.ts
12796
12796
  import fs33 from "fs";
@@ -13490,18 +13490,121 @@ async function stageVerifiedPiTarball(input, run) {
13490
13490
  return { stageDir, evidence, sourceAlias };
13491
13491
  }
13492
13492
 
13493
- // src/lib/pi-install-preflight.ts
13493
+ // src/lib/pi-host-version.ts
13494
+ import fs35 from "fs";
13495
+ import path43 from "path";
13494
13496
  var PI_PACKAGE_NAME = "@earendil-works/pi-coding-agent";
13497
+ function invalidManagedPi(diagnostic) {
13498
+ return { version: null, diagnostic };
13499
+ }
13500
+ function readJsonFile(file) {
13501
+ try {
13502
+ const stat = fs35.lstatSync(file, { throwIfNoEntry: false });
13503
+ if (!stat?.isFile() || stat.isSymbolicLink() || stat.size > 1024 * 1024) return null;
13504
+ return JSON.parse(fs35.readFileSync(file, "utf8"));
13505
+ } catch {
13506
+ return null;
13507
+ }
13508
+ }
13509
+ function piPackageVersion(file) {
13510
+ try {
13511
+ const value = readJsonFile(file);
13512
+ if (value === null || typeof value !== "object" || Array.isArray(value)) return null;
13513
+ const packageName = Reflect.get(value, "name");
13514
+ const version = Reflect.get(value, "version");
13515
+ return packageName === PI_PACKAGE_NAME && typeof version === "string" && version !== "" && !/\s/.test(version) ? version : null;
13516
+ } catch {
13517
+ return null;
13518
+ }
13519
+ }
13520
+ function managedPiVersion(executable, resolved2) {
13521
+ const binDir = path43.dirname(resolved2);
13522
+ if (path43.basename(resolved2) !== "pi" || path43.basename(binDir) !== "bin") {
13523
+ return invalidManagedPi("launcher gestionado de Pi no reconocido");
13524
+ }
13525
+ const agentDir = path43.dirname(binDir);
13526
+ const installDir = path43.join(agentDir, "install");
13527
+ try {
13528
+ if (!fs35.lstatSync(executable).isSymbolicLink()) {
13529
+ return invalidManagedPi("el entrypoint gestionado de Pi no es un symlink");
13530
+ }
13531
+ const metadata = readJsonFile(path43.join(installDir, "managed-install.json"));
13532
+ if (metadata === null || typeof metadata !== "object" || Array.isArray(metadata)) {
13533
+ return invalidManagedPi("install/managed-install.json falta o no es JSON v\xE1lido");
13534
+ }
13535
+ const entrypoint = Reflect.get(metadata, "entrypoint");
13536
+ if (Reflect.get(metadata, "kind") !== "pi-managed-install" || Reflect.get(metadata, "schemaVersion") !== 1 || Reflect.get(metadata, "layout") !== "releases-v1" || entrypoint === null || typeof entrypoint !== "object" || Array.isArray(entrypoint) || Reflect.get(entrypoint, "type") !== "symlink" || Reflect.get(entrypoint, "path") !== executable) {
13537
+ return invalidManagedPi("install/managed-install.json no coincide con el entrypoint de Pi");
13538
+ }
13539
+ const currentPath = path43.join(installDir, "current-version");
13540
+ const currentStat = fs35.lstatSync(currentPath, { throwIfNoEntry: false });
13541
+ if (!currentStat?.isFile() || currentStat.isSymbolicLink() || currentStat.size > 128) {
13542
+ return invalidManagedPi("install/current-version falta o no es un archivo regular acotado");
13543
+ }
13544
+ const version = fs35.readFileSync(currentPath, "utf8").trim();
13545
+ if (version === "." || version === ".." || !/^[0-9A-Za-z._+-]+$/.test(version)) {
13546
+ return invalidManagedPi("install/current-version contiene una versi\xF3n inv\xE1lida");
13547
+ }
13548
+ const releaseDir = path43.join(installDir, "releases", version);
13549
+ if (fs35.realpathSync(releaseDir) !== releaseDir) {
13550
+ return invalidManagedPi("install/releases contiene un enlace fuera del release gestionado");
13551
+ }
13552
+ const packageDir = path43.join(releaseDir, "node_modules", "@earendil-works", "pi-coding-agent");
13553
+ if (fs35.realpathSync(packageDir) !== packageDir) {
13554
+ return invalidManagedPi("el paquete Pi del release gestionado es un symlink");
13555
+ }
13556
+ const packageVersion = piPackageVersion(path43.join(packageDir, "package.json"));
13557
+ return packageVersion === version ? { version, diagnostic: null } : invalidManagedPi("el manifest de @earendil-works/pi-coding-agent no coincide con install/current-version");
13558
+ } catch {
13559
+ return invalidManagedPi("no se pudo leer la metadata del release Pi gestionado");
13560
+ }
13561
+ }
13562
+ function hasManagedPiMarker(resolved2) {
13563
+ const binDir = path43.dirname(resolved2);
13564
+ if (path43.basename(resolved2) !== "pi" || path43.basename(binDir) !== "bin") return false;
13565
+ const installDir = path43.join(path43.dirname(binDir), "install");
13566
+ try {
13567
+ return fs35.lstatSync(path43.join(installDir, "managed-install.json"), { throwIfNoEntry: false }) !== void 0 || fs35.lstatSync(path43.join(installDir, "current-version"), { throwIfNoEntry: false }) !== void 0;
13568
+ } catch {
13569
+ return true;
13570
+ }
13571
+ }
13572
+ function inspectPiHostVersion(executable) {
13573
+ const absoluteExecutable = path43.resolve(executable);
13574
+ let resolved2;
13575
+ try {
13576
+ resolved2 = fs35.realpathSync(absoluteExecutable);
13577
+ } catch {
13578
+ return { version: null, diagnostic: "no se pudo resolver el ejecutable Pi" };
13579
+ }
13580
+ if (hasManagedPiMarker(resolved2)) return managedPiVersion(absoluteExecutable, resolved2);
13581
+ let current = path43.dirname(resolved2);
13582
+ for (let depth = 0; depth < 8; depth += 1) {
13583
+ for (const manifest of [
13584
+ path43.join(current, "package.json"),
13585
+ path43.join(current, "node_modules", "@earendil-works", "pi-coding-agent", "package.json")
13586
+ ]) {
13587
+ const version = piPackageVersion(manifest);
13588
+ if (version !== null) return { version, diagnostic: null };
13589
+ }
13590
+ const parent = path43.dirname(current);
13591
+ if (parent === current) break;
13592
+ current = parent;
13593
+ }
13594
+ return { version: null, diagnostic: "no se encontr\xF3 el manifest del paquete Pi instalado" };
13595
+ }
13596
+
13597
+ // src/lib/pi-install-preflight.ts
13495
13598
  function fail9(message) {
13496
13599
  throw new Error(`pi-install-preflight: ${message}`);
13497
13600
  }
13498
13601
  function isStrictChild3(child, root) {
13499
- const rel = path43.relative(path43.resolve(root), path43.resolve(child));
13500
- return rel !== "" && rel !== ".." && !rel.startsWith(`..${path43.sep}`) && !path43.isAbsolute(rel);
13602
+ const rel = path44.relative(path44.resolve(root), path44.resolve(child));
13603
+ return rel !== "" && rel !== ".." && !rel.startsWith(`..${path44.sep}`) && !path44.isAbsolute(rel);
13501
13604
  }
13502
13605
  function lstatOrNull4(p7) {
13503
13606
  try {
13504
- return fs35.lstatSync(p7);
13607
+ return fs36.lstatSync(p7);
13505
13608
  } catch {
13506
13609
  return null;
13507
13610
  }
@@ -13517,24 +13620,24 @@ function validatePaths(paths) {
13517
13620
  fail9("paths must be an object");
13518
13621
  }
13519
13622
  const { homeDir, agentDir, piExecutable, downloadsDir } = paths;
13520
- if (typeof homeDir !== "string" || homeDir === "" || !path43.isAbsolute(homeDir)) {
13623
+ if (typeof homeDir !== "string" || homeDir === "" || !path44.isAbsolute(homeDir)) {
13521
13624
  fail9("homeDir must be a non-empty absolute path");
13522
13625
  }
13523
- if (typeof agentDir !== "string" || agentDir === "" || !path43.isAbsolute(agentDir)) {
13626
+ if (typeof agentDir !== "string" || agentDir === "" || !path44.isAbsolute(agentDir)) {
13524
13627
  fail9("agentDir must be a non-empty absolute path");
13525
13628
  }
13526
- if (typeof piExecutable !== "string" || piExecutable === "" || !path43.isAbsolute(piExecutable)) {
13629
+ if (typeof piExecutable !== "string" || piExecutable === "" || !path44.isAbsolute(piExecutable)) {
13527
13630
  fail9("piExecutable must be a non-empty absolute path");
13528
13631
  }
13529
13632
  if (piExecutable === "npm") {
13530
13633
  fail9("piExecutable must be the detected Pi CLI, never npm");
13531
13634
  }
13532
- if (typeof downloadsDir !== "string" || downloadsDir === "" || !path43.isAbsolute(downloadsDir)) {
13635
+ if (typeof downloadsDir !== "string" || downloadsDir === "" || !path44.isAbsolute(downloadsDir)) {
13533
13636
  fail9("downloadsDir must be a non-empty absolute path");
13534
13637
  }
13535
- const homeResolved = path43.resolve(homeDir);
13536
- const agentResolved = path43.resolve(agentDir);
13537
- const downloadsResolved = path43.resolve(downloadsDir);
13638
+ const homeResolved = path44.resolve(homeDir);
13639
+ const agentResolved = path44.resolve(agentDir);
13640
+ const downloadsResolved = path44.resolve(downloadsDir);
13538
13641
  assertRealDir2(homeResolved, "homeDir");
13539
13642
  assertRealDir2(agentResolved, "agentDir");
13540
13643
  assertRealDir2(downloadsResolved, "downloadsDir");
@@ -13562,43 +13665,6 @@ function validateDeps(deps) {
13562
13665
  }
13563
13666
  return { fetchImpl, run };
13564
13667
  }
13565
- function readJsonFile(file) {
13566
- return JSON.parse(fs35.readFileSync(file, "utf8"));
13567
- }
13568
- function detectPiHostVersion(piExecutable) {
13569
- let current;
13570
- try {
13571
- current = path43.dirname(fs35.realpathSync(piExecutable));
13572
- } catch {
13573
- fail9(`cannot resolve Pi executable: ${piExecutable}`);
13574
- }
13575
- for (let depth = 0; depth < 8; depth++) {
13576
- const manifests = [
13577
- path43.join(current, "package.json"),
13578
- path43.join(current, "node_modules", PI_PACKAGE_NAME, "package.json")
13579
- ];
13580
- for (const manifest of manifests) {
13581
- let parsed;
13582
- try {
13583
- parsed = readJsonFile(manifest);
13584
- } catch {
13585
- continue;
13586
- }
13587
- if (parsed !== null && typeof parsed === "object" && Reflect.get(parsed, "name") === PI_PACKAGE_NAME && typeof Reflect.get(parsed, "version") === "string") {
13588
- const version = Reflect.get(parsed, "version");
13589
- if (version !== "" && !/\s/.test(version)) {
13590
- return version;
13591
- }
13592
- }
13593
- }
13594
- const parent = path43.dirname(current);
13595
- if (parent === current) {
13596
- break;
13597
- }
13598
- current = parent;
13599
- }
13600
- fail9(`cannot detect Pi host version from executable: ${piExecutable}`);
13601
- }
13602
13668
  async function preparePiManagedInstall(paths, deps) {
13603
13669
  const { homeDir, agentDir, piExecutable, downloadsDir } = validatePaths(paths);
13604
13670
  const { fetchImpl, run } = validateDeps(deps);
@@ -13627,8 +13693,8 @@ async function preparePiManagedInstall(paths, deps) {
13627
13693
  `pi-install-preflight: producer commit resolution failed: ${error instanceof Error ? error.message : String(error)}`
13628
13694
  );
13629
13695
  }
13630
- const downloadsResolved = path43.resolve(downloadsDir);
13631
- const destination = path43.join(downloadsResolved, `jorgex-pi-${release.version}.tgz`);
13696
+ const downloadsResolved = path44.resolve(downloadsDir);
13697
+ const destination = path44.join(downloadsResolved, `jorgex-pi-${release.version}.tgz`);
13632
13698
  if (!isStrictChild3(destination, downloadsResolved)) {
13633
13699
  fail9(`tarball destination escapes downloadsDir: ${destination}`);
13634
13700
  }
@@ -13657,7 +13723,8 @@ async function preparePiManagedInstall(paths, deps) {
13657
13723
  } catch (error) {
13658
13724
  throw error;
13659
13725
  }
13660
- const hostVersion = detectPiHostVersion(piExecutable);
13726
+ const hostInspection = inspectPiHostVersion(piExecutable);
13727
+ const hostVersion = hostInspection.version ?? fail9(`cannot detect Pi host version: ${hostInspection.diagnostic ?? "unknown reason"}`);
13661
13728
  let candidate;
13662
13729
  try {
13663
13730
  candidate = await buildStagedPiCandidate({
@@ -13679,16 +13746,16 @@ import { createHash as createHash8 } from "crypto";
13679
13746
 
13680
13747
  // src/lib/pi-private-release.ts
13681
13748
  import crypto2 from "crypto";
13682
- import fs36 from "fs";
13683
- import path44 from "path";
13749
+ import fs37 from "fs";
13750
+ import path45 from "path";
13684
13751
  var RELEASE_ID_PATTERN = /^[0-9a-f]{64}$/;
13685
13752
  var EXPECTED_ENTRY = "jorgex-pi";
13686
13753
  function resolved(p7) {
13687
- return path44.resolve(p7);
13754
+ return path45.resolve(p7);
13688
13755
  }
13689
13756
  function isStrictChild4(child, root) {
13690
- const rel = path44.relative(resolved(root), resolved(child));
13691
- return rel !== "" && rel !== ".." && !rel.startsWith(`..${path44.sep}`) && !path44.isAbsolute(rel);
13757
+ const rel = path45.relative(resolved(root), resolved(child));
13758
+ return rel !== "" && rel !== ".." && !rel.startsWith(`..${path45.sep}`) && !path45.isAbsolute(rel);
13692
13759
  }
13693
13760
  function assertStrictChild(child, root, label) {
13694
13761
  if (!isStrictChild4(child, root)) {
@@ -13697,7 +13764,7 @@ function assertStrictChild(child, root, label) {
13697
13764
  }
13698
13765
  function lstatOrNull5(p7) {
13699
13766
  try {
13700
- return fs36.lstatSync(p7);
13767
+ return fs37.lstatSync(p7);
13701
13768
  } catch {
13702
13769
  return null;
13703
13770
  }
@@ -13719,7 +13786,7 @@ function assertAncestorsClean(dir, stop, label) {
13719
13786
  throw new Error(`${label} ancestor is a symlink: ${cur}`);
13720
13787
  }
13721
13788
  if (cur === stopResolved) break;
13722
- const parent = path44.dirname(cur);
13789
+ const parent = path45.dirname(cur);
13723
13790
  if (parent === cur) break;
13724
13791
  cur = parent;
13725
13792
  if (cur.length < stopResolved.length) break;
@@ -13731,7 +13798,7 @@ function assertFilePathClean(file, stop, label) {
13731
13798
  if (st !== null && st.isSymbolicLink()) {
13732
13799
  throw new Error(`${label} is a symlink: ${file}`);
13733
13800
  }
13734
- assertAncestorsClean(path44.dirname(resolved(file)), stop, label);
13801
+ assertAncestorsClean(path45.dirname(resolved(file)), stop, label);
13735
13802
  }
13736
13803
  function assertDirClean(dir, stop, label) {
13737
13804
  assertStrictChild(dir, stop, label);
@@ -13743,17 +13810,17 @@ function assertDirClean(dir, stop, label) {
13743
13810
  }
13744
13811
  function assertLinkInsideRoot(linkPath, allowedRoot, label, finalKind) {
13745
13812
  const allowedResolved = resolved(allowedRoot);
13746
- const linkParent = path44.dirname(resolved(linkPath));
13813
+ const linkParent = path45.dirname(resolved(linkPath));
13747
13814
  if (linkParent !== allowedResolved && !isStrictChild4(linkParent, allowedResolved)) {
13748
13815
  throw new Error(`${label} escapes owner root: ${linkPath}`);
13749
13816
  }
13750
13817
  let target;
13751
13818
  try {
13752
- target = fs36.readlinkSync(linkPath);
13819
+ target = fs37.readlinkSync(linkPath);
13753
13820
  } catch {
13754
13821
  throw new Error(`${label} is broken or unreadable: ${linkPath}`);
13755
13822
  }
13756
- if (target === "" || path44.isAbsolute(target)) {
13823
+ if (target === "" || path45.isAbsolute(target)) {
13757
13824
  throw new Error(`${label} must be a relative symlink: ${linkPath}`);
13758
13825
  }
13759
13826
  const parentStat = lstatOrNull5(linkParent);
@@ -13769,7 +13836,7 @@ function assertLinkInsideRoot(linkPath, allowedRoot, label, finalKind) {
13769
13836
  const part = ops[i];
13770
13837
  const isLast = i === ops.length - 1;
13771
13838
  if (part === "..") {
13772
- cur = path44.dirname(cur);
13839
+ cur = path45.dirname(cur);
13773
13840
  if (cur !== allowedResolved && !isStrictChild4(cur, allowedResolved)) {
13774
13841
  throw new Error(`${label} escapes owner root: ${linkPath} -> ${target}`);
13775
13842
  }
@@ -13792,7 +13859,7 @@ function assertLinkInsideRoot(linkPath, allowedRoot, label, finalKind) {
13792
13859
  }
13793
13860
  continue;
13794
13861
  }
13795
- const next = path44.join(cur, part);
13862
+ const next = path45.join(cur, part);
13796
13863
  if (next !== allowedResolved && !isStrictChild4(next, allowedResolved)) {
13797
13864
  throw new Error(`${label} escapes owner root: ${linkPath} -> ${target}`);
13798
13865
  }
@@ -13832,12 +13899,12 @@ function validateStageTree(stagedNpm) {
13832
13899
  const dir = stack.pop();
13833
13900
  let entries;
13834
13901
  try {
13835
- entries = fs36.readdirSync(dir, { withFileTypes: true });
13902
+ entries = fs37.readdirSync(dir, { withFileTypes: true });
13836
13903
  } catch {
13837
13904
  throw new Error(`staged tree unreadable: ${dir}`);
13838
13905
  }
13839
13906
  for (const entry of entries) {
13840
- const full = path44.join(dir, entry.name);
13907
+ const full = path45.join(dir, entry.name);
13841
13908
  if (entry.isSymbolicLink()) {
13842
13909
  assertInternalSymlink(full, root, "staged symlink");
13843
13910
  continue;
@@ -13849,39 +13916,39 @@ function validateStageTree(stagedNpm) {
13849
13916
  }
13850
13917
  }
13851
13918
  function atomicWritePrivate(target, content) {
13852
- const dir = path44.dirname(resolved(target));
13853
- fs36.mkdirSync(dir, { recursive: true });
13854
- const tmp = path44.join(dir, `.tmp-${crypto2.randomBytes(16).toString("hex")}`);
13919
+ const dir = path45.dirname(resolved(target));
13920
+ fs37.mkdirSync(dir, { recursive: true });
13921
+ const tmp = path45.join(dir, `.tmp-${crypto2.randomBytes(16).toString("hex")}`);
13855
13922
  let fd = null;
13856
13923
  try {
13857
- fd = fs36.openSync(tmp, "wx", 384);
13858
- fs36.writeFileSync(fd, content, "utf8");
13859
- fs36.fsyncSync(fd);
13860
- fs36.closeSync(fd);
13924
+ fd = fs37.openSync(tmp, "wx", 384);
13925
+ fs37.writeFileSync(fd, content, "utf8");
13926
+ fs37.fsyncSync(fd);
13927
+ fs37.closeSync(fd);
13861
13928
  fd = null;
13862
13929
  } finally {
13863
13930
  if (fd !== null) {
13864
13931
  try {
13865
- fs36.closeSync(fd);
13932
+ fs37.closeSync(fd);
13866
13933
  } catch {
13867
13934
  }
13868
- fs36.rmSync(tmp, { force: true });
13935
+ fs37.rmSync(tmp, { force: true });
13869
13936
  }
13870
13937
  }
13871
13938
  const tmpStat = lstatOrNull5(tmp);
13872
13939
  if (tmpStat === null || !tmpStat.isFile()) {
13873
13940
  try {
13874
- fs36.rmSync(tmp, { force: true });
13941
+ fs37.rmSync(tmp, { force: true });
13875
13942
  } catch {
13876
13943
  failIncomplete(`cannot clean private temp (recovery incomplete): ${tmp}`);
13877
13944
  }
13878
13945
  throw new Error(`private temp is not a regular file: ${target}`);
13879
13946
  }
13880
13947
  try {
13881
- fs36.renameSync(tmp, target);
13948
+ fs37.renameSync(tmp, target);
13882
13949
  } catch (err) {
13883
13950
  try {
13884
- fs36.rmSync(tmp, { force: true });
13951
+ fs37.rmSync(tmp, { force: true });
13885
13952
  } catch {
13886
13953
  const original = err instanceof Error ? err.message : String(err ?? "rename failed");
13887
13954
  failIncomplete(`cannot clean private temp after rename failure (recovery incomplete): ${tmp}: ${original}`);
@@ -13898,7 +13965,7 @@ async function activateVerifiedPiRelease(input) {
13898
13965
  if (typeof input.homeDir !== "string" || input.homeDir === "") {
13899
13966
  throw new Error(`homeDir must be a non-empty absolute path`);
13900
13967
  }
13901
- if (!path44.isAbsolute(input.homeDir)) {
13968
+ if (!path45.isAbsolute(input.homeDir)) {
13902
13969
  throw new Error(`homeDir must be absolute: ${input.homeDir}`);
13903
13970
  }
13904
13971
  if (!RELEASE_ID_PATTERN.test(releaseId)) {
@@ -13934,22 +14001,22 @@ async function activateVerifiedPiRelease(input) {
13934
14001
  if (stageStat === null || !stageStat.isDirectory() || stageStat.isSymbolicLink()) {
13935
14002
  throw new Error(`stageDir must be a real directory: ${input.stageDir}`);
13936
14003
  }
13937
- const settingsPath = path44.join(agentDir, "settings.json");
13938
- const npmDir = path44.join(agentDir, "npm");
13939
- const nodeModules = path44.join(npmDir, "node_modules");
13940
- const linkPath = path44.join(nodeModules, EXPECTED_ENTRY);
13941
- const stagedNpm = path44.join(stageDir, "npm");
13942
- const stagedModules = path44.join(stagedNpm, "node_modules");
13943
- const stagedEntry = path44.join(stagedModules, EXPECTED_ENTRY);
13944
- const releaseRoot = path44.join(npmDir, "jorgex-pi-managed", "releases");
13945
- const releaseDir = path44.join(releaseRoot, releaseId);
13946
- const managedRoot = path44.join(npmDir, "jorgex-pi-managed");
13947
- const markerPath = path44.join(managedRoot, "active-transaction.json");
13948
- const lockPath = path44.join(managedRoot, "transaction.lock");
13949
- const backupDir = path44.join(stageDir, ".activate-backup");
13950
- const backupEntry = path44.join(backupDir, "entry");
13951
- const backupSettings = path44.join(backupDir, "settings.json");
13952
- const backupReceipt = path44.join(backupDir, "receipt.json");
14004
+ const settingsPath = path45.join(agentDir, "settings.json");
14005
+ const npmDir = path45.join(agentDir, "npm");
14006
+ const nodeModules = path45.join(npmDir, "node_modules");
14007
+ const linkPath = path45.join(nodeModules, EXPECTED_ENTRY);
14008
+ const stagedNpm = path45.join(stageDir, "npm");
14009
+ const stagedModules = path45.join(stagedNpm, "node_modules");
14010
+ const stagedEntry = path45.join(stagedModules, EXPECTED_ENTRY);
14011
+ const releaseRoot = path45.join(npmDir, "jorgex-pi-managed", "releases");
14012
+ const releaseDir = path45.join(releaseRoot, releaseId);
14013
+ const managedRoot = path45.join(npmDir, "jorgex-pi-managed");
14014
+ const markerPath = path45.join(managedRoot, "active-transaction.json");
14015
+ const lockPath = path45.join(managedRoot, "transaction.lock");
14016
+ const backupDir = path45.join(stageDir, ".activate-backup");
14017
+ const backupEntry = path45.join(backupDir, "entry");
14018
+ const backupSettings = path45.join(backupDir, "settings.json");
14019
+ const backupReceipt = path45.join(backupDir, "receipt.json");
13953
14020
  const expectedTarget = `../jorgex-pi-managed/releases/${releaseId}/node_modules/${EXPECTED_ENTRY}`;
13954
14021
  assertStrictChild(agentDir, homeDir, "agentDir");
13955
14022
  assertStrictChild(receiptPath, homeDir, "receiptPath");
@@ -14002,7 +14069,7 @@ async function activateVerifiedPiRelease(input) {
14002
14069
  let oldEntryExisted = false;
14003
14070
  if (linkStat !== null) {
14004
14071
  oldEntryExisted = true;
14005
- assertAncestorsClean(path44.dirname(linkPath), homeDir, "managed entry");
14072
+ assertAncestorsClean(path45.dirname(linkPath), homeDir, "managed entry");
14006
14073
  if (linkStat.isSymbolicLink()) {
14007
14074
  assertManagedEntrySymlink(linkPath, npmDir, "managed entry");
14008
14075
  } else if (!linkStat.isDirectory()) {
@@ -14019,10 +14086,10 @@ async function activateVerifiedPiRelease(input) {
14019
14086
  let oldReceipt = null;
14020
14087
  try {
14021
14088
  if (lstatOrNull5(settingsPath) !== null) {
14022
- oldSettings = fs36.readFileSync(settingsPath, "utf8");
14089
+ oldSettings = fs37.readFileSync(settingsPath, "utf8");
14023
14090
  }
14024
14091
  if (lstatOrNull5(receiptPath) !== null) {
14025
- oldReceipt = fs36.readFileSync(receiptPath, "utf8");
14092
+ oldReceipt = fs37.readFileSync(receiptPath, "utf8");
14026
14093
  }
14027
14094
  } catch {
14028
14095
  throw new Error(`cannot read previous settings/receipt`);
@@ -14034,7 +14101,7 @@ async function activateVerifiedPiRelease(input) {
14034
14101
  const ownedBackupFiles = /* @__PURE__ */ new Map();
14035
14102
  const releaseLock = () => {
14036
14103
  if (!lockAcquired) return;
14037
- fs36.rmSync(lockPath, { force: true });
14104
+ fs37.rmSync(lockPath, { force: true });
14038
14105
  lockAcquired = false;
14039
14106
  };
14040
14107
  const captureBackupDirIdentity = () => {
@@ -14060,7 +14127,7 @@ async function activateVerifiedPiRelease(input) {
14060
14127
  if (dirStat.dev !== backupDirDev || dirStat.ino !== backupDirIno) return "backup dir replaced";
14061
14128
  let entries;
14062
14129
  try {
14063
- entries = fs36.readdirSync(backupDir);
14130
+ entries = fs37.readdirSync(backupDir);
14064
14131
  } catch {
14065
14132
  return "cannot list backup";
14066
14133
  }
@@ -14070,7 +14137,7 @@ async function activateVerifiedPiRelease(input) {
14070
14137
  if (!allowed.has(entry)) return `unknown backup entry: ${entry}`;
14071
14138
  }
14072
14139
  for (const entry of entries) {
14073
- const full = resolved(path44.join(backupDir, entry));
14140
+ const full = resolved(path45.join(backupDir, entry));
14074
14141
  const owned = ownedBackupFiles.get(full);
14075
14142
  if (!owned) return `unowned backup file: ${entry}`;
14076
14143
  const st = lstatOrNull5(full);
@@ -14078,14 +14145,14 @@ async function activateVerifiedPiRelease(input) {
14078
14145
  if (st.dev !== owned.dev || st.ino !== owned.ino) return `backup file replaced: ${entry}`;
14079
14146
  let cur;
14080
14147
  try {
14081
- cur = fs36.readFileSync(full, "utf8");
14148
+ cur = fs37.readFileSync(full, "utf8");
14082
14149
  } catch {
14083
14150
  return `cannot read backup file: ${entry}`;
14084
14151
  }
14085
14152
  if (cur !== owned.content) return `backup file bytes drifted: ${entry}`;
14086
14153
  }
14087
14154
  for (const [fullPath] of ownedBackupFiles) {
14088
- const base = path44.basename(fullPath);
14155
+ const base = path45.basename(fullPath);
14089
14156
  if (!entries.includes(base)) return `owned backup file missing: ${base}`;
14090
14157
  }
14091
14158
  return null;
@@ -14107,7 +14174,7 @@ async function activateVerifiedPiRelease(input) {
14107
14174
  }
14108
14175
  let cur;
14109
14176
  try {
14110
- cur = fs36.readFileSync(fullPath, "utf8");
14177
+ cur = fs37.readFileSync(fullPath, "utf8");
14111
14178
  } catch {
14112
14179
  failIncomplete(
14113
14180
  `backup drifted during cleanup, preserving foreign state (recovery incomplete): ${fullPath}: ${original}`
@@ -14119,7 +14186,7 @@ async function activateVerifiedPiRelease(input) {
14119
14186
  `backup drifted during cleanup, preserving foreign state (recovery incomplete): ${fullPath}: ${original}`
14120
14187
  );
14121
14188
  }
14122
- fs36.unlinkSync(fullPath);
14189
+ fs37.unlinkSync(fullPath);
14123
14190
  }
14124
14191
  } catch (err) {
14125
14192
  if (err instanceof Error && err.recovery === "incomplete") throw err;
@@ -14129,13 +14196,13 @@ async function activateVerifiedPiRelease(input) {
14129
14196
  );
14130
14197
  }
14131
14198
  try {
14132
- const remaining = fs36.readdirSync(backupDir);
14199
+ const remaining = fs37.readdirSync(backupDir);
14133
14200
  if (remaining.length !== 0) {
14134
14201
  failIncomplete(
14135
14202
  `backup dir not empty after owned cleanup, preserving foreign state (recovery incomplete): ${backupDir}: ${original}`
14136
14203
  );
14137
14204
  }
14138
- fs36.rmdirSync(backupDir);
14205
+ fs37.rmdirSync(backupDir);
14139
14206
  } catch (err) {
14140
14207
  if (err instanceof Error && err.recovery === "incomplete") throw err;
14141
14208
  const msg = err instanceof Error ? err.message : String(err ?? "rmdir failed");
@@ -14144,7 +14211,7 @@ async function activateVerifiedPiRelease(input) {
14144
14211
  );
14145
14212
  }
14146
14213
  try {
14147
- fs36.rmSync(markerPath, { force: true });
14214
+ fs37.rmSync(markerPath, { force: true });
14148
14215
  releaseLock();
14149
14216
  } catch {
14150
14217
  failIncomplete(`cannot clear transaction state after rollback: ${original}`);
@@ -14160,7 +14227,7 @@ async function activateVerifiedPiRelease(input) {
14160
14227
  if (!backupCreated) {
14161
14228
  const problems = [];
14162
14229
  try {
14163
- fs36.rmSync(markerPath, { force: true });
14230
+ fs37.rmSync(markerPath, { force: true });
14164
14231
  } catch {
14165
14232
  problems.push("cannot remove marker");
14166
14233
  }
@@ -14179,7 +14246,7 @@ async function activateVerifiedPiRelease(input) {
14179
14246
  if (err instanceof Error) throw err;
14180
14247
  throw new Error(original);
14181
14248
  };
14182
- fs36.mkdirSync(managedRoot, { recursive: true });
14249
+ fs37.mkdirSync(managedRoot, { recursive: true });
14183
14250
  assertAncestorsClean(managedRoot, homeDir, "managed root");
14184
14251
  const managedRootStat = lstatOrNull5(managedRoot);
14185
14252
  if (managedRootStat === null || !managedRootStat.isDirectory() || managedRootStat.isSymbolicLink()) {
@@ -14188,14 +14255,14 @@ async function activateVerifiedPiRelease(input) {
14188
14255
  const lockToken = `${JSON.stringify({ pid: process.pid, stageDir, releaseId, startedAt: (/* @__PURE__ */ new Date()).toISOString() })}
14189
14256
  `;
14190
14257
  try {
14191
- fs36.writeFileSync(lockPath, lockToken, { encoding: "utf8", flag: "wx", mode: 384 });
14258
+ fs37.writeFileSync(lockPath, lockToken, { encoding: "utf8", flag: "wx", mode: 384 });
14192
14259
  lockAcquired = true;
14193
14260
  } catch {
14194
14261
  failIncomplete(`transaction lock busy: concurrent activation holds the exclusive lock (recovery incomplete): ${lockPath}`);
14195
14262
  }
14196
14263
  if (lstatOrNull5(markerPath) !== null) {
14197
14264
  try {
14198
- fs36.rmSync(lockPath, { force: true });
14265
+ fs37.rmSync(lockPath, { force: true });
14199
14266
  lockAcquired = false;
14200
14267
  } catch {
14201
14268
  }
@@ -14204,10 +14271,10 @@ async function activateVerifiedPiRelease(input) {
14204
14271
  const markerContent = `${JSON.stringify({ stageDir, backupDir, releaseId, releaseDir, phase: "prepared", pid: process.pid }, null, 2)}
14205
14272
  `;
14206
14273
  try {
14207
- fs36.writeFileSync(markerPath, markerContent, { encoding: "utf8", flag: "wx", mode: 384 });
14274
+ fs37.writeFileSync(markerPath, markerContent, { encoding: "utf8", flag: "wx", mode: 384 });
14208
14275
  } catch {
14209
14276
  try {
14210
- fs36.rmSync(lockPath, { force: true });
14277
+ fs37.rmSync(lockPath, { force: true });
14211
14278
  lockAcquired = false;
14212
14279
  } catch {
14213
14280
  }
@@ -14225,7 +14292,7 @@ async function activateVerifiedPiRelease(input) {
14225
14292
  }
14226
14293
  }
14227
14294
  try {
14228
- fs36.mkdirSync(backupDir);
14295
+ fs37.mkdirSync(backupDir);
14229
14296
  backupCreated = true;
14230
14297
  captureBackupDirIdentity();
14231
14298
  } catch (err) {
@@ -14245,7 +14312,7 @@ async function activateVerifiedPiRelease(input) {
14245
14312
  }
14246
14313
  const persistBackupCopy = (target, content) => {
14247
14314
  if (content === null) return;
14248
- fs36.writeFileSync(target, content, { encoding: "utf8", flag: "wx", mode: 384 });
14315
+ fs37.writeFileSync(target, content, { encoding: "utf8", flag: "wx", mode: 384 });
14249
14316
  trackOwnedBackupFile(target, content);
14250
14317
  };
14251
14318
  let entryMoved = false;
@@ -14255,10 +14322,10 @@ async function activateVerifiedPiRelease(input) {
14255
14322
  try {
14256
14323
  persistBackupCopy(backupSettings, oldSettings);
14257
14324
  persistBackupCopy(backupReceipt, oldReceipt);
14258
- const metaPath = path44.join(backupDir, "meta.json");
14325
+ const metaPath = path45.join(backupDir, "meta.json");
14259
14326
  const metaContent = `${JSON.stringify({ releaseId, oldEntryExisted }, null, 2)}
14260
14327
  `;
14261
- fs36.writeFileSync(metaPath, metaContent, { encoding: "utf8", flag: "wx", mode: 384 });
14328
+ fs37.writeFileSync(metaPath, metaContent, { encoding: "utf8", flag: "wx", mode: 384 });
14262
14329
  trackOwnedBackupFile(metaPath, metaContent);
14263
14330
  } catch {
14264
14331
  abortBeforePublish(new Error(`cannot persist private backup`));
@@ -14274,7 +14341,7 @@ async function activateVerifiedPiRelease(input) {
14274
14341
  } else {
14275
14342
  let target = null;
14276
14343
  try {
14277
- target = fs36.readlinkSync(linkPath);
14344
+ target = fs37.readlinkSync(linkPath);
14278
14345
  } catch {
14279
14346
  target = null;
14280
14347
  }
@@ -14286,7 +14353,7 @@ async function activateVerifiedPiRelease(input) {
14286
14353
  if (drift === null && wroteSettings) {
14287
14354
  let cur = null;
14288
14355
  try {
14289
- cur = fs36.readFileSync(settingsPath, "utf8");
14356
+ cur = fs37.readFileSync(settingsPath, "utf8");
14290
14357
  } catch {
14291
14358
  cur = null;
14292
14359
  }
@@ -14295,7 +14362,7 @@ async function activateVerifiedPiRelease(input) {
14295
14362
  if (drift === null && wroteReceipt) {
14296
14363
  let cur = null;
14297
14364
  try {
14298
- cur = fs36.readFileSync(receiptPath, "utf8");
14365
+ cur = fs37.readFileSync(receiptPath, "utf8");
14299
14366
  } catch {
14300
14367
  cur = null;
14301
14368
  }
@@ -14311,7 +14378,7 @@ async function activateVerifiedPiRelease(input) {
14311
14378
  if (cur === null || !cur.isSymbolicLink()) {
14312
14379
  problems.push("published entry link missing");
14313
14380
  } else {
14314
- fs36.unlinkSync(linkPath);
14381
+ fs37.unlinkSync(linkPath);
14315
14382
  }
14316
14383
  } else if (lstatOrNull5(linkPath) !== null) {
14317
14384
  problems.push("unexpected managed entry");
@@ -14327,7 +14394,7 @@ async function activateVerifiedPiRelease(input) {
14327
14394
  } else if (lstatOrNull5(linkPath) !== null) {
14328
14395
  problems.push("managed entry still present");
14329
14396
  } else {
14330
- fs36.renameSync(backupEntry, linkPath);
14397
+ fs37.renameSync(backupEntry, linkPath);
14331
14398
  }
14332
14399
  } else if (lstatOrNull5(linkPath) !== null) {
14333
14400
  problems.push("unexpected managed entry");
@@ -14340,7 +14407,7 @@ async function activateVerifiedPiRelease(input) {
14340
14407
  if (oldSettings !== null) {
14341
14408
  atomicWritePrivate(settingsPath, oldSettings);
14342
14409
  } else {
14343
- fs36.rmSync(settingsPath, { force: true });
14410
+ fs37.rmSync(settingsPath, { force: true });
14344
14411
  }
14345
14412
  }
14346
14413
  } catch {
@@ -14351,7 +14418,7 @@ async function activateVerifiedPiRelease(input) {
14351
14418
  if (oldReceipt !== null) {
14352
14419
  atomicWritePrivate(receiptPath, oldReceipt);
14353
14420
  } else {
14354
- fs36.rmSync(receiptPath, { force: true });
14421
+ fs37.rmSync(receiptPath, { force: true });
14355
14422
  }
14356
14423
  }
14357
14424
  } catch {
@@ -14361,7 +14428,7 @@ async function activateVerifiedPiRelease(input) {
14361
14428
  const destStat = lstatOrNull5(releaseDir);
14362
14429
  const stagedStat = lstatOrNull5(stagedNpm);
14363
14430
  if (destStat !== null && stagedStat === null) {
14364
- fs36.renameSync(releaseDir, stagedNpm);
14431
+ fs37.renameSync(releaseDir, stagedNpm);
14365
14432
  } else if (destStat !== null && stagedStat !== null) {
14366
14433
  problems.push("staged tree and promoted release both present");
14367
14434
  } else if (destStat === null && stagedStat === null) {
@@ -14381,7 +14448,7 @@ async function activateVerifiedPiRelease(input) {
14381
14448
  clearOwnedBackupThenCooperativeState(original);
14382
14449
  } else {
14383
14450
  try {
14384
- fs36.rmSync(markerPath, { force: true });
14451
+ fs37.rmSync(markerPath, { force: true });
14385
14452
  releaseLock();
14386
14453
  } catch {
14387
14454
  failIncomplete(`cannot clear transaction state after rollback: ${original}`);
@@ -14397,14 +14464,14 @@ async function activateVerifiedPiRelease(input) {
14397
14464
  };
14398
14465
  try {
14399
14466
  if (oldEntryExisted) {
14400
- fs36.renameSync(linkPath, backupEntry);
14467
+ fs37.renameSync(linkPath, backupEntry);
14401
14468
  entryMoved = true;
14402
14469
  }
14403
14470
  } catch {
14404
14471
  abortBeforePublish(new Error(`cannot backup previous managed entry`));
14405
14472
  }
14406
14473
  try {
14407
- fs36.mkdirSync(releaseRoot, { recursive: true });
14474
+ fs37.mkdirSync(releaseRoot, { recursive: true });
14408
14475
  assertAncestorsClean(releaseRoot, homeDir, "release root");
14409
14476
  const rootStat = lstatOrNull5(releaseRoot);
14410
14477
  if (rootStat === null || !rootStat.isDirectory() || rootStat.isSymbolicLink()) {
@@ -14413,8 +14480,8 @@ async function activateVerifiedPiRelease(input) {
14413
14480
  if (lstatOrNull5(releaseDir) !== null) {
14414
14481
  throw new Error(`release already exists: ${releaseDir}`);
14415
14482
  }
14416
- fs36.renameSync(stagedNpm, releaseDir);
14417
- fs36.symlinkSync(expectedTarget, linkPath, "dir");
14483
+ fs37.renameSync(stagedNpm, releaseDir);
14484
+ fs37.symlinkSync(expectedTarget, linkPath, "dir");
14418
14485
  publishedLink = true;
14419
14486
  atomicWritePrivate(settingsPath, input.nextSettings);
14420
14487
  wroteSettings = true;
@@ -14432,7 +14499,7 @@ async function activateVerifiedPiRelease(input) {
14432
14499
  rollback(err);
14433
14500
  }
14434
14501
  try {
14435
- fs36.rmSync(markerPath, { force: true });
14502
+ fs37.rmSync(markerPath, { force: true });
14436
14503
  releaseLock();
14437
14504
  } catch {
14438
14505
  failIncomplete(`cannot clear transaction state after activation (recovery incomplete): ${markerPath}`);
@@ -14448,14 +14515,14 @@ function isManagedDependency(value) {
14448
14515
  }
14449
14516
  function readTextOrNull(p7) {
14450
14517
  try {
14451
- return fs36.readFileSync(p7, "utf8");
14518
+ return fs37.readFileSync(p7, "utf8");
14452
14519
  } catch {
14453
14520
  return null;
14454
14521
  }
14455
14522
  }
14456
14523
  function safeReadlink(p7) {
14457
14524
  try {
14458
- return fs36.readlinkSync(p7);
14525
+ return fs37.readlinkSync(p7);
14459
14526
  } catch {
14460
14527
  return null;
14461
14528
  }
@@ -14471,7 +14538,7 @@ function deactivateVerifiedPiRelease(input) {
14471
14538
  if (typeof input.homeDir !== "string" || input.homeDir === "" || typeof input.agentDir !== "string" || input.agentDir === "" || typeof input.receiptPath !== "string" || input.receiptPath === "" || typeof mp.releaseDir !== "string" || mp.releaseDir === "" || typeof mp.linkPath !== "string" || mp.linkPath === "" || typeof mp.backupDir !== "string" || mp.backupDir === "") {
14472
14539
  throw new Error(`homeDir, agentDir, receiptPath and managedPackage paths must be non-empty strings`);
14473
14540
  }
14474
- if (!path44.isAbsolute(input.homeDir)) {
14541
+ if (!path45.isAbsolute(input.homeDir)) {
14475
14542
  throw new Error(`homeDir must be absolute: ${input.homeDir}`);
14476
14543
  }
14477
14544
  if (typeof mp.lockSha256 !== "string" || !HEX64_PATTERN.test(mp.lockSha256)) {
@@ -14512,23 +14579,23 @@ function deactivateVerifiedPiRelease(input) {
14512
14579
  if (agentStat === null || !agentStat.isDirectory() || agentStat.isSymbolicLink()) {
14513
14580
  throw new Error(`agentDir must be a real directory: ${input.agentDir}`);
14514
14581
  }
14515
- const settingsPath = path44.join(agentDir, "settings.json");
14516
- const npmDir = path44.join(agentDir, "npm");
14517
- const nodeModules = path44.join(npmDir, "node_modules");
14518
- const expectedLink = path44.join(nodeModules, EXPECTED_ENTRY);
14519
- const releaseRoot = path44.join(npmDir, "jorgex-pi-managed", "releases");
14520
- const managedRoot = path44.join(npmDir, "jorgex-pi-managed");
14521
- const markerPath = path44.join(managedRoot, "active-transaction.json");
14522
- const lockPath = path44.join(managedRoot, "transaction.lock");
14582
+ const settingsPath = path45.join(agentDir, "settings.json");
14583
+ const npmDir = path45.join(agentDir, "npm");
14584
+ const nodeModules = path45.join(npmDir, "node_modules");
14585
+ const expectedLink = path45.join(nodeModules, EXPECTED_ENTRY);
14586
+ const releaseRoot = path45.join(npmDir, "jorgex-pi-managed", "releases");
14587
+ const managedRoot = path45.join(npmDir, "jorgex-pi-managed");
14588
+ const markerPath = path45.join(managedRoot, "active-transaction.json");
14589
+ const lockPath = path45.join(managedRoot, "transaction.lock");
14523
14590
  if (linkPath !== expectedLink) {
14524
14591
  throw new Error(`managed link must be the owned entry: ${expectedLink}`);
14525
14592
  }
14526
- const releaseId = path44.basename(releaseDir);
14527
- if (path44.dirname(releaseDir) !== releaseRoot || !HEX64_PATTERN.test(releaseId)) {
14593
+ const releaseId = path45.basename(releaseDir);
14594
+ if (path45.dirname(releaseDir) !== releaseRoot || !HEX64_PATTERN.test(releaseId)) {
14528
14595
  throw new Error(`managed release must live under the private releases root: ${releaseDir}`);
14529
14596
  }
14530
14597
  const expectedTarget = `../jorgex-pi-managed/releases/${releaseId}/node_modules/${EXPECTED_ENTRY}`;
14531
- const packageRoot = path44.join(releaseDir, "node_modules", EXPECTED_ENTRY);
14598
+ const packageRoot = path45.join(releaseDir, "node_modules", EXPECTED_ENTRY);
14532
14599
  assertStrictChild(agentDir, homeDir, "agentDir");
14533
14600
  assertStrictChild(receiptPath, homeDir, "receiptPath");
14534
14601
  assertStrictChild(releaseDir, agentDir, "managed release");
@@ -14567,7 +14634,7 @@ function deactivateVerifiedPiRelease(input) {
14567
14634
  if (linkStat === null || !linkStat.isSymbolicLink()) {
14568
14635
  throw new Error(`managed entry must be the owned symlink: ${linkPath}`);
14569
14636
  }
14570
- assertAncestorsClean(path44.dirname(linkPath), homeDir, "managed entry");
14637
+ assertAncestorsClean(path45.dirname(linkPath), homeDir, "managed entry");
14571
14638
  const observedTarget = safeReadlink(linkPath);
14572
14639
  if (observedTarget === null || observedTarget !== expectedTarget) {
14573
14640
  throw new Error(`managed entry points outside the owned release: ${linkPath}`);
@@ -14579,7 +14646,7 @@ function deactivateVerifiedPiRelease(input) {
14579
14646
  }
14580
14647
  let liveRealpath = null;
14581
14648
  try {
14582
- liveRealpath = fs36.realpathSync(linkPath);
14649
+ liveRealpath = fs37.realpathSync(linkPath);
14583
14650
  } catch {
14584
14651
  liveRealpath = null;
14585
14652
  }
@@ -14596,7 +14663,7 @@ function deactivateVerifiedPiRelease(input) {
14596
14663
  throw new Error(`activation backup must be a real directory: ${mp.backupDir}`);
14597
14664
  }
14598
14665
  assertAncestorsClean(activationBackupDir, homeDir, "activation backup");
14599
- const lockFile = path44.join(releaseDir, "package-lock.json");
14666
+ const lockFile = path45.join(releaseDir, "package-lock.json");
14600
14667
  const lockStat = lstatOrNull5(lockFile);
14601
14668
  if (lockStat === null || lockStat.isSymbolicLink() || !lockStat.isFile()) {
14602
14669
  throw new Error(`managed lock must be a regular file: ${lockFile}`);
@@ -14606,7 +14673,7 @@ function deactivateVerifiedPiRelease(input) {
14606
14673
  }
14607
14674
  let lockBytes;
14608
14675
  try {
14609
- lockBytes = fs36.readFileSync(lockFile);
14676
+ lockBytes = fs37.readFileSync(lockFile);
14610
14677
  } catch {
14611
14678
  throw new Error(`cannot read managed lock: ${lockFile}`);
14612
14679
  }
@@ -14624,19 +14691,19 @@ function deactivateVerifiedPiRelease(input) {
14624
14691
  let oldReceipt = null;
14625
14692
  try {
14626
14693
  if (lstatOrNull5(settingsPath) !== null) {
14627
- oldSettings = fs36.readFileSync(settingsPath, "utf8");
14694
+ oldSettings = fs37.readFileSync(settingsPath, "utf8");
14628
14695
  }
14629
- oldReceipt = fs36.readFileSync(receiptPath, "utf8");
14696
+ oldReceipt = fs37.readFileSync(receiptPath, "utf8");
14630
14697
  } catch {
14631
14698
  throw new Error(`cannot read previous settings/receipt`);
14632
14699
  }
14633
14700
  let lockAcquired = false;
14634
14701
  const releaseLock = () => {
14635
14702
  if (!lockAcquired) return;
14636
- fs36.rmSync(lockPath, { force: true });
14703
+ fs37.rmSync(lockPath, { force: true });
14637
14704
  lockAcquired = false;
14638
14705
  };
14639
- fs36.mkdirSync(managedRoot, { recursive: true });
14706
+ fs37.mkdirSync(managedRoot, { recursive: true });
14640
14707
  assertAncestorsClean(managedRoot, homeDir, "managed root");
14641
14708
  const managedRootStat = lstatOrNull5(managedRoot);
14642
14709
  if (managedRootStat === null || !managedRootStat.isDirectory() || managedRootStat.isSymbolicLink()) {
@@ -14644,7 +14711,7 @@ function deactivateVerifiedPiRelease(input) {
14644
14711
  }
14645
14712
  let uninstallBackupDir = "";
14646
14713
  for (let i = 0; i < 5 && uninstallBackupDir === ""; i++) {
14647
- const candidateDir = path44.join(managedRoot, `uninstall-backup-${crypto2.randomBytes(8).toString("hex")}`);
14714
+ const candidateDir = path45.join(managedRoot, `uninstall-backup-${crypto2.randomBytes(8).toString("hex")}`);
14648
14715
  if (lstatOrNull5(candidateDir) === null) uninstallBackupDir = candidateDir;
14649
14716
  }
14650
14717
  if (uninstallBackupDir === "") {
@@ -14654,14 +14721,14 @@ function deactivateVerifiedPiRelease(input) {
14654
14721
  const lockToken = `${JSON.stringify({ op: "uninstall", pid: process.pid, agentDir, releaseId, startedAt: (/* @__PURE__ */ new Date()).toISOString() })}
14655
14722
  `;
14656
14723
  try {
14657
- fs36.writeFileSync(lockPath, lockToken, { encoding: "utf8", flag: "wx", mode: 384 });
14724
+ fs37.writeFileSync(lockPath, lockToken, { encoding: "utf8", flag: "wx", mode: 384 });
14658
14725
  lockAcquired = true;
14659
14726
  } catch {
14660
14727
  failIncomplete(`transaction lock busy: concurrent operation holds the exclusive lock (recovery incomplete): ${lockPath}`);
14661
14728
  }
14662
14729
  if (lstatOrNull5(markerPath) !== null) {
14663
14730
  try {
14664
- fs36.rmSync(lockPath, { force: true });
14731
+ fs37.rmSync(lockPath, { force: true });
14665
14732
  lockAcquired = false;
14666
14733
  } catch {
14667
14734
  }
@@ -14670,10 +14737,10 @@ function deactivateVerifiedPiRelease(input) {
14670
14737
  const markerContent = `${JSON.stringify({ phase: "uninstall", releaseDir, linkPath, receiptPath, backupDir: uninstallBackupDir, activationBackupDir, releaseId, pid: process.pid }, null, 2)}
14671
14738
  `;
14672
14739
  try {
14673
- fs36.writeFileSync(markerPath, markerContent, { encoding: "utf8", flag: "wx", mode: 384 });
14740
+ fs37.writeFileSync(markerPath, markerContent, { encoding: "utf8", flag: "wx", mode: 384 });
14674
14741
  } catch {
14675
14742
  try {
14676
- fs36.rmSync(lockPath, { force: true });
14743
+ fs37.rmSync(lockPath, { force: true });
14677
14744
  lockAcquired = false;
14678
14745
  } catch {
14679
14746
  }
@@ -14682,7 +14749,7 @@ function deactivateVerifiedPiRelease(input) {
14682
14749
  const abortOwnTransaction = (err) => {
14683
14750
  const problems = [];
14684
14751
  try {
14685
- fs36.rmSync(markerPath, { force: true });
14752
+ fs37.rmSync(markerPath, { force: true });
14686
14753
  } catch {
14687
14754
  problems.push("cannot remove marker");
14688
14755
  }
@@ -14692,7 +14759,7 @@ function deactivateVerifiedPiRelease(input) {
14692
14759
  problems.push("cannot release lock");
14693
14760
  }
14694
14761
  try {
14695
- fs36.rmSync(uninstallBackupDir, { recursive: true, force: true });
14762
+ fs37.rmSync(uninstallBackupDir, { recursive: true, force: true });
14696
14763
  } catch {
14697
14764
  problems.push("cannot clear backup");
14698
14765
  }
@@ -14728,7 +14795,7 @@ function deactivateVerifiedPiRelease(input) {
14728
14795
  }
14729
14796
  if (drift !== null) {
14730
14797
  try {
14731
- fs36.rmSync(markerPath, { force: true });
14798
+ fs37.rmSync(markerPath, { force: true });
14732
14799
  releaseLock();
14733
14800
  } catch {
14734
14801
  }
@@ -14737,7 +14804,7 @@ function deactivateVerifiedPiRelease(input) {
14737
14804
  };
14738
14805
  recheckLiveState();
14739
14806
  try {
14740
- fs36.mkdirSync(uninstallBackupDir, { recursive: true });
14807
+ fs37.mkdirSync(uninstallBackupDir, { recursive: true });
14741
14808
  } catch (err) {
14742
14809
  abortOwnTransaction(err);
14743
14810
  }
@@ -14747,22 +14814,22 @@ function deactivateVerifiedPiRelease(input) {
14747
14814
  }
14748
14815
  let backupEntries = [];
14749
14816
  try {
14750
- backupEntries = fs36.readdirSync(uninstallBackupDir);
14817
+ backupEntries = fs37.readdirSync(uninstallBackupDir);
14751
14818
  } catch {
14752
14819
  abortOwnTransaction(new Error(`cannot inspect uninstall backup: ${uninstallBackupDir}`));
14753
14820
  }
14754
14821
  if (backupEntries.length !== 0) {
14755
14822
  abortOwnTransaction(new Error(`uninstall backup is not empty: ${uninstallBackupDir}`));
14756
14823
  }
14757
- const backupReleaseDir = path44.join(uninstallBackupDir, "release");
14758
- const backupReceiptFile = path44.join(uninstallBackupDir, "pi-receipt.json");
14759
- const backupSettingsFile = path44.join(uninstallBackupDir, "settings.json");
14824
+ const backupReleaseDir = path45.join(uninstallBackupDir, "release");
14825
+ const backupReceiptFile = path45.join(uninstallBackupDir, "pi-receipt.json");
14826
+ const backupSettingsFile = path45.join(uninstallBackupDir, "settings.json");
14760
14827
  try {
14761
14828
  if (oldSettings !== null) {
14762
- fs36.writeFileSync(backupSettingsFile, oldSettings, { encoding: "utf8", flag: "wx", mode: 384 });
14829
+ fs37.writeFileSync(backupSettingsFile, oldSettings, { encoding: "utf8", flag: "wx", mode: 384 });
14763
14830
  }
14764
- fs36.writeFileSync(
14765
- path44.join(uninstallBackupDir, "meta.json"),
14831
+ fs37.writeFileSync(
14832
+ path45.join(uninstallBackupDir, "meta.json"),
14766
14833
  `${JSON.stringify({ phase: "uninstall", releaseDir, linkPath, receiptPath, linkTarget: observedTarget }, null, 2)}
14767
14834
  `,
14768
14835
  { encoding: "utf8", flag: "wx", mode: 384 }
@@ -14815,14 +14882,14 @@ function deactivateVerifiedPiRelease(input) {
14815
14882
  const problems = [];
14816
14883
  if (movedRelease) {
14817
14884
  try {
14818
- fs36.renameSync(backupReleaseDir, releaseDir);
14885
+ fs37.renameSync(backupReleaseDir, releaseDir);
14819
14886
  } catch {
14820
14887
  problems.push("cannot restore release");
14821
14888
  }
14822
14889
  }
14823
14890
  if (removedLink) {
14824
14891
  try {
14825
- fs36.symlinkSync(observedTarget, linkPath, "dir");
14892
+ fs37.symlinkSync(observedTarget, linkPath, "dir");
14826
14893
  } catch {
14827
14894
  problems.push("cannot restore managed entry");
14828
14895
  }
@@ -14832,7 +14899,7 @@ function deactivateVerifiedPiRelease(input) {
14832
14899
  if (oldSettings !== null) {
14833
14900
  atomicWritePrivate(settingsPath, oldSettings);
14834
14901
  } else {
14835
- fs36.rmSync(settingsPath, { force: true });
14902
+ fs37.rmSync(settingsPath, { force: true });
14836
14903
  }
14837
14904
  } catch {
14838
14905
  problems.push("cannot restore previous settings");
@@ -14840,7 +14907,7 @@ function deactivateVerifiedPiRelease(input) {
14840
14907
  }
14841
14908
  if (movedReceipt) {
14842
14909
  try {
14843
- fs36.renameSync(backupReceiptFile, receiptPath);
14910
+ fs37.renameSync(backupReceiptFile, receiptPath);
14844
14911
  } catch {
14845
14912
  problems.push("cannot restore receipt");
14846
14913
  }
@@ -14849,9 +14916,9 @@ function deactivateVerifiedPiRelease(input) {
14849
14916
  failIncomplete(`uninstall rollback incomplete (${problems.join("; ")}): ${original}`);
14850
14917
  }
14851
14918
  try {
14852
- fs36.rmSync(markerPath, { force: true });
14919
+ fs37.rmSync(markerPath, { force: true });
14853
14920
  releaseLock();
14854
- fs36.rmSync(uninstallBackupDir, { recursive: true, force: true });
14921
+ fs37.rmSync(uninstallBackupDir, { recursive: true, force: true });
14855
14922
  } catch {
14856
14923
  failIncomplete(`cannot clear transaction state after rollback: ${original}`);
14857
14924
  }
@@ -14864,11 +14931,11 @@ function deactivateVerifiedPiRelease(input) {
14864
14931
  throw wrapped;
14865
14932
  };
14866
14933
  try {
14867
- fs36.unlinkSync(linkPath);
14934
+ fs37.unlinkSync(linkPath);
14868
14935
  removedLink = true;
14869
- fs36.renameSync(releaseDir, backupReleaseDir);
14936
+ fs37.renameSync(releaseDir, backupReleaseDir);
14870
14937
  movedRelease = true;
14871
- fs36.renameSync(receiptPath, backupReceiptFile);
14938
+ fs37.renameSync(receiptPath, backupReceiptFile);
14872
14939
  movedReceipt = true;
14873
14940
  atomicWritePrivate(settingsPath, input.nextSettings);
14874
14941
  wroteSettings = true;
@@ -14890,7 +14957,7 @@ function deactivateVerifiedPiRelease(input) {
14890
14957
  rollbackDeactivate(new Error(`verify must be synchronous and return void, got thenable`));
14891
14958
  }
14892
14959
  try {
14893
- fs36.rmSync(markerPath, { force: true });
14960
+ fs37.rmSync(markerPath, { force: true });
14894
14961
  releaseLock();
14895
14962
  } catch {
14896
14963
  failIncomplete(`cannot clear transaction state after uninstall (recovery incomplete): ${markerPath}`);
@@ -14931,7 +14998,7 @@ function readRegularTextLegacy(file, label) {
14931
14998
  throw new Error(`${label} exceeds size bound: ${file}`);
14932
14999
  }
14933
15000
  try {
14934
- return fs36.readFileSync(file, "utf8");
15001
+ return fs37.readFileSync(file, "utf8");
14935
15002
  } catch {
14936
15003
  throw new Error(`cannot read ${label}: ${file}`);
14937
15004
  }
@@ -14943,7 +15010,7 @@ function deactivateVerifiedLegacyPiEntry(input) {
14943
15010
  if (typeof input.homeDir !== "string" || input.homeDir === "" || typeof input.agentDir !== "string" || input.agentDir === "" || typeof input.receiptPath !== "string" || input.receiptPath === "" || typeof input.source !== "string" || input.source === "") {
14944
15011
  throw new Error(`homeDir, agentDir, receiptPath and source must be non-empty strings`);
14945
15012
  }
14946
- if (!path44.isAbsolute(input.homeDir)) {
15013
+ if (!path45.isAbsolute(input.homeDir)) {
14947
15014
  throw new Error(`homeDir must be absolute: ${input.homeDir}`);
14948
15015
  }
14949
15016
  const sourceMatch = LEGACY_SOURCE_PATTERN.exec(input.source);
@@ -14977,13 +15044,13 @@ function deactivateVerifiedLegacyPiEntry(input) {
14977
15044
  if (agentStat === null || !agentStat.isDirectory() || agentStat.isSymbolicLink()) {
14978
15045
  throw new Error(`agentDir must be a real directory: ${input.agentDir}`);
14979
15046
  }
14980
- const settingsPath = path44.join(agentDir, "settings.json");
14981
- const npmDir = path44.join(agentDir, "npm");
14982
- const nodeModules = path44.join(npmDir, "node_modules");
14983
- const legacyEntry = path44.join(nodeModules, EXPECTED_ENTRY);
14984
- const managedRoot = path44.join(npmDir, "jorgex-pi-managed");
14985
- const markerPath = path44.join(managedRoot, "active-transaction.json");
14986
- const lockPath = path44.join(managedRoot, "transaction.lock");
15047
+ const settingsPath = path45.join(agentDir, "settings.json");
15048
+ const npmDir = path45.join(agentDir, "npm");
15049
+ const nodeModules = path45.join(npmDir, "node_modules");
15050
+ const legacyEntry = path45.join(nodeModules, EXPECTED_ENTRY);
15051
+ const managedRoot = path45.join(npmDir, "jorgex-pi-managed");
15052
+ const markerPath = path45.join(managedRoot, "active-transaction.json");
15053
+ const lockPath = path45.join(managedRoot, "transaction.lock");
14987
15054
  assertStrictChild(agentDir, homeDir, "agentDir");
14988
15055
  assertStrictChild(receiptPath, homeDir, "receiptPath");
14989
15056
  assertStrictChild(managedRoot, agentDir, "managed root");
@@ -15016,8 +15083,8 @@ function deactivateVerifiedLegacyPiEntry(input) {
15016
15083
  if (entryStat === null || !entryStat.isDirectory() || entryStat.isSymbolicLink()) {
15017
15084
  throw new Error(`managed entry must be a real directory, not a symlink: ${legacyEntry}`);
15018
15085
  }
15019
- assertAncestorsClean(path44.dirname(legacyEntry), homeDir, "managed entry");
15020
- const manifestPath = path44.join(legacyEntry, "package.json");
15086
+ assertAncestorsClean(path45.dirname(legacyEntry), homeDir, "managed entry");
15087
+ const manifestPath = path45.join(legacyEntry, "package.json");
15021
15088
  const manifestStat = lstatOrNull5(manifestPath);
15022
15089
  if (manifestStat === null || !manifestStat.isFile() || manifestStat.isSymbolicLink()) {
15023
15090
  throw new Error(`managed entry manifest must be a regular file: ${manifestPath}`);
@@ -15114,10 +15181,10 @@ function deactivateVerifiedLegacyPiEntry(input) {
15114
15181
  let lockAcquired = false;
15115
15182
  const releaseLock = () => {
15116
15183
  if (!lockAcquired) return;
15117
- fs36.rmSync(lockPath, { force: true });
15184
+ fs37.rmSync(lockPath, { force: true });
15118
15185
  lockAcquired = false;
15119
15186
  };
15120
- fs36.mkdirSync(managedRoot, { recursive: true });
15187
+ fs37.mkdirSync(managedRoot, { recursive: true });
15121
15188
  assertAncestorsClean(managedRoot, homeDir, "managed root");
15122
15189
  const managedRootStat = lstatOrNull5(managedRoot);
15123
15190
  if (managedRootStat === null || !managedRootStat.isDirectory() || managedRootStat.isSymbolicLink()) {
@@ -15125,7 +15192,7 @@ function deactivateVerifiedLegacyPiEntry(input) {
15125
15192
  }
15126
15193
  let uninstallBackupDir = "";
15127
15194
  for (let i = 0; i < 5 && uninstallBackupDir === ""; i++) {
15128
- const candidateDir = path44.join(managedRoot, `uninstall-backup-${crypto2.randomBytes(8).toString("hex")}`);
15195
+ const candidateDir = path45.join(managedRoot, `uninstall-backup-${crypto2.randomBytes(8).toString("hex")}`);
15129
15196
  if (lstatOrNull5(candidateDir) === null) uninstallBackupDir = candidateDir;
15130
15197
  }
15131
15198
  if (uninstallBackupDir === "") {
@@ -15135,14 +15202,14 @@ function deactivateVerifiedLegacyPiEntry(input) {
15135
15202
  const lockToken = `${JSON.stringify({ op: "uninstall-legacy", pid: process.pid, agentDir, source: input.source, startedAt: (/* @__PURE__ */ new Date()).toISOString() })}
15136
15203
  `;
15137
15204
  try {
15138
- fs36.writeFileSync(lockPath, lockToken, { encoding: "utf8", flag: "wx", mode: 384 });
15205
+ fs37.writeFileSync(lockPath, lockToken, { encoding: "utf8", flag: "wx", mode: 384 });
15139
15206
  lockAcquired = true;
15140
15207
  } catch {
15141
15208
  failIncomplete(`transaction lock busy: concurrent operation holds the exclusive lock (recovery incomplete): ${lockPath}`);
15142
15209
  }
15143
15210
  if (lstatOrNull5(markerPath) !== null) {
15144
15211
  try {
15145
- fs36.rmSync(lockPath, { force: true });
15212
+ fs37.rmSync(lockPath, { force: true });
15146
15213
  lockAcquired = false;
15147
15214
  } catch {
15148
15215
  }
@@ -15151,10 +15218,10 @@ function deactivateVerifiedLegacyPiEntry(input) {
15151
15218
  const markerContent = `${JSON.stringify({ phase: "uninstall-legacy", legacyEntry, receiptPath, backupDir: uninstallBackupDir, source: input.source, pid: process.pid }, null, 2)}
15152
15219
  `;
15153
15220
  try {
15154
- fs36.writeFileSync(markerPath, markerContent, { encoding: "utf8", flag: "wx", mode: 384 });
15221
+ fs37.writeFileSync(markerPath, markerContent, { encoding: "utf8", flag: "wx", mode: 384 });
15155
15222
  } catch {
15156
15223
  try {
15157
- fs36.rmSync(lockPath, { force: true });
15224
+ fs37.rmSync(lockPath, { force: true });
15158
15225
  lockAcquired = false;
15159
15226
  } catch {
15160
15227
  }
@@ -15163,7 +15230,7 @@ function deactivateVerifiedLegacyPiEntry(input) {
15163
15230
  const abortOwnTransaction = (err) => {
15164
15231
  const problems = [];
15165
15232
  try {
15166
- fs36.rmSync(markerPath, { force: true });
15233
+ fs37.rmSync(markerPath, { force: true });
15167
15234
  } catch {
15168
15235
  problems.push("cannot remove marker");
15169
15236
  }
@@ -15173,7 +15240,7 @@ function deactivateVerifiedLegacyPiEntry(input) {
15173
15240
  problems.push("cannot release lock");
15174
15241
  }
15175
15242
  try {
15176
- fs36.rmSync(uninstallBackupDir, { recursive: true, force: true });
15243
+ fs37.rmSync(uninstallBackupDir, { recursive: true, force: true });
15177
15244
  } catch {
15178
15245
  problems.push("cannot clear backup");
15179
15246
  }
@@ -15192,7 +15259,7 @@ function deactivateVerifiedLegacyPiEntry(input) {
15192
15259
  abortOwnTransaction(new Error(`receipt or settings drifted before uninstall: ${legacyEntry}`));
15193
15260
  }
15194
15261
  try {
15195
- fs36.mkdirSync(uninstallBackupDir, { recursive: true });
15262
+ fs37.mkdirSync(uninstallBackupDir, { recursive: true });
15196
15263
  } catch (err) {
15197
15264
  abortOwnTransaction(err);
15198
15265
  }
@@ -15202,20 +15269,20 @@ function deactivateVerifiedLegacyPiEntry(input) {
15202
15269
  }
15203
15270
  let backupEntries = [];
15204
15271
  try {
15205
- backupEntries = fs36.readdirSync(uninstallBackupDir);
15272
+ backupEntries = fs37.readdirSync(uninstallBackupDir);
15206
15273
  } catch {
15207
15274
  abortOwnTransaction(new Error(`cannot inspect uninstall backup: ${uninstallBackupDir}`));
15208
15275
  }
15209
15276
  if (backupEntries.length !== 0) {
15210
15277
  abortOwnTransaction(new Error(`uninstall backup is not empty: ${uninstallBackupDir}`));
15211
15278
  }
15212
- const backupEntryDir = path44.join(uninstallBackupDir, "entry");
15213
- const backupReceiptFile = path44.join(uninstallBackupDir, "pi-receipt.json");
15214
- const backupSettingsFile = path44.join(uninstallBackupDir, "settings.json");
15279
+ const backupEntryDir = path45.join(uninstallBackupDir, "entry");
15280
+ const backupReceiptFile = path45.join(uninstallBackupDir, "pi-receipt.json");
15281
+ const backupSettingsFile = path45.join(uninstallBackupDir, "settings.json");
15215
15282
  try {
15216
- fs36.writeFileSync(backupSettingsFile, oldSettings, { encoding: "utf8", flag: "wx", mode: 384 });
15217
- fs36.writeFileSync(
15218
- path44.join(uninstallBackupDir, "meta.json"),
15283
+ fs37.writeFileSync(backupSettingsFile, oldSettings, { encoding: "utf8", flag: "wx", mode: 384 });
15284
+ fs37.writeFileSync(
15285
+ path45.join(uninstallBackupDir, "meta.json"),
15219
15286
  `${JSON.stringify({ phase: "uninstall-legacy", legacyEntry, receiptPath, source: input.source }, null, 2)}
15220
15287
  `,
15221
15288
  { encoding: "utf8", flag: "wx", mode: 384 }
@@ -15259,14 +15326,14 @@ function deactivateVerifiedLegacyPiEntry(input) {
15259
15326
  const problems = [];
15260
15327
  if (movedReceipt) {
15261
15328
  try {
15262
- fs36.renameSync(backupReceiptFile, receiptPath);
15329
+ fs37.renameSync(backupReceiptFile, receiptPath);
15263
15330
  } catch {
15264
15331
  problems.push("cannot restore receipt");
15265
15332
  }
15266
15333
  }
15267
15334
  if (movedEntry) {
15268
15335
  try {
15269
- fs36.renameSync(backupEntryDir, legacyEntry);
15336
+ fs37.renameSync(backupEntryDir, legacyEntry);
15270
15337
  } catch {
15271
15338
  problems.push("cannot restore previous entry");
15272
15339
  }
@@ -15282,9 +15349,9 @@ function deactivateVerifiedLegacyPiEntry(input) {
15282
15349
  failIncomplete(`uninstall rollback incomplete (${problems.join("; ")}): ${original}`);
15283
15350
  }
15284
15351
  try {
15285
- fs36.rmSync(markerPath, { force: true });
15352
+ fs37.rmSync(markerPath, { force: true });
15286
15353
  releaseLock();
15287
- fs36.rmSync(uninstallBackupDir, { recursive: true, force: true });
15354
+ fs37.rmSync(uninstallBackupDir, { recursive: true, force: true });
15288
15355
  } catch {
15289
15356
  failIncomplete(`cannot clear transaction state after rollback: ${original}`);
15290
15357
  }
@@ -15297,9 +15364,9 @@ function deactivateVerifiedLegacyPiEntry(input) {
15297
15364
  throw wrapped;
15298
15365
  };
15299
15366
  try {
15300
- fs36.renameSync(legacyEntry, backupEntryDir);
15367
+ fs37.renameSync(legacyEntry, backupEntryDir);
15301
15368
  movedEntry = true;
15302
- fs36.renameSync(receiptPath, backupReceiptFile);
15369
+ fs37.renameSync(receiptPath, backupReceiptFile);
15303
15370
  movedReceipt = true;
15304
15371
  atomicWritePrivate(settingsPath, input.nextSettings);
15305
15372
  wroteSettings = true;
@@ -15321,7 +15388,7 @@ function deactivateVerifiedLegacyPiEntry(input) {
15321
15388
  rollbackLegacy(new Error(`verify must be synchronous and return void, got thenable`));
15322
15389
  }
15323
15390
  try {
15324
- fs36.rmSync(markerPath, { force: true });
15391
+ fs37.rmSync(markerPath, { force: true });
15325
15392
  releaseLock();
15326
15393
  } catch {
15327
15394
  failIncomplete(`cannot clear transaction state after uninstall (recovery incomplete): ${markerPath}`);
@@ -15377,8 +15444,8 @@ async function activatePreparedPiInstall(input, deps) {
15377
15444
  // src/lib/pi-stage-smoke.ts
15378
15445
  init_detect();
15379
15446
  import { spawn, spawnSync as spawnSync4 } from "child_process";
15380
- import fs37 from "fs";
15381
- import path45 from "path";
15447
+ import fs38 from "fs";
15448
+ import path46 from "path";
15382
15449
  var REQUIRED_COMMANDS = ["goal", "subagents", "permission-system", "websearch", "jorgex:header"];
15383
15450
  var EXPECTED_ARGV = ["--mode", "rpc", "--no-session", "--no-approve", "--offline", "--no-context-files"];
15384
15451
  var KNOWN_STDERR_WARNING = "[pi-web-access] Dynamic tool activation requires Pi 0.86.1 or newer; web tools remain eagerly available.";
@@ -15395,13 +15462,13 @@ function isRecord12(value) {
15395
15462
  }
15396
15463
  function lstatOrNull6(p7) {
15397
15464
  try {
15398
- return fs37.lstatSync(p7);
15465
+ return fs38.lstatSync(p7);
15399
15466
  } catch {
15400
15467
  return null;
15401
15468
  }
15402
15469
  }
15403
15470
  function assertPiExecutable(piExecutable) {
15404
- const absolute = path45.resolve(piExecutable);
15471
+ const absolute = path46.resolve(piExecutable);
15405
15472
  const linkStat = lstatOrNull6(absolute);
15406
15473
  if (linkStat === null) {
15407
15474
  fail10(`piExecutable must exist: ${piExecutable}`);
@@ -15409,13 +15476,13 @@ function assertPiExecutable(piExecutable) {
15409
15476
  if (linkStat.isSymbolicLink()) {
15410
15477
  let real;
15411
15478
  try {
15412
- real = fs37.realpathSync(absolute);
15479
+ real = fs38.realpathSync(absolute);
15413
15480
  } catch {
15414
15481
  fail10(`piExecutable symlink is broken: ${piExecutable}`);
15415
15482
  }
15416
15483
  let targetStat;
15417
15484
  try {
15418
- targetStat = fs37.statSync(real);
15485
+ targetStat = fs38.statSync(real);
15419
15486
  } catch {
15420
15487
  fail10(`piExecutable symlink target is missing: ${piExecutable}`);
15421
15488
  }
@@ -15424,7 +15491,7 @@ function assertPiExecutable(piExecutable) {
15424
15491
  }
15425
15492
  if (process.platform !== "win32") {
15426
15493
  try {
15427
- fs37.accessSync(real, fs37.constants.X_OK);
15494
+ fs38.accessSync(real, fs38.constants.X_OK);
15428
15495
  } catch {
15429
15496
  fail10(`piExecutable symlink target is not executable: ${piExecutable}`);
15430
15497
  }
@@ -15436,7 +15503,7 @@ function assertPiExecutable(piExecutable) {
15436
15503
  }
15437
15504
  if (process.platform !== "win32") {
15438
15505
  try {
15439
- fs37.accessSync(absolute, fs37.constants.X_OK);
15506
+ fs38.accessSync(absolute, fs38.constants.X_OK);
15440
15507
  } catch {
15441
15508
  fail10(`piExecutable is not executable: ${piExecutable}`);
15442
15509
  }
@@ -15444,7 +15511,7 @@ function assertPiExecutable(piExecutable) {
15444
15511
  return absolute;
15445
15512
  }
15446
15513
  function assertRealDir3(p7, label) {
15447
- const resolved2 = path45.resolve(p7);
15514
+ const resolved2 = path46.resolve(p7);
15448
15515
  const st = lstatOrNull6(resolved2);
15449
15516
  if (st === null || !st.isDirectory() || st.isSymbolicLink()) {
15450
15517
  fail10(`${label} must be a real directory: ${p7}`);
@@ -15459,24 +15526,24 @@ function sleep(ms) {
15459
15526
  }
15460
15527
  function runtimePath2(piExecutable) {
15461
15528
  const entries = process.platform === "win32" ? [
15462
- path45.dirname(piExecutable),
15463
- path45.dirname(process.execPath),
15464
- process.env.SystemRoot ? path45.join(process.env.SystemRoot, "System32") : null
15465
- ] : [path45.dirname(piExecutable), path45.dirname(process.execPath), "/usr/local/bin", "/usr/bin", "/bin"];
15466
- return [...new Set(entries.filter((entry) => entry !== null))].join(path45.delimiter);
15529
+ path46.dirname(piExecutable),
15530
+ path46.dirname(process.execPath),
15531
+ process.env.SystemRoot ? path46.join(process.env.SystemRoot, "System32") : null
15532
+ ] : [path46.dirname(piExecutable), path46.dirname(process.execPath), "/usr/local/bin", "/usr/bin", "/bin"];
15533
+ return [...new Set(entries.filter((entry) => entry !== null))].join(path46.delimiter);
15467
15534
  }
15468
15535
  function buildSandboxEnv(stageRoot, stageDir, piExecutable) {
15469
- const home = path45.join(stageRoot, "home");
15470
- const appdata = path45.join(stageRoot, "appdata");
15471
- const localappdata = path45.join(stageRoot, "localappdata");
15472
- const xdgConfig = path45.join(stageRoot, "xdg-config");
15473
- const xdgData = path45.join(stageRoot, "xdg-data");
15474
- const xdgCache = path45.join(stageRoot, "xdg-cache");
15475
- const temporary = path45.join(stageRoot, "tmp");
15476
- const npmCache = path45.join(stageRoot, "npm-cache");
15536
+ const home = path46.join(stageRoot, "home");
15537
+ const appdata = path46.join(stageRoot, "appdata");
15538
+ const localappdata = path46.join(stageRoot, "localappdata");
15539
+ const xdgConfig = path46.join(stageRoot, "xdg-config");
15540
+ const xdgData = path46.join(stageRoot, "xdg-data");
15541
+ const xdgCache = path46.join(stageRoot, "xdg-cache");
15542
+ const temporary = path46.join(stageRoot, "tmp");
15543
+ const npmCache = path46.join(stageRoot, "npm-cache");
15477
15544
  for (const dir of [home, appdata, localappdata, xdgConfig, xdgData, xdgCache, temporary, npmCache]) {
15478
15545
  try {
15479
- fs37.mkdirSync(dir, { recursive: true, mode: 448 });
15546
+ fs38.mkdirSync(dir, { recursive: true, mode: 448 });
15480
15547
  } catch {
15481
15548
  fail10(`cannot prepare isolated stage dir: ${dir}`);
15482
15549
  }
@@ -15553,7 +15620,7 @@ async function stopOwned(child) {
15553
15620
  if (process.platform === "win32") {
15554
15621
  try {
15555
15622
  const systemRoot = process.env.SystemRoot ?? process.env.WINDIR ?? "C:\\Windows";
15556
- const taskkill = path45.join(systemRoot, "System32", "taskkill.exe");
15623
+ const taskkill = path46.join(systemRoot, "System32", "taskkill.exe");
15557
15624
  spawnSync4(taskkill, ["/pid", String(pid), "/t", "/f"], {
15558
15625
  shell: false,
15559
15626
  stdio: "ignore",
@@ -15702,26 +15769,26 @@ async function smokeStagedPiRuntime(input) {
15702
15769
  async function runSmoke(input) {
15703
15770
  if (!isRecord12(input)) fail10("input must be an object");
15704
15771
  const { piExecutable, stageDir, timeoutMs } = input;
15705
- if (typeof piExecutable !== "string" || piExecutable === "" || !path45.isAbsolute(piExecutable)) {
15772
+ if (typeof piExecutable !== "string" || piExecutable === "" || !path46.isAbsolute(piExecutable)) {
15706
15773
  fail10("piExecutable must be a non-empty absolute path");
15707
15774
  }
15708
- if (typeof stageDir !== "string" || stageDir === "" || !path45.isAbsolute(stageDir)) {
15775
+ if (typeof stageDir !== "string" || stageDir === "" || !path46.isAbsolute(stageDir)) {
15709
15776
  fail10("stageDir must be a non-empty absolute path");
15710
15777
  }
15711
15778
  const piResolved = assertPiExecutable(piExecutable);
15712
15779
  const stageResolved = assertRealDir3(stageDir, "stageDir");
15713
- if (path45.basename(stageResolved) !== "pi-agent") {
15780
+ if (path46.basename(stageResolved) !== "pi-agent") {
15714
15781
  fail10("stageDir must be the staged pi-agent dir (stageRoot/pi-agent)");
15715
15782
  }
15716
- const stageRoot = path45.dirname(stageResolved);
15783
+ const stageRoot = path46.dirname(stageResolved);
15717
15784
  const stageRootStat = lstatOrNull6(stageRoot);
15718
15785
  if (stageRootStat === null || !stageRootStat.isDirectory() || stageRootStat.isSymbolicLink()) {
15719
15786
  fail10("stageRoot must be a real directory");
15720
15787
  }
15721
- if (!path45.basename(stageRoot).startsWith("stage-")) {
15788
+ if (!path46.basename(stageRoot).startsWith("stage-")) {
15722
15789
  fail10("stageRoot must be a private stage- dir");
15723
15790
  }
15724
- const workspace = path45.join(stageRoot, "workspace");
15791
+ const workspace = path46.join(stageRoot, "workspace");
15725
15792
  assertRealDir3(workspace, "stage workspace");
15726
15793
  let timeout = DEFAULT_TIMEOUT_MS;
15727
15794
  if (timeoutMs !== void 0) {
@@ -15900,8 +15967,8 @@ ${JSON.stringify({ id: commandsId, type: "get_commands" })}
15900
15967
  // src/lib/pi-cached-artifact.ts
15901
15968
  init_npm_provider();
15902
15969
  import { createHash as createHash9, timingSafeEqual as timingSafeEqual6 } from "crypto";
15903
- import fs38 from "fs";
15904
- import path46 from "path";
15970
+ import fs39 from "fs";
15971
+ import path47 from "path";
15905
15972
  var PACKAGE_NAME5 = "jorgex-pi";
15906
15973
  var HEX643 = /^[0-9a-f]{64}$/;
15907
15974
  var HEX1283 = /^[0-9a-f]{128}$/;
@@ -15912,14 +15979,14 @@ function isRecord13(value) {
15912
15979
  }
15913
15980
  function lstatOrNull7(p7) {
15914
15981
  try {
15915
- return fs38.lstatSync(p7);
15982
+ return fs39.lstatSync(p7);
15916
15983
  } catch {
15917
15984
  return null;
15918
15985
  }
15919
15986
  }
15920
15987
  function isStrictChild5(child, root) {
15921
- const rel = path46.relative(root, child);
15922
- return rel !== "" && rel !== ".." && !rel.startsWith(`..${path46.sep}`) && !path46.isAbsolute(rel);
15988
+ const rel = path47.relative(root, child);
15989
+ return rel !== "" && rel !== ".." && !rel.startsWith(`..${path47.sep}`) && !path47.isAbsolute(rel);
15923
15990
  }
15924
15991
  function equalHex2(aHex, bHex) {
15925
15992
  let a;
@@ -15936,12 +16003,12 @@ function verifyCachedPiArtifact(input) {
15936
16003
  try {
15937
16004
  if (!isRecord13(input)) return false;
15938
16005
  const { receipt, homeDir, downloadsDir } = input;
15939
- if (typeof homeDir !== "string" || homeDir === "" || !path46.isAbsolute(homeDir)) return false;
15940
- if (typeof downloadsDir !== "string" || downloadsDir === "" || !path46.isAbsolute(downloadsDir)) {
16006
+ if (typeof homeDir !== "string" || homeDir === "" || !path47.isAbsolute(homeDir)) return false;
16007
+ if (typeof downloadsDir !== "string" || downloadsDir === "" || !path47.isAbsolute(downloadsDir)) {
15941
16008
  return false;
15942
16009
  }
15943
- const homeResolved = path46.resolve(homeDir);
15944
- const downloadsResolved = path46.resolve(downloadsDir);
16010
+ const homeResolved = path47.resolve(homeDir);
16011
+ const downloadsResolved = path47.resolve(downloadsDir);
15945
16012
  const homeStat = lstatOrNull7(homeResolved);
15946
16013
  if (homeStat === null || !homeStat.isDirectory() || homeStat.isSymbolicLink()) return false;
15947
16014
  const downloadsStat = lstatOrNull7(downloadsResolved);
@@ -15949,12 +16016,12 @@ function verifyCachedPiArtifact(input) {
15949
16016
  return false;
15950
16017
  }
15951
16018
  if (!isStrictChild5(downloadsResolved, homeResolved)) return false;
15952
- const rel = path46.relative(homeResolved, downloadsResolved);
15953
- const parts = rel.split(path46.sep);
16019
+ const rel = path47.relative(homeResolved, downloadsResolved);
16020
+ const parts = rel.split(path47.sep);
15954
16021
  let cursor = homeResolved;
15955
16022
  for (const part of parts) {
15956
16023
  if (part === "" || part === "." || part === "..") return false;
15957
- cursor = path46.join(cursor, part);
16024
+ cursor = path47.join(cursor, part);
15958
16025
  const st2 = lstatOrNull7(cursor);
15959
16026
  if (st2 === null || !st2.isDirectory() || st2.isSymbolicLink()) return false;
15960
16027
  }
@@ -15980,8 +16047,8 @@ function verifyCachedPiArtifact(input) {
15980
16047
  if (typeof sha2562 !== "string" || !HEX643.test(sha2562)) return false;
15981
16048
  if (typeof sha512 !== "string" || !HEX1283.test(sha512)) return false;
15982
16049
  const fileName = `${PACKAGE_NAME5}-${version}.tgz`;
15983
- const target = path46.join(downloadsResolved, fileName);
15984
- if (path46.dirname(target) !== downloadsResolved) return false;
16050
+ const target = path47.join(downloadsResolved, fileName);
16051
+ if (path47.dirname(target) !== downloadsResolved) return false;
15985
16052
  const st = lstatOrNull7(target);
15986
16053
  if (st === null) return false;
15987
16054
  if (st.isSymbolicLink()) return false;
@@ -15990,7 +16057,7 @@ function verifyCachedPiArtifact(input) {
15990
16057
  if (st.size > MAX_TARBALL_BYTES4) return false;
15991
16058
  let fd;
15992
16059
  try {
15993
- fd = fs38.openSync(target, "r");
16060
+ fd = fs39.openSync(target, "r");
15994
16061
  } catch {
15995
16062
  return false;
15996
16063
  }
@@ -16002,7 +16069,7 @@ function verifyCachedPiArtifact(input) {
16002
16069
  for (; ; ) {
16003
16070
  let read;
16004
16071
  try {
16005
- read = fs38.readSync(fd, buffer, 0, buffer.length, null);
16072
+ read = fs39.readSync(fd, buffer, 0, buffer.length, null);
16006
16073
  } catch {
16007
16074
  return false;
16008
16075
  }
@@ -16014,7 +16081,7 @@ function verifyCachedPiArtifact(input) {
16014
16081
  }
16015
16082
  } finally {
16016
16083
  try {
16017
- fs38.closeSync(fd);
16084
+ fs39.closeSync(fd);
16018
16085
  } catch {
16019
16086
  }
16020
16087
  }
@@ -16176,30 +16243,30 @@ async function resolvePiEngramRequirement(input, deps) {
16176
16243
  } : { kind: "existing", bin: detected, scope: "host" };
16177
16244
  }
16178
16245
  function runtimePath3(piExecutable) {
16179
- const entries = process.platform === "win32" ? [piExecutable === void 0 ? null : path47.dirname(piExecutable), path47.dirname(process.execPath), process.env.SystemRoot ? path47.join(process.env.SystemRoot, "System32") : null] : [piExecutable === void 0 ? null : path47.dirname(piExecutable), path47.dirname(process.execPath), "/usr/local/bin", "/usr/bin", "/bin"];
16180
- return [...new Set(entries.filter((entry) => entry !== null))].join(path47.delimiter);
16246
+ const entries = process.platform === "win32" ? [piExecutable === void 0 ? null : path48.dirname(piExecutable), path48.dirname(process.execPath), process.env.SystemRoot ? path48.join(process.env.SystemRoot, "System32") : null] : [piExecutable === void 0 ? null : path48.dirname(piExecutable), path48.dirname(process.execPath), "/usr/local/bin", "/usr/bin", "/bin"];
16247
+ return [...new Set(entries.filter((entry) => entry !== null))].join(path48.delimiter);
16181
16248
  }
16182
16249
  function targetPaths(targetDir, engramBin, piExecutable) {
16183
- const root = path47.resolve(targetDir);
16184
- const codingAgentDir = path47.join(root, "pi-agent");
16185
- const home = path47.join(root, "home");
16186
- const temporary = path47.join(root, "tmp");
16250
+ const root = path48.resolve(targetDir);
16251
+ const codingAgentDir = path48.join(root, "pi-agent");
16252
+ const home = path48.join(root, "home");
16253
+ const temporary = path48.join(root, "tmp");
16187
16254
  return {
16188
16255
  codingAgentDir,
16189
- receiptPath: path47.join(root, "state", "pi-receipt.json"),
16190
- packageRunner: path47.join(codingAgentDir, "npm", "node_modules", "jorgex-pi", "bin", "jorgex-pi.mjs"),
16256
+ receiptPath: path48.join(root, "state", "pi-receipt.json"),
16257
+ packageRunner: path48.join(codingAgentDir, "npm", "node_modules", "jorgex-pi", "bin", "jorgex-pi.mjs"),
16191
16258
  environment: {
16192
16259
  HOME: home,
16193
16260
  USERPROFILE: home,
16194
- APPDATA: path47.join(root, "appdata"),
16195
- LOCALAPPDATA: path47.join(root, "localappdata"),
16196
- XDG_CONFIG_HOME: path47.join(root, "xdg-config"),
16197
- XDG_DATA_HOME: path47.join(root, "xdg-data"),
16198
- XDG_CACHE_HOME: path47.join(root, "xdg-cache"),
16261
+ APPDATA: path48.join(root, "appdata"),
16262
+ LOCALAPPDATA: path48.join(root, "localappdata"),
16263
+ XDG_CONFIG_HOME: path48.join(root, "xdg-config"),
16264
+ XDG_DATA_HOME: path48.join(root, "xdg-data"),
16265
+ XDG_CACHE_HOME: path48.join(root, "xdg-cache"),
16199
16266
  TEMP: temporary,
16200
16267
  TMP: temporary,
16201
16268
  TMPDIR: temporary,
16202
- npm_config_cache: path47.join(root, "npm-cache"),
16269
+ npm_config_cache: path48.join(root, "npm-cache"),
16203
16270
  NPM_CONFIG_IGNORE_SCRIPTS: "true",
16204
16271
  NPM_CONFIG_UPDATE_NOTIFIER: "false",
16205
16272
  PI_CODING_AGENT_DIR: codingAgentDir,
@@ -16210,15 +16277,15 @@ function targetPaths(targetDir, engramBin, piExecutable) {
16210
16277
  }
16211
16278
  function userPaths(engramBin, piExecutable) {
16212
16279
  const home = os6.homedir();
16213
- const codingAgentDir = process.env.PI_CODING_AGENT_DIR ?? path47.join(home, ".pi", "agent");
16280
+ const codingAgentDir = process.env.PI_CODING_AGENT_DIR ?? path48.join(home, ".pi", "agent");
16214
16281
  return {
16215
16282
  codingAgentDir,
16216
- receiptPath: path47.join(dataDir(), "pi-receipt.json"),
16217
- packageRunner: path47.join(codingAgentDir, "npm", "node_modules", "jorgex-pi", "bin", "jorgex-pi.mjs"),
16283
+ receiptPath: path48.join(dataDir(), "pi-receipt.json"),
16284
+ packageRunner: path48.join(codingAgentDir, "npm", "node_modules", "jorgex-pi", "bin", "jorgex-pi.mjs"),
16218
16285
  environment: {
16219
16286
  HOME: home,
16220
- XDG_CONFIG_HOME: process.env.XDG_CONFIG_HOME ?? path47.join(home, ".config"),
16221
- XDG_CACHE_HOME: process.env.XDG_CACHE_HOME ?? path47.join(home, ".cache"),
16287
+ XDG_CONFIG_HOME: process.env.XDG_CONFIG_HOME ?? path48.join(home, ".config"),
16288
+ XDG_CACHE_HOME: process.env.XDG_CACHE_HOME ?? path48.join(home, ".cache"),
16222
16289
  TMPDIR: os6.tmpdir(),
16223
16290
  NPM_CONFIG_IGNORE_SCRIPTS: "true",
16224
16291
  NPM_CONFIG_UPDATE_NOTIFIER: "false",
@@ -16254,7 +16321,7 @@ function runPiRuntime(input, deps) {
16254
16321
  }
16255
16322
  const candidate = input.candidate ?? PI_RUNTIME_CANDIDATE;
16256
16323
  const paths = input.targetDir === void 0 ? userPaths(input.engramBin, input.detected.executable) : targetPaths(input.targetDir, input.engramBin, input.detected.executable);
16257
- const settingsJson = deps.readSettings(path47.join(paths.codingAgentDir, "settings.json"));
16324
+ const settingsJson = deps.readSettings(path48.join(paths.codingAgentDir, "settings.json"));
16258
16325
  const receiptJson = deps.readReceipt(paths.receiptPath);
16259
16326
  const lifecycleInput = {
16260
16327
  candidate,
@@ -16319,60 +16386,32 @@ function runPiRuntime(input, deps) {
16319
16386
  persistReturnedReceipt(result, paths, deps);
16320
16387
  return result;
16321
16388
  }
16322
- function readJsonFile2(file) {
16323
- return JSON.parse(fs39.readFileSync(file, "utf8"));
16324
- }
16325
- function packageVersionFromExecutable(executable) {
16326
- let current;
16327
- try {
16328
- current = path47.dirname(fs39.realpathSync(executable));
16329
- } catch {
16330
- return null;
16331
- }
16332
- for (let depth = 0; depth < 8; depth++) {
16333
- const manifests = [
16334
- path47.join(current, "package.json"),
16335
- path47.join(current, "node_modules", "@earendil-works", "pi-coding-agent", "package.json")
16336
- ];
16337
- for (const manifest of manifests) {
16338
- try {
16339
- const parsed = readJsonFile2(manifest);
16340
- if (parsed !== null && typeof parsed === "object" && Reflect.get(parsed, "name") === "@earendil-works/pi-coding-agent" && typeof Reflect.get(parsed, "version") === "string") {
16341
- return Reflect.get(parsed, "version");
16342
- }
16343
- } catch {
16344
- }
16345
- }
16346
- const parent = path47.dirname(current);
16347
- if (parent === current) break;
16348
- current = parent;
16349
- }
16350
- return null;
16351
- }
16352
16389
  function detectPiRuntime() {
16353
16390
  const executable = lookPath("pi");
16354
16391
  const home = os6.homedir();
16392
+ const inspection = executable === null ? null : inspectPiHostVersion(executable);
16355
16393
  return {
16356
16394
  id: "pi",
16357
16395
  name: "Pi",
16358
16396
  installed: executable !== null,
16359
16397
  executable,
16360
- version: executable === null ? null : packageVersionFromExecutable(executable),
16361
- codingAgentDir: process.env.PI_CODING_AGENT_DIR ?? path47.join(home, ".pi", "agent")
16398
+ version: inspection?.version ?? null,
16399
+ versionDiagnostic: inspection?.diagnostic ?? null,
16400
+ codingAgentDir: process.env.PI_CODING_AGENT_DIR ?? path48.join(home, ".pi", "agent")
16362
16401
  };
16363
16402
  }
16364
16403
  function hasManagedPiRuntime(targetDir) {
16365
- const receipt = targetDir === void 0 ? path47.join(dataDir(), "pi-receipt.json") : path47.join(path47.resolve(targetDir), "state", "pi-receipt.json");
16366
- return fs39.statSync(receipt, { throwIfNoEntry: false })?.isFile() === true;
16404
+ const receipt = targetDir === void 0 ? path48.join(dataDir(), "pi-receipt.json") : path48.join(path48.resolve(targetDir), "state", "pi-receipt.json");
16405
+ return fs40.statSync(receipt, { throwIfNoEntry: false })?.isFile() === true;
16367
16406
  }
16368
16407
  function resolvePiEngramBin(targetDir) {
16369
16408
  if (targetDir === void 0) return detectEngram();
16370
- const candidate = path47.join(path47.resolve(targetDir), "bin", process.platform === "win32" ? "engram.exe" : "engram");
16371
- return fs39.statSync(candidate, { throwIfNoEntry: false })?.isFile() ? candidate : null;
16409
+ const candidate = path48.join(path48.resolve(targetDir), "bin", process.platform === "win32" ? "engram.exe" : "engram");
16410
+ return fs40.statSync(candidate, { throwIfNoEntry: false })?.isFile() ? candidate : null;
16372
16411
  }
16373
16412
  function readOptional(file, fallback) {
16374
16413
  try {
16375
- return fs39.readFileSync(file, "utf8");
16414
+ return fs40.readFileSync(file, "utf8");
16376
16415
  } catch (error) {
16377
16416
  if (error.code === "ENOENT") return fallback;
16378
16417
  throw error;
@@ -16438,7 +16477,7 @@ function preparedInstallMismatch(candidate, prepared) {
16438
16477
  return "la release preparada no coincide con la versi\xF3n/SRI del candidato";
16439
16478
  }
16440
16479
  const stageDir = prepared?.stageDir;
16441
- if (typeof stageDir !== "string" || stageDir === "" || !/(^|[\\/])stage-[0-9a-f]{32}[\\/]pi-agent$/.test(path47.resolve(stageDir))) {
16480
+ if (typeof stageDir !== "string" || stageDir === "" || !/(^|[\\/])stage-[0-9a-f]{32}[\\/]pi-agent$/.test(path48.resolve(stageDir))) {
16442
16481
  return "el stage preparado no tiene el layout aislado esperado (stage-<hex>/pi-agent)";
16443
16482
  }
16444
16483
  const evidence = prepared?.evidence;
@@ -16513,12 +16552,12 @@ function backupLegacyMigrationState(settingsPath, receiptPath, backupRoot) {
16513
16552
  }
16514
16553
  }
16515
16554
  function verifyActivePiRelease(input) {
16516
- const agentDir = path47.resolve(input.agentDir);
16517
- const npmDir = path47.join(agentDir, "npm");
16518
- const managedRoot = path47.join(npmDir, "jorgex-pi-managed");
16555
+ const agentDir = path48.resolve(input.agentDir);
16556
+ const npmDir = path48.join(agentDir, "npm");
16557
+ const managedRoot = path48.join(npmDir, "jorgex-pi-managed");
16519
16558
  let receiptRaw;
16520
16559
  try {
16521
- receiptRaw = fs39.readFileSync(input.receiptPath, "utf8");
16560
+ receiptRaw = fs40.readFileSync(input.receiptPath, "utf8");
16522
16561
  } catch {
16523
16562
  throw new Error(`pi-verify-active: no se pudo leer el receipt promovido: ${input.receiptPath}`);
16524
16563
  }
@@ -16547,7 +16586,7 @@ function verifyActivePiRelease(input) {
16547
16586
  throw new Error("pi-verify-active: el scope del receipt promovido no coincide con el esperado");
16548
16587
  }
16549
16588
  const scopeDir = scopeRecord["codingAgentDir"];
16550
- if (typeof scopeDir !== "string" || !path47.isAbsolute(scopeDir) || path47.resolve(scopeDir) !== agentDir) {
16589
+ if (typeof scopeDir !== "string" || !path48.isAbsolute(scopeDir) || path48.resolve(scopeDir) !== agentDir) {
16551
16590
  throw new Error("pi-verify-active: el codingAgentDir del receipt promovido no coincide con el agentDir");
16552
16591
  }
16553
16592
  const receiptEngram = record["engram"];
@@ -16578,40 +16617,40 @@ function verifyActivePiRelease(input) {
16578
16617
  throw new Error("pi-verify-active: el receipt promovido no conserva las seis dependencias de la evidencia");
16579
16618
  }
16580
16619
  const linkPath = managedRecord["linkPath"];
16581
- if (typeof linkPath !== "string" || !path47.isAbsolute(linkPath)) {
16620
+ if (typeof linkPath !== "string" || !path48.isAbsolute(linkPath)) {
16582
16621
  throw new Error("pi-verify-active: el receipt promovido no trae un linkPath absoluto");
16583
16622
  }
16584
- const linkResolved = path47.resolve(linkPath);
16585
- if (linkResolved !== path47.join(npmDir, "node_modules", "jorgex-pi")) {
16623
+ const linkResolved = path48.resolve(linkPath);
16624
+ if (linkResolved !== path48.join(npmDir, "node_modules", "jorgex-pi")) {
16586
16625
  throw new Error("pi-verify-active: el enlace publicado sale del entry propio");
16587
16626
  }
16588
16627
  const releaseDir = managedRecord["releaseDir"];
16589
- if (typeof releaseDir !== "string" || !path47.isAbsolute(releaseDir)) {
16628
+ if (typeof releaseDir !== "string" || !path48.isAbsolute(releaseDir)) {
16590
16629
  throw new Error("pi-verify-active: el receipt promovido no trae un releaseDir absoluto");
16591
16630
  }
16592
- const releaseResolved = path47.resolve(releaseDir);
16593
- const releaseRel = path47.relative(managedRoot, releaseResolved);
16594
- if (releaseRel === "" || releaseRel === ".." || releaseRel.startsWith(`..${path47.sep}`) || path47.isAbsolute(releaseRel)) {
16631
+ const releaseResolved = path48.resolve(releaseDir);
16632
+ const releaseRel = path48.relative(managedRoot, releaseResolved);
16633
+ if (releaseRel === "" || releaseRel === ".." || releaseRel.startsWith(`..${path48.sep}`) || path48.isAbsolute(releaseRel)) {
16595
16634
  throw new Error("pi-verify-active: el release promovido sale del root gestionado");
16596
16635
  }
16597
16636
  let target;
16598
16637
  try {
16599
- const linkStat = fs39.lstatSync(linkResolved);
16638
+ const linkStat = fs40.lstatSync(linkResolved);
16600
16639
  if (!linkStat.isSymbolicLink()) {
16601
16640
  throw new Error("pi-verify-active: el entry publicado no es un enlace");
16602
16641
  }
16603
- target = fs39.readlinkSync(linkResolved);
16642
+ target = fs40.readlinkSync(linkResolved);
16604
16643
  } catch (error) {
16605
16644
  if (error instanceof Error && error.message.startsWith("pi-verify-active: ")) throw error;
16606
16645
  throw new Error("pi-verify-active: no se pudo leer el enlace publicado");
16607
16646
  }
16608
- const packageRoot = path47.join(releaseResolved, "node_modules", "jorgex-pi");
16609
- if (target === "" || path47.isAbsolute(target) || path47.resolve(path47.dirname(linkResolved), target) !== packageRoot) {
16647
+ const packageRoot = path48.join(releaseResolved, "node_modules", "jorgex-pi");
16648
+ if (target === "" || path48.isAbsolute(target) || path48.resolve(path48.dirname(linkResolved), target) !== packageRoot) {
16610
16649
  throw new Error("pi-verify-active: el enlace publicado no apunta al release promovido");
16611
16650
  }
16612
16651
  let realRoot;
16613
16652
  try {
16614
- realRoot = fs39.realpathSync(linkResolved);
16653
+ realRoot = fs40.realpathSync(linkResolved);
16615
16654
  } catch {
16616
16655
  throw new Error("pi-verify-active: no se pudo resolver el realpath del enlace publicado");
16617
16656
  }
@@ -16629,8 +16668,8 @@ function verifyActivePiRelease(input) {
16629
16668
  }
16630
16669
  }
16631
16670
  function isStrictChildPath(child, root) {
16632
- const rel = path47.relative(path47.resolve(root), path47.resolve(child));
16633
- return rel !== "" && rel !== ".." && !rel.startsWith(`..${path47.sep}`) && !path47.isAbsolute(rel);
16671
+ const rel = path48.relative(path48.resolve(root), path48.resolve(child));
16672
+ return rel !== "" && rel !== ".." && !rel.startsWith(`..${path48.sep}`) && !path48.isAbsolute(rel);
16634
16673
  }
16635
16674
  async function preparePiRuntimeSystem(input) {
16636
16675
  if (input.operation !== "install" && input.operation !== "update") {
@@ -16648,7 +16687,7 @@ async function preparePiRuntimeSystem(input) {
16648
16687
  remedy: "El update con --target-dir nunca ejecuta preflight de red; aporta un stage preverificado o usa update real."
16649
16688
  };
16650
16689
  }
16651
- if (typeof input.engramBin !== "string" || input.engramBin === "" || !path47.isAbsolute(input.engramBin)) {
16690
+ if (typeof input.engramBin !== "string" || input.engramBin === "" || !path48.isAbsolute(input.engramBin)) {
16652
16691
  return {
16653
16692
  kind: "blocked",
16654
16693
  reason: "engram-required",
@@ -16656,7 +16695,7 @@ async function preparePiRuntimeSystem(input) {
16656
16695
  };
16657
16696
  }
16658
16697
  const updateExecutable = input.detected.executable;
16659
- if (typeof updateExecutable !== "string" || updateExecutable === "" || !path47.isAbsolute(updateExecutable)) {
16698
+ if (typeof updateExecutable !== "string" || updateExecutable === "" || !path48.isAbsolute(updateExecutable)) {
16660
16699
  return {
16661
16700
  kind: "blocked",
16662
16701
  reason: "pi-executable-missing",
@@ -16671,16 +16710,16 @@ async function preparePiRuntimeSystem(input) {
16671
16710
  };
16672
16711
  }
16673
16712
  const updateHomeDir = os6.homedir();
16674
- if (typeof updateHomeDir !== "string" || updateHomeDir === "" || !path47.isAbsolute(updateHomeDir)) {
16713
+ if (typeof updateHomeDir !== "string" || updateHomeDir === "" || !path48.isAbsolute(updateHomeDir)) {
16675
16714
  return {
16676
16715
  kind: "blocked",
16677
16716
  reason: "preflight-failed",
16678
16717
  remedy: "HOME ilegible para el preflight Pi; Pi no qued\xF3 activado."
16679
16718
  };
16680
16719
  }
16681
- const updateAgentDir = process.env.PI_CODING_AGENT_DIR ?? path47.join(updateHomeDir, ".pi", "agent");
16682
- const updateReceiptPath = path47.join(updateHomeDir, ".jorgex-stack", "pi-receipt.json");
16683
- const updateDownloadsDir = path47.join(updateHomeDir, ".jorgex-stack", "packages");
16720
+ const updateAgentDir = process.env.PI_CODING_AGENT_DIR ?? path48.join(updateHomeDir, ".pi", "agent");
16721
+ const updateReceiptPath = path48.join(updateHomeDir, ".jorgex-stack", "pi-receipt.json");
16722
+ const updateDownloadsDir = path48.join(updateHomeDir, ".jorgex-stack", "packages");
16684
16723
  if (!isStrictChildPath(updateAgentDir, updateHomeDir)) {
16685
16724
  return {
16686
16725
  kind: "blocked",
@@ -16688,7 +16727,7 @@ async function preparePiRuntimeSystem(input) {
16688
16727
  remedy: `PI_CODING_AGENT_DIR (${updateAgentDir}) est\xE1 fuera de la frontera de restore HOME (${updateHomeDir}); corrige el destino antes de reintentar; Pi no qued\xF3 activado.`
16689
16728
  };
16690
16729
  }
16691
- const updateSettingsPath = path47.join(updateAgentDir, "settings.json");
16730
+ const updateSettingsPath = path48.join(updateAgentDir, "settings.json");
16692
16731
  let updateReceiptRaw;
16693
16732
  let updateSettingsRaw;
16694
16733
  try {
@@ -16704,7 +16743,7 @@ async function preparePiRuntimeSystem(input) {
16704
16743
  const stripUpdateGateNewline = (value) => value.endsWith("\n") ? value.slice(0, -1) : value;
16705
16744
  const updateReceiptJson = updateReceiptRaw === null ? null : stripUpdateGateNewline(updateReceiptRaw);
16706
16745
  const updateSettingsJson = stripUpdateGateNewline(updateSettingsRaw);
16707
- const updatePackageRunner = path47.join(updateAgentDir, "npm", "node_modules", "jorgex-pi", "bin", "jorgex-pi.mjs");
16746
+ const updatePackageRunner = path48.join(updateAgentDir, "npm", "node_modules", "jorgex-pi", "bin", "jorgex-pi.mjs");
16708
16747
  const updateGate = verifyOfflineManagedPiRelease(
16709
16748
  {
16710
16749
  detected: {
@@ -16732,7 +16771,7 @@ async function preparePiRuntimeSystem(input) {
16732
16771
  return "remedy" in updateGate && typeof updateGate.remedy === "string" ? updateGate : { kind: "blocked", reason: updateGate.reason, remedy: `Verificaci\xF3n offline del receipt Pi fall\xF3 (${updateGate.reason}); sin preflight ni cambios. Pi no qued\xF3 activado.` };
16733
16772
  }
16734
16773
  try {
16735
- fs39.mkdirSync(updateDownloadsDir, { recursive: true });
16774
+ fs40.mkdirSync(updateDownloadsDir, { recursive: true });
16736
16775
  } catch (error) {
16737
16776
  return {
16738
16777
  kind: "blocked",
@@ -16788,7 +16827,7 @@ async function preparePiRuntimeSystem(input) {
16788
16827
  };
16789
16828
  }
16790
16829
  const piExecutable = input.detected.executable;
16791
- if (typeof piExecutable !== "string" || piExecutable === "" || !path47.isAbsolute(piExecutable)) {
16830
+ if (typeof piExecutable !== "string" || piExecutable === "" || !path48.isAbsolute(piExecutable)) {
16792
16831
  return {
16793
16832
  kind: "blocked",
16794
16833
  reason: "pi-executable-missing",
@@ -16804,7 +16843,7 @@ async function preparePiRuntimeSystem(input) {
16804
16843
  }
16805
16844
  const homeDir = os6.homedir();
16806
16845
  const agentDir = userPaths(input.engramBin, piExecutable).codingAgentDir;
16807
- const downloadsDir = path47.join(dataDir(), "packages");
16846
+ const downloadsDir = path48.join(dataDir(), "packages");
16808
16847
  if (!isStrictChildPath(agentDir, homeDir)) {
16809
16848
  return {
16810
16849
  kind: "blocked",
@@ -16814,7 +16853,7 @@ async function preparePiRuntimeSystem(input) {
16814
16853
  }
16815
16854
  let preflightReceipt;
16816
16855
  try {
16817
- preflightReceipt = fs39.lstatSync(path47.join(dataDir(), "pi-receipt.json"), { throwIfNoEntry: false });
16856
+ preflightReceipt = fs40.lstatSync(path48.join(dataDir(), "pi-receipt.json"), { throwIfNoEntry: false });
16818
16857
  } catch (error) {
16819
16858
  if (error.code === "ENOENT") {
16820
16859
  preflightReceipt = void 0;
@@ -16829,7 +16868,7 @@ async function preparePiRuntimeSystem(input) {
16829
16868
  if (preflightReceipt === void 0) {
16830
16869
  let preflightEntry;
16831
16870
  try {
16832
- preflightEntry = fs39.lstatSync(path47.join(agentDir, "npm", "node_modules", "jorgex-pi"), {
16871
+ preflightEntry = fs40.lstatSync(path48.join(agentDir, "npm", "node_modules", "jorgex-pi"), {
16833
16872
  throwIfNoEntry: false
16834
16873
  });
16835
16874
  } catch (error) {
@@ -16852,7 +16891,7 @@ async function preparePiRuntimeSystem(input) {
16852
16891
  }
16853
16892
  }
16854
16893
  try {
16855
- fs39.mkdirSync(downloadsDir, { recursive: true });
16894
+ fs40.mkdirSync(downloadsDir, { recursive: true });
16856
16895
  } catch (error) {
16857
16896
  return {
16858
16897
  kind: "blocked",
@@ -16948,7 +16987,7 @@ async function runPiRuntimeSystem(input) {
16948
16987
  remedy: `${mismatch}; Pi no qued\xF3 activado y no se descarg\xF3 ni modific\xF3 nada.`
16949
16988
  };
16950
16989
  }
16951
- const settingsPath = path47.join(paths.codingAgentDir, "settings.json");
16990
+ const settingsPath = path48.join(paths.codingAgentDir, "settings.json");
16952
16991
  let settingsJson = readOptional(settingsPath, '{"packages":[]}');
16953
16992
  const receiptJson = readOptional(paths.receiptPath, null);
16954
16993
  const scopeKind = input.targetDir === void 0 ? "real" : "target-dir";
@@ -16991,8 +17030,8 @@ async function runPiRuntimeSystem(input) {
16991
17030
  };
16992
17031
  }
16993
17032
  try {
16994
- const freshEntry = path47.join(paths.codingAgentDir, "npm", "node_modules", "jorgex-pi");
16995
- if (fs39.lstatSync(freshEntry, { throwIfNoEntry: false }) !== void 0) {
17033
+ const freshEntry = path48.join(paths.codingAgentDir, "npm", "node_modules", "jorgex-pi");
17034
+ if (fs40.lstatSync(freshEntry, { throwIfNoEntry: false }) !== void 0) {
16996
17035
  return {
16997
17036
  kind: "blocked",
16998
17037
  reason: "unowned-entry",
@@ -17102,7 +17141,7 @@ async function runPiRuntimeSystem(input) {
17102
17141
  backupLegacyMigrationState(
17103
17142
  settingsPath,
17104
17143
  paths.receiptPath,
17105
- input.targetDir === void 0 ? void 0 : path47.join(path47.resolve(input.targetDir), "backups")
17144
+ input.targetDir === void 0 ? void 0 : path48.join(path48.resolve(input.targetDir), "backups")
17106
17145
  );
17107
17146
  } catch (error) {
17108
17147
  return {
@@ -17112,7 +17151,7 @@ async function runPiRuntimeSystem(input) {
17112
17151
  };
17113
17152
  }
17114
17153
  }
17115
- const homeDir = input.targetDir === void 0 ? os6.homedir() : path47.resolve(input.targetDir);
17154
+ const homeDir = input.targetDir === void 0 ? os6.homedir() : path48.resolve(input.targetDir);
17116
17155
  const agentDir = paths.codingAgentDir;
17117
17156
  const receiptPath = paths.receiptPath;
17118
17157
  const stageDir = prepared.stageDir;
@@ -17165,7 +17204,7 @@ async function runPiRuntimeSystem(input) {
17165
17204
  }
17166
17205
  if (input.operation === "update") {
17167
17206
  const engramBinForUpdate = input.engramBin;
17168
- if (engramBinForUpdate === null || !path47.isAbsolute(engramBinForUpdate)) {
17207
+ if (engramBinForUpdate === null || !path48.isAbsolute(engramBinForUpdate)) {
17169
17208
  return {
17170
17209
  kind: "blocked",
17171
17210
  reason: "engram-required",
@@ -17196,10 +17235,10 @@ async function runPiRuntimeSystem(input) {
17196
17235
  remedy: `${updateMismatch}; Pi no qued\xF3 activado y no se descarg\xF3 ni modific\xF3 nada.`
17197
17236
  };
17198
17237
  }
17199
- const updateSettingsPath = path47.join(paths.codingAgentDir, "settings.json");
17238
+ const updateSettingsPath = path48.join(paths.codingAgentDir, "settings.json");
17200
17239
  const updateScopeKind = input.targetDir === void 0 ? "real" : "target-dir";
17201
- const updateHomeDir = input.targetDir === void 0 ? os6.homedir() : path47.resolve(input.targetDir);
17202
- const updateDownloadsDir = input.targetDir === void 0 ? path47.join(dataDir(), "packages") : path47.join(path47.resolve(input.targetDir), "downloads");
17240
+ const updateHomeDir = input.targetDir === void 0 ? os6.homedir() : path48.resolve(input.targetDir);
17241
+ const updateDownloadsDir = input.targetDir === void 0 ? path48.join(dataDir(), "packages") : path48.join(path48.resolve(input.targetDir), "downloads");
17203
17242
  const stripUpdateNewline = (value) => value.endsWith("\n") ? value.slice(0, -1) : value;
17204
17243
  let updateSettingsRaw;
17205
17244
  let updateReceiptRaw;
@@ -17378,13 +17417,13 @@ async function runPiRuntimeSystem(input) {
17378
17417
  };
17379
17418
  }
17380
17419
  }
17381
- const packageRoot = path47.dirname(path47.dirname(paths.packageRunner));
17420
+ const packageRoot = path48.dirname(path48.dirname(paths.packageRunner));
17382
17421
  const writeReceipt = (receipt) => {
17383
17422
  writeText(paths.receiptPath, `${JSON.stringify(receipt, null, 2)}
17384
17423
  `);
17385
17424
  };
17386
17425
  if (input.operation === "sync") {
17387
- const settingsJson = readOptional(path47.join(paths.codingAgentDir, "settings.json"), '{"packages":[]}');
17426
+ const settingsJson = readOptional(path48.join(paths.codingAgentDir, "settings.json"), '{"packages":[]}');
17388
17427
  const receiptJson = readOptional(paths.receiptPath, null);
17389
17428
  if (receiptJson === null) {
17390
17429
  return {
@@ -17435,11 +17474,11 @@ async function runPiRuntimeSystem(input) {
17435
17474
  run: runProcess,
17436
17475
  verifyManagedArtifact: (receipt) => verifyCachedPiArtifact({
17437
17476
  receipt,
17438
- homeDir: input.targetDir === void 0 ? os6.homedir() : path47.resolve(input.targetDir),
17439
- downloadsDir: input.targetDir === void 0 ? path47.join(dataDir(), "packages") : path47.join(path47.resolve(input.targetDir), "downloads")
17477
+ homeDir: input.targetDir === void 0 ? os6.homedir() : path48.resolve(input.targetDir),
17478
+ downloadsDir: input.targetDir === void 0 ? path48.join(dataDir(), "packages") : path48.join(path48.resolve(input.targetDir), "downloads")
17440
17479
  }),
17441
- isPackageAbsent: () => !fs39.existsSync(packageRoot),
17442
- deleteReceipt: () => fs39.rmSync(paths.receiptPath, { force: true })
17480
+ isPackageAbsent: () => !fs40.existsSync(packageRoot),
17481
+ deleteReceipt: () => fs40.rmSync(paths.receiptPath, { force: true })
17443
17482
  }
17444
17483
  );
17445
17484
  }
@@ -17451,7 +17490,7 @@ async function runPiRuntimeSystem(input) {
17451
17490
  }
17452
17491
  }
17453
17492
  if (input.operation === "models") {
17454
- const settingsJson = readOptional(path47.join(paths.codingAgentDir, "settings.json"), '{"packages":[]}');
17493
+ const settingsJson = readOptional(path48.join(paths.codingAgentDir, "settings.json"), '{"packages":[]}');
17455
17494
  const receiptJson = readOptional(paths.receiptPath, null);
17456
17495
  if (receiptJson === null) {
17457
17496
  return {
@@ -17502,11 +17541,11 @@ async function runPiRuntimeSystem(input) {
17502
17541
  run: runProcess,
17503
17542
  verifyManagedArtifact: (receipt) => verifyCachedPiArtifact({
17504
17543
  receipt,
17505
- homeDir: input.targetDir === void 0 ? os6.homedir() : path47.resolve(input.targetDir),
17506
- downloadsDir: input.targetDir === void 0 ? path47.join(dataDir(), "packages") : path47.join(path47.resolve(input.targetDir), "downloads")
17544
+ homeDir: input.targetDir === void 0 ? os6.homedir() : path48.resolve(input.targetDir),
17545
+ downloadsDir: input.targetDir === void 0 ? path48.join(dataDir(), "packages") : path48.join(path48.resolve(input.targetDir), "downloads")
17507
17546
  }),
17508
- isPackageAbsent: () => !fs39.existsSync(packageRoot),
17509
- deleteReceipt: () => fs39.rmSync(paths.receiptPath, { force: true })
17547
+ isPackageAbsent: () => !fs40.existsSync(packageRoot),
17548
+ deleteReceipt: () => fs40.rmSync(paths.receiptPath, { force: true })
17510
17549
  }
17511
17550
  );
17512
17551
  }
@@ -17523,17 +17562,17 @@ async function runPiRuntimeSystem(input) {
17523
17562
  value,
17524
17563
  {
17525
17564
  backupSettings: () => createBackup(
17526
- [path47.join(paths.codingAgentDir, "settings.json")],
17565
+ [path48.join(paths.codingAgentDir, "settings.json")],
17527
17566
  "pi-package-uninstall",
17528
- input.targetDir === void 0 ? void 0 : path47.join(path47.resolve(input.targetDir), "backups")
17567
+ input.targetDir === void 0 ? void 0 : path48.join(path48.resolve(input.targetDir), "backups")
17529
17568
  ),
17530
17569
  run: runProcess,
17531
17570
  verifyManagedArtifact: (receipt) => verifyCachedPiArtifact({
17532
17571
  receipt,
17533
- homeDir: input.targetDir === void 0 ? os6.homedir() : path47.resolve(input.targetDir),
17534
- downloadsDir: input.targetDir === void 0 ? path47.join(dataDir(), "packages") : path47.join(path47.resolve(input.targetDir), "downloads")
17572
+ homeDir: input.targetDir === void 0 ? os6.homedir() : path48.resolve(input.targetDir),
17573
+ downloadsDir: input.targetDir === void 0 ? path48.join(dataDir(), "packages") : path48.join(path48.resolve(input.targetDir), "downloads")
17535
17574
  }),
17536
- readSettings: () => fs39.readFileSync(path47.join(paths.codingAgentDir, "settings.json"), "utf8"),
17575
+ readSettings: () => fs40.readFileSync(path48.join(paths.codingAgentDir, "settings.json"), "utf8"),
17537
17576
  verifyLegacyPackage: (receipt) => {
17538
17577
  const op = value;
17539
17578
  let effectiveEngram = op.engramBin;
@@ -17542,7 +17581,7 @@ async function runPiRuntimeSystem(input) {
17542
17581
  const engram = Reflect.get(receipt, "engram");
17543
17582
  if (engram === null || typeof engram !== "object" || Array.isArray(engram)) return false;
17544
17583
  const binary = Reflect.get(engram, "binary");
17545
- if (typeof binary !== "string" || binary === "" || !path47.isAbsolute(binary)) return false;
17584
+ if (typeof binary !== "string" || binary === "" || !path48.isAbsolute(binary)) return false;
17546
17585
  effectiveEngram = binary;
17547
17586
  }
17548
17587
  if (typeof effectiveEngram !== "string" || effectiveEngram === "") return false;
@@ -17566,17 +17605,17 @@ async function runPiRuntimeSystem(input) {
17566
17605
  }
17567
17606
  let currentReceiptRaw = null;
17568
17607
  try {
17569
- currentReceiptRaw = fs39.readFileSync(paths.receiptPath, "utf8");
17608
+ currentReceiptRaw = fs40.readFileSync(paths.receiptPath, "utf8");
17570
17609
  } catch {
17571
17610
  return { kind: "blocked", reason: "remove-failed" };
17572
17611
  }
17573
17612
  if (typeof op.receiptJson === "string" && currentReceiptRaw !== op.receiptJson) {
17574
17613
  return { kind: "blocked", reason: "receipt-untrusted" };
17575
17614
  }
17576
- const settingsPath = path47.join(paths.codingAgentDir, "settings.json");
17577
- const legacyEntry = path47.join(paths.codingAgentDir, "npm", "node_modules", "jorgex-pi");
17615
+ const settingsPath = path48.join(paths.codingAgentDir, "settings.json");
17616
+ const legacyEntry = path48.join(paths.codingAgentDir, "npm", "node_modules", "jorgex-pi");
17578
17617
  return deactivateVerifiedLegacyPiEntry({
17579
- homeDir: input.targetDir === void 0 ? os6.homedir() : path47.resolve(input.targetDir),
17618
+ homeDir: input.targetDir === void 0 ? os6.homedir() : path48.resolve(input.targetDir),
17580
17619
  agentDir: paths.codingAgentDir,
17581
17620
  receiptPath: paths.receiptPath,
17582
17621
  source,
@@ -17584,19 +17623,19 @@ async function runPiRuntimeSystem(input) {
17584
17623
  verify: () => {
17585
17624
  let entryStat = null;
17586
17625
  try {
17587
- entryStat = fs39.lstatSync(legacyEntry);
17626
+ entryStat = fs40.lstatSync(legacyEntry);
17588
17627
  } catch (error) {
17589
17628
  if (error.code !== "ENOENT") throw error;
17590
17629
  }
17591
17630
  if (entryStat !== null) throw new Error("managed entry still present after uninstall");
17592
17631
  let receiptStat = null;
17593
17632
  try {
17594
- receiptStat = fs39.lstatSync(paths.receiptPath);
17633
+ receiptStat = fs40.lstatSync(paths.receiptPath);
17595
17634
  } catch (error) {
17596
17635
  if (error.code !== "ENOENT") throw error;
17597
17636
  }
17598
17637
  if (receiptStat !== null) throw new Error("receipt still present after uninstall");
17599
- if (fs39.readFileSync(settingsPath, "utf8") !== nextSettings) {
17638
+ if (fs40.readFileSync(settingsPath, "utf8") !== nextSettings) {
17600
17639
  throw new Error("settings mismatch after uninstall");
17601
17640
  }
17602
17641
  }
@@ -17611,9 +17650,9 @@ async function runPiRuntimeSystem(input) {
17611
17650
  if (typeof mp.releaseDir !== "string" || typeof mp.linkPath !== "string" || typeof mp.backupDir !== "string") {
17612
17651
  return { kind: "blocked", reason: "remove-failed" };
17613
17652
  }
17614
- const settingsPath = path47.join(paths.codingAgentDir, "settings.json");
17653
+ const settingsPath = path48.join(paths.codingAgentDir, "settings.json");
17615
17654
  return deactivateVerifiedPiRelease({
17616
- homeDir: input.targetDir === void 0 ? os6.homedir() : path47.resolve(input.targetDir),
17655
+ homeDir: input.targetDir === void 0 ? os6.homedir() : path48.resolve(input.targetDir),
17617
17656
  agentDir: paths.codingAgentDir,
17618
17657
  receiptPath: paths.receiptPath,
17619
17658
  managedPackage: mp,
@@ -17621,33 +17660,33 @@ async function runPiRuntimeSystem(input) {
17621
17660
  verify: () => {
17622
17661
  let entryStat = null;
17623
17662
  try {
17624
- entryStat = fs39.lstatSync(mp.linkPath);
17663
+ entryStat = fs40.lstatSync(mp.linkPath);
17625
17664
  } catch (error) {
17626
17665
  if (error.code !== "ENOENT") throw error;
17627
17666
  }
17628
17667
  if (entryStat !== null) throw new Error("managed entry still present after uninstall");
17629
17668
  let releaseStat = null;
17630
17669
  try {
17631
- releaseStat = fs39.lstatSync(mp.releaseDir);
17670
+ releaseStat = fs40.lstatSync(mp.releaseDir);
17632
17671
  } catch (error) {
17633
17672
  if (error.code !== "ENOENT") throw error;
17634
17673
  }
17635
17674
  if (releaseStat !== null) throw new Error("managed release still present after uninstall");
17636
17675
  let receiptStat = null;
17637
17676
  try {
17638
- receiptStat = fs39.lstatSync(paths.receiptPath);
17677
+ receiptStat = fs40.lstatSync(paths.receiptPath);
17639
17678
  } catch (error) {
17640
17679
  if (error.code !== "ENOENT") throw error;
17641
17680
  }
17642
17681
  if (receiptStat !== null) throw new Error("receipt still present after uninstall");
17643
- if (fs39.readFileSync(settingsPath, "utf8") !== nextSettings) {
17682
+ if (fs40.readFileSync(settingsPath, "utf8") !== nextSettings) {
17644
17683
  throw new Error("settings mismatch after uninstall");
17645
17684
  }
17646
17685
  }
17647
17686
  });
17648
17687
  },
17649
- isPackageAbsent: () => !fs39.existsSync(packageRoot),
17650
- deleteReceipt: () => fs39.rmSync(paths.receiptPath, { force: true })
17688
+ isPackageAbsent: () => !fs40.existsSync(packageRoot),
17689
+ deleteReceipt: () => fs40.rmSync(paths.receiptPath, { force: true })
17651
17690
  }
17652
17691
  )
17653
17692
  };
@@ -17660,8 +17699,8 @@ init_pi();
17660
17699
  init_system_prompt_sections();
17661
17700
 
17662
17701
  // src/lib/pi-browser-contract.ts
17663
- import fs40 from "fs";
17664
- import path48 from "path";
17702
+ import fs41 from "fs";
17703
+ import path49 from "path";
17665
17704
  var CONTRACT_FILE = "browser-handoffs.v1.json";
17666
17705
  var MAX_CONTRACT_BYTES = 4 * 1024;
17667
17706
  function fail11(message) {
@@ -17672,23 +17711,23 @@ function validSchemas(value) {
17672
17711
  }
17673
17712
  function requirePiBrowserHandoffSchemas(packageRoot, required) {
17674
17713
  if (required.playwright === void 0 && required.devtools === void 0) return;
17675
- if (typeof packageRoot !== "string" || !path48.isAbsolute(packageRoot)) fail11("package root is not absolute");
17714
+ if (typeof packageRoot !== "string" || !path49.isAbsolute(packageRoot)) fail11("package root is not absolute");
17676
17715
  let realRoot;
17677
17716
  try {
17678
- realRoot = fs40.realpathSync(packageRoot);
17679
- if (!fs40.statSync(realRoot).isDirectory()) fail11("package root is not a directory");
17717
+ realRoot = fs41.realpathSync(packageRoot);
17718
+ if (!fs41.statSync(realRoot).isDirectory()) fail11("package root is not a directory");
17680
17719
  } catch {
17681
17720
  fail11("installed Pi package root is unavailable");
17682
17721
  }
17683
- const contractDir = path48.join(realRoot, "contract");
17684
- const file = path48.join(contractDir, CONTRACT_FILE);
17722
+ const contractDir = path49.join(realRoot, "contract");
17723
+ const file = path49.join(contractDir, CONTRACT_FILE);
17685
17724
  let raw;
17686
17725
  try {
17687
- const dirStat = fs40.lstatSync(contractDir);
17688
- const stat = fs40.lstatSync(file);
17726
+ const dirStat = fs41.lstatSync(contractDir);
17727
+ const stat = fs41.lstatSync(file);
17689
17728
  if (!dirStat.isDirectory() || dirStat.isSymbolicLink() || !stat.isFile() || stat.isSymbolicLink() || stat.size > MAX_CONTRACT_BYTES) fail11("contract is not a bounded regular file");
17690
- if (fs40.realpathSync(file) !== file) fail11("contract path is not canonical");
17691
- raw = fs40.readFileSync(file);
17729
+ if (fs41.realpathSync(file) !== file) fail11("contract path is not canonical");
17730
+ raw = fs41.readFileSync(file);
17692
17731
  if (raw.byteLength > MAX_CONTRACT_BYTES || !Buffer.from(raw.toString("utf8"), "utf8").equals(raw)) {
17693
17732
  fail11("contract is not bounded UTF-8");
17694
17733
  }
@@ -17717,8 +17756,8 @@ function requirePiBrowserHandoffSchemas(packageRoot, required) {
17717
17756
 
17718
17757
  // src/lib/pi-managed-runtime.ts
17719
17758
  init_paths();
17720
- import fs41 from "fs";
17721
- import path49 from "path";
17759
+ import fs42 from "fs";
17760
+ import path50 from "path";
17722
17761
  function projectionOperation(operation) {
17723
17762
  return operation === "update" ? "sync" : operation;
17724
17763
  }
@@ -17876,7 +17915,7 @@ async function runManagedPiSystem(input) {
17876
17915
  const needsDevtoolsObservation = devtoolsMcpEnabled === true && input.operation !== "uninstall" && input.operation !== "models";
17877
17916
  let devtoolsMcpObservedVersion = null;
17878
17917
  let devtoolsVerifiedForPersist;
17879
- const devtoolsManagedStateDir = input.targetDir === void 0 ? dataDir() : path49.join(input.targetDir, "home", ".jorgex-stack");
17918
+ const devtoolsManagedStateDir = input.targetDir === void 0 ? dataDir() : path50.join(input.targetDir, "home", ".jorgex-stack");
17880
17919
  if (needsDevtoolsObservation) {
17881
17920
  if (input.targetDir !== void 0) {
17882
17921
  devtoolsMcpObservedVersion = isValidObservedVersion(injectedDevtoolsObserved) ? { version: injectedDevtoolsObserved.version, integrity: injectedDevtoolsObserved.integrity } : null;
@@ -17924,8 +17963,8 @@ async function runManagedPiSystem(input) {
17924
17963
  if (needsDevtoolsObservation) {
17925
17964
  try {
17926
17965
  if (input.targetDir !== void 0) {
17927
- const target = fs41.lstatSync(input.targetDir);
17928
- const home = fs41.lstatSync(path49.join(input.targetDir, "home"));
17966
+ const target = fs42.lstatSync(input.targetDir);
17967
+ const home = fs42.lstatSync(path50.join(input.targetDir, "home"));
17929
17968
  if (!target.isDirectory() || target.isSymbolicLink() || !home.isDirectory() || home.isSymbolicLink()) {
17930
17969
  throw new Error("HOME del target Pi no es un directorio real aislado");
17931
17970
  }
@@ -17949,7 +17988,7 @@ async function runManagedPiSystem(input) {
17949
17988
  const playwrightCapabilityEffective = playwrightCapability?.effective === true;
17950
17989
  const playwrightCliEnabled = input.targetDir === void 0 && supportsPlaywright && selectedPlaywright && playwrightCapabilityEffective;
17951
17990
  const playwrightManagedStateDir = playwrightCliEnabled && input.operation !== "uninstall" && input.operation !== "models" ? dataDir() : void 0;
17952
- const playwrightDispatcherPath = playwrightManagedStateDir === void 0 ? void 0 : path49.join(path49.dirname(stackRoot()), "dist", "browser-playwright.js");
17991
+ const playwrightDispatcherPath = playwrightManagedStateDir === void 0 ? void 0 : path50.join(path50.dirname(stackRoot()), "dist", "browser-playwright.js");
17953
17992
  let effectivePackageSource = PI_RUNTIME_CANDIDATE.package.source;
17954
17993
  const projectionInput = {
17955
17994
  writingStyle,
@@ -18006,7 +18045,7 @@ async function runManagedPiSystem(input) {
18006
18045
  },
18007
18046
  runProjection(operation) {
18008
18047
  if (playwrightCliEnabled || devtoolsMcpEnabled) {
18009
- const packageRoot = path49.join(path49.dirname(piSystemPromptFile(input.targetDir)), "npm", "node_modules", "jorgex-pi");
18048
+ const packageRoot = path50.join(path50.dirname(piSystemPromptFile(input.targetDir)), "npm", "node_modules", "jorgex-pi");
18010
18049
  try {
18011
18050
  requirePiBrowserHandoffSchemas(packageRoot, {
18012
18051
  ...playwrightCliEnabled ? { playwright: 2 } : {},
@@ -18059,7 +18098,7 @@ init_fsx();
18059
18098
 
18060
18099
  // src/lib/quality-runner.ts
18061
18100
  init_detect();
18062
- import path50 from "path";
18101
+ import path51 from "path";
18063
18102
  import { spawn as spawn2, spawnSync as spawnSync6 } from "child_process";
18064
18103
 
18065
18104
  // src/lib/quality-policy.ts
@@ -18652,7 +18691,7 @@ function killProcessTree(child) {
18652
18691
  if (pid === void 0) return;
18653
18692
  if (process.platform === "win32") {
18654
18693
  const systemRoot = process.env.SystemRoot ?? process.env.WINDIR ?? "C:\\Windows";
18655
- const taskkill = path50.join(systemRoot, "System32", "taskkill.exe");
18694
+ const taskkill = path51.join(systemRoot, "System32", "taskkill.exe");
18656
18695
  const result = spawnSync6(taskkill, ["/pid", String(pid), "/t", "/f"], {
18657
18696
  shell: false,
18658
18697
  stdio: "ignore",
@@ -18898,9 +18937,9 @@ async function runQualityPlan(input) {
18898
18937
  }
18899
18938
 
18900
18939
  // src/lib/engram-install.ts
18901
- import fs42 from "fs";
18940
+ import fs43 from "fs";
18902
18941
  import os7 from "os";
18903
- import path51 from "path";
18942
+ import path52 from "path";
18904
18943
  import { execFileSync as execFileSync8 } from "child_process";
18905
18944
  import { createHash as createHash11 } from "crypto";
18906
18945
  var MAX_ENGRAM_ARCHIVE_BYTES = 64 * 1024 * 1024;
@@ -18909,16 +18948,16 @@ var DIGEST_RE = /^sha256:[0-9a-f]{64}$/;
18909
18948
  async function installMissingEngram(options = {}) {
18910
18949
  const platform = options.platform ?? process.platform;
18911
18950
  const homeDir = options.homeDir ?? os7.homedir();
18912
- if (!path51.isAbsolute(homeDir)) return { ok: false, reason: "El directorio personal debe ser absoluto." };
18951
+ if (!path52.isAbsolute(homeDir)) return { ok: false, reason: "El directorio personal debe ser absoluto." };
18913
18952
  const binaryName = platform === "win32" ? "engram.exe" : "engram";
18914
- const bin = path51.join(homeDir, ".local", "bin", binaryName);
18953
+ const bin = path52.join(homeDir, ".local", "bin", binaryName);
18915
18954
  let staging;
18916
18955
  let outcome;
18917
18956
  try {
18918
- const existing = fs42.lstatSync(bin, { throwIfNoEntry: false });
18957
+ const existing = fs43.lstatSync(bin, { throwIfNoEntry: false });
18919
18958
  if (existing) {
18920
- if (!fs42.statSync(bin).isFile()) throw new Error(`El destino Engram no es un archivo: ${bin}`);
18921
- fs42.accessSync(bin, platform === "win32" ? fs42.constants.F_OK : fs42.constants.X_OK);
18959
+ if (!fs43.statSync(bin).isFile()) throw new Error(`El destino Engram no es un archivo: ${bin}`);
18960
+ fs43.accessSync(bin, platform === "win32" ? fs43.constants.F_OK : fs43.constants.X_OK);
18922
18961
  outcome = { ok: true, bin };
18923
18962
  } else {
18924
18963
  const fetchFn = options.fetch ?? globalThis.fetch;
@@ -19031,19 +19070,19 @@ async function installMissingEngram(options = {}) {
19031
19070
  if (size !== approvedSize || createHash11("sha256").update(archive).digest("hex") !== approvedSha) {
19032
19071
  throw new Error("Engram: tama\xF1o o hash SHA-256 no coincide con el artefacto aprobado.");
19033
19072
  }
19034
- fs42.mkdirSync(path51.dirname(bin), { recursive: true });
19035
- staging = fs42.mkdtempSync(path51.join(path51.dirname(bin), ".engram-install-"));
19036
- const archivePath = path51.join(staging, expectedName);
19037
- fs42.writeFileSync(archivePath, archive, { flag: "wx", mode: 384 });
19073
+ fs43.mkdirSync(path52.dirname(bin), { recursive: true });
19074
+ staging = fs43.mkdtempSync(path52.join(path52.dirname(bin), ".engram-install-"));
19075
+ const archivePath = path52.join(staging, expectedName);
19076
+ fs43.writeFileSync(archivePath, archive, { flag: "wx", mode: 384 });
19038
19077
  const binary = execFileSync8(resolveTarBin(), ["-xOf", archivePath, binaryName], {
19039
19078
  maxBuffer: 64 * 1024 * 1024,
19040
19079
  timeout: 3e4,
19041
19080
  stdio: ["ignore", "pipe", "pipe"]
19042
19081
  });
19043
19082
  if (binary.length === 0) throw new Error("El artefacto Engram no contiene un binario v\xE1lido.");
19044
- const stagedBin = path51.join(staging, binaryName);
19045
- fs42.writeFileSync(stagedBin, binary, { flag: "wx", mode: 493 });
19046
- fs42.linkSync(stagedBin, bin);
19083
+ const stagedBin = path52.join(staging, binaryName);
19084
+ fs43.writeFileSync(stagedBin, binary, { flag: "wx", mode: 493 });
19085
+ fs43.linkSync(stagedBin, bin);
19047
19086
  outcome = { ok: true, bin };
19048
19087
  }
19049
19088
  } catch (error) {
@@ -19051,7 +19090,7 @@ async function installMissingEngram(options = {}) {
19051
19090
  }
19052
19091
  if (staging !== void 0) {
19053
19092
  try {
19054
- fs42.rmSync(staging, { recursive: true, force: true });
19093
+ fs43.rmSync(staging, { recursive: true, force: true });
19055
19094
  } catch (cleanupError) {
19056
19095
  const cleanupMsg = cleanupError instanceof Error ? cleanupError.message : String(cleanupError);
19057
19096
  if (outcome !== void 0 && outcome.ok) {
@@ -19447,7 +19486,7 @@ async function runSelectedPi(options) {
19447
19486
  return 1;
19448
19487
  }
19449
19488
  if (detected.version === null) {
19450
- console.error("No se pudo verificar la versi\xF3n instalada de Pi sin ejecutarlo; revisa la instalaci\xF3n de Pi.");
19489
+ console.error(`No se pudo verificar la versi\xF3n instalada de Pi sin ejecutarlo: ${detected.versionDiagnostic ?? "causa desconocida"}. Repara Pi con su instalador oficial antes de reintentar.`);
19451
19490
  return 1;
19452
19491
  }
19453
19492
  let engramBin = resolvedEngramBin === void 0 ? resolvePiEngramBin(targetDir) : resolvedEngramBin;
@@ -19618,7 +19657,7 @@ Flags disponibles: jorgex-stack --help`
19618
19657
  return;
19619
19658
  }
19620
19659
  try {
19621
- const plan = JSON.parse(fs43.readFileSync(flags.positional[0], "utf8"));
19660
+ const plan = JSON.parse(fs44.readFileSync(flags.positional[0], "utf8"));
19622
19661
  const result = await runQualityPlan(plan);
19623
19662
  const serialized = serializeQualityReceipt(result.receipt);
19624
19663
  if (flags.receipt === void 0) process.stdout.write(`${serialized}