UNPKG

pi-lens

Version:

Real-time code feedback for pi — LSP, linters, formatters, type-checking, structural analysis & booboo

5,415 lines • 181 kB
import { createRequire as __pilensCreateRequire } from "node:module"; const require = __pilensCreateRequire(import.meta.url);
import {
  detectFileRole,
  findNestedProjectMutationValue,
  findPiLensConfigInDir,
  findPiLensProjectConfig,
  ignoredRecordCollector,
  loadPiLensConfigInDir,
  loadPiLensProjectConfig,
  readConfigDocument,
  reportConfigReadFailure,
  reportPiLensConfigRecords,
  resolveOnePiLensConfigDocument,
  warnIgnoredConfigOnce
} from "./chunk-DQ2NZ7C4.js";
import {
  CANONICAL_GLOBAL_CONFIG_FILE,
  FRESHNESS_CADENCE_MS,
  GLOBAL_CONFIG_LOCATIONS,
  LEGACY_ROOT_LSP_KEYS,
  canonicalPathIdentity,
  errorClassName,
  getPiLensGlobalConfigPath,
  getProductionGlobalConfigResolution
} from "./chunk-VNMT7C64.js";
import {
  DEFAULT_MAX_OUTPUT_BYTES,
  createBoundedOutputSink,
  truncatedByOutputCap,
  writeFileAtomicAsync
} from "./chunk-2EECBNC5.js";
import {
  GLOBAL_NON_FLAG_CONFIG_SECTIONS,
  LENS_FLAGS,
  assignFlagConfigSection,
  compareOrdinal,
  flagConfigSectionKeys,
  flagValueFromConfig,
  getLensFlagSpec,
  incrementDegradationCount,
  readFlagConfigValue,
  readToolConfig,
  recordDegradation,
  recordDegradationOnce
} from "./chunk-N3YQJI6O.js";
import {
  logExtension
} from "./chunk-O6TQT6RI.js";
import {
  logLatency
} from "./chunk-5THXD6X5.js";
import {
  getProcessSingleton
} from "./chunk-UK3CMEAL.js";
import {
  sweepOwnStagingFiles
} from "./chunk-LJDODBBZ.js";
import {
  BoundedFifoMap,
  BoundedSet
} from "./chunk-ABBOA7UD.js";
import {
  Minimatch,
  homeRelativePath,
  isExternalOrVendorFile,
  isFullyQualifiedWin32,
  isRealGitMarker,
  isUnderDir,
  normalizeEphemeralMapKey,
  normalizeFilePath,
  normalizeLoggedPath,
  normalizeMapKey,
  toProjectRelativePath
} from "./chunk-Q5U6FMDI.js";
import {
  __commonJS,
  __require,
  __toESM
} from "./chunk-NXL4FFQQ.js";

// node_modules/pidusage/lib/bin.js
var require_bin = __commonJS({
  "node_modules/pidusage/lib/bin.js"(exports, module) {
    "use strict";
    var spawn2 = __require("child_process").spawn;
    function run(cmd, args, options, done) {
      if (typeof options === "function") {
        done = options;
        options = void 0;
      }
      let executed = false;
      const ch = spawn2(cmd, args, options);
      let stdout = "";
      let stderr = "";
      ch.stdout.on("data", function(d) {
        stdout += d.toString();
      });
      ch.stderr.on("data", function(d) {
        stderr += d.toString();
      });
      ch.on("error", function(err) {
        if (executed) return;
        executed = true;
        done(new Error(err));
      });
      ch.on("close", function(code, signal) {
        if (executed) return;
        executed = true;
        if (stderr) {
          return done(new Error(stderr));
        }
        done(null, stdout, code);
      });
    }
    module.exports = run;
  }
});

// node_modules/pidusage/lib/history.js
var require_history = __commonJS({
  "node_modules/pidusage/lib/history.js"(exports, module) {
    "use strict";
    var DEFAULT_MAXAGE = 6e4;
    var expiration = {};
    var history = {};
    var expireListeners = {};
    var size = 0;
    var interval = null;
    function get(pid, maxage) {
      if (maxage <= 0) {
        return;
      }
      if (history[pid] !== void 0) {
        expiration[pid] = Date.now() + (maxage || DEFAULT_MAXAGE);
      }
      return history[pid];
    }
    function set(pid, object, maxage, onExpire) {
      if (object === void 0 || maxage <= 0) return;
      expiration[pid] = Date.now() + (maxage || DEFAULT_MAXAGE);
      if (history[pid] === void 0) {
        size++;
        sheduleInvalidator(maxage);
      }
      history[pid] = object;
      if (onExpire) {
        expireListeners[pid] = onExpire;
      }
    }
    function sheduleInvalidator(maxage) {
      if (size > 0) {
        if (interval === null) {
          interval = setInterval(runInvalidator, (maxage || DEFAULT_MAXAGE) / 2);
          if (typeof interval.unref === "function") {
            interval.unref();
          }
        }
        return;
      }
      if (interval !== null) {
        clearInterval(interval);
        interval = null;
      }
    }
    function runInvalidator() {
      const now = Date.now();
      const pids = Object.keys(expiration);
      for (let i = 0; i < pids.length; i++) {
        const pid = pids[i];
        if (expiration[pid] < now) {
          size--;
          if (expireListeners[pid]) {
            expireListeners[pid](history[pid]);
          }
          delete history[pid];
          delete expiration[pid];
          delete expireListeners[pid];
        }
      }
      sheduleInvalidator();
    }
    function deleteLoop(obj) {
      for (const i in obj) {
        delete obj[i];
      }
    }
    function clear() {
      if (interval !== null) {
        clearInterval(interval);
        interval = null;
      }
      deleteLoop(history);
      deleteLoop(expiration);
      deleteLoop(expireListeners);
    }
    module.exports = {
      get,
      set,
      clear
    };
  }
});

// node_modules/pidusage/lib/ps.js
var require_ps = __commonJS({
  "node_modules/pidusage/lib/ps.js"(exports, module) {
    "use strict";
    var os3 = __require("os");
    var bin = require_bin();
    var history = require_history();
    var PLATFORM = os3.platform();
    function parseTime(timestr, centisec) {
      let time = 0;
      const tpart = timestr.split(/-|:|\./);
      let i = tpart.length - 1;
      if (i >= 0 && centisec && PLATFORM === "darwin") {
        time += parseInt(tpart[i--], 10) * 10;
      }
      if (i >= 0) {
        time += parseInt(tpart[i--], 10) * 1e3;
      }
      if (i >= 0) {
        time += parseInt(tpart[i--], 10) * 6e4;
      }
      if (i >= 0) {
        time += parseInt(tpart[i--], 10) * 36e5;
      }
      if (i >= 0) {
        time += parseInt(tpart[i--], 10) * 864e5;
      }
      return time;
    }
    function ps(pids, options, done) {
      const pArg = pids.join(",");
      let args = ["-o", "etime,pid,ppid,pcpu,rss,time", "-p", pArg];
      if (PLATFORM === "aix" || PLATFORM === "os400") {
        args = ["-o", "etime,pid,ppid,pcpu,rssize,time", "-p", pArg];
      }
      bin("ps", args, function(err, stdout, code) {
        if (err) {
          if (PLATFORM === "os390" && /no matching processes found/.test(err)) {
            err = new Error("No matching pid found");
            err.code = "ENOENT";
          }
          return done(err);
        }
        if (code === 1) {
          const error = new Error("No matching pid found");
          error.code = "ENOENT";
          return done(error);
        }
        if (code !== 0) {
          return done(new Error("pidusage ps command exited with code " + code));
        }
        const date = Date.now();
        stdout = stdout.split(os3.EOL);
        const statistics = {};
        for (let i = 1; i < stdout.length; i++) {
          const line = stdout[i].trim().split(/\s+/);
          if (!line || line.length !== 6) {
            continue;
          }
          const pid = parseInt(line[1], 10);
          let hst = history.get(pid, options.maxage);
          if (hst === void 0) hst = {};
          const ppid = parseInt(line[2], 10);
          const memory = parseInt(line[4], 10) * 1024;
          const etime = parseTime(line[0]);
          const ctime = parseTime(line[5], true);
          const total = ctime - (hst.ctime || 0);
          const seconds = Math.abs(hst.elapsed !== void 0 ? etime - hst.elapsed : etime);
          const cpu = seconds > 0 ? total / seconds * 100 : 0;
          statistics[pid] = {
            cpu,
            memory,
            ppid,
            pid,
            ctime,
            elapsed: etime,
            timestamp: date
          };
          history.set(pid, statistics[pid], options.maxage);
        }
        done(null, statistics);
      });
    }
    module.exports = ps;
  }
});

// node_modules/pidusage/lib/helpers/parallel.js
var require_parallel = __commonJS({
  "node_modules/pidusage/lib/helpers/parallel.js"(exports, module) {
    function parallel(fns, options, done) {
      if (typeof options === "function") {
        done = options;
        options = {};
      }
      let keys;
      if (!Array.isArray(fns)) {
        keys = Object.keys(fns);
      }
      const length = keys ? keys.length : fns.length;
      let pending = length;
      const results = keys ? {} : [];
      function each(i, err, result) {
        results[i] = result;
        if (--pending === 0 || err && !options.graceful) {
          if (options.graceful && err && length > 1) {
            err = null;
          }
          done && done(err, results);
          done = null;
        }
      }
      if (keys) {
        keys.forEach(function(key) {
          fns[key](function(err, res) {
            each(key, err, res);
          });
        });
      } else {
        fns.forEach(function(fn, i) {
          fn(function(err, res) {
            each(i, err, res);
          });
        });
      }
    }
    module.exports = parallel;
  }
});

// node_modules/pidusage/lib/helpers/cpu.js
var require_cpu = __commonJS({
  "node_modules/pidusage/lib/helpers/cpu.js"(exports, module) {
    var os3 = __require("os");
    var fs9 = __require("fs");
    var exec = __require("child_process").exec;
    var parallel = require_parallel();
    function updateCpu(cpu, next) {
      if (cpu !== null) {
        getRealUptime(function(err, uptime) {
          if (err) return next(err);
          cpu.uptime = uptime;
          next(null, cpu);
        });
        return;
      }
      parallel([
        getClockAndPageSize,
        getRealUptime
      ], function(err, data) {
        if (err) return next(err);
        cpu = {
          clockTick: data[0].clockTick,
          pageSize: data[0].pageSize,
          uptime: data[1]
        };
        next(null, cpu);
      });
    }
    module.exports = updateCpu;
    function getRealUptime(next) {
      fs9.readFile("/proc/uptime", "utf8", function(err, uptime) {
        if (err || uptime === void 0) {
          if (!process.env.PIDUSAGE_SILENT) {
            console.warn("[pidusage] We couldn't find uptime from /proc/uptime, using os.uptime() value");
          }
          return next(null, os3.uptime() || /* @__PURE__ */ new Date() / 1e3);
        }
        return next(null, parseFloat(uptime.split(" ")[0]));
      });
    }
    function getClockAndPageSize(next) {
      parallel([
        function getClockTick(cb) {
          getconf("CLK_TCK", { default: 100 }, cb);
        },
        function getPageSize(cb) {
          getconf("PAGESIZE", { default: 4096 }, cb);
        }
      ], function(err, data) {
        if (err) return next(err);
        next(null, { clockTick: data[0], pageSize: data[1] });
      });
    }
    function getconf(keyword, options, next) {
      if (typeof options === "function") {
        next = options;
        options = { default: "" };
      }
      exec("getconf " + keyword, function(error, stdout, stderr) {
        if (error !== null) {
          if (!process.env.PIDUSAGE_SILENT) {
            console.error('Error while calling "getconf ' + keyword + '"', error);
          }
          return next(null, options.default);
        }
        stdout = parseInt(stdout);
        if (!isNaN(stdout)) {
          return next(null, stdout);
        }
        return next(null, options.default);
      });
    }
  }
});

// node_modules/safe-buffer/index.js
var require_safe_buffer = __commonJS({
  "node_modules/safe-buffer/index.js"(exports, module) {
    var buffer = __require("buffer");
    var Buffer2 = buffer.Buffer;
    function copyProps(src, dst) {
      for (var key in src) {
        dst[key] = src[key];
      }
    }
    if (Buffer2.from && Buffer2.alloc && Buffer2.allocUnsafe && Buffer2.allocUnsafeSlow) {
      module.exports = buffer;
    } else {
      copyProps(buffer, exports);
      exports.Buffer = SafeBuffer;
    }
    function SafeBuffer(arg, encodingOrOffset, length) {
      return Buffer2(arg, encodingOrOffset, length);
    }
    SafeBuffer.prototype = Object.create(Buffer2.prototype);
    copyProps(Buffer2, SafeBuffer);
    SafeBuffer.from = function(arg, encodingOrOffset, length) {
      if (typeof arg === "number") {
        throw new TypeError("Argument must not be a number");
      }
      return Buffer2(arg, encodingOrOffset, length);
    };
    SafeBuffer.alloc = function(size, fill, encoding) {
      if (typeof size !== "number") {
        throw new TypeError("Argument must be a number");
      }
      var buf = Buffer2(size);
      if (fill !== void 0) {
        if (typeof encoding === "string") {
          buf.fill(fill, encoding);
        } else {
          buf.fill(fill);
        }
      } else {
        buf.fill(0);
      }
      return buf;
    };
    SafeBuffer.allocUnsafe = function(size) {
      if (typeof size !== "number") {
        throw new TypeError("Argument must be a number");
      }
      return Buffer2(size);
    };
    SafeBuffer.allocUnsafeSlow = function(size) {
      if (typeof size !== "number") {
        throw new TypeError("Argument must be a number");
      }
      return buffer.SlowBuffer(size);
    };
  }
});

// node_modules/pidusage/lib/procfile.js
var require_procfile = __commonJS({
  "node_modules/pidusage/lib/procfile.js"(exports, module) {
    var fs9 = __require("fs");
    var path12 = __require("path");
    var updateCpu = require_cpu();
    var parallel = require_parallel();
    var history = require_history();
    var cpuInfo = null;
    var Buffer2 = require_safe_buffer().Buffer;
    var SIZE = 1024;
    function noop() {
    }
    function open(path13, history2, cb) {
      if (history2.fd) {
        return cb(null, history2.fd);
      }
      fs9.open(path13, "r", cb);
    }
    function close(history2) {
      if (history2.fd) {
        fs9.close(history2.fd, noop);
      }
    }
    function readUntilEnd(fd, buf, cb) {
      let firstRead = false;
      if (typeof buf === "function") {
        cb = buf;
        buf = Buffer2.alloc(SIZE);
        firstRead = true;
      }
      fs9.read(fd, buf, 0, SIZE, 0, function(err, bytesRead, buffer) {
        if (err) {
          cb(err);
          return;
        }
        const data = Buffer2.concat([buf, buffer], firstRead ? bytesRead : buf.length + bytesRead);
        if (bytesRead === SIZE) {
          readUntilEnd(fd, data, cb);
          return;
        }
        cb(null, buf);
      });
    }
    function readProcFile(pid, options, done) {
      let hst = history.get(pid, options.maxage);
      let again = false;
      if (hst === void 0) {
        again = true;
        hst = {};
      }
      open(path12.join("/proc", "" + pid, "stat"), hst, function(err, fd) {
        if (err) {
          if (err.code === "ENOENT") {
            err.message = "No matching pid found";
          }
          return done(err, null);
        }
        if (err) {
          return done(err);
        }
        readUntilEnd(fd, function(err2, buffer) {
          if (err2) {
            return done(err2);
          }
          let infos = buffer.toString("utf8");
          const date = Date.now();
          const index = infos.lastIndexOf(")");
          infos = infos.substr(index + 2).split(" ");
          const stat = {
            ppid: parseInt(infos[1]),
            utime: parseFloat(infos[11]) * 1e3 / cpuInfo.clockTick,
            stime: parseFloat(infos[12]) * 1e3 / cpuInfo.clockTick,
            cutime: parseFloat(infos[13]) * 1e3 / cpuInfo.clockTick,
            cstime: parseFloat(infos[14]) * 1e3 / cpuInfo.clockTick,
            start: parseFloat(infos[19]) * 1e3 / cpuInfo.clockTick,
            rss: parseFloat(infos[21]),
            uptime: cpuInfo.uptime * 1e3,
            fd
          };
          const memory = stat.rss * cpuInfo.pageSize;
          const childrens = options.childrens ? stat.cutime + stat.cstime : 0;
          const total = stat.stime - (hst.stime || 0) + stat.utime - (hst.utime || 0) + childrens;
          const seconds = Math.abs(hst.uptime !== void 0 ? stat.uptime - hst.uptime : stat.start - stat.uptime);
          const cpu = seconds > 0 ? total / seconds * 100 : 0;
          history.set(pid, stat, options.maxage, close);
          if (again) {
            return readProcFile(pid, options, done);
          }
          return done(null, {
            cpu,
            memory,
            ctime: stat.utime + stat.stime,
            elapsed: stat.uptime - stat.start,
            timestamp: date,
            pid,
            ppid: stat.ppid
          });
        });
      });
    }
    function procfile(pids, options, done) {
      updateCpu(cpuInfo, function(err, result) {
        if (err) return done(err);
        cpuInfo = result;
        const fns = {};
        pids.forEach(function(pid, i) {
          fns[pid] = function(cb) {
            readProcFile(pid, options, cb);
          };
        });
        parallel(fns, { graceful: true }, done);
      });
    }
    module.exports = procfile;
  }
});

// node_modules/pidusage/lib/wmic.js
var require_wmic = __commonJS({
  "node_modules/pidusage/lib/wmic.js"(exports, module) {
    "use strict";
    var os3 = __require("os");
    var bin = require_bin();
    var history = require_history();
    function parseDate(datestr) {
      const year = datestr.substring(0, 4);
      const month = datestr.substring(4, 6);
      const day = datestr.substring(6, 8);
      const hour = datestr.substring(8, 10);
      const minutes = datestr.substring(10, 12);
      const seconds = datestr.substring(12, 14);
      const useconds = datestr.substring(15, 21);
      const sign = datestr.substring(21, 22);
      const tmz = parseInt(datestr.substring(22, 25), 10);
      const tmzh = Math.floor(tmz / 60);
      const tmzm = tmz % 60;
      return /* @__PURE__ */ new Date(
        year + "-" + month + "-" + day + "T" + hour + ":" + minutes + ":" + seconds + "." + useconds + sign + (tmzh > 9 ? tmzh : "0" + tmzh) + (tmzm > 9 ? tmzm : "0" + tmzm)
      );
    }
    function wmic(pids, options, done) {
      let whereClause = "ProcessId=" + pids[0];
      for (let i = 1; i < pids.length; i++) {
        whereClause += " or ProcessId=" + pids[i];
      }
      const args = [
        "PROCESS",
        "where",
        '"' + whereClause + '"',
        "get",
        "CreationDate,KernelModeTime,ParentProcessId,ProcessId,UserModeTime,WorkingSetSize"
      ];
      bin("wmic", args, { windowsHide: true, windowsVerbatimArguments: true }, function(err, stdout, code) {
        if (err) {
          if (err.message.indexOf("No Instance(s) Available.") !== -1) {
            const error = new Error("No matching pid found");
            error.code = "ENOENT";
            return done(error);
          }
          return done(err);
        }
        if (code !== 0) {
          return done(new Error("pidusage wmic command exited with code " + code));
        }
        const date = Date.now();
        const uptime = Math.floor(os3.uptime() || date / 1e3);
        stdout = stdout.split(os3.EOL);
        let again = false;
        const statistics = {};
        for (let i = 1; i < stdout.length; i++) {
          const line = stdout[i].trim().split(/\s+/);
          if (!line || line.length !== 6) {
            continue;
          }
          const creation = parseDate(line[0]);
          const ppid = parseInt(line[2], 10);
          const pid = parseInt(line[3], 10);
          const kerneltime = Math.round(parseInt(line[1], 10) / 1e4);
          const usertime = Math.round(parseInt(line[4], 10) / 1e4);
          const memory = parseInt(line[5], 10);
          let hst = history.get(pid, options.maxage);
          if (hst === void 0) {
            again = true;
            hst = { ctime: kerneltime + usertime, uptime };
          }
          const total = (kerneltime + usertime - hst.ctime) / 1e3;
          const seconds = uptime - hst.uptime;
          const cpu = seconds > 0 ? total / seconds * 100 : 0;
          history.set(pid, { ctime: usertime + kerneltime, uptime }, options.maxage);
          statistics[pid] = {
            cpu,
            memory,
            ppid,
            pid,
            ctime: usertime + kerneltime,
            elapsed: date - creation.getTime(),
            timestamp: date
          };
        }
        if (again) {
          return wmic(pids, options, function(err2, stats) {
            if (err2) return done(err2);
            done(null, Object.assign(statistics, stats));
          });
        }
        done(null, statistics);
      });
    }
    module.exports = wmic;
  }
});

// node_modules/pidusage/lib/gwmi.js
var require_gwmi = __commonJS({
  "node_modules/pidusage/lib/gwmi.js"(exports, module) {
    "use strict";
    var os3 = __require("os");
    var bin = require_bin();
    var history = require_history();
    function parseDate(datestr) {
      const year = datestr.substring(0, 4);
      const month = datestr.substring(4, 6);
      const day = datestr.substring(6, 8);
      const hour = datestr.substring(8, 10);
      const minutes = datestr.substring(10, 12);
      const seconds = datestr.substring(12, 14);
      const useconds = datestr.substring(15, 21);
      const sign = datestr.substring(21, 22);
      const tmz = parseInt(datestr.substring(22, 25), 10);
      const tmzh = Math.floor(tmz / 60);
      const tmzm = tmz % 60;
      return /* @__PURE__ */ new Date(
        year + "-" + month + "-" + day + "T" + hour + ":" + minutes + ":" + seconds + "." + useconds + sign + (tmzh > 9 ? tmzh : "0" + tmzh) + (tmzm > 9 ? tmzm : "0" + tmzm)
      );
    }
    function gwmi(pids, options, done) {
      let whereClause = "ProcessId=" + pids[0];
      for (let i = 1; i < pids.length; i++) {
        whereClause += " or ProcessId=" + pids[i];
      }
      const property = "CreationDate,KernelModeTime,ParentProcessId,ProcessId,UserModeTime,WorkingSetSize";
      const args = ["win32_process", "-Filter", "'" + whereClause + "'", "| select " + property, "| format-table"];
      bin("gwmi", args, { windowsHide: true, windowsVerbatimArguments: true, shell: "powershell.exe" }, function(err, stdout, code) {
        if (err) {
          if (err.message.indexOf("No Instance(s) Available.") !== -1) {
            const error = new Error("No matching pid found");
            error.code = "ENOENT";
            return done(error);
          }
          return done(err);
        }
        if (code !== 0) {
          return done(new Error("pidusage gwmi command exited with code " + code));
        }
        const date = Date.now();
        const uptime = Math.floor(os3.uptime() || date / 1e3);
        stdout = stdout.split(os3.EOL).slice(1);
        const index = stdout.findIndex((v) => !!v);
        stdout = stdout.slice(index + 2);
        if (!stdout.length) {
          const error = new Error("No matching pid found");
          error.code = "ENOENT";
          return done(error);
        }
        let again = false;
        const statistics = {};
        for (let i = 0; i < stdout.length; i++) {
          const line = stdout[i].trim().split(/\s+/);
          if (!line || line.length === 1) {
            continue;
          }
          const creation = parseDate(line[0]);
          const ppid = parseInt(line[2], 10);
          const pid = parseInt(line[3], 10);
          const kerneltime = Math.round(parseInt(line[1], 10) / 1e4);
          const usertime = Math.round(parseInt(line[4], 10) / 1e4);
          const memory = parseInt(line[5], 10);
          let hst = history.get(pid, options.maxage);
          if (hst === void 0) {
            again = true;
            hst = { ctime: kerneltime + usertime, uptime };
          }
          const total = (kerneltime + usertime - hst.ctime) / 1e3;
          const seconds = uptime - hst.uptime;
          const cpu = seconds > 0 ? total / seconds * 100 : 0;
          history.set(pid, { ctime: usertime + kerneltime, uptime }, options.maxage);
          statistics[pid] = {
            cpu,
            memory,
            ppid,
            pid,
            ctime: usertime + kerneltime,
            elapsed: date - creation.getTime(),
            timestamp: date
          };
        }
        if (again) {
          return gwmi(pids, options, function(err2, stats) {
            if (err2) return done(err2);
            done(null, Object.assign(statistics, stats));
          });
        }
        done(null, statistics);
      });
    }
    module.exports = gwmi;
  }
});

// node_modules/pidusage/lib/stats.js
var require_stats = __commonJS({
  "node_modules/pidusage/lib/stats.js"(exports, module) {
    "use strict";
    var fs9 = __require("fs");
    var os3 = __require("os");
    var spawn2 = __require("child_process").spawn;
    var requireMap = {
      ps: () => require_ps(),
      procfile: () => require_procfile(),
      wmic: () => require_wmic(),
      gwmi: () => require_gwmi()
    };
    var platformToMethod = {
      aix: "ps",
      os400: "ps",
      android: "procfile",
      alpine: "procfile",
      darwin: "ps",
      freebsd: "ps",
      os390: "ps",
      linux: "procfile",
      netbsd: "procfile",
      openbsd: "ps",
      sunos: "ps",
      win: "wmic"
    };
    var platform = os3.platform();
    if (fs9.existsSync("/etc/alpine-release")) {
      platform = "alpine";
    }
    if (platform.match(/^win/)) {
      platform = "win";
    }
    var stat;
    try {
      stat = requireMap[platformToMethod[platform]]();
    } catch (err) {
    }
    function get(pids, options, callback) {
      let fn = stat;
      if (platform !== "win" && options.usePs === true) {
        fn = requireMap.ps();
      }
      if (platform === "win") {
        let child;
        try {
          child = spawn2("wmic", function(err) {
            if (err) throw new Error(err);
          });
        } catch (err) {
          fn = requireMap.gwmi();
        } finally {
          if (child) {
            child.kill();
          }
        }
      }
      if (fn === void 0) {
        return callback(new Error(os3.platform() + " is not supported yet, please open an issue (https://github.com/soyuka/pidusage)"));
      }
      let single = false;
      if (!Array.isArray(pids)) {
        single = true;
        pids = [pids];
      }
      if (pids.length === 0) {
        return callback(new TypeError("You must provide at least one pid"));
      }
      for (let i = 0; i < pids.length; i++) {
        pids[i] = parseInt(pids[i], 10);
        if (isNaN(pids[i]) || pids[i] < 0) {
          return callback(new TypeError("One of the pids provided is invalid"));
        }
      }
      fn(pids, options, function(err, stats) {
        if (err) {
          return callback(err);
        }
        if (single) {
          callback(null, stats[pids[0]]);
        } else {
          callback(null, stats);
        }
      });
    }
    module.exports = get;
  }
});

// node_modules/pidusage/index.js
var require_pidusage = __commonJS({
  "node_modules/pidusage/index.js"(exports, module) {
    "use strict";
    var stats = require_stats();
    function pidusage2(pids, options, callback) {
      if (typeof options === "function") {
        callback = options;
        options = {};
      }
      if (options === void 0) {
        options = {};
      }
      options = Object.assign({
        usePs: /^true$/i.test(process.env.PIDUSAGE_USE_PS),
        maxage: process.env.PIDUSAGE_MAXAGE
      }, options);
      if (typeof callback === "function") {
        stats(pids, options, callback);
        return;
      }
      return new Promise(function(resolve6, reject) {
        stats(pids, options, function(err, data) {
          if (err) return reject(err);
          resolve6(data);
        });
      });
    }
    module.exports = pidusage2;
    module.exports.clear = require_history().clear;
  }
});

// dist/clients/safe-spawn.js
import { spawn, spawnSync } from "node:child_process";
import * as fs8 from "node:fs";
import * as path11 from "node:path";

// dist/clients/resource-sampler.js
var import_pidusage = __toESM(require_pidusage(), 1);

// dist/clients/instance-reaper.js
import { spawn as nodeSpawn2 } from "node:child_process";

// dist/clients/bounded-pid-file-lock.js
import { randomUUID } from "node:crypto";
import * as fs2 from "node:fs";
import fsp from "node:fs/promises";
import path2 from "node:path";

// dist/clients/generation-lock.js
import { randomInt } from "node:crypto";
import * as fs from "node:fs";
import * as path from "node:path";
var GENERATION = /^lock\.(\d+)(\.released)?$/;
function pidFileOwner(file) {
  try {
    const pid = Number(fs.readFileSync(file, "utf8").trim().split(/\s+/)[0]);
    return Number.isInteger(pid) && pid > 0 ? pid : void 0;
  } catch {
    return void 0;
  }
}
function isPidAlive(pid) {
  if (pid === void 0)
    return false;
  try {
    process.kill(pid, 0);
    return true;
  } catch (error) {
    return error?.code !== "ESRCH";
  }
}
function pidFileIsStale(file, staleMs) {
  try {
    const stat = fs.statSync(file);
    if (Date.now() - stat.mtimeMs > staleMs)
      return true;
    const pid = pidFileOwner(file);
    return pid !== void 0 && !isPidAlive(pid);
  } catch {
    return false;
  }
}
function isLockContention(error) {
  const code = error?.code;
  return code === "EEXIST" || code === "EPERM" || code === "EBUSY";
}
function generationPath(dir, generation) {
  return path.join(dir, `lock.${generation}`);
}
function releasedName(generation) {
  return `lock.${generation}.released`;
}
function topGeneration(entries) {
  let top = 0;
  for (const name of entries) {
    const match = GENERATION.exec(name);
    if (match && !match[2])
      top = Math.max(top, Number(match[1]));
  }
  return top;
}
function removeBelowPredecessor(dir, entries, generation) {
  for (const name of entries) {
    const match = GENERATION.exec(name);
    if (!match || Number(match[1]) + 1 >= generation)
      continue;
    try {
      fs.unlinkSync(path.join(dir, name));
    } catch {
    }
  }
}
function recordGenerationTakeover(hold) {
  incrementDegradationCount({
    kind: "generation-lock-stale-takeover",
    subject: path.resolve(hold.dir),
    reason: `took over lock generation ${hold.generation - 1} from a dead or aged-out holder`
  });
}
function recordLegacyLockHeld(legacyPath) {
  incrementDegradationCount({
    kind: "generation-lock-legacy-held",
    subject: path.resolve(legacyPath),
    reason: `backed off: ${path.basename(legacyPath)} is held by another writer (one from before #3476, or a holder past the generation lease)`
  });
}
function releaseGeneration(hold) {
  try {
    fs.writeFileSync(path.join(hold.dir, releasedName(hold.generation)), "");
  } catch {
  }
}
function heartbeatIntervalMs(leaseMs) {
  return Math.max(1e3, Math.floor(leaseMs / 4));
}
function startGenerationHeartbeat(hold, intervalMs) {
  const file = generationPath(hold.dir, hold.generation);
  const timer = setInterval(() => {
    try {
      const now = /* @__PURE__ */ new Date();
      fs.utimesSync(file, now, now);
    } catch {
    }
  }, intervalMs);
  timer.unref();
  return { stop: () => clearInterval(timer) };
}
function ownsTopGeneration(hold) {
  try {
    const entries = fs.readdirSync(hold.dir);
    if (entries.includes(releasedName(hold.generation)))
      return false;
    return topGeneration(entries) === hold.generation;
  } catch {
    return false;
  }
}
function tryAcquireGeneration(dir, staleMs) {
  fs.mkdirSync(dir, { recursive: true });
  const listed = fs.readdirSync(dir);
  const top = topGeneration(listed);
  const free = top === 0 || listed.includes(releasedName(top));
  if (!free && !pidFileIsStale(generationPath(dir, top), staleMs)) {
    return void 0;
  }
  const hold = { dir, generation: top + 1, tookOverStale: !free };
  try {
    fs.writeFileSync(generationPath(dir, hold.generation), `${process.pid} ${Date.now()}
`, { flag: "wx" });
  } catch (error) {
    if (isLockContention(error))
      return void 0;
    throw error;
  }
  let entries;
  try {
    entries = fs.readdirSync(dir);
  } catch (cause) {
    releaseGeneration(hold);
    throw cause;
  }
  if (topGeneration(entries) > hold.generation) {
    releaseGeneration(hold);
    return void 0;
  }
  removeBelowPredecessor(dir, entries, hold.generation);
  return hold;
}
var timedOutHolders = new BoundedFifoMap(16);
function topGenerationHolder(dir) {
  try {
    const top = topGeneration(fs.readdirSync(dir));
    return `lock.${top} ${fs.readFileSync(generationPath(dir, top), "utf8").trim()}`;
  } catch {
    return void 0;
  }
}
function withGenerationLockSync(dir, timing, op) {
  const deadline = Date.now() + timing.waitMs;
  const timedOutHolder = timedOutHolders.get(dir);
  for (; ; ) {
    let hold;
    try {
      hold = tryAcquireGeneration(dir, timing.staleMs);
    } catch (cause) {
      return { held: false, cause };
    }
    if (hold) {
      if (hold.tookOverStale)
        recordGenerationTakeover(hold);
      try {
        return { held: true, value: op() };
      } finally {
        releaseGeneration(hold);
      }
    }
    if (timedOutHolder !== void 0 && topGenerationHolder(dir) === timedOutHolder) {
      recordDegradationOnce({
        kind: "generation-lock-wait-skipped",
        subject: dir,
        reason: `did not wait: ${timedOutHolder} still holds the lock after an earlier wait ran out`
      });
      return { held: false };
    }
    if (Date.now() >= deadline) {
      timedOutHolders.set(dir, topGenerationHolder(dir));
      return { held: false };
    }
    Atomics.wait(new Int32Array(new SharedArrayBuffer(4)), 0, 0, randomInt(5, 26));
  }
}

// dist/clients/bounded-pid-file-lock.js
var waitArray = new Int32Array(new SharedArrayBuffer(4));
var UNREADABLE_LOCK_STALE_MS = 5e3;
function generationDir(lockPath) {
  return `${lockPath}s`;
}
function boundedLockIsStale(lockPath) {
  const [pidText] = fs2.readFileSync(lockPath, "utf8").split(":", 1);
  const pid = Number.parseInt(pidText ?? "", 10);
  if (Number.isSafeInteger(pid) && pid > 0)
    return !ownerPidIsLive(pid);
  return Date.now() - fs2.statSync(lockPath).mtimeMs > UNREADABLE_LOCK_STALE_MS;
}
function ownerPidIsLive(pid) {
  if (!Number.isSafeInteger(pid) || pid <= 0)
    return false;
  try {
    process.kill(pid, 0);
    return true;
  } catch (error) {
    return error.code === "EPERM";
  }
}
function quarantinePath(lockPath, token) {
  return `${lockPath}.quarantine-${process.pid}-${token}`;
}
async function restoreQuarantinedLock(lockPath, quarantined) {
  try {
    await fsp.rename(quarantined, lockPath);
  } catch {
  }
}
async function releaseQuarantineLock(lockPath, token) {
  const quarantined = quarantinePath(lockPath, `release-${token}`);
  let renamed = false;
  for (let attempt = 0; attempt < 3; attempt += 1) {
    try {
      await fsp.rename(lockPath, quarantined);
      renamed = true;
      break;
    } catch (error) {
      if (error.code !== "ENOENT" || attempt === 2)
        return;
      await new Promise((resolve6) => setImmediate(resolve6));
    }
  }
  if (!renamed)
    return;
  try {
    const owner = JSON.parse(await fsp.readFile(path2.join(quarantined, "owner.json"), "utf8"));
    if (owner.token === token) {
      await fsp.rm(quarantined, { recursive: true, force: true });
    } else {
      await restoreQuarantinedLock(lockPath, quarantined);
    }
  } catch {
    await restoreQuarantinedLock(lockPath, quarantined);
  }
}
function quarantineOwnerIsStale(owner, staleMs) {
  const pidUsable = Number.isInteger(owner.pid) && owner.pid > 0;
  if (pidUsable && !ownerPidIsLive(owner.pid))
    return true;
  return Number.isFinite(owner.createdAt) && Date.now() - owner.createdAt > staleMs;
}
async function reclaimQuarantineLock(lockPath, staleMs) {
  const quarantined = quarantinePath(lockPath, `reclaim-${Date.now()}-${randomUUID()}`);
  try {
    await fsp.rename(lockPath, quarantined);
  } catch {
    return false;
  }
  let stale = false;
  try {
    const owner = JSON.parse(await fsp.readFile(path2.join(quarantined, "owner.json"), "utf8"));
    stale = quarantineOwnerIsStale(owner, staleMs);
  } catch {
    try {
      stale = Date.now() - (await fsp.stat(quarantined)).mtimeMs > staleMs;
    } catch {
      stale = false;
    }
  }
  if (stale) {
    await fsp.rm(quarantined, { recursive: true, force: true });
    return true;
  }
  await restoreQuarantinedLock(lockPath, quarantined);
  return false;
}
async function tryAcquireQuarantineLock(lockPath, staleMs) {
  const owner = {
    pid: process.pid,
    createdAt: Date.now(),
    token: `${process.pid}-${Date.now()}-${randomUUID()}`
  };
  for (let attempt = 0; attempt < 2; attempt += 1) {
    try {
      await fsp.mkdir(lockPath);
      try {
        await fsp.writeFile(path2.join(lockPath, "owner.json"), JSON.stringify(owner), "utf8");
      } catch (error) {
        await fsp.rm(lockPath, { recursive: true, force: true }).catch(() => {
        });
        throw error;
      }
      return () => releaseQuarantineLock(lockPath, owner.token);
    } catch (error) {
      if (error.code !== "EEXIST")
        throw error;
    }
    let stale;
    try {
      const existing = JSON.parse(await fsp.readFile(path2.join(lockPath, "owner.json"), "utf8"));
      stale = quarantineOwnerIsStale(existing, staleMs);
    } catch {
      try {
        stale = Date.now() - (await fsp.stat(lockPath)).mtimeMs > staleMs;
      } catch {
        stale = true;
      }
    }
    if (!stale || !await reclaimQuarantineLock(lockPath, staleMs))
      return null;
  }
  return null;
}
async function tryAcquireQuarantineGeneration(lockPath, staleMs) {
  const hold = tryAcquireGeneration(generationDir(lockPath), staleMs);
  if (!hold)
    return "busy";
  if (hold.tookOverStale)
    recordGenerationTakeover(hold);
  let releaseLegacy;
  try {
    releaseLegacy = await tryAcquireQuarantineLock(lockPath, staleMs);
  } catch (cause) {
    releaseGeneration(hold);
    throw cause;
  }
  if (releaseLegacy) {
    const heartbeat = startGenerationHeartbeat(hold, heartbeatIntervalMs(staleMs));
    return async () => {
      heartbeat.stop();
      await releaseLegacy();
      releaseGeneration(hold);
    };
  }
  releaseGeneration(hold);
  return "legacy-held";
}
async function acquireQuarantinePidFileLock(lockPath, options) {
  const deadline = Date.now() + options.waitMs;
  let legacyHeldRecorded = false;
  for (; ; ) {
    const release2 = await tryAcquireQuarantineGeneration(lockPath, options.staleMs);
    if (typeof release2 === "function")
      return release2;
    if (release2 === "legacy-held" && !legacyHeldRecorded) {
      legacyHeldRecorded = true;
      recordLegacyLockHeld(lockPath);
    }
    const remaining = deadline - Date.now();
    if (remaining <= 0) {
      if (options.onContention === "skip-log") {
        options.logContention();
        return null;
      }
      throw new Error(options.timeoutMessage);
    }
    await new Promise((resolve6) => setTimeout(resolve6, Math.min(options.retryMs, remaining)));
  }
}
function createLegacyBoundedLock(lockPath, token) {
  try {
    fs2.writeFileSync(lockPath, token, { encoding: "utf8", flag: "wx" });
    return true;
  } catch (cause) {
    if (isLockContention(cause))
      return false;
    throw cause;
  }
}
function takeLegacyBoundedLock(lockPath, token) {
  if (createLegacyBoundedLock(lockPath, token))
    return true;
  try {
    if (!boundedLockIsStale(lockPath))
      return false;
    fs2.unlinkSync(lockPath);
  } catch {
    return false;
  }
  return createLegacyBoundedLock(lockPath, token);
}
function releaseLegacyBoundedLock(lockPath, token) {
  try {
    if (fs2.readFileSync(lockPath, "utf8") === token)
      fs2.unlinkSync(lockPath);
  } catch {
  }
}
function tryAcquireBoundedLock(lockPath, token) {
  const hold = tryAcquireGeneration(generationDir(lockPath), UNREADABLE_LOCK_STALE_MS);
  if (!hold)
    return "busy";
  if (hold.tookOverStale)
    recordGenerationTakeover(hold);
  let took;
  try {
    took = takeLegacyBoundedLock(lockPath, token);
  } catch (cause) {
    releaseGeneration(hold);
    throw cause;
  }
  if (took)
    return hold;
  releaseGeneration(hold);
  return "legacy-held";
}
var timedOutHolders2 = new BoundedFifoMap(16);
function currentHolderIdentity(dir, lockPath, hold) {
  if (hold === "busy")
    return topGenerationHolder(dir);
  try {
    const content = fs2.readFileSync(lockPath, "utf8");
    return content ? `legacy ${content}` : void 0;
  } catch {
    return void 0;
  }
}
function acquireBoundedPidFileLock(lockPath, options) {
  const token = `${process.pid}:${Date.now()}:${randomUUID()}`;
  const deadline = Date.now() + options.waitMs;
  const dir = generationDir(lockPath);
  const timedOutHolder = timedOutHolders2.get(dir);
  let legacyHeldRecorded = false;
  for (; ; ) {
    const hold = tryAcquireBoundedLock(lockPath, token);
    if (typeof hold === "object") {
      return () => {
        releaseLegacyBoundedLock(lockPath, token);
        releaseGeneration(hold);
      };
    }
    if (hold === "legacy-held" && !legacyHeldRecorded) {
      legacyHeldRecorded = true;
      recordLegacyLockHeld(lockPath);
    }
    if (timedOutHolder !== void 0 && currentHolderIdentity(dir, lockPath, hold) === timedOutHolder) {
      recordDegradationOnce({
        kind: "bounded-pid-lock-wait-skipped",
        subject: path2.resolve(dir),
        reason: `did not wait: ${timedOutHolder} still holds the lock after an earlier wait ran out`
      });
      if (options.onContention === "skip-log") {
        options.logContention();
        return null;
      }
      throw new Error(options.timeoutMessage);
    }
    if (Date.now() >= deadline) {
      timedOutHolders2.set(dir, currentHolderIdentity(dir, lockPath, hold));
      if (options.onContention === "skip-log") {
        options.logContention();
        return null;
      }
      throw new Error(options.timeoutMessage);
    }
    Atomics.wait(waitArray, 0, 0, options.retryMs);
  }
}

// dist/clients/child-unref.js
import { spawn as nodeSpawn } from "node:child_process";
function unrefChildAndPipes(child) {
  try {
    child.unref();
    for (const stream of [child.stdout, child.stderr, child.stdin]) {
      stream?.unref?.();
    }
  } catch {
  }
}
function spawnCollectStdoutResult(command, args, options, collectOptions = {}) {
  return new Promise((resolve6) => {
    let settled = false;
    let timer;
    const settle = (result) => {
      if (settled)
        return;
      settled = true;
      if (timer)
        clearTimeout(timer);
      resolve6(result);
    };
    try {
      const child = nodeSpawn(command, args, options);
      unrefChildAndPipes(child);
      const out = createBoundedOutputSink();
      child.stdout?.on("data", (chunk) => out.append(chunk));
      child.once("error", (error) => settle({ stdout: "", status: "spawn-error", error }));
      child.once("close", (code, signal) => settle(code === 0 && signal === null ? { stdout: out.text, status: "ok" } : {
        stdout: "",
        status: "exit-error",
        exitCode: code,
        exitSignal: signal
      }));
      const timeoutMs = collectOptions.timeoutMs;
      if (typeof timeoutMs === "number" && timeoutMs > 0) {
        timer = setTimeout(() => {
          void terminateTimedOutChild(child, collectOptions.onTimeout).then((timeoutKill) => settle({ stdout: out.text, status: "timeout", timeoutKill }));
        }, timeoutMs);
        timer.unref();
      }
    } catch (error) {
      settle({ stdout: "", status: "spawn-error", error });
    }
  });
}
async function terminateTimedOutChild(child, onTimeout) {
  if (onTimeout) {
    try {
      return await onTimeout(child);
    } catch {
      return "unverified";
    }
  }
  try {
    child.kill();
  } catch {
  }
  return "unverified";
}

// dist/clients/file-utils.js
import * as fs4 from "node:fs";
import { createHash, randomBytes } from "node:crypto";
import * as os2 from "node:os";
import * as path7 from "node:path";

// dist/clients/spawn-timeout-cooldown.js
import path3 from "node:path";
var COOLDOWN_STATE_KEY = /* @__PURE__ */ Symbol.for("pi-lens:spawn-timeout-cooldown");
var _global = globalThis;
if (!_global[COOLDOWN_STATE_KEY]) {
  _global[COOLDOWN_STATE_KEY] = { timedOutByCommand: /* @__PURE__ */ new Map() };
}
var timedOutByCommand = _global[COOLDOWN_STATE_KEY].timedOutByCommand;
function wrapperKindOf(command) {
  const ext = path3.extname(command);
  return ext ? ext.slice(1) : "bare";
}
function cooldownKey(command) {
  return path3.basename(command).replace(/\.[^.]+$/, "").toLowerCase();
}
function noteSpawnTimeout(input) {
  const key = cooldownKey(input.command);
  timedOutByCommand.set(key, {
    tool: input.tool,
    command: input.command,
    phase: input.phase,
    atMs: Date.now()
  });
  logLatency({
    type: "phase",
    toolName: input.tool,
    phase: "spawn_timeout_cooldown",
    filePath: normalizeLoggedPath(input.command),
    durationMs: input.durationMs ?? 0,
    status: "cooldown_armed",
    metadata: {
      command: input.command,
      wrapperKind: wrapperKindOf(input.command),
      timeoutPhase: input.phase,
      ...input.durationMs !== void 0 && {
        timeoutBudgetMs: input.durationMs
      },
      ...input.teardown && {
        teardownMs: input.teardown.ms,
        teardownOutcome: input.teardown.outcome
      }
    }
  });
}
function isInSpawnTimeoutCooldown(command) {
  return timedOutByCommand.has(cooldownKey(command));
}
function resetSpawnTimeoutCooldowns() {
  timedOutByCommand.clear();
}

// dist/clients/git-tracked-ignore.js
import * as path4 from "node:path";
function recordTruncatedLsFiles(parseSite) {
  recordDegradationOnce({
    kind: "git-tracked-ignore-truncated",
    subject: `git-ls-files:${parseSite}`,
    reason: "safeSpawnAsync capped git ls-files stdout"
  });
}
var MAX_LS_FILES_OUTPUT_BYTES = 16 * 1024 * 1024;
function parseUntrackedIgnoredOutput(stdout, cwd) {
  const ids = /* @__PURE__ */ new Set();
  for (const line of stdout.split(/\r?\n/)) {
    const rel = line.trim();
    if (!rel)
      continue;
    const dirSegments = rel.split("/").slice(0, -1);
    if (dirSegments.some((segment) => isExcludedDirName(segment)))
      continue;
    ids.add(normalizeMapKey(path4.join(cwd, rel)));
  }
  return ids;
}
async function fetchUntrackedIgnoredIds(cwd) {
  try {
    const result = await safeSpawnAsync("git", ["ls-files", "--others", "--ignored", "--exclude-standard"], {
      cwd,
      timeout: 1e4,
      maxOutputBytes: MAX_LS_FILES_OUTPUT_BYTES,
      resourceLabel: "git-tracked-ignore"
    });
    if (truncatedByOutputCap(result)) {
      recordTruncatedLsFiles("untracked-ignored");
      return void 0;
    }
    if (result.error || result.status !== 0)
      return void 0;
    return parseUntrackedIgnoredOutput(result.stdout, cwd);
  } catch {
    return void 0;
  }
}
var CACHE_TTL_MS = 3e4;
var _cache = /* @__PURE__ */ new Map();
function collectUntrackedIgnoredIds(cwd) {
  const key = normalizeMapKey(cwd);
  const now = Date.now();
  const cached = _cache.get(key);
  if (cached && now - cached.fetchedAtMs < CACHE_TTL_MS)
    return cached.promise;
  const promise = fetchUntrackedIgnoredIds(cwd);
  _cache.set(key, { promise, fetchedAtMs: now });
  return promise;
}
function parseTrackedFilesOutput(stdout, cwd) {
  const ids = /* @__PURE__ */ new Set();
  const base = normalizeMapKey(cwd);
  for (const line of stdout.split(/\r?\n/)) {
    const rel = line.trim();
    if (!rel)
      continue;
    const dirSegments = rel.split("/").slice(0, -1);
    if (dirSegments.some((segment) => isExcludedDirName(segment)))
      continue;
    ids.add(normalizeEphemeralMapKey(path4.join(base, rel)));
  }
  return ids;
}
async function fetchTrackedFiles(cwd) {
  try {
    const result = await safeSpawnAsync("git", ["ls-files"], {
      cwd,
      timeout: 1e4,
      maxOutputBytes: MAX_LS_FILES_OUTPUT_BYTES,
      resourceLabel: "git-tracked-ignore"
    });
    if (truncatedByOutputCap(result)) {
      recordTruncatedLsFiles("tracked");
      return void 0;
    }
    if (result.error || result.status !== 0)
      return void 0;
    return parseTrackedFilesOutput(result.stdout, cwd);
  } catch {
    return void 0;
  }
}
var _trackedCache = /* @__PURE__ */ new Map();
var _trackedSnapshot = /* @__PURE__ */ new Map();
function collectTrackedFiles(cwd) {
  const key = normalizeEphemeralMapKey(cwd);
  const now = Date.now();
  for (const [snapshotKey, entry] of _trackedCache) {
    if (now - entry.fetchedAtMs >= CACHE_TTL_MS)
      _trackedSnapshot.delete(snapshotKey);
  }
  const cached = _trackedCache.get(key);
  if (cached && now - cached.fetchedAtMs < CACHE_TTL_MS)
    return cached.promise;
  const promise = fetchTrackedFiles(cwd).then((result) => {
    _trackedSnapshot.set(key, result);
    return result;
  });
  _trackedCache.set(key, { promise, fetchedAtMs: now });
  return promise;
}
function getTrackedFilesSnapshot(cwd) {
  return _trackedSnapshot.get(normalizeEphemeralMapKey(cwd));
}

// dist/clients/lens-config.js
import * as path5 from "node:path";
function globalCanonicalLocation() {
  const location = GLOBAL_CONFIG_LOCATIONS.find((candidate) => candidate.relativePath === CANONICAL_GLOBAL_CONFIG_FILE);
  if (!location) {
    throw new Error(`no canonical global config location named ${CANONICAL_GLOBAL_CONFIG_FILE}`);
  }
  return location;
}
function warnInvalidGlobalConfigOnce(configPath, reason, code) {
  warnIgnoredConfigOnce({
    subsystem: "lens-config",
    file: configPath,
    reason,
    ...code === void 0 ? {} : { code }
  });
}
function asConfigObject(value) {
  return value && typeof value === "object" && !Array.isArray(value) ? value : void 0;
}
function reportGlobalConfigProbeRetention() {
  const resolution = getProductionGlobalConfigResolution();
  if (resolution.source !== "legacy-default-unprobed" && resolution.source !== "pi-coding-agent-dir-unprobed") {
    return;
  }
  recordDegradationOnce({
    kind: "config-location-probe-failed",
    subject: resolution.path,
    // #3704/#3696: subject already carries the unbounded path; keep the
    // fixed diagnostic ahead of it so the ledger cap cannot erase it.
    reason: `existence probe failed (${resolution.existsProbeFailed?.errorClassName}); the location is retained as the config source and its read failures report through PILENS_CFG_0001`,
    metadata: { subsystem: "lens-config", configPath: resolution.path }
  });
}
function reportGlobalConfigShadowing() {
  const resolution = getProductionGlobalConfigResolution();
  if (resolution.shadowedPath === void 0)
    return;
  const winningPath = canonicalPathIdentity(resolution.path);
  const shadowedPath = canonicalPathIdentity(resolution.shadowedPath);
  recordDegradationOnce({
    kind: "config-location-shadowed",
    subject: winningPath,
    reason: `shadowed global config ${shadowedPath}; winning path is the record subject`,
    metadata: {
      subsystem: "lens-config",
      configPath: winningPath,
      shadowedPath
    },
    code: "PILENS_CFG_0010"
  });
}
function loadPiLensGlobalConfig(configPath) {
  const derivedPath = configPath === void 0;
  if (derivedPath) {
    reportGlobalConfigProbeRetention();
    reportGlobalConfigShadowing();
  }
  const resolvedPath = configPath ?? getPiLensGlobalConfigPath();
  const location = globalCanonicalLocation();
  const outcome = readConfigDocument(resolvedPath);
  if (outcome.status === "missing")
    return void 0;
  if (outcome.status === "error") {
    reportConfigReadFailure({
      file: resolvedPath,
      location,
      tier: "global",
      error: outcome.error,
      sourceText: outcome.sourceText
    });
    return void 0;
  }
  const { note, records: notedRecords } = ignoredRecordCollector(resolvedPath, "global");
  try {
    const parsed = outcome.value;
    if (!parsed || typeof parsed !== "object" || Array.isArray(parsed)) {
      note("top-level value must be an object");
      return void 0;
    }
    const document = {
      tier: "global",
      file: resolvedPath,
      location,
      value: parsed
    };
    const resolved = resolveOnePiLensConfigDocument(document);
    reportPiLensConfigRecords(resolved.records);
    const raw = resolved.value;
    const warnInvalid = note;
    const config = {};
    const toolConfig = readToolConfig(raw, warnInvalid);
    if (toolConfig)
      config.tools = toolConfig;
    for (const spec of LENS_FLAGS) {
      if (spec.readGlobal)
        continue;
      assignFlagConfigSection(raw, config, spec.configKey, warnInvalid);
    }
    const ignore = Array.isArray(raw.ignore) ? raw.ignore.filter((p) => typeof p === "string") : void 0;
    if (ignore && ignore.length > 0)
      config.ignore = ignore;
    const startup = asConfigObject(raw.startup);
    if (startup) {
      const startupConfig = {};
      const mode = startup.mode;
      const scans = asConfigObject(startup.scans);
      if (mode === "quick" || mode === "full" || mode === "minimal")
        startupConfig.mode = mode;
      else if ("mode" in startup)
        warnInvalid('startup.mode must be "quick", "full", or "minimal"');
      if (scans) {
        if (typeof scans.enabled === "boolean") {
          startupConfig.scans = { enabled: scans.enabled };
        } else if ("enabled" in scans)
          warnInvalid("startup.scans.enabled must be a boolean");
      }
      if (startupConfig.mode !== void 0 || startupConfig.scans !== void 0)
        config.startup = startupConfig;
    }
    const dispatch = asConfigObject(raw.dispatch);
    if (dispatch) {
      const floor = dispatch.runnerTimeoutFloorMs;
      if (typeof floor === "number" && Number.isFinite(floor) && floor > 0) {
        config.dispatch = { runnerTimeoutFloorMs: floor };
      } else {
        if ("runnerTimeoutFloorMs" in dispatch) {
          warnInvalid("dispatch.runnerTimeoutFloorMs must be a positive finite number");
        }
        config.dispatch = { runnerTimeoutFloorMs: void 0 };
      }
    }
    const autoFix = asConfigObject(asConfigObject(raw.actionableWarnings)?.autoFix);
    if (autoFix && "maxFixes" in autoFix) {
      if (typeof autoFix.maxFixes === "number" && Number.isFinite(autoFix.maxFixes) && autoFix.maxFixes >= 0) {
        config.actionableWarnings ??= {};
        const warnings = config.actionableWarnings;
        warnings.autoFix ??= {};
        warnings.autoFix.maxFixes = Math.floor(autoFix.maxFixes);
      } else {
        warnInvalid("actionableWarnings.autoFix.maxFixes must be a non-negative finite number");
      }
    }
    const widget = asConfigObject(raw.widget);
    if (widget) {
      if (typeof widget.visible === "boolean") {
        config.widget = { visible: widget.visible };
      } else {
        if ("visible" in widget) {
          warnInvalid("widget.visible must be a boolean");
        }
        config.widget = { visible: void 0 };
      }
    }
    const format = asConfigObject(raw.format);
    if (format) {
      config.format ??= {};
      const formatSection = config.format;
      if (format.mode === "immediate" || format.mode === "deferred") {
        formatSection.mode = format.mode;
      } else {
        if ("mode" in format) {
          warnInvalid('format.mode must be "immediate" or "deferred"');
        }
        formatSection.mode = void 0;
      }
    }
    const knownGlobalConfigKeys = /* @__PURE__ */ new Set([
      ...flagConfigSectionKeys(LENS_FLAGS),
      ...GLOBAL_NON_FLAG_CONFIG_SECTIONS,
      ...LEGACY_ROOT_LSP_KEYS
    ]);
    for (const key of Object.keys(raw)) {
      if (!knownGlobalConfigKeys.has(key)) {
        warnInvalid(`unknown key "${key}" is not a recognized pi-lens setting (check for a typo); ignored`);
      }
    }
    return config;
  } catch (error) {
    warnInvalidGlobalConfigOnce(resolvedPath, `global config could not be interpreted (${errorClassName(error)}); configuration ignored`, "PILENS_CFG_0008");
    return void 0;
  } finally {
    reportPiLensConfigRecords(notedRecords());
  }
}
function getGlobalIgnorePatterns(configPath) {
  return loadPiLensGlobalConfig(configPath)?.ignore ?? [];
}
function resolvePiLensFlagWithSource(name, value, config, projectConfig, editedFilePath, projectRoot) {
  const spec = getLensFlagSpec(name);
  if (spec?.env && process.env[spec.env] === "1") {
    return { value: true, source: "env" };
  }
  if (value)
    return { value, source: "cli" };
  if (!spec)
    return { value, source: "default" };
  if (spec.scope === "project") {
    const nested = editedFilePath && projectRoot ? findNestedProjectMutationValue(spec, editedFilePath, projectRoot) : void 0;
    if (nested) {
      return {
        value: flagValueFromConfig(spec, nested.value),
        source: path5.resolve(nested.dir) === path5.resolve(projectRoot) ? "project" : `nested-project:${nested.dir}`
      };
    }
    const projectValue = readFlagConfigValue(projectConfig, spec.configKey);
    if (projectValue !== void 0) {
      return {
        value: flagValueFromConfig(spec, projectValue),
        source: "project"
      };
    }
  }
  const globalValue = spec.readGlobal ? spec.readGlobal(config ?? {}) : readFlagConfigValue(config, spec.configKey);
  if (globalValue !== void 0) {
    return { value: flagValueFromConfig(spec, globalValue), source: "global" };
  }
  return { value: spec.default, source: "default" };
}
function resolvePiLensFlag(name, value, config, projectConfig, editedFilePath, projectRoot) {
  return resolvePiLensFlagWithSource(name, value, config, projectConfig, editedFilePath, projectRoot).value;
}

// dist/clients/ephemeral-root.js
import * as fs3 from "node:fs";
import * as os from "node:os";
import * as path6 from "node:path";
var NOT_EPHEMERAL = { checkout: false };
var classified = new BoundedFifoMap(1024);
function realPathOfNearestExisting(target) {
  const resolved = path6.resolve(target);
  const tail = [];
  for (let current = resolved; ; current = path6.dirname(current)) {
    try {
      return path6.join(fs3.realpathSync.native(current), ...tail.reverse());
    } catch {
      if (path6.dirname(current) === current)
        return resolved;
      tail.push(path6.basename(current));
    }
  }
}
function classifyTmpDir(dir) {
  const tmpSpelling = os.tmpdir();
  const key = `${normalizeEphemeralMapKey(tmpSpelling)}\0${normalizeEphemeralMapKey(path6.resolve(dir))}`;
  const memo = classified.get(key);
  if (memo)
    return memo;
  const tmpRoot = realPathOfNearestExisting(tmpSpelling);
  const real = realPathOfNearestExisting(dir);
  let result = NOT_EPHEMERAL;
  if (isUnderDir(real, tmpRoot)) {
    for (let current = real; current !== tmpRoot && path6.dirname(current) !== current; current = path6.dirname(current)) {
      if (isRealGitMarker(path6.join(current, ".git"))) {
        result = { checkout: true };
        break;
      }
    }
    if (!result.checkout) {
      const segments = path6.relative(tmpRoot, real).split(path6.sep);
      const index = segments.findIndex((segment) => /^pi-agent(?:-|$)/i.test(segment));
      if (index >= 0) {
        result = {
          checkout: false,
          stagingRoot: path6.join(tmpRoot, ...segments.slice(0, index + 1))
        };
      }
    }
  }
  classified.set(key, result);
  return result;
}
function ephemeralStagingRoot(filePath) {
  return classifyTmpDir(path6.dirname(path6.resolve(filePath))).stagingRoot;
}
function isEphemeralCheckoutRoot(dir) {
  return classifyTmpDir(dir).checkout;
}

// dist/clients/file-utils.js
function getProjectDataDir(cwd) {
  const legacyProjectDir = path7.join(cwd, ".pi-lens");
  const configuredBase = process.env.PILENS_DATA_DIR?.trim();
  if (!configuredBase && fs4.existsSync(legacyProjectDir)) {
    return legacyProjectDir;
  }
  const resolvedBase = projectDataBase();
  const memoKey = `${resolvedBase}\0${path7.resolve(cwd)}`;
  const cached = settledDataDirs.get(memoKey);
  if (cached !== void 0)
    return cached;
  const canonical = canonicalProjectRoot(cwd);
  const readable = projectDataDirReadableSlug(canonical.root);
  const hash = projectDataDirRootHash(canonical.root);
  const slug = `${readable || "default"}-${hash}`;
  const base = isEphemeralCheckoutRoot(cwd) ? ephemeralDataBase(resolvedBase) : resolvedBase;
  const dir = path7.join(base, slug);
  if (base !== resolvedBase && pendingDataDirMigrations.length < 32) {
    pendingDataDirMigrations.push({ to: dir, outcome: "ephemeral" });
  }
  const settled = settleProjectDataDir(base, readable || "default", dir, memoKey, canonical.fallback);
  return settled;
}
function projectDataBase() {
  const configuredBase = process.env.PILENS_DATA_DIR?.trim();
  return configuredBase || path7.join(getGlobalPiLensDir(), "projects");
}
var EPHEMERAL_DATA_DIR_NAME = ".ephemeral";
var EPHEMERAL_TOKEN_PATTERN = /^(\d+)-[0-9a-f]{8}$/;
function ephemeralDataToken() {
  return getProcessSingleton("project-data-ephemeral-token", 1, () => ({
    token: `${process.pid}-${randomBytes(4).toString("hex")}`,
    exitHook: false
  }));
}
function ephemeralDataBase(resolvedBase) {
  const state = ephemeralDataToken();
  if (!state.exitHook) {
    state.exitHook = true;
    process.once("exit", removeEphemeralDataDirs);
  }
  return path7.join(resolvedBase, EPHEMERAL_DATA_DIR_NAME, state.token);
}
function removeEphemeralDataDirs() {
  const dir = path7.join(projectDataBase(), EPHEMERAL_DATA_DIR_NAME, ephemeralDataToken().token);
  try {
    fs4.rmSync(dir, { recursive: true, force: true });
  } catch {
  }
}
async function sweepDeadEphemeralDataDirs(options) {
  const parent = path7.join(projectDataBase(), EPHEMERAL_DATA_DIR_NAME);
  let handle;
  try {
    handle = await fs4.promises.opendir(parent);
  } catch {
    return 0;
  }
  let removed = 0;
  try {
    for (let i = 0; i < (options.maxEntries ?? 512); i++) {
      const entry = await handle.read();
      if (entry === null)
        break;
      const pid = entry.isDirectory() ? EPHEMERAL_TOKEN_PATTERN.exec(entry.name)?.[1] : void 0;
      if (pid === void 0 || options.isPidAlive(Number(pid)))
        continue;
      try {
        await fs4.promises.rm(path7.join(parent, entry.name), {
          recursive: true,
          force: true
        });
        removed++;
      } catch {
      }
    }
  } catch {
  } finally {
    await handle.close().catch(() => {
    });
  }
  return removed;
}
function projectDataDirReadableSlug(canonicalRoot) {
  const normalized = normalizeFilePath(canonicalRoot);
  return normalized.replace(/^[a-z]:/i, "").replace(/\/+/g, "-").replace(/[^A-Za-z0-9-]/g, "").replace(/^-+/, "").replace(/-+$/, "");
}
function canonicalProjectRoot(cwd) {
  const resolved = path7.resolve(cwd);
  try {
    fs4.realpathSync(resolved);
  } catch {
    return { root: resolved, fallback: true };
  }
  return { root: resolved, fallback: false };
}
function projectDataDirRootHash(canonicalRoot) {
  return createHash("sha256").update(canonicalRoot).digest("hex").slice(0, 8);
}
var pendingDataDirMigrations = [];
var settledDataDirs = /* @__PURE__ */ new Map();
function resetProjectDataDirSessionState() {
  pendingDataDirMigrations.splice(0);
}
function settleProjectDataDir(base, oldSlug, dir, memoKey, identityFallback) {
  const oldDir = path7.join(base, oldSlug);
  const newExists = fs4.existsSync(dir);
  const oldExists = fs4.existsSync(oldDir);
  if (!oldExists) {
    if (identityFallback && pendingDataDirMigrations.length < 32) {
      pendingDataDirMigrations.push({
        to: dir,
        outcome: "identity-fallback"
      });
    }
    settledDataDirs.set(memoKey, dir);
    return dir;
  }
  if (!newExists) {
    try {
      fs4.renameSync(oldDir, dir);
    } catch (error) {
      if (error.code === "ENOENT") {
        if (fs4.existsSync(dir)) {
          settledDataDirs.set(memoKey, dir);
          return dir;
        }
        if (fs4.existsSync(oldDir))
          return oldDir;
        return dir;
      }
      if (pendingDataDirMigrations.length < 32) {
        pendingDataDirMigrations.push({
          to: dir,
          outcome: "rename-failed"
        });
      }
      settledDataDirs.set(memoKey, oldDir);
      return oldDir;
    }
  }
  settledDataDirs.set(memoKey, dir);
  if (pendingDataDirMigrations.length < 32) {
    pendingDataDirMigrations.push({
      to: dir,
      outcome: newExists ? "coexisting" : "renamed"
    });
  }
  return dir;
}
function drainProjectDataDirMigrations() {
  return pendingDataDirMigrations.splice(0);
}
function displayProjectDataPath(cwd, ...segments) {
  const absolute = path7.resolve(getProjectDataDir(cwd), ...segments);
  const absolutePosix = absolute.replace(/\\/g, "/");
  const relative3 = toProjectRelativePath(absolute, cwd);
  if (relative3 !== absolutePosix) {
    return relative3;
  }
  return homeRelativePath(absolutePosix);
}
function getGlobalPiLensDir() {
  const override = process.env.PI_LENS_HOME?.trim();
  if (override)
    return path7.resolve(override);
  return path7.join(os2.homedir(), ".pi-lens");
}
var EXCLUDED_DIRS = [
  "node_modules",
  ".git",
  "dist",
  "build",
  ".turbo",
  ".cache",
  "target",
  "out",
  ".parcel-cache",
  ".svelte-kit",
  ".nuxt",
  ".yarn",
  ".pnpm-store",
  ".gradle",
  ".next",
  ".pi-lens",
  ".pi",
  // pi agent directory
  // The SAME agent, rebranded: pi derives its config-dir name as
  // `pkg.piConfig?.configDir || ".pi"` (pi-coding-agent 0.85.1,
  // `dist/bundle/chunks/chunk-JVUZSMYM.js`), so a redistribution spells its
  // `<configDir>/agent/sessions` history `.omp/agent/sessions` instead.
  // #3112: a project-local one was walked entry-by-entry and spent the whole
  // startup-scan entry budget, so a five-file project reported
  // `too-many-entries` and never warmed its caches.
  ".omp",
  ".ruff_cache",
  // Python linter cache
  ".worktrees",
  ".claude",
  ".codex",
  ".rescue",
  ".agents",
  ".gstack",
  ".superpowers",
  ".guardrails",
  ".playwright-cli",
  ".playwright-mcp",
  ".vscode",
  "venv",
  ".venv",
  "coverage",
  "__pycache__",
  ".tox",
  ".pytest_cache",
  "*.dSYM",
  // Vendored upstream source conventions — universally too large to scan
  "vendor",
  // Go modules, PHP Composer, Ruby Bundler
  "third_party",
  // Chromium/Google convention (llama.cpp, sherpa-onnx, gRPC, TF)
  "third-party",
  "vendors"
];
function resolveGitIgnoreRoot(startDir) {
  const fallback = path7.resolve(startDir);
  let current = fallback;
  while (true) {
    if (fs4.existsSync(path7.join(current, ".git")))
      return current;
    const parent = path7.dirname(current);
    if (parent === current)
      return fallback;
    current = parent;
  }
}
function collapseSlashes(value) {
  let out = "";
  let previousWasSlash = false;
  for (const ch of value) {
    if (ch === "/") {
      if (!previousWasSlash)
        out += ch;
      previousWasSlash = true;
      continue;
    }
    out += ch === "\\" ? "/" : ch;
    previousWasSlash = false;
  }
  return out;
}
function stripLeadingDotSlash(value) {
  return value.startsWith("./") ? value.slice(2) : value;
}
function stripTrailingSlashes(value) {
  let end = value.length;
  while (end > 0 && value[end - 1] === "/")
    end -= 1;
  return value.slice(0, end);
}
function stripLeadingSlashes(value) {
  let start = 0;
  while (start < value.length && value[start] === "/")
    start += 1;
  return value.slice(start);
}
function normalizeIgnorePath(value) {
  return collapseSlashes(stripLeadingDotSlash(value));
}
function stripTrailingSpaces(value) {
  let end = value.length;
  while (end > 0 && value[end - 1] === " " && value[end - 2] !== "\\")
    end -= 1;
  return value.slice(0, end).replace(/\\ /g, " ");
}
function parseGitignoreContent(content, layer) {
  const patterns = [];
  for (const rawLine of content.split(/\r?\n/)) {
    let line = stripTrailingSpaces(rawLine.trimStart());
    if (!line || line.startsWith("#"))
      continue;
    let negated = false;
    if (line.startsWith("!")) {
      negated = true;
      line = line.slice(1);
    }
    line = normalizeIgnorePath(line);
    if (!line)
      continue;
    const directoryOnly = line.endsWith("/");
    if (directoryOnly)
      line = stripTrailingSlashes(line);
    const rooted = line.startsWith("/");
    if (rooted)
      line = stripLeadingSlashes(line);
    if (!line)
      continue;
    patterns.push({
      pattern: line,
      negated,
      directoryOnly,
      rooted,
      hasSlash: line.includes("/"),
      layer
    });
  }
  return patterns;
}
function expandGitignorePattern(pattern) {
  const body = pattern.pattern;
  if (pattern.directoryOnly) {
    if (pattern.rooted || pattern.hasSlash)
      return [body, `${body}/**`];
    return [body, `${body}/**`, `**/${body}`, `**/${body}/**`];
  }
  if (pattern.rooted || pattern.hasSlash)
    return [body];
  return [body, `**/${body}`];
}
function matchesGitignorePattern(pattern, relativePath, isDirectory, matchExpanded) {
  const candidate = stripLeadingSlashes(normalizeIgnorePath(relativePath));
  if (!candidate)
    return false;
  const candidates = isDirectory ? [candidate, `${candidate}/`] : [candidate];
  return expandGitignorePattern(pattern).some((expanded) => {
    if (isDirectory && expanded.endsWith("/**")) {
      const prefix = expanded.slice(0, -3);
      if (candidate === prefix || candidate.startsWith(`${prefix}/`))
        return true;
    }
    return candidates.some((value) => matchExpanded(value, expanded));
  });
}
function readGitignorePatterns(rootDir, layer = "gitignore") {
  const gitignorePath = path7.join(rootDir, ".gitignore");
  try {
    return parseGitignoreContent(fs4.readFileSync(gitignorePath, "utf-8"), layer);
  } catch {
    return [];
  }
}
function ancestorDirsBetween(rootDir, targetDir) {
  const relative3 = path7.relative(rootDir, targetDir);
  if (relative3.startsWith("..") || path7.isAbsolute(relative3))
    return [];
  const dirs = [rootDir];
  if (!relative3)
    return dirs;
  let current = rootDir;
  for (const segment of relative3.split(path7.sep).filter(Boolean)) {
    current = path7.join(current, segment);
    dirs.push(current);
  }
  return dirs;
}
function buildProjectIgnoreMatcher(resolvedRoot, patterns) {
  const consumedIgnoreSources = /* @__PURE__ */ new Map();
  const rememberIgnoreSource = (filePath, signature = fileFreshnessSignature(filePath)) => {
    consumedIgnoreSources.set(filePath, { path: filePath, ...signature });
  };
  rememberIgnoreSource(path7.join(resolvedRoot, ".gitignore"));
  const nestedCache = /* @__PURE__ */ new Map();
  const patternsForDir = (dir) => {
    if (dir === resolvedRoot)
      return patterns;
    const cached = nestedCache.get(dir);
    const now = Date.now();
    if (cached !== void 0 && now - cached.checkedAtMs < PROJECT_IGNORE_FRESHNESS_CADENCE_MS) {
      return cached.patterns;
    }
    const gitignoreSig = gitignoreSignature(dir);
    rememberIgnoreSource(path7.join(dir, ".gitignore"), gitignoreSig);
    const pilensInfo = findPiLensConfigInDir(dir);
    const pilensMtime = pilensInfo?.mtimeMs ?? -1;
    const pilensSize = pilensInfo?.size ?? -1;
    if (cached?.gitignoreMtimeMs === gitignoreSig.mtimeMs && cached?.gitignoreSize === gitignoreSig.size && cached?.pilensMtimeMs === pilensMtime && cached?.pilensSize === pilensSize) {
      cached.checkedAtMs = now;
      return cached.patterns;
    }
    const nestedConfig = loadPiLensConfigInDir(dir);
    const nextPatterns = [
      ...readGitignorePatterns(dir),
      ...parseGitignoreContent(nestedConfig.ignore.join("\n"), "pilens")
    ];
    nestedCache.set(dir, {
      checkedAtMs: now,
      gitignoreMtimeMs: gitignoreSig.mtimeMs,
      gitignoreSize: gitignoreSig.size,
      pilensMtimeMs: pilensMtime,
      pilensSize,
      patterns: nextPatterns
    });
    if (cached !== void 0)
      dropVerdictsUnder(dir);
    return nextPatterns;
  };
  const patternMemo = /* @__PURE__ */ new Map();
  function dropVerdictsUnder(subtree) {
    const resolvedSubtree = path7.resolve(subtree);
    for (const key of patternMemo.keys()) {
      const memoPath = key.slice(2);
      const relative3 = path7.relative(resolvedSubtree, memoPath);
      if (!relative3 || !relative3.startsWith("..") && !path7.isAbsolute(relative3)) {
        patternMemo.delete(key);
      }
    }
  }
  const invalidateSubtree = (subtree) => {
    dropVerdictsUnder(subtree);
    nestedCache.delete(path7.resolve(subtree));
  };
  const gitignoreGlobOptions = {
    dot: true,
    nocase: process.platform === "win32"
  };
  const compiledGlobs = /* @__PURE__ */ new Map();
  const matchExpanded = (value, expanded) => {
    let compiled = compiledGlobs.get(expanded);
    if (compiled === void 0) {
      compiled = new Minimatch(expanded, gitignoreGlobOptions);
      compiledGlobs.set(expanded, compiled);
    }
    return compiled.match(value);
  };
  function isTrackedAndRescued(resolved) {
    const snapshot = getTrackedFilesSnapshot(resolvedRoot);
    if (!snapshot)
      return false;
    return snapshot.has(normalizeEphemeralMapKey(resolved));
  }
  return {
    rootDir: resolvedRoot,
    patterns,
    getConsumedIgnoreSources: () => [...consumedIgnoreSources.values()],
    refreshConsumedIgnoreSource(filePath) {
      if (consumedIgnoreSources.has(filePath))
        rememberIgnoreSource(filePath);
    },
    invalidateSubtree,
    ensureTrackedIndex() {
      return collectTrackedFiles(resolvedRoot).then(() => void 0);
    },
    isIgnored(filePath, isDirectory = false) {
      const resolved = path7.resolve(filePath);
      const memoKey = (isDirectory ? "D:" : "F:") + resolved;
      let verdict = patternMemo.get(memoKey);
      if (verdict === void 0) {
        const rootRelative = path7.relative(resolvedRoot, resolved);
        if (!rootRelative || rootRelative.startsWith("..") || path7.isAbsolute(rootRelative)) {
          verdict = { ignored: false, layer: void 0 };
        } else {
          let ignored = false;
          let layer;
          const patternDirs = ancestorDirsBetween(resolvedRoot, path7.dirname(resolved));
          for (const dir of patternDirs) {
            const dirPatterns = patternsForDir(dir);
            if (dirPatterns.length === 0)
              continue;
            const relative3 = path7.relative(dir, resolved);
            const normalized = normalizeIgnorePath(relative3);
            for (const pattern of dirPatterns) {
              if (!matchesGitignorePattern(pattern, normalized, isDirectory, matchExpanded))
                continue;
              ignored = !pattern.negated;
              layer = pattern.layer;
            }
          }
          verdict = { ignored, layer };
        }
        patternMemo.set(memoKey, verdict);
      }
      if (!verdict.ignored)
        return false;
      if (!isDirectory && verdict.layer !== "pilens" && isTrackedAndRescued(resolved)) {
        return false;
      }
      return true;
    }
  };
}
function createProjectIgnoreMatcher(rootDir, extraPatterns = [], globalPatterns = []) {
  const resolvedRoot = resolveGitIgnoreRoot(rootDir);
  const patterns = [
    ...parseGitignoreContent(globalPatterns.join("\n"), "global"),
    ...readGitignorePatterns(resolvedRoot, "gitignore"),
    ...parseGitignoreContent(extraPatterns.join("\n"), "pilens")
  ];
  return buildProjectIgnoreMatcher(resolvedRoot, patterns);
}
var projectIgnoreMatcherCache = /* @__PURE__ */ new Map();
var PROJECT_IGNORE_FRESHNESS_CADENCE_MS = FRESHNESS_CADENCE_MS;
function fileFreshnessSignature(filePath) {
  try {
    const stat = fs4.statSync(filePath);
    return { mtimeMs: stat.mtimeMs, size: stat.size };
  } catch {
    return { mtimeMs: -1, size: -1 };
  }
}
function globalConfigSignature() {
  return fileFreshnessSignature(getPiLensGlobalConfigPath());
}
function gitignoreSignature(rootDir) {
  return fileFreshnessSignature(path7.join(rootDir, ".gitignore"));
}
function hasIgnoreSourceDrift(sources) {
  return sources.some((source) => {
    const current = fileFreshnessSignature(source.path);
    return current.mtimeMs !== source.mtimeMs || current.size !== source.size;
  });
}
function lensConfigInfo(rootDir) {
  const info = findPiLensProjectConfig(rootDir);
  return info ? { info, path: info.path, mtimeMs: info.mtimeMs, size: info.size } : { info, path: void 0, mtimeMs: -1, size: -1 };
}
function getProjectIgnoreMatcher(rootDir) {
  const resolvedRoot = resolveGitIgnoreRoot(rootDir);
  const gitignoreSig = gitignoreSignature(resolvedRoot);
  const lensConfig = lensConfigInfo(resolvedRoot);
  const globalSig = globalConfigSignature();
  const cached = projectIgnoreMatcherCache.get(resolvedRoot);
  if (cached) {
    const known = new Set(cached.ignoreSources.map((source) => source.path));
    for (const source of cached.matcher.getConsumedIgnoreSources()) {
      if (!known.has(source.path))
        cached.ignoreSources.push(source);
    }
  }
  if (cached && Date.now() - cached.lastIgnoreFreshnessCheckMs >= PROJECT_IGNORE_FRESHNESS_CADENCE_MS) {
    cached.lastIgnoreFreshnessCheckMs = Date.now();
    if (hasIgnoreSourceDrift(cached.ignoreSources)) {
      for (const source of cached.ignoreSources) {
        if (hasIgnoreSourceDrift([source])) {
          const sourceIndex = cached.ignoreSources.findIndex((cachedSource) => cachedSource.path === source.path);
          invalidateProjectIgnoreMatcherForPath(source.path);
          cached.matcher.refreshConsumedIgnoreSource(source.path);
          const refreshedSource = cached.matcher.getConsumedIgnoreSources().find((current) => current.path === source.path);
          if (sourceIndex !== -1 && refreshedSource !== void 0) {
            cached.ignoreSources.splice(sourceIndex, 1, refreshedSource);
          }
        }
      }
    }
  }
  if (cached?.gitignoreMtimeMs === gitignoreSig.mtimeMs && cached?.gitignoreSize === gitignoreSig.size && cached?.lensConfigPath === lensConfig.path && cached?.lensConfigMtimeMs === lensConfig.mtimeMs && cached?.lensConfigSize === lensConfig.size && cached?.globalConfigMtimeMs === globalSig.mtimeMs && cached?.globalConfigSize === globalSig.size) {
    return cached.matcher;
  }
  const projectConfig = loadPiLensProjectConfig(resolvedRoot, lensConfig.info);
  const matcher = createProjectIgnoreMatcher(resolvedRoot, projectConfig.ignore, getGlobalIgnorePatterns());
  projectIgnoreMatcherCache.set(resolvedRoot, {
    ignoreSources: [...matcher.getConsumedIgnoreSources()],
    lastIgnoreFreshnessCheckMs: Date.now(),
    gitignoreMtimeMs: gitignoreSig.mtimeMs,
    gitignoreSize: gitignoreSig.size,
    lensConfigPath: lensConfig.path,
    lensConfigMtimeMs: lensConfig.mtimeMs,
    lensConfigSize: lensConfig.size,
    globalConfigMtimeMs: globalSig.mtimeMs,
    globalConfigSize: globalSig.size,
    matcher
  });
  return matcher;
}
function invalidateProjectIgnoreMatcherForPath(filePath) {
  const resolvedPath = path7.resolve(filePath);
  if (path7.basename(resolvedPath).toLowerCase() !== ".gitignore")
    return;
  for (const [cachedRoot, cached] of projectIgnoreMatcherCache) {
    if (!isUnderDir(resolvedPath, cachedRoot))
      continue;
    if (normalizeFilePath(resolvedPath) === normalizeFilePath(path7.join(cachedRoot, ".gitignore"))) {
      projectIgnoreMatcherCache.delete(cachedRoot);
      continue;
    }
    cached.matcher.invalidateSubtree(path7.dirname(resolvedPath));
  }
}
function isPathIgnoredByProject(filePath, rootDir, isDirectory = false) {
  return getProjectIgnoreMatcher(rootDir).isIgnored(filePath, isDirectory);
}
function isRecordableProjectPath(filePath, projectRoot) {
  if (isPathIgnoredByProject(filePath, projectRoot, false))
    return false;
  if (isExternalOrVendorFile(filePath, projectRoot))
    return false;
  return true;
}
var projectIgnoreGlobsCache = /* @__PURE__ */ new Map();
function getProjectIgnoreGlobs(rootDir) {
  const resolvedRoot = path7.resolve(rootDir);
  const signature = gitignoreSignature(resolvedRoot);
  const cached = projectIgnoreGlobsCache.get(resolvedRoot);
  if (cached && cached.mtimeMs === signature.mtimeMs && cached.size === signature.size) {
    return cached.globs;
  }
  const globs = readGitignorePatterns(resolvedRoot).filter((pattern) => !pattern.negated).flatMap((pattern) => expandGitignorePattern(pattern));
  projectIgnoreGlobsCache.set(resolvedRoot, { ...signature, globs });
  return globs;
}
function globToRegExp(glob) {
  const escaped = glob.replace(/\*+/g, "*").replace(/[.+^${}()|[\]\\]/g, "\\$&").replace(/\*/g, ".*").replace(/\?/g, ".");
  return new RegExp(`^${escaped}$`, "i");
}
function isExcludedDirName(dirName, extraPatterns = []) {
  const candidate = dirName.trim();
  if (!candidate)
    return false;
  const patterns = [...EXCLUDED_DIRS, ...extraPatterns].map((p) => p.trim()).filter((p) => p.length > 0);
  const candidateLower = candidate.toLowerCase();
  for (const pattern of patterns) {
    const patLower = pattern.toLowerCase();
    if (!patLower.includes("*") && !patLower.includes("?")) {
      if (candidateLower === patLower)
        return true;
      continue;
    }
    if (globToRegExp(pattern).test(candidate))
      return true;
  }
  return false;
}
function getExcludedDirGlobs() {
  return EXCLUDED_DIRS.map((dir) => `**/${dir}/**`);
}
function getKnipIgnorePatterns() {
  return [
    ...getExcludedDirGlobs(),
    "**/*.test.ts",
    "**/*.test.tsx",
    "**/*.test.js",
    "**/*.test.jsx",
    "**/*.spec.ts",
    "**/*.spec.tsx",
    "**/*.spec.js",
    "**/*.spec.jsx",
    "**/*.poc.test.ts",
    "**/*.poc.test.tsx",
    "**/__tests__/**",
    "**/tests/**"
  ];
}
function isTestFile(filePath) {
  if (detectFileRole(filePath) === "test")
    return true;
  const normalized = filePath.replace(/\\/g, "/");
  return normalized.includes("test-utils") || normalized.startsWith("test-") || normalized.includes(".fixture.") || normalized.includes(".mock.");
}

// dist/clients/instance-registry.js
import * as fs7 from "node:fs";
import * as path10 from "node:path";

// dist/clients/generation-guard.js
var declaredSources = /* @__PURE__ */ new Set();
var MAX_DECLARED_SOURCES = 128;
function declare(name) {
  if (!name.trim()) {
    throw new Error("generation source needs a non-empty name");
  }
  if (declaredSources.size < MAX_DECLARED_SOURCES)
    declaredSources.add(name);
  return name;
}
var FENCE_TALLY_FAMILY = "generation-guard.fence-tally";
var FENCE_TALLY_VERSION = 1;
var OTHER_SOURCES = "(other)";
function fenceTallies() {
  return getProcessSingleton(FENCE_TALLY_FAMILY, FENCE_TALLY_VERSION, () => /* @__PURE__ */ new Map());
}
function tallyFence(sourceName, dropped) {
  const tallies = fenceTallies();
  const key = declaredSources.has(sourceName) ? sourceName : OTHER_SOURCES;
  let tally = tallies.get(key);
  if (!tally) {
    tally = { guarded: 0, dropped: 0 };
    tallies.set(key, tally);
  }
  tally.guarded += 1;
  if (dropped)
    tally.dropped += 1;
}
function recordStaleWrite(sourceName, subject, captured, observed) {
  incrementDegradationCount({
    kind: "generation-guard-stale-write",
    subject: `${sourceName}:${subject}`,
    reason: `write dropped: captured generation ${captured}, current ${observed}`
  });
}
function makeHandle(sourceName, generation, read, tallyName) {
  return {
    generation,
    isCurrent() {
      return read() === generation;
    },
    guardedWrite(subject, write) {
      const observed = read();
      if (observed !== generation) {
        tallyFence(tallyName, true);
        recordStaleWrite(sourceName, subject, generation, observed);
        return void 0;
      }
      tallyFence(tallyName, false);
      return write();
    }
  };
}
function createGenerationSource(name, store) {
  declare(name);
  const local = { generation: 0 };
  const cell = store ?? (() => local);
  const read = () => cell().generation;
  return {
    name,
    current: read,
    bump() {
      const held = cell();
      held.generation += 1;
      return held.generation;
    },
    capture() {
      return makeHandle(name, read(), read, name);
    }
  };
}
var DEFAULT_MAX_KEYS = 512;
function createGenerationMap(name, options = {}) {
  declare(name);
  const normalize = options.normalizeKey ?? ((key) => key);
  const maxKeys = Math.max(1, options.maxKeys ?? DEFAULT_MAX_KEYS);
  const stamps = new BoundedFifoMap(maxKeys);
  let nextTicket = 0;
  let invalidations = 0;
  const read = (key) => stamps.get(key) ?? 0;
  function issue(key) {
    nextTicket += 1;
    stamps.delete(key);
    const evicted = stamps.set(key, nextTicket);
    invalidations += evicted.length;
    return nextTicket;
  }
  return {
    name,
    current(key) {
      return read(normalize(key));
    },
    bump(key) {
      invalidations += 1;
      return issue(normalize(key));
    },
    capture(key) {
      const normalized = normalize(key);
      const stamp = read(normalized) || issue(normalized);
      const capturedInvalidations = invalidations;
      return makeHandle(`${name}[${normalized}]`, stamp, () => {
        if (invalidations === capturedInvalidations)
          return stamp;
        return read(normalize(key));
      }, name);
    },
    forget(key) {
      invalidations += 1;
      stamps.delete(normalize(key));
    },
    clear() {
      invalidations += 1;
      stamps.clear();
    },
    size() {
      return stamps.size;
    }
  };
}

// dist/clients/instance-registry-lock.js
import * as fs5 from "node:fs";
import { randomInt as randomInt2 } from "node:crypto";
import * as path8 from "node:path";
var OWN_HOLDS_FAMILY = "instance-registry.lock-own-holds";
var OWN_HOLDS_VERSION = 1;
function ownAsyncHolds() {
  return getProcessSingleton(OWN_HOLDS_FAMILY, OWN_HOLDS_VERSION, () => ({
    count: 0
  }));
}
var LOCK_STALE_MS = 5e3;
var LOCK_WAIT_MS = 500;
var LOCK_MIN_BACKOFF_MS = 5;
var LOCK_MAX_BACKOFF_MS = 25;
function generationDir2(target) {
  return `${target}.locks`;
}
function legacyLockPath(target) {
  return `${target}.lock`;
}
function createLegacyLock(lock) {
  try {
    fs5.writeFileSync(lock, `${process.pid} ${Date.now()}
`, { flag: "wx" });
    return true;
  } catch (error) {
    if (isLockContention(error))
      return false;
    throw error;
  }
}
function takeLegacyLock(lock) {
  if (createLegacyLock(lock))
    return true;
  if (!pidFileIsStale(lock, LOCK_STALE_MS))
    return false;
  try {
    fs5.unlinkSync(lock);
  } catch {
  }
  return createLegacyLock(lock);
}
function releaseLegacyLock(lock) {
  if (pidFileOwner(lock) !== process.pid)
    return;
  try {
    fs5.unlinkSync(lock);
  } catch {
  }
}
function tryAcquire(target) {
  let hold;
  try {
    hold = tryAcquireGeneration(generationDir2(target), LOCK_STALE_MS);
    if (!hold)
      return "busy";
    if (hold.tookOverStale)
      recordStaleTakeover(target, hold);
    if (takeLegacyLock(legacyLockPath(target)))
      return hold;
    recordLegacyHeld(target);
    releaseGeneration(hold);
    return "busy";
  } catch (cause) {
    recordLockFailure(target, cause);
    if (hold)
      releaseGeneration(hold);
    return "failed";
  }
}
function release(target, hold) {
  releaseLegacyLock(legacyLockPath(target));
  releaseGeneration(hold);
}
function recordLockFailure(target, cause) {
  const code = cause?.code ?? "unknown";
  incrementDegradationCount({
    kind: "instance-registry-lock-failed",
    subject: path8.resolve(target),
    reason: `lock acquisition failed for ${path8.basename(target)} (${code}); the registry write was skipped`
  });
}
function recordStaleTakeover(target, hold) {
  incrementDegradationCount({
    kind: "instance-registry-lock-stale-takeover",
    subject: path8.resolve(target),
    reason: `took over lock generation ${hold.generation - 1} from a dead or aged-out holder`
  });
}
function recordLegacyHeld(target) {
  const lock = legacyLockPath(target);
  incrementDegradationCount({
    kind: "instance-registry-lock-legacy-held",
    subject: path8.resolve(lock),
    reason: `backed off: ${path8.basename(lock)} is held by pid ${pidFileOwner(lock) ?? "unknown"}, a writer from before #3476`
  });
}
function recordLockTimeout(target) {
  incrementDegradationCount({
    kind: "instance-registry-lock-timeout",
    subject: path8.resolve(target),
    reason: `lock acquisition exhausted for ${path8.basename(target)}`
  });
}
function backoffMs() {
  return randomInt2(LOCK_MIN_BACKOFF_MS, LOCK_MAX_BACKOFF_MS + 1);
}
var LOCK_WAIT_THROUGH_LEASE_MS = LOCK_STALE_MS + LOCK_WAIT_MS;
async function withInstanceRegistryLock(target, op, waitMs = LOCK_WAIT_MS) {
  const deadline = Date.now() + waitMs;
  while (Date.now() <= deadline) {
    const hold = tryAcquire(target);
    if (hold === "failed")
      return void 0;
    if (hold === "busy") {
      if (Date.now() <= deadline)
        await new Promise((resolve6) => setTimeout(resolve6, backoffMs()));
      continue;
    }
    const holds = ownAsyncHolds();
    holds.count += 1;
    try {
      return await op();
    } finally {
      holds.count -= 1;
      release(target, hold);
    }
  }
  recordLockTimeout(target);
  return void 0;
}

// dist/scripts/lib/process-scan.mjs
import fs6 from "node:fs";
import path9 from "node:path";
function runningOnWindows() {
  return process.platform === "win32";
}
var FIELD_COLUMNS = Object.freeze({
  pid: { wmi: "ProcessId", ps: "pid", token: "int" },
  ppid: { wmi: "ParentProcessId", ps: "ppid", token: "int" },
  ageMs: { wmi: "CreationDate", ps: "etime", token: "age" },
  rssBytes: { wmi: "WorkingSetSize", ps: null, token: "int" },
  cpuKernel100ns: { wmi: "KernelModeTime", ps: null, token: "int" },
  cpuUser100ns: { wmi: "UserModeTime", ps: null, token: "int" },
  startedAt: { wmi: "CreationDate", ps: "lstart", token: "lstart" },
  command: { wmi: "CommandLine", ps: "args", token: "tail" }
});
var FIELD_ORDER = Object.freeze(Object.keys(FIELD_COLUMNS));
var ALL_PROCESS_FIELDS = Object.freeze(["pid", "ppid", "command"]);
var FILTERABLE_COLUMNS = /* @__PURE__ */ new Set(["ProcessId", "Name", "CommandLine"]);
function windowsExe(name) {
  return path9.join(process.env.SystemRoot ?? path9.join("C:", "Windows"), "System32", name);
}
function posixPsPath() {
  try {
    if (fs6.existsSync("/bin/ps"))
      return "/bin/ps";
    if (fs6.existsSync("/usr/bin/ps"))
      return "/usr/bin/ps";
  } catch {
  }
  return "/bin/ps";
}
function normalizeProcessFields(fields) {
  const requested = new Set((fields ?? ALL_PROCESS_FIELDS).filter((field) => field in FIELD_COLUMNS));
  requested.add("pid");
  return FIELD_ORDER.filter((field) => requested.has(field));
}
function escapeWqlLikeValue(value) {
  return String(value).replaceAll("'", "''").replaceAll(/[%_]/g, (ch) => `[${ch}]`);
}
function escapeWqlStringValue(value) {
  return String(value).replaceAll("'", "''");
}
function assertPid(value) {
  const pid = Number(value);
  if (!Number.isInteger(pid) || pid <= 0) {
    throw new Error(`process filter: invalid pid ${String(value)}`);
  }
  return pid;
}
function wqlFilterExpression(filter) {
  const { column, op, values } = filter;
  if (!FILTERABLE_COLUMNS.has(column)) {
    throw new Error(`process filter: unsupported column ${String(column)}`);
  }
  const list = [...values];
  if (list.length === 0) {
    throw new Error(`process filter: ${column} filter has no values`);
  }
  if (column === "ProcessId") {
    return list.map((value) => `ProcessId=${assertPid(value)}`).join(" OR ");
  }
  if (op === "like") {
    return list.map((value) => `${column} LIKE '%${escapeWqlLikeValue(value)}%'`).join(" OR ");
  }
  return list.map((value) => `${column} = '${escapeWqlStringValue(value)}'`).join(" OR ");
}
function buildProcessQuery(fields = ALL_PROCESS_FIELDS, options = {}) {
  const layout = normalizeProcessFields(fields);
  const filter = options.filter;
  if (runningOnWindows()) {
    const columns2 = [
      ...new Set(layout.map((field) => FIELD_COLUMNS[field].wmi))
    ];
    const where = filter ? ` WHERE ${wqlFilterExpression(filter)}` : "";
    const excludeSelf = options.excludeSelfPid ? " | Where-Object { $_.ProcessId -ne $PID }" : "";
    const prelude = (layout.includes("ageMs") ? "$age = if ($_.CreationDate -is [datetime]) { [int64]((Get-Date) - $_.CreationDate).TotalMilliseconds } else { '' }; " : "") + (layout.includes("startedAt") ? "$st = if ($_.CreationDate -is [datetime]) { $_.CreationDate.ToUniversalTime().ToString('o') } else { '' }; " : "");
    const row = layout.map((field) => {
      if (field === "ageMs")
        return "$age";
      if (field === "startedAt")
        return "$st";
      return `$($_.${FIELD_COLUMNS[field].wmi})`;
    }).join("`t");
    return {
      command: windowsExe("WindowsPowerShell\\v1.0\\powershell.exe"),
      args: [
        "-NoProfile",
        "-NonInteractive",
        "-Command",
        `Get-CimInstance -Query "SELECT ${columns2.join(",")} FROM Win32_Process${where}"${excludeSelf} | ForEach-Object { ${prelude}"${row}" }`
      ],
      tabSeparated: true,
      fields: layout,
      serverSideFiltered: Boolean(filter)
    };
  }
  const unsupported = layout.filter((field) => !FIELD_COLUMNS[field].ps);
  if (unsupported.length > 0) {
    throw new Error(`process query: ${unsupported.join(", ")} has no POSIX ps column`);
  }
  if (layout.includes("startedAt") && process.platform === "linux") {
    throw new Error("process query: startedAt on Linux is read from /proc, not ps");
  }
  const columns = layout.map((field) => `${FIELD_COLUMNS[field].ps}=`).join(",");
  const pidFilter = filter && filter.column === "ProcessId" && filter.op === "eq" ? [...filter.values].map((value) => assertPid(value)) : null;
  return {
    command: posixPsPath(),
    args: pidFilter ? ["-p", pidFilter.join(","), "-o", columns] : ["-eo", columns],
    tabSeparated: false,
    fields: layout,
    serverSideFiltered: Boolean(pidFilter),
    // BSD `ps` formats `lstart` with strftime("%c") in the local zone, so
    // two readers with different locales or zones would print one process
    // two ways. Pinned, every reader prints the same text.
    ...layout.includes("startedAt") ? { env: posixStartEnv() } : {}
  };
}
function posixStartEnv() {
  return { ...process.env, LC_ALL: "C", TZ: "UTC0" };
}
function readLinuxProcessStart(pid) {
  try {
    const ticks = parseLinuxStatStart(fs6.readFileSync(`/proc/${assertPid(pid)}/stat`, "utf8"));
    const boot = fs6.readFileSync("/proc/sys/kernel/random/boot_id", "utf8").trim();
    const offset = readBoottimeOffsetTicks();
    return ticks === void 0 || offset === void 0 || !/^[0-9a-f-]{36}$/.test(boot) ? void 0 : `${Number(ticks) - offset}@${boot}`;
  } catch {
    return void 0;
  }
}
var USER_HZ = 100;
var NSEC_PER_TICK = 1e9 / USER_HZ;
function readBoottimeOffsetTicks() {
  let text;
  try {
    text = fs6.readFileSync("/proc/self/timens_offsets", "utf8");
  } catch (error) {
    return (
      /** @type {NodeJS.ErrnoException} */
      error.code === "ENOENT" ? 0 : void 0
    );
  }
  const match = /^boottime\s+(-?\d+)\s+(\d+)\s*$/m.exec(String(text));
  if (!match)
    return void 0;
  const nsec = Number(match[2]);
  if (nsec % NSEC_PER_TICK !== 0)
    return void 0;
  return Number(match[1]) * USER_HZ + nsec / NSEC_PER_TICK;
}
function parseLinuxStatStart(stat) {
  const fields = String(stat).slice(stat.lastIndexOf(")") + 2).split(" ");
  const start = fields[19];
  return /^\d+$/.test(start ?? "") ? start : void 0;
}
function readLinuxPidNamespace(pid) {
  try {
    return fs6.readlinkSync(`/proc/${assertPid(pid)}/ns/pid`);
  } catch {
    return void 0;
  }
}
function parseNonNegativeInt(raw) {
  const token = String(raw ?? "").trim();
  if (!/^\d+$/.test(token))
    return void 0;
  const value = Number(token);
  return Number.isFinite(value) ? value : void 0;
}
function ageMsFromPosixEtime(raw) {
  const token = String(raw ?? "").trim();
  if (!/^(?:\d+-)?(?:\d+:)?\d+:\d+$/.test(token))
    return void 0;
  let days = 0;
  let rest = token;
  const dash = rest.indexOf("-");
  if (dash >= 0) {
    days = Number(rest.slice(0, dash));
    rest = rest.slice(dash + 1);
  }
  const parts = rest.split(":").map(Number);
  if (parts.some((part) => !Number.isFinite(part)))
    return void 0;
  const [hours, minutes, seconds] = parts.length === 3 ? parts : [0, parts[0], parts[1]];
  return ((days * 24 + hours) * 60 * 60 + minutes * 60 + seconds) * 1e3;
}
function posixTokenPattern(field) {
  const token = FIELD_COLUMNS[field].token;
  if (token === "age")
    return "(\\S+)";
  if (token === "lstart")
    return "(\\S+\\s+\\S+\\s+\\d+\\s+\\d+:\\d+:\\d+\\s+\\d+)";
  return "(\\d+)";
}
var LSTART_MONTHS = [
  "Jan",
  "Feb",
  "Mar",
  "Apr",
  "May",
  "Jun",
  "Jul",
  "Aug",
  "Sep",
  "Oct",
  "Nov",
  "Dec"
];
function isoFromLstart(raw) {
  const match = /^\w{3}\s+(\w{3})\s+(\d{1,2})\s+(\d{1,2}):(\d{2}):(\d{2})\s+(\d{4})$/.exec(String(raw ?? "").trim());
  if (!match)
    return void 0;
  const month = LSTART_MONTHS.indexOf(match[1]);
  if (month === -1)
    return void 0;
  const [day, hours, minutes, seconds, year] = [2, 3, 4, 5, 6].map((i) => Number(match[i]));
  return new Date(Date.UTC(year, month, day, hours, minutes, seconds)).toISOString();
}
function parseProcessTable(out, tabSeparated, fields = ALL_PROCESS_FIELDS) {
  const layout = normalizeProcessFields(fields);
  const commandIndex = layout.indexOf("command");
  const positional = tabSeparated ? null : new RegExp(`^\\s*${layout.filter((field) => field !== "command").map((field) => posixTokenPattern(field)).join("\\s+")}${commandIndex === -1 ? "\\s*$" : "\\s+(.*)$"}`);
  const rows = [];
  for (const line of String(out ?? "").split(/\r?\n/)) {
    if (!line.trim())
      continue;
    let parts;
    if (tabSeparated) {
      const split = line.split("	");
      if (split.length < layout.length - (commandIndex === -1 ? 0 : 1))
        continue;
      parts = commandIndex === -1 ? split : [
        ...split.slice(0, commandIndex),
        split.slice(commandIndex).join("	")
      ];
    } else {
      const match = positional?.exec(line);
      if (!match)
        continue;
      parts = match.slice(1);
    }
    const value = (field) => {
      const at = layout.indexOf(field);
      return at === -1 ? void 0 : parts[at];
    };
    const pid = Number(value("pid"));
    if (!Number.isInteger(pid) || pid <= 0)
      continue;
    const ppid = Number(value("ppid"));
    const row = {
      pid,
      ppid: Number.isInteger(ppid) && ppid > 0 ? ppid : 0,
      command: value("command") ?? ""
    };
    for (const field of layout) {
      if (field === "pid" || field === "ppid" || field === "command")
        continue;
      const raw = value(field);
      if (field === "ageMs") {
        row.ageMs = tabSeparated ? parseNonNegativeInt(raw) : ageMsFromPosixEtime(raw ?? "");
      } else if (field === "startedAt") {
        row.startedAt = tabSeparated ? String(raw ?? "").trim() : isoFromLstart(raw ?? "");
      } else {
        row[field] = parseNonNegativeInt(raw);
      }
    }
    rows.push(row);
  }
  return rows;
}

// dist/clients/process-snapshot.js
async function queryProcessTable(request, options) {
  let query;
  try {
    query = buildProcessQuery(request.fields, {
      filter: request.filter,
      excludeSelfPid: request.excludeSelfPid
    });
  } catch {
    return { rows: [], status: "spawn-error", serverSideFiltered: false };
  }
  const result = await spawnCollectStdoutResult(query.command, query.args, {
    shell: false,
    windowsHide: true,
    stdio: ["ignore", "pipe", "ignore"],
    env: query.env
  }, { timeoutMs: options.timeoutMs, onTimeout: options.onTimeout });
  return {
    // Whatever the collector kept is parsed rather than discarded here: it
    // drops stdout on a non-zero exit (that output is not evidence of what
    // is NOT running) but KEEPS the partial table from a timed-out child,
    // and the caller decides what a partial table is worth by reading
    // `status`. Re-deciding that here would be a second policy.
    rows: parseProcessTable(result.stdout, query.tabSeparated, query.fields),
    status: result.status,
    exitCode: result.exitCode,
    timeoutKill: result.timeoutKill,
    serverSideFiltered: query.serverSideFiltered
  };
}
function validPids(pids) {
  return [...new Set(pids.filter((p) => Number.isInteger(p) && p > 0))];
}
async function queryProcessIdentities(pids, options) {
  const valid = validPids(pids);
  const identities = /* @__PURE__ */ new Map();
  if (valid.length === 0)
    return { identities, status: "ok" };
  const linux = process.platform === "linux";
  const result = await queryProcessTable({
    fields: linux ? ["pid", "command"] : ["pid", "startedAt", "command"],
    filter: { column: "ProcessId", op: "eq", values: valid }
  }, options);
  for (const row of result.rows) {
    const start = linux ? readLinuxProcessStart(row.pid) : row.startedAt;
    identities.set(row.pid, {
      command: row.command,
      start: start ? start : void 0
    });
  }
  return { identities, status: result.status };
}
var OWNER_TAG_ENV = "PI_LENS_OWNER";
function formatOwnerTag(tag) {
  return `${tag.pid}:${tag.start}`;
}
async function ownerTagForChildren(options) {
  if (process.platform === "win32")
    return void 0;
  const start = await ownProcessStart(options);
  return start === void 0 ? void 0 : formatOwnerTag({ pid: process.pid, start });
}
function isInPidNamespace(entry, namespace) {
  return entry.pidNamespace === void 0 || entry.pidNamespace === namespace;
}
function ownPidNamespace() {
  return process.platform === "linux" ? readLinuxPidNamespace(process.pid) : void 0;
}
var ownStart = null;
function ownProcessStart(options) {
  if (process.platform === "linux")
    return Promise.resolve(readLinuxProcessStart(process.pid));
  if (ownStart)
    return ownStart.promise;
  const cell = {
    promise: readProcessStart(process.pid, options).then((start) => {
      if (start === void 0)
        ownStart = null;
      else
        cell.value = start;
      return start;
    })
  };
  ownStart = cell;
  return cell.promise;
}
async function readProcessStart(pid, options) {
  if (process.platform === "linux")
    return readLinuxProcessStart(pid);
  return (await queryProcessIdentities([pid], options)).identities.get(pid)?.start;
}

// dist/clients/instance-registry-tail.js
var REGISTRY_TAIL_FAMILY = "instance-registry.mutation-tail";
var REGISTRY_TAIL_VERSION = 1;
function registryTailState() {
  return getProcessSingleton(REGISTRY_TAIL_FAMILY, REGISTRY_TAIL_VERSION, () => ({
    tail: Promise.resolve()
  }));
}
function queueRegistryMutation(op) {
  const state = registryTailState();
  const run = state.tail.then(op);
  state.tail = run.catch(() => {
  });
  return run;
}

// dist/clients/subagent-mode.js
var cachedClassification;
function classifySubagentSession() {
  if (cachedClassification !== void 0)
    return cachedClassification;
  if (process.env.PI_SUBAGENT_CHILD === "1") {
    cachedClassification = { isSubagent: true, marker: "pi-subagents" };
    return cachedClassification;
  }
  const childAgent = process.env.PI_SUBAGENT_CHILD_AGENT || void 0;
  const parentPid = process.env.PI_SUBAGENT_PARENT_PID || void 0;
  if (childAgent !== void 0 && parentPid !== void 0) {
    cachedClassification = { isSubagent: true, marker: "avtc-pi-subagent" };
    return cachedClassification;
  }
  cachedClassification = { isSubagent: false };
  return cachedClassification;
}
function isSubagentSession() {
  if (process.env.PI_LENS_SUBAGENT_FULL === "1")
    return false;
  return classifySubagentSession().isSubagent;
}
function getSubagentIdentity() {
  const runId = process.env.PI_SUBAGENT_RUN_ID || void 0;
  const agentName = process.env.PI_SUBAGENT_CHILD_AGENT || void 0;
  const parentPidRaw = process.env.PI_SUBAGENT_PARENT_PID || void 0;
  const parsedParentPid = parentPidRaw === void 0 ? void 0 : Number(parentPidRaw);
  const parentPid = parsedParentPid !== void 0 && Number.isSafeInteger(parsedParentPid) && parsedParentPid > 0 ? parsedParentPid : void 0;
  const classification = classifySubagentSession();
  if (runId === void 0 && agentName === void 0 && parentPid === void 0 && !classification.isSubagent) {
    return void 0;
  }
  return { runId, agentName, marker: classification.marker, parentPid };
}
function subagentLightModeNotice() {
  return "subagent session \u2014 skipped background code-quality scans (set PI_LENS_SUBAGENT_FULL=1 to override)";
}

// dist/clients/instance-registry.js
function registryPath() {
  return path10.join(getGlobalPiLensDir(), "instances.json");
}
function startReadOptions() {
  return {
    timeoutMs: BACKSTOP_SCAN_TIMEOUT_MS,
    onTimeout: (child) => terminateScannerChild(child, {
      kind: "orphan-backstop-scanner-escalated",
      timeoutMs: BACKSTOP_SCAN_TIMEOUT_MS
    })
  };
}
function isOwnEntry(entry, selfStart) {
  return entry.pid === process.pid && (entry.processStart === void 0 || entry.processStart === selfStart);
}
var _enabledCache;
function isInstanceRegistryEnabled() {
  if (_enabledCache !== void 0)
    return _enabledCache;
  _enabledCache = process.env.PI_LENS_INSTANCE_REGISTRY !== "0";
  return _enabledCache;
}
function recordCorruptRegistryRead(reasonCode) {
  recordDegradationOnce({
    kind: "instance-registry-corrupt",
    subject: "instances.json",
    reason: `read failed (${reasonCode}); treating as empty`
  });
}
async function readRegistryAsync() {
  try {
    const raw = await fs7.promises.readFile(registryPath(), "utf-8");
    const parsed = JSON.parse(raw);
    if (parsed && Array.isArray(parsed.instances)) {
      return parsed;
    }
    recordCorruptRegistryRead("invalid shape");
    return { instances: [] };
  } catch (err) {
    const code = err?.code;
    if (code !== "ENOENT")
      recordCorruptRegistryRead(code ?? "invalid");
    return { instances: [] };
  }
}
async function readInstanceRegistry() {
  const file = await readRegistryAsync();
  return file.instances;
}
async function writeRegistryAsync(file) {
  const dir = getGlobalPiLensDir();
  const target = registryPath();
  try {
    await fs7.promises.mkdir(dir, { recursive: true });
  } catch {
    return;
  }
  await writeFileAtomicAsync(target, JSON.stringify(file));
}
var REGISTRY_WRITE_RETRIES = 3;
async function writeRegistryWithRetry(mutate, isCommitted) {
  await withInstanceRegistryLock(registryPath(), async () => {
    for (let attempt = 0; attempt < REGISTRY_WRITE_RETRIES; attempt++) {
      const next = mutate(await readRegistryAsync());
      if (next === void 0)
        return;
      await writeRegistryAsync(next);
      if (isCommitted(await readRegistryAsync()))
        return;
    }
  });
}
function getInstanceRoots(entry) {
  const listed = Array.isArray(entry.projectRoots) ? entry.projectRoots.filter((root) => typeof root === "string" && root.length > 0) : [];
  if (listed.length > 0)
    return listed;
  return typeof entry.projectRoot === "string" && entry.projectRoot.length > 0 ? [entry.projectRoot] : [];
}
var INSTANCE_ROOT_CAP = 32;
function mergeInstanceRoots(priorRoots, normalizedRoot) {
  const roots = priorRoots.includes(normalizedRoot) ? [...priorRoots] : [...priorRoots, normalizedRoot];
  while (roots.length > INSTANCE_ROOT_CAP)
    roots.splice(1, 1);
  return roots;
}
function registerInstance(projectRoot) {
  const generation = registrationGeneration().capture();
  return queueRegistryMutation(() => registerInstanceNow(projectRoot, generation));
}
async function registerInstanceNow(projectRoot, generation) {
  if (!isInstanceRegistryEnabled())
    return;
  const normalizedRoot = normalizeFilePath(projectRoot);
  if (!registrationIsCurrent(generation, normalizedRoot))
    return;
  rememberRegistrationRoot(projectRoot);
  const pid = process.pid;
  const now = (/* @__PURE__ */ new Date()).toISOString();
  const identity = isSubagentSession() ? getSubagentIdentity() : void 0;
  const selfStart = await ownProcessStart(startReadOptions());
  const subagent = identity ? {
    marker: identity.marker,
    agentType: identity.agentName,
    parentPid: identity.parentPid,
    runId: identity.runId
  } : void 0;
  await writeRegistryWithRetry((file) => {
    if (!registrationIsCurrent(generation, normalizedRoot))
      return void 0;
    const others = file.instances.filter((entry) => !isOwnEntry(entry, selfStart));
    const existing = file.instances.find((entry) => isOwnEntry(entry, selfStart));
    const existingRoots = existing ? getInstanceRoots(existing) : [];
    const roots = existing?.rootSource === "lsp-fallback" ? existingRoots.slice(1).reduce((acc, root) => mergeInstanceRoots(acc, root), [normalizedRoot]) : mergeInstanceRoots(existingRoots, normalizedRoot);
    const namespace = ownPidNamespace();
    others.push({
      pid,
      ...selfStart === void 0 ? {} : { processStart: selfStart },
      ...namespace === void 0 ? {} : { pidNamespace: namespace },
      startedAt: existing?.startedAt ?? now,
      projectRoot: roots[0] ?? normalizedRoot,
      projectRoots: roots,
      lspChildren: existing?.lspChildren ?? [],
      lspChildCount: existing?.lspChildren?.length ?? 0,
      rssBytes: process.memoryUsage().rss,
      heartbeatAt: now,
      ...subagent ? { subagent } : {}
    });
    return { instances: others };
  }, (file) => file.instances.some((entry) => isOwnEntry(entry, selfStart)));
}
async function updateHeartbeat(patch = {}) {
  return queueRegistryMutation(() => updateHeartbeatNow(patch));
}
async function updateHeartbeatNow(patch) {
  if (!isInstanceRegistryEnabled())
    return;
  const pid = process.pid;
  const selfStart = await ownProcessStart(startReadOptions());
  let missing = false;
  await withInstanceRegistryLock(registryPath(), async () => {
    const file = await readRegistryAsync();
    const idx = file.instances.findIndex((entry) => isOwnEntry(entry, selfStart));
    if (idx === -1) {
      missing = true;
      return;
    }
    const now = (/* @__PURE__ */ new Date()).toISOString();
    const current = file.instances[idx];
    const lspChildren = patch.childUsage ? current.lspChildren.map((child) => {
      const usage = patch.childUsage?.[child.pid];
      if (!usage)
        return child;
      return {
        ...child,
        rssBytes: usage.rssBytes ?? child.rssBytes,
        cpuPercent: usage.cpuPercent ?? child.cpuPercent
      };
    }) : current.lspChildren;
    file.instances[idx] = {
      ...current,
      rssBytes: patch.rssBytes ?? process.memoryUsage().rss,
      cpuPercent: patch.cpuPercent ?? current.cpuPercent,
      lspChildren,
      lspChildCount: lspChildren.length,
      heartbeatAt: now
    };
    await writeRegistryAsync(file);
  });
  const intent = registrationIntent();
  if (missing && intent.root !== void 0 && intent.target === registryPath()) {
    incrementDegradationCount({
      kind: "instance-registry-registration-missing",
      subject: String(pid),
      reason: "entry missing at heartbeat; re-registering from the session root"
    });
    void registerInstance(intent.root);
  }
}
var REGISTRATION_INTENT_FAMILY = "instance-registry.registration-intent";
var REGISTRATION_INTENT_VERSION = 1;
function registrationIntent() {
  return getProcessSingleton(REGISTRATION_INTENT_FAMILY, REGISTRATION_INTENT_VERSION, () => ({ root: void 0, target: void 0 }));
}
var REGISTRATION_GENERATION_FAMILY = "instance-registry.registration-generation";
var REGISTRATION_GENERATION_VERSION = 1;
function registrationGeneration() {
  return getProcessSingleton(REGISTRATION_GENERATION_FAMILY, REGISTRATION_GENERATION_VERSION, () => createGenerationSource("instance-registry-registration"));
}
function registrationIsCurrent(generation, normalizedRoot) {
  if (generation.isCurrent())
    return true;
  incrementDegradationCount({
    kind: "instance-registry-registration-superseded",
    subject: normalizedRoot,
    reason: "the session ended before this registration landed; dropped"
  });
  return false;
}
function rememberRegistrationRoot(root) {
  const intent = registrationIntent();
  intent.root = root;
  intent.target = root === void 0 ? void 0 : registryPath();
}
function recordLspChild(entry) {
  const generation = registrationGeneration().capture();
  return queueRegistryMutation(() => recordLspChildNow(entry, generation));
}
async function recordLspChildNow(entry, generation) {
  if (!isInstanceRegistryEnabled())
    return;
  const pid = process.pid;
  const now = (/* @__PURE__ */ new Date()).toISOString();
  const [selfStart, childStart] = await Promise.all([
    ownProcessStart(startReadOptions()),
    readProcessStart(entry.pid, startReadOptions())
  ]);
  const childEntry = {
    pid: entry.pid,
    serverId: entry.serverId,
    command: entry.command,
    marker: entry.marker,
    spawnedAt: now,
    ...childStart === void 0 ? {} : { processStart: childStart }
  };
  const hostIdentity = getSubagentIdentity();
  await writeRegistryWithRetry((file) => {
    const idx = file.instances.findIndex((inst) => isOwnEntry(inst, selfStart));
    if (idx === -1) {
      const guessedRoot = normalizeFilePath(entry.sessionIdentity?.projectRoot ?? process.cwd());
      if (!registrationIsCurrent(generation, guessedRoot))
        return void 0;
      recordDegradationOnce({
        kind: "instance-registry-registration-missing",
        subject: String(pid),
        reason: "synthesizing host entry while recording an LSP child"
      });
      const identity = entry.sessionIdentity;
      if (!identity?.projectRoot) {
        recordDegradationOnce({
          kind: "instance-registry-identity-fallback",
          subject: String(pid),
          reason: "session cwd unavailable; using process cwd"
        });
      }
      const projectRoot = normalizeFilePath(identity?.projectRoot ?? process.cwd());
      const namespace = ownPidNamespace();
      file.instances.push({
        pid,
        ...selfStart === void 0 ? {} : { processStart: selfStart },
        ...namespace === void 0 ? {} : { pidNamespace: namespace },
        startedAt: identity?.startedAt ?? now,
        projectRoot,
        rootSource: identity?.rootSource ?? "lsp-fallback",
        projectRoots: [projectRoot],
        lspChildren: [childEntry],
        lspChildCount: 1,
        rssBytes: process.memoryUsage().rss,
        heartbeatAt: now,
        ...hostIdentity ? {
          subagent: {
            marker: hostIdentity.marker,
            agentType: hostIdentity.agentName,
            parentPid: hostIdentity.parentPid,
            runId: hostIdentity.runId
          }
        } : {}
      });
    } else {
      const current = file.instances[idx];
      const filtered = current.lspChildren.filter((child) => child.pid !== entry.pid);
      filtered.push(childEntry);
      file.instances[idx] = {
        ...current,
        lspChildren: filtered,
        lspChildCount: filtered.length
      };
    }
    return file;
  }, (file) => file.instances.some((instance) => isOwnEntry(instance, selfStart) && instance.lspChildren.some((child) => child.pid === entry.pid)));
}
function removeLspChild(pid, expectedMarker) {
  return queueRegistryMutation(() => removeLspChildNow(pid, expectedMarker));
}
async function removeLspChildNow(pid, expectedMarker) {
  if (!isInstanceRegistryEnabled())
    return;
  const selfStart = await ownProcessStart(startReadOptions());
  await withInstanceRegistryLock(registryPath(), async () => {
    const file = await readRegistryAsync();
    const idx = file.instances.findIndex((inst) => isOwnEntry(inst, selfStart));
    if (idx === -1)
      return;
    const current = file.instances[idx];
    const filtered = current.lspChildren.filter((child) => {
      if (child.pid !== pid)
        return true;
      if (expectedMarker && child.marker && child.marker !== expectedMarker) {
        return true;
      }
      return false;
    });
    if (filtered.length === current.lspChildren.length)
      return;
    file.instances[idx] = {
      ...current,
      lspChildren: filtered,
      lspChildCount: filtered.length
    };
    await writeRegistryAsync(file);
  });
}
function rootsOverlap(a, b) {
  if (a === b)
    return true;
  const [shorter, longer] = a.length < b.length ? [a, b] : [b, a];
  return longer.startsWith(shorter.endsWith("/") ? shorter : `${shorter}/`);
}
function selectLivePeerInstances(entries, root, now = Date.now(), isPidAlive2 = realIsPidAlive, match = "exact") {
  const normalizedRoot = normalizeFilePath(root);
  return entries.filter((entry) => entry.pid !== process.pid && // #2130: a host serves a SET of roots. Matching only
  // `entry.projectRoot` made every secondary root invisible, so a peer
  // working in the same checkout under its second root read as "no
  // peer" — and the shared-checkout guard then allowed the destructive
  // command it exists to block.
  getInstanceRoots(entry).some((entryRoot) => match === "exact" ? entryRoot === normalizedRoot : rootsOverlap(entryRoot, normalizedRoot)) && isPidAlive2(entry.pid) && Number.isFinite(Date.parse(entry.heartbeatAt)) && now - Date.parse(entry.heartbeatAt) <= STALE_HEARTBEAT_MS).sort((a, b) => Date.parse(a.startedAt) - Date.parse(b.startedAt));
}
function computeResourceFootprint(instances, isPidAlive2) {
  const liveInstances = isPidAlive2 ? instances.filter((instance) => isPidAlive2(instance.pid)) : instances;
  const perInstance = liveInstances.map((instance) => {
    const lspChildRssBytes = instance.lspChildren.reduce((sum, child) => sum + (child.rssBytes ?? 0), 0);
    const lspChildCpuPercent = instance.lspChildren.reduce((sum, child) => sum + (child.cpuPercent ?? 0), 0);
    const roots = getInstanceRoots(instance);
    return {
      pid: instance.pid,
      projectRoot: roots[0] ?? instance.projectRoot,
      projectRoots: roots,
      rssBytes: instance.rssBytes ?? 0,
      cpuPercent: instance.cpuPercent ?? 0,
      lspChildCount: instance.lspChildren.length,
      lspChildRssBytes,
      lspChildCpuPercent
    };
  });
  let totalRssBytes = 0;
  let totalCpuPercent = 0;
  let totalLspChildCount = 0;
  for (const inst of perInstance) {
    totalRssBytes += inst.rssBytes + inst.lspChildRssBytes;
    totalCpuPercent += inst.cpuPercent + inst.lspChildCpuPercent;
    totalLspChildCount += inst.lspChildCount;
  }
  return {
    instanceCount: perInstance.length,
    totalRssBytes,
    totalCpuPercent,
    totalLspChildCount,
    perInstance
  };
}
async function getResourceFootprint(isPidAlive2 = realIsPidAlive) {
  const instances = await readInstanceRegistry();
  const namespace = ownPidNamespace();
  const dead = instances.filter((instance) => !isPidAlive2(instance.pid) && instance.lspChildren.length === 0 && isInPidNamespace(instance, namespace)).map((instance) => ({
    pid: instance.pid,
    processStart: instance.processStart,
    pidNamespace: instance.pidNamespace
  }));
  if (dead.length > 0) {
    queueRegistryMutation(() => prunePids(dead)).catch(() => {
    });
  }
  return computeResourceFootprint(instances, isPidAlive2);
}
async function pruneDeadInstances(dead) {
  const result = await withInstanceRegistryLock(registryPath(), async () => {
    const file = await readRegistryAsync();
    const key = (identity) => `${identity.pid}:${identity.processStart ?? ""}:${identity.pidNamespace ?? ""}`;
    const targets = new Set(dead.map(key));
    const remaining = file.instances.filter((entry) => !targets.has(key(entry)));
    if (remaining.length === file.instances.length)
      return "no-match";
    await writeRegistryAsync({ instances: remaining });
    return "pruned";
  });
  return result ?? "could-not-acquire";
}
async function prunePids(dead) {
  await pruneDeadInstances(dead);
}

// dist/clients/instance-reaper.js
var STALE_HEARTBEAT_MS = 6 * 60 * 60 * 1e3;
var isWindows = process.platform === "win32";
function realIsPidAlive(pid) {
  if (!Number.isFinite(pid) || pid <= 0)
    return false;
  try {
    process.kill(pid, 0);
    return true;
  } catch (err) {
    const code = err?.code;
    if (code === "ESRCH")
      return false;
    return true;
  }
}
var STAGE_PID_PATTERN = /\.stage-(\d+)-/;
function isStaleStageFile(entry, artifactPrefix) {
  if (!entry.startsWith(artifactPrefix))
    return false;
  const match = STAGE_PID_PATTERN.exec(entry);
  if (!match)
    return false;
  return !realIsPidAlive(Number(match[1]));
}
var ATOMIC_STAGE_SWEEP_MAX_ENTRIES = 512;
async function sweepAtomicWriteStages(directories, options = {}) {
  const requestedMax = options.maxEntries ?? ATOMIC_STAGE_SWEEP_MAX_ENTRIES;
  const maxEntries = Number.isFinite(requestedMax) ? Math.max(1, Math.floor(requestedMax)) : ATOMIC_STAGE_SWEEP_MAX_ENTRIES;
  const isPidAlive2 = options.isPidAlive ?? realIsPidAlive;
  return sweepOwnStagingFiles(directories, { maxEntries, isPidAlive: isPidAlive2 });
}
var KILL_VERIFY_ATTEMPTS = 5;
var KILL_VERIFY_INTERVAL_MS = 100;
function sleepUnref(ms) {
  return new Promise((resolve6) => {
    const timer = setTimeout(resolve6, ms);
    timer.unref();
  });
}
async function killPidTree(pid, options = {}) {
  if (!Number.isFinite(pid) || pid <= 0)
    return "invalid";
  if (options.confirmIdentity && !await options.confirmIdentity())
    return "changed";
  if (isWindows) {
    try {
      const taskkill = windowsExe("taskkill.exe");
      const killer = nodeSpawn2(taskkill, ["/F", "/T", "/PID", String(pid)], {
        shell: false,
        windowsHide: true,
        stdio: "ignore"
      });
      unrefChildAndPipes(killer);
      await new Promise((resolve6) => {
        killer.once("close", () => resolve6());
        killer.once("error", () => resolve6());
      });
    } catch {
    }
  } else {
    try {
      process.kill(-pid, "SIGKILL");
    } catch {
      try {
        process.kill(pid, "SIGKILL");
      } catch {
      }
    }
  }
  return await verifyPidGone(pid, options);
}
async function verifyPidGone(pid, options = {}) {
  const isPidAlive2 = options.isPidAlive ?? realIsPidAlive;
  const attempts = Math.max(1, options.verifyAttempts ?? KILL_VERIFY_ATTEMPTS);
  const intervalMs = Math.max(0, options.verifyIntervalMs ?? KILL_VERIFY_INTERVAL_MS);
  for (let attempt = 0; attempt < attempts; attempt++) {
    let alive;
    try {
      alive = isPidAlive2(pid);
    } catch {
      alive = true;
    }
    if (!alive)
      return "gone";
    if (attempt < attempts - 1)
      await sleepUnref(intervalMs);
  }
  return "alive";
}
var MANAGED_BINARIES = [
  { name: "ast-grep", launcher: "native" },
  { name: "opengrep-core", launcher: "native" },
  { name: "opengrep", launcher: "native" },
  { name: "marksman", launcher: "native" },
  { name: "zizmor", launcher: "native" },
  { name: "typos-lsp", launcher: "native" },
  { name: "yaml-language-server", launcher: "node" },
  { name: "typescript-language-server", launcher: "node" }
];
var MANAGED_BINARY_NAMES = MANAGED_BINARIES.map((binary) => binary.name);
var MANAGED_IMAGE_NAMES = [
  ...new Set(MANAGED_BINARIES.map((binary) => binary.launcher === "node" ? "node.exe" : `${binary.name}.exe`))
];
async function terminateScannerChild(child, options) {
  const pid = child.pid;
  const outcome = typeof pid === "number" && pid > 0 ? await killPidTree(pid, {
    verifyAttempts: options.verifyAttempts,
    verifyIntervalMs: options.verifyIntervalMs
  }) : "invalid";
  incrementDegradationCount({
    kind: options.kind,
    subject: `${isWindows ? "win32-cim" : "posix-ps"}#${pid ?? "no-pid"}`,
    reason: `scan exceeded its ${options.timeoutMs}ms timeout; tree kill reported ${outcome}`
  });
  return outcome;
}
var BACKSTOP_SCAN_TIMEOUT_MS = 5e3;
var BACKSTOP_COOLDOWN_MS = 30 * 60 * 1e3;

// dist/clients/resource-sampler.js
var RESOURCE_SAMPLE_QUERY_TIMEOUT_MS = 2e3;
var SPAWN_SAMPLER_LEDGER_SUBJECT = "spawn-usage-sampler";
function recordQueryFailure(subject, status, exitCode) {
  const exitReason = status === "exit-error" ? ` (exit code ${exitCode ?? "unknown"})` : "";
  recordDegradationOnce({
    kind: "resource-sampler-query-failed",
    subject,
    reason: `process-table query ${status}${exitReason}`
  });
}
function runningOnWindows2() {
  return process.platform === "win32";
}
function walkDescendantPids(rootPid, pairs) {
  const childrenByParent = /* @__PURE__ */ new Map();
  for (const [pid, ppid] of pairs) {
    const list = childrenByParent.get(ppid);
    if (list)
      list.push(pid);
    else
      childrenByParent.set(ppid, [pid]);
  }
  const descendants = [];
  const queue = [rootPid];
  const visited = /* @__PURE__ */ new Set([rootPid]);
  while (queue.length > 0) {
    const current = queue.shift();
    for (const child of childrenByParent.get(current) ?? []) {
      if (visited.has(child))
        continue;
      visited.add(child);
      descendants.push(child);
      queue.push(child);
    }
  }
  return descendants;
}
async function findDescendantPidsWindows(rootPid) {
  if (!runningOnWindows2() || !Number.isFinite(rootPid) || rootPid <= 0)
    return [];
  const result = await queryProcessTable({ fields: ["pid", "ppid"] }, {
    timeoutMs: RESOURCE_SAMPLE_QUERY_TIMEOUT_MS,
    onTimeout: (child) => terminateScannerChild(child, {
      kind: "resource-sampler-scanner-escalated",
      timeoutMs: RESOURCE_SAMPLE_QUERY_TIMEOUT_MS
    })
  });
  if (result.status !== "ok") {
    recordQueryFailure("windows-descendant-process-table", result.status, result.exitCode);
    return null;
  }
  return walkDescendantPids(rootPid, result.rows.map((row) => [row.pid, row.ppid]));
}
var windowsCpuHistory = /* @__PURE__ */ new Map();
var CPU_HISTORY_MAX_AGE_MS = 6e4;
var CPU_HISTORY_MAX_ENTRIES = 4096;
async function sampleProcessesWindows(valid) {
  const samples = /* @__PURE__ */ new Map();
  if (valid.length === 0)
    return samples;
  const query = await queryProcessTable({
    fields: [
      "pid",
      "rssBytes",
      "cpuKernel100ns",
      "cpuUser100ns",
      "startedAt"
    ],
    filter: { column: "ProcessId", op: "eq", values: valid }
  }, {
    timeoutMs: RESOURCE_SAMPLE_QUERY_TIMEOUT_MS,
    onTimeout: (child) => terminateScannerChild(child, {
      kind: "resource-sampler-scanner-escalated",
      timeoutMs: RESOURCE_SAMPLE_QUERY_TIMEOUT_MS
    })
  });
  if (query.status !== "ok") {
    recordQueryFailure("windows-process-table", query.status, query.exitCode);
    return null;
  }
  try {
    const now = Date.now();
    const seen = /* @__PURE__ */ new Set();
    for (const row of query.rows) {
      const pid = row.pid;
      const workingSet = row.rssBytes;
      const kernel100ns = row.cpuKernel100ns;
      const user100ns = row.cpuUser100ns;
      const processIdentity = row.startedAt ?? "";
      if (workingSet === void 0 || kernel100ns === void 0 || user100ns === void 0 || processIdentity.length === 0)
        continue;
      const cpuMs = Math.round(kernel100ns / 1e4) + Math.round(user100ns / 1e4);
      const historyKey = `${pid}:${processIdentity}`;
      for (const [key, prior] of windowsCpuHistory) {
        if (prior.processIdentity !== processIdentity && key.startsWith(`${pid}:`)) {
          windowsCpuHistory.delete(key);
        }
      }
      const prev = windowsCpuHistory.get(historyKey);
      if (prev && cpuMs < prev.cpuMs) {
        windowsCpuHistory.delete(historyKey);
        continue;
      }
      let cpuPercent = 0;
      if (prev) {
        const wallMs = now - prev.ts;
        if (wallMs > 0) {
          cpuPercent = (cpuMs - prev.cpuMs) / wallMs * 100;
          if (!Number.isFinite(cpuPercent) || cpuPercent < 0)
            cpuPercent = 0;
        }
      }
      windowsCpuHistory.set(historyKey, { processIdentity, cpuMs, ts: now });
      seen.add(pid);
      samples.set(pid, { rssBytes: workingSet, cpuPercent });
    }
    for (const [key, entry] of windowsCpuHistory) {
      const pid = Number(key.slice(0, key.indexOf(":")));
      if (!seen.has(pid) && now - entry.ts > CPU_HISTORY_MAX_AGE_MS) {
        windowsCpuHistory.delete(key);
      }
    }
    while (windowsCpuHistory.size > CPU_HISTORY_MAX_ENTRIES) {
      let oldestKey;
      let oldestTs = Number.POSITIVE_INFINITY;
      for (const [key, entry] of windowsCpuHistory) {
        if (entry.ts < oldestTs) {
          oldestKey = key;
          oldestTs = entry.ts;
        }
      }
      if (oldestKey === void 0)
        break;
      windowsCpuHistory.delete(oldestKey);
    }
  } catch {
  }
  return samples;
}
async function sampleProcesses(pids) {
  const result = /* @__PURE__ */ new Map();
  const valid = [...new Set(pids.filter((p) => Number.isFinite(p) && p > 0))];
  if (valid.length === 0)
    return result;
  if (runningOnWindows2()) {
    return await sampleProcessesWindows(valid);
  }
  try {
    const stats = await (0, import_pidusage.default)(valid);
    for (const pid of valid) {
      const stat = stats[String(pid)];
      if (!stat)
        continue;
      if (!Number.isFinite(stat.cpu) || stat.cpu < 0 || !Number.isFinite(stat.memory) || stat.memory < 0)
        continue;
      result.set(pid, {
        rssBytes: stat.memory,
        cpuPercent: stat.cpu
      });
    }
  } catch {
    recordQueryFailure("posix-pidusage-process-table", "spawn-error");
    return null;
  }
  return result;
}
var UsageAccumulator = class {
  sampleCount = 0;
  cpuSum = 0;
  rssSum = 0;
  cpuPeak = 0;
  rssPeak = 0;
  addSample(usage) {
    this.sampleCount++;
    this.cpuSum += usage.cpuPercent;
    this.rssSum += usage.rssBytes;
    if (usage.cpuPercent > this.cpuPeak)
      this.cpuPeak = usage.cpuPercent;
    if (usage.rssBytes > this.rssPeak)
      this.rssPeak = usage.rssBytes;
  }
  get count() {
    return this.sampleCount;
  }
  summarize() {
    if (this.sampleCount === 0)
      return null;
    return {
      sampleCount: this.sampleCount,
      avgCpuPercent: this.cpuSum / this.sampleCount,
      peakCpuPercent: this.cpuPeak,
      avgRssBytes: this.rssSum / this.sampleCount,
      peakRssBytes: this.rssPeak
    };
  }
};
async function sampleProcessTreeCpuPercent(pid, windowMs = 1200, floorPercent = 10) {
  if (!Number.isFinite(pid) || pid <= 0) {
    return { busy: false, measured: false, cpuPercent: null };
  }
  const targetPid = pid;
  const readOnce = async () => {
    try {
      const descendants = runningOnWindows2() ? await findDescendantPidsWindows(targetPid) : [];
      if (descendants === null)
        return null;
      const pids = runningOnWindows2() ? [targetPid, ...descendants] : [targetPid];
      const usageByPid = await sampleProcesses(pids);
      if (usageByPid === null)
        return null;
      const targetUsage = usageByPid.get(targetPid);
      if (!targetUsage)
        return { cpuPercent: 0, measured: false };
      let cpuPercent = 0;
      for (const usage of usageByPid.values())
        cpuPercent += usage.cpuPercent;
      return { cpuPercent, measured: true };
    } catch {
      return null;
    }
  };
  const first = await readOnce();
  const second = await new Promise((resolve6) => {
    const timer = setTimeout(() => {
      void readOnce().then(resolve6);
    }, windowMs);
    timer.unref?.();
  });
  if (first === null && second === null) {
    return { busy: false, measured: false, cpuPercent: null };
  }
  if (first === null || second === null || !first.measured || !second.measured) {
    return { busy: false, measured: false, cpuPercent: null };
  }
  const observed = second.cpuPercent;
  return {
    busy: observed > floorPercent,
    measured: true,
    cpuPercent: observed
  };
}
var SPAWN_SAMPLE_INTERVAL_MS = 750;
var SPAWN_SAMPLE_FULL_RATE_TICKS = 8;
var SPAWN_SAMPLE_MAX_INTERVAL_MULTIPLIER = 16;
function startSpawnUsageSampler(pid, intervalMs = SPAWN_SAMPLE_INTERVAL_MS, lifetimeCapMs) {
  if (!Number.isFinite(pid) || pid <= 0) {
    return { stop: () => null };
  }
  const targetPid = pid;
  const accumulator = new UsageAccumulator();
  const startedAt = Date.now();
  let stopped = false;
  let inFlight = false;
  let tickCount = 0;
  let timer;
  const tick = async () => {
    if (stopped)
      return;
    try {
      const descendants = runningOnWindows2() ? await findDescendantPidsWindows(targetPid) : [];
      if (descendants === null)
        return;
      const pids = runningOnWindows2() ? [targetPid, ...descendants] : [targetPid];
      const usageByPid = await sampleProcesses(pids);
      if (usageByPid === null)
        return;
      if (stopped || usageByPid.size === 0)
        return;
      let rssBytes = 0;
      let cpuPercent = 0;
      for (const usage of usageByPid.values()) {
        rssBytes += usage.rssBytes;
        cpuPercent += usage.cpuPercent;
      }
      accumulator.addSample({ rssBytes, cpuPercent });
    } catch {
    }
  };
  const releaseInFlight = () => {
    inFlight = false;
  };
  const nextDelayMs = () => {
    if (tickCount <= SPAWN_SAMPLE_FULL_RATE_TICKS)
      return intervalMs;
    const grown = intervalMs * 2 ** (tickCount - SPAWN_SAMPLE_FULL_RATE_TICKS);
    return Math.min(grown, intervalMs * SPAWN_SAMPLE_MAX_INTERVAL_MULTIPLIER);
  };
  const arm = (delayMs) => {
    timer = setTimeout(runTick, delayMs);
    timer.unref?.();
  };
  function runTick() {
    timer = void 0;
    if (stopped)
      return;
    if (Date.now() - startedAt >= lifetimeCapMs) {
      incrementDegradationCount({
        kind: "resource-sampler-lifetime-capped",
        subject: SPAWN_SAMPLER_LEDGER_SUBJECT,
        reason: `spawn sampler stopped polling at its ${lifetimeCapMs}ms lifetime cap; the child was still running`
      });
      return;
    }
    tickCount++;
    if (inFlight) {
      incrementDegradationCount({
        kind: "resource-sampler-tick-overlapped",
        subject: SPAWN_SAMPLER_LEDGER_SUBJECT,
        reason: `spawn sampler skipped a poll tick: the previous sample was still in flight after ${intervalMs}ms`
      });
    } else {
      inFlight = true;
      void tick().then(releaseInFlight, releaseInFlight);
    }
    arm(nextDelayMs());
  }
  tickCount = 1;
  inFlight = true;
  void tick().then(releaseInFlight, releaseInFlight);
  arm(nextDelayMs());
  return {
    stop() {
      if (stopped)
        return accumulator.summarize();
      stopped = true;
      if (timer !== void 0)
        clearTimeout(timer);
      timer = void 0;
      return accumulator.summarize();
    }
  };
}

// dist/clients/safe-spawn.js
var SpawnFailureError = class extends Error {
  kind;
  cause;
  name = "SpawnFailureError";
  constructor(kind, message, cause) {
    super(message, { cause });
    this.kind = kind;
    this.cause = cause;
  }
};
function hasSpawnFailureKind(error, kind) {
  return error instanceof Error && "kind" in error && error.kind === kind;
}
function resolveTeardownOutcome(input) {
  if (input.killStartedAtMs === void 0 || input.deathObservedAtMs === void 0) {
    return void 0;
  }
  if (input.deathObservedAtMs <= input.killStartedAtMs) {
    return { ms: 0, outcome: "exited" };
  }
  return {
    ms: Math.max(0, input.deathObservedAtMs - input.killStartedAtMs),
    outcome: input.escalated ? "escalate-kill" : "killed-by-signal"
  };
}
function toError(error) {
  return error instanceof Error ? error : new Error(String(error));
}
function errorCode(error) {
  return error.code;
}
async function cwdIsUnresolvable(cwd) {
  if (cwd === void 0)
    return false;
  try {
    return !(await fs8.promises.stat(cwd)).isDirectory();
  } catch {
    return true;
  }
}
function cwdIsUnresolvableSync(cwd) {
  if (cwd === void 0)
    return false;
  try {
    return !fs8.statSync(cwd).isDirectory();
  } catch {
    return true;
  }
}
function commandProbablyPresent(command) {
  const exts = process.platform === "win32" ? [
    "",
    ...(process.env.PATHEXT ?? ".COM;.EXE;.BAT;.CMD").split(";").filter(Boolean)
  ] : [""];
  const existsWithExt = (base) => {
    for (const ext of exts) {
      try {
        if (fs8.existsSync(base + ext))
          return true;
      } catch {
      }
    }
    return false;
  };
  if (path11.isAbsolute(command))
    return existsWithExt(command);
  if (command.includes("/") || command.includes("\\"))
    return "ambiguous";
  for (const dir of (process.env.PATH ?? "").split(path11.delimiter)) {
    if (dir && existsWithExt(path11.join(dir, command)))
      return true;
  }
  return false;
}
function classifyWithCwdFlag(cause, options, cwdUnresolvable) {
  const code = errorCode(cause);
  let failure;
  if (code === "ENOENT" && cwdUnresolvable && commandProbablyPresent(options.command) !== false) {
    failure = new SpawnFailureError("cwd-unresolvable", `Cannot spawn ${options.command}: working directory is unresolvable (${options.cwd})`, cause);
  } else if (code === "ENOENT") {
    failure = new SpawnFailureError("tool-not-found", `Cannot spawn ${options.command}: tool not found (${cause.message})`, cause);
  } else if (code === "EACCES" || code === "EPERM") {
    failure = new SpawnFailureError("permission-denied", `Cannot spawn ${options.command}: permission denied`, cause);
  } else {
    failure = new SpawnFailureError("spawn-failed", `Cannot spawn ${options.command}: ${cause.message}`, cause);
  }
  recordSpawnClassification(failure, options);
  return failure;
}
var loggedSpawnClassifications = /* @__PURE__ */ new Set();
var SPAWN_CLASSIFICATION_LOG_CAP = 200;
function recordSpawnClassification(failure, options) {
  const pair = `${failure.kind}\0${options.command}`;
  if (!loggedSpawnClassifications.has(pair)) {
    if (loggedSpawnClassifications.size >= SPAWN_CLASSIFICATION_LOG_CAP) {
      loggedSpawnClassifications.clear();
    }
    loggedSpawnClassifications.add(pair);
    logExtension({
      subsystem: "safe-spawn",
      level: "debug",
      message: "spawn failure classified",
      metadata: {
        kind: failure.kind,
        command: options.command,
        cwd: options.cwd
      }
    });
  }
  if (failure.kind !== "tool-not-found") {
    recordDegradation({
      kind: "spawn-failure",
      subject: options.command,
      reason: `${failure.kind}${options.cwd ? ` in ${options.cwd}` : ""}`
    });
  }
}
async function classifySpawnFailure(error, options) {
  const cause = toError(error);
  const needsCwdProbe = errorCode(cause) === "ENOENT";
  const cwdUnresolvable = needsCwdProbe && await cwdIsUnresolvable(options.cwd);
  return classifyWithCwdFlag(cause, options, cwdUnresolvable);
}
function classifySpawnFailureSync(error, options) {
  const cause = toError(error);
  const needsCwdProbe = errorCode(cause) === "ENOENT";
  const cwdUnresolvable = needsCwdProbe && cwdIsUnresolvableSync(options.cwd);
  return classifyWithCwdFlag(cause, options, cwdUnresolvable);
}
var lifetimeStateKey = /* @__PURE__ */ Symbol.for("pi-lens.safe-spawn.lifetime-state");
var processWithLifetimeState = process;
var lifetimeState = processWithLifetimeState[lifetimeStateKey] ?? (processWithLifetimeState[lifetimeStateKey] = {
  pids: /* @__PURE__ */ new Set(),
  installed: false
});
var PROC_PPID_READABLE = (() => {
  if (process.platform !== "linux")
    return false;
  try {
    return /^PPid:\s*\d+$/m.test(fs8.readFileSync("/proc/self/status", "utf8"));
  } catch {
    return false;
  }
})();
var VERIFIED_OWN_PID_CAP = 512;
var verifiedOwnPids = new BoundedFifoMap(VERIFIED_OWN_PID_CAP);
var HELD_OWN_PID_SWEEP_AT = 256;
var heldOwnPids = new BoundedSet(HELD_OWN_PID_SWEEP_AT);
function groupIsGone(pid) {
  try {
    process.kill(-pid, 0);
    return false;
  } catch (error) {
    return errorCode(error) === "ESRCH";
  }
}
function sweepHeldOwnPids() {
  if (heldOwnPids.size < HELD_OWN_PID_SWEEP_AT)
    return;
  for (const pid of heldOwnPids) {
    if (groupIsGone(pid))
      heldOwnPids.delete(pid);
  }
}
function holdOwnChildPid(pid, site) {
  const owned = isOwnLiveChild(pid, site);
  if (!owned || !PROC_PPID_READABLE || typeof pid !== "number")
    return owned;
  verifiedOwnPids.delete(pid);
  sweepHeldOwnPids();
  heldOwnPids.add(pid);
  return true;
}
function releaseOwnChildPid(pid) {
  if (typeof pid === "number")
    heldOwnPids.delete(pid);
}
function recordProcUnavailable(site) {
  if (process.platform !== "linux")
    return;
  recordDegradationOnce({
    kind: "kill-ownership-unverifiable",
    subject: site,
    reason: "/proc/self/status is unreadable on this Linux host; kill-by-pid ownership falls back to best-effort"
  });
}
function isOwnLiveChild(pid, site, handle) {
  if (typeof pid !== "number" || !Number.isInteger(pid) || pid <= 0)
    return false;
  if (!PROC_PPID_READABLE) {
    if (handle && (handle.exitCode != null || handle.signalCode != null))
      return false;
    recordProcUnavailable(site);
    return true;
  }
  let status;
  try {
    status = fs8.readFileSync(`/proc/${pid}/status`, "utf8");
  } catch {
    return heldOwnPids.has(pid) || verifiedOwnPids.has(pid);
  }
  const parent = /^PPid:\s*(\d+)$/m.exec(status);
  if (!parent)
    return true;
  if (Number(parent[1]) === process.pid) {
    if (!heldOwnPids.has(pid))
      verifiedOwnPids.set(pid, true);
    return true;
  }
  incrementDegradationCount({
    kind: "kill-foreign-pid-refused",
    subject: site,
    reason: `pid ${pid} has parent ${parent[1]}, not this process \u2014 signal refused`
  });
  return false;
}
function killPidTreeSync(pid) {
  if (process.platform === "win32") {
    try {
      const taskkill = `${process.env.SystemRoot ?? "C:\\Windows"}\\System32\\taskkill.exe`;
      spawnSync(taskkill, ["/F", "/T", "/PID", String(pid)], {
        shell: false,
        windowsHide: true,
        stdio: "ignore"
      });
    } catch {
    }
    return;
  }
  try {
    try {
      process.kill(-pid, "SIGKILL");
    } catch {
      process.kill(pid, "SIGKILL");
    }
  } catch {
  }
}
function installLifetimeCleanup() {
  if (lifetimeState.installed)
    return;
  lifetimeState.installed = true;
  process.once("exit", () => {
    for (const pid of lifetimeState.pids)
      killPidTreeSync(pid);
  });
  for (const signal of ["SIGINT", "SIGTERM", "SIGHUP"]) {
    process.once(signal, () => {
      for (const pid of lifetimeState.pids)
        killPidTreeSync(pid);
      if (process.platform === "win32" && signal === "SIGHUP") {
        recordDegradationOnce({
          kind: "safe-spawn-signal-reraise-unsupported",
          subject: `${process.platform}:${signal}`,
          reason: `${process.platform} ${signal}: self signal re-raise is unsupported by the Windows libuv signal capability`,
          metadata: {
            platform: process.platform,
            signal,
            reason: "unsupported"
          }
        });
        return;
      }
      try {
        process.kill(process.pid, signal);
      } catch (error) {
        recordDegradationOnce({
          kind: "safe-spawn-signal-reraise-unsupported",
          subject: `${process.platform}:${signal}`,
          reason: `${process.platform} ${signal}: self signal re-raise was refused (${error.code ?? error.message})`,
          metadata: {
            platform: process.platform,
            signal,
            reason: "refused",
            code: error.code ?? null
          }
        });
      }
    });
  }
}
var ambientAbortSignal;
function setAmbientAbortSignal(signal) {
  ambientAbortSignal = signal;
}
function getAmbientAbortSignal() {
  return ambientAbortSignal;
}
function cmdEscapeArg(arg) {
  if (!/[\s"&|<>^()]/.test(arg))
    return arg;
  return `"${arg.replace(/"/g, '""')}"`;
}
function buildWindowsShellCommand(command, args) {
  const chcp = `${process.env.SystemRoot ?? "C:\\Windows"}\\System32\\chcp.com`;
  return `${chcp} 65001 >nul 2>&1 & ${[command, ...args].map(cmdEscapeArg).join(" ")}`;
}
var WINDOWS_DIRECT_RESOLVABLE_EXTS = /* @__PURE__ */ new Set([
  ".exe",
  ".com",
  ".cmd",
  ".bat"
]);
function mergeWindowsEnvironment(base, overrides) {
  const entries = /* @__PURE__ */ new Map();
  const assign = (source) => {
    if (!source)
      return;
    for (const [key, value] of Object.entries(source)) {
      const folded = key.toLowerCase();
      entries.delete(folded);
      if (value !== void 0)
        entries.set(folded, { key, value });
    }
  };
  assign(base);
  assign(overrides);
  const merged = {};
  for (const { key, value } of entries.values())
    merged[key] = value;
  return merged;
}
function getWindowsEnvironmentValue(env, name) {
  let value;
  for (const [key, entry] of Object.entries(env)) {
    if (key.toLowerCase() === name.toLowerCase())
      value = entry;
  }
  return value;
}
function driveLetter(value) {
  const match = /^([A-Za-z]):/.exec(value);
  return match?.[1]?.toUpperCase();
}
function isDriveAbsolute(value, drive) {
  return value.length >= 3 && value[0]?.toUpperCase() === drive.toUpperCase() && value[1] === ":" && (value[2] === "\\" || value[2] === "/");
}
function isDriveAbsoluteAnyDrive(value) {
  const drive = driveLetter(value);
  return drive !== void 0 && isDriveAbsolute(value, drive);
}
function isUncWindowsPath(value) {
  return (value[0] === "\\" || value[0] === "/") && (value[1] === "\\" || value[1] === "/") && value[2] !== "\\" && value[2] !== "/";
}
function isFullyQualifiedWindowsPath(value) {
  return isFullyQualifiedWin32(value) && !isRootedWindowsPath(value);
}
function isRootedWindowsPath(value) {
  return (value[0] === "\\" || value[0] === "/") && driveLetter(value) === void 0 && !isUncWindowsPath(value);
}
function resolveRootedWindowsPath(value, driveSource) {
  const drive = driveLetter(driveSource);
  if (drive === void 0)
    return path11.win32.normalize(value);
  return path11.win32.normalize(path11.win32.resolve(`${drive}:\\`, value));
}
function getValidatedPerDriveCwd(env, drive) {
  const value = getWindowsEnvironmentValue(env, `=${drive}:`);
  if (value === void 0 || !isDriveAbsolute(value, drive))
    return void 0;
  return path11.win32.normalize(value);
}
function resolveEffectiveWindowsCwd(cwd, env) {
  if (cwd === void 0) {
    return path11.win32.normalize(process.cwd());
  }
  const requestedDrive = driveLetter(cwd);
  if (requestedDrive !== void 0 && !isDriveAbsoluteAnyDrive(cwd)) {
    const base = getValidatedPerDriveCwd(env, requestedDrive);
    return base === void 0 ? void 0 : path11.win32.normalize(path11.win32.resolve(base, cwd));
  }
  if (isFullyQualifiedWindowsPath(cwd))
    return path11.win32.normalize(cwd);
  if (isRootedWindowsPath(cwd)) {
    return resolveRootedWindowsPath(cwd, process.cwd());
  }
  return path11.win32.normalize(path11.win32.resolve(process.cwd(), cwd));
}
function resolveDriveRelativeWindowsPath(value, effectiveCwd, env) {
  const drive = driveLetter(value);
  if (drive === void 0)
    return void 0;
  const cwdDrive = effectiveCwd === void 0 ? void 0 : driveLetter(effectiveCwd);
  const base = cwdDrive?.toUpperCase() === drive ? effectiveCwd : getValidatedPerDriveCwd(env, drive);
  if (base === void 0)
    return void 0;
  return path11.win32.normalize(path11.win32.resolve(base, value));
}
function resolveWindowsPathEntry(entry, effectiveCwd, env) {
  if (driveLetter(entry) !== void 0 && !isDriveAbsoluteAnyDrive(entry)) {
    return resolveDriveRelativeWindowsPath(entry, effectiveCwd, env);
  }
  if (isFullyQualifiedWindowsPath(entry))
    return path11.win32.normalize(entry);
  if (isRootedWindowsPath(entry)) {
    return effectiveCwd === void 0 ? void 0 : resolveRootedWindowsPath(entry, effectiveCwd);
  }
  if (effectiveCwd === void 0)
    return void 0;
  return path11.win32.normalize(path11.win32.resolve(effectiveCwd, entry));
}
var WINDOWS_COMMAND_CACHE_MAX_ENTRIES = 256;
var WINDOWS_COMMAND_NEGATIVE_CACHE_TTL_MS = 1e3;
var windowsCommandCache = new BoundedFifoMap(WINDOWS_COMMAND_CACHE_MAX_ENTRIES);
function resetSafeSpawnWindowsCommandCache() {
  windowsCommandCache.clear();
  loggedSpawnClassifications.clear();
}
function cacheWindowsCommandResult(key, resolved) {
  windowsCommandCache.set(key, { resolved, checkedAt: Date.now() });
}
function getPathExts(env) {
  const raw = getWindowsEnvironmentValue(env, "PATHEXT") ?? ".COM;.EXE;.BAT;.CMD";
  return raw.split(";").map((ext) => ext.trim().toLowerCase()).filter(Boolean);
}
function statIsFile(candidate) {
  try {
    return fs8.statSync(candidate).isFile();
  } catch {
    return false;
  }
}
function resolveWindowsCommandUncached(command, effectiveCwd, env) {
  const pathExts = getPathExts(env);
  const existingExt = path11.win32.extname(command).toLowerCase();
  const hasExplicitExt = existingExt.length > 0;
  const isKnownExecutableExt = (ext) => WINDOWS_DIRECT_RESOLVABLE_EXTS.has(ext) || pathExts.includes(ext);
  const tryBase = (base) => {
    if (hasExplicitExt && isKnownExecutableExt(existingExt) && statIsFile(base)) {
      return { resolvedPath: base, ext: existingExt };
    }
    if (!hasExplicitExt || !pathExts.includes(existingExt)) {
      for (const ext of pathExts) {
        const candidate = base + ext;
        if (statIsFile(candidate))
          return { resolvedPath: candidate, ext };
      }
    }
    return null;
  };
  const hasPathSep = /[\\/]/.test(command);
  const hasDrivePrefix = driveLetter(command) !== void 0;
  if (hasPathSep || hasDrivePrefix || isFullyQualifiedWindowsPath(command)) {
    let base;
    if (isFullyQualifiedWindowsPath(command)) {
      base = path11.win32.normalize(command);
    } else if (hasDrivePrefix) {
      base = resolveDriveRelativeWindowsPath(command, effectiveCwd, env);
    } else if (isRootedWindowsPath(command)) {
      base = effectiveCwd === void 0 ? void 0 : resolveRootedWindowsPath(command, effectiveCwd);
    } else if (effectiveCwd !== void 0) {
      base = path11.win32.normalize(path11.win32.resolve(effectiveCwd, command));
    }
    return base === void 0 ? null : tryBase(base);
  }
  const pathValue = getWindowsEnvironmentValue(env, "PATH") ?? "";
  const pathDirs = pathValue.split(path11.win32.delimiter);
  for (const dir of pathDirs) {
    if (!dir)
      continue;
    const resolvedDir = resolveWindowsPathEntry(dir, effectiveCwd, env);
    if (resolvedDir === void 0)
      continue;
    const found = tryBase(path11.win32.join(resolvedDir, command));
    if (found)
      return found;
  }
  return null;
}
function resolveWindowsCommandForEnvironment(command, cwd, env) {
  const effectiveCwd = resolveEffectiveWindowsCwd(cwd, env);
  const pathValue = getWindowsEnvironmentValue(env, "PATH");
  const pathExtValue = getWindowsEnvironmentValue(env, "PATHEXT");
  const perDriveCwds = Object.entries(env).flatMap(([key, value]) => /^=[A-Za-z]:$/.test(key) ? [[key.toLowerCase(), value]] : []).sort(([left], [right]) => compareOrdinal(left, right));
  const cacheKey = JSON.stringify([
    "win32",
    command,
    pathValue === void 0 ? ["absent"] : ["present", pathValue],
    pathExtValue === void 0 ? ["absent"] : ["present", pathExtValue],
    effectiveCwd === void 0 ? ["unresolved"] : ["resolved", effectiveCwd],
    perDriveCwds
  ]);
  const cached = windowsCommandCache.get(cacheKey);
  if (cached) {
    if (cached.resolved && statIsFile(cached.resolved.resolvedPath)) {
      return cached.resolved;
    }
    if (!cached.resolved && Date.now() - cached.checkedAt <= WINDOWS_COMMAND_NEGATIVE_CACHE_TTL_MS) {
      return null;
    }
    windowsCommandCache.delete(cacheKey);
  }
  const resolved = resolveWindowsCommandUncached(command, effectiveCwd, env);
  cacheWindowsCommandResult(cacheKey, resolved);
  return resolved;
}
function resolveWindowsCommand(command, cwd, env) {
  return resolveWindowsCommandForEnvironment(command, cwd, env);
}
function getSpawnEnvironment(overrides) {
  return process.platform === "win32" ? mergeWindowsEnvironment(process.env, overrides) : { ...process.env, ...overrides };
}
var CMD_UNSAFE_CHARS = /["%!\r\n]/;
function findCmdUnsafeValue(command, args) {
  if (CMD_UNSAFE_CHARS.test(command))
    return command;
  return args.find((arg) => CMD_UNSAFE_CHARS.test(arg));
}
function synthesizeEnoentError(command) {
  const err = new Error(`spawn ${command} ENOENT`);
  err.code = "ENOENT";
  err.syscall = "spawn";
  err.path = command;
  return err;
}
var utf8ConsoleCodePageApplied = false;
function ensureUtf8ConsoleCodePageOnce() {
  if (utf8ConsoleCodePageApplied)
    return;
  utf8ConsoleCodePageApplied = true;
  try {
    const cmdExe = `${process.env.SystemRoot ?? "C:\\Windows"}\\System32\\cmd.exe`;
    spawnSync(cmdExe, ["/d", "/s", "/c", "chcp 65001 >nul 2>&1"], {
      shell: false,
      windowsHide: true,
      // #1980 population sweep: a synchronous spawn with no timeout parks
      // the event loop for as long as the child takes, and nothing here
      // bounds that. `chcp` is normally instant, but this runs before the
      // FIRST real spawn of the process, which is exactly when a cold or
      // antivirus-throttled cmd.exe is slowest. Matches the 5s bound every
      // other synchronous child-process site in this repo already carries.
      timeout: 5e3
    });
  } catch {
  }
}
function resetUtf8ConsoleCodePageStateForTests() {
  utf8ConsoleCodePageApplied = false;
}
var EXIT_PIPE_IDLE_GRACE_MS = 100;
var EXIT_PIPE_IDLE_MAX_WAIT_MS = 2e3;
var SPAWN_SAMPLER_TEARDOWN_GRACE_MS = 5e3;
async function safeSpawnAsync(command, args, options) {
  const configuredTimeout = options?.timeout !== void 0 && Number.isFinite(options.timeout) && options.timeout >= 0 ? options.timeout : 3e4;
  const deadlineRemaining = options?.deadlineAt !== void 0 && Number.isFinite(options.deadlineAt) ? options.deadlineAt - Date.now() : Number.POSITIVE_INFINITY;
  const timeout = Math.max(0, Math.min(configuredTimeout, deadlineRemaining));
  const abortSignal = options?.signal ?? (options?.ignoreAmbientSignal ? void 0 : ambientAbortSignal);
  return new Promise((resolve6) => {
    if (abortSignal?.aborted) {
      const cause = new Error("Spawn aborted before start");
      resolve6({
        stdout: "",
        stderr: "",
        status: null,
        error: cause,
        failure: "aborted",
        spawnFailure: new SpawnFailureError("killed", cause.message, cause)
      });
      return;
    }
    if (timeout <= 0) {
      const cause = new Error(`Process timed out after ${timeout}ms`);
      resolve6({
        stdout: "",
        stderr: "",
        status: null,
        error: cause,
        failure: "timeout",
        spawnFailure: new SpawnFailureError("timeout", cause.message, cause)
      });
      return;
    }
    let stdout = "";
    let stderr = "";
    let timedOut = false;
    let aborted = false;
    let killed = false;
    let outputTruncated = false;
    let killedForOutputCap = false;
    let observedOutputBytes = 0;
    let retainedOutputBytes = 0;
    let outputHandlerFailed = false;
    let streamingMatch = false;
    let resolved = false;
    let pendingSpawnError;
    let escalationTimer;
    let teardownStartedAtMs;
    let teardownEscalated = false;
    let closed = false;
    let rearmIdleGrace;
    const callerCap = options?.maxOutputBytes;
    const capFromCaller = callerCap !== void 0 && Number.isFinite(callerCap) && callerCap > 0;
    const maxOutputBytes = capFromCaller ? Math.floor(callerCap) : DEFAULT_MAX_OUTPUT_BYTES;
    const outputTruncationMarker = "\n...[output truncated]...\n";
    let retainedHead = [];
    let retainedTail = [];
    let retainedTailBytes = 0;
    let retainedTailLimit = 0;
    let truncationStream = "stderr";
    const streamingMatcher = options?.matchWhileStreaming;
    const streamingCarryBytes = streamingMatcher ? Math.max(0, streamingMatcher.source.length - 1) : 0;
    const streamingCarry = {
      stdout: "",
      stderr: ""
    };
    const bytePrefix = (text, bytes) => Buffer.from(text).subarray(0, bytes).toString();
    const byteSuffix = (text, bytes) => {
      const buffer = Buffer.from(text);
      return buffer.subarray(Math.max(0, buffer.byteLength - bytes)).toString();
    };
    const appendTail = (part, maxBytes) => {
      if (maxBytes <= 0)
        return;
      retainedTail.push({ stream: part.stream, text: part.text });
      retainedTailBytes += Buffer.byteLength(part.text);
      while (retainedTailBytes > maxBytes && retainedTail.length > 0) {
        const first = retainedTail[0];
        const excess = retainedTailBytes - maxBytes;
        const firstBytes = Buffer.byteLength(first.text);
        if (firstBytes <= excess) {
          retainedTail.shift();
          retainedTailBytes -= firstBytes;
        } else {
          first.text = byteSuffix(first.text, firstBytes - excess);
          retainedTailBytes -= excess;
        }
      }
    };
    const renderOutput = (stream) => {
      const head = retainedHead.filter((part) => part.stream === stream).map((part) => part.text).join("");
      const tail = retainedTail.filter((part) => part.stream === stream).map((part) => part.text).join("");
      const marker = stream === truncationStream ? outputTruncationMarker : "";
      return head + marker + tail;
    };
    const refreshRetainedOutputs = () => {
      stdout = renderOutput("stdout");
      stderr = renderOutput("stderr");
    };
    const appendOutput = (stream, current, chunk) => {
      const text = typeof chunk === "string" ? chunk : chunk.toString();
      if (outputTruncated) {
        appendTail({ stream, text }, retainedTailLimit);
        truncationStream = stream;
        return renderOutput(stream);
      }
      const bytes = Buffer.byteLength(text);
      if (retainedOutputBytes + bytes <= maxOutputBytes) {
        retainedOutputBytes += bytes;
        return current + text;
      }
      outputTruncated = true;
      truncationStream = stream;
      const available = Math.max(0, maxOutputBytes - Buffer.byteLength(outputTruncationMarker));
      const headBytes = Math.floor(available / 2);
      const tailBytes = available - headBytes;
      retainedTailLimit = tailBytes;
      const parts = [
        { stream: "stdout", text: stdout },
        { stream: "stderr", text: stderr },
        { stream, text }
      ];
      let headRemaining = headBytes;
      for (const part of parts) {
        if (headRemaining <= 0)
          break;
        const kept = bytePrefix(part.text, headRemaining);
        if (kept)
          retainedHead.push({ stream: part.stream, text: kept });
        headRemaining -= Buffer.byteLength(kept);
      }
      let tailRemaining = tailBytes;
      for (let index = parts.length - 1; index >= 0 && tailRemaining > 0; index--) {
        const part = parts[index];
        const kept = byteSuffix(part.text, tailRemaining);
        if (kept) {
          retainedTail.unshift({ stream: part.stream, text: kept });
          tailRemaining -= Buffer.byteLength(kept);
        }
      }
      retainedTailBytes = tailBytes - tailRemaining;
      return renderOutput(stream);
    };
    const matchStreamingChunk = (stream, chunk) => {
      if (streamingMatch || !streamingMatcher)
        return;
      const text = typeof chunk === "string" ? chunk : chunk.toString();
      streamingMatcher.lastIndex = 0;
      streamingMatch = streamingMatcher.test(streamingCarry[stream] + text);
      if (streamingCarryBytes > 0) {
        streamingCarry[stream] = Buffer.from(streamingCarry[stream] + text).subarray(-streamingCarryBytes).toString();
      }
    };
    const isWindows2 = process.platform === "win32";
    const spawnEnv = getSpawnEnvironment(options?.env);
    const spawnCwd = isWindows2 ? resolveEffectiveWindowsCwd(options?.cwd, spawnEnv) ?? options?.cwd : options?.cwd;
    let spawnCmd = command;
    let spawnArgs = args;
    let windowsVerbatimArguments = false;
    let resolutionError;
    if (isWindows2) {
      const resolved2 = resolveWindowsCommand(command, options?.cwd, spawnEnv);
      if (!resolved2) {
        resolutionError = synthesizeEnoentError(command);
      } else if (resolved2.ext === ".cmd" || resolved2.ext === ".bat") {
        const unsafeValue = findCmdUnsafeValue(resolved2.resolvedPath, args);
        if (unsafeValue !== void 0) {
          resolutionError = new Error(`Refusing to spawn "${resolved2.resolvedPath}" via cmd.exe: ${JSON.stringify(unsafeValue)} contains a character (", %, !, or CR/LF) that cannot be safely escaped on a cmd.exe /c command line (CWE-78, #817). Rename/quote the value or invoke the tool without going through cmd.exe.`);
        } else {
          spawnCmd = `${process.env.SystemRoot ?? "C:\\Windows"}\\System32\\cmd.exe`;
          spawnArgs = [
            "/d",
            "/s",
            "/c",
            buildWindowsShellCommand(resolved2.resolvedPath, args)
          ];
          windowsVerbatimArguments = true;
        }
      } else {
        ensureUtf8ConsoleCodePageOnce();
        spawnCmd = resolved2.resolvedPath;
        spawnArgs = args;
      }
    }
    if (resolutionError) {
      void classifySpawnFailure(resolutionError, {
        command,
        cwd: options?.cwd
      }).then((spawnFailure) => resolve6({
        stdout: "",
        stderr: "",
        status: null,
        error: resolutionError,
        failure: "spawn",
        spawnFailure
      }));
      return;
    }
    let child;
    const posixProcessGroup = process.platform !== "win32";
    try {
      child = spawn(spawnCmd, spawnArgs, {
        cwd: spawnCwd,
        env: spawnEnv,
        windowsHide: true,
        shell: false,
        windowsVerbatimArguments,
        detached: posixProcessGroup
      });
    } catch (err) {
      const cause = toError(err);
      void classifySpawnFailure(cause, { command, cwd: options?.cwd }).then((spawnFailure) => resolve6({
        stdout: "",
        stderr: "",
        status: null,
        error: cause,
        failure: "spawn",
        spawnFailure
      }));
      return;
    }
    if (options?.input !== void 0) {
      child.stdin?.on("error", () => {
      });
      child.stdin?.end(options.input);
    }
    const ownsChildPid = isOwnLiveChild(child.pid, "safe-spawn-register");
    if (ownsChildPid && (posixProcessGroup || options?.lifetimeCoupled)) {
      installLifetimeCleanup();
      lifetimeState.pids.add(child.pid);
    }
    let usageSampler;
    try {
      usageSampler = startSpawnUsageSampler(
        // The poll CADENCE is the sampler's own policy (it owns the backoff
        // too); the DEADLINE is this function's. Passing `undefined` rather
        // than importing the cadence constant keeps this module's view of
        // the sampler at one export, which is also what every existing
        // `vi.mock` of it provides.
        child.pid,
        void 0,
        timeout + SPAWN_SAMPLER_TEARDOWN_GRACE_MS
      );
    } catch {
      usageSampler = { stop: () => null };
    }
    const resourceLabel = options?.resourceLabel ?? command;
    let killFailed = false;
    const trySend = (send) => {
      try {
        send();
        return true;
      } catch {
        return false;
      }
    };
    const noteKillFailure = (phase) => {
      if (killFailed)
        return;
      killFailed = true;
      incrementDegradationCount({
        kind: "spawn-kill-failed",
        subject: resourceLabel,
        reason: `every signal available for the ${phase} teardown was refused; the child may still be running`,
        metadata: { phase, pid: child.pid }
      });
    };
    const killTree = async (phase) => {
      if (isWindows2 && child.pid && child.pid > 0) {
        const taskkill = `${process.env.SystemRoot ?? "C:\\Windows"}\\System32\\taskkill.exe`;
        try {
          await new Promise((done) => {
            const killer = spawn(taskkill, ["/F", "/T", "/PID", String(child.pid)], {
              shell: false,
              windowsHide: true,
              stdio: "ignore"
            });
            killer.once("close", () => done());
            killer.once("error", () => {
              if (!trySend(() => child.kill("SIGKILL")))
                noteKillFailure(phase);
              done();
            });
          });
        } catch {
          if (!trySend(() => child.kill("SIGKILL")))
            noteKillFailure(phase);
        }
      } else if (posixProcessGroup && ownsChildPid) {
        const pgid = -child.pid;
        if (!trySend(() => process.kill(pgid, "SIGTERM"))) {
          if (!trySend(() => child.kill("SIGTERM")))
            noteKillFailure(phase);
        }
        escalationTimer = setTimeout(() => {
          const escalated = trySend(() => {
            let groupAlive = true;
            try {
              process.kill(pgid, 0);
            } catch {
              groupAlive = false;
            }
            if (!groupAlive)
              return;
            teardownEscalated = true;
            logLatency({
              type: "phase",
              phase: "spawn_group_kill_escalation",
              filePath: "",
              durationMs: 0,
              metadata: { pgid: child.pid }
            });
            trySend(() => process.kill(pgid, "SIGKILL"));
          });
          if (!escalated)
            noteKillFailure(phase);
        }, 1e3);
      } else {
        if (!trySend(() => child.kill("SIGTERM")))
          noteKillFailure(phase);
        escalationTimer = setTimeout(() => {
          if (closed)
            return;
          teardownEscalated = true;
          if (!trySend(() => child.kill("SIGKILL")))
            noteKillFailure(phase);
        }, 1e3);
      }
    };
    const onAbort = () => {
      aborted = true;
      if (!killed && !child.killed) {
        killed = true;
        void killTree("abort");
      }
    };
    abortSignal?.addEventListener("abort", onAbort, { once: true });
    let killPromise;
    const stopForOutputLimit = () => {
      const waitingForStreamingMatch = streamingMatcher !== void 0 && !streamingMatch;
      if (outputTruncated && !waitingForStreamingMatch && !killed && !child.killed) {
        killedForOutputCap = true;
        killed = true;
        killPromise = killTree("output-cap");
      }
    };
    const recordOutputCapTrip = () => {
      incrementDegradationCount({
        kind: "spawn-output-cap-truncated",
        subject: resourceLabel,
        reason: `retained output reached the ${maxOutputBytes}-byte ${capFromCaller ? "caller" : "default"} cap after ${observedOutputBytes} bytes; child ${killedForOutputCap ? "terminated" : "left running"}`,
        metadata: {
          capBytes: maxOutputBytes,
          capSource: capFromCaller ? "caller" : "default",
          observedBytes: observedOutputBytes,
          killed: killedForOutputCap
        }
      });
    };
    const failOutputHandler = (stream, error) => {
      outputHandlerFailed = true;
      outputTruncated = true;
      incrementDegradationCount({
        kind: "spawn-output-handler-fault",
        subject: resourceLabel,
        reason: `${stream} chunk handling threw ${error.name} after ${observedOutputBytes} bytes; retention stopped and the child was terminated`,
        metadata: {
          stream,
          error: error.name,
          capBytes: maxOutputBytes,
          observedBytes: observedOutputBytes
        }
      });
      if (!killed && !child.killed) {
        killedForOutputCap = true;
        killed = true;
        killPromise = killTree("handler-fault");
      }
    };
    child.stdout?.setEncoding("utf-8");
    child.stderr?.setEncoding("utf-8");
    const onOutputChunk = (stream, data) => {
      if (outputHandlerFailed)
        return;
      try {
        observedOutputBytes += Buffer.byteLength(data);
        const wasTruncated = outputTruncated;
        matchStreamingChunk(stream, data);
        if (stream === "stdout")
          stdout = appendOutput(stream, stdout, data);
        else
          stderr = appendOutput(stream, stderr, data);
        if (outputTruncated)
          refreshRetainedOutputs();
        stopForOutputLimit();
        if (!wasTruncated && outputTruncated)
          recordOutputCapTrip();
        rearmIdleGrace?.();
      } catch (error) {
        failOutputHandler(stream, toError(error));
      }
    };
    child.stdout?.on("data", (data) => onOutputChunk("stdout", data));
    child.stderr?.on("data", (data) => onOutputChunk("stderr", data));
    let closeSeen = false;
    let closedAtMs;
    child.on("close", () => {
      closeSeen = true;
      closedAtMs ??= Date.now();
    });
    const timeoutId = setTimeout(() => {
      timedOut = true;
      if (!killed && !child.killed) {
        killed = true;
        teardownStartedAtMs = Date.now();
        killPromise = killTree("timeout");
      }
    }, timeout);
    const finishResourceUsage = () => {
      const summary = usageSampler.stop();
      if (!summary)
        return void 0;
      try {
        logLatency({
          type: "phase",
          phase: "spawn_resource_usage",
          filePath: "",
          durationMs: 0,
          metadata: {
            command: resourceLabel,
            ...summary
          }
        });
      } catch {
      }
      return summary;
    };
    const waitForPipeIdle = () => {
      if (!child.stdout && !child.stderr)
        return Promise.resolve();
      if (closeSeen)
        return Promise.resolve();
      return new Promise((finishIdleWait) => {
        let settled2 = false;
        let graceTimer;
        const capTimer = setTimeout(() => {
          finish();
        }, EXIT_PIPE_IDLE_MAX_WAIT_MS);
        const finish = () => {
          if (settled2)
            return;
          settled2 = true;
          rearmIdleGrace = void 0;
          if (graceTimer)
            clearTimeout(graceTimer);
          clearTimeout(capTimer);
          child.removeListener?.("close", finish);
          finishIdleWait();
        };
        child.on("close", finish);
        rearmIdleGrace = () => {
          if (graceTimer)
            clearTimeout(graceTimer);
          graceTimer = setTimeout(finish, EXIT_PIPE_IDLE_GRACE_MS);
        };
        rearmIdleGrace();
      });
    };
    let settled = false;
    const onChildSettle = (code, signal) => {
      if (settled || resolved)
        return;
      settled = true;
      closed = true;
      clearTimeout(timeoutId);
      abortSignal?.removeEventListener("abort", onAbort);
      if (child.pid)
        lifetimeState.pids.delete(child.pid);
      void finalize(code, signal);
    };
    const finalize = async (code, signal) => {
      await killPromise;
      if (resolved)
        return;
      if (escalationTimer && !posixProcessGroup) {
        clearTimeout(escalationTimer);
      }
      resolved = true;
      await waitForPipeIdle();
      const resourceUsage = finishResourceUsage();
      const outputInfo = {
        ...outputTruncated ? { outputTruncated: true } : {},
        ...killedForOutputCap ? { killedForOutputCap: true } : {},
        ...killFailed ? { killFailed: true } : {}
      };
      const streamingMatchInfo = streamingMatch ? { streamingMatch: true } : {};
      const signalInfo = signal ? { signal } : {};
      if (timedOut) {
        const cause = new Error(`Process timed out after ${timeout}ms (killed with ${signal || "SIGTERM"})`);
        const timeoutTeardown = resolveTeardownOutcome({
          killStartedAtMs: teardownStartedAtMs,
          deathObservedAtMs: closedAtMs,
          escalated: teardownEscalated
        });
        resolve6({
          stdout,
          stderr,
          status: null,
          error: cause,
          failure: "timeout",
          ...signalInfo,
          ...timeoutTeardown && { timeoutTeardown },
          spawnFailure: new SpawnFailureError("timeout", cause.message, cause),
          ...outputInfo,
          ...streamingMatchInfo,
          resourceUsage
        });
      } else if (aborted) {
        const cause = new Error("Spawn aborted");
        resolve6({
          stdout,
          stderr,
          status: null,
          error: cause,
          failure: "aborted",
          ...signalInfo,
          spawnFailure: new SpawnFailureError("killed", cause.message, cause),
          ...outputInfo,
          ...streamingMatchInfo,
          resourceUsage
        });
      } else if (signal) {
        const cause = new Error(`Process killed by signal: ${signal}`);
        resolve6({
          stdout,
          stderr,
          status: null,
          error: cause,
          failure: "signal",
          ...signalInfo,
          spawnFailure: new SpawnFailureError("killed", cause.message, cause),
          ...outputInfo,
          ...streamingMatchInfo,
          resourceUsage
        });
      } else if (code === null || code < 0) {
        const cause = pendingSpawnError ?? synthesizeEnoentError(command);
        const spawnFailure = await classifySpawnFailure(cause, {
          command,
          cwd: options?.cwd
        });
        resolve6({
          stdout,
          stderr,
          status: code,
          error: cause,
          failure: "spawn",
          spawnFailure,
          ...outputInfo,
          ...streamingMatchInfo,
          resourceUsage
        });
      } else {
        resolve6({
          stdout,
          stderr,
          status: code,
          ...outputInfo,
          ...streamingMatchInfo,
          resourceUsage
        });
      }
    };
    child.on("exit", onChildSettle);
    child.on("close", onChildSettle);
    child.on("error", (err) => {
      pendingSpawnError = err;
      if (resolved)
        return;
      resolved = true;
      closed = true;
      clearTimeout(timeoutId);
      abortSignal?.removeEventListener("abort", onAbort);
      if (escalationTimer && !posixProcessGroup) {
        clearTimeout(escalationTimer);
      }
      if (child.pid)
        lifetimeState.pids.delete(child.pid);
      const resourceUsage = finishResourceUsage();
      let failure = "spawn";
      if (aborted)
        failure = "aborted";
      else if (timedOut)
        failure = "timeout";
      const controlFailure = aborted ? new SpawnFailureError("killed", err.message, err) : timedOut ? new SpawnFailureError("timeout", err.message, err) : void 0;
      const finish = (spawnFailure) => resolve6({
        stdout,
        stderr,
        status: null,
        error: err,
        failure,
        spawnFailure,
        ...outputTruncated ? { outputTruncated: true } : {},
        ...killedForOutputCap ? { killedForOutputCap: true } : {},
        ...killFailed ? { killFailed: true } : {},
        ...streamingMatch ? { streamingMatch: true } : {},
        resourceUsage
      });
      if (controlFailure)
        finish(controlFailure);
      else {
        void classifySpawnFailure(err, { command, cwd: options?.cwd }).then(finish);
      }
    });
  });
}
async function safeSpawnBatch(commands, concurrency = 3) {
  const results = [];
  for (let i = 0; i < commands.length; i += concurrency) {
    const batch = commands.slice(i, i + concurrency);
    const batchResults = await Promise.all(batch.map(({ command, args, options }) => safeSpawnAsync(command, args, options)));
    results.push(...batchResults);
  }
  return results;
}
async function isCommandAvailableAsync(command) {
  const finder = process.platform === "win32" ? "where" : "which";
  const result = await safeSpawnAsync(finder, [command], { timeout: 5e3 });
  return result.status === 0 && !result.error;
}
async function findCommandAsync(command) {
  const finder = process.platform === "win32" ? "where" : "which";
  const result = await safeSpawnAsync(finder, [command], { timeout: 5e3 });
  if (result.status !== 0 || result.error)
    return null;
  return result.stdout.trim().split("\n")[0] || null;
}
function safeSpawn(command, args, options) {
  const spawnEnv = getSpawnEnvironment(options?.env);
  if (process.platform === "win32") {
    const spawnCwd = resolveEffectiveWindowsCwd(options?.cwd, spawnEnv) ?? options?.cwd;
    const resolved = resolveWindowsCommand(command, options?.cwd, spawnEnv);
    if (!resolved) {
      const error = synthesizeEnoentError(command);
      return {
        stdout: "",
        stderr: "",
        status: null,
        error,
        failure: "spawn",
        spawnFailure: classifySpawnFailureSync(error, {
          command,
          cwd: options?.cwd
        })
      };
    }
    let spawnCmd;
    let spawnArgs;
    let windowsVerbatimArguments = false;
    if (resolved.ext === ".cmd" || resolved.ext === ".bat") {
      const unsafeValue = findCmdUnsafeValue(resolved.resolvedPath, args);
      if (unsafeValue !== void 0) {
        const error = new Error(`Refusing to spawn "${resolved.resolvedPath}" via cmd.exe: ${JSON.stringify(unsafeValue)} contains a character (", %, !, or CR/LF) that cannot be safely escaped on a cmd.exe /c command line (CWE-78, #817). Rename/quote the value or invoke the tool without going through cmd.exe.`);
        return {
          stdout: "",
          stderr: "",
          status: null,
          error,
          failure: "spawn",
          spawnFailure: classifySpawnFailureSync(error, {
            command,
            cwd: options?.cwd
          })
        };
      }
      spawnCmd = `${process.env.SystemRoot ?? "C:\\Windows"}\\System32\\cmd.exe`;
      spawnArgs = [
        "/d",
        "/s",
        "/c",
        buildWindowsShellCommand(resolved.resolvedPath, args)
      ];
      windowsVerbatimArguments = true;
    } else {
      ensureUtf8ConsoleCodePageOnce();
      spawnCmd = resolved.resolvedPath;
      spawnArgs = args;
    }
    const result2 = spawnSync(spawnCmd, spawnArgs, {
      ...options,
      cwd: spawnCwd,
      env: spawnEnv,
      encoding: "utf-8",
      shell: false,
      windowsHide: true,
      windowsVerbatimArguments
    });
    const spawnFailure2 = result2.error ? classifySpawnFailureSync(result2.error, { command, cwd: options?.cwd }) : void 0;
    return {
      stdout: result2.stdout?.toString() || "",
      stderr: result2.stderr?.toString() || "",
      status: result2.status,
      error: result2.error,
      ...spawnFailure2 ? { failure: "spawn", spawnFailure: spawnFailure2 } : {}
    };
  }
  const result = spawnSync(command, args, {
    ...options,
    // Explicit override, not just the spread above: `options.env` alone
    // would otherwise reach the child as a full replacement (no
    // process.env merge, no PATH) instead of the merged environment the
    // resolver/Windows branch above both use (#1201) — the module's
    // "resolver and child receive the same merged environment" invariant
    // must hold on every platform, not just Windows.
    env: spawnEnv,
    encoding: "utf-8",
    shell: false,
    windowsHide: true
  });
  const spawnFailure = result.error ? classifySpawnFailureSync(result.error, { command, cwd: options?.cwd }) : void 0;
  return {
    stdout: result.stdout?.toString() || "",
    stderr: result.stderr?.toString() || "",
    status: result.status,
    error: result.error,
    ...spawnFailure ? { failure: "spawn", spawnFailure } : {}
  };
}
function isCommandAvailable(command) {
  const result = safeSpawn(process.platform === "win32" ? "where" : "which", [command], { timeout: 5e3 });
  return result.status === 0;
}
function findCommand(command) {
  const finder = process.platform === "win32" ? "where" : "which";
  const result = safeSpawn(finder, [command], { timeout: 5e3 });
  if (result.status !== 0)
    return null;
  return result.stdout.trim().split("\n")[0] || null;
}

export {
  noteSpawnTimeout,
  isInSpawnTimeoutCooldown,
  resetSpawnTimeoutCooldowns,
  isLockContention,
  recordGenerationTakeover,
  recordLegacyLockHeld,
  releaseGeneration,
  heartbeatIntervalMs,
  startGenerationHeartbeat,
  ownsTopGeneration,
  tryAcquireGeneration,
  withGenerationLockSync,
  acquireQuarantinePidFileLock,
  acquireBoundedPidFileLock,
  createGenerationSource,
  createGenerationMap,
  OWNER_TAG_ENV,
  ownerTagForChildren,
  isSubagentSession,
  getSubagentIdentity,
  subagentLightModeNotice,
  readInstanceRegistry,
  updateHeartbeat,
  recordLspChild,
  removeLspChild,
  selectLivePeerInstances,
  getResourceFootprint,
  realIsPidAlive,
  isStaleStageFile,
  sweepAtomicWriteStages,
  sampleProcessTreeCpuPercent,
  SpawnFailureError,
  hasSpawnFailureKind,
  resolveTeardownOutcome,
  classifySpawnFailure,
  VERIFIED_OWN_PID_CAP,
  holdOwnChildPid,
  releaseOwnChildPid,
  isOwnLiveChild,
  setAmbientAbortSignal,
  getAmbientAbortSignal,
  buildWindowsShellCommand,
  mergeWindowsEnvironment,
  WINDOWS_COMMAND_CACHE_MAX_ENTRIES,
  resetSafeSpawnWindowsCommandCache,
  resolveWindowsCommandForEnvironment,
  resetUtf8ConsoleCodePageStateForTests,
  safeSpawnAsync,
  safeSpawnBatch,
  isCommandAvailableAsync,
  findCommandAsync,
  safeSpawn,
  isCommandAvailable,
  findCommand,
  collectUntrackedIgnoredIds,
  collectTrackedFiles,
  loadPiLensGlobalConfig,
  resolvePiLensFlag,
  ephemeralStagingRoot,
  isEphemeralCheckoutRoot,
  getProjectDataDir,
  sweepDeadEphemeralDataDirs,
  resetProjectDataDirSessionState,
  drainProjectDataDirMigrations,
  displayProjectDataPath,
  getGlobalPiLensDir,
  EXCLUDED_DIRS,
  getProjectIgnoreMatcher,
  isPathIgnoredByProject,
  isRecordableProjectPath,
  getProjectIgnoreGlobs,
  isExcludedDirName,
  getExcludedDirGlobs,
  getKnipIgnorePatterns,
  isTestFile
};
/*! Bundled license information:

safe-buffer/index.js:
  (*! safe-buffer. MIT License. Feross Aboukhadijeh <https://feross.org/opensource> *)
*/