zx
Version: 
A tool for writing better scripts
890 lines (886 loc) • 26.2 kB
JavaScript
"use strict";
const {
  __spreadValues,
  __export,
  __toESM,
  __toCommonJS,
  __async,
  __await,
  __asyncGenerator,
  __forAwait
} = require('./esblib.cjs');
// src/core.ts
var core_exports = {};
__export(core_exports, {
  $: () => $,
  ProcessOutput: () => ProcessOutput,
  ProcessPromise: () => ProcessPromise,
  cd: () => cd,
  defaults: () => defaults,
  kill: () => kill,
  log: () => import_util2.log,
  resolveDefaults: () => resolveDefaults,
  syncProcessCwd: () => syncProcessCwd,
  useBash: () => useBash,
  usePowerShell: () => usePowerShell,
  usePwsh: () => usePwsh,
  within: () => within
});
module.exports = __toCommonJS(core_exports);
var import_node_child_process = require("child_process");
var import_node_async_hooks = require("async_hooks");
var import_node_fs = __toESM(require("fs"), 1);
var import_node_util = require("util");
var import_node_os = require("os");
var import_node_events = require("events");
// src/error.ts
var EXIT_CODES = {
  2: "Misuse of shell builtins",
  126: "Invoked command cannot execute",
  127: "Command not found",
  128: "Invalid exit argument",
  129: "Hangup",
  130: "Interrupt",
  131: "Quit and dump core",
  132: "Illegal instruction",
  133: "Trace/breakpoint trap",
  134: "Process aborted",
  135: 'Bus error: "access to undefined portion of memory object"',
  136: 'Floating point exception: "erroneous arithmetic operation"',
  137: "Kill (terminate immediately)",
  138: "User-defined 1",
  139: "Segmentation violation",
  140: "User-defined 2",
  141: "Write to pipe with no one reading",
  142: "Signal raised by alarm",
  143: "Termination (request to terminate)",
  145: "Child process terminated, stopped (or continued*)",
  146: "Continue if stopped",
  147: "Stop executing temporarily",
  148: "Terminal stop signal",
  149: 'Background process attempting to read from tty ("in")',
  150: 'Background process attempting to write to tty ("out")',
  151: "Urgent data available on socket",
  152: "CPU time limit exceeded",
  153: "File size limit exceeded",
  154: 'Signal raised by timer counting virtual time: "virtual timer expired"',
  155: "Profiling timer expired",
  157: "Pollable event",
  159: "Bad syscall"
};
var ERRNO_CODES = {
  0: "Success",
  1: "Not super-user",
  2: "No such file or directory",
  3: "No such process",
  4: "Interrupted system call",
  5: "I/O error",
  6: "No such device or address",
  7: "Arg list too long",
  8: "Exec format error",
  9: "Bad file number",
  10: "No children",
  11: "No more processes",
  12: "Not enough core",
  13: "Permission denied",
  14: "Bad address",
  15: "Block device required",
  16: "Mount device busy",
  17: "File exists",
  18: "Cross-device link",
  19: "No such device",
  20: "Not a directory",
  21: "Is a directory",
  22: "Invalid argument",
  23: "Too many open files in system",
  24: "Too many open files",
  25: "Not a typewriter",
  26: "Text file busy",
  27: "File too large",
  28: "No space left on device",
  29: "Illegal seek",
  30: "Read only file system",
  31: "Too many links",
  32: "Broken pipe",
  33: "Math arg out of domain of func",
  34: "Math result not representable",
  35: "File locking deadlock error",
  36: "File or path name too long",
  37: "No record locks available",
  38: "Function not implemented",
  39: "Directory not empty",
  40: "Too many symbolic links",
  42: "No message of desired type",
  43: "Identifier removed",
  44: "Channel number out of range",
  45: "Level 2 not synchronized",
  46: "Level 3 halted",
  47: "Level 3 reset",
  48: "Link number out of range",
  49: "Protocol driver not attached",
  50: "No CSI structure available",
  51: "Level 2 halted",
  52: "Invalid exchange",
  53: "Invalid request descriptor",
  54: "Exchange full",
  55: "No anode",
  56: "Invalid request code",
  57: "Invalid slot",
  59: "Bad font file fmt",
  60: "Device not a stream",
  61: "No data (for no delay io)",
  62: "Timer expired",
  63: "Out of streams resources",
  64: "Machine is not on the network",
  65: "Package not installed",
  66: "The object is remote",
  67: "The link has been severed",
  68: "Advertise error",
  69: "Srmount error",
  70: "Communication error on send",
  71: "Protocol error",
  72: "Multihop attempted",
  73: "Cross mount point (not really error)",
  74: "Trying to read unreadable message",
  75: "Value too large for defined data type",
  76: "Given log. name not unique",
  77: "f.d. invalid for this operation",
  78: "Remote address changed",
  79: "Can   access a needed shared lib",
  80: "Accessing a corrupted shared lib",
  81: ".lib section in a.out corrupted",
  82: "Attempting to link in too many libs",
  83: "Attempting to exec a shared library",
  84: "Illegal byte sequence",
  86: "Streams pipe error",
  87: "Too many users",
  88: "Socket operation on non-socket",
  89: "Destination address required",
  90: "Message too long",
  91: "Protocol wrong type for socket",
  92: "Protocol not available",
  93: "Unknown protocol",
  94: "Socket type not supported",
  95: "Not supported",
  96: "Protocol family not supported",
  97: "Address family not supported by protocol family",
  98: "Address already in use",
  99: "Address not available",
  100: "Network interface is not configured",
  101: "Network is unreachable",
  102: "Connection reset by network",
  103: "Connection aborted",
  104: "Connection reset by peer",
  105: "No buffer space available",
  106: "Socket is already connected",
  107: "Socket is not connected",
  108: "Can't send after socket shutdown",
  109: "Too many references",
  110: "Connection timed out",
  111: "Connection refused",
  112: "Host is down",
  113: "Host is unreachable",
  114: "Socket already connected",
  115: "Connection already in progress",
  116: "Stale file handle",
  122: "Quota exceeded",
  123: "No medium (in tape drive)",
  125: "Operation canceled",
  130: "Previous owner died",
  131: "State not recoverable"
};
function getErrnoMessage(errno) {
  return ERRNO_CODES[-errno] || "Unknown error";
}
function getExitCodeInfo(exitCode) {
  return EXIT_CODES[exitCode];
}
var formatExitMessage = (code, signal, stderr, from) => {
  let message = `exit code: ${code}`;
  if (code != 0 || signal != null) {
    message = `${stderr || "\n"}    at ${from}`;
    message += `
    exit code: ${code}${getExitCodeInfo(code) ? " (" + getExitCodeInfo(code) + ")" : ""}`;
    if (signal != null) {
      message += `
    signal: ${signal}`;
    }
  }
  return message;
};
var formatErrorMessage = (err, from) => {
  return `${err.message}
    errno: ${err.errno} (${getErrnoMessage(err.errno)})
    code: ${err.code}
    at ${from}`;
};
function getCallerLocation(err = new Error("zx error")) {
  return getCallerLocationFromString(err.stack);
}
function getCallerLocationFromString(stackString = "unknown") {
  var _a;
  return ((_a = stackString.split(/^\s*(at\s)?/m).filter((s) => s == null ? void 0 : s.includes(":"))[2]) == null ? void 0 : _a.trim()) || stackString;
}
// src/core.ts
var import_vendor_core = require("./vendor-core.cjs");
var import_util = require("./util.cjs");
var import_util2 = require("./util.cjs");
var CWD = Symbol("processCwd");
var SYNC = Symbol("syncExec");
var EOL = Buffer.from(import_node_os.EOL);
var BR_CC = "\n".charCodeAt(0);
var SIGTERM = "SIGTERM";
var ENV_PREFIX = "ZX_";
var storage = new import_node_async_hooks.AsyncLocalStorage();
function getStore() {
  return storage.getStore() || defaults;
}
function within(callback) {
  return storage.run(__spreadValues({}, getStore()), callback);
}
var defaults = resolveDefaults({
  [CWD]: process.cwd(),
  [SYNC]: false,
  verbose: false,
  env: process.env,
  sync: false,
  shell: true,
  stdio: "pipe",
  nothrow: false,
  quiet: false,
  prefix: "",
  postfix: "",
  detached: false,
  preferLocal: false,
  spawn: import_node_child_process.spawn,
  spawnSync: import_node_child_process.spawnSync,
  log: import_util.log,
  kill,
  killSignal: SIGTERM,
  timeoutSignal: SIGTERM
});
var $ = new Proxy(
  function(pieces, ...args) {
    const snapshot = getStore();
    if (!Array.isArray(pieces)) {
      return function(...args2) {
        const self = this;
        return within(
          () => Object.assign($, snapshot, pieces).apply(self, args2)
        );
      };
    }
    const from = getCallerLocation();
    if (pieces.some((p) => p == void 0))
      throw new Error(`Malformed command at ${from}`);
    checkShell();
    checkQuote();
    let resolve, reject;
    const process2 = new ProcessPromise((...args2) => [resolve, reject] = args2);
    const cmd = (0, import_vendor_core.buildCmd)(
      $.quote,
      pieces,
      args
    );
    const sync = snapshot[SYNC];
    process2._bind(
      cmd,
      from,
      resolve,
      (v) => {
        reject(v);
        if (sync) throw v;
      },
      snapshot
    );
    if (!process2.isHalted() || sync) process2.run();
    return sync ? process2.output : process2;
  },
  {
    set(_, key, value) {
      const target = key in Function.prototype ? _ : getStore();
      Reflect.set(target, key === "sync" ? SYNC : key, value);
      return true;
    },
    get(_, key) {
      if (key === "sync") return $({ sync: true });
      const target = key in Function.prototype ? _ : getStore();
      return Reflect.get(target, key);
    }
  }
);
var _ProcessPromise = class _ProcessPromise extends Promise {
  constructor() {
    super(...arguments);
    this._stage = "initial";
    this._id = (0, import_util.randomId)();
    this._command = "";
    this._from = "";
    this._snapshot = getStore();
    this._piped = false;
    this._ee = new import_node_events.EventEmitter();
    this._stdin = new import_vendor_core.VoidStream();
    this._zurk = null;
    this._output = null;
    this._reject = import_util.noop;
    this._resolve = import_util.noop;
    // Stream-like API
    this.writable = true;
  }
  _bind(cmd, from, resolve, reject, options) {
    this._command = cmd;
    this._from = from;
    this._resolve = resolve;
    this._reject = reject;
    this._snapshot = __spreadValues({ ac: new AbortController() }, options);
    if (this._snapshot.halt) this._stage = "halted";
  }
  run() {
    var _a, _b, _c, _d, _e, _f, _g;
    if (this.isRunning() || this.isSettled()) return this;
    this._stage = "running";
    (_a = this._pipedFrom) == null ? void 0 : _a.run();
    const self = this;
    const $2 = self._snapshot;
    const id = self.id;
    const sync = $2[SYNC];
    const timeout = (_b = self._timeout) != null ? _b : $2.timeout;
    const timeoutSignal = (_c = self._timeoutSignal) != null ? _c : $2.timeoutSignal;
    if ($2.preferLocal) {
      const dirs = $2.preferLocal === true ? [$2.cwd, $2[CWD]] : [$2.preferLocal].flat();
      $2.env = (0, import_util.preferLocalBin)($2.env, ...dirs);
    }
    $2.log({
      kind: "cmd",
      cmd: self.cmd,
      verbose: self.isVerbose(),
      id
    });
    this._zurk = (0, import_vendor_core.exec)({
      sync,
      id,
      cmd: self.fullCmd,
      cwd: (_d = $2.cwd) != null ? _d : $2[CWD],
      input: (_f = (_e = $2.input) == null ? void 0 : _e.stdout) != null ? _f : $2.input,
      ac: $2.ac,
      signal: $2.signal,
      shell: (0, import_util.isString)($2.shell) ? $2.shell : true,
      env: $2.env,
      spawn: $2.spawn,
      spawnSync: $2.spawnSync,
      store: $2.store,
      stdin: self._stdin,
      stdio: (_g = self._stdio) != null ? _g : $2.stdio,
      detached: $2.detached,
      ee: self._ee,
      run: (cb) => cb(),
      on: {
        start: () => {
          !sync && timeout && self.timeout(timeout, timeoutSignal);
        },
        stdout: (data) => {
          if (self._piped) return;
          $2.log({ kind: "stdout", data, verbose: self.isVerbose(), id });
        },
        stderr: (data) => {
          $2.log({ kind: "stderr", data, verbose: !self.isQuiet(), id });
        },
        end: (data, c) => {
          const { error, status, signal, duration, ctx } = data;
          const { stdout, stderr, stdall } = ctx.store;
          const dto = __spreadValues({
            code: () => status,
            signal: () => signal,
            duration: () => duration,
            stdout: (0, import_util.once)(() => (0, import_util.bufArrJoin)(stdout)),
            stderr: (0, import_util.once)(() => (0, import_util.bufArrJoin)(stderr)),
            stdall: (0, import_util.once)(() => (0, import_util.bufArrJoin)(stdall)),
            message: (0, import_util.once)(() => ProcessOutput.getExitMessage(
              status,
              signal,
              dto.stderr(),
              self._from
            ))
          }, error && {
            code: () => null,
            signal: () => null,
            message: () => ProcessOutput.getErrorMessage(error, self._from)
          });
          if (stdout.length && (0, import_util.getLast)((0, import_util.getLast)(stdout)) !== BR_CC) c.on.stdout(EOL, c);
          if (stderr.length && (0, import_util.getLast)((0, import_util.getLast)(stderr)) !== BR_CC) c.on.stderr(EOL, c);
          $2.log({ kind: "end", signal, exitCode: status, duration, error, verbose: self.isVerbose(), id });
          const output = self._output = new ProcessOutput(dto);
          if (error || status !== 0 && !self.isNothrow()) {
            self._stage = "rejected";
            self._reject(output);
          } else {
            self._stage = "fulfilled";
            self._resolve(output);
          }
        }
      }
    });
    return this;
  }
  _pipe(source, dest, ...args) {
    if ((0, import_util.isStringLiteral)(dest, ...args))
      return this.pipe[source](
        $({
          halt: true,
          ac: this._snapshot.ac,
          signal: this._snapshot.signal
        })(dest, ...args)
      );
    this._piped = true;
    const ee = this._ee;
    const from = new import_vendor_core.VoidStream();
    const fill = () => {
      for (const chunk of this._zurk.store[source]) from.write(chunk);
      return true;
    };
    const fillEnd = () => this.isSettled() && fill() && from.end();
    if (!this.isSettled()) {
      const onData = (chunk) => from.write(chunk);
      ee.once(source, () => {
        fill();
        ee.on(source, onData);
      }).once("end", () => {
        ee.removeListener(source, onData);
        from.end();
      });
    }
    if ((0, import_util.isString)(dest)) dest = import_node_fs.default.createWriteStream(dest);
    if (dest instanceof _ProcessPromise) {
      dest._pipedFrom = this;
      if (dest.isHalted() && this.isHalted()) {
        ee.once("start", () => from.pipe(dest.run()._stdin));
      } else {
        this.catch((e) => dest.isNothrow() ? import_util.noop : dest._reject(e));
        from.pipe(dest.run()._stdin);
      }
      fillEnd();
      return dest;
    }
    from.once("end", () => dest.emit("end-piped-from")).pipe(dest);
    fillEnd();
    return promisifyStream(dest, this);
  }
  abort(reason) {
    var _a, _b;
    if (this.signal !== ((_a = this._snapshot.ac) == null ? void 0 : _a.signal))
      throw new Error("The signal is controlled by another process.");
    if (!this.child)
      throw new Error("Trying to abort a process without creating one.");
    (_b = this._zurk) == null ? void 0 : _b.ac.abort(reason);
  }
  kill(signal = $.killSignal) {
    if (!this.child)
      throw new Error("Trying to kill a process without creating one.");
    if (!this.child.pid) throw new Error("The process pid is undefined.");
    return $.kill(this.child.pid, signal);
  }
  /**
   *  @deprecated Use $({halt: true})`cmd` instead.
   */
  halt() {
    return this;
  }
  // Getters
  get id() {
    return this._id;
  }
  get pid() {
    var _a;
    return (_a = this.child) == null ? void 0 : _a.pid;
  }
  get cmd() {
    return this._command;
  }
  get fullCmd() {
    return this._snapshot.prefix + this.cmd + this._snapshot.postfix;
  }
  get child() {
    var _a;
    return (_a = this._zurk) == null ? void 0 : _a.child;
  }
  get stdin() {
    var _a;
    return (_a = this.child) == null ? void 0 : _a.stdin;
  }
  get stdout() {
    var _a;
    return (_a = this.child) == null ? void 0 : _a.stdout;
  }
  get stderr() {
    var _a;
    return (_a = this.child) == null ? void 0 : _a.stderr;
  }
  get exitCode() {
    return this.then(
      (p) => p.exitCode,
      (p) => p.exitCode
    );
  }
  get signal() {
    var _a;
    return this._snapshot.signal || ((_a = this._snapshot.ac) == null ? void 0 : _a.signal);
  }
  get output() {
    return this._output;
  }
  get stage() {
    return this._stage;
  }
  // Configurators
  stdio(stdin, stdout = "pipe", stderr = "pipe") {
    this._stdio = [stdin, stdout, stderr];
    return this;
  }
  nothrow(v = true) {
    this._nothrow = v;
    return this;
  }
  quiet(v = true) {
    this._quiet = v;
    return this;
  }
  verbose(v = true) {
    this._verbose = v;
    return this;
  }
  timeout(d, signal = this._timeoutSignal || $.timeoutSignal) {
    if (this.isSettled()) return this;
    this._timeout = (0, import_util.parseDuration)(d);
    this._timeoutSignal = signal;
    if (this._timeoutId) clearTimeout(this._timeoutId);
    if (this._timeout && this.isRunning()) {
      this._timeoutId = setTimeout(
        () => this.kill(this._timeoutSignal),
        this._timeout
      );
      this.finally(() => clearTimeout(this._timeoutId)).catch(import_util.noop);
    }
    return this;
  }
  // Output formatters
  json() {
    return this.then((p) => p.json());
  }
  text(encoding) {
    return this.then((p) => p.text(encoding));
  }
  lines() {
    return this.then((p) => p.lines());
  }
  buffer() {
    return this.then((p) => p.buffer());
  }
  blob(type) {
    return this.then((p) => p.blob(type));
  }
  // Status checkers
  isQuiet() {
    var _a;
    return (_a = this._quiet) != null ? _a : this._snapshot.quiet;
  }
  isVerbose() {
    var _a;
    return ((_a = this._verbose) != null ? _a : this._snapshot.verbose) && !this.isQuiet();
  }
  isNothrow() {
    var _a;
    return (_a = this._nothrow) != null ? _a : this._snapshot.nothrow;
  }
  isHalted() {
    return this.stage === "halted";
  }
  isSettled() {
    return !!this.output;
  }
  isRunning() {
    return this.stage === "running";
  }
  // Promise API
  then(onfulfilled, onrejected) {
    return super.then(onfulfilled, onrejected);
  }
  catch(onrejected) {
    return super.catch(onrejected);
  }
  // Async iterator API
  [Symbol.asyncIterator]() {
    return __asyncGenerator(this, null, function* () {
      let last;
      const getLines = (chunk) => {
        const lines = ((last || "") + (0, import_util.bufToString)(chunk)).split("\n");
        last = lines.pop();
        return lines;
      };
      for (const chunk of this._zurk.store.stdout) {
        const lines = getLines(chunk);
        for (const line of lines) yield line;
      }
      try {
        for (var iter = __forAwait(this.stdout[Symbol.asyncIterator] ? this.stdout : import_vendor_core.VoidStream.from(this.stdout)), more, temp, error; more = !(temp = yield new __await(iter.next())).done; more = false) {
          const chunk = temp.value;
          const lines = getLines(chunk);
          for (const line of lines) yield line;
        }
      } catch (temp) {
        error = [temp];
      } finally {
        try {
          more && (temp = iter.return) && (yield new __await(temp.call(iter)));
        } finally {
          if (error)
            throw error[0];
        }
      }
      if (last) yield last;
      if ((yield new __await(this.exitCode)) !== 0) throw this._output;
    });
  }
  emit(event, ...args) {
    return this;
  }
  on(event, cb) {
    this._stdin.on(event, cb);
    return this;
  }
  once(event, cb) {
    this._stdin.once(event, cb);
    return this;
  }
  write(data, encoding, cb) {
    this._stdin.write(data, encoding, cb);
    return this;
  }
  end(chunk, cb) {
    this._stdin.end(chunk, cb);
    return this;
  }
  removeListener(event, cb) {
    this._stdin.removeListener(event, cb);
    return this;
  }
};
Object.defineProperty(_ProcessPromise.prototype, "pipe", { get() {
  const self = this;
  const getPipeMethod = (kind) => function(dest, ...args) {
    return self._pipe.call(self, kind, dest, ...args);
  };
  const stdout = getPipeMethod("stdout");
  const stderr = getPipeMethod("stderr");
  const stdall = getPipeMethod("stdall");
  return Object.assign(stdout, { stderr, stdout, stdall });
} });
var ProcessPromise = _ProcessPromise;
var ProcessOutput = class extends Error {
  constructor(code, signal = null, stdout = "", stderr = "", combined = "", message = "", duration = 0) {
    super(message);
    this._code = null;
    this._signal = signal;
    this._stdout = stdout;
    this._stderr = stderr;
    this._combined = combined;
    this._duration = duration;
    if (code !== null && typeof code === "object") {
      Object.defineProperties(this, {
        _code: { get: code.code },
        _signal: { get: code.signal },
        _duration: { get: code.duration },
        _stdout: { get: code.stdout },
        _stderr: { get: code.stderr },
        _combined: { get: code.stdall },
        message: { get: code.message }
      });
    } else {
      this._code = code;
    }
  }
  toString() {
    return this._combined;
  }
  json() {
    return JSON.parse(this._combined);
  }
  buffer() {
    return Buffer.from(this._combined);
  }
  blob(type = "text/plain") {
    if (!globalThis.Blob)
      throw new Error(
        "Blob is not supported in this environment. Provide a polyfill"
      );
    return new Blob([this.buffer()], { type });
  }
  text(encoding = "utf8") {
    return encoding === "utf8" ? this.toString() : this.buffer().toString(encoding);
  }
  lines() {
    return this.valueOf().split(/\r?\n/);
  }
  valueOf() {
    return this._combined.trim();
  }
  get stdout() {
    return this._stdout;
  }
  get stderr() {
    return this._stderr;
  }
  get exitCode() {
    return this._code;
  }
  get signal() {
    return this._signal;
  }
  get duration() {
    return this._duration;
  }
  [import_node_util.inspect.custom]() {
    let stringify = (s, c) => s.length === 0 ? "''" : c((0, import_node_util.inspect)(s));
    return `ProcessOutput {
  stdout: ${stringify(this.stdout, import_vendor_core.chalk.green)},
  stderr: ${stringify(this.stderr, import_vendor_core.chalk.red)},
  signal: ${(0, import_node_util.inspect)(this.signal)},
  exitCode: ${(this.exitCode === 0 ? import_vendor_core.chalk.green : import_vendor_core.chalk.red)(this.exitCode)}${getExitCodeInfo(this.exitCode) ? import_vendor_core.chalk.grey(" (" + getExitCodeInfo(this.exitCode) + ")") : ""},
  duration: ${this.duration}
}`;
  }
};
ProcessOutput.getExitMessage = formatExitMessage;
ProcessOutput.getErrorMessage = formatErrorMessage;
function usePowerShell() {
  $.shell = import_vendor_core.which.sync("powershell.exe");
  $.prefix = "";
  $.postfix = "; exit $LastExitCode";
  $.quote = import_util.quotePowerShell;
}
function usePwsh() {
  $.shell = import_vendor_core.which.sync("pwsh");
  $.prefix = "";
  $.postfix = "; exit $LastExitCode";
  $.quote = import_util.quotePowerShell;
}
function useBash() {
  $.shell = import_vendor_core.which.sync("bash");
  $.prefix = "set -euo pipefail;";
  $.postfix = "";
  $.quote = import_util.quote;
}
try {
  useBash();
} catch (err) {
}
function checkShell() {
  if (!$.shell)
    throw new Error(`No shell is available: https://\xEF.at/zx-no-shell`);
}
function checkQuote() {
  if (!$.quote)
    throw new Error("No quote function is defined: https://\xEF.at/no-quote-func");
}
var cwdSyncHook;
function syncProcessCwd(flag = true) {
  cwdSyncHook = cwdSyncHook || (0, import_node_async_hooks.createHook)({
    init: syncCwd,
    before: syncCwd,
    promiseResolve: syncCwd,
    after: syncCwd,
    destroy: syncCwd
  });
  if (flag) cwdSyncHook.enable();
  else cwdSyncHook.disable();
}
function syncCwd() {
  if ($[CWD] != process.cwd()) process.chdir($[CWD]);
}
function cd(dir) {
  if (dir instanceof ProcessOutput) {
    dir = dir.toString().trim();
  }
  $.log({ kind: "cd", dir, verbose: !$.quiet && $.verbose });
  process.chdir(dir);
  $[CWD] = process.cwd();
}
function kill(_0) {
  return __async(this, arguments, function* (pid, signal = $.killSignal) {
    const children = yield import_vendor_core.ps.tree({ pid, recursive: true });
    for (const p of children) {
      try {
        process.kill(+p.pid, signal);
      } catch (e) {
      }
    }
    try {
      process.kill(-pid, signal);
    } catch (e) {
      try {
        process.kill(+pid, signal);
      } catch (e2) {
      }
    }
  });
}
var promisifyStream = (stream, from) => (0, import_util.proxyOverride)(stream, {
  then(res = import_util.noop, rej = import_util.noop) {
    return new Promise(
      (_res, _rej) => stream.once("error", (e) => _rej(rej(e))).once(
        "finish",
        () => _res(res((0, import_util.proxyOverride)(stream, from._output)))
      ).once(
        "end-piped-from",
        () => _res(res((0, import_util.proxyOverride)(stream, from._output)))
      )
    );
  },
  run() {
    return from.run();
  },
  _pipedFrom: from,
  pipe(...args) {
    const piped = stream.pipe.apply(stream, args);
    return piped instanceof ProcessPromise ? piped : promisifyStream(piped, from);
  }
});
function resolveDefaults(defs = defaults, prefix = ENV_PREFIX, env = process.env) {
  const allowed = /* @__PURE__ */ new Set([
    "cwd",
    "preferLocal",
    "detached",
    "verbose",
    "quiet",
    "timeout",
    "timeoutSignal",
    "killSignal",
    "prefix",
    "postfix",
    "shell"
  ]);
  return Object.entries(env).reduce((m, [k, v]) => {
    if (v && k.startsWith(prefix)) {
      const _k = (0, import_util.toCamelCase)(k.slice(prefix.length));
      const _v = (0, import_util.parseBool)(v);
      if (allowed.has(_k)) m[_k] = _v;
    }
    return m;
  }, defs);
}
/* c8 ignore next 100 */
// Annotate the CommonJS export names for ESM import in node:
0 && (module.exports = {
  $,
  ProcessOutput,
  ProcessPromise,
  cd,
  defaults,
  kill,
  log,
  resolveDefaults,
  syncProcessCwd,
  useBash,
  usePowerShell,
  usePwsh,
  within
});