@threadbase-sh/streamer 1.29.1 → 1.30.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/cli.cjs CHANGED
@@ -26158,7 +26158,7 @@ var require_thread_stream = __commonJS({
26158
26158
  var { version: version2 } = require_package();
26159
26159
  var { EventEmitter: EventEmitter6 } = require("events");
26160
26160
  var { Worker } = require("worker_threads");
26161
- var { join: join26 } = require("path");
26161
+ var { join: join28 } = require("path");
26162
26162
  var { pathToFileURL } = require("url");
26163
26163
  var { wait } = require_wait();
26164
26164
  var {
@@ -26209,7 +26209,7 @@ var require_thread_stream = __commonJS({
26209
26209
  function createWorker(stream, opts) {
26210
26210
  const { filename, workerData } = opts;
26211
26211
  const bundlerOverrides = "__bundlerPathsOverrides" in globalThis ? globalThis.__bundlerPathsOverrides : {};
26212
- const toExecute = bundlerOverrides["thread-stream-worker"] || join26(__dirname, "lib", "worker.js");
26212
+ const toExecute = bundlerOverrides["thread-stream-worker"] || join28(__dirname, "lib", "worker.js");
26213
26213
  const worker = new Worker(toExecute, {
26214
26214
  ...opts.workerOpts,
26215
26215
  name: opts.workerOpts?.name || "thread-stream",
@@ -26675,9 +26675,9 @@ var require_transport = __commonJS({
26675
26675
  "node_modules/pino/lib/transport.js"(exports2, module2) {
26676
26676
  "use strict";
26677
26677
  var { createRequire } = require("module");
26678
- var { existsSync: existsSync12 } = require("fs");
26678
+ var { existsSync: existsSync13 } = require("fs");
26679
26679
  var getCallers = require_caller();
26680
- var { join: join26, isAbsolute: isAbsolute3, sep: sep2 } = require("path");
26680
+ var { join: join28, isAbsolute: isAbsolute3, sep: sep2 } = require("path");
26681
26681
  var { fileURLToPath: fileURLToPath3 } = require("url");
26682
26682
  var sleep = require_atomic_sleep();
26683
26683
  var onExit = require_on_exit_leak_free();
@@ -26749,7 +26749,7 @@ var require_transport = __commonJS({
26749
26749
  return false;
26750
26750
  }
26751
26751
  }
26752
- return isAbsolute3(path2) && !existsSync12(path2);
26752
+ return isAbsolute3(path2) && !existsSync13(path2);
26753
26753
  }
26754
26754
  function stripQuotes(value) {
26755
26755
  const first = value[0];
@@ -26830,7 +26830,7 @@ var require_transport = __commonJS({
26830
26830
  throw new Error("only one of target or targets can be specified");
26831
26831
  }
26832
26832
  if (targets) {
26833
- target = bundlerOverrides["pino-worker"] || join26(__dirname, "worker.js");
26833
+ target = bundlerOverrides["pino-worker"] || join28(__dirname, "worker.js");
26834
26834
  options.targets = targets.filter((dest) => dest.target).map((dest) => {
26835
26835
  return {
26836
26836
  ...dest,
@@ -26848,7 +26848,7 @@ var require_transport = __commonJS({
26848
26848
  });
26849
26849
  });
26850
26850
  } else if (pipeline2) {
26851
- target = bundlerOverrides["pino-worker"] || join26(__dirname, "worker.js");
26851
+ target = bundlerOverrides["pino-worker"] || join28(__dirname, "worker.js");
26852
26852
  options.pipelines = [pipeline2.map((dest) => {
26853
26853
  return {
26854
26854
  ...dest,
@@ -26871,7 +26871,7 @@ var require_transport = __commonJS({
26871
26871
  return origin;
26872
26872
  }
26873
26873
  if (origin === "pino/file") {
26874
- return join26(__dirname, "..", "file.js");
26874
+ return join28(__dirname, "..", "file.js");
26875
26875
  }
26876
26876
  let fixTarget2;
26877
26877
  for (const filePath of callers) {
@@ -27852,7 +27852,7 @@ var require_safe_stable_stringify = __commonJS({
27852
27852
  return circularValue;
27853
27853
  }
27854
27854
  let res = "";
27855
- let join26 = ",";
27855
+ let join28 = ",";
27856
27856
  const originalIndentation = indentation;
27857
27857
  if (Array.isArray(value)) {
27858
27858
  if (value.length === 0) {
@@ -27866,7 +27866,7 @@ var require_safe_stable_stringify = __commonJS({
27866
27866
  indentation += spacer;
27867
27867
  res += `
27868
27868
  ${indentation}`;
27869
- join26 = `,
27869
+ join28 = `,
27870
27870
  ${indentation}`;
27871
27871
  }
27872
27872
  const maximumValuesToStringify = Math.min(value.length, maximumBreadth);
@@ -27874,13 +27874,13 @@ ${indentation}`;
27874
27874
  for (; i < maximumValuesToStringify - 1; i++) {
27875
27875
  const tmp2 = stringifyFnReplacer(String(i), value, stack, replacer, spacer, indentation);
27876
27876
  res += tmp2 !== void 0 ? tmp2 : "null";
27877
- res += join26;
27877
+ res += join28;
27878
27878
  }
27879
27879
  const tmp = stringifyFnReplacer(String(i), value, stack, replacer, spacer, indentation);
27880
27880
  res += tmp !== void 0 ? tmp : "null";
27881
27881
  if (value.length - 1 > maximumBreadth) {
27882
27882
  const removedKeys = value.length - maximumBreadth - 1;
27883
- res += `${join26}"... ${getItemCount(removedKeys)} not stringified"`;
27883
+ res += `${join28}"... ${getItemCount(removedKeys)} not stringified"`;
27884
27884
  }
27885
27885
  if (spacer !== "") {
27886
27886
  res += `
@@ -27901,7 +27901,7 @@ ${originalIndentation}`;
27901
27901
  let separator = "";
27902
27902
  if (spacer !== "") {
27903
27903
  indentation += spacer;
27904
- join26 = `,
27904
+ join28 = `,
27905
27905
  ${indentation}`;
27906
27906
  whitespace = " ";
27907
27907
  }
@@ -27915,13 +27915,13 @@ ${indentation}`;
27915
27915
  const tmp = stringifyFnReplacer(key2, value, stack, replacer, spacer, indentation);
27916
27916
  if (tmp !== void 0) {
27917
27917
  res += `${separator}${strEscape(key2)}:${whitespace}${tmp}`;
27918
- separator = join26;
27918
+ separator = join28;
27919
27919
  }
27920
27920
  }
27921
27921
  if (keyLength > maximumBreadth) {
27922
27922
  const removedKeys = keyLength - maximumBreadth;
27923
27923
  res += `${separator}"...":${whitespace}"${getItemCount(removedKeys)} not stringified"`;
27924
- separator = join26;
27924
+ separator = join28;
27925
27925
  }
27926
27926
  if (spacer !== "" && separator.length > 1) {
27927
27927
  res = `
@@ -27962,7 +27962,7 @@ ${originalIndentation}`;
27962
27962
  }
27963
27963
  const originalIndentation = indentation;
27964
27964
  let res = "";
27965
- let join26 = ",";
27965
+ let join28 = ",";
27966
27966
  if (Array.isArray(value)) {
27967
27967
  if (value.length === 0) {
27968
27968
  return "[]";
@@ -27975,7 +27975,7 @@ ${originalIndentation}`;
27975
27975
  indentation += spacer;
27976
27976
  res += `
27977
27977
  ${indentation}`;
27978
- join26 = `,
27978
+ join28 = `,
27979
27979
  ${indentation}`;
27980
27980
  }
27981
27981
  const maximumValuesToStringify = Math.min(value.length, maximumBreadth);
@@ -27983,13 +27983,13 @@ ${indentation}`;
27983
27983
  for (; i < maximumValuesToStringify - 1; i++) {
27984
27984
  const tmp2 = stringifyArrayReplacer(String(i), value[i], stack, replacer, spacer, indentation);
27985
27985
  res += tmp2 !== void 0 ? tmp2 : "null";
27986
- res += join26;
27986
+ res += join28;
27987
27987
  }
27988
27988
  const tmp = stringifyArrayReplacer(String(i), value[i], stack, replacer, spacer, indentation);
27989
27989
  res += tmp !== void 0 ? tmp : "null";
27990
27990
  if (value.length - 1 > maximumBreadth) {
27991
27991
  const removedKeys = value.length - maximumBreadth - 1;
27992
- res += `${join26}"... ${getItemCount(removedKeys)} not stringified"`;
27992
+ res += `${join28}"... ${getItemCount(removedKeys)} not stringified"`;
27993
27993
  }
27994
27994
  if (spacer !== "") {
27995
27995
  res += `
@@ -28002,7 +28002,7 @@ ${originalIndentation}`;
28002
28002
  let whitespace = "";
28003
28003
  if (spacer !== "") {
28004
28004
  indentation += spacer;
28005
- join26 = `,
28005
+ join28 = `,
28006
28006
  ${indentation}`;
28007
28007
  whitespace = " ";
28008
28008
  }
@@ -28011,7 +28011,7 @@ ${indentation}`;
28011
28011
  const tmp = stringifyArrayReplacer(key2, value[key2], stack, replacer, spacer, indentation);
28012
28012
  if (tmp !== void 0) {
28013
28013
  res += `${separator}${strEscape(key2)}:${whitespace}${tmp}`;
28014
- separator = join26;
28014
+ separator = join28;
28015
28015
  }
28016
28016
  }
28017
28017
  if (spacer !== "" && separator.length > 1) {
@@ -28069,20 +28069,20 @@ ${originalIndentation}`;
28069
28069
  indentation += spacer;
28070
28070
  let res2 = `
28071
28071
  ${indentation}`;
28072
- const join27 = `,
28072
+ const join29 = `,
28073
28073
  ${indentation}`;
28074
28074
  const maximumValuesToStringify = Math.min(value.length, maximumBreadth);
28075
28075
  let i = 0;
28076
28076
  for (; i < maximumValuesToStringify - 1; i++) {
28077
28077
  const tmp2 = stringifyIndent(String(i), value[i], stack, spacer, indentation);
28078
28078
  res2 += tmp2 !== void 0 ? tmp2 : "null";
28079
- res2 += join27;
28079
+ res2 += join29;
28080
28080
  }
28081
28081
  const tmp = stringifyIndent(String(i), value[i], stack, spacer, indentation);
28082
28082
  res2 += tmp !== void 0 ? tmp : "null";
28083
28083
  if (value.length - 1 > maximumBreadth) {
28084
28084
  const removedKeys = value.length - maximumBreadth - 1;
28085
- res2 += `${join27}"... ${getItemCount(removedKeys)} not stringified"`;
28085
+ res2 += `${join29}"... ${getItemCount(removedKeys)} not stringified"`;
28086
28086
  }
28087
28087
  res2 += `
28088
28088
  ${originalIndentation}`;
@@ -28098,16 +28098,16 @@ ${originalIndentation}`;
28098
28098
  return '"[Object]"';
28099
28099
  }
28100
28100
  indentation += spacer;
28101
- const join26 = `,
28101
+ const join28 = `,
28102
28102
  ${indentation}`;
28103
28103
  let res = "";
28104
28104
  let separator = "";
28105
28105
  let maximumPropertiesToStringify = Math.min(keyLength, maximumBreadth);
28106
28106
  if (isTypedArrayWithEntries(value)) {
28107
- res += stringifyTypedArray(value, join26, maximumBreadth);
28107
+ res += stringifyTypedArray(value, join28, maximumBreadth);
28108
28108
  keys = keys.slice(value.length);
28109
28109
  maximumPropertiesToStringify -= value.length;
28110
- separator = join26;
28110
+ separator = join28;
28111
28111
  }
28112
28112
  if (deterministic) {
28113
28113
  keys = sort(keys, comparator);
@@ -28118,13 +28118,13 @@ ${indentation}`;
28118
28118
  const tmp = stringifyIndent(key2, value[key2], stack, spacer, indentation);
28119
28119
  if (tmp !== void 0) {
28120
28120
  res += `${separator}${strEscape(key2)}: ${tmp}`;
28121
- separator = join26;
28121
+ separator = join28;
28122
28122
  }
28123
28123
  }
28124
28124
  if (keyLength > maximumBreadth) {
28125
28125
  const removedKeys = keyLength - maximumBreadth;
28126
28126
  res += `${separator}"...": "${getItemCount(removedKeys)} not stringified"`;
28127
- separator = join26;
28127
+ separator = join28;
28128
28128
  }
28129
28129
  if (separator !== "") {
28130
28130
  res = `
@@ -35847,17 +35847,17 @@ var require_logger = __commonJS({
35847
35847
  * Some optimizations are performed to avoid creating unnecessary objects and to keep runtime
35848
35848
  * overhead associated with resolving metadata as low as possible.
35849
35849
  */
35850
- static compose(logger2, metaOrFunc) {
35851
- if (logger2 instanceof _LoggerWithComposedMetadata) {
35852
- const contributors = appendToChain(logger2.contributors, metaOrFunc);
35850
+ static compose(logger3, metaOrFunc) {
35851
+ if (logger3 instanceof _LoggerWithComposedMetadata) {
35852
+ const contributors = appendToChain(logger3.contributors, metaOrFunc);
35853
35853
  if (contributors === void 0)
35854
- return logger2;
35855
- return new _LoggerWithComposedMetadata(logger2.parentLogger, contributors);
35854
+ return logger3;
35855
+ return new _LoggerWithComposedMetadata(logger3.parentLogger, contributors);
35856
35856
  } else {
35857
35857
  const contributors = appendToChain(void 0, metaOrFunc);
35858
35858
  if (contributors === void 0)
35859
- return logger2;
35860
- return new _LoggerWithComposedMetadata(logger2, contributors);
35859
+ return logger3;
35860
+ return new _LoggerWithComposedMetadata(logger3, contributors);
35861
35861
  }
35862
35862
  }
35863
35863
  constructor(parentLogger, contributors) {
@@ -36938,8 +36938,8 @@ var require_logging = __commonJS({
36938
36938
  return _logger;
36939
36939
  };
36940
36940
  exports2.getLogger = getLogger3;
36941
- var setLogger = (logger2) => {
36942
- _logger = logger2;
36941
+ var setLogger = (logger3) => {
36942
+ _logger = logger3;
36943
36943
  };
36944
36944
  exports2.setLogger = setLogger;
36945
36945
  var setLoggerVerbosity = (verbosity) => {
@@ -60048,8 +60048,8 @@ var require_src3 = __commonJS({
60048
60048
  throw new Error("Not available in this library. Use @grpc/proto-loader and loadPackageDefinition instead");
60049
60049
  };
60050
60050
  exports2.load = load;
60051
- var setLogger = (logger2) => {
60052
- logging.setLogger(logger2);
60051
+ var setLogger = (logger3) => {
60052
+ logging.setLogger(logger3);
60053
60053
  };
60054
60054
  exports2.setLogger = setLogger;
60055
60055
  var setLogVerbosity = (verbosity) => {
@@ -100406,11 +100406,11 @@ var require_out = __commonJS({
100406
100406
  async.read(path2, getSettings(optionsOrSettingsOrCallback), callback);
100407
100407
  }
100408
100408
  exports2.stat = stat10;
100409
- function statSync10(path2, optionsOrSettings) {
100409
+ function statSync11(path2, optionsOrSettings) {
100410
100410
  const settings = getSettings(optionsOrSettings);
100411
100411
  return sync.read(path2, settings);
100412
100412
  }
100413
- exports2.statSync = statSync10;
100413
+ exports2.statSync = statSync11;
100414
100414
  function getSettings(settingsOrOptions = {}) {
100415
100415
  if (settingsOrOptions instanceof settings_1.default) {
100416
100416
  return settingsOrOptions;
@@ -123538,8 +123538,8 @@ function darwinPlistPath() {
123538
123538
  return `${process.env.HOME}/Library/LaunchAgents/${resolveLoadedLabel()}.plist`;
123539
123539
  }
123540
123540
  function getLogPaths() {
123541
- const dir = (0, import_node_path24.join)(installDir(), "logs");
123542
- return { stdout: (0, import_node_path24.join)(dir, "stdout.log"), stderr: (0, import_node_path24.join)(dir, "stderr.log") };
123541
+ const dir = (0, import_node_path25.join)(installDir(), "logs");
123542
+ return { stdout: (0, import_node_path25.join)(dir, "stdout.log"), stderr: (0, import_node_path25.join)(dir, "stderr.log") };
123543
123543
  }
123544
123544
  function getAgentPid() {
123545
123545
  try {
@@ -123559,12 +123559,12 @@ function getAgentPid() {
123559
123559
  return null;
123560
123560
  }
123561
123561
  }
123562
- var import_node_child_process4, import_node_path24, BREW_LAUNCHD_LABEL2;
123562
+ var import_node_child_process4, import_node_path25, BREW_LAUNCHD_LABEL2;
123563
123563
  var init_launchd = __esm({
123564
123564
  "src/lifecycle/launchd.ts"() {
123565
123565
  "use strict";
123566
123566
  import_node_child_process4 = require("child_process");
123567
- import_node_path24 = require("path");
123567
+ import_node_path25 = require("path");
123568
123568
  init_constants();
123569
123569
  BREW_LAUNCHD_LABEL2 = "homebrew.mxcl.tb-streamer";
123570
123570
  }
@@ -123589,9 +123589,9 @@ var init_marker_schema = __esm({
123589
123589
 
123590
123590
  // src/lifecycle/marker.ts
123591
123591
  function readMarker() {
123592
- if (!(0, import_node_fs20.existsSync)(markerPath())) return null;
123592
+ if (!(0, import_node_fs21.existsSync)(markerPath())) return null;
123593
123593
  try {
123594
- const raw2 = (0, import_node_fs20.readFileSync)(markerPath(), "utf8");
123594
+ const raw2 = (0, import_node_fs21.readFileSync)(markerPath(), "utf8");
123595
123595
  const parsed = JSON.parse(raw2);
123596
123596
  return MarkerSchema.parse(parsed);
123597
123597
  } catch (err) {
@@ -123603,21 +123603,21 @@ function readMarker() {
123603
123603
  }
123604
123604
  function writeMarker(marker) {
123605
123605
  MarkerSchema.parse(marker);
123606
- (0, import_node_fs20.mkdirSync)((0, import_node_path25.dirname)(markerPath()), { recursive: true });
123606
+ (0, import_node_fs21.mkdirSync)((0, import_node_path26.dirname)(markerPath()), { recursive: true });
123607
123607
  const tmp = `${markerPath()}.tmp`;
123608
- (0, import_node_fs20.writeFileSync)(tmp, `${JSON.stringify(marker, null, 2)}
123608
+ (0, import_node_fs21.writeFileSync)(tmp, `${JSON.stringify(marker, null, 2)}
123609
123609
  `, { mode: 384 });
123610
- (0, import_node_fs20.renameSync)(tmp, markerPath());
123610
+ (0, import_node_fs21.renameSync)(tmp, markerPath());
123611
123611
  }
123612
123612
  function clearMarker() {
123613
- if ((0, import_node_fs20.existsSync)(markerPath())) (0, import_node_fs20.rmSync)(markerPath());
123613
+ if ((0, import_node_fs21.existsSync)(markerPath())) (0, import_node_fs21.rmSync)(markerPath());
123614
123614
  }
123615
- var import_node_fs20, import_node_path25, log3;
123615
+ var import_node_fs21, import_node_path26, log3;
123616
123616
  var init_marker = __esm({
123617
123617
  "src/lifecycle/marker.ts"() {
123618
123618
  "use strict";
123619
- import_node_fs20 = require("fs");
123620
- import_node_path25 = require("path");
123619
+ import_node_fs21 = require("fs");
123620
+ import_node_path26 = require("path");
123621
123621
  init_logger();
123622
123622
  init_constants();
123623
123623
  init_marker_schema();
@@ -123818,9 +123818,9 @@ The supervised prod streamer is already holding port ${prodPort}.
123818
123818
  // src/lifecycle/prefs.ts
123819
123819
  function readPrefs() {
123820
123820
  const path2 = prefsPath();
123821
- if (!(0, import_node_fs22.existsSync)(path2)) return { repos: {} };
123821
+ if (!(0, import_node_fs23.existsSync)(path2)) return { repos: {} };
123822
123822
  try {
123823
- return PrefsSchema.parse(JSON.parse((0, import_node_fs22.readFileSync)(path2, "utf8")));
123823
+ return PrefsSchema.parse(JSON.parse((0, import_node_fs23.readFileSync)(path2, "utf8")));
123824
123824
  } catch (err) {
123825
123825
  log5.warn(`prefs at ${path2} are malformed; treating as empty`, {
123826
123826
  error: err instanceof Error ? err.message : String(err)
@@ -123830,11 +123830,11 @@ function readPrefs() {
123830
123830
  }
123831
123831
  function savePrefs(p2) {
123832
123832
  const path2 = prefsPath();
123833
- (0, import_node_fs22.mkdirSync)((0, import_node_path26.dirname)(path2), { recursive: true });
123833
+ (0, import_node_fs23.mkdirSync)((0, import_node_path27.dirname)(path2), { recursive: true });
123834
123834
  const tmp = `${path2}.tmp`;
123835
- (0, import_node_fs22.writeFileSync)(tmp, `${JSON.stringify(p2, null, 2)}
123835
+ (0, import_node_fs23.writeFileSync)(tmp, `${JSON.stringify(p2, null, 2)}
123836
123836
  `, { mode: 384 });
123837
- (0, import_node_fs22.renameSync)(tmp, path2);
123837
+ (0, import_node_fs23.renameSync)(tmp, path2);
123838
123838
  }
123839
123839
  function writePrefForRepo(repoToplevel, choice) {
123840
123840
  const p2 = readPrefs();
@@ -123855,14 +123855,14 @@ function forgetRepo(repoToplevel) {
123855
123855
  }
123856
123856
  function forgetAll() {
123857
123857
  const path2 = prefsPath();
123858
- if ((0, import_node_fs22.existsSync)(path2)) (0, import_node_fs22.rmSync)(path2);
123858
+ if ((0, import_node_fs23.existsSync)(path2)) (0, import_node_fs23.rmSync)(path2);
123859
123859
  }
123860
- var import_node_fs22, import_node_path26, log5, PrefsSchema;
123860
+ var import_node_fs23, import_node_path27, log5, PrefsSchema;
123861
123861
  var init_prefs = __esm({
123862
123862
  "src/lifecycle/prefs.ts"() {
123863
123863
  "use strict";
123864
- import_node_fs22 = require("fs");
123865
- import_node_path26 = require("path");
123864
+ import_node_fs23 = require("fs");
123865
+ import_node_path27 = require("path");
123866
123866
  init_zod();
123867
123867
  init_logger();
123868
123868
  init_constants();
@@ -130754,9 +130754,9 @@ var NodeFsHandler = class {
130754
130754
  if (this.fsw.closed) {
130755
130755
  return;
130756
130756
  }
130757
- const dirname17 = sysPath.dirname(file2);
130757
+ const dirname18 = sysPath.dirname(file2);
130758
130758
  const basename12 = sysPath.basename(file2);
130759
- const parent = this.fsw._getWatchedDir(dirname17);
130759
+ const parent = this.fsw._getWatchedDir(dirname18);
130760
130760
  let prevStats = stats;
130761
130761
  if (parent.has(basename12))
130762
130762
  return;
@@ -130783,7 +130783,7 @@ var NodeFsHandler = class {
130783
130783
  prevStats = newStats2;
130784
130784
  }
130785
130785
  } catch (error51) {
130786
- this.fsw._remove(dirname17, basename12);
130786
+ this.fsw._remove(dirname18, basename12);
130787
130787
  }
130788
130788
  } else if (parent.has(basename12)) {
130789
130789
  const at2 = newStats.atimeMs;
@@ -134993,11 +134993,11 @@ async function search(query, options, scanner) {
134993
134993
 
134994
134994
  // src/server.ts
134995
134995
  var import_events3 = require("events");
134996
- var import_fs25 = require("fs");
134996
+ var import_fs26 = require("fs");
134997
134997
  var import_promises19 = require("fs/promises");
134998
134998
  var import_http = require("http");
134999
- var import_os10 = require("os");
135000
- var import_path22 = require("path");
134999
+ var import_os11 = require("os");
135000
+ var import_path23 = require("path");
135001
135001
  var import_readline4 = require("readline");
135002
135002
 
135003
135003
  // src/agent/agent-client.ts
@@ -137480,7 +137480,8 @@ function isLocalRequest(remoteAddr) {
137480
137480
  const addr = remoteAddr ?? "";
137481
137481
  return addr === "127.0.0.1" || addr === "::1" || addr === "::ffff:127.0.0.1";
137482
137482
  }
137483
- var PUBLIC_PATHS = /* @__PURE__ */ new Set(["/healthz"]);
137483
+ var PUBLIC_PATHS = /* @__PURE__ */ new Set(["/healthz", "/ws"]);
137484
+ var LOCAL_ONLY_PATHS = /* @__PURE__ */ new Set(["/api/logs", "/api/logs/meta"]);
137484
137485
  var PUBLIC_POST_PATHS = /* @__PURE__ */ new Set(["/api/pair/exchange", "/api/__update"]);
137485
137486
  var PUBLIC_POST_PREFIXES = ["/internal/sessions/"];
137486
137487
  var authMiddleware = (deps) => async (c, next) => {
@@ -137491,8 +137492,12 @@ var authMiddleware = (deps) => async (c, next) => {
137491
137492
  await next();
137492
137493
  return;
137493
137494
  }
137495
+ const remoteAddr = c.env.incoming?.socket?.remoteAddress;
137496
+ if (LOCAL_ONLY_PATHS.has(path2) && isLocalRequest(remoteAddr)) {
137497
+ await next();
137498
+ return;
137499
+ }
137494
137500
  if (deps.localNoAuth) {
137495
- const remoteAddr = c.env.incoming?.socket?.remoteAddress;
137496
137501
  if (isLocalRequest(remoteAddr)) {
137497
137502
  await next();
137498
137503
  return;
@@ -137659,6 +137664,126 @@ var createHealthRoutes = () => {
137659
137664
  return app;
137660
137665
  };
137661
137666
 
137667
+ // src/api/routes/logs.routes.ts
137668
+ var import_node_fs6 = require("fs");
137669
+ var import_node_path9 = require("path");
137670
+ init_constants();
137671
+ init_logger();
137672
+ var logger2 = getLogger("logs-api");
137673
+ function resolveLogPath(source) {
137674
+ return (0, import_node_path9.join)(installDir(), "logs", `${source}.log`);
137675
+ }
137676
+ function pickDefaultSource() {
137677
+ for (const source of ["stdout", "stderr", "dev"]) {
137678
+ const p2 = resolveLogPath(source);
137679
+ if ((0, import_node_fs6.existsSync)(p2) && (0, import_node_fs6.statSync)(p2).size > 0) return source;
137680
+ }
137681
+ return "stdout";
137682
+ }
137683
+ function readLogLines(filePath, sinceOffset, limit) {
137684
+ if (!(0, import_node_fs6.existsSync)(filePath)) {
137685
+ return { lines: [], offset: 0, total: 0 };
137686
+ }
137687
+ const fd = (0, import_node_fs6.openSync)(filePath, "r");
137688
+ try {
137689
+ const { size } = (0, import_node_fs6.fstatSync)(fd);
137690
+ if (size === 0) return { lines: [], offset: 0, total: 0 };
137691
+ const maxBytes = Math.min(size, 2 * 1024 * 1024);
137692
+ const start = size - maxBytes;
137693
+ const buf = Buffer.alloc(maxBytes);
137694
+ (0, import_node_fs6.readSync)(fd, buf, 0, maxBytes, start);
137695
+ let text = buf.toString("utf8");
137696
+ if (start > 0) {
137697
+ const firstNl = text.indexOf("\n");
137698
+ if (firstNl >= 0) text = text.slice(firstNl + 1);
137699
+ }
137700
+ const allLines = text.split("\n").filter((line) => line.trim() && !line.startsWith("==="));
137701
+ let lines;
137702
+ let newOffset;
137703
+ if (sinceOffset > 0 && sinceOffset < allLines.length) {
137704
+ lines = allLines.slice(sinceOffset, sinceOffset + limit);
137705
+ newOffset = sinceOffset + lines.length;
137706
+ } else if (sinceOffset >= allLines.length && sinceOffset > 0) {
137707
+ lines = [];
137708
+ newOffset = allLines.length;
137709
+ } else {
137710
+ lines = allLines.slice(-limit);
137711
+ newOffset = allLines.length;
137712
+ }
137713
+ return { lines, offset: newOffset, total: allLines.length };
137714
+ } finally {
137715
+ (0, import_node_fs6.closeSync)(fd);
137716
+ }
137717
+ }
137718
+ function createLogsRoutes() {
137719
+ const app = new Hono2();
137720
+ app.get("/", (c) => {
137721
+ try {
137722
+ const sourceParam = (c.req.query("source") || "").toLowerCase();
137723
+ const source = sourceParam === "stdout" || sourceParam === "stderr" || sourceParam === "dev" ? sourceParam : pickDefaultSource();
137724
+ const logPath = resolveLogPath(source);
137725
+ const sinceOffset = parseInt(c.req.query("since") || "0", 10);
137726
+ const limit = Math.min(parseInt(c.req.query("limit") || "100", 10) || 100, 1e3);
137727
+ if (!(0, import_node_fs6.existsSync)(logPath)) {
137728
+ return c.json({
137729
+ logs: [],
137730
+ message: `No log file found for source=${source}`,
137731
+ offset: 0,
137732
+ total: 0,
137733
+ source
137734
+ });
137735
+ }
137736
+ const { lines, offset, total } = readLogLines(logPath, sinceOffset, limit);
137737
+ const stats = (0, import_node_fs6.statSync)(logPath);
137738
+ return c.json({
137739
+ logs: lines,
137740
+ offset,
137741
+ total,
137742
+ hasMore: offset < total,
137743
+ source,
137744
+ fileSize: stats.size,
137745
+ fileModified: stats.mtime.toISOString()
137746
+ });
137747
+ } catch (error51) {
137748
+ logger2.error("Failed to read logs", { error: String(error51) });
137749
+ return c.json(
137750
+ {
137751
+ error: "Failed to read logs",
137752
+ logs: [],
137753
+ offset: 0,
137754
+ total: 0
137755
+ },
137756
+ 500
137757
+ );
137758
+ }
137759
+ });
137760
+ app.get("/meta", (c) => {
137761
+ try {
137762
+ const sources = ["stdout", "stderr", "dev"].map((source) => {
137763
+ const logPath = resolveLogPath(source);
137764
+ if (!(0, import_node_fs6.existsSync)(logPath)) {
137765
+ return { source, exists: false, total: 0, fileSize: 0 };
137766
+ }
137767
+ const stats = (0, import_node_fs6.statSync)(logPath);
137768
+ return {
137769
+ source,
137770
+ exists: true,
137771
+ fileSize: stats.size,
137772
+ fileModified: stats.mtime.toISOString()
137773
+ };
137774
+ });
137775
+ return c.json({
137776
+ defaultSource: pickDefaultSource(),
137777
+ sources
137778
+ });
137779
+ } catch (error51) {
137780
+ logger2.error("Failed to read log metadata", { error: String(error51) });
137781
+ return c.json({ error: "Failed to read log metadata", exists: false }, 500);
137782
+ }
137783
+ });
137784
+ return app;
137785
+ }
137786
+
137662
137787
  // src/api/routes/misc.routes.ts
137663
137788
  var import_node_child_process2 = require("child_process");
137664
137789
  var import_node_crypto = require("crypto");
@@ -137810,7 +137935,7 @@ function verifySignature(rawBody, signature, secret) {
137810
137935
  }
137811
137936
  }
137812
137937
  function isWithinSkew(timestampHeader, skewSeconds) {
137813
- if (!timestampHeader) return true;
137938
+ if (!timestampHeader) return false;
137814
137939
  const t = Number(timestampHeader);
137815
137940
  if (!Number.isFinite(t)) return false;
137816
137941
  const now = Math.floor(Date.now() / 1e3);
@@ -138021,18 +138146,21 @@ var createSessionRoutes = (deps) => {
138021
138146
  };
138022
138147
 
138023
138148
  // src/api/routes/ws.routes.ts
138149
+ init_auth();
138024
138150
  var createWsRoutes = (deps, upgradeWebSocket) => {
138025
138151
  const app = new Hono2();
138026
138152
  app.get(
138027
138153
  "/ws",
138028
- upgradeWebSocket(() => {
138154
+ upgradeWebSocket((c) => {
138155
+ const key = c.req.query("key");
138156
+ const preAuthed = typeof key === "string" && validateApiKey(key, deps.apiKey);
138029
138157
  let openWs = null;
138030
138158
  return {
138031
138159
  onOpen(_evt, ws2) {
138032
138160
  const raw2 = ws2.raw;
138033
138161
  if (!raw2) return;
138034
138162
  openWs = raw2;
138035
- deps.handleWsOpen(raw2);
138163
+ deps.handleWsOpen(raw2, preAuthed);
138036
138164
  },
138037
138165
  onMessage(evt, _ws) {
138038
138166
  if (openWs) deps.handleWsMessage(openWs, evt.data);
@@ -138077,6 +138205,7 @@ var createHonoApp = (deps, upgradeWebSocket) => {
138077
138205
  app.route("/api", createBrowseRoutes(deps));
138078
138206
  app.route("/", createScannerRoutes(deps));
138079
138207
  app.route("/internal", createProgressRoutes(deps));
138208
+ app.route("/api/logs", createLogsRoutes());
138080
138209
  if (upgradeWebSocket) {
138081
138210
  app.route("/", createWsRoutes(deps, upgradeWebSocket));
138082
138211
  }
@@ -139738,13 +139867,13 @@ function handleListProjects(url2, res) {
139738
139867
  }
139739
139868
 
139740
139869
  // src/live-session-manager.ts
139741
- var import_path19 = require("path");
139870
+ var import_path20 = require("path");
139742
139871
 
139743
139872
  // src/codex-pty-runner.ts
139744
139873
  var import_headless = __toESM(require_xterm_headless(), 1);
139745
139874
  var import_crypto7 = require("crypto");
139746
- var import_fs21 = require("fs");
139747
- var import_path17 = require("path");
139875
+ var import_fs22 = require("fs");
139876
+ var import_path18 = require("path");
139748
139877
  init_logger();
139749
139878
 
139750
139879
  // src/platform.ts
@@ -139870,6 +139999,69 @@ function resolveCodexExe() {
139870
139999
  return _codexExe;
139871
140000
  }
139872
140001
 
140002
+ // src/services/questions/codexGateAnswers.ts
140003
+ var import_fs21 = require("fs");
140004
+ var import_os9 = require("os");
140005
+ var import_path17 = require("path");
140006
+ function gateAnswersPath() {
140007
+ const dir = process.env.THREADBASE_CONFIG_DIR ?? (0, import_path17.join)((0, import_os9.homedir)(), ".threadbase");
140008
+ return (0, import_path17.join)(dir, "gate-answers.json");
140009
+ }
140010
+ function loadGateAnswers() {
140011
+ try {
140012
+ const parsed = JSON.parse((0, import_fs21.readFileSync)(gateAnswersPath(), "utf-8"));
140013
+ return parsed && typeof parsed === "object" ? parsed : {};
140014
+ } catch {
140015
+ return {};
140016
+ }
140017
+ }
140018
+ function saveGateAnswer(key, value) {
140019
+ const path2 = gateAnswersPath();
140020
+ (0, import_fs21.mkdirSync)((0, import_path17.dirname)(path2), { recursive: true });
140021
+ (0, import_fs21.writeFileSync)(path2, `${JSON.stringify({ ...loadGateAnswers(), [key]: value }, null, 2)}
140022
+ `);
140023
+ }
140024
+ function rememberedGateDigit(gate) {
140025
+ const answers = loadGateAnswers();
140026
+ if (gate === "hooks") {
140027
+ if (answers.codexHooksGate === "trust_all") return "2";
140028
+ if (answers.codexHooksGate === "continue_untrusted") return "3";
140029
+ return null;
140030
+ }
140031
+ return answers.codexTrustGate === "yes" ? "1" : null;
140032
+ }
140033
+
140034
+ // src/utils/debounce.ts
140035
+ function debounce(fn, waitMs) {
140036
+ let timer = null;
140037
+ let lastArgs = null;
140038
+ const run2 = () => {
140039
+ timer = null;
140040
+ if (lastArgs) {
140041
+ const args = lastArgs;
140042
+ lastArgs = null;
140043
+ fn(...args);
140044
+ }
140045
+ };
140046
+ const debounced = (...args) => {
140047
+ lastArgs = args;
140048
+ if (timer) clearTimeout(timer);
140049
+ timer = setTimeout(run2, waitMs);
140050
+ };
140051
+ debounced.cancel = () => {
140052
+ if (timer) clearTimeout(timer);
140053
+ timer = null;
140054
+ lastArgs = null;
140055
+ };
140056
+ debounced.flush = () => {
140057
+ if (timer) {
140058
+ clearTimeout(timer);
140059
+ run2();
140060
+ }
140061
+ };
140062
+ return debounced;
140063
+ }
140064
+
139873
140065
  // src/codex-pty-runner.ts
139874
140066
  var OUTPUT_BUFFER_MAX = 65536;
139875
140067
  var PTY_COLS = 120;
@@ -139877,6 +140069,9 @@ var PTY_ROWS = 40;
139877
140069
  var SCREEN_SCROLLBACK = 1e3;
139878
140070
  var CODEX_PROMPT_READY_TEXT = "Ready";
139879
140071
  var CODEX_TRUST_GATE_REGEX = /trust the contents/i;
140072
+ var CODEX_HOOKS_GATE_REGEX = /hooks need review/i;
140073
+ var QUIET_DETECT_MS = 500;
140074
+ var CODEX_READY_FALLBACK_MS = 8e3;
139880
140075
  var SUBMIT_BYTES = "\r";
139881
140076
  var CODEX_SUBMIT_DELAY_MS = 16;
139882
140077
  function digestBytes(s3) {
@@ -139884,6 +140079,40 @@ function digestBytes(s3) {
139884
140079
  if (escaped.length <= 200) return escaped;
139885
140080
  return `${escaped.slice(0, 100)}\u2026[${escaped.length - 200}B omitted]\u2026${escaped.slice(-100)}`;
139886
140081
  }
140082
+ function gateCard(gate, lines) {
140083
+ if (gate === "hooks") {
140084
+ const countLine = lines.find((l) => /new or changed/i.test(l))?.trim();
140085
+ return {
140086
+ prompt: [
140087
+ "Hooks need review",
140088
+ countLine,
140089
+ "Hooks can run outside the sandbox after you trust them."
140090
+ ].filter(Boolean).join(" \u2014 "),
140091
+ options: [
140092
+ { index: 2, label: "Trust all and continue", answerKeys: "2\r" },
140093
+ { index: 3, label: "Continue without trusting (hooks won't run)", answerKeys: "3\r" },
140094
+ {
140095
+ index: 4,
140096
+ label: "Trust all and continue (remember for all projects)",
140097
+ answerKeys: "4\r"
140098
+ },
140099
+ {
140100
+ index: 5,
140101
+ label: "Continue without trusting (remember for all projects)",
140102
+ answerKeys: "5\r"
140103
+ }
140104
+ ]
140105
+ };
140106
+ }
140107
+ return {
140108
+ prompt: lines.find((l) => CODEX_TRUST_GATE_REGEX.test(l))?.trim() ?? "Do you trust the contents of this directory?",
140109
+ options: [
140110
+ { index: 1, label: "Yes, continue", answerKeys: "1\r" },
140111
+ { index: 2, label: "No, quit", answerKeys: "2\r" },
140112
+ { index: 3, label: "Yes, continue (remember for all projects)", answerKeys: "3\r" }
140113
+ ]
140114
+ };
140115
+ }
139887
140116
  var pty = null;
139888
140117
  async function loadPty() {
139889
140118
  if (pty) return pty;
@@ -139910,8 +140139,8 @@ var CodexPtyRunner = class {
139910
140139
  onOutput;
139911
140140
  onStatusChange;
139912
140141
  onReady;
139913
- // Accepted for shape-compatibility with PTYManagerOptions; Codex has no
139914
- // detected equivalent yet (Phase 0) never invoked.
140142
+ // Broadcasts Codex's blocking startup gates (directory trust, hooks review)
140143
+ // as question cards; null dismisses the card once the gate leaves the screen.
139915
140144
  onPermissionChange;
139916
140145
  onLiveQuestion;
139917
140146
  onLiveQuestionGone;
@@ -139922,8 +140151,18 @@ var CodexPtyRunner = class {
139922
140151
  // Inputs received via sendInput() while the session was still pendingReady.
139923
140152
  // Flushed in arrival order once Codex reaches Ready.
139924
140153
  queuedInputs = /* @__PURE__ */ new Map();
139925
- // Per-session debounce so the directory-trust gate's \r is only written once.
139926
- trustGateAnswered = /* @__PURE__ */ new Set();
140154
+ // Gate currently on a session's screen (card broadcast, unanswered). While
140155
+ // set, queued-input flushes are held — a flushed digit would CONFIRM a
140156
+ // dialog option — and sendKeys() intercepts remember-variant digits.
140157
+ openGate = /* @__PURE__ */ new Map();
140158
+ // `${sessionId}:${gate}` once a gate has been actioned (auto-answered or
140159
+ // card broadcast) — dedupes repaints of the same dialog.
140160
+ gateActioned = /* @__PURE__ */ new Set();
140161
+ // Per-session trailing debounce re-armed on every chunk; on quiet, re-runs
140162
+ // screen detection so a blocked/truncated boot still reaches ready.
140163
+ quietCheckers = /* @__PURE__ */ new Map();
140164
+ // Per-session flat backstop from spawn (CODEX_READY_FALLBACK_MS).
140165
+ readyFallbackTimers = /* @__PURE__ */ new Map();
139927
140166
  // In-flight start()/startFresh() calls keyed by sessionId. A second
139928
140167
  // concurrent resume for the same session (double-tap, client retry) awaits
139929
140168
  // the first call's promise instead of spawning a duplicate PTY (CRITICAL #3).
@@ -139953,7 +140192,7 @@ var CodexPtyRunner = class {
139953
140192
  }
139954
140193
  async doStart(sessionId, options) {
139955
140194
  const nodePty = await loadPty();
139956
- const projectName = options.projectName ?? (0, import_path17.basename)(options.projectPath);
140195
+ const projectName = options.projectName ?? (0, import_path18.basename)(options.projectPath);
139957
140196
  const proc = nodePty.spawn(
139958
140197
  resolveCodexExe(),
139959
140198
  ["resume", sessionId, "--cd", options.projectPath, "--no-alt-screen"],
@@ -139982,6 +140221,7 @@ var CodexPtyRunner = class {
139982
140221
  };
139983
140222
  this.sessions.set(sessionId, session);
139984
140223
  this.pendingReady.add(sessionId);
140224
+ this.armReadyFallback(sessionId);
139985
140225
  proc.onData((data) => {
139986
140226
  this.handleOutput(sessionId, data);
139987
140227
  });
@@ -139998,7 +140238,7 @@ var CodexPtyRunner = class {
139998
140238
  async startFresh(options) {
139999
140239
  const nodePty = await loadPty();
140000
140240
  const sessionId = (0, import_crypto7.randomUUID)();
140001
- const projectName = options.projectName ?? (0, import_path17.basename)(options.projectPath);
140241
+ const projectName = options.projectName ?? (0, import_path18.basename)(options.projectPath);
140002
140242
  const args = ["--cd", options.projectPath, "--no-alt-screen"];
140003
140243
  if (options.systemPrompt) {
140004
140244
  args.push(options.systemPrompt);
@@ -140027,6 +140267,7 @@ var CodexPtyRunner = class {
140027
140267
  };
140028
140268
  this.sessions.set(sessionId, session);
140029
140269
  this.pendingReady.add(sessionId);
140270
+ this.armReadyFallback(sessionId);
140030
140271
  proc.onData((data) => {
140031
140272
  this.handleOutput(sessionId, data);
140032
140273
  });
@@ -140036,6 +140277,21 @@ var CodexPtyRunner = class {
140036
140277
  });
140037
140278
  return toPublicSession(session);
140038
140279
  }
140280
+ // Flat backstop: if neither the "Ready" marker nor the quiet-checker settled
140281
+ // the session within CODEX_READY_FALLBACK_MS of spawn, mark it ready anyway
140282
+ // so start requests resolve and mobile can watch the boot live. unref() so a
140283
+ // pending timer never holds the process open.
140284
+ armReadyFallback(sessionId) {
140285
+ const timer = setTimeout(() => {
140286
+ this.readyFallbackTimers.delete(sessionId);
140287
+ const session = this.sessions.get(sessionId);
140288
+ if (session?.status === "running" && this.pendingReady.has(sessionId)) {
140289
+ this.markReady(sessionId, session, "fallback:timeout");
140290
+ }
140291
+ }, CODEX_READY_FALLBACK_MS);
140292
+ timer.unref?.();
140293
+ this.readyFallbackTimers.set(sessionId, timer);
140294
+ }
140039
140295
  // Write raw key bytes directly to the PTY, same as PTYManager.sendKeys.
140040
140296
  sendKeys(sessionId, keys) {
140041
140297
  const session = this.sessions.get(sessionId);
@@ -140047,13 +140303,47 @@ var CodexPtyRunner = class {
140047
140303
  session.status = "running";
140048
140304
  this.onStatusChange?.(toPublicSession(session));
140049
140305
  }
140306
+ const gate = this.openGate.get(sessionId);
140307
+ const digit = gate ? /^([0-9])\r?$/.exec(keys)?.[1] : void 0;
140308
+ const out = gate && digit ? this.resolveGateAnswer(sessionId, gate, digit) : keys;
140050
140309
  this.log.info(
140051
- `[codex.keys.write] ${sessionId.slice(0, 8)} bytes=${keys.length} digest=${digestBytes(keys)}`,
140052
- { event: "codex.keys_write", sessionId, byteLen: keys.length }
140310
+ `[codex.keys.write] ${sessionId.slice(0, 8)} bytes=${out.length} digest=${digestBytes(out)}`,
140311
+ { event: "codex.keys_write", sessionId, byteLen: out.length }
140053
140312
  );
140054
- session.process.write(keys);
140313
+ session.process.write(out);
140055
140314
  session.lastActivityAt = /* @__PURE__ */ new Date();
140056
140315
  }
140316
+ // Map a gate-card digit to the PTY bytes that answer the real dialog,
140317
+ // persisting the choice when the digit was a synthetic "remember for all
140318
+ // projects" option (those numbers don't exist on the actual dialog and must
140319
+ // never reach codex). The trailing \r mobile sends is dropped: a digit alone
140320
+ // selects AND confirms (live-probe verified), and a stray Enter would land
140321
+ // on whatever screen follows.
140322
+ resolveGateAnswer(sessionId, gate, digit) {
140323
+ let real = digit;
140324
+ let remembered = false;
140325
+ if (gate === "hooks" && digit === "4") {
140326
+ saveGateAnswer("codexHooksGate", "trust_all");
140327
+ real = "2";
140328
+ remembered = true;
140329
+ } else if (gate === "hooks" && digit === "5") {
140330
+ saveGateAnswer("codexHooksGate", "continue_untrusted");
140331
+ real = "3";
140332
+ remembered = true;
140333
+ } else if (gate === "trust" && digit === "3") {
140334
+ saveGateAnswer("codexTrustGate", "yes");
140335
+ real = "1";
140336
+ remembered = true;
140337
+ }
140338
+ this.log.info(`[codex.gate_answer] ${sessionId.slice(0, 8)} ${gate} digit=${real}`, {
140339
+ event: "codex.gate_answer",
140340
+ sessionId,
140341
+ gate,
140342
+ digit: real,
140343
+ remembered
140344
+ });
140345
+ return real;
140346
+ }
140057
140347
  sendInput(sessionId, input) {
140058
140348
  const session = this.sessions.get(sessionId);
140059
140349
  if (!session) throw new Error(`Session not found: ${sessionId}`);
@@ -140123,8 +140413,12 @@ var CodexPtyRunner = class {
140123
140413
  }, CODEX_SUBMIT_DELAY_MS);
140124
140414
  }
140125
140415
  // Drain any inputs sent while the session was still pendingReady, writing
140126
- // them in arrival order now that Codex is Ready.
140416
+ // them in arrival order now that Codex is Ready. No-op while a gate dialog
140417
+ // is open (a flushed digit would confirm a dialog option) or while still
140418
+ // pendingReady (markReady drains it) — the gate-close path re-drives it for
140419
+ // the ready-with-gate-open case.
140127
140420
  flushQueuedInputs(sessionId) {
140421
+ if (this.openGate.has(sessionId) || this.pendingReady.has(sessionId)) return;
140128
140422
  const queue = this.queuedInputs.get(sessionId);
140129
140423
  if (!queue || queue.length === 0) return;
140130
140424
  this.queuedInputs.delete(sessionId);
@@ -140169,7 +140463,7 @@ var CodexPtyRunner = class {
140169
140463
  if (!session) return;
140170
140464
  this.pendingReady.delete(sessionId);
140171
140465
  this.queuedInputs.delete(sessionId);
140172
- this.trustGateAnswered.delete(sessionId);
140466
+ this.clearSessionDetectors(sessionId);
140173
140467
  try {
140174
140468
  session.process.kill("SIGINT");
140175
140469
  } catch {
@@ -140180,6 +140474,21 @@ var CodexPtyRunner = class {
140180
140474
  this.sessions.delete(sessionId);
140181
140475
  this.onStatusChange?.(toPublicSession(session));
140182
140476
  }
140477
+ // Drop a session's detection state: quiet-checker, ready-fallback timer,
140478
+ // gate bookkeeping — and dismiss a still-open gate card so mobile doesn't
140479
+ // keep rendering a question for a dead PTY.
140480
+ clearSessionDetectors(sessionId) {
140481
+ this.quietCheckers.get(sessionId)?.cancel();
140482
+ this.quietCheckers.delete(sessionId);
140483
+ const timer = this.readyFallbackTimers.get(sessionId);
140484
+ if (timer) clearTimeout(timer);
140485
+ this.readyFallbackTimers.delete(sessionId);
140486
+ if (this.openGate.delete(sessionId)) {
140487
+ this.onPermissionChange?.(sessionId, null);
140488
+ }
140489
+ this.gateActioned.delete(`${sessionId}:hooks`);
140490
+ this.gateActioned.delete(`${sessionId}:trust`);
140491
+ }
140183
140492
  getOutput(sessionId) {
140184
140493
  const session = this.sessions.get(sessionId);
140185
140494
  if (!session) throw new Error(`Session not found: ${sessionId}`);
@@ -140219,10 +140528,19 @@ var CodexPtyRunner = class {
140219
140528
  }
140220
140529
  session.screen.dispose();
140221
140530
  }
140531
+ for (const sessionId of Array.from(this.quietCheckers.keys())) {
140532
+ this.clearSessionDetectors(sessionId);
140533
+ }
140534
+ for (const timer of this.readyFallbackTimers.values()) {
140535
+ clearTimeout(timer);
140536
+ }
140222
140537
  this.sessions.clear();
140223
140538
  this.pendingReady.clear();
140224
140539
  this.queuedInputs.clear();
140225
- this.trustGateAnswered.clear();
140540
+ this.openGate.clear();
140541
+ this.gateActioned.clear();
140542
+ this.quietCheckers.clear();
140543
+ this.readyFallbackTimers.clear();
140226
140544
  }
140227
140545
  handleOutput(sessionId, data) {
140228
140546
  const session = this.sessions.get(sessionId);
@@ -140237,44 +140555,92 @@ var CodexPtyRunner = class {
140237
140555
  session.screen.write(data);
140238
140556
  session.lastOutput = stripAnsi(data);
140239
140557
  this.onOutput?.(sessionId, data);
140240
- this.detectReady(sessionId, session).catch((err) => {
140558
+ this.detectScreenState(sessionId, "chunk").catch((err) => {
140241
140559
  this.log.warn("[codex.ready_detect] failed", {
140242
140560
  event: "codex.ready_detect_failed",
140243
140561
  sessionId,
140244
140562
  err
140245
140563
  });
140246
140564
  });
140565
+ let quiet = this.quietCheckers.get(sessionId);
140566
+ if (!quiet) {
140567
+ quiet = debounce(() => {
140568
+ this.detectScreenState(sessionId, "quiet").catch((err) => {
140569
+ this.log.warn("[codex.ready_detect] failed", {
140570
+ event: "codex.ready_detect_failed",
140571
+ sessionId,
140572
+ err
140573
+ });
140574
+ });
140575
+ }, QUIET_DETECT_MS);
140576
+ this.quietCheckers.set(sessionId, quiet);
140577
+ }
140578
+ quiet();
140247
140579
  }
140248
- // Renders the session's headless screen and checks for the directory-trust
140249
- // gate (answered once, debounced) and the "Ready" status-bar text. Only
140250
- // transitions to waiting_input / fires onReady when the rendered status
140251
- // line literally contains "Ready" `›` alone (visible during "Starting")
140252
- // is NOT a valid readiness signal (Phase 0).
140253
- async detectReady(sessionId, session) {
140254
- if (session.status !== "running" || !this.pendingReady.has(sessionId)) return;
140580
+ // Renders the session's headless screen and drives both detections:
140581
+ // - Gates (directory trust, hooks review) checked on EVERY pass,
140582
+ // independent of pendingReady, so a gate appearing after ready is still
140583
+ // surfaced and a gate leaving the screen closes its card.
140584
+ // - Readiness the "Ready" status-bar marker while pendingReady, plus the
140585
+ // quiet path: after QUIET_DETECT_MS of PTY silence a still-pending
140586
+ // session is marked ready anyway (`›` alone is NOT a marker — Phase 0 —
140587
+ // but a quiet boot screen is more useful to the user live than a
140588
+ // spinner, and "Ready" may be truncated off the 120-col status bar).
140589
+ async detectScreenState(sessionId, trigger) {
140590
+ const session = this.sessions.get(sessionId);
140591
+ if (!session || session.status === "idle") return;
140255
140592
  const lines = await this.getOutputLines(sessionId, PTY_ROWS);
140256
140593
  const screenText = lines.join("\n");
140257
- if (CODEX_TRUST_GATE_REGEX.test(screenText)) {
140258
- if (!this.trustGateAnswered.has(sessionId)) {
140259
- this.trustGateAnswered.add(sessionId);
140260
- this.log.info(`[codex.trust_gate] ${sessionId.slice(0, 8)} auto-answering`, {
140261
- event: "codex.trust_gate",
140262
- sessionId
140263
- });
140264
- session.process.write("\r");
140265
- }
140266
- return;
140594
+ const gate = CODEX_HOOKS_GATE_REGEX.test(screenText) ? "hooks" : CODEX_TRUST_GATE_REGEX.test(screenText) ? "trust" : null;
140595
+ if (gate) {
140596
+ this.handleGate(sessionId, session, gate, lines);
140597
+ } else if (this.openGate.delete(sessionId)) {
140598
+ this.onPermissionChange?.(sessionId, null);
140599
+ this.flushQueuedInputs(sessionId);
140267
140600
  }
140601
+ if (session.status !== "running" || !this.pendingReady.has(sessionId)) return;
140268
140602
  const lastNonBlank2 = [...lines].reverse().find((l) => l.trim() !== "") ?? "";
140269
- if (!lastNonBlank2.includes(CODEX_PROMPT_READY_TEXT)) return;
140270
- this.markReady(sessionId, session);
140603
+ if (lastNonBlank2.includes(CODEX_PROMPT_READY_TEXT)) {
140604
+ this.markReady(sessionId, session, `marker:${CODEX_PROMPT_READY_TEXT}`);
140605
+ } else if (trigger === "quiet") {
140606
+ this.markReady(sessionId, session, "quiet:timeout");
140607
+ }
140271
140608
  }
140272
- markReady(sessionId, session) {
140609
+ // Answer a gate from the persisted remember-store, or surface it as a
140610
+ // question card over the permission transport. Actioned once per session and
140611
+ // gate type — repaints of the same dialog neither re-write nor re-broadcast.
140612
+ handleGate(sessionId, session, gate, lines) {
140613
+ const key = `${sessionId}:${gate}`;
140614
+ if (this.gateActioned.has(key)) return;
140615
+ this.gateActioned.add(key);
140616
+ const remembered = rememberedGateDigit(gate);
140617
+ if (remembered) {
140618
+ this.log.info(`[codex.gate_auto_answer] ${sessionId.slice(0, 8)} ${gate} \u2192 ${remembered}`, {
140619
+ event: "codex.gate_auto_answer",
140620
+ sessionId,
140621
+ gate,
140622
+ digit: remembered
140623
+ });
140624
+ session.process.write(remembered);
140625
+ return;
140626
+ }
140627
+ this.openGate.set(sessionId, gate);
140628
+ const card = gateCard(gate, lines);
140629
+ this.log.info(`[codex.gate_prompt] ${sessionId.slice(0, 8)} ${gate}`, {
140630
+ event: "codex.gate_prompt",
140631
+ sessionId,
140632
+ gate,
140633
+ prompt: card.prompt
140634
+ });
140635
+ this.onPermissionChange?.(sessionId, card);
140636
+ }
140637
+ markReady(sessionId, session, reason) {
140273
140638
  session.lastActivityAt = /* @__PURE__ */ new Date();
140274
140639
  session.status = "waiting_input";
140275
- this.log.info(`[codex.ready] ${sessionId.slice(0, 8)}`, {
140640
+ this.log.info(`[codex.ready] ${sessionId.slice(0, 8)} ${reason}`, {
140276
140641
  event: "codex.ready",
140277
- sessionId
140642
+ sessionId,
140643
+ reason
140278
140644
  });
140279
140645
  this.onStatusChange?.(toPublicSession(session));
140280
140646
  if (this.pendingReady.has(sessionId)) {
@@ -140290,7 +140656,7 @@ var CodexPtyRunner = class {
140290
140656
  session.status = "idle";
140291
140657
  const elapsedMs = session.completedAt.getTime() - session.startedAt.getTime();
140292
140658
  if (exitCode !== 0 && elapsedMs < 2e3 && session.lastOutput === "") {
140293
- if (!(0, import_fs21.existsSync)(session.projectPath)) {
140659
+ if (!(0, import_fs22.existsSync)(session.projectPath)) {
140294
140660
  session.failureReason = `Project directory not found: ${session.projectPath}`;
140295
140661
  } else {
140296
140662
  session.failureReason = `Codex process exited immediately (code ${exitCode}).`;
@@ -140300,7 +140666,7 @@ var CodexPtyRunner = class {
140300
140666
  session.screen.dispose();
140301
140667
  this.sessions.delete(sessionId);
140302
140668
  this.queuedInputs.delete(sessionId);
140303
- this.trustGateAnswered.delete(sessionId);
140669
+ this.clearSessionDetectors(sessionId);
140304
140670
  }
140305
140671
  };
140306
140672
  function toPublicSession(s3) {
@@ -140327,8 +140693,8 @@ function stripAnsi(str) {
140327
140693
  // src/pty-manager.ts
140328
140694
  var import_headless2 = __toESM(require_xterm_headless(), 1);
140329
140695
  var import_crypto8 = require("crypto");
140330
- var import_fs22 = require("fs");
140331
- var import_path18 = require("path");
140696
+ var import_fs23 = require("fs");
140697
+ var import_path19 = require("path");
140332
140698
  init_logger();
140333
140699
 
140334
140700
  // src/services/questions/detectPermissionGate.ts
@@ -140484,9 +140850,15 @@ function detectShellPrompt(lines) {
140484
140850
  ]
140485
140851
  };
140486
140852
  }
140487
- if (NUMBERED_RE.test(last.text)) {
140853
+ const lastNumberedIdx = (() => {
140854
+ for (let i = last.idx; i >= 0; i--) {
140855
+ if (NUMBERED_RE.test(lines[i])) return i;
140856
+ }
140857
+ return -1;
140858
+ })();
140859
+ if (lastNumberedIdx >= 0) {
140488
140860
  const options = [];
140489
- for (let i = 0; i <= last.idx; i++) {
140861
+ for (let i = 0; i <= lastNumberedIdx; i++) {
140490
140862
  const m2 = NUMBERED_RE.exec(lines[i]);
140491
140863
  if (!m2) continue;
140492
140864
  const num = Number.parseInt(m2[1], 10);
@@ -140514,37 +140886,6 @@ function detectShellPrompt(lines) {
140514
140886
  return null;
140515
140887
  }
140516
140888
 
140517
- // src/utils/debounce.ts
140518
- function debounce(fn, waitMs) {
140519
- let timer = null;
140520
- let lastArgs = null;
140521
- const run2 = () => {
140522
- timer = null;
140523
- if (lastArgs) {
140524
- const args = lastArgs;
140525
- lastArgs = null;
140526
- fn(...args);
140527
- }
140528
- };
140529
- const debounced = (...args) => {
140530
- lastArgs = args;
140531
- if (timer) clearTimeout(timer);
140532
- timer = setTimeout(run2, waitMs);
140533
- };
140534
- debounced.cancel = () => {
140535
- if (timer) clearTimeout(timer);
140536
- timer = null;
140537
- lastArgs = null;
140538
- };
140539
- debounced.flush = () => {
140540
- if (timer) {
140541
- clearTimeout(timer);
140542
- run2();
140543
- }
140544
- };
140545
- return debounced;
140546
- }
140547
-
140548
140889
  // src/pty-manager.ts
140549
140890
  var OUTPUT_BUFFER_MAX2 = 65536;
140550
140891
  var PTY_COLS2 = 120;
@@ -140552,7 +140893,7 @@ var PTY_ROWS2 = 40;
140552
140893
  var SCREEN_SCROLLBACK2 = 1e3;
140553
140894
  var CLAUDE_PROMPT_MARKERS = ["\u256D", "\u276F"];
140554
140895
  var PROMPT_MARKER_FALLBACK_MS = 1e4;
140555
- var QUIET_DETECT_MS = 500;
140896
+ var QUIET_DETECT_MS2 = 500;
140556
140897
  function buildPasteBytes(input) {
140557
140898
  return `\x1B[200~${input}\x1B[201~`;
140558
140899
  }
@@ -140680,7 +141021,7 @@ var PTYManager = class {
140680
141021
  }
140681
141022
  async doStart(sessionId, options) {
140682
141023
  const nodePty = await loadPty2();
140683
- const projectName = options.projectName ?? (0, import_path18.basename)(options.projectPath);
141024
+ const projectName = options.projectName ?? (0, import_path19.basename)(options.projectPath);
140684
141025
  const proc = nodePty.spawn(
140685
141026
  resolveClaudeExe(),
140686
141027
  [
@@ -140731,7 +141072,7 @@ var PTYManager = class {
140731
141072
  async startFresh(options) {
140732
141073
  const nodePty = await loadPty2();
140733
141074
  const sessionId = (0, import_crypto8.randomUUID)();
140734
- const projectName = options.projectName ?? (0, import_path18.basename)(options.projectPath);
141075
+ const projectName = options.projectName ?? (0, import_path19.basename)(options.projectPath);
140735
141076
  const args = [
140736
141077
  "--permission-mode",
140737
141078
  options.permissionMode ?? "acceptEdits",
@@ -141052,7 +141393,7 @@ var PTYManager = class {
141052
141393
  });
141053
141394
  let quiet = this.quietCheckers.get(sessionId);
141054
141395
  if (!quiet) {
141055
- quiet = debounce(() => this.handleQuiet(sessionId), QUIET_DETECT_MS);
141396
+ quiet = debounce(() => this.handleQuiet(sessionId), QUIET_DETECT_MS2);
141056
141397
  this.quietCheckers.set(sessionId, quiet);
141057
141398
  }
141058
141399
  quiet();
@@ -141175,7 +141516,7 @@ var PTYManager = class {
141175
141516
  session.status = "idle";
141176
141517
  const elapsedMs = session.completedAt.getTime() - session.startedAt.getTime();
141177
141518
  if (exitCode !== 0 && elapsedMs < 2e3 && session.lastOutput === "") {
141178
- if (!(0, import_fs22.existsSync)(session.projectPath)) {
141519
+ if (!(0, import_fs23.existsSync)(session.projectPath)) {
141179
141520
  session.failureReason = `Project directory not found: ${session.projectPath}`;
141180
141521
  } else {
141181
141522
  session.failureReason = `Process exited immediately (code ${exitCode}). Check that the Claude binary is installed and accessible.`;
@@ -141303,7 +141644,7 @@ var LiveSessionManager = class {
141303
141644
  const runner = this.runners.get(provider);
141304
141645
  if (runner) return runner;
141305
141646
  const err = new Error(
141306
- `Live ${provider} sessions are not implemented yet for ${(0, import_path19.basename)(projectPath)}`
141647
+ `Live ${provider} sessions are not implemented yet for ${(0, import_path20.basename)(projectPath)}`
141307
141648
  );
141308
141649
  err.statusCode = 501;
141309
141650
  throw err;
@@ -141369,10 +141710,10 @@ var PairTokenStore = class {
141369
141710
 
141370
141711
  // src/process-discovery.ts
141371
141712
  var import_child_process2 = require("child_process");
141372
- var import_os9 = require("os");
141373
- var import_path20 = require("path");
141713
+ var import_os10 = require("os");
141714
+ var import_path21 = require("path");
141374
141715
  async function discoverClaudeProcesses() {
141375
- if ((0, import_os9.platform)() === "win32") return discoverWindows();
141716
+ if ((0, import_os10.platform)() === "win32") return discoverWindows();
141376
141717
  return discoverUnix();
141377
141718
  }
141378
141719
  async function discoverUnix() {
@@ -141389,7 +141730,7 @@ async function discoverUnix() {
141389
141730
  return {
141390
141731
  pid,
141391
141732
  projectPath: cwd,
141392
- projectName: (0, import_path20.basename)(cwd),
141733
+ projectName: (0, import_path21.basename)(cwd),
141393
141734
  branch: await readGitBranch2(cwd),
141394
141735
  conversationId,
141395
141736
  startedAt
@@ -141411,7 +141752,7 @@ async function discoverWindows() {
141411
141752
  return {
141412
141753
  pid,
141413
141754
  projectPath: info.cwd,
141414
- projectName: (0, import_path20.basename)(info.cwd),
141755
+ projectName: (0, import_path21.basename)(info.cwd),
141415
141756
  branch: await readGitBranch2(info.cwd),
141416
141757
  conversationId: extractResumeId(info.args),
141417
141758
  startedAt: info.startedAt
@@ -141492,7 +141833,7 @@ async function getProcessInfoWindows(pid) {
141492
141833
  const startedAt = /* @__PURE__ */ new Date(`${year}-${month}-${day}T${hour}:${min}:${sec}`);
141493
141834
  if (Number.isNaN(startedAt.getTime())) return null;
141494
141835
  const exePath = parts[3] ?? "";
141495
- const cwd = exePath ? (0, import_path20.dirname)(exePath) : "";
141836
+ const cwd = exePath ? (0, import_path21.dirname)(exePath) : "";
141496
141837
  return { cwd, args, startedAt };
141497
141838
  } catch {
141498
141839
  return null;
@@ -141533,13 +141874,13 @@ function seal(plaintext, recipientPublicKeyBase64) {
141533
141874
 
141534
141875
  // node_modules/chokidar/index.js
141535
141876
  var import_node_events2 = require("events");
141536
- var import_node_fs7 = require("fs");
141877
+ var import_node_fs8 = require("fs");
141537
141878
  var import_promises16 = require("fs/promises");
141538
141879
  var sp2 = __toESM(require("path"), 1);
141539
141880
 
141540
141881
  // node_modules/readdirp/index.js
141541
141882
  var import_promises14 = require("fs/promises");
141542
- var import_node_path9 = require("path");
141883
+ var import_node_path10 = require("path");
141543
141884
  var import_node_stream2 = require("stream");
141544
141885
  var EntryTypes2 = {
141545
141886
  FILE_TYPE: "files",
@@ -141629,7 +141970,7 @@ var ReaddirpStream2 = class extends import_node_stream2.Readable {
141629
141970
  this._wantsDir = type ? DIR_TYPES2.has(type) : false;
141630
141971
  this._wantsFile = type ? FILE_TYPES2.has(type) : false;
141631
141972
  this._wantsEverything = type === EntryTypes2.EVERYTHING_TYPE;
141632
- this._root = (0, import_node_path9.resolve)(root);
141973
+ this._root = (0, import_node_path10.resolve)(root);
141633
141974
  this._isDirent = !opts.alwaysStat;
141634
141975
  this._statsProp = this._isDirent ? "dirent" : "stats";
141635
141976
  this._rdOptions = { encoding: "utf8", withFileTypes: this._isDirent };
@@ -141700,8 +142041,8 @@ var ReaddirpStream2 = class extends import_node_stream2.Readable {
141700
142041
  let entry;
141701
142042
  const basename12 = this._isDirent ? dirent.name : dirent;
141702
142043
  try {
141703
- const fullPath = (0, import_node_path9.resolve)((0, import_node_path9.join)(path2, basename12));
141704
- entry = { path: (0, import_node_path9.relative)(this._root, fullPath), fullPath, basename: basename12 };
142044
+ const fullPath = (0, import_node_path10.resolve)((0, import_node_path10.join)(path2, basename12));
142045
+ entry = { path: (0, import_node_path10.relative)(this._root, fullPath), fullPath, basename: basename12 };
141705
142046
  entry[this._statsProp] = this._isDirent ? dirent : await this._stat(fullPath);
141706
142047
  } catch (err) {
141707
142048
  this._onError(err);
@@ -141735,7 +142076,7 @@ var ReaddirpStream2 = class extends import_node_stream2.Readable {
141735
142076
  }
141736
142077
  if (entryRealPathStats.isDirectory()) {
141737
142078
  const len = entryRealPath.length;
141738
- if (full.startsWith(entryRealPath) && full.substr(len, 1) === import_node_path9.sep) {
142079
+ if (full.startsWith(entryRealPath) && full.substr(len, 1) === import_node_path10.sep) {
141739
142080
  const recursiveError = new Error(`Circular symlink detected: "${full}" points to "${entryRealPath}"`);
141740
142081
  recursiveError.code = RECURSIVE_ERROR_CODE2;
141741
142082
  return this._onError(recursiveError);
@@ -141771,7 +142112,7 @@ function readdirp2(root, options = {}) {
141771
142112
  }
141772
142113
 
141773
142114
  // node_modules/chokidar/handler.js
141774
- var import_node_fs6 = require("fs");
142115
+ var import_node_fs7 = require("fs");
141775
142116
  var import_promises15 = require("fs/promises");
141776
142117
  var import_node_os3 = require("os");
141777
142118
  var sp = __toESM(require("path"), 1);
@@ -142109,7 +142450,7 @@ function createFsWatchInstance2(path2, options, listener, errHandler, emitRaw) {
142109
142450
  }
142110
142451
  };
142111
142452
  try {
142112
- return (0, import_node_fs6.watch)(path2, {
142453
+ return (0, import_node_fs7.watch)(path2, {
142113
142454
  persistent: options.persistent
142114
142455
  }, handleEvent);
142115
142456
  } catch (error51) {
@@ -142192,7 +142533,7 @@ var setFsWatchFileListener2 = (path2, fullPath, options, handlers) => {
142192
142533
  let cont = FsWatchFileInstances2.get(fullPath);
142193
142534
  const copts = cont && cont.options;
142194
142535
  if (copts && (copts.persistent < options.persistent || copts.interval > options.interval)) {
142195
- (0, import_node_fs6.unwatchFile)(fullPath);
142536
+ (0, import_node_fs7.unwatchFile)(fullPath);
142196
142537
  cont = void 0;
142197
142538
  }
142198
142539
  if (cont) {
@@ -142203,7 +142544,7 @@ var setFsWatchFileListener2 = (path2, fullPath, options, handlers) => {
142203
142544
  listeners: listener,
142204
142545
  rawEmitters: rawEmitter,
142205
142546
  options,
142206
- watcher: (0, import_node_fs6.watchFile)(fullPath, options, (curr, prev) => {
142547
+ watcher: (0, import_node_fs7.watchFile)(fullPath, options, (curr, prev) => {
142207
142548
  foreach2(cont.rawEmitters, (rawEmitter2) => {
142208
142549
  rawEmitter2(EV2.CHANGE, fullPath, { curr, prev });
142209
142550
  });
@@ -142220,7 +142561,7 @@ var setFsWatchFileListener2 = (path2, fullPath, options, handlers) => {
142220
142561
  delFromSet2(cont, KEY_RAW2, rawEmitter);
142221
142562
  if (isEmptySet2(cont.listeners)) {
142222
142563
  FsWatchFileInstances2.delete(fullPath);
142223
- (0, import_node_fs6.unwatchFile)(fullPath);
142564
+ (0, import_node_fs7.unwatchFile)(fullPath);
142224
142565
  cont.options = cont.watcher = void 0;
142225
142566
  Object.freeze(cont);
142226
142567
  }
@@ -142276,9 +142617,9 @@ var NodeFsHandler2 = class {
142276
142617
  if (this.fsw.closed) {
142277
142618
  return;
142278
142619
  }
142279
- const dirname17 = sp.dirname(file2);
142620
+ const dirname18 = sp.dirname(file2);
142280
142621
  const basename12 = sp.basename(file2);
142281
- const parent = this.fsw._getWatchedDir(dirname17);
142622
+ const parent = this.fsw._getWatchedDir(dirname18);
142282
142623
  let prevStats = stats;
142283
142624
  if (parent.has(basename12))
142284
142625
  return;
@@ -142305,7 +142646,7 @@ var NodeFsHandler2 = class {
142305
142646
  prevStats = newStats2;
142306
142647
  }
142307
142648
  } catch (error51) {
142308
- this.fsw._remove(dirname17, basename12);
142649
+ this.fsw._remove(dirname18, basename12);
142309
142650
  }
142310
142651
  } else if (parent.has(basename12)) {
142311
142652
  const at2 = newStats.atimeMs;
@@ -143090,7 +143431,7 @@ var FSWatcher2 = class extends import_node_events2.EventEmitter {
143090
143431
  const now = /* @__PURE__ */ new Date();
143091
143432
  const writes = this._pendingWrites;
143092
143433
  function awaitWriteFinishFn(prevStat) {
143093
- (0, import_node_fs7.stat)(fullPath, (err, curStat) => {
143434
+ (0, import_node_fs8.stat)(fullPath, (err, curStat) => {
143094
143435
  if (err || !writes.has(path2)) {
143095
143436
  if (err && err.code !== "ENOENT")
143096
143437
  awfEmit(err);
@@ -143264,7 +143605,7 @@ function watch2(paths, options = {}) {
143264
143605
  var chokidar_default = { watch: watch2, FSWatcher: FSWatcher2 };
143265
143606
 
143266
143607
  // src/services/conversations/conversationWatcher.ts
143267
- var import_fs23 = require("fs");
143608
+ var import_fs24 = require("fs");
143268
143609
  var import_promises17 = require("fs/promises");
143269
143610
  var ConversationWatcher = class {
143270
143611
  files = /* @__PURE__ */ new Map();
@@ -143287,7 +143628,7 @@ var ConversationWatcher = class {
143287
143628
  if (this.files.has(filePath)) return;
143288
143629
  let offset;
143289
143630
  try {
143290
- offset = (0, import_fs23.statSync)(filePath).size;
143631
+ offset = (0, import_fs24.statSync)(filePath).size;
143291
143632
  } catch {
143292
143633
  offset = 0;
143293
143634
  }
@@ -143462,14 +143803,14 @@ function findSearchTarget(messages, query) {
143462
143803
  }
143463
143804
 
143464
143805
  // src/services/conversations/pruneAgentConversations.ts
143465
- var import_fs24 = require("fs");
143806
+ var import_fs25 = require("fs");
143466
143807
  function pruneAgentConversations(cache) {
143467
143808
  const db = cache.getDatabase();
143468
143809
  const rows = db.prepare("SELECT id, file_path FROM conversation_meta").all();
143469
143810
  let pruned = 0;
143470
143811
  let missing = 0;
143471
143812
  for (const row of rows) {
143472
- if (!(0, import_fs24.existsSync)(row.file_path)) {
143813
+ if (!(0, import_fs25.existsSync)(row.file_path)) {
143473
143814
  missing += 1;
143474
143815
  continue;
143475
143816
  }
@@ -143492,6 +143833,13 @@ function deriveProjectChatTitle(input) {
143492
143833
  return `Untitled \xB7 ${input.id.slice(0, 8)}`;
143493
143834
  }
143494
143835
 
143836
+ // src/services/questions/permissionAnswerKeys.ts
143837
+ var ANSWER_KEYS_ALLOWLIST = /^(?:\r|[yn]\r|\x03|\d+\r)$/;
143838
+ function sanitizeAnswerKeys(keys) {
143839
+ if (keys === void 0) return void 0;
143840
+ return ANSWER_KEYS_ALLOWLIST.test(keys) ? keys : void 0;
143841
+ }
143842
+
143495
143843
  // src/services/questions/detectAskUserQuestion.ts
143496
143844
  function normalizeContent2(raw2) {
143497
143845
  if (Array.isArray(raw2)) return raw2;
@@ -143831,7 +144179,7 @@ function discoveredToResponse(d, conversationId) {
143831
144179
  var import_crypto10 = require("crypto");
143832
144180
  var import_promises18 = require("fs/promises");
143833
144181
  var import_heic_convert = __toESM(require_heic_convert(), 1);
143834
- var import_path21 = require("path");
144182
+ var import_path22 = require("path");
143835
144183
  var UPLOAD_DIR_NAME = ".threadbase-uploads";
143836
144184
  var MAX_BYTES = 25 * 1024 * 1024;
143837
144185
  var HEIC_MIMES = /* @__PURE__ */ new Set(["image/heic", "image/heif"]);
@@ -143864,9 +144212,9 @@ async function saveUploadFile(input) {
143864
144212
  }
143865
144213
  const id = `up_${(0, import_crypto10.randomBytes)(8).toString("hex")}`;
143866
144214
  const safeName = sanitizeFilename(originalName) || `file${MIME_TO_EXT[mimeType] ?? ""}`;
143867
- const dir = (0, import_path21.join)(input.projectPath, UPLOAD_DIR_NAME, input.sessionId);
144215
+ const dir = (0, import_path22.join)(input.projectPath, UPLOAD_DIR_NAME, input.sessionId);
143868
144216
  await (0, import_promises18.mkdir)(dir, { recursive: true });
143869
- const filePath = (0, import_path21.join)(dir, `${Date.now()}-${id}-${safeName}`);
144217
+ const filePath = (0, import_path22.join)(dir, `${Date.now()}-${id}-${safeName}`);
143870
144218
  await (0, import_promises18.writeFile)(filePath, buffer);
143871
144219
  return {
143872
144220
  id,
@@ -144334,8 +144682,10 @@ var WSHub = class {
144334
144682
  var BROWSE_SYSTEM_PROMPT = (browseRoot) => `You are working within the project boundary: ${browseRoot}. Do not read, write, or execute commands that access files or directories outside this boundary.`;
144335
144683
  var DEFAULT_SYSTEM_PROMPT = "When presenting options or choices to the user, limit the options to at most 3.";
144336
144684
  var DEFAULT_PTY_GRACE_PERIOD_MS = 27e4;
144685
+ var DEFAULT_WS_AUTH_TIMEOUT_MS = 5e3;
144686
+ var WS_CLOSE_UNAUTHORIZED = 4401;
144337
144687
  var REFRESH_TTL_MS = 2e3;
144338
- var START_READY_TIMEOUT_MS = 15e3;
144688
+ var START_READY_TIMEOUT_MS = 1e4;
144339
144689
  function parseIncludeAgentsEnv(raw2) {
144340
144690
  if (raw2 === void 0) return false;
144341
144691
  const v2 = raw2.trim().toLowerCase();
@@ -144424,6 +144774,14 @@ var StreamerServer = class {
144424
144774
  clientIdToWs = /* @__PURE__ */ new Map();
144425
144775
  // Reverse map for cleanup on close
144426
144776
  wsToClientId = /* @__PURE__ */ new Map();
144777
+ // M1 — WS auth. Sockets that have authenticated (via ?key= at upgrade OR a
144778
+ // { type: "auth", token } first message). Only authed sockets are added to
144779
+ // the hub and receive broadcasts.
144780
+ // Plan: https://github.com/RonenMars/threadbase-streamer/blob/a251353bfa417bd48ce3f15086bc336a2c622629/docs/plans/2026-06-24-security-hardening.md#L40
144781
+ wsAuthed = /* @__PURE__ */ new Set();
144782
+ // Keyless sockets awaiting their first-message auth handshake → close timer.
144783
+ wsAuthPending = /* @__PURE__ */ new Map();
144784
+ wsAuthTimeoutMs;
144427
144785
  cache = null;
144428
144786
  projectsRepo = null;
144429
144787
  conversationsRepo = null;
@@ -144461,11 +144819,12 @@ var StreamerServer = class {
144461
144819
  this.disableDb = config2.disableDb ?? false;
144462
144820
  this.scannerPersistenceDisabled = config2.scannerPersistent === false;
144463
144821
  this.scanProfiles = config2.scanProfiles;
144464
- this.codexRoots = config2.codexRoots ?? [(0, import_path22.join)((0, import_os10.homedir)(), ".codex", "sessions")];
144822
+ this.codexRoots = config2.codexRoots ?? [(0, import_path23.join)((0, import_os11.homedir)(), ".codex", "sessions")];
144465
144823
  this.ptyGracePeriodMs = config2.ptyGracePeriodMs ?? DEFAULT_PTY_GRACE_PERIOD_MS;
144824
+ this.wsAuthTimeoutMs = config2.wsAuthTimeoutMs ?? DEFAULT_WS_AUTH_TIMEOUT_MS;
144466
144825
  this.defaultSystemPrompt = config2.defaultSystemPrompt ?? DEFAULT_SYSTEM_PROMPT;
144467
144826
  this.defaultPermissionMode = config2.defaultPermissionMode ?? loadDefaultPermissionMode() ?? "acceptEdits";
144468
- this.cacheDir = config2.cacheDir ?? loadCacheDir() ?? (0, import_path22.join)((0, import_os10.homedir)(), ".threadbase", "cache");
144827
+ this.cacheDir = config2.cacheDir ?? loadCacheDir() ?? (0, import_path23.join)((0, import_os11.homedir)(), ".threadbase", "cache");
144469
144828
  this.tailSize = config2.tailSize ?? loadTailSize() ?? 10;
144470
144829
  this.directoryDebounceMs = parseDirScanDebounceEnv(process.env.THREADBASE_DIR_SCAN_DEBOUNCE_MS) ?? config2.directoryScanDebounceMs ?? 1e3;
144471
144830
  this.markScannerStaleDebounced = debounce(() => {
@@ -144506,7 +144865,7 @@ var StreamerServer = class {
144506
144865
  const seqs = cache.extendMessageIndex(
144507
144866
  filePath,
144508
144867
  spans,
144509
- (0, import_fs25.statSync)(filePath),
144868
+ (0, import_fs26.statSync)(filePath),
144510
144869
  readFrom,
144511
144870
  endOffset
144512
144871
  );
@@ -144667,7 +145026,7 @@ var StreamerServer = class {
144667
145026
  temporalClient,
144668
145027
  taskQueue: agentConfig.temporal.taskQueue
144669
145028
  });
144670
- const conversationsBaseDir = agentConfig.conversationsDir || (0, import_path22.join)((0, import_path22.dirname)(this.cacheDir), "conversations");
145029
+ const conversationsBaseDir = agentConfig.conversationsDir || (0, import_path23.join)((0, import_path23.dirname)(this.cacheDir), "conversations");
144671
145030
  conversationWriter = createConversationWriter({
144672
145031
  baseDir: conversationsBaseDir
144673
145032
  });
@@ -144720,17 +145079,39 @@ var StreamerServer = class {
144720
145079
  handlePairExchange: (req, res) => this.handlePairExchange(req, res),
144721
145080
  handleBrowse: (url2, res) => this.handleBrowse(url2, res),
144722
145081
  handleMkdir: (req, res) => this.handleMkdir(req, res),
144723
- handleWsOpen: (ws2) => {
144724
- this.wsHub.addClient(ws2);
144725
- const sessions = this.sessionStore.list(this.ptyAttachedIds());
144726
- ws2.send(JSON.stringify({ type: "session_list", sessions }));
144727
- if (this.cacheReady) {
144728
- ws2.send(JSON.stringify({ type: "cache_ready" }));
145082
+ handleWsOpen: (ws2, preAuthed) => {
145083
+ if (preAuthed) {
145084
+ this.completeWsAuth(ws2);
145085
+ return;
144729
145086
  }
145087
+ const timer = setTimeout(() => {
145088
+ this.wsAuthPending.delete(ws2);
145089
+ try {
145090
+ ws2.close(WS_CLOSE_UNAUTHORIZED, "auth timeout");
145091
+ } catch {
145092
+ }
145093
+ }, this.wsAuthTimeoutMs);
145094
+ this.wsAuthPending.set(ws2, timer);
144730
145095
  },
144731
145096
  handleWsMessage: async (ws2, raw2) => {
144732
145097
  try {
144733
145098
  const msg = JSON.parse(String(raw2));
145099
+ if (!this.wsAuthed.has(ws2)) {
145100
+ if (msg.type === "auth" && typeof msg.token === "string") {
145101
+ const t = this.wsAuthPending.get(ws2);
145102
+ if (t) clearTimeout(t);
145103
+ this.wsAuthPending.delete(ws2);
145104
+ if (validateApiKey(msg.token, this.apiKey)) {
145105
+ this.completeWsAuth(ws2);
145106
+ } else {
145107
+ try {
145108
+ ws2.close(WS_CLOSE_UNAUTHORIZED, "unauthorized");
145109
+ } catch {
145110
+ }
145111
+ }
145112
+ }
145113
+ return;
145114
+ }
144734
145115
  if (msg.type === "register" && typeof msg.clientId === "string") {
144735
145116
  const oldClientId = this.wsToClientId.get(ws2);
144736
145117
  if (oldClientId) this.clientIdToWs.delete(oldClientId);
@@ -144743,14 +145124,54 @@ var StreamerServer = class {
144743
145124
  const lines = await this.ptyManager.getOutputLines(msg.sessionId, 200);
144744
145125
  ws2.send(JSON.stringify({ type: "terminal_replay", sessionId: msg.sessionId, lines }));
144745
145126
  }
145127
+ const pendingGate = this.pendingPermission.get(msg.sessionId);
145128
+ if (pendingGate) {
145129
+ this.log.info(`[ws.replay_permission] ${msg.sessionId.slice(0, 8)}`, {
145130
+ event: "ws.replay_permission",
145131
+ sessionId: msg.sessionId
145132
+ });
145133
+ ws2.send(
145134
+ JSON.stringify({
145135
+ type: "permission",
145136
+ sessionId: msg.sessionId,
145137
+ ...pendingGate.prompt ? { prompt: pendingGate.prompt } : {},
145138
+ ...pendingGate.detail ? { detail: pendingGate.detail } : {},
145139
+ options: pendingGate.options,
145140
+ ...pendingGate.cursor !== void 0 ? { cursor: pendingGate.cursor } : {}
145141
+ })
145142
+ );
145143
+ }
145144
+ const pendingQuestion = this.pendingQuestions.get(msg.sessionId);
145145
+ if (pendingQuestion) {
145146
+ this.log.info(`[ws.replay_question] ${msg.sessionId.slice(0, 8)}`, {
145147
+ event: "ws.replay_question",
145148
+ sessionId: msg.sessionId
145149
+ });
145150
+ ws2.send(
145151
+ JSON.stringify({
145152
+ type: "question",
145153
+ sessionId: msg.sessionId,
145154
+ toolUseId: pendingQuestion.toolUseId,
145155
+ questions: pendingQuestion.questions
145156
+ })
145157
+ );
145158
+ }
144746
145159
  }
144747
145160
  if (msg.type === "hold_session" && typeof msg.sessionId === "string") {
144748
- this.startGraceTimer(msg.sessionId, 0);
145161
+ if (this.sessionSubscribers.get(msg.sessionId)?.has(ws2)) {
145162
+ this.startGraceTimer(msg.sessionId, 0);
145163
+ }
144749
145164
  }
144750
145165
  } catch {
144751
145166
  }
144752
145167
  },
144753
145168
  handleWsClose: (ws2) => {
145169
+ const pendingTimer = this.wsAuthPending.get(ws2);
145170
+ if (pendingTimer) {
145171
+ clearTimeout(pendingTimer);
145172
+ this.wsAuthPending.delete(ws2);
145173
+ }
145174
+ this.wsAuthed.delete(ws2);
144754
145175
  const clientId = this.wsToClientId.get(ws2);
144755
145176
  if (clientId) {
144756
145177
  this.clientIdToWs.delete(clientId);
@@ -144820,6 +145241,20 @@ var StreamerServer = class {
144820
145241
  this.wsHub.broadcast(payload);
144821
145242
  }
144822
145243
  }
145244
+ // M1: finalize a WebSocket auth (via ?key= at upgrade or a first-message
145245
+ // handshake) — register it with the hub and send the initial snapshot. Only
145246
+ // authed sockets reach this, so no unauthenticated client ever receives a
145247
+ // broadcast.
145248
+ // Plan: https://github.com/RonenMars/threadbase-streamer/blob/a251353bfa417bd48ce3f15086bc336a2c622629/docs/plans/2026-06-24-security-hardening.md#L40
145249
+ completeWsAuth(ws2) {
145250
+ this.wsAuthed.add(ws2);
145251
+ this.wsHub.addClient(ws2);
145252
+ const sessions = this.sessionStore.list(this.ptyAttachedIds());
145253
+ ws2.send(JSON.stringify({ type: "session_list", sessions }));
145254
+ if (this.cacheReady) {
145255
+ ws2.send(JSON.stringify({ type: "cache_ready" }));
145256
+ }
145257
+ }
144823
145258
  addSessionSubscriber(sessionId, ws2) {
144824
145259
  let subs = this.sessionSubscribers.get(sessionId);
144825
145260
  if (!subs) {
@@ -144891,7 +145326,7 @@ var StreamerServer = class {
144891
145326
  });
144892
145327
  try {
144893
145328
  this.cache = ConversationCache.open(
144894
- (0, import_path22.join)(this.cacheDir, "cache.db"),
145329
+ (0, import_path23.join)(this.cacheDir, "cache.db"),
144895
145330
  this.tailSize,
144896
145331
  void 0,
144897
145332
  {
@@ -144917,11 +145352,11 @@ var StreamerServer = class {
144917
145352
  if (this.scanProfiles && this.scanProfiles.length > 0) {
144918
145353
  for (const profile of this.scanProfiles) {
144919
145354
  if (profile.enabled) {
144920
- this.fileWatcher.watchDirectory((0, import_path22.join)(profile.configDir, "projects"));
145355
+ this.fileWatcher.watchDirectory((0, import_path23.join)(profile.configDir, "projects"));
144921
145356
  }
144922
145357
  }
144923
145358
  } else {
144924
- this.fileWatcher.watchDirectory((0, import_path22.join)((0, import_os10.homedir)(), ".claude", "projects"));
145359
+ this.fileWatcher.watchDirectory((0, import_path23.join)((0, import_os11.homedir)(), ".claude", "projects"));
144925
145360
  }
144926
145361
  } catch (err) {
144927
145362
  const message = err instanceof Error ? err.message : String(err);
@@ -145106,6 +145541,9 @@ var StreamerServer = class {
145106
145541
  this.ptyManager.dispose();
145107
145542
  this.fileWatcher.dispose();
145108
145543
  this.wsHub.dispose();
145544
+ for (const timer of this.wsAuthPending.values()) clearTimeout(timer);
145545
+ this.wsAuthPending.clear();
145546
+ this.wsAuthed.clear();
145109
145547
  this.pairTokens.dispose();
145110
145548
  if (this.dbPool) {
145111
145549
  await this.dbPool.end();
@@ -145503,17 +145941,17 @@ var StreamerServer = class {
145503
145941
  return scanner;
145504
145942
  }
145505
145943
  findJsonlPath(uuid3) {
145506
- const projectsDir = (0, import_path22.join)((0, import_os10.homedir)(), ".claude", "projects");
145507
- if (!(0, import_fs25.existsSync)(projectsDir)) return null;
145944
+ const projectsDir = (0, import_path23.join)((0, import_os11.homedir)(), ".claude", "projects");
145945
+ if (!(0, import_fs26.existsSync)(projectsDir)) return null;
145508
145946
  const filename = `${uuid3}.jsonl`;
145509
- for (const dir of (0, import_fs25.readdirSync)(projectsDir)) {
145510
- const fp = (0, import_path22.join)(projectsDir, dir, filename);
145511
- if ((0, import_fs25.existsSync)(fp)) return fp;
145512
- const projectDir = (0, import_path22.join)(projectsDir, dir);
145947
+ for (const dir of (0, import_fs26.readdirSync)(projectsDir)) {
145948
+ const fp = (0, import_path23.join)(projectsDir, dir, filename);
145949
+ if ((0, import_fs26.existsSync)(fp)) return fp;
145950
+ const projectDir = (0, import_path23.join)(projectsDir, dir);
145513
145951
  try {
145514
- for (const sub of (0, import_fs25.readdirSync)(projectDir)) {
145515
- const subagentPath = (0, import_path22.join)(projectDir, sub, "subagents", filename);
145516
- if ((0, import_fs25.existsSync)(subagentPath)) return subagentPath;
145952
+ for (const sub of (0, import_fs26.readdirSync)(projectDir)) {
145953
+ const subagentPath = (0, import_path23.join)(projectDir, sub, "subagents", filename);
145954
+ if ((0, import_fs26.existsSync)(subagentPath)) return subagentPath;
145517
145955
  }
145518
145956
  } catch {
145519
145957
  }
@@ -145522,7 +145960,7 @@ var StreamerServer = class {
145522
145960
  }
145523
145961
  async readCwdFromJsonl(filePath) {
145524
145962
  return new Promise((resolve6) => {
145525
- const rl = (0, import_readline4.createInterface)({ input: (0, import_fs25.createReadStream)(filePath), crlfDelay: Infinity });
145963
+ const rl = (0, import_readline4.createInterface)({ input: (0, import_fs26.createReadStream)(filePath), crlfDelay: Infinity });
145526
145964
  let found = false;
145527
145965
  rl.on("line", (line) => {
145528
145966
  if (found) return;
@@ -145660,7 +146098,7 @@ var StreamerServer = class {
145660
146098
  if (!conv.filePath) return false;
145661
146099
  let mtimeMs = null;
145662
146100
  try {
145663
- mtimeMs = (0, import_fs25.statSync)(conv.filePath).mtimeMs;
146101
+ mtimeMs = (0, import_fs26.statSync)(conv.filePath).mtimeMs;
145664
146102
  } catch {
145665
146103
  return false;
145666
146104
  }
@@ -146028,7 +146466,7 @@ var StreamerServer = class {
146028
146466
  handleGetSession(sessionId, res) {
146029
146467
  const session = this.sessionStore.get(sessionId, this.ptyAttachedIds());
146030
146468
  if (session) {
146031
- if (!(0, import_fs25.existsSync)(session.projectPath)) {
146469
+ if (!(0, import_fs26.existsSync)(session.projectPath)) {
146032
146470
  session.failureReason = `Project directory not found: ${session.projectPath}`;
146033
146471
  }
146034
146472
  json2(res, 200, session);
@@ -146232,12 +146670,21 @@ var StreamerServer = class {
146232
146670
  return;
146233
146671
  }
146234
146672
  this.pendingPermission.set(sessionId, gate);
146673
+ const safeOptions = gate.options.map((o) => {
146674
+ const answerKeys = sanitizeAnswerKeys(o.answerKeys);
146675
+ return answerKeys === void 0 ? { index: o.index, label: o.label } : { ...o, answerKeys };
146676
+ });
146677
+ const subscriberCount = this.sessionSubscribers.get(sessionId)?.size ?? 0;
146678
+ this.log.info(
146679
+ `[ws.broadcast_permission] ${sessionId.slice(0, 8)} subscribers=${subscriberCount}`,
146680
+ { event: "ws.broadcast_permission", sessionId, subscriberCount }
146681
+ );
146235
146682
  this.wsHub.broadcast({
146236
146683
  type: "permission",
146237
146684
  sessionId,
146238
146685
  ...gate.prompt ? { prompt: gate.prompt } : {},
146239
146686
  ...gate.detail ? { detail: gate.detail } : {},
146240
- options: gate.options,
146687
+ options: safeOptions,
146241
146688
  ...gate.cursor !== void 0 ? { cursor: gate.cursor } : {}
146242
146689
  });
146243
146690
  }
@@ -146424,7 +146871,7 @@ var StreamerServer = class {
146424
146871
  sessionStore: this.sessionStore,
146425
146872
  // biome-ignore lint/style/noNonNullAssertion: agentClient is set when agentConfig.enabled is true
146426
146873
  agentClient: this.agentClient,
146427
- conversationsDir: this.cacheDir ? (0, import_path22.join)((0, import_path22.dirname)(this.cacheDir), "conversations") : "",
146874
+ conversationsDir: this.cacheDir ? (0, import_path23.join)((0, import_path23.dirname)(this.cacheDir), "conversations") : "",
146428
146875
  agentConfig: this.agentConfig
146429
146876
  });
146430
146877
  json2(res, result.status, result.body);
@@ -146565,9 +147012,9 @@ var StreamerServer = class {
146565
147012
  // was passed to Claude via --session-id so the filename matches from the start.
146566
147013
  watchForJsonl(sessionId, projectPath) {
146567
147014
  const encoded = projectPath.replace(/[/\\:.]/g, "-");
146568
- const projectsDir = (0, import_path22.join)((0, import_os10.homedir)(), ".claude", "projects", encoded);
147015
+ const projectsDir = (0, import_path23.join)((0, import_os11.homedir)(), ".claude", "projects", encoded);
146569
147016
  const expectedFile = `${sessionId}.jsonl`;
146570
- const filePath = (0, import_path22.join)(projectsDir, expectedFile);
147017
+ const filePath = (0, import_path23.join)(projectsDir, expectedFile);
146571
147018
  const deadline = Date.now() + 12e4;
146572
147019
  let watcher = null;
146573
147020
  const cleanup = () => {
@@ -146585,12 +147032,12 @@ var StreamerServer = class {
146585
147032
  cleanup();
146586
147033
  return;
146587
147034
  }
146588
- let resolvedFilePath = (0, import_fs25.existsSync)(filePath) ? filePath : null;
146589
- if (!resolvedFilePath && (0, import_fs25.existsSync)(projectsDir)) {
147035
+ let resolvedFilePath = (0, import_fs26.existsSync)(filePath) ? filePath : null;
147036
+ if (!resolvedFilePath && (0, import_fs26.existsSync)(projectsDir)) {
146590
147037
  try {
146591
147038
  const now = Date.now();
146592
- const recent = (0, import_fs25.readdirSync)(projectsDir).filter((f2) => f2.endsWith(".jsonl")).map((f2) => ({ f: f2, mtime: (0, import_fs25.statSync)((0, import_path22.join)(projectsDir, f2)).mtimeMs })).filter(({ mtime }) => now - mtime < 5e3).sort((a, b2) => b2.mtime - a.mtime)[0];
146593
- if (recent) resolvedFilePath = (0, import_path22.join)(projectsDir, recent.f);
147039
+ const recent = (0, import_fs26.readdirSync)(projectsDir).filter((f2) => f2.endsWith(".jsonl")).map((f2) => ({ f: f2, mtime: (0, import_fs26.statSync)((0, import_path23.join)(projectsDir, f2)).mtimeMs })).filter(({ mtime }) => now - mtime < 5e3).sort((a, b2) => b2.mtime - a.mtime)[0];
147040
+ if (recent) resolvedFilePath = (0, import_path23.join)(projectsDir, recent.f);
146594
147041
  } catch {
146595
147042
  }
146596
147043
  }
@@ -146599,7 +147046,7 @@ var StreamerServer = class {
146599
147046
  this.sessionFileMap.set(sessionId, resolvedFilePath);
146600
147047
  this.fileWatcher.watch(resolvedFilePath);
146601
147048
  try {
146602
- const existing = (0, import_fs25.readFileSync)(resolvedFilePath, "utf8").split("\n").filter(Boolean);
147049
+ const existing = (0, import_fs26.readFileSync)(resolvedFilePath, "utf8").split("\n").filter(Boolean);
146603
147050
  if (existing.length > 0) {
146604
147051
  this.broadcastConversationLines(sessionId, existing);
146605
147052
  }
@@ -146622,7 +147069,7 @@ var StreamerServer = class {
146622
147069
  if (this.sessionFileMap.has(sessionId)) return;
146623
147070
  try {
146624
147071
  require("fs").mkdirSync(projectsDir, { recursive: true });
146625
- watcher = (0, import_fs25.watch)(projectsDir, tryWire);
147072
+ watcher = (0, import_fs26.watch)(projectsDir, tryWire);
146626
147073
  watcher.on("error", cleanup);
146627
147074
  } catch {
146628
147075
  }
@@ -146638,7 +147085,7 @@ var StreamerServer = class {
146638
147085
  watchForCodexRollout(sessionId, projectPath) {
146639
147086
  const deadline = Date.now() + 12e4;
146640
147087
  const now = /* @__PURE__ */ new Date();
146641
- const dateDir = (0, import_path22.join)(
147088
+ const dateDir = (0, import_path23.join)(
146642
147089
  String(now.getFullYear()),
146643
147090
  String(now.getMonth() + 1).padStart(2, "0"),
146644
147091
  String(now.getDate()).padStart(2, "0")
@@ -146651,7 +147098,7 @@ var StreamerServer = class {
146651
147098
  };
146652
147099
  const matchesProjectPath = (candidatePath) => {
146653
147100
  try {
146654
- const firstLine = (0, import_fs25.readFileSync)(candidatePath, "utf8").split("\n", 1)[0];
147101
+ const firstLine = (0, import_fs26.readFileSync)(candidatePath, "utf8").split("\n", 1)[0];
146655
147102
  if (!firstLine) return null;
146656
147103
  const parsed = JSON.parse(firstLine);
146657
147104
  if (parsed?.type !== "session_meta") return null;
@@ -146679,18 +147126,18 @@ var StreamerServer = class {
146679
147126
  this.sessionStore.listManaged().filter((s3) => s3.id !== sessionId && s3.boundConversationId != null).map((s3) => s3.boundConversationId)
146680
147127
  );
146681
147128
  for (const root of this.codexRoots) {
146682
- const sessionsDir = (0, import_path22.join)(root, dateDir);
146683
- if (!(0, import_fs25.existsSync)(sessionsDir)) continue;
147129
+ const sessionsDir = (0, import_path23.join)(root, dateDir);
147130
+ if (!(0, import_fs26.existsSync)(sessionsDir)) continue;
146684
147131
  let candidateFiles;
146685
147132
  try {
146686
- candidateFiles = (0, import_fs25.readdirSync)(sessionsDir).filter((f2) => f2.endsWith(".jsonl"));
147133
+ candidateFiles = (0, import_fs26.readdirSync)(sessionsDir).filter((f2) => f2.endsWith(".jsonl"));
146687
147134
  } catch {
146688
147135
  continue;
146689
147136
  }
146690
147137
  const nowMs = Date.now();
146691
- const recentCandidates = candidateFiles.map((f2) => ({ f: f2, mtime: (0, import_fs25.statSync)((0, import_path22.join)(sessionsDir, f2)).mtimeMs })).filter(({ mtime }) => nowMs - mtime < 1e4).sort((a, b2) => b2.mtime - a.mtime);
147138
+ const recentCandidates = candidateFiles.map((f2) => ({ f: f2, mtime: (0, import_fs26.statSync)((0, import_path23.join)(sessionsDir, f2)).mtimeMs })).filter(({ mtime }) => nowMs - mtime < 1e4).sort((a, b2) => b2.mtime - a.mtime);
146692
147139
  for (const { f: f2 } of recentCandidates) {
146693
- const candidatePath = (0, import_path22.join)(sessionsDir, f2);
147140
+ const candidatePath = (0, import_path23.join)(sessionsDir, f2);
146694
147141
  const match2 = matchesProjectPath(candidatePath);
146695
147142
  if (!match2) continue;
146696
147143
  if (boundElsewhere.has(match2.id)) continue;
@@ -146700,7 +147147,7 @@ var StreamerServer = class {
146700
147147
  this.sessionFileMap.set(sessionId, candidatePath);
146701
147148
  this.fileWatcher.watch(candidatePath);
146702
147149
  try {
146703
- const existing = (0, import_fs25.readFileSync)(candidatePath, "utf8").split("\n").filter(Boolean);
147150
+ const existing = (0, import_fs26.readFileSync)(candidatePath, "utf8").split("\n").filter(Boolean);
146704
147151
  if (existing.length > 0) {
146705
147152
  this.broadcastConversationLines(sessionId, existing);
146706
147153
  }
@@ -146822,7 +147269,7 @@ var StreamerServer = class {
146822
147269
  };
146823
147270
  function classifyResumability(cwd) {
146824
147271
  if (!cwd) return { resumable: true };
146825
- if ((0, import_fs25.existsSync)(cwd)) return { resumable: true };
147272
+ if ((0, import_fs26.existsSync)(cwd)) return { resumable: true };
146826
147273
  const ranInWorktree = /\/\.worktrees\//.test(cwd) || /\/\.claude\/worktrees\//.test(cwd);
146827
147274
  return {
146828
147275
  resumable: false,
@@ -147086,7 +147533,7 @@ async function checkForUpdate(opts) {
147086
147533
  }
147087
147534
 
147088
147535
  // src/updater/install.ts
147089
- var import_node_fs19 = require("fs");
147536
+ var import_node_fs20 = require("fs");
147090
147537
 
147091
147538
  // src/updater/active-sessions.ts
147092
147539
  async function countActiveSessions(opts) {
@@ -147139,8 +147586,8 @@ function isBrewInstall(scriptPath = process.argv[1] ?? "") {
147139
147586
 
147140
147587
  // src/updater/download.ts
147141
147588
  var import_node_crypto4 = require("crypto");
147142
- var import_node_fs8 = require("fs");
147143
- var import_node_path10 = require("path");
147589
+ var import_node_fs9 = require("fs");
147590
+ var import_node_path11 = require("path");
147144
147591
  var import_promises20 = require("stream/promises");
147145
147592
 
147146
147593
  // src/updater/manifest.ts
@@ -147200,13 +147647,13 @@ async function downloadAndVerify(opts) {
147200
147647
  `Manifest references ${artifact.filename} but it is not attached to the release`
147201
147648
  );
147202
147649
  }
147203
- (0, import_node_fs8.mkdirSync)((0, import_node_path10.dirname)(targetPath), { recursive: true });
147650
+ (0, import_node_fs9.mkdirSync)((0, import_node_path11.dirname)(targetPath), { recursive: true });
147204
147651
  const res = await fetch(asset.browserDownloadUrl);
147205
147652
  if (!res.ok || !res.body) {
147206
147653
  throw new Error(`Failed to download ${artifact.filename}: ${res.status} ${res.statusText}`);
147207
147654
  }
147208
147655
  const hash2 = (0, import_node_crypto4.createHash)("sha256");
147209
- const out = (0, import_node_fs8.createWriteStream)(targetPath);
147656
+ const out = (0, import_node_fs9.createWriteStream)(targetPath);
147210
147657
  let bytes = 0;
147211
147658
  const measured = new TransformStream({
147212
147659
  transform(chunk, controller) {
@@ -147218,19 +147665,19 @@ async function downloadAndVerify(opts) {
147218
147665
  try {
147219
147666
  await (0, import_promises20.pipeline)(res.body.pipeThrough(measured), out);
147220
147667
  } catch (err) {
147221
- (0, import_node_fs8.rmSync)(targetPath, { force: true });
147668
+ (0, import_node_fs9.rmSync)(targetPath, { force: true });
147222
147669
  throw err;
147223
147670
  }
147224
147671
  const actual = hash2.digest("hex");
147225
147672
  if (actual !== artifact.sha256) {
147226
- (0, import_node_fs8.rmSync)(targetPath, { force: true });
147673
+ (0, import_node_fs9.rmSync)(targetPath, { force: true });
147227
147674
  throw new Error(
147228
147675
  `sha256 mismatch for ${artifact.filename}: expected ${artifact.sha256}, got ${actual}`
147229
147676
  );
147230
147677
  }
147231
- const stat10 = (0, import_node_fs8.statSync)(targetPath);
147678
+ const stat10 = (0, import_node_fs9.statSync)(targetPath);
147232
147679
  if (stat10.size !== artifact.size) {
147233
- (0, import_node_fs8.rmSync)(targetPath, { force: true });
147680
+ (0, import_node_fs9.rmSync)(targetPath, { force: true });
147234
147681
  throw new Error(
147235
147682
  `size mismatch for ${artifact.filename}: expected ${artifact.size}, got ${stat10.size}`
147236
147683
  );
@@ -147240,16 +147687,16 @@ async function downloadAndVerify(opts) {
147240
147687
 
147241
147688
  // src/updater/paths.ts
147242
147689
  var import_node_os4 = require("os");
147243
- var import_node_path11 = require("path");
147244
- var THREADBASE_ROOT = (0, import_node_path11.join)((0, import_node_os4.homedir)(), ".threadbase");
147245
- var RELEASES_DIR = (0, import_node_path11.join)(THREADBASE_ROOT, "releases");
147246
- var CURRENT_SYMLINK = (0, import_node_path11.join)(THREADBASE_ROOT, "current");
147247
- var DOWNLOAD_DIR = (0, import_node_path11.join)(THREADBASE_ROOT, "releases", ".tmp");
147690
+ var import_node_path12 = require("path");
147691
+ var THREADBASE_ROOT = (0, import_node_path12.join)((0, import_node_os4.homedir)(), ".threadbase");
147692
+ var RELEASES_DIR = (0, import_node_path12.join)(THREADBASE_ROOT, "releases");
147693
+ var CURRENT_SYMLINK = (0, import_node_path12.join)(THREADBASE_ROOT, "current");
147694
+ var DOWNLOAD_DIR = (0, import_node_path12.join)(THREADBASE_ROOT, "releases", ".tmp");
147248
147695
  function releaseDir(version2) {
147249
- return (0, import_node_path11.join)(RELEASES_DIR, version2);
147696
+ return (0, import_node_path12.join)(RELEASES_DIR, version2);
147250
147697
  }
147251
147698
  function downloadPath(version2, filename) {
147252
- return (0, import_node_path11.join)(DOWNLOAD_DIR, `${version2}-${filename}`);
147699
+ return (0, import_node_path12.join)(DOWNLOAD_DIR, `${version2}-${filename}`);
147253
147700
  }
147254
147701
 
147255
147702
  // src/updater/restart.ts
@@ -147330,111 +147777,111 @@ async function stopService(opts = {}) {
147330
147777
  }
147331
147778
 
147332
147779
  // src/updater/stamp-version.ts
147333
- var import_node_fs9 = require("fs");
147334
- var import_node_path12 = require("path");
147780
+ var import_node_fs10 = require("fs");
147781
+ var import_node_path13 = require("path");
147335
147782
  function stampVersionTxt(destDir, version2) {
147336
- const distDir = (0, import_node_path12.join)(destDir, "dist");
147337
- (0, import_node_fs9.mkdirSync)(distDir, { recursive: true });
147338
- (0, import_node_fs9.writeFileSync)((0, import_node_path12.join)(distDir, "version.txt"), `${version2}+update
147783
+ const distDir = (0, import_node_path13.join)(destDir, "dist");
147784
+ (0, import_node_fs10.mkdirSync)(distDir, { recursive: true });
147785
+ (0, import_node_fs10.writeFileSync)((0, import_node_path13.join)(distDir, "version.txt"), `${version2}+update
147339
147786
  `);
147340
147787
  }
147341
147788
 
147342
147789
  // src/updater/swap.ts
147343
- var import_node_fs10 = require("fs");
147344
- var import_node_path13 = require("path");
147790
+ var import_node_fs11 = require("fs");
147791
+ var import_node_path14 = require("path");
147345
147792
  var import_semver2 = __toESM(require_semver2(), 1);
147346
147793
  var KEEP_LAST_N = 2;
147347
147794
  function swapCurrent(version2) {
147348
147795
  const target = releaseDir(version2);
147349
- if (!(0, import_node_fs10.existsSync)(target)) {
147796
+ if (!(0, import_node_fs11.existsSync)(target)) {
147350
147797
  throw new Error(`Cannot swap to ${version2}: ${target} does not exist`);
147351
147798
  }
147352
147799
  if (process.platform === "win32") {
147353
147800
  const tmp = `${CURRENT_SYMLINK}.new`;
147354
- (0, import_node_fs10.rmSync)(tmp, { recursive: true, force: true });
147355
- (0, import_node_fs10.cpSync)(target, tmp, { recursive: true });
147356
- if ((0, import_node_fs10.existsSync)(CURRENT_SYMLINK)) {
147357
- (0, import_node_fs10.rmSync)(CURRENT_SYMLINK, { recursive: true, force: true });
147801
+ (0, import_node_fs11.rmSync)(tmp, { recursive: true, force: true });
147802
+ (0, import_node_fs11.cpSync)(target, tmp, { recursive: true });
147803
+ if ((0, import_node_fs11.existsSync)(CURRENT_SYMLINK)) {
147804
+ (0, import_node_fs11.rmSync)(CURRENT_SYMLINK, { recursive: true, force: true });
147358
147805
  }
147359
- (0, import_node_fs10.renameSync)(tmp, CURRENT_SYMLINK);
147360
- (0, import_node_fs10.copyFileSync)((0, import_node_path13.join)(CURRENT_SYMLINK, "dist", "cli.cjs"), (0, import_node_path13.join)(THREADBASE_ROOT, "cli.js"));
147806
+ (0, import_node_fs11.renameSync)(tmp, CURRENT_SYMLINK);
147807
+ (0, import_node_fs11.copyFileSync)((0, import_node_path14.join)(CURRENT_SYMLINK, "dist", "cli.cjs"), (0, import_node_path14.join)(THREADBASE_ROOT, "cli.js"));
147361
147808
  return;
147362
147809
  }
147363
147810
  const tmpLink = `${CURRENT_SYMLINK}.new`;
147364
- if ((0, import_node_fs10.existsSync)(tmpLink) || lstatSafeIsSymlink(tmpLink)) {
147365
- (0, import_node_fs10.unlinkSync)(tmpLink);
147811
+ if ((0, import_node_fs11.existsSync)(tmpLink) || lstatSafeIsSymlink(tmpLink)) {
147812
+ (0, import_node_fs11.unlinkSync)(tmpLink);
147366
147813
  }
147367
- (0, import_node_fs10.symlinkSync)(target, tmpLink);
147368
- (0, import_node_fs10.renameSync)(tmpLink, CURRENT_SYMLINK);
147369
- const cliJs = (0, import_node_path13.join)(THREADBASE_ROOT, "cli.js");
147814
+ (0, import_node_fs11.symlinkSync)(target, tmpLink);
147815
+ (0, import_node_fs11.renameSync)(tmpLink, CURRENT_SYMLINK);
147816
+ const cliJs = (0, import_node_path14.join)(THREADBASE_ROOT, "cli.js");
147370
147817
  const tmpCliJs = `${cliJs}.new`;
147371
- if ((0, import_node_fs10.existsSync)(tmpCliJs) || lstatSafeIsSymlink(tmpCliJs)) (0, import_node_fs10.unlinkSync)(tmpCliJs);
147372
- (0, import_node_fs10.symlinkSync)((0, import_node_path13.join)(target, "dist", "cli.cjs"), tmpCliJs);
147373
- (0, import_node_fs10.renameSync)(tmpCliJs, cliJs);
147818
+ if ((0, import_node_fs11.existsSync)(tmpCliJs) || lstatSafeIsSymlink(tmpCliJs)) (0, import_node_fs11.unlinkSync)(tmpCliJs);
147819
+ (0, import_node_fs11.symlinkSync)((0, import_node_path14.join)(target, "dist", "cli.cjs"), tmpCliJs);
147820
+ (0, import_node_fs11.renameSync)(tmpCliJs, cliJs);
147374
147821
  }
147375
147822
  function lstatSafeIsSymlink(path2) {
147376
147823
  try {
147377
- return (0, import_node_fs10.lstatSync)(path2).isSymbolicLink();
147824
+ return (0, import_node_fs11.lstatSync)(path2).isSymbolicLink();
147378
147825
  } catch {
147379
147826
  return false;
147380
147827
  }
147381
147828
  }
147382
147829
  function pruneOldReleases(activeVersion, keep = KEEP_LAST_N) {
147383
- if (!(0, import_node_fs10.existsSync)(RELEASES_DIR)) return [];
147384
- const entries = (0, import_node_fs10.readdirSync)(RELEASES_DIR, { withFileTypes: true }).filter((e) => e.isDirectory() && !e.name.startsWith(".")).map((e) => e.name).filter((name) => import_semver2.default.valid(name) !== null);
147830
+ if (!(0, import_node_fs11.existsSync)(RELEASES_DIR)) return [];
147831
+ const entries = (0, import_node_fs11.readdirSync)(RELEASES_DIR, { withFileTypes: true }).filter((e) => e.isDirectory() && !e.name.startsWith(".")).map((e) => e.name).filter((name) => import_semver2.default.valid(name) !== null);
147385
147832
  const sorted = entries.sort((a, b2) => import_semver2.default.rcompare(a, b2));
147386
147833
  const toKeep = new Set(sorted.slice(0, keep));
147387
147834
  toKeep.add(activeVersion);
147388
147835
  const removed = [];
147389
147836
  for (const name of sorted) {
147390
147837
  if (toKeep.has(name)) continue;
147391
- (0, import_node_fs10.rmSync)(releaseDir(name), { recursive: true, force: true });
147838
+ (0, import_node_fs11.rmSync)(releaseDir(name), { recursive: true, force: true });
147392
147839
  removed.push(name);
147393
147840
  }
147394
147841
  return removed;
147395
147842
  }
147396
147843
  function ensureReleasesDir() {
147397
- (0, import_node_fs10.mkdirSync)(RELEASES_DIR, { recursive: true });
147844
+ (0, import_node_fs11.mkdirSync)(RELEASES_DIR, { recursive: true });
147398
147845
  }
147399
147846
 
147400
147847
  // src/updater/unpack.ts
147401
- var import_node_fs17 = require("fs");
147848
+ var import_node_fs18 = require("fs");
147402
147849
 
147403
147850
  // node_modules/tar/dist/esm/index.min.js
147404
147851
  var import_events4 = __toESM(require("events"), 1);
147405
- var import_fs26 = __toESM(require("fs"), 1);
147852
+ var import_fs27 = __toESM(require("fs"), 1);
147406
147853
  var import_node_events3 = require("events");
147407
147854
  var import_node_stream3 = __toESM(require("stream"), 1);
147408
147855
  var import_node_string_decoder = require("string_decoder");
147409
- var import_node_path14 = __toESM(require("path"), 1);
147410
- var import_node_fs11 = __toESM(require("fs"), 1);
147411
- var import_path23 = require("path");
147856
+ var import_node_path15 = __toESM(require("path"), 1);
147857
+ var import_node_fs12 = __toESM(require("fs"), 1);
147858
+ var import_path24 = require("path");
147412
147859
  var import_events5 = require("events");
147413
147860
  var import_assert = __toESM(require("assert"), 1);
147414
147861
  var import_buffer2 = require("buffer");
147415
147862
  var Ps = __toESM(require("zlib"), 1);
147416
147863
  var import_zlib = __toESM(require("zlib"), 1);
147417
- var import_node_path15 = require("path");
147418
147864
  var import_node_path16 = require("path");
147419
- var import_fs27 = __toESM(require("fs"), 1);
147420
- var import_fs28 = __toESM(require("fs"), 1);
147421
- var import_path24 = __toESM(require("path"), 1);
147422
147865
  var import_node_path17 = require("path");
147866
+ var import_fs28 = __toESM(require("fs"), 1);
147867
+ var import_fs29 = __toESM(require("fs"), 1);
147423
147868
  var import_path25 = __toESM(require("path"), 1);
147424
- var import_node_fs12 = __toESM(require("fs"), 1);
147869
+ var import_node_path18 = require("path");
147870
+ var import_path26 = __toESM(require("path"), 1);
147871
+ var import_node_fs13 = __toESM(require("fs"), 1);
147425
147872
  var import_node_assert = __toESM(require("assert"), 1);
147426
147873
  var import_node_crypto5 = require("crypto");
147427
- var import_node_fs13 = __toESM(require("fs"), 1);
147428
- var import_node_path18 = __toESM(require("path"), 1);
147429
- var import_fs29 = __toESM(require("fs"), 1);
147430
147874
  var import_node_fs14 = __toESM(require("fs"), 1);
147431
147875
  var import_node_path19 = __toESM(require("path"), 1);
147876
+ var import_fs30 = __toESM(require("fs"), 1);
147432
147877
  var import_node_fs15 = __toESM(require("fs"), 1);
147433
- var import_promises21 = __toESM(require("fs/promises"), 1);
147434
147878
  var import_node_path20 = __toESM(require("path"), 1);
147435
- var import_node_path21 = require("path");
147436
147879
  var import_node_fs16 = __toESM(require("fs"), 1);
147437
- var import_node_path22 = __toESM(require("path"), 1);
147880
+ var import_promises21 = __toESM(require("fs/promises"), 1);
147881
+ var import_node_path21 = __toESM(require("path"), 1);
147882
+ var import_node_path22 = require("path");
147883
+ var import_node_fs17 = __toESM(require("fs"), 1);
147884
+ var import_node_path23 = __toESM(require("path"), 1);
147438
147885
  var zr = Object.defineProperty;
147439
147886
  var Ur = (s3, t) => {
147440
147887
  for (var e in t) zr(s3, e, { get: t[e], enumerable: true });
@@ -147778,7 +148225,7 @@ var A = class extends import_node_events3.EventEmitter {
147778
148225
  return Wr;
147779
148226
  }
147780
148227
  };
147781
- var Jr = import_fs26.default.writev;
148228
+ var Jr = import_fs27.default.writev;
147782
148229
  var ht = /* @__PURE__ */ Symbol("_autoClose");
147783
148230
  var H2 = /* @__PURE__ */ Symbol("_close");
147784
148231
  var te = /* @__PURE__ */ Symbol("_ended");
@@ -147833,7 +148280,7 @@ var _t = class extends A {
147833
148280
  throw new TypeError("this is a readable stream");
147834
148281
  }
147835
148282
  [at]() {
147836
- import_fs26.default.open(this[U], "r", (t, e) => this[Ht](t, e));
148283
+ import_fs27.default.open(this[U], "r", (t, e) => this[Ht](t, e));
147837
148284
  }
147838
148285
  [Ht](t, e) {
147839
148286
  t ? this[Ut](t) : (this[u] = e, this.emit("open", e), this[zt]());
@@ -147846,7 +148293,7 @@ var _t = class extends A {
147846
148293
  this[j] = true;
147847
148294
  let t = this[vi]();
147848
148295
  if (t.length === 0) return process.nextTick(() => this[Ii](null, 0, t));
147849
- import_fs26.default.read(this[u], t, 0, t.length, null, (e, i, r) => this[Ii](e, i, r));
148296
+ import_fs27.default.read(this[u], t, 0, t.length, null, (e, i, r) => this[Ii](e, i, r));
147850
148297
  }
147851
148298
  }
147852
148299
  [Ii](t, e, i) {
@@ -147855,7 +148302,7 @@ var _t = class extends A {
147855
148302
  [H2]() {
147856
148303
  if (this[ht] && typeof this[u] == "number") {
147857
148304
  let t = this[u];
147858
- this[u] = void 0, import_fs26.default.close(t, (e) => e ? this.emit("error", e) : this.emit("close"));
148305
+ this[u] = void 0, import_fs27.default.close(t, (e) => e ? this.emit("error", e) : this.emit("close"));
147859
148306
  }
147860
148307
  }
147861
148308
  [Ut](t) {
@@ -147883,7 +148330,7 @@ var Be = class extends _t {
147883
148330
  [at]() {
147884
148331
  let t = true;
147885
148332
  try {
147886
- this[Ht](null, import_fs26.default.openSync(this[U], "r")), t = false;
148333
+ this[Ht](null, import_fs27.default.openSync(this[U], "r")), t = false;
147887
148334
  } finally {
147888
148335
  t && this[H2]();
147889
148336
  }
@@ -147894,7 +148341,7 @@ var Be = class extends _t {
147894
148341
  if (!this[j]) {
147895
148342
  this[j] = true;
147896
148343
  do {
147897
- let e = this[vi](), i = e.length === 0 ? 0 : import_fs26.default.readSync(this[u], e, 0, e.length, null);
148344
+ let e = this[vi](), i = e.length === 0 ? 0 : import_fs27.default.readSync(this[u], e, 0, e.length, null);
147898
148345
  if (!this[ki](i, e)) break;
147899
148346
  } while (true);
147900
148347
  this[j] = false;
@@ -147907,7 +148354,7 @@ var Be = class extends _t {
147907
148354
  [H2]() {
147908
148355
  if (this[ht] && typeof this[u] == "number") {
147909
148356
  let t = this[u];
147910
- this[u] = void 0, import_fs26.default.closeSync(t), this.emit("close");
148357
+ this[u] = void 0, import_fs27.default.closeSync(t), this.emit("close");
147911
148358
  }
147912
148359
  }
147913
148360
  };
@@ -147949,7 +148396,7 @@ var et = class extends import_events4.default {
147949
148396
  this[H2](), this[gt] = true, this.emit("error", t);
147950
148397
  }
147951
148398
  [at]() {
147952
- import_fs26.default.open(this[U], this[tt], this[ie], (t, e) => this[Ht](t, e));
148399
+ import_fs27.default.open(this[U], this[tt], this[ie], (t, e) => this[Ht](t, e));
147953
148400
  }
147954
148401
  [Ht](t, e) {
147955
148402
  this[Me] && this[tt] === "r+" && t && t.code === "ENOENT" ? (this[tt] = "w", this[at]()) : t ? this[Ut](t) : (this[u] = e, this.emit("open", e), this[gt] || this[Ai]());
@@ -147961,7 +148408,7 @@ var et = class extends import_events4.default {
147961
148408
  return typeof t == "string" && (t = Buffer.from(t, e)), this[te] ? (this.emit("error", new Error("write() after end()")), false) : this[u] === void 0 || this[gt] || this[Y2].length ? (this[Y2].push(t), this[ke] = true, false) : (this[gt] = true, this[ve](t), true);
147962
148409
  }
147963
148410
  [ve](t) {
147964
- import_fs26.default.write(this[u], t, 0, t.length, this[ot], (e, i) => this[Pt](e, i));
148411
+ import_fs27.default.write(this[u], t, 0, t.length, this[ot], (e, i) => this[Pt](e, i));
147965
148412
  }
147966
148413
  [Pt](t, e) {
147967
148414
  t ? this[Ut](t) : (this[ot] !== void 0 && typeof e == "number" && (this[ot] += e), this[Y2].length ? this[Ai]() : (this[gt] = false, this[te] && !this[Ni] ? (this[Ni] = true, this[H2](), this.emit("finish")) : this[ke] && (this[ke] = false, this.emit("drain"))));
@@ -147977,7 +148424,7 @@ var et = class extends import_events4.default {
147977
148424
  [H2]() {
147978
148425
  if (this[ht] && typeof this[u] == "number") {
147979
148426
  let t = this[u];
147980
- this[u] = void 0, import_fs26.default.close(t, (e) => e ? this.emit("error", e) : this.emit("close"));
148427
+ this[u] = void 0, import_fs27.default.close(t, (e) => e ? this.emit("error", e) : this.emit("close"));
147981
148428
  }
147982
148429
  }
147983
148430
  };
@@ -147985,24 +148432,24 @@ var Wt = class extends et {
147985
148432
  [at]() {
147986
148433
  let t;
147987
148434
  if (this[Me] && this[tt] === "r+") try {
147988
- t = import_fs26.default.openSync(this[U], this[tt], this[ie]);
148435
+ t = import_fs27.default.openSync(this[U], this[tt], this[ie]);
147989
148436
  } catch (e) {
147990
148437
  if (e?.code === "ENOENT") return this[tt] = "w", this[at]();
147991
148438
  throw e;
147992
148439
  }
147993
- else t = import_fs26.default.openSync(this[U], this[tt], this[ie]);
148440
+ else t = import_fs27.default.openSync(this[U], this[tt], this[ie]);
147994
148441
  this[Ht](null, t);
147995
148442
  }
147996
148443
  [H2]() {
147997
148444
  if (this[ht] && typeof this[u] == "number") {
147998
148445
  let t = this[u];
147999
- this[u] = void 0, import_fs26.default.closeSync(t), this.emit("close");
148446
+ this[u] = void 0, import_fs27.default.closeSync(t), this.emit("close");
148000
148447
  }
148001
148448
  }
148002
148449
  [ve](t) {
148003
148450
  let e = true;
148004
148451
  try {
148005
- this[Pt](null, import_fs26.default.writeSync(this[u], t, 0, t.length, this[ot])), e = false;
148452
+ this[Pt](null, import_fs27.default.writeSync(this[u], t, 0, t.length, this[ot])), e = false;
148006
148453
  } finally {
148007
148454
  if (e) try {
148008
148455
  this[H2]();
@@ -148328,12 +148775,12 @@ var F = class {
148328
148775
  }
148329
148776
  };
148330
148777
  var un = (s3, t) => {
148331
- let i = s3, r = "", n, o = import_node_path15.posix.parse(s3).root || ".";
148778
+ let i = s3, r = "", n, o = import_node_path16.posix.parse(s3).root || ".";
148332
148779
  if (Buffer.byteLength(i) < 100) n = [i, r, false];
148333
148780
  else {
148334
- r = import_node_path15.posix.dirname(i), i = import_node_path15.posix.basename(i);
148781
+ r = import_node_path16.posix.dirname(i), i = import_node_path16.posix.basename(i);
148335
148782
  do
148336
- Buffer.byteLength(i) <= 100 && Buffer.byteLength(r) <= t ? n = [i, r, false] : Buffer.byteLength(i) > 100 && Buffer.byteLength(r) <= t ? n = [i.slice(0, 99), r, true] : (i = import_node_path15.posix.join(import_node_path15.posix.basename(r), i), r = import_node_path15.posix.dirname(r));
148783
+ Buffer.byteLength(i) <= 100 && Buffer.byteLength(r) <= t ? n = [i, r, false] : Buffer.byteLength(i) > 100 && Buffer.byteLength(r) <= t ? n = [i.slice(0, 99), r, true] : (i = import_node_path16.posix.join(import_node_path16.posix.basename(r), i), r = import_node_path16.posix.dirname(r));
148337
148784
  while (r !== o && n === void 0);
148338
148785
  n || (n = [s3.slice(0, 99), "", true]);
148339
148786
  }
@@ -148379,7 +148826,7 @@ var ft = class s {
148379
148826
  if (t === "") return Buffer.allocUnsafe(0);
148380
148827
  let e = Buffer.byteLength(t), i = 512 * Math.ceil(1 + e / 512), r = Buffer.allocUnsafe(i);
148381
148828
  for (let n = 0; n < 512; n++) r[n] = 0;
148382
- new F({ path: ("PaxHeader/" + (0, import_node_path16.basename)(this.path ?? "")).slice(0, 99), mode: this.mode || 420, uid: this.uid, gid: this.gid, size: e, mtime: this.mtime, type: this.global ? "GlobalExtendedHeader" : "ExtendedHeader", linkpath: "", uname: this.uname || "", gname: this.gname || "", devmaj: 0, devmin: 0, atime: this.atime, ctime: this.ctime }).encode(r), r.write(t, 512, e, "utf8");
148829
+ new F({ path: ("PaxHeader/" + (0, import_node_path17.basename)(this.path ?? "")).slice(0, 99), mode: this.mode || 420, uid: this.uid, gid: this.gid, size: e, mtime: this.mtime, type: this.global ? "GlobalExtendedHeader" : "ExtendedHeader", linkpath: "", uname: this.uname || "", gname: this.gname || "", devmaj: 0, devmin: 0, atime: this.atime, ctime: this.ctime }).encode(r), r.write(t, 512, e, "utf8");
148383
148830
  for (let n = e + 512; n < r.length; n++) r[n] = 0;
148384
148831
  return r;
148385
148832
  }
@@ -148785,11 +149232,11 @@ var vn = (s3) => {
148785
149232
  };
148786
149233
  var Qi = (s3, t) => {
148787
149234
  let e = new Map(t.map((n) => [ut(n), true])), i = s3.filter, r = (n, o = "") => {
148788
- let h = o || (0, import_path23.parse)(n).root || ".", a;
149235
+ let h = o || (0, import_path24.parse)(n).root || ".", a;
148789
149236
  if (n === h) a = false;
148790
149237
  else {
148791
149238
  let l = e.get(n);
148792
- a = l !== void 0 ? l : r((0, import_path23.dirname)(n), h);
149239
+ a = l !== void 0 ? l : r((0, import_path24.dirname)(n), h);
148793
149240
  }
148794
149241
  return e.set(n, a), a;
148795
149242
  };
@@ -148798,15 +149245,15 @@ var Qi = (s3, t) => {
148798
149245
  var Mn = (s3) => {
148799
149246
  let t = new rt(s3), e = s3.file, i;
148800
149247
  try {
148801
- i = import_node_fs11.default.openSync(e, "r");
148802
- let r = import_node_fs11.default.fstatSync(i), n = s3.maxReadSize || 16 * 1024 * 1024;
149248
+ i = import_node_fs12.default.openSync(e, "r");
149249
+ let r = import_node_fs12.default.fstatSync(i), n = s3.maxReadSize || 16 * 1024 * 1024;
148803
149250
  if (r.size < n) {
148804
- let o = Buffer.allocUnsafe(r.size), h = import_node_fs11.default.readSync(i, o, 0, r.size, 0);
149251
+ let o = Buffer.allocUnsafe(r.size), h = import_node_fs12.default.readSync(i, o, 0, r.size, 0);
148805
149252
  t.end(h === o.byteLength ? o : o.subarray(0, h));
148806
149253
  } else {
148807
149254
  let o = 0, h = Buffer.allocUnsafe(n);
148808
149255
  for (; o < r.size; ) {
148809
- let a = import_node_fs11.default.readSync(i, h, 0, n, o);
149256
+ let a = import_node_fs12.default.readSync(i, h, 0, n, o);
148810
149257
  if (a === 0) break;
148811
149258
  o += a, t.write(h.subarray(0, a));
148812
149259
  }
@@ -148814,7 +149261,7 @@ var Mn = (s3) => {
148814
149261
  }
148815
149262
  } finally {
148816
149263
  if (typeof i == "number") try {
148817
- import_node_fs11.default.closeSync(i);
149264
+ import_node_fs12.default.closeSync(i);
148818
149265
  } catch {
148819
149266
  }
148820
149267
  }
@@ -148822,7 +149269,7 @@ var Mn = (s3) => {
148822
149269
  var Bn = (s3, t) => {
148823
149270
  let e = new rt(s3), i = s3.maxReadSize || 16 * 1024 * 1024, r = s3.file;
148824
149271
  return new Promise((o, h) => {
148825
- e.on("error", h), e.on("end", o), import_node_fs11.default.stat(r, (a, l) => {
149272
+ e.on("error", h), e.on("end", o), import_node_fs12.default.stat(r, (a, l) => {
148826
149273
  if (a) h(a);
148827
149274
  else {
148828
149275
  let c = new _t(r, { readSize: i, size: l.size });
@@ -148835,7 +149282,7 @@ var Ct = K(Mn, Bn, (s3) => new rt(s3), (s3) => new rt(s3), (s3, t) => {
148835
149282
  t?.length && Qi(s3, t), s3.noResume || vn(s3);
148836
149283
  });
148837
149284
  var Ji = (s3, t, e) => (s3 &= 4095, e && (s3 = (s3 | 384) & -19), t && (s3 & 256 && (s3 |= 64), s3 & 32 && (s3 |= 8), s3 & 4 && (s3 |= 1)), s3);
148838
- var { isAbsolute: zn, parse: qs } = import_node_path17.win32;
149285
+ var { isAbsolute: zn, parse: qs } = import_node_path18.win32;
148839
149286
  var ce = (s3) => {
148840
149287
  let t = "", e = qs(s3);
148841
149288
  for (; zn(s3) || e.root; ) {
@@ -148909,7 +149356,7 @@ var de = class extends A {
148909
149356
  let [o, h] = ce(this.path);
148910
149357
  o && typeof h == "string" && (this.path = h, r = o);
148911
149358
  }
148912
- this.win32 = !!i.win32 || process.platform === "win32", this.win32 && (this.path = Qs(this.path.replaceAll(/\\/g, "/")), t = t.replaceAll(/\\/g, "/")), this.absolute = f(i.absolute || import_path24.default.resolve(this.cwd, t)), this.path === "" && (this.path = "./"), r && this.warn("TAR_ENTRY_INFO", `stripping ${r} from absolute path`, { entry: this, path: r + this.path });
149359
+ this.win32 = !!i.win32 || process.platform === "win32", this.win32 && (this.path = Qs(this.path.replaceAll(/\\/g, "/")), t = t.replaceAll(/\\/g, "/")), this.absolute = f(i.absolute || import_path25.default.resolve(this.cwd, t)), this.path === "" && (this.path = "./"), r && this.warn("TAR_ENTRY_INFO", `stripping ${r} from absolute path`, { entry: this, path: r + this.path });
148913
149360
  let n = this.statCache.get(this.absolute);
148914
149361
  n ? this[si](n) : this[ss]();
148915
149362
  }
@@ -148920,7 +149367,7 @@ var de = class extends A {
148920
149367
  return t === "error" && (this.#t = true), super.emit(t, ...e);
148921
149368
  }
148922
149369
  [ss]() {
148923
- import_fs28.default.lstat(this.absolute, (t, e) => {
149370
+ import_fs29.default.lstat(this.absolute, (t, e) => {
148924
149371
  if (t) return this.emit("error", t);
148925
149372
  this[si](e);
148926
149373
  });
@@ -148958,7 +149405,7 @@ var de = class extends A {
148958
149405
  this.path.slice(-1) !== "/" && (this.path += "/"), this.stat.size = 0, this[fe](), this.end();
148959
149406
  }
148960
149407
  [is]() {
148961
- import_fs28.default.readlink(this.absolute, (t, e) => {
149408
+ import_fs29.default.readlink(this.absolute, (t, e) => {
148962
149409
  if (t) return this.emit("error", t);
148963
149410
  this[ns](e);
148964
149411
  });
@@ -148968,7 +149415,7 @@ var de = class extends A {
148968
149415
  }
148969
149416
  [sr](t) {
148970
149417
  if (!this.stat) throw new Error("cannot create link entry without stat");
148971
- this.type = "Link", this.linkpath = f(import_path24.default.relative(this.cwd, t)), this.stat.size = 0, this[fe](), this.end();
149418
+ this.type = "Link", this.linkpath = f(import_path25.default.relative(this.cwd, t)), this.stat.size = 0, this[fe](), this.end();
148972
149419
  }
148973
149420
  [er]() {
148974
149421
  if (!this.stat) throw new Error("cannot create file entry without stat");
@@ -148981,7 +149428,7 @@ var de = class extends A {
148981
149428
  this[os]();
148982
149429
  }
148983
149430
  [os]() {
148984
- import_fs28.default.open(this.absolute, "r", (t, e) => {
149431
+ import_fs29.default.open(this.absolute, "r", (t, e) => {
148985
149432
  if (t) return this.emit("error", t);
148986
149433
  this[hs](e);
148987
149434
  });
@@ -148996,14 +149443,14 @@ var de = class extends A {
148996
149443
  [ii]() {
148997
149444
  let { fd: t, buf: e, offset: i, length: r, pos: n } = this;
148998
149445
  if (t === void 0 || e === void 0) throw new Error("cannot read file without first opening");
148999
- import_fs28.default.read(t, e, i, r, n, (o, h) => {
149446
+ import_fs29.default.read(t, e, i, r, n, (o, h) => {
149000
149447
  if (o) return this[pt](() => this.emit("error", o));
149001
149448
  this[rs](h);
149002
149449
  });
149003
149450
  }
149004
149451
  [pt](t = () => {
149005
149452
  }) {
149006
- this.fd !== void 0 && import_fs28.default.close(this.fd, t);
149453
+ this.fd !== void 0 && import_fs29.default.close(this.fd, t);
149007
149454
  }
149008
149455
  [rs](t) {
149009
149456
  if (t <= 0 && this.remain > 0) {
@@ -149038,20 +149485,20 @@ var de = class extends A {
149038
149485
  var ni = class extends de {
149039
149486
  sync = true;
149040
149487
  [ss]() {
149041
- this[si](import_fs28.default.lstatSync(this.absolute));
149488
+ this[si](import_fs29.default.lstatSync(this.absolute));
149042
149489
  }
149043
149490
  [is]() {
149044
- this[ns](import_fs28.default.readlinkSync(this.absolute));
149491
+ this[ns](import_fs29.default.readlinkSync(this.absolute));
149045
149492
  }
149046
149493
  [os]() {
149047
- this[hs](import_fs28.default.openSync(this.absolute, "r"));
149494
+ this[hs](import_fs29.default.openSync(this.absolute, "r"));
149048
149495
  }
149049
149496
  [ii]() {
149050
149497
  let t = true;
149051
149498
  try {
149052
149499
  let { fd: e, buf: i, offset: r, length: n, pos: o } = this;
149053
149500
  if (e === void 0 || i === void 0) throw new Error("fd and buf must be set in READ method");
149054
- let h = import_fs28.default.readSync(e, i, r, n, o);
149501
+ let h = import_fs29.default.readSync(e, i, r, n, o);
149055
149502
  this[rs](h), t = false;
149056
149503
  } finally {
149057
149504
  if (t) try {
@@ -149066,7 +149513,7 @@ var ni = class extends de {
149066
149513
  }
149067
149514
  [pt](t = () => {
149068
149515
  }) {
149069
- this.fd !== void 0 && import_fs28.default.closeSync(this.fd), t();
149516
+ this.fd !== void 0 && import_fs29.default.closeSync(this.fd), t();
149070
149517
  }
149071
149518
  };
149072
149519
  var oi = class extends A {
@@ -149382,7 +149829,7 @@ var wt = class extends A {
149382
149829
  return typeof t == "string" ? this[ci](t) : this[or](t), this.flowing;
149383
149830
  }
149384
149831
  [or](t) {
149385
- let e = f(import_path25.default.resolve(this.cwd, t.path));
149832
+ let e = f(import_path26.default.resolve(this.cwd, t.path));
149386
149833
  if (!this.filter(t.path, t)) t.resume();
149387
149834
  else {
149388
149835
  let i = new pi(t.path, e);
@@ -149391,13 +149838,13 @@ var wt = class extends A {
149391
149838
  this[Ft]();
149392
149839
  }
149393
149840
  [ci](t) {
149394
- let e = f(import_path25.default.resolve(this.cwd, t));
149841
+ let e = f(import_path26.default.resolve(this.cwd, t));
149395
149842
  this[W2].push(new pi(t, e)), this[Ft]();
149396
149843
  }
149397
149844
  [ds](t) {
149398
149845
  t.pending = true, this[G] += 1;
149399
149846
  let e = this.follow ? "stat" : "lstat";
149400
- import_fs27.default[e](t.absolute, (i, r) => {
149847
+ import_fs28.default[e](t.absolute, (i, r) => {
149401
149848
  t.pending = false, this[G] -= 1, i ? this.emit("error", i) : this[li](t, r);
149402
149849
  });
149403
149850
  }
@@ -149411,7 +149858,7 @@ var wt = class extends A {
149411
149858
  this[Ft]();
149412
149859
  }
149413
149860
  [ms](t) {
149414
- t.pending = true, this[G] += 1, import_fs27.default.readdir(t.absolute, (e, i) => {
149861
+ t.pending = true, this[G] += 1, import_fs28.default.readdir(t.absolute, (e, i) => {
149415
149862
  if (t.pending = false, this[G] -= 1, e) return this.emit("error", e);
149416
149863
  this[fi](t, i);
149417
149864
  });
@@ -149512,10 +149959,10 @@ var kt = class extends wt {
149512
149959
  }
149513
149960
  [ds](t) {
149514
149961
  let e = this.follow ? "statSync" : "lstatSync";
149515
- this[li](t, import_fs27.default[e](t.absolute));
149962
+ this[li](t, import_fs28.default[e](t.absolute));
149516
149963
  }
149517
149964
  [ms](t) {
149518
- this[fi](t, import_fs27.default.readdirSync(t.absolute));
149965
+ this[fi](t, import_fs28.default.readdirSync(t.absolute));
149519
149966
  }
149520
149967
  [di](t) {
149521
149968
  let e = t.entry, i = this.zip;
@@ -149544,11 +149991,11 @@ var $n = (s3, t) => {
149544
149991
  };
149545
149992
  var fr = (s3, t) => {
149546
149993
  t.forEach((e) => {
149547
- e.charAt(0) === "@" ? Ct({ file: import_node_path14.default.resolve(s3.cwd, e.slice(1)), sync: true, noResume: true, onReadEntry: (i) => s3.add(i) }) : s3.add(e);
149994
+ e.charAt(0) === "@" ? Ct({ file: import_node_path15.default.resolve(s3.cwd, e.slice(1)), sync: true, noResume: true, onReadEntry: (i) => s3.add(i) }) : s3.add(e);
149548
149995
  }), s3.end();
149549
149996
  };
149550
149997
  var dr = async (s3, t) => {
149551
- for (let e of t) e.charAt(0) === "@" ? await Ct({ file: import_node_path14.default.resolve(String(s3.cwd), e.slice(1)), noResume: true, onReadEntry: (i) => {
149998
+ for (let e of t) e.charAt(0) === "@" ? await Ct({ file: import_node_path15.default.resolve(String(s3.cwd), e.slice(1)), noResume: true, onReadEntry: (i) => {
149552
149999
  s3.add(i);
149553
150000
  } }) : s3.add(e);
149554
150001
  s3.end();
@@ -149566,8 +150013,8 @@ var Qn = K(Vn, $n, Xn, qn, (s3, t) => {
149566
150013
  });
149567
150014
  var Jn = process.env.__FAKE_PLATFORM__ || process.platform;
149568
150015
  var Er = Jn === "win32";
149569
- var { O_CREAT: wr, O_NOFOLLOW: mr, O_TRUNC: Sr, O_WRONLY: yr } = import_fs29.default.constants;
149570
- var Rr = Number(process.env.__FAKE_FS_O_FILENAME__) || import_fs29.default.constants.UV_FS_O_FILEMAP || 0;
150016
+ var { O_CREAT: wr, O_NOFOLLOW: mr, O_TRUNC: Sr, O_WRONLY: yr } = import_fs30.default.constants;
150017
+ var Rr = Number(process.env.__FAKE_FS_O_FILENAME__) || import_fs30.default.constants.UV_FS_O_FILEMAP || 0;
149571
150018
  var jn = Er && !!Rr;
149572
150019
  var to = 512 * 1024;
149573
150020
  var eo = Rr | Sr | wr | yr;
@@ -149575,29 +150022,29 @@ var ur = !Er && typeof mr == "number" ? mr | Sr | wr | yr : null;
149575
150022
  var us = ur !== null ? () => ur : jn ? (s3) => s3 < to ? eo : "w" : () => "w";
149576
150023
  var ps = (s3, t, e) => {
149577
150024
  try {
149578
- return import_node_fs14.default.lchownSync(s3, t, e);
150025
+ return import_node_fs15.default.lchownSync(s3, t, e);
149579
150026
  } catch (i) {
149580
150027
  if (i?.code !== "ENOENT") throw i;
149581
150028
  }
149582
150029
  };
149583
150030
  var Ei = (s3, t, e, i) => {
149584
- import_node_fs14.default.lchown(s3, t, e, (r) => {
150031
+ import_node_fs15.default.lchown(s3, t, e, (r) => {
149585
150032
  i(r && r?.code !== "ENOENT" ? r : null);
149586
150033
  });
149587
150034
  };
149588
150035
  var io = (s3, t, e, i, r) => {
149589
- if (t.isDirectory()) Es(import_node_path19.default.resolve(s3, t.name), e, i, (n) => {
150036
+ if (t.isDirectory()) Es(import_node_path20.default.resolve(s3, t.name), e, i, (n) => {
149590
150037
  if (n) return r(n);
149591
- let o = import_node_path19.default.resolve(s3, t.name);
150038
+ let o = import_node_path20.default.resolve(s3, t.name);
149592
150039
  Ei(o, e, i, r);
149593
150040
  });
149594
150041
  else {
149595
- let n = import_node_path19.default.resolve(s3, t.name);
150042
+ let n = import_node_path20.default.resolve(s3, t.name);
149596
150043
  Ei(n, e, i, r);
149597
150044
  }
149598
150045
  };
149599
150046
  var Es = (s3, t, e, i) => {
149600
- import_node_fs14.default.readdir(s3, { withFileTypes: true }, (r, n) => {
150047
+ import_node_fs15.default.readdir(s3, { withFileTypes: true }, (r, n) => {
149601
150048
  if (r) {
149602
150049
  if (r.code === "ENOENT") return i();
149603
150050
  if (r.code !== "ENOTDIR" && r.code !== "ENOTSUP") return i(r);
@@ -149613,12 +150060,12 @@ var Es = (s3, t, e, i) => {
149613
150060
  });
149614
150061
  };
149615
150062
  var so = (s3, t, e, i) => {
149616
- t.isDirectory() && ws(import_node_path19.default.resolve(s3, t.name), e, i), ps(import_node_path19.default.resolve(s3, t.name), e, i);
150063
+ t.isDirectory() && ws(import_node_path20.default.resolve(s3, t.name), e, i), ps(import_node_path20.default.resolve(s3, t.name), e, i);
149617
150064
  };
149618
150065
  var ws = (s3, t, e) => {
149619
150066
  let i;
149620
150067
  try {
149621
- i = import_node_fs14.default.readdirSync(s3, { withFileTypes: true });
150068
+ i = import_node_fs15.default.readdirSync(s3, { withFileTypes: true });
149622
150069
  } catch (r) {
149623
150070
  let n = r;
149624
150071
  if (n?.code === "ENOENT") return;
@@ -149652,32 +150099,32 @@ var St = class extends Error {
149652
150099
  }
149653
150100
  };
149654
150101
  var no = (s3, t) => {
149655
- import_node_fs15.default.stat(s3, (e, i) => {
150102
+ import_node_fs16.default.stat(s3, (e, i) => {
149656
150103
  (e || !i.isDirectory()) && (e = new Se(s3, e?.code || "ENOTDIR")), t(e);
149657
150104
  });
149658
150105
  };
149659
150106
  var gr = (s3, t, e) => {
149660
150107
  s3 = f(s3);
149661
150108
  let i = t.umask ?? 18, r = t.mode | 448, n = (r & i) !== 0, o = t.uid, h = t.gid, a = typeof o == "number" && typeof h == "number" && (o !== t.processUid || h !== t.processGid), l = t.preserve, c = t.unlink, d = f(t.cwd), S2 = (E, x) => {
149662
- E ? e(E) : x && a ? Es(x, o, h, (Le) => S2(Le)) : n ? import_node_fs15.default.chmod(s3, r, e) : e();
150109
+ E ? e(E) : x && a ? Es(x, o, h, (Le) => S2(Le)) : n ? import_node_fs16.default.chmod(s3, r, e) : e();
149663
150110
  };
149664
150111
  if (s3 === d) return no(s3, S2);
149665
150112
  if (l) return import_promises21.default.mkdir(s3, { mode: r, recursive: true }).then((E) => S2(null, E ?? void 0), S2);
149666
- let D = f(import_node_path20.default.relative(d, s3)).split("/");
150113
+ let D = f(import_node_path21.default.relative(d, s3)).split("/");
149667
150114
  Ss(d, D, r, c, d, void 0, S2);
149668
150115
  };
149669
150116
  var Ss = (s3, t, e, i, r, n, o) => {
149670
150117
  if (t.length === 0) return o(null, n);
149671
- let h = t.shift(), a = f(import_node_path20.default.resolve(s3 + "/" + h));
149672
- import_node_fs15.default.mkdir(a, e, br(a, t, e, i, r, n, o));
150118
+ let h = t.shift(), a = f(import_node_path21.default.resolve(s3 + "/" + h));
150119
+ import_node_fs16.default.mkdir(a, e, br(a, t, e, i, r, n, o));
149673
150120
  };
149674
150121
  var br = (s3, t, e, i, r, n, o) => (h) => {
149675
- h ? import_node_fs15.default.lstat(s3, (a, l) => {
150122
+ h ? import_node_fs16.default.lstat(s3, (a, l) => {
149676
150123
  if (a) a.path = a.path && f(a.path), o(a);
149677
150124
  else if (l.isDirectory()) Ss(s3, t, e, i, r, n, o);
149678
- else if (i) import_node_fs15.default.unlink(s3, (c) => {
150125
+ else if (i) import_node_fs16.default.unlink(s3, (c) => {
149679
150126
  if (c) return o(c);
149680
- import_node_fs15.default.mkdir(s3, e, br(s3, t, e, i, r, n, o));
150127
+ import_node_fs16.default.mkdir(s3, e, br(s3, t, e, i, r, n, o));
149681
150128
  });
149682
150129
  else {
149683
150130
  if (l.isSymbolicLink()) return o(new St(s3, s3 + "/" + t.join("/")));
@@ -149688,7 +150135,7 @@ var br = (s3, t, e, i, r, n, o) => (h) => {
149688
150135
  var oo = (s3) => {
149689
150136
  let t = false, e;
149690
150137
  try {
149691
- t = import_node_fs15.default.statSync(s3).isDirectory();
150138
+ t = import_node_fs16.default.statSync(s3).isDirectory();
149692
150139
  } catch (i) {
149693
150140
  e = i?.code;
149694
150141
  } finally {
@@ -149698,20 +150145,20 @@ var oo = (s3) => {
149698
150145
  var _r = (s3, t) => {
149699
150146
  s3 = f(s3);
149700
150147
  let e = t.umask ?? 18, i = t.mode | 448, r = (i & e) !== 0, n = t.uid, o = t.gid, h = typeof n == "number" && typeof o == "number" && (n !== t.processUid || o !== t.processGid), a = t.preserve, l = t.unlink, c = f(t.cwd), d = (E) => {
149701
- E && h && ws(E, n, o), r && import_node_fs15.default.chmodSync(s3, i);
150148
+ E && h && ws(E, n, o), r && import_node_fs16.default.chmodSync(s3, i);
149702
150149
  };
149703
150150
  if (s3 === c) return oo(c), d();
149704
- if (a) return d(import_node_fs15.default.mkdirSync(s3, { mode: i, recursive: true }) ?? void 0);
149705
- let T2 = f(import_node_path20.default.relative(c, s3)).split("/"), D;
150151
+ if (a) return d(import_node_fs16.default.mkdirSync(s3, { mode: i, recursive: true }) ?? void 0);
150152
+ let T2 = f(import_node_path21.default.relative(c, s3)).split("/"), D;
149706
150153
  for (let E = T2.shift(), x = c; E && (x += "/" + E); E = T2.shift()) {
149707
- x = f(import_node_path20.default.resolve(x));
150154
+ x = f(import_node_path21.default.resolve(x));
149708
150155
  try {
149709
- import_node_fs15.default.mkdirSync(x, i), D = D || x;
150156
+ import_node_fs16.default.mkdirSync(x, i), D = D || x;
149710
150157
  } catch {
149711
- let Le = import_node_fs15.default.lstatSync(x);
150158
+ let Le = import_node_fs16.default.lstatSync(x);
149712
150159
  if (Le.isDirectory()) continue;
149713
150160
  if (l) {
149714
- import_node_fs15.default.unlinkSync(x), import_node_fs15.default.mkdirSync(x, i), D = D || x;
150161
+ import_node_fs16.default.unlinkSync(x), import_node_fs16.default.mkdirSync(x, i), D = D || x;
149715
150162
  continue;
149716
150163
  } else if (Le.isSymbolicLink()) return new St(x, x + "/" + T2.join("/"));
149717
150164
  }
@@ -149733,14 +150180,14 @@ var ho = process.env.TESTING_TAR_FAKE_PLATFORM || process.platform;
149733
150180
  var ao = ho === "win32";
149734
150181
  var lo = (s3) => s3.split("/").slice(0, -1).reduce((e, i) => {
149735
150182
  let r = e.at(-1);
149736
- return r !== void 0 && (i = (0, import_node_path21.join)(r, i)), e.push(i || "/"), e;
150183
+ return r !== void 0 && (i = (0, import_node_path22.join)(r, i)), e.push(i || "/"), e;
149737
150184
  }, []);
149738
150185
  var yi = class {
149739
150186
  #t = /* @__PURE__ */ new Map();
149740
150187
  #i = /* @__PURE__ */ new Map();
149741
150188
  #s = /* @__PURE__ */ new Set();
149742
150189
  reserve(t, e) {
149743
- t = ao ? ["win32 parallelization disabled"] : t.map((r) => ut((0, import_node_path21.join)(Tr(r))));
150190
+ t = ao ? ["win32 parallelization disabled"] : t.map((r) => ut((0, import_node_path22.join)(Tr(r))));
149744
150191
  let i = new Set(t.map((r) => lo(r)).reduce((r, n) => r.concat(n)));
149745
150192
  this.#i.set(e, { dirs: i, paths: t });
149746
150193
  for (let r of t) {
@@ -149830,17 +150277,17 @@ var fo = process.env.TESTING_TAR_FAKE_PLATFORM || process.platform;
149830
150277
  var Te = fo === "win32";
149831
150278
  var mo = 1024;
149832
150279
  var uo = (s3, t) => {
149833
- if (!Te) return import_node_fs13.default.unlink(s3, t);
150280
+ if (!Te) return import_node_fs14.default.unlink(s3, t);
149834
150281
  let e = s3 + ".DELETE." + (0, import_node_crypto5.randomBytes)(16).toString("hex");
149835
- import_node_fs13.default.rename(s3, e, (i) => {
150282
+ import_node_fs14.default.rename(s3, e, (i) => {
149836
150283
  if (i) return t(i);
149837
- import_node_fs13.default.unlink(e, t);
150284
+ import_node_fs14.default.unlink(e, t);
149838
150285
  });
149839
150286
  };
149840
150287
  var po = (s3) => {
149841
- if (!Te) return import_node_fs13.default.unlinkSync(s3);
150288
+ if (!Te) return import_node_fs14.default.unlinkSync(s3);
149842
150289
  let t = s3 + ".DELETE." + (0, import_node_crypto5.randomBytes)(16).toString("hex");
149843
- import_node_fs13.default.renameSync(s3, t), import_node_fs13.default.unlinkSync(t);
150290
+ import_node_fs14.default.renameSync(s3, t), import_node_fs14.default.unlinkSync(t);
149844
150291
  };
149845
150292
  var vr = (s3, t, e) => s3 !== void 0 && s3 === s3 >>> 0 ? s3 : t !== void 0 && t === t >>> 0 ? t : e;
149846
150293
  var Xt = class extends rt {
@@ -149880,7 +150327,7 @@ var Xt = class extends rt {
149880
150327
  if (t.preserveOwner) throw new TypeError("cannot preserve owner in archive and also set owner explicitly");
149881
150328
  this.uid = t.uid, this.gid = t.gid, this.setOwner = true;
149882
150329
  } else this.uid = void 0, this.gid = void 0, this.setOwner = false;
149883
- this.preserveOwner = t.preserveOwner === void 0 && typeof t.uid != "number" ? process.getuid?.() === 0 : !!t.preserveOwner, this.processUid = (this.preserveOwner || this.setOwner) && process.getuid ? process.getuid() : void 0, this.processGid = (this.preserveOwner || this.setOwner) && process.getgid ? process.getgid() : void 0, this.maxDepth = typeof t.maxDepth == "number" ? t.maxDepth : mo, this.forceChown = t.forceChown === true, this.win32 = !!t.win32 || Te, this.newer = !!t.newer, this.keep = !!t.keep, this.noMtime = !!t.noMtime, this.preservePaths = !!t.preservePaths, this.unlink = !!t.unlink, this.cwd = f(import_node_path18.default.resolve(t.cwd || process.cwd())), this.strip = Number(t.strip) || 0, this.processUmask = this.chmod ? typeof t.processUmask == "number" ? t.processUmask : Lr() : 0, this.umask = typeof t.umask == "number" ? t.umask : this.processUmask, this.dmode = t.dmode || 511 & ~this.umask, this.fmode = t.fmode || 438 & ~this.umask, this.on("entry", (e) => this[Dr](e));
150330
+ this.preserveOwner = t.preserveOwner === void 0 && typeof t.uid != "number" ? process.getuid?.() === 0 : !!t.preserveOwner, this.processUid = (this.preserveOwner || this.setOwner) && process.getuid ? process.getuid() : void 0, this.processGid = (this.preserveOwner || this.setOwner) && process.getgid ? process.getgid() : void 0, this.maxDepth = typeof t.maxDepth == "number" ? t.maxDepth : mo, this.forceChown = t.forceChown === true, this.win32 = !!t.win32 || Te, this.newer = !!t.newer, this.keep = !!t.keep, this.noMtime = !!t.noMtime, this.preservePaths = !!t.preservePaths, this.unlink = !!t.unlink, this.cwd = f(import_node_path19.default.resolve(t.cwd || process.cwd())), this.strip = Number(t.strip) || 0, this.processUmask = this.chmod ? typeof t.processUmask == "number" ? t.processUmask : Lr() : 0, this.umask = typeof t.umask == "number" ? t.umask : this.processUmask, this.dmode = t.dmode || 511 & ~this.umask, this.fmode = t.fmode || 438 & ~this.umask, this.on("entry", (e) => this[Dr](e));
149884
150331
  }
149885
150332
  warn(t, e, i = {}) {
149886
150333
  return (t === "TAR_BAD_ARCHIVE" || t === "TAR_ABORT") && (i.recoverable = false), super.warn(t, e, i);
@@ -149894,7 +150341,7 @@ var Xt = class extends rt {
149894
150341
  let [n, o] = ce(i), h = o.replaceAll(/\\/g, "/").split("/");
149895
150342
  if (h.includes("..") || Te && /^[a-z]:\.\.$/i.test(h[0] ?? "")) {
149896
150343
  if (e === "path" || r === "Link") return this.warn("TAR_ENTRY_ERROR", `${e} contains '..'`, { entry: t, [e]: i }), false;
149897
- let a = import_node_path18.default.posix.dirname(t.path), l = import_node_path18.default.posix.normalize(import_node_path18.default.posix.join(a, h.join("/")));
150344
+ let a = import_node_path19.default.posix.dirname(t.path), l = import_node_path19.default.posix.normalize(import_node_path19.default.posix.join(a, h.join("/")));
149898
150345
  if (l.startsWith("../") || l === "..") return this.warn("TAR_ENTRY_ERROR", `${e} escapes extraction directory`, { entry: t, [e]: i }), false;
149899
150346
  }
149900
150347
  return n && (t[e] = String(o), this.warn("TAR_ENTRY_INFO", `stripping ${n} from absolute ${e}`, { entry: t, [e]: i })), true;
@@ -149912,12 +150359,12 @@ var Xt = class extends rt {
149912
150359
  }
149913
150360
  if (isFinite(this.maxDepth) && i.length > this.maxDepth) return this.warn("TAR_ENTRY_ERROR", "path excessively deep", { entry: t, path: e, depth: i.length, maxDepth: this.maxDepth }), false;
149914
150361
  if (!this[Rs](t, "path") || !this[Rs](t, "linkpath")) return false;
149915
- if (t.absolute = import_node_path18.default.isAbsolute(t.path) ? f(import_node_path18.default.resolve(t.path)) : f(import_node_path18.default.resolve(this.cwd, t.path)), !this.preservePaths && typeof t.absolute == "string" && t.absolute.indexOf(this.cwd + "/") !== 0 && t.absolute !== this.cwd) return this.warn("TAR_ENTRY_ERROR", "path escaped extraction target", { entry: t, path: f(t.path), resolvedPath: t.absolute, cwd: this.cwd }), false;
150362
+ if (t.absolute = import_node_path19.default.isAbsolute(t.path) ? f(import_node_path19.default.resolve(t.path)) : f(import_node_path19.default.resolve(this.cwd, t.path)), !this.preservePaths && typeof t.absolute == "string" && t.absolute.indexOf(this.cwd + "/") !== 0 && t.absolute !== this.cwd) return this.warn("TAR_ENTRY_ERROR", "path escaped extraction target", { entry: t, path: f(t.path), resolvedPath: t.absolute, cwd: this.cwd }), false;
149916
150363
  if (t.absolute === this.cwd && t.type !== "Directory" && t.type !== "GNUDumpDir") return false;
149917
150364
  if (this.win32) {
149918
- let { root: r } = import_node_path18.default.win32.parse(String(t.absolute));
150365
+ let { root: r } = import_node_path19.default.win32.parse(String(t.absolute));
149919
150366
  t.absolute = r + ts(String(t.absolute).slice(r.length));
149920
- let { root: n } = import_node_path18.default.win32.parse(t.path);
150367
+ let { root: n } = import_node_path19.default.win32.parse(t.path);
149921
150368
  t.path = n + ts(t.path.slice(n.length));
149922
150369
  }
149923
150370
  return true;
@@ -149956,16 +150403,16 @@ var Xt = class extends rt {
149956
150403
  [Ts](t, e) {
149957
150404
  let i = typeof t.mode == "number" ? t.mode & 4095 : this.fmode, r = new et(String(t.absolute), { flags: us(t.size), mode: i, autoClose: false });
149958
150405
  r.on("error", (a) => {
149959
- r.fd && import_node_fs13.default.close(r.fd, () => {
150406
+ r.fd && import_node_fs14.default.close(r.fd, () => {
149960
150407
  }), r.write = () => true, this[O](a, t), e();
149961
150408
  });
149962
150409
  let n = 1, o = (a) => {
149963
150410
  if (a) {
149964
- r.fd && import_node_fs13.default.close(r.fd, () => {
150411
+ r.fd && import_node_fs14.default.close(r.fd, () => {
149965
150412
  }), this[O](a, t), e();
149966
150413
  return;
149967
150414
  }
149968
- --n === 0 && r.fd !== void 0 && import_node_fs13.default.close(r.fd, (l) => {
150415
+ --n === 0 && r.fd !== void 0 && import_node_fs14.default.close(r.fd, (l) => {
149969
150416
  l ? this[O](l, t) : this[$t](), e();
149970
150417
  });
149971
150418
  };
@@ -149974,12 +150421,12 @@ var Xt = class extends rt {
149974
150421
  if (typeof l == "number" && t.mtime && !this.noMtime) {
149975
150422
  n++;
149976
150423
  let c = t.atime || /* @__PURE__ */ new Date(), d = t.mtime;
149977
- import_node_fs13.default.futimes(l, c, d, (S2) => S2 ? import_node_fs13.default.utimes(a, c, d, (T2) => o(T2 && S2)) : o());
150424
+ import_node_fs14.default.futimes(l, c, d, (S2) => S2 ? import_node_fs14.default.utimes(a, c, d, (T2) => o(T2 && S2)) : o());
149978
150425
  }
149979
150426
  if (typeof l == "number" && this[ge](t)) {
149980
150427
  n++;
149981
150428
  let c = this[be](t), d = this[_e](t);
149982
- typeof c == "number" && typeof d == "number" && import_node_fs13.default.fchown(l, c, d, (S2) => S2 ? import_node_fs13.default.chown(a, c, d, (T2) => o(T2 && S2)) : o());
150429
+ typeof c == "number" && typeof d == "number" && import_node_fs14.default.fchown(l, c, d, (S2) => S2 ? import_node_fs14.default.chown(a, c, d, (T2) => o(T2 && S2)) : o());
149983
150430
  }
149984
150431
  o();
149985
150432
  });
@@ -149998,20 +150445,20 @@ var Xt = class extends rt {
149998
150445
  let n = 1, o = () => {
149999
150446
  --n === 0 && (e(), this[$t](), t.resume());
150000
150447
  };
150001
- t.mtime && !this.noMtime && (n++, import_node_fs13.default.utimes(String(t.absolute), t.atime || /* @__PURE__ */ new Date(), t.mtime, o)), this[ge](t) && (n++, import_node_fs13.default.chown(String(t.absolute), Number(this[be](t)), Number(this[_e](t)), o)), o();
150448
+ t.mtime && !this.noMtime && (n++, import_node_fs14.default.utimes(String(t.absolute), t.atime || /* @__PURE__ */ new Date(), t.mtime, o)), this[ge](t) && (n++, import_node_fs14.default.chown(String(t.absolute), Number(this[be](t)), Number(this[_e](t)), o)), o();
150002
150449
  });
150003
150450
  }
150004
150451
  [Cr](t) {
150005
150452
  t.unsupported = true, this.warn("TAR_ENTRY_UNSUPPORTED", `unsupported entry type: ${t.type}`, { entry: t }), t.resume();
150006
150453
  }
150007
150454
  [Ar](t, e) {
150008
- let i = f(import_node_path18.default.relative(this.cwd, import_node_path18.default.resolve(import_node_path18.default.dirname(String(t.absolute)), String(t.linkpath)))).split("/");
150455
+ let i = f(import_node_path19.default.relative(this.cwd, import_node_path19.default.resolve(import_node_path19.default.dirname(String(t.absolute)), String(t.linkpath)))).split("/");
150009
150456
  this[Re](t, this.cwd, i, () => this[gi](t, String(t.linkpath), "symlink", e), (r) => {
150010
150457
  this[O](r, t), e();
150011
150458
  });
150012
150459
  }
150013
150460
  [Ir](t, e) {
150014
- let i = f(import_node_path18.default.resolve(this.cwd, String(t.linkpath))), r = f(String(t.linkpath)).split("/");
150461
+ let i = f(import_node_path19.default.resolve(this.cwd, String(t.linkpath))), r = f(String(t.linkpath)).split("/");
150015
150462
  this[Re](t, this.cwd, r, () => this[gi](t, i, "link", e), (n) => {
150016
150463
  this[O](n, t), e();
150017
150464
  });
@@ -150019,10 +150466,10 @@ var Xt = class extends rt {
150019
150466
  [Re](t, e, i, r, n) {
150020
150467
  let o = i.shift();
150021
150468
  if (this.preservePaths || o === void 0) return r();
150022
- let h = import_node_path18.default.resolve(e, o);
150023
- import_node_fs13.default.lstat(h, (a, l) => {
150469
+ let h = import_node_path19.default.resolve(e, o);
150470
+ import_node_fs14.default.lstat(h, (a, l) => {
150024
150471
  if (a) return r();
150025
- if (l?.isSymbolicLink()) return n(new St(h, import_node_path18.default.resolve(h, i.join("/"))));
150472
+ if (l?.isSymbolicLink()) return n(new St(h, import_node_path19.default.resolve(h, i.join("/"))));
150026
150473
  this[Re](t, h, i, r, n);
150027
150474
  });
150028
150475
  }
@@ -150056,7 +150503,7 @@ var Xt = class extends rt {
150056
150503
  });
150057
150504
  }, n = () => {
150058
150505
  if (t.absolute !== this.cwd) {
150059
- let h = f(import_node_path18.default.dirname(String(t.absolute)));
150506
+ let h = f(import_node_path19.default.dirname(String(t.absolute)));
150060
150507
  if (h !== this.cwd) return this[yt](h, this.dmode, (a) => {
150061
150508
  if (a) {
150062
150509
  this[O](a, t), i();
@@ -150067,7 +150514,7 @@ var Xt = class extends rt {
150067
150514
  }
150068
150515
  o();
150069
150516
  }, o = () => {
150070
- import_node_fs13.default.lstat(String(t.absolute), (h, a) => {
150517
+ import_node_fs14.default.lstat(String(t.absolute), (h, a) => {
150071
150518
  if (a && (this.keep || this.newer && a.mtime > (t.mtime ?? a.mtime))) {
150072
150519
  this[Ls](t), i();
150073
150520
  return;
@@ -150076,9 +150523,9 @@ var Xt = class extends rt {
150076
150523
  if (a.isDirectory()) {
150077
150524
  if (t.type === "Directory") {
150078
150525
  let l = this.chmod && t.mode && (a.mode & 4095) !== t.mode, c = (d) => this[P](d ?? null, t, i);
150079
- return l ? import_node_fs13.default.chmod(String(t.absolute), Number(t.mode), c) : c();
150526
+ return l ? import_node_fs14.default.chmod(String(t.absolute), Number(t.mode), c) : c();
150080
150527
  }
150081
- if (t.absolute !== this.cwd) return import_node_fs13.default.rmdir(String(t.absolute), (l) => this[P](l ?? null, t, i));
150528
+ if (t.absolute !== this.cwd) return import_node_fs14.default.rmdir(String(t.absolute), (l) => this[P](l ?? null, t, i));
150082
150529
  }
150083
150530
  if (t.absolute === this.cwd) return this[P](null, t, i);
150084
150531
  uo(String(t.absolute), (l) => this[P](l ?? null, t, i));
@@ -150106,7 +150553,7 @@ var Xt = class extends rt {
150106
150553
  }
150107
150554
  }
150108
150555
  [gi](t, e, i, r) {
150109
- import_node_fs13.default[i](e, String(t.absolute), (n) => {
150556
+ import_node_fs14.default[i](e, String(t.absolute), (n) => {
150110
150557
  n ? this[O](n, t) : (this[$t](), t.resume()), r();
150111
150558
  });
150112
150559
  }
@@ -150131,23 +150578,23 @@ var xe = class extends Xt {
150131
150578
  this[Oe] = true;
150132
150579
  }
150133
150580
  if (t.absolute !== this.cwd) {
150134
- let n = f(import_node_path18.default.dirname(String(t.absolute)));
150581
+ let n = f(import_node_path19.default.dirname(String(t.absolute)));
150135
150582
  if (n !== this.cwd) {
150136
150583
  let o = this[yt](n, this.dmode);
150137
150584
  if (o) return this[O](o, t);
150138
150585
  }
150139
150586
  }
150140
- let [e, i] = ye(() => import_node_fs13.default.lstatSync(String(t.absolute)));
150587
+ let [e, i] = ye(() => import_node_fs14.default.lstatSync(String(t.absolute)));
150141
150588
  if (i && (this.keep || this.newer && i.mtime > (t.mtime ?? i.mtime))) return this[Ls](t);
150142
150589
  if (e || this[Os](t, i)) return this[P](null, t);
150143
150590
  if (i.isDirectory()) {
150144
150591
  if (t.type === "Directory") {
150145
150592
  let o = this.chmod && t.mode && (i.mode & 4095) !== t.mode, [h] = o ? ye(() => {
150146
- import_node_fs13.default.chmodSync(String(t.absolute), Number(t.mode));
150593
+ import_node_fs14.default.chmodSync(String(t.absolute), Number(t.mode));
150147
150594
  }) : [];
150148
150595
  return this[P](h, t);
150149
150596
  }
150150
- let [n] = ye(() => import_node_fs13.default.rmdirSync(String(t.absolute)));
150597
+ let [n] = ye(() => import_node_fs14.default.rmdirSync(String(t.absolute)));
150151
150598
  this[P](n, t);
150152
150599
  }
150153
150600
  let [r] = t.absolute === this.cwd ? [] : ye(() => po(String(t.absolute)));
@@ -150157,21 +150604,21 @@ var xe = class extends Xt {
150157
150604
  let i = typeof t.mode == "number" ? t.mode & 4095 : this.fmode, r = (h) => {
150158
150605
  let a;
150159
150606
  try {
150160
- import_node_fs13.default.closeSync(n);
150607
+ import_node_fs14.default.closeSync(n);
150161
150608
  } catch (l) {
150162
150609
  a = l;
150163
150610
  }
150164
150611
  (h || a) && this[O](h || a, t), e();
150165
150612
  }, n;
150166
150613
  try {
150167
- n = import_node_fs13.default.openSync(String(t.absolute), us(t.size), i);
150614
+ n = import_node_fs14.default.openSync(String(t.absolute), us(t.size), i);
150168
150615
  } catch (h) {
150169
150616
  return r(h);
150170
150617
  }
150171
150618
  let o = this.transform && this.transform(t) || t;
150172
150619
  o !== t && (o.on("error", (h) => this[O](h, t)), t.pipe(o)), o.on("data", (h) => {
150173
150620
  try {
150174
- import_node_fs13.default.writeSync(n, h, 0, h.length);
150621
+ import_node_fs14.default.writeSync(n, h, 0, h.length);
150175
150622
  } catch (a) {
150176
150623
  r(a);
150177
150624
  }
@@ -150180,10 +150627,10 @@ var xe = class extends Xt {
150180
150627
  if (t.mtime && !this.noMtime) {
150181
150628
  let a = t.atime || /* @__PURE__ */ new Date(), l = t.mtime;
150182
150629
  try {
150183
- import_node_fs13.default.futimesSync(n, a, l);
150630
+ import_node_fs14.default.futimesSync(n, a, l);
150184
150631
  } catch (c) {
150185
150632
  try {
150186
- import_node_fs13.default.utimesSync(String(t.absolute), a, l);
150633
+ import_node_fs14.default.utimesSync(String(t.absolute), a, l);
150187
150634
  } catch {
150188
150635
  h = c;
150189
150636
  }
@@ -150192,10 +150639,10 @@ var xe = class extends Xt {
150192
150639
  if (this[ge](t)) {
150193
150640
  let a = this[be](t), l = this[_e](t);
150194
150641
  try {
150195
- import_node_fs13.default.fchownSync(n, Number(a), Number(l));
150642
+ import_node_fs14.default.fchownSync(n, Number(a), Number(l));
150196
150643
  } catch (c) {
150197
150644
  try {
150198
- import_node_fs13.default.chownSync(String(t.absolute), Number(a), Number(l));
150645
+ import_node_fs14.default.chownSync(String(t.absolute), Number(a), Number(l));
150199
150646
  } catch {
150200
150647
  h = h || c;
150201
150648
  }
@@ -150211,11 +150658,11 @@ var xe = class extends Xt {
150211
150658
  return;
150212
150659
  }
150213
150660
  if (t.mtime && !this.noMtime) try {
150214
- import_node_fs13.default.utimesSync(String(t.absolute), t.atime || /* @__PURE__ */ new Date(), t.mtime);
150661
+ import_node_fs14.default.utimesSync(String(t.absolute), t.atime || /* @__PURE__ */ new Date(), t.mtime);
150215
150662
  } catch {
150216
150663
  }
150217
150664
  if (this[ge](t)) try {
150218
- import_node_fs13.default.chownSync(String(t.absolute), Number(this[be](t)), Number(this[_e](t)));
150665
+ import_node_fs14.default.chownSync(String(t.absolute), Number(this[be](t)), Number(this[_e](t)));
150219
150666
  } catch {
150220
150667
  }
150221
150668
  e(), t.resume();
@@ -150231,30 +150678,30 @@ var xe = class extends Xt {
150231
150678
  if (this.preservePaths || i.length === 0) return r();
150232
150679
  let o = e;
150233
150680
  for (let h of i) {
150234
- o = import_node_path18.default.resolve(o, h);
150235
- let [a, l] = ye(() => import_node_fs13.default.lstatSync(o));
150681
+ o = import_node_path19.default.resolve(o, h);
150682
+ let [a, l] = ye(() => import_node_fs14.default.lstatSync(o));
150236
150683
  if (a) return r();
150237
- if (l.isSymbolicLink()) return n(new St(o, import_node_path18.default.resolve(e, i.join("/"))));
150684
+ if (l.isSymbolicLink()) return n(new St(o, import_node_path19.default.resolve(e, i.join("/"))));
150238
150685
  }
150239
150686
  r();
150240
150687
  }
150241
150688
  [gi](t, e, i, r) {
150242
150689
  let n = `${i}Sync`;
150243
150690
  try {
150244
- import_node_fs13.default[n](e, String(t.absolute)), r(), t.resume();
150691
+ import_node_fs14.default[n](e, String(t.absolute)), r(), t.resume();
150245
150692
  } catch (o) {
150246
150693
  return this[O](o, t);
150247
150694
  }
150248
150695
  }
150249
150696
  };
150250
150697
  var Eo = (s3) => {
150251
- let t = new xe(s3), e = s3.file, i = import_node_fs12.default.statSync(e), r = s3.maxReadSize || 16 * 1024 * 1024;
150698
+ let t = new xe(s3), e = s3.file, i = import_node_fs13.default.statSync(e), r = s3.maxReadSize || 16 * 1024 * 1024;
150252
150699
  new Be(e, { readSize: r, size: i.size }).pipe(t);
150253
150700
  };
150254
150701
  var wo = (s3, t) => {
150255
150702
  let e = new Xt(s3), i = s3.maxReadSize || 16 * 1024 * 1024, r = s3.file;
150256
150703
  return new Promise((o, h) => {
150257
- e.on("error", h), e.on("close", o), import_node_fs12.default.stat(r, (a, l) => {
150704
+ e.on("error", h), e.on("close", o), import_node_fs13.default.stat(r, (a, l) => {
150258
150705
  if (a) h(a);
150259
150706
  else {
150260
150707
  let c = new _t(r, { readSize: i, size: l.size });
@@ -150270,15 +150717,15 @@ var yo = (s3, t) => {
150270
150717
  let e = new kt(s3), i = true, r, n;
150271
150718
  try {
150272
150719
  try {
150273
- r = import_node_fs16.default.openSync(s3.file, "r+");
150720
+ r = import_node_fs17.default.openSync(s3.file, "r+");
150274
150721
  } catch (a) {
150275
- if (a?.code === "ENOENT") r = import_node_fs16.default.openSync(s3.file, "w+");
150722
+ if (a?.code === "ENOENT") r = import_node_fs17.default.openSync(s3.file, "w+");
150276
150723
  else throw a;
150277
150724
  }
150278
- let o = import_node_fs16.default.fstatSync(r), h = Buffer.alloc(512);
150725
+ let o = import_node_fs17.default.fstatSync(r), h = Buffer.alloc(512);
150279
150726
  t: for (n = 0; n < o.size; n += 512) {
150280
150727
  for (let c = 0, d = 0; c < 512; c += d) {
150281
- if (d = import_node_fs16.default.readSync(r, h, c, h.length - c, n + c), n === 0 && h[0] === 31 && h[1] === 139) throw new Error("cannot append to compressed archives");
150728
+ if (d = import_node_fs17.default.readSync(r, h, c, h.length - c, n + c), n === 0 && h[0] === 31 && h[1] === 139) throw new Error("cannot append to compressed archives");
150282
150729
  if (!d) break t;
150283
150730
  }
150284
150731
  let a = new F(h);
@@ -150290,7 +150737,7 @@ var yo = (s3, t) => {
150290
150737
  i = false, Ro(s3, e, n, r, t);
150291
150738
  } finally {
150292
150739
  if (i) try {
150293
- import_node_fs16.default.closeSync(r);
150740
+ import_node_fs17.default.closeSync(r);
150294
150741
  } catch {
150295
150742
  }
150296
150743
  }
@@ -150303,29 +150750,29 @@ var go = (s3, t) => {
150303
150750
  t = Array.from(t);
150304
150751
  let e = new wt(s3), i = (n, o, h) => {
150305
150752
  let a = (T2, D) => {
150306
- T2 ? import_node_fs16.default.close(n, (E) => h(T2)) : h(null, D);
150753
+ T2 ? import_node_fs17.default.close(n, (E) => h(T2)) : h(null, D);
150307
150754
  }, l = 0;
150308
150755
  if (o === 0) return a(null, 0);
150309
150756
  let c = 0, d = Buffer.alloc(512), S2 = (T2, D) => {
150310
150757
  if (T2 || D === void 0) return a(T2);
150311
- if (c += D, c < 512 && D) return import_node_fs16.default.read(n, d, c, d.length - c, l + c, S2);
150758
+ if (c += D, c < 512 && D) return import_node_fs17.default.read(n, d, c, d.length - c, l + c, S2);
150312
150759
  if (l === 0 && d[0] === 31 && d[1] === 139) return a(new Error("cannot append to compressed archives"));
150313
150760
  if (c < 512) return a(null, l);
150314
150761
  let E = new F(d);
150315
150762
  if (!E.cksumValid) return a(null, l);
150316
150763
  let x = 512 * Math.ceil((E.size ?? 0) / 512);
150317
150764
  if (l + x + 512 > o || (l += x + 512, l >= o)) return a(null, l);
150318
- s3.mtimeCache && E.mtime && s3.mtimeCache.set(String(E.path), E.mtime), c = 0, import_node_fs16.default.read(n, d, 0, 512, l, S2);
150765
+ s3.mtimeCache && E.mtime && s3.mtimeCache.set(String(E.path), E.mtime), c = 0, import_node_fs17.default.read(n, d, 0, 512, l, S2);
150319
150766
  };
150320
- import_node_fs16.default.read(n, d, 0, 512, l, S2);
150767
+ import_node_fs17.default.read(n, d, 0, 512, l, S2);
150321
150768
  };
150322
150769
  return new Promise((n, o) => {
150323
150770
  e.on("error", o);
150324
150771
  let h = "r+", a = (l, c) => {
150325
- if (l && l.code === "ENOENT" && h === "r+") return h = "w+", import_node_fs16.default.open(s3.file, h, a);
150772
+ if (l && l.code === "ENOENT" && h === "r+") return h = "w+", import_node_fs17.default.open(s3.file, h, a);
150326
150773
  if (l || !c) return o(l);
150327
- import_node_fs16.default.fstat(c, (d, S2) => {
150328
- if (d) return import_node_fs16.default.close(c, () => o(d));
150774
+ import_node_fs17.default.fstat(c, (d, S2) => {
150775
+ if (d) return import_node_fs17.default.close(c, () => o(d));
150329
150776
  i(c, S2.size, (T2, D) => {
150330
150777
  if (T2) return o(T2);
150331
150778
  let E = new et(s3.file, { fd: c, start: D });
@@ -150333,16 +150780,16 @@ var go = (s3, t) => {
150333
150780
  });
150334
150781
  });
150335
150782
  };
150336
- import_node_fs16.default.open(s3.file, h, a);
150783
+ import_node_fs17.default.open(s3.file, h, a);
150337
150784
  });
150338
150785
  };
150339
150786
  var bo = (s3, t) => {
150340
150787
  t.forEach((e) => {
150341
- e.charAt(0) === "@" ? Ct({ file: import_node_path22.default.resolve(s3.cwd, e.slice(1)), sync: true, noResume: true, onReadEntry: (i) => s3.add(i) }) : s3.add(e);
150788
+ e.charAt(0) === "@" ? Ct({ file: import_node_path23.default.resolve(s3.cwd, e.slice(1)), sync: true, noResume: true, onReadEntry: (i) => s3.add(i) }) : s3.add(e);
150342
150789
  }), s3.end();
150343
150790
  };
150344
150791
  var _o = async (s3, t) => {
150345
- for (let e of t) e.charAt(0) === "@" ? await Ct({ file: import_node_path22.default.resolve(String(s3.cwd), e.slice(1)), noResume: true, onReadEntry: (i) => s3.add(i) }) : s3.add(e);
150792
+ for (let e of t) e.charAt(0) === "@" ? await Ct({ file: import_node_path23.default.resolve(String(s3.cwd), e.slice(1)), noResume: true, onReadEntry: (i) => s3.add(i) }) : s3.add(e);
150346
150793
  s3.end();
150347
150794
  };
150348
150795
  var vt = K(yo, go, () => {
@@ -150365,19 +150812,19 @@ var To = (s3) => {
150365
150812
  // src/updater/unpack.ts
150366
150813
  async function unpackTarball(opts) {
150367
150814
  const { tarballPath, destDir } = opts;
150368
- (0, import_node_fs17.rmSync)(destDir, { recursive: true, force: true });
150369
- (0, import_node_fs17.mkdirSync)(destDir, { recursive: true });
150815
+ (0, import_node_fs18.rmSync)(destDir, { recursive: true, force: true });
150816
+ (0, import_node_fs18.mkdirSync)(destDir, { recursive: true });
150370
150817
  await So({ file: tarballPath, cwd: destDir });
150371
150818
  }
150372
150819
 
150373
150820
  // src/updater/update-log.ts
150374
- var import_node_fs18 = require("fs");
150375
- var import_node_path23 = require("path");
150376
- var LOG_PATH = (0, import_node_path23.join)(THREADBASE_ROOT, "update.log");
150821
+ var import_node_fs19 = require("fs");
150822
+ var import_node_path24 = require("path");
150823
+ var LOG_PATH = (0, import_node_path24.join)(THREADBASE_ROOT, "update.log");
150377
150824
  function appendUpdateLog(line) {
150378
150825
  try {
150379
- (0, import_node_fs18.mkdirSync)(THREADBASE_ROOT, { recursive: true });
150380
- (0, import_node_fs18.appendFileSync)(LOG_PATH, `${(/* @__PURE__ */ new Date()).toISOString()} ${line}
150826
+ (0, import_node_fs19.mkdirSync)(THREADBASE_ROOT, { recursive: true });
150827
+ (0, import_node_fs19.appendFileSync)(LOG_PATH, `${(/* @__PURE__ */ new Date()).toISOString()} ${line}
150381
150828
  `, "utf8");
150382
150829
  } catch {
150383
150830
  }
@@ -150448,7 +150895,7 @@ async function runInstall(opts) {
150448
150895
  }
150449
150896
  }
150450
150897
  ensureReleasesDir();
150451
- (0, import_node_fs19.mkdirSync)(DOWNLOAD_DIR, { recursive: true });
150898
+ (0, import_node_fs20.mkdirSync)(DOWNLOAD_DIR, { recursive: true });
150452
150899
  const tarballPath = downloadPath(targetVersion, artifact.filename);
150453
150900
  await downloadAndVerify({ manifest, assets: target.assets, targetPath: tarballPath });
150454
150901
  const destDir = releaseDir(targetVersion);
@@ -150482,7 +150929,7 @@ async function runInstall(opts) {
150482
150929
 
150483
150930
  // cli/prod.ts
150484
150931
  var import_node_child_process6 = require("child_process");
150485
- var import_node_fs21 = require("fs");
150932
+ var import_node_fs22 = require("fs");
150486
150933
  init_constants();
150487
150934
  init_launchd();
150488
150935
  init_marker();
@@ -150568,7 +151015,7 @@ async function runProdDoctor(opts) {
150568
151015
  return { findings, repairs };
150569
151016
  }
150570
151017
  var defaultSpawnTail = ({ files, lines, follow }) => {
150571
- const existing = files.filter((f2) => (0, import_node_fs21.existsSync)(f2));
151018
+ const existing = files.filter((f2) => (0, import_node_fs22.existsSync)(f2));
150572
151019
  if (existing.length === 0) {
150573
151020
  return Promise.resolve({
150574
151021
  ok: false,
@@ -150840,12 +151287,12 @@ program2.command("cache").description("Manage the local SQLite conversation cach
150840
151287
  "Cache directory (default: ~/.threadbase/cache)",
150841
151288
  `${process.env.HOME}/.threadbase/cache`
150842
151289
  ).action((opts) => {
150843
- const { rmSync: rmSync6, existsSync: existsSync12 } = require("fs");
150844
- const { join: join26 } = require("path");
150845
- const dbPath = join26(opts.cacheDir, "cache.db");
151290
+ const { rmSync: rmSync6, existsSync: existsSync13 } = require("fs");
151291
+ const { join: join28 } = require("path");
151292
+ const dbPath = join28(opts.cacheDir, "cache.db");
150846
151293
  for (const suffix of ["", "-shm", "-wal"]) {
150847
151294
  const f2 = dbPath + suffix;
150848
- if (existsSync12(f2)) {
151295
+ if (existsSync13(f2)) {
150849
151296
  rmSync6(f2);
150850
151297
  log7.info(`Deleted ${f2}`, { path: f2 }, "console");
150851
151298
  }